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 
     48 /* To avoid EBCDIC trouble when parsing on zOS */
     49 #if defined(__MVS__)
     50 #pragma convert("ISO8859-1")
     51 #endif
     52 
     53 #define IN_LIBXML
     54 #include "libxml.h"
     55 
     56 #ifdef LIBXML_SCHEMAS_ENABLED
     57 
     58 #include <string.h>
     59 #include <libxml/xmlmemory.h>
     60 #include <libxml/parser.h>
     61 #include <libxml/parserInternals.h>
     62 #include <libxml/hash.h>
     63 #include <libxml/uri.h>
     64 #include <libxml/xmlschemas.h>
     65 #include <libxml/schemasInternals.h>
     66 #include <libxml/xmlschemastypes.h>
     67 #include <libxml/xmlautomata.h>
     68 #include <libxml/xmlregexp.h>
     69 #include <libxml/dict.h>
     70 #include <libxml/encoding.h>
     71 #include <libxml/xmlIO.h>
     72 #ifdef LIBXML_PATTERN_ENABLED
     73 #include <libxml/pattern.h>
     74 #endif
     75 #ifdef LIBXML_READER_ENABLED
     76 #include <libxml/xmlreader.h>
     77 #endif
     78 
     79 /* #define DEBUG 1 */
     80 
     81 /* #define DEBUG_CONTENT 1 */
     82 
     83 /* #define DEBUG_TYPE 1 */
     84 
     85 /* #define DEBUG_CONTENT_REGEXP 1 */
     86 
     87 /* #define DEBUG_AUTOMATA 1 */
     88 
     89 /* #define DEBUG_IDC */
     90 
     91 /* #define DEBUG_IDC_NODE_TABLE */
     92 
     93 /* #define WXS_ELEM_DECL_CONS_ENABLED */
     94 
     95 #ifdef DEBUG_IDC
     96  #ifndef DEBUG_IDC_NODE_TABLE
     97   #define DEBUG_IDC_NODE_TABLE
     98  #endif
     99 #endif
    100 
    101 /* #define ENABLE_PARTICLE_RESTRICTION 1 */
    102 
    103 #define ENABLE_REDEFINE
    104 
    105 /* #define ENABLE_NAMED_LOCALS */
    106 
    107 /* #define ENABLE_IDC_NODE_TABLES_TEST */
    108 
    109 #define DUMP_CONTENT_MODEL
    110 
    111 #ifdef LIBXML_READER_ENABLED
    112 /* #define XML_SCHEMA_READER_ENABLED */
    113 #endif
    114 
    115 #define UNBOUNDED (1 << 30)
    116 #define TODO								\
    117     xmlGenericError(xmlGenericErrorContext,				\
    118 	    "Unimplemented block at %s:%d\n",				\
    119             __FILE__, __LINE__);
    120 
    121 #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
    122 
    123 /*
    124  * The XML Schemas namespaces
    125  */
    126 static const xmlChar *xmlSchemaNs = (const xmlChar *)
    127     "http://www.w3.org/2001/XMLSchema";
    128 
    129 static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
    130     "http://www.w3.org/2001/XMLSchema-instance";
    131 
    132 static const xmlChar *xmlNamespaceNs = (const xmlChar *)
    133     "http://www.w3.org/2000/xmlns/";
    134 
    135 /*
    136 * Come casting macros.
    137 */
    138 #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
    139 #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
    140 #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
    141 #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
    142 #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
    143 #define WXS_PTC_CAST (xmlSchemaParticlePtr)
    144 #define WXS_TYPE_CAST (xmlSchemaTypePtr)
    145 #define WXS_ELEM_CAST (xmlSchemaElementPtr)
    146 #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
    147 #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
    148 #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
    149 #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
    150 #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
    151 #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
    152 #define WXS_IDC_CAST (xmlSchemaIDCPtr)
    153 #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
    154 #define WXS_LIST_CAST (xmlSchemaItemListPtr)
    155 
    156 /*
    157 * Macros to query common properties of components.
    158 */
    159 #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
    160 
    161 #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
    162 /*
    163 * Macros for element declarations.
    164 */
    165 #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
    166 
    167 #define WXS_SUBST_HEAD(item) (item)->refDecl
    168 /*
    169 * Macros for attribute declarations.
    170 */
    171 #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
    172 /*
    173 * Macros for attribute uses.
    174 */
    175 #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
    176 
    177 #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
    178 
    179 #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
    180 
    181 #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
    182 /*
    183 * Macros for attribute groups.
    184 */
    185 #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
    186 #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
    187 /*
    188 * Macros for particles.
    189 */
    190 #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
    191 
    192 #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
    193 
    194 #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
    195 
    196 #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
    197 /*
    198 * Macros for model groups definitions.
    199 */
    200 #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
    201 /*
    202 * Macros for model groups.
    203 */
    204 #define WXS_IS_MODEL_GROUP(i) \
    205     (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
    206      ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
    207      ((i)->type == XML_SCHEMA_TYPE_ALL))
    208 
    209 #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
    210 /*
    211 * Macros for schema buckets.
    212 */
    213 #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
    214     ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
    215 
    216 #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
    217     ((t) == XML_SCHEMA_SCHEMA_IMPORT))
    218 
    219 #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
    220 
    221 #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
    222 /*
    223 * Macros for complex/simple types.
    224 */
    225 #define WXS_IS_ANYTYPE(i) \
    226      (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
    227       ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
    228 
    229 #define WXS_IS_COMPLEX(i) \
    230     (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
    231      ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
    232 
    233 #define WXS_IS_SIMPLE(item) \
    234     ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
    235      ((item->type == XML_SCHEMA_TYPE_BASIC) && \
    236       (item->builtInType != XML_SCHEMAS_ANYTYPE)))
    237 
    238 #define WXS_IS_ANY_SIMPLE_TYPE(i) \
    239     (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
    240       ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
    241 
    242 #define WXS_IS_RESTRICTION(t) \
    243     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
    244 
    245 #define WXS_IS_EXTENSION(t) \
    246     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
    247 
    248 #define WXS_IS_TYPE_NOT_FIXED(i) \
    249     (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
    250      (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
    251 
    252 #define WXS_IS_TYPE_NOT_FIXED_1(item) \
    253     (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
    254      (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
    255 
    256 #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
    257 
    258 #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
    259 /*
    260 * Macros for exclusively for complex types.
    261 */
    262 #define WXS_HAS_COMPLEX_CONTENT(item) \
    263     ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
    264      (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
    265      (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
    266 
    267 #define WXS_HAS_SIMPLE_CONTENT(item) \
    268     ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
    269      (item->contentType == XML_SCHEMA_CONTENT_BASIC))
    270 
    271 #define WXS_HAS_MIXED_CONTENT(item) \
    272     (item->contentType == XML_SCHEMA_CONTENT_MIXED)
    273 
    274 #define WXS_EMPTIABLE(t) \
    275     (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
    276 
    277 #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
    278 
    279 #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
    280 
    281 #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
    282 /*
    283 * Macros for exclusively for simple types.
    284 */
    285 #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
    286 
    287 #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
    288 
    289 #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
    290 
    291 #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
    292 /*
    293 * Misc parser context macros.
    294 */
    295 #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
    296 
    297 #define WXS_HAS_BUCKETS(ctx) \
    298 ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
    299 (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
    300 
    301 #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
    302 
    303 #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
    304 
    305 #define WXS_SCHEMA(ctx) (ctx)->schema
    306 
    307 #define WXS_ADD_LOCAL(ctx, item) \
    308     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
    309 
    310 #define WXS_ADD_GLOBAL(ctx, item) \
    311     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
    312 
    313 #define WXS_ADD_PENDING(ctx, item) \
    314     xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
    315 /*
    316 * xmlSchemaItemList macros.
    317 */
    318 #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
    319 /*
    320 * Misc macros.
    321 */
    322 #define IS_SCHEMA(node, type) \
    323    ((node != NULL) && (node->ns != NULL) && \
    324     (xmlStrEqual(node->name, (const xmlChar *) type)) && \
    325     (xmlStrEqual(node->ns->href, xmlSchemaNs)))
    326 
    327 #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
    328 
    329 /*
    330 * Since we put the default/fixed values into the dict, we can
    331 * use pointer comparison for those values.
    332 * REMOVED: (xmlStrEqual((v1), (v2)))
    333 */
    334 #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
    335 
    336 #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
    337 
    338 #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
    339 
    340 #define HFAILURE if (res == -1) goto exit_failure;
    341 
    342 #define HERROR if (res != 0) goto exit_error;
    343 
    344 #define HSTOP(ctx) if ((ctx)->stop) goto exit;
    345 /*
    346 * Some flags used for various schema constraints.
    347 */
    348 #define SUBSET_RESTRICTION  1<<0
    349 #define SUBSET_EXTENSION    1<<1
    350 #define SUBSET_SUBSTITUTION 1<<2
    351 #define SUBSET_LIST         1<<3
    352 #define SUBSET_UNION        1<<4
    353 
    354 typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
    355 typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
    356 
    357 typedef struct _xmlSchemaItemList xmlSchemaItemList;
    358 typedef xmlSchemaItemList *xmlSchemaItemListPtr;
    359 struct _xmlSchemaItemList {
    360     void **items;  /* used for dynamic addition of schemata */
    361     int nbItems; /* used for dynamic addition of schemata */
    362     int sizeItems; /* used for dynamic addition of schemata */
    363 };
    364 
    365 #define XML_SCHEMA_CTXT_PARSER 1
    366 #define XML_SCHEMA_CTXT_VALIDATOR 2
    367 
    368 typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
    369 typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
    370 struct _xmlSchemaAbstractCtxt {
    371     int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
    372     void *dummy; /* Fix alignment issues */
    373 };
    374 
    375 typedef struct _xmlSchemaBucket xmlSchemaBucket;
    376 typedef xmlSchemaBucket *xmlSchemaBucketPtr;
    377 
    378 #define XML_SCHEMA_SCHEMA_MAIN 0
    379 #define XML_SCHEMA_SCHEMA_IMPORT 1
    380 #define XML_SCHEMA_SCHEMA_INCLUDE 2
    381 #define XML_SCHEMA_SCHEMA_REDEFINE 3
    382 
    383 /**
    384  * xmlSchemaSchemaRelation:
    385  *
    386  * Used to create a graph of schema relationships.
    387  */
    388 typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
    389 typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
    390 struct _xmlSchemaSchemaRelation {
    391     xmlSchemaSchemaRelationPtr next;
    392     int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
    393     const xmlChar *importNamespace;
    394     xmlSchemaBucketPtr bucket;
    395 };
    396 
    397 #define XML_SCHEMA_BUCKET_MARKED 1<<0
    398 #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
    399 
    400 struct _xmlSchemaBucket {
    401     int type;
    402     int flags;
    403     const xmlChar *schemaLocation;
    404     const xmlChar *origTargetNamespace;
    405     const xmlChar *targetNamespace;
    406     xmlDocPtr doc;
    407     xmlSchemaSchemaRelationPtr relations;
    408     int located;
    409     int parsed;
    410     int imported;
    411     int preserveDoc;
    412     xmlSchemaItemListPtr globals; /* Global components. */
    413     xmlSchemaItemListPtr locals; /* Local components. */
    414 };
    415 
    416 /**
    417  * xmlSchemaImport:
    418  * (extends xmlSchemaBucket)
    419  *
    420  * Reflects a schema. Holds some information
    421  * about the schema and its toplevel components. Duplicate
    422  * toplevel components are not checked at this level.
    423  */
    424 typedef struct _xmlSchemaImport xmlSchemaImport;
    425 typedef xmlSchemaImport *xmlSchemaImportPtr;
    426 struct _xmlSchemaImport {
    427     int type; /* Main OR import OR include. */
    428     int flags;
    429     const xmlChar *schemaLocation; /* The URI of the schema document. */
    430     /* For chameleon includes, @origTargetNamespace will be NULL */
    431     const xmlChar *origTargetNamespace;
    432     /*
    433     * For chameleon includes, @targetNamespace will be the
    434     * targetNamespace of the including schema.
    435     */
    436     const xmlChar *targetNamespace;
    437     xmlDocPtr doc; /* The schema node-tree. */
    438     /* @relations will hold any included/imported/redefined schemas. */
    439     xmlSchemaSchemaRelationPtr relations;
    440     int located;
    441     int parsed;
    442     int imported;
    443     int preserveDoc;
    444     xmlSchemaItemListPtr globals;
    445     xmlSchemaItemListPtr locals;
    446     /* The imported schema. */
    447     xmlSchemaPtr schema;
    448 };
    449 
    450 /*
    451 * (extends xmlSchemaBucket)
    452 */
    453 typedef struct _xmlSchemaInclude xmlSchemaInclude;
    454 typedef xmlSchemaInclude *xmlSchemaIncludePtr;
    455 struct _xmlSchemaInclude {
    456     int type;
    457     int flags;
    458     const xmlChar *schemaLocation;
    459     const xmlChar *origTargetNamespace;
    460     const xmlChar *targetNamespace;
    461     xmlDocPtr doc;
    462     xmlSchemaSchemaRelationPtr relations;
    463     int located;
    464     int parsed;
    465     int imported;
    466     int preserveDoc;
    467     xmlSchemaItemListPtr globals; /* Global components. */
    468     xmlSchemaItemListPtr locals; /* Local components. */
    469 
    470     /* The owning main or import schema bucket. */
    471     xmlSchemaImportPtr ownerImport;
    472 };
    473 
    474 /**
    475  * xmlSchemaBasicItem:
    476  *
    477  * The abstract base type for schema components.
    478  */
    479 typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
    480 typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
    481 struct _xmlSchemaBasicItem {
    482     xmlSchemaTypeType type;
    483     void *dummy; /* Fix alignment issues */
    484 };
    485 
    486 /**
    487  * xmlSchemaAnnotItem:
    488  *
    489  * The abstract base type for annotated schema components.
    490  * (Extends xmlSchemaBasicItem)
    491  */
    492 typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
    493 typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
    494 struct _xmlSchemaAnnotItem {
    495     xmlSchemaTypeType type;
    496     xmlSchemaAnnotPtr annot;
    497 };
    498 
    499 /**
    500  * xmlSchemaTreeItem:
    501  *
    502  * The abstract base type for tree-like structured schema components.
    503  * (Extends xmlSchemaAnnotItem)
    504  */
    505 typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
    506 typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
    507 struct _xmlSchemaTreeItem {
    508     xmlSchemaTypeType type;
    509     xmlSchemaAnnotPtr annot;
    510     xmlSchemaTreeItemPtr next;
    511     xmlSchemaTreeItemPtr children;
    512 };
    513 
    514 
    515 #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
    516 /**
    517  * xmlSchemaAttributeUsePtr:
    518  *
    519  * The abstract base type for tree-like structured schema components.
    520  * (Extends xmlSchemaTreeItem)
    521  */
    522 typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
    523 typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
    524 struct _xmlSchemaAttributeUse {
    525     xmlSchemaTypeType type;
    526     xmlSchemaAnnotPtr annot;
    527     xmlSchemaAttributeUsePtr next; /* The next attr. use. */
    528     /*
    529     * The attr. decl. OR a QName-ref. to an attr. decl. OR
    530     * a QName-ref. to an attribute group definition.
    531     */
    532     xmlSchemaAttributePtr attrDecl;
    533 
    534     int flags;
    535     xmlNodePtr node;
    536     int occurs; /* required, optional */
    537     const xmlChar * defValue;
    538     xmlSchemaValPtr defVal;
    539 };
    540 
    541 /**
    542  * xmlSchemaAttributeUseProhibPtr:
    543  *
    544  * A helper component to reflect attribute prohibitions.
    545  * (Extends xmlSchemaBasicItem)
    546  */
    547 typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
    548 typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
    549 struct _xmlSchemaAttributeUseProhib {
    550     xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
    551     xmlNodePtr node;
    552     const xmlChar *name;
    553     const xmlChar *targetNamespace;
    554     int isRef;
    555 };
    556 
    557 /**
    558  * xmlSchemaRedef:
    559  */
    560 typedef struct _xmlSchemaRedef xmlSchemaRedef;
    561 typedef xmlSchemaRedef *xmlSchemaRedefPtr;
    562 struct _xmlSchemaRedef {
    563     xmlSchemaRedefPtr next;
    564     xmlSchemaBasicItemPtr item; /* The redefining component. */
    565     xmlSchemaBasicItemPtr reference; /* The referencing component. */
    566     xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
    567     const xmlChar *refName; /* The name of the to-be-redefined component. */
    568     const xmlChar *refTargetNs; /* The target namespace of the
    569                                    to-be-redefined comp. */
    570     xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
    571 };
    572 
    573 /**
    574  * xmlSchemaConstructionCtxt:
    575  */
    576 typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
    577 typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
    578 struct _xmlSchemaConstructionCtxt {
    579     xmlSchemaPtr mainSchema; /* The main schema. */
    580     xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
    581     xmlDictPtr dict;
    582     xmlSchemaItemListPtr buckets; /* List of schema buckets. */
    583     /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
    584     xmlSchemaBucketPtr bucket; /* The current schema bucket */
    585     xmlSchemaItemListPtr pending; /* All Components of all schemas that
    586                                      need to be fixed. */
    587     xmlHashTablePtr substGroups;
    588     xmlSchemaRedefPtr redefs;
    589     xmlSchemaRedefPtr lastRedef;
    590 };
    591 
    592 #define XML_SCHEMAS_PARSE_ERROR		1
    593 #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
    594 
    595 struct _xmlSchemaParserCtxt {
    596     int type;
    597     void *errCtxt;             /* user specific error context */
    598     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
    599     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
    600     int err;
    601     int nberrors;
    602     xmlStructuredErrorFunc serror;
    603 
    604     xmlSchemaConstructionCtxtPtr constructor;
    605     int ownsConstructor; /* TODO: Move this to parser *flags*. */
    606 
    607     /* xmlSchemaPtr topschema;	*/
    608     /* xmlHashTablePtr namespaces;  */
    609 
    610     xmlSchemaPtr schema;        /* The main schema in use */
    611     int counter;
    612 
    613     const xmlChar *URL;
    614     xmlDocPtr doc;
    615     int preserve;		/* Whether the doc should be freed  */
    616 
    617     const char *buffer;
    618     int size;
    619 
    620     /*
    621      * Used to build complex element content models
    622      */
    623     xmlAutomataPtr am;
    624     xmlAutomataStatePtr start;
    625     xmlAutomataStatePtr end;
    626     xmlAutomataStatePtr state;
    627 
    628     xmlDictPtr dict;		/* dictionary for interned string names */
    629     xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
    630     int options;
    631     xmlSchemaValidCtxtPtr vctxt;
    632     int isS4S;
    633     int isRedefine;
    634     int xsiAssemble;
    635     int stop; /* If the parser should stop; i.e. a critical error. */
    636     const xmlChar *targetNamespace;
    637     xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
    638 
    639     xmlSchemaRedefPtr redef; /* Used for redefinitions. */
    640     int redefCounter; /* Used for redefinitions. */
    641     xmlSchemaItemListPtr attrProhibs;
    642 };
    643 
    644 /**
    645  * xmlSchemaQNameRef:
    646  *
    647  * A component reference item (not a schema component)
    648  * (Extends xmlSchemaBasicItem)
    649  */
    650 typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
    651 typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
    652 struct _xmlSchemaQNameRef {
    653     xmlSchemaTypeType type;
    654     xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
    655     xmlSchemaTypeType itemType;
    656     const xmlChar *name;
    657     const xmlChar *targetNamespace;
    658     xmlNodePtr node;
    659 };
    660 
    661 /**
    662  * xmlSchemaParticle:
    663  *
    664  * A particle component.
    665  * (Extends xmlSchemaTreeItem)
    666  */
    667 typedef struct _xmlSchemaParticle xmlSchemaParticle;
    668 typedef xmlSchemaParticle *xmlSchemaParticlePtr;
    669 struct _xmlSchemaParticle {
    670     xmlSchemaTypeType type;
    671     xmlSchemaAnnotPtr annot;
    672     xmlSchemaTreeItemPtr next; /* next particle */
    673     xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
    674 	a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
    675         etc.) */
    676     int minOccurs;
    677     int maxOccurs;
    678     xmlNodePtr node;
    679 };
    680 
    681 /**
    682  * xmlSchemaModelGroup:
    683  *
    684  * A model group component.
    685  * (Extends xmlSchemaTreeItem)
    686  */
    687 typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
    688 typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
    689 struct _xmlSchemaModelGroup {
    690     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
    691     xmlSchemaAnnotPtr annot;
    692     xmlSchemaTreeItemPtr next; /* not used */
    693     xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
    694     xmlNodePtr node;
    695 };
    696 
    697 #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
    698 #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
    699 /**
    700  * xmlSchemaModelGroupDef:
    701  *
    702  * A model group definition component.
    703  * (Extends xmlSchemaTreeItem)
    704  */
    705 typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
    706 typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
    707 struct _xmlSchemaModelGroupDef {
    708     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
    709     xmlSchemaAnnotPtr annot;
    710     xmlSchemaTreeItemPtr next; /* not used */
    711     xmlSchemaTreeItemPtr children; /* the "model group" */
    712     const xmlChar *name;
    713     const xmlChar *targetNamespace;
    714     xmlNodePtr node;
    715     int flags;
    716 };
    717 
    718 typedef struct _xmlSchemaIDC xmlSchemaIDC;
    719 typedef xmlSchemaIDC *xmlSchemaIDCPtr;
    720 
    721 /**
    722  * xmlSchemaIDCSelect:
    723  *
    724  * The identity-constraint "field" and "selector" item, holding the
    725  * XPath expression.
    726  */
    727 typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
    728 typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
    729 struct _xmlSchemaIDCSelect {
    730     xmlSchemaIDCSelectPtr next;
    731     xmlSchemaIDCPtr idc;
    732     int index; /* an index position if significant for IDC key-sequences */
    733     const xmlChar *xpath; /* the XPath expression */
    734     void *xpathComp; /* the compiled XPath expression */
    735 };
    736 
    737 /**
    738  * xmlSchemaIDC:
    739  *
    740  * The identity-constraint definition component.
    741  * (Extends xmlSchemaAnnotItem)
    742  */
    743 
    744 struct _xmlSchemaIDC {
    745     xmlSchemaTypeType type;
    746     xmlSchemaAnnotPtr annot;
    747     xmlSchemaIDCPtr next;
    748     xmlNodePtr node;
    749     const xmlChar *name;
    750     const xmlChar *targetNamespace;
    751     xmlSchemaIDCSelectPtr selector;
    752     xmlSchemaIDCSelectPtr fields;
    753     int nbFields;
    754     xmlSchemaQNameRefPtr ref;
    755 };
    756 
    757 /**
    758  * xmlSchemaIDCAug:
    759  *
    760  * The augmented IDC information used for validation.
    761  */
    762 typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
    763 typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
    764 struct _xmlSchemaIDCAug {
    765     xmlSchemaIDCAugPtr next; /* next in a list */
    766     xmlSchemaIDCPtr def; /* the IDC definition */
    767     int keyrefDepth; /* the lowest tree level to which IDC
    768                         tables need to be bubbled upwards */
    769 };
    770 
    771 /**
    772  * xmlSchemaPSVIIDCKeySequence:
    773  *
    774  * The key sequence of a node table item.
    775  */
    776 typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
    777 typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
    778 struct _xmlSchemaPSVIIDCKey {
    779     xmlSchemaTypePtr type;
    780     xmlSchemaValPtr val;
    781 };
    782 
    783 /**
    784  * xmlSchemaPSVIIDCNode:
    785  *
    786  * The node table item of a node table.
    787  */
    788 typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
    789 typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
    790 struct _xmlSchemaPSVIIDCNode {
    791     xmlNodePtr node;
    792     xmlSchemaPSVIIDCKeyPtr *keys;
    793     int nodeLine;
    794     int nodeQNameID;
    795 
    796 };
    797 
    798 /**
    799  * xmlSchemaPSVIIDCBinding:
    800  *
    801  * The identity-constraint binding item of the [identity-constraint table].
    802  */
    803 typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
    804 typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
    805 struct _xmlSchemaPSVIIDCBinding {
    806     xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
    807     xmlSchemaIDCPtr definition; /* the IDC definition */
    808     xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
    809     int nbNodes; /* number of entries in the node table */
    810     int sizeNodes; /* size of the node table */
    811     xmlSchemaItemListPtr dupls;
    812 };
    813 
    814 
    815 #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
    816 #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
    817 
    818 #define XPATH_STATE_OBJ_MATCHES -2
    819 #define XPATH_STATE_OBJ_BLOCKED -3
    820 
    821 typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
    822 typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
    823 
    824 /**
    825  * xmlSchemaIDCStateObj:
    826  *
    827  * The state object used to evaluate XPath expressions.
    828  */
    829 typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
    830 typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
    831 struct _xmlSchemaIDCStateObj {
    832     int type;
    833     xmlSchemaIDCStateObjPtr next; /* next if in a list */
    834     int depth; /* depth of creation */
    835     int *history; /* list of (depth, state-id) tuples */
    836     int nbHistory;
    837     int sizeHistory;
    838     xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
    839                                        matcher */
    840     xmlSchemaIDCSelectPtr sel;
    841     void *xpathCtxt;
    842 };
    843 
    844 #define IDC_MATCHER 0
    845 
    846 /**
    847  * xmlSchemaIDCMatcher:
    848  *
    849  * Used to evaluate IDC selectors (and fields).
    850  */
    851 struct _xmlSchemaIDCMatcher {
    852     int type;
    853     int depth; /* the tree depth at creation time */
    854     xmlSchemaIDCMatcherPtr next; /* next in the list */
    855     xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
    856     xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
    857     int idcType;
    858     xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
    859                                          elements */
    860     int sizeKeySeqs;
    861     xmlSchemaItemListPtr targets; /* list of target-node
    862                                      (xmlSchemaPSVIIDCNodePtr) entries */
    863 };
    864 
    865 /*
    866 * Element info flags.
    867 */
    868 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
    869 #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
    870 #define XML_SCHEMA_ELEM_INFO_NILLED	       1<<2
    871 #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE	       1<<3
    872 
    873 #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
    874 #define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
    875 #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
    876 
    877 #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
    878 #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
    879 #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
    880 #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
    881 
    882 /**
    883  * xmlSchemaNodeInfo:
    884  *
    885  * Holds information of an element node.
    886  */
    887 struct _xmlSchemaNodeInfo {
    888     int nodeType;
    889     xmlNodePtr node;
    890     int nodeLine;
    891     const xmlChar *localName;
    892     const xmlChar *nsName;
    893     const xmlChar *value;
    894     xmlSchemaValPtr val; /* the pre-computed value if any */
    895     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
    896 
    897     int flags; /* combination of node info flags */
    898 
    899     int valNeeded;
    900     int normVal;
    901 
    902     xmlSchemaElementPtr decl; /* the element/attribute declaration */
    903     int depth;
    904     xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
    905                                             for the scope element*/
    906     xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
    907                                            element */
    908     xmlRegExecCtxtPtr regexCtxt;
    909 
    910     const xmlChar **nsBindings; /* Namespace bindings on this element */
    911     int nbNsBindings;
    912     int sizeNsBindings;
    913 
    914     int hasKeyrefs;
    915     int appliedXPath; /* Indicates that an XPath has been applied. */
    916 };
    917 
    918 #define XML_SCHEMAS_ATTR_UNKNOWN 1
    919 #define XML_SCHEMAS_ATTR_ASSESSED 2
    920 #define XML_SCHEMAS_ATTR_PROHIBITED 3
    921 #define XML_SCHEMAS_ATTR_ERR_MISSING 4
    922 #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
    923 #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
    924 #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
    925 #define XML_SCHEMAS_ATTR_DEFAULT 8
    926 #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
    927 #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
    928 #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
    929 #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
    930 #define XML_SCHEMAS_ATTR_WILD_SKIP 13
    931 #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
    932 #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
    933 #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
    934 #define XML_SCHEMAS_ATTR_META 17
    935 /*
    936 * @metaType values of xmlSchemaAttrInfo.
    937 */
    938 #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
    939 #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
    940 #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
    941 #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
    942 #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
    943 
    944 typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
    945 typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
    946 struct _xmlSchemaAttrInfo {
    947     int nodeType;
    948     xmlNodePtr node;
    949     int nodeLine;
    950     const xmlChar *localName;
    951     const xmlChar *nsName;
    952     const xmlChar *value;
    953     xmlSchemaValPtr val; /* the pre-computed value if any */
    954     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
    955     int flags; /* combination of node info flags */
    956 
    957     xmlSchemaAttributePtr decl; /* the attribute declaration */
    958     xmlSchemaAttributeUsePtr use;  /* the attribute use */
    959     int state;
    960     int metaType;
    961     const xmlChar *vcValue; /* the value constraint value */
    962     xmlSchemaNodeInfoPtr parent;
    963 };
    964 
    965 
    966 #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
    967 /**
    968  * xmlSchemaValidCtxt:
    969  *
    970  * A Schemas validation context
    971  */
    972 struct _xmlSchemaValidCtxt {
    973     int type;
    974     void *errCtxt;             /* user specific data block */
    975     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
    976     xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
    977     xmlStructuredErrorFunc serror;
    978 
    979     xmlSchemaPtr schema;        /* The schema in use */
    980     xmlDocPtr doc;
    981     xmlParserInputBufferPtr input;
    982     xmlCharEncoding enc;
    983     xmlSAXHandlerPtr sax;
    984     xmlParserCtxtPtr parserCtxt;
    985     void *user_data; /* TODO: What is this for? */
    986     char *filename;
    987 
    988     int err;
    989     int nberrors;
    990 
    991     xmlNodePtr node;
    992     xmlNodePtr cur;
    993     /* xmlSchemaTypePtr type; */
    994 
    995     xmlRegExecCtxtPtr regexp;
    996     xmlSchemaValPtr value;
    997 
    998     int valueWS;
    999     int options;
   1000     xmlNodePtr validationRoot;
   1001     xmlSchemaParserCtxtPtr pctxt;
   1002     int xsiAssemble;
   1003 
   1004     int depth;
   1005     xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
   1006     int sizeElemInfos;
   1007     xmlSchemaNodeInfoPtr inode; /* the current element information */
   1008 
   1009     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
   1010 
   1011     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
   1012     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
   1013     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
   1014 
   1015     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
   1016     int nbIdcNodes;
   1017     int sizeIdcNodes;
   1018 
   1019     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
   1020     int nbIdcKeys;
   1021     int sizeIdcKeys;
   1022 
   1023     int flags;
   1024 
   1025     xmlDictPtr dict;
   1026 
   1027 #ifdef LIBXML_READER_ENABLED
   1028     xmlTextReaderPtr reader;
   1029 #endif
   1030 
   1031     xmlSchemaAttrInfoPtr *attrInfos;
   1032     int nbAttrInfos;
   1033     int sizeAttrInfos;
   1034 
   1035     int skipDepth;
   1036     xmlSchemaItemListPtr nodeQNames;
   1037     int hasKeyrefs;
   1038     int createIDCNodeTables;
   1039     int psviExposeIDCNodeTables;
   1040 
   1041     /* Locator for error reporting in streaming mode */
   1042     xmlSchemaValidityLocatorFunc locFunc;
   1043     void *locCtxt;
   1044 };
   1045 
   1046 /**
   1047  * xmlSchemaSubstGroup:
   1048  *
   1049  *
   1050  */
   1051 typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
   1052 typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
   1053 struct _xmlSchemaSubstGroup {
   1054     xmlSchemaElementPtr head;
   1055     xmlSchemaItemListPtr members;
   1056 };
   1057 
   1058 /************************************************************************
   1059  *									*
   1060  *			Some predeclarations				*
   1061  *									*
   1062  ************************************************************************/
   1063 
   1064 static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
   1065                                  xmlSchemaPtr schema,
   1066                                  xmlNodePtr node);
   1067 static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
   1068                                  xmlSchemaPtr schema,
   1069                                  xmlNodePtr node);
   1070 static int
   1071 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   1072                    xmlSchemaAbstractCtxtPtr ctxt);
   1073 static const xmlChar *
   1074 xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
   1075 static int
   1076 xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   1077                      xmlNodePtr node);
   1078 static int
   1079 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   1080                        xmlSchemaParserCtxtPtr ctxt);
   1081 static void
   1082 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
   1083 static xmlSchemaWhitespaceValueType
   1084 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
   1085 static xmlSchemaTreeItemPtr
   1086 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   1087 			 xmlNodePtr node, xmlSchemaTypeType type,
   1088 			 int withParticle);
   1089 static const xmlChar *
   1090 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
   1091 static xmlSchemaTypeLinkPtr
   1092 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
   1093 static void
   1094 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   1095 		     const char *funcName,
   1096 		     const char *message) LIBXML_ATTR_FORMAT(3,0);
   1097 static int
   1098 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
   1099 			     xmlSchemaTypePtr type,
   1100 			     xmlSchemaTypePtr baseType,
   1101 			     int subset);
   1102 static void
   1103 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   1104 				   xmlSchemaParserCtxtPtr ctxt);
   1105 static void
   1106 xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
   1107 static xmlSchemaQNameRefPtr
   1108 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   1109 				xmlSchemaPtr schema,
   1110 				xmlNodePtr node);
   1111 
   1112 /************************************************************************
   1113  *									*
   1114  *			Helper functions			        *
   1115  *									*
   1116  ************************************************************************/
   1117 
   1118 /**
   1119  * xmlSchemaItemTypeToStr:
   1120  * @type: the type of the schema item
   1121  *
   1122  * Returns the component name of a schema item.
   1123  */
   1124 static const xmlChar *
   1125 xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
   1126 {
   1127     switch (type) {
   1128 	case XML_SCHEMA_TYPE_BASIC:
   1129 	    return(BAD_CAST "simple type definition");
   1130 	case XML_SCHEMA_TYPE_SIMPLE:
   1131 	    return(BAD_CAST "simple type definition");
   1132 	case XML_SCHEMA_TYPE_COMPLEX:
   1133 	    return(BAD_CAST "complex type definition");
   1134 	case XML_SCHEMA_TYPE_ELEMENT:
   1135 	    return(BAD_CAST "element declaration");
   1136 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1137 	    return(BAD_CAST "attribute use");
   1138 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1139 	    return(BAD_CAST "attribute declaration");
   1140 	case XML_SCHEMA_TYPE_GROUP:
   1141 	    return(BAD_CAST "model group definition");
   1142 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1143 	    return(BAD_CAST "attribute group definition");
   1144 	case XML_SCHEMA_TYPE_NOTATION:
   1145 	    return(BAD_CAST "notation declaration");
   1146 	case XML_SCHEMA_TYPE_SEQUENCE:
   1147 	    return(BAD_CAST "model group (sequence)");
   1148 	case XML_SCHEMA_TYPE_CHOICE:
   1149 	    return(BAD_CAST "model group (choice)");
   1150 	case XML_SCHEMA_TYPE_ALL:
   1151 	    return(BAD_CAST "model group (all)");
   1152 	case XML_SCHEMA_TYPE_PARTICLE:
   1153 	    return(BAD_CAST "particle");
   1154 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1155 	    return(BAD_CAST "unique identity-constraint");
   1156 	    /* return(BAD_CAST "IDC (unique)"); */
   1157 	case XML_SCHEMA_TYPE_IDC_KEY:
   1158 	    return(BAD_CAST "key identity-constraint");
   1159 	    /* return(BAD_CAST "IDC (key)"); */
   1160 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1161 	    return(BAD_CAST "keyref identity-constraint");
   1162 	    /* return(BAD_CAST "IDC (keyref)"); */
   1163 	case XML_SCHEMA_TYPE_ANY:
   1164 	    return(BAD_CAST "wildcard (any)");
   1165 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1166 	    return(BAD_CAST "[helper component] QName reference");
   1167 	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   1168 	    return(BAD_CAST "[helper component] attribute use prohibition");
   1169 	default:
   1170 	    return(BAD_CAST "Not a schema component");
   1171     }
   1172 }
   1173 
   1174 /**
   1175  * xmlSchemaGetComponentTypeStr:
   1176  * @type: the type of the schema item
   1177  *
   1178  * Returns the component name of a schema item.
   1179  */
   1180 static const xmlChar *
   1181 xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
   1182 {
   1183     switch (item->type) {
   1184 	case XML_SCHEMA_TYPE_BASIC:
   1185 	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
   1186 		return(BAD_CAST "complex type definition");
   1187 	    else
   1188 		return(BAD_CAST "simple type definition");
   1189 	default:
   1190 	    return(xmlSchemaItemTypeToStr(item->type));
   1191     }
   1192 }
   1193 
   1194 /**
   1195  * xmlSchemaGetComponentNode:
   1196  * @item: a schema component
   1197  *
   1198  * Returns node associated with the schema component.
   1199  * NOTE that such a node need not be available; plus, a component's
   1200  * node need not to reflect the component directly, since there is no
   1201  * one-to-one relationship between the XML Schema representation and
   1202  * the component representation.
   1203  */
   1204 static xmlNodePtr
   1205 xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
   1206 {
   1207     switch (item->type) {
   1208 	case XML_SCHEMA_TYPE_ELEMENT:
   1209 	    return (((xmlSchemaElementPtr) item)->node);
   1210 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1211 	    return (((xmlSchemaAttributePtr) item)->node);
   1212 	case XML_SCHEMA_TYPE_COMPLEX:
   1213 	case XML_SCHEMA_TYPE_SIMPLE:
   1214 	    return (((xmlSchemaTypePtr) item)->node);
   1215 	case XML_SCHEMA_TYPE_ANY:
   1216 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1217 	    return (((xmlSchemaWildcardPtr) item)->node);
   1218 	case XML_SCHEMA_TYPE_PARTICLE:
   1219 	    return (((xmlSchemaParticlePtr) item)->node);
   1220 	case XML_SCHEMA_TYPE_SEQUENCE:
   1221 	case XML_SCHEMA_TYPE_CHOICE:
   1222 	case XML_SCHEMA_TYPE_ALL:
   1223 	    return (((xmlSchemaModelGroupPtr) item)->node);
   1224 	case XML_SCHEMA_TYPE_GROUP:
   1225 	    return (((xmlSchemaModelGroupDefPtr) item)->node);
   1226 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1227 	    return (((xmlSchemaAttributeGroupPtr) item)->node);
   1228 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1229 	case XML_SCHEMA_TYPE_IDC_KEY:
   1230 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1231 	    return (((xmlSchemaIDCPtr) item)->node);
   1232 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1233 	    return(((xmlSchemaQNameRefPtr) item)->node);
   1234 	/* TODO: What to do with NOTATIONs?
   1235 	case XML_SCHEMA_TYPE_NOTATION:
   1236 	    return (((xmlSchemaNotationPtr) item)->node);
   1237 	*/
   1238 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1239 	    return (((xmlSchemaAttributeUsePtr) item)->node);
   1240 	default:
   1241 	    return (NULL);
   1242     }
   1243 }
   1244 
   1245 #if 0
   1246 /**
   1247  * xmlSchemaGetNextComponent:
   1248  * @item: a schema component
   1249  *
   1250  * Returns the next sibling of the schema component.
   1251  */
   1252 static xmlSchemaBasicItemPtr
   1253 xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
   1254 {
   1255     switch (item->type) {
   1256 	case XML_SCHEMA_TYPE_ELEMENT:
   1257 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
   1258 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1259 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
   1260 	case XML_SCHEMA_TYPE_COMPLEX:
   1261 	case XML_SCHEMA_TYPE_SIMPLE:
   1262 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
   1263 	case XML_SCHEMA_TYPE_ANY:
   1264 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1265 	    return (NULL);
   1266 	case XML_SCHEMA_TYPE_PARTICLE:
   1267 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
   1268 	case XML_SCHEMA_TYPE_SEQUENCE:
   1269 	case XML_SCHEMA_TYPE_CHOICE:
   1270 	case XML_SCHEMA_TYPE_ALL:
   1271 	    return (NULL);
   1272 	case XML_SCHEMA_TYPE_GROUP:
   1273 	    return (NULL);
   1274 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1275 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
   1276 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1277 	case XML_SCHEMA_TYPE_IDC_KEY:
   1278 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1279 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
   1280 	default:
   1281 	    return (NULL);
   1282     }
   1283 }
   1284 #endif
   1285 
   1286 
   1287 /**
   1288  * xmlSchemaFormatQName:
   1289  * @buf: the string buffer
   1290  * @namespaceName:  the namespace name
   1291  * @localName: the local name
   1292  *
   1293  * Returns the given QName in the format "{namespaceName}localName" or
   1294  * just "localName" if @namespaceName is NULL.
   1295  *
   1296  * Returns the localName if @namespaceName is NULL, a formatted
   1297  * string otherwise.
   1298  */
   1299 static const xmlChar*
   1300 xmlSchemaFormatQName(xmlChar **buf,
   1301 		     const xmlChar *namespaceName,
   1302 		     const xmlChar *localName)
   1303 {
   1304     FREE_AND_NULL(*buf)
   1305     if (namespaceName != NULL) {
   1306 	*buf = xmlStrdup(BAD_CAST "{");
   1307 	*buf = xmlStrcat(*buf, namespaceName);
   1308 	*buf = xmlStrcat(*buf, BAD_CAST "}");
   1309     }
   1310     if (localName != NULL) {
   1311 	if (namespaceName == NULL)
   1312 	    return(localName);
   1313 	*buf = xmlStrcat(*buf, localName);
   1314     } else {
   1315 	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
   1316     }
   1317     return ((const xmlChar *) *buf);
   1318 }
   1319 
   1320 static const xmlChar*
   1321 xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
   1322 {
   1323     if (ns != NULL)
   1324 	return (xmlSchemaFormatQName(buf, ns->href, localName));
   1325     else
   1326 	return (xmlSchemaFormatQName(buf, NULL, localName));
   1327 }
   1328 
   1329 static const xmlChar *
   1330 xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
   1331 {
   1332     switch (item->type) {
   1333 	case XML_SCHEMA_TYPE_ELEMENT:
   1334 	    return (((xmlSchemaElementPtr) item)->name);
   1335 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1336 	    return (((xmlSchemaAttributePtr) item)->name);
   1337 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1338 	    return (((xmlSchemaAttributeGroupPtr) item)->name);
   1339 	case XML_SCHEMA_TYPE_BASIC:
   1340 	case XML_SCHEMA_TYPE_SIMPLE:
   1341 	case XML_SCHEMA_TYPE_COMPLEX:
   1342 	    return (((xmlSchemaTypePtr) item)->name);
   1343 	case XML_SCHEMA_TYPE_GROUP:
   1344 	    return (((xmlSchemaModelGroupDefPtr) item)->name);
   1345 	case XML_SCHEMA_TYPE_IDC_KEY:
   1346 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1347 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1348 	    return (((xmlSchemaIDCPtr) item)->name);
   1349 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1350 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
   1351 		return(xmlSchemaGetComponentName(
   1352 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
   1353 	    } else
   1354 		return(NULL);
   1355 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1356 	    return (((xmlSchemaQNameRefPtr) item)->name);
   1357 	case XML_SCHEMA_TYPE_NOTATION:
   1358 	    return (((xmlSchemaNotationPtr) item)->name);
   1359 	default:
   1360 	    /*
   1361 	    * Other components cannot have names.
   1362 	    */
   1363 	    break;
   1364     }
   1365     return (NULL);
   1366 }
   1367 
   1368 #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
   1369 #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
   1370 /*
   1371 static const xmlChar *
   1372 xmlSchemaGetQNameRefName(void *ref)
   1373 {
   1374     return(((xmlSchemaQNameRefPtr) ref)->name);
   1375 }
   1376 
   1377 static const xmlChar *
   1378 xmlSchemaGetQNameRefTargetNs(void *ref)
   1379 {
   1380     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
   1381 }
   1382 */
   1383 
   1384 static const xmlChar *
   1385 xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
   1386 {
   1387     switch (item->type) {
   1388 	case XML_SCHEMA_TYPE_ELEMENT:
   1389 	    return (((xmlSchemaElementPtr) item)->targetNamespace);
   1390 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   1391 	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
   1392 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1393 	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
   1394 	case XML_SCHEMA_TYPE_BASIC:
   1395 	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
   1396 	case XML_SCHEMA_TYPE_SIMPLE:
   1397 	case XML_SCHEMA_TYPE_COMPLEX:
   1398 	    return (((xmlSchemaTypePtr) item)->targetNamespace);
   1399 	case XML_SCHEMA_TYPE_GROUP:
   1400 	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
   1401 	case XML_SCHEMA_TYPE_IDC_KEY:
   1402 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1403 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1404 	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
   1405 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   1406 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
   1407 		return(xmlSchemaGetComponentTargetNs(
   1408 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
   1409 	    }
   1410 	    /* TODO: Will returning NULL break something? */
   1411 	    break;
   1412 	case XML_SCHEMA_EXTRA_QNAMEREF:
   1413 	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
   1414 	case XML_SCHEMA_TYPE_NOTATION:
   1415 	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
   1416 	default:
   1417 	    /*
   1418 	    * Other components cannot have names.
   1419 	    */
   1420 	    break;
   1421     }
   1422     return (NULL);
   1423 }
   1424 
   1425 static const xmlChar*
   1426 xmlSchemaGetComponentQName(xmlChar **buf,
   1427 			   void *item)
   1428 {
   1429     return (xmlSchemaFormatQName(buf,
   1430 	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
   1431 	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
   1432 }
   1433 
   1434 static const xmlChar*
   1435 xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
   1436 {
   1437     xmlChar *str = NULL;
   1438 
   1439     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
   1440     *buf = xmlStrcat(*buf, BAD_CAST " '");
   1441     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
   1442 	(xmlSchemaBasicItemPtr) item));
   1443     *buf = xmlStrcat(*buf, BAD_CAST "'");
   1444     FREE_AND_NULL(str);
   1445     return(*buf);
   1446 }
   1447 
   1448 static const xmlChar*
   1449 xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
   1450 {
   1451     return(xmlSchemaGetComponentDesignation(buf, idc));
   1452 }
   1453 
   1454 /**
   1455  * xmlSchemaWildcardPCToString:
   1456  * @pc: the type of processContents
   1457  *
   1458  * Returns a string representation of the type of
   1459  * processContents.
   1460  */
   1461 static const xmlChar *
   1462 xmlSchemaWildcardPCToString(int pc)
   1463 {
   1464     switch (pc) {
   1465 	case XML_SCHEMAS_ANY_SKIP:
   1466 	    return (BAD_CAST "skip");
   1467 	case XML_SCHEMAS_ANY_LAX:
   1468 	    return (BAD_CAST "lax");
   1469 	case XML_SCHEMAS_ANY_STRICT:
   1470 	    return (BAD_CAST "strict");
   1471 	default:
   1472 	    return (BAD_CAST "invalid process contents");
   1473     }
   1474 }
   1475 
   1476 /**
   1477  * xmlSchemaGetCanonValueWhtspExt:
   1478  * @val: the precomputed value
   1479  * @retValue: the returned value
   1480  * @ws: the whitespace type of the value
   1481  *
   1482  * Get a the canonical representation of the value.
   1483  * The caller has to free the returned retValue.
   1484  *
   1485  * Returns 0 if the value could be built and -1 in case of
   1486  *         API errors or if the value type is not supported yet.
   1487  */
   1488 static int
   1489 xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
   1490 			       xmlSchemaWhitespaceValueType ws,
   1491 			       xmlChar **retValue)
   1492 {
   1493     int list;
   1494     xmlSchemaValType valType;
   1495     const xmlChar *value, *value2 = NULL;
   1496 
   1497 
   1498     if ((retValue == NULL) || (val == NULL))
   1499 	return (-1);
   1500     list = xmlSchemaValueGetNext(val) ? 1 : 0;
   1501     *retValue = NULL;
   1502     do {
   1503 	value = NULL;
   1504 	valType = xmlSchemaGetValType(val);
   1505 	switch (valType) {
   1506 	    case XML_SCHEMAS_STRING:
   1507 	    case XML_SCHEMAS_NORMSTRING:
   1508 	    case XML_SCHEMAS_ANYSIMPLETYPE:
   1509 		value = xmlSchemaValueGetAsString(val);
   1510 		if (value != NULL) {
   1511 		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
   1512 			value2 = xmlSchemaCollapseString(value);
   1513 		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
   1514 			value2 = xmlSchemaWhiteSpaceReplace(value);
   1515 		    if (value2 != NULL)
   1516 			value = value2;
   1517 		}
   1518 		break;
   1519 	    default:
   1520 		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
   1521 		    if (value2 != NULL)
   1522 			xmlFree((xmlChar *) value2);
   1523 		    goto internal_error;
   1524 		}
   1525 		value = value2;
   1526 	}
   1527 	if (*retValue == NULL)
   1528 	    if (value == NULL) {
   1529 		if (! list)
   1530 		    *retValue = xmlStrdup(BAD_CAST "");
   1531 	    } else
   1532 		*retValue = xmlStrdup(value);
   1533 	else if (value != NULL) {
   1534 	    /* List. */
   1535 	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
   1536 	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
   1537 	}
   1538 	FREE_AND_NULL(value2)
   1539 	val = xmlSchemaValueGetNext(val);
   1540     } while (val != NULL);
   1541 
   1542     return (0);
   1543 internal_error:
   1544     if (*retValue != NULL)
   1545 	xmlFree((xmlChar *) (*retValue));
   1546     if (value2 != NULL)
   1547 	xmlFree((xmlChar *) value2);
   1548     return (-1);
   1549 }
   1550 
   1551 /**
   1552  * xmlSchemaFormatItemForReport:
   1553  * @buf: the string buffer
   1554  * @itemDes: the designation of the item
   1555  * @itemName: the name of the item
   1556  * @item: the item as an object
   1557  * @itemNode: the node of the item
   1558  * @local: the local name
   1559  * @parsing: if the function is used during the parse
   1560  *
   1561  * Returns a representation of the given item used
   1562  * for error reports.
   1563  *
   1564  * The following order is used to build the resulting
   1565  * designation if the arguments are not NULL:
   1566  * 1a. If itemDes not NULL -> itemDes
   1567  * 1b. If (itemDes not NULL) and (itemName not NULL)
   1568  *     -> itemDes + itemName
   1569  * 2. If the preceding was NULL and (item not NULL) -> item
   1570  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
   1571  *
   1572  * If the itemNode is an attribute node, the name of the attribute
   1573  * will be appended to the result.
   1574  *
   1575  * Returns the formatted string and sets @buf to the resulting value.
   1576  */
   1577 static xmlChar*
   1578 xmlSchemaFormatItemForReport(xmlChar **buf,
   1579 		     const xmlChar *itemDes,
   1580 		     xmlSchemaBasicItemPtr item,
   1581 		     xmlNodePtr itemNode)
   1582 {
   1583     xmlChar *str = NULL;
   1584     int named = 1;
   1585 
   1586     if (*buf != NULL) {
   1587 	xmlFree(*buf);
   1588 	*buf = NULL;
   1589     }
   1590 
   1591     if (itemDes != NULL) {
   1592 	*buf = xmlStrdup(itemDes);
   1593     } else if (item != NULL) {
   1594 	switch (item->type) {
   1595 	case XML_SCHEMA_TYPE_BASIC: {
   1596 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1597 
   1598 	    if (WXS_IS_ATOMIC(type))
   1599 		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
   1600 	    else if (WXS_IS_LIST(type))
   1601 		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
   1602 	    else if (WXS_IS_UNION(type))
   1603 		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
   1604 	    else
   1605 		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
   1606 	    *buf = xmlStrcat(*buf, type->name);
   1607 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1608 	    }
   1609 	    break;
   1610 	case XML_SCHEMA_TYPE_SIMPLE: {
   1611 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1612 
   1613 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1614 		*buf = xmlStrdup(BAD_CAST"");
   1615 	    } else {
   1616 		*buf = xmlStrdup(BAD_CAST "local ");
   1617 	    }
   1618 	    if (WXS_IS_ATOMIC(type))
   1619 		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
   1620 	    else if (WXS_IS_LIST(type))
   1621 		*buf = xmlStrcat(*buf, BAD_CAST "list type");
   1622 	    else if (WXS_IS_UNION(type))
   1623 		*buf = xmlStrcat(*buf, BAD_CAST "union type");
   1624 	    else
   1625 		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
   1626 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1627 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1628 		*buf = xmlStrcat(*buf, type->name);
   1629 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1630 	    }
   1631 	    }
   1632 	    break;
   1633 	case XML_SCHEMA_TYPE_COMPLEX: {
   1634 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
   1635 
   1636 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
   1637 		*buf = xmlStrdup(BAD_CAST "");
   1638 	    else
   1639 		*buf = xmlStrdup(BAD_CAST "local ");
   1640 	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
   1641 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
   1642 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1643 		*buf = xmlStrcat(*buf, type->name);
   1644 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1645 	    }
   1646 	    }
   1647 	    break;
   1648 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
   1649 		xmlSchemaAttributeUsePtr ause;
   1650 
   1651 		ause = WXS_ATTR_USE_CAST item;
   1652 		*buf = xmlStrdup(BAD_CAST "attribute use ");
   1653 		if (WXS_ATTRUSE_DECL(ause) != NULL) {
   1654 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1655 		    *buf = xmlStrcat(*buf,
   1656 			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
   1657 		    FREE_AND_NULL(str)
   1658 			*buf = xmlStrcat(*buf, BAD_CAST "'");
   1659 		} else {
   1660 		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
   1661 		}
   1662 	    }
   1663 	    break;
   1664 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   1665 		xmlSchemaAttributePtr attr;
   1666 
   1667 		attr = (xmlSchemaAttributePtr) item;
   1668 		*buf = xmlStrdup(BAD_CAST "attribute decl.");
   1669 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1670 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1671 		    attr->targetNamespace, attr->name));
   1672 		FREE_AND_NULL(str)
   1673 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1674 	    }
   1675 	    break;
   1676 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   1677 	    xmlSchemaGetComponentDesignation(buf, item);
   1678 	    break;
   1679 	case XML_SCHEMA_TYPE_ELEMENT: {
   1680 		xmlSchemaElementPtr elem;
   1681 
   1682 		elem = (xmlSchemaElementPtr) item;
   1683 		*buf = xmlStrdup(BAD_CAST "element decl.");
   1684 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1685 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1686 		    elem->targetNamespace, elem->name));
   1687 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1688 	    }
   1689 	    break;
   1690 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
   1691 	case XML_SCHEMA_TYPE_IDC_KEY:
   1692 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   1693 	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
   1694 		*buf = xmlStrdup(BAD_CAST "unique '");
   1695 	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
   1696 		*buf = xmlStrdup(BAD_CAST "key '");
   1697 	    else
   1698 		*buf = xmlStrdup(BAD_CAST "keyRef '");
   1699 	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
   1700 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1701 	    break;
   1702 	case XML_SCHEMA_TYPE_ANY:
   1703 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   1704 	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
   1705 		    ((xmlSchemaWildcardPtr) item)->processContents));
   1706 	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
   1707 	    break;
   1708 	case XML_SCHEMA_FACET_MININCLUSIVE:
   1709 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   1710 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   1711 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   1712 	case XML_SCHEMA_FACET_TOTALDIGITS:
   1713 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   1714 	case XML_SCHEMA_FACET_PATTERN:
   1715 	case XML_SCHEMA_FACET_ENUMERATION:
   1716 	case XML_SCHEMA_FACET_WHITESPACE:
   1717 	case XML_SCHEMA_FACET_LENGTH:
   1718 	case XML_SCHEMA_FACET_MAXLENGTH:
   1719 	case XML_SCHEMA_FACET_MINLENGTH:
   1720 	    *buf = xmlStrdup(BAD_CAST "facet '");
   1721 	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
   1722 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1723 	    break;
   1724 	case XML_SCHEMA_TYPE_GROUP: {
   1725 		*buf = xmlStrdup(BAD_CAST "model group def.");
   1726 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1727 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
   1728 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1729 		FREE_AND_NULL(str)
   1730 	    }
   1731 	    break;
   1732 	case XML_SCHEMA_TYPE_SEQUENCE:
   1733 	case XML_SCHEMA_TYPE_CHOICE:
   1734 	case XML_SCHEMA_TYPE_ALL:
   1735 	case XML_SCHEMA_TYPE_PARTICLE:
   1736 	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
   1737 	    break;
   1738 	case XML_SCHEMA_TYPE_NOTATION: {
   1739 		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
   1740 		*buf = xmlStrcat(*buf, BAD_CAST " '");
   1741 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
   1742 		*buf = xmlStrcat(*buf, BAD_CAST "'");
   1743 		FREE_AND_NULL(str);
   1744 	    }
   1745             /* Falls through. */
   1746 	default:
   1747 	    named = 0;
   1748 	}
   1749     } else
   1750 	named = 0;
   1751 
   1752     if ((named == 0) && (itemNode != NULL)) {
   1753 	xmlNodePtr elem;
   1754 
   1755 	if (itemNode->type == XML_ATTRIBUTE_NODE)
   1756 	    elem = itemNode->parent;
   1757 	else
   1758 	    elem = itemNode;
   1759 	*buf = xmlStrdup(BAD_CAST "Element '");
   1760 	if (elem->ns != NULL) {
   1761 	    *buf = xmlStrcat(*buf,
   1762 		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
   1763 	    FREE_AND_NULL(str)
   1764 	} else
   1765 	    *buf = xmlStrcat(*buf, elem->name);
   1766 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   1767 
   1768     }
   1769     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
   1770 	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
   1771 	if (itemNode->ns != NULL) {
   1772 	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
   1773 		itemNode->ns->href, itemNode->name));
   1774 	    FREE_AND_NULL(str)
   1775 	} else
   1776 	    *buf = xmlStrcat(*buf, itemNode->name);
   1777 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   1778     }
   1779     FREE_AND_NULL(str)
   1780 
   1781     return (xmlEscapeFormatString(buf));
   1782 }
   1783 
   1784 /**
   1785  * xmlSchemaFormatFacetEnumSet:
   1786  * @buf: the string buffer
   1787  * @type: the type holding the enumeration facets
   1788  *
   1789  * Builds a string consisting of all enumeration elements.
   1790  *
   1791  * Returns a string of all enumeration elements.
   1792  */
   1793 static const xmlChar *
   1794 xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
   1795 			    xmlChar **buf, xmlSchemaTypePtr type)
   1796 {
   1797     xmlSchemaFacetPtr facet;
   1798     xmlSchemaWhitespaceValueType ws;
   1799     xmlChar *value = NULL;
   1800     int res, found = 0;
   1801 
   1802     if (*buf != NULL)
   1803 	xmlFree(*buf);
   1804     *buf = NULL;
   1805 
   1806     do {
   1807 	/*
   1808 	* Use the whitespace type of the base type.
   1809 	*/
   1810 	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
   1811 	for (facet = type->facets; facet != NULL; facet = facet->next) {
   1812 	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   1813 		continue;
   1814 	    found = 1;
   1815 	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
   1816 		ws, &value);
   1817 	    if (res == -1) {
   1818 		xmlSchemaInternalErr(actxt,
   1819 		    "xmlSchemaFormatFacetEnumSet",
   1820 		    "compute the canonical lexical representation");
   1821 		if (*buf != NULL)
   1822 		    xmlFree(*buf);
   1823 		*buf = NULL;
   1824 		return (NULL);
   1825 	    }
   1826 	    if (*buf == NULL)
   1827 		*buf = xmlStrdup(BAD_CAST "'");
   1828 	    else
   1829 		*buf = xmlStrcat(*buf, BAD_CAST ", '");
   1830 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   1831 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   1832 	    if (value != NULL) {
   1833 		xmlFree((xmlChar *)value);
   1834 		value = NULL;
   1835 	    }
   1836 	}
   1837 	/*
   1838 	* The enumeration facet of a type restricts the enumeration
   1839 	* facet of the ancestor type; i.e., such restricted enumerations
   1840 	* do not belong to the set of the given type. Thus we break
   1841 	* on the first found enumeration.
   1842 	*/
   1843 	if (found)
   1844 	    break;
   1845 	type = type->baseType;
   1846     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
   1847 
   1848     return ((const xmlChar *) *buf);
   1849 }
   1850 
   1851 /************************************************************************
   1852  *									*
   1853  *			Error functions				        *
   1854  *									*
   1855  ************************************************************************/
   1856 
   1857 #if 0
   1858 static void
   1859 xmlSchemaErrMemory(const char *msg)
   1860 {
   1861     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
   1862                      msg);
   1863 }
   1864 #endif
   1865 
   1866 static void
   1867 xmlSchemaPSimpleErr(const char *msg)
   1868 {
   1869     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
   1870                      msg);
   1871 }
   1872 
   1873 /**
   1874  * xmlSchemaPErrMemory:
   1875  * @node: a context node
   1876  * @extra:  extra informations
   1877  *
   1878  * Handle an out of memory condition
   1879  */
   1880 static void
   1881 xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
   1882                     const char *extra, xmlNodePtr node)
   1883 {
   1884     if (ctxt != NULL)
   1885         ctxt->nberrors++;
   1886     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
   1887                      extra);
   1888 }
   1889 
   1890 /**
   1891  * xmlSchemaPErr:
   1892  * @ctxt: the parsing context
   1893  * @node: the context node
   1894  * @error: the error code
   1895  * @msg: the error message
   1896  * @str1: extra data
   1897  * @str2: extra data
   1898  *
   1899  * Handle a parser error
   1900  */
   1901 static void LIBXML_ATTR_FORMAT(4,0)
   1902 xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
   1903               const char *msg, const xmlChar * str1, const xmlChar * str2)
   1904 {
   1905     xmlGenericErrorFunc channel = NULL;
   1906     xmlStructuredErrorFunc schannel = NULL;
   1907     void *data = NULL;
   1908 
   1909     if (ctxt != NULL) {
   1910         ctxt->nberrors++;
   1911 	ctxt->err = error;
   1912         channel = ctxt->error;
   1913         data = ctxt->errCtxt;
   1914 	schannel = ctxt->serror;
   1915     }
   1916     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
   1917                     error, XML_ERR_ERROR, NULL, 0,
   1918                     (const char *) str1, (const char *) str2, NULL, 0, 0,
   1919                     msg, str1, str2);
   1920 }
   1921 
   1922 /**
   1923  * xmlSchemaPErr2:
   1924  * @ctxt: the parsing context
   1925  * @node: the context node
   1926  * @node: the current child
   1927  * @error: the error code
   1928  * @msg: the error message
   1929  * @str1: extra data
   1930  * @str2: extra data
   1931  *
   1932  * Handle a parser error
   1933  */
   1934 static void LIBXML_ATTR_FORMAT(5,0)
   1935 xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   1936                xmlNodePtr child, int error,
   1937                const char *msg, const xmlChar * str1, const xmlChar * str2)
   1938 {
   1939     if (child != NULL)
   1940         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
   1941     else
   1942         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
   1943 }
   1944 
   1945 
   1946 /**
   1947  * xmlSchemaPErrExt:
   1948  * @ctxt: the parsing context
   1949  * @node: the context node
   1950  * @error: the error code
   1951  * @strData1: extra data
   1952  * @strData2: extra data
   1953  * @strData3: extra data
   1954  * @msg: the message
   1955  * @str1:  extra parameter for the message display
   1956  * @str2:  extra parameter for the message display
   1957  * @str3:  extra parameter for the message display
   1958  * @str4:  extra parameter for the message display
   1959  * @str5:  extra parameter for the message display
   1960  *
   1961  * Handle a parser error
   1962  */
   1963 static void LIBXML_ATTR_FORMAT(7,0)
   1964 xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
   1965 		const xmlChar * strData1, const xmlChar * strData2,
   1966 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
   1967 		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
   1968 		const xmlChar * str5)
   1969 {
   1970 
   1971     xmlGenericErrorFunc channel = NULL;
   1972     xmlStructuredErrorFunc schannel = NULL;
   1973     void *data = NULL;
   1974 
   1975     if (ctxt != NULL) {
   1976         ctxt->nberrors++;
   1977 	ctxt->err = error;
   1978         channel = ctxt->error;
   1979         data = ctxt->errCtxt;
   1980 	schannel = ctxt->serror;
   1981     }
   1982     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
   1983                     error, XML_ERR_ERROR, NULL, 0,
   1984                     (const char *) strData1, (const char *) strData2,
   1985 		    (const char *) strData3, 0, 0, msg, str1, str2,
   1986 		    str3, str4, str5);
   1987 }
   1988 
   1989 /************************************************************************
   1990  *									*
   1991  *			Allround error functions			*
   1992  *									*
   1993  ************************************************************************/
   1994 
   1995 /**
   1996  * xmlSchemaVTypeErrMemory:
   1997  * @node: a context node
   1998  * @extra:  extra informations
   1999  *
   2000  * Handle an out of memory condition
   2001  */
   2002 static void
   2003 xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
   2004                     const char *extra, xmlNodePtr node)
   2005 {
   2006     if (ctxt != NULL) {
   2007         ctxt->nberrors++;
   2008         ctxt->err = XML_SCHEMAV_INTERNAL;
   2009     }
   2010     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
   2011                      extra);
   2012 }
   2013 
   2014 static void LIBXML_ATTR_FORMAT(2,0)
   2015 xmlSchemaPSimpleInternalErr(xmlNodePtr node,
   2016 			    const char *msg, const xmlChar *str)
   2017 {
   2018      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
   2019 	 msg, (const char *) str);
   2020 }
   2021 
   2022 #define WXS_ERROR_TYPE_ERROR 1
   2023 #define WXS_ERROR_TYPE_WARNING 2
   2024 /**
   2025  * xmlSchemaErr4Line:
   2026  * @ctxt: the validation context
   2027  * @errorLevel: the error level
   2028  * @error: the error code
   2029  * @node: the context node
   2030  * @line: the line number
   2031  * @msg: the error message
   2032  * @str1: extra data
   2033  * @str2: extra data
   2034  * @str3: extra data
   2035  * @str4: extra data
   2036  *
   2037  * Handle a validation error
   2038  */
   2039 static void LIBXML_ATTR_FORMAT(6,0)
   2040 xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
   2041 		  xmlErrorLevel errorLevel,
   2042 		  int error, xmlNodePtr node, int line, const char *msg,
   2043 		  const xmlChar *str1, const xmlChar *str2,
   2044 		  const xmlChar *str3, const xmlChar *str4)
   2045 {
   2046     xmlStructuredErrorFunc schannel = NULL;
   2047     xmlGenericErrorFunc channel = NULL;
   2048     void *data = NULL;
   2049 
   2050     if (ctxt != NULL) {
   2051 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2052 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
   2053 	    const char *file = NULL;
   2054 	    int col = 0;
   2055 	    if (errorLevel != XML_ERR_WARNING) {
   2056 		vctxt->nberrors++;
   2057 		vctxt->err = error;
   2058 		channel = vctxt->error;
   2059 	    } else {
   2060 		channel = vctxt->warning;
   2061 	    }
   2062 	    schannel = vctxt->serror;
   2063 	    data = vctxt->errCtxt;
   2064 
   2065 	    /*
   2066 	    * Error node. If we specify a line number, then
   2067 	    * do not channel any node to the error function.
   2068 	    */
   2069 	    if (line == 0) {
   2070 		if ((node == NULL) &&
   2071 		    (vctxt->depth >= 0) &&
   2072 		    (vctxt->inode != NULL)) {
   2073 		    node = vctxt->inode->node;
   2074 		}
   2075 		/*
   2076 		* Get filename and line if no node-tree.
   2077 		*/
   2078 		if ((node == NULL) &&
   2079 		    (vctxt->parserCtxt != NULL) &&
   2080 		    (vctxt->parserCtxt->input != NULL)) {
   2081 		    file = vctxt->parserCtxt->input->filename;
   2082 		    line = vctxt->parserCtxt->input->line;
   2083 		    col = vctxt->parserCtxt->input->col;
   2084 		}
   2085 	    } else {
   2086 		/*
   2087 		* Override the given node's (if any) position
   2088 		* and channel only the given line number.
   2089 		*/
   2090 		node = NULL;
   2091 		/*
   2092 		* Get filename.
   2093 		*/
   2094 		if (vctxt->doc != NULL)
   2095 		    file = (const char *) vctxt->doc->URL;
   2096 		else if ((vctxt->parserCtxt != NULL) &&
   2097 		    (vctxt->parserCtxt->input != NULL))
   2098 		    file = vctxt->parserCtxt->input->filename;
   2099 	    }
   2100 	    if (vctxt->locFunc != NULL) {
   2101 	        if ((file == NULL) || (line == 0)) {
   2102 		    unsigned long l;
   2103 		    const char *f;
   2104 		    vctxt->locFunc(vctxt->locCtxt, &f, &l);
   2105 		    if (file == NULL)
   2106 		        file = f;
   2107 		    if (line == 0)
   2108 		        line = (int) l;
   2109 		}
   2110 	    }
   2111 	    if ((file == NULL) && (vctxt->filename != NULL))
   2112 	        file = vctxt->filename;
   2113 
   2114 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2115 		node, XML_FROM_SCHEMASV,
   2116 		error, errorLevel, file, line,
   2117 		(const char *) str1, (const char *) str2,
   2118 		(const char *) str3, 0, col, msg, str1, str2, str3, str4);
   2119 
   2120 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
   2121 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
   2122 	    if (errorLevel != XML_ERR_WARNING) {
   2123 		pctxt->nberrors++;
   2124 		pctxt->err = error;
   2125 		channel = pctxt->error;
   2126 	    } else {
   2127 		channel = pctxt->warning;
   2128 	    }
   2129 	    schannel = pctxt->serror;
   2130 	    data = pctxt->errCtxt;
   2131 	    __xmlRaiseError(schannel, channel, data, ctxt,
   2132 		node, XML_FROM_SCHEMASP, error,
   2133 		errorLevel, NULL, 0,
   2134 		(const char *) str1, (const char *) str2,
   2135 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
   2136 	} else {
   2137 	    TODO
   2138 	}
   2139     }
   2140 }
   2141 
   2142 /**
   2143  * xmlSchemaErr3:
   2144  * @ctxt: the validation context
   2145  * @node: the context node
   2146  * @error: the error code
   2147  * @msg: the error message
   2148  * @str1: extra data
   2149  * @str2: extra data
   2150  * @str3: extra data
   2151  *
   2152  * Handle a validation error
   2153  */
   2154 static void LIBXML_ATTR_FORMAT(4,0)
   2155 xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
   2156 	      int error, xmlNodePtr node, const char *msg,
   2157 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
   2158 {
   2159     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2160 	msg, str1, str2, str3, NULL);
   2161 }
   2162 
   2163 static void LIBXML_ATTR_FORMAT(4,0)
   2164 xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
   2165 	      int error, xmlNodePtr node, const char *msg,
   2166 	      const xmlChar *str1, const xmlChar *str2,
   2167 	      const xmlChar *str3, const xmlChar *str4)
   2168 {
   2169     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
   2170 	msg, str1, str2, str3, str4);
   2171 }
   2172 
   2173 static void LIBXML_ATTR_FORMAT(4,0)
   2174 xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
   2175 	     int error, xmlNodePtr node, const char *msg,
   2176 	     const xmlChar *str1, const xmlChar *str2)
   2177 {
   2178     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
   2179 }
   2180 
   2181 static xmlChar *
   2182 xmlSchemaFormatNodeForError(xmlChar ** msg,
   2183 			    xmlSchemaAbstractCtxtPtr actxt,
   2184 			    xmlNodePtr node)
   2185 {
   2186     xmlChar *str = NULL;
   2187 
   2188     *msg = NULL;
   2189     if ((node != NULL) &&
   2190 	(node->type != XML_ELEMENT_NODE) &&
   2191 	(node->type != XML_ATTRIBUTE_NODE))
   2192     {
   2193 	/*
   2194 	* Don't try to format other nodes than element and
   2195 	* attribute nodes.
   2196 	* Play safe and return an empty string.
   2197 	*/
   2198 	*msg = xmlStrdup(BAD_CAST "");
   2199 	return(*msg);
   2200     }
   2201     if (node != NULL) {
   2202 	/*
   2203 	* Work on tree nodes.
   2204 	*/
   2205 	if (node->type == XML_ATTRIBUTE_NODE) {
   2206 	    xmlNodePtr elem = node->parent;
   2207 
   2208 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2209 	    if (elem->ns != NULL)
   2210 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2211 		    elem->ns->href, elem->name));
   2212 	    else
   2213 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2214 		    NULL, elem->name));
   2215 	    FREE_AND_NULL(str);
   2216 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2217 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2218 	} else {
   2219 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2220 	}
   2221 	if (node->ns != NULL)
   2222 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2223 	    node->ns->href, node->name));
   2224 	else
   2225 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2226 	    NULL, node->name));
   2227 	FREE_AND_NULL(str);
   2228 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2229     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   2230 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
   2231 	/*
   2232 	* Work on node infos.
   2233 	*/
   2234 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
   2235 	    xmlSchemaNodeInfoPtr ielem =
   2236 		vctxt->elemInfos[vctxt->depth];
   2237 
   2238 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2239 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2240 		ielem->nsName, ielem->localName));
   2241 	    FREE_AND_NULL(str);
   2242 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
   2243 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
   2244 	} else {
   2245 	    *msg = xmlStrdup(BAD_CAST "Element '");
   2246 	}
   2247 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
   2248 	    vctxt->inode->nsName, vctxt->inode->localName));
   2249 	FREE_AND_NULL(str);
   2250 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
   2251     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   2252 	/*
   2253 	* Hmm, no node while parsing?
   2254 	* Return an empty string, in case NULL will break something.
   2255 	*/
   2256 	*msg = xmlStrdup(BAD_CAST "");
   2257     } else {
   2258 	TODO
   2259 	return (NULL);
   2260     }
   2261 
   2262     /*
   2263      * xmlSchemaFormatItemForReport() also returns an escaped format
   2264      * string, so do this before calling it below (in the future).
   2265      */
   2266     xmlEscapeFormatString(msg);
   2267 
   2268     /*
   2269     * VAL TODO: The output of the given schema component is currently
   2270     * disabled.
   2271     */
   2272 #if 0
   2273     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
   2274 	*msg = xmlStrcat(*msg, BAD_CAST " [");
   2275 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
   2276 	    NULL, type, NULL, 0));
   2277 	FREE_AND_NULL(str)
   2278 	*msg = xmlStrcat(*msg, BAD_CAST "]");
   2279     }
   2280 #endif
   2281     return (*msg);
   2282 }
   2283 
   2284 static void LIBXML_ATTR_FORMAT(3,0)
   2285 xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
   2286 		     const char *funcName,
   2287 		     const char *message,
   2288 		     const xmlChar *str1,
   2289 		     const xmlChar *str2)
   2290 {
   2291     xmlChar *msg = NULL;
   2292 
   2293     if (actxt == NULL)
   2294         return;
   2295     msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
   2296     msg = xmlStrcat(msg, BAD_CAST message);
   2297     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2298 
   2299     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
   2300 	xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
   2301 	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
   2302     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
   2303 	xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
   2304 	    (const char *) msg, (const xmlChar *) funcName, str1, str2);
   2305 
   2306     FREE_AND_NULL(msg)
   2307 }
   2308 
   2309 static void LIBXML_ATTR_FORMAT(3,0)
   2310 xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
   2311 		     const char *funcName,
   2312 		     const char *message)
   2313 {
   2314     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
   2315 }
   2316 
   2317 #if 0
   2318 static void LIBXML_ATTR_FORMAT(3,0)
   2319 xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
   2320 		     const char *funcName,
   2321 		     const char *message,
   2322 		     const xmlChar *str1,
   2323 		     const xmlChar *str2)
   2324 {
   2325     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
   2326 	str1, str2);
   2327 }
   2328 #endif
   2329 
   2330 static void LIBXML_ATTR_FORMAT(5,0)
   2331 xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
   2332 		   xmlParserErrors error,
   2333 		   xmlNodePtr node,
   2334 		   xmlSchemaBasicItemPtr item,
   2335 		   const char *message,
   2336 		   const xmlChar *str1, const xmlChar *str2,
   2337 		   const xmlChar *str3, const xmlChar *str4)
   2338 {
   2339     xmlChar *msg = NULL;
   2340 
   2341     if ((node == NULL) && (item != NULL) &&
   2342 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
   2343 	node = WXS_ITEM_NODE(item);
   2344 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
   2345 	msg = xmlStrcat(msg, BAD_CAST ": ");
   2346     } else
   2347 	xmlSchemaFormatNodeForError(&msg, actxt, node);
   2348     msg = xmlStrcat(msg, (const xmlChar *) message);
   2349     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2350     xmlSchemaErr4(actxt, error, node,
   2351 	(const char *) msg, str1, str2, str3, str4);
   2352     FREE_AND_NULL(msg)
   2353 }
   2354 
   2355 static void LIBXML_ATTR_FORMAT(5,0)
   2356 xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
   2357 		   xmlParserErrors error,
   2358 		   xmlNodePtr node,
   2359 		   xmlSchemaBasicItemPtr item,
   2360 		   const char *message,
   2361 		   const xmlChar *str1,
   2362 		   const xmlChar *str2)
   2363 {
   2364     xmlSchemaCustomErr4(actxt, error, node, item,
   2365 	message, str1, str2, NULL, NULL);
   2366 }
   2367 
   2368 
   2369 
   2370 static void LIBXML_ATTR_FORMAT(5,0)
   2371 xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
   2372 		   xmlParserErrors error,
   2373 		   xmlNodePtr node,
   2374 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2375 		   const char *message,
   2376 		   const xmlChar *str1,
   2377 		   const xmlChar *str2,
   2378 		   const xmlChar *str3)
   2379 {
   2380     xmlChar *msg = NULL;
   2381 
   2382     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2383     msg = xmlStrcat(msg, (const xmlChar *) message);
   2384     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2385 
   2386     /* URGENT TODO: Set the error code to something sane. */
   2387     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
   2388 	(const char *) msg, str1, str2, str3, NULL);
   2389 
   2390     FREE_AND_NULL(msg)
   2391 }
   2392 
   2393 
   2394 
   2395 static void LIBXML_ATTR_FORMAT(5,0)
   2396 xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
   2397 		   xmlParserErrors error,
   2398 		   xmlSchemaPSVIIDCNodePtr idcNode,
   2399 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2400 		   const char *message,
   2401 		   const xmlChar *str1,
   2402 		   const xmlChar *str2)
   2403 {
   2404     xmlChar *msg = NULL, *qname = NULL;
   2405 
   2406     msg = xmlStrdup(BAD_CAST "Element '%s': ");
   2407     msg = xmlStrcat(msg, (const xmlChar *) message);
   2408     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2409     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
   2410 	error, NULL, idcNode->nodeLine, (const char *) msg,
   2411 	xmlSchemaFormatQName(&qname,
   2412 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
   2413 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
   2414 	str1, str2, NULL);
   2415     FREE_AND_NULL(qname);
   2416     FREE_AND_NULL(msg);
   2417 }
   2418 
   2419 static int
   2420 xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
   2421 			   xmlNodePtr node)
   2422 {
   2423     if (node != NULL)
   2424 	return (node->type);
   2425     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
   2426 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
   2427 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
   2428     return (-1);
   2429 }
   2430 
   2431 static int
   2432 xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
   2433 {
   2434     switch (item->type) {
   2435 	case XML_SCHEMA_TYPE_COMPLEX:
   2436 	case XML_SCHEMA_TYPE_SIMPLE:
   2437 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
   2438 		return(1);
   2439 	    break;
   2440 	case XML_SCHEMA_TYPE_GROUP:
   2441 	    return (1);
   2442 	case XML_SCHEMA_TYPE_ELEMENT:
   2443 	    if ( ((xmlSchemaElementPtr) item)->flags &
   2444 		XML_SCHEMAS_ELEM_GLOBAL)
   2445 		return(1);
   2446 	    break;
   2447 	case XML_SCHEMA_TYPE_ATTRIBUTE:
   2448 	    if ( ((xmlSchemaAttributePtr) item)->flags &
   2449 		XML_SCHEMAS_ATTR_GLOBAL)
   2450 		return(1);
   2451 	    break;
   2452 	/* Note that attribute groups are always global. */
   2453 	default:
   2454 	    return(1);
   2455     }
   2456     return (0);
   2457 }
   2458 
   2459 static void
   2460 xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2461 		       xmlParserErrors error,
   2462 		       xmlNodePtr node,
   2463 		       const xmlChar *value,
   2464 		       xmlSchemaTypePtr type,
   2465 		       int displayValue)
   2466 {
   2467     xmlChar *msg = NULL;
   2468 
   2469     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2470 
   2471     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2472 	    XML_ATTRIBUTE_NODE))
   2473 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   2474     else
   2475 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
   2476 	    "value of ");
   2477 
   2478     if (! xmlSchemaIsGlobalItem(type))
   2479 	msg = xmlStrcat(msg, BAD_CAST "the local ");
   2480     else
   2481 	msg = xmlStrcat(msg, BAD_CAST "the ");
   2482 
   2483     if (WXS_IS_ATOMIC(type))
   2484 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
   2485     else if (WXS_IS_LIST(type))
   2486 	msg = xmlStrcat(msg, BAD_CAST "list type");
   2487     else if (WXS_IS_UNION(type))
   2488 	msg = xmlStrcat(msg, BAD_CAST "union type");
   2489 
   2490     if (xmlSchemaIsGlobalItem(type)) {
   2491 	xmlChar *str = NULL;
   2492 	msg = xmlStrcat(msg, BAD_CAST " '");
   2493 	if (type->builtInType != 0) {
   2494 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
   2495 	    str = xmlStrdup(type->name);
   2496 	} else {
   2497 	    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
   2498 	    if (!str)
   2499 		str = xmlStrdup(qName);
   2500 	}
   2501 	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
   2502 	msg = xmlStrcat(msg, BAD_CAST "'");
   2503 	FREE_AND_NULL(str);
   2504     }
   2505     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2506     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
   2507 	    XML_ATTRIBUTE_NODE))
   2508 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2509     else
   2510 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2511     FREE_AND_NULL(msg)
   2512 }
   2513 
   2514 static const xmlChar *
   2515 xmlSchemaFormatErrorNodeQName(xmlChar ** str,
   2516 			      xmlSchemaNodeInfoPtr ni,
   2517 			      xmlNodePtr node)
   2518 {
   2519     if (node != NULL) {
   2520 	if (node->ns != NULL)
   2521 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
   2522 	else
   2523 	    return (xmlSchemaFormatQName(str, NULL, node->name));
   2524     } else if (ni != NULL)
   2525 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
   2526     return (NULL);
   2527 }
   2528 
   2529 static void
   2530 xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
   2531 			xmlParserErrors error,
   2532 			xmlSchemaAttrInfoPtr ni,
   2533 			xmlNodePtr node)
   2534 {
   2535     xmlChar *msg = NULL, *str = NULL;
   2536 
   2537     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2538     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
   2539     xmlSchemaErr(actxt, error, node, (const char *) msg,
   2540 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
   2541 	NULL);
   2542     FREE_AND_NULL(str)
   2543     FREE_AND_NULL(msg)
   2544 }
   2545 
   2546 static void LIBXML_ATTR_FORMAT(5,0)
   2547 xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
   2548 		        xmlParserErrors error,
   2549 		        xmlNodePtr node,
   2550 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
   2551 			const char *message,
   2552 			int nbval,
   2553 			int nbneg,
   2554 			xmlChar **values)
   2555 {
   2556     xmlChar *str = NULL, *msg = NULL;
   2557     xmlChar *localName, *nsName;
   2558     const xmlChar *cur, *end;
   2559     int i;
   2560 
   2561     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2562     msg = xmlStrcat(msg, (const xmlChar *) message);
   2563     msg = xmlStrcat(msg, BAD_CAST ".");
   2564     /*
   2565     * Note that is does not make sense to report that we have a
   2566     * wildcard here, since the wildcard might be unfolded into
   2567     * multiple transitions.
   2568     */
   2569     if (nbval + nbneg > 0) {
   2570 	if (nbval + nbneg > 1) {
   2571 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
   2572 	} else
   2573 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
   2574 	nsName = NULL;
   2575 
   2576 	for (i = 0; i < nbval + nbneg; i++) {
   2577 	    cur = values[i];
   2578 	    if (cur == NULL)
   2579 	        continue;
   2580 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
   2581 	        (cur[3] == ' ')) {
   2582 		cur += 4;
   2583 		str = xmlStrcat(str, BAD_CAST "##other");
   2584 	    }
   2585 	    /*
   2586 	    * Get the local name.
   2587 	    */
   2588 	    localName = NULL;
   2589 
   2590 	    end = cur;
   2591 	    if (*end == '*') {
   2592 		localName = xmlStrdup(BAD_CAST "*");
   2593 		end++;
   2594 	    } else {
   2595 		while ((*end != 0) && (*end != '|'))
   2596 		    end++;
   2597 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
   2598 	    }
   2599 	    if (*end != 0) {
   2600 		end++;
   2601 		/*
   2602 		* Skip "*|*" if they come with negated expressions, since
   2603 		* they represent the same negated wildcard.
   2604 		*/
   2605 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
   2606 		    /*
   2607 		    * Get the namespace name.
   2608 		    */
   2609 		    cur = end;
   2610 		    if (*end == '*') {
   2611 			nsName = xmlStrdup(BAD_CAST "{*}");
   2612 		    } else {
   2613 			while (*end != 0)
   2614 			    end++;
   2615 
   2616 			if (i >= nbval)
   2617 			    nsName = xmlStrdup(BAD_CAST "{##other:");
   2618 			else
   2619 			    nsName = xmlStrdup(BAD_CAST "{");
   2620 
   2621 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
   2622 			nsName = xmlStrcat(nsName, BAD_CAST "}");
   2623 		    }
   2624 		    str = xmlStrcat(str, BAD_CAST nsName);
   2625 		    FREE_AND_NULL(nsName)
   2626 		} else {
   2627 		    FREE_AND_NULL(localName);
   2628 		    continue;
   2629 		}
   2630 	    }
   2631 	    str = xmlStrcat(str, BAD_CAST localName);
   2632 	    FREE_AND_NULL(localName);
   2633 
   2634 	    if (i < nbval + nbneg -1)
   2635 		str = xmlStrcat(str, BAD_CAST ", ");
   2636 	}
   2637 	str = xmlStrcat(str, BAD_CAST " ).\n");
   2638 	msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
   2639 	FREE_AND_NULL(str)
   2640     } else
   2641       msg = xmlStrcat(msg, BAD_CAST "\n");
   2642     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2643     xmlFree(msg);
   2644 }
   2645 
   2646 static void LIBXML_ATTR_FORMAT(8,0)
   2647 xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
   2648 		  xmlParserErrors error,
   2649 		  xmlNodePtr node,
   2650 		  const xmlChar *value,
   2651 		  unsigned long length,
   2652 		  xmlSchemaTypePtr type,
   2653 		  xmlSchemaFacetPtr facet,
   2654 		  const char *message,
   2655 		  const xmlChar *str1,
   2656 		  const xmlChar *str2)
   2657 {
   2658     xmlChar *str = NULL, *msg = NULL;
   2659     xmlSchemaTypeType facetType;
   2660     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
   2661 
   2662     xmlSchemaFormatNodeForError(&msg, actxt, node);
   2663     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
   2664 	facetType = XML_SCHEMA_FACET_ENUMERATION;
   2665 	/*
   2666 	* If enumerations are validated, one must not expect the
   2667 	* facet to be given.
   2668 	*/
   2669     } else
   2670 	facetType = facet->type;
   2671     msg = xmlStrcat(msg, BAD_CAST "[");
   2672     msg = xmlStrcat(msg, BAD_CAST "facet '");
   2673     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
   2674     msg = xmlStrcat(msg, BAD_CAST "'] ");
   2675     if (message == NULL) {
   2676 	/*
   2677 	* Use a default message.
   2678 	*/
   2679 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
   2680 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
   2681 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
   2682 
   2683 	    char len[25], actLen[25];
   2684 
   2685 	    /* FIXME, TODO: What is the max expected string length of the
   2686 	    * this value?
   2687 	    */
   2688 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2689 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
   2690 	    else
   2691 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
   2692 
   2693 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
   2694 	    snprintf(actLen, 24, "%lu", length);
   2695 
   2696 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
   2697 		msg = xmlStrcat(msg,
   2698 		BAD_CAST "this differs from the allowed length of '%s'.\n");
   2699 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
   2700 		msg = xmlStrcat(msg,
   2701 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
   2702 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
   2703 		msg = xmlStrcat(msg,
   2704 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
   2705 
   2706 	    if (nodeType == XML_ATTRIBUTE_NODE)
   2707 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
   2708 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
   2709 	    else
   2710 		xmlSchemaErr(actxt, error, node, (const char *) msg,
   2711 		    (const xmlChar *) actLen, (const xmlChar *) len);
   2712 
   2713 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
   2714 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
   2715 		"of the set {%s}.\n");
   2716 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2717 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
   2718 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
   2719 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
   2720 		"by the pattern '%s'.\n");
   2721 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2722 		facet->value);
   2723 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
   2724 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
   2725 		"minimum value allowed ('%s').\n");
   2726 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2727 		facet->value);
   2728 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
   2729 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
   2730 		"maximum value allowed ('%s').\n");
   2731 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2732 		facet->value);
   2733 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
   2734 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
   2735 		"'%s'.\n");
   2736 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2737 		facet->value);
   2738 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
   2739 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
   2740 		"'%s'.\n");
   2741 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
   2742 		facet->value);
   2743 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
   2744 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
   2745 		"digits than are allowed ('%s').\n");
   2746 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2747 		facet->value);
   2748 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
   2749 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
   2750 		"digits than are allowed ('%s').\n");
   2751 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
   2752 		facet->value);
   2753 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
   2754 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
   2755 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
   2756 	} else {
   2757 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
   2758 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
   2759 	}
   2760     } else {
   2761 	msg = xmlStrcat(msg, (const xmlChar *) message);
   2762 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   2763 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
   2764     }
   2765     FREE_AND_NULL(str)
   2766     xmlFree(msg);
   2767 }
   2768 
   2769 #define VERROR(err, type, msg) \
   2770     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
   2771 
   2772 #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
   2773 
   2774 #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
   2775 #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
   2776 
   2777 #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
   2778 
   2779 
   2780 /**
   2781  * xmlSchemaPMissingAttrErr:
   2782  * @ctxt: the schema validation context
   2783  * @ownerDes: the designation of  the owner
   2784  * @ownerName: the name of the owner
   2785  * @ownerItem: the owner as a schema object
   2786  * @ownerElem: the owner as an element node
   2787  * @node: the parent element node of the missing attribute node
   2788  * @type: the corresponding type of the attribute node
   2789  *
   2790  * Reports an illegal attribute.
   2791  */
   2792 static void
   2793 xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2794 			 xmlParserErrors error,
   2795 			 xmlSchemaBasicItemPtr ownerItem,
   2796 			 xmlNodePtr ownerElem,
   2797 			 const char *name,
   2798 			 const char *message)
   2799 {
   2800     xmlChar *des = NULL;
   2801 
   2802     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2803 
   2804     if (message != NULL)
   2805 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
   2806     else
   2807 	xmlSchemaPErr(ctxt, ownerElem, error,
   2808 	    "%s: The attribute '%s' is required but missing.\n",
   2809 	    BAD_CAST des, BAD_CAST name);
   2810     FREE_AND_NULL(des);
   2811 }
   2812 
   2813 
   2814 /**
   2815  * xmlSchemaPResCompAttrErr:
   2816  * @ctxt: the schema validation context
   2817  * @error: the error code
   2818  * @ownerDes: the designation of  the owner
   2819  * @ownerItem: the owner as a schema object
   2820  * @ownerElem: the owner as an element node
   2821  * @name: the name of the attribute holding the QName
   2822  * @refName: the referenced local name
   2823  * @refURI: the referenced namespace URI
   2824  * @message: optional message
   2825  *
   2826  * Used to report QName attribute values that failed to resolve
   2827  * to schema components.
   2828  */
   2829 static void
   2830 xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2831 			 xmlParserErrors error,
   2832 			 xmlSchemaBasicItemPtr ownerItem,
   2833 			 xmlNodePtr ownerElem,
   2834 			 const char *name,
   2835 			 const xmlChar *refName,
   2836 			 const xmlChar *refURI,
   2837 			 xmlSchemaTypeType refType,
   2838 			 const char *refTypeStr)
   2839 {
   2840     xmlChar *des = NULL, *strA = NULL;
   2841 
   2842     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   2843     if (refTypeStr == NULL)
   2844 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
   2845     xmlSchemaPErrExt(ctxt, ownerElem, error,
   2846 	    NULL, NULL, NULL,
   2847 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
   2848 	    "%s.\n", BAD_CAST des, BAD_CAST name,
   2849 	    xmlSchemaFormatQName(&strA, refURI, refName),
   2850 	    BAD_CAST refTypeStr, NULL);
   2851     FREE_AND_NULL(des)
   2852     FREE_AND_NULL(strA)
   2853 }
   2854 
   2855 /**
   2856  * xmlSchemaPCustomAttrErr:
   2857  * @ctxt: the schema parser context
   2858  * @error: the error code
   2859  * @ownerDes: the designation of the owner
   2860  * @ownerItem: the owner as a schema object
   2861  * @attr: the illegal attribute node
   2862  *
   2863  * Reports an illegal attribute during the parse.
   2864  */
   2865 static void
   2866 xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2867 			xmlParserErrors error,
   2868 			xmlChar **ownerDes,
   2869 			xmlSchemaBasicItemPtr ownerItem,
   2870 			xmlAttrPtr attr,
   2871 			const char *msg)
   2872 {
   2873     xmlChar *des = NULL;
   2874 
   2875     if (ownerDes == NULL)
   2876 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
   2877     else if (*ownerDes == NULL) {
   2878 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
   2879 	des = *ownerDes;
   2880     } else
   2881 	des = *ownerDes;
   2882     if (attr == NULL) {
   2883 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
   2884 	    "%s, attribute '%s': %s.\n",
   2885 	    BAD_CAST des, (const xmlChar *) "Unknown",
   2886 	    (const xmlChar *) msg, NULL, NULL);
   2887     } else {
   2888 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   2889 	    "%s, attribute '%s': %s.\n",
   2890 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
   2891     }
   2892     if (ownerDes == NULL)
   2893 	FREE_AND_NULL(des);
   2894 }
   2895 
   2896 /**
   2897  * xmlSchemaPIllegalAttrErr:
   2898  * @ctxt: the schema parser context
   2899  * @error: the error code
   2900  * @ownerDes: the designation of the attribute's owner
   2901  * @ownerItem: the attribute's owner item
   2902  * @attr: the illegal attribute node
   2903  *
   2904  * Reports an illegal attribute during the parse.
   2905  */
   2906 static void
   2907 xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
   2908 			 xmlParserErrors error,
   2909 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
   2910 			 xmlAttrPtr attr)
   2911 {
   2912     xmlChar *strA = NULL, *strB = NULL;
   2913 
   2914     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
   2915     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
   2916 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
   2917 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
   2918 	NULL, NULL);
   2919     FREE_AND_NULL(strA);
   2920     FREE_AND_NULL(strB);
   2921 }
   2922 
   2923 /**
   2924  * xmlSchemaPCustomErr:
   2925  * @ctxt: the schema parser context
   2926  * @error: the error code
   2927  * @itemDes: the designation of the schema item
   2928  * @item: the schema item
   2929  * @itemElem: the node of the schema item
   2930  * @message: the error message
   2931  * @str1: an optional param for the error message
   2932  * @str2: an optional param for the error message
   2933  * @str3: an optional param for the error message
   2934  *
   2935  * Reports an error during parsing.
   2936  */
   2937 static void LIBXML_ATTR_FORMAT(5,0)
   2938 xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
   2939 		    xmlParserErrors error,
   2940 		    xmlSchemaBasicItemPtr item,
   2941 		    xmlNodePtr itemElem,
   2942 		    const char *message,
   2943 		    const xmlChar *str1,
   2944 		    const xmlChar *str2,
   2945 		    const xmlChar *str3)
   2946 {
   2947     xmlChar *des = NULL, *msg = NULL;
   2948 
   2949     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
   2950     msg = xmlStrdup(BAD_CAST "%s: ");
   2951     msg = xmlStrcat(msg, (const xmlChar *) message);
   2952     msg = xmlStrcat(msg, BAD_CAST ".\n");
   2953     if ((itemElem == NULL) && (item != NULL))
   2954 	itemElem = WXS_ITEM_NODE(item);
   2955     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
   2956 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
   2957     FREE_AND_NULL(des);
   2958     FREE_AND_NULL(msg);
   2959 }
   2960 
   2961 /**
   2962  * xmlSchemaPCustomErr:
   2963  * @ctxt: the schema parser context
   2964  * @error: the error code
   2965  * @itemDes: the designation of the schema item
   2966  * @item: the schema item
   2967  * @itemElem: the node of the schema item
   2968  * @message: the error message
   2969  * @str1: the optional param for the error message
   2970  *
   2971  * Reports an error during parsing.
   2972  */
   2973 static void LIBXML_ATTR_FORMAT(5,0)
   2974 xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
   2975 		    xmlParserErrors error,
   2976 		    xmlSchemaBasicItemPtr item,
   2977 		    xmlNodePtr itemElem,
   2978 		    const char *message,
   2979 		    const xmlChar *str1)
   2980 {
   2981     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
   2982 	str1, NULL, NULL);
   2983 }
   2984 
   2985 /**
   2986  * xmlSchemaPAttrUseErr:
   2987  * @ctxt: the schema parser context
   2988  * @error: the error code
   2989  * @itemDes: the designation of the schema type
   2990  * @item: the schema type
   2991  * @itemElem: the node of the schema type
   2992  * @attr: the invalid schema attribute
   2993  * @message: the error message
   2994  * @str1: the optional param for the error message
   2995  *
   2996  * Reports an attribute use error during parsing.
   2997  */
   2998 static void LIBXML_ATTR_FORMAT(6,0)
   2999 xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
   3000 		    xmlParserErrors error,
   3001 		    xmlNodePtr node,
   3002 		    xmlSchemaBasicItemPtr ownerItem,
   3003 		    const xmlSchemaAttributeUsePtr attruse,
   3004 		    const char *message,
   3005 		    const xmlChar *str1, const xmlChar *str2,
   3006 		    const xmlChar *str3,const xmlChar *str4)
   3007 {
   3008     xmlChar *str = NULL, *msg = NULL;
   3009 
   3010     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
   3011     msg = xmlStrcat(msg, BAD_CAST ", ");
   3012     msg = xmlStrcat(msg,
   3013 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
   3014 	WXS_BASIC_CAST attruse, NULL));
   3015     FREE_AND_NULL(str);
   3016     msg = xmlStrcat(msg, BAD_CAST ": ");
   3017     msg = xmlStrcat(msg, (const xmlChar *) message);
   3018     msg = xmlStrcat(msg, BAD_CAST ".\n");
   3019     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
   3020 	(const char *) msg, str1, str2, str3, str4);
   3021     xmlFree(msg);
   3022 }
   3023 
   3024 /**
   3025  * xmlSchemaPIllegalFacetAtomicErr:
   3026  * @ctxt: the schema parser context
   3027  * @error: the error code
   3028  * @type: the schema type
   3029  * @baseType: the base type of type
   3030  * @facet: the illegal facet
   3031  *
   3032  * Reports an illegal facet for atomic simple types.
   3033  */
   3034 static void
   3035 xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
   3036 			  xmlParserErrors error,
   3037 			  xmlSchemaTypePtr type,
   3038 			  xmlSchemaTypePtr baseType,
   3039 			  xmlSchemaFacetPtr facet)
   3040 {
   3041     xmlChar *des = NULL, *strT = NULL;
   3042 
   3043     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
   3044     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
   3045 	"%s: The facet '%s' is not allowed on types derived from the "
   3046 	"type %s.\n",
   3047 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
   3048 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
   3049 	NULL, NULL);
   3050     FREE_AND_NULL(des);
   3051     FREE_AND_NULL(strT);
   3052 }
   3053 
   3054 /**
   3055  * xmlSchemaPIllegalFacetListUnionErr:
   3056  * @ctxt: the schema parser context
   3057  * @error: the error code
   3058  * @itemDes: the designation of the schema item involved
   3059  * @item: the schema item involved
   3060  * @facet: the illegal facet
   3061  *
   3062  * Reports an illegal facet for <list> and <union>.
   3063  */
   3064 static void
   3065 xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
   3066 			  xmlParserErrors error,
   3067 			  xmlSchemaTypePtr type,
   3068 			  xmlSchemaFacetPtr facet)
   3069 {
   3070     xmlChar *des = NULL;
   3071 
   3072     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
   3073 	type->node);
   3074     xmlSchemaPErr(ctxt, type->node, error,
   3075 	"%s: The facet '%s' is not allowed.\n",
   3076 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
   3077     FREE_AND_NULL(des);
   3078 }
   3079 
   3080 /**
   3081  * xmlSchemaPMutualExclAttrErr:
   3082  * @ctxt: the schema validation context
   3083  * @error: the error code
   3084  * @elemDes: the designation of the parent element node
   3085  * @attr: the bad attribute node
   3086  * @type: the corresponding type of the attribute node
   3087  *
   3088  * Reports an illegal attribute.
   3089  */
   3090 static void
   3091 xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
   3092 			 xmlParserErrors error,
   3093 			 xmlSchemaBasicItemPtr ownerItem,
   3094 			 xmlAttrPtr attr,
   3095 			 const char *name1,
   3096 			 const char *name2)
   3097 {
   3098     xmlChar *des = NULL;
   3099 
   3100     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
   3101     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
   3102 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
   3103 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
   3104     FREE_AND_NULL(des);
   3105 }
   3106 
   3107 /**
   3108  * xmlSchemaPSimpleTypeErr:
   3109  * @ctxt:  the schema validation context
   3110  * @error: the error code
   3111  * @type: the type specifier
   3112  * @ownerDes: the designation of the owner
   3113  * @ownerItem: the schema object if existent
   3114  * @node: the validated node
   3115  * @value: the validated value
   3116  *
   3117  * Reports a simple type validation error.
   3118  * TODO: Should this report the value of an element as well?
   3119  */
   3120 static void LIBXML_ATTR_FORMAT(8,0)
   3121 xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
   3122 			xmlParserErrors error,
   3123 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
   3124 			xmlNodePtr node,
   3125 			xmlSchemaTypePtr type,
   3126 			const char *expected,
   3127 			const xmlChar *value,
   3128 			const char *message,
   3129 			const xmlChar *str1,
   3130 			const xmlChar *str2)
   3131 {
   3132     xmlChar *msg = NULL;
   3133 
   3134     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
   3135     if (message == NULL) {
   3136 	/*
   3137 	* Use default messages.
   3138 	*/
   3139 	if (type != NULL) {
   3140 	    if (node->type == XML_ATTRIBUTE_NODE)
   3141 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
   3142 	    else
   3143 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
   3144 		"valid value of ");
   3145 	    if (! xmlSchemaIsGlobalItem(type))
   3146 		msg = xmlStrcat(msg, BAD_CAST "the local ");
   3147 	    else
   3148 		msg = xmlStrcat(msg, BAD_CAST "the ");
   3149 
   3150 	    if (WXS_IS_ATOMIC(type))
   3151 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
   3152 	    else if (WXS_IS_LIST(type))
   3153 		msg = xmlStrcat(msg, BAD_CAST "list type");
   3154 	    else if (WXS_IS_UNION(type))
   3155 		msg = xmlStrcat(msg, BAD_CAST "union type");
   3156 
   3157 	    if (xmlSchemaIsGlobalItem(type)) {
   3158 		xmlChar *str = NULL;
   3159 		msg = xmlStrcat(msg, BAD_CAST " '");
   3160 		if (type->builtInType != 0) {
   3161 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
   3162 		    str = xmlStrdup(type->name);
   3163 		} else {
   3164 		    const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
   3165 		    if (!str)
   3166 			str = xmlStrdup(qName);
   3167 		}
   3168 		msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
   3169 		msg = xmlStrcat(msg, BAD_CAST "'.");
   3170 		FREE_AND_NULL(str);
   3171 	    }
   3172 	} else {
   3173 	    if (node->type == XML_ATTRIBUTE_NODE)
   3174 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
   3175 	    else
   3176 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
   3177 		"valid.");
   3178 	}
   3179 	if (expected) {
   3180 	    xmlChar *expectedEscaped = xmlCharStrdup(expected);
   3181 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
   3182 	    msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
   3183 	    FREE_AND_NULL(expectedEscaped);
   3184 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
   3185 	} else
   3186 	    msg = xmlStrcat(msg, BAD_CAST "\n");
   3187 	if (node->type == XML_ATTRIBUTE_NODE)
   3188 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
   3189 	else
   3190 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
   3191     } else {
   3192 	msg = xmlStrcat(msg, BAD_CAST message);
   3193 	msg = xmlStrcat(msg, BAD_CAST ".\n");
   3194 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
   3195 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
   3196     }
   3197     /* Cleanup. */
   3198     FREE_AND_NULL(msg)
   3199 }
   3200 
   3201 /**
   3202  * xmlSchemaPContentErr:
   3203  * @ctxt: the schema parser context
   3204  * @error: the error code
   3205  * @onwerDes: the designation of the holder of the content
   3206  * @ownerItem: the owner item of the holder of the content
   3207  * @ownerElem: the node of the holder of the content
   3208  * @child: the invalid child node
   3209  * @message: the optional error message
   3210  * @content: the optional string describing the correct content
   3211  *
   3212  * Reports an error concerning the content of a schema element.
   3213  */
   3214 static void
   3215 xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
   3216 		     xmlParserErrors error,
   3217 		     xmlSchemaBasicItemPtr ownerItem,
   3218 		     xmlNodePtr ownerElem,
   3219 		     xmlNodePtr child,
   3220 		     const char *message,
   3221 		     const char *content)
   3222 {
   3223     xmlChar *des = NULL;
   3224 
   3225     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
   3226     if (message != NULL)
   3227 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3228 	    "%s: %s.\n",
   3229 	    BAD_CAST des, BAD_CAST message);
   3230     else {
   3231 	if (content != NULL) {
   3232 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3233 		"%s: The content is not valid. Expected is %s.\n",
   3234 		BAD_CAST des, BAD_CAST content);
   3235 	} else {
   3236 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
   3237 		"%s: The content is not valid.\n",
   3238 		BAD_CAST des, NULL);
   3239 	}
   3240     }
   3241     FREE_AND_NULL(des)
   3242 }
   3243 
   3244 /************************************************************************
   3245  *									*
   3246  *			Streamable error functions                      *
   3247  *									*
   3248  ************************************************************************/
   3249 
   3250 
   3251 
   3252 
   3253 /************************************************************************
   3254  *									*
   3255  *			Validation helper functions			*
   3256  *									*
   3257  ************************************************************************/
   3258 
   3259 
   3260 /************************************************************************
   3261  *									*
   3262  *			Allocation functions				*
   3263  *									*
   3264  ************************************************************************/
   3265 
   3266 /**
   3267  * xmlSchemaNewSchemaForParserCtxt:
   3268  * @ctxt:  a schema validation context
   3269  *
   3270  * Allocate a new Schema structure.
   3271  *
   3272  * Returns the newly allocated structure or NULL in case or error
   3273  */
   3274 static xmlSchemaPtr
   3275 xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
   3276 {
   3277     xmlSchemaPtr ret;
   3278 
   3279     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
   3280     if (ret == NULL) {
   3281         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
   3282         return (NULL);
   3283     }
   3284     memset(ret, 0, sizeof(xmlSchema));
   3285     ret->dict = ctxt->dict;
   3286     xmlDictReference(ret->dict);
   3287 
   3288     return (ret);
   3289 }
   3290 
   3291 /**
   3292  * xmlSchemaNewFacet:
   3293  *
   3294  * Allocate a new Facet structure.
   3295  *
   3296  * Returns the newly allocated structure or NULL in case or error
   3297  */
   3298 xmlSchemaFacetPtr
   3299 xmlSchemaNewFacet(void)
   3300 {
   3301     xmlSchemaFacetPtr ret;
   3302 
   3303     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
   3304     if (ret == NULL) {
   3305         return (NULL);
   3306     }
   3307     memset(ret, 0, sizeof(xmlSchemaFacet));
   3308 
   3309     return (ret);
   3310 }
   3311 
   3312 /**
   3313  * xmlSchemaNewAnnot:
   3314  * @ctxt:  a schema validation context
   3315  * @node:  a node
   3316  *
   3317  * Allocate a new annotation structure.
   3318  *
   3319  * Returns the newly allocated structure or NULL in case or error
   3320  */
   3321 static xmlSchemaAnnotPtr
   3322 xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   3323 {
   3324     xmlSchemaAnnotPtr ret;
   3325 
   3326     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
   3327     if (ret == NULL) {
   3328         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
   3329         return (NULL);
   3330     }
   3331     memset(ret, 0, sizeof(xmlSchemaAnnot));
   3332     ret->content = node;
   3333     return (ret);
   3334 }
   3335 
   3336 static xmlSchemaItemListPtr
   3337 xmlSchemaItemListCreate(void)
   3338 {
   3339     xmlSchemaItemListPtr ret;
   3340 
   3341     ret = xmlMalloc(sizeof(xmlSchemaItemList));
   3342     if (ret == NULL) {
   3343 	xmlSchemaPErrMemory(NULL,
   3344 	    "allocating an item list structure", NULL);
   3345 	return (NULL);
   3346     }
   3347     memset(ret, 0, sizeof(xmlSchemaItemList));
   3348     return (ret);
   3349 }
   3350 
   3351 static void
   3352 xmlSchemaItemListClear(xmlSchemaItemListPtr list)
   3353 {
   3354     if (list->items != NULL) {
   3355 	xmlFree(list->items);
   3356 	list->items = NULL;
   3357     }
   3358     list->nbItems = 0;
   3359     list->sizeItems = 0;
   3360 }
   3361 
   3362 static int
   3363 xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
   3364 {
   3365     if (list->items == NULL) {
   3366 	list->items = (void **) xmlMalloc(
   3367 	    20 * sizeof(void *));
   3368 	if (list->items == NULL) {
   3369 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3370 	    return(-1);
   3371 	}
   3372 	list->sizeItems = 20;
   3373     } else if (list->sizeItems <= list->nbItems) {
   3374 	list->sizeItems *= 2;
   3375 	list->items = (void **) xmlRealloc(list->items,
   3376 	    list->sizeItems * sizeof(void *));
   3377 	if (list->items == NULL) {
   3378 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3379 	    list->sizeItems = 0;
   3380 	    return(-1);
   3381 	}
   3382     }
   3383     list->items[list->nbItems++] = item;
   3384     return(0);
   3385 }
   3386 
   3387 static int
   3388 xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
   3389 			 int initialSize,
   3390 			 void *item)
   3391 {
   3392     if (list->items == NULL) {
   3393 	if (initialSize <= 0)
   3394 	    initialSize = 1;
   3395 	list->items = (void **) xmlMalloc(
   3396 	    initialSize * sizeof(void *));
   3397 	if (list->items == NULL) {
   3398 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3399 	    return(-1);
   3400 	}
   3401 	list->sizeItems = initialSize;
   3402     } else if (list->sizeItems <= list->nbItems) {
   3403 	list->sizeItems *= 2;
   3404 	list->items = (void **) xmlRealloc(list->items,
   3405 	    list->sizeItems * sizeof(void *));
   3406 	if (list->items == NULL) {
   3407 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3408 	    list->sizeItems = 0;
   3409 	    return(-1);
   3410 	}
   3411     }
   3412     list->items[list->nbItems++] = item;
   3413     return(0);
   3414 }
   3415 
   3416 static int
   3417 xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
   3418 {
   3419     if (list->items == NULL) {
   3420 	list->items = (void **) xmlMalloc(
   3421 	    20 * sizeof(void *));
   3422 	if (list->items == NULL) {
   3423 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3424 	    return(-1);
   3425 	}
   3426 	list->sizeItems = 20;
   3427     } else if (list->sizeItems <= list->nbItems) {
   3428 	list->sizeItems *= 2;
   3429 	list->items = (void **) xmlRealloc(list->items,
   3430 	    list->sizeItems * sizeof(void *));
   3431 	if (list->items == NULL) {
   3432 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3433 	    list->sizeItems = 0;
   3434 	    return(-1);
   3435 	}
   3436     }
   3437     /*
   3438     * Just append if the index is greater/equal than the item count.
   3439     */
   3440     if (idx >= list->nbItems) {
   3441 	list->items[list->nbItems++] = item;
   3442     } else {
   3443 	int i;
   3444 	for (i = list->nbItems; i > idx; i--)
   3445 	    list->items[i] = list->items[i-1];
   3446 	list->items[idx] = item;
   3447 	list->nbItems++;
   3448     }
   3449     return(0);
   3450 }
   3451 
   3452 #if 0 /* enable if ever needed */
   3453 static int
   3454 xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
   3455 			    int initialSize,
   3456 			    void *item,
   3457 			    int idx)
   3458 {
   3459     if (list->items == NULL) {
   3460 	if (initialSize <= 0)
   3461 	    initialSize = 1;
   3462 	list->items = (void **) xmlMalloc(
   3463 	    initialSize * sizeof(void *));
   3464 	if (list->items == NULL) {
   3465 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
   3466 	    return(-1);
   3467 	}
   3468 	list->sizeItems = initialSize;
   3469     } else if (list->sizeItems <= list->nbItems) {
   3470 	list->sizeItems *= 2;
   3471 	list->items = (void **) xmlRealloc(list->items,
   3472 	    list->sizeItems * sizeof(void *));
   3473 	if (list->items == NULL) {
   3474 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
   3475 	    list->sizeItems = 0;
   3476 	    return(-1);
   3477 	}
   3478     }
   3479     /*
   3480     * Just append if the index is greater/equal than the item count.
   3481     */
   3482     if (idx >= list->nbItems) {
   3483 	list->items[list->nbItems++] = item;
   3484     } else {
   3485 	int i;
   3486 	for (i = list->nbItems; i > idx; i--)
   3487 	    list->items[i] = list->items[i-1];
   3488 	list->items[idx] = item;
   3489 	list->nbItems++;
   3490     }
   3491     return(0);
   3492 }
   3493 #endif
   3494 
   3495 static int
   3496 xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
   3497 {
   3498     int i;
   3499     if ((list->items == NULL) || (idx >= list->nbItems)) {
   3500 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
   3501 	    "index error.\n");
   3502 	return(-1);
   3503     }
   3504 
   3505     if (list->nbItems == 1) {
   3506 	/* TODO: Really free the list? */
   3507 	xmlFree(list->items);
   3508 	list->items = NULL;
   3509 	list->nbItems = 0;
   3510 	list->sizeItems = 0;
   3511     } else if (list->nbItems -1 == idx) {
   3512 	list->nbItems--;
   3513     } else {
   3514 	for (i = idx; i < list->nbItems -1; i++)
   3515 	    list->items[i] = list->items[i+1];
   3516 	list->nbItems--;
   3517     }
   3518     return(0);
   3519 }
   3520 
   3521 /**
   3522  * xmlSchemaItemListFree:
   3523  * @annot:  a schema type structure
   3524  *
   3525  * Deallocate a annotation structure
   3526  */
   3527 static void
   3528 xmlSchemaItemListFree(xmlSchemaItemListPtr list)
   3529 {
   3530     if (list == NULL)
   3531 	return;
   3532     if (list->items != NULL)
   3533 	xmlFree(list->items);
   3534     xmlFree(list);
   3535 }
   3536 
   3537 static void
   3538 xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
   3539 {
   3540     if (bucket == NULL)
   3541 	return;
   3542     if (bucket->globals != NULL) {
   3543 	xmlSchemaComponentListFree(bucket->globals);
   3544 	xmlSchemaItemListFree(bucket->globals);
   3545     }
   3546     if (bucket->locals != NULL) {
   3547 	xmlSchemaComponentListFree(bucket->locals);
   3548 	xmlSchemaItemListFree(bucket->locals);
   3549     }
   3550     if (bucket->relations != NULL) {
   3551 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
   3552 	do {
   3553 	    prev = cur;
   3554 	    cur = cur->next;
   3555 	    xmlFree(prev);
   3556 	} while (cur != NULL);
   3557     }
   3558     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
   3559 	xmlFreeDoc(bucket->doc);
   3560     }
   3561     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
   3562 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
   3563 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
   3564     }
   3565     xmlFree(bucket);
   3566 }
   3567 
   3568 static void
   3569 xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
   3570 {
   3571     xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
   3572 }
   3573 
   3574 static xmlSchemaBucketPtr
   3575 xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
   3576 			 int type, const xmlChar *targetNamespace)
   3577 {
   3578     xmlSchemaBucketPtr ret;
   3579     int size;
   3580     xmlSchemaPtr mainSchema;
   3581 
   3582     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
   3583 	PERROR_INT("xmlSchemaBucketCreate",
   3584 	    "no main schema on constructor");
   3585 	return(NULL);
   3586     }
   3587     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
   3588     /* Create the schema bucket. */
   3589     if (WXS_IS_BUCKET_INCREDEF(type))
   3590 	size = sizeof(xmlSchemaInclude);
   3591     else
   3592 	size = sizeof(xmlSchemaImport);
   3593     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
   3594     if (ret == NULL) {
   3595 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
   3596 	return(NULL);
   3597     }
   3598     memset(ret, 0, size);
   3599     ret->targetNamespace = targetNamespace;
   3600     ret->type = type;
   3601     ret->globals = xmlSchemaItemListCreate();
   3602     if (ret->globals == NULL) {
   3603 	xmlFree(ret);
   3604 	return(NULL);
   3605     }
   3606     ret->locals = xmlSchemaItemListCreate();
   3607     if (ret->locals == NULL) {
   3608 	xmlFree(ret);
   3609 	return(NULL);
   3610     }
   3611     /*
   3612     * The following will assure that only the first bucket is marked as
   3613     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
   3614     * For each following import buckets an xmlSchema will be created.
   3615     * An xmlSchema will be created for every distinct targetNamespace.
   3616     * We assign the targetNamespace to the schemata here.
   3617     */
   3618     if (! WXS_HAS_BUCKETS(pctxt)) {
   3619 	if (WXS_IS_BUCKET_INCREDEF(type)) {
   3620 	    PERROR_INT("xmlSchemaBucketCreate",
   3621 		"first bucket but it's an include or redefine");
   3622 	    xmlSchemaBucketFree(ret);
   3623 	    return(NULL);
   3624 	}
   3625 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
   3626 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
   3627 	/* Point to the *main* schema. */
   3628 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
   3629 	WXS_IMPBUCKET(ret)->schema = mainSchema;
   3630 	/*
   3631 	* Ensure that the main schema gets a targetNamespace.
   3632 	*/
   3633 	mainSchema->targetNamespace = targetNamespace;
   3634     } else {
   3635 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
   3636 	    PERROR_INT("xmlSchemaBucketCreate",
   3637 		"main bucket but it's not the first one");
   3638 	    xmlSchemaBucketFree(ret);
   3639 	    return(NULL);
   3640 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
   3641 	    /*
   3642 	    * Create a schema for imports and assign the
   3643 	    * targetNamespace.
   3644 	    */
   3645 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
   3646 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
   3647 		xmlSchemaBucketFree(ret);
   3648 		return(NULL);
   3649 	    }
   3650 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
   3651 	}
   3652     }
   3653     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   3654 	int res;
   3655 	/*
   3656 	* Imports go into the "schemasImports" slot of the main *schema*.
   3657 	* Note that we create an import entry for the main schema as well; i.e.,
   3658 	* even if there's only one schema, we'll get an import.
   3659 	*/
   3660 	if (mainSchema->schemasImports == NULL) {
   3661 	    mainSchema->schemasImports = xmlHashCreateDict(5,
   3662 		WXS_CONSTRUCTOR(pctxt)->dict);
   3663 	    if (mainSchema->schemasImports == NULL) {
   3664 		xmlSchemaBucketFree(ret);
   3665 		return(NULL);
   3666 	    }
   3667 	}
   3668 	if (targetNamespace == NULL)
   3669 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3670 		XML_SCHEMAS_NO_NAMESPACE, ret);
   3671 	else
   3672 	    res = xmlHashAddEntry(mainSchema->schemasImports,
   3673 		targetNamespace, ret);
   3674 	if (res != 0) {
   3675 	    PERROR_INT("xmlSchemaBucketCreate",
   3676 		"failed to add the schema bucket to the hash");
   3677 	    xmlSchemaBucketFree(ret);
   3678 	    return(NULL);
   3679 	}
   3680     } else {
   3681 	/* Set the @ownerImport of an include bucket. */
   3682 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
   3683 	    WXS_INCBUCKET(ret)->ownerImport =
   3684 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
   3685 	else
   3686 	    WXS_INCBUCKET(ret)->ownerImport =
   3687 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
   3688 
   3689 	/* Includes got into the "includes" slot of the *main* schema. */
   3690 	if (mainSchema->includes == NULL) {
   3691 	    mainSchema->includes = xmlSchemaItemListCreate();
   3692 	    if (mainSchema->includes == NULL) {
   3693 		xmlSchemaBucketFree(ret);
   3694 		return(NULL);
   3695 	    }
   3696 	}
   3697 	xmlSchemaItemListAdd(mainSchema->includes, ret);
   3698     }
   3699     /*
   3700     * Add to list of all buckets; this is used for lookup
   3701     * during schema construction time only.
   3702     */
   3703     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
   3704 	return(NULL);
   3705     return(ret);
   3706 }
   3707 
   3708 static int
   3709 xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
   3710 {
   3711     if (*list == NULL) {
   3712 	*list = xmlSchemaItemListCreate();
   3713 	if (*list == NULL)
   3714 	    return(-1);
   3715     }
   3716     xmlSchemaItemListAddSize(*list, initialSize, item);
   3717     return(0);
   3718 }
   3719 
   3720 /**
   3721  * xmlSchemaFreeAnnot:
   3722  * @annot:  a schema type structure
   3723  *
   3724  * Deallocate a annotation structure
   3725  */
   3726 static void
   3727 xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
   3728 {
   3729     if (annot == NULL)
   3730         return;
   3731     if (annot->next == NULL) {
   3732 	xmlFree(annot);
   3733     } else {
   3734 	xmlSchemaAnnotPtr prev;
   3735 
   3736 	do {
   3737 	    prev = annot;
   3738 	    annot = annot->next;
   3739 	    xmlFree(prev);
   3740 	} while (annot != NULL);
   3741     }
   3742 }
   3743 
   3744 /**
   3745  * xmlSchemaFreeNotation:
   3746  * @schema:  a schema notation structure
   3747  *
   3748  * Deallocate a Schema Notation structure.
   3749  */
   3750 static void
   3751 xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
   3752 {
   3753     if (nota == NULL)
   3754         return;
   3755     xmlFree(nota);
   3756 }
   3757 
   3758 /**
   3759  * xmlSchemaFreeAttribute:
   3760  * @attr:  an attribute declaration
   3761  *
   3762  * Deallocates an attribute declaration structure.
   3763  */
   3764 static void
   3765 xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
   3766 {
   3767     if (attr == NULL)
   3768         return;
   3769     if (attr->annot != NULL)
   3770 	xmlSchemaFreeAnnot(attr->annot);
   3771     if (attr->defVal != NULL)
   3772 	xmlSchemaFreeValue(attr->defVal);
   3773     xmlFree(attr);
   3774 }
   3775 
   3776 /**
   3777  * xmlSchemaFreeAttributeUse:
   3778  * @use:  an attribute use
   3779  *
   3780  * Deallocates an attribute use structure.
   3781  */
   3782 static void
   3783 xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
   3784 {
   3785     if (use == NULL)
   3786         return;
   3787     if (use->annot != NULL)
   3788 	xmlSchemaFreeAnnot(use->annot);
   3789     if (use->defVal != NULL)
   3790 	xmlSchemaFreeValue(use->defVal);
   3791     xmlFree(use);
   3792 }
   3793 
   3794 /**
   3795  * xmlSchemaFreeAttributeUseProhib:
   3796  * @prohib:  an attribute use prohibition
   3797  *
   3798  * Deallocates an attribute use structure.
   3799  */
   3800 static void
   3801 xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
   3802 {
   3803     if (prohib == NULL)
   3804         return;
   3805     xmlFree(prohib);
   3806 }
   3807 
   3808 /**
   3809  * xmlSchemaFreeWildcardNsSet:
   3810  * set:  a schema wildcard namespace
   3811  *
   3812  * Deallocates a list of wildcard constraint structures.
   3813  */
   3814 static void
   3815 xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
   3816 {
   3817     xmlSchemaWildcardNsPtr next;
   3818 
   3819     while (set != NULL) {
   3820 	next = set->next;
   3821 	xmlFree(set);
   3822 	set = next;
   3823     }
   3824 }
   3825 
   3826 /**
   3827  * xmlSchemaFreeWildcard:
   3828  * @wildcard:  a wildcard structure
   3829  *
   3830  * Deallocates a wildcard structure.
   3831  */
   3832 void
   3833 xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
   3834 {
   3835     if (wildcard == NULL)
   3836         return;
   3837     if (wildcard->annot != NULL)
   3838         xmlSchemaFreeAnnot(wildcard->annot);
   3839     if (wildcard->nsSet != NULL)
   3840 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
   3841     if (wildcard->negNsSet != NULL)
   3842 	xmlFree(wildcard->negNsSet);
   3843     xmlFree(wildcard);
   3844 }
   3845 
   3846 /**
   3847  * xmlSchemaFreeAttributeGroup:
   3848  * @schema:  a schema attribute group structure
   3849  *
   3850  * Deallocate a Schema Attribute Group structure.
   3851  */
   3852 static void
   3853 xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
   3854 {
   3855     if (attrGr == NULL)
   3856         return;
   3857     if (attrGr->annot != NULL)
   3858         xmlSchemaFreeAnnot(attrGr->annot);
   3859     if (attrGr->attrUses != NULL)
   3860 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
   3861     xmlFree(attrGr);
   3862 }
   3863 
   3864 /**
   3865  * xmlSchemaFreeQNameRef:
   3866  * @item: a QName reference structure
   3867  *
   3868  * Deallocatea a QName reference structure.
   3869  */
   3870 static void
   3871 xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
   3872 {
   3873     xmlFree(item);
   3874 }
   3875 
   3876 /**
   3877  * xmlSchemaFreeTypeLinkList:
   3878  * @alink: a type link
   3879  *
   3880  * Deallocate a list of types.
   3881  */
   3882 static void
   3883 xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
   3884 {
   3885     xmlSchemaTypeLinkPtr next;
   3886 
   3887     while (link != NULL) {
   3888 	next = link->next;
   3889 	xmlFree(link);
   3890 	link = next;
   3891     }
   3892 }
   3893 
   3894 static void
   3895 xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
   3896 {
   3897     xmlSchemaIDCStateObjPtr next;
   3898     while (sto != NULL) {
   3899 	next = sto->next;
   3900 	if (sto->history != NULL)
   3901 	    xmlFree(sto->history);
   3902 	if (sto->xpathCtxt != NULL)
   3903 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   3904 	xmlFree(sto);
   3905 	sto = next;
   3906     }
   3907 }
   3908 
   3909 /**
   3910  * xmlSchemaFreeIDC:
   3911  * @idc: a identity-constraint definition
   3912  *
   3913  * Deallocates an identity-constraint definition.
   3914  */
   3915 static void
   3916 xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
   3917 {
   3918     xmlSchemaIDCSelectPtr cur, prev;
   3919 
   3920     if (idcDef == NULL)
   3921 	return;
   3922     if (idcDef->annot != NULL)
   3923         xmlSchemaFreeAnnot(idcDef->annot);
   3924     /* Selector */
   3925     if (idcDef->selector != NULL) {
   3926 	if (idcDef->selector->xpathComp != NULL)
   3927 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
   3928 	xmlFree(idcDef->selector);
   3929     }
   3930     /* Fields */
   3931     if (idcDef->fields != NULL) {
   3932 	cur = idcDef->fields;
   3933 	do {
   3934 	    prev = cur;
   3935 	    cur = cur->next;
   3936 	    if (prev->xpathComp != NULL)
   3937 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
   3938 	    xmlFree(prev);
   3939 	} while (cur != NULL);
   3940     }
   3941     xmlFree(idcDef);
   3942 }
   3943 
   3944 /**
   3945  * xmlSchemaFreeElement:
   3946  * @schema:  a schema element structure
   3947  *
   3948  * Deallocate a Schema Element structure.
   3949  */
   3950 static void
   3951 xmlSchemaFreeElement(xmlSchemaElementPtr elem)
   3952 {
   3953     if (elem == NULL)
   3954         return;
   3955     if (elem->annot != NULL)
   3956         xmlSchemaFreeAnnot(elem->annot);
   3957     if (elem->contModel != NULL)
   3958         xmlRegFreeRegexp(elem->contModel);
   3959     if (elem->defVal != NULL)
   3960 	xmlSchemaFreeValue(elem->defVal);
   3961     xmlFree(elem);
   3962 }
   3963 
   3964 /**
   3965  * xmlSchemaFreeFacet:
   3966  * @facet:  a schema facet structure
   3967  *
   3968  * Deallocate a Schema Facet structure.
   3969  */
   3970 void
   3971 xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
   3972 {
   3973     if (facet == NULL)
   3974         return;
   3975     if (facet->val != NULL)
   3976         xmlSchemaFreeValue(facet->val);
   3977     if (facet->regexp != NULL)
   3978         xmlRegFreeRegexp(facet->regexp);
   3979     if (facet->annot != NULL)
   3980         xmlSchemaFreeAnnot(facet->annot);
   3981     xmlFree(facet);
   3982 }
   3983 
   3984 /**
   3985  * xmlSchemaFreeType:
   3986  * @type:  a schema type structure
   3987  *
   3988  * Deallocate a Schema Type structure.
   3989  */
   3990 void
   3991 xmlSchemaFreeType(xmlSchemaTypePtr type)
   3992 {
   3993     if (type == NULL)
   3994         return;
   3995     if (type->annot != NULL)
   3996         xmlSchemaFreeAnnot(type->annot);
   3997     if (type->facets != NULL) {
   3998         xmlSchemaFacetPtr facet, next;
   3999 
   4000         facet = type->facets;
   4001         while (facet != NULL) {
   4002             next = facet->next;
   4003             xmlSchemaFreeFacet(facet);
   4004             facet = next;
   4005         }
   4006     }
   4007     if (type->attrUses != NULL)
   4008 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
   4009     if (type->memberTypes != NULL)
   4010 	xmlSchemaFreeTypeLinkList(type->memberTypes);
   4011     if (type->facetSet != NULL) {
   4012 	xmlSchemaFacetLinkPtr next, link;
   4013 
   4014 	link = type->facetSet;
   4015 	do {
   4016 	    next = link->next;
   4017 	    xmlFree(link);
   4018 	    link = next;
   4019 	} while (link != NULL);
   4020     }
   4021     if (type->contModel != NULL)
   4022         xmlRegFreeRegexp(type->contModel);
   4023     xmlFree(type);
   4024 }
   4025 
   4026 /**
   4027  * xmlSchemaFreeModelGroupDef:
   4028  * @item:  a schema model group definition
   4029  *
   4030  * Deallocates a schema model group definition.
   4031  */
   4032 static void
   4033 xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
   4034 {
   4035     if (item->annot != NULL)
   4036 	xmlSchemaFreeAnnot(item->annot);
   4037     xmlFree(item);
   4038 }
   4039 
   4040 /**
   4041  * xmlSchemaFreeModelGroup:
   4042  * @item:  a schema model group
   4043  *
   4044  * Deallocates a schema model group structure.
   4045  */
   4046 static void
   4047 xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
   4048 {
   4049     if (item->annot != NULL)
   4050 	xmlSchemaFreeAnnot(item->annot);
   4051     xmlFree(item);
   4052 }
   4053 
   4054 static void
   4055 xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
   4056 {
   4057     if ((list == NULL) || (list->nbItems == 0))
   4058 	return;
   4059     {
   4060 	xmlSchemaTreeItemPtr item;
   4061 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
   4062 	int i;
   4063 
   4064 	for (i = 0; i < list->nbItems; i++) {
   4065 	    item = items[i];
   4066 	    if (item == NULL)
   4067 		continue;
   4068 	    switch (item->type) {
   4069 		case XML_SCHEMA_TYPE_SIMPLE:
   4070 		case XML_SCHEMA_TYPE_COMPLEX:
   4071 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
   4072 		    break;
   4073 		case XML_SCHEMA_TYPE_ATTRIBUTE:
   4074 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
   4075 		    break;
   4076 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   4077 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
   4078 		    break;
   4079 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   4080 		    xmlSchemaFreeAttributeUseProhib(
   4081 			(xmlSchemaAttributeUseProhibPtr) item);
   4082 		    break;
   4083 		case XML_SCHEMA_TYPE_ELEMENT:
   4084 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
   4085 		    break;
   4086 		case XML_SCHEMA_TYPE_PARTICLE:
   4087 		    if (item->annot != NULL)
   4088 			xmlSchemaFreeAnnot(item->annot);
   4089 		    xmlFree(item);
   4090 		    break;
   4091 		case XML_SCHEMA_TYPE_SEQUENCE:
   4092 		case XML_SCHEMA_TYPE_CHOICE:
   4093 		case XML_SCHEMA_TYPE_ALL:
   4094 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
   4095 		    break;
   4096 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   4097 		    xmlSchemaFreeAttributeGroup(
   4098 			(xmlSchemaAttributeGroupPtr) item);
   4099 		    break;
   4100 		case XML_SCHEMA_TYPE_GROUP:
   4101 		    xmlSchemaFreeModelGroupDef(
   4102 			(xmlSchemaModelGroupDefPtr) item);
   4103 		    break;
   4104 		case XML_SCHEMA_TYPE_ANY:
   4105 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   4106 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
   4107 		    break;
   4108 		case XML_SCHEMA_TYPE_IDC_KEY:
   4109 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
   4110 		case XML_SCHEMA_TYPE_IDC_KEYREF:
   4111 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
   4112 		    break;
   4113 		case XML_SCHEMA_TYPE_NOTATION:
   4114 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
   4115 		    break;
   4116 		case XML_SCHEMA_EXTRA_QNAMEREF:
   4117 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
   4118 		    break;
   4119 		default: {
   4120 		    /* TODO: This should never be hit. */
   4121 		    xmlSchemaPSimpleInternalErr(NULL,
   4122 			"Internal error: xmlSchemaComponentListFree, "
   4123 			"unexpected component type '%s'\n",
   4124 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
   4125 			 }
   4126 		    break;
   4127 	    }
   4128 	}
   4129 	list->nbItems = 0;
   4130     }
   4131 }
   4132 
   4133 /**
   4134  * xmlSchemaFree:
   4135  * @schema:  a schema structure
   4136  *
   4137  * Deallocate a Schema structure.
   4138  */
   4139 void
   4140 xmlSchemaFree(xmlSchemaPtr schema)
   4141 {
   4142     if (schema == NULL)
   4143         return;
   4144     /* @volatiles is not used anymore :-/ */
   4145     if (schema->volatiles != NULL)
   4146 	TODO
   4147     /*
   4148     * Note that those slots are not responsible for freeing
   4149     * schema components anymore; this will now be done by
   4150     * the schema buckets.
   4151     */
   4152     if (schema->notaDecl != NULL)
   4153         xmlHashFree(schema->notaDecl, NULL);
   4154     if (schema->attrDecl != NULL)
   4155         xmlHashFree(schema->attrDecl, NULL);
   4156     if (schema->attrgrpDecl != NULL)
   4157         xmlHashFree(schema->attrgrpDecl, NULL);
   4158     if (schema->elemDecl != NULL)
   4159         xmlHashFree(schema->elemDecl, NULL);
   4160     if (schema->typeDecl != NULL)
   4161         xmlHashFree(schema->typeDecl, NULL);
   4162     if (schema->groupDecl != NULL)
   4163         xmlHashFree(schema->groupDecl, NULL);
   4164     if (schema->idcDef != NULL)
   4165         xmlHashFree(schema->idcDef, NULL);
   4166 
   4167     if (schema->schemasImports != NULL)
   4168 	xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
   4169     if (schema->includes != NULL) {
   4170 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
   4171 	int i;
   4172 	for (i = 0; i < list->nbItems; i++) {
   4173 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
   4174 	}
   4175 	xmlSchemaItemListFree(list);
   4176     }
   4177     if (schema->annot != NULL)
   4178         xmlSchemaFreeAnnot(schema->annot);
   4179     /* Never free the doc here, since this will be done by the buckets. */
   4180 
   4181     xmlDictFree(schema->dict);
   4182     xmlFree(schema);
   4183 }
   4184 
   4185 /************************************************************************
   4186  *									*
   4187  *			Debug functions					*
   4188  *									*
   4189  ************************************************************************/
   4190 
   4191 #ifdef LIBXML_OUTPUT_ENABLED
   4192 
   4193 static void
   4194 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
   4195 
   4196 /**
   4197  * xmlSchemaElementDump:
   4198  * @elem:  an element
   4199  * @output:  the file output
   4200  *
   4201  * Dump the element
   4202  */
   4203 static void
   4204 xmlSchemaElementDump(void *payload, void *data,
   4205                      const xmlChar * name ATTRIBUTE_UNUSED,
   4206 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
   4207                      const xmlChar * context ATTRIBUTE_UNUSED)
   4208 {
   4209     xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
   4210     FILE *output = (FILE *) data;
   4211     if (elem == NULL)
   4212         return;
   4213 
   4214 
   4215     fprintf(output, "Element");
   4216     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
   4217 	fprintf(output, " (global)");
   4218     fprintf(output, ": '%s' ", elem->name);
   4219     if (namespace != NULL)
   4220 	fprintf(output, "ns '%s'", namespace);
   4221     fprintf(output, "\n");
   4222 #if 0
   4223     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
   4224 	fprintf(output, "  min %d ", elem->minOccurs);
   4225         if (elem->maxOccurs >= UNBOUNDED)
   4226             fprintf(output, "max: unbounded\n");
   4227         else if (elem->maxOccurs != 1)
   4228             fprintf(output, "max: %d\n", elem->maxOccurs);
   4229         else
   4230             fprintf(output, "\n");
   4231     }
   4232 #endif
   4233     /*
   4234     * Misc other properties.
   4235     */
   4236     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
   4237 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
   4238 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
   4239 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
   4240 	fprintf(output, "  props: ");
   4241 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
   4242 	    fprintf(output, "[fixed] ");
   4243 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
   4244 	    fprintf(output, "[default] ");
   4245 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   4246 	    fprintf(output, "[abstract] ");
   4247 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
   4248 	    fprintf(output, "[nillable] ");
   4249 	fprintf(output, "\n");
   4250     }
   4251     /*
   4252     * Default/fixed value.
   4253     */
   4254     if (elem->value != NULL)
   4255 	fprintf(output, "  value: '%s'\n", elem->value);
   4256     /*
   4257     * Type.
   4258     */
   4259     if (elem->namedType != NULL) {
   4260 	fprintf(output, "  type: '%s' ", elem->namedType);
   4261 	if (elem->namedTypeNs != NULL)
   4262 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
   4263 	else
   4264 	    fprintf(output, "\n");
   4265     } else if (elem->subtypes != NULL) {
   4266 	/*
   4267 	* Dump local types.
   4268 	*/
   4269 	xmlSchemaTypeDump(elem->subtypes, output);
   4270     }
   4271     /*
   4272     * Substitution group.
   4273     */
   4274     if (elem->substGroup != NULL) {
   4275 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
   4276 	if (elem->substGroupNs != NULL)
   4277 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
   4278 	else
   4279 	    fprintf(output, "\n");
   4280     }
   4281 }
   4282 
   4283 /**
   4284  * xmlSchemaAnnotDump:
   4285  * @output:  the file output
   4286  * @annot:  a annotation
   4287  *
   4288  * Dump the annotation
   4289  */
   4290 static void
   4291 xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
   4292 {
   4293     xmlChar *content;
   4294 
   4295     if (annot == NULL)
   4296         return;
   4297 
   4298     content = xmlNodeGetContent(annot->content);
   4299     if (content != NULL) {
   4300         fprintf(output, "  Annot: %s\n", content);
   4301         xmlFree(content);
   4302     } else
   4303         fprintf(output, "  Annot: empty\n");
   4304 }
   4305 
   4306 /**
   4307  * xmlSchemaContentModelDump:
   4308  * @particle: the schema particle
   4309  * @output: the file output
   4310  * @depth: the depth used for intentation
   4311  *
   4312  * Dump a SchemaType structure
   4313  */
   4314 static void
   4315 xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
   4316 {
   4317     xmlChar *str = NULL;
   4318     xmlSchemaTreeItemPtr term;
   4319     char shift[100];
   4320     int i;
   4321 
   4322     if (particle == NULL)
   4323 	return;
   4324     for (i = 0;((i < depth) && (i < 25));i++)
   4325         shift[2 * i] = shift[2 * i + 1] = ' ';
   4326     shift[2 * i] = shift[2 * i + 1] = 0;
   4327     fprintf(output, "%s", shift);
   4328     if (particle->children == NULL) {
   4329 	fprintf(output, "MISSING particle term\n");
   4330 	return;
   4331     }
   4332     term = particle->children;
   4333     if (term == NULL) {
   4334 	fprintf(output, "(NULL)");
   4335     } else {
   4336 	switch (term->type) {
   4337 	    case XML_SCHEMA_TYPE_ELEMENT:
   4338 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
   4339 		    ((xmlSchemaElementPtr)term)->targetNamespace,
   4340 		    ((xmlSchemaElementPtr)term)->name));
   4341 		FREE_AND_NULL(str);
   4342 		break;
   4343 	    case XML_SCHEMA_TYPE_SEQUENCE:
   4344 		fprintf(output, "SEQUENCE");
   4345 		break;
   4346 	    case XML_SCHEMA_TYPE_CHOICE:
   4347 		fprintf(output, "CHOICE");
   4348 		break;
   4349 	    case XML_SCHEMA_TYPE_ALL:
   4350 		fprintf(output, "ALL");
   4351 		break;
   4352 	    case XML_SCHEMA_TYPE_ANY:
   4353 		fprintf(output, "ANY");
   4354 		break;
   4355 	    default:
   4356 		fprintf(output, "UNKNOWN\n");
   4357 		return;
   4358 	}
   4359     }
   4360     if (particle->minOccurs != 1)
   4361 	fprintf(output, " min: %d", particle->minOccurs);
   4362     if (particle->maxOccurs >= UNBOUNDED)
   4363 	fprintf(output, " max: unbounded");
   4364     else if (particle->maxOccurs != 1)
   4365 	fprintf(output, " max: %d", particle->maxOccurs);
   4366     fprintf(output, "\n");
   4367     if (term &&
   4368 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   4369 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
   4370 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
   4371 	 (term->children != NULL)) {
   4372 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
   4373 	    output, depth +1);
   4374     }
   4375     if (particle->next != NULL)
   4376 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
   4377 		output, depth);
   4378 }
   4379 
   4380 /**
   4381  * xmlSchemaAttrUsesDump:
   4382  * @uses:  attribute uses list
   4383  * @output:  the file output
   4384  *
   4385  * Dumps a list of attribute use components.
   4386  */
   4387 static void
   4388 xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
   4389 {
   4390     xmlSchemaAttributeUsePtr use;
   4391     xmlSchemaAttributeUseProhibPtr prohib;
   4392     xmlSchemaQNameRefPtr ref;
   4393     const xmlChar *name, *tns;
   4394     xmlChar *str = NULL;
   4395     int i;
   4396 
   4397     if ((uses == NULL) || (uses->nbItems == 0))
   4398         return;
   4399 
   4400     fprintf(output, "  attributes:\n");
   4401     for (i = 0; i < uses->nbItems; i++) {
   4402 	use = uses->items[i];
   4403 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   4404 	    fprintf(output, "  [prohibition] ");
   4405 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
   4406 	    name = prohib->name;
   4407 	    tns = prohib->targetNamespace;
   4408 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
   4409 	    fprintf(output, "  [reference] ");
   4410 	    ref = (xmlSchemaQNameRefPtr) use;
   4411 	    name = ref->name;
   4412 	    tns = ref->targetNamespace;
   4413 	} else {
   4414 	    fprintf(output, "  [use] ");
   4415 	    name = WXS_ATTRUSE_DECL_NAME(use);
   4416 	    tns = WXS_ATTRUSE_DECL_TNS(use);
   4417 	}
   4418 	fprintf(output, "'%s'\n",
   4419 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
   4420 	FREE_AND_NULL(str);
   4421     }
   4422 }
   4423 
   4424 /**
   4425  * xmlSchemaTypeDump:
   4426  * @output:  the file output
   4427  * @type:  a type structure
   4428  *
   4429  * Dump a SchemaType structure
   4430  */
   4431 static void
   4432 xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
   4433 {
   4434     if (type == NULL) {
   4435         fprintf(output, "Type: NULL\n");
   4436         return;
   4437     }
   4438     fprintf(output, "Type: ");
   4439     if (type->name != NULL)
   4440         fprintf(output, "'%s' ", type->name);
   4441     else
   4442         fprintf(output, "(no name) ");
   4443     if (type->targetNamespace != NULL)
   4444 	fprintf(output, "ns '%s' ", type->targetNamespace);
   4445     switch (type->type) {
   4446         case XML_SCHEMA_TYPE_BASIC:
   4447             fprintf(output, "[basic] ");
   4448             break;
   4449         case XML_SCHEMA_TYPE_SIMPLE:
   4450             fprintf(output, "[simple] ");
   4451             break;
   4452         case XML_SCHEMA_TYPE_COMPLEX:
   4453             fprintf(output, "[complex] ");
   4454             break;
   4455         case XML_SCHEMA_TYPE_SEQUENCE:
   4456             fprintf(output, "[sequence] ");
   4457             break;
   4458         case XML_SCHEMA_TYPE_CHOICE:
   4459             fprintf(output, "[choice] ");
   4460             break;
   4461         case XML_SCHEMA_TYPE_ALL:
   4462             fprintf(output, "[all] ");
   4463             break;
   4464         case XML_SCHEMA_TYPE_UR:
   4465             fprintf(output, "[ur] ");
   4466             break;
   4467         case XML_SCHEMA_TYPE_RESTRICTION:
   4468             fprintf(output, "[restriction] ");
   4469             break;
   4470         case XML_SCHEMA_TYPE_EXTENSION:
   4471             fprintf(output, "[extension] ");
   4472             break;
   4473         default:
   4474             fprintf(output, "[unknown type %d] ", type->type);
   4475             break;
   4476     }
   4477     fprintf(output, "content: ");
   4478     switch (type->contentType) {
   4479         case XML_SCHEMA_CONTENT_UNKNOWN:
   4480             fprintf(output, "[unknown] ");
   4481             break;
   4482         case XML_SCHEMA_CONTENT_EMPTY:
   4483             fprintf(output, "[empty] ");
   4484             break;
   4485         case XML_SCHEMA_CONTENT_ELEMENTS:
   4486             fprintf(output, "[element] ");
   4487             break;
   4488         case XML_SCHEMA_CONTENT_MIXED:
   4489             fprintf(output, "[mixed] ");
   4490             break;
   4491         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   4492 	/* not used. */
   4493             break;
   4494         case XML_SCHEMA_CONTENT_BASIC:
   4495             fprintf(output, "[basic] ");
   4496             break;
   4497         case XML_SCHEMA_CONTENT_SIMPLE:
   4498             fprintf(output, "[simple] ");
   4499             break;
   4500         case XML_SCHEMA_CONTENT_ANY:
   4501             fprintf(output, "[any] ");
   4502             break;
   4503     }
   4504     fprintf(output, "\n");
   4505     if (type->base != NULL) {
   4506         fprintf(output, "  base type: '%s'", type->base);
   4507 	if (type->baseNs != NULL)
   4508 	    fprintf(output, " ns '%s'\n", type->baseNs);
   4509 	else
   4510 	    fprintf(output, "\n");
   4511     }
   4512     if (type->attrUses != NULL)
   4513 	xmlSchemaAttrUsesDump(type->attrUses, output);
   4514     if (type->annot != NULL)
   4515         xmlSchemaAnnotDump(output, type->annot);
   4516 #ifdef DUMP_CONTENT_MODEL
   4517     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
   4518 	(type->subtypes != NULL)) {
   4519 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
   4520 	    output, 1);
   4521     }
   4522 #endif
   4523 }
   4524 
   4525 static void
   4526 xmlSchemaTypeDumpEntry(void *type, void *output,
   4527                        const xmlChar *name ATTRIBUTE_UNUSED)
   4528 {
   4529     xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
   4530 }
   4531 
   4532 /**
   4533  * xmlSchemaDump:
   4534  * @output:  the file output
   4535  * @schema:  a schema structure
   4536  *
   4537  * Dump a Schema structure.
   4538  */
   4539 void
   4540 xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
   4541 {
   4542     if (output == NULL)
   4543         return;
   4544     if (schema == NULL) {
   4545         fprintf(output, "Schemas: NULL\n");
   4546         return;
   4547     }
   4548     fprintf(output, "Schemas: ");
   4549     if (schema->name != NULL)
   4550         fprintf(output, "%s, ", schema->name);
   4551     else
   4552         fprintf(output, "no name, ");
   4553     if (schema->targetNamespace != NULL)
   4554         fprintf(output, "%s", (const char *) schema->targetNamespace);
   4555     else
   4556         fprintf(output, "no target namespace");
   4557     fprintf(output, "\n");
   4558     if (schema->annot != NULL)
   4559         xmlSchemaAnnotDump(output, schema->annot);
   4560     xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
   4561     xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
   4562 }
   4563 
   4564 #ifdef DEBUG_IDC_NODE_TABLE
   4565 /**
   4566  * xmlSchemaDebugDumpIDCTable:
   4567  * @vctxt: the WXS validation context
   4568  *
   4569  * Displays the current IDC table for debug purposes.
   4570  */
   4571 static void
   4572 xmlSchemaDebugDumpIDCTable(FILE * output,
   4573 			   const xmlChar *namespaceName,
   4574 			   const xmlChar *localName,
   4575 			   xmlSchemaPSVIIDCBindingPtr bind)
   4576 {
   4577     xmlChar *str = NULL;
   4578     const xmlChar *value;
   4579     xmlSchemaPSVIIDCNodePtr tab;
   4580     xmlSchemaPSVIIDCKeyPtr key;
   4581     int i, j, res;
   4582 
   4583     fprintf(output, "IDC: TABLES on '%s'\n",
   4584 	xmlSchemaFormatQName(&str, namespaceName, localName));
   4585     FREE_AND_NULL(str)
   4586 
   4587     if (bind == NULL)
   4588 	return;
   4589     do {
   4590 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
   4591 	    xmlSchemaGetComponentQName(&str,
   4592 		bind->definition), bind->nbNodes);
   4593 	FREE_AND_NULL(str)
   4594 	for (i = 0; i < bind->nbNodes; i++) {
   4595 	    tab = bind->nodeTable[i];
   4596 	    fprintf(output, "         ( ");
   4597 	    for (j = 0; j < bind->definition->nbFields; j++) {
   4598 		key = tab->keys[j];
   4599 		if ((key != NULL) && (key->val != NULL)) {
   4600 		    res = xmlSchemaGetCanonValue(key->val, &value);
   4601 		    if (res >= 0)
   4602 			fprintf(output, "'%s' ", value);
   4603 		    else
   4604 			fprintf(output, "CANON-VALUE-FAILED ");
   4605 		    if (res == 0)
   4606 			FREE_AND_NULL(value)
   4607 		} else if (key != NULL)
   4608 		    fprintf(output, "(no val), ");
   4609 		else
   4610 		    fprintf(output, "(key missing), ");
   4611 	    }
   4612 	    fprintf(output, ")\n");
   4613 	}
   4614 	if (bind->dupls && bind->dupls->nbItems) {
   4615 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
   4616 	    for (i = 0; i < bind->dupls->nbItems; i++) {
   4617 		tab = bind->dupls->items[i];
   4618 		fprintf(output, "         ( ");
   4619 		for (j = 0; j < bind->definition->nbFields; j++) {
   4620 		    key = tab->keys[j];
   4621 		    if ((key != NULL) && (key->val != NULL)) {
   4622 			res = xmlSchemaGetCanonValue(key->val, &value);
   4623 			if (res >= 0)
   4624 			    fprintf(output, "'%s' ", value);
   4625 			else
   4626 			    fprintf(output, "CANON-VALUE-FAILED ");
   4627 			if (res == 0)
   4628 			    FREE_AND_NULL(value)
   4629 		    } else if (key != NULL)
   4630 		    fprintf(output, "(no val), ");
   4631 			else
   4632 			    fprintf(output, "(key missing), ");
   4633 		}
   4634 		fprintf(output, ")\n");
   4635 	    }
   4636 	}
   4637 	bind = bind->next;
   4638     } while (bind != NULL);
   4639 }
   4640 #endif /* DEBUG_IDC */
   4641 #endif /* LIBXML_OUTPUT_ENABLED */
   4642 
   4643 /************************************************************************
   4644  *									*
   4645  *			Utilities					*
   4646  *									*
   4647  ************************************************************************/
   4648 
   4649 /**
   4650  * xmlSchemaGetPropNode:
   4651  * @node: the element node
   4652  * @name: the name of the attribute
   4653  *
   4654  * Seeks an attribute with a name of @name in
   4655  * no namespace.
   4656  *
   4657  * Returns the attribute or NULL if not present.
   4658  */
   4659 static xmlAttrPtr
   4660 xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
   4661 {
   4662     xmlAttrPtr prop;
   4663 
   4664     if ((node == NULL) || (name == NULL))
   4665 	return(NULL);
   4666     prop = node->properties;
   4667     while (prop != NULL) {
   4668         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
   4669 	    return(prop);
   4670 	prop = prop->next;
   4671     }
   4672     return (NULL);
   4673 }
   4674 
   4675 /**
   4676  * xmlSchemaGetPropNodeNs:
   4677  * @node: the element node
   4678  * @uri: the uri
   4679  * @name: the name of the attribute
   4680  *
   4681  * Seeks an attribute with a local name of @name and
   4682  * a namespace URI of @uri.
   4683  *
   4684  * Returns the attribute or NULL if not present.
   4685  */
   4686 static xmlAttrPtr
   4687 xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
   4688 {
   4689     xmlAttrPtr prop;
   4690 
   4691     if ((node == NULL) || (name == NULL))
   4692 	return(NULL);
   4693     prop = node->properties;
   4694     while (prop != NULL) {
   4695 	if ((prop->ns != NULL) &&
   4696 	    xmlStrEqual(prop->name, BAD_CAST name) &&
   4697 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
   4698 	    return(prop);
   4699 	prop = prop->next;
   4700     }
   4701     return (NULL);
   4702 }
   4703 
   4704 static const xmlChar *
   4705 xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
   4706 {
   4707     xmlChar *val;
   4708     const xmlChar *ret;
   4709 
   4710     val = xmlNodeGetContent(node);
   4711     if (val == NULL)
   4712 	val = xmlStrdup((xmlChar *)"");
   4713     ret = xmlDictLookup(ctxt->dict, val, -1);
   4714     xmlFree(val);
   4715     return(ret);
   4716 }
   4717 
   4718 static const xmlChar *
   4719 xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
   4720 {
   4721     return((const xmlChar*) xmlNodeGetContent(node));
   4722 }
   4723 
   4724 /**
   4725  * xmlSchemaGetProp:
   4726  * @ctxt: the parser context
   4727  * @node: the node
   4728  * @name: the property name
   4729  *
   4730  * Read a attribute value and internalize the string
   4731  *
   4732  * Returns the string or NULL if not present.
   4733  */
   4734 static const xmlChar *
   4735 xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   4736                  const char *name)
   4737 {
   4738     xmlChar *val;
   4739     const xmlChar *ret;
   4740 
   4741     val = xmlGetNoNsProp(node, BAD_CAST name);
   4742     if (val == NULL)
   4743         return(NULL);
   4744     ret = xmlDictLookup(ctxt->dict, val, -1);
   4745     xmlFree(val);
   4746     return(ret);
   4747 }
   4748 
   4749 /************************************************************************
   4750  *									*
   4751  *			Parsing functions				*
   4752  *									*
   4753  ************************************************************************/
   4754 
   4755 #define WXS_FIND_GLOBAL_ITEM(slot)			\
   4756     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
   4757 	ret = xmlHashLookup(schema->slot, name); \
   4758 	if (ret != NULL) goto exit; \
   4759     } \
   4760     if (xmlHashSize(schema->schemasImports) > 1) { \
   4761 	xmlSchemaImportPtr import; \
   4762 	if (nsName == NULL) \
   4763 	    import = xmlHashLookup(schema->schemasImports, \
   4764 		XML_SCHEMAS_NO_NAMESPACE); \
   4765 	else \
   4766 	    import = xmlHashLookup(schema->schemasImports, nsName); \
   4767 	if (import == NULL) \
   4768 	    goto exit; \
   4769 	ret = xmlHashLookup(import->schema->slot, name); \
   4770     }
   4771 
   4772 /**
   4773  * xmlSchemaGetElem:
   4774  * @schema:  the schema context
   4775  * @name:  the element name
   4776  * @ns:  the element namespace
   4777  *
   4778  * Lookup a global element declaration in the schema.
   4779  *
   4780  * Returns the element declaration or NULL if not found.
   4781  */
   4782 static xmlSchemaElementPtr
   4783 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
   4784                  const xmlChar * nsName)
   4785 {
   4786     xmlSchemaElementPtr ret = NULL;
   4787 
   4788     if ((name == NULL) || (schema == NULL))
   4789         return(NULL);
   4790     if (schema != NULL) {
   4791 	WXS_FIND_GLOBAL_ITEM(elemDecl)
   4792     }
   4793 exit:
   4794 #ifdef DEBUG
   4795     if (ret == NULL) {
   4796         if (nsName == NULL)
   4797             fprintf(stderr, "Unable to lookup element decl. %s", name);
   4798         else
   4799             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
   4800                     nsName);
   4801     }
   4802 #endif
   4803     return (ret);
   4804 }
   4805 
   4806 /**
   4807  * xmlSchemaGetType:
   4808  * @schema:  the main schema
   4809  * @name:  the type's name
   4810  * nsName:  the type's namespace
   4811  *
   4812  * Lookup a type in the schemas or the predefined types
   4813  *
   4814  * Returns the group definition or NULL if not found.
   4815  */
   4816 static xmlSchemaTypePtr
   4817 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
   4818                  const xmlChar * nsName)
   4819 {
   4820     xmlSchemaTypePtr ret = NULL;
   4821 
   4822     if (name == NULL)
   4823         return (NULL);
   4824     /* First try the built-in types. */
   4825     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
   4826 	ret = xmlSchemaGetPredefinedType(name, nsName);
   4827 	if (ret != NULL)
   4828 	    goto exit;
   4829 	/*
   4830 	* Note that we try the parsed schemas as well here
   4831 	* since one might have parsed the S4S, which contain more
   4832 	* than the built-in types.
   4833 	* TODO: Can we optimize this?
   4834 	*/
   4835     }
   4836     if (schema != NULL) {
   4837 	WXS_FIND_GLOBAL_ITEM(typeDecl)
   4838     }
   4839 exit:
   4840 
   4841 #ifdef DEBUG
   4842     if (ret == NULL) {
   4843         if (nsName == NULL)
   4844             fprintf(stderr, "Unable to lookup type %s", name);
   4845         else
   4846             fprintf(stderr, "Unable to lookup type %s:%s", name,
   4847                     nsName);
   4848     }
   4849 #endif
   4850     return (ret);
   4851 }
   4852 
   4853 /**
   4854  * xmlSchemaGetAttributeDecl:
   4855  * @schema:  the context of the schema
   4856  * @name:  the name of the attribute
   4857  * @ns:  the target namespace of the attribute
   4858  *
   4859  * Lookup a an attribute in the schema or imported schemas
   4860  *
   4861  * Returns the attribute declaration or NULL if not found.
   4862  */
   4863 static xmlSchemaAttributePtr
   4864 xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
   4865                  const xmlChar * nsName)
   4866 {
   4867     xmlSchemaAttributePtr ret = NULL;
   4868 
   4869     if ((name == NULL) || (schema == NULL))
   4870         return (NULL);
   4871     if (schema != NULL) {
   4872 	WXS_FIND_GLOBAL_ITEM(attrDecl)
   4873     }
   4874 exit:
   4875 #ifdef DEBUG
   4876     if (ret == NULL) {
   4877         if (nsName == NULL)
   4878             fprintf(stderr, "Unable to lookup attribute %s", name);
   4879         else
   4880             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
   4881                     nsName);
   4882     }
   4883 #endif
   4884     return (ret);
   4885 }
   4886 
   4887 /**
   4888  * xmlSchemaGetAttributeGroup:
   4889  * @schema:  the context of the schema
   4890  * @name:  the name of the attribute group
   4891  * @ns:  the target namespace of the attribute group
   4892  *
   4893  * Lookup a an attribute group in the schema or imported schemas
   4894  *
   4895  * Returns the attribute group definition or NULL if not found.
   4896  */
   4897 static xmlSchemaAttributeGroupPtr
   4898 xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
   4899                  const xmlChar * nsName)
   4900 {
   4901     xmlSchemaAttributeGroupPtr ret = NULL;
   4902 
   4903     if ((name == NULL) || (schema == NULL))
   4904         return (NULL);
   4905     if (schema != NULL) {
   4906 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
   4907     }
   4908 exit:
   4909     /* TODO:
   4910     if ((ret != NULL) && (ret->redef != NULL)) {
   4911 	* Return the last redefinition. *
   4912 	ret = ret->redef;
   4913     }
   4914     */
   4915 #ifdef DEBUG
   4916     if (ret == NULL) {
   4917         if (nsName == NULL)
   4918             fprintf(stderr, "Unable to lookup attribute group %s", name);
   4919         else
   4920             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
   4921                     nsName);
   4922     }
   4923 #endif
   4924     return (ret);
   4925 }
   4926 
   4927 /**
   4928  * xmlSchemaGetGroup:
   4929  * @schema:  the context of the schema
   4930  * @name:  the name of the group
   4931  * @ns:  the target namespace of the group
   4932  *
   4933  * Lookup a group in the schema or imported schemas
   4934  *
   4935  * Returns the group definition or NULL if not found.
   4936  */
   4937 static xmlSchemaModelGroupDefPtr
   4938 xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
   4939                  const xmlChar * nsName)
   4940 {
   4941     xmlSchemaModelGroupDefPtr ret = NULL;
   4942 
   4943     if ((name == NULL) || (schema == NULL))
   4944         return (NULL);
   4945     if (schema != NULL) {
   4946 	WXS_FIND_GLOBAL_ITEM(groupDecl)
   4947     }
   4948 exit:
   4949 
   4950 #ifdef DEBUG
   4951     if (ret == NULL) {
   4952         if (nsName == NULL)
   4953             fprintf(stderr, "Unable to lookup group %s", name);
   4954         else
   4955             fprintf(stderr, "Unable to lookup group %s:%s", name,
   4956                     nsName);
   4957     }
   4958 #endif
   4959     return (ret);
   4960 }
   4961 
   4962 static xmlSchemaNotationPtr
   4963 xmlSchemaGetNotation(xmlSchemaPtr schema,
   4964 		     const xmlChar *name,
   4965 		     const xmlChar *nsName)
   4966 {
   4967     xmlSchemaNotationPtr ret = NULL;
   4968 
   4969     if ((name == NULL) || (schema == NULL))
   4970         return (NULL);
   4971     if (schema != NULL) {
   4972 	WXS_FIND_GLOBAL_ITEM(notaDecl)
   4973     }
   4974 exit:
   4975     return (ret);
   4976 }
   4977 
   4978 static xmlSchemaIDCPtr
   4979 xmlSchemaGetIDC(xmlSchemaPtr schema,
   4980 		const xmlChar *name,
   4981 		const xmlChar *nsName)
   4982 {
   4983     xmlSchemaIDCPtr ret = NULL;
   4984 
   4985     if ((name == NULL) || (schema == NULL))
   4986         return (NULL);
   4987     if (schema != NULL) {
   4988 	WXS_FIND_GLOBAL_ITEM(idcDef)
   4989     }
   4990 exit:
   4991     return (ret);
   4992 }
   4993 
   4994 /**
   4995  * xmlSchemaGetNamedComponent:
   4996  * @schema:  the schema
   4997  * @name:  the name of the group
   4998  * @ns:  the target namespace of the group
   4999  *
   5000  * Lookup a group in the schema or imported schemas
   5001  *
   5002  * Returns the group definition or NULL if not found.
   5003  */
   5004 static xmlSchemaBasicItemPtr
   5005 xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
   5006 			   xmlSchemaTypeType itemType,
   5007 			   const xmlChar *name,
   5008 			   const xmlChar *targetNs)
   5009 {
   5010     switch (itemType) {
   5011 	case XML_SCHEMA_TYPE_GROUP:
   5012 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
   5013 		name, targetNs));
   5014 	case XML_SCHEMA_TYPE_ELEMENT:
   5015 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
   5016 		name, targetNs));
   5017 	default:
   5018 	    TODO
   5019 	    return (NULL);
   5020     }
   5021 }
   5022 
   5023 /************************************************************************
   5024  *									*
   5025  *			Parsing functions				*
   5026  *									*
   5027  ************************************************************************/
   5028 
   5029 #define IS_BLANK_NODE(n)						\
   5030     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
   5031 
   5032 /**
   5033  * xmlSchemaIsBlank:
   5034  * @str:  a string
   5035  * @len: the length of the string or -1
   5036  *
   5037  * Check if a string is ignorable
   5038  *
   5039  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
   5040  */
   5041 static int
   5042 xmlSchemaIsBlank(xmlChar * str, int len)
   5043 {
   5044     if (str == NULL)
   5045         return (1);
   5046     if (len < 0) {
   5047 	while (*str != 0) {
   5048 	    if (!(IS_BLANK_CH(*str)))
   5049 		return (0);
   5050 	    str++;
   5051 	}
   5052     } else while ((*str != 0) && (len != 0)) {
   5053 	if (!(IS_BLANK_CH(*str)))
   5054 	    return (0);
   5055 	str++;
   5056 	len--;
   5057     }
   5058 
   5059     return (1);
   5060 }
   5061 
   5062 #define WXS_COMP_NAME(c, t) ((t) (c))->name
   5063 #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
   5064 /*
   5065 * xmlSchemaFindRedefCompInGraph:
   5066 * ATTENTION TODO: This uses pointer comp. for strings.
   5067 */
   5068 static xmlSchemaBasicItemPtr
   5069 xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
   5070 			      xmlSchemaTypeType type,
   5071 			      const xmlChar *name,
   5072 			      const xmlChar *nsName)
   5073 {
   5074     xmlSchemaBasicItemPtr ret;
   5075     int i;
   5076 
   5077     if ((bucket == NULL) || (name == NULL))
   5078 	return(NULL);
   5079     if ((bucket->globals == NULL) ||
   5080 	(bucket->globals->nbItems == 0))
   5081 	goto subschemas;
   5082     /*
   5083     * Search in global components.
   5084     */
   5085     for (i = 0; i < bucket->globals->nbItems; i++) {
   5086 	ret = bucket->globals->items[i];
   5087 	if (ret->type == type) {
   5088 	    switch (type) {
   5089 		case XML_SCHEMA_TYPE_COMPLEX:
   5090 		case XML_SCHEMA_TYPE_SIMPLE:
   5091 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
   5092 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
   5093 			nsName))
   5094 		    {
   5095 			return(ret);
   5096 		    }
   5097 		    break;
   5098 		case XML_SCHEMA_TYPE_GROUP:
   5099 		    if ((WXS_COMP_NAME(ret,
   5100 			    xmlSchemaModelGroupDefPtr) == name) &&
   5101 			(WXS_COMP_TNS(ret,
   5102 			    xmlSchemaModelGroupDefPtr) == nsName))
   5103 		    {
   5104 			return(ret);
   5105 		    }
   5106 		    break;
   5107 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   5108 		    if ((WXS_COMP_NAME(ret,
   5109 			    xmlSchemaAttributeGroupPtr) == name) &&
   5110 			(WXS_COMP_TNS(ret,
   5111 			    xmlSchemaAttributeGroupPtr) == nsName))
   5112 		    {
   5113 			return(ret);
   5114 		    }
   5115 		    break;
   5116 		default:
   5117 		    /* Should not be hit. */
   5118 		    return(NULL);
   5119 	    }
   5120 	}
   5121     }
   5122 subschemas:
   5123     /*
   5124     * Process imported/included schemas.
   5125     */
   5126     if (bucket->relations != NULL) {
   5127 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   5128 
   5129 	/*
   5130 	* TODO: Marking the bucket will not avoid multiple searches
   5131 	* in the same schema, but avoids at least circularity.
   5132 	*/
   5133 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
   5134 	do {
   5135 	    if ((rel->bucket != NULL) &&
   5136 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
   5137 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
   5138 		    type, name, nsName);
   5139 		if (ret != NULL)
   5140 		    return(ret);
   5141 	    }
   5142 	    rel = rel->next;
   5143 	} while (rel != NULL);
   5144 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
   5145     }
   5146     return(NULL);
   5147 }
   5148 
   5149 /**
   5150  * xmlSchemaAddNotation:
   5151  * @ctxt:  a schema parser context
   5152  * @schema:  the schema being built
   5153  * @name:  the item name
   5154  *
   5155  * Add an XML schema annotation declaration
   5156  * *WARNING* this interface is highly subject to change
   5157  *
   5158  * Returns the new struture or NULL in case of error
   5159  */
   5160 static xmlSchemaNotationPtr
   5161 xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5162                      const xmlChar *name, const xmlChar *nsName,
   5163 		     xmlNodePtr node ATTRIBUTE_UNUSED)
   5164 {
   5165     xmlSchemaNotationPtr ret = NULL;
   5166 
   5167     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5168         return (NULL);
   5169 
   5170     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
   5171     if (ret == NULL) {
   5172         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
   5173         return (NULL);
   5174     }
   5175     memset(ret, 0, sizeof(xmlSchemaNotation));
   5176     ret->type = XML_SCHEMA_TYPE_NOTATION;
   5177     ret->name = name;
   5178     ret->targetNamespace = nsName;
   5179     /* TODO: do we need the node to be set?
   5180     * ret->node = node;*/
   5181     WXS_ADD_GLOBAL(ctxt, ret);
   5182     return (ret);
   5183 }
   5184 
   5185 /**
   5186  * xmlSchemaAddAttribute:
   5187  * @ctxt:  a schema parser context
   5188  * @schema:  the schema being built
   5189  * @name:  the item name
   5190  * @namespace:  the namespace
   5191  *
   5192  * Add an XML schema Attrribute declaration
   5193  * *WARNING* this interface is highly subject to change
   5194  *
   5195  * Returns the new struture or NULL in case of error
   5196  */
   5197 static xmlSchemaAttributePtr
   5198 xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5199                       const xmlChar * name, const xmlChar * nsName,
   5200 		      xmlNodePtr node, int topLevel)
   5201 {
   5202     xmlSchemaAttributePtr ret = NULL;
   5203 
   5204     if ((ctxt == NULL) || (schema == NULL))
   5205         return (NULL);
   5206 
   5207     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
   5208     if (ret == NULL) {
   5209         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
   5210         return (NULL);
   5211     }
   5212     memset(ret, 0, sizeof(xmlSchemaAttribute));
   5213     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
   5214     ret->node = node;
   5215     ret->name = name;
   5216     ret->targetNamespace = nsName;
   5217 
   5218     if (topLevel)
   5219 	WXS_ADD_GLOBAL(ctxt, ret);
   5220     else
   5221 	WXS_ADD_LOCAL(ctxt, ret);
   5222     WXS_ADD_PENDING(ctxt, ret);
   5223     return (ret);
   5224 }
   5225 
   5226 /**
   5227  * xmlSchemaAddAttributeUse:
   5228  * @ctxt:  a schema parser context
   5229  * @schema:  the schema being built
   5230  * @name:  the item name
   5231  * @namespace:  the namespace
   5232  *
   5233  * Add an XML schema Attrribute declaration
   5234  * *WARNING* this interface is highly subject to change
   5235  *
   5236  * Returns the new struture or NULL in case of error
   5237  */
   5238 static xmlSchemaAttributeUsePtr
   5239 xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
   5240 			 xmlNodePtr node)
   5241 {
   5242     xmlSchemaAttributeUsePtr ret = NULL;
   5243 
   5244     if (pctxt == NULL)
   5245         return (NULL);
   5246 
   5247     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
   5248     if (ret == NULL) {
   5249         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
   5250         return (NULL);
   5251     }
   5252     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
   5253     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
   5254     ret->node = node;
   5255 
   5256     WXS_ADD_LOCAL(pctxt, ret);
   5257     return (ret);
   5258 }
   5259 
   5260 /*
   5261 * xmlSchemaAddRedef:
   5262 *
   5263 * Adds a redefinition information. This is used at a later stage to:
   5264 * resolve references to the redefined components and to check constraints.
   5265 */
   5266 static xmlSchemaRedefPtr
   5267 xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
   5268 		  xmlSchemaBucketPtr targetBucket,
   5269 		  void *item,
   5270 		  const xmlChar *refName,
   5271 		  const xmlChar *refTargetNs)
   5272 {
   5273     xmlSchemaRedefPtr ret;
   5274 
   5275     ret = (xmlSchemaRedefPtr)
   5276 	xmlMalloc(sizeof(xmlSchemaRedef));
   5277     if (ret == NULL) {
   5278 	xmlSchemaPErrMemory(pctxt,
   5279 	    "allocating redefinition info", NULL);
   5280 	return (NULL);
   5281     }
   5282     memset(ret, 0, sizeof(xmlSchemaRedef));
   5283     ret->item = item;
   5284     ret->targetBucket = targetBucket;
   5285     ret->refName = refName;
   5286     ret->refTargetNs = refTargetNs;
   5287     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
   5288 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
   5289     else
   5290 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
   5291     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
   5292 
   5293     return (ret);
   5294 }
   5295 
   5296 /**
   5297  * xmlSchemaAddAttributeGroupDefinition:
   5298  * @ctxt:  a schema parser context
   5299  * @schema:  the schema being built
   5300  * @name:  the item name
   5301  * @nsName:  the target namespace
   5302  * @node: the corresponding node
   5303  *
   5304  * Add an XML schema Attrribute Group definition.
   5305  *
   5306  * Returns the new struture or NULL in case of error
   5307  */
   5308 static xmlSchemaAttributeGroupPtr
   5309 xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   5310                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   5311 			   const xmlChar *name,
   5312 			   const xmlChar *nsName,
   5313 			   xmlNodePtr node)
   5314 {
   5315     xmlSchemaAttributeGroupPtr ret = NULL;
   5316 
   5317     if ((pctxt == NULL) || (name == NULL))
   5318         return (NULL);
   5319 
   5320     ret = (xmlSchemaAttributeGroupPtr)
   5321         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
   5322     if (ret == NULL) {
   5323 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
   5324 	return (NULL);
   5325     }
   5326     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
   5327     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
   5328     ret->name = name;
   5329     ret->targetNamespace = nsName;
   5330     ret->node = node;
   5331 
   5332     /* TODO: Remove the flag. */
   5333     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
   5334     if (pctxt->isRedefine) {
   5335 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
   5336 	    ret, name, nsName);
   5337 	if (pctxt->redef == NULL) {
   5338 	    xmlFree(ret);
   5339 	    return(NULL);
   5340 	}
   5341 	pctxt->redefCounter = 0;
   5342     }
   5343     WXS_ADD_GLOBAL(pctxt, ret);
   5344     WXS_ADD_PENDING(pctxt, ret);
   5345     return (ret);
   5346 }
   5347 
   5348 /**
   5349  * xmlSchemaAddElement:
   5350  * @ctxt:  a schema parser context
   5351  * @schema:  the schema being built
   5352  * @name:  the type name
   5353  * @namespace:  the type namespace
   5354  *
   5355  * Add an XML schema Element declaration
   5356  * *WARNING* this interface is highly subject to change
   5357  *
   5358  * Returns the new struture or NULL in case of error
   5359  */
   5360 static xmlSchemaElementPtr
   5361 xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
   5362                     const xmlChar * name, const xmlChar * nsName,
   5363 		    xmlNodePtr node, int topLevel)
   5364 {
   5365     xmlSchemaElementPtr ret = NULL;
   5366 
   5367     if ((ctxt == NULL) || (name == NULL))
   5368         return (NULL);
   5369 
   5370     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
   5371     if (ret == NULL) {
   5372         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
   5373         return (NULL);
   5374     }
   5375     memset(ret, 0, sizeof(xmlSchemaElement));
   5376     ret->type = XML_SCHEMA_TYPE_ELEMENT;
   5377     ret->name = name;
   5378     ret->targetNamespace = nsName;
   5379     ret->node = node;
   5380 
   5381     if (topLevel)
   5382 	WXS_ADD_GLOBAL(ctxt, ret);
   5383     else
   5384 	WXS_ADD_LOCAL(ctxt, ret);
   5385     WXS_ADD_PENDING(ctxt, ret);
   5386     return (ret);
   5387 }
   5388 
   5389 /**
   5390  * xmlSchemaAddType:
   5391  * @ctxt:  a schema parser context
   5392  * @schema:  the schema being built
   5393  * @name:  the item name
   5394  * @namespace:  the namespace
   5395  *
   5396  * Add an XML schema item
   5397  * *WARNING* this interface is highly subject to change
   5398  *
   5399  * Returns the new struture or NULL in case of error
   5400  */
   5401 static xmlSchemaTypePtr
   5402 xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5403 		 xmlSchemaTypeType type,
   5404                  const xmlChar * name, const xmlChar * nsName,
   5405 		 xmlNodePtr node, int topLevel)
   5406 {
   5407     xmlSchemaTypePtr ret = NULL;
   5408 
   5409     if ((ctxt == NULL) || (schema == NULL))
   5410         return (NULL);
   5411 
   5412     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
   5413     if (ret == NULL) {
   5414         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
   5415         return (NULL);
   5416     }
   5417     memset(ret, 0, sizeof(xmlSchemaType));
   5418     ret->type = type;
   5419     ret->name = name;
   5420     ret->targetNamespace = nsName;
   5421     ret->node = node;
   5422     if (topLevel) {
   5423 	if (ctxt->isRedefine) {
   5424 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5425 		ret, name, nsName);
   5426 	    if (ctxt->redef == NULL) {
   5427 		xmlFree(ret);
   5428 		return(NULL);
   5429 	    }
   5430 	    ctxt->redefCounter = 0;
   5431 	}
   5432 	WXS_ADD_GLOBAL(ctxt, ret);
   5433     } else
   5434 	WXS_ADD_LOCAL(ctxt, ret);
   5435     WXS_ADD_PENDING(ctxt, ret);
   5436     return (ret);
   5437 }
   5438 
   5439 static xmlSchemaQNameRefPtr
   5440 xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
   5441 		     xmlSchemaTypeType refType,
   5442 		     const xmlChar *refName,
   5443 		     const xmlChar *refNs)
   5444 {
   5445     xmlSchemaQNameRefPtr ret;
   5446 
   5447     ret = (xmlSchemaQNameRefPtr)
   5448 	xmlMalloc(sizeof(xmlSchemaQNameRef));
   5449     if (ret == NULL) {
   5450 	xmlSchemaPErrMemory(pctxt,
   5451 	    "allocating QName reference item", NULL);
   5452 	return (NULL);
   5453     }
   5454     ret->node = NULL;
   5455     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
   5456     ret->name = refName;
   5457     ret->targetNamespace = refNs;
   5458     ret->item = NULL;
   5459     ret->itemType = refType;
   5460     /*
   5461     * Store the reference item in the schema.
   5462     */
   5463     WXS_ADD_LOCAL(pctxt, ret);
   5464     return (ret);
   5465 }
   5466 
   5467 static xmlSchemaAttributeUseProhibPtr
   5468 xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
   5469 {
   5470     xmlSchemaAttributeUseProhibPtr ret;
   5471 
   5472     ret = (xmlSchemaAttributeUseProhibPtr)
   5473 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
   5474     if (ret == NULL) {
   5475 	xmlSchemaPErrMemory(pctxt,
   5476 	    "allocating attribute use prohibition", NULL);
   5477 	return (NULL);
   5478     }
   5479     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
   5480     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
   5481     WXS_ADD_LOCAL(pctxt, ret);
   5482     return (ret);
   5483 }
   5484 
   5485 
   5486 /**
   5487  * xmlSchemaAddModelGroup:
   5488  * @ctxt:  a schema parser context
   5489  * @schema:  the schema being built
   5490  * @type: the "compositor" type of the model group
   5491  * @node: the node in the schema doc
   5492  *
   5493  * Adds a schema model group
   5494  * *WARNING* this interface is highly subject to change
   5495  *
   5496  * Returns the new struture or NULL in case of error
   5497  */
   5498 static xmlSchemaModelGroupPtr
   5499 xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
   5500 		       xmlSchemaPtr schema,
   5501 		       xmlSchemaTypeType type,
   5502 		       xmlNodePtr node)
   5503 {
   5504     xmlSchemaModelGroupPtr ret = NULL;
   5505 
   5506     if ((ctxt == NULL) || (schema == NULL))
   5507         return (NULL);
   5508 
   5509     ret = (xmlSchemaModelGroupPtr)
   5510 	xmlMalloc(sizeof(xmlSchemaModelGroup));
   5511     if (ret == NULL) {
   5512 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
   5513 	    NULL);
   5514 	return (NULL);
   5515     }
   5516     memset(ret, 0, sizeof(xmlSchemaModelGroup));
   5517     ret->type = type;
   5518     ret->node = node;
   5519     WXS_ADD_LOCAL(ctxt, ret);
   5520     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
   5521 	(type == XML_SCHEMA_TYPE_CHOICE))
   5522 	WXS_ADD_PENDING(ctxt, ret);
   5523     return (ret);
   5524 }
   5525 
   5526 
   5527 /**
   5528  * xmlSchemaAddParticle:
   5529  * @ctxt:  a schema parser context
   5530  * @schema:  the schema being built
   5531  * @node: the corresponding node in the schema doc
   5532  * @min: the minOccurs
   5533  * @max: the maxOccurs
   5534  *
   5535  * Adds an XML schema particle component.
   5536  * *WARNING* this interface is highly subject to change
   5537  *
   5538  * Returns the new struture or NULL in case of error
   5539  */
   5540 static xmlSchemaParticlePtr
   5541 xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
   5542 		     xmlNodePtr node, int min, int max)
   5543 {
   5544     xmlSchemaParticlePtr ret = NULL;
   5545     if (ctxt == NULL)
   5546         return (NULL);
   5547 
   5548 #ifdef DEBUG
   5549     fprintf(stderr, "Adding particle component\n");
   5550 #endif
   5551     ret = (xmlSchemaParticlePtr)
   5552 	xmlMalloc(sizeof(xmlSchemaParticle));
   5553     if (ret == NULL) {
   5554 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
   5555 	    NULL);
   5556 	return (NULL);
   5557     }
   5558     ret->type = XML_SCHEMA_TYPE_PARTICLE;
   5559     ret->annot = NULL;
   5560     ret->node = node;
   5561     ret->minOccurs = min;
   5562     ret->maxOccurs = max;
   5563     ret->next = NULL;
   5564     ret->children = NULL;
   5565 
   5566     WXS_ADD_LOCAL(ctxt, ret);
   5567     /*
   5568     * Note that addition to pending components will be done locally
   5569     * to the specific parsing function, since the most particles
   5570     * need not to be fixed up (i.e. the reference to be resolved).
   5571     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
   5572     */
   5573     return (ret);
   5574 }
   5575 
   5576 /**
   5577  * xmlSchemaAddModelGroupDefinition:
   5578  * @ctxt:  a schema validation context
   5579  * @schema:  the schema being built
   5580  * @name:  the group name
   5581  *
   5582  * Add an XML schema Group definition
   5583  *
   5584  * Returns the new struture or NULL in case of error
   5585  */
   5586 static xmlSchemaModelGroupDefPtr
   5587 xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   5588 				 xmlSchemaPtr schema,
   5589 				 const xmlChar *name,
   5590 				 const xmlChar *nsName,
   5591 				 xmlNodePtr node)
   5592 {
   5593     xmlSchemaModelGroupDefPtr ret = NULL;
   5594 
   5595     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5596         return (NULL);
   5597 
   5598     ret = (xmlSchemaModelGroupDefPtr)
   5599 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
   5600     if (ret == NULL) {
   5601         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
   5602         return (NULL);
   5603     }
   5604     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
   5605     ret->name = name;
   5606     ret->type = XML_SCHEMA_TYPE_GROUP;
   5607     ret->node = node;
   5608     ret->targetNamespace = nsName;
   5609 
   5610     if (ctxt->isRedefine) {
   5611 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
   5612 	    ret, name, nsName);
   5613 	if (ctxt->redef == NULL) {
   5614 	    xmlFree(ret);
   5615 	    return(NULL);
   5616 	}
   5617 	ctxt->redefCounter = 0;
   5618     }
   5619     WXS_ADD_GLOBAL(ctxt, ret);
   5620     WXS_ADD_PENDING(ctxt, ret);
   5621     return (ret);
   5622 }
   5623 
   5624 /**
   5625  * xmlSchemaNewWildcardNs:
   5626  * @ctxt:  a schema validation context
   5627  *
   5628  * Creates a new wildcard namespace constraint.
   5629  *
   5630  * Returns the new struture or NULL in case of error
   5631  */
   5632 static xmlSchemaWildcardNsPtr
   5633 xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
   5634 {
   5635     xmlSchemaWildcardNsPtr ret;
   5636 
   5637     ret = (xmlSchemaWildcardNsPtr)
   5638 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
   5639     if (ret == NULL) {
   5640 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
   5641 	return (NULL);
   5642     }
   5643     ret->value = NULL;
   5644     ret->next = NULL;
   5645     return (ret);
   5646 }
   5647 
   5648 static xmlSchemaIDCPtr
   5649 xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5650                   const xmlChar *name, const xmlChar *nsName,
   5651 		  int category, xmlNodePtr node)
   5652 {
   5653     xmlSchemaIDCPtr ret = NULL;
   5654 
   5655     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
   5656         return (NULL);
   5657 
   5658     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
   5659     if (ret == NULL) {
   5660         xmlSchemaPErrMemory(ctxt,
   5661 	    "allocating an identity-constraint definition", NULL);
   5662         return (NULL);
   5663     }
   5664     memset(ret, 0, sizeof(xmlSchemaIDC));
   5665     /* The target namespace of the parent element declaration. */
   5666     ret->targetNamespace = nsName;
   5667     ret->name = name;
   5668     ret->type = category;
   5669     ret->node = node;
   5670 
   5671     WXS_ADD_GLOBAL(ctxt, ret);
   5672     /*
   5673     * Only keyrefs need to be fixup up.
   5674     */
   5675     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
   5676 	WXS_ADD_PENDING(ctxt, ret);
   5677     return (ret);
   5678 }
   5679 
   5680 /**
   5681  * xmlSchemaAddWildcard:
   5682  * @ctxt:  a schema validation context
   5683  * @schema: a schema
   5684  *
   5685  * Adds a wildcard.
   5686  * It corresponds to a xsd:anyAttribute and xsd:any.
   5687  *
   5688  * Returns the new struture or NULL in case of error
   5689  */
   5690 static xmlSchemaWildcardPtr
   5691 xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   5692 		     xmlSchemaTypeType type, xmlNodePtr node)
   5693 {
   5694     xmlSchemaWildcardPtr ret = NULL;
   5695 
   5696     if ((ctxt == NULL) || (schema == NULL))
   5697         return (NULL);
   5698 
   5699     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
   5700     if (ret == NULL) {
   5701         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
   5702         return (NULL);
   5703     }
   5704     memset(ret, 0, sizeof(xmlSchemaWildcard));
   5705     ret->type = type;
   5706     ret->node = node;
   5707     WXS_ADD_LOCAL(ctxt, ret);
   5708     return (ret);
   5709 }
   5710 
   5711 static void
   5712 xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
   5713 {
   5714     if (group == NULL)
   5715 	return;
   5716     if (group->members != NULL)
   5717 	xmlSchemaItemListFree(group->members);
   5718     xmlFree(group);
   5719 }
   5720 
   5721 static void
   5722 xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
   5723 {
   5724     xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
   5725 }
   5726 
   5727 static xmlSchemaSubstGroupPtr
   5728 xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
   5729 		       xmlSchemaElementPtr head)
   5730 {
   5731     xmlSchemaSubstGroupPtr ret;
   5732 
   5733     /* Init subst group hash. */
   5734     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
   5735 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
   5736 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5737 	    return(NULL);
   5738     }
   5739     /* Create a new substitution group. */
   5740     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
   5741     if (ret == NULL) {
   5742 	xmlSchemaPErrMemory(NULL,
   5743 	    "allocating a substitution group container", NULL);
   5744 	return(NULL);
   5745     }
   5746     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
   5747     ret->head = head;
   5748     /* Create list of members. */
   5749     ret->members = xmlSchemaItemListCreate();
   5750     if (ret->members == NULL) {
   5751 	xmlSchemaSubstGroupFree(ret);
   5752 	return(NULL);
   5753     }
   5754     /* Add subst group to hash. */
   5755     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
   5756 	head->name, head->targetNamespace, ret) != 0) {
   5757 	PERROR_INT("xmlSchemaSubstGroupAdd",
   5758 	    "failed to add a new substitution container");
   5759 	xmlSchemaSubstGroupFree(ret);
   5760 	return(NULL);
   5761     }
   5762     return(ret);
   5763 }
   5764 
   5765 static xmlSchemaSubstGroupPtr
   5766 xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
   5767 		       xmlSchemaElementPtr head)
   5768 {
   5769     if (WXS_SUBST_GROUPS(pctxt) == NULL)
   5770 	return(NULL);
   5771     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
   5772 	head->name, head->targetNamespace));
   5773 
   5774 }
   5775 
   5776 /**
   5777  * xmlSchemaAddElementSubstitutionMember:
   5778  * @pctxt:  a schema parser context
   5779  * @head:  the head of the substitution group
   5780  * @member: the new member of the substitution group
   5781  *
   5782  * Allocate a new annotation structure.
   5783  *
   5784  * Returns the newly allocated structure or NULL in case or error
   5785  */
   5786 static int
   5787 xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
   5788 				      xmlSchemaElementPtr head,
   5789 				      xmlSchemaElementPtr member)
   5790 {
   5791     xmlSchemaSubstGroupPtr substGroup = NULL;
   5792 
   5793     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
   5794 	return (-1);
   5795 
   5796     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
   5797     if (substGroup == NULL)
   5798 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
   5799     if (substGroup == NULL)
   5800 	return(-1);
   5801     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
   5802 	return(-1);
   5803     return(0);
   5804 }
   5805 
   5806 /************************************************************************
   5807  *									*
   5808  *		Utilities for parsing					*
   5809  *									*
   5810  ************************************************************************/
   5811 
   5812 /**
   5813  * xmlSchemaPValAttrNodeQNameValue:
   5814  * @ctxt:  a schema parser context
   5815  * @schema: the schema context
   5816  * @ownerDes: the designation of the parent element
   5817  * @ownerItem: the parent as a schema object
   5818  * @value:  the QName value
   5819  * @local: the resulting local part if found, the attribute value otherwise
   5820  * @uri:  the resulting namespace URI if found
   5821  *
   5822  * Extracts the local name and the URI of a QName value and validates it.
   5823  * This one is intended to be used on attribute values that
   5824  * should resolve to schema components.
   5825  *
   5826  * Returns 0, in case the QName is valid, a positive error code
   5827  * if not valid and -1 if an internal error occurs.
   5828  */
   5829 static int
   5830 xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
   5831 				       xmlSchemaPtr schema,
   5832 				       xmlSchemaBasicItemPtr ownerItem,
   5833 				       xmlAttrPtr attr,
   5834 				       const xmlChar *value,
   5835 				       const xmlChar **uri,
   5836 				       const xmlChar **local)
   5837 {
   5838     const xmlChar *pref;
   5839     xmlNsPtr ns;
   5840     int len, ret;
   5841 
   5842     *uri = NULL;
   5843     *local = NULL;
   5844     ret = xmlValidateQName(value, 1);
   5845     if (ret > 0) {
   5846 	xmlSchemaPSimpleTypeErr(ctxt,
   5847 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5848 	    ownerItem, (xmlNodePtr) attr,
   5849 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   5850 	    NULL, value, NULL, NULL, NULL);
   5851 	*local = value;
   5852 	return (ctxt->err);
   5853     } else if (ret < 0)
   5854 	return (-1);
   5855 
   5856     if (!strchr((char *) value, ':')) {
   5857 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
   5858 	if (ns)
   5859 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5860 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
   5861 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
   5862 	    * parser context. */
   5863 	    /*
   5864 	    * This one takes care of included schemas with no
   5865 	    * target namespace.
   5866 	    */
   5867 	    *uri = ctxt->targetNamespace;
   5868 	}
   5869 	*local = xmlDictLookup(ctxt->dict, value, -1);
   5870 	return (0);
   5871     }
   5872     /*
   5873     * At this point xmlSplitQName3 has to return a local name.
   5874     */
   5875     *local = xmlSplitQName3(value, &len);
   5876     *local = xmlDictLookup(ctxt->dict, *local, -1);
   5877     pref = xmlDictLookup(ctxt->dict, value, len);
   5878     ns = xmlSearchNs(attr->doc, attr->parent, pref);
   5879     if (ns == NULL) {
   5880 	xmlSchemaPSimpleTypeErr(ctxt,
   5881 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   5882 	    ownerItem, (xmlNodePtr) attr,
   5883 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
   5884 	    "The value '%s' of simple type 'xs:QName' has no "
   5885 	    "corresponding namespace declaration in scope", value, NULL);
   5886 	return (ctxt->err);
   5887     } else {
   5888         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
   5889     }
   5890     return (0);
   5891 }
   5892 
   5893 /**
   5894  * xmlSchemaPValAttrNodeQName:
   5895  * @ctxt:  a schema parser context
   5896  * @schema: the schema context
   5897  * @ownerDes: the designation of the owner element
   5898  * @ownerItem: the owner as a schema object
   5899  * @attr:  the attribute node
   5900  * @local: the resulting local part if found, the attribute value otherwise
   5901  * @uri:  the resulting namespace URI if found
   5902  *
   5903  * Extracts and validates the QName of an attribute value.
   5904  * This one is intended to be used on attribute values that
   5905  * should resolve to schema components.
   5906  *
   5907  * Returns 0, in case the QName is valid, a positive error code
   5908  * if not valid and -1 if an internal error occurs.
   5909  */
   5910 static int
   5911 xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
   5912 				       xmlSchemaPtr schema,
   5913 				       xmlSchemaBasicItemPtr ownerItem,
   5914 				       xmlAttrPtr attr,
   5915 				       const xmlChar **uri,
   5916 				       const xmlChar **local)
   5917 {
   5918     const xmlChar *value;
   5919 
   5920     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   5921     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   5922 	ownerItem, attr, value, uri, local));
   5923 }
   5924 
   5925 /**
   5926  * xmlSchemaPValAttrQName:
   5927  * @ctxt:  a schema parser context
   5928  * @schema: the schema context
   5929  * @ownerDes: the designation of the parent element
   5930  * @ownerItem: the owner as a schema object
   5931  * @ownerElem:  the parent node of the attribute
   5932  * @name:  the name of the attribute
   5933  * @local: the resulting local part if found, the attribute value otherwise
   5934  * @uri:  the resulting namespace URI if found
   5935  *
   5936  * Extracts and validates the QName of an attribute value.
   5937  *
   5938  * Returns 0, in case the QName is valid, a positive error code
   5939  * if not valid and -1 if an internal error occurs.
   5940  */
   5941 static int
   5942 xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
   5943 				   xmlSchemaPtr schema,
   5944 				   xmlSchemaBasicItemPtr ownerItem,
   5945 				   xmlNodePtr ownerElem,
   5946 				   const char *name,
   5947 				   const xmlChar **uri,
   5948 				   const xmlChar **local)
   5949 {
   5950     xmlAttrPtr attr;
   5951 
   5952     attr = xmlSchemaGetPropNode(ownerElem, name);
   5953     if (attr == NULL) {
   5954 	*local = NULL;
   5955 	*uri = NULL;
   5956 	return (0);
   5957     }
   5958     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
   5959 	ownerItem, attr, uri, local));
   5960 }
   5961 
   5962 /**
   5963  * xmlSchemaPValAttrID:
   5964  * @ctxt:  a schema parser context
   5965  * @schema: the schema context
   5966  * @ownerDes: the designation of the parent element
   5967  * @ownerItem: the owner as a schema object
   5968  * @ownerElem:  the parent node of the attribute
   5969  * @name:  the name of the attribute
   5970  *
   5971  * Extracts and validates the ID of an attribute value.
   5972  *
   5973  * Returns 0, in case the ID is valid, a positive error code
   5974  * if not valid and -1 if an internal error occurs.
   5975  */
   5976 static int
   5977 xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
   5978 {
   5979     int ret;
   5980     const xmlChar *value;
   5981 
   5982     if (attr == NULL)
   5983 	return(0);
   5984     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
   5985     ret = xmlValidateNCName(value, 1);
   5986     if (ret == 0) {
   5987 	/*
   5988 	* NOTE: the IDness might have already be declared in the DTD
   5989 	*/
   5990 	if (attr->atype != XML_ATTRIBUTE_ID) {
   5991 	    xmlIDPtr res;
   5992 	    xmlChar *strip;
   5993 
   5994 	    /*
   5995 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
   5996 	    * moment.
   5997 	    */
   5998 	    strip = xmlSchemaCollapseString(value);
   5999 	    if (strip != NULL) {
   6000 		xmlFree((xmlChar *) value);
   6001 		value = strip;
   6002 	    }
   6003 	    res = xmlAddID(NULL, attr->doc, value, attr);
   6004 	    if (res == NULL) {
   6005 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6006 		xmlSchemaPSimpleTypeErr(ctxt,
   6007 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6008 		    NULL, (xmlNodePtr) attr,
   6009 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   6010 		    NULL, NULL, "Duplicate value '%s' of simple "
   6011 		    "type 'xs:ID'", value, NULL);
   6012 	    } else
   6013 		attr->atype = XML_ATTRIBUTE_ID;
   6014 	}
   6015     } else if (ret > 0) {
   6016 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6017 	xmlSchemaPSimpleTypeErr(ctxt,
   6018 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6019 	    NULL, (xmlNodePtr) attr,
   6020 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
   6021 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
   6022 	    "not a valid 'xs:NCName'",
   6023 	    value, NULL);
   6024     }
   6025     if (value != NULL)
   6026 	xmlFree((xmlChar *)value);
   6027 
   6028     return (ret);
   6029 }
   6030 
   6031 static int
   6032 xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
   6033 		    xmlNodePtr ownerElem,
   6034 		    const xmlChar *name)
   6035 {
   6036     xmlAttrPtr attr;
   6037 
   6038     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
   6039     if (attr == NULL)
   6040 	return(0);
   6041     return(xmlSchemaPValAttrNodeID(ctxt, attr));
   6042 
   6043 }
   6044 
   6045 /**
   6046  * xmlGetMaxOccurs:
   6047  * @ctxt:  a schema validation context
   6048  * @node:  a subtree containing XML Schema informations
   6049  *
   6050  * Get the maxOccurs property
   6051  *
   6052  * Returns the default if not found, or the value
   6053  */
   6054 static int
   6055 xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6056 		int min, int max, int def, const char *expected)
   6057 {
   6058     const xmlChar *val, *cur;
   6059     int ret = 0;
   6060     xmlAttrPtr attr;
   6061 
   6062     attr = xmlSchemaGetPropNode(node, "maxOccurs");
   6063     if (attr == NULL)
   6064 	return (def);
   6065     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6066 
   6067     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
   6068 	if (max != UNBOUNDED) {
   6069 	    xmlSchemaPSimpleTypeErr(ctxt,
   6070 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6071 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
   6072 		NULL, (xmlNodePtr) attr, NULL, expected,
   6073 		val, NULL, NULL, NULL);
   6074 	    return (def);
   6075 	} else
   6076 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
   6077     }
   6078 
   6079     cur = val;
   6080     while (IS_BLANK_CH(*cur))
   6081         cur++;
   6082     if (*cur == 0) {
   6083         xmlSchemaPSimpleTypeErr(ctxt,
   6084 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6085 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6086 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6087 	    val, NULL, NULL, NULL);
   6088 	return (def);
   6089     }
   6090     while ((*cur >= '0') && (*cur <= '9')) {
   6091         ret = ret * 10 + (*cur - '0');
   6092         cur++;
   6093     }
   6094     while (IS_BLANK_CH(*cur))
   6095         cur++;
   6096     /*
   6097     * TODO: Restrict the maximal value to Integer.
   6098     */
   6099     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6100 	xmlSchemaPSimpleTypeErr(ctxt,
   6101 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6102 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6103 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6104 	    val, NULL, NULL, NULL);
   6105         return (def);
   6106     }
   6107     return (ret);
   6108 }
   6109 
   6110 /**
   6111  * xmlGetMinOccurs:
   6112  * @ctxt:  a schema validation context
   6113  * @node:  a subtree containing XML Schema informations
   6114  *
   6115  * Get the minOccurs property
   6116  *
   6117  * Returns the default if not found, or the value
   6118  */
   6119 static int
   6120 xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
   6121 		int min, int max, int def, const char *expected)
   6122 {
   6123     const xmlChar *val, *cur;
   6124     int ret = 0;
   6125     xmlAttrPtr attr;
   6126 
   6127     attr = xmlSchemaGetPropNode(node, "minOccurs");
   6128     if (attr == NULL)
   6129 	return (def);
   6130     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6131     cur = val;
   6132     while (IS_BLANK_CH(*cur))
   6133         cur++;
   6134     if (*cur == 0) {
   6135         xmlSchemaPSimpleTypeErr(ctxt,
   6136 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6137 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6138 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6139 	    val, NULL, NULL, NULL);
   6140         return (def);
   6141     }
   6142     while ((*cur >= '0') && (*cur <= '9')) {
   6143         ret = ret * 10 + (*cur - '0');
   6144         cur++;
   6145     }
   6146     while (IS_BLANK_CH(*cur))
   6147         cur++;
   6148     /*
   6149     * TODO: Restrict the maximal value to Integer.
   6150     */
   6151     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
   6152 	xmlSchemaPSimpleTypeErr(ctxt,
   6153 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6154 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
   6155 	    NULL, (xmlNodePtr) attr, NULL, expected,
   6156 	    val, NULL, NULL, NULL);
   6157         return (def);
   6158     }
   6159     return (ret);
   6160 }
   6161 
   6162 /**
   6163  * xmlSchemaPGetBoolNodeValue:
   6164  * @ctxt:  a schema validation context
   6165  * @ownerDes:  owner designation
   6166  * @ownerItem:  the owner as a schema item
   6167  * @node: the node holding the value
   6168  *
   6169  * Converts a boolean string value into 1 or 0.
   6170  *
   6171  * Returns 0 or 1.
   6172  */
   6173 static int
   6174 xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
   6175 			   xmlSchemaBasicItemPtr ownerItem,
   6176 			   xmlNodePtr node)
   6177 {
   6178     xmlChar *value = NULL;
   6179     int res = 0;
   6180 
   6181     value = xmlNodeGetContent(node);
   6182     /*
   6183     * 3.2.2.1 Lexical representation
   6184     * An instance of a datatype that is defined as `boolean`
   6185     * can have the following legal literals {true, false, 1, 0}.
   6186     */
   6187     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
   6188         res = 1;
   6189     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
   6190         res = 0;
   6191     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
   6192 	res = 1;
   6193     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
   6194         res = 0;
   6195     else {
   6196         xmlSchemaPSimpleTypeErr(ctxt,
   6197 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6198 	    ownerItem, node,
   6199 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6200 	    NULL, BAD_CAST value,
   6201 	    NULL, NULL, NULL);
   6202     }
   6203     if (value != NULL)
   6204 	xmlFree(value);
   6205     return (res);
   6206 }
   6207 
   6208 /**
   6209  * xmlGetBooleanProp:
   6210  * @ctxt:  a schema validation context
   6211  * @node:  a subtree containing XML Schema informations
   6212  * @name:  the attribute name
   6213  * @def:  the default value
   6214  *
   6215  * Evaluate if a boolean property is set
   6216  *
   6217  * Returns the default if not found, 0 if found to be false,
   6218  * 1 if found to be true
   6219  */
   6220 static int
   6221 xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
   6222 		  xmlNodePtr node,
   6223                   const char *name, int def)
   6224 {
   6225     const xmlChar *val;
   6226 
   6227     val = xmlSchemaGetProp(ctxt, node, name);
   6228     if (val == NULL)
   6229         return (def);
   6230     /*
   6231     * 3.2.2.1 Lexical representation
   6232     * An instance of a datatype that is defined as `boolean`
   6233     * can have the following legal literals {true, false, 1, 0}.
   6234     */
   6235     if (xmlStrEqual(val, BAD_CAST "true"))
   6236         def = 1;
   6237     else if (xmlStrEqual(val, BAD_CAST "false"))
   6238         def = 0;
   6239     else if (xmlStrEqual(val, BAD_CAST "1"))
   6240 	def = 1;
   6241     else if (xmlStrEqual(val, BAD_CAST "0"))
   6242         def = 0;
   6243     else {
   6244         xmlSchemaPSimpleTypeErr(ctxt,
   6245 	    XML_SCHEMAP_INVALID_BOOLEAN,
   6246 	    NULL,
   6247 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
   6248 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   6249 	    NULL, val, NULL, NULL, NULL);
   6250     }
   6251     return (def);
   6252 }
   6253 
   6254 /************************************************************************
   6255  *									*
   6256  *		Shema extraction from an Infoset			*
   6257  *									*
   6258  ************************************************************************/
   6259 static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
   6260                                                  ctxt, xmlSchemaPtr schema,
   6261                                                  xmlNodePtr node,
   6262 						 int topLevel);
   6263 static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
   6264                                                   ctxt,
   6265                                                   xmlSchemaPtr schema,
   6266                                                   xmlNodePtr node,
   6267 						  int topLevel);
   6268 static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
   6269                                                   ctxt,
   6270                                                   xmlSchemaPtr schema,
   6271                                                   xmlNodePtr node,
   6272 						  xmlSchemaTypeType parentType);
   6273 static xmlSchemaBasicItemPtr
   6274 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   6275 			     xmlSchemaPtr schema,
   6276 			     xmlNodePtr node,
   6277 			     xmlSchemaItemListPtr uses,
   6278 			     int parentType);
   6279 static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
   6280                                            xmlSchemaPtr schema,
   6281                                            xmlNodePtr node);
   6282 static xmlSchemaWildcardPtr
   6283 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   6284                            xmlSchemaPtr schema, xmlNodePtr node);
   6285 
   6286 /**
   6287  * xmlSchemaPValAttrNodeValue:
   6288  *
   6289  * @ctxt:  a schema parser context
   6290  * @ownerDes: the designation of the parent element
   6291  * @ownerItem: the schema object owner if existent
   6292  * @attr:  the schema attribute node being validated
   6293  * @value: the value
   6294  * @type: the built-in type to be validated against
   6295  *
   6296  * Validates a value against the given built-in type.
   6297  * This one is intended to be used internally for validation
   6298  * of schema attribute values during parsing of the schema.
   6299  *
   6300  * Returns 0 if the value is valid, a positive error code
   6301  * number otherwise and -1 in case of an internal or API error.
   6302  */
   6303 static int
   6304 xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
   6305 			   xmlSchemaBasicItemPtr ownerItem,
   6306 			   xmlAttrPtr attr,
   6307 			   const xmlChar *value,
   6308 			   xmlSchemaTypePtr type)
   6309 {
   6310 
   6311     int ret = 0;
   6312 
   6313     /*
   6314     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
   6315     * one is really meant to be used internally, so better not.
   6316     */
   6317     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
   6318 	return (-1);
   6319     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6320 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6321 	    "the given type is not a built-in type");
   6322 	return (-1);
   6323     }
   6324     switch (type->builtInType) {
   6325 	case XML_SCHEMAS_NCNAME:
   6326 	case XML_SCHEMAS_QNAME:
   6327 	case XML_SCHEMAS_ANYURI:
   6328 	case XML_SCHEMAS_TOKEN:
   6329 	case XML_SCHEMAS_LANGUAGE:
   6330 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
   6331 		(xmlNodePtr) attr);
   6332 	    break;
   6333 	default: {
   6334 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
   6335 		"validation using the given type is not supported while "
   6336 		"parsing a schema");
   6337 	    return (-1);
   6338 	}
   6339     }
   6340     /*
   6341     * TODO: Should we use the S4S error codes instead?
   6342     */
   6343     if (ret < 0) {
   6344 	PERROR_INT("xmlSchemaPValAttrNodeValue",
   6345 	    "failed to validate a schema attribute value");
   6346 	return (-1);
   6347     } else if (ret > 0) {
   6348 	if (WXS_IS_LIST(type))
   6349 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   6350 	else
   6351 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   6352 	xmlSchemaPSimpleTypeErr(pctxt,
   6353 	    ret, ownerItem, (xmlNodePtr) attr,
   6354 	    type, NULL, value, NULL, NULL, NULL);
   6355     }
   6356     return (ret);
   6357 }
   6358 
   6359 /**
   6360  * xmlSchemaPValAttrNode:
   6361  *
   6362  * @ctxt:  a schema parser context
   6363  * @ownerDes: the designation of the parent element
   6364  * @ownerItem: the schema object owner if existent
   6365  * @attr:  the schema attribute node being validated
   6366  * @type: the built-in type to be validated against
   6367  * @value: the resulting value if any
   6368  *
   6369  * Extracts and validates a value against the given built-in type.
   6370  * This one is intended to be used internally for validation
   6371  * of schema attribute values during parsing of the schema.
   6372  *
   6373  * Returns 0 if the value is valid, a positive error code
   6374  * number otherwise and -1 in case of an internal or API error.
   6375  */
   6376 static int
   6377 xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
   6378 			   xmlSchemaBasicItemPtr ownerItem,
   6379 			   xmlAttrPtr attr,
   6380 			   xmlSchemaTypePtr type,
   6381 			   const xmlChar **value)
   6382 {
   6383     const xmlChar *val;
   6384 
   6385     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
   6386 	return (-1);
   6387 
   6388     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6389     if (value != NULL)
   6390 	*value = val;
   6391 
   6392     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
   6393 	val, type));
   6394 }
   6395 
   6396 /**
   6397  * xmlSchemaPValAttr:
   6398  *
   6399  * @ctxt:  a schema parser context
   6400  * @node: the element node of the attribute
   6401  * @ownerDes: the designation of the parent element
   6402  * @ownerItem: the schema object owner if existent
   6403  * @ownerElem: the owner element node
   6404  * @name:  the name of the schema attribute node
   6405  * @type: the built-in type to be validated against
   6406  * @value: the resulting value if any
   6407  *
   6408  * Extracts and validates a value against the given built-in type.
   6409  * This one is intended to be used internally for validation
   6410  * of schema attribute values during parsing of the schema.
   6411  *
   6412  * Returns 0 if the value is valid, a positive error code
   6413  * number otherwise and -1 in case of an internal or API error.
   6414  */
   6415 static int
   6416 xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
   6417 		       xmlSchemaBasicItemPtr ownerItem,
   6418 		       xmlNodePtr ownerElem,
   6419 		       const char *name,
   6420 		       xmlSchemaTypePtr type,
   6421 		       const xmlChar **value)
   6422 {
   6423     xmlAttrPtr attr;
   6424 
   6425     if ((ctxt == NULL) || (type == NULL)) {
   6426 	if (value != NULL)
   6427 	    *value = NULL;
   6428 	return (-1);
   6429     }
   6430     if (type->type != XML_SCHEMA_TYPE_BASIC) {
   6431 	if (value != NULL)
   6432 	    *value = NULL;
   6433 	xmlSchemaPErr(ctxt, ownerElem,
   6434 	    XML_SCHEMAP_INTERNAL,
   6435 	    "Internal error: xmlSchemaPValAttr, the given "
   6436 	    "type '%s' is not a built-in type.\n",
   6437 	    type->name, NULL);
   6438 	return (-1);
   6439     }
   6440     attr = xmlSchemaGetPropNode(ownerElem, name);
   6441     if (attr == NULL) {
   6442 	if (value != NULL)
   6443 	    *value = NULL;
   6444 	return (0);
   6445     }
   6446     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
   6447 	type, value));
   6448 }
   6449 
   6450 static int
   6451 xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
   6452 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6453 		  xmlNodePtr node,
   6454 		  xmlAttrPtr attr,
   6455 		  const xmlChar *namespaceName)
   6456 {
   6457     /* TODO: Pointer comparison instead? */
   6458     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
   6459 	return (0);
   6460     if (xmlStrEqual(xmlSchemaNs, namespaceName))
   6461 	return (0);
   6462     /*
   6463     * Check if the referenced namespace was <import>ed.
   6464     */
   6465     if (WXS_BUCKET(pctxt)->relations != NULL) {
   6466 	xmlSchemaSchemaRelationPtr rel;
   6467 
   6468 	rel = WXS_BUCKET(pctxt)->relations;
   6469 	do {
   6470 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
   6471 		xmlStrEqual(namespaceName, rel->importNamespace))
   6472 		return (0);
   6473 	    rel = rel->next;
   6474 	} while (rel != NULL);
   6475     }
   6476     /*
   6477     * No matching <import>ed namespace found.
   6478     */
   6479     {
   6480 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
   6481 
   6482 	if (namespaceName == NULL)
   6483 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6484 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6485 		"References from this schema to components in no "
   6486 		"namespace are not allowed, since not indicated by an "
   6487 		"import statement", NULL, NULL);
   6488 	else
   6489 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   6490 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
   6491 		"References from this schema to components in the "
   6492 		"namespace '%s' are not allowed, since not indicated by an "
   6493 		"import statement", namespaceName, NULL);
   6494     }
   6495     return (XML_SCHEMAP_SRC_RESOLVE);
   6496 }
   6497 
   6498 /**
   6499  * xmlSchemaParseLocalAttributes:
   6500  * @ctxt:  a schema validation context
   6501  * @schema:  the schema being built
   6502  * @node:  a subtree containing XML Schema informations
   6503  * @type:  the hosting type where the attributes will be anchored
   6504  *
   6505  * Parses attribute uses and attribute declarations and
   6506  * attribute group references.
   6507  */
   6508 static int
   6509 xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6510                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
   6511 			int parentType, int *hasRefs)
   6512 {
   6513     void *item;
   6514 
   6515     while ((IS_SCHEMA((*child), "attribute")) ||
   6516            (IS_SCHEMA((*child), "attributeGroup"))) {
   6517         if (IS_SCHEMA((*child), "attribute")) {
   6518 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
   6519 		*list, parentType);
   6520         } else {
   6521             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
   6522 	    if ((item != NULL) && (hasRefs != NULL))
   6523 		*hasRefs = 1;
   6524         }
   6525 	if (item != NULL) {
   6526 	    if (*list == NULL) {
   6527 		/* TODO: Customize grow factor. */
   6528 		*list = xmlSchemaItemListCreate();
   6529 		if (*list == NULL)
   6530 		    return(-1);
   6531 	    }
   6532 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
   6533 		return(-1);
   6534 	}
   6535         *child = (*child)->next;
   6536     }
   6537     return (0);
   6538 }
   6539 
   6540 /**
   6541  * xmlSchemaParseAnnotation:
   6542  * @ctxt:  a schema validation context
   6543  * @schema:  the schema being built
   6544  * @node:  a subtree containing XML Schema informations
   6545  *
   6546  * parse a XML schema Attrribute declaration
   6547  * *WARNING* this interface is highly subject to change
   6548  *
   6549  * Returns -1 in case of error, 0 if the declaration is improper and
   6550  *         1 in case of success.
   6551  */
   6552 static xmlSchemaAnnotPtr
   6553 xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
   6554 {
   6555     xmlSchemaAnnotPtr ret;
   6556     xmlNodePtr child = NULL;
   6557     xmlAttrPtr attr;
   6558     int barked = 0;
   6559 
   6560     /*
   6561     * INFO: S4S completed.
   6562     */
   6563     /*
   6564     * id = ID
   6565     * {any attributes with non-schema namespace . . .}>
   6566     * Content: (appinfo | documentation)*
   6567     */
   6568     if ((ctxt == NULL) || (node == NULL))
   6569         return (NULL);
   6570     if (needed)
   6571 	ret = xmlSchemaNewAnnot(ctxt, node);
   6572     else
   6573 	ret = NULL;
   6574     attr = node->properties;
   6575     while (attr != NULL) {
   6576 	if (((attr->ns == NULL) &&
   6577 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
   6578 	    ((attr->ns != NULL) &&
   6579 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6580 
   6581 	    xmlSchemaPIllegalAttrErr(ctxt,
   6582 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6583 	}
   6584 	attr = attr->next;
   6585     }
   6586     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6587     /*
   6588     * And now for the children...
   6589     */
   6590     child = node->children;
   6591     while (child != NULL) {
   6592 	if (IS_SCHEMA(child, "appinfo")) {
   6593 	    /* TODO: make available the content of "appinfo". */
   6594 	    /*
   6595 	    * source = anyURI
   6596 	    * {any attributes with non-schema namespace . . .}>
   6597 	    * Content: ({any})*
   6598 	    */
   6599 	    attr = child->properties;
   6600 	    while (attr != NULL) {
   6601 		if (((attr->ns == NULL) &&
   6602 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
   6603 		     ((attr->ns != NULL) &&
   6604 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
   6605 
   6606 		    xmlSchemaPIllegalAttrErr(ctxt,
   6607 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6608 		}
   6609 		attr = attr->next;
   6610 	    }
   6611 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
   6612 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   6613 	    child = child->next;
   6614 	} else if (IS_SCHEMA(child, "documentation")) {
   6615 	    /* TODO: make available the content of "documentation". */
   6616 	    /*
   6617 	    * source = anyURI
   6618 	    * {any attributes with non-schema namespace . . .}>
   6619 	    * Content: ({any})*
   6620 	    */
   6621 	    attr = child->properties;
   6622 	    while (attr != NULL) {
   6623 		if (attr->ns == NULL) {
   6624 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
   6625 			xmlSchemaPIllegalAttrErr(ctxt,
   6626 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6627 		    }
   6628 		} else {
   6629 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
   6630 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
   6631 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
   6632 
   6633 			xmlSchemaPIllegalAttrErr(ctxt,
   6634 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6635 		    }
   6636 		}
   6637 		attr = attr->next;
   6638 	    }
   6639 	    /*
   6640 	    * Attribute "xml:lang".
   6641 	    */
   6642 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
   6643 	    if (attr != NULL)
   6644 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
   6645 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
   6646 	    child = child->next;
   6647 	} else {
   6648 	    if (!barked)
   6649 		xmlSchemaPContentErr(ctxt,
   6650 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6651 		    NULL, node, child, NULL, "(appinfo | documentation)*");
   6652 	    barked = 1;
   6653 	    child = child->next;
   6654 	}
   6655     }
   6656 
   6657     return (ret);
   6658 }
   6659 
   6660 /**
   6661  * xmlSchemaParseFacet:
   6662  * @ctxt:  a schema validation context
   6663  * @schema:  the schema being built
   6664  * @node:  a subtree containing XML Schema informations
   6665  *
   6666  * parse a XML schema Facet declaration
   6667  * *WARNING* this interface is highly subject to change
   6668  *
   6669  * Returns the new type structure or NULL in case of error
   6670  */
   6671 static xmlSchemaFacetPtr
   6672 xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6673                     xmlNodePtr node)
   6674 {
   6675     xmlSchemaFacetPtr facet;
   6676     xmlNodePtr child = NULL;
   6677     const xmlChar *value;
   6678 
   6679     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6680         return (NULL);
   6681 
   6682     facet = xmlSchemaNewFacet();
   6683     if (facet == NULL) {
   6684         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
   6685         return (NULL);
   6686     }
   6687     facet->node = node;
   6688     value = xmlSchemaGetProp(ctxt, node, "value");
   6689     if (value == NULL) {
   6690         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
   6691                        "Facet %s has no value\n", node->name, NULL);
   6692         xmlSchemaFreeFacet(facet);
   6693         return (NULL);
   6694     }
   6695     if (IS_SCHEMA(node, "minInclusive")) {
   6696         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
   6697     } else if (IS_SCHEMA(node, "minExclusive")) {
   6698         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
   6699     } else if (IS_SCHEMA(node, "maxInclusive")) {
   6700         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
   6701     } else if (IS_SCHEMA(node, "maxExclusive")) {
   6702         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
   6703     } else if (IS_SCHEMA(node, "totalDigits")) {
   6704         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
   6705     } else if (IS_SCHEMA(node, "fractionDigits")) {
   6706         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
   6707     } else if (IS_SCHEMA(node, "pattern")) {
   6708         facet->type = XML_SCHEMA_FACET_PATTERN;
   6709     } else if (IS_SCHEMA(node, "enumeration")) {
   6710         facet->type = XML_SCHEMA_FACET_ENUMERATION;
   6711     } else if (IS_SCHEMA(node, "whiteSpace")) {
   6712         facet->type = XML_SCHEMA_FACET_WHITESPACE;
   6713     } else if (IS_SCHEMA(node, "length")) {
   6714         facet->type = XML_SCHEMA_FACET_LENGTH;
   6715     } else if (IS_SCHEMA(node, "maxLength")) {
   6716         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
   6717     } else if (IS_SCHEMA(node, "minLength")) {
   6718         facet->type = XML_SCHEMA_FACET_MINLENGTH;
   6719     } else {
   6720         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
   6721                        "Unknown facet type %s\n", node->name, NULL);
   6722         xmlSchemaFreeFacet(facet);
   6723         return (NULL);
   6724     }
   6725     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6726     facet->value = value;
   6727     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   6728 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   6729 	const xmlChar *fixed;
   6730 
   6731 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
   6732 	if (fixed != NULL) {
   6733 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
   6734 		facet->fixed = 1;
   6735 	}
   6736     }
   6737     child = node->children;
   6738 
   6739     if (IS_SCHEMA(child, "annotation")) {
   6740         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6741         child = child->next;
   6742     }
   6743     if (child != NULL) {
   6744         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
   6745                        "Facet %s has unexpected child content\n",
   6746                        node->name, NULL);
   6747     }
   6748     return (facet);
   6749 }
   6750 
   6751 /**
   6752  * xmlSchemaParseWildcardNs:
   6753  * @ctxt:  a schema parser context
   6754  * @wildc:  the wildcard, already created
   6755  * @node:  a subtree containing XML Schema informations
   6756  *
   6757  * Parses the attribute "processContents" and "namespace"
   6758  * of a xsd:anyAttribute and xsd:any.
   6759  * *WARNING* this interface is highly subject to change
   6760  *
   6761  * Returns 0 if everything goes fine, a positive error code
   6762  * if something is not valid and -1 if an internal error occurs.
   6763  */
   6764 static int
   6765 xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
   6766 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
   6767 			 xmlSchemaWildcardPtr wildc,
   6768 			 xmlNodePtr node)
   6769 {
   6770     const xmlChar *pc, *ns, *dictnsItem;
   6771     int ret = 0;
   6772     xmlChar *nsItem;
   6773     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
   6774     xmlAttrPtr attr;
   6775 
   6776     pc = xmlSchemaGetProp(ctxt, node, "processContents");
   6777     if ((pc == NULL)
   6778         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
   6779         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6780     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
   6781         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
   6782     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
   6783         wildc->processContents = XML_SCHEMAS_ANY_LAX;
   6784     } else {
   6785         xmlSchemaPSimpleTypeErr(ctxt,
   6786 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   6787 	    NULL, node,
   6788 	    NULL, "(strict | skip | lax)", pc,
   6789 	    NULL, NULL, NULL);
   6790         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
   6791 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   6792     }
   6793     /*
   6794      * Build the namespace constraints.
   6795      */
   6796     attr = xmlSchemaGetPropNode(node, "namespace");
   6797     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   6798     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
   6799 	wildc->any = 1;
   6800     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
   6801 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   6802 	if (wildc->negNsSet == NULL) {
   6803 	    return (-1);
   6804 	}
   6805 	wildc->negNsSet->value = ctxt->targetNamespace;
   6806     } else {
   6807 	const xmlChar *end, *cur;
   6808 
   6809 	cur = ns;
   6810 	do {
   6811 	    while (IS_BLANK_CH(*cur))
   6812 		cur++;
   6813 	    end = cur;
   6814 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   6815 		end++;
   6816 	    if (end == cur)
   6817 		break;
   6818 	    nsItem = xmlStrndup(cur, end - cur);
   6819 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
   6820 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
   6821 		xmlSchemaPSimpleTypeErr(ctxt,
   6822 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
   6823 		    NULL, (xmlNodePtr) attr,
   6824 		    NULL,
   6825 		    "((##any | ##other) | List of (xs:anyURI | "
   6826 		    "(##targetNamespace | ##local)))",
   6827 		    nsItem, NULL, NULL, NULL);
   6828 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
   6829 	    } else {
   6830 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
   6831 		    dictnsItem = ctxt->targetNamespace;
   6832 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
   6833 		    dictnsItem = NULL;
   6834 		} else {
   6835 		    /*
   6836 		    * Validate the item (anyURI).
   6837 		    */
   6838 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
   6839 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
   6840 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
   6841 		}
   6842 		/*
   6843 		* Avoid dublicate namespaces.
   6844 		*/
   6845 		tmp = wildc->nsSet;
   6846 		while (tmp != NULL) {
   6847 		    if (dictnsItem == tmp->value)
   6848 			break;
   6849 		    tmp = tmp->next;
   6850 		}
   6851 		if (tmp == NULL) {
   6852 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   6853 		    if (tmp == NULL) {
   6854 			xmlFree(nsItem);
   6855 			return (-1);
   6856 		    }
   6857 		    tmp->value = dictnsItem;
   6858 		    tmp->next = NULL;
   6859 		    if (wildc->nsSet == NULL)
   6860 			wildc->nsSet = tmp;
   6861 		    else if (lastNs != NULL)
   6862 			lastNs->next = tmp;
   6863 		    lastNs = tmp;
   6864 		}
   6865 
   6866 	    }
   6867 	    xmlFree(nsItem);
   6868 	    cur = end;
   6869 	} while (*cur != 0);
   6870     }
   6871     return (ret);
   6872 }
   6873 
   6874 static int
   6875 xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
   6876 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
   6877 				 xmlNodePtr node,
   6878 				 int minOccurs,
   6879 				 int maxOccurs) {
   6880 
   6881     if ((maxOccurs == 0) && ( minOccurs == 0))
   6882 	return (0);
   6883     if (maxOccurs != UNBOUNDED) {
   6884 	/*
   6885 	* TODO: Maybe we should better not create the particle,
   6886 	* if min/max is invalid, since it could confuse the build of the
   6887 	* content model.
   6888 	*/
   6889 	/*
   6890 	* 3.9.6 Schema Component Constraint: Particle Correct
   6891 	*
   6892 	*/
   6893 	if (maxOccurs < 1) {
   6894 	    /*
   6895 	    * 2.2 {max occurs} must be greater than or equal to 1.
   6896 	    */
   6897 	    xmlSchemaPCustomAttrErr(ctxt,
   6898 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
   6899 		NULL, NULL,
   6900 		xmlSchemaGetPropNode(node, "maxOccurs"),
   6901 		"The value must be greater than or equal to 1");
   6902 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
   6903 	} else if (minOccurs > maxOccurs) {
   6904 	    /*
   6905 	    * 2.1 {min occurs} must not be greater than {max occurs}.
   6906 	    */
   6907 	    xmlSchemaPCustomAttrErr(ctxt,
   6908 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
   6909 		NULL, NULL,
   6910 		xmlSchemaGetPropNode(node, "minOccurs"),
   6911 		"The value must not be greater than the value of 'maxOccurs'");
   6912 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
   6913 	}
   6914     }
   6915     return (0);
   6916 }
   6917 
   6918 /**
   6919  * xmlSchemaParseAny:
   6920  * @ctxt:  a schema validation context
   6921  * @schema:  the schema being built
   6922  * @node:  a subtree containing XML Schema informations
   6923  *
   6924  * Parsea a XML schema <any> element. A particle and wildcard
   6925  * will be created (except if minOccurs==maxOccurs==0, in this case
   6926  * nothing will be created).
   6927  * *WARNING* this interface is highly subject to change
   6928  *
   6929  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
   6930  */
   6931 static xmlSchemaParticlePtr
   6932 xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   6933                   xmlNodePtr node)
   6934 {
   6935     xmlSchemaParticlePtr particle;
   6936     xmlNodePtr child = NULL;
   6937     xmlSchemaWildcardPtr wild;
   6938     int min, max;
   6939     xmlAttrPtr attr;
   6940     xmlSchemaAnnotPtr annot = NULL;
   6941 
   6942     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   6943         return (NULL);
   6944     /*
   6945     * Check for illegal attributes.
   6946     */
   6947     attr = node->properties;
   6948     while (attr != NULL) {
   6949 	if (attr->ns == NULL) {
   6950 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   6951 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   6952 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   6953 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   6954 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   6955 		xmlSchemaPIllegalAttrErr(ctxt,
   6956 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6957 	    }
   6958 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   6959 	    xmlSchemaPIllegalAttrErr(ctxt,
   6960 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   6961 	}
   6962 	attr = attr->next;
   6963     }
   6964     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   6965     /*
   6966     * minOccurs/maxOccurs.
   6967     */
   6968     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   6969 	"(xs:nonNegativeInteger | unbounded)");
   6970     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
   6971 	"xs:nonNegativeInteger");
   6972     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   6973     /*
   6974     * Create & parse the wildcard.
   6975     */
   6976     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
   6977     if (wild == NULL)
   6978 	return (NULL);
   6979     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
   6980     /*
   6981     * And now for the children...
   6982     */
   6983     child = node->children;
   6984     if (IS_SCHEMA(child, "annotation")) {
   6985         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   6986         child = child->next;
   6987     }
   6988     if (child != NULL) {
   6989 	xmlSchemaPContentErr(ctxt,
   6990 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   6991 	    NULL, node, child,
   6992 	    NULL, "(annotation?)");
   6993     }
   6994     /*
   6995     * No component if minOccurs==maxOccurs==0.
   6996     */
   6997     if ((min == 0) && (max == 0)) {
   6998 	/* Don't free the wildcard, since it's already on the list. */
   6999 	return (NULL);
   7000     }
   7001     /*
   7002     * Create the particle.
   7003     */
   7004     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   7005     if (particle == NULL)
   7006         return (NULL);
   7007     particle->annot = annot;
   7008     particle->children = (xmlSchemaTreeItemPtr) wild;
   7009 
   7010     return (particle);
   7011 }
   7012 
   7013 /**
   7014  * xmlSchemaParseNotation:
   7015  * @ctxt:  a schema validation context
   7016  * @schema:  the schema being built
   7017  * @node:  a subtree containing XML Schema informations
   7018  *
   7019  * parse a XML schema Notation declaration
   7020  *
   7021  * Returns the new structure or NULL in case of error
   7022  */
   7023 static xmlSchemaNotationPtr
   7024 xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   7025                        xmlNodePtr node)
   7026 {
   7027     const xmlChar *name;
   7028     xmlSchemaNotationPtr ret;
   7029     xmlNodePtr child = NULL;
   7030 
   7031     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7032         return (NULL);
   7033     name = xmlSchemaGetProp(ctxt, node, "name");
   7034     if (name == NULL) {
   7035         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
   7036                        "Notation has no name\n", NULL, NULL);
   7037         return (NULL);
   7038     }
   7039     ret = xmlSchemaAddNotation(ctxt, schema, name,
   7040 	ctxt->targetNamespace, node);
   7041     if (ret == NULL)
   7042         return (NULL);
   7043     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7044 
   7045     child = node->children;
   7046     if (IS_SCHEMA(child, "annotation")) {
   7047         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7048         child = child->next;
   7049     }
   7050     if (child != NULL) {
   7051 	xmlSchemaPContentErr(ctxt,
   7052 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7053 	    NULL, node, child,
   7054 	    NULL, "(annotation?)");
   7055     }
   7056 
   7057     return (ret);
   7058 }
   7059 
   7060 /**
   7061  * xmlSchemaParseAnyAttribute:
   7062  * @ctxt:  a schema validation context
   7063  * @schema:  the schema being built
   7064  * @node:  a subtree containing XML Schema informations
   7065  *
   7066  * parse a XML schema AnyAttrribute declaration
   7067  * *WARNING* this interface is highly subject to change
   7068  *
   7069  * Returns a wildcard or NULL.
   7070  */
   7071 static xmlSchemaWildcardPtr
   7072 xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
   7073                            xmlSchemaPtr schema, xmlNodePtr node)
   7074 {
   7075     xmlSchemaWildcardPtr ret;
   7076     xmlNodePtr child = NULL;
   7077     xmlAttrPtr attr;
   7078 
   7079     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   7080         return (NULL);
   7081 
   7082     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   7083 	node);
   7084     if (ret == NULL) {
   7085         return (NULL);
   7086     }
   7087     /*
   7088     * Check for illegal attributes.
   7089     */
   7090     attr = node->properties;
   7091     while (attr != NULL) {
   7092 	if (attr->ns == NULL) {
   7093 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7094 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   7095 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
   7096 		xmlSchemaPIllegalAttrErr(ctxt,
   7097 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7098 	    }
   7099 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7100 	    xmlSchemaPIllegalAttrErr(ctxt,
   7101 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7102 	}
   7103 	attr = attr->next;
   7104     }
   7105     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   7106     /*
   7107     * Parse the namespace list.
   7108     */
   7109     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
   7110 	return (NULL);
   7111     /*
   7112     * And now for the children...
   7113     */
   7114     child = node->children;
   7115     if (IS_SCHEMA(child, "annotation")) {
   7116         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   7117         child = child->next;
   7118     }
   7119     if (child != NULL) {
   7120 	xmlSchemaPContentErr(ctxt,
   7121 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7122 	    NULL, node, child,
   7123 	    NULL, "(annotation?)");
   7124     }
   7125 
   7126     return (ret);
   7127 }
   7128 
   7129 
   7130 /**
   7131  * xmlSchemaParseAttribute:
   7132  * @ctxt:  a schema validation context
   7133  * @schema:  the schema being built
   7134  * @node:  a subtree containing XML Schema informations
   7135  *
   7136  * parse a XML schema Attrribute declaration
   7137  * *WARNING* this interface is highly subject to change
   7138  *
   7139  * Returns the attribute declaration.
   7140  */
   7141 static xmlSchemaBasicItemPtr
   7142 xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7143 			     xmlSchemaPtr schema,
   7144 			     xmlNodePtr node,
   7145 			     xmlSchemaItemListPtr uses,
   7146 			     int parentType)
   7147 {
   7148     const xmlChar *attrValue, *name = NULL, *ns = NULL;
   7149     xmlSchemaAttributeUsePtr use = NULL;
   7150     xmlNodePtr child = NULL;
   7151     xmlAttrPtr attr;
   7152     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
   7153     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7154     int	nberrors, hasForm = 0, defValueType = 0;
   7155 
   7156 #define WXS_ATTR_DEF_VAL_DEFAULT 1
   7157 #define WXS_ATTR_DEF_VAL_FIXED 2
   7158 
   7159     /*
   7160      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7161      */
   7162 
   7163     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7164         return (NULL);
   7165     attr = xmlSchemaGetPropNode(node, "ref");
   7166     if (attr != NULL) {
   7167 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
   7168 	    NULL, attr, &tmpNs, &tmpName) != 0) {
   7169 	    return (NULL);
   7170 	}
   7171 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
   7172 	    return(NULL);
   7173 	isRef = 1;
   7174     }
   7175     nberrors = pctxt->nberrors;
   7176     /*
   7177     * Check for illegal attributes.
   7178     */
   7179     attr = node->properties;
   7180     while (attr != NULL) {
   7181 	if (attr->ns == NULL) {
   7182 	    if (isRef) {
   7183 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7184 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7185 		    goto attr_next;
   7186 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
   7187 		    goto attr_next;
   7188 		}
   7189 	    } else {
   7190 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   7191 		    goto attr_next;
   7192 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   7193 		    xmlSchemaPValAttrNodeID(pctxt, attr);
   7194 		    goto attr_next;
   7195 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
   7196 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
   7197 			attr, &tmpNs, &tmpName);
   7198 		    goto attr_next;
   7199 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
   7200 		    /*
   7201 		    * Evaluate the target namespace
   7202 		    */
   7203 		    hasForm = 1;
   7204 		    attrValue = xmlSchemaGetNodeContent(pctxt,
   7205 			(xmlNodePtr) attr);
   7206 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   7207 			ns = pctxt->targetNamespace;
   7208 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
   7209 		    {
   7210 			xmlSchemaPSimpleTypeErr(pctxt,
   7211 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   7212 			    NULL, (xmlNodePtr) attr,
   7213 			    NULL, "(qualified | unqualified)",
   7214 			    attrValue, NULL, NULL, NULL);
   7215 		    }
   7216 		    goto attr_next;
   7217 		}
   7218 	    }
   7219 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
   7220 
   7221 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7222 		/* TODO: Maybe we need to normalize the value beforehand. */
   7223 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
   7224 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
   7225 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
   7226 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
   7227 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
   7228 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
   7229 		else {
   7230 		    xmlSchemaPSimpleTypeErr(pctxt,
   7231 			XML_SCHEMAP_INVALID_ATTR_USE,
   7232 			NULL, (xmlNodePtr) attr,
   7233 			NULL, "(optional | prohibited | required)",
   7234 			attrValue, NULL, NULL, NULL);
   7235 		}
   7236 		goto attr_next;
   7237 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
   7238 		/*
   7239 		* 3.2.3 : 1
   7240 		* default and fixed must not both be present.
   7241 		*/
   7242 		if (defValue) {
   7243 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7244 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7245 			NULL, attr, "default", "fixed");
   7246 		} else {
   7247 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7248 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
   7249 		}
   7250 		goto attr_next;
   7251 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
   7252 		/*
   7253 		* 3.2.3 : 1
   7254 		* default and fixed must not both be present.
   7255 		*/
   7256 		if (defValue) {
   7257 		    xmlSchemaPMutualExclAttrErr(pctxt,
   7258 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7259 			NULL, attr, "default", "fixed");
   7260 		} else {
   7261 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7262 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
   7263 		}
   7264 		goto attr_next;
   7265 	    }
   7266 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
   7267 	    goto attr_next;
   7268 
   7269 	xmlSchemaPIllegalAttrErr(pctxt,
   7270 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7271 
   7272 attr_next:
   7273 	attr = attr->next;
   7274     }
   7275     /*
   7276     * 3.2.3 : 2
   7277     * If default and use are both present, use must have
   7278     * the actual value optional.
   7279     */
   7280     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
   7281 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
   7282 	xmlSchemaPSimpleTypeErr(pctxt,
   7283 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
   7284 	    NULL, node, NULL,
   7285 	    "(optional | prohibited | required)", NULL,
   7286 	    "The value of the attribute 'use' must be 'optional' "
   7287 	    "if the attribute 'default' is present",
   7288 	    NULL, NULL);
   7289     }
   7290     /*
   7291     * We want correct attributes.
   7292     */
   7293     if (nberrors != pctxt->nberrors)
   7294 	return(NULL);
   7295     if (! isRef) {
   7296 	xmlSchemaAttributePtr attrDecl;
   7297 
   7298 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
   7299 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
   7300 	    ns = pctxt->targetNamespace;
   7301 	/*
   7302 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7303 	* TODO: Move this to the component layer.
   7304 	*/
   7305 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
   7306 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7307 		XML_SCHEMAP_NO_XSI,
   7308 		node, NULL,
   7309 		"The target namespace must not match '%s'",
   7310 		xmlSchemaInstanceNs, NULL);
   7311 	}
   7312 	attr = xmlSchemaGetPropNode(node, "name");
   7313 	if (attr == NULL) {
   7314 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7315 		NULL, node, "name", NULL);
   7316 	    return (NULL);
   7317 	}
   7318 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7319 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7320 	    return (NULL);
   7321 	}
   7322 	/*
   7323 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7324 	* TODO: Move this to the component layer.
   7325 	*/
   7326 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
   7327 	    xmlSchemaPSimpleTypeErr(pctxt,
   7328 		XML_SCHEMAP_NO_XMLNS,
   7329 		NULL, (xmlNodePtr) attr,
   7330 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7331 		"The value of the attribute must not match 'xmlns'",
   7332 		NULL, NULL);
   7333 	    return (NULL);
   7334 	}
   7335 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
   7336 	    goto check_children;
   7337 	/*
   7338 	* Create the attribute use component.
   7339 	*/
   7340 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7341 	if (use == NULL)
   7342 	    return(NULL);
   7343 	use->occurs = occurs;
   7344 	/*
   7345 	* Create the attribute declaration.
   7346 	*/
   7347 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
   7348 	if (attrDecl == NULL)
   7349 	    return (NULL);
   7350 	if (tmpName != NULL) {
   7351 	    attrDecl->typeName = tmpName;
   7352 	    attrDecl->typeNs = tmpNs;
   7353 	}
   7354 	use->attrDecl = attrDecl;
   7355 	/*
   7356 	* Value constraint.
   7357 	*/
   7358 	if (defValue != NULL) {
   7359 	    attrDecl->defValue = defValue;
   7360 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7361 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
   7362 	}
   7363     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7364 	xmlSchemaQNameRefPtr ref;
   7365 
   7366 	/*
   7367 	* Create the attribute use component.
   7368 	*/
   7369 	use = xmlSchemaAddAttributeUse(pctxt, node);
   7370 	if (use == NULL)
   7371 	    return(NULL);
   7372 	/*
   7373 	* We need to resolve the reference at later stage.
   7374 	*/
   7375 	WXS_ADD_PENDING(pctxt, use);
   7376 	use->occurs = occurs;
   7377 	/*
   7378 	* Create a QName reference to the attribute declaration.
   7379 	*/
   7380 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
   7381 	    tmpName, tmpNs);
   7382 	if (ref == NULL)
   7383 	    return(NULL);
   7384 	/*
   7385 	* Assign the reference. This will be substituted for the
   7386 	* referenced attribute declaration when the QName is resolved.
   7387 	*/
   7388 	use->attrDecl = WXS_ATTR_CAST ref;
   7389 	/*
   7390 	* Value constraint.
   7391 	*/
   7392 	if (defValue != NULL)
   7393 	    use->defValue = defValue;
   7394 	if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
   7395 	    use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
   7396     }
   7397 
   7398 check_children:
   7399     /*
   7400     * And now for the children...
   7401     */
   7402     child = node->children;
   7403     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
   7404 	xmlSchemaAttributeUseProhibPtr prohib;
   7405 
   7406 	if (IS_SCHEMA(child, "annotation")) {
   7407 	    xmlSchemaParseAnnotation(pctxt, child, 0);
   7408 	    child = child->next;
   7409 	}
   7410 	if (child != NULL) {
   7411 	    xmlSchemaPContentErr(pctxt,
   7412 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7413 		NULL, node, child, NULL,
   7414 		"(annotation?)");
   7415 	}
   7416 	/*
   7417 	* Check for pointlessness of attribute prohibitions.
   7418 	*/
   7419 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
   7420 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7421 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7422 		node, NULL,
   7423 		"Skipping attribute use prohibition, since it is "
   7424 		"pointless inside an <attributeGroup>",
   7425 		NULL, NULL, NULL);
   7426 	    return(NULL);
   7427 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
   7428 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7429 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7430 		node, NULL,
   7431 		"Skipping attribute use prohibition, since it is "
   7432 		"pointless when extending a type",
   7433 		NULL, NULL, NULL);
   7434 	    return(NULL);
   7435 	}
   7436 	if (! isRef) {
   7437 	    tmpName = name;
   7438 	    tmpNs = ns;
   7439 	}
   7440 	/*
   7441 	* Check for duplicate attribute prohibitions.
   7442 	*/
   7443 	if (uses) {
   7444 	    int i;
   7445 
   7446 	    for (i = 0; i < uses->nbItems; i++) {
   7447 		use = uses->items[i];
   7448 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
   7449 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
   7450 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
   7451 		{
   7452 		    xmlChar *str = NULL;
   7453 
   7454 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   7455 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   7456 			node, NULL,
   7457 			"Skipping duplicate attribute use prohibition '%s'",
   7458 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
   7459 			NULL, NULL);
   7460 		    FREE_AND_NULL(str)
   7461 		    return(NULL);
   7462 		}
   7463 	    }
   7464 	}
   7465 	/*
   7466 	* Create the attribute prohibition helper component.
   7467 	*/
   7468 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
   7469 	if (prohib == NULL)
   7470 	    return(NULL);
   7471 	prohib->node = node;
   7472 	prohib->name = tmpName;
   7473 	prohib->targetNamespace = tmpNs;
   7474 	if (isRef) {
   7475 	    /*
   7476 	    * We need at least to resolve to the attribute declaration.
   7477 	    */
   7478 	    WXS_ADD_PENDING(pctxt, prohib);
   7479 	}
   7480 	return(WXS_BASIC_CAST prohib);
   7481     } else {
   7482 	if (IS_SCHEMA(child, "annotation")) {
   7483 	    /*
   7484 	    * TODO: Should this go into the attr decl?
   7485 	    */
   7486 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7487 	    child = child->next;
   7488 	}
   7489 	if (isRef) {
   7490 	    if (child != NULL) {
   7491 		if (IS_SCHEMA(child, "simpleType"))
   7492 		    /*
   7493 		    * 3.2.3 : 3.2
   7494 		    * If ref is present, then all of <simpleType>,
   7495 		    * form and type must be absent.
   7496 		    */
   7497 		    xmlSchemaPContentErr(pctxt,
   7498 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
   7499 			NULL, node, child, NULL,
   7500 			"(annotation?)");
   7501 		else
   7502 		    xmlSchemaPContentErr(pctxt,
   7503 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7504 			NULL, node, child, NULL,
   7505 			"(annotation?)");
   7506 	    }
   7507 	} else {
   7508 	    if (IS_SCHEMA(child, "simpleType")) {
   7509 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
   7510 		    /*
   7511 		    * 3.2.3 : 4
   7512 		    * type and <simpleType> must not both be present.
   7513 		    */
   7514 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7515 			NULL, node, child,
   7516 			"The attribute 'type' and the <simpleType> child "
   7517 			"are mutually exclusive", NULL);
   7518 		} else
   7519 		    WXS_ATTRUSE_TYPEDEF(use) =
   7520 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7521 		child = child->next;
   7522 	    }
   7523 	    if (child != NULL)
   7524 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7525 		NULL, node, child, NULL,
   7526 		"(annotation?, simpleType?)");
   7527 	}
   7528     }
   7529     return (WXS_BASIC_CAST use);
   7530 }
   7531 
   7532 
   7533 static xmlSchemaAttributePtr
   7534 xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
   7535 			      xmlSchemaPtr schema,
   7536 			      xmlNodePtr node)
   7537 {
   7538     const xmlChar *attrValue;
   7539     xmlSchemaAttributePtr ret;
   7540     xmlNodePtr child = NULL;
   7541     xmlAttrPtr attr;
   7542 
   7543     /*
   7544      * Note that the w3c spec assumes the schema to be validated with schema
   7545      * for schemas beforehand.
   7546      *
   7547      * 3.2.3 Constraints on XML Representations of Attribute Declarations
   7548      */
   7549     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7550         return (NULL);
   7551     /*
   7552     * 3.2.3 : 3.1
   7553     * One of ref or name must be present, but not both
   7554     */
   7555     attr = xmlSchemaGetPropNode(node, "name");
   7556     if (attr == NULL) {
   7557 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
   7558 	    NULL, node, "name", NULL);
   7559 	return (NULL);
   7560     }
   7561     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   7562 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
   7563 	return (NULL);
   7564     }
   7565     /*
   7566     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
   7567     * TODO: Move this to the component layer.
   7568     */
   7569     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
   7570 	xmlSchemaPSimpleTypeErr(pctxt,
   7571 	    XML_SCHEMAP_NO_XMLNS,
   7572 	    NULL, (xmlNodePtr) attr,
   7573 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
   7574 	    "The value of the attribute must not match 'xmlns'",
   7575 	    NULL, NULL);
   7576 	return (NULL);
   7577     }
   7578     /*
   7579     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
   7580     * TODO: Move this to the component layer.
   7581     *       Or better leave it here and add it to the component layer
   7582     *       if we have a schema construction API.
   7583     */
   7584     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
   7585 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7586 	    XML_SCHEMAP_NO_XSI, node, NULL,
   7587 	    "The target namespace must not match '%s'",
   7588 	    xmlSchemaInstanceNs, NULL);
   7589     }
   7590 
   7591     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
   7592 	pctxt->targetNamespace, node, 1);
   7593     if (ret == NULL)
   7594 	return (NULL);
   7595     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
   7596 
   7597     /*
   7598     * Check for illegal attributes.
   7599     */
   7600     attr = node->properties;
   7601     while (attr != NULL) {
   7602 	if (attr->ns == NULL) {
   7603 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   7604 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   7605 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   7606 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7607 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
   7608 	    {
   7609 		xmlSchemaPIllegalAttrErr(pctxt,
   7610 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7611 	    }
   7612 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7613 	    xmlSchemaPIllegalAttrErr(pctxt,
   7614 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7615 	}
   7616 	attr = attr->next;
   7617     }
   7618     xmlSchemaPValAttrQName(pctxt, schema, NULL,
   7619 	node, "type", &ret->typeNs, &ret->typeName);
   7620 
   7621     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7622     /*
   7623     * Attribute "fixed".
   7624     */
   7625     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
   7626     if (ret->defValue != NULL)
   7627 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
   7628     /*
   7629     * Attribute "default".
   7630     */
   7631     attr = xmlSchemaGetPropNode(node, "default");
   7632     if (attr != NULL) {
   7633 	/*
   7634 	* 3.2.3 : 1
   7635 	* default and fixed must not both be present.
   7636 	*/
   7637 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
   7638 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
   7639 		WXS_BASIC_CAST ret, attr, "default", "fixed");
   7640 	} else
   7641 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
   7642     }
   7643     /*
   7644     * And now for the children...
   7645     */
   7646     child = node->children;
   7647     if (IS_SCHEMA(child, "annotation")) {
   7648         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7649         child = child->next;
   7650     }
   7651     if (IS_SCHEMA(child, "simpleType")) {
   7652 	if (ret->typeName != NULL) {
   7653 	    /*
   7654 	    * 3.2.3 : 4
   7655 	    * type and <simpleType> must not both be present.
   7656 	    */
   7657 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
   7658 		NULL, node, child,
   7659 		"The attribute 'type' and the <simpleType> child "
   7660 		"are mutually exclusive", NULL);
   7661 	} else
   7662 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
   7663 	child = child->next;
   7664     }
   7665     if (child != NULL)
   7666 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7667 	    NULL, node, child, NULL,
   7668 	    "(annotation?, simpleType?)");
   7669 
   7670     return (ret);
   7671 }
   7672 
   7673 /**
   7674  * xmlSchemaParseAttributeGroupRef:
   7675  * @ctxt:  a schema validation context
   7676  * @schema:  the schema being built
   7677  * @node:  a subtree containing XML Schema informations
   7678  *
   7679  * Parse an attribute group definition reference.
   7680  * Note that a reference to an attribute group does not
   7681  * correspond to any component at all.
   7682  * *WARNING* this interface is highly subject to change
   7683  *
   7684  * Returns the attribute group or NULL in case of error.
   7685  */
   7686 static xmlSchemaQNameRefPtr
   7687 xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
   7688 				xmlSchemaPtr schema,
   7689 				xmlNodePtr node)
   7690 {
   7691     xmlSchemaQNameRefPtr ret;
   7692     xmlNodePtr child = NULL;
   7693     xmlAttrPtr attr;
   7694     const xmlChar *refNs = NULL, *ref = NULL;
   7695 
   7696     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7697         return (NULL);
   7698 
   7699     attr = xmlSchemaGetPropNode(node, "ref");
   7700     if (attr == NULL) {
   7701 	xmlSchemaPMissingAttrErr(pctxt,
   7702 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7703 	    NULL, node, "ref", NULL);
   7704 	return (NULL);
   7705     }
   7706     xmlSchemaPValAttrNodeQName(pctxt, schema,
   7707 	NULL, attr, &refNs, &ref);
   7708     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
   7709 	return(NULL);
   7710 
   7711     /*
   7712     * Check for illegal attributes.
   7713     */
   7714     attr = node->properties;
   7715     while (attr != NULL) {
   7716 	if (attr->ns == NULL) {
   7717 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   7718 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7719 	    {
   7720 		xmlSchemaPIllegalAttrErr(pctxt,
   7721 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7722 	    }
   7723 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7724 	    xmlSchemaPIllegalAttrErr(pctxt,
   7725 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7726 	}
   7727 	attr = attr->next;
   7728     }
   7729     /* Attribute ID */
   7730     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7731 
   7732     /*
   7733     * And now for the children...
   7734     */
   7735     child = node->children;
   7736     if (IS_SCHEMA(child, "annotation")) {
   7737 	/*
   7738 	* TODO: We do not have a place to store the annotation, do we?
   7739 	*/
   7740         xmlSchemaParseAnnotation(pctxt, child, 0);
   7741         child = child->next;
   7742     }
   7743     if (child != NULL) {
   7744 	xmlSchemaPContentErr(pctxt,
   7745 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7746 	    NULL, node, child, NULL,
   7747 	    "(annotation?)");
   7748     }
   7749 
   7750     /*
   7751     * Handle attribute group redefinitions.
   7752     */
   7753     if (pctxt->isRedefine && pctxt->redef &&
   7754 	(pctxt->redef->item->type ==
   7755 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   7756 	(ref == pctxt->redef->refName) &&
   7757 	(refNs == pctxt->redef->refTargetNs))
   7758     {
   7759 	/*
   7760 	* SPEC src-redefine:
   7761 	* (7.1) "If it has an <attributeGroup> among its contents
   7762 	* the `actual value` of whose ref [attribute] is the same
   7763 	* as the `actual value` of its own name attribute plus
   7764 	* target namespace, then it must have exactly one such group."
   7765 	*/
   7766 	if (pctxt->redefCounter != 0) {
   7767 	    xmlChar *str = NULL;
   7768 
   7769 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   7770 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   7771 		"The redefining attribute group definition "
   7772 		"'%s' must not contain more than one "
   7773 		"reference to the redefined definition",
   7774 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
   7775 	    FREE_AND_NULL(str);
   7776 	    return(NULL);
   7777 	}
   7778 	pctxt->redefCounter++;
   7779 	/*
   7780 	* URGENT TODO: How to ensure that the reference will not be
   7781 	* handled by the normal component resolution mechanism?
   7782 	*/
   7783 	ret = xmlSchemaNewQNameRef(pctxt,
   7784 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7785 	if (ret == NULL)
   7786 	    return(NULL);
   7787 	ret->node = node;
   7788 	pctxt->redef->reference = WXS_BASIC_CAST ret;
   7789     } else {
   7790 	/*
   7791 	* Create a QName-reference helper component. We will substitute this
   7792 	* component for the attribute uses of the referenced attribute group
   7793 	* definition.
   7794 	*/
   7795 	ret = xmlSchemaNewQNameRef(pctxt,
   7796 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
   7797 	if (ret == NULL)
   7798 	    return(NULL);
   7799 	ret->node = node;
   7800 	/* Add to pending items, to be able to resolve the reference. */
   7801 	WXS_ADD_PENDING(pctxt, ret);
   7802     }
   7803     return (ret);
   7804 }
   7805 
   7806 /**
   7807  * xmlSchemaParseAttributeGroupDefinition:
   7808  * @pctxt:  a schema validation context
   7809  * @schema:  the schema being built
   7810  * @node:  a subtree containing XML Schema informations
   7811  *
   7812  * parse a XML schema Attribute Group declaration
   7813  * *WARNING* this interface is highly subject to change
   7814  *
   7815  * Returns the attribute group definition or NULL in case of error.
   7816  */
   7817 static xmlSchemaAttributeGroupPtr
   7818 xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
   7819 				       xmlSchemaPtr schema,
   7820 				       xmlNodePtr node)
   7821 {
   7822     const xmlChar *name;
   7823     xmlSchemaAttributeGroupPtr ret;
   7824     xmlNodePtr child = NULL;
   7825     xmlAttrPtr attr;
   7826     int hasRefs = 0;
   7827 
   7828     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   7829         return (NULL);
   7830 
   7831     attr = xmlSchemaGetPropNode(node, "name");
   7832     if (attr == NULL) {
   7833 	xmlSchemaPMissingAttrErr(pctxt,
   7834 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   7835 	    NULL, node, "name", NULL);
   7836 	return (NULL);
   7837     }
   7838     /*
   7839     * The name is crucial, exit if invalid.
   7840     */
   7841     if (xmlSchemaPValAttrNode(pctxt,
   7842 	NULL, attr,
   7843 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   7844 	return (NULL);
   7845     }
   7846     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
   7847 	name, pctxt->targetNamespace, node);
   7848     if (ret == NULL)
   7849 	return (NULL);
   7850     /*
   7851     * Check for illegal attributes.
   7852     */
   7853     attr = node->properties;
   7854     while (attr != NULL) {
   7855 	if (attr->ns == NULL) {
   7856 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   7857 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
   7858 	    {
   7859 		xmlSchemaPIllegalAttrErr(pctxt,
   7860 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7861 	    }
   7862 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   7863 	    xmlSchemaPIllegalAttrErr(pctxt,
   7864 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   7865 	}
   7866 	attr = attr->next;
   7867     }
   7868     /* Attribute ID */
   7869     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   7870     /*
   7871     * And now for the children...
   7872     */
   7873     child = node->children;
   7874     if (IS_SCHEMA(child, "annotation")) {
   7875         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
   7876         child = child->next;
   7877     }
   7878     /*
   7879     * Parse contained attribute decls/refs.
   7880     */
   7881     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
   7882 	(xmlSchemaItemListPtr *) &(ret->attrUses),
   7883 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
   7884 	return(NULL);
   7885     if (hasRefs)
   7886 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
   7887     /*
   7888     * Parse the attribute wildcard.
   7889     */
   7890     if (IS_SCHEMA(child, "anyAttribute")) {
   7891 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
   7892 	    schema, child);
   7893 	child = child->next;
   7894     }
   7895     if (child != NULL) {
   7896 	xmlSchemaPContentErr(pctxt,
   7897 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   7898 	    NULL, node, child, NULL,
   7899 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
   7900     }
   7901     return (ret);
   7902 }
   7903 
   7904 /**
   7905  * xmlSchemaPValAttrFormDefault:
   7906  * @value:  the value
   7907  * @flags: the flags to be modified
   7908  * @flagQualified: the specific flag for "qualified"
   7909  *
   7910  * Returns 0 if the value is valid, 1 otherwise.
   7911  */
   7912 static int
   7913 xmlSchemaPValAttrFormDefault(const xmlChar *value,
   7914 			     int *flags,
   7915 			     int flagQualified)
   7916 {
   7917     if (xmlStrEqual(value, BAD_CAST "qualified")) {
   7918 	if  ((*flags & flagQualified) == 0)
   7919 	    *flags |= flagQualified;
   7920     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
   7921 	return (1);
   7922 
   7923     return (0);
   7924 }
   7925 
   7926 /**
   7927  * xmlSchemaPValAttrBlockFinal:
   7928  * @value:  the value
   7929  * @flags: the flags to be modified
   7930  * @flagAll: the specific flag for "#all"
   7931  * @flagExtension: the specific flag for "extension"
   7932  * @flagRestriction: the specific flag for "restriction"
   7933  * @flagSubstitution: the specific flag for "substitution"
   7934  * @flagList: the specific flag for "list"
   7935  * @flagUnion: the specific flag for "union"
   7936  *
   7937  * Validates the value of the attribute "final" and "block". The value
   7938  * is converted into the specified flag values and returned in @flags.
   7939  *
   7940  * Returns 0 if the value is valid, 1 otherwise.
   7941  */
   7942 
   7943 static int
   7944 xmlSchemaPValAttrBlockFinal(const xmlChar *value,
   7945 			    int *flags,
   7946 			    int flagAll,
   7947 			    int flagExtension,
   7948 			    int flagRestriction,
   7949 			    int flagSubstitution,
   7950 			    int flagList,
   7951 			    int flagUnion)
   7952 {
   7953     int ret = 0;
   7954 
   7955     /*
   7956     * TODO: This does not check for dublicate entries.
   7957     */
   7958     if ((flags == NULL) || (value == NULL))
   7959 	return (-1);
   7960     if (value[0] == 0)
   7961 	return (0);
   7962     if (xmlStrEqual(value, BAD_CAST "#all")) {
   7963 	if (flagAll != -1)
   7964 	    *flags |= flagAll;
   7965 	else {
   7966 	    if (flagExtension != -1)
   7967 		*flags |= flagExtension;
   7968 	    if (flagRestriction != -1)
   7969 		*flags |= flagRestriction;
   7970 	    if (flagSubstitution != -1)
   7971 		*flags |= flagSubstitution;
   7972 	    if (flagList != -1)
   7973 		*flags |= flagList;
   7974 	    if (flagUnion != -1)
   7975 		*flags |= flagUnion;
   7976 	}
   7977     } else {
   7978 	const xmlChar *end, *cur = value;
   7979 	xmlChar *item;
   7980 
   7981 	do {
   7982 	    while (IS_BLANK_CH(*cur))
   7983 		cur++;
   7984 	    end = cur;
   7985 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   7986 		end++;
   7987 	    if (end == cur)
   7988 		break;
   7989 	    item = xmlStrndup(cur, end - cur);
   7990 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
   7991 		if (flagExtension != -1) {
   7992 		    if ((*flags & flagExtension) == 0)
   7993 			*flags |= flagExtension;
   7994 		} else
   7995 		    ret = 1;
   7996 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
   7997 		if (flagRestriction != -1) {
   7998 		    if ((*flags & flagRestriction) == 0)
   7999 			*flags |= flagRestriction;
   8000 		} else
   8001 		    ret = 1;
   8002 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
   8003 		if (flagSubstitution != -1) {
   8004 		    if ((*flags & flagSubstitution) == 0)
   8005 			*flags |= flagSubstitution;
   8006 		} else
   8007 		    ret = 1;
   8008 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
   8009 		if (flagList != -1) {
   8010 		    if ((*flags & flagList) == 0)
   8011 			*flags |= flagList;
   8012 		} else
   8013 		    ret = 1;
   8014 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
   8015 		if (flagUnion != -1) {
   8016 		    if ((*flags & flagUnion) == 0)
   8017 			*flags |= flagUnion;
   8018 		} else
   8019 		    ret = 1;
   8020 	    } else
   8021 		ret = 1;
   8022 	    if (item != NULL)
   8023 		xmlFree(item);
   8024 	    cur = end;
   8025 	} while ((ret == 0) && (*cur != 0));
   8026     }
   8027 
   8028     return (ret);
   8029 }
   8030 
   8031 static int
   8032 xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
   8033 			     xmlSchemaIDCPtr idc,
   8034 			     xmlSchemaIDCSelectPtr selector,
   8035 			     xmlAttrPtr attr,
   8036 			     int isField)
   8037 {
   8038     xmlNodePtr node;
   8039 
   8040     /*
   8041     * c-selector-xpath:
   8042     * Schema Component Constraint: Selector Value OK
   8043     *
   8044     * TODO: 1 The {selector} must be a valid XPath expression, as defined
   8045     * in [XPath].
   8046     */
   8047     if (selector == NULL) {
   8048 	xmlSchemaPErr(ctxt, idc->node,
   8049 	    XML_SCHEMAP_INTERNAL,
   8050 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
   8051 	    "the selector is not specified.\n", NULL, NULL);
   8052 	return (-1);
   8053     }
   8054     if (attr == NULL)
   8055 	node = idc->node;
   8056     else
   8057 	node = (xmlNodePtr) attr;
   8058     if (selector->xpath == NULL) {
   8059 	xmlSchemaPCustomErr(ctxt,
   8060 	    /* TODO: Adjust error code. */
   8061 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8062 	    NULL, node,
   8063 	    "The XPath expression of the selector is not valid", NULL);
   8064 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8065     } else {
   8066 	const xmlChar **nsArray = NULL;
   8067 	xmlNsPtr *nsList = NULL;
   8068 	/*
   8069 	* Compile the XPath expression.
   8070 	*/
   8071 	/*
   8072 	* TODO: We need the array of in-scope namespaces for compilation.
   8073 	* TODO: Call xmlPatterncompile with different options for selector/
   8074 	* field.
   8075 	*/
   8076 	if (attr == NULL)
   8077 	    nsList = NULL;
   8078 	else
   8079 	    nsList = xmlGetNsList(attr->doc, attr->parent);
   8080 	/*
   8081 	* Build an array of prefixes and namespaces.
   8082 	*/
   8083 	if (nsList != NULL) {
   8084 	    int i, count = 0;
   8085 
   8086 	    for (i = 0; nsList[i] != NULL; i++)
   8087 		count++;
   8088 
   8089 	    nsArray = (const xmlChar **) xmlMalloc(
   8090 		(count * 2 + 1) * sizeof(const xmlChar *));
   8091 	    if (nsArray == NULL) {
   8092 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
   8093 		    NULL);
   8094 		xmlFree(nsList);
   8095 		return (-1);
   8096 	    }
   8097 	    for (i = 0; i < count; i++) {
   8098 		nsArray[2 * i] = nsList[i]->href;
   8099 		nsArray[2 * i + 1] = nsList[i]->prefix;
   8100 	    }
   8101 	    nsArray[count * 2] = NULL;
   8102 	    xmlFree(nsList);
   8103 	}
   8104 	/*
   8105 	* TODO: Differentiate between "selector" and "field".
   8106 	*/
   8107 	if (isField)
   8108 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8109 		NULL, XML_PATTERN_XSFIELD, nsArray);
   8110 	else
   8111 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
   8112 		NULL, XML_PATTERN_XSSEL, nsArray);
   8113 	if (nsArray != NULL)
   8114 	    xmlFree((xmlChar **) nsArray);
   8115 
   8116 	if (selector->xpathComp == NULL) {
   8117 	    xmlSchemaPCustomErr(ctxt,
   8118 		/* TODO: Adjust error code? */
   8119 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8120 		NULL, node,
   8121 		"The XPath expression '%s' could not be "
   8122 		"compiled", selector->xpath);
   8123 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
   8124 	}
   8125     }
   8126     return (0);
   8127 }
   8128 
   8129 #define ADD_ANNOTATION(annot)   \
   8130     xmlSchemaAnnotPtr cur = item->annot; \
   8131     if (item->annot == NULL) {  \
   8132 	item->annot = annot;    \
   8133 	return (annot);         \
   8134     }                           \
   8135     cur = item->annot;          \
   8136     if (cur->next != NULL) {    \
   8137 	cur = cur->next;	\
   8138     }                           \
   8139     cur->next = annot;
   8140 
   8141 /**
   8142  * xmlSchemaAssignAnnotation:
   8143  * @item: the schema component
   8144  * @annot: the annotation
   8145  *
   8146  * Adds the annotation to the given schema component.
   8147  *
   8148  * Returns the given annotaion.
   8149  */
   8150 static xmlSchemaAnnotPtr
   8151 xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
   8152 		       xmlSchemaAnnotPtr annot)
   8153 {
   8154     if ((annItem == NULL) || (annot == NULL))
   8155 	return (NULL);
   8156     switch (annItem->type) {
   8157 	case XML_SCHEMA_TYPE_ELEMENT: {
   8158 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
   8159 		ADD_ANNOTATION(annot)
   8160 	    }
   8161 	    break;
   8162 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
   8163 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
   8164 		ADD_ANNOTATION(annot)
   8165 	    }
   8166 	    break;
   8167 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
   8168 	case XML_SCHEMA_TYPE_ANY: {
   8169 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
   8170 		ADD_ANNOTATION(annot)
   8171 	    }
   8172 	    break;
   8173 	case XML_SCHEMA_TYPE_PARTICLE:
   8174 	case XML_SCHEMA_TYPE_IDC_KEY:
   8175 	case XML_SCHEMA_TYPE_IDC_KEYREF:
   8176 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
   8177 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
   8178 		ADD_ANNOTATION(annot)
   8179 	    }
   8180 	    break;
   8181 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
   8182 		xmlSchemaAttributeGroupPtr item =
   8183 		    (xmlSchemaAttributeGroupPtr) annItem;
   8184 		ADD_ANNOTATION(annot)
   8185 	    }
   8186 	    break;
   8187 	case XML_SCHEMA_TYPE_NOTATION: {
   8188 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
   8189 		ADD_ANNOTATION(annot)
   8190 	    }
   8191 	    break;
   8192 	case XML_SCHEMA_FACET_MININCLUSIVE:
   8193 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
   8194 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
   8195 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   8196 	case XML_SCHEMA_FACET_TOTALDIGITS:
   8197 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
   8198 	case XML_SCHEMA_FACET_PATTERN:
   8199 	case XML_SCHEMA_FACET_ENUMERATION:
   8200 	case XML_SCHEMA_FACET_WHITESPACE:
   8201 	case XML_SCHEMA_FACET_LENGTH:
   8202 	case XML_SCHEMA_FACET_MAXLENGTH:
   8203 	case XML_SCHEMA_FACET_MINLENGTH: {
   8204 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
   8205 		ADD_ANNOTATION(annot)
   8206 	    }
   8207 	    break;
   8208 	case XML_SCHEMA_TYPE_SIMPLE:
   8209 	case XML_SCHEMA_TYPE_COMPLEX: {
   8210 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
   8211 		ADD_ANNOTATION(annot)
   8212 	    }
   8213 	    break;
   8214 	case XML_SCHEMA_TYPE_GROUP: {
   8215 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
   8216 		ADD_ANNOTATION(annot)
   8217 	    }
   8218 	    break;
   8219 	case XML_SCHEMA_TYPE_SEQUENCE:
   8220 	case XML_SCHEMA_TYPE_CHOICE:
   8221 	case XML_SCHEMA_TYPE_ALL: {
   8222 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
   8223 		ADD_ANNOTATION(annot)
   8224 	    }
   8225 	    break;
   8226 	default:
   8227 	     xmlSchemaPCustomErr(NULL,
   8228 		XML_SCHEMAP_INTERNAL,
   8229 		NULL, NULL,
   8230 		"Internal error: xmlSchemaAddAnnotation, "
   8231 		"The item is not a annotated schema component", NULL);
   8232 	     break;
   8233     }
   8234     return (annot);
   8235 }
   8236 
   8237 /**
   8238  * xmlSchemaParseIDCSelectorAndField:
   8239  * @ctxt:  a schema validation context
   8240  * @schema:  the schema being built
   8241  * @node:  a subtree containing XML Schema informations
   8242  *
   8243  * Parses a XML Schema identity-contraint definition's
   8244  * <selector> and <field> elements.
   8245  *
   8246  * Returns the parsed identity-constraint definition.
   8247  */
   8248 static xmlSchemaIDCSelectPtr
   8249 xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
   8250 			  xmlSchemaIDCPtr idc,
   8251 			  xmlNodePtr node,
   8252 			  int isField)
   8253 {
   8254     xmlSchemaIDCSelectPtr item;
   8255     xmlNodePtr child = NULL;
   8256     xmlAttrPtr attr;
   8257 
   8258     /*
   8259     * Check for illegal attributes.
   8260     */
   8261     attr = node->properties;
   8262     while (attr != NULL) {
   8263 	if (attr->ns == NULL) {
   8264 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8265 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
   8266 		xmlSchemaPIllegalAttrErr(ctxt,
   8267 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8268 	    }
   8269 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8270 	    xmlSchemaPIllegalAttrErr(ctxt,
   8271 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8272 	}
   8273 	attr = attr->next;
   8274     }
   8275     /*
   8276     * Create the item.
   8277     */
   8278     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
   8279     if (item == NULL) {
   8280         xmlSchemaPErrMemory(ctxt,
   8281 	    "allocating a 'selector' of an identity-constraint definition",
   8282 	    NULL);
   8283         return (NULL);
   8284     }
   8285     memset(item, 0, sizeof(xmlSchemaIDCSelect));
   8286     /*
   8287     * Attribute "xpath" (mandatory).
   8288     */
   8289     attr = xmlSchemaGetPropNode(node, "xpath");
   8290     if (attr == NULL) {
   8291 	xmlSchemaPMissingAttrErr(ctxt,
   8292 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8293 	    NULL, node,
   8294 	    "name", NULL);
   8295     } else {
   8296 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8297 	/*
   8298 	* URGENT TODO: "field"s have an other syntax than "selector"s.
   8299 	*/
   8300 
   8301 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
   8302 	    isField) == -1) {
   8303 	    xmlSchemaPErr(ctxt,
   8304 		(xmlNodePtr) attr,
   8305 		XML_SCHEMAP_INTERNAL,
   8306 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
   8307 		"validating the XPath expression of a IDC selector.\n",
   8308 		NULL, NULL);
   8309 	}
   8310 
   8311     }
   8312     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8313     /*
   8314     * And now for the children...
   8315     */
   8316     child = node->children;
   8317     if (IS_SCHEMA(child, "annotation")) {
   8318 	/*
   8319 	* Add the annotation to the parent IDC.
   8320 	*/
   8321 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
   8322 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   8323 	child = child->next;
   8324     }
   8325     if (child != NULL) {
   8326 	xmlSchemaPContentErr(ctxt,
   8327 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8328 	    NULL, node, child,
   8329 	    NULL, "(annotation?)");
   8330     }
   8331 
   8332     return (item);
   8333 }
   8334 
   8335 /**
   8336  * xmlSchemaParseIDC:
   8337  * @ctxt:  a schema validation context
   8338  * @schema:  the schema being built
   8339  * @node:  a subtree containing XML Schema informations
   8340  *
   8341  * Parses a XML Schema identity-contraint definition.
   8342  *
   8343  * Returns the parsed identity-constraint definition.
   8344  */
   8345 static xmlSchemaIDCPtr
   8346 xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
   8347 		  xmlSchemaPtr schema,
   8348 		  xmlNodePtr node,
   8349 		  xmlSchemaTypeType idcCategory,
   8350 		  const xmlChar *targetNamespace)
   8351 {
   8352     xmlSchemaIDCPtr item = NULL;
   8353     xmlNodePtr child = NULL;
   8354     xmlAttrPtr attr;
   8355     const xmlChar *name = NULL;
   8356     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
   8357 
   8358     /*
   8359     * Check for illegal attributes.
   8360     */
   8361     attr = node->properties;
   8362     while (attr != NULL) {
   8363 	if (attr->ns == NULL) {
   8364 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8365 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8366 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
   8367 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
   8368 		xmlSchemaPIllegalAttrErr(ctxt,
   8369 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8370 	    }
   8371 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8372 	    xmlSchemaPIllegalAttrErr(ctxt,
   8373 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8374 	}
   8375 	attr = attr->next;
   8376     }
   8377     /*
   8378     * Attribute "name" (mandatory).
   8379     */
   8380     attr = xmlSchemaGetPropNode(node, "name");
   8381     if (attr == NULL) {
   8382 	xmlSchemaPMissingAttrErr(ctxt,
   8383 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   8384 	    NULL, node,
   8385 	    "name", NULL);
   8386 	return (NULL);
   8387     } else if (xmlSchemaPValAttrNode(ctxt,
   8388 	NULL, attr,
   8389 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   8390 	return (NULL);
   8391     }
   8392     /* Create the component. */
   8393     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
   8394 	idcCategory, node);
   8395     if (item == NULL)
   8396 	return(NULL);
   8397 
   8398     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8399     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
   8400 	/*
   8401 	* Attribute "refer" (mandatory).
   8402 	*/
   8403 	attr = xmlSchemaGetPropNode(node, "refer");
   8404 	if (attr == NULL) {
   8405 	    xmlSchemaPMissingAttrErr(ctxt,
   8406 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8407 		NULL, node,
   8408 		"refer", NULL);
   8409 	} else {
   8410 	    /*
   8411 	    * Create a reference item.
   8412 	    */
   8413 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
   8414 		NULL, NULL);
   8415 	    if (item->ref == NULL)
   8416 		return (NULL);
   8417 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8418 		NULL, attr,
   8419 		&(item->ref->targetNamespace),
   8420 		&(item->ref->name));
   8421 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
   8422 		item->ref->targetNamespace);
   8423 	}
   8424     }
   8425     /*
   8426     * And now for the children...
   8427     */
   8428     child = node->children;
   8429     if (IS_SCHEMA(child, "annotation")) {
   8430 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8431 	child = child->next;
   8432     }
   8433     if (child == NULL) {
   8434 	xmlSchemaPContentErr(ctxt,
   8435 		XML_SCHEMAP_S4S_ELEM_MISSING,
   8436 		NULL, node, child,
   8437 		"A child element is missing",
   8438 		"(annotation?, (selector, field+))");
   8439     }
   8440     /*
   8441     * Child element <selector>.
   8442     */
   8443     if (IS_SCHEMA(child, "selector")) {
   8444 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
   8445 	    item, child, 0);
   8446 	child = child->next;
   8447 	/*
   8448 	* Child elements <field>.
   8449 	*/
   8450 	if (IS_SCHEMA(child, "field")) {
   8451 	    do {
   8452 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
   8453 		    item, child, 1);
   8454 		if (field != NULL) {
   8455 		    field->index = item->nbFields;
   8456 		    item->nbFields++;
   8457 		    if (lastField != NULL)
   8458 			lastField->next = field;
   8459 		    else
   8460 			item->fields = field;
   8461 		    lastField = field;
   8462 		}
   8463 		child = child->next;
   8464 	    } while (IS_SCHEMA(child, "field"));
   8465 	} else {
   8466 	    xmlSchemaPContentErr(ctxt,
   8467 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8468 		NULL, node, child,
   8469 		NULL, "(annotation?, (selector, field+))");
   8470 	}
   8471     }
   8472     if (child != NULL) {
   8473 	xmlSchemaPContentErr(ctxt,
   8474 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8475 	    NULL, node, child,
   8476 	    NULL, "(annotation?, (selector, field+))");
   8477     }
   8478 
   8479     return (item);
   8480 }
   8481 
   8482 /**
   8483  * xmlSchemaParseElement:
   8484  * @ctxt:  a schema validation context
   8485  * @schema:  the schema being built
   8486  * @node:  a subtree containing XML Schema informations
   8487  * @topLevel: indicates if this is global declaration
   8488  *
   8489  * Parses a XML schema element declaration.
   8490  * *WARNING* this interface is highly subject to change
   8491  *
   8492  * Returns the element declaration or a particle; NULL in case
   8493  * of an error or if the particle has minOccurs==maxOccurs==0.
   8494  */
   8495 static xmlSchemaBasicItemPtr
   8496 xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8497                       xmlNodePtr node, int *isElemRef, int topLevel)
   8498 {
   8499     xmlSchemaElementPtr decl = NULL;
   8500     xmlSchemaParticlePtr particle = NULL;
   8501     xmlSchemaAnnotPtr annot = NULL;
   8502     xmlNodePtr child = NULL;
   8503     xmlAttrPtr attr, nameAttr;
   8504     int min, max, isRef = 0;
   8505     xmlChar *des = NULL;
   8506 
   8507     /* 3.3.3 Constraints on XML Representations of Element Declarations */
   8508     /* TODO: Complete implementation of 3.3.6 */
   8509 
   8510     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8511         return (NULL);
   8512 
   8513     if (isElemRef != NULL)
   8514 	*isElemRef = 0;
   8515     /*
   8516     * If we get a "ref" attribute on a local <element> we will assume it's
   8517     * a reference - even if there's a "name" attribute; this seems to be more
   8518     * robust.
   8519     */
   8520     nameAttr = xmlSchemaGetPropNode(node, "name");
   8521     attr = xmlSchemaGetPropNode(node, "ref");
   8522     if ((topLevel) || (attr == NULL)) {
   8523 	if (nameAttr == NULL) {
   8524 	    xmlSchemaPMissingAttrErr(ctxt,
   8525 		XML_SCHEMAP_S4S_ATTR_MISSING,
   8526 		NULL, node, "name", NULL);
   8527 	    return (NULL);
   8528 	}
   8529     } else
   8530 	isRef = 1;
   8531 
   8532     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8533     child = node->children;
   8534     if (IS_SCHEMA(child, "annotation")) {
   8535 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   8536 	child = child->next;
   8537     }
   8538     /*
   8539     * Skip particle part if a global declaration.
   8540     */
   8541     if (topLevel)
   8542 	goto declaration_part;
   8543     /*
   8544     * The particle part ==================================================
   8545     */
   8546     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   8547     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
   8548     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   8549     particle = xmlSchemaAddParticle(ctxt, node, min, max);
   8550     if (particle == NULL)
   8551 	goto return_null;
   8552 
   8553     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
   8554 
   8555     if (isRef) {
   8556 	const xmlChar *refNs = NULL, *ref = NULL;
   8557 	xmlSchemaQNameRefPtr refer = NULL;
   8558 	/*
   8559 	* The reference part =============================================
   8560 	*/
   8561 	if (isElemRef != NULL)
   8562 	    *isElemRef = 1;
   8563 
   8564 	xmlSchemaPValAttrNodeQName(ctxt, schema,
   8565 	    NULL, attr, &refNs, &ref);
   8566 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   8567 	/*
   8568 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
   8569 	*/
   8570 	if (nameAttr != NULL) {
   8571 	    xmlSchemaPMutualExclAttrErr(ctxt,
   8572 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
   8573 	}
   8574 	/*
   8575 	* Check for illegal attributes.
   8576 	*/
   8577 	attr = node->properties;
   8578 	while (attr != NULL) {
   8579 	    if (attr->ns == NULL) {
   8580 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
   8581 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
   8582 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
   8583 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
   8584 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
   8585 		{
   8586 		    attr = attr->next;
   8587 		    continue;
   8588 		} else {
   8589 		    /* SPEC (3.3.3 : 2.2) */
   8590 		    xmlSchemaPCustomAttrErr(ctxt,
   8591 			XML_SCHEMAP_SRC_ELEMENT_2_2,
   8592 			NULL, NULL, attr,
   8593 			"Only the attributes 'minOccurs', 'maxOccurs' and "
   8594 			"'id' are allowed in addition to 'ref'");
   8595 		    break;
   8596 		}
   8597 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8598 		xmlSchemaPIllegalAttrErr(ctxt,
   8599 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8600 	    }
   8601 	    attr = attr->next;
   8602 	}
   8603 	/*
   8604 	* No children except <annotation> expected.
   8605 	*/
   8606 	if (child != NULL) {
   8607 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8608 		NULL, node, child, NULL, "(annotation?)");
   8609 	}
   8610 	if ((min == 0) && (max == 0))
   8611 	    goto return_null;
   8612 	/*
   8613 	* Create the reference item and attach it to the particle.
   8614 	*/
   8615 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
   8616 	    ref, refNs);
   8617 	if (refer == NULL)
   8618 	    goto return_null;
   8619 	particle->children = (xmlSchemaTreeItemPtr) refer;
   8620 	particle->annot = annot;
   8621 	/*
   8622 	* Add the particle to pending components, since the reference
   8623 	* need to be resolved.
   8624 	*/
   8625 	WXS_ADD_PENDING(ctxt, particle);
   8626 	return ((xmlSchemaBasicItemPtr) particle);
   8627     }
   8628     /*
   8629     * The declaration part ===============================================
   8630     */
   8631 declaration_part:
   8632     {
   8633 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
   8634 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
   8635 
   8636 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
   8637 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
   8638 	    goto return_null;
   8639 	/*
   8640 	* Evaluate the target namespace.
   8641 	*/
   8642 	if (topLevel) {
   8643 	    ns = ctxt->targetNamespace;
   8644 	} else {
   8645 	    attr = xmlSchemaGetPropNode(node, "form");
   8646 	    if (attr != NULL) {
   8647 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8648 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
   8649 		    ns = ctxt->targetNamespace;
   8650 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
   8651 		    xmlSchemaPSimpleTypeErr(ctxt,
   8652 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8653 			NULL, (xmlNodePtr) attr,
   8654 			NULL, "(qualified | unqualified)",
   8655 			attrValue, NULL, NULL, NULL);
   8656 		}
   8657 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   8658 		ns = ctxt->targetNamespace;
   8659 	}
   8660 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
   8661 	if (decl == NULL) {
   8662 	    goto return_null;
   8663 	}
   8664 	/*
   8665 	* Check for illegal attributes.
   8666 	*/
   8667 	attr = node->properties;
   8668 	while (attr != NULL) {
   8669 	    if (attr->ns == NULL) {
   8670 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   8671 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
   8672 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8673 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
   8674 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
   8675 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
   8676 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
   8677 		{
   8678 		    if (topLevel == 0) {
   8679 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   8680 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   8681 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
   8682 			{
   8683 			    xmlSchemaPIllegalAttrErr(ctxt,
   8684 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8685 			}
   8686 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
   8687 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
   8688 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
   8689 
   8690 			xmlSchemaPIllegalAttrErr(ctxt,
   8691 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8692 		    }
   8693 		}
   8694 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8695 
   8696 		xmlSchemaPIllegalAttrErr(ctxt,
   8697 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8698 	    }
   8699 	    attr = attr->next;
   8700 	}
   8701 	/*
   8702 	* Extract/validate attributes.
   8703 	*/
   8704 	if (topLevel) {
   8705 	    /*
   8706 	    * Process top attributes of global element declarations here.
   8707 	    */
   8708 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
   8709 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
   8710 	    xmlSchemaPValAttrQName(ctxt, schema,
   8711 		NULL, node, "substitutionGroup",
   8712 		&(decl->substGroupNs), &(decl->substGroup));
   8713 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
   8714 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
   8715 	    /*
   8716 	    * Attribute "final".
   8717 	    */
   8718 	    attr = xmlSchemaGetPropNode(node, "final");
   8719 	    if (attr == NULL) {
   8720 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   8721 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
   8722 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   8723 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
   8724 	    } else {
   8725 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8726 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8727 		    -1,
   8728 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
   8729 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
   8730 		    xmlSchemaPSimpleTypeErr(ctxt,
   8731 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8732 			NULL, (xmlNodePtr) attr,
   8733 			NULL, "(#all | List of (extension | restriction))",
   8734 			attrValue, NULL, NULL, NULL);
   8735 		}
   8736 	    }
   8737 	}
   8738 	/*
   8739 	* Attribute "block".
   8740 	*/
   8741 	attr = xmlSchemaGetPropNode(node, "block");
   8742 	if (attr == NULL) {
   8743 	    /*
   8744 	    * Apply default "block" values.
   8745 	    */
   8746 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   8747 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
   8748 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   8749 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
   8750 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   8751 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
   8752 	} else {
   8753 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8754 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
   8755 		-1,
   8756 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
   8757 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
   8758 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
   8759 		xmlSchemaPSimpleTypeErr(ctxt,
   8760 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   8761 		    NULL, (xmlNodePtr) attr,
   8762 		    NULL, "(#all | List of (extension | "
   8763 		    "restriction | substitution))", attrValue,
   8764 		    NULL, NULL, NULL);
   8765 	    }
   8766 	}
   8767 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
   8768 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
   8769 
   8770 	attr = xmlSchemaGetPropNode(node, "type");
   8771 	if (attr != NULL) {
   8772 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
   8773 		NULL, attr,
   8774 		&(decl->namedTypeNs), &(decl->namedType));
   8775 	    xmlSchemaCheckReference(ctxt, schema, node,
   8776 		attr, decl->namedTypeNs);
   8777 	}
   8778 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
   8779 	attr = xmlSchemaGetPropNode(node, "fixed");
   8780 	if (attr != NULL) {
   8781 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8782 	    if (decl->value != NULL) {
   8783 		/*
   8784 		* 3.3.3 : 1
   8785 		* default and fixed must not both be present.
   8786 		*/
   8787 		xmlSchemaPMutualExclAttrErr(ctxt,
   8788 		    XML_SCHEMAP_SRC_ELEMENT_1,
   8789 		    NULL, attr, "default", "fixed");
   8790 	    } else {
   8791 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
   8792 		decl->value = fixed;
   8793 	    }
   8794 	}
   8795 	/*
   8796 	* And now for the children...
   8797 	*/
   8798 	if (IS_SCHEMA(child, "complexType")) {
   8799 	    /*
   8800 	    * 3.3.3 : 3
   8801 	    * "type" and either <simpleType> or <complexType> are mutually
   8802 	    * exclusive
   8803 	    */
   8804 	    if (decl->namedType != NULL) {
   8805 		xmlSchemaPContentErr(ctxt,
   8806 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8807 		    NULL, node, child,
   8808 		    "The attribute 'type' and the <complexType> child are "
   8809 		    "mutually exclusive", NULL);
   8810 	    } else
   8811 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
   8812 	    child = child->next;
   8813 	} else if (IS_SCHEMA(child, "simpleType")) {
   8814 	    /*
   8815 	    * 3.3.3 : 3
   8816 	    * "type" and either <simpleType> or <complexType> are
   8817 	    * mutually exclusive
   8818 	    */
   8819 	    if (decl->namedType != NULL) {
   8820 		xmlSchemaPContentErr(ctxt,
   8821 		    XML_SCHEMAP_SRC_ELEMENT_3,
   8822 		    NULL, node, child,
   8823 		    "The attribute 'type' and the <simpleType> child are "
   8824 		    "mutually exclusive", NULL);
   8825 	    } else
   8826 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   8827 	    child = child->next;
   8828 	}
   8829 	while ((IS_SCHEMA(child, "unique")) ||
   8830 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
   8831 	    if (IS_SCHEMA(child, "unique")) {
   8832 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8833 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
   8834 	    } else if (IS_SCHEMA(child, "key")) {
   8835 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8836 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
   8837 	    } else if (IS_SCHEMA(child, "keyref")) {
   8838 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
   8839 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
   8840 	    }
   8841 	    if (lastIDC != NULL)
   8842 		lastIDC->next = curIDC;
   8843 	    else
   8844 		decl->idcs = (void *) curIDC;
   8845 	    lastIDC = curIDC;
   8846 	    child = child->next;
   8847 	}
   8848 	if (child != NULL) {
   8849 	    xmlSchemaPContentErr(ctxt,
   8850 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   8851 		NULL, node, child,
   8852 		NULL, "(annotation?, ((simpleType | complexType)?, "
   8853 		"(unique | key | keyref)*))");
   8854 	}
   8855 	decl->annot = annot;
   8856     }
   8857     /*
   8858     * NOTE: Element Declaration Representation OK 4. will be checked at a
   8859     * different layer.
   8860     */
   8861     FREE_AND_NULL(des)
   8862     if (topLevel)
   8863 	return ((xmlSchemaBasicItemPtr) decl);
   8864     else {
   8865 	particle->children = (xmlSchemaTreeItemPtr) decl;
   8866 	return ((xmlSchemaBasicItemPtr) particle);
   8867     }
   8868 
   8869 return_null:
   8870     FREE_AND_NULL(des);
   8871     if (annot != NULL) {
   8872 	if (particle != NULL)
   8873 	    particle->annot = NULL;
   8874 	if (decl != NULL)
   8875 	    decl->annot = NULL;
   8876 	xmlSchemaFreeAnnot(annot);
   8877     }
   8878     return (NULL);
   8879 }
   8880 
   8881 /**
   8882  * xmlSchemaParseUnion:
   8883  * @ctxt:  a schema validation context
   8884  * @schema:  the schema being built
   8885  * @node:  a subtree containing XML Schema informations
   8886  *
   8887  * parse a XML schema Union definition
   8888  * *WARNING* this interface is highly subject to change
   8889  *
   8890  * Returns -1 in case of internal error, 0 in case of success and a positive
   8891  * error code otherwise.
   8892  */
   8893 static int
   8894 xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   8895                     xmlNodePtr node)
   8896 {
   8897     xmlSchemaTypePtr type;
   8898     xmlNodePtr child = NULL;
   8899     xmlAttrPtr attr;
   8900     const xmlChar *cur = NULL;
   8901 
   8902     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   8903         return (-1);
   8904     /* Not a component, don't create it. */
   8905     type = ctxt->ctxtType;
   8906     /*
   8907     * Mark the simple type as being of variety "union".
   8908     */
   8909     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   8910     /*
   8911     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   8912     * then the `simple ur-type definition`."
   8913     */
   8914     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   8915     /*
   8916     * Check for illegal attributes.
   8917     */
   8918     attr = node->properties;
   8919     while (attr != NULL) {
   8920 	if (attr->ns == NULL) {
   8921 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   8922 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
   8923 		xmlSchemaPIllegalAttrErr(ctxt,
   8924 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8925 	    }
   8926 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   8927 	    xmlSchemaPIllegalAttrErr(ctxt,
   8928 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   8929 	}
   8930 	attr = attr->next;
   8931     }
   8932     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   8933     /*
   8934     * Attribute "memberTypes". This is a list of QNames.
   8935     * TODO: Check the value to contain anything.
   8936     */
   8937     attr = xmlSchemaGetPropNode(node, "memberTypes");
   8938     if (attr != NULL) {
   8939 	const xmlChar *end;
   8940 	xmlChar *tmp;
   8941 	const xmlChar *localName, *nsName;
   8942 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
   8943 	xmlSchemaQNameRefPtr ref;
   8944 
   8945 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   8946 	type->base = cur;
   8947 	do {
   8948 	    while (IS_BLANK_CH(*cur))
   8949 		cur++;
   8950 	    end = cur;
   8951 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   8952 		end++;
   8953 	    if (end == cur)
   8954 		break;
   8955 	    tmp = xmlStrndup(cur, end - cur);
   8956 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
   8957 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
   8958 		/*
   8959 		* Create the member type link.
   8960 		*/
   8961 		link = (xmlSchemaTypeLinkPtr)
   8962 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
   8963 		if (link == NULL) {
   8964 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
   8965 			"allocating a type link", NULL);
   8966 		    return (-1);
   8967 		}
   8968 		link->type = NULL;
   8969 		link->next = NULL;
   8970 		if (lastLink == NULL)
   8971 		    type->memberTypes = link;
   8972 		else
   8973 		    lastLink->next = link;
   8974 		lastLink = link;
   8975 		/*
   8976 		* Create a reference item.
   8977 		*/
   8978 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
   8979 		    localName, nsName);
   8980 		if (ref == NULL) {
   8981 		    FREE_AND_NULL(tmp)
   8982 		    return (-1);
   8983 		}
   8984 		/*
   8985 		* Assign the reference to the link, it will be resolved
   8986 		* later during fixup of the union simple type.
   8987 		*/
   8988 		link->type = (xmlSchemaTypePtr) ref;
   8989 	    }
   8990 	    FREE_AND_NULL(tmp)
   8991 	    cur = end;
   8992 	} while (*cur != 0);
   8993 
   8994     }
   8995     /*
   8996     * And now for the children...
   8997     */
   8998     child = node->children;
   8999     if (IS_SCHEMA(child, "annotation")) {
   9000 	/*
   9001 	* Add the annotation to the simple type ancestor.
   9002 	*/
   9003 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   9004 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   9005         child = child->next;
   9006     }
   9007     if (IS_SCHEMA(child, "simpleType")) {
   9008 	xmlSchemaTypePtr subtype, last = NULL;
   9009 
   9010 	/*
   9011 	* Anchor the member types in the "subtypes" field of the
   9012 	* simple type.
   9013 	*/
   9014 	while (IS_SCHEMA(child, "simpleType")) {
   9015 	    subtype = (xmlSchemaTypePtr)
   9016 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   9017 	    if (subtype != NULL) {
   9018 		if (last == NULL) {
   9019 		    type->subtypes = subtype;
   9020 		    last = subtype;
   9021 		} else {
   9022 		    last->next = subtype;
   9023 		    last = subtype;
   9024 		}
   9025 		last->next = NULL;
   9026 	    }
   9027 	    child = child->next;
   9028 	}
   9029     }
   9030     if (child != NULL) {
   9031 	xmlSchemaPContentErr(ctxt,
   9032 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9033 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
   9034     }
   9035     if ((attr == NULL) && (type->subtypes == NULL)) {
   9036 	 /*
   9037 	* src-union-memberTypes-or-simpleTypes
   9038 	* Either the memberTypes [attribute] of the <union> element must
   9039 	* be non-empty or there must be at least one simpleType [child].
   9040 	*/
   9041 	xmlSchemaPCustomErr(ctxt,
   9042 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
   9043 	    NULL, node,
   9044 	    "Either the attribute 'memberTypes' or "
   9045 	    "at least one <simpleType> child must be present", NULL);
   9046     }
   9047     return (0);
   9048 }
   9049 
   9050 /**
   9051  * xmlSchemaParseList:
   9052  * @ctxt:  a schema validation context
   9053  * @schema:  the schema being built
   9054  * @node:  a subtree containing XML Schema informations
   9055  *
   9056  * parse a XML schema List definition
   9057  * *WARNING* this interface is highly subject to change
   9058  *
   9059  * Returns -1 in case of error, 0 if the declaration is improper and
   9060  *         1 in case of success.
   9061  */
   9062 static xmlSchemaTypePtr
   9063 xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9064                    xmlNodePtr node)
   9065 {
   9066     xmlSchemaTypePtr type;
   9067     xmlNodePtr child = NULL;
   9068     xmlAttrPtr attr;
   9069 
   9070     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9071         return (NULL);
   9072     /* Not a component, don't create it. */
   9073     type = ctxt->ctxtType;
   9074     /*
   9075     * Mark the type as being of variety "list".
   9076     */
   9077     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   9078     /*
   9079     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
   9080     * then the `simple ur-type definition`."
   9081     */
   9082     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   9083     /*
   9084     * Check for illegal attributes.
   9085     */
   9086     attr = node->properties;
   9087     while (attr != NULL) {
   9088 	if (attr->ns == NULL) {
   9089 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9090 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
   9091 		xmlSchemaPIllegalAttrErr(ctxt,
   9092 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9093 	    }
   9094 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9095 	    xmlSchemaPIllegalAttrErr(ctxt,
   9096 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9097 	}
   9098 	attr = attr->next;
   9099     }
   9100 
   9101     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9102 
   9103     /*
   9104     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
   9105     * fields for holding the reference to the itemType.
   9106     *
   9107     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
   9108     * the "ref" fields.
   9109     */
   9110     xmlSchemaPValAttrQName(ctxt, schema, NULL,
   9111 	node, "itemType", &(type->baseNs), &(type->base));
   9112     /*
   9113     * And now for the children...
   9114     */
   9115     child = node->children;
   9116     if (IS_SCHEMA(child, "annotation")) {
   9117 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   9118 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   9119         child = child->next;
   9120     }
   9121     if (IS_SCHEMA(child, "simpleType")) {
   9122 	/*
   9123 	* src-list-itemType-or-simpleType
   9124 	* Either the itemType [attribute] or the <simpleType> [child] of
   9125 	* the <list> element must be present, but not both.
   9126 	*/
   9127 	if (type->base != NULL) {
   9128 	    xmlSchemaPCustomErr(ctxt,
   9129 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9130 		NULL, node,
   9131 		"The attribute 'itemType' and the <simpleType> child "
   9132 		"are mutually exclusive", NULL);
   9133 	} else {
   9134 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   9135 	}
   9136         child = child->next;
   9137     } else if (type->base == NULL) {
   9138 	xmlSchemaPCustomErr(ctxt,
   9139 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9140 	    NULL, node,
   9141 	    "Either the attribute 'itemType' or the <simpleType> child "
   9142 	    "must be present", NULL);
   9143     }
   9144     if (child != NULL) {
   9145 	xmlSchemaPContentErr(ctxt,
   9146 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9147 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
   9148     }
   9149     if ((type->base == NULL) &&
   9150 	(type->subtypes == NULL) &&
   9151 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
   9152 	xmlSchemaPCustomErr(ctxt,
   9153 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   9154 	    NULL, node,
   9155 	    "Either the attribute 'itemType' or the <simpleType> child "
   9156 	    "must be present", NULL);
   9157     }
   9158     return (NULL);
   9159 }
   9160 
   9161 /**
   9162  * xmlSchemaParseSimpleType:
   9163  * @ctxt:  a schema validation context
   9164  * @schema:  the schema being built
   9165  * @node:  a subtree containing XML Schema informations
   9166  *
   9167  * parse a XML schema Simple Type definition
   9168  * *WARNING* this interface is highly subject to change
   9169  *
   9170  * Returns -1 in case of error, 0 if the declaration is improper and
   9171  * 1 in case of success.
   9172  */
   9173 static xmlSchemaTypePtr
   9174 xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   9175                          xmlNodePtr node, int topLevel)
   9176 {
   9177     xmlSchemaTypePtr type, oldCtxtType;
   9178     xmlNodePtr child = NULL;
   9179     const xmlChar *attrValue = NULL;
   9180     xmlAttrPtr attr;
   9181     int hasRestriction = 0;
   9182 
   9183     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9184         return (NULL);
   9185 
   9186     if (topLevel) {
   9187 	attr = xmlSchemaGetPropNode(node, "name");
   9188 	if (attr == NULL) {
   9189 	    xmlSchemaPMissingAttrErr(ctxt,
   9190 		XML_SCHEMAP_S4S_ATTR_MISSING,
   9191 		NULL, node,
   9192 		"name", NULL);
   9193 	    return (NULL);
   9194 	} else {
   9195 	    if (xmlSchemaPValAttrNode(ctxt,
   9196 		NULL, attr,
   9197 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
   9198 		return (NULL);
   9199 	    /*
   9200 	    * Skip built-in types.
   9201 	    */
   9202 	    if (ctxt->isS4S) {
   9203 		xmlSchemaTypePtr biType;
   9204 
   9205 		if (ctxt->isRedefine) {
   9206 		    /*
   9207 		    * REDEFINE: Disallow redefinition of built-in-types.
   9208 		    * TODO: It seems that the spec does not say anything
   9209 		    * about this case.
   9210 		    */
   9211 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9212 			NULL, node,
   9213 			"Redefinition of built-in simple types is not "
   9214 			"supported", NULL);
   9215 		    return(NULL);
   9216 		}
   9217 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
   9218 		if (biType != NULL)
   9219 		    return (biType);
   9220 	    }
   9221 	}
   9222     }
   9223     /*
   9224     * TargetNamespace:
   9225     * SPEC "The `actual value` of the targetNamespace [attribute]
   9226     * of the <schema> ancestor element information item if present,
   9227     * otherwise `absent`.
   9228     */
   9229     if (topLevel == 0) {
   9230 #ifdef ENABLE_NAMED_LOCALS
   9231         char buf[40];
   9232 #endif
   9233 	/*
   9234 	* Parse as local simple type definition.
   9235 	*/
   9236 #ifdef ENABLE_NAMED_LOCALS
   9237         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
   9238 	type = xmlSchemaAddType(ctxt, schema,
   9239 	    XML_SCHEMA_TYPE_SIMPLE,
   9240 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   9241 	    ctxt->targetNamespace, node, 0);
   9242 #else
   9243 	type = xmlSchemaAddType(ctxt, schema,
   9244 	    XML_SCHEMA_TYPE_SIMPLE,
   9245 	    NULL, ctxt->targetNamespace, node, 0);
   9246 #endif
   9247 	if (type == NULL)
   9248 	    return (NULL);
   9249 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9250 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9251 	/*
   9252 	* Check for illegal attributes.
   9253 	*/
   9254 	attr = node->properties;
   9255 	while (attr != NULL) {
   9256 	    if (attr->ns == NULL) {
   9257 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   9258 		    xmlSchemaPIllegalAttrErr(ctxt,
   9259 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9260 		}
   9261 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9262 		    xmlSchemaPIllegalAttrErr(ctxt,
   9263 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9264 	    }
   9265 	    attr = attr->next;
   9266 	}
   9267     } else {
   9268 	/*
   9269 	* Parse as global simple type definition.
   9270 	*
   9271 	* Note that attrValue is the value of the attribute "name" here.
   9272 	*/
   9273 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
   9274 	    attrValue, ctxt->targetNamespace, node, 1);
   9275 	if (type == NULL)
   9276 	    return (NULL);
   9277 	type->type = XML_SCHEMA_TYPE_SIMPLE;
   9278 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   9279 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   9280 	/*
   9281 	* Check for illegal attributes.
   9282 	*/
   9283 	attr = node->properties;
   9284 	while (attr != NULL) {
   9285 	    if (attr->ns == NULL) {
   9286 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9287 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9288 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
   9289 		    xmlSchemaPIllegalAttrErr(ctxt,
   9290 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9291 		}
   9292 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9293 		xmlSchemaPIllegalAttrErr(ctxt,
   9294 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9295 	    }
   9296 	    attr = attr->next;
   9297 	}
   9298 	/*
   9299 	* Attribute "final".
   9300 	*/
   9301 	attr = xmlSchemaGetPropNode(node, "final");
   9302 	if (attr == NULL) {
   9303 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9304 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   9305 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9306 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
   9307 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9308 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
   9309 	} else {
   9310 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
   9311 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   9312 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
   9313 		XML_SCHEMAS_TYPE_FINAL_LIST,
   9314 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
   9315 
   9316 		xmlSchemaPSimpleTypeErr(ctxt,
   9317 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9318 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
   9319 		    NULL, "(#all | List of (list | union | restriction)",
   9320 		    attrValue, NULL, NULL, NULL);
   9321 	    }
   9322 	}
   9323     }
   9324     type->targetNamespace = ctxt->targetNamespace;
   9325     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9326     /*
   9327     * And now for the children...
   9328     */
   9329     oldCtxtType = ctxt->ctxtType;
   9330 
   9331     ctxt->ctxtType = type;
   9332 
   9333     child = node->children;
   9334     if (IS_SCHEMA(child, "annotation")) {
   9335         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9336         child = child->next;
   9337     }
   9338     if (child == NULL) {
   9339 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
   9340 	    NULL, node, child, NULL,
   9341 	    "(annotation?, (restriction | list | union))");
   9342     } else if (IS_SCHEMA(child, "restriction")) {
   9343         xmlSchemaParseRestriction(ctxt, schema, child,
   9344 	    XML_SCHEMA_TYPE_SIMPLE);
   9345 	hasRestriction = 1;
   9346         child = child->next;
   9347     } else if (IS_SCHEMA(child, "list")) {
   9348         xmlSchemaParseList(ctxt, schema, child);
   9349         child = child->next;
   9350     } else if (IS_SCHEMA(child, "union")) {
   9351         xmlSchemaParseUnion(ctxt, schema, child);
   9352         child = child->next;
   9353     }
   9354     if (child != NULL) {
   9355 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9356 	    NULL, node, child, NULL,
   9357 	    "(annotation?, (restriction | list | union))");
   9358     }
   9359     /*
   9360     * REDEFINE: SPEC src-redefine (5)
   9361     * "Within the [children], each <simpleType> must have a
   9362     * <restriction> among its [children] ... the `actual value` of whose
   9363     * base [attribute] must be the same as the `actual value` of its own
   9364     * name attribute plus target namespace;"
   9365     */
   9366     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
   9367 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   9368 	    NULL, node, "This is a redefinition, thus the "
   9369 	    "<simpleType> must have a <restriction> child", NULL);
   9370     }
   9371 
   9372     ctxt->ctxtType = oldCtxtType;
   9373     return (type);
   9374 }
   9375 
   9376 /**
   9377  * xmlSchemaParseModelGroupDefRef:
   9378  * @ctxt:  the parser context
   9379  * @schema: the schema being built
   9380  * @node:  the node
   9381  *
   9382  * Parses a reference to a model group definition.
   9383  *
   9384  * We will return a particle component with a qname-component or
   9385  * NULL in case of an error.
   9386  */
   9387 static xmlSchemaTreeItemPtr
   9388 xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
   9389 			       xmlSchemaPtr schema,
   9390 			       xmlNodePtr node)
   9391 {
   9392     xmlSchemaParticlePtr item;
   9393     xmlNodePtr child = NULL;
   9394     xmlAttrPtr attr;
   9395     const xmlChar *ref = NULL, *refNs = NULL;
   9396     int min, max;
   9397 
   9398     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9399         return (NULL);
   9400 
   9401     attr = xmlSchemaGetPropNode(node, "ref");
   9402     if (attr == NULL) {
   9403 	xmlSchemaPMissingAttrErr(ctxt,
   9404 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9405 	    NULL, node, "ref", NULL);
   9406 	return (NULL);
   9407     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
   9408 	attr, &refNs, &ref) != 0) {
   9409 	return (NULL);
   9410     }
   9411     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
   9412     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   9413     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   9414 	"(xs:nonNegativeInteger | unbounded)");
   9415     /*
   9416     * Check for illegal attributes.
   9417     */
   9418     attr = node->properties;
   9419     while (attr != NULL) {
   9420 	if (attr->ns == NULL) {
   9421 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
   9422 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   9423 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
   9424 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
   9425 		xmlSchemaPIllegalAttrErr(ctxt,
   9426 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9427 	    }
   9428 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9429 	    xmlSchemaPIllegalAttrErr(ctxt,
   9430 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9431 	}
   9432 	attr = attr->next;
   9433     }
   9434     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9435     item = xmlSchemaAddParticle(ctxt, node, min, max);
   9436     if (item == NULL)
   9437 	return (NULL);
   9438     /*
   9439     * Create a qname-reference and set as the term; it will be substituted
   9440     * for the model group after the reference has been resolved.
   9441     */
   9442     item->children = (xmlSchemaTreeItemPtr)
   9443 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
   9444     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
   9445     /*
   9446     * And now for the children...
   9447     */
   9448     child = node->children;
   9449     /* TODO: Is annotation even allowed for a model group reference? */
   9450     if (IS_SCHEMA(child, "annotation")) {
   9451 	/*
   9452 	* TODO: What to do exactly with the annotation?
   9453 	*/
   9454 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9455 	child = child->next;
   9456     }
   9457     if (child != NULL) {
   9458 	xmlSchemaPContentErr(ctxt,
   9459 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9460 	    NULL, node, child, NULL,
   9461 	    "(annotation?)");
   9462     }
   9463     /*
   9464     * Corresponds to no component at all if minOccurs==maxOccurs==0.
   9465     */
   9466     if ((min == 0) && (max == 0))
   9467 	return (NULL);
   9468 
   9469     return ((xmlSchemaTreeItemPtr) item);
   9470 }
   9471 
   9472 /**
   9473  * xmlSchemaParseModelGroupDefinition:
   9474  * @ctxt:  a schema validation context
   9475  * @schema:  the schema being built
   9476  * @node:  a subtree containing XML Schema informations
   9477  *
   9478  * Parses a XML schema model group definition.
   9479  *
   9480  * Note that the contraint src-redefine (6.2) can't be applied until
   9481  * references have been resolved. So we will do this at the
   9482  * component fixup level.
   9483  *
   9484  * *WARNING* this interface is highly subject to change
   9485  *
   9486  * Returns -1 in case of error, 0 if the declaration is improper and
   9487  *         1 in case of success.
   9488  */
   9489 static xmlSchemaModelGroupDefPtr
   9490 xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
   9491 				   xmlSchemaPtr schema,
   9492 				   xmlNodePtr node)
   9493 {
   9494     xmlSchemaModelGroupDefPtr item;
   9495     xmlNodePtr child = NULL;
   9496     xmlAttrPtr attr;
   9497     const xmlChar *name;
   9498 
   9499     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   9500         return (NULL);
   9501 
   9502     attr = xmlSchemaGetPropNode(node, "name");
   9503     if (attr == NULL) {
   9504 	xmlSchemaPMissingAttrErr(ctxt,
   9505 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   9506 	    NULL, node,
   9507 	    "name", NULL);
   9508 	return (NULL);
   9509     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9510 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   9511 	return (NULL);
   9512     }
   9513     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
   9514 	ctxt->targetNamespace, node);
   9515     if (item == NULL)
   9516 	return (NULL);
   9517     /*
   9518     * Check for illegal attributes.
   9519     */
   9520     attr = node->properties;
   9521     while (attr != NULL) {
   9522 	if (attr->ns == NULL) {
   9523 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
   9524 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   9525 		xmlSchemaPIllegalAttrErr(ctxt,
   9526 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9527 	    }
   9528 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   9529 	    xmlSchemaPIllegalAttrErr(ctxt,
   9530 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   9531 	}
   9532 	attr = attr->next;
   9533     }
   9534     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9535     /*
   9536     * And now for the children...
   9537     */
   9538     child = node->children;
   9539     if (IS_SCHEMA(child, "annotation")) {
   9540 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9541 	child = child->next;
   9542     }
   9543     if (IS_SCHEMA(child, "all")) {
   9544 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9545 	    XML_SCHEMA_TYPE_ALL, 0);
   9546 	child = child->next;
   9547     } else if (IS_SCHEMA(child, "choice")) {
   9548 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9549 	    XML_SCHEMA_TYPE_CHOICE, 0);
   9550 	child = child->next;
   9551     } else if (IS_SCHEMA(child, "sequence")) {
   9552 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
   9553 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
   9554 	child = child->next;
   9555     }
   9556 
   9557 
   9558 
   9559     if (child != NULL) {
   9560 	xmlSchemaPContentErr(ctxt,
   9561 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9562 	    NULL, node, child, NULL,
   9563 	    "(annotation?, (all | choice | sequence)?)");
   9564     }
   9565     return (item);
   9566 }
   9567 
   9568 /**
   9569  * xmlSchemaCleanupDoc:
   9570  * @ctxt:  a schema validation context
   9571  * @node:  the root of the document.
   9572  *
   9573  * removes unwanted nodes in a schemas document tree
   9574  */
   9575 static void
   9576 xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
   9577 {
   9578     xmlNodePtr delete, cur;
   9579 
   9580     if ((ctxt == NULL) || (root == NULL)) return;
   9581 
   9582     /*
   9583      * Remove all the blank text nodes
   9584      */
   9585     delete = NULL;
   9586     cur = root;
   9587     while (cur != NULL) {
   9588         if (delete != NULL) {
   9589             xmlUnlinkNode(delete);
   9590             xmlFreeNode(delete);
   9591             delete = NULL;
   9592         }
   9593         if (cur->type == XML_TEXT_NODE) {
   9594             if (IS_BLANK_NODE(cur)) {
   9595                 if (xmlNodeGetSpacePreserve(cur) != 1) {
   9596                     delete = cur;
   9597                 }
   9598             }
   9599         } else if ((cur->type != XML_ELEMENT_NODE) &&
   9600                    (cur->type != XML_CDATA_SECTION_NODE)) {
   9601             delete = cur;
   9602             goto skip_children;
   9603         }
   9604 
   9605         /*
   9606          * Skip to next node
   9607          */
   9608         if (cur->children != NULL) {
   9609             if ((cur->children->type != XML_ENTITY_DECL) &&
   9610                 (cur->children->type != XML_ENTITY_REF_NODE) &&
   9611                 (cur->children->type != XML_ENTITY_NODE)) {
   9612                 cur = cur->children;
   9613                 continue;
   9614             }
   9615         }
   9616       skip_children:
   9617         if (cur->next != NULL) {
   9618             cur = cur->next;
   9619             continue;
   9620         }
   9621 
   9622         do {
   9623             cur = cur->parent;
   9624             if (cur == NULL)
   9625                 break;
   9626             if (cur == root) {
   9627                 cur = NULL;
   9628                 break;
   9629             }
   9630             if (cur->next != NULL) {
   9631                 cur = cur->next;
   9632                 break;
   9633             }
   9634         } while (cur != NULL);
   9635     }
   9636     if (delete != NULL) {
   9637         xmlUnlinkNode(delete);
   9638         xmlFreeNode(delete);
   9639         delete = NULL;
   9640     }
   9641 }
   9642 
   9643 
   9644 static void
   9645 xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
   9646 {
   9647     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
   9648 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
   9649 
   9650     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
   9651 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
   9652 
   9653     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   9654 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
   9655     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   9656 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
   9657     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
   9658 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
   9659     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
   9660 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
   9661 
   9662     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   9663 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
   9664     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   9665 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
   9666     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
   9667 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
   9668 }
   9669 
   9670 static int
   9671 xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
   9672 			     xmlSchemaPtr schema,
   9673 			     xmlNodePtr node)
   9674 {
   9675     xmlAttrPtr attr;
   9676     const xmlChar *val;
   9677     int res = 0, oldErrs = ctxt->nberrors;
   9678 
   9679     /*
   9680     * Those flags should be moved to the parser context flags,
   9681     * since they are not visible at the component level. I.e.
   9682     * they are used if processing schema *documents* only.
   9683     */
   9684     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   9685     HFAILURE;
   9686 
   9687     /*
   9688     * Since the version is of type xs:token, we won't bother to
   9689     * check it.
   9690     */
   9691     /* REMOVED:
   9692     attr = xmlSchemaGetPropNode(node, "version");
   9693     if (attr != NULL) {
   9694 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
   9695 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
   9696 	HFAILURE;
   9697     }
   9698     */
   9699     attr = xmlSchemaGetPropNode(node, "targetNamespace");
   9700     if (attr != NULL) {
   9701 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
   9702 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
   9703 	HFAILURE;
   9704 	if (res != 0) {
   9705 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
   9706 	    goto exit;
   9707 	}
   9708     }
   9709     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
   9710     if (attr != NULL) {
   9711 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9712 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9713 	    XML_SCHEMAS_QUALIF_ELEM);
   9714 	HFAILURE;
   9715 	if (res != 0) {
   9716 	    xmlSchemaPSimpleTypeErr(ctxt,
   9717 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
   9718 		NULL, (xmlNodePtr) attr, NULL,
   9719 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9720 	}
   9721     }
   9722     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
   9723     if (attr != NULL) {
   9724 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9725 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
   9726 	    XML_SCHEMAS_QUALIF_ATTR);
   9727 	HFAILURE;
   9728 	if (res != 0) {
   9729 	    xmlSchemaPSimpleTypeErr(ctxt,
   9730 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
   9731 		NULL, (xmlNodePtr) attr, NULL,
   9732 		"(qualified | unqualified)", val, NULL, NULL, NULL);
   9733 	}
   9734     }
   9735     attr = xmlSchemaGetPropNode(node, "finalDefault");
   9736     if (attr != NULL) {
   9737 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9738 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9739 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
   9740 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
   9741 	    -1,
   9742 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
   9743 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
   9744 	HFAILURE;
   9745 	if (res != 0) {
   9746 	    xmlSchemaPSimpleTypeErr(ctxt,
   9747 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9748 		NULL, (xmlNodePtr) attr, NULL,
   9749 		"(#all | List of (extension | restriction | list | union))",
   9750 		val, NULL, NULL, NULL);
   9751 	}
   9752     }
   9753     attr = xmlSchemaGetPropNode(node, "blockDefault");
   9754     if (attr != NULL) {
   9755 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
   9756 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
   9757 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
   9758 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
   9759 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
   9760 	HFAILURE;
   9761 	if (res != 0) {
   9762 	    xmlSchemaPSimpleTypeErr(ctxt,
   9763 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   9764 		NULL, (xmlNodePtr) attr, NULL,
   9765 		"(#all | List of (extension | restriction | substitution))",
   9766 		val, NULL, NULL, NULL);
   9767 	}
   9768     }
   9769 
   9770 exit:
   9771     if (oldErrs != ctxt->nberrors)
   9772 	res = ctxt->err;
   9773     return(res);
   9774 exit_failure:
   9775     return(-1);
   9776 }
   9777 
   9778 /**
   9779  * xmlSchemaParseSchemaTopLevel:
   9780  * @ctxt:  a schema validation context
   9781  * @schema:  the schemas
   9782  * @nodes:  the list of top level nodes
   9783  *
   9784  * Returns the internal XML Schema structure built from the resource or
   9785  *         NULL in case of error
   9786  */
   9787 static int
   9788 xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
   9789                              xmlSchemaPtr schema, xmlNodePtr nodes)
   9790 {
   9791     xmlNodePtr child;
   9792     xmlSchemaAnnotPtr annot;
   9793     int res = 0, oldErrs, tmpOldErrs;
   9794 
   9795     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
   9796         return(-1);
   9797 
   9798     oldErrs = ctxt->nberrors;
   9799     child = nodes;
   9800     while ((IS_SCHEMA(child, "include")) ||
   9801 	   (IS_SCHEMA(child, "import")) ||
   9802 	   (IS_SCHEMA(child, "redefine")) ||
   9803 	   (IS_SCHEMA(child, "annotation"))) {
   9804 	if (IS_SCHEMA(child, "annotation")) {
   9805 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9806 	    if (schema->annot == NULL)
   9807 		schema->annot = annot;
   9808 	    else
   9809 		xmlSchemaFreeAnnot(annot);
   9810 	} else if (IS_SCHEMA(child, "import")) {
   9811 	    tmpOldErrs = ctxt->nberrors;
   9812 	    res = xmlSchemaParseImport(ctxt, schema, child);
   9813 	    HFAILURE;
   9814 	    HSTOP(ctxt);
   9815 	    if (tmpOldErrs != ctxt->nberrors)
   9816 		goto exit;
   9817 	} else if (IS_SCHEMA(child, "include")) {
   9818 	    tmpOldErrs = ctxt->nberrors;
   9819 	    res = xmlSchemaParseInclude(ctxt, schema, child);
   9820 	    HFAILURE;
   9821 	    HSTOP(ctxt);
   9822 	    if (tmpOldErrs != ctxt->nberrors)
   9823 		goto exit;
   9824 	} else if (IS_SCHEMA(child, "redefine")) {
   9825 	    tmpOldErrs = ctxt->nberrors;
   9826 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
   9827 	    HFAILURE;
   9828 	    HSTOP(ctxt);
   9829 	    if (tmpOldErrs != ctxt->nberrors)
   9830 		goto exit;
   9831 	}
   9832 	child = child->next;
   9833     }
   9834     /*
   9835     * URGENT TODO: Change the functions to return int results.
   9836     * We need especially to catch internal errors.
   9837     */
   9838     while (child != NULL) {
   9839 	if (IS_SCHEMA(child, "complexType")) {
   9840 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
   9841 	    child = child->next;
   9842 	} else if (IS_SCHEMA(child, "simpleType")) {
   9843 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
   9844 	    child = child->next;
   9845 	} else if (IS_SCHEMA(child, "element")) {
   9846 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
   9847 	    child = child->next;
   9848 	} else if (IS_SCHEMA(child, "attribute")) {
   9849 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
   9850 	    child = child->next;
   9851 	} else if (IS_SCHEMA(child, "attributeGroup")) {
   9852 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
   9853 	    child = child->next;
   9854 	} else if (IS_SCHEMA(child, "group")) {
   9855 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
   9856 	    child = child->next;
   9857 	} else if (IS_SCHEMA(child, "notation")) {
   9858 	    xmlSchemaParseNotation(ctxt, schema, child);
   9859 	    child = child->next;
   9860 	} else {
   9861 	    xmlSchemaPContentErr(ctxt,
   9862 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   9863 		NULL, child->parent, child,
   9864 		NULL, "((include | import | redefine | annotation)*, "
   9865 		"(((simpleType | complexType | group | attributeGroup) "
   9866 		"| element | attribute | notation), annotation*)*)");
   9867 	    child = child->next;
   9868 	}
   9869 	while (IS_SCHEMA(child, "annotation")) {
   9870 	    /*
   9871 	    * TODO: We should add all annotations.
   9872 	    */
   9873 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   9874 	    if (schema->annot == NULL)
   9875 		schema->annot = annot;
   9876 	    else
   9877 		xmlSchemaFreeAnnot(annot);
   9878 	    child = child->next;
   9879 	}
   9880     }
   9881 exit:
   9882     ctxt->ctxtType = NULL;
   9883     if (oldErrs != ctxt->nberrors)
   9884 	res = ctxt->err;
   9885     return(res);
   9886 exit_failure:
   9887     return(-1);
   9888 }
   9889 
   9890 static xmlSchemaSchemaRelationPtr
   9891 xmlSchemaSchemaRelationCreate(void)
   9892 {
   9893     xmlSchemaSchemaRelationPtr ret;
   9894 
   9895     ret = (xmlSchemaSchemaRelationPtr)
   9896 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
   9897     if (ret == NULL) {
   9898 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
   9899 	return(NULL);
   9900     }
   9901     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
   9902     return(ret);
   9903 }
   9904 
   9905 #if 0
   9906 static void
   9907 xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
   9908 {
   9909     xmlFree(rel);
   9910 }
   9911 #endif
   9912 
   9913 static void
   9914 xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
   9915 {
   9916     xmlSchemaRedefPtr prev;
   9917 
   9918     while (redef != NULL) {
   9919 	prev = redef;
   9920 	redef = redef->next;
   9921 	xmlFree(prev);
   9922     }
   9923 }
   9924 
   9925 static void
   9926 xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
   9927 {
   9928     /*
   9929     * After the construction context has been freed, there will be
   9930     * no schema graph available any more. Only the schema buckets
   9931     * will stay alive, which are put into the "schemasImports" and
   9932     * "includes" slots of the xmlSchema.
   9933     */
   9934     if (con->buckets != NULL)
   9935 	xmlSchemaItemListFree(con->buckets);
   9936     if (con->pending != NULL)
   9937 	xmlSchemaItemListFree(con->pending);
   9938     if (con->substGroups != NULL)
   9939 	xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
   9940     if (con->redefs != NULL)
   9941 	xmlSchemaRedefListFree(con->redefs);
   9942     if (con->dict != NULL)
   9943 	xmlDictFree(con->dict);
   9944     xmlFree(con);
   9945 }
   9946 
   9947 static xmlSchemaConstructionCtxtPtr
   9948 xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
   9949 {
   9950     xmlSchemaConstructionCtxtPtr ret;
   9951 
   9952     ret = (xmlSchemaConstructionCtxtPtr)
   9953 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
   9954     if (ret == NULL) {
   9955         xmlSchemaPErrMemory(NULL,
   9956 	    "allocating schema construction context", NULL);
   9957         return (NULL);
   9958     }
   9959     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
   9960 
   9961     ret->buckets = xmlSchemaItemListCreate();
   9962     if (ret->buckets == NULL) {
   9963 	xmlSchemaPErrMemory(NULL,
   9964 	    "allocating list of schema buckets", NULL);
   9965 	xmlFree(ret);
   9966         return (NULL);
   9967     }
   9968     ret->pending = xmlSchemaItemListCreate();
   9969     if (ret->pending == NULL) {
   9970 	xmlSchemaPErrMemory(NULL,
   9971 	    "allocating list of pending global components", NULL);
   9972 	xmlSchemaConstructionCtxtFree(ret);
   9973         return (NULL);
   9974     }
   9975     ret->dict = dict;
   9976     xmlDictReference(dict);
   9977     return(ret);
   9978 }
   9979 
   9980 static xmlSchemaParserCtxtPtr
   9981 xmlSchemaParserCtxtCreate(void)
   9982 {
   9983     xmlSchemaParserCtxtPtr ret;
   9984 
   9985     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
   9986     if (ret == NULL) {
   9987         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
   9988                             NULL);
   9989         return (NULL);
   9990     }
   9991     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
   9992     ret->type = XML_SCHEMA_CTXT_PARSER;
   9993     ret->attrProhibs = xmlSchemaItemListCreate();
   9994     if (ret->attrProhibs == NULL) {
   9995 	xmlFree(ret);
   9996 	return(NULL);
   9997     }
   9998     return(ret);
   9999 }
   10000 
   10001 /**
   10002  * xmlSchemaNewParserCtxtUseDict:
   10003  * @URL:  the location of the schema
   10004  * @dict: the dictionary to be used
   10005  *
   10006  * Create an XML Schemas parse context for that file/resource expected
   10007  * to contain an XML Schemas file.
   10008  *
   10009  * Returns the parser context or NULL in case of error
   10010  */
   10011 static xmlSchemaParserCtxtPtr
   10012 xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
   10013 {
   10014     xmlSchemaParserCtxtPtr ret;
   10015 
   10016     ret = xmlSchemaParserCtxtCreate();
   10017     if (ret == NULL)
   10018         return (NULL);
   10019     ret->dict = dict;
   10020     xmlDictReference(dict);
   10021     if (URL != NULL)
   10022 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
   10023     return (ret);
   10024 }
   10025 
   10026 static int
   10027 xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
   10028 {
   10029     if (vctxt->pctxt == NULL) {
   10030         if (vctxt->schema != NULL)
   10031 	    vctxt->pctxt =
   10032 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
   10033 	else
   10034 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
   10035 	if (vctxt->pctxt == NULL) {
   10036 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
   10037 		"failed to create a temp. parser context");
   10038 	    return (-1);
   10039 	}
   10040 	/* TODO: Pass user data. */
   10041 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
   10042 	    vctxt->warning, vctxt->errCtxt);
   10043 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
   10044 	    vctxt->errCtxt);
   10045     }
   10046     return (0);
   10047 }
   10048 
   10049 /**
   10050  * xmlSchemaGetSchemaBucket:
   10051  * @pctxt: the schema parser context
   10052  * @schemaLocation: the URI of the schema document
   10053  *
   10054  * Returns a schema bucket if it was already parsed.
   10055  *
   10056  * Returns a schema bucket if it was already parsed from
   10057  *         @schemaLocation, NULL otherwise.
   10058  */
   10059 static xmlSchemaBucketPtr
   10060 xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10061 			    const xmlChar *schemaLocation)
   10062 {
   10063     xmlSchemaBucketPtr cur;
   10064     xmlSchemaItemListPtr list;
   10065 
   10066     list = pctxt->constructor->buckets;
   10067     if (list->nbItems == 0)
   10068 	return(NULL);
   10069     else {
   10070 	int i;
   10071 	for (i = 0; i < list->nbItems; i++) {
   10072 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10073 	    /* Pointer comparison! */
   10074 	    if (cur->schemaLocation == schemaLocation)
   10075 		return(cur);
   10076 	}
   10077     }
   10078     return(NULL);
   10079 }
   10080 
   10081 static xmlSchemaBucketPtr
   10082 xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
   10083 				     const xmlChar *schemaLocation,
   10084 				     const xmlChar *targetNamespace)
   10085 {
   10086     xmlSchemaBucketPtr cur;
   10087     xmlSchemaItemListPtr list;
   10088 
   10089     list = pctxt->constructor->buckets;
   10090     if (list->nbItems == 0)
   10091 	return(NULL);
   10092     else {
   10093 	int i;
   10094 	for (i = 0; i < list->nbItems; i++) {
   10095 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10096 	    /* Pointer comparison! */
   10097 	    if ((cur->origTargetNamespace == NULL) &&
   10098 		(cur->schemaLocation == schemaLocation) &&
   10099 		(cur->targetNamespace == targetNamespace))
   10100 		return(cur);
   10101 	}
   10102     }
   10103     return(NULL);
   10104 }
   10105 
   10106 
   10107 #define IS_BAD_SCHEMA_DOC(b) \
   10108     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
   10109 
   10110 static xmlSchemaBucketPtr
   10111 xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
   10112 				 const xmlChar *targetNamespace,
   10113 				 int imported)
   10114 {
   10115     xmlSchemaBucketPtr cur;
   10116     xmlSchemaItemListPtr list;
   10117 
   10118     list = pctxt->constructor->buckets;
   10119     if (list->nbItems == 0)
   10120 	return(NULL);
   10121     else {
   10122 	int i;
   10123 	for (i = 0; i < list->nbItems; i++) {
   10124 	    cur = (xmlSchemaBucketPtr) list->items[i];
   10125 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
   10126 		(cur->origTargetNamespace == targetNamespace) &&
   10127 		((imported && cur->imported) ||
   10128 		 ((!imported) && (!cur->imported))))
   10129 		return(cur);
   10130 	}
   10131     }
   10132     return(NULL);
   10133 }
   10134 
   10135 static int
   10136 xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
   10137 		     xmlSchemaPtr schema,
   10138 		     xmlSchemaBucketPtr bucket)
   10139 {
   10140     int oldFlags;
   10141     xmlDocPtr oldDoc;
   10142     xmlNodePtr node;
   10143     int ret, oldErrs;
   10144     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
   10145 
   10146     /*
   10147     * Save old values; reset the *main* schema.
   10148     * URGENT TODO: This is not good; move the per-document information
   10149     * to the parser. Get rid of passing the main schema to the
   10150     * parsing functions.
   10151     */
   10152     oldFlags = schema->flags;
   10153     oldDoc = schema->doc;
   10154     if (schema->flags != 0)
   10155 	xmlSchemaClearSchemaDefaults(schema);
   10156     schema->doc = bucket->doc;
   10157     pctxt->schema = schema;
   10158     /*
   10159     * Keep the current target namespace on the parser *not* on the
   10160     * main schema.
   10161     */
   10162     pctxt->targetNamespace = bucket->targetNamespace;
   10163     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   10164 
   10165     if ((bucket->targetNamespace != NULL) &&
   10166 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
   10167 	/*
   10168 	* We are parsing the schema for schemas!
   10169 	*/
   10170 	pctxt->isS4S = 1;
   10171     }
   10172     /* Mark it as parsed, even if parsing fails. */
   10173     bucket->parsed++;
   10174     /* Compile the schema doc. */
   10175     node = xmlDocGetRootElement(bucket->doc);
   10176     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
   10177     if (ret != 0)
   10178 	goto exit;
   10179     /* An empty schema; just get out. */
   10180     if (node->children == NULL)
   10181 	goto exit;
   10182     oldErrs = pctxt->nberrors;
   10183     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
   10184     if (ret != 0)
   10185 	goto exit;
   10186     /*
   10187     * TODO: Not nice, but I'm not 100% sure we will get always an error
   10188     * as a result of the obove functions; so better rely on pctxt->err
   10189     * as well.
   10190     */
   10191     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
   10192 	ret = pctxt->err;
   10193 	goto exit;
   10194     }
   10195 
   10196 exit:
   10197     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
   10198     /* Restore schema values. */
   10199     schema->doc = oldDoc;
   10200     schema->flags = oldFlags;
   10201     return(ret);
   10202 }
   10203 
   10204 static int
   10205 xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
   10206 		     xmlSchemaPtr schema,
   10207 		     xmlSchemaBucketPtr bucket)
   10208 {
   10209     xmlSchemaParserCtxtPtr newpctxt;
   10210     int res = 0;
   10211 
   10212     if (bucket == NULL)
   10213 	return(0);
   10214     if (bucket->parsed) {
   10215 	PERROR_INT("xmlSchemaParseNewDoc",
   10216 	    "reparsing a schema doc");
   10217 	return(-1);
   10218     }
   10219     if (bucket->doc == NULL) {
   10220 	PERROR_INT("xmlSchemaParseNewDoc",
   10221 	    "parsing a schema doc, but there's no doc");
   10222 	return(-1);
   10223     }
   10224     if (pctxt->constructor == NULL) {
   10225 	PERROR_INT("xmlSchemaParseNewDoc",
   10226 	    "no constructor");
   10227 	return(-1);
   10228     }
   10229     /* Create and init the temporary parser context. */
   10230     newpctxt = xmlSchemaNewParserCtxtUseDict(
   10231 	(const char *) bucket->schemaLocation, pctxt->dict);
   10232     if (newpctxt == NULL)
   10233 	return(-1);
   10234     newpctxt->constructor = pctxt->constructor;
   10235     /*
   10236     * TODO: Can we avoid that the parser knows about the main schema?
   10237     * It would be better if he knows about the current schema bucket
   10238     * only.
   10239     */
   10240     newpctxt->schema = schema;
   10241     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
   10242 	pctxt->errCtxt);
   10243     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
   10244 	pctxt->errCtxt);
   10245     newpctxt->counter = pctxt->counter;
   10246 
   10247 
   10248     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
   10249 
   10250     /* Channel back errors and cleanup the temporary parser context. */
   10251     if (res != 0)
   10252 	pctxt->err = res;
   10253     pctxt->nberrors += newpctxt->nberrors;
   10254     pctxt->counter = newpctxt->counter;
   10255     newpctxt->constructor = NULL;
   10256     /* Free the parser context. */
   10257     xmlSchemaFreeParserCtxt(newpctxt);
   10258     return(res);
   10259 }
   10260 
   10261 static void
   10262 xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
   10263 				xmlSchemaSchemaRelationPtr rel)
   10264 {
   10265     xmlSchemaSchemaRelationPtr cur = bucket->relations;
   10266 
   10267     if (cur == NULL) {
   10268 	bucket->relations = rel;
   10269 	return;
   10270     }
   10271     while (cur->next != NULL)
   10272 	cur = cur->next;
   10273     cur->next = rel;
   10274 }
   10275 
   10276 
   10277 static const xmlChar *
   10278 xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
   10279 			  xmlNodePtr ctxtNode)
   10280 {
   10281     /*
   10282     * Build an absolue location URI.
   10283     */
   10284     if (location != NULL) {
   10285 	if (ctxtNode == NULL)
   10286 	    return(location);
   10287 	else {
   10288 	    xmlChar *base, *URI;
   10289 	    const xmlChar *ret = NULL;
   10290 
   10291 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
   10292 	    if (base == NULL) {
   10293 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
   10294 	    } else {
   10295 		URI = xmlBuildURI(location, base);
   10296 		xmlFree(base);
   10297 	    }
   10298 	    if (URI != NULL) {
   10299 		ret = xmlDictLookup(dict, URI, -1);
   10300 		xmlFree(URI);
   10301 		return(ret);
   10302 	    }
   10303 	}
   10304     }
   10305     return(NULL);
   10306 }
   10307 
   10308 
   10309 
   10310 /**
   10311  * xmlSchemaAddSchemaDoc:
   10312  * @pctxt:  a schema validation context
   10313  * @schema:  the schema being built
   10314  * @node:  a subtree containing XML Schema informations
   10315  *
   10316  * Parse an included (and to-be-redefined) XML schema document.
   10317  *
   10318  * Returns 0 on success, a positive error code on errors and
   10319  *         -1 in case of an internal or API error.
   10320  */
   10321 
   10322 static int
   10323 xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
   10324 		int type, /* import or include or redefine */
   10325 		const xmlChar *schemaLocation,
   10326 		xmlDocPtr schemaDoc,
   10327 		const char *schemaBuffer,
   10328 		int schemaBufferLen,
   10329 		xmlNodePtr invokingNode,
   10330 		const xmlChar *sourceTargetNamespace,
   10331 		const xmlChar *importNamespace,
   10332 		xmlSchemaBucketPtr *bucket)
   10333 {
   10334     const xmlChar *targetNamespace = NULL;
   10335     xmlSchemaSchemaRelationPtr relation = NULL;
   10336     xmlDocPtr doc = NULL;
   10337     int res = 0, err = 0, located = 0, preserveDoc = 0;
   10338     xmlSchemaBucketPtr bkt = NULL;
   10339 
   10340     if (bucket != NULL)
   10341 	*bucket = NULL;
   10342 
   10343     switch (type) {
   10344 	case XML_SCHEMA_SCHEMA_IMPORT:
   10345 	case XML_SCHEMA_SCHEMA_MAIN:
   10346 	    err = XML_SCHEMAP_SRC_IMPORT;
   10347 	    break;
   10348 	case XML_SCHEMA_SCHEMA_INCLUDE:
   10349 	    err = XML_SCHEMAP_SRC_INCLUDE;
   10350 	    break;
   10351 	case XML_SCHEMA_SCHEMA_REDEFINE:
   10352 	    err = XML_SCHEMAP_SRC_REDEFINE;
   10353 	    break;
   10354     }
   10355 
   10356 
   10357     /* Special handling for the main schema:
   10358     * skip the location and relation logic and just parse the doc.
   10359     * We need just a bucket to be returned in this case.
   10360     */
   10361     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
   10362 	goto doc_load;
   10363 
   10364     /* Note that we expect the location to be an absulute URI. */
   10365     if (schemaLocation != NULL) {
   10366 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
   10367 	if ((bkt != NULL) &&
   10368 	    (pctxt->constructor->bucket == bkt)) {
   10369 	    /* Report self-imports/inclusions/redefinitions. */
   10370 
   10371 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10372 		invokingNode, NULL,
   10373 		"The schema must not import/include/redefine itself",
   10374 		NULL, NULL);
   10375 	    goto exit;
   10376 	}
   10377     }
   10378     /*
   10379     * Create a relation for the graph of schemas.
   10380     */
   10381     relation = xmlSchemaSchemaRelationCreate();
   10382     if (relation == NULL)
   10383 	return(-1);
   10384     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
   10385 	relation);
   10386     relation->type = type;
   10387 
   10388     /*
   10389     * Save the namespace import information.
   10390     */
   10391     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10392 	relation->importNamespace = importNamespace;
   10393 	if (schemaLocation == NULL) {
   10394 	    /*
   10395 	    * No location; this is just an import of the namespace.
   10396 	    * Note that we don't assign a bucket to the relation
   10397 	    * in this case.
   10398 	    */
   10399 	    goto exit;
   10400 	}
   10401 	targetNamespace = importNamespace;
   10402     }
   10403 
   10404     /* Did we already fetch the doc? */
   10405     if (bkt != NULL) {
   10406 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
   10407 	    /*
   10408 	    * We included/redefined and then try to import a schema,
   10409 	    * but the new location provided for import was different.
   10410 	    */
   10411 	    if (schemaLocation == NULL)
   10412 		schemaLocation = BAD_CAST "in_memory_buffer";
   10413 	    if (!xmlStrEqual(schemaLocation,
   10414 		bkt->schemaLocation)) {
   10415 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10416 		    invokingNode, NULL,
   10417 		    "The schema document '%s' cannot be imported, since "
   10418 		    "it was already included or redefined",
   10419 		    schemaLocation, NULL);
   10420 		goto exit;
   10421 	    }
   10422 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
   10423 	    /*
   10424 	    * We imported and then try to include/redefine a schema,
   10425 	    * but the new location provided for the include/redefine
   10426 	    * was different.
   10427 	    */
   10428 	    if (schemaLocation == NULL)
   10429 		schemaLocation = BAD_CAST "in_memory_buffer";
   10430 	    if (!xmlStrEqual(schemaLocation,
   10431 		bkt->schemaLocation)) {
   10432 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
   10433 		    invokingNode, NULL,
   10434 		    "The schema document '%s' cannot be included or "
   10435 		    "redefined, since it was already imported",
   10436 		    schemaLocation, NULL);
   10437 		goto exit;
   10438 	    }
   10439 	}
   10440     }
   10441 
   10442     if (WXS_IS_BUCKET_IMPMAIN(type)) {
   10443 	/*
   10444 	* Given that the schemaLocation [attribute] is only a hint, it is open
   10445 	* to applications to ignore all but the first <import> for a given
   10446 	* namespace, regardless of the `actual value` of schemaLocation, but
   10447 	* such a strategy risks missing useful information when new
   10448 	* schemaLocations are offered.
   10449 	*
   10450 	* We will use the first <import> that comes with a location.
   10451 	* Further <import>s *with* a location, will result in an error.
   10452 	* TODO: Better would be to just report a warning here, but
   10453 	* we'll try it this way until someone complains.
   10454 	*
   10455 	* Schema Document Location Strategy:
   10456 	* 3 Based on the namespace name, identify an existing schema document,
   10457 	* either as a resource which is an XML document or a <schema> element
   10458 	* information item, in some local schema repository;
   10459 	* 5 Attempt to resolve the namespace name to locate such a resource.
   10460 	*
   10461 	* NOTE: (3) and (5) are not supported.
   10462 	*/
   10463 	if (bkt != NULL) {
   10464 	    relation->bucket = bkt;
   10465 	    goto exit;
   10466 	}
   10467 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
   10468 	    importNamespace, 1);
   10469 
   10470 	if (bkt != NULL) {
   10471 	    relation->bucket = bkt;
   10472 	    if (bkt->schemaLocation == NULL) {
   10473 		/* First given location of the schema; load the doc. */
   10474 		bkt->schemaLocation = schemaLocation;
   10475 	    } else {
   10476 		if (!xmlStrEqual(schemaLocation,
   10477 		    bkt->schemaLocation)) {
   10478 		    /*
   10479 		    * Additional location given; just skip it.
   10480 		    * URGENT TODO: We should report a warning here.
   10481 		    * res = XML_SCHEMAP_SRC_IMPORT;
   10482 		    */
   10483 		    if (schemaLocation == NULL)
   10484 			schemaLocation = BAD_CAST "in_memory_buffer";
   10485 
   10486 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10487 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
   10488 			invokingNode, NULL,
   10489 			"Skipping import of schema located at '%s' for the "
   10490 			"namespace '%s', since this namespace was already "
   10491 			"imported with the schema located at '%s'",
   10492 			schemaLocation, importNamespace, bkt->schemaLocation);
   10493 		}
   10494 		goto exit;
   10495 	    }
   10496 	}
   10497 	/*
   10498 	* No bucket + first location: load the doc and create a
   10499 	* bucket.
   10500 	*/
   10501     } else {
   10502 	/* <include> and <redefine> */
   10503 	if (bkt != NULL) {
   10504 
   10505 	    if ((bkt->origTargetNamespace == NULL) &&
   10506 		(bkt->targetNamespace != sourceTargetNamespace)) {
   10507 		xmlSchemaBucketPtr chamel;
   10508 
   10509 		/*
   10510 		* Chameleon include/redefine: skip loading only if it was
   10511 		* aleady build for the targetNamespace of the including
   10512 		* schema.
   10513 		*/
   10514 		/*
   10515 		* URGENT TODO: If the schema is a chameleon-include then copy
   10516 		* the components into the including schema and modify the
   10517 		* targetNamespace of those components, do nothing otherwise.
   10518 		* NOTE: This is currently worked-around by compiling the
   10519 		* chameleon for every destinct including targetNamespace; thus
   10520 		* not performant at the moment.
   10521 		* TODO: Check when the namespace in wildcards for chameleons
   10522 		* needs to be converted: before we built wildcard intersections
   10523 		* or after.
   10524 		*   Answer: after!
   10525 		*/
   10526 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
   10527 		    schemaLocation, sourceTargetNamespace);
   10528 		if (chamel != NULL) {
   10529 		    /* A fitting chameleon was already parsed; NOP. */
   10530 		    relation->bucket = chamel;
   10531 		    goto exit;
   10532 		}
   10533 		/*
   10534 		* We need to parse the chameleon again for a different
   10535 		* targetNamespace.
   10536 		* CHAMELEON TODO: Optimize this by only parsing the
   10537 		* chameleon once, and then copying the components to
   10538 		* the new targetNamespace.
   10539 		*/
   10540 		bkt = NULL;
   10541 	    } else {
   10542 		relation->bucket = bkt;
   10543 		goto exit;
   10544 	    }
   10545 	}
   10546     }
   10547     if ((bkt != NULL) && (bkt->doc != NULL)) {
   10548 	PERROR_INT("xmlSchemaAddSchemaDoc",
   10549 	    "trying to load a schema doc, but a doc is already "
   10550 	    "assigned to the schema bucket");
   10551 	goto exit_failure;
   10552     }
   10553 
   10554 doc_load:
   10555     /*
   10556     * Load the document.
   10557     */
   10558     if (schemaDoc != NULL) {
   10559 	doc = schemaDoc;
   10560 	/* Don' free this one, since it was provided by the caller. */
   10561 	preserveDoc = 1;
   10562 	/* TODO: Does the context or the doc hold the location? */
   10563 	if (schemaDoc->URL != NULL)
   10564 	    schemaLocation = xmlDictLookup(pctxt->dict,
   10565 		schemaDoc->URL, -1);
   10566         else
   10567 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10568     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
   10569 	xmlParserCtxtPtr parserCtxt;
   10570 
   10571 	parserCtxt = xmlNewParserCtxt();
   10572 	if (parserCtxt == NULL) {
   10573 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
   10574 		"allocating a parser context", NULL);
   10575 	    goto exit_failure;
   10576 	}
   10577 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
   10578 	    /*
   10579 	    * TODO: Do we have to burden the schema parser dict with all
   10580 	    * the content of the schema doc?
   10581 	    */
   10582 	    xmlDictFree(parserCtxt->dict);
   10583 	    parserCtxt->dict = pctxt->dict;
   10584 	    xmlDictReference(parserCtxt->dict);
   10585 	}
   10586 	if (schemaLocation != NULL) {
   10587 	    /* Parse from file. */
   10588 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
   10589 		NULL, SCHEMAS_PARSE_OPTIONS);
   10590 	} else if (schemaBuffer != NULL) {
   10591 	    /* Parse from memory buffer. */
   10592 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
   10593 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
   10594 	    schemaLocation = BAD_CAST "in_memory_buffer";
   10595 	    if (doc != NULL)
   10596 		doc->URL = xmlStrdup(schemaLocation);
   10597 	}
   10598 	/*
   10599 	* For <import>:
   10600 	* 2.1 The referent is (a fragment of) a resource which is an
   10601 	* XML document (see clause 1.1), which in turn corresponds to
   10602 	* a <schema> element information item in a well-formed information
   10603 	* set, which in turn corresponds to a valid schema.
   10604 	* TODO: (2.1) fragments of XML documents are not supported.
   10605 	*
   10606 	* 2.2 The referent is a <schema> element information item in
   10607 	* a well-formed information set, which in turn corresponds
   10608 	* to a valid schema.
   10609 	* TODO: (2.2) is not supported.
   10610 	*/
   10611 	if (doc == NULL) {
   10612 	    xmlErrorPtr lerr;
   10613 	    lerr = xmlGetLastError();
   10614 	    /*
   10615 	    * Check if this a parser error, or if the document could
   10616 	    * just not be located.
   10617 	    * TODO: Try to find specific error codes to react only on
   10618 	    * localisation failures.
   10619 	    */
   10620 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
   10621 		/*
   10622 		* We assume a parser error here.
   10623 		*/
   10624 		located = 1;
   10625 		/* TODO: Error code ?? */
   10626 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
   10627 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   10628 		    invokingNode, NULL,
   10629 		    "Failed to parse the XML resource '%s'",
   10630 		    schemaLocation, NULL);
   10631 	    }
   10632 	}
   10633 	xmlFreeParserCtxt(parserCtxt);
   10634 	if ((doc == NULL) && located)
   10635 	    goto exit_error;
   10636     } else {
   10637 	xmlSchemaPErr(pctxt, NULL,
   10638 	    XML_SCHEMAP_NOTHING_TO_PARSE,
   10639 	    "No information for parsing was provided with the "
   10640 	    "given schema parser context.\n",
   10641 	    NULL, NULL);
   10642 	goto exit_failure;
   10643     }
   10644     /*
   10645     * Preprocess the document.
   10646     */
   10647     if (doc != NULL) {
   10648 	xmlNodePtr docElem = NULL;
   10649 
   10650 	located = 1;
   10651 	docElem = xmlDocGetRootElement(doc);
   10652 	if (docElem == NULL) {
   10653 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
   10654 		invokingNode, NULL,
   10655 		"The document '%s' has no document element",
   10656 		schemaLocation, NULL);
   10657 	    goto exit_error;
   10658 	}
   10659 	/*
   10660 	* Remove all the blank text nodes.
   10661 	*/
   10662 	xmlSchemaCleanupDoc(pctxt, docElem);
   10663 	/*
   10664 	* Check the schema's top level element.
   10665 	*/
   10666 	if (!IS_SCHEMA(docElem, "schema")) {
   10667 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
   10668 		invokingNode, NULL,
   10669 		"The XML document '%s' is not a schema document",
   10670 		schemaLocation, NULL);
   10671 	    goto exit_error;
   10672 	}
   10673 	/*
   10674 	* Note that we don't apply a type check for the
   10675 	* targetNamespace value here.
   10676 	*/
   10677 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
   10678 	    "targetNamespace");
   10679     }
   10680 
   10681 /* after_doc_loading: */
   10682     if ((bkt == NULL) && located) {
   10683 	/* Only create a bucket if the schema was located. */
   10684         bkt = xmlSchemaBucketCreate(pctxt, type,
   10685 	    targetNamespace);
   10686 	if (bkt == NULL)
   10687 	    goto exit_failure;
   10688     }
   10689     if (bkt != NULL) {
   10690 	bkt->schemaLocation = schemaLocation;
   10691 	bkt->located = located;
   10692 	if (doc != NULL) {
   10693 	    bkt->doc = doc;
   10694 	    bkt->targetNamespace = targetNamespace;
   10695 	    bkt->origTargetNamespace = targetNamespace;
   10696 	    if (preserveDoc)
   10697 		bkt->preserveDoc = 1;
   10698 	}
   10699 	if (WXS_IS_BUCKET_IMPMAIN(type))
   10700 	    bkt->imported++;
   10701 	    /*
   10702 	    * Add it to the graph of schemas.
   10703 	    */
   10704 	if (relation != NULL)
   10705 	    relation->bucket = bkt;
   10706     }
   10707 
   10708 exit:
   10709     /*
   10710     * Return the bucket explicitely; this is needed for the
   10711     * main schema.
   10712     */
   10713     if (bucket != NULL)
   10714 	*bucket = bkt;
   10715     return (0);
   10716 
   10717 exit_error:
   10718     if ((doc != NULL) && (! preserveDoc)) {
   10719 	xmlFreeDoc(doc);
   10720 	if (bkt != NULL)
   10721 	    bkt->doc = NULL;
   10722     }
   10723     return(pctxt->err);
   10724 
   10725 exit_failure:
   10726     if ((doc != NULL) && (! preserveDoc)) {
   10727 	xmlFreeDoc(doc);
   10728 	if (bkt != NULL)
   10729 	    bkt->doc = NULL;
   10730     }
   10731     return (-1);
   10732 }
   10733 
   10734 /**
   10735  * xmlSchemaParseImport:
   10736  * @ctxt:  a schema validation context
   10737  * @schema:  the schema being built
   10738  * @node:  a subtree containing XML Schema informations
   10739  *
   10740  * parse a XML schema Import definition
   10741  * *WARNING* this interface is highly subject to change
   10742  *
   10743  * Returns 0 in case of success, a positive error code if
   10744  * not valid and -1 in case of an internal error.
   10745  */
   10746 static int
   10747 xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   10748                      xmlNodePtr node)
   10749 {
   10750     xmlNodePtr child;
   10751     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
   10752     const xmlChar *thisTargetNamespace;
   10753     xmlAttrPtr attr;
   10754     int ret = 0;
   10755     xmlSchemaBucketPtr bucket = NULL;
   10756 
   10757     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   10758         return (-1);
   10759 
   10760     /*
   10761     * Check for illegal attributes.
   10762     */
   10763     attr = node->properties;
   10764     while (attr != NULL) {
   10765 	if (attr->ns == NULL) {
   10766 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10767 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
   10768 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10769 		xmlSchemaPIllegalAttrErr(pctxt,
   10770 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10771 	    }
   10772 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10773 	    xmlSchemaPIllegalAttrErr(pctxt,
   10774 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10775 	}
   10776 	attr = attr->next;
   10777     }
   10778     /*
   10779     * Extract and validate attributes.
   10780     */
   10781     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10782 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10783 	&namespaceName) != 0) {
   10784 	xmlSchemaPSimpleTypeErr(pctxt,
   10785 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10786 	    NULL, node,
   10787 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10788 	    NULL, namespaceName, NULL, NULL, NULL);
   10789 	return (pctxt->err);
   10790     }
   10791 
   10792     if (xmlSchemaPValAttr(pctxt, NULL, node,
   10793 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10794 	&schemaLocation) != 0) {
   10795 	xmlSchemaPSimpleTypeErr(pctxt,
   10796 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   10797 	    NULL, node,
   10798 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10799 	    NULL, schemaLocation, NULL, NULL, NULL);
   10800 	return (pctxt->err);
   10801     }
   10802     /*
   10803     * And now for the children...
   10804     */
   10805     child = node->children;
   10806     if (IS_SCHEMA(child, "annotation")) {
   10807         /*
   10808          * the annotation here is simply discarded ...
   10809 	 * TODO: really?
   10810          */
   10811         child = child->next;
   10812     }
   10813     if (child != NULL) {
   10814 	xmlSchemaPContentErr(pctxt,
   10815 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   10816 	    NULL, node, child, NULL,
   10817 	    "(annotation?)");
   10818     }
   10819     /*
   10820     * Apply additional constraints.
   10821     *
   10822     * Note that it is important to use the original @targetNamespace
   10823     * (or none at all), to rule out imports of schemas _with_ a
   10824     * @targetNamespace if the importing schema is a chameleon schema
   10825     * (with no @targetNamespace).
   10826     */
   10827     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
   10828     if (namespaceName != NULL) {
   10829 	/*
   10830 	* 1.1 If the namespace [attribute] is present, then its `actual value`
   10831 	* must not match the `actual value` of the enclosing <schema>'s
   10832 	* targetNamespace [attribute].
   10833 	*/
   10834 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
   10835 	    xmlSchemaPCustomErr(pctxt,
   10836 		XML_SCHEMAP_SRC_IMPORT_1_1,
   10837 		NULL, node,
   10838 		"The value of the attribute 'namespace' must not match "
   10839 		"the target namespace '%s' of the importing schema",
   10840 		thisTargetNamespace);
   10841 	    return (pctxt->err);
   10842 	}
   10843     } else {
   10844 	/*
   10845 	* 1.2 If the namespace [attribute] is not present, then the enclosing
   10846 	* <schema> must have a targetNamespace [attribute].
   10847 	*/
   10848 	if (thisTargetNamespace == NULL) {
   10849 	    xmlSchemaPCustomErr(pctxt,
   10850 		XML_SCHEMAP_SRC_IMPORT_1_2,
   10851 		NULL, node,
   10852 		"The attribute 'namespace' must be existent if "
   10853 		"the importing schema has no target namespace",
   10854 		NULL);
   10855 	    return (pctxt->err);
   10856 	}
   10857     }
   10858     /*
   10859     * Locate and acquire the schema document.
   10860     */
   10861     if (schemaLocation != NULL)
   10862 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   10863 	    schemaLocation, node);
   10864     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   10865 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
   10866 	namespaceName, &bucket);
   10867 
   10868     if (ret != 0)
   10869 	return(ret);
   10870 
   10871     /*
   10872     * For <import>: "It is *not* an error for the application
   10873     * schema reference strategy to fail."
   10874     * So just don't parse if no schema document was found.
   10875     * Note that we will get no bucket if the schema could not be
   10876     * located or if there was no schemaLocation.
   10877     */
   10878     if ((bucket == NULL) && (schemaLocation != NULL)) {
   10879 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   10880 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
   10881 	    node, NULL,
   10882 	    "Failed to locate a schema at location '%s'. "
   10883 	    "Skipping the import", schemaLocation, NULL, NULL);
   10884     }
   10885 
   10886     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
   10887 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
   10888     }
   10889 
   10890     return (ret);
   10891 }
   10892 
   10893 static int
   10894 xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
   10895 				     xmlSchemaPtr schema,
   10896 				     xmlNodePtr node,
   10897 				     xmlChar **schemaLocation,
   10898 				     int type)
   10899 {
   10900     xmlAttrPtr attr;
   10901 
   10902     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
   10903 	(schemaLocation == NULL))
   10904         return (-1);
   10905 
   10906     *schemaLocation = NULL;
   10907     /*
   10908     * Check for illegal attributes.
   10909     * Applies for both <include> and <redefine>.
   10910     */
   10911     attr = node->properties;
   10912     while (attr != NULL) {
   10913 	if (attr->ns == NULL) {
   10914 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   10915 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
   10916 		xmlSchemaPIllegalAttrErr(pctxt,
   10917 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10918 	    }
   10919 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   10920 	    xmlSchemaPIllegalAttrErr(pctxt,
   10921 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   10922 	}
   10923 	attr = attr->next;
   10924     }
   10925     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
   10926     /*
   10927     * Preliminary step, extract the URI-Reference and make an URI
   10928     * from the base.
   10929     */
   10930     /*
   10931     * Attribute "schemaLocation" is mandatory.
   10932     */
   10933     attr = xmlSchemaGetPropNode(node, "schemaLocation");
   10934     if (attr != NULL) {
   10935         xmlChar *base = NULL;
   10936         xmlChar *uri = NULL;
   10937 
   10938 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
   10939 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
   10940 	    (const xmlChar **) schemaLocation) != 0)
   10941 	    goto exit_error;
   10942 	base = xmlNodeGetBase(node->doc, node);
   10943 	if (base == NULL) {
   10944 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
   10945 	} else {
   10946 	    uri = xmlBuildURI(*schemaLocation, base);
   10947 	    xmlFree(base);
   10948 	}
   10949 	if (uri == NULL) {
   10950 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
   10951 		"could not build an URI from the schemaLocation")
   10952 	    goto exit_failure;
   10953 	}
   10954 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
   10955 	xmlFree(uri);
   10956     } else {
   10957 	xmlSchemaPMissingAttrErr(pctxt,
   10958 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   10959 	    NULL, node, "schemaLocation", NULL);
   10960 	goto exit_error;
   10961     }
   10962     /*
   10963     * Report self-inclusion and self-redefinition.
   10964     */
   10965     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
   10966 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   10967 	    xmlSchemaPCustomErr(pctxt,
   10968 		XML_SCHEMAP_SRC_REDEFINE,
   10969 		NULL, node,
   10970 		"The schema document '%s' cannot redefine itself.",
   10971 		*schemaLocation);
   10972 	} else {
   10973 	    xmlSchemaPCustomErr(pctxt,
   10974 		XML_SCHEMAP_SRC_INCLUDE,
   10975 		NULL, node,
   10976 		"The schema document '%s' cannot include itself.",
   10977 		*schemaLocation);
   10978 	}
   10979 	goto exit_error;
   10980     }
   10981 
   10982     return(0);
   10983 exit_error:
   10984     return(pctxt->err);
   10985 exit_failure:
   10986     return(-1);
   10987 }
   10988 
   10989 static int
   10990 xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
   10991 				xmlSchemaPtr schema,
   10992 				xmlNodePtr node,
   10993 				int type)
   10994 {
   10995     xmlNodePtr child = NULL;
   10996     const xmlChar *schemaLocation = NULL;
   10997     int res = 0; /* hasRedefinitions = 0 */
   10998     int isChameleon = 0, wasChameleon = 0;
   10999     xmlSchemaBucketPtr bucket = NULL;
   11000 
   11001     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
   11002         return (-1);
   11003 
   11004     /*
   11005     * Parse attributes. Note that the returned schemaLocation will
   11006     * be already converted to an absolute URI.
   11007     */
   11008     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
   11009 	node, (xmlChar **) (&schemaLocation), type);
   11010     if (res != 0)
   11011 	return(res);
   11012     /*
   11013     * Load and add the schema document.
   11014     */
   11015     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
   11016 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
   11017     if (res != 0)
   11018 	return(res);
   11019     /*
   11020     * If we get no schema bucket back, then this means that the schema
   11021     * document could not be located or was broken XML or was not
   11022     * a schema document.
   11023     */
   11024     if ((bucket == NULL) || (bucket->doc == NULL)) {
   11025 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
   11026 	    /*
   11027 	    * WARNING for <include>:
   11028 	    * We will raise an error if the schema cannot be located
   11029 	    * for inclusions, since the that was the feedback from the
   11030 	    * schema people. I.e. the following spec piece will *not* be
   11031 	    * satisfied:
   11032 	    * SPEC src-include: "It is not an error for the `actual value` of the
   11033 	    * schemaLocation [attribute] to fail to resolve it all, in which
   11034 	    * case no corresponding inclusion is performed.
   11035 	    * So do we need a warning report here?"
   11036 	    */
   11037 	    res = XML_SCHEMAP_SRC_INCLUDE;
   11038 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   11039 		node, NULL,
   11040 		"Failed to load the document '%s' for inclusion",
   11041 		schemaLocation, NULL);
   11042 	} else {
   11043 	    /*
   11044 	    * NOTE: This was changed to raise an error even if no redefinitions
   11045 	    * are specified.
   11046 	    *
   11047 	    * SPEC src-redefine (1)
   11048 	    * "If there are any element information items among the [children]
   11049 	    * other than <annotation> then the `actual value` of the
   11050 	    * schemaLocation [attribute] must successfully resolve."
   11051 	    * TODO: Ask the WG if a the location has always to resolve
   11052 	    * here as well!
   11053 	    */
   11054 	    res = XML_SCHEMAP_SRC_REDEFINE;
   11055 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
   11056 		node, NULL,
   11057 		"Failed to load the document '%s' for redefinition",
   11058 		schemaLocation, NULL);
   11059 	}
   11060     } else {
   11061 	/*
   11062 	* Check targetNamespace sanity before parsing the new schema.
   11063 	* TODO: Note that we won't check further content if the
   11064 	* targetNamespace was bad.
   11065 	*/
   11066 	if (bucket->origTargetNamespace != NULL) {
   11067 	    /*
   11068 	    * SPEC src-include (2.1)
   11069 	    * "SII has a targetNamespace [attribute], and its `actual
   11070 	    * value` is identical to the `actual value` of the targetNamespace
   11071 	    * [attribute] of SII' (which must have such an [attribute])."
   11072 	    */
   11073 	    if (pctxt->targetNamespace == NULL) {
   11074 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11075 		    XML_SCHEMAP_SRC_INCLUDE,
   11076 		    node, NULL,
   11077 		    "The target namespace of the included/redefined schema "
   11078 		    "'%s' has to be absent, since the including/redefining "
   11079 		    "schema has no target namespace",
   11080 		    schemaLocation, NULL);
   11081 		goto exit_error;
   11082 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
   11083 		pctxt->targetNamespace)) {
   11084 		/* TODO: Change error function. */
   11085 		xmlSchemaPCustomErrExt(pctxt,
   11086 		    XML_SCHEMAP_SRC_INCLUDE,
   11087 		    NULL, node,
   11088 		    "The target namespace '%s' of the included/redefined "
   11089 		    "schema '%s' differs from '%s' of the "
   11090 		    "including/redefining schema",
   11091 		    bucket->origTargetNamespace, schemaLocation,
   11092 		    pctxt->targetNamespace);
   11093 		goto exit_error;
   11094 	    }
   11095 	} else if (pctxt->targetNamespace != NULL) {
   11096 	    /*
   11097 	    * Chameleons: the original target namespace will
   11098 	    * differ from the resulting namespace.
   11099 	    */
   11100 	    isChameleon = 1;
   11101 	    if (bucket->parsed &&
   11102 		bucket->origTargetNamespace != NULL) {
   11103 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   11104 		    XML_SCHEMAP_SRC_INCLUDE,
   11105 		    node, NULL,
   11106 		    "The target namespace of the included/redefined schema "
   11107 		    "'%s' has to be absent or the same as the "
   11108 		    "including/redefining schema's target namespace",
   11109 		    schemaLocation, NULL);
   11110 		goto exit_error;
   11111 	    }
   11112 	    bucket->targetNamespace = pctxt->targetNamespace;
   11113 	}
   11114     }
   11115     /*
   11116     * Parse the schema.
   11117     */
   11118     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
   11119 	if (isChameleon) {
   11120 	    /* TODO: Get rid of this flag on the schema itself. */
   11121 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
   11122 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11123 	    } else
   11124 		wasChameleon = 1;
   11125 	}
   11126 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
   11127 	/* Restore chameleon flag. */
   11128 	if (isChameleon && (!wasChameleon))
   11129 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
   11130     }
   11131     /*
   11132     * And now for the children...
   11133     */
   11134     child = node->children;
   11135     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11136 	/*
   11137 	* Parse (simpleType | complexType | group | attributeGroup))*
   11138 	*/
   11139 	pctxt->redefined = bucket;
   11140 	/*
   11141 	* How to proceed if the redefined schema was not located?
   11142 	*/
   11143 	pctxt->isRedefine = 1;
   11144 	while (IS_SCHEMA(child, "annotation") ||
   11145 	    IS_SCHEMA(child, "simpleType") ||
   11146 	    IS_SCHEMA(child, "complexType") ||
   11147 	    IS_SCHEMA(child, "group") ||
   11148 	    IS_SCHEMA(child, "attributeGroup")) {
   11149 	    if (IS_SCHEMA(child, "annotation")) {
   11150 		/*
   11151 		* TODO: discard or not?
   11152 		*/
   11153 	    } else if (IS_SCHEMA(child, "simpleType")) {
   11154 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
   11155 	    } else if (IS_SCHEMA(child, "complexType")) {
   11156 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
   11157 		/* hasRedefinitions = 1; */
   11158 	    } else if (IS_SCHEMA(child, "group")) {
   11159 		/* hasRedefinitions = 1; */
   11160 		xmlSchemaParseModelGroupDefinition(pctxt,
   11161 		    schema, child);
   11162 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
   11163 		/* hasRedefinitions = 1; */
   11164 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
   11165 		    child);
   11166 	    }
   11167 	    child = child->next;
   11168 	}
   11169 	pctxt->redefined = NULL;
   11170 	pctxt->isRedefine = 0;
   11171     } else {
   11172 	if (IS_SCHEMA(child, "annotation")) {
   11173 	    /*
   11174 	    * TODO: discard or not?
   11175 	    */
   11176 	    child = child->next;
   11177 	}
   11178     }
   11179     if (child != NULL) {
   11180 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
   11181 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
   11182 	    xmlSchemaPContentErr(pctxt, res,
   11183 		NULL, node, child, NULL,
   11184 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
   11185 	} else {
   11186 	     xmlSchemaPContentErr(pctxt, res,
   11187 		NULL, node, child, NULL,
   11188 		"(annotation?)");
   11189 	}
   11190     }
   11191     return(res);
   11192 
   11193 exit_error:
   11194     return(pctxt->err);
   11195 }
   11196 
   11197 static int
   11198 xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11199                        xmlNodePtr node)
   11200 {
   11201     int res;
   11202 #ifndef ENABLE_REDEFINE
   11203     TODO
   11204     return(0);
   11205 #endif
   11206     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11207 	XML_SCHEMA_SCHEMA_REDEFINE);
   11208     if (res != 0)
   11209 	return(res);
   11210     return(0);
   11211 }
   11212 
   11213 static int
   11214 xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
   11215                        xmlNodePtr node)
   11216 {
   11217     int res;
   11218 
   11219     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
   11220 	XML_SCHEMA_SCHEMA_INCLUDE);
   11221     if (res != 0)
   11222 	return(res);
   11223     return(0);
   11224 }
   11225 
   11226 /**
   11227  * xmlSchemaParseModelGroup:
   11228  * @ctxt:  a schema validation context
   11229  * @schema:  the schema being built
   11230  * @node:  a subtree containing XML Schema informations
   11231  * @type: the "compositor" type
   11232  * @particleNeeded: if a a model group with a particle
   11233  *
   11234  * parse a XML schema Sequence definition.
   11235  * Applies parts of:
   11236  *   Schema Representation Constraint:
   11237  *     Redefinition Constraints and Semantics (src-redefine)
   11238  *     (6.1), (6.1.1), (6.1.2)
   11239  *
   11240  *   Schema Component Constraint:
   11241  *     All Group Limited (cos-all-limited) (2)
   11242  *     TODO: Actually this should go to component-level checks,
   11243  *     but is done here due to performance. Move it to an other layer
   11244  *     is schema construction via an API is implemented.
   11245  *
   11246  * *WARNING* this interface is highly subject to change
   11247  *
   11248  * Returns -1 in case of error, 0 if the declaration is improper and
   11249  *         1 in case of success.
   11250  */
   11251 static xmlSchemaTreeItemPtr
   11252 xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11253 			 xmlNodePtr node, xmlSchemaTypeType type,
   11254 			 int withParticle)
   11255 {
   11256     xmlSchemaModelGroupPtr item;
   11257     xmlSchemaParticlePtr particle = NULL;
   11258     xmlNodePtr child = NULL;
   11259     xmlAttrPtr attr;
   11260     int min = 1, max = 1, isElemRef, hasRefs = 0;
   11261 
   11262     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11263         return (NULL);
   11264     /*
   11265     * Create a model group with the given compositor.
   11266     */
   11267     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
   11268     if (item == NULL)
   11269 	return (NULL);
   11270 
   11271     if (withParticle) {
   11272 	if (type == XML_SCHEMA_TYPE_ALL) {
   11273 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
   11274 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
   11275 	} else {
   11276 	    /* choice + sequence */
   11277 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
   11278 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
   11279 		"(xs:nonNegativeInteger | unbounded)");
   11280 	}
   11281 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
   11282 	/*
   11283 	* Create a particle
   11284 	*/
   11285 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
   11286 	if (particle == NULL)
   11287 	    return (NULL);
   11288 	particle->children = (xmlSchemaTreeItemPtr) item;
   11289 	/*
   11290 	* Check for illegal attributes.
   11291 	*/
   11292 	attr = node->properties;
   11293 	while (attr != NULL) {
   11294 	    if (attr->ns == NULL) {
   11295 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11296 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
   11297 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
   11298 		    xmlSchemaPIllegalAttrErr(ctxt,
   11299 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11300 		}
   11301 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11302 		xmlSchemaPIllegalAttrErr(ctxt,
   11303 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11304 	    }
   11305 	    attr = attr->next;
   11306 	}
   11307     } else {
   11308 	/*
   11309 	* Check for illegal attributes.
   11310 	*/
   11311 	attr = node->properties;
   11312 	while (attr != NULL) {
   11313 	    if (attr->ns == NULL) {
   11314 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
   11315 		    xmlSchemaPIllegalAttrErr(ctxt,
   11316 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11317 		}
   11318 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11319 		xmlSchemaPIllegalAttrErr(ctxt,
   11320 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11321 	    }
   11322 	    attr = attr->next;
   11323 	}
   11324     }
   11325 
   11326     /*
   11327     * Extract and validate attributes.
   11328     */
   11329     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11330     /*
   11331     * And now for the children...
   11332     */
   11333     child = node->children;
   11334     if (IS_SCHEMA(child, "annotation")) {
   11335         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   11336         child = child->next;
   11337     }
   11338     if (type == XML_SCHEMA_TYPE_ALL) {
   11339 	xmlSchemaParticlePtr part, last = NULL;
   11340 
   11341 	while (IS_SCHEMA(child, "element")) {
   11342 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
   11343 		schema, child, &isElemRef, 0);
   11344 	    /*
   11345 	    * SPEC cos-all-limited (2)
   11346 	    * "The {max occurs} of all the particles in the {particles}
   11347 	    * of the ('all') group must be 0 or 1.
   11348 	    */
   11349 	    if (part != NULL) {
   11350 		if (isElemRef)
   11351 		    hasRefs++;
   11352 		if (part->minOccurs > 1) {
   11353 		    xmlSchemaPCustomErr(ctxt,
   11354 			XML_SCHEMAP_COS_ALL_LIMITED,
   11355 			NULL, child,
   11356 			"Invalid value for minOccurs (must be 0 or 1)",
   11357 			NULL);
   11358 		    /* Reset to 1. */
   11359 		    part->minOccurs = 1;
   11360 		}
   11361 		if (part->maxOccurs > 1) {
   11362 		    xmlSchemaPCustomErr(ctxt,
   11363 			XML_SCHEMAP_COS_ALL_LIMITED,
   11364 			NULL, child,
   11365 			"Invalid value for maxOccurs (must be 0 or 1)",
   11366 			NULL);
   11367 		    /* Reset to 1. */
   11368 		    part->maxOccurs = 1;
   11369 		}
   11370 		if (last == NULL)
   11371 		    item->children = (xmlSchemaTreeItemPtr) part;
   11372 		else
   11373 		    last->next = (xmlSchemaTreeItemPtr) part;
   11374 		last = part;
   11375 	    }
   11376 	    child = child->next;
   11377 	}
   11378 	if (child != NULL) {
   11379 	    xmlSchemaPContentErr(ctxt,
   11380 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11381 		NULL, node, child, NULL,
   11382 		"(annotation?, (annotation?, element*)");
   11383 	}
   11384     } else {
   11385 	/* choice + sequence */
   11386 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
   11387 
   11388 	while ((IS_SCHEMA(child, "element")) ||
   11389 	    (IS_SCHEMA(child, "group")) ||
   11390 	    (IS_SCHEMA(child, "any")) ||
   11391 	    (IS_SCHEMA(child, "choice")) ||
   11392 	    (IS_SCHEMA(child, "sequence"))) {
   11393 
   11394 	    if (IS_SCHEMA(child, "element")) {
   11395 		part = (xmlSchemaTreeItemPtr)
   11396 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
   11397 		if (part && isElemRef)
   11398 		    hasRefs++;
   11399 	    } else if (IS_SCHEMA(child, "group")) {
   11400 		part =
   11401 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11402 		if (part != NULL)
   11403 		    hasRefs++;
   11404 		/*
   11405 		* Handle redefinitions.
   11406 		*/
   11407 		if (ctxt->isRedefine && ctxt->redef &&
   11408 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
   11409 		    part && part->children)
   11410 		{
   11411 		    if ((xmlSchemaGetQNameRefName(part->children) ==
   11412 			    ctxt->redef->refName) &&
   11413 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
   11414 			    ctxt->redef->refTargetNs))
   11415 		    {
   11416 			/*
   11417 			* SPEC src-redefine:
   11418 			* (6.1) "If it has a <group> among its contents at
   11419 			* some level the `actual value` of whose ref
   11420 			* [attribute] is the same as the `actual value` of
   11421 			* its own name attribute plus target namespace, then
   11422 			* all of the following must be true:"
   11423 			* (6.1.1) "It must have exactly one such group."
   11424 			*/
   11425 			if (ctxt->redefCounter != 0) {
   11426 			    xmlChar *str = NULL;
   11427 
   11428 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11429 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11430 				"The redefining model group definition "
   11431 				"'%s' must not contain more than one "
   11432 				"reference to the redefined definition",
   11433 				xmlSchemaFormatQName(&str,
   11434 				    ctxt->redef->refTargetNs,
   11435 				    ctxt->redef->refName),
   11436 				NULL);
   11437 			    FREE_AND_NULL(str)
   11438 			    part = NULL;
   11439 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
   11440 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
   11441 			{
   11442 			    xmlChar *str = NULL;
   11443 			    /*
   11444 			    * SPEC src-redefine:
   11445 			    * (6.1.2) "The `actual value` of both that
   11446 			    * group's minOccurs and maxOccurs [attribute]
   11447 			    * must be 1 (or `absent`).
   11448 			    */
   11449 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   11450 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
   11451 				"The redefining model group definition "
   11452 				"'%s' must not contain a reference to the "
   11453 				"redefined definition with a "
   11454 				"maxOccurs/minOccurs other than 1",
   11455 				xmlSchemaFormatQName(&str,
   11456 				    ctxt->redef->refTargetNs,
   11457 				    ctxt->redef->refName),
   11458 				NULL);
   11459 			    FREE_AND_NULL(str)
   11460 			    part = NULL;
   11461 			}
   11462 			ctxt->redef->reference = WXS_BASIC_CAST part;
   11463 			ctxt->redefCounter++;
   11464 		    }
   11465 		}
   11466 	    } else if (IS_SCHEMA(child, "any")) {
   11467 		part = (xmlSchemaTreeItemPtr)
   11468 		    xmlSchemaParseAny(ctxt, schema, child);
   11469 	    } else if (IS_SCHEMA(child, "choice")) {
   11470 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11471 		    XML_SCHEMA_TYPE_CHOICE, 1);
   11472 	    } else if (IS_SCHEMA(child, "sequence")) {
   11473 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
   11474 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11475 	    }
   11476 	    if (part != NULL) {
   11477 		if (last == NULL)
   11478 		    item->children = part;
   11479 		else
   11480 		    last->next = part;
   11481 		last = part;
   11482 	    }
   11483 	    child = child->next;
   11484 	}
   11485 	if (child != NULL) {
   11486 	    xmlSchemaPContentErr(ctxt,
   11487 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11488 		NULL, node, child, NULL,
   11489 		"(annotation?, (element | group | choice | sequence | any)*)");
   11490 	}
   11491     }
   11492     if ((max == 0) && (min == 0))
   11493 	return (NULL);
   11494     if (hasRefs) {
   11495 	/*
   11496 	* We need to resolve references.
   11497 	*/
   11498 	WXS_ADD_PENDING(ctxt, item);
   11499     }
   11500     if (withParticle)
   11501 	return ((xmlSchemaTreeItemPtr) particle);
   11502     else
   11503 	return ((xmlSchemaTreeItemPtr) item);
   11504 }
   11505 
   11506 /**
   11507  * xmlSchemaParseRestriction:
   11508  * @ctxt:  a schema validation context
   11509  * @schema:  the schema being built
   11510  * @node:  a subtree containing XML Schema informations
   11511  *
   11512  * parse a XML schema Restriction definition
   11513  * *WARNING* this interface is highly subject to change
   11514  *
   11515  * Returns the type definition or NULL in case of error
   11516  */
   11517 static xmlSchemaTypePtr
   11518 xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11519                           xmlNodePtr node, xmlSchemaTypeType parentType)
   11520 {
   11521     xmlSchemaTypePtr type;
   11522     xmlNodePtr child = NULL;
   11523     xmlAttrPtr attr;
   11524 
   11525     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11526         return (NULL);
   11527     /* Not a component, don't create it. */
   11528     type = ctxt->ctxtType;
   11529     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   11530 
   11531     /*
   11532     * Check for illegal attributes.
   11533     */
   11534     attr = node->properties;
   11535     while (attr != NULL) {
   11536 	if (attr->ns == NULL) {
   11537 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11538 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11539 		xmlSchemaPIllegalAttrErr(ctxt,
   11540 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11541 	    }
   11542 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11543 	    xmlSchemaPIllegalAttrErr(ctxt,
   11544 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11545 	}
   11546 	attr = attr->next;
   11547     }
   11548     /*
   11549     * Extract and validate attributes.
   11550     */
   11551     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11552     /*
   11553     * Attribute
   11554     */
   11555     /*
   11556     * Extract the base type. The "base" attribute is mandatory if inside
   11557     * a complex type or if redefining.
   11558     *
   11559     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
   11560     * among its [children]), the simple type definition which is
   11561     * the {content type} of the type definition `resolved` to by
   11562     * the `actual value` of the base [attribute]"
   11563     */
   11564     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
   11565 	&(type->baseNs), &(type->base)) == 0)
   11566     {
   11567 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
   11568 	    xmlSchemaPMissingAttrErr(ctxt,
   11569 		XML_SCHEMAP_S4S_ATTR_MISSING,
   11570 		NULL, node, "base", NULL);
   11571 	} else if ((ctxt->isRedefine) &&
   11572 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
   11573 	{
   11574 	    if (type->base == NULL) {
   11575 		xmlSchemaPMissingAttrErr(ctxt,
   11576 		    XML_SCHEMAP_S4S_ATTR_MISSING,
   11577 		    NULL, node, "base", NULL);
   11578 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
   11579 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
   11580 	    {
   11581 		xmlChar *str1 = NULL, *str2 = NULL;
   11582 		/*
   11583 		* REDEFINE: SPEC src-redefine (5)
   11584 		* "Within the [children], each <simpleType> must have a
   11585 		* <restriction> among its [children] ... the `actual value` of
   11586 		* whose base [attribute] must be the same as the `actual value`
   11587 		* of its own name attribute plus target namespace;"
   11588 		*/
   11589 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   11590 		    NULL, node, "This is a redefinition, but the QName "
   11591 		    "value '%s' of the 'base' attribute does not match the "
   11592 		    "type's designation '%s'",
   11593 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
   11594 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
   11595 			type->name), NULL);
   11596 		FREE_AND_NULL(str1);
   11597 		FREE_AND_NULL(str2);
   11598 		/* Avoid confusion and erase the values. */
   11599 		type->base = NULL;
   11600 		type->baseNs = NULL;
   11601 	    }
   11602 	}
   11603     }
   11604     /*
   11605     * And now for the children...
   11606     */
   11607     child = node->children;
   11608     if (IS_SCHEMA(child, "annotation")) {
   11609 	/*
   11610 	* Add the annotation to the simple type ancestor.
   11611 	*/
   11612 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11613 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11614         child = child->next;
   11615     }
   11616     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
   11617 	/*
   11618 	* Corresponds to <simpleType><restriction><simpleType>.
   11619 	*/
   11620 	if (IS_SCHEMA(child, "simpleType")) {
   11621 	    if (type->base != NULL) {
   11622 		/*
   11623 		* src-restriction-base-or-simpleType
   11624 		* Either the base [attribute] or the simpleType [child] of the
   11625 		* <restriction> element must be present, but not both.
   11626 		*/
   11627 		xmlSchemaPContentErr(ctxt,
   11628 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11629 		    NULL, node, child,
   11630 		    "The attribute 'base' and the <simpleType> child are "
   11631 		    "mutually exclusive", NULL);
   11632 	    } else {
   11633 		type->baseType = (xmlSchemaTypePtr)
   11634 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11635 	    }
   11636 	    child = child->next;
   11637 	} else if (type->base == NULL) {
   11638 	    xmlSchemaPContentErr(ctxt,
   11639 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
   11640 		NULL, node, child,
   11641 		"Either the attribute 'base' or a <simpleType> child "
   11642 		"must be present", NULL);
   11643 	}
   11644     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11645 	/*
   11646 	* Corresponds to <complexType><complexContent><restriction>...
   11647 	* followed by:
   11648 	*
   11649 	* Model groups <all>, <choice> and <sequence>.
   11650 	*/
   11651 	if (IS_SCHEMA(child, "all")) {
   11652 	    type->subtypes = (xmlSchemaTypePtr)
   11653 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11654 		    XML_SCHEMA_TYPE_ALL, 1);
   11655 	    child = child->next;
   11656 	} else if (IS_SCHEMA(child, "choice")) {
   11657 	    type->subtypes = (xmlSchemaTypePtr)
   11658 		xmlSchemaParseModelGroup(ctxt,
   11659 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
   11660 	    child = child->next;
   11661 	} else if (IS_SCHEMA(child, "sequence")) {
   11662 	    type->subtypes = (xmlSchemaTypePtr)
   11663 		xmlSchemaParseModelGroup(ctxt, schema, child,
   11664 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   11665 	    child = child->next;
   11666 	/*
   11667 	* Model group reference <group>.
   11668 	*/
   11669 	} else if (IS_SCHEMA(child, "group")) {
   11670 	    type->subtypes = (xmlSchemaTypePtr)
   11671 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11672 	    /*
   11673 	    * Note that the reference will be resolved in
   11674 	    * xmlSchemaResolveTypeReferences();
   11675 	    */
   11676 	    child = child->next;
   11677 	}
   11678     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11679 	/*
   11680 	* Corresponds to <complexType><simpleContent><restriction>...
   11681 	*
   11682 	* "1.1 the simple type definition corresponding to the <simpleType>
   11683 	* among the [children] of <restriction> if there is one;"
   11684 	*/
   11685 	if (IS_SCHEMA(child, "simpleType")) {
   11686 	    /*
   11687 	    * We will store the to-be-restricted simple type in
   11688 	    * type->contentTypeDef *temporarily*.
   11689 	    */
   11690 	    type->contentTypeDef = (xmlSchemaTypePtr)
   11691 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
   11692 	    if ( type->contentTypeDef == NULL)
   11693 		return (NULL);
   11694 	    child = child->next;
   11695 	}
   11696     }
   11697 
   11698     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
   11699 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
   11700 	xmlSchemaFacetPtr facet, lastfacet = NULL;
   11701 	/*
   11702 	* Corresponds to <complexType><simpleContent><restriction>...
   11703 	* <simpleType><restriction>...
   11704 	*/
   11705 
   11706 	/*
   11707 	* Add the facets to the simple type ancestor.
   11708 	*/
   11709 	/*
   11710 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
   11711 	* Simple Type Definition Schema Representation Constraint:
   11712 	* *Single Facet Value*
   11713 	*/
   11714 	while ((IS_SCHEMA(child, "minInclusive")) ||
   11715 	    (IS_SCHEMA(child, "minExclusive")) ||
   11716 	    (IS_SCHEMA(child, "maxInclusive")) ||
   11717 	    (IS_SCHEMA(child, "maxExclusive")) ||
   11718 	    (IS_SCHEMA(child, "totalDigits")) ||
   11719 	    (IS_SCHEMA(child, "fractionDigits")) ||
   11720 	    (IS_SCHEMA(child, "pattern")) ||
   11721 	    (IS_SCHEMA(child, "enumeration")) ||
   11722 	    (IS_SCHEMA(child, "whiteSpace")) ||
   11723 	    (IS_SCHEMA(child, "length")) ||
   11724 	    (IS_SCHEMA(child, "maxLength")) ||
   11725 	    (IS_SCHEMA(child, "minLength"))) {
   11726 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
   11727 	    if (facet != NULL) {
   11728 		if (lastfacet == NULL)
   11729 		    type->facets = facet;
   11730 		else
   11731 		    lastfacet->next = facet;
   11732 		lastfacet = facet;
   11733 		lastfacet->next = NULL;
   11734 	    }
   11735 	    child = child->next;
   11736 	}
   11737 	/*
   11738 	* Create links for derivation and validation.
   11739 	*/
   11740 	if (type->facets != NULL) {
   11741 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
   11742 
   11743 	    facet = type->facets;
   11744 	    do {
   11745 		facetLink = (xmlSchemaFacetLinkPtr)
   11746 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
   11747 		if (facetLink == NULL) {
   11748 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
   11749 		    xmlFree(facetLink);
   11750 		    return (NULL);
   11751 		}
   11752 		facetLink->facet = facet;
   11753 		facetLink->next = NULL;
   11754 		if (lastFacetLink == NULL)
   11755 		    type->facetSet = facetLink;
   11756 		else
   11757 		    lastFacetLink->next = facetLink;
   11758 		lastFacetLink = facetLink;
   11759 		facet = facet->next;
   11760 	    } while (facet != NULL);
   11761 	}
   11762     }
   11763     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
   11764 	/*
   11765 	* Attribute uses/declarations.
   11766 	*/
   11767 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11768 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11769 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   11770 	    return(NULL);
   11771 	/*
   11772 	* Attribute wildcard.
   11773 	*/
   11774 	if (IS_SCHEMA(child, "anyAttribute")) {
   11775 	    type->attributeWildcard =
   11776 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11777 	    child = child->next;
   11778 	}
   11779     }
   11780     if (child != NULL) {
   11781 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11782 	    xmlSchemaPContentErr(ctxt,
   11783 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11784 		NULL, node, child, NULL,
   11785 		"annotation?, (group | all | choice | sequence)?, "
   11786 		"((attribute | attributeGroup)*, anyAttribute?))");
   11787 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
   11788 	     xmlSchemaPContentErr(ctxt,
   11789 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11790 		NULL, node, child, NULL,
   11791 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11792 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11793 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11794 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
   11795 	} else {
   11796 	    /* Simple type */
   11797 	    xmlSchemaPContentErr(ctxt,
   11798 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11799 		NULL, node, child, NULL,
   11800 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
   11801 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
   11802 		"length | minLength | maxLength | enumeration | whiteSpace | "
   11803 		"pattern)*))");
   11804 	}
   11805     }
   11806     return (NULL);
   11807 }
   11808 
   11809 /**
   11810  * xmlSchemaParseExtension:
   11811  * @ctxt:  a schema validation context
   11812  * @schema:  the schema being built
   11813  * @node:  a subtree containing XML Schema informations
   11814  *
   11815  * Parses an <extension>, which is found inside a
   11816  * <simpleContent> or <complexContent>.
   11817  * *WARNING* this interface is highly subject to change.
   11818  *
   11819  * TODO: Returns the type definition or NULL in case of error
   11820  */
   11821 static xmlSchemaTypePtr
   11822 xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   11823                         xmlNodePtr node, xmlSchemaTypeType parentType)
   11824 {
   11825     xmlSchemaTypePtr type;
   11826     xmlNodePtr child = NULL;
   11827     xmlAttrPtr attr;
   11828 
   11829     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   11830         return (NULL);
   11831     /* Not a component, don't create it. */
   11832     type = ctxt->ctxtType;
   11833     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
   11834 
   11835     /*
   11836     * Check for illegal attributes.
   11837     */
   11838     attr = node->properties;
   11839     while (attr != NULL) {
   11840 	if (attr->ns == NULL) {
   11841 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   11842 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
   11843 		xmlSchemaPIllegalAttrErr(ctxt,
   11844 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11845 	    }
   11846 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11847 	    xmlSchemaPIllegalAttrErr(ctxt,
   11848 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11849 	}
   11850 	attr = attr->next;
   11851     }
   11852 
   11853     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11854 
   11855     /*
   11856     * Attribute "base" - mandatory.
   11857     */
   11858     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
   11859 	"base", &(type->baseNs), &(type->base)) == 0) &&
   11860 	(type->base == NULL)) {
   11861 	xmlSchemaPMissingAttrErr(ctxt,
   11862 	    XML_SCHEMAP_S4S_ATTR_MISSING,
   11863 	    NULL, node, "base", NULL);
   11864     }
   11865     /*
   11866     * And now for the children...
   11867     */
   11868     child = node->children;
   11869     if (IS_SCHEMA(child, "annotation")) {
   11870 	/*
   11871 	* Add the annotation to the type ancestor.
   11872 	*/
   11873 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   11874 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   11875         child = child->next;
   11876     }
   11877     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11878 	/*
   11879 	* Corresponds to <complexType><complexContent><extension>... and:
   11880 	*
   11881 	* Model groups <all>, <choice>, <sequence> and <group>.
   11882 	*/
   11883 	if (IS_SCHEMA(child, "all")) {
   11884 	    type->subtypes = (xmlSchemaTypePtr)
   11885 		xmlSchemaParseModelGroup(ctxt, schema,
   11886 		    child, XML_SCHEMA_TYPE_ALL, 1);
   11887 	    child = child->next;
   11888 	} else if (IS_SCHEMA(child, "choice")) {
   11889 	    type->subtypes = (xmlSchemaTypePtr)
   11890 		xmlSchemaParseModelGroup(ctxt, schema,
   11891 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
   11892 	    child = child->next;
   11893 	} else if (IS_SCHEMA(child, "sequence")) {
   11894 	    type->subtypes = (xmlSchemaTypePtr)
   11895 		xmlSchemaParseModelGroup(ctxt, schema,
   11896 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
   11897 	    child = child->next;
   11898 	} else if (IS_SCHEMA(child, "group")) {
   11899 	    type->subtypes = (xmlSchemaTypePtr)
   11900 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   11901 	    /*
   11902 	    * Note that the reference will be resolved in
   11903 	    * xmlSchemaResolveTypeReferences();
   11904 	    */
   11905 	    child = child->next;
   11906 	}
   11907     }
   11908     if (child != NULL) {
   11909 	/*
   11910 	* Attribute uses/declarations.
   11911 	*/
   11912 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   11913 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   11914 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
   11915 	    return(NULL);
   11916 	/*
   11917 	* Attribute wildcard.
   11918 	*/
   11919 	if (IS_SCHEMA(child, "anyAttribute")) {
   11920 	    ctxt->ctxtType->attributeWildcard =
   11921 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
   11922 	    child = child->next;
   11923 	}
   11924     }
   11925     if (child != NULL) {
   11926 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
   11927 	    /* Complex content extension. */
   11928 	    xmlSchemaPContentErr(ctxt,
   11929 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11930 		NULL, node, child, NULL,
   11931 		"(annotation?, ((group | all | choice | sequence)?, "
   11932 		"((attribute | attributeGroup)*, anyAttribute?)))");
   11933 	} else {
   11934 	    /* Simple content extension. */
   11935 	    xmlSchemaPContentErr(ctxt,
   11936 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   11937 		NULL, node, child, NULL,
   11938 		"(annotation?, ((attribute | attributeGroup)*, "
   11939 		"anyAttribute?))");
   11940 	}
   11941     }
   11942     return (NULL);
   11943 }
   11944 
   11945 /**
   11946  * xmlSchemaParseSimpleContent:
   11947  * @ctxt:  a schema validation context
   11948  * @schema:  the schema being built
   11949  * @node:  a subtree containing XML Schema informations
   11950  *
   11951  * parse a XML schema SimpleContent definition
   11952  * *WARNING* this interface is highly subject to change
   11953  *
   11954  * Returns the type definition or NULL in case of error
   11955  */
   11956 static int
   11957 xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
   11958                             xmlSchemaPtr schema, xmlNodePtr node,
   11959 			    int *hasRestrictionOrExtension)
   11960 {
   11961     xmlSchemaTypePtr type;
   11962     xmlNodePtr child = NULL;
   11963     xmlAttrPtr attr;
   11964 
   11965     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   11966 	(hasRestrictionOrExtension == NULL))
   11967         return (-1);
   11968     *hasRestrictionOrExtension = 0;
   11969     /* Not a component, don't create it. */
   11970     type = ctxt->ctxtType;
   11971     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   11972     /*
   11973     * Check for illegal attributes.
   11974     */
   11975     attr = node->properties;
   11976     while (attr != NULL) {
   11977 	if (attr->ns == NULL) {
   11978 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
   11979 		xmlSchemaPIllegalAttrErr(ctxt,
   11980 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11981 	    }
   11982 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   11983 	    xmlSchemaPIllegalAttrErr(ctxt,
   11984 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   11985 	}
   11986 	attr = attr->next;
   11987     }
   11988 
   11989     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   11990 
   11991     /*
   11992     * And now for the children...
   11993     */
   11994     child = node->children;
   11995     if (IS_SCHEMA(child, "annotation")) {
   11996 	/*
   11997 	* Add the annotation to the complex type ancestor.
   11998 	*/
   11999 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   12000 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   12001         child = child->next;
   12002     }
   12003     if (child == NULL) {
   12004 	xmlSchemaPContentErr(ctxt,
   12005 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12006 	    NULL, node, NULL, NULL,
   12007 	    "(annotation?, (restriction | extension))");
   12008     }
   12009     if (child == NULL) {
   12010 	xmlSchemaPContentErr(ctxt,
   12011 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12012 	    NULL, node, NULL, NULL,
   12013 	    "(annotation?, (restriction | extension))");
   12014     }
   12015     if (IS_SCHEMA(child, "restriction")) {
   12016         xmlSchemaParseRestriction(ctxt, schema, child,
   12017 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   12018 	(*hasRestrictionOrExtension) = 1;
   12019         child = child->next;
   12020     } else if (IS_SCHEMA(child, "extension")) {
   12021         xmlSchemaParseExtension(ctxt, schema, child,
   12022 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
   12023 	(*hasRestrictionOrExtension) = 1;
   12024         child = child->next;
   12025     }
   12026     if (child != NULL) {
   12027 	xmlSchemaPContentErr(ctxt,
   12028 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12029 	    NULL, node, child, NULL,
   12030 	    "(annotation?, (restriction | extension))");
   12031     }
   12032     return (0);
   12033 }
   12034 
   12035 /**
   12036  * xmlSchemaParseComplexContent:
   12037  * @ctxt:  a schema validation context
   12038  * @schema:  the schema being built
   12039  * @node:  a subtree containing XML Schema informations
   12040  *
   12041  * parse a XML schema ComplexContent definition
   12042  * *WARNING* this interface is highly subject to change
   12043  *
   12044  * Returns the type definition or NULL in case of error
   12045  */
   12046 static int
   12047 xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
   12048                              xmlSchemaPtr schema, xmlNodePtr node,
   12049 			     int *hasRestrictionOrExtension)
   12050 {
   12051     xmlSchemaTypePtr type;
   12052     xmlNodePtr child = NULL;
   12053     xmlAttrPtr attr;
   12054 
   12055     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
   12056 	(hasRestrictionOrExtension == NULL))
   12057         return (-1);
   12058     *hasRestrictionOrExtension = 0;
   12059     /* Not a component, don't create it. */
   12060     type = ctxt->ctxtType;
   12061     /*
   12062     * Check for illegal attributes.
   12063     */
   12064     attr = node->properties;
   12065     while (attr != NULL) {
   12066 	if (attr->ns == NULL) {
   12067 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
   12068 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
   12069 	    {
   12070 		xmlSchemaPIllegalAttrErr(ctxt,
   12071 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12072 	    }
   12073 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12074 	    xmlSchemaPIllegalAttrErr(ctxt,
   12075 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12076 	}
   12077 	attr = attr->next;
   12078     }
   12079 
   12080     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12081 
   12082     /*
   12083     * Set the 'mixed' on the complex type ancestor.
   12084     */
   12085     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
   12086 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
   12087 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12088     }
   12089     child = node->children;
   12090     if (IS_SCHEMA(child, "annotation")) {
   12091 	/*
   12092 	* Add the annotation to the complex type ancestor.
   12093 	*/
   12094 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
   12095 	    xmlSchemaParseAnnotation(ctxt, child, 1));
   12096         child = child->next;
   12097     }
   12098     if (child == NULL) {
   12099 	xmlSchemaPContentErr(ctxt,
   12100 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12101 	    NULL, node, NULL,
   12102 	    NULL, "(annotation?, (restriction | extension))");
   12103     }
   12104     if (child == NULL) {
   12105 	xmlSchemaPContentErr(ctxt,
   12106 	    XML_SCHEMAP_S4S_ELEM_MISSING,
   12107 	    NULL, node, NULL,
   12108 	    NULL, "(annotation?, (restriction | extension))");
   12109     }
   12110     if (IS_SCHEMA(child, "restriction")) {
   12111         xmlSchemaParseRestriction(ctxt, schema, child,
   12112 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12113 	(*hasRestrictionOrExtension) = 1;
   12114         child = child->next;
   12115     } else if (IS_SCHEMA(child, "extension")) {
   12116         xmlSchemaParseExtension(ctxt, schema, child,
   12117 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
   12118 	(*hasRestrictionOrExtension) = 1;
   12119         child = child->next;
   12120     }
   12121     if (child != NULL) {
   12122 	xmlSchemaPContentErr(ctxt,
   12123 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12124 	    NULL, node, child,
   12125 	    NULL, "(annotation?, (restriction | extension))");
   12126     }
   12127     return (0);
   12128 }
   12129 
   12130 /**
   12131  * xmlSchemaParseComplexType:
   12132  * @ctxt:  a schema validation context
   12133  * @schema:  the schema being built
   12134  * @node:  a subtree containing XML Schema informations
   12135  *
   12136  * parse a XML schema Complex Type definition
   12137  * *WARNING* this interface is highly subject to change
   12138  *
   12139  * Returns the type definition or NULL in case of error
   12140  */
   12141 static xmlSchemaTypePtr
   12142 xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
   12143                           xmlNodePtr node, int topLevel)
   12144 {
   12145     xmlSchemaTypePtr type, ctxtType;
   12146     xmlNodePtr child = NULL;
   12147     const xmlChar *name = NULL;
   12148     xmlAttrPtr attr;
   12149     const xmlChar *attrValue;
   12150 #ifdef ENABLE_NAMED_LOCALS
   12151     char buf[40];
   12152 #endif
   12153     int final = 0, block = 0, hasRestrictionOrExtension = 0;
   12154 
   12155 
   12156     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
   12157         return (NULL);
   12158 
   12159     ctxtType = ctxt->ctxtType;
   12160 
   12161     if (topLevel) {
   12162 	attr = xmlSchemaGetPropNode(node, "name");
   12163 	if (attr == NULL) {
   12164 	    xmlSchemaPMissingAttrErr(ctxt,
   12165 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
   12166 	    return (NULL);
   12167 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
   12168 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
   12169 	    return (NULL);
   12170 	}
   12171     }
   12172 
   12173     if (topLevel == 0) {
   12174 	/*
   12175 	* Parse as local complex type definition.
   12176 	*/
   12177 #ifdef ENABLE_NAMED_LOCALS
   12178         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
   12179 	type = xmlSchemaAddType(ctxt, schema,
   12180 	    XML_SCHEMA_TYPE_COMPLEX,
   12181 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
   12182 	    ctxt->targetNamespace, node, 0);
   12183 #else
   12184 	type = xmlSchemaAddType(ctxt, schema,
   12185 	    XML_SCHEMA_TYPE_COMPLEX,
   12186 	    NULL, ctxt->targetNamespace, node, 0);
   12187 #endif
   12188 	if (type == NULL)
   12189 	    return (NULL);
   12190 	name = type->name;
   12191 	type->node = node;
   12192 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12193 	/*
   12194 	* TODO: We need the target namespace.
   12195 	*/
   12196     } else {
   12197 	/*
   12198 	* Parse as global complex type definition.
   12199 	*/
   12200 	type = xmlSchemaAddType(ctxt, schema,
   12201 	    XML_SCHEMA_TYPE_COMPLEX,
   12202 	    name, ctxt->targetNamespace, node, 1);
   12203 	if (type == NULL)
   12204 	    return (NULL);
   12205 	type->node = node;
   12206 	type->type = XML_SCHEMA_TYPE_COMPLEX;
   12207 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
   12208     }
   12209     type->targetNamespace = ctxt->targetNamespace;
   12210     /*
   12211     * Handle attributes.
   12212     */
   12213     attr = node->properties;
   12214     while (attr != NULL) {
   12215 	if (attr->ns == NULL) {
   12216 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
   12217 		/*
   12218 		* Attribute "id".
   12219 		*/
   12220 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
   12221 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
   12222 		/*
   12223 		* Attribute "mixed".
   12224 		*/
   12225 		if (xmlSchemaPGetBoolNodeValue(ctxt,
   12226 			NULL, (xmlNodePtr) attr))
   12227 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
   12228 	    } else if (topLevel) {
   12229 		/*
   12230 		* Attributes of global complex type definitions.
   12231 		*/
   12232 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
   12233 		    /* Pass. */
   12234 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
   12235 		    /*
   12236 		    * Attribute "abstract".
   12237 		    */
   12238 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
   12239 			    NULL, (xmlNodePtr) attr))
   12240 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
   12241 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
   12242 		    /*
   12243 		    * Attribute "final".
   12244 		    */
   12245 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12246 			(xmlNodePtr) attr);
   12247 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
   12248 			&(type->flags),
   12249 			-1,
   12250 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
   12251 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
   12252 			-1, -1, -1) != 0)
   12253 		    {
   12254 			xmlSchemaPSimpleTypeErr(ctxt,
   12255 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12256 			    NULL, (xmlNodePtr) attr, NULL,
   12257 			    "(#all | List of (extension | restriction))",
   12258 			    attrValue, NULL, NULL, NULL);
   12259 		    } else
   12260 			final = 1;
   12261 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
   12262 		    /*
   12263 		    * Attribute "block".
   12264 		    */
   12265 		    attrValue = xmlSchemaGetNodeContent(ctxt,
   12266 			(xmlNodePtr) attr);
   12267 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
   12268 			-1,
   12269 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
   12270 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
   12271 			-1, -1, -1) != 0) {
   12272 			xmlSchemaPSimpleTypeErr(ctxt,
   12273 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
   12274 			    NULL, (xmlNodePtr) attr, NULL,
   12275 			    "(#all | List of (extension | restriction)) ",
   12276 			    attrValue, NULL, NULL, NULL);
   12277 		    } else
   12278 			block = 1;
   12279 		} else {
   12280 			xmlSchemaPIllegalAttrErr(ctxt,
   12281 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12282 		}
   12283 	    } else {
   12284 		xmlSchemaPIllegalAttrErr(ctxt,
   12285 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12286 	    }
   12287 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
   12288 	    xmlSchemaPIllegalAttrErr(ctxt,
   12289 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
   12290 	}
   12291 	attr = attr->next;
   12292     }
   12293     if (! block) {
   12294 	/*
   12295 	* Apply default "block" values.
   12296 	*/
   12297 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
   12298 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   12299 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
   12300 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   12301     }
   12302     if (! final) {
   12303 	/*
   12304 	* Apply default "block" values.
   12305 	*/
   12306 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
   12307 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
   12308 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
   12309 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
   12310     }
   12311     /*
   12312     * And now for the children...
   12313     */
   12314     child = node->children;
   12315     if (IS_SCHEMA(child, "annotation")) {
   12316         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
   12317         child = child->next;
   12318     }
   12319     ctxt->ctxtType = type;
   12320     if (IS_SCHEMA(child, "simpleContent")) {
   12321 	/*
   12322 	* <complexType><simpleContent>...
   12323 	* 3.4.3 : 2.2
   12324 	* Specifying mixed='true' when the <simpleContent>
   12325 	* alternative is chosen has no effect
   12326 	*/
   12327 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   12328 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
   12329         xmlSchemaParseSimpleContent(ctxt, schema, child,
   12330 	    &hasRestrictionOrExtension);
   12331         child = child->next;
   12332     } else if (IS_SCHEMA(child, "complexContent")) {
   12333 	/*
   12334 	* <complexType><complexContent>...
   12335 	*/
   12336 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   12337         xmlSchemaParseComplexContent(ctxt, schema, child,
   12338 	    &hasRestrictionOrExtension);
   12339         child = child->next;
   12340     } else {
   12341 	/*
   12342 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
   12343 	*
   12344 	* SPEC
   12345 	* "...the third alternative (neither <simpleContent> nor
   12346 	* <complexContent>) is chosen. This case is understood as shorthand
   12347 	* for complex content restricting the `ur-type definition`, and the
   12348 	* details of the mappings should be modified as necessary.
   12349 	*/
   12350 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   12351 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
   12352 	/*
   12353 	* Parse model groups.
   12354 	*/
   12355         if (IS_SCHEMA(child, "all")) {
   12356             type->subtypes = (xmlSchemaTypePtr)
   12357 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12358 		    XML_SCHEMA_TYPE_ALL, 1);
   12359             child = child->next;
   12360         } else if (IS_SCHEMA(child, "choice")) {
   12361             type->subtypes = (xmlSchemaTypePtr)
   12362 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12363 		    XML_SCHEMA_TYPE_CHOICE, 1);
   12364             child = child->next;
   12365         } else if (IS_SCHEMA(child, "sequence")) {
   12366             type->subtypes = (xmlSchemaTypePtr)
   12367 		xmlSchemaParseModelGroup(ctxt, schema, child,
   12368 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
   12369             child = child->next;
   12370         } else if (IS_SCHEMA(child, "group")) {
   12371             type->subtypes = (xmlSchemaTypePtr)
   12372 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
   12373 	    /*
   12374 	    * Note that the reference will be resolved in
   12375 	    * xmlSchemaResolveTypeReferences();
   12376 	    */
   12377             child = child->next;
   12378         }
   12379 	/*
   12380 	* Parse attribute decls/refs.
   12381 	*/
   12382         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
   12383 	    (xmlSchemaItemListPtr *) &(type->attrUses),
   12384 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
   12385 	    return(NULL);
   12386 	/*
   12387 	* Parse attribute wildcard.
   12388 	*/
   12389 	if (IS_SCHEMA(child, "anyAttribute")) {
   12390 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
   12391 	    child = child->next;
   12392 	}
   12393     }
   12394     if (child != NULL) {
   12395 	xmlSchemaPContentErr(ctxt,
   12396 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
   12397 	    NULL, node, child,
   12398 	    NULL, "(annotation?, (simpleContent | complexContent | "
   12399 	    "((group | all | choice | sequence)?, ((attribute | "
   12400 	    "attributeGroup)*, anyAttribute?))))");
   12401     }
   12402     /*
   12403     * REDEFINE: SPEC src-redefine (5)
   12404     */
   12405     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
   12406 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
   12407 	    NULL, node, "This is a redefinition, thus the "
   12408 	    "<complexType> must have a <restriction> or <extension> "
   12409 	    "grand-child", NULL);
   12410     }
   12411     ctxt->ctxtType = ctxtType;
   12412     return (type);
   12413 }
   12414 
   12415 /************************************************************************
   12416  *									*
   12417  *			Validating using Schemas			*
   12418  *									*
   12419  ************************************************************************/
   12420 
   12421 /************************************************************************
   12422  *									*
   12423  *			Reading/Writing Schemas				*
   12424  *									*
   12425  ************************************************************************/
   12426 
   12427 #if 0 /* Will be enabled if it is clear what options are needed. */
   12428 /**
   12429  * xmlSchemaParserCtxtSetOptions:
   12430  * @ctxt:	a schema parser context
   12431  * @options: a combination of xmlSchemaParserOption
   12432  *
   12433  * Sets the options to be used during the parse.
   12434  *
   12435  * Returns 0 in case of success, -1 in case of an
   12436  * API error.
   12437  */
   12438 static int
   12439 xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
   12440 			      int options)
   12441 
   12442 {
   12443     int i;
   12444 
   12445     if (ctxt == NULL)
   12446 	return (-1);
   12447     /*
   12448     * WARNING: Change the start value if adding to the
   12449     * xmlSchemaParseOption.
   12450     */
   12451     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   12452         if (options & 1<<i) {
   12453 	    return (-1);
   12454         }
   12455     }
   12456     ctxt->options = options;
   12457     return (0);
   12458 }
   12459 
   12460 /**
   12461  * xmlSchemaValidCtxtGetOptions:
   12462  * @ctxt: a schema parser context
   12463  *
   12464  * Returns the option combination of the parser context.
   12465  */
   12466 static int
   12467 xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
   12468 
   12469 {
   12470     if (ctxt == NULL)
   12471 	return (-1);
   12472     else
   12473 	return (ctxt->options);
   12474 }
   12475 #endif
   12476 
   12477 /**
   12478  * xmlSchemaNewParserCtxt:
   12479  * @URL:  the location of the schema
   12480  *
   12481  * Create an XML Schemas parse context for that file/resource expected
   12482  * to contain an XML Schemas file.
   12483  *
   12484  * Returns the parser context or NULL in case of error
   12485  */
   12486 xmlSchemaParserCtxtPtr
   12487 xmlSchemaNewParserCtxt(const char *URL)
   12488 {
   12489     xmlSchemaParserCtxtPtr ret;
   12490 
   12491     if (URL == NULL)
   12492         return (NULL);
   12493 
   12494     ret = xmlSchemaParserCtxtCreate();
   12495     if (ret == NULL)
   12496 	return(NULL);
   12497     ret->dict = xmlDictCreate();
   12498     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
   12499     return (ret);
   12500 }
   12501 
   12502 /**
   12503  * xmlSchemaNewMemParserCtxt:
   12504  * @buffer:  a pointer to a char array containing the schemas
   12505  * @size:  the size of the array
   12506  *
   12507  * Create an XML Schemas parse context for that memory buffer expected
   12508  * to contain an XML Schemas file.
   12509  *
   12510  * Returns the parser context or NULL in case of error
   12511  */
   12512 xmlSchemaParserCtxtPtr
   12513 xmlSchemaNewMemParserCtxt(const char *buffer, int size)
   12514 {
   12515     xmlSchemaParserCtxtPtr ret;
   12516 
   12517     if ((buffer == NULL) || (size <= 0))
   12518         return (NULL);
   12519     ret = xmlSchemaParserCtxtCreate();
   12520     if (ret == NULL)
   12521 	return(NULL);
   12522     ret->buffer = buffer;
   12523     ret->size = size;
   12524     ret->dict = xmlDictCreate();
   12525     return (ret);
   12526 }
   12527 
   12528 /**
   12529  * xmlSchemaNewDocParserCtxt:
   12530  * @doc:  a preparsed document tree
   12531  *
   12532  * Create an XML Schemas parse context for that document.
   12533  * NB. The document may be modified during the parsing process.
   12534  *
   12535  * Returns the parser context or NULL in case of error
   12536  */
   12537 xmlSchemaParserCtxtPtr
   12538 xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
   12539 {
   12540     xmlSchemaParserCtxtPtr ret;
   12541 
   12542     if (doc == NULL)
   12543       return (NULL);
   12544     ret = xmlSchemaParserCtxtCreate();
   12545     if (ret == NULL)
   12546 	return(NULL);
   12547     ret->doc = doc;
   12548     ret->dict = xmlDictCreate();
   12549     /* The application has responsibility for the document */
   12550     ret->preserve = 1;
   12551 
   12552     return (ret);
   12553 }
   12554 
   12555 /**
   12556  * xmlSchemaFreeParserCtxt:
   12557  * @ctxt:  the schema parser context
   12558  *
   12559  * Free the resources associated to the schema parser context
   12560  */
   12561 void
   12562 xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
   12563 {
   12564     if (ctxt == NULL)
   12565         return;
   12566     if (ctxt->doc != NULL && !ctxt->preserve)
   12567         xmlFreeDoc(ctxt->doc);
   12568     if (ctxt->vctxt != NULL) {
   12569 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
   12570     }
   12571     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
   12572 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   12573 	ctxt->constructor = NULL;
   12574 	ctxt->ownsConstructor = 0;
   12575     }
   12576     if (ctxt->attrProhibs != NULL)
   12577 	xmlSchemaItemListFree(ctxt->attrProhibs);
   12578     xmlDictFree(ctxt->dict);
   12579     xmlFree(ctxt);
   12580 }
   12581 
   12582 /************************************************************************
   12583  *									*
   12584  *			Building the content models			*
   12585  *									*
   12586  ************************************************************************/
   12587 
   12588 /**
   12589  * xmlSchemaBuildContentModelForSubstGroup:
   12590  *
   12591  * Returns 1 if nillable, 0 otherwise
   12592  */
   12593 static int
   12594 xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
   12595 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
   12596 {
   12597     xmlAutomataStatePtr start, tmp;
   12598     xmlSchemaElementPtr elemDecl, member;
   12599     xmlSchemaSubstGroupPtr substGroup;
   12600     int i;
   12601     int ret = 0;
   12602 
   12603     elemDecl = (xmlSchemaElementPtr) particle->children;
   12604     /*
   12605     * Wrap the substitution group with a CHOICE.
   12606     */
   12607     start = pctxt->state;
   12608     if (end == NULL)
   12609 	end = xmlAutomataNewState(pctxt->am);
   12610     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
   12611     if (substGroup == NULL) {
   12612 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
   12613 	    XML_SCHEMAP_INTERNAL,
   12614 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
   12615 	    "declaration is marked having a subst. group but none "
   12616 	    "available.\n", elemDecl->name, NULL);
   12617 	return(0);
   12618     }
   12619     if (counter >= 0) {
   12620 	/*
   12621 	* NOTE that we put the declaration in, even if it's abstract.
   12622 	* However, an error will be raised during *validation* if an element
   12623 	* information item shall be validated against an abstract element
   12624 	* declaration.
   12625 	*/
   12626 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
   12627         xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12628 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12629 	/*
   12630 	* Add subst. group members.
   12631 	*/
   12632 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12633 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12634             xmlAutomataNewTransition2(pctxt->am, tmp, end,
   12635 		               member->name, member->targetNamespace, member);
   12636 	}
   12637     } else if (particle->maxOccurs == 1) {
   12638 	/*
   12639 	* NOTE that we put the declaration in, even if it's abstract,
   12640 	*/
   12641 	xmlAutomataNewEpsilon(pctxt->am,
   12642 	    xmlAutomataNewTransition2(pctxt->am,
   12643 	    start, NULL,
   12644 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
   12645 	/*
   12646 	* Add subst. group members.
   12647 	*/
   12648 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12649 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12650 	    /*
   12651 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
   12652 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
   12653 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
   12654 	    *  section in xmlSchemaBuildAContentModel() ).
   12655 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
   12656 	    *  intended for the above "counter" section originally. I.e.,
   12657 	    *  check xs:all with subst-groups.
   12658 	    *
   12659 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
   12660 	    *	               member->name, member->targetNamespace,
   12661 	    *		       1, 1, member);
   12662 	    */
   12663 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
   12664 		member->name, member->targetNamespace, member);
   12665 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
   12666 	}
   12667     } else {
   12668 	xmlAutomataStatePtr hop;
   12669 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12670 	    UNBOUNDED : particle->maxOccurs - 1;
   12671 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12672 
   12673 	counter =
   12674 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
   12675 	    maxOccurs);
   12676 	hop = xmlAutomataNewState(pctxt->am);
   12677 
   12678 	xmlAutomataNewEpsilon(pctxt->am,
   12679 	    xmlAutomataNewTransition2(pctxt->am,
   12680 	    start, NULL,
   12681 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
   12682 	    hop);
   12683 	/*
   12684 	 * Add subst. group members.
   12685 	 */
   12686 	for (i = 0; i < substGroup->members->nbItems; i++) {
   12687 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
   12688 	    xmlAutomataNewEpsilon(pctxt->am,
   12689 		xmlAutomataNewTransition2(pctxt->am,
   12690 		start, NULL,
   12691 		member->name, member->targetNamespace, member),
   12692 		hop);
   12693 	}
   12694 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12695 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12696     }
   12697     if (particle->minOccurs == 0) {
   12698 	xmlAutomataNewEpsilon(pctxt->am, start, end);
   12699         ret = 1;
   12700     }
   12701     pctxt->state = end;
   12702     return(ret);
   12703 }
   12704 
   12705 /**
   12706  * xmlSchemaBuildContentModelForElement:
   12707  *
   12708  * Returns 1 if nillable, 0 otherwise
   12709  */
   12710 static int
   12711 xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
   12712 				     xmlSchemaParticlePtr particle)
   12713 {
   12714     int ret = 0;
   12715 
   12716     if (((xmlSchemaElementPtr) particle->children)->flags &
   12717 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   12718 	/*
   12719 	* Substitution groups.
   12720 	*/
   12721 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
   12722     } else {
   12723 	xmlSchemaElementPtr elemDecl;
   12724 	xmlAutomataStatePtr start;
   12725 
   12726 	elemDecl = (xmlSchemaElementPtr) particle->children;
   12727 
   12728 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
   12729 	    return(0);
   12730 	if (particle->maxOccurs == 1) {
   12731 	    start = ctxt->state;
   12732 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12733 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12734 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
   12735 	           (particle->minOccurs < 2)) {
   12736 	    /* Special case. */
   12737 	    start = ctxt->state;
   12738 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12739 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12740 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
   12741 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12742 	} else {
   12743 	    int counter;
   12744 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   12745 			    UNBOUNDED : particle->maxOccurs - 1;
   12746 	    int minOccurs = particle->minOccurs < 1 ?
   12747 			    0 : particle->minOccurs - 1;
   12748 
   12749 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
   12750 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
   12751 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
   12752 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
   12753 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
   12754 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
   12755 		NULL, counter);
   12756 	}
   12757 	if (particle->minOccurs == 0) {
   12758 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
   12759             ret = 1;
   12760         }
   12761     }
   12762     return(ret);
   12763 }
   12764 
   12765 /**
   12766  * xmlSchemaBuildAContentModel:
   12767  * @ctxt:  the schema parser context
   12768  * @particle:  the particle component
   12769  * @name:  the complex type's name whose content is being built
   12770  *
   12771  * Create the automaton for the {content type} of a complex type.
   12772  *
   12773  * Returns 1 if the content is nillable, 0 otherwise
   12774  */
   12775 static int
   12776 xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
   12777 			    xmlSchemaParticlePtr particle)
   12778 {
   12779     int ret = 0, tmp2;
   12780 
   12781     if (particle == NULL) {
   12782 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
   12783 	return(1);
   12784     }
   12785     if (particle->children == NULL) {
   12786 	/*
   12787 	* Just return in this case. A missing "term" of the particle
   12788 	* might arise due to an invalid "term" component.
   12789 	*/
   12790 	return(1);
   12791     }
   12792 
   12793     switch (particle->children->type) {
   12794 	case XML_SCHEMA_TYPE_ANY: {
   12795 	    xmlAutomataStatePtr start, end;
   12796 	    xmlSchemaWildcardPtr wild;
   12797 	    xmlSchemaWildcardNsPtr ns;
   12798 
   12799 	    wild = (xmlSchemaWildcardPtr) particle->children;
   12800 
   12801 	    start = pctxt->state;
   12802 	    end = xmlAutomataNewState(pctxt->am);
   12803 
   12804 	    if (particle->maxOccurs == 1) {
   12805 		if (wild->any == 1) {
   12806 		    /*
   12807 		    * We need to add both transitions:
   12808 		    *
   12809 		    * 1. the {"*", "*"} for elements in a namespace.
   12810 		    */
   12811 		    pctxt->state =
   12812 			xmlAutomataNewTransition2(pctxt->am,
   12813 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12814 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12815 		    /*
   12816 		    * 2. the {"*"} for elements in no namespace.
   12817 		    */
   12818 		    pctxt->state =
   12819 			xmlAutomataNewTransition2(pctxt->am,
   12820 			start, NULL, BAD_CAST "*", NULL, wild);
   12821 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12822 
   12823 		} else if (wild->nsSet != NULL) {
   12824 		    ns = wild->nsSet;
   12825 		    do {
   12826 			pctxt->state = start;
   12827 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
   12828 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
   12829 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   12830 			ns = ns->next;
   12831 		    } while (ns != NULL);
   12832 
   12833 		} else if (wild->negNsSet != NULL) {
   12834 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12835 			start, end, BAD_CAST "*", wild->negNsSet->value,
   12836 			wild);
   12837 		}
   12838 	    } else {
   12839 		int counter;
   12840 		xmlAutomataStatePtr hop;
   12841 		int maxOccurs =
   12842 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
   12843                                            particle->maxOccurs - 1;
   12844 		int minOccurs =
   12845 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   12846 
   12847 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   12848 		hop = xmlAutomataNewState(pctxt->am);
   12849 		if (wild->any == 1) {
   12850 		    pctxt->state =
   12851 			xmlAutomataNewTransition2(pctxt->am,
   12852 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
   12853 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12854 		    pctxt->state =
   12855 			xmlAutomataNewTransition2(pctxt->am,
   12856 			start, NULL, BAD_CAST "*", NULL, wild);
   12857 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12858 		} else if (wild->nsSet != NULL) {
   12859 		    ns = wild->nsSet;
   12860 		    do {
   12861 			pctxt->state =
   12862 			    xmlAutomataNewTransition2(pctxt->am,
   12863 				start, NULL, BAD_CAST "*", ns->value, wild);
   12864 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   12865 			ns = ns->next;
   12866 		    } while (ns != NULL);
   12867 
   12868 		} else if (wild->negNsSet != NULL) {
   12869 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
   12870 			start, hop, BAD_CAST "*", wild->negNsSet->value,
   12871 			wild);
   12872 		}
   12873 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
   12874 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   12875 	    }
   12876 	    if (particle->minOccurs == 0) {
   12877 		xmlAutomataNewEpsilon(pctxt->am, start, end);
   12878                 ret = 1;
   12879 	    }
   12880 	    pctxt->state = end;
   12881             break;
   12882 	}
   12883         case XML_SCHEMA_TYPE_ELEMENT:
   12884 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
   12885 	    break;
   12886         case XML_SCHEMA_TYPE_SEQUENCE:{
   12887             xmlSchemaTreeItemPtr sub;
   12888 
   12889             ret = 1;
   12890             /*
   12891              * If max and min occurances are default (1) then
   12892              * simply iterate over the particles of the <sequence>.
   12893              */
   12894             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
   12895                 sub = particle->children->children;
   12896 
   12897                 while (sub != NULL) {
   12898                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12899                                         (xmlSchemaParticlePtr) sub);
   12900                     if (tmp2 != 1) ret = 0;
   12901                     sub = sub->next;
   12902                 }
   12903             } else {
   12904                 xmlAutomataStatePtr oldstate = pctxt->state;
   12905 
   12906                 if (particle->maxOccurs >= UNBOUNDED) {
   12907                     if (particle->minOccurs > 1) {
   12908                         xmlAutomataStatePtr tmp;
   12909                         int counter;
   12910 
   12911                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12912                             oldstate, NULL);
   12913                         oldstate = pctxt->state;
   12914 
   12915                         counter = xmlAutomataNewCounter(pctxt->am,
   12916                             particle->minOccurs - 1, UNBOUNDED);
   12917 
   12918                         sub = particle->children->children;
   12919                         while (sub != NULL) {
   12920                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12921                                             (xmlSchemaParticlePtr) sub);
   12922                             if (tmp2 != 1) ret = 0;
   12923                             sub = sub->next;
   12924                         }
   12925                         tmp = pctxt->state;
   12926                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
   12927                                                    oldstate, counter);
   12928                         pctxt->state =
   12929                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
   12930                                                        NULL, counter);
   12931                         if (ret == 1)
   12932                             xmlAutomataNewEpsilon(pctxt->am,
   12933                                                 oldstate, pctxt->state);
   12934 
   12935                     } else {
   12936                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12937                             oldstate, NULL);
   12938                         oldstate = pctxt->state;
   12939 
   12940                         sub = particle->children->children;
   12941                         while (sub != NULL) {
   12942                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12943                                         (xmlSchemaParticlePtr) sub);
   12944                             if (tmp2 != 1) ret = 0;
   12945                             sub = sub->next;
   12946                         }
   12947                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
   12948                                               oldstate);
   12949                         /*
   12950                          * epsilon needed to block previous trans from
   12951                          * being allowed to enter back from another
   12952                          * construct
   12953                          */
   12954                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12955                                             pctxt->state, NULL);
   12956                         if (particle->minOccurs == 0) {
   12957                             xmlAutomataNewEpsilon(pctxt->am,
   12958                                 oldstate, pctxt->state);
   12959                             ret = 1;
   12960                         }
   12961                     }
   12962                 } else if ((particle->maxOccurs > 1)
   12963                            || (particle->minOccurs > 1)) {
   12964                     xmlAutomataStatePtr tmp;
   12965                     int counter;
   12966 
   12967                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   12968                         oldstate, NULL);
   12969                     oldstate = pctxt->state;
   12970 
   12971                     counter = xmlAutomataNewCounter(pctxt->am,
   12972                         particle->minOccurs - 1,
   12973                         particle->maxOccurs - 1);
   12974 
   12975                     sub = particle->children->children;
   12976                     while (sub != NULL) {
   12977                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12978                                         (xmlSchemaParticlePtr) sub);
   12979                         if (tmp2 != 1) ret = 0;
   12980                         sub = sub->next;
   12981                     }
   12982                     tmp = pctxt->state;
   12983                     xmlAutomataNewCountedTrans(pctxt->am,
   12984                         tmp, oldstate, counter);
   12985                     pctxt->state =
   12986                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
   12987                                                    counter);
   12988                     if ((particle->minOccurs == 0) || (ret == 1)) {
   12989                         xmlAutomataNewEpsilon(pctxt->am,
   12990                                             oldstate, pctxt->state);
   12991                         ret = 1;
   12992                     }
   12993                 } else {
   12994                     sub = particle->children->children;
   12995                     while (sub != NULL) {
   12996                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
   12997                                         (xmlSchemaParticlePtr) sub);
   12998                         if (tmp2 != 1) ret = 0;
   12999                         sub = sub->next;
   13000                     }
   13001 
   13002 		    /*
   13003 		     * epsilon needed to block previous trans from
   13004 		     * being allowed to enter back from another
   13005 		     * construct
   13006 		     */
   13007 		    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
   13008 					pctxt->state, NULL);
   13009 
   13010                     if (particle->minOccurs == 0) {
   13011                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
   13012                                               pctxt->state);
   13013                         ret = 1;
   13014                     }
   13015                 }
   13016             }
   13017             break;
   13018         }
   13019         case XML_SCHEMA_TYPE_CHOICE:{
   13020             xmlSchemaTreeItemPtr sub;
   13021             xmlAutomataStatePtr start, end;
   13022 
   13023             ret = 0;
   13024             start = pctxt->state;
   13025             end = xmlAutomataNewState(pctxt->am);
   13026 
   13027             /*
   13028              * iterate over the subtypes and remerge the end with an
   13029              * epsilon transition
   13030              */
   13031             if (particle->maxOccurs == 1) {
   13032                 sub = particle->children->children;
   13033                 while (sub != NULL) {
   13034                     pctxt->state = start;
   13035                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   13036                                         (xmlSchemaParticlePtr) sub);
   13037                     if (tmp2 == 1) ret = 1;
   13038                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
   13039                     sub = sub->next;
   13040                 }
   13041             } else {
   13042                 int counter;
   13043                 xmlAutomataStatePtr hop, base;
   13044                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
   13045                     UNBOUNDED : particle->maxOccurs - 1;
   13046                 int minOccurs =
   13047                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
   13048 
   13049                 /*
   13050                  * use a counter to keep track of the number of transtions
   13051                  * which went through the choice.
   13052                  */
   13053                 counter =
   13054                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
   13055                 hop = xmlAutomataNewState(pctxt->am);
   13056                 base = xmlAutomataNewState(pctxt->am);
   13057 
   13058                 sub = particle->children->children;
   13059                 while (sub != NULL) {
   13060                     pctxt->state = base;
   13061                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
   13062                                         (xmlSchemaParticlePtr) sub);
   13063                     if (tmp2 == 1) ret = 1;
   13064                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
   13065                     sub = sub->next;
   13066                 }
   13067                 xmlAutomataNewEpsilon(pctxt->am, start, base);
   13068                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
   13069                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
   13070                 if (ret == 1)
   13071                     xmlAutomataNewEpsilon(pctxt->am, base, end);
   13072             }
   13073             if (particle->minOccurs == 0) {
   13074                 xmlAutomataNewEpsilon(pctxt->am, start, end);
   13075                 ret = 1;
   13076             }
   13077             pctxt->state = end;
   13078             break;
   13079         }
   13080         case XML_SCHEMA_TYPE_ALL:{
   13081             xmlAutomataStatePtr start, tmp;
   13082             xmlSchemaParticlePtr sub;
   13083             xmlSchemaElementPtr elemDecl;
   13084 
   13085             ret = 1;
   13086 
   13087             sub = (xmlSchemaParticlePtr) particle->children->children;
   13088             if (sub == NULL)
   13089                 break;
   13090 
   13091             ret = 0;
   13092 
   13093             start = pctxt->state;
   13094             tmp = xmlAutomataNewState(pctxt->am);
   13095             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
   13096             pctxt->state = tmp;
   13097             while (sub != NULL) {
   13098                 pctxt->state = tmp;
   13099 
   13100                 elemDecl = (xmlSchemaElementPtr) sub->children;
   13101                 if (elemDecl == NULL) {
   13102                     PERROR_INT("xmlSchemaBuildAContentModel",
   13103                         "<element> particle has no term");
   13104                     return(ret);
   13105                 };
   13106                 /*
   13107                 * NOTE: The {max occurs} of all the particles in the
   13108                 * {particles} of the group must be 0 or 1; this is
   13109                 * already ensured during the parse of the content of
   13110                 * <all>.
   13111                 */
   13112                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
   13113                     int counter;
   13114 
   13115                     /*
   13116                      * This is an abstract group, we need to share
   13117                      * the same counter for all the element transitions
   13118                      * derived from the group
   13119                      */
   13120                     counter = xmlAutomataNewCounter(pctxt->am,
   13121                                        sub->minOccurs, sub->maxOccurs);
   13122                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
   13123                                        sub, counter, pctxt->state);
   13124                 } else {
   13125                     if ((sub->minOccurs == 1) &&
   13126                         (sub->maxOccurs == 1)) {
   13127                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
   13128                                                 pctxt->state,
   13129                                                 elemDecl->name,
   13130                                                 elemDecl->targetNamespace,
   13131                                                 1, 1, elemDecl);
   13132                     } else if ((sub->minOccurs == 0) &&
   13133                         (sub->maxOccurs == 1)) {
   13134 
   13135                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
   13136                                                  pctxt->state,
   13137                                                  elemDecl->name,
   13138                                                  elemDecl->targetNamespace,
   13139                                                  0,
   13140                                                  1,
   13141                                                  elemDecl);
   13142                     }
   13143                 }
   13144                 sub = (xmlSchemaParticlePtr) sub->next;
   13145             }
   13146             pctxt->state =
   13147                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
   13148             if (particle->minOccurs == 0) {
   13149                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
   13150                 ret = 1;
   13151             }
   13152             break;
   13153         }
   13154 	case XML_SCHEMA_TYPE_GROUP:
   13155 	    /*
   13156 	    * If we hit a model group definition, then this means that
   13157 	    * it was empty, thus was not substituted for the containing
   13158 	    * model group. Just do nothing in this case.
   13159 	    * TODO: But the group should be substituted and not occur at
   13160 	    * all in the content model at this point. Fix this.
   13161 	    */
   13162             ret = 1;
   13163 	    break;
   13164         default:
   13165 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   13166 		"xmlSchemaBuildAContentModel",
   13167 		"found unexpected term of type '%s' in content model",
   13168 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
   13169             return(ret);
   13170     }
   13171     return(ret);
   13172 }
   13173 
   13174 /**
   13175  * xmlSchemaBuildContentModel:
   13176  * @ctxt:  the schema parser context
   13177  * @type:  the complex type definition
   13178  * @name:  the element name
   13179  *
   13180  * Builds the content model of the complex type.
   13181  */
   13182 static void
   13183 xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
   13184 			   xmlSchemaParserCtxtPtr ctxt)
   13185 {
   13186     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
   13187 	(type->contModel != NULL) ||
   13188 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
   13189 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
   13190 	return;
   13191 
   13192 #ifdef DEBUG_CONTENT
   13193     xmlGenericError(xmlGenericErrorContext,
   13194                     "Building content model for %s\n", name);
   13195 #endif
   13196     ctxt->am = NULL;
   13197     ctxt->am = xmlNewAutomata();
   13198     if (ctxt->am == NULL) {
   13199         xmlGenericError(xmlGenericErrorContext,
   13200 	    "Cannot create automata for complex type %s\n", type->name);
   13201         return;
   13202     }
   13203     ctxt->state = xmlAutomataGetInitState(ctxt->am);
   13204     /*
   13205     * Build the automaton.
   13206     */
   13207     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
   13208     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
   13209     type->contModel = xmlAutomataCompile(ctxt->am);
   13210     if (type->contModel == NULL) {
   13211         xmlSchemaPCustomErr(ctxt,
   13212 	    XML_SCHEMAP_INTERNAL,
   13213 	    WXS_BASIC_CAST type, type->node,
   13214 	    "Failed to compile the content model", NULL);
   13215     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
   13216         xmlSchemaPCustomErr(ctxt,
   13217 	    XML_SCHEMAP_NOT_DETERMINISTIC,
   13218 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
   13219 	    WXS_BASIC_CAST type, type->node,
   13220 	    "The content model is not determinist", NULL);
   13221     } else {
   13222 #ifdef DEBUG_CONTENT_REGEXP
   13223         xmlGenericError(xmlGenericErrorContext,
   13224                         "Content model of %s:\n", type->name);
   13225         xmlRegexpPrint(stderr, type->contModel);
   13226 #endif
   13227     }
   13228     ctxt->state = NULL;
   13229     xmlFreeAutomata(ctxt->am);
   13230     ctxt->am = NULL;
   13231 }
   13232 
   13233 /**
   13234  * xmlSchemaResolveElementReferences:
   13235  * @elem:  the schema element context
   13236  * @ctxt:  the schema parser context
   13237  *
   13238  * Resolves the references of an element declaration
   13239  * or particle, which has an element declaration as it's
   13240  * term.
   13241  */
   13242 static void
   13243 xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
   13244 				  xmlSchemaParserCtxtPtr ctxt)
   13245 {
   13246     if ((ctxt == NULL) || (elemDecl == NULL) ||
   13247 	((elemDecl != NULL) &&
   13248 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
   13249         return;
   13250     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
   13251 
   13252     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
   13253 	xmlSchemaTypePtr type;
   13254 
   13255 	/* (type definition) ... otherwise the type definition `resolved`
   13256 	* to by the `actual value` of the type [attribute] ...
   13257 	*/
   13258 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
   13259 	    elemDecl->namedTypeNs);
   13260 	if (type == NULL) {
   13261 	    xmlSchemaPResCompAttrErr(ctxt,
   13262 		XML_SCHEMAP_SRC_RESOLVE,
   13263 		WXS_BASIC_CAST elemDecl, elemDecl->node,
   13264 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
   13265 		XML_SCHEMA_TYPE_BASIC, "type definition");
   13266 	} else
   13267 	    elemDecl->subtypes = type;
   13268     }
   13269     if (elemDecl->substGroup != NULL) {
   13270 	xmlSchemaElementPtr substHead;
   13271 
   13272 	/*
   13273 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
   13274 	* substitutionGroup?
   13275 	*/
   13276 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
   13277 	    elemDecl->substGroupNs);
   13278 	if (substHead == NULL) {
   13279 	    xmlSchemaPResCompAttrErr(ctxt,
   13280 		XML_SCHEMAP_SRC_RESOLVE,
   13281 		WXS_BASIC_CAST elemDecl, NULL,
   13282 		"substitutionGroup", elemDecl->substGroup,
   13283 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
   13284 	} else {
   13285 	    xmlSchemaResolveElementReferences(substHead, ctxt);
   13286 	    /*
   13287 	    * Set the "substitution group affiliation".
   13288 	    * NOTE that now we use the "refDecl" field for this.
   13289 	    */
   13290 	    WXS_SUBST_HEAD(elemDecl) = substHead;
   13291 	    /*
   13292 	    * The type definitions is set to:
   13293 	    * SPEC "...the {type definition} of the element
   13294 	    * declaration `resolved` to by the `actual value`
   13295 	    * of the substitutionGroup [attribute], if present"
   13296 	    */
   13297 	    if (elemDecl->subtypes == NULL)
   13298 		elemDecl->subtypes = substHead->subtypes;
   13299 	}
   13300     }
   13301     /*
   13302     * SPEC "The definition of anyType serves as the default type definition
   13303     * for element declarations whose XML representation does not specify one."
   13304     */
   13305     if ((elemDecl->subtypes == NULL) &&
   13306 	(elemDecl->namedType == NULL) &&
   13307 	(elemDecl->substGroup == NULL))
   13308 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   13309 }
   13310 
   13311 /**
   13312  * xmlSchemaResolveUnionMemberTypes:
   13313  * @ctxt:  the schema parser context
   13314  * @type:  the schema simple type definition
   13315  *
   13316  * Checks and builds the "member type definitions" property of the union
   13317  * simple type. This handles part (1), part (2) is done in
   13318  * xmlSchemaFinishMemberTypeDefinitionsProperty()
   13319  *
   13320  * Returns -1 in case of an internal error, 0 otherwise.
   13321  */
   13322 static int
   13323 xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
   13324 				 xmlSchemaTypePtr type)
   13325 {
   13326 
   13327     xmlSchemaTypeLinkPtr link, lastLink, newLink;
   13328     xmlSchemaTypePtr memberType;
   13329 
   13330     /*
   13331     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
   13332     * define the explicit members as the type definitions `resolved`
   13333     * to by the items in the `actual value` of the memberTypes [attribute],
   13334     * if any, followed by the type definitions corresponding to the
   13335     * <simpleType>s among the [children] of <union>, if any."
   13336     */
   13337     /*
   13338     * Resolve references.
   13339     */
   13340     link = type->memberTypes;
   13341     lastLink = NULL;
   13342     while (link != NULL) {
   13343 	const xmlChar *name, *nsName;
   13344 
   13345 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
   13346 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
   13347 
   13348 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
   13349 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
   13350 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   13351 		WXS_BASIC_CAST type, type->node, "memberTypes",
   13352 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
   13353 	    /*
   13354 	    * Remove the member type link.
   13355 	    */
   13356 	    if (lastLink == NULL)
   13357 		type->memberTypes = link->next;
   13358 	    else
   13359 		lastLink->next = link->next;
   13360 	    newLink = link;
   13361 	    link = link->next;
   13362 	    xmlFree(newLink);
   13363 	} else {
   13364 	    link->type = memberType;
   13365 	    lastLink = link;
   13366 	    link = link->next;
   13367 	}
   13368     }
   13369     /*
   13370     * Add local simple types,
   13371     */
   13372     memberType = type->subtypes;
   13373     while (memberType != NULL) {
   13374 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
   13375 	if (link == NULL) {
   13376 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
   13377 	    return (-1);
   13378 	}
   13379 	link->type = memberType;
   13380 	link->next = NULL;
   13381 	if (lastLink == NULL)
   13382 	    type->memberTypes = link;
   13383 	else
   13384 	    lastLink->next = link;
   13385 	lastLink = link;
   13386 	memberType = memberType->next;
   13387     }
   13388     return (0);
   13389 }
   13390 
   13391 /**
   13392  * xmlSchemaIsDerivedFromBuiltInType:
   13393  * @ctxt:  the schema parser context
   13394  * @type:  the type definition
   13395  * @valType: the value type
   13396  *
   13397  *
   13398  * Returns 1 if the type has the given value type, or
   13399  * is derived from such a type.
   13400  */
   13401 static int
   13402 xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13403 {
   13404     if (type == NULL)
   13405 	return (0);
   13406     if (WXS_IS_COMPLEX(type))
   13407 	return (0);
   13408     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13409 	if (type->builtInType == valType)
   13410 	    return(1);
   13411 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13412 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
   13413 	    return (0);
   13414 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13415     }
   13416     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13417 }
   13418 
   13419 #if 0
   13420 /**
   13421  * xmlSchemaIsDerivedFromBuiltInType:
   13422  * @ctxt:  the schema parser context
   13423  * @type:  the type definition
   13424  * @valType: the value type
   13425  *
   13426  *
   13427  * Returns 1 if the type has the given value type, or
   13428  * is derived from such a type.
   13429  */
   13430 static int
   13431 xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
   13432 {
   13433     if (type == NULL)
   13434 	return (0);
   13435     if (WXS_IS_COMPLEX(type))
   13436 	return (0);
   13437     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   13438 	if (type->builtInType == valType)
   13439 	    return(1);
   13440 	return (0);
   13441     } else
   13442 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
   13443 
   13444     return (0);
   13445 }
   13446 
   13447 static xmlSchemaTypePtr
   13448 xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
   13449 {
   13450     if (type == NULL)
   13451 	return (NULL);
   13452     if (WXS_IS_COMPLEX(type))
   13453 	return (NULL);
   13454     if (type->type == XML_SCHEMA_TYPE_BASIC)
   13455 	return(type);
   13456     return(xmlSchemaQueryBuiltInType(type->subtypes));
   13457 }
   13458 #endif
   13459 
   13460 /**
   13461  * xmlSchemaGetPrimitiveType:
   13462  * @type:  the simpleType definition
   13463  *
   13464  * Returns the primitive type of the given type or
   13465  * NULL in case of error.
   13466  */
   13467 static xmlSchemaTypePtr
   13468 xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
   13469 {
   13470 
   13471     while (type != NULL) {
   13472 	/*
   13473 	* Note that anySimpleType is actually not a primitive type
   13474 	* but we need that here.
   13475 	*/
   13476 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
   13477 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
   13478 	    return (type);
   13479 	type = type->baseType;
   13480     }
   13481 
   13482     return (NULL);
   13483 }
   13484 
   13485 #if 0
   13486 /**
   13487  * xmlSchemaGetBuiltInTypeAncestor:
   13488  * @type:  the simpleType definition
   13489  *
   13490  * Returns the primitive type of the given type or
   13491  * NULL in case of error.
   13492  */
   13493 static xmlSchemaTypePtr
   13494 xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
   13495 {
   13496     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
   13497 	return (0);
   13498     while (type != NULL) {
   13499 	if (type->type == XML_SCHEMA_TYPE_BASIC)
   13500 	    return (type);
   13501 	type = type->baseType;
   13502     }
   13503 
   13504     return (NULL);
   13505 }
   13506 #endif
   13507 
   13508 /**
   13509  * xmlSchemaCloneWildcardNsConstraints:
   13510  * @ctxt:  the schema parser context
   13511  * @dest:  the destination wildcard
   13512  * @source: the source wildcard
   13513  *
   13514  * Clones the namespace constraints of source
   13515  * and assignes them to dest.
   13516  * Returns -1 on internal error, 0 otherwise.
   13517  */
   13518 static int
   13519 xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
   13520 				    xmlSchemaWildcardPtr dest,
   13521 				    xmlSchemaWildcardPtr source)
   13522 {
   13523     xmlSchemaWildcardNsPtr cur, tmp, last;
   13524 
   13525     if ((source == NULL) || (dest == NULL))
   13526 	return(-1);
   13527     dest->any = source->any;
   13528     cur = source->nsSet;
   13529     last = NULL;
   13530     while (cur != NULL) {
   13531 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13532 	if (tmp == NULL)
   13533 	    return(-1);
   13534 	tmp->value = cur->value;
   13535 	if (last == NULL)
   13536 	    dest->nsSet = tmp;
   13537 	else
   13538 	    last->next = tmp;
   13539 	last = tmp;
   13540 	cur = cur->next;
   13541     }
   13542     if (dest->negNsSet != NULL)
   13543 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
   13544     if (source->negNsSet != NULL) {
   13545 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13546 	if (dest->negNsSet == NULL)
   13547 	    return(-1);
   13548 	dest->negNsSet->value = source->negNsSet->value;
   13549     } else
   13550 	dest->negNsSet = NULL;
   13551     return(0);
   13552 }
   13553 
   13554 /**
   13555  * xmlSchemaUnionWildcards:
   13556  * @ctxt:  the schema parser context
   13557  * @completeWild:  the first wildcard
   13558  * @curWild: the second wildcard
   13559  *
   13560  * Unions the namespace constraints of the given wildcards.
   13561  * @completeWild will hold the resulting union.
   13562  * Returns a positive error code on failure, -1 in case of an
   13563  * internal error, 0 otherwise.
   13564  */
   13565 static int
   13566 xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
   13567 			    xmlSchemaWildcardPtr completeWild,
   13568 			    xmlSchemaWildcardPtr curWild)
   13569 {
   13570     xmlSchemaWildcardNsPtr cur, curB, tmp;
   13571 
   13572     /*
   13573     * 1 If O1 and O2 are the same value, then that value must be the
   13574     * value.
   13575     */
   13576     if ((completeWild->any == curWild->any) &&
   13577 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13578 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13579 
   13580 	if ((completeWild->negNsSet == NULL) ||
   13581 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13582 
   13583 	    if (completeWild->nsSet != NULL) {
   13584 		int found = 0;
   13585 
   13586 		/*
   13587 		* Check equality of sets.
   13588 		*/
   13589 		cur = completeWild->nsSet;
   13590 		while (cur != NULL) {
   13591 		    found = 0;
   13592 		    curB = curWild->nsSet;
   13593 		    while (curB != NULL) {
   13594 			if (cur->value == curB->value) {
   13595 			    found = 1;
   13596 			    break;
   13597 			}
   13598 			curB = curB->next;
   13599 		    }
   13600 		    if (!found)
   13601 			break;
   13602 		    cur = cur->next;
   13603 		}
   13604 		if (found)
   13605 		    return(0);
   13606 	    } else
   13607 		return(0);
   13608 	}
   13609     }
   13610     /*
   13611     * 2 If either O1 or O2 is any, then any must be the value
   13612     */
   13613     if (completeWild->any != curWild->any) {
   13614 	if (completeWild->any == 0) {
   13615 	    completeWild->any = 1;
   13616 	    if (completeWild->nsSet != NULL) {
   13617 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13618 		completeWild->nsSet = NULL;
   13619 	    }
   13620 	    if (completeWild->negNsSet != NULL) {
   13621 		xmlFree(completeWild->negNsSet);
   13622 		completeWild->negNsSet = NULL;
   13623 	    }
   13624 	}
   13625 	return (0);
   13626     }
   13627     /*
   13628     * 3 If both O1 and O2 are sets of (namespace names or `absent`),
   13629     * then the union of those sets must be the value.
   13630     */
   13631     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13632 	int found;
   13633 	xmlSchemaWildcardNsPtr start;
   13634 
   13635 	cur = curWild->nsSet;
   13636 	start = completeWild->nsSet;
   13637 	while (cur != NULL) {
   13638 	    found = 0;
   13639 	    curB = start;
   13640 	    while (curB != NULL) {
   13641 		if (cur->value == curB->value) {
   13642 		    found = 1;
   13643 		    break;
   13644 		}
   13645 		curB = curB->next;
   13646 	    }
   13647 	    if (!found) {
   13648 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
   13649 		if (tmp == NULL)
   13650 		    return (-1);
   13651 		tmp->value = cur->value;
   13652 		tmp->next = completeWild->nsSet;
   13653 		completeWild->nsSet = tmp;
   13654 	    }
   13655 	    cur = cur->next;
   13656 	}
   13657 
   13658 	return(0);
   13659     }
   13660     /*
   13661     * 4 If the two are negations of different values (namespace names
   13662     * or `absent`), then a pair of not and `absent` must be the value.
   13663     */
   13664     if ((completeWild->negNsSet != NULL) &&
   13665 	(curWild->negNsSet != NULL) &&
   13666 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
   13667 	completeWild->negNsSet->value = NULL;
   13668 
   13669 	return(0);
   13670     }
   13671     /*
   13672      * 5.
   13673      */
   13674     if (((completeWild->negNsSet != NULL) &&
   13675 	(completeWild->negNsSet->value != NULL) &&
   13676 	(curWild->nsSet != NULL)) ||
   13677 	((curWild->negNsSet != NULL) &&
   13678 	(curWild->negNsSet->value != NULL) &&
   13679 	(completeWild->nsSet != NULL))) {
   13680 
   13681 	int nsFound, absentFound = 0;
   13682 
   13683 	if (completeWild->nsSet != NULL) {
   13684 	    cur = completeWild->nsSet;
   13685 	    curB = curWild->negNsSet;
   13686 	} else {
   13687 	    cur = curWild->nsSet;
   13688 	    curB = completeWild->negNsSet;
   13689 	}
   13690 	nsFound = 0;
   13691 	while (cur != NULL) {
   13692 	    if (cur->value == NULL)
   13693 		absentFound = 1;
   13694 	    else if (cur->value == curB->value)
   13695 		nsFound = 1;
   13696 	    if (nsFound && absentFound)
   13697 		break;
   13698 	    cur = cur->next;
   13699 	}
   13700 
   13701 	if (nsFound && absentFound) {
   13702 	    /*
   13703 	    * 5.1 If the set S includes both the negated namespace
   13704 	    * name and `absent`, then any must be the value.
   13705 	    */
   13706 	    completeWild->any = 1;
   13707 	    if (completeWild->nsSet != NULL) {
   13708 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13709 		completeWild->nsSet = NULL;
   13710 	    }
   13711 	    if (completeWild->negNsSet != NULL) {
   13712 		xmlFree(completeWild->negNsSet);
   13713 		completeWild->negNsSet = NULL;
   13714 	    }
   13715 	} else if (nsFound && (!absentFound)) {
   13716 	    /*
   13717 	    * 5.2 If the set S includes the negated namespace name
   13718 	    * but not `absent`, then a pair of not and `absent` must
   13719 	    * be the value.
   13720 	    */
   13721 	    if (completeWild->nsSet != NULL) {
   13722 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13723 		completeWild->nsSet = NULL;
   13724 	    }
   13725 	    if (completeWild->negNsSet == NULL) {
   13726 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13727 		if (completeWild->negNsSet == NULL)
   13728 		    return (-1);
   13729 	    }
   13730 	    completeWild->negNsSet->value = NULL;
   13731 	} else if ((!nsFound) && absentFound) {
   13732 	    /*
   13733 	    * 5.3 If the set S includes `absent` but not the negated
   13734 	    * namespace name, then the union is not expressible.
   13735 	    */
   13736 	    xmlSchemaPErr(ctxt, completeWild->node,
   13737 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
   13738 		"The union of the wilcard is not expressible.\n",
   13739 		NULL, NULL);
   13740 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
   13741 	} else if ((!nsFound) && (!absentFound)) {
   13742 	    /*
   13743 	    * 5.4 If the set S does not include either the negated namespace
   13744 	    * name or `absent`, then whichever of O1 or O2 is a pair of not
   13745 	    * and a namespace name must be the value.
   13746 	    */
   13747 	    if (completeWild->negNsSet == NULL) {
   13748 		if (completeWild->nsSet != NULL) {
   13749 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13750 		    completeWild->nsSet = NULL;
   13751 		}
   13752 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13753 		if (completeWild->negNsSet == NULL)
   13754 		    return (-1);
   13755 		completeWild->negNsSet->value = curWild->negNsSet->value;
   13756 	    }
   13757 	}
   13758 	return (0);
   13759     }
   13760     /*
   13761      * 6.
   13762      */
   13763     if (((completeWild->negNsSet != NULL) &&
   13764 	(completeWild->negNsSet->value == NULL) &&
   13765 	(curWild->nsSet != NULL)) ||
   13766 	((curWild->negNsSet != NULL) &&
   13767 	(curWild->negNsSet->value == NULL) &&
   13768 	(completeWild->nsSet != NULL))) {
   13769 
   13770 	if (completeWild->nsSet != NULL) {
   13771 	    cur = completeWild->nsSet;
   13772 	} else {
   13773 	    cur = curWild->nsSet;
   13774 	}
   13775 	while (cur != NULL) {
   13776 	    if (cur->value == NULL) {
   13777 		/*
   13778 		* 6.1 If the set S includes `absent`, then any must be the
   13779 		* value.
   13780 		*/
   13781 		completeWild->any = 1;
   13782 		if (completeWild->nsSet != NULL) {
   13783 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13784 		    completeWild->nsSet = NULL;
   13785 		}
   13786 		if (completeWild->negNsSet != NULL) {
   13787 		    xmlFree(completeWild->negNsSet);
   13788 		    completeWild->negNsSet = NULL;
   13789 		}
   13790 		return (0);
   13791 	    }
   13792 	    cur = cur->next;
   13793 	}
   13794 	if (completeWild->negNsSet == NULL) {
   13795 	    /*
   13796 	    * 6.2 If the set S does not include `absent`, then a pair of not
   13797 	    * and `absent` must be the value.
   13798 	    */
   13799 	    if (completeWild->nsSet != NULL) {
   13800 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
   13801 		completeWild->nsSet = NULL;
   13802 	    }
   13803 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
   13804 	    if (completeWild->negNsSet == NULL)
   13805 		return (-1);
   13806 	    completeWild->negNsSet->value = NULL;
   13807 	}
   13808 	return (0);
   13809     }
   13810     return (0);
   13811 
   13812 }
   13813 
   13814 /**
   13815  * xmlSchemaIntersectWildcards:
   13816  * @ctxt:  the schema parser context
   13817  * @completeWild:  the first wildcard
   13818  * @curWild: the second wildcard
   13819  *
   13820  * Intersects the namespace constraints of the given wildcards.
   13821  * @completeWild will hold the resulting intersection.
   13822  * Returns a positive error code on failure, -1 in case of an
   13823  * internal error, 0 otherwise.
   13824  */
   13825 static int
   13826 xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
   13827 			    xmlSchemaWildcardPtr completeWild,
   13828 			    xmlSchemaWildcardPtr curWild)
   13829 {
   13830     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
   13831 
   13832     /*
   13833     * 1 If O1 and O2 are the same value, then that value must be the
   13834     * value.
   13835     */
   13836     if ((completeWild->any == curWild->any) &&
   13837 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
   13838 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
   13839 
   13840 	if ((completeWild->negNsSet == NULL) ||
   13841 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
   13842 
   13843 	    if (completeWild->nsSet != NULL) {
   13844 		int found = 0;
   13845 
   13846 		/*
   13847 		* Check equality of sets.
   13848 		*/
   13849 		cur = completeWild->nsSet;
   13850 		while (cur != NULL) {
   13851 		    found = 0;
   13852 		    curB = curWild->nsSet;
   13853 		    while (curB != NULL) {
   13854 			if (cur->value == curB->value) {
   13855 			    found = 1;
   13856 			    break;
   13857 			}
   13858 			curB = curB->next;
   13859 		    }
   13860 		    if (!found)
   13861 			break;
   13862 		    cur = cur->next;
   13863 		}
   13864 		if (found)
   13865 		    return(0);
   13866 	    } else
   13867 		return(0);
   13868 	}
   13869     }
   13870     /*
   13871     * 2 If either O1 or O2 is any, then the other must be the value.
   13872     */
   13873     if ((completeWild->any != curWild->any) && (completeWild->any)) {
   13874 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13875 	    return(-1);
   13876 	return(0);
   13877     }
   13878     /*
   13879     * 3 If either O1 or O2 is a pair of not and a value (a namespace
   13880     * name or `absent`) and the other is a set of (namespace names or
   13881     * `absent`), then that set, minus the negated value if it was in
   13882     * the set, minus `absent` if it was in the set, must be the value.
   13883     */
   13884     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
   13885 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
   13886 	const xmlChar *neg;
   13887 
   13888 	if (completeWild->nsSet == NULL) {
   13889 	    neg = completeWild->negNsSet->value;
   13890 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
   13891 		return(-1);
   13892 	} else
   13893 	    neg = curWild->negNsSet->value;
   13894 	/*
   13895 	* Remove absent and negated.
   13896 	*/
   13897 	prev = NULL;
   13898 	cur = completeWild->nsSet;
   13899 	while (cur != NULL) {
   13900 	    if (cur->value == NULL) {
   13901 		if (prev == NULL)
   13902 		    completeWild->nsSet = cur->next;
   13903 		else
   13904 		    prev->next = cur->next;
   13905 		xmlFree(cur);
   13906 		break;
   13907 	    }
   13908 	    prev = cur;
   13909 	    cur = cur->next;
   13910 	}
   13911 	if (neg != NULL) {
   13912 	    prev = NULL;
   13913 	    cur = completeWild->nsSet;
   13914 	    while (cur != NULL) {
   13915 		if (cur->value == neg) {
   13916 		    if (prev == NULL)
   13917 			completeWild->nsSet = cur->next;
   13918 		    else
   13919 			prev->next = cur->next;
   13920 		    xmlFree(cur);
   13921 		    break;
   13922 		}
   13923 		prev = cur;
   13924 		cur = cur->next;
   13925 	    }
   13926 	}
   13927 
   13928 	return(0);
   13929     }
   13930     /*
   13931     * 4 If both O1 and O2 are sets of (namespace names or `absent`),
   13932     * then the intersection of those sets must be the value.
   13933     */
   13934     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
   13935 	int found;
   13936 
   13937 	cur = completeWild->nsSet;
   13938 	prev = NULL;
   13939 	while (cur != NULL) {
   13940 	    found = 0;
   13941 	    curB = curWild->nsSet;
   13942 	    while (curB != NULL) {
   13943 		if (cur->value == curB->value) {
   13944 		    found = 1;
   13945 		    break;
   13946 		}
   13947 		curB = curB->next;
   13948 	    }
   13949 	    if (!found) {
   13950 		if (prev == NULL)
   13951 		    completeWild->nsSet = cur->next;
   13952 		else
   13953 		    prev->next = cur->next;
   13954 		tmp = cur->next;
   13955 		xmlFree(cur);
   13956 		cur = tmp;
   13957 		continue;
   13958 	    }
   13959 	    prev = cur;
   13960 	    cur = cur->next;
   13961 	}
   13962 
   13963 	return(0);
   13964     }
   13965     /* 5 If the two are negations of different namespace names,
   13966     * then the intersection is not expressible
   13967     */
   13968     if ((completeWild->negNsSet != NULL) &&
   13969 	(curWild->negNsSet != NULL) &&
   13970 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13971 	(completeWild->negNsSet->value != NULL) &&
   13972 	(curWild->negNsSet->value != NULL)) {
   13973 
   13974 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
   13975 	    "The intersection of the wilcard is not expressible.\n",
   13976 	    NULL, NULL);
   13977 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
   13978     }
   13979     /*
   13980     * 6 If the one is a negation of a namespace name and the other
   13981     * is a negation of `absent`, then the one which is the negation
   13982     * of a namespace name must be the value.
   13983     */
   13984     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
   13985 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
   13986 	(completeWild->negNsSet->value == NULL)) {
   13987 	completeWild->negNsSet->value =  curWild->negNsSet->value;
   13988     }
   13989     return(0);
   13990 }
   13991 
   13992 /**
   13993  * xmlSchemaIsWildcardNsConstraintSubset:
   13994  * @ctxt:  the schema parser context
   13995  * @sub:  the first wildcard
   13996  * @super: the second wildcard
   13997  *
   13998  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
   13999  *
   14000  * Returns 0 if the namespace constraint of @sub is an intensional
   14001  * subset of @super, 1 otherwise.
   14002  */
   14003 static int
   14004 xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
   14005 			  xmlSchemaWildcardPtr super)
   14006 {
   14007     /*
   14008     * 1 super must be any.
   14009     */
   14010     if (super->any)
   14011 	return (0);
   14012     /*
   14013     * 2.1 sub must be a pair of not and a namespace name or `absent`.
   14014     * 2.2 super must be a pair of not and the same value.
   14015     */
   14016     if ((sub->negNsSet != NULL) &&
   14017 	(super->negNsSet != NULL) &&
   14018 	(sub->negNsSet->value == super->negNsSet->value))
   14019 	return (0);
   14020     /*
   14021     * 3.1 sub must be a set whose members are either namespace names or `absent`.
   14022     */
   14023     if (sub->nsSet != NULL) {
   14024 	/*
   14025 	* 3.2.1 super must be the same set or a superset thereof.
   14026 	*/
   14027 	if (super->nsSet != NULL) {
   14028 	    xmlSchemaWildcardNsPtr cur, curB;
   14029 	    int found = 0;
   14030 
   14031 	    cur = sub->nsSet;
   14032 	    while (cur != NULL) {
   14033 		found = 0;
   14034 		curB = super->nsSet;
   14035 		while (curB != NULL) {
   14036 		    if (cur->value == curB->value) {
   14037 			found = 1;
   14038 			break;
   14039 		    }
   14040 		    curB = curB->next;
   14041 		}
   14042 		if (!found)
   14043 		    return (1);
   14044 		cur = cur->next;
   14045 	    }
   14046 	    if (found)
   14047 		return (0);
   14048 	} else if (super->negNsSet != NULL) {
   14049 	    xmlSchemaWildcardNsPtr cur;
   14050 	    /*
   14051 	    * 3.2.2 super must be a pair of not and a namespace name or
   14052 	    * `absent` and that value must not be in sub's set.
   14053 	    */
   14054 	    cur = sub->nsSet;
   14055 	    while (cur != NULL) {
   14056 		if (cur->value == super->negNsSet->value)
   14057 		    return (1);
   14058 		cur = cur->next;
   14059 	    }
   14060 	    return (0);
   14061 	}
   14062     }
   14063     return (1);
   14064 }
   14065 
   14066 static int
   14067 xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
   14068 				     int *fixed,
   14069 				     const xmlChar **value,
   14070 				     xmlSchemaValPtr *val)
   14071 {
   14072     *fixed = 0;
   14073     *value = NULL;
   14074     if (val != 0)
   14075 	*val = NULL;
   14076 
   14077     if (attruse->defValue != NULL) {
   14078 	*value = attruse->defValue;
   14079 	if (val != NULL)
   14080 	    *val = attruse->defVal;
   14081 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
   14082 	    *fixed = 1;
   14083 	return(1);
   14084     } else if ((attruse->attrDecl != NULL) &&
   14085 	(attruse->attrDecl->defValue != NULL)) {
   14086 	*value = attruse->attrDecl->defValue;
   14087 	if (val != NULL)
   14088 	    *val = attruse->attrDecl->defVal;
   14089 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
   14090 	    *fixed = 1;
   14091 	return(1);
   14092     }
   14093     return(0);
   14094 }
   14095 /**
   14096  * xmlSchemaCheckCVCWildcardNamespace:
   14097  * @wild:  the wildcard
   14098  * @ns:  the namespace
   14099  *
   14100  * Validation Rule: Wildcard allows Namespace Name
   14101  * (cvc-wildcard-namespace)
   14102  *
   14103  * Returns 0 if the given namespace matches the wildcard,
   14104  * 1 otherwise and -1 on API errors.
   14105  */
   14106 static int
   14107 xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
   14108 				   const xmlChar* ns)
   14109 {
   14110     if (wild == NULL)
   14111 	return(-1);
   14112 
   14113     if (wild->any)
   14114 	return(0);
   14115     else if (wild->nsSet != NULL) {
   14116 	xmlSchemaWildcardNsPtr cur;
   14117 
   14118 	cur = wild->nsSet;
   14119 	while (cur != NULL) {
   14120 	    if (xmlStrEqual(cur->value, ns))
   14121 		return(0);
   14122 	    cur = cur->next;
   14123 	}
   14124     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
   14125 	(!xmlStrEqual(wild->negNsSet->value, ns)))
   14126 	return(0);
   14127 
   14128     return(1);
   14129 }
   14130 
   14131 #define XML_SCHEMA_ACTION_DERIVE 0
   14132 #define XML_SCHEMA_ACTION_REDEFINE 1
   14133 
   14134 #define WXS_ACTION_STR(a) \
   14135 ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
   14136 
   14137 /*
   14138 * Schema Component Constraint:
   14139 *   Derivation Valid (Restriction, Complex)
   14140 *   derivation-ok-restriction (2) - (4)
   14141 *
   14142 * ATTENTION:
   14143 * In XML Schema 1.1 this will be:
   14144 * Validation Rule:
   14145 *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
   14146 *
   14147 */
   14148 static int
   14149 xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
   14150 				       int action,
   14151 				       xmlSchemaBasicItemPtr item,
   14152 				       xmlSchemaBasicItemPtr baseItem,
   14153 				       xmlSchemaItemListPtr uses,
   14154 				       xmlSchemaItemListPtr baseUses,
   14155 				       xmlSchemaWildcardPtr wild,
   14156 				       xmlSchemaWildcardPtr baseWild)
   14157 {
   14158     xmlSchemaAttributeUsePtr cur = NULL, bcur;
   14159     int i, j, found; /* err = 0; */
   14160     const xmlChar *bEffValue;
   14161     int effFixed;
   14162 
   14163     if (uses != NULL) {
   14164 	for (i = 0; i < uses->nbItems; i++) {
   14165 	    cur = uses->items[i];
   14166 	    found = 0;
   14167 	    if (baseUses == NULL)
   14168 		goto not_found;
   14169 	    for (j = 0; j < baseUses->nbItems; j++) {
   14170 		bcur = baseUses->items[j];
   14171 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14172 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14173 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
   14174 			WXS_ATTRUSE_DECL_TNS(bcur)))
   14175 		{
   14176 		    /*
   14177 		    * (2.1) "If there is an attribute use in the {attribute
   14178 		    * uses} of the {base type definition} (call this B) whose
   14179 		    * {attribute declaration} has the same {name} and {target
   14180 		    * namespace}, then  all of the following must be true:"
   14181 		    */
   14182 		    found = 1;
   14183 
   14184 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   14185 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
   14186 		    {
   14187 			xmlChar *str = NULL;
   14188 			/*
   14189 			* (2.1.1) "one of the following must be true:"
   14190 			* (2.1.1.1) "B's {required} is false."
   14191 			* (2.1.1.2) "R's {required} is true."
   14192 			*/
   14193 			xmlSchemaPAttrUseErr4(pctxt,
   14194 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
   14195 			    WXS_ITEM_NODE(item), item, cur,
   14196 			    "The 'optional' attribute use is inconsistent "
   14197 			    "with the corresponding 'required' attribute use of "
   14198 			    "the %s %s",
   14199 			    WXS_ACTION_STR(action),
   14200 			    xmlSchemaGetComponentDesignation(&str, baseItem),
   14201 			    NULL, NULL);
   14202 			FREE_AND_NULL(str);
   14203 			/* err = pctxt->err; */
   14204 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   14205 			WXS_ATTRUSE_TYPEDEF(cur),
   14206 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
   14207 		    {
   14208 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   14209 
   14210 			/*
   14211 			* SPEC (2.1.2) "R's {attribute declaration}'s
   14212 			* {type definition} must be validly derived from
   14213 			* B's {type definition} given the empty set as
   14214 			* defined in Type Derivation OK (Simple) ($3.14.6)."
   14215 			*/
   14216 			xmlSchemaPAttrUseErr4(pctxt,
   14217 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
   14218 			    WXS_ITEM_NODE(item), item, cur,
   14219 			    "The attribute declaration's %s "
   14220 			    "is not validly derived from "
   14221 			    "the corresponding %s of the "
   14222 			    "attribute declaration in the %s %s",
   14223 			    xmlSchemaGetComponentDesignation(&strA,
   14224 				WXS_ATTRUSE_TYPEDEF(cur)),
   14225 			    xmlSchemaGetComponentDesignation(&strB,
   14226 				WXS_ATTRUSE_TYPEDEF(bcur)),
   14227 			    WXS_ACTION_STR(action),
   14228 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
   14229 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
   14230 			FREE_AND_NULL(strA);
   14231 			FREE_AND_NULL(strB);
   14232 			FREE_AND_NULL(strC);
   14233 			/* err = pctxt->err; */
   14234 		    } else {
   14235 			/*
   14236 			* 2.1.3 [Definition:]  Let the effective value
   14237 			* constraint of an attribute use be its {value
   14238 			* constraint}, if present, otherwise its {attribute
   14239 			* declaration}'s {value constraint} .
   14240 			*/
   14241 			xmlSchemaGetEffectiveValueConstraint(bcur,
   14242 			    &effFixed, &bEffValue, NULL);
   14243 			/*
   14244 			* 2.1.3 ... one of the following must be true
   14245 			*
   14246 			* 2.1.3.1 B's `effective value constraint` is
   14247 			* `absent` or default.
   14248 			*/
   14249 			if ((bEffValue != NULL) &&
   14250 			    (effFixed == 1)) {
   14251 			    const xmlChar *rEffValue = NULL;
   14252 
   14253 			    xmlSchemaGetEffectiveValueConstraint(bcur,
   14254 				&effFixed, &rEffValue, NULL);
   14255 			    /*
   14256 			    * 2.1.3.2 R's `effective value constraint` is
   14257 			    * fixed with the same string as B's.
   14258 			    * MAYBE TODO: Compare the computed values.
   14259 			    *       Hmm, it says "same string" so
   14260 			    *       string-equality might really be sufficient.
   14261 			    */
   14262 			    if ((effFixed == 0) ||
   14263 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
   14264 			    {
   14265 				xmlChar *str = NULL;
   14266 
   14267 				xmlSchemaPAttrUseErr4(pctxt,
   14268 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
   14269 				    WXS_ITEM_NODE(item), item, cur,
   14270 				    "The effective value constraint of the "
   14271 				    "attribute use is inconsistent with "
   14272 				    "its correspondent in the %s %s",
   14273 				    WXS_ACTION_STR(action),
   14274 				    xmlSchemaGetComponentDesignation(&str,
   14275 					baseItem),
   14276 				    NULL, NULL);
   14277 				FREE_AND_NULL(str);
   14278 				/* err = pctxt->err; */
   14279 			    }
   14280 			}
   14281 		    }
   14282 		    break;
   14283 		}
   14284 	    }
   14285 not_found:
   14286 	    if (!found) {
   14287 		/*
   14288 		* (2.2) "otherwise the {base type definition} must have an
   14289 		* {attribute wildcard} and the {target namespace} of the
   14290 		* R's {attribute declaration} must be `valid` with respect
   14291 		* to that wildcard, as defined in Wildcard allows Namespace
   14292 		* Name ($3.10.4)."
   14293 		*/
   14294 		if ((baseWild == NULL) ||
   14295 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
   14296 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
   14297 		{
   14298 		    xmlChar *str = NULL;
   14299 
   14300 		    xmlSchemaPAttrUseErr4(pctxt,
   14301 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
   14302 			WXS_ITEM_NODE(item), item, cur,
   14303 			"Neither a matching attribute use, "
   14304 			"nor a matching wildcard exists in the %s %s",
   14305 			WXS_ACTION_STR(action),
   14306 			xmlSchemaGetComponentDesignation(&str, baseItem),
   14307 			NULL, NULL);
   14308 		    FREE_AND_NULL(str);
   14309 		    /* err = pctxt->err; */
   14310 		}
   14311 	    }
   14312 	}
   14313     }
   14314     /*
   14315     * SPEC derivation-ok-restriction (3):
   14316     * (3) "For each attribute use in the {attribute uses} of the {base type
   14317     * definition} whose {required} is true, there must be an attribute
   14318     * use with an {attribute declaration} with the same {name} and
   14319     * {target namespace} as its {attribute declaration} in the {attribute
   14320     * uses} of the complex type definition itself whose {required} is true.
   14321     */
   14322     if (baseUses != NULL) {
   14323 	for (j = 0; j < baseUses->nbItems; j++) {
   14324 	    bcur = baseUses->items[j];
   14325 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
   14326 		continue;
   14327 	    found = 0;
   14328 	    if (uses != NULL) {
   14329 		for (i = 0; i < uses->nbItems; i++) {
   14330 		    cur = uses->items[i];
   14331 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
   14332 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
   14333 			(WXS_ATTRUSE_DECL_TNS(cur) ==
   14334 			WXS_ATTRUSE_DECL_TNS(bcur))) {
   14335 			found = 1;
   14336 			break;
   14337 		    }
   14338 		}
   14339 	    }
   14340 	    if (!found) {
   14341 		xmlChar *strA = NULL, *strB = NULL;
   14342 
   14343 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14344 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
   14345 		    NULL, item,
   14346 		    "A matching attribute use for the "
   14347 		    "'required' %s of the %s %s is missing",
   14348 		    xmlSchemaGetComponentDesignation(&strA, bcur),
   14349 		    WXS_ACTION_STR(action),
   14350 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
   14351 		    NULL);
   14352 		FREE_AND_NULL(strA);
   14353 		FREE_AND_NULL(strB);
   14354 	    }
   14355 	}
   14356     }
   14357     /*
   14358     * derivation-ok-restriction (4)
   14359     */
   14360     if (wild != NULL) {
   14361 	/*
   14362 	* (4) "If there is an {attribute wildcard}, all of the
   14363 	* following must be true:"
   14364 	*/
   14365 	if (baseWild == NULL) {
   14366 	    xmlChar *str = NULL;
   14367 
   14368 	    /*
   14369 	    * (4.1) "The {base type definition} must also have one."
   14370 	    */
   14371 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14372 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
   14373 		NULL, item,
   14374 		"The %s has an attribute wildcard, "
   14375 		"but the %s %s '%s' does not have one",
   14376 		WXS_ITEM_TYPE_NAME(item),
   14377 		WXS_ACTION_STR(action),
   14378 		WXS_ITEM_TYPE_NAME(baseItem),
   14379 		xmlSchemaGetComponentQName(&str, baseItem));
   14380 	    FREE_AND_NULL(str);
   14381 	    return(pctxt->err);
   14382 	} else if ((baseWild->any == 0) &&
   14383 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
   14384 	{
   14385 	    xmlChar *str = NULL;
   14386 	    /*
   14387 	    * (4.2) "The complex type definition's {attribute wildcard}'s
   14388 	    * {namespace constraint} must be a subset of the {base type
   14389 	    * definition}'s {attribute wildcard}'s {namespace constraint},
   14390 	    * as defined by Wildcard Subset ($3.10.6)."
   14391 	    */
   14392 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14393 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
   14394 		NULL, item,
   14395 		"The attribute wildcard is not a valid "
   14396 		"subset of the wildcard in the %s %s '%s'",
   14397 		WXS_ACTION_STR(action),
   14398 		WXS_ITEM_TYPE_NAME(baseItem),
   14399 		xmlSchemaGetComponentQName(&str, baseItem),
   14400 		NULL);
   14401 	    FREE_AND_NULL(str);
   14402 	    return(pctxt->err);
   14403 	}
   14404 	/* 4.3 Unless the {base type definition} is the `ur-type
   14405 	* definition`, the complex type definition's {attribute
   14406 	* wildcard}'s {process contents} must be identical to or
   14407 	* stronger than the {base type definition}'s {attribute
   14408 	* wildcard}'s {process contents}, where strict is stronger
   14409 	* than lax is stronger than skip.
   14410 	*/
   14411 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
   14412 	    (wild->processContents < baseWild->processContents)) {
   14413 	    xmlChar *str = NULL;
   14414 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   14415 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
   14416 		NULL, baseItem,
   14417 		"The {process contents} of the attribute wildcard is "
   14418 		"weaker than the one in the %s %s '%s'",
   14419 		WXS_ACTION_STR(action),
   14420 		WXS_ITEM_TYPE_NAME(baseItem),
   14421 		xmlSchemaGetComponentQName(&str, baseItem),
   14422 		NULL);
   14423 	    FREE_AND_NULL(str)
   14424 		return(pctxt->err);
   14425 	}
   14426     }
   14427     return(0);
   14428 }
   14429 
   14430 
   14431 static int
   14432 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   14433 				  xmlSchemaBasicItemPtr item,
   14434 				  xmlSchemaWildcardPtr *completeWild,
   14435 				  xmlSchemaItemListPtr list,
   14436 				  xmlSchemaItemListPtr prohibs);
   14437 /**
   14438  * xmlSchemaFixupTypeAttributeUses:
   14439  * @ctxt:  the schema parser context
   14440  * @type:  the complex type definition
   14441  *
   14442  *
   14443  * Builds the wildcard and the attribute uses on the given complex type.
   14444  * Returns -1 if an internal error occurs, 0 otherwise.
   14445  *
   14446  * ATTENTION TODO: Experimantally this uses pointer comparisons for
   14447  * strings, so recheck this if we start to hardcode some schemata, since
   14448  * they might not be in the same dict.
   14449  * NOTE: It is allowed to "extend" the xs:anyType type.
   14450  */
   14451 static int
   14452 xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
   14453 				  xmlSchemaTypePtr type)
   14454 {
   14455     xmlSchemaTypePtr baseType = NULL;
   14456     xmlSchemaAttributeUsePtr use;
   14457     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
   14458 
   14459     if (type->baseType == NULL) {
   14460 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14461 	    "no base type");
   14462         return (-1);
   14463     }
   14464     baseType = type->baseType;
   14465     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14466 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
   14467 	    return(-1);
   14468 
   14469     uses = type->attrUses;
   14470     baseUses = baseType->attrUses;
   14471     /*
   14472     * Expand attribute group references. And build the 'complete'
   14473     * wildcard, i.e. intersect multiple wildcards.
   14474     * Move attribute prohibitions into a separate list.
   14475     */
   14476     if (uses != NULL) {
   14477 	if (WXS_IS_RESTRICTION(type)) {
   14478 	    /*
   14479 	    * This one will transfer all attr. prohibitions
   14480 	    * into pctxt->attrProhibs.
   14481 	    */
   14482 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14483 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14484 		pctxt->attrProhibs) == -1)
   14485 	    {
   14486 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14487 		"failed to expand attributes");
   14488 	    }
   14489 	    if (pctxt->attrProhibs->nbItems != 0)
   14490 		prohibs = pctxt->attrProhibs;
   14491 	} else {
   14492 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
   14493 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
   14494 		NULL) == -1)
   14495 	    {
   14496 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
   14497 		"failed to expand attributes");
   14498 	    }
   14499 	}
   14500     }
   14501     /*
   14502     * Inherit the attribute uses of the base type.
   14503     */
   14504     if (baseUses != NULL) {
   14505 	int i, j;
   14506 	xmlSchemaAttributeUseProhibPtr pro;
   14507 
   14508 	if (WXS_IS_RESTRICTION(type)) {
   14509 	    int usesCount;
   14510 	    xmlSchemaAttributeUsePtr tmp;
   14511 
   14512 	    if (uses != NULL)
   14513 		usesCount = uses->nbItems;
   14514 	    else
   14515 		usesCount = 0;
   14516 
   14517 	    /* Restriction. */
   14518 	    for (i = 0; i < baseUses->nbItems; i++) {
   14519 		use = baseUses->items[i];
   14520 		if (prohibs) {
   14521 		    /*
   14522 		    * Filter out prohibited uses.
   14523 		    */
   14524 		    for (j = 0; j < prohibs->nbItems; j++) {
   14525 			pro = prohibs->items[j];
   14526 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
   14527 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14528 				pro->targetNamespace))
   14529 			{
   14530 			    goto inherit_next;
   14531 			}
   14532 		    }
   14533 		}
   14534 		if (usesCount) {
   14535 		    /*
   14536 		    * Filter out existing uses.
   14537 		    */
   14538 		    for (j = 0; j < usesCount; j++) {
   14539 			tmp = uses->items[j];
   14540 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   14541 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
   14542 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   14543 				WXS_ATTRUSE_DECL_TNS(tmp)))
   14544 			{
   14545 			    goto inherit_next;
   14546 			}
   14547 		    }
   14548 		}
   14549 		if (uses == NULL) {
   14550 		    type->attrUses = xmlSchemaItemListCreate();
   14551 		    if (type->attrUses == NULL)
   14552 			goto exit_failure;
   14553 		    uses = type->attrUses;
   14554 		}
   14555 		xmlSchemaItemListAddSize(uses, 2, use);
   14556 inherit_next: {}
   14557 	    }
   14558 	} else {
   14559 	    /* Extension. */
   14560 	    for (i = 0; i < baseUses->nbItems; i++) {
   14561 		use = baseUses->items[i];
   14562 		if (uses == NULL) {
   14563 		    type->attrUses = xmlSchemaItemListCreate();
   14564 		    if (type->attrUses == NULL)
   14565 			goto exit_failure;
   14566 		    uses = type->attrUses;
   14567 		}
   14568 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
   14569 	    }
   14570 	}
   14571     }
   14572     /*
   14573     * Shrink attr. uses.
   14574     */
   14575     if (uses) {
   14576 	if (uses->nbItems == 0) {
   14577 	    xmlSchemaItemListFree(uses);
   14578 	    type->attrUses = NULL;
   14579 	}
   14580 	/*
   14581 	* TODO: We could shrink the size of the array
   14582 	* to fit the actual number of items.
   14583 	*/
   14584     }
   14585     /*
   14586     * Compute the complete wildcard.
   14587     */
   14588     if (WXS_IS_EXTENSION(type)) {
   14589 	if (baseType->attributeWildcard != NULL) {
   14590 	    /*
   14591 	    * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
   14592 	    * the appropriate case among the following:"
   14593 	    */
   14594 	    if (type->attributeWildcard != NULL) {
   14595 		/*
   14596 		* Union the complete wildcard with the base wildcard.
   14597 		* SPEC {attribute wildcard}
   14598 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
   14599 		* and {annotation} are those of the `complete wildcard`,
   14600 		* and whose {namespace constraint} is the intensional union
   14601 		* of the {namespace constraint} of the `complete wildcard`
   14602 		* and of the `base wildcard`, as defined in Attribute
   14603 		* Wildcard Union ($3.10.6)."
   14604 		*/
   14605 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
   14606 		    baseType->attributeWildcard) == -1)
   14607 		    goto exit_failure;
   14608 	    } else {
   14609 		/*
   14610 		* (3.2.2.1.1) "If the `complete wildcard` is `absent`,
   14611 		* then the `base wildcard`."
   14612 		*/
   14613 		type->attributeWildcard = baseType->attributeWildcard;
   14614 	    }
   14615 	} else {
   14616 	    /*
   14617 	    * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
   14618 	    * `complete wildcard`"
   14619 	    * NOOP
   14620 	    */
   14621 	}
   14622     } else {
   14623 	/*
   14624 	* SPEC {attribute wildcard}
   14625 	* (3.1) "If the <restriction> alternative is chosen, then the
   14626 	* `complete wildcard`;"
   14627 	* NOOP
   14628 	*/
   14629     }
   14630 
   14631     return (0);
   14632 
   14633 exit_failure:
   14634     return(-1);
   14635 }
   14636 
   14637 /**
   14638  * xmlSchemaTypeFinalContains:
   14639  * @schema:  the schema
   14640  * @type:  the type definition
   14641  * @final: the final
   14642  *
   14643  * Evaluates if a type definition contains the given "final".
   14644  * This does take "finalDefault" into account as well.
   14645  *
   14646  * Returns 1 if the type does containt the given "final",
   14647  * 0 otherwise.
   14648  */
   14649 static int
   14650 xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
   14651 {
   14652     if (type == NULL)
   14653 	return (0);
   14654     if (type->flags & final)
   14655 	return (1);
   14656     else
   14657 	return (0);
   14658 }
   14659 
   14660 /**
   14661  * xmlSchemaGetUnionSimpleTypeMemberTypes:
   14662  * @type:  the Union Simple Type
   14663  *
   14664  * Returns a list of member types of @type if existing,
   14665  * returns NULL otherwise.
   14666  */
   14667 static xmlSchemaTypeLinkPtr
   14668 xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
   14669 {
   14670     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
   14671 	if (type->memberTypes != NULL)
   14672 	    return (type->memberTypes);
   14673 	else
   14674 	    type = type->baseType;
   14675     }
   14676     return (NULL);
   14677 }
   14678 
   14679 /**
   14680  * xmlSchemaGetParticleTotalRangeMin:
   14681  * @particle: the particle
   14682  *
   14683  * Schema Component Constraint: Effective Total Range
   14684  * (all and sequence) + (choice)
   14685  *
   14686  * Returns the minimun Effective Total Range.
   14687  */
   14688 static int
   14689 xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
   14690 {
   14691     if ((particle->children == NULL) ||
   14692 	(particle->minOccurs == 0))
   14693 	return (0);
   14694     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14695 	int min = -1, cur;
   14696 	xmlSchemaParticlePtr part =
   14697 	    (xmlSchemaParticlePtr) particle->children->children;
   14698 
   14699 	if (part == NULL)
   14700 	    return (0);
   14701 	while (part != NULL) {
   14702 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14703 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14704 		cur = part->minOccurs;
   14705 	    else
   14706 		cur = xmlSchemaGetParticleTotalRangeMin(part);
   14707 	    if (cur == 0)
   14708 		return (0);
   14709 	    if ((min > cur) || (min == -1))
   14710 		min = cur;
   14711 	    part = (xmlSchemaParticlePtr) part->next;
   14712 	}
   14713 	return (particle->minOccurs * min);
   14714     } else {
   14715 	/* <all> and <sequence> */
   14716 	int sum = 0;
   14717 	xmlSchemaParticlePtr part =
   14718 	    (xmlSchemaParticlePtr) particle->children->children;
   14719 
   14720 	if (part == NULL)
   14721 	    return (0);
   14722 	do {
   14723 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14724 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14725 		sum += part->minOccurs;
   14726 	    else
   14727 		sum += xmlSchemaGetParticleTotalRangeMin(part);
   14728 	    part = (xmlSchemaParticlePtr) part->next;
   14729 	} while (part != NULL);
   14730 	return (particle->minOccurs * sum);
   14731     }
   14732 }
   14733 
   14734 #if 0
   14735 /**
   14736  * xmlSchemaGetParticleTotalRangeMax:
   14737  * @particle: the particle
   14738  *
   14739  * Schema Component Constraint: Effective Total Range
   14740  * (all and sequence) + (choice)
   14741  *
   14742  * Returns the maximum Effective Total Range.
   14743  */
   14744 static int
   14745 xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
   14746 {
   14747     if ((particle->children == NULL) ||
   14748 	(particle->children->children == NULL))
   14749 	return (0);
   14750     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
   14751 	int max = -1, cur;
   14752 	xmlSchemaParticlePtr part =
   14753 	    (xmlSchemaParticlePtr) particle->children->children;
   14754 
   14755 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14756 	    if (part->children == NULL)
   14757 		continue;
   14758 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14759 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14760 		cur = part->maxOccurs;
   14761 	    else
   14762 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14763 	    if (cur == UNBOUNDED)
   14764 		return (UNBOUNDED);
   14765 	    if ((max < cur) || (max == -1))
   14766 		max = cur;
   14767 	}
   14768 	/* TODO: Handle overflows? */
   14769 	return (particle->maxOccurs * max);
   14770     } else {
   14771 	/* <all> and <sequence> */
   14772 	int sum = 0, cur;
   14773 	xmlSchemaParticlePtr part =
   14774 	    (xmlSchemaParticlePtr) particle->children->children;
   14775 
   14776 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
   14777 	    if (part->children == NULL)
   14778 		continue;
   14779 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
   14780 		(part->children->type == XML_SCHEMA_TYPE_ANY))
   14781 		cur = part->maxOccurs;
   14782 	    else
   14783 		cur = xmlSchemaGetParticleTotalRangeMax(part);
   14784 	    if (cur == UNBOUNDED)
   14785 		return (UNBOUNDED);
   14786 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
   14787 		return (UNBOUNDED);
   14788 	    sum += cur;
   14789 	}
   14790 	/* TODO: Handle overflows? */
   14791 	return (particle->maxOccurs * sum);
   14792     }
   14793 }
   14794 #endif
   14795 
   14796 /**
   14797  * xmlSchemaIsParticleEmptiable:
   14798  * @particle: the particle
   14799  *
   14800  * Schema Component Constraint: Particle Emptiable
   14801  * Checks whether the given particle is emptiable.
   14802  *
   14803  * Returns 1 if emptiable, 0 otherwise.
   14804  */
   14805 static int
   14806 xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
   14807 {
   14808     /*
   14809     * SPEC (1) "Its {min occurs} is 0."
   14810     */
   14811     if ((particle == NULL) || (particle->minOccurs == 0) ||
   14812 	(particle->children == NULL))
   14813 	return (1);
   14814     /*
   14815     * SPEC (2) "Its {term} is a group and the minimum part of the
   14816     * effective total range of that group, [...] is 0."
   14817     */
   14818     if (WXS_IS_MODEL_GROUP(particle->children)) {
   14819 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
   14820 	    return (1);
   14821     }
   14822     return (0);
   14823 }
   14824 
   14825 /**
   14826  * xmlSchemaCheckCOSSTDerivedOK:
   14827  * @actxt: a context
   14828  * @type:  the derived simple type definition
   14829  * @baseType:  the base type definition
   14830  * @subset: the subset of ('restriction', ect.)
   14831  *
   14832  * Schema Component Constraint:
   14833  * Type Derivation OK (Simple) (cos-st-derived-OK)
   14834  *
   14835  * Checks wheter @type can be validly
   14836  * derived from @baseType.
   14837  *
   14838  * Returns 0 on success, an positive error code otherwise.
   14839  */
   14840 static int
   14841 xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   14842 			     xmlSchemaTypePtr type,
   14843 			     xmlSchemaTypePtr baseType,
   14844 			     int subset)
   14845 {
   14846     /*
   14847     * 1 They are the same type definition.
   14848     * TODO: The identy check might have to be more complex than this.
   14849     */
   14850     if (type == baseType)
   14851 	return (0);
   14852     /*
   14853     * 2.1 restriction is not in the subset, or in the {final}
   14854     * of its own {base type definition};
   14855     *
   14856     * NOTE that this will be used also via "xsi:type".
   14857     *
   14858     * TODO: Revise this, it looks strange. How can the "type"
   14859     * not be fixed or *in* fixing?
   14860     */
   14861     if (WXS_IS_TYPE_NOT_FIXED(type))
   14862 	if (xmlSchemaTypeFixup(type, actxt) == -1)
   14863 	    return(-1);
   14864     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   14865 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
   14866 	    return(-1);
   14867     if ((subset & SUBSET_RESTRICTION) ||
   14868 	(xmlSchemaTypeFinalContains(type->baseType,
   14869 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
   14870 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
   14871     }
   14872     /* 2.2 */
   14873     if (type->baseType == baseType) {
   14874 	/*
   14875 	* 2.2.1 D's `base type definition` is B.
   14876 	*/
   14877 	return (0);
   14878     }
   14879     /*
   14880     * 2.2.2 D's `base type definition` is not the `ur-type definition`
   14881     * and is validly derived from B given the subset, as defined by this
   14882     * constraint.
   14883     */
   14884     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
   14885 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   14886 	    baseType, subset) == 0)) {
   14887 	return (0);
   14888     }
   14889     /*
   14890     * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
   14891     * definition`.
   14892     */
   14893     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
   14894 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
   14895 	return (0);
   14896     }
   14897     /*
   14898     * 2.2.4 B's {variety} is union and D is validly derived from a type
   14899     * definition in B's {member type definitions} given the subset, as
   14900     * defined by this constraint.
   14901     *
   14902     * NOTE: This seems not to involve built-in types, since there is no
   14903     * built-in Union Simple Type.
   14904     */
   14905     if (WXS_IS_UNION(baseType)) {
   14906 	xmlSchemaTypeLinkPtr cur;
   14907 
   14908 	cur = baseType->memberTypes;
   14909 	while (cur != NULL) {
   14910 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
   14911 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
   14912 		    return(-1);
   14913 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
   14914 		    type, cur->type, subset) == 0)
   14915 	    {
   14916 		/*
   14917 		* It just has to be validly derived from at least one
   14918 		* member-type.
   14919 		*/
   14920 		return (0);
   14921 	    }
   14922 	    cur = cur->next;
   14923 	}
   14924     }
   14925     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
   14926 }
   14927 
   14928 /**
   14929  * xmlSchemaCheckTypeDefCircularInternal:
   14930  * @pctxt:  the schema parser context
   14931  * @ctxtType:  the type definition
   14932  * @ancestor: an ancestor of @ctxtType
   14933  *
   14934  * Checks st-props-correct (2) + ct-props-correct (3).
   14935  * Circular type definitions are not allowed.
   14936  *
   14937  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
   14938  * circular, 0 otherwise.
   14939  */
   14940 static int
   14941 xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
   14942 			   xmlSchemaTypePtr ctxtType,
   14943 			   xmlSchemaTypePtr ancestor)
   14944 {
   14945     int ret;
   14946 
   14947     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
   14948 	return (0);
   14949 
   14950     if (ctxtType == ancestor) {
   14951 	xmlSchemaPCustomErr(pctxt,
   14952 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
   14953 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
   14954 	    "The definition is circular", NULL);
   14955 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
   14956     }
   14957     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
   14958 	/*
   14959 	* Avoid inifinite recursion on circular types not yet checked.
   14960 	*/
   14961 	return (0);
   14962     }
   14963     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
   14964     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
   14965 	ancestor->baseType);
   14966     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
   14967     return (ret);
   14968 }
   14969 
   14970 /**
   14971  * xmlSchemaCheckTypeDefCircular:
   14972  * @item:  the complex/simple type definition
   14973  * @ctxt:  the parser context
   14974  * @name:  the name
   14975  *
   14976  * Checks for circular type definitions.
   14977  */
   14978 static void
   14979 xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
   14980 			      xmlSchemaParserCtxtPtr ctxt)
   14981 {
   14982     if ((item == NULL) ||
   14983 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
   14984 	(item->baseType == NULL))
   14985 	return;
   14986     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
   14987 	item->baseType);
   14988 }
   14989 
   14990 /*
   14991 * Simple Type Definition Representation OK (src-simple-type) 4
   14992 *
   14993 * "4 Circular union type definition is disallowed. That is, if the
   14994 * <union> alternative is chosen, there must not be any entries in the
   14995 * memberTypes [attribute] at any depth which resolve to the component
   14996 * corresponding to the <simpleType>."
   14997 *
   14998 * Note that this should work on the *representation* of a component,
   14999 * thus assumes any union types in the member types not being yet
   15000 * substituted. At this stage we need the variety of the types
   15001 * to be already computed.
   15002 */
   15003 static int
   15004 xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
   15005 					xmlSchemaTypePtr ctxType,
   15006 					xmlSchemaTypeLinkPtr members)
   15007 {
   15008     xmlSchemaTypeLinkPtr member;
   15009     xmlSchemaTypePtr memberType;
   15010 
   15011     member = members;
   15012     while (member != NULL) {
   15013 	memberType = member->type;
   15014 	while ((memberType != NULL) &&
   15015 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
   15016 	    if (memberType == ctxType) {
   15017 		xmlSchemaPCustomErr(pctxt,
   15018 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
   15019 		    WXS_BASIC_CAST ctxType, NULL,
   15020 		    "The union type definition is circular", NULL);
   15021 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
   15022 	    }
   15023 	    if ((WXS_IS_UNION(memberType)) &&
   15024 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
   15025 	    {
   15026 		int res;
   15027 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
   15028 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
   15029 		    ctxType,
   15030 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
   15031 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
   15032 		if (res != 0)
   15033 		    return(res);
   15034 	    }
   15035 	    memberType = memberType->baseType;
   15036 	}
   15037 	member = member->next;
   15038     }
   15039     return(0);
   15040 }
   15041 
   15042 static int
   15043 xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
   15044 				   xmlSchemaTypePtr type)
   15045 {
   15046     if (! WXS_IS_UNION(type))
   15047 	return(0);
   15048     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
   15049 	type->memberTypes));
   15050 }
   15051 
   15052 /**
   15053  * xmlSchemaResolveTypeReferences:
   15054  * @item:  the complex/simple type definition
   15055  * @ctxt:  the parser context
   15056  * @name:  the name
   15057  *
   15058  * Resolvese type definition references
   15059  */
   15060 static void
   15061 xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
   15062 			 xmlSchemaParserCtxtPtr ctxt)
   15063 {
   15064     if (typeDef == NULL)
   15065 	return;
   15066 
   15067     /*
   15068     * Resolve the base type.
   15069     */
   15070     if (typeDef->baseType == NULL) {
   15071 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
   15072 	    typeDef->base, typeDef->baseNs);
   15073 	if (typeDef->baseType == NULL) {
   15074 	    xmlSchemaPResCompAttrErr(ctxt,
   15075 		XML_SCHEMAP_SRC_RESOLVE,
   15076 		WXS_BASIC_CAST typeDef, typeDef->node,
   15077 		"base", typeDef->base, typeDef->baseNs,
   15078 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   15079 	    return;
   15080 	}
   15081     }
   15082     if (WXS_IS_SIMPLE(typeDef)) {
   15083 	if (WXS_IS_UNION(typeDef)) {
   15084 	    /*
   15085 	    * Resolve the memberTypes.
   15086 	    */
   15087 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
   15088 	    return;
   15089 	} else if (WXS_IS_LIST(typeDef)) {
   15090 	    /*
   15091 	    * Resolve the itemType.
   15092 	    */
   15093 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
   15094 
   15095 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
   15096 		    typeDef->base, typeDef->baseNs);
   15097 
   15098 		if ((typeDef->subtypes == NULL) ||
   15099 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
   15100 		{
   15101 		    typeDef->subtypes = NULL;
   15102 		    xmlSchemaPResCompAttrErr(ctxt,
   15103 			XML_SCHEMAP_SRC_RESOLVE,
   15104 			WXS_BASIC_CAST typeDef, typeDef->node,
   15105 			"itemType", typeDef->base, typeDef->baseNs,
   15106 			XML_SCHEMA_TYPE_SIMPLE, NULL);
   15107 		}
   15108 	    }
   15109 	    return;
   15110 	}
   15111     }
   15112     /*
   15113     * The ball of letters below means, that if we have a particle
   15114     * which has a QName-helper component as its {term}, we want
   15115     * to resolve it...
   15116     */
   15117     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
   15118 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
   15119 	    XML_SCHEMA_TYPE_PARTICLE) &&
   15120 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
   15121 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
   15122 	    XML_SCHEMA_EXTRA_QNAMEREF))
   15123     {
   15124 	xmlSchemaQNameRefPtr ref =
   15125 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
   15126 	xmlSchemaModelGroupDefPtr groupDef;
   15127 
   15128 	/*
   15129 	* URGENT TODO: Test this.
   15130 	*/
   15131 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
   15132 	/*
   15133 	* Resolve the MG definition reference.
   15134 	*/
   15135 	groupDef =
   15136 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
   15137 		ref->itemType, ref->name, ref->targetNamespace);
   15138 	if (groupDef == NULL) {
   15139 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   15140 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
   15141 		"ref", ref->name, ref->targetNamespace, ref->itemType,
   15142 		NULL);
   15143 	    /* Remove the particle. */
   15144 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15145 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
   15146 	    /* Remove the particle. */
   15147 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
   15148 	else {
   15149 	    /*
   15150 	    * Assign the MG definition's {model group} to the
   15151 	    * particle's {term}.
   15152 	    */
   15153 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
   15154 
   15155 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
   15156 		/*
   15157 		* SPEC cos-all-limited (1.2)
   15158 		* "1.2 the {term} property of a particle with
   15159 		* {max occurs}=1 which is part of a pair which constitutes
   15160 		* the {content type} of a complex type definition."
   15161 		*/
   15162 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
   15163 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   15164 			/* TODO: error code */
   15165 			XML_SCHEMAP_COS_ALL_LIMITED,
   15166 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
   15167 			"The particle's {max occurs} must be 1, since the "
   15168 			"reference resolves to an 'all' model group",
   15169 			NULL, NULL);
   15170 		}
   15171 	    }
   15172 	}
   15173     }
   15174 }
   15175 
   15176 
   15177 
   15178 /**
   15179  * xmlSchemaCheckSTPropsCorrect:
   15180  * @ctxt:  the schema parser context
   15181  * @type:  the simple type definition
   15182  *
   15183  * Checks st-props-correct.
   15184  *
   15185  * Returns 0 if the properties are correct,
   15186  * if not, a positive error code and -1 on internal
   15187  * errors.
   15188  */
   15189 static int
   15190 xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   15191 			     xmlSchemaTypePtr type)
   15192 {
   15193     xmlSchemaTypePtr baseType = type->baseType;
   15194     xmlChar *str = NULL;
   15195 
   15196     /* STATE: error funcs converted. */
   15197     /*
   15198     * Schema Component Constraint: Simple Type Definition Properties Correct
   15199     *
   15200     * NOTE: This is somehow redundant, since we actually built a simple type
   15201     * to have all the needed information; this acts as an self test.
   15202     */
   15203     /* Base type: If the datatype has been `derived` by `restriction`
   15204     * then the Simple Type Definition component from which it is `derived`,
   15205     * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
   15206     */
   15207     if (baseType == NULL) {
   15208 	/*
   15209 	* TODO: Think about: "modulo the impact of Missing
   15210 	* Sub-components ($5.3)."
   15211 	*/
   15212 	xmlSchemaPCustomErr(ctxt,
   15213 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15214 	    WXS_BASIC_CAST type, NULL,
   15215 	    "No base type existent", NULL);
   15216 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15217 
   15218     }
   15219     if (! WXS_IS_SIMPLE(baseType)) {
   15220 	xmlSchemaPCustomErr(ctxt,
   15221 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15222 	    WXS_BASIC_CAST type, NULL,
   15223 	    "The base type '%s' is not a simple type",
   15224 	    xmlSchemaGetComponentQName(&str, baseType));
   15225 	FREE_AND_NULL(str)
   15226 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15227     }
   15228     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
   15229 	(WXS_IS_RESTRICTION(type) == 0) &&
   15230 	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
   15231          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
   15232 	xmlSchemaPCustomErr(ctxt,
   15233 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15234 	    WXS_BASIC_CAST type, NULL,
   15235 	    "A type, derived by list or union, must have "
   15236 	    "the simple ur-type definition as base type, not '%s'",
   15237 	    xmlSchemaGetComponentQName(&str, baseType));
   15238 	FREE_AND_NULL(str)
   15239 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15240     }
   15241     /*
   15242     * Variety: One of {atomic, list, union}.
   15243     */
   15244     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
   15245 	(! WXS_IS_LIST(type))) {
   15246 	xmlSchemaPCustomErr(ctxt,
   15247 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
   15248 	    WXS_BASIC_CAST type, NULL,
   15249 	    "The variety is absent", NULL);
   15250 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
   15251     }
   15252     /* TODO: Finish this. Hmm, is this finished? */
   15253 
   15254     /*
   15255     * 3 The {final} of the {base type definition} must not contain restriction.
   15256     */
   15257     if (xmlSchemaTypeFinalContains(baseType,
   15258 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15259 	xmlSchemaPCustomErr(ctxt,
   15260 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
   15261 	    WXS_BASIC_CAST type, NULL,
   15262 	    "The 'final' of its base type '%s' must not contain "
   15263 	    "'restriction'",
   15264 	    xmlSchemaGetComponentQName(&str, baseType));
   15265 	FREE_AND_NULL(str)
   15266 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
   15267     }
   15268 
   15269     /*
   15270     * 2 All simple type definitions must be derived ultimately from the `simple
   15271     * ur-type definition` (so circular definitions are disallowed). That is, it
   15272     * must be possible to reach a built-in primitive datatype or the `simple
   15273     * ur-type definition` by repeatedly following the {base type definition}.
   15274     *
   15275     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
   15276     */
   15277     return (0);
   15278 }
   15279 
   15280 /**
   15281  * xmlSchemaCheckCOSSTRestricts:
   15282  * @ctxt:  the schema parser context
   15283  * @type:  the simple type definition
   15284  *
   15285  * Schema Component Constraint:
   15286  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
   15287 
   15288  * Checks if the given @type (simpleType) is derived validly by restriction.
   15289  * STATUS:
   15290  *
   15291  * Returns -1 on internal errors, 0 if the type is validly derived,
   15292  * a positive error code otherwise.
   15293  */
   15294 static int
   15295 xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
   15296 			     xmlSchemaTypePtr type)
   15297 {
   15298     xmlChar *str = NULL;
   15299 
   15300     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
   15301 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15302 	    "given type is not a user-derived simpleType");
   15303 	return (-1);
   15304     }
   15305 
   15306     if (WXS_IS_ATOMIC(type)) {
   15307 	xmlSchemaTypePtr primitive;
   15308 	/*
   15309 	* 1.1 The {base type definition} must be an atomic simple
   15310 	* type definition or a built-in primitive datatype.
   15311 	*/
   15312 	if (! WXS_IS_ATOMIC(type->baseType)) {
   15313 	    xmlSchemaPCustomErr(pctxt,
   15314 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
   15315 		WXS_BASIC_CAST type, NULL,
   15316 		"The base type '%s' is not an atomic simple type",
   15317 		xmlSchemaGetComponentQName(&str, type->baseType));
   15318 	    FREE_AND_NULL(str)
   15319 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
   15320 	}
   15321 	/* 1.2 The {final} of the {base type definition} must not contain
   15322 	* restriction.
   15323 	*/
   15324 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
   15325 	if (xmlSchemaTypeFinalContains(type->baseType,
   15326 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15327 	    xmlSchemaPCustomErr(pctxt,
   15328 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
   15329 		WXS_BASIC_CAST type, NULL,
   15330 		"The final of its base type '%s' must not contain 'restriction'",
   15331 		xmlSchemaGetComponentQName(&str, type->baseType));
   15332 	    FREE_AND_NULL(str)
   15333 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
   15334 	}
   15335 
   15336 	/*
   15337 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
   15338 	* type definition}, as specified in the appropriate subsection of 3.2
   15339 	* Primitive datatypes.
   15340 	*/
   15341 	if (type->facets != NULL) {
   15342 	    xmlSchemaFacetPtr facet;
   15343 	    int ok = 1;
   15344 
   15345 	    primitive = xmlSchemaGetPrimitiveType(type);
   15346 	    if (primitive == NULL) {
   15347 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15348 		    "failed to get primitive type");
   15349 		return (-1);
   15350 	    }
   15351 	    facet = type->facets;
   15352 	    do {
   15353 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
   15354 		    ok = 0;
   15355 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
   15356 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
   15357 			type, primitive, facet);
   15358 		}
   15359 		facet = facet->next;
   15360 	    } while (facet != NULL);
   15361 	    if (ok == 0)
   15362 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
   15363 	}
   15364 	/*
   15365 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
   15366 	* of the {base type definition} (call this BF),then the DF's {value}
   15367 	* must be a valid restriction of BF's {value} as defined in
   15368 	* [XML Schemas: Datatypes]."
   15369 	*
   15370 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
   15371 	* xmlSchemaDeriveAndValidateFacets()
   15372 	*/
   15373     } else if (WXS_IS_LIST(type)) {
   15374 	xmlSchemaTypePtr itemType = NULL;
   15375 
   15376 	itemType = type->subtypes;
   15377 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
   15378 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15379 		"failed to evaluate the item type");
   15380 	    return (-1);
   15381 	}
   15382 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
   15383 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
   15384 	/*
   15385 	* 2.1 The {item type definition} must have a {variety} of atomic or
   15386 	* union (in which case all the {member type definitions}
   15387 	* must be atomic).
   15388 	*/
   15389 	if ((! WXS_IS_ATOMIC(itemType)) &&
   15390 	    (! WXS_IS_UNION(itemType))) {
   15391 	    xmlSchemaPCustomErr(pctxt,
   15392 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15393 		WXS_BASIC_CAST type, NULL,
   15394 		"The item type '%s' does not have a variety of atomic or union",
   15395 		xmlSchemaGetComponentQName(&str, itemType));
   15396 	    FREE_AND_NULL(str)
   15397 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15398 	} else if (WXS_IS_UNION(itemType)) {
   15399 	    xmlSchemaTypeLinkPtr member;
   15400 
   15401 	    member = itemType->memberTypes;
   15402 	    while (member != NULL) {
   15403 		if (! WXS_IS_ATOMIC(member->type)) {
   15404 		    xmlSchemaPCustomErr(pctxt,
   15405 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
   15406 			WXS_BASIC_CAST type, NULL,
   15407 			"The item type is a union type, but the "
   15408 			"member type '%s' of this item type is not atomic",
   15409 			xmlSchemaGetComponentQName(&str, member->type));
   15410 		    FREE_AND_NULL(str)
   15411 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
   15412 		}
   15413 		member = member->next;
   15414 	    }
   15415 	}
   15416 
   15417 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
   15418 	    xmlSchemaFacetPtr facet;
   15419 	    /*
   15420 	    * This is the case if we have: <simpleType><list ..
   15421 	    */
   15422 	    /*
   15423 	    * 2.3.1
   15424 	    * 2.3.1.1 The {final} of the {item type definition} must not
   15425 	    * contain list.
   15426 	    */
   15427 	    if (xmlSchemaTypeFinalContains(itemType,
   15428 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
   15429 		xmlSchemaPCustomErr(pctxt,
   15430 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
   15431 		    WXS_BASIC_CAST type, NULL,
   15432 		    "The final of its item type '%s' must not contain 'list'",
   15433 		    xmlSchemaGetComponentQName(&str, itemType));
   15434 		FREE_AND_NULL(str)
   15435 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
   15436 	    }
   15437 	    /*
   15438 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
   15439 	    * facet component.
   15440 	    * OPTIMIZE TODO: the S4S already disallows any facet
   15441 	    * to be specified.
   15442 	    */
   15443 	    if (type->facets != NULL) {
   15444 		facet = type->facets;
   15445 		do {
   15446 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
   15447 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15448 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
   15449 			    type, facet);
   15450 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
   15451 		    }
   15452 		    facet = facet->next;
   15453 		} while (facet != NULL);
   15454 	    }
   15455 	    /*
   15456 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
   15457 	    * A `list` datatype can be `derived` from an `atomic` datatype
   15458 	    * whose `lexical space` allows space (such as string or anyURI)or
   15459 	    * a `union` datatype any of whose {member type definitions}'s
   15460 	    * `lexical space` allows space.
   15461 	    */
   15462 	} else {
   15463 	    /*
   15464 	    * This is the case if we have: <simpleType><restriction ...
   15465 	    * I.e. the variety of "list" is inherited.
   15466 	    */
   15467 	    /*
   15468 	    * 2.3.2
   15469 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
   15470 	    */
   15471 	    if (! WXS_IS_LIST(type->baseType)) {
   15472 		xmlSchemaPCustomErr(pctxt,
   15473 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
   15474 		    WXS_BASIC_CAST type, NULL,
   15475 		    "The base type '%s' must be a list type",
   15476 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15477 		FREE_AND_NULL(str)
   15478 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
   15479 	    }
   15480 	    /*
   15481 	    * 2.3.2.2 The {final} of the {base type definition} must not
   15482 	    * contain restriction.
   15483 	    */
   15484 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15485 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15486 		xmlSchemaPCustomErr(pctxt,
   15487 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
   15488 		    WXS_BASIC_CAST type, NULL,
   15489 		    "The 'final' of the base type '%s' must not contain 'restriction'",
   15490 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15491 		FREE_AND_NULL(str)
   15492 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
   15493 	    }
   15494 	    /*
   15495 	    * 2.3.2.3 The {item type definition} must be validly derived
   15496 	    * from the {base type definition}'s {item type definition} given
   15497 	    * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
   15498 	    */
   15499 	    {
   15500 		xmlSchemaTypePtr baseItemType;
   15501 
   15502 		baseItemType = type->baseType->subtypes;
   15503 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
   15504 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15505 			"failed to eval the item type of a base type");
   15506 		    return (-1);
   15507 		}
   15508 		if ((itemType != baseItemType) &&
   15509 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
   15510 			baseItemType, 0) != 0)) {
   15511 		    xmlChar *strBIT = NULL, *strBT = NULL;
   15512 		    xmlSchemaPCustomErrExt(pctxt,
   15513 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
   15514 			WXS_BASIC_CAST type, NULL,
   15515 			"The item type '%s' is not validly derived from "
   15516 			"the item type '%s' of the base type '%s'",
   15517 			xmlSchemaGetComponentQName(&str, itemType),
   15518 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
   15519 			xmlSchemaGetComponentQName(&strBT, type->baseType));
   15520 
   15521 		    FREE_AND_NULL(str)
   15522 		    FREE_AND_NULL(strBIT)
   15523 		    FREE_AND_NULL(strBT)
   15524 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
   15525 		}
   15526 	    }
   15527 
   15528 	    if (type->facets != NULL) {
   15529 		xmlSchemaFacetPtr facet;
   15530 		int ok = 1;
   15531 		/*
   15532 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
   15533 		* and enumeration facet components are allowed among the {facets}.
   15534 		*/
   15535 		facet = type->facets;
   15536 		do {
   15537 		    switch (facet->type) {
   15538 			case XML_SCHEMA_FACET_LENGTH:
   15539 			case XML_SCHEMA_FACET_MINLENGTH:
   15540 			case XML_SCHEMA_FACET_MAXLENGTH:
   15541 			case XML_SCHEMA_FACET_WHITESPACE:
   15542 			    /*
   15543 			    * TODO: 2.5.1.2 List datatypes
   15544 			    * The value of `whiteSpace` is fixed to the value collapse.
   15545 			    */
   15546 			case XML_SCHEMA_FACET_PATTERN:
   15547 			case XML_SCHEMA_FACET_ENUMERATION:
   15548 			    break;
   15549 			default: {
   15550 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15551 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
   15552 				type, facet);
   15553 			    /*
   15554 			    * We could return, but it's nicer to report all
   15555 			    * invalid facets.
   15556 			    */
   15557 			    ok = 0;
   15558 			}
   15559 		    }
   15560 		    facet = facet->next;
   15561 		} while (facet != NULL);
   15562 		if (ok == 0)
   15563 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
   15564 		/*
   15565 		* SPEC (2.3.2.5) (same as 1.3.2)
   15566 		*
   15567 		* NOTE (2.3.2.5) This is currently done in
   15568 		* xmlSchemaDeriveAndValidateFacets()
   15569 		*/
   15570 	    }
   15571 	}
   15572     } else if (WXS_IS_UNION(type)) {
   15573 	/*
   15574 	* 3.1 The {member type definitions} must all have {variety} of
   15575 	* atomic or list.
   15576 	*/
   15577 	xmlSchemaTypeLinkPtr member;
   15578 
   15579 	member = type->memberTypes;
   15580 	while (member != NULL) {
   15581 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
   15582 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
   15583 
   15584 	    if ((! WXS_IS_ATOMIC(member->type)) &&
   15585 		(! WXS_IS_LIST(member->type))) {
   15586 		xmlSchemaPCustomErr(pctxt,
   15587 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
   15588 		    WXS_BASIC_CAST type, NULL,
   15589 		    "The member type '%s' is neither an atomic, nor a list type",
   15590 		    xmlSchemaGetComponentQName(&str, member->type));
   15591 		FREE_AND_NULL(str)
   15592 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
   15593 	    }
   15594 	    member = member->next;
   15595 	}
   15596 	/*
   15597 	* 3.3.1 If the {base type definition} is the `simple ur-type
   15598 	* definition`
   15599 	*/
   15600 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
   15601 	    /*
   15602 	    * 3.3.1.1 All of the {member type definitions} must have a
   15603 	    * {final} which does not contain union.
   15604 	    */
   15605 	    member = type->memberTypes;
   15606 	    while (member != NULL) {
   15607 		if (xmlSchemaTypeFinalContains(member->type,
   15608 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
   15609 		    xmlSchemaPCustomErr(pctxt,
   15610 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
   15611 			WXS_BASIC_CAST type, NULL,
   15612 			"The 'final' of member type '%s' contains 'union'",
   15613 			xmlSchemaGetComponentQName(&str, member->type));
   15614 		    FREE_AND_NULL(str)
   15615 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
   15616 		}
   15617 		member = member->next;
   15618 	    }
   15619 	    /*
   15620 	    * 3.3.1.2 The {facets} must be empty.
   15621 	    */
   15622 	    if (type->facetSet != NULL) {
   15623 		xmlSchemaPCustomErr(pctxt,
   15624 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
   15625 		    WXS_BASIC_CAST type, NULL,
   15626 		    "No facets allowed", NULL);
   15627 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
   15628 	    }
   15629 	} else {
   15630 	    /*
   15631 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
   15632 	    * I.e. the variety of "list" is inherited.
   15633 	    */
   15634 	    if (! WXS_IS_UNION(type->baseType)) {
   15635 		xmlSchemaPCustomErr(pctxt,
   15636 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
   15637 		    WXS_BASIC_CAST type, NULL,
   15638 		    "The base type '%s' is not a union type",
   15639 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15640 		FREE_AND_NULL(str)
   15641 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
   15642 	    }
   15643 	    /*
   15644 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
   15645 	    */
   15646 	    if (xmlSchemaTypeFinalContains(type->baseType,
   15647 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
   15648 		xmlSchemaPCustomErr(pctxt,
   15649 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
   15650 		    WXS_BASIC_CAST type, NULL,
   15651 		    "The 'final' of its base type '%s' must not contain 'restriction'",
   15652 		    xmlSchemaGetComponentQName(&str, type->baseType));
   15653 		FREE_AND_NULL(str)
   15654 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
   15655 	    }
   15656 	    /*
   15657 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
   15658 	    * derived from the corresponding type definitions in the {base
   15659 	    * type definition}'s {member type definitions} given the empty set,
   15660 	    * as defined in Type Derivation OK (Simple) ($3.14.6).
   15661 	    */
   15662 	    {
   15663 		xmlSchemaTypeLinkPtr baseMember;
   15664 
   15665 		/*
   15666 		* OPTIMIZE: if the type is restricting, it has no local defined
   15667 		* member types and inherits the member types of the base type;
   15668 		* thus a check for equality can be skipped.
   15669 		*/
   15670 		/*
   15671 		* Even worse: I cannot see a scenario where a restricting
   15672 		* union simple type can have other member types as the member
   15673 		* types of it's base type. This check seems not necessary with
   15674 		* respect to the derivation process in libxml2.
   15675 		* But necessary if constructing types with an API.
   15676 		*/
   15677 		if (type->memberTypes != NULL) {
   15678 		    member = type->memberTypes;
   15679 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
   15680 		    if ((member == NULL) && (baseMember != NULL)) {
   15681 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15682 			    "different number of member types in base");
   15683 		    }
   15684 		    while (member != NULL) {
   15685 			if (baseMember == NULL) {
   15686 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
   15687 			    "different number of member types in base");
   15688 			} else if ((member->type != baseMember->type) &&
   15689 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
   15690 				member->type, baseMember->type, 0) != 0)) {
   15691 			    xmlChar *strBMT = NULL, *strBT = NULL;
   15692 
   15693 			    xmlSchemaPCustomErrExt(pctxt,
   15694 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
   15695 				WXS_BASIC_CAST type, NULL,
   15696 				"The member type %s is not validly "
   15697 				"derived from its corresponding member "
   15698 				"type %s of the base type %s",
   15699 				xmlSchemaGetComponentQName(&str, member->type),
   15700 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
   15701 				xmlSchemaGetComponentQName(&strBT, type->baseType));
   15702 			    FREE_AND_NULL(str)
   15703 			    FREE_AND_NULL(strBMT)
   15704 			    FREE_AND_NULL(strBT)
   15705 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
   15706 			}
   15707 			member = member->next;
   15708                         if (baseMember != NULL)
   15709                             baseMember = baseMember->next;
   15710 		    }
   15711 		}
   15712 	    }
   15713 	    /*
   15714 	    * 3.3.2.4 Only pattern and enumeration facet components are
   15715 	    * allowed among the {facets}.
   15716 	    */
   15717 	    if (type->facets != NULL) {
   15718 		xmlSchemaFacetPtr facet;
   15719 		int ok = 1;
   15720 
   15721 		facet = type->facets;
   15722 		do {
   15723 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
   15724 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
   15725 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
   15726 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
   15727 				type, facet);
   15728 			ok = 0;
   15729 		    }
   15730 		    facet = facet->next;
   15731 		} while (facet != NULL);
   15732 		if (ok == 0)
   15733 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
   15734 
   15735 	    }
   15736 	    /*
   15737 	    * SPEC (3.3.2.5) (same as 1.3.2)
   15738 	    *
   15739 	    * NOTE (3.3.2.5) This is currently done in
   15740 	    * xmlSchemaDeriveAndValidateFacets()
   15741 	    */
   15742 	}
   15743     }
   15744 
   15745     return (0);
   15746 }
   15747 
   15748 /**
   15749  * xmlSchemaCheckSRCSimpleType:
   15750  * @ctxt:  the schema parser context
   15751  * @type:  the simple type definition
   15752  *
   15753  * Checks crc-simple-type constraints.
   15754  *
   15755  * Returns 0 if the constraints are satisfied,
   15756  * if not a positive error code and -1 on internal
   15757  * errors.
   15758  */
   15759 #if 0
   15760 static int
   15761 xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
   15762 			    xmlSchemaTypePtr type)
   15763 {
   15764     /*
   15765     * src-simple-type.1 The corresponding simple type definition, if any,
   15766     * must satisfy the conditions set out in Constraints on Simple Type
   15767     * Definition Schema Components ($3.14.6).
   15768     */
   15769     if (WXS_IS_RESTRICTION(type)) {
   15770 	/*
   15771 	* src-simple-type.2 "If the <restriction> alternative is chosen,
   15772 	* either it must have a base [attribute] or a <simpleType> among its
   15773 	* [children], but not both."
   15774 	* NOTE: This is checked in the parse function of <restriction>.
   15775 	*/
   15776 	/*
   15777 	*
   15778 	*/
   15779     } else if (WXS_IS_LIST(type)) {
   15780 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
   15781 	* an itemType [attribute] or a <simpleType> among its [children],
   15782 	* but not both."
   15783 	*
   15784 	* NOTE: This is checked in the parse function of <list>.
   15785 	*/
   15786     } else if (WXS_IS_UNION(type)) {
   15787 	/*
   15788 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
   15789 	*/
   15790     }
   15791     return (0);
   15792 }
   15793 #endif
   15794 
   15795 static int
   15796 xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
   15797 {
   15798    if (ctxt->vctxt == NULL) {
   15799 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
   15800 	if (ctxt->vctxt == NULL) {
   15801 	    xmlSchemaPErr(ctxt, NULL,
   15802 		XML_SCHEMAP_INTERNAL,
   15803 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
   15804 		"failed to create a temp. validation context.\n",
   15805 		NULL, NULL);
   15806 	    return (-1);
   15807 	}
   15808 	/* TODO: Pass user data. */
   15809 	xmlSchemaSetValidErrors(ctxt->vctxt,
   15810 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
   15811 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
   15812 	    ctxt->serror, ctxt->errCtxt);
   15813     }
   15814     return (0);
   15815 }
   15816 
   15817 static int
   15818 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   15819 			     xmlNodePtr node,
   15820 			     xmlSchemaTypePtr type,
   15821 			     const xmlChar *value,
   15822 			     xmlSchemaValPtr *retVal,
   15823 			     int fireErrors,
   15824 			     int normalize,
   15825 			     int isNormalized);
   15826 
   15827 /**
   15828  * xmlSchemaParseCheckCOSValidDefault:
   15829  * @pctxt:  the schema parser context
   15830  * @type:  the simple type definition
   15831  * @value: the default value
   15832  * @node: an optional node (the holder of the value)
   15833  *
   15834  * Schema Component Constraint: Element Default Valid (Immediate)
   15835  * (cos-valid-default)
   15836  * This will be used by the parser only. For the validator there's
   15837  * an other version.
   15838  *
   15839  * Returns 0 if the constraints are satisfied,
   15840  * if not, a positive error code and -1 on internal
   15841  * errors.
   15842  */
   15843 static int
   15844 xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
   15845 				   xmlNodePtr node,
   15846 				   xmlSchemaTypePtr type,
   15847 				   const xmlChar *value,
   15848 				   xmlSchemaValPtr *val)
   15849 {
   15850     int ret = 0;
   15851 
   15852     /*
   15853     * cos-valid-default:
   15854     * Schema Component Constraint: Element Default Valid (Immediate)
   15855     * For a string to be a valid default with respect to a type
   15856     * definition the appropriate case among the following must be true:
   15857     */
   15858     if WXS_IS_COMPLEX(type) {
   15859 	/*
   15860 	* Complex type.
   15861 	*
   15862 	* SPEC (2.1) "its {content type} must be a simple type definition
   15863 	* or mixed."
   15864 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   15865 	* type}'s particle must be `emptiable` as defined by
   15866 	* Particle Emptiable ($3.9.6)."
   15867 	*/
   15868 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
   15869 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
   15870 	    /* NOTE that this covers (2.2.2) as well. */
   15871 	    xmlSchemaPCustomErr(pctxt,
   15872 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
   15873 		WXS_BASIC_CAST type, type->node,
   15874 		"For a string to be a valid default, the type definition "
   15875 		"must be a simple type or a complex type with mixed content "
   15876 		"and a particle emptiable", NULL);
   15877 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
   15878 	}
   15879     }
   15880     /*
   15881     * 1 If the type definition is a simple type definition, then the string
   15882     * must be `valid` with respect to that definition as defined by String
   15883     * Valid ($3.14.4).
   15884     *
   15885     * AND
   15886     *
   15887     * 2.2.1 If the {content type} is a simple type definition, then the
   15888     * string must be `valid` with respect to that simple type definition
   15889     * as defined by String Valid ($3.14.4).
   15890     */
   15891     if (WXS_IS_SIMPLE(type))
   15892 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15893 	    type, value, val, 1, 1, 0);
   15894     else if (WXS_HAS_SIMPLE_CONTENT(type))
   15895 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
   15896 	    type->contentTypeDef, value, val, 1, 1, 0);
   15897     else
   15898 	return (ret);
   15899 
   15900     if (ret < 0) {
   15901 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
   15902 	    "calling xmlSchemaVCheckCVCSimpleType()");
   15903     }
   15904 
   15905     return (ret);
   15906 }
   15907 
   15908 /**
   15909  * xmlSchemaCheckCTPropsCorrect:
   15910  * @ctxt:  the schema parser context
   15911  * @type:  the complex type definition
   15912  *
   15913  *.(4.6) Constraints on Complex Type Definition Schema Components
   15914  * Schema Component Constraint:
   15915  * Complex Type Definition Properties Correct (ct-props-correct)
   15916  * STATUS: (seems) complete
   15917  *
   15918  * Returns 0 if the constraints are satisfied, a positive
   15919  * error code if not and -1 if an internal error occurred.
   15920  */
   15921 static int
   15922 xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   15923 			     xmlSchemaTypePtr type)
   15924 {
   15925     /*
   15926     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
   15927     *
   15928     * SPEC (1) "The values of the properties of a complex type definition must
   15929     * be as described in the property tableau in The Complex Type Definition
   15930     * Schema Component ($3.4.1), modulo the impact of Missing
   15931     * Sub-components ($5.3)."
   15932     */
   15933     if ((type->baseType != NULL) &&
   15934 	(WXS_IS_SIMPLE(type->baseType)) &&
   15935 	(WXS_IS_EXTENSION(type) == 0)) {
   15936 	/*
   15937 	* SPEC (2) "If the {base type definition} is a simple type definition,
   15938 	* the {derivation method} must be extension."
   15939 	*/
   15940 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15941 	    XML_SCHEMAP_SRC_CT_1,
   15942 	    NULL, WXS_BASIC_CAST type,
   15943 	    "If the base type is a simple type, the derivation method must be "
   15944 	    "'extension'", NULL, NULL);
   15945 	return (XML_SCHEMAP_SRC_CT_1);
   15946     }
   15947     /*
   15948     * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
   15949     * definition`. That is, it must be possible to reach the `ur-type
   15950     * definition` by repeatedly following the {base type definition}."
   15951     *
   15952     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
   15953     */
   15954     /*
   15955     * NOTE that (4) and (5) need the following:
   15956     *   - attribute uses need to be already inherited (apply attr. prohibitions)
   15957     *   - attribute group references need to be expanded already
   15958     *   - simple types need to be typefixed already
   15959     */
   15960     if (type->attrUses &&
   15961 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
   15962     {
   15963 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
   15964 	xmlSchemaAttributeUsePtr use, tmp;
   15965 	int i, j, hasId = 0;
   15966 
   15967 	for (i = uses->nbItems -1; i >= 0; i--) {
   15968 	    use = uses->items[i];
   15969 
   15970 	    /*
   15971 	    * SPEC ct-props-correct
   15972 	    * (4) "Two distinct attribute declarations in the
   15973 	    * {attribute uses} must not have identical {name}s and
   15974 	    * {target namespace}s."
   15975 	    */
   15976 	    if (i > 0) {
   15977 		for (j = i -1; j >= 0; j--) {
   15978 		    tmp = uses->items[j];
   15979 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   15980 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   15981 			(WXS_ATTRUSE_DECL_TNS(use) ==
   15982 			WXS_ATTRUSE_DECL_TNS(tmp)))
   15983 		    {
   15984 			xmlChar *str = NULL;
   15985 
   15986 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   15987 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   15988 			    NULL, WXS_BASIC_CAST type,
   15989 			    "Duplicate %s",
   15990 			    xmlSchemaGetComponentDesignation(&str, use),
   15991 			    NULL);
   15992 			FREE_AND_NULL(str);
   15993 			/*
   15994 			* Remove the duplicate.
   15995 			*/
   15996 			if (xmlSchemaItemListRemove(uses, i) == -1)
   15997 			    goto exit_failure;
   15998 			goto next_use;
   15999 		    }
   16000 		}
   16001 	    }
   16002 	    /*
   16003 	    * SPEC ct-props-correct
   16004 	    * (5) "Two distinct attribute declarations in the
   16005 	    * {attribute uses} must not have {type definition}s which
   16006 	    * are or are derived from ID."
   16007 	    */
   16008 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   16009 		if (xmlSchemaIsDerivedFromBuiltInType(
   16010 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   16011 		{
   16012 		    if (hasId) {
   16013 			xmlChar *str = NULL;
   16014 
   16015 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16016 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   16017 			    NULL, WXS_BASIC_CAST type,
   16018 			    "There must not exist more than one attribute "
   16019 			    "declaration of type 'xs:ID' "
   16020 			    "(or derived from 'xs:ID'). The %s violates this "
   16021 			    "constraint",
   16022 			    xmlSchemaGetComponentDesignation(&str, use),
   16023 			    NULL);
   16024 			FREE_AND_NULL(str);
   16025 			if (xmlSchemaItemListRemove(uses, i) == -1)
   16026 			    goto exit_failure;
   16027 		    }
   16028 
   16029 		    hasId = 1;
   16030 		}
   16031 	    }
   16032 next_use: {}
   16033 	}
   16034     }
   16035     return (0);
   16036 exit_failure:
   16037     return(-1);
   16038 }
   16039 
   16040 static int
   16041 xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
   16042 		       xmlSchemaTypePtr typeB)
   16043 {
   16044     /*
   16045     * TODO: This should implement component-identity
   16046     * in the future.
   16047     */
   16048     if ((typeA == NULL) || (typeB == NULL))
   16049 	return (0);
   16050     return (typeA == typeB);
   16051 }
   16052 
   16053 /**
   16054  * xmlSchemaCheckCOSCTDerivedOK:
   16055  * @ctxt:  the schema parser context
   16056  * @type:  the to-be derived complex type definition
   16057  * @baseType:  the base complex type definition
   16058  * @set: the given set
   16059  *
   16060  * Schema Component Constraint:
   16061  * Type Derivation OK (Complex) (cos-ct-derived-ok)
   16062  *
   16063  * STATUS: completed
   16064  *
   16065  * Returns 0 if the constraints are satisfied, or 1
   16066  * if not.
   16067  */
   16068 static int
   16069 xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16070 			     xmlSchemaTypePtr type,
   16071 			     xmlSchemaTypePtr baseType,
   16072 			     int set)
   16073 {
   16074     int equal = xmlSchemaAreEqualTypes(type, baseType);
   16075     /* TODO: Error codes. */
   16076     /*
   16077     * SPEC "For a complex type definition (call it D, for derived)
   16078     * to be validly derived from a type definition (call this
   16079     * B, for base) given a subset of {extension, restriction}
   16080     * all of the following must be true:"
   16081     */
   16082     if (! equal) {
   16083 	/*
   16084 	* SPEC (1) "If B and D are not the same type definition, then the
   16085 	* {derivation method} of D must not be in the subset."
   16086 	*/
   16087 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
   16088 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
   16089 	    return (1);
   16090     } else {
   16091 	/*
   16092 	* SPEC (2.1) "B and D must be the same type definition."
   16093 	*/
   16094 	return (0);
   16095     }
   16096     /*
   16097     * SPEC (2.2) "B must be D's {base type definition}."
   16098     */
   16099     if (type->baseType == baseType)
   16100 	return (0);
   16101     /*
   16102     * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
   16103     * definition`."
   16104     */
   16105     if (WXS_IS_ANYTYPE(type->baseType))
   16106 	return (1);
   16107 
   16108     if (WXS_IS_COMPLEX(type->baseType)) {
   16109 	/*
   16110 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
   16111 	* must be validly derived from B given the subset as defined by this
   16112 	* constraint."
   16113 	*/
   16114 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
   16115 	    baseType, set));
   16116     } else {
   16117 	/*
   16118 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
   16119 	* must be validly derived from B given the subset as defined in Type
   16120 	* Derivation OK (Simple) ($3.14.6).
   16121 	*/
   16122 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
   16123 	    baseType, set));
   16124     }
   16125 }
   16126 
   16127 /**
   16128  * xmlSchemaCheckCOSDerivedOK:
   16129  * @type:  the derived simple type definition
   16130  * @baseType:  the base type definition
   16131  *
   16132  * Calls:
   16133  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
   16134  *
   16135  * Checks wheter @type can be validly derived from @baseType.
   16136  *
   16137  * Returns 0 on success, an positive error code otherwise.
   16138  */
   16139 static int
   16140 xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
   16141 			   xmlSchemaTypePtr type,
   16142 			   xmlSchemaTypePtr baseType,
   16143 			   int set)
   16144 {
   16145     if (WXS_IS_SIMPLE(type))
   16146 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
   16147     else
   16148 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
   16149 }
   16150 
   16151 /**
   16152  * xmlSchemaCheckCOSCTExtends:
   16153  * @ctxt:  the schema parser context
   16154  * @type:  the complex type definition
   16155  *
   16156  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16157  * Schema Component Constraint:
   16158  * Derivation Valid (Extension) (cos-ct-extends)
   16159  *
   16160  * STATUS:
   16161  *   missing:
   16162  *     (1.5)
   16163  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
   16164  *
   16165  * Returns 0 if the constraints are satisfied, a positive
   16166  * error code if not and -1 if an internal error occurred.
   16167  */
   16168 static int
   16169 xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
   16170 			   xmlSchemaTypePtr type)
   16171 {
   16172     xmlSchemaTypePtr base = type->baseType;
   16173     /*
   16174     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
   16175     * temporarily only.
   16176     */
   16177     /*
   16178     * SPEC (1) "If the {base type definition} is a complex type definition,
   16179     * then all of the following must be true:"
   16180     */
   16181     if (WXS_IS_COMPLEX(base)) {
   16182 	/*
   16183 	* SPEC (1.1) "The {final} of the {base type definition} must not
   16184 	* contain extension."
   16185 	*/
   16186 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16187 	    xmlSchemaPCustomErr(ctxt,
   16188 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16189 		WXS_BASIC_CAST type, NULL,
   16190 		"The 'final' of the base type definition "
   16191 		"contains 'extension'", NULL);
   16192 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16193 	}
   16194 
   16195 	/*
   16196 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
   16197 	* since they are automatically satisfied through the
   16198 	* inheriting mechanism.
   16199 	* Note that even if redefining components, the inheriting mechanism
   16200 	* is used.
   16201 	*/
   16202 #if 0
   16203 	/*
   16204 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
   16205 	* uses}
   16206 	* of the complex type definition itself, that is, for every attribute
   16207 	* use in the {attribute uses} of the {base type definition}, there
   16208 	* must be an attribute use in the {attribute uses} of the complex
   16209 	* type definition itself whose {attribute declaration} has the same
   16210 	* {name}, {target namespace} and {type definition} as its attribute
   16211 	* declaration"
   16212 	*/
   16213 	if (base->attrUses != NULL) {
   16214 	    int i, j, found;
   16215 	    xmlSchemaAttributeUsePtr use, buse;
   16216 
   16217 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
   16218 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
   16219 		found = 0;
   16220 		if (type->attrUses != NULL) {
   16221 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
   16222 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
   16223 		    {
   16224 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
   16225 				WXS_ATTRUSE_DECL_NAME(buse)) &&
   16226 			    (WXS_ATTRUSE_DECL_TNS(use) ==
   16227 				WXS_ATTRUSE_DECL_TNS(buse)) &&
   16228 			    (WXS_ATTRUSE_TYPEDEF(use) ==
   16229 				WXS_ATTRUSE_TYPEDEF(buse))
   16230 			{
   16231 			    found = 1;
   16232 			    break;
   16233 			}
   16234 		    }
   16235 		}
   16236 		if (! found) {
   16237 		    xmlChar *str = NULL;
   16238 
   16239 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16240 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
   16241 			NULL, WXS_BASIC_CAST type,
   16242 			/*
   16243 			* TODO: The report does not indicate that also the
   16244 			* type needs to be the same.
   16245 			*/
   16246 			"This type is missing a matching correspondent "
   16247 			"for its {base type}'s %s in its {attribute uses}",
   16248 			xmlSchemaGetComponentDesignation(&str,
   16249 			    buse->children),
   16250 			NULL);
   16251 		    FREE_AND_NULL(str)
   16252 		}
   16253 	    }
   16254 	}
   16255 	/*
   16256 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
   16257 	* definition must also have one, and the base type definition's
   16258 	* {attribute  wildcard}'s {namespace constraint} must be a subset
   16259 	* of the complex  type definition's {attribute wildcard}'s {namespace
   16260 	* constraint}, as defined by Wildcard Subset ($3.10.6)."
   16261 	*/
   16262 
   16263 	/*
   16264 	* MAYBE TODO: Enable if ever needed. But this will be needed only
   16265 	* if created the type via a schema construction API.
   16266 	*/
   16267 	if (base->attributeWildcard != NULL) {
   16268 	    if (type->attributeWilcard == NULL) {
   16269 		xmlChar *str = NULL;
   16270 
   16271 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16272 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16273 		    NULL, type,
   16274 		    "The base %s has an attribute wildcard, "
   16275 		    "but this type is missing an attribute wildcard",
   16276 		    xmlSchemaGetComponentDesignation(&str, base));
   16277 		FREE_AND_NULL(str)
   16278 
   16279 	    } else if (xmlSchemaCheckCOSNSSubset(
   16280 		base->attributeWildcard, type->attributeWildcard))
   16281 	    {
   16282 		xmlChar *str = NULL;
   16283 
   16284 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   16285 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
   16286 		    NULL, type,
   16287 		    "The attribute wildcard is not a valid "
   16288 		    "superset of the one in the base %s",
   16289 		    xmlSchemaGetComponentDesignation(&str, base));
   16290 		FREE_AND_NULL(str)
   16291 	    }
   16292 	}
   16293 #endif
   16294 	/*
   16295 	* SPEC (1.4) "One of the following must be true:"
   16296 	*/
   16297 	if ((type->contentTypeDef != NULL) &&
   16298 	    (type->contentTypeDef == base->contentTypeDef)) {
   16299 	    /*
   16300 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
   16301 	    * and the {content type} of the complex type definition itself
   16302 	    * must be the same simple type definition"
   16303 	    * PASS
   16304 	    */
   16305 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
   16306 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
   16307 	    /*
   16308 	    * SPEC (1.4.2) "The {content type} of both the {base type
   16309 	    * definition} and the complex type definition itself must
   16310 	    * be empty."
   16311 	    * PASS
   16312 	    */
   16313 	} else {
   16314 	    /*
   16315 	    * SPEC (1.4.3) "All of the following must be true:"
   16316 	    */
   16317 	    if (type->subtypes == NULL) {
   16318 		/*
   16319 		* SPEC 1.4.3.1 The {content type} of the complex type
   16320 		* definition itself must specify a particle.
   16321 		*/
   16322 		xmlSchemaPCustomErr(ctxt,
   16323 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16324 		    WXS_BASIC_CAST type, NULL,
   16325 		    "The content type must specify a particle", NULL);
   16326 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16327 	    }
   16328 	    /*
   16329 	    * SPEC (1.4.3.2) "One of the following must be true:"
   16330 	    */
   16331 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16332 		/*
   16333 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
   16334 		* definition} must be empty.
   16335 		* PASS
   16336 		*/
   16337 	    } else {
   16338 		/*
   16339 		* SPEC (1.4.3.2.2) "All of the following must be true:"
   16340 		*/
   16341 		if ((type->contentType != base->contentType) ||
   16342 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
   16343 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
   16344 		    /*
   16345 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
   16346 		    * or both must be element-only."
   16347 		    */
   16348 		    xmlSchemaPCustomErr(ctxt,
   16349 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16350 			WXS_BASIC_CAST type, NULL,
   16351 			"The content type of both, the type and its base "
   16352 			"type, must either 'mixed' or 'element-only'", NULL);
   16353 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16354 		}
   16355 		/*
   16356 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
   16357 		* complex type definition must be a `valid extension`
   16358 		* of the {base type definition}'s particle, as defined
   16359 		* in Particle Valid (Extension) ($3.9.6)."
   16360 		*
   16361 		* NOTE that we won't check "Particle Valid (Extension)",
   16362 		* since it is ensured by the derivation process in
   16363 		* xmlSchemaTypeFixup(). We need to implement this when heading
   16364 		* for a construction API
   16365 		* TODO: !! This is needed to be checked if redefining a type !!
   16366 		*/
   16367 	    }
   16368 	    /*
   16369 	    * URGENT TODO (1.5)
   16370 	    */
   16371 	}
   16372     } else {
   16373 	/*
   16374 	* SPEC (2) "If the {base type definition} is a simple type definition,
   16375 	* then all of the following must be true:"
   16376 	*/
   16377 	if (type->contentTypeDef != base) {
   16378 	    /*
   16379 	    * SPEC (2.1) "The {content type} must be the same simple type
   16380 	    * definition."
   16381 	    */
   16382 	    xmlSchemaPCustomErr(ctxt,
   16383 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16384 		WXS_BASIC_CAST type, NULL,
   16385 		"The content type must be the simple base type", NULL);
   16386 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16387 	}
   16388 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
   16389 	    /*
   16390 	    * SPEC (2.2) "The {final} of the {base type definition} must not
   16391 	    * contain extension"
   16392 	    * NOTE that this is the same as (1.1).
   16393 	    */
   16394 	    xmlSchemaPCustomErr(ctxt,
   16395 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
   16396 		WXS_BASIC_CAST type, NULL,
   16397 		"The 'final' of the base type definition "
   16398 		"contains 'extension'", NULL);
   16399 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
   16400 	}
   16401     }
   16402     return (0);
   16403 }
   16404 
   16405 /**
   16406  * xmlSchemaCheckDerivationOKRestriction:
   16407  * @ctxt:  the schema parser context
   16408  * @type:  the complex type definition
   16409  *
   16410  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16411  * Schema Component Constraint:
   16412  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
   16413  *
   16414  * STATUS:
   16415  *   missing:
   16416  *     (5.4.2) ???
   16417  *
   16418  * ATTENTION:
   16419  * In XML Schema 1.1 this will be:
   16420  * Validation Rule: Checking complex type subsumption
   16421  *
   16422  * Returns 0 if the constraints are satisfied, a positive
   16423  * error code if not and -1 if an internal error occurred.
   16424  */
   16425 static int
   16426 xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
   16427 				      xmlSchemaTypePtr type)
   16428 {
   16429     xmlSchemaTypePtr base;
   16430 
   16431     /*
   16432     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
   16433     * temporarily only.
   16434     */
   16435     base = type->baseType;
   16436     if (! WXS_IS_COMPLEX(base)) {
   16437 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16438 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16439 	    type->node, WXS_BASIC_CAST type,
   16440 	    "The base type must be a complex type", NULL, NULL);
   16441 	return(ctxt->err);
   16442     }
   16443     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
   16444 	/*
   16445 	* SPEC (1) "The {base type definition} must be a complex type
   16446 	* definition whose {final} does not contain restriction."
   16447 	*/
   16448 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16449 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16450 	    type->node, WXS_BASIC_CAST type,
   16451 	    "The 'final' of the base type definition "
   16452 	    "contains 'restriction'", NULL, NULL);
   16453 	return (ctxt->err);
   16454     }
   16455     /*
   16456     * SPEC (2), (3) and (4)
   16457     * Those are handled in a separate function, since the
   16458     * same constraints are needed for redefinition of
   16459     * attribute groups as well.
   16460     */
   16461     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
   16462 	XML_SCHEMA_ACTION_DERIVE,
   16463 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
   16464 	type->attrUses, base->attrUses,
   16465 	type->attributeWildcard,
   16466 	base->attributeWildcard) == -1)
   16467     {
   16468 	return(-1);
   16469     }
   16470     /*
   16471     * SPEC (5) "One of the following must be true:"
   16472     */
   16473     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
   16474 	/*
   16475 	* SPEC (5.1) "The {base type definition} must be the
   16476 	* `ur-type definition`."
   16477 	* PASS
   16478 	*/
   16479     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16480 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16481 	/*
   16482 	* SPEC (5.2.1) "The {content type} of the complex type definition
   16483 	* must be a simple type definition"
   16484 	*
   16485 	* SPEC (5.2.2) "One of the following must be true:"
   16486 	*/
   16487 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16488 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
   16489 	{
   16490 	    int err;
   16491 	    /*
   16492 	    * SPEC (5.2.2.1) "The {content type} of the {base type
   16493 	    * definition} must be a simple type definition from which
   16494 	    * the {content type} is validly derived given the empty
   16495 	    * set as defined in Type Derivation OK (Simple) ($3.14.6)."
   16496 	    *
   16497 	    * ATTENTION TODO: This seems not needed if the type implicitely
   16498 	    * derived from the base type.
   16499 	    *
   16500 	    */
   16501 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
   16502 		type->contentTypeDef, base->contentTypeDef, 0);
   16503 	    if (err != 0) {
   16504 		xmlChar *strA = NULL, *strB = NULL;
   16505 
   16506 		if (err == -1)
   16507 		    return(-1);
   16508 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   16509 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16510 		    NULL, WXS_BASIC_CAST type,
   16511 		    "The {content type} %s is not validly derived from the "
   16512 		    "base type's {content type} %s",
   16513 		    xmlSchemaGetComponentDesignation(&strA,
   16514 			type->contentTypeDef),
   16515 		    xmlSchemaGetComponentDesignation(&strB,
   16516 			base->contentTypeDef));
   16517 		FREE_AND_NULL(strA);
   16518 		FREE_AND_NULL(strB);
   16519 		return(ctxt->err);
   16520 	    }
   16521 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16522 	    (xmlSchemaIsParticleEmptiable(
   16523 		(xmlSchemaParticlePtr) base->subtypes))) {
   16524 	    /*
   16525 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
   16526 	    * and have a particle which is `emptiable` as defined in
   16527 	    * Particle Emptiable ($3.9.6)."
   16528 	    * PASS
   16529 	    */
   16530 	} else {
   16531 	    xmlSchemaPCustomErr(ctxt,
   16532 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16533 		WXS_BASIC_CAST type, NULL,
   16534 		"The content type of the base type must be either "
   16535 		"a simple type or 'mixed' and an emptiable particle", NULL);
   16536 	    return (ctxt->err);
   16537 	}
   16538     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16539 	/*
   16540 	* SPEC (5.3.1) "The {content type} of the complex type itself must
   16541 	* be empty"
   16542 	*/
   16543 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   16544 	    /*
   16545 	    * SPEC (5.3.2.1) "The {content type} of the {base type
   16546 	    * definition} must also be empty."
   16547 	    * PASS
   16548 	    */
   16549 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16550 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
   16551 	    xmlSchemaIsParticleEmptiable(
   16552 		(xmlSchemaParticlePtr) base->subtypes)) {
   16553 	    /*
   16554 	    * SPEC (5.3.2.2) "The {content type} of the {base type
   16555 	    * definition} must be elementOnly or mixed and have a particle
   16556 	    * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
   16557 	    * PASS
   16558 	    */
   16559 	} else {
   16560 	    xmlSchemaPCustomErr(ctxt,
   16561 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16562 		WXS_BASIC_CAST type, NULL,
   16563 		"The content type of the base type must be either "
   16564 		"empty or 'mixed' (or 'elements-only') and an emptiable "
   16565 		"particle", NULL);
   16566 	    return (ctxt->err);
   16567 	}
   16568     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
   16569 	WXS_HAS_MIXED_CONTENT(type)) {
   16570 	/*
   16571 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
   16572 	* itself must be element-only"
   16573 	*/
   16574 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
   16575 	    /*
   16576 	    * SPEC (5.4.1.2) "The {content type} of the complex type
   16577 	    * definition itself and of the {base type definition} must be
   16578 	    * mixed"
   16579 	    */
   16580 	    xmlSchemaPCustomErr(ctxt,
   16581 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16582 		WXS_BASIC_CAST type, NULL,
   16583 		"If the content type is 'mixed', then the content type of the "
   16584 		"base type must also be 'mixed'", NULL);
   16585 	    return (ctxt->err);
   16586 	}
   16587 	/*
   16588 	* SPEC (5.4.2) "The particle of the complex type definition itself
   16589 	* must be a `valid restriction` of the particle of the {content
   16590 	* type} of the {base type definition} as defined in Particle Valid
   16591 	* (Restriction) ($3.9.6).
   16592 	*
   16593 	* URGENT TODO: (5.4.2)
   16594 	*/
   16595     } else {
   16596 	xmlSchemaPCustomErr(ctxt,
   16597 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
   16598 	    WXS_BASIC_CAST type, NULL,
   16599 	    "The type is not a valid restriction of its base type", NULL);
   16600 	return (ctxt->err);
   16601     }
   16602     return (0);
   16603 }
   16604 
   16605 /**
   16606  * xmlSchemaCheckCTComponent:
   16607  * @ctxt:  the schema parser context
   16608  * @type:  the complex type definition
   16609  *
   16610  * (3.4.6) Constraints on Complex Type Definition Schema Components
   16611  *
   16612  * Returns 0 if the constraints are satisfied, a positive
   16613  * error code if not and -1 if an internal error occurred.
   16614  */
   16615 static int
   16616 xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
   16617 			  xmlSchemaTypePtr type)
   16618 {
   16619     int ret;
   16620     /*
   16621     * Complex Type Definition Properties Correct
   16622     */
   16623     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
   16624     if (ret != 0)
   16625 	return (ret);
   16626     if (WXS_IS_EXTENSION(type))
   16627 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
   16628     else
   16629 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
   16630     return (ret);
   16631 }
   16632 
   16633 /**
   16634  * xmlSchemaCheckSRCCT:
   16635  * @ctxt:  the schema parser context
   16636  * @type:  the complex type definition
   16637  *
   16638  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
   16639  * Schema Representation Constraint:
   16640  * Complex Type Definition Representation OK (src-ct)
   16641  *
   16642  * Returns 0 if the constraints are satisfied, a positive
   16643  * error code if not and -1 if an internal error occurred.
   16644  */
   16645 static int
   16646 xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
   16647 		    xmlSchemaTypePtr type)
   16648 {
   16649     xmlSchemaTypePtr base;
   16650     int ret = 0;
   16651 
   16652     /*
   16653     * TODO: Adjust the error codes here, as I used
   16654     * XML_SCHEMAP_SRC_CT_1 only yet.
   16655     */
   16656     base = type->baseType;
   16657     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
   16658 	/*
   16659 	* 1 If the <complexContent> alternative is chosen, the type definition
   16660 	* `resolved` to by the `actual value` of the base [attribute]
   16661 	* must be a complex type definition;
   16662 	*/
   16663 	if (! WXS_IS_COMPLEX(base)) {
   16664 	    xmlChar *str = NULL;
   16665 	    xmlSchemaPCustomErr(ctxt,
   16666 		XML_SCHEMAP_SRC_CT_1,
   16667 		WXS_BASIC_CAST type, type->node,
   16668 		"If using <complexContent>, the base type is expected to be "
   16669 		"a complex type. The base type '%s' is a simple type",
   16670 		xmlSchemaFormatQName(&str, base->targetNamespace,
   16671 		base->name));
   16672 	    FREE_AND_NULL(str)
   16673 	    return (XML_SCHEMAP_SRC_CT_1);
   16674 	}
   16675     } else {
   16676 	/*
   16677 	* SPEC
   16678 	* 2 If the <simpleContent> alternative is chosen, all of the
   16679 	* following must be true:
   16680 	* 2.1 The type definition `resolved` to by the `actual value` of the
   16681 	* base [attribute] must be one of the following:
   16682 	*/
   16683 	if (WXS_IS_SIMPLE(base)) {
   16684 	    if (WXS_IS_EXTENSION(type) == 0) {
   16685 		xmlChar *str = NULL;
   16686 		/*
   16687 		* 2.1.3 only if the <extension> alternative is also
   16688 		* chosen, a simple type definition.
   16689 		*/
   16690 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
   16691 		xmlSchemaPCustomErr(ctxt,
   16692 		    XML_SCHEMAP_SRC_CT_1,
   16693 		    WXS_BASIC_CAST type, NULL,
   16694 		    "If using <simpleContent> and <restriction>, the base "
   16695 		    "type must be a complex type. The base type '%s' is "
   16696 		    "a simple type",
   16697 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16698 			base->name));
   16699 		FREE_AND_NULL(str)
   16700 		return (XML_SCHEMAP_SRC_CT_1);
   16701 	    }
   16702 	} else {
   16703 	    /* Base type is a complex type. */
   16704 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
   16705 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
   16706 		/*
   16707 		* 2.1.1 a complex type definition whose {content type} is a
   16708 		* simple type definition;
   16709 		* PASS
   16710 		*/
   16711 		if (base->contentTypeDef == NULL) {
   16712 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
   16713 			WXS_BASIC_CAST type, NULL,
   16714 			"Internal error: xmlSchemaCheckSRCCT, "
   16715 			"'%s', base type has no content type",
   16716 			type->name);
   16717 		    return (-1);
   16718 		}
   16719 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   16720 		(WXS_IS_RESTRICTION(type))) {
   16721 
   16722 		/*
   16723 		* 2.1.2 only if the <restriction> alternative is also
   16724 		* chosen, a complex type definition whose {content type}
   16725 		* is mixed and a particle emptiable.
   16726 		*/
   16727 		if (! xmlSchemaIsParticleEmptiable(
   16728 		    (xmlSchemaParticlePtr) base->subtypes)) {
   16729 		    ret = XML_SCHEMAP_SRC_CT_1;
   16730 		} else
   16731 		    /*
   16732 		    * Attention: at this point the <simpleType> child is in
   16733 		    * ->contentTypeDef (put there during parsing).
   16734 		    */
   16735 		    if (type->contentTypeDef == NULL) {
   16736 		    xmlChar *str = NULL;
   16737 		    /*
   16738 		    * 2.2 If clause 2.1.2 above is satisfied, then there
   16739 		    * must be a <simpleType> among the [children] of
   16740 		    * <restriction>.
   16741 		    */
   16742 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
   16743 		    xmlSchemaPCustomErr(ctxt,
   16744 			XML_SCHEMAP_SRC_CT_1,
   16745 			WXS_BASIC_CAST type, NULL,
   16746 			"A <simpleType> is expected among the children "
   16747 			"of <restriction>, if <simpleContent> is used and "
   16748 			"the base type '%s' is a complex type",
   16749 			xmlSchemaFormatQName(&str, base->targetNamespace,
   16750 			base->name));
   16751 		    FREE_AND_NULL(str)
   16752 		    return (XML_SCHEMAP_SRC_CT_1);
   16753 		}
   16754 	    } else {
   16755 		ret = XML_SCHEMAP_SRC_CT_1;
   16756 	    }
   16757 	}
   16758 	if (ret > 0) {
   16759 	    xmlChar *str = NULL;
   16760 	    if (WXS_IS_RESTRICTION(type)) {
   16761 		xmlSchemaPCustomErr(ctxt,
   16762 		    XML_SCHEMAP_SRC_CT_1,
   16763 		    WXS_BASIC_CAST type, NULL,
   16764 		    "If <simpleContent> and <restriction> is used, the "
   16765 		    "base type must be a simple type or a complex type with "
   16766 		    "mixed content and particle emptiable. The base type "
   16767 		    "'%s' is none of those",
   16768 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16769 		    base->name));
   16770 	    } else {
   16771 		xmlSchemaPCustomErr(ctxt,
   16772 		    XML_SCHEMAP_SRC_CT_1,
   16773 		    WXS_BASIC_CAST type, NULL,
   16774 		    "If <simpleContent> and <extension> is used, the "
   16775 		    "base type must be a simple type. The base type '%s' "
   16776 		    "is a complex type",
   16777 		    xmlSchemaFormatQName(&str, base->targetNamespace,
   16778 		    base->name));
   16779 	    }
   16780 	    FREE_AND_NULL(str)
   16781 	}
   16782     }
   16783     /*
   16784     * SPEC (3) "The corresponding complex type definition component must
   16785     * satisfy the conditions set out in Constraints on Complex Type
   16786     * Definition Schema Components ($3.4.6);"
   16787     * NOTE (3) will be done in xmlSchemaTypeFixup().
   16788     */
   16789     /*
   16790     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
   16791     * above for {attribute wildcard} is satisfied, the intensional
   16792     * intersection must be expressible, as defined in Attribute Wildcard
   16793     * Intersection ($3.10.6).
   16794     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
   16795     */
   16796     return (ret);
   16797 }
   16798 
   16799 #ifdef ENABLE_PARTICLE_RESTRICTION
   16800 /**
   16801  * xmlSchemaCheckParticleRangeOK:
   16802  * @ctxt:  the schema parser context
   16803  * @type:  the complex type definition
   16804  *
   16805  * (3.9.6) Constraints on Particle Schema Components
   16806  * Schema Component Constraint:
   16807  * Occurrence Range OK (range-ok)
   16808  *
   16809  * STATUS: complete
   16810  *
   16811  * Returns 0 if the constraints are satisfied, a positive
   16812  * error code if not and -1 if an internal error occurred.
   16813  */
   16814 static int
   16815 xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
   16816 			      int bmin, int bmax)
   16817 {
   16818     if (rmin < bmin)
   16819 	return (1);
   16820     if ((bmax != UNBOUNDED) &&
   16821 	(rmax > bmax))
   16822 	return (1);
   16823     return (0);
   16824 }
   16825 
   16826 /**
   16827  * xmlSchemaCheckRCaseNameAndTypeOK:
   16828  * @ctxt:  the schema parser context
   16829  * @r: the restricting element declaration particle
   16830  * @b: the base element declaration particle
   16831  *
   16832  * (3.9.6) Constraints on Particle Schema Components
   16833  * Schema Component Constraint:
   16834  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
   16835  * (rcase-NameAndTypeOK)
   16836  *
   16837  * STATUS:
   16838  *   MISSING (3.2.3)
   16839  *   CLARIFY: (3.2.2)
   16840  *
   16841  * Returns 0 if the constraints are satisfied, a positive
   16842  * error code if not and -1 if an internal error occurred.
   16843  */
   16844 static int
   16845 xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
   16846 				 xmlSchemaParticlePtr r,
   16847 				 xmlSchemaParticlePtr b)
   16848 {
   16849     xmlSchemaElementPtr elemR, elemB;
   16850 
   16851     /* TODO: Error codes (rcase-NameAndTypeOK). */
   16852     elemR = (xmlSchemaElementPtr) r->children;
   16853     elemB = (xmlSchemaElementPtr) b->children;
   16854     /*
   16855     * SPEC (1) "The declarations' {name}s and {target namespace}s are
   16856     * the same."
   16857     */
   16858     if ((elemR != elemB) &&
   16859 	((! xmlStrEqual(elemR->name, elemB->name)) ||
   16860 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
   16861 	return (1);
   16862     /*
   16863     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16864     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16865     */
   16866     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16867 	    b->minOccurs, b->maxOccurs) != 0)
   16868 	return (1);
   16869     /*
   16870     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
   16871     * {scope} are global."
   16872     */
   16873     if (elemR == elemB)
   16874 	return (0);
   16875     /*
   16876     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
   16877     */
   16878     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
   16879 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
   16880 	 return (1);
   16881     /*
   16882     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
   16883     * or is not fixed, or R's declaration's {value constraint} is fixed
   16884     * with the same value."
   16885     */
   16886     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
   16887 	((elemR->value == NULL) ||
   16888 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
   16889 	 /* TODO: Equality of the initial value or normalized or canonical? */
   16890 	 (! xmlStrEqual(elemR->value, elemB->value))))
   16891 	 return (1);
   16892     /*
   16893     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
   16894     * definitions} is a subset of B's declaration's {identity-constraint
   16895     * definitions}, if any."
   16896     */
   16897     if (elemB->idcs != NULL) {
   16898 	/* TODO */
   16899     }
   16900     /*
   16901     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
   16902     * superset of B's declaration's {disallowed substitutions}."
   16903     */
   16904     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
   16905 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
   16906 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
   16907 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
   16908 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
   16909 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
   16910 	 return (1);
   16911     /*
   16912     * SPEC (3.2.5) "R's {type definition} is validly derived given
   16913     * {extension, list, union} from B's {type definition}"
   16914     *
   16915     * BADSPEC TODO: What's the point of adding "list" and "union" to the
   16916     * set, if the corresponding constraints handle "restriction" and
   16917     * "extension" only?
   16918     *
   16919     */
   16920     {
   16921 	int set = 0;
   16922 
   16923 	set |= SUBSET_EXTENSION;
   16924 	set |= SUBSET_LIST;
   16925 	set |= SUBSET_UNION;
   16926 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
   16927 	    elemB->subtypes, set) != 0)
   16928 	    return (1);
   16929     }
   16930     return (0);
   16931 }
   16932 
   16933 /**
   16934  * xmlSchemaCheckRCaseNSCompat:
   16935  * @ctxt:  the schema parser context
   16936  * @r: the restricting element declaration particle
   16937  * @b: the base wildcard particle
   16938  *
   16939  * (3.9.6) Constraints on Particle Schema Components
   16940  * Schema Component Constraint:
   16941  * Particle Derivation OK (Elt:Any -- NSCompat)
   16942  * (rcase-NSCompat)
   16943  *
   16944  * STATUS: complete
   16945  *
   16946  * Returns 0 if the constraints are satisfied, a positive
   16947  * error code if not and -1 if an internal error occurred.
   16948  */
   16949 static int
   16950 xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
   16951 			    xmlSchemaParticlePtr r,
   16952 			    xmlSchemaParticlePtr b)
   16953 {
   16954     /* TODO:Error codes (rcase-NSCompat). */
   16955     /*
   16956     * SPEC "For an element declaration particle to be a `valid restriction`
   16957     * of a wildcard particle all of the following must be true:"
   16958     *
   16959     * SPEC (1) "The element declaration's {target namespace} is `valid`
   16960     * with respect to the wildcard's {namespace constraint} as defined by
   16961     * Wildcard allows Namespace Name ($3.10.4)."
   16962     */
   16963     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
   16964 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
   16965 	return (1);
   16966     /*
   16967     * SPEC (2) "R's occurrence range is a valid restriction of B's
   16968     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   16969     */
   16970     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   16971 	    b->minOccurs, b->maxOccurs) != 0)
   16972 	return (1);
   16973 
   16974     return (0);
   16975 }
   16976 
   16977 /**
   16978  * xmlSchemaCheckRCaseRecurseAsIfGroup:
   16979  * @ctxt:  the schema parser context
   16980  * @r: the restricting element declaration particle
   16981  * @b: the base model group particle
   16982  *
   16983  * (3.9.6) Constraints on Particle Schema Components
   16984  * Schema Component Constraint:
   16985  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
   16986  * (rcase-RecurseAsIfGroup)
   16987  *
   16988  * STATUS: TODO
   16989  *
   16990  * Returns 0 if the constraints are satisfied, a positive
   16991  * error code if not and -1 if an internal error occurred.
   16992  */
   16993 static int
   16994 xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
   16995 				    xmlSchemaParticlePtr r,
   16996 				    xmlSchemaParticlePtr b)
   16997 {
   16998     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
   16999     TODO
   17000     return (0);
   17001 }
   17002 
   17003 /**
   17004  * xmlSchemaCheckRCaseNSSubset:
   17005  * @ctxt:  the schema parser context
   17006  * @r: the restricting wildcard particle
   17007  * @b: the base wildcard particle
   17008  *
   17009  * (3.9.6) Constraints on Particle Schema Components
   17010  * Schema Component Constraint:
   17011  * Particle Derivation OK (Any:Any -- NSSubset)
   17012  * (rcase-NSSubset)
   17013  *
   17014  * STATUS: complete
   17015  *
   17016  * Returns 0 if the constraints are satisfied, a positive
   17017  * error code if not and -1 if an internal error occurred.
   17018  */
   17019 static int
   17020 xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
   17021 				    xmlSchemaParticlePtr r,
   17022 				    xmlSchemaParticlePtr b,
   17023 				    int isAnyTypeBase)
   17024 {
   17025     /* TODO: Error codes (rcase-NSSubset). */
   17026     /*
   17027     * SPEC (1) "R's occurrence range is a valid restriction of B's
   17028     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   17029     */
   17030     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   17031 	    b->minOccurs, b->maxOccurs))
   17032 	return (1);
   17033     /*
   17034     * SPEC (2) "R's {namespace constraint} must be an intensional subset
   17035     * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
   17036     */
   17037     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
   17038 	(xmlSchemaWildcardPtr) b->children))
   17039 	return (1);
   17040     /*
   17041     * SPEC (3) "Unless B is the content model wildcard of the `ur-type
   17042     * definition`, R's {process contents} must be identical to or stronger
   17043     * than B's {process contents}, where strict is stronger than lax is
   17044     * stronger than skip."
   17045     */
   17046     if (! isAnyTypeBase) {
   17047 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
   17048 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
   17049 	    return (1);
   17050     }
   17051 
   17052     return (0);
   17053 }
   17054 
   17055 /**
   17056  * xmlSchemaCheckCOSParticleRestrict:
   17057  * @ctxt:  the schema parser context
   17058  * @type:  the complex type definition
   17059  *
   17060  * (3.9.6) Constraints on Particle Schema Components
   17061  * Schema Component Constraint:
   17062  * Particle Valid (Restriction) (cos-particle-restrict)
   17063  *
   17064  * STATUS: TODO
   17065  *
   17066  * Returns 0 if the constraints are satisfied, a positive
   17067  * error code if not and -1 if an internal error occurred.
   17068  */
   17069 static int
   17070 xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
   17071 				  xmlSchemaParticlePtr r,
   17072 				  xmlSchemaParticlePtr b)
   17073 {
   17074     int ret = 0;
   17075 
   17076     /*part = WXS_TYPE_PARTICLE(type);
   17077     basePart = WXS_TYPE_PARTICLE(base);
   17078     */
   17079 
   17080     TODO
   17081 
   17082     /*
   17083     * SPEC (1) "They are the same particle."
   17084     */
   17085     if (r == b)
   17086 	return (0);
   17087 
   17088 
   17089     return (0);
   17090 }
   17091 
   17092 #if 0
   17093 /**
   17094  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
   17095  * @ctxt:  the schema parser context
   17096  * @r: the model group particle
   17097  * @b: the base wildcard particle
   17098  *
   17099  * (3.9.6) Constraints on Particle Schema Components
   17100  * Schema Component Constraint:
   17101  * Particle Derivation OK (All/Choice/Sequence:Any --
   17102  *                         NSRecurseCheckCardinality)
   17103  * (rcase-NSRecurseCheckCardinality)
   17104  *
   17105  * STATUS: TODO: subst-groups
   17106  *
   17107  * Returns 0 if the constraints are satisfied, a positive
   17108  * error code if not and -1 if an internal error occurred.
   17109  */
   17110 static int
   17111 xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
   17112 					     xmlSchemaParticlePtr r,
   17113 					     xmlSchemaParticlePtr b)
   17114 {
   17115     xmlSchemaParticlePtr part;
   17116     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
   17117     if ((r->children == NULL) || (r->children->children == NULL))
   17118 	return (-1);
   17119     /*
   17120     * SPEC "For a group particle to be a `valid restriction` of a
   17121     * wildcard particle..."
   17122     *
   17123     * SPEC (1) "Every member of the {particles} of the group is a `valid
   17124     * restriction` of the wildcard as defined by
   17125     * Particle Valid (Restriction) ($3.9.6)."
   17126     */
   17127     part = (xmlSchemaParticlePtr) r->children->children;
   17128     do {
   17129 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
   17130 	    return (1);
   17131 	part = (xmlSchemaParticlePtr) part->next;
   17132     } while (part != NULL);
   17133     /*
   17134     * SPEC (2) "The effective total range of the group [...] is a
   17135     * valid restriction of B's occurrence range as defined by
   17136     * Occurrence Range OK ($3.9.6)."
   17137     */
   17138     if (xmlSchemaCheckParticleRangeOK(
   17139 	    xmlSchemaGetParticleTotalRangeMin(r),
   17140 	    xmlSchemaGetParticleTotalRangeMax(r),
   17141 	    b->minOccurs, b->maxOccurs) != 0)
   17142 	return (1);
   17143     return (0);
   17144 }
   17145 #endif
   17146 
   17147 /**
   17148  * xmlSchemaCheckRCaseRecurse:
   17149  * @ctxt:  the schema parser context
   17150  * @r: the <all> or <sequence> model group particle
   17151  * @b: the base <all> or <sequence> model group particle
   17152  *
   17153  * (3.9.6) Constraints on Particle Schema Components
   17154  * Schema Component Constraint:
   17155  * Particle Derivation OK (All:All,Sequence:Sequence --
   17156                            Recurse)
   17157  * (rcase-Recurse)
   17158  *
   17159  * STATUS:  ?
   17160  * TODO: subst-groups
   17161  *
   17162  * Returns 0 if the constraints are satisfied, a positive
   17163  * error code if not and -1 if an internal error occurred.
   17164  */
   17165 static int
   17166 xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
   17167 			   xmlSchemaParticlePtr r,
   17168 			   xmlSchemaParticlePtr b)
   17169 {
   17170     /* xmlSchemaParticlePtr part; */
   17171     /* TODO: Error codes (rcase-Recurse). */
   17172     if ((r->children == NULL) || (b->children == NULL) ||
   17173 	(r->children->type != b->children->type))
   17174 	return (-1);
   17175     /*
   17176     * SPEC "For an all or sequence group particle to be a `valid
   17177     * restriction` of another group particle with the same {compositor}..."
   17178     *
   17179     * SPEC (1) "R's occurrence range is a valid restriction of B's
   17180     * occurrence range as defined by Occurrence Range OK ($3.9.6)."
   17181     */
   17182     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
   17183 	    b->minOccurs, b->maxOccurs))
   17184 	return (1);
   17185 
   17186 
   17187     return (0);
   17188 }
   17189 
   17190 #endif
   17191 
   17192 #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
   17193     xmlSchemaPCustomErrExt(pctxt,      \
   17194 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17195 	WXS_BASIC_CAST fac1, fac1->node, \
   17196 	"It is an error for both '%s' and '%s' to be specified on the "\
   17197 	"same type definition", \
   17198 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
   17199 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
   17200 
   17201 #define FACET_RESTR_ERR(fac1, msg) \
   17202     xmlSchemaPCustomErr(pctxt,      \
   17203 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17204 	WXS_BASIC_CAST fac1, fac1->node, \
   17205 	msg, NULL);
   17206 
   17207 #define FACET_RESTR_FIXED_ERR(fac) \
   17208     xmlSchemaPCustomErr(pctxt, \
   17209 	XML_SCHEMAP_INVALID_FACET_VALUE, \
   17210 	WXS_BASIC_CAST fac, fac->node, \
   17211 	"The base type's facet is 'fixed', thus the value must not " \
   17212 	"differ", NULL);
   17213 
   17214 static void
   17215 xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
   17216 			xmlSchemaFacetPtr facet1,
   17217 			xmlSchemaFacetPtr facet2,
   17218 			int lessGreater,
   17219 			int orEqual,
   17220 			int ofBase)
   17221 {
   17222     xmlChar *msg = NULL;
   17223 
   17224     msg = xmlStrdup(BAD_CAST "'");
   17225     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
   17226     msg = xmlStrcat(msg, BAD_CAST "' has to be");
   17227     if (lessGreater == 0)
   17228 	msg = xmlStrcat(msg, BAD_CAST " equal to");
   17229     if (lessGreater == 1)
   17230 	msg = xmlStrcat(msg, BAD_CAST " greater than");
   17231     else
   17232 	msg = xmlStrcat(msg, BAD_CAST " less than");
   17233 
   17234     if (orEqual)
   17235 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
   17236     msg = xmlStrcat(msg, BAD_CAST " '");
   17237     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
   17238     if (ofBase)
   17239 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
   17240     else
   17241 	msg = xmlStrcat(msg, BAD_CAST "'");
   17242 
   17243     xmlSchemaPCustomErr(pctxt,
   17244 	XML_SCHEMAP_INVALID_FACET_VALUE,
   17245 	WXS_BASIC_CAST facet1, NULL,
   17246 	(const char *) msg, NULL);
   17247 
   17248     if (msg != NULL)
   17249 	xmlFree(msg);
   17250 }
   17251 
   17252 /*
   17253 * xmlSchemaDeriveAndValidateFacets:
   17254 *
   17255 * Schema Component Constraint: Simple Type Restriction (Facets)
   17256 * (st-restrict-facets)
   17257 */
   17258 static int
   17259 xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
   17260 				 xmlSchemaTypePtr type)
   17261 {
   17262     xmlSchemaTypePtr base = type->baseType;
   17263     xmlSchemaFacetLinkPtr link, cur, last = NULL;
   17264     xmlSchemaFacetPtr facet, bfacet,
   17265 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
   17266 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
   17267 	fmininc = NULL, fmaxinc = NULL,
   17268 	fminexc = NULL, fmaxexc = NULL,
   17269 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
   17270 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
   17271 	bfmininc = NULL, bfmaxinc = NULL,
   17272 	bfminexc = NULL, bfmaxexc = NULL;
   17273     int res; /* err = 0, fixedErr; */
   17274 
   17275     /*
   17276     * SPEC st-restrict-facets 1:
   17277     * "The {variety} of R is the same as that of B."
   17278     */
   17279     /*
   17280     * SPEC st-restrict-facets 2:
   17281     * "If {variety} is atomic, the {primitive type definition}
   17282     * of R is the same as that of B."
   17283     *
   17284     * NOTE: we leave 1 & 2 out for now, since this will be
   17285     * satisfied by the derivation process.
   17286     * CONSTRUCTION TODO: Maybe needed if using a construction API.
   17287     */
   17288     /*
   17289     * SPEC st-restrict-facets 3:
   17290     * "The {facets} of R are the union of S and the {facets}
   17291     * of B, eliminating duplicates. To eliminate duplicates,
   17292     * when a facet of the same kind occurs in both S and the
   17293     * {facets} of B, the one in the {facets} of B is not
   17294     * included, with the exception of enumeration and pattern
   17295     * facets, for which multiple occurrences with distinct values
   17296     * are allowed."
   17297     */
   17298 
   17299     if ((type->facetSet == NULL) && (base->facetSet == NULL))
   17300 	return (0);
   17301 
   17302     last = type->facetSet;
   17303     if (last != NULL)
   17304 	while (last->next != NULL)
   17305 	    last = last->next;
   17306 
   17307     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
   17308 	facet = cur->facet;
   17309 	switch (facet->type) {
   17310 	    case XML_SCHEMA_FACET_LENGTH:
   17311 		flength = facet; break;
   17312 	    case XML_SCHEMA_FACET_MINLENGTH:
   17313 		fminlen = facet; break;
   17314 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17315 		fmininc = facet; break;
   17316 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17317 		fminexc = facet; break;
   17318 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17319 		fmaxlen = facet; break;
   17320 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17321 		fmaxinc = facet; break;
   17322 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17323 		fmaxexc = facet; break;
   17324 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17325 		ftotdig = facet; break;
   17326 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17327 		ffracdig = facet; break;
   17328 	    default:
   17329 		break;
   17330 	}
   17331     }
   17332     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17333 	facet = cur->facet;
   17334 	switch (facet->type) {
   17335 	    case XML_SCHEMA_FACET_LENGTH:
   17336 		bflength = facet; break;
   17337 	    case XML_SCHEMA_FACET_MINLENGTH:
   17338 		bfminlen = facet; break;
   17339 	    case XML_SCHEMA_FACET_MININCLUSIVE:
   17340 		bfmininc = facet; break;
   17341 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
   17342 		bfminexc = facet; break;
   17343 	    case XML_SCHEMA_FACET_MAXLENGTH:
   17344 		bfmaxlen = facet; break;
   17345 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
   17346 		bfmaxinc = facet; break;
   17347 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   17348 		bfmaxexc = facet; break;
   17349 	    case XML_SCHEMA_FACET_TOTALDIGITS:
   17350 		bftotdig = facet; break;
   17351 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
   17352 		bffracdig = facet; break;
   17353 	    default:
   17354 		break;
   17355 	}
   17356     }
   17357     /*
   17358     * length and minLength or maxLength (2.2) + (3.2)
   17359     */
   17360     if (flength && (fminlen || fmaxlen)) {
   17361 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
   17362 	    "either of 'minLength' or 'maxLength' to be specified on "
   17363 	    "the same type definition")
   17364     }
   17365     /*
   17366     * Mutual exclusions in the same derivation step.
   17367     */
   17368     if ((fmaxinc) && (fmaxexc)) {
   17369 	/*
   17370 	* SCC "maxInclusive and maxExclusive"
   17371 	*/
   17372 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
   17373     }
   17374     if ((fmininc) && (fminexc)) {
   17375 	/*
   17376 	* SCC "minInclusive and minExclusive"
   17377 	*/
   17378 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
   17379     }
   17380 
   17381     if (flength && bflength) {
   17382 	/*
   17383 	* SCC "length valid restriction"
   17384 	* The values have to be equal.
   17385 	*/
   17386 	res = xmlSchemaCompareValues(flength->val, bflength->val);
   17387 	if (res == -2)
   17388 	    goto internal_error;
   17389 	if (res != 0)
   17390 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
   17391 	if ((res != 0) && (bflength->fixed)) {
   17392 	    FACET_RESTR_FIXED_ERR(flength)
   17393 	}
   17394 
   17395     }
   17396     if (fminlen && bfminlen) {
   17397 	/*
   17398 	* SCC "minLength valid restriction"
   17399 	* minLength >= BASE minLength
   17400 	*/
   17401 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
   17402 	if (res == -2)
   17403 	    goto internal_error;
   17404 	if (res == -1)
   17405 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
   17406 	if ((res != 0) && (bfminlen->fixed)) {
   17407 	    FACET_RESTR_FIXED_ERR(fminlen)
   17408 	}
   17409     }
   17410     if (fmaxlen && bfmaxlen) {
   17411 	/*
   17412 	* SCC "maxLength valid restriction"
   17413 	* maxLength <= BASE minLength
   17414 	*/
   17415 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
   17416 	if (res == -2)
   17417 	    goto internal_error;
   17418 	if (res == 1)
   17419 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
   17420 	if ((res != 0) && (bfmaxlen->fixed)) {
   17421 	    FACET_RESTR_FIXED_ERR(fmaxlen)
   17422 	}
   17423     }
   17424     /*
   17425     * SCC "length and minLength or maxLength"
   17426     */
   17427     if (! flength)
   17428 	flength = bflength;
   17429     if (flength) {
   17430 	if (! fminlen)
   17431 	    fminlen = bfminlen;
   17432 	if (fminlen) {
   17433 	    /* (1.1) length >= minLength */
   17434 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
   17435 	    if (res == -2)
   17436 		goto internal_error;
   17437 	    if (res == -1)
   17438 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
   17439 	}
   17440 	if (! fmaxlen)
   17441 	    fmaxlen = bfmaxlen;
   17442 	if (fmaxlen) {
   17443 	    /* (2.1) length <= maxLength */
   17444 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
   17445 	    if (res == -2)
   17446 		goto internal_error;
   17447 	    if (res == 1)
   17448 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
   17449 	}
   17450     }
   17451     if (fmaxinc) {
   17452 	/*
   17453 	* "maxInclusive"
   17454 	*/
   17455 	if (fmininc) {
   17456 	    /* SCC "maxInclusive >= minInclusive" */
   17457 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
   17458 	    if (res == -2)
   17459 		goto internal_error;
   17460 	    if (res == -1) {
   17461 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
   17462 	    }
   17463 	}
   17464 	/*
   17465 	* SCC "maxInclusive valid restriction"
   17466 	*/
   17467 	if (bfmaxinc) {
   17468 	    /* maxInclusive <= BASE maxInclusive */
   17469 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
   17470 	    if (res == -2)
   17471 		goto internal_error;
   17472 	    if (res == 1)
   17473 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
   17474 	    if ((res != 0) && (bfmaxinc->fixed)) {
   17475 		FACET_RESTR_FIXED_ERR(fmaxinc)
   17476 	    }
   17477 	}
   17478 	if (bfmaxexc) {
   17479 	    /* maxInclusive < BASE maxExclusive */
   17480 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
   17481 	    if (res == -2)
   17482 		goto internal_error;
   17483 	    if (res != -1) {
   17484 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
   17485 	    }
   17486 	}
   17487 	if (bfmininc) {
   17488 	    /* maxInclusive >= BASE minInclusive */
   17489 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
   17490 	    if (res == -2)
   17491 		goto internal_error;
   17492 	    if (res == -1) {
   17493 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
   17494 	    }
   17495 	}
   17496 	if (bfminexc) {
   17497 	    /* maxInclusive > BASE minExclusive */
   17498 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
   17499 	    if (res == -2)
   17500 		goto internal_error;
   17501 	    if (res != 1) {
   17502 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
   17503 	    }
   17504 	}
   17505     }
   17506     if (fmaxexc) {
   17507 	/*
   17508 	* "maxExclusive >= minExclusive"
   17509 	*/
   17510 	if (fminexc) {
   17511 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
   17512 	    if (res == -2)
   17513 		goto internal_error;
   17514 	    if (res == -1) {
   17515 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
   17516 	    }
   17517 	}
   17518 	/*
   17519 	* "maxExclusive valid restriction"
   17520 	*/
   17521 	if (bfmaxexc) {
   17522 	    /* maxExclusive <= BASE maxExclusive */
   17523 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
   17524 	    if (res == -2)
   17525 		goto internal_error;
   17526 	    if (res == 1) {
   17527 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
   17528 	    }
   17529 	    if ((res != 0) && (bfmaxexc->fixed)) {
   17530 		FACET_RESTR_FIXED_ERR(fmaxexc)
   17531 	    }
   17532 	}
   17533 	if (bfmaxinc) {
   17534 	    /* maxExclusive <= BASE maxInclusive */
   17535 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
   17536 	    if (res == -2)
   17537 		goto internal_error;
   17538 	    if (res == 1) {
   17539 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
   17540 	    }
   17541 	}
   17542 	if (bfmininc) {
   17543 	    /* maxExclusive > BASE minInclusive */
   17544 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
   17545 	    if (res == -2)
   17546 		goto internal_error;
   17547 	    if (res != 1) {
   17548 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
   17549 	    }
   17550 	}
   17551 	if (bfminexc) {
   17552 	    /* maxExclusive > BASE minExclusive */
   17553 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
   17554 	    if (res == -2)
   17555 		goto internal_error;
   17556 	    if (res != 1) {
   17557 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
   17558 	    }
   17559 	}
   17560     }
   17561     if (fminexc) {
   17562 	/*
   17563 	* "minExclusive < maxInclusive"
   17564 	*/
   17565 	if (fmaxinc) {
   17566 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
   17567 	    if (res == -2)
   17568 		goto internal_error;
   17569 	    if (res != -1) {
   17570 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
   17571 	    }
   17572 	}
   17573 	/*
   17574 	* "minExclusive valid restriction"
   17575 	*/
   17576 	if (bfminexc) {
   17577 	    /* minExclusive >= BASE minExclusive */
   17578 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
   17579 	    if (res == -2)
   17580 		goto internal_error;
   17581 	    if (res == -1) {
   17582 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
   17583 	    }
   17584 	    if ((res != 0) && (bfminexc->fixed)) {
   17585 		FACET_RESTR_FIXED_ERR(fminexc)
   17586 	    }
   17587 	}
   17588 	if (bfmaxinc) {
   17589 	    /* minExclusive <= BASE maxInclusive */
   17590 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
   17591 	    if (res == -2)
   17592 		goto internal_error;
   17593 	    if (res == 1) {
   17594 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
   17595 	    }
   17596 	}
   17597 	if (bfmininc) {
   17598 	    /* minExclusive >= BASE minInclusive */
   17599 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
   17600 	    if (res == -2)
   17601 		goto internal_error;
   17602 	    if (res == -1) {
   17603 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
   17604 	    }
   17605 	}
   17606 	if (bfmaxexc) {
   17607 	    /* minExclusive < BASE maxExclusive */
   17608 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
   17609 	    if (res == -2)
   17610 		goto internal_error;
   17611 	    if (res != -1) {
   17612 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
   17613 	    }
   17614 	}
   17615     }
   17616     if (fmininc) {
   17617 	/*
   17618 	* "minInclusive < maxExclusive"
   17619 	*/
   17620 	if (fmaxexc) {
   17621 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
   17622 	    if (res == -2)
   17623 		goto internal_error;
   17624 	    if (res != -1) {
   17625 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
   17626 	    }
   17627 	}
   17628 	/*
   17629 	* "minExclusive valid restriction"
   17630 	*/
   17631 	if (bfmininc) {
   17632 	    /* minInclusive >= BASE minInclusive */
   17633 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
   17634 	    if (res == -2)
   17635 		goto internal_error;
   17636 	    if (res == -1) {
   17637 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
   17638 	    }
   17639 	    if ((res != 0) && (bfmininc->fixed)) {
   17640 		FACET_RESTR_FIXED_ERR(fmininc)
   17641 	    }
   17642 	}
   17643 	if (bfmaxinc) {
   17644 	    /* minInclusive <= BASE maxInclusive */
   17645 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
   17646 	    if (res == -2)
   17647 		goto internal_error;
   17648 	    if (res == 1) {
   17649 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
   17650 	    }
   17651 	}
   17652 	if (bfminexc) {
   17653 	    /* minInclusive > BASE minExclusive */
   17654 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
   17655 	    if (res == -2)
   17656 		goto internal_error;
   17657 	    if (res != 1)
   17658 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
   17659 	}
   17660 	if (bfmaxexc) {
   17661 	    /* minInclusive < BASE maxExclusive */
   17662 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
   17663 	    if (res == -2)
   17664 		goto internal_error;
   17665 	    if (res != -1)
   17666 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
   17667 	}
   17668     }
   17669     if (ftotdig && bftotdig) {
   17670 	/*
   17671 	* SCC " totalDigits valid restriction"
   17672 	* totalDigits <= BASE totalDigits
   17673 	*/
   17674 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
   17675 	if (res == -2)
   17676 	    goto internal_error;
   17677 	if (res == 1)
   17678 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
   17679 	    -1, 1, 1);
   17680 	if ((res != 0) && (bftotdig->fixed)) {
   17681 	    FACET_RESTR_FIXED_ERR(ftotdig)
   17682 	}
   17683     }
   17684     if (ffracdig && bffracdig) {
   17685 	/*
   17686 	* SCC  "fractionDigits valid restriction"
   17687 	* fractionDigits <= BASE fractionDigits
   17688 	*/
   17689 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
   17690 	if (res == -2)
   17691 	    goto internal_error;
   17692 	if (res == 1)
   17693 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
   17694 	    -1, 1, 1);
   17695 	if ((res != 0) && (bffracdig->fixed)) {
   17696 	    FACET_RESTR_FIXED_ERR(ffracdig)
   17697 	}
   17698     }
   17699     /*
   17700     * SCC "fractionDigits less than or equal to totalDigits"
   17701     */
   17702     if (! ftotdig)
   17703 	ftotdig = bftotdig;
   17704     if (! ffracdig)
   17705 	ffracdig = bffracdig;
   17706     if (ftotdig && ffracdig) {
   17707 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
   17708 	if (res == -2)
   17709 	    goto internal_error;
   17710 	if (res == 1)
   17711 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
   17712 		-1, 1, 0);
   17713     }
   17714     /*
   17715     * *Enumerations* won' be added here, since only the first set
   17716     * of enumerations in the ancestor-or-self axis is used
   17717     * for validation, plus we need to use the base type of those
   17718     * enumerations for whitespace.
   17719     *
   17720     * *Patterns*: won't be add here, since they are ORed at
   17721     * type level and ANDed at ancestor level. This will
   17722     * happed during validation by walking the base axis
   17723     * of the type.
   17724     */
   17725     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
   17726 	bfacet = cur->facet;
   17727 	/*
   17728 	* Special handling of enumerations and patterns.
   17729 	* TODO: hmm, they should not appear in the set, so remove this.
   17730 	*/
   17731 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
   17732 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
   17733 	    continue;
   17734 	/*
   17735 	* Search for a duplicate facet in the current type.
   17736 	*/
   17737 	link = type->facetSet;
   17738 	/* err = 0; */
   17739 	/* fixedErr = 0; */
   17740 	while (link != NULL) {
   17741 	    facet = link->facet;
   17742 	    if (facet->type == bfacet->type) {
   17743 		switch (facet->type) {
   17744 		    case XML_SCHEMA_FACET_WHITESPACE:
   17745 			/*
   17746 			* The whitespace must be stronger.
   17747 			*/
   17748 			if (facet->whitespace < bfacet->whitespace) {
   17749 			    FACET_RESTR_ERR(facet,
   17750 				"The 'whitespace' value has to be equal to "
   17751 				"or stronger than the 'whitespace' value of "
   17752 				"the base type")
   17753 			}
   17754 			if ((bfacet->fixed) &&
   17755 			    (facet->whitespace != bfacet->whitespace)) {
   17756 			    FACET_RESTR_FIXED_ERR(facet)
   17757 			}
   17758 			break;
   17759 		    default:
   17760 			break;
   17761 		}
   17762 		/* Duplicate found. */
   17763 		break;
   17764 	    }
   17765 	    link = link->next;
   17766 	}
   17767 	/*
   17768 	* If no duplicate was found: add the base types's facet
   17769 	* to the set.
   17770 	*/
   17771 	if (link == NULL) {
   17772 	    link = (xmlSchemaFacetLinkPtr)
   17773 		xmlMalloc(sizeof(xmlSchemaFacetLink));
   17774 	    if (link == NULL) {
   17775 		xmlSchemaPErrMemory(pctxt,
   17776 		    "deriving facets, creating a facet link", NULL);
   17777 		return (-1);
   17778 	    }
   17779 	    link->facet = cur->facet;
   17780 	    link->next = NULL;
   17781 	    if (last == NULL)
   17782 		type->facetSet = link;
   17783 	    else
   17784 		last->next = link;
   17785 	    last = link;
   17786 	}
   17787 
   17788     }
   17789 
   17790     return (0);
   17791 internal_error:
   17792     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
   17793 	"an error occurred");
   17794     return (-1);
   17795 }
   17796 
   17797 static int
   17798 xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
   17799 					     xmlSchemaTypePtr type)
   17800 {
   17801     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
   17802     /*
   17803     * The actual value is then formed by replacing any union type
   17804     * definition in the `explicit members` with the members of their
   17805     * {member type definitions}, in order.
   17806     *
   17807     * TODO: There's a bug entry at
   17808     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
   17809     * which indicates that we'll keep the union types the future.
   17810     */
   17811     link = type->memberTypes;
   17812     while (link != NULL) {
   17813 
   17814 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
   17815 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
   17816 
   17817 	if (WXS_IS_UNION(link->type)) {
   17818 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
   17819 	    if (subLink != NULL) {
   17820 		link->type = subLink->type;
   17821 		if (subLink->next != NULL) {
   17822 		    lastLink = link->next;
   17823 		    subLink = subLink->next;
   17824 		    prevLink = link;
   17825 		    while (subLink != NULL) {
   17826 			newLink = (xmlSchemaTypeLinkPtr)
   17827 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
   17828 			if (newLink == NULL) {
   17829 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
   17830 				NULL);
   17831 			    return (-1);
   17832 			}
   17833 			newLink->type = subLink->type;
   17834 			prevLink->next = newLink;
   17835 			prevLink = newLink;
   17836 			newLink->next = lastLink;
   17837 
   17838 			subLink = subLink->next;
   17839 		    }
   17840 		}
   17841 	    }
   17842 	}
   17843 	link = link->next;
   17844     }
   17845     return (0);
   17846 }
   17847 
   17848 static void
   17849 xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
   17850 {
   17851     int has = 0, needVal = 0, normVal = 0;
   17852 
   17853     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
   17854     if (has) {
   17855 	needVal = (type->baseType->flags &
   17856 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
   17857 	normVal = (type->baseType->flags &
   17858 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
   17859     }
   17860     if (type->facets != NULL) {
   17861 	xmlSchemaFacetPtr fac;
   17862 
   17863 	for (fac = type->facets; fac != NULL; fac = fac->next) {
   17864 	    switch (fac->type) {
   17865 		case XML_SCHEMA_FACET_WHITESPACE:
   17866 		    break;
   17867 		case XML_SCHEMA_FACET_PATTERN:
   17868 		    normVal = 1;
   17869 		    has = 1;
   17870 		    break;
   17871 		case XML_SCHEMA_FACET_ENUMERATION:
   17872 		    needVal = 1;
   17873 		    normVal = 1;
   17874 		    has = 1;
   17875 		    break;
   17876 		default:
   17877 		    has = 1;
   17878 		    break;
   17879 	    }
   17880 	}
   17881     }
   17882     if (normVal)
   17883 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
   17884     if (needVal)
   17885 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17886     if (has)
   17887 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
   17888 
   17889     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
   17890 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
   17891 	/*
   17892 	* OPTIMIZE VAL TODO: Some facets need a computed value.
   17893 	*/
   17894 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
   17895 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
   17896 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
   17897 	}
   17898     }
   17899 }
   17900 
   17901 static int
   17902 xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
   17903 {
   17904 
   17905 
   17906     /*
   17907     * Evaluate the whitespace-facet value.
   17908     */
   17909     if (WXS_IS_LIST(type)) {
   17910 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17911 	return (0);
   17912     } else if (WXS_IS_UNION(type))
   17913 	return (0);
   17914 
   17915     if (type->facetSet != NULL) {
   17916 	xmlSchemaFacetLinkPtr lin;
   17917 
   17918 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
   17919 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
   17920 		switch (lin->facet->whitespace) {
   17921 		case XML_SCHEMAS_FACET_PRESERVE:
   17922 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17923 		    break;
   17924 		case XML_SCHEMAS_FACET_REPLACE:
   17925 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17926 		    break;
   17927 		case XML_SCHEMAS_FACET_COLLAPSE:
   17928 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17929 		    break;
   17930 		default:
   17931 		    return (-1);
   17932 		}
   17933 		return (0);
   17934 	    }
   17935 	}
   17936     }
   17937     /*
   17938     * For all `atomic` datatypes other than string (and types `derived`
   17939     * by `restriction` from it) the value of whiteSpace is fixed to
   17940     * collapse
   17941     */
   17942     {
   17943 	xmlSchemaTypePtr anc;
   17944 
   17945 	for (anc = type->baseType; anc != NULL &&
   17946 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
   17947 		anc = anc->baseType) {
   17948 
   17949 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
   17950 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
   17951 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
   17952 
   17953 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
   17954 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
   17955 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
   17956 
   17957 		} else
   17958 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
   17959 		break;
   17960 	    }
   17961 	}
   17962     }
   17963     return (0);
   17964 }
   17965 
   17966 static int
   17967 xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
   17968 			  xmlSchemaTypePtr type)
   17969 {
   17970     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   17971 	return(0);
   17972     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
   17973 	return(0);
   17974     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
   17975 
   17976     if (WXS_IS_LIST(type)) {
   17977 	/*
   17978 	* Corresponds to <simpleType><list>...
   17979 	*/
   17980 	if (type->subtypes == NULL) {
   17981 	    /*
   17982 	    * This one is really needed, so get out.
   17983 	    */
   17984 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17985 		"list type has no item-type assigned");
   17986 	    return(-1);
   17987 	}
   17988     } else if (WXS_IS_UNION(type)) {
   17989 	/*
   17990 	* Corresponds to <simpleType><union>...
   17991 	*/
   17992 	if (type->memberTypes == NULL) {
   17993 	    /*
   17994 	    * This one is really needed, so get out.
   17995 	    */
   17996 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   17997 		"union type has no member-types assigned");
   17998 	    return(-1);
   17999 	}
   18000     } else {
   18001 	/*
   18002 	* Corresponds to <simpleType><restriction>...
   18003 	*/
   18004 	if (type->baseType == NULL) {
   18005 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
   18006 		"type has no base-type assigned");
   18007 	    return(-1);
   18008 	}
   18009 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
   18010 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
   18011 		return(-1);
   18012 	/*
   18013 	* Variety
   18014 	* If the <restriction> alternative is chosen, then the
   18015 	* {variety} of the {base type definition}.
   18016 	*/
   18017 	if (WXS_IS_ATOMIC(type->baseType))
   18018 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
   18019 	else if (WXS_IS_LIST(type->baseType)) {
   18020 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
   18021 	    /*
   18022 	    * Inherit the itemType.
   18023 	    */
   18024 	    type->subtypes = type->baseType->subtypes;
   18025 	} else if (WXS_IS_UNION(type->baseType)) {
   18026 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
   18027 	    /*
   18028 	    * NOTE that we won't assign the memberTypes of the base,
   18029 	    * since this will make trouble when freeing them; we will
   18030 	    * use a lookup function to access them instead.
   18031 	    */
   18032 	}
   18033     }
   18034     return(0);
   18035 }
   18036 
   18037 #ifdef DEBUG_TYPE
   18038 static void
   18039 xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
   18040 		       xmlSchemaTypePtr type)
   18041 {
   18042     if (type->node != NULL) {
   18043         xmlGenericError(xmlGenericErrorContext,
   18044                         "Type of %s : %s:%d :", name,
   18045                         type->node->doc->URL,
   18046                         xmlGetLineNo(type->node));
   18047     } else {
   18048         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
   18049     }
   18050     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
   18051 	switch (type->contentType) {
   18052 	    case XML_SCHEMA_CONTENT_SIMPLE:
   18053 		xmlGenericError(xmlGenericErrorContext, "simple\n");
   18054 		break;
   18055 	    case XML_SCHEMA_CONTENT_ELEMENTS:
   18056 		xmlGenericError(xmlGenericErrorContext, "elements\n");
   18057 		break;
   18058 	    case XML_SCHEMA_CONTENT_UNKNOWN:
   18059 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
   18060 		break;
   18061 	    case XML_SCHEMA_CONTENT_EMPTY:
   18062 		xmlGenericError(xmlGenericErrorContext, "empty\n");
   18063 		break;
   18064 	    case XML_SCHEMA_CONTENT_MIXED:
   18065 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
   18066 		    type->subtypes))
   18067 		    xmlGenericError(xmlGenericErrorContext,
   18068 			"mixed as emptiable particle\n");
   18069 		else
   18070 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
   18071 		break;
   18072 		/* Removed, since not used. */
   18073 		/*
   18074 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
   18075 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
   18076 		break;
   18077 		*/
   18078 	    case XML_SCHEMA_CONTENT_BASIC:
   18079 		xmlGenericError(xmlGenericErrorContext, "basic\n");
   18080 		break;
   18081 	    default:
   18082 		xmlGenericError(xmlGenericErrorContext,
   18083 		    "not registered !!!\n");
   18084 		break;
   18085 	}
   18086     }
   18087 }
   18088 #endif
   18089 
   18090 /*
   18091 * 3.14.6 Constraints on Simple Type Definition Schema Components
   18092 */
   18093 static int
   18094 xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
   18095 				 xmlSchemaTypePtr type)
   18096 {
   18097     int res, olderrs = pctxt->nberrors;
   18098 
   18099     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
   18100 	return(-1);
   18101 
   18102     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18103 	return(0);
   18104 
   18105     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18106     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
   18107 
   18108     if (type->baseType == NULL) {
   18109 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
   18110 	    "missing baseType");
   18111 	goto exit_failure;
   18112     }
   18113     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
   18114 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
   18115     /*
   18116     * If a member type of a union is a union itself, we need to substitute
   18117     * that member type for its member types.
   18118     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
   18119     * types in WXS 1.1.
   18120     */
   18121     if ((type->memberTypes != NULL) &&
   18122 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
   18123 	return(-1);
   18124     /*
   18125     * SPEC src-simple-type 1
   18126     * "The corresponding simple type definition, if any, must satisfy
   18127     * the conditions set out in Constraints on Simple Type Definition
   18128     * Schema Components ($3.14.6)."
   18129     */
   18130     /*
   18131     * Schema Component Constraint: Simple Type Definition Properties Correct
   18132     * (st-props-correct)
   18133     */
   18134     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
   18135     HFAILURE HERROR
   18136     /*
   18137     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
   18138     * (cos-st-restricts)
   18139     */
   18140     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
   18141     HFAILURE HERROR
   18142     /*
   18143     * TODO: Removed the error report, since it got annoying to get an
   18144     * extra error report, if anything failed until now.
   18145     * Enable this if needed.
   18146     *
   18147     * xmlSchemaPErr(ctxt, type->node,
   18148     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
   18149     *    "Simple type '%s' does not satisfy the constraints "
   18150     *    "on simple type definitions.\n",
   18151     *    type->name, NULL);
   18152     */
   18153     /*
   18154     * Schema Component Constraint: Simple Type Restriction (Facets)
   18155     * (st-restrict-facets)
   18156     */
   18157     res = xmlSchemaCheckFacetValues(type, pctxt);
   18158     HFAILURE HERROR
   18159     if ((type->facetSet != NULL) ||
   18160 	(type->baseType->facetSet != NULL)) {
   18161 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
   18162 	HFAILURE HERROR
   18163     }
   18164     /*
   18165     * Whitespace value.
   18166     */
   18167     res = xmlSchemaTypeFixupWhitespace(type);
   18168     HFAILURE HERROR
   18169     xmlSchemaTypeFixupOptimFacets(type);
   18170 
   18171 exit_error:
   18172 #ifdef DEBUG_TYPE
   18173     xmlSchemaDebugFixedType(pctxt, type);
   18174 #endif
   18175     if (olderrs != pctxt->nberrors)
   18176 	return(pctxt->err);
   18177     return(0);
   18178 
   18179 exit_failure:
   18180 #ifdef DEBUG_TYPE
   18181     xmlSchemaDebugFixedType(pctxt, type);
   18182 #endif
   18183     return(-1);
   18184 }
   18185 
   18186 static int
   18187 xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
   18188 			  xmlSchemaTypePtr type)
   18189 {
   18190     int res = 0, olderrs = pctxt->nberrors;
   18191     xmlSchemaTypePtr baseType = type->baseType;
   18192 
   18193     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18194 	return(0);
   18195     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
   18196     if (baseType == NULL) {
   18197 	PERROR_INT("xmlSchemaFixupComplexType",
   18198 	    "missing baseType");
   18199 	goto exit_failure;
   18200     }
   18201     /*
   18202     * Fixup the base type.
   18203     */
   18204     if (WXS_IS_TYPE_NOT_FIXED(baseType))
   18205 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
   18206     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
   18207 	/*
   18208 	* Skip fixup if the base type is invalid.
   18209 	* TODO: Generate a warning!
   18210 	*/
   18211 	return(0);
   18212     }
   18213     /*
   18214     * This basically checks if the base type can be derived.
   18215     */
   18216     res = xmlSchemaCheckSRCCT(pctxt, type);
   18217     HFAILURE HERROR
   18218     /*
   18219     * Fixup the content type.
   18220     */
   18221     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
   18222 	/*
   18223 	* Corresponds to <complexType><simpleContent>...
   18224 	*/
   18225 	if ((WXS_IS_COMPLEX(baseType)) &&
   18226 	    (baseType->contentTypeDef != NULL) &&
   18227 	    (WXS_IS_RESTRICTION(type))) {
   18228 	    xmlSchemaTypePtr contentBase, content;
   18229 #ifdef ENABLE_NAMED_LOCALS
   18230 	    char buf[30];
   18231 	    const xmlChar *tmpname;
   18232 #endif
   18233 	    /*
   18234 	    * SPEC (1) If <restriction> + base type is <complexType>,
   18235 	    * "whose own {content type} is a simple type..."
   18236 	    */
   18237 	    if (type->contentTypeDef != NULL) {
   18238 		/*
   18239 		* SPEC (1.1) "the simple type definition corresponding to the
   18240 		* <simpleType> among the [children] of <restriction> if there
   18241 		* is one;"
   18242 		* Note that this "<simpleType> among the [children]" was put
   18243 		* into ->contentTypeDef during parsing.
   18244 		*/
   18245 		contentBase = type->contentTypeDef;
   18246 		type->contentTypeDef = NULL;
   18247 	    } else {
   18248 		/*
   18249 		* (1.2) "...otherwise (<restriction> has no <simpleType>
   18250 		* among its [children]), the simple type definition which
   18251 		* is the {content type} of the ... base type."
   18252 		*/
   18253 		contentBase = baseType->contentTypeDef;
   18254 	    }
   18255 	    /*
   18256 	    * SPEC
   18257 	    * "... a simple type definition which restricts the simple
   18258 	    * type definition identified in clause 1.1 or clause 1.2
   18259 	    * with a set of facet components"
   18260 	    *
   18261 	    * Create the anonymous simple type, which will be the content
   18262 	    * type of the complex type.
   18263 	    */
   18264 #ifdef ENABLE_NAMED_LOCALS
   18265 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
   18266 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
   18267 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18268 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
   18269 		type->node, 0);
   18270 #else
   18271 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
   18272 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
   18273 		type->node, 0);
   18274 #endif
   18275 	    if (content == NULL)
   18276 		goto exit_failure;
   18277 	    /*
   18278 	    * We will use the same node as for the <complexType>
   18279 	    * to have it somehow anchored in the schema doc.
   18280 	    */
   18281 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
   18282 	    content->baseType = contentBase;
   18283 	    /*
   18284 	    * Move the facets, previously anchored on the
   18285 	    * complexType during parsing.
   18286 	    */
   18287 	    content->facets = type->facets;
   18288 	    type->facets = NULL;
   18289 	    content->facetSet = type->facetSet;
   18290 	    type->facetSet = NULL;
   18291 
   18292 	    type->contentTypeDef = content;
   18293 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
   18294 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
   18295 	    /*
   18296 	    * Fixup the newly created type. We don't need to check
   18297 	    * for circularity here.
   18298 	    */
   18299 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
   18300 	    HFAILURE HERROR
   18301 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
   18302 	    HFAILURE HERROR
   18303 
   18304 	} else if ((WXS_IS_COMPLEX(baseType)) &&
   18305 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   18306 	    (WXS_IS_RESTRICTION(type))) {
   18307 	    /*
   18308 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
   18309 	    * an emptiable particle, then a simple type definition which
   18310 	    * restricts the <restriction>'s <simpleType> child.
   18311 	    */
   18312 	    if ((type->contentTypeDef == NULL) ||
   18313 		(type->contentTypeDef->baseType == NULL)) {
   18314 		/*
   18315 		* TODO: Check if this ever happens.
   18316 		*/
   18317 		xmlSchemaPCustomErr(pctxt,
   18318 		    XML_SCHEMAP_INTERNAL,
   18319 		    WXS_BASIC_CAST type, NULL,
   18320 		    "Internal error: xmlSchemaTypeFixup, "
   18321 		    "complex type '%s': the <simpleContent><restriction> "
   18322 		    "is missing a <simpleType> child, but was not catched "
   18323 		    "by xmlSchemaCheckSRCCT()", type->name);
   18324 		goto exit_failure;
   18325 	    }
   18326 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
   18327 	    /*
   18328 	    * SPEC (3) If <extension> + base is <complexType> with
   18329 	    * <simpleType> content, "...then the {content type} of that
   18330 	    * complex type definition"
   18331 	    */
   18332 	    if (baseType->contentTypeDef == NULL) {
   18333 		/*
   18334 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
   18335 		* should have catched this already.
   18336 		*/
   18337 		xmlSchemaPCustomErr(pctxt,
   18338 		    XML_SCHEMAP_INTERNAL,
   18339 		    WXS_BASIC_CAST type, NULL,
   18340 		    "Internal error: xmlSchemaTypeFixup, "
   18341 		    "complex type '%s': the <extension>ed base type is "
   18342 		    "a complex type with no simple content type",
   18343 		    type->name);
   18344 		goto exit_failure;
   18345 	    }
   18346 	    type->contentTypeDef = baseType->contentTypeDef;
   18347 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
   18348 	    /*
   18349 	    * SPEC (4) <extension> + base is <simpleType>
   18350 	    * "... then that simple type definition"
   18351 	    */
   18352 	    type->contentTypeDef = baseType;
   18353 	} else {
   18354 	    /*
   18355 	    * TODO: Check if this ever happens.
   18356 	    */
   18357 	    xmlSchemaPCustomErr(pctxt,
   18358 		XML_SCHEMAP_INTERNAL,
   18359 		WXS_BASIC_CAST type, NULL,
   18360 		"Internal error: xmlSchemaTypeFixup, "
   18361 		"complex type '%s' with <simpleContent>: unhandled "
   18362 		"derivation case", type->name);
   18363 	    goto exit_failure;
   18364 	}
   18365     } else {
   18366 	int dummySequence = 0;
   18367 	xmlSchemaParticlePtr particle =
   18368 	    (xmlSchemaParticlePtr) type->subtypes;
   18369 	/*
   18370 	* Corresponds to <complexType><complexContent>...
   18371 	*
   18372 	* NOTE that the effective mixed was already set during parsing of
   18373 	* <complexType> and <complexContent>; its flag value is
   18374 	* XML_SCHEMAS_TYPE_MIXED.
   18375 	*
   18376 	* Compute the "effective content":
   18377 	* (2.1.1) + (2.1.2) + (2.1.3)
   18378 	*/
   18379 	if ((particle == NULL) ||
   18380 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
   18381 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
   18382 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
   18383 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
   18384 	    (particle->minOccurs == 0))) &&
   18385 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
   18386 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
   18387 		/*
   18388 		* SPEC (2.1.4) "If the `effective mixed` is true, then
   18389 		* a particle whose properties are as follows:..."
   18390 		*
   18391 		* Empty sequence model group with
   18392 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
   18393 		* NOTE that we sill assign it the <complexType> node to
   18394 		* somehow anchor it in the doc.
   18395 		*/
   18396 		if ((particle == NULL) ||
   18397 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
   18398 		    /*
   18399 		    * Create the particle.
   18400 		    */
   18401 		    particle = xmlSchemaAddParticle(pctxt,
   18402 			type->node, 1, 1);
   18403 		    if (particle == NULL)
   18404 			goto exit_failure;
   18405 		    /*
   18406 		    * Create the model group.
   18407 		    */ /* URGENT TODO: avoid adding to pending items. */
   18408 		    particle->children = (xmlSchemaTreeItemPtr)
   18409 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18410 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18411 		    if (particle->children == NULL)
   18412 			goto exit_failure;
   18413 
   18414 		    type->subtypes = (xmlSchemaTypePtr) particle;
   18415 		}
   18416 		dummySequence = 1;
   18417 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18418 	    } else {
   18419 		/*
   18420 		* SPEC (2.1.5) "otherwise empty"
   18421 		*/
   18422 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
   18423 	    }
   18424 	} else {
   18425 	    /*
   18426 	    * SPEC (2.2) "otherwise the particle corresponding to the
   18427 	    * <all>, <choice>, <group> or <sequence> among the
   18428 	    * [children]."
   18429 	    */
   18430 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
   18431 	}
   18432 	/*
   18433 	* Compute the "content type".
   18434 	*/
   18435 	if (WXS_IS_RESTRICTION(type)) {
   18436 	    /*
   18437 	    * SPEC (3.1) "If <restriction>..."
   18438 	    * (3.1.1) + (3.1.2) */
   18439 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
   18440 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18441 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18442 	    }
   18443 	} else {
   18444 	    /*
   18445 	    * SPEC (3.2) "If <extension>..."
   18446 	    */
   18447 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18448 		/*
   18449 		* SPEC (3.2.1)
   18450 		* "If the `effective content` is empty, then the
   18451 		*  {content type} of the [...] base ..."
   18452 		*/
   18453 		type->contentType = baseType->contentType;
   18454 		type->subtypes = baseType->subtypes;
   18455 		/*
   18456 		* Fixes bug #347316:
   18457 		* This is the case when the base type has a simple
   18458 		* type definition as content.
   18459 		*/
   18460 		type->contentTypeDef = baseType->contentTypeDef;
   18461 		/*
   18462 		* NOTE that the effective mixed is ignored here.
   18463 		*/
   18464 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
   18465 		/*
   18466 		* SPEC (3.2.2)
   18467 		*/
   18468 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18469 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18470 	    } else {
   18471 		/*
   18472 		* SPEC (3.2.3)
   18473 		*/
   18474 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
   18475 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
   18476 		    /*
   18477 		    * "A model group whose {compositor} is sequence and whose
   18478 		    * {particles} are..."
   18479 		    */
   18480 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
   18481 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
   18482 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
   18483 			XML_SCHEMA_TYPE_ALL))
   18484 		{
   18485 		    /*
   18486 		    * SPEC cos-all-limited (1)
   18487 		    */
   18488 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18489 			/* TODO: error code */
   18490 			XML_SCHEMAP_COS_ALL_LIMITED,
   18491 			WXS_ITEM_NODE(type), NULL,
   18492 			"The type has an 'all' model group in its "
   18493 			"{content type} and thus cannot be derived from "
   18494 			"a non-empty type, since this would produce a "
   18495 			"'sequence' model group containing the 'all' "
   18496 			"model group; 'all' model groups are not "
   18497 			"allowed to appear inside other model groups",
   18498 			NULL, NULL);
   18499 
   18500 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
   18501 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
   18502 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
   18503 			XML_SCHEMA_TYPE_ALL))
   18504 		{
   18505 		    /*
   18506 		    * SPEC cos-all-limited (1)
   18507 		    */
   18508 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18509 			/* TODO: error code */
   18510 			XML_SCHEMAP_COS_ALL_LIMITED,
   18511 			WXS_ITEM_NODE(type), NULL,
   18512 			"A type cannot be derived by extension from a type "
   18513 			"which has an 'all' model group in its "
   18514 			"{content type}, since this would produce a "
   18515 			"'sequence' model group containing the 'all' "
   18516 			"model group; 'all' model groups are not "
   18517 			"allowed to appear inside other model groups",
   18518 			NULL, NULL);
   18519 
   18520 		} else if (! dummySequence) {
   18521 		    xmlSchemaTreeItemPtr effectiveContent =
   18522 			(xmlSchemaTreeItemPtr) type->subtypes;
   18523 		    /*
   18524 		    * Create the particle.
   18525 		    */
   18526 		    particle = xmlSchemaAddParticle(pctxt,
   18527 			type->node, 1, 1);
   18528 		    if (particle == NULL)
   18529 			goto exit_failure;
   18530 		    /*
   18531 		    * Create the "sequence" model group.
   18532 		    */
   18533 		    particle->children = (xmlSchemaTreeItemPtr)
   18534 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
   18535 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
   18536 		    if (particle->children == NULL)
   18537 			goto exit_failure;
   18538 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
   18539 		    /*
   18540 		    * SPEC "the particle of the {content type} of
   18541 		    * the ... base ..."
   18542 		    * Create a duplicate of the base type's particle
   18543 		    * and assign its "term" to it.
   18544 		    */
   18545 		    particle->children->children =
   18546 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
   18547 			type->node,
   18548 			((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
   18549 			((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
   18550 		    if (particle->children->children == NULL)
   18551 			goto exit_failure;
   18552 		    particle = (xmlSchemaParticlePtr)
   18553 			particle->children->children;
   18554 		    particle->children =
   18555 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
   18556 		    /*
   18557 		    * SPEC "followed by the `effective content`."
   18558 		    */
   18559 		    particle->next = effectiveContent;
   18560 		    /*
   18561 		    * This all will result in:
   18562 		    * new-particle
   18563 		    *   --> new-sequence(
   18564 		    *         new-particle
   18565 		    *           --> base-model,
   18566 		    *         this-particle
   18567 		    *	        --> this-model
   18568 		    *	    )
   18569 		    */
   18570 		} else {
   18571 		    /*
   18572 		    * This is the case when there is already an empty
   18573 		    * <sequence> with minOccurs==maxOccurs==1.
   18574 		    * Just add the base types's content type.
   18575 		    * NOTE that, although we miss to add an intermediate
   18576 		    * <sequence>, this should produce no difference to
   18577 		    * neither the regex compilation of the content model,
   18578 		    * nor to the complex type contraints.
   18579 		    */
   18580 		    particle->children->children =
   18581 			(xmlSchemaTreeItemPtr) baseType->subtypes;
   18582 		}
   18583 	    }
   18584 	}
   18585     }
   18586     /*
   18587     * Now fixup attribute uses:
   18588     *   - expand attr. group references
   18589     *     - intersect attribute wildcards
   18590     *   - inherit attribute uses of the base type
   18591     *   - inherit or union attr. wildcards if extending
   18592     *   - apply attr. use prohibitions if restricting
   18593     */
   18594     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
   18595     HFAILURE HERROR
   18596     /*
   18597     * Apply the complex type component constraints; this will not
   18598     * check attributes, since this is done in
   18599     * xmlSchemaFixupTypeAttributeUses().
   18600     */
   18601     res = xmlSchemaCheckCTComponent(pctxt, type);
   18602     HFAILURE HERROR
   18603 
   18604 #ifdef DEBUG_TYPE
   18605     xmlSchemaDebugFixedType(pctxt, type);
   18606 #endif
   18607     if (olderrs != pctxt->nberrors)
   18608 	return(pctxt->err);
   18609     else
   18610 	return(0);
   18611 
   18612 exit_error:
   18613     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18614 #ifdef DEBUG_TYPE
   18615     xmlSchemaDebugFixedType(pctxt, type);
   18616 #endif
   18617     return(pctxt->err);
   18618 
   18619 exit_failure:
   18620     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
   18621 #ifdef DEBUG_TYPE
   18622     xmlSchemaDebugFixedType(pctxt, type);
   18623 #endif
   18624     return(-1);
   18625 }
   18626 
   18627 
   18628 /**
   18629  * xmlSchemaTypeFixup:
   18630  * @typeDecl:  the schema type definition
   18631  * @ctxt:  the schema parser context
   18632  *
   18633  * Fixes the content model of the type.
   18634  * URGENT TODO: We need an int result!
   18635  */
   18636 static int
   18637 xmlSchemaTypeFixup(xmlSchemaTypePtr type,
   18638                    xmlSchemaAbstractCtxtPtr actxt)
   18639 {
   18640     if (type == NULL)
   18641         return(0);
   18642     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
   18643 	AERROR_INT("xmlSchemaTypeFixup",
   18644 	    "this function needs a parser context");
   18645 	return(-1);
   18646     }
   18647     if (! WXS_IS_TYPE_NOT_FIXED(type))
   18648 	return(0);
   18649     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
   18650 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
   18651     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
   18652 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
   18653     return(0);
   18654 }
   18655 
   18656 /**
   18657  * xmlSchemaCheckFacet:
   18658  * @facet:  the facet
   18659  * @typeDecl:  the schema type definition
   18660  * @pctxt:  the schema parser context or NULL
   18661  * @name: the optional name of the type
   18662  *
   18663  * Checks and computes the values of facets.
   18664  *
   18665  * Returns 0 if valid, a positive error code if not valid and
   18666  *         -1 in case of an internal or API error.
   18667  */
   18668 int
   18669 xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
   18670                     xmlSchemaTypePtr typeDecl,
   18671                     xmlSchemaParserCtxtPtr pctxt,
   18672 		    const xmlChar * name ATTRIBUTE_UNUSED)
   18673 {
   18674     int ret = 0, ctxtGiven;
   18675 
   18676     if ((facet == NULL) || (typeDecl == NULL))
   18677         return(-1);
   18678     /*
   18679     * TODO: will the parser context be given if used from
   18680     * the relaxNG module?
   18681     */
   18682     if (pctxt == NULL)
   18683 	ctxtGiven = 0;
   18684     else
   18685 	ctxtGiven = 1;
   18686 
   18687     switch (facet->type) {
   18688         case XML_SCHEMA_FACET_MININCLUSIVE:
   18689         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   18690         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   18691         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   18692 	case XML_SCHEMA_FACET_ENUMERATION: {
   18693                 /*
   18694                  * Okay we need to validate the value
   18695                  * at that point.
   18696                  */
   18697 		xmlSchemaTypePtr base;
   18698 
   18699 		/* 4.3.5.5 Constraints on enumeration Schema Components
   18700 		* Schema Component Constraint: enumeration valid restriction
   18701 		* It is an `error` if any member of {value} is not in the
   18702 		* `value space` of {base type definition}.
   18703 		*
   18704 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
   18705 		* The value `must` be in the
   18706 		* `value space` of the `base type`.
   18707 		*/
   18708 		/*
   18709 		* This function is intended to deliver a compiled value
   18710 		* on the facet. In this implementation of XML Schemata the
   18711 		* type holding a facet, won't be a built-in type.
   18712 		* Thus to ensure that other API
   18713 		* calls (relaxng) do work, if the given type is a built-in
   18714 		* type, we will assume that the given built-in type *is
   18715 		* already* the base type.
   18716 		*/
   18717 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
   18718 		    base = typeDecl->baseType;
   18719 		    if (base == NULL) {
   18720 			PERROR_INT("xmlSchemaCheckFacet",
   18721 			    "a type user derived type has no base type");
   18722 			return (-1);
   18723 		    }
   18724 		} else
   18725 		    base = typeDecl;
   18726 
   18727 		if (! ctxtGiven) {
   18728 		    /*
   18729 		    * A context is needed if called from RelaxNG.
   18730 		    */
   18731 		    pctxt = xmlSchemaNewParserCtxt("*");
   18732 		    if (pctxt == NULL)
   18733 			return (-1);
   18734 		}
   18735 		/*
   18736 		* NOTE: This call does not check the content nodes,
   18737 		* since they are not available:
   18738 		* facet->node is just the node holding the facet
   18739 		* definition, *not* the attribute holding the *value*
   18740 		* of the facet.
   18741 		*/
   18742 		ret = xmlSchemaVCheckCVCSimpleType(
   18743 		    ACTXT_CAST pctxt, facet->node, base,
   18744 		    facet->value, &(facet->val), 1, 1, 0);
   18745                 if (ret != 0) {
   18746 		    if (ret < 0) {
   18747 			/* No error message for RelaxNG. */
   18748 			if (ctxtGiven) {
   18749 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18750 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
   18751 				"Internal error: xmlSchemaCheckFacet, "
   18752 				"failed to validate the value '%s' of the "
   18753 				"facet '%s' against the base type",
   18754 				facet->value, xmlSchemaFacetTypeToString(facet->type));
   18755 			}
   18756 			goto internal_error;
   18757 		    }
   18758 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18759 		    /* No error message for RelaxNG. */
   18760 		    if (ctxtGiven) {
   18761 			xmlChar *str = NULL;
   18762 
   18763 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18764 			    ret, facet->node, WXS_BASIC_CAST facet,
   18765 			    "The value '%s' of the facet does not validate "
   18766 			    "against the base type '%s'",
   18767 			    facet->value,
   18768 			    xmlSchemaFormatQName(&str,
   18769 				base->targetNamespace, base->name));
   18770 			FREE_AND_NULL(str);
   18771 		    }
   18772 		    goto exit;
   18773                 } else if (facet->val == NULL) {
   18774 		    if (ctxtGiven) {
   18775 			PERROR_INT("xmlSchemaCheckFacet",
   18776 			    "value was not computed");
   18777 		    }
   18778 		    TODO
   18779 		}
   18780                 break;
   18781             }
   18782         case XML_SCHEMA_FACET_PATTERN:
   18783             facet->regexp = xmlRegexpCompile(facet->value);
   18784             if (facet->regexp == NULL) {
   18785 		ret = XML_SCHEMAP_REGEXP_INVALID;
   18786 		/* No error message for RelaxNG. */
   18787 		if (ctxtGiven) {
   18788 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18789 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18790 			"The value '%s' of the facet 'pattern' is not a "
   18791 			"valid regular expression",
   18792 			facet->value, NULL);
   18793 		}
   18794             }
   18795             break;
   18796         case XML_SCHEMA_FACET_TOTALDIGITS:
   18797         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   18798         case XML_SCHEMA_FACET_LENGTH:
   18799         case XML_SCHEMA_FACET_MAXLENGTH:
   18800         case XML_SCHEMA_FACET_MINLENGTH:
   18801 
   18802 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
   18803 		ret = xmlSchemaValidatePredefinedType(
   18804 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
   18805 		    facet->value, &(facet->val));
   18806 	    } else {
   18807 		ret = xmlSchemaValidatePredefinedType(
   18808 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
   18809 		    facet->value, &(facet->val));
   18810 	    }
   18811 	    if (ret != 0) {
   18812 		if (ret < 0) {
   18813 		    /* No error message for RelaxNG. */
   18814 		    if (ctxtGiven) {
   18815 			PERROR_INT("xmlSchemaCheckFacet",
   18816 			    "validating facet value");
   18817 		    }
   18818 		    goto internal_error;
   18819 		}
   18820 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18821 		/* No error message for RelaxNG. */
   18822 		if (ctxtGiven) {
   18823 		    /* error code */
   18824 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
   18825 			ret, facet->node, WXS_BASIC_CAST typeDecl,
   18826 			"The value '%s' of the facet '%s' is not a valid '%s'",
   18827 			facet->value,
   18828 			xmlSchemaFacetTypeToString(facet->type),
   18829 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
   18830 			    BAD_CAST "nonNegativeInteger" :
   18831 			    BAD_CAST "positiveInteger",
   18832 			NULL);
   18833 		}
   18834 	    }
   18835 	    break;
   18836 
   18837         case XML_SCHEMA_FACET_WHITESPACE:{
   18838                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
   18839                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
   18840                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
   18841                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
   18842                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
   18843                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
   18844                 } else {
   18845 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
   18846                     /* No error message for RelaxNG. */
   18847 		    if (ctxtGiven) {
   18848 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
   18849 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   18850 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
   18851 			    "The value '%s' of the facet 'whitespace' is not "
   18852 			    "valid", facet->value, NULL);
   18853                     }
   18854                 }
   18855             }
   18856         default:
   18857             break;
   18858     }
   18859 exit:
   18860     if ((! ctxtGiven) && (pctxt != NULL))
   18861 	xmlSchemaFreeParserCtxt(pctxt);
   18862     return (ret);
   18863 internal_error:
   18864     if ((! ctxtGiven) && (pctxt != NULL))
   18865 	xmlSchemaFreeParserCtxt(pctxt);
   18866     return (-1);
   18867 }
   18868 
   18869 /**
   18870  * xmlSchemaCheckFacetValues:
   18871  * @typeDecl:  the schema type definition
   18872  * @ctxt:  the schema parser context
   18873  *
   18874  * Checks the default values types, especially for facets
   18875  */
   18876 static int
   18877 xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
   18878 			  xmlSchemaParserCtxtPtr pctxt)
   18879 {
   18880     int res, olderrs = pctxt->nberrors;
   18881     const xmlChar *name = typeDecl->name;
   18882     /*
   18883     * NOTE: It is intended to use the facets list, instead
   18884     * of facetSet.
   18885     */
   18886     if (typeDecl->facets != NULL) {
   18887 	xmlSchemaFacetPtr facet = typeDecl->facets;
   18888 
   18889 	/*
   18890 	* Temporarily assign the "schema" to the validation context
   18891 	* of the parser context. This is needed for NOTATION validation.
   18892 	*/
   18893 	if (pctxt->vctxt == NULL) {
   18894 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
   18895 		return(-1);
   18896 	}
   18897 	pctxt->vctxt->schema = pctxt->schema;
   18898 	while (facet != NULL) {
   18899 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
   18900 	    HFAILURE
   18901 	    facet = facet->next;
   18902 	}
   18903 	pctxt->vctxt->schema = NULL;
   18904     }
   18905     if (olderrs != pctxt->nberrors)
   18906 	return(pctxt->err);
   18907     return(0);
   18908 exit_failure:
   18909     return(-1);
   18910 }
   18911 
   18912 /**
   18913  * xmlSchemaGetCircModelGrDefRef:
   18914  * @ctxtMGroup: the searched model group
   18915  * @selfMGroup: the second searched model group
   18916  * @particle: the first particle
   18917  *
   18918  * This one is intended to be used by
   18919  * xmlSchemaCheckGroupDefCircular only.
   18920  *
   18921  * Returns the particle with the circular model group definition reference,
   18922  * otherwise NULL.
   18923  */
   18924 static xmlSchemaTreeItemPtr
   18925 xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
   18926 			      xmlSchemaTreeItemPtr particle)
   18927 {
   18928     xmlSchemaTreeItemPtr circ = NULL;
   18929     xmlSchemaTreeItemPtr term;
   18930     xmlSchemaModelGroupDefPtr gdef;
   18931 
   18932     for (; particle != NULL; particle = particle->next) {
   18933 	term = particle->children;
   18934 	if (term == NULL)
   18935 	    continue;
   18936 	switch (term->type) {
   18937 	    case XML_SCHEMA_TYPE_GROUP:
   18938 		gdef = (xmlSchemaModelGroupDefPtr) term;
   18939 		if (gdef == groupDef)
   18940 		    return (particle);
   18941 		/*
   18942 		* Mark this model group definition to avoid infinite
   18943 		* recursion on circular references not yet examined.
   18944 		*/
   18945 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
   18946 		    continue;
   18947 		if (gdef->children != NULL) {
   18948 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18949 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
   18950 			gdef->children->children);
   18951 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
   18952 		    if (circ != NULL)
   18953 			return (circ);
   18954 		}
   18955 		break;
   18956 	    case XML_SCHEMA_TYPE_SEQUENCE:
   18957 	    case XML_SCHEMA_TYPE_CHOICE:
   18958 	    case XML_SCHEMA_TYPE_ALL:
   18959 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
   18960 		if (circ != NULL)
   18961 		    return (circ);
   18962 		break;
   18963 	    default:
   18964 		break;
   18965 	}
   18966     }
   18967     return (NULL);
   18968 }
   18969 
   18970 /**
   18971  * xmlSchemaCheckGroupDefCircular:
   18972  * @item:  the model group definition
   18973  * @ctxt:  the parser context
   18974  * @name:  the name
   18975  *
   18976  * Checks for circular references to model group definitions.
   18977  */
   18978 static void
   18979 xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
   18980 			       xmlSchemaParserCtxtPtr ctxt)
   18981 {
   18982     /*
   18983     * Schema Component Constraint: Model Group Correct
   18984     * 2 Circular groups are disallowed. That is, within the {particles}
   18985     * of a group there must not be at any depth a particle whose {term}
   18986     * is the group itself.
   18987     */
   18988     if ((item == NULL) ||
   18989 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
   18990 	(item->children == NULL))
   18991 	return;
   18992     {
   18993 	xmlSchemaTreeItemPtr circ;
   18994 
   18995 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
   18996 	if (circ != NULL) {
   18997 	    xmlChar *str = NULL;
   18998 	    /*
   18999 	    * TODO: The error report is not adequate: this constraint
   19000 	    * is defined for model groups but not definitions, but since
   19001 	    * there cannot be any circular model groups without a model group
   19002 	    * definition (if not using a construction API), we check those
   19003 	    * defintions only.
   19004 	    */
   19005 	    xmlSchemaPCustomErr(ctxt,
   19006 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
   19007 		NULL, WXS_ITEM_NODE(circ),
   19008 		"Circular reference to the model group definition '%s' "
   19009 		"defined", xmlSchemaFormatQName(&str,
   19010 		    item->targetNamespace, item->name));
   19011 	    FREE_AND_NULL(str)
   19012 	    /*
   19013 	    * NOTE: We will cut the reference to avoid further
   19014 	    * confusion of the processor. This is a fatal error.
   19015 	    */
   19016 	    circ->children = NULL;
   19017 	}
   19018     }
   19019 }
   19020 
   19021 /**
   19022  * xmlSchemaModelGroupToModelGroupDefFixup:
   19023  * @ctxt:  the parser context
   19024  * @mg:  the model group
   19025  *
   19026  * Assigns the model group of model group definitions to the "term"
   19027  * of the referencing particle.
   19028  * In xmlSchemaResolveModelGroupParticleReferences the model group
   19029  * definitions were assigned to the "term", since needed for the
   19030  * circularity check.
   19031  *
   19032  * Schema Component Constraint:
   19033  *     All Group Limited (cos-all-limited) (1.2)
   19034  */
   19035 static void
   19036 xmlSchemaModelGroupToModelGroupDefFixup(
   19037     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
   19038     xmlSchemaModelGroupPtr mg)
   19039 {
   19040     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   19041 
   19042     while (particle != NULL) {
   19043 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   19044 	    ((WXS_PARTICLE_TERM(particle))->type !=
   19045 		XML_SCHEMA_TYPE_GROUP))
   19046 	{
   19047 	    particle = WXS_PTC_CAST particle->next;
   19048 	    continue;
   19049 	}
   19050 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
   19051 	    /*
   19052 	    * TODO: Remove the particle.
   19053 	    */
   19054 	    WXS_PARTICLE_TERM(particle) = NULL;
   19055 	    particle = WXS_PTC_CAST particle->next;
   19056 	    continue;
   19057 	}
   19058 	/*
   19059 	* Assign the model group to the {term} of the particle.
   19060 	*/
   19061 	WXS_PARTICLE_TERM(particle) =
   19062 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
   19063 
   19064 	particle = WXS_PTC_CAST particle->next;
   19065     }
   19066 }
   19067 
   19068 /**
   19069  * xmlSchemaCheckAttrGroupCircularRecur:
   19070  * @ctxtGr: the searched attribute group
   19071  * @attr: the current attribute list to be processed
   19072  *
   19073  * This one is intended to be used by
   19074  * xmlSchemaCheckAttrGroupCircular only.
   19075  *
   19076  * Returns the circular attribute grou reference, otherwise NULL.
   19077  */
   19078 static xmlSchemaQNameRefPtr
   19079 xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
   19080 				     xmlSchemaItemListPtr list)
   19081 {
   19082     xmlSchemaAttributeGroupPtr gr;
   19083     xmlSchemaQNameRefPtr ref, circ;
   19084     int i;
   19085     /*
   19086     * We will search for an attribute group reference which
   19087     * references the context attribute group.
   19088     */
   19089     for (i = 0; i < list->nbItems; i++) {
   19090 	ref = list->items[i];
   19091 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19092 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
   19093 	    (ref->item != NULL))
   19094 	{
   19095 	    gr = WXS_ATTR_GROUP_CAST ref->item;
   19096 	    if (gr == ctxtGr)
   19097 		return(ref);
   19098 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
   19099 		continue;
   19100 	    /*
   19101 	    * Mark as visited to avoid infinite recursion on
   19102 	    * circular references not yet examined.
   19103 	    */
   19104 	    if ((gr->attrUses) &&
   19105 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
   19106 	    {
   19107 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
   19108 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
   19109 		    (xmlSchemaItemListPtr) gr->attrUses);
   19110 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
   19111 		if (circ != NULL)
   19112 		    return (circ);
   19113 	    }
   19114 
   19115 	}
   19116     }
   19117     return (NULL);
   19118 }
   19119 
   19120 /**
   19121  * xmlSchemaCheckAttrGroupCircular:
   19122  * attrGr:  the attribute group definition
   19123  * @ctxt:  the parser context
   19124  * @name:  the name
   19125  *
   19126  * Checks for circular references of attribute groups.
   19127  */
   19128 static int
   19129 xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
   19130 				xmlSchemaParserCtxtPtr ctxt)
   19131 {
   19132     /*
   19133     * Schema Representation Constraint:
   19134     * Attribute Group Definition Representation OK
   19135     * 3 Circular group reference is disallowed outside <redefine>.
   19136     * That is, unless this element information item's parent is
   19137     * <redefine>, then among the [children], if any, there must
   19138     * not be an <attributeGroup> with ref [attribute] which resolves
   19139     * to the component corresponding to this <attributeGroup>. Indirect
   19140     * circularity is also ruled out. That is, when QName resolution
   19141     * (Schema Document) ($3.15.3) is applied to a `QName` arising from
   19142     * any <attributeGroup>s with a ref [attribute] among the [children],
   19143     * it must not be the case that a `QName` is encountered at any depth
   19144     * which resolves to the component corresponding to this <attributeGroup>.
   19145     */
   19146     if (attrGr->attrUses == NULL)
   19147 	return(0);
   19148     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
   19149 	return(0);
   19150     else {
   19151 	xmlSchemaQNameRefPtr circ;
   19152 
   19153 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
   19154 	    (xmlSchemaItemListPtr) attrGr->attrUses);
   19155 	if (circ != NULL) {
   19156 	    xmlChar *str = NULL;
   19157 	    /*
   19158 	    * TODO: Report the referenced attr group as QName.
   19159 	    */
   19160 	    xmlSchemaPCustomErr(ctxt,
   19161 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
   19162 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
   19163 		"Circular reference to the attribute group '%s' "
   19164 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
   19165 	    FREE_AND_NULL(str);
   19166 	    /*
   19167 	    * NOTE: We will cut the reference to avoid further
   19168 	    * confusion of the processor.
   19169 	    * BADSPEC TODO: The spec should define how to process in this case.
   19170 	    */
   19171 	    circ->item = NULL;
   19172 	    return(ctxt->err);
   19173 	}
   19174     }
   19175     return(0);
   19176 }
   19177 
   19178 static int
   19179 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19180 				  xmlSchemaAttributeGroupPtr attrGr);
   19181 
   19182 /**
   19183  * xmlSchemaExpandAttributeGroupRefs:
   19184  * @pctxt: the parser context
   19185  * @node: the node of the component holding the attribute uses
   19186  * @completeWild: the intersected wildcard to be returned
   19187  * @list: the attribute uses
   19188  *
   19189  * Substitutes contained attribute group references
   19190  * for their attribute uses. Wilcards are intersected.
   19191  * Attribute use prohibitions are removed from the list
   19192  * and returned via the @prohibs list.
   19193  * Pointlessness of attr. prohibs, if a matching attr. decl
   19194  * is existent a well, are checked.
   19195  */
   19196 static int
   19197 xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
   19198 				  xmlSchemaBasicItemPtr item,
   19199 				  xmlSchemaWildcardPtr *completeWild,
   19200 				  xmlSchemaItemListPtr list,
   19201 				  xmlSchemaItemListPtr prohibs)
   19202 {
   19203     xmlSchemaAttributeGroupPtr gr;
   19204     xmlSchemaAttributeUsePtr use;
   19205     xmlSchemaItemListPtr sublist;
   19206     int i, j;
   19207     int created = (*completeWild == NULL) ? 0 : 1;
   19208 
   19209     if (prohibs)
   19210 	prohibs->nbItems = 0;
   19211 
   19212     for (i = 0; i < list->nbItems; i++) {
   19213 	use = list->items[i];
   19214 
   19215 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
   19216 	    if (prohibs == NULL) {
   19217 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
   19218 		    "unexpected attr prohibition found");
   19219 		return(-1);
   19220 	    }
   19221 	    /*
   19222 	    * Remove from attribute uses.
   19223 	    */
   19224 	    if (xmlSchemaItemListRemove(list, i) == -1)
   19225 		return(-1);
   19226 	    i--;
   19227 	    /*
   19228 	    * Note that duplicate prohibitions were already
   19229 	    * handled at parsing time.
   19230 	    */
   19231 	    /*
   19232 	    * Add to list of prohibitions.
   19233 	    */
   19234 	    xmlSchemaItemListAddSize(prohibs, 2, use);
   19235 	    continue;
   19236 	}
   19237 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
   19238 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
   19239 	{
   19240 	    if ((WXS_QNAME_CAST use)->item == NULL)
   19241 		return(-1);
   19242 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
   19243 	    /*
   19244 	    * Expand the referenced attr. group.
   19245 	    * TODO: remove this, this is done in a previous step, so
   19246 	    * already done here.
   19247 	    */
   19248 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
   19249 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
   19250 		    return(-1);
   19251 	    }
   19252 	    /*
   19253 	    * Build the 'complete' wildcard; i.e. intersect multiple
   19254 	    * wildcards.
   19255 	    */
   19256 	    if (gr->attributeWildcard != NULL) {
   19257 		if (*completeWild == NULL) {
   19258 		    *completeWild = gr->attributeWildcard;
   19259 		} else {
   19260 		    if (! created) {
   19261 			xmlSchemaWildcardPtr tmpWild;
   19262 
   19263 			 /*
   19264 			* Copy the first encountered wildcard as context,
   19265 			* except for the annotation.
   19266 			*
   19267 			* Although the complete wildcard might not correspond
   19268 			* to any node in the schema, we will anchor it on
   19269 			* the node of the owner component.
   19270 			*/
   19271 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
   19272 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
   19273 			    WXS_ITEM_NODE(item));
   19274 			if (tmpWild == NULL)
   19275 			    return(-1);
   19276 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
   19277 			    tmpWild, *completeWild) == -1)
   19278 			    return (-1);
   19279 			tmpWild->processContents = (*completeWild)->processContents;
   19280 			*completeWild = tmpWild;
   19281 			created = 1;
   19282 		    }
   19283 
   19284 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
   19285 			gr->attributeWildcard) == -1)
   19286 			return(-1);
   19287 		}
   19288 	    }
   19289 	    /*
   19290 	    * Just remove the reference if the referenced group does not
   19291 	    * contain any attribute uses.
   19292 	    */
   19293 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
   19294 	    if ((sublist == NULL) || sublist->nbItems == 0) {
   19295 		if (xmlSchemaItemListRemove(list, i) == -1)
   19296 		    return(-1);
   19297 		i--;
   19298 		continue;
   19299 	    }
   19300 	    /*
   19301 	    * Add the attribute uses.
   19302 	    */
   19303 	    list->items[i] = sublist->items[0];
   19304 	    if (sublist->nbItems != 1) {
   19305 		for (j = 1; j < sublist->nbItems; j++) {
   19306 		    i++;
   19307 		    if (xmlSchemaItemListInsert(list,
   19308 			    sublist->items[j], i) == -1)
   19309 			return(-1);
   19310 		}
   19311 	    }
   19312 	}
   19313 
   19314     }
   19315     /*
   19316     * Handle pointless prohibitions of declared attributes.
   19317     */
   19318     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
   19319 	xmlSchemaAttributeUseProhibPtr prohib;
   19320 
   19321 	for (i = prohibs->nbItems -1; i >= 0; i--) {
   19322 	    prohib = prohibs->items[i];
   19323 	    for (j = 0; j < list->nbItems; j++) {
   19324 		use = list->items[j];
   19325 
   19326 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
   19327 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
   19328 		{
   19329 		    xmlChar *str = NULL;
   19330 
   19331 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
   19332 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
   19333 			prohib->node, NULL,
   19334 			"Skipping pointless attribute use prohibition "
   19335 			"'%s', since a corresponding attribute use "
   19336 			"exists already in the type definition",
   19337 			xmlSchemaFormatQName(&str,
   19338 			    prohib->targetNamespace, prohib->name),
   19339 			NULL, NULL);
   19340 		    FREE_AND_NULL(str);
   19341 		    /*
   19342 		    * Remove the prohibition.
   19343 		    */
   19344 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
   19345 			return(-1);
   19346 		    break;
   19347 		}
   19348 	    }
   19349 	}
   19350     }
   19351     return(0);
   19352 }
   19353 
   19354 /**
   19355  * xmlSchemaAttributeGroupExpandRefs:
   19356  * @pctxt:  the parser context
   19357  * @attrGr:  the attribute group definition
   19358  *
   19359  * Computation of:
   19360  * {attribute uses} property
   19361  * {attribute wildcard} property
   19362  *
   19363  * Substitutes contained attribute group references
   19364  * for their attribute uses. Wilcards are intersected.
   19365  */
   19366 static int
   19367 xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
   19368 				  xmlSchemaAttributeGroupPtr attrGr)
   19369 {
   19370     if ((attrGr->attrUses == NULL) ||
   19371 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
   19372 	return(0);
   19373 
   19374     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
   19375     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
   19376 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
   19377 	return(-1);
   19378     return(0);
   19379 }
   19380 
   19381 /**
   19382  * xmlSchemaAttributeGroupExpandRefs:
   19383  * @pctxt:  the parser context
   19384  * @attrGr:  the attribute group definition
   19385  *
   19386  * Substitutes contained attribute group references
   19387  * for their attribute uses. Wilcards are intersected.
   19388  *
   19389  * Schema Component Constraint:
   19390  *    Attribute Group Definition Properties Correct (ag-props-correct)
   19391  */
   19392 static int
   19393 xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19394 				  xmlSchemaAttributeGroupPtr attrGr)
   19395 {
   19396     /*
   19397     * SPEC ag-props-correct
   19398     * (1) "The values of the properties of an attribute group definition
   19399     * must be as described in the property tableau in The Attribute
   19400     * Group Definition Schema Component ($3.6.1), modulo the impact of
   19401     * Missing Sub-components ($5.3);"
   19402     */
   19403 
   19404     if ((attrGr->attrUses != NULL) &&
   19405 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
   19406     {
   19407 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
   19408 	xmlSchemaAttributeUsePtr use, tmp;
   19409 	int i, j, hasId = 0;
   19410 
   19411 	for (i = uses->nbItems -1; i >= 0; i--) {
   19412 	    use = uses->items[i];
   19413 	    /*
   19414 	    * SPEC ag-props-correct
   19415 	    * (2) "Two distinct members of the {attribute uses} must not have
   19416 	    * {attribute declaration}s both of whose {name}s match and whose
   19417 	    * {target namespace}s are identical."
   19418 	    */
   19419 	    if (i > 0) {
   19420 		for (j = i -1; j >= 0; j--) {
   19421 		    tmp = uses->items[j];
   19422 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
   19423 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
   19424 			(WXS_ATTRUSE_DECL_TNS(use) ==
   19425 			WXS_ATTRUSE_DECL_TNS(tmp)))
   19426 		    {
   19427 			xmlChar *str = NULL;
   19428 
   19429 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19430 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19431 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19432 			    "Duplicate %s",
   19433 			    xmlSchemaGetComponentDesignation(&str, use),
   19434 			    NULL);
   19435 			FREE_AND_NULL(str);
   19436 			/*
   19437 			* Remove the duplicate.
   19438 			*/
   19439 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19440 			    return(-1);
   19441 			goto next_use;
   19442 		    }
   19443 		}
   19444 	    }
   19445 	    /*
   19446 	    * SPEC ag-props-correct
   19447 	    * (3) "Two distinct members of the {attribute uses} must not have
   19448 	    * {attribute declaration}s both of whose {type definition}s are or
   19449 	    * are derived from ID."
   19450 	    * TODO: Does 'derived' include member-types of unions?
   19451 	    */
   19452 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
   19453 		if (xmlSchemaIsDerivedFromBuiltInType(
   19454 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   19455 		{
   19456 		    if (hasId) {
   19457 			xmlChar *str = NULL;
   19458 
   19459 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19460 			    XML_SCHEMAP_AG_PROPS_CORRECT,
   19461 			    attrGr->node, WXS_BASIC_CAST attrGr,
   19462 			    "There must not exist more than one attribute "
   19463 			    "declaration of type 'xs:ID' "
   19464 			    "(or derived from 'xs:ID'). The %s violates this "
   19465 			    "constraint",
   19466 			    xmlSchemaGetComponentDesignation(&str, use),
   19467 			    NULL);
   19468 			FREE_AND_NULL(str);
   19469 			if (xmlSchemaItemListRemove(uses, i) == -1)
   19470 			    return(-1);
   19471 		    }
   19472 		    hasId = 1;
   19473 		}
   19474 	    }
   19475 next_use: {}
   19476 	}
   19477     }
   19478     return(0);
   19479 }
   19480 
   19481 /**
   19482  * xmlSchemaResolveAttrGroupReferences:
   19483  * @attrgrpDecl:  the schema attribute definition
   19484  * @ctxt:  the schema parser context
   19485  * @name:  the attribute name
   19486  *
   19487  * Resolves references to attribute group definitions.
   19488  */
   19489 static int
   19490 xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
   19491 				    xmlSchemaParserCtxtPtr ctxt)
   19492 {
   19493     xmlSchemaAttributeGroupPtr group;
   19494 
   19495     if (ref->item != NULL)
   19496         return(0);
   19497     group = xmlSchemaGetAttributeGroup(ctxt->schema,
   19498 	ref->name,
   19499 	ref->targetNamespace);
   19500     if (group == NULL) {
   19501 	xmlSchemaPResCompAttrErr(ctxt,
   19502 	    XML_SCHEMAP_SRC_RESOLVE,
   19503 	    NULL, ref->node,
   19504 	    "ref", ref->name, ref->targetNamespace,
   19505 	    ref->itemType, NULL);
   19506 	return(ctxt->err);
   19507     }
   19508     ref->item = WXS_BASIC_CAST group;
   19509     return(0);
   19510 }
   19511 
   19512 /**
   19513  * xmlSchemaCheckAttrPropsCorrect:
   19514  * @item:  an schema attribute declaration/use
   19515  * @ctxt:  a schema parser context
   19516  * @name:  the name of the attribute
   19517  *
   19518  *
   19519  * Schema Component Constraint:
   19520  *    Attribute Declaration Properties Correct (a-props-correct)
   19521  *
   19522  * Validates the value constraints of an attribute declaration/use.
   19523  * NOTE that this needs the simle type definitions to be already
   19524  *   builded and checked.
   19525  */
   19526 static int
   19527 xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19528 			       xmlSchemaAttributePtr attr)
   19529 {
   19530 
   19531     /*
   19532     * SPEC a-props-correct (1)
   19533     * "The values of the properties of an attribute declaration must
   19534     * be as described in the property tableau in The Attribute
   19535     * Declaration Schema Component ($3.2.1), modulo the impact of
   19536     * Missing Sub-components ($5.3)."
   19537     */
   19538 
   19539     if (WXS_ATTR_TYPEDEF(attr) == NULL)
   19540 	return(0);
   19541 
   19542     if (attr->defValue != NULL) {
   19543 	int ret;
   19544 
   19545 	/*
   19546 	* SPEC a-props-correct (3)
   19547 	* "If the {type definition} is or is derived from ID then there
   19548 	* must not be a {value constraint}."
   19549 	*/
   19550 	if (xmlSchemaIsDerivedFromBuiltInType(
   19551 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
   19552 	{
   19553 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19554 		XML_SCHEMAP_A_PROPS_CORRECT_3,
   19555 		NULL, WXS_BASIC_CAST attr,
   19556 		"Value constraints are not allowed if the type definition "
   19557 		"is or is derived from xs:ID",
   19558 		NULL, NULL);
   19559 	    return(pctxt->err);
   19560 	}
   19561 	/*
   19562 	* SPEC a-props-correct (2)
   19563 	* "if there is a {value constraint}, the canonical lexical
   19564 	* representation of its value must be `valid` with respect
   19565 	* to the {type definition} as defined in String Valid ($3.14.4)."
   19566 	* TODO: Don't care about the *canonical* stuff here, this requirement
   19567 	* will be removed in WXS 1.1 anyway.
   19568 	*/
   19569 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
   19570 	    attr->node, WXS_ATTR_TYPEDEF(attr),
   19571 	    attr->defValue, &(attr->defVal),
   19572 	    1, 1, 0);
   19573 	if (ret != 0) {
   19574 	    if (ret < 0) {
   19575 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
   19576 		    "calling xmlSchemaVCheckCVCSimpleType()");
   19577 		return(-1);
   19578 	    }
   19579 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19580 		XML_SCHEMAP_A_PROPS_CORRECT_2,
   19581 		NULL, WXS_BASIC_CAST attr,
   19582 		"The value of the value constraint is not valid",
   19583 		NULL, NULL);
   19584 	    return(pctxt->err);
   19585 	}
   19586     }
   19587 
   19588     return(0);
   19589 }
   19590 
   19591 static xmlSchemaElementPtr
   19592 xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
   19593 				 xmlSchemaElementPtr ancestor)
   19594 {
   19595     xmlSchemaElementPtr ret;
   19596 
   19597     if (WXS_SUBST_HEAD(ancestor) == NULL)
   19598 	return (NULL);
   19599     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
   19600 	return (ancestor);
   19601 
   19602     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
   19603 	return (NULL);
   19604     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
   19605     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
   19606 	WXS_SUBST_HEAD(ancestor));
   19607     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
   19608 
   19609     return (ret);
   19610 }
   19611 
   19612 /**
   19613  * xmlSchemaCheckElemPropsCorrect:
   19614  * @ctxt:  a schema parser context
   19615  * @decl: the element declaration
   19616  * @name:  the name of the attribute
   19617  *
   19618  * Schema Component Constraint:
   19619  * Element Declaration Properties Correct (e-props-correct)
   19620  *
   19621  * STATUS:
   19622  *   missing: (6)
   19623  */
   19624 static int
   19625 xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
   19626 			       xmlSchemaElementPtr elemDecl)
   19627 {
   19628     int ret = 0;
   19629     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
   19630     /*
   19631     * SPEC (1) "The values of the properties of an element declaration
   19632     * must be as described in the property tableau in The Element
   19633     * Declaration Schema Component ($3.3.1), modulo the impact of Missing
   19634     * Sub-components ($5.3)."
   19635     */
   19636     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
   19637 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
   19638 
   19639 	xmlSchemaCheckElementDeclComponent(head, pctxt);
   19640 	/*
   19641 	* SPEC (3) "If there is a non-`absent` {substitution group
   19642 	* affiliation}, then {scope} must be global."
   19643 	*/
   19644 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
   19645 	    xmlSchemaPCustomErr(pctxt,
   19646 		XML_SCHEMAP_E_PROPS_CORRECT_3,
   19647 		WXS_BASIC_CAST elemDecl, NULL,
   19648 		"Only global element declarations can have a "
   19649 		"substitution group affiliation", NULL);
   19650 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
   19651 	}
   19652 	/*
   19653 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
   19654 	* That is, it must not be possible to return to an element declaration
   19655 	* by repeatedly following the {substitution group affiliation}
   19656 	* property."
   19657 	*/
   19658 	if (head == elemDecl)
   19659 	    circ = head;
   19660 	else if (WXS_SUBST_HEAD(head) != NULL)
   19661 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
   19662 	else
   19663 	    circ = NULL;
   19664 	if (circ != NULL) {
   19665 	    xmlChar *strA = NULL, *strB = NULL;
   19666 
   19667 	    xmlSchemaPCustomErrExt(pctxt,
   19668 		XML_SCHEMAP_E_PROPS_CORRECT_6,
   19669 		WXS_BASIC_CAST circ, NULL,
   19670 		"The element declaration '%s' defines a circular "
   19671 		"substitution group to element declaration '%s'",
   19672 		xmlSchemaGetComponentQName(&strA, circ),
   19673 		xmlSchemaGetComponentQName(&strB, head),
   19674 		NULL);
   19675 	    FREE_AND_NULL(strA)
   19676 	    FREE_AND_NULL(strB)
   19677 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
   19678 	}
   19679 	/*
   19680 	* SPEC (4) "If there is a {substitution group affiliation},
   19681 	* the {type definition}
   19682 	* of the element declaration must be validly derived from the {type
   19683 	* definition} of the {substitution group affiliation}, given the value
   19684 	* of the {substitution group exclusions} of the {substitution group
   19685 	* affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
   19686 	* (if the {type definition} is complex) or as defined in
   19687 	* Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
   19688 	* simple)."
   19689 	*
   19690 	* NOTE: {substitution group exclusions} means the values of the
   19691 	* attribute "final".
   19692 	*/
   19693 
   19694 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
   19695 	    int set = 0;
   19696 
   19697 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
   19698 		set |= SUBSET_EXTENSION;
   19699 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
   19700 		set |= SUBSET_RESTRICTION;
   19701 
   19702 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
   19703 		WXS_ELEM_TYPEDEF(head), set) != 0) {
   19704 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
   19705 
   19706 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
   19707 		xmlSchemaPCustomErrExt(pctxt,
   19708 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
   19709 		    WXS_BASIC_CAST elemDecl, NULL,
   19710 		    "The type definition '%s' was "
   19711 		    "either rejected by the substitution group "
   19712 		    "affiliation '%s', or not validly derived from its type "
   19713 		    "definition '%s'",
   19714 		    xmlSchemaGetComponentQName(&strA, typeDef),
   19715 		    xmlSchemaGetComponentQName(&strB, head),
   19716 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
   19717 		FREE_AND_NULL(strA)
   19718 		FREE_AND_NULL(strB)
   19719 		FREE_AND_NULL(strC)
   19720 	    }
   19721 	}
   19722     }
   19723     /*
   19724     * SPEC (5) "If the {type definition} or {type definition}'s
   19725     * {content type}
   19726     * is or is derived from ID then there must not be a {value constraint}.
   19727     * Note: The use of ID as a type definition for elements goes beyond
   19728     * XML 1.0, and should be avoided if backwards compatibility is desired"
   19729     */
   19730     if ((elemDecl->value != NULL) &&
   19731 	((WXS_IS_SIMPLE(typeDef) &&
   19732 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
   19733 	 (WXS_IS_COMPLEX(typeDef) &&
   19734 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
   19735 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
   19736 	    XML_SCHEMAS_ID)))) {
   19737 
   19738 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
   19739 	xmlSchemaPCustomErr(pctxt,
   19740 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
   19741 	    WXS_BASIC_CAST elemDecl, NULL,
   19742 	    "The type definition (or type definition's content type) is or "
   19743 	    "is derived from ID; value constraints are not allowed in "
   19744 	    "conjunction with such a type definition", NULL);
   19745     } else if (elemDecl->value != NULL) {
   19746 	int vcret;
   19747 	xmlNodePtr node = NULL;
   19748 
   19749 	/*
   19750 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
   19751 	* representation of its value must be `valid` with respect to the
   19752 	* {type definition} as defined in Element Default Valid (Immediate)
   19753 	* ($3.3.6)."
   19754 	*/
   19755 	if (typeDef == NULL) {
   19756 	    xmlSchemaPErr(pctxt, elemDecl->node,
   19757 		XML_SCHEMAP_INTERNAL,
   19758 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
   19759 		"type is missing... skipping validation of "
   19760 		"the value constraint", NULL, NULL);
   19761 	    return (-1);
   19762 	}
   19763 	if (elemDecl->node != NULL) {
   19764 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
   19765 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19766 		    BAD_CAST "fixed");
   19767 	    else
   19768 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
   19769 		    BAD_CAST "default");
   19770 	}
   19771 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
   19772 	    typeDef, elemDecl->value, &(elemDecl->defVal));
   19773 	if (vcret != 0) {
   19774 	    if (vcret < 0) {
   19775 		PERROR_INT("xmlSchemaElemCheckValConstr",
   19776 		    "failed to validate the value constraint of an "
   19777 		    "element declaration");
   19778 		return (-1);
   19779 	    }
   19780 	    return (vcret);
   19781 	}
   19782     }
   19783 
   19784     return (ret);
   19785 }
   19786 
   19787 /**
   19788  * xmlSchemaCheckElemSubstGroup:
   19789  * @ctxt:  a schema parser context
   19790  * @decl: the element declaration
   19791  * @name:  the name of the attribute
   19792  *
   19793  * Schema Component Constraint:
   19794  * Substitution Group (cos-equiv-class)
   19795  *
   19796  * In Libxml2 the subst. groups will be precomputed, in terms of that
   19797  * a list will be built for each subst. group head, holding all direct
   19798  * referents to this head.
   19799  * NOTE that this function needs:
   19800  *   1. circular subst. groups to be checked beforehand
   19801  *   2. the declaration's type to be derived from the head's type
   19802  *
   19803  * STATUS:
   19804  *
   19805  */
   19806 static void
   19807 xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
   19808 			     xmlSchemaElementPtr elemDecl)
   19809 {
   19810     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
   19811 	/* SPEC (1) "Its {abstract} is false." */
   19812 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
   19813 	return;
   19814     {
   19815 	xmlSchemaElementPtr head;
   19816 	xmlSchemaTypePtr headType, type;
   19817 	int set, methSet;
   19818 	/*
   19819 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
   19820 	* {disallowed substitutions} as the blocking constraint, as defined in
   19821 	* Substitution Group OK (Transitive) ($3.3.6)."
   19822 	*/
   19823 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
   19824 	    head = WXS_SUBST_HEAD(head)) {
   19825 	    set = 0;
   19826 	    methSet = 0;
   19827 	    /*
   19828 	    * The blocking constraints.
   19829 	    */
   19830 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
   19831 		continue;
   19832 	    headType = head->subtypes;
   19833 	    type = elemDecl->subtypes;
   19834 	    if (headType == type)
   19835 		goto add_member;
   19836 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
   19837 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19838 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
   19839 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19840 	    /*
   19841 	    * SPEC: Substitution Group OK (Transitive) (2.3)
   19842 	    * "The set of all {derivation method}s involved in the
   19843 	    * derivation of D's {type definition} from C's {type definition}
   19844 	    * does not intersect with the union of the blocking constraint,
   19845 	    * C's {prohibited substitutions} (if C is complex, otherwise the
   19846 	    * empty set) and the {prohibited substitutions} (respectively the
   19847 	    * empty set) of any intermediate {type definition}s in the
   19848 	    * derivation of D's {type definition} from C's {type definition}."
   19849 	    */
   19850 	    /*
   19851 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
   19852 	    * subst.head axis, the methSet does not need to be computed for
   19853 	    * the full depth over and over.
   19854 	    */
   19855 	    /*
   19856 	    * The set of all {derivation method}s involved in the derivation
   19857 	    */
   19858 	    while ((type != NULL) && (type != headType)) {
   19859 		if ((WXS_IS_EXTENSION(type)) &&
   19860 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19861 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19862 
   19863 		if (WXS_IS_RESTRICTION(type) &&
   19864 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19865 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19866 
   19867 		type = type->baseType;
   19868 	    }
   19869 	    /*
   19870 	    * The {prohibited substitutions} of all intermediate types +
   19871 	    * the head's type.
   19872 	    */
   19873 	    type = elemDecl->subtypes->baseType;
   19874 	    while (type != NULL) {
   19875 		if (WXS_IS_COMPLEX(type)) {
   19876 		    if ((type->flags &
   19877 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19878 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
   19879 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
   19880 		    if ((type->flags &
   19881 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19882 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
   19883 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
   19884 		} else
   19885 		    break;
   19886 		if (type == headType)
   19887 		    break;
   19888 		type = type->baseType;
   19889 	    }
   19890 	    if ((set != 0) &&
   19891 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
   19892 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
   19893 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
   19894 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
   19895 		continue;
   19896 	    }
   19897 add_member:
   19898 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
   19899 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
   19900 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
   19901 	}
   19902     }
   19903 }
   19904 
   19905 #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
   19906 /**
   19907  * xmlSchemaCheckElementDeclComponent
   19908  * @pctxt: the schema parser context
   19909  * @ctxtComponent: the context component (an element declaration)
   19910  * @ctxtParticle: the first particle of the context component
   19911  * @searchParticle: the element declaration particle to be analysed
   19912  *
   19913  * Schema Component Constraint: Element Declarations Consistent
   19914  */
   19915 static int
   19916 xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
   19917 				    xmlSchemaBasicItemPtr ctxtComponent,
   19918 				    xmlSchemaParticlePtr ctxtParticle,
   19919 				    xmlSchemaParticlePtr searchParticle,
   19920 				    xmlSchemaParticlePtr curParticle,
   19921 				    int search)
   19922 {
   19923     return(0);
   19924 
   19925     int ret = 0;
   19926     xmlSchemaParticlePtr cur = curParticle;
   19927     if (curParticle == NULL) {
   19928 	return(0);
   19929     }
   19930     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
   19931 	/*
   19932 	* Just return in this case. A missing "term" of the particle
   19933 	* might arise due to an invalid "term" component.
   19934 	*/
   19935 	return(0);
   19936     }
   19937     while (cur != NULL) {
   19938 	switch (WXS_PARTICLE_TERM(cur)->type) {
   19939 	    case XML_SCHEMA_TYPE_ANY:
   19940 		break;
   19941 	    case XML_SCHEMA_TYPE_ELEMENT:
   19942 		if (search == 0) {
   19943 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
   19944 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
   19945 		    if (ret != 0)
   19946 			return(ret);
   19947 		} else {
   19948 		    xmlSchemaElementPtr elem =
   19949 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
   19950 		    /*
   19951 		    * SPEC Element Declarations Consistent:
   19952 		    * "If the {particles} contains, either directly,
   19953 		    * indirectly (that is, within the {particles} of a
   19954 		    * contained model group, recursively) or `implicitly`
   19955 		    * two or more element declaration particles with
   19956 		    * the same {name} and {target namespace}, then
   19957 		    * all their type definitions must be the same
   19958 		    * top-level definition [...]"
   19959 		    */
   19960 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
   19961 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
   19962 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19963 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
   19964 		    {
   19965 			xmlChar *strA = NULL, *strB = NULL;
   19966 
   19967 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
   19968 			    /* TODO: error code */
   19969 			    XML_SCHEMAP_COS_NONAMBIG,
   19970 			    WXS_ITEM_NODE(cur), NULL,
   19971 			    "In the content model of %s, there are multiple "
   19972 			    "element declarations for '%s' with different "
   19973 			    "type definitions",
   19974 			    xmlSchemaGetComponentDesignation(&strA,
   19975 				ctxtComponent),
   19976 			    xmlSchemaFormatQName(&strB,
   19977 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
   19978 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
   19979 			FREE_AND_NULL(strA);
   19980 			FREE_AND_NULL(strB);
   19981 			return(XML_SCHEMAP_COS_NONAMBIG);
   19982 		    }
   19983 		}
   19984 		break;
   19985 	    case XML_SCHEMA_TYPE_SEQUENCE: {
   19986 		break;
   19987 		}
   19988 	    case XML_SCHEMA_TYPE_CHOICE:{
   19989 		/*
   19990 		xmlSchemaTreeItemPtr sub;
   19991 
   19992 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
   19993 		while (sub != NULL) {
   19994 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
   19995 			ctxtParticle, ctxtElem);
   19996 		    if (ret != 0)
   19997 			return(ret);
   19998 		    sub = sub->next;
   19999 		}
   20000 		*/
   20001 		break;
   20002 		}
   20003 	    case XML_SCHEMA_TYPE_ALL:
   20004 		break;
   20005 	    case XML_SCHEMA_TYPE_GROUP:
   20006 		break;
   20007 	    default:
   20008 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
   20009 		    "xmlSchemaCheckElementDeclConsistent",
   20010 		    "found unexpected term of type '%s' in content model",
   20011 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
   20012 		return(-1);
   20013 	}
   20014 	cur = (xmlSchemaParticlePtr) cur->next;
   20015     }
   20016 
   20017 exit:
   20018     return(ret);
   20019 }
   20020 #endif
   20021 
   20022 /**
   20023  * xmlSchemaCheckElementDeclComponent
   20024  * @item:  an schema element declaration/particle
   20025  * @ctxt:  a schema parser context
   20026  * @name:  the name of the attribute
   20027  *
   20028  * Validates the value constraints of an element declaration.
   20029  * Adds substitution group members.
   20030  */
   20031 static void
   20032 xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
   20033 				   xmlSchemaParserCtxtPtr ctxt)
   20034 {
   20035     if (elemDecl == NULL)
   20036 	return;
   20037     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
   20038 	return;
   20039     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
   20040     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
   20041 	/*
   20042 	* Adds substitution group members.
   20043 	*/
   20044 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
   20045     }
   20046 }
   20047 
   20048 /**
   20049  * xmlSchemaResolveModelGroupParticleReferences:
   20050  * @particle:  a particle component
   20051  * @ctxt:  a parser context
   20052  *
   20053  * Resolves references of a model group's {particles} to
   20054  * model group definitions and to element declarations.
   20055  */
   20056 static void
   20057 xmlSchemaResolveModelGroupParticleReferences(
   20058     xmlSchemaParserCtxtPtr ctxt,
   20059     xmlSchemaModelGroupPtr mg)
   20060 {
   20061     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
   20062     xmlSchemaQNameRefPtr ref;
   20063     xmlSchemaBasicItemPtr refItem;
   20064 
   20065     /*
   20066     * URGENT TODO: Test this.
   20067     */
   20068     while (particle != NULL) {
   20069 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
   20070 	    ((WXS_PARTICLE_TERM(particle))->type !=
   20071 		XML_SCHEMA_EXTRA_QNAMEREF))
   20072 	{
   20073 	    goto next_particle;
   20074 	}
   20075 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
   20076 	/*
   20077 	* Resolve the reference.
   20078 	* NULL the {term} by default.
   20079 	*/
   20080 	particle->children = NULL;
   20081 
   20082 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
   20083 	    ref->itemType, ref->name, ref->targetNamespace);
   20084 	if (refItem == NULL) {
   20085 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
   20086 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
   20087 		ref->targetNamespace, ref->itemType, NULL);
   20088 	    /* TODO: remove the particle. */
   20089 	    goto next_particle;
   20090 	}
   20091 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
   20092 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
   20093 		/* TODO: remove the particle. */
   20094 		goto next_particle;
   20095 	    /*
   20096 	    * NOTE that we will assign the model group definition
   20097 	    * itself to the "term" of the particle. This will ease
   20098 	    * the check for circular model group definitions. After
   20099 	    * that the "term" will be assigned the model group of the
   20100 	    * model group definition.
   20101 	    */
   20102 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
   20103 		    XML_SCHEMA_TYPE_ALL) {
   20104 		/*
   20105 		* SPEC cos-all-limited (1)
   20106 		* SPEC cos-all-limited (1.2)
   20107 		* "It appears only as the value of one or both of the
   20108 		* following properties:"
   20109 		* (1.1) "the {model group} property of a model group
   20110 		*        definition."
   20111 		* (1.2) "the {term} property of a particle [... of] the "
   20112 		* {content type} of a complex type definition."
   20113 		*/
   20114 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20115 		    /* TODO: error code */
   20116 		    XML_SCHEMAP_COS_ALL_LIMITED,
   20117 		    WXS_ITEM_NODE(particle), NULL,
   20118 		    "A model group definition is referenced, but "
   20119 		    "it contains an 'all' model group, which "
   20120 		    "cannot be contained by model groups",
   20121 		    NULL, NULL);
   20122 		/* TODO: remove the particle. */
   20123 		goto next_particle;
   20124 	    }
   20125 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20126 	} else {
   20127 	    /*
   20128 	    * TODO: Are referenced element declarations the only
   20129 	    * other components we expect here?
   20130 	    */
   20131 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
   20132 	}
   20133 next_particle:
   20134 	particle = WXS_PTC_CAST particle->next;
   20135     }
   20136 }
   20137 
   20138 static int
   20139 xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
   20140 		       xmlSchemaValPtr y)
   20141 {
   20142     xmlSchemaTypePtr tx, ty, ptx, pty;
   20143     int ret;
   20144 
   20145     while (x != NULL) {
   20146 	/* Same types. */
   20147 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
   20148 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
   20149 	ptx = xmlSchemaGetPrimitiveType(tx);
   20150 	pty = xmlSchemaGetPrimitiveType(ty);
   20151 	/*
   20152 	* (1) if a datatype T' is `derived` by `restriction` from an
   20153 	* atomic datatype T then the `value space` of T' is a subset of
   20154 	* the `value space` of T. */
   20155 	/*
   20156 	* (2) if datatypes T' and T'' are `derived` by `restriction`
   20157 	* from a common atomic ancestor T then the `value space`s of T'
   20158 	* and T'' may overlap.
   20159 	*/
   20160 	if (ptx != pty)
   20161 	    return(0);
   20162 	/*
   20163 	* We assume computed values to be normalized, so do a fast
   20164 	* string comparison for string based types.
   20165 	*/
   20166 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
   20167 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
   20168 	    if (! xmlStrEqual(
   20169 		xmlSchemaValueGetAsString(x),
   20170 		xmlSchemaValueGetAsString(y)))
   20171 		return (0);
   20172 	} else {
   20173 	    ret = xmlSchemaCompareValuesWhtsp(
   20174 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
   20175 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
   20176 	    if (ret == -2)
   20177 		return(-1);
   20178 	    if (ret != 0)
   20179 		return(0);
   20180 	}
   20181 	/*
   20182 	* Lists.
   20183 	*/
   20184 	x = xmlSchemaValueGetNext(x);
   20185 	if (x != NULL) {
   20186 	    y = xmlSchemaValueGetNext(y);
   20187 	    if (y == NULL)
   20188 		return (0);
   20189 	} else if (xmlSchemaValueGetNext(y) != NULL)
   20190 	    return (0);
   20191 	else
   20192 	    return (1);
   20193     }
   20194     return (0);
   20195 }
   20196 
   20197 /**
   20198  * xmlSchemaResolveAttrUseReferences:
   20199  * @item:  an attribute use
   20200  * @ctxt:  a parser context
   20201  *
   20202  * Resolves the referenced attribute declaration.
   20203  */
   20204 static int
   20205 xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
   20206 				  xmlSchemaParserCtxtPtr ctxt)
   20207 {
   20208     if ((ctxt == NULL) || (ause == NULL))
   20209 	return(-1);
   20210     if ((ause->attrDecl == NULL) ||
   20211 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
   20212 	return(0);
   20213 
   20214     {
   20215 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
   20216 
   20217 	/*
   20218 	* TODO: Evaluate, what errors could occur if the declaration is not
   20219 	* found.
   20220 	*/
   20221 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
   20222 	    ref->name, ref->targetNamespace);
   20223         if (ause->attrDecl == NULL) {
   20224 	    xmlSchemaPResCompAttrErr(ctxt,
   20225 		XML_SCHEMAP_SRC_RESOLVE,
   20226 		WXS_BASIC_CAST ause, ause->node,
   20227 		"ref", ref->name, ref->targetNamespace,
   20228 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20229             return(ctxt->err);;
   20230         }
   20231     }
   20232     return(0);
   20233 }
   20234 
   20235 /**
   20236  * xmlSchemaCheckAttrUsePropsCorrect:
   20237  * @ctxt:  a parser context
   20238  * @use:  an attribute use
   20239  *
   20240  * Schema Component Constraint:
   20241  * Attribute Use Correct (au-props-correct)
   20242  *
   20243  */
   20244 static int
   20245 xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
   20246 			     xmlSchemaAttributeUsePtr use)
   20247 {
   20248     if ((ctxt == NULL) || (use == NULL))
   20249 	return(-1);
   20250     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
   20251 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
   20252 	return(0);
   20253 
   20254     /*
   20255     * SPEC au-props-correct (1)
   20256     * "The values of the properties of an attribute use must be as
   20257     * described in the property tableau in The Attribute Use Schema
   20258     * Component ($3.5.1), modulo the impact of Missing
   20259     * Sub-components ($5.3)."
   20260     */
   20261 
   20262     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
   20263 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
   20264         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20265     {
   20266 	xmlSchemaPCustomErr(ctxt,
   20267 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20268 	    WXS_BASIC_CAST use, NULL,
   20269 	    "The attribute declaration has a 'fixed' value constraint "
   20270 	    ", thus the attribute use must also have a 'fixed' value "
   20271 	    "constraint",
   20272 	    NULL);
   20273 	return(ctxt->err);
   20274     }
   20275     /*
   20276     * Compute and check the value constraint's value.
   20277     */
   20278     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
   20279 	int ret;
   20280 	/*
   20281 	* TODO: The spec seems to be missing a check of the
   20282 	* value constraint of the attribute use. We will do it here.
   20283 	*/
   20284 	/*
   20285 	* SPEC a-props-correct (3)
   20286 	*/
   20287 	if (xmlSchemaIsDerivedFromBuiltInType(
   20288 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
   20289 	{
   20290 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20291 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20292 		NULL, WXS_BASIC_CAST use,
   20293 		"Value constraints are not allowed if the type definition "
   20294 		"is or is derived from xs:ID",
   20295 		NULL, NULL);
   20296 	    return(ctxt->err);
   20297 	}
   20298 
   20299 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
   20300 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
   20301 	    use->defValue, &(use->defVal),
   20302 	    1, 1, 0);
   20303 	if (ret != 0) {
   20304 	    if (ret < 0) {
   20305 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
   20306 		    "calling xmlSchemaVCheckCVCSimpleType()");
   20307 		return(-1);
   20308 	    }
   20309 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
   20310 		XML_SCHEMAP_AU_PROPS_CORRECT,
   20311 		NULL, WXS_BASIC_CAST use,
   20312 		"The value of the value constraint is not valid",
   20313 		NULL, NULL);
   20314 	    return(ctxt->err);
   20315 	}
   20316     }
   20317     /*
   20318     * SPEC au-props-correct (2)
   20319     * "If the {attribute declaration} has a fixed
   20320     * {value constraint}, then if the attribute use itself has a
   20321     * {value constraint}, it must also be fixed and its value must match
   20322     * that of the {attribute declaration}'s {value constraint}."
   20323     */
   20324     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
   20325 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
   20326     {
   20327 	if (! xmlSchemaAreValuesEqual(use->defVal,
   20328 		(WXS_ATTRUSE_DECL(use))->defVal))
   20329 	{
   20330 	    xmlSchemaPCustomErr(ctxt,
   20331 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
   20332 		WXS_BASIC_CAST use, NULL,
   20333 		"The 'fixed' value constraint of the attribute use "
   20334 		"must match the attribute declaration's value "
   20335 		"constraint '%s'",
   20336 		(WXS_ATTRUSE_DECL(use))->defValue);
   20337 	}
   20338 	return(ctxt->err);
   20339     }
   20340     return(0);
   20341 }
   20342 
   20343 
   20344 
   20345 
   20346 /**
   20347  * xmlSchemaResolveAttrTypeReferences:
   20348  * @item:  an attribute declaration
   20349  * @ctxt:  a parser context
   20350  *
   20351  * Resolves the referenced type definition component.
   20352  */
   20353 static int
   20354 xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
   20355 				   xmlSchemaParserCtxtPtr ctxt)
   20356 {
   20357     /*
   20358     * The simple type definition corresponding to the <simpleType> element
   20359     * information item in the [children], if present, otherwise the simple
   20360     * type definition `resolved` to by the `actual value` of the type
   20361     * [attribute], if present, otherwise the `simple ur-type definition`.
   20362     */
   20363     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
   20364 	return(0);
   20365     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
   20366     if (item->subtypes != NULL)
   20367         return(0);
   20368     if (item->typeName != NULL) {
   20369         xmlSchemaTypePtr type;
   20370 
   20371 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
   20372 	    item->typeNs);
   20373 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
   20374 	    xmlSchemaPResCompAttrErr(ctxt,
   20375 		XML_SCHEMAP_SRC_RESOLVE,
   20376 		WXS_BASIC_CAST item, item->node,
   20377 		"type", item->typeName, item->typeNs,
   20378 		XML_SCHEMA_TYPE_SIMPLE, NULL);
   20379 	    return(ctxt->err);
   20380 	} else
   20381 	    item->subtypes = type;
   20382 
   20383     } else {
   20384 	/*
   20385 	* The type defaults to the xs:anySimpleType.
   20386 	*/
   20387 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
   20388     }
   20389     return(0);
   20390 }
   20391 
   20392 /**
   20393  * xmlSchemaResolveIDCKeyReferences:
   20394  * @idc:  the identity-constraint definition
   20395  * @ctxt:  the schema parser context
   20396  * @name:  the attribute name
   20397  *
   20398  * Resolve keyRef references to key/unique IDCs.
   20399  * Schema Component Constraint:
   20400  *   Identity-constraint Definition Properties Correct (c-props-correct)
   20401  */
   20402 static int
   20403 xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
   20404 			  xmlSchemaParserCtxtPtr pctxt)
   20405 {
   20406     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
   20407         return(0);
   20408     if (idc->ref->name != NULL) {
   20409 	idc->ref->item = (xmlSchemaBasicItemPtr)
   20410 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
   20411 		idc->ref->targetNamespace);
   20412         if (idc->ref->item == NULL) {
   20413 	    /*
   20414 	    * TODO: It is actually not an error to fail to resolve
   20415 	    * at this stage. BUT we need to be that strict!
   20416 	    */
   20417 	    xmlSchemaPResCompAttrErr(pctxt,
   20418 		XML_SCHEMAP_SRC_RESOLVE,
   20419 		WXS_BASIC_CAST idc, idc->node,
   20420 		"refer", idc->ref->name,
   20421 		idc->ref->targetNamespace,
   20422 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
   20423             return(pctxt->err);
   20424 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   20425 	    /*
   20426 	    * SPEC c-props-correct (1)
   20427 	    */
   20428 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20429 		XML_SCHEMAP_C_PROPS_CORRECT,
   20430 		NULL, WXS_BASIC_CAST idc,
   20431 		"The keyref references a keyref",
   20432 		NULL, NULL);
   20433 	    idc->ref->item = NULL;
   20434 	    return(pctxt->err);
   20435 	} else {
   20436 	    if (idc->nbFields !=
   20437 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
   20438 		xmlChar *str = NULL;
   20439 		xmlSchemaIDCPtr refer;
   20440 
   20441 		refer = (xmlSchemaIDCPtr) idc->ref->item;
   20442 		/*
   20443 		* SPEC c-props-correct(2)
   20444 		* "If the {identity-constraint category} is keyref,
   20445 		* the cardinality of the {fields} must equal that of
   20446 		* the {fields} of the {referenced key}.
   20447 		*/
   20448 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20449 		    XML_SCHEMAP_C_PROPS_CORRECT,
   20450 		    NULL, WXS_BASIC_CAST idc,
   20451 		    "The cardinality of the keyref differs from the "
   20452 		    "cardinality of the referenced key/unique '%s'",
   20453 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
   20454 			refer->name),
   20455 		    NULL);
   20456 		FREE_AND_NULL(str)
   20457 		return(pctxt->err);
   20458 	    }
   20459 	}
   20460     }
   20461     return(0);
   20462 }
   20463 
   20464 static int
   20465 xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
   20466 				       xmlSchemaParserCtxtPtr pctxt)
   20467 {
   20468     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
   20469 	prohib->targetNamespace) == NULL) {
   20470 
   20471 	xmlSchemaPResCompAttrErr(pctxt,
   20472 	    XML_SCHEMAP_SRC_RESOLVE,
   20473 	    NULL, prohib->node,
   20474 	    "ref", prohib->name, prohib->targetNamespace,
   20475 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
   20476 	return(XML_SCHEMAP_SRC_RESOLVE);
   20477     }
   20478     return(0);
   20479 }
   20480 
   20481 #define WXS_REDEFINED_TYPE(c) \
   20482 (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
   20483 
   20484 #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
   20485 (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20486 
   20487 #define WXS_REDEFINED_ATTR_GROUP(c) \
   20488 (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20489 
   20490 static int
   20491 xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
   20492 {
   20493     int err = 0;
   20494     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20495     xmlSchemaBasicItemPtr prev, item;
   20496     int wasRedefined;
   20497 
   20498     if (redef == NULL)
   20499 	return(0);
   20500 
   20501     do {
   20502 	item = redef->item;
   20503 	/*
   20504 	* First try to locate the redefined component in the
   20505 	* schema graph starting with the redefined schema.
   20506 	* NOTE: According to this schema bug entry:
   20507 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
   20508 	*   it's not clear if the referenced component needs to originate
   20509 	*   from the <redefine>d schema _document_ or the schema; the latter
   20510 	*   would include all imported and included sub-schemas of the
   20511 	*   <redefine>d schema. Currenlty we latter approach is used.
   20512 	*   SUPPLEMENT: It seems that the WG moves towards the latter
   20513 	*   approach, so we are doing it right.
   20514 	*
   20515 	*/
   20516 	prev = xmlSchemaFindRedefCompInGraph(
   20517 	    redef->targetBucket, item->type,
   20518 	    redef->refName, redef->refTargetNs);
   20519 	if (prev == NULL) {
   20520 	    xmlChar *str = NULL;
   20521 	    xmlNodePtr node;
   20522 
   20523 	    /*
   20524 	    * SPEC src-redefine:
   20525 	    * (6.2.1) "The `actual value` of its own name attribute plus
   20526 	    * target namespace must successfully `resolve` to a model
   20527 	    * group definition in I."
   20528 	    * (7.2.1) "The `actual value` of its own name attribute plus
   20529 	    * target namespace must successfully `resolve` to an attribute
   20530 	    * group definition in I."
   20531 
   20532 	    *
   20533 	    * Note that, if we are redefining with the use of references
   20534 	    * to components, the spec assumes the src-resolve to be used;
   20535 	    * but this won't assure that we search only *inside* the
   20536 	    * redefined schema.
   20537 	    */
   20538 	    if (redef->reference)
   20539 		node = WXS_ITEM_NODE(redef->reference);
   20540 	    else
   20541 		node = WXS_ITEM_NODE(item);
   20542 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20543 		/*
   20544 		* TODO: error code.
   20545 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
   20546 		* reference kind.
   20547 		*/
   20548 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
   20549 		"The %s '%s' to be redefined could not be found in "
   20550 		"the redefined schema",
   20551 		WXS_ITEM_TYPE_NAME(item),
   20552 		xmlSchemaFormatQName(&str, redef->refTargetNs,
   20553 		    redef->refName));
   20554 	    FREE_AND_NULL(str);
   20555 	    err = pctxt->err;
   20556 	    redef = redef->next;
   20557 	    continue;
   20558 	}
   20559 	/*
   20560 	* TODO: Obtaining and setting the redefinition state is really
   20561 	* clumsy.
   20562 	*/
   20563 	wasRedefined = 0;
   20564 	switch (item->type) {
   20565 	    case XML_SCHEMA_TYPE_COMPLEX:
   20566 	    case XML_SCHEMA_TYPE_SIMPLE:
   20567 		if ((WXS_TYPE_CAST prev)->flags &
   20568 		    XML_SCHEMAS_TYPE_REDEFINED)
   20569 		{
   20570 		    wasRedefined = 1;
   20571 		    break;
   20572 		}
   20573 		/* Mark it as redefined. */
   20574 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
   20575 		/*
   20576 		* Assign the redefined type to the
   20577 		* base type of the redefining type.
   20578 		* TODO: How
   20579 		*/
   20580 		((xmlSchemaTypePtr) item)->baseType =
   20581 		    (xmlSchemaTypePtr) prev;
   20582 		break;
   20583 	    case XML_SCHEMA_TYPE_GROUP:
   20584 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
   20585 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
   20586 		{
   20587 		    wasRedefined = 1;
   20588 		    break;
   20589 		}
   20590 		/* Mark it as redefined. */
   20591 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
   20592 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
   20593 		if (redef->reference != NULL) {
   20594 		    /*
   20595 		    * Overwrite the QName-reference with the
   20596 		    * referenced model group def.
   20597 		    */
   20598 		    (WXS_PTC_CAST redef->reference)->children =
   20599 			WXS_TREE_CAST prev;
   20600 		}
   20601 		redef->target = prev;
   20602 		break;
   20603 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20604 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
   20605 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
   20606 		{
   20607 		    wasRedefined = 1;
   20608 		    break;
   20609 		}
   20610 		(WXS_ATTR_GROUP_CAST prev)->flags |=
   20611 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
   20612 		if (redef->reference != NULL) {
   20613 		    /*
   20614 		    * Assign the redefined attribute group to the
   20615 		    * QName-reference component.
   20616 		    * This is the easy case, since we will just
   20617 		    * expand the redefined group.
   20618 		    */
   20619 		    (WXS_QNAME_CAST redef->reference)->item = prev;
   20620 		    redef->target = NULL;
   20621 		} else {
   20622 		    /*
   20623 		    * This is the complicated case: we need
   20624 		    * to apply src-redefine (7.2.2) at a later
   20625 		    * stage, i.e. when attribute group references
   20626 		    * have beed expanded and simple types have
   20627 		    * beed fixed.
   20628 		    */
   20629 		    redef->target = prev;
   20630 		}
   20631 		break;
   20632 	    default:
   20633 		PERROR_INT("xmlSchemaResolveRedefReferences",
   20634 		    "Unexpected redefined component type");
   20635 		return(-1);
   20636 	}
   20637 	if (wasRedefined) {
   20638 	    xmlChar *str = NULL;
   20639 	    xmlNodePtr node;
   20640 
   20641 	    if (redef->reference)
   20642 		node = WXS_ITEM_NODE(redef->reference);
   20643 	    else
   20644 		node = WXS_ITEM_NODE(redef->item);
   20645 
   20646 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20647 		/* TODO: error code. */
   20648 		XML_SCHEMAP_SRC_REDEFINE,
   20649 		node, NULL,
   20650 		"The referenced %s was already redefined. Multiple "
   20651 		"redefinition of the same component is not supported",
   20652 		xmlSchemaGetComponentDesignation(&str, prev),
   20653 		NULL);
   20654 	    FREE_AND_NULL(str)
   20655 	    err = pctxt->err;
   20656 	    redef = redef->next;
   20657 	    continue;
   20658 	}
   20659 	redef = redef->next;
   20660     } while (redef != NULL);
   20661 
   20662     return(err);
   20663 }
   20664 
   20665 static int
   20666 xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
   20667 {
   20668     int err = 0;
   20669     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
   20670     xmlSchemaBasicItemPtr item;
   20671 
   20672     if (redef == NULL)
   20673 	return(0);
   20674 
   20675     do {
   20676 	if (redef->target == NULL) {
   20677 	    redef = redef->next;
   20678 	    continue;
   20679 	}
   20680 	item = redef->item;
   20681 
   20682 	switch (item->type) {
   20683 	    case XML_SCHEMA_TYPE_SIMPLE:
   20684 	    case XML_SCHEMA_TYPE_COMPLEX:
   20685 		/*
   20686 		* Since the spec wants the {name} of the redefined
   20687 		* type to be 'absent', we'll NULL it.
   20688 		*/
   20689 		(WXS_TYPE_CAST redef->target)->name = NULL;
   20690 
   20691 		/*
   20692 		* TODO: Seems like there's nothing more to do. The normal
   20693 		* inheritance mechanism is used. But not 100% sure.
   20694 		*/
   20695 		break;
   20696 	    case XML_SCHEMA_TYPE_GROUP:
   20697 		/*
   20698 		* URGENT TODO:
   20699 		* SPEC src-redefine:
   20700 		* (6.2.2) "The {model group} of the model group definition
   20701 		* which corresponds to it per XML Representation of Model
   20702 		* Group Definition Schema Components ($3.7.2) must be a
   20703 		* `valid restriction` of the {model group} of that model
   20704 		* group definition in I, as defined in Particle Valid
   20705 		* (Restriction) ($3.9.6)."
   20706 		*/
   20707 		break;
   20708 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20709 		/*
   20710 		* SPEC src-redefine:
   20711 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
   20712 		* the attribute group definition which corresponds to it
   20713 		* per XML Representation of Attribute Group Definition Schema
   20714 		* Components ($3.6.2) must be `valid restrictions` of the
   20715 		* {attribute uses} and {attribute wildcard} of that attribute
   20716 		* group definition in I, as defined in clause 2, clause 3 and
   20717 		* clause 4 of Derivation Valid (Restriction, Complex)
   20718 		* ($3.4.6) (where references to the base type definition are
   20719 		* understood as references to the attribute group definition
   20720 		* in I)."
   20721 		*/
   20722 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
   20723 		    XML_SCHEMA_ACTION_REDEFINE,
   20724 		    item, redef->target,
   20725 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
   20726 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
   20727 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
   20728 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
   20729 		if (err == -1)
   20730 		    return(-1);
   20731 		break;
   20732 	    default:
   20733 		break;
   20734 	}
   20735 	redef = redef->next;
   20736     } while (redef != NULL);
   20737     return(0);
   20738 }
   20739 
   20740 
   20741 static int
   20742 xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
   20743 		       xmlSchemaBucketPtr bucket)
   20744 {
   20745     xmlSchemaBasicItemPtr item;
   20746     int err;
   20747     xmlHashTablePtr *table;
   20748     const xmlChar *name;
   20749     int i;
   20750 
   20751 #define WXS_GET_GLOBAL_HASH(c, slot) { \
   20752     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
   20753 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
   20754     else \
   20755 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
   20756 
   20757     /*
   20758     * Add global components to the schema's hash tables.
   20759     * This is the place where duplicate components will be
   20760     * detected.
   20761     * TODO: I think normally we should support imports of the
   20762     *   same namespace from multiple locations. We don't do currently,
   20763     *   but if we do then according to:
   20764     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
   20765     *   we would need, if imported directly, to import redefined
   20766     *   components as well to be able to catch clashing components.
   20767     *   (I hope I'll still know what this means after some months :-()
   20768     */
   20769     if (bucket == NULL)
   20770 	return(-1);
   20771     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
   20772 	return(0);
   20773     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
   20774 
   20775     for (i = 0; i < bucket->globals->nbItems; i++) {
   20776 	item = bucket->globals->items[i];
   20777 	table = NULL;
   20778 	switch (item->type) {
   20779 	    case XML_SCHEMA_TYPE_COMPLEX:
   20780 	    case XML_SCHEMA_TYPE_SIMPLE:
   20781 		if (WXS_REDEFINED_TYPE(item))
   20782 		    continue;
   20783 		name = (WXS_TYPE_CAST item)->name;
   20784 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
   20785 		break;
   20786 	    case XML_SCHEMA_TYPE_ELEMENT:
   20787 		name = (WXS_ELEM_CAST item)->name;
   20788 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
   20789 		break;
   20790 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20791 		name = (WXS_ATTR_CAST item)->name;
   20792 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
   20793 		break;
   20794 	    case XML_SCHEMA_TYPE_GROUP:
   20795 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
   20796 		    continue;
   20797 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
   20798 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
   20799 		break;
   20800 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   20801 		if (WXS_REDEFINED_ATTR_GROUP(item))
   20802 		    continue;
   20803 		name = (WXS_ATTR_GROUP_CAST item)->name;
   20804 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
   20805 		break;
   20806 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20807 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20808 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20809 		name = (WXS_IDC_CAST item)->name;
   20810 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
   20811 		break;
   20812 	    case XML_SCHEMA_TYPE_NOTATION:
   20813 		name = ((xmlSchemaNotationPtr) item)->name;
   20814 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
   20815 		break;
   20816 	    default:
   20817 		PERROR_INT("xmlSchemaAddComponents",
   20818 		    "Unexpected global component type");
   20819 		continue;
   20820 	}
   20821 	if (*table == NULL) {
   20822 	    *table = xmlHashCreateDict(10, pctxt->dict);
   20823 	    if (*table == NULL) {
   20824 		PERROR_INT("xmlSchemaAddComponents",
   20825 		    "failed to create a component hash table");
   20826 		return(-1);
   20827 	    }
   20828 	}
   20829 	err = xmlHashAddEntry(*table, name, item);
   20830 	if (err != 0) {
   20831 	    xmlChar *str = NULL;
   20832 
   20833 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
   20834 		XML_SCHEMAP_REDEFINED_TYPE,
   20835 		WXS_ITEM_NODE(item),
   20836 		WXS_BASIC_CAST item,
   20837 		"A global %s '%s' does already exist",
   20838 		WXS_ITEM_TYPE_NAME(item),
   20839 		xmlSchemaGetComponentQName(&str, item));
   20840 	    FREE_AND_NULL(str);
   20841 	}
   20842     }
   20843     /*
   20844     * Process imported/included schemas.
   20845     */
   20846     if (bucket->relations != NULL) {
   20847 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
   20848 	do {
   20849 	    if ((rel->bucket != NULL) &&
   20850 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
   20851 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
   20852 		    return(-1);
   20853 	    }
   20854 	    rel = rel->next;
   20855 	} while (rel != NULL);
   20856     }
   20857     return(0);
   20858 }
   20859 
   20860 static int
   20861 xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
   20862 			 xmlSchemaBucketPtr rootBucket)
   20863 {
   20864     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
   20865     xmlSchemaTreeItemPtr item, *items;
   20866     int nbItems, i, ret = 0;
   20867     xmlSchemaBucketPtr oldbucket = con->bucket;
   20868     xmlSchemaElementPtr elemDecl;
   20869 
   20870 #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
   20871 
   20872     if ((con->pending == NULL) ||
   20873 	(con->pending->nbItems == 0))
   20874 	return(0);
   20875 
   20876     /*
   20877     * Since xmlSchemaFixupComplexType() will create new particles
   20878     * (local components), and those particle components need a bucket
   20879     * on the constructor, we'll assure here that the constructor has
   20880     * a bucket.
   20881     * TODO: Think about storing locals _only_ on the main bucket.
   20882     */
   20883     if (con->bucket == NULL)
   20884 	con->bucket = rootBucket;
   20885 
   20886     /* TODO:
   20887     * SPEC (src-redefine):
   20888     * (6.2) "If it has no such self-reference, then all of the
   20889     * following must be true:"
   20890 
   20891     * (6.2.2) The {model group} of the model group definition which
   20892     * corresponds to it per XML Representation of Model Group
   20893     * Definition Schema Components ($3.7.2) must be a `valid
   20894     * restriction` of the {model group} of that model group definition
   20895     * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
   20896     */
   20897     xmlSchemaCheckSRCRedefineFirst(pctxt);
   20898 
   20899     /*
   20900     * Add global components to the schemata's hash tables.
   20901     */
   20902     xmlSchemaAddComponents(pctxt, rootBucket);
   20903 
   20904     pctxt->ctxtType = NULL;
   20905     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   20906     nbItems = con->pending->nbItems;
   20907     /*
   20908     * Now that we have parsed *all* the schema document(s) and converted
   20909     * them to schema components, we can resolve references, apply component
   20910     * constraints, create the FSA from the content model, etc.
   20911     */
   20912     /*
   20913     * Resolve references of..
   20914     *
   20915     * 1. element declarations:
   20916     *   - the type definition
   20917     *   - the substitution group affiliation
   20918     * 2. simple/complex types:
   20919     *   - the base type definition
   20920     *   - the memberTypes of union types
   20921     *   - the itemType of list types
   20922     * 3. attributes declarations and attribute uses:
   20923     *   - the type definition
   20924     *   - if an attribute use, then the attribute declaration
   20925     * 4. attribute group references:
   20926     *   - the attribute group definition
   20927     * 5. particles:
   20928     *   - the term of the particle (e.g. a model group)
   20929     * 6. IDC key-references:
   20930     *   - the referenced IDC 'key' or 'unique' definition
   20931     * 7. Attribute prohibitions which had a "ref" attribute.
   20932     */
   20933     for (i = 0; i < nbItems; i++) {
   20934 	item = items[i];
   20935 	switch (item->type) {
   20936 	    case XML_SCHEMA_TYPE_ELEMENT:
   20937 		xmlSchemaResolveElementReferences(
   20938 		    (xmlSchemaElementPtr) item, pctxt);
   20939 		FIXHFAILURE;
   20940 		break;
   20941 	    case XML_SCHEMA_TYPE_COMPLEX:
   20942 	    case XML_SCHEMA_TYPE_SIMPLE:
   20943 		xmlSchemaResolveTypeReferences(
   20944 		    (xmlSchemaTypePtr) item, pctxt);
   20945 		FIXHFAILURE;
   20946 		break;
   20947 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   20948 		xmlSchemaResolveAttrTypeReferences(
   20949 		    (xmlSchemaAttributePtr) item, pctxt);
   20950 		FIXHFAILURE;
   20951 		break;
   20952 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   20953 		xmlSchemaResolveAttrUseReferences(
   20954 		    (xmlSchemaAttributeUsePtr) item, pctxt);
   20955 		FIXHFAILURE;
   20956 		break;
   20957 	    case XML_SCHEMA_EXTRA_QNAMEREF:
   20958 		if ((WXS_QNAME_CAST item)->itemType ==
   20959 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
   20960 		{
   20961 		    xmlSchemaResolveAttrGroupReferences(
   20962 			WXS_QNAME_CAST item, pctxt);
   20963 		}
   20964 		FIXHFAILURE;
   20965 		break;
   20966 	    case XML_SCHEMA_TYPE_SEQUENCE:
   20967 	    case XML_SCHEMA_TYPE_CHOICE:
   20968 	    case XML_SCHEMA_TYPE_ALL:
   20969 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
   20970 		    WXS_MODEL_GROUP_CAST item);
   20971 		FIXHFAILURE;
   20972 		break;
   20973 	    case XML_SCHEMA_TYPE_IDC_KEY:
   20974 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
   20975 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
   20976 		xmlSchemaResolveIDCKeyReferences(
   20977 		    (xmlSchemaIDCPtr) item, pctxt);
   20978 		FIXHFAILURE;
   20979 		break;
   20980 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
   20981 		/*
   20982 		* Handle attribue prohibition which had a
   20983 		* "ref" attribute.
   20984 		*/
   20985 		xmlSchemaResolveAttrUseProhibReferences(
   20986 		    WXS_ATTR_PROHIB_CAST item, pctxt);
   20987 		FIXHFAILURE;
   20988 		break;
   20989 	    default:
   20990 		break;
   20991 	}
   20992     }
   20993     if (pctxt->nberrors != 0)
   20994 	goto exit_error;
   20995 
   20996     /*
   20997     * Now that all references are resolved we
   20998     * can check for circularity of...
   20999     * 1. the base axis of type definitions
   21000     * 2. nested model group definitions
   21001     * 3. nested attribute group definitions
   21002     * TODO: check for circual substitution groups.
   21003     */
   21004     for (i = 0; i < nbItems; i++) {
   21005 	item = items[i];
   21006 	/*
   21007 	* Let's better stop on the first error here.
   21008 	*/
   21009 	switch (item->type) {
   21010 	    case XML_SCHEMA_TYPE_COMPLEX:
   21011 	    case XML_SCHEMA_TYPE_SIMPLE:
   21012 		xmlSchemaCheckTypeDefCircular(
   21013 		    (xmlSchemaTypePtr) item, pctxt);
   21014 		FIXHFAILURE;
   21015 		if (pctxt->nberrors != 0)
   21016 		    goto exit_error;
   21017 		break;
   21018 	    case XML_SCHEMA_TYPE_GROUP:
   21019 		xmlSchemaCheckGroupDefCircular(
   21020 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
   21021 		FIXHFAILURE;
   21022 		if (pctxt->nberrors != 0)
   21023 		    goto exit_error;
   21024 		break;
   21025 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21026 		xmlSchemaCheckAttrGroupCircular(
   21027 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
   21028 		FIXHFAILURE;
   21029 		if (pctxt->nberrors != 0)
   21030 		    goto exit_error;
   21031 		break;
   21032 	    default:
   21033 		break;
   21034 	}
   21035     }
   21036     if (pctxt->nberrors != 0)
   21037 	goto exit_error;
   21038     /*
   21039     * Model group definition references:
   21040     * Such a reference is reflected by a particle at the component
   21041     * level. Until now the 'term' of such particles pointed
   21042     * to the model group definition; this was done, in order to
   21043     * ease circularity checks. Now we need to set the 'term' of
   21044     * such particles to the model group of the model group definition.
   21045     */
   21046     for (i = 0; i < nbItems; i++) {
   21047 	item = items[i];
   21048 	switch (item->type) {
   21049 	    case XML_SCHEMA_TYPE_SEQUENCE:
   21050 	    case XML_SCHEMA_TYPE_CHOICE:
   21051 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
   21052 		    WXS_MODEL_GROUP_CAST item);
   21053 		break;
   21054 	    default:
   21055 		break;
   21056 	}
   21057     }
   21058     if (pctxt->nberrors != 0)
   21059 	goto exit_error;
   21060     /*
   21061     * Expand attribute group references of attribute group definitions.
   21062     */
   21063     for (i = 0; i < nbItems; i++) {
   21064 	item = items[i];
   21065 	switch (item->type) {
   21066             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21067 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
   21068 		    WXS_ATTR_GROUP_HAS_REFS(item))
   21069 		{
   21070 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
   21071 			WXS_ATTR_GROUP_CAST item);
   21072 		    FIXHFAILURE;
   21073 		}
   21074 		break;
   21075 	    default:
   21076 		break;
   21077 	}
   21078     }
   21079     if (pctxt->nberrors != 0)
   21080 	goto exit_error;
   21081     /*
   21082     * First compute the variety of simple types. This is needed as
   21083     * a seperate step, since otherwise we won't be able to detect
   21084     * circular union types in all cases.
   21085     */
   21086     for (i = 0; i < nbItems; i++) {
   21087 	item = items[i];
   21088 	switch (item->type) {
   21089             case XML_SCHEMA_TYPE_SIMPLE:
   21090 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
   21091 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
   21092 			(xmlSchemaTypePtr) item);
   21093 		    FIXHFAILURE;
   21094 		}
   21095 		break;
   21096 	    default:
   21097 		break;
   21098 	}
   21099     }
   21100     if (pctxt->nberrors != 0)
   21101 	goto exit_error;
   21102     /*
   21103     * Detect circular union types. Note that this needs the variety to
   21104     * be already computed.
   21105     */
   21106     for (i = 0; i < nbItems; i++) {
   21107 	item = items[i];
   21108 	switch (item->type) {
   21109             case XML_SCHEMA_TYPE_SIMPLE:
   21110 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
   21111 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
   21112 			(xmlSchemaTypePtr) item);
   21113 		    FIXHFAILURE;
   21114 		}
   21115 		break;
   21116 	    default:
   21117 		break;
   21118 	}
   21119     }
   21120     if (pctxt->nberrors != 0)
   21121 	goto exit_error;
   21122 
   21123     /*
   21124     * Do the complete type fixup for simple types.
   21125     */
   21126     for (i = 0; i < nbItems; i++) {
   21127 	item = items[i];
   21128 	switch (item->type) {
   21129             case XML_SCHEMA_TYPE_SIMPLE:
   21130 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21131 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
   21132 		    FIXHFAILURE;
   21133 		}
   21134 		break;
   21135 	    default:
   21136 		break;
   21137 	}
   21138     }
   21139     if (pctxt->nberrors != 0)
   21140 	goto exit_error;
   21141     /*
   21142     * At this point we need build and check all simple types.
   21143     */
   21144     /*
   21145     * Apply contraints for attribute declarations.
   21146     */
   21147     for (i = 0; i < nbItems; i++) {
   21148 	item = items[i];
   21149 	switch (item->type) {
   21150 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
   21151 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
   21152 		FIXHFAILURE;
   21153 		break;
   21154 	    default:
   21155 		break;
   21156 	}
   21157     }
   21158     if (pctxt->nberrors != 0)
   21159 	goto exit_error;
   21160     /*
   21161     * Apply constraints for attribute uses.
   21162     */
   21163     for (i = 0; i < nbItems; i++) {
   21164 	item = items[i];
   21165 	switch (item->type) {
   21166 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
   21167 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
   21168 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
   21169 			WXS_ATTR_USE_CAST item);
   21170 		    FIXHFAILURE;
   21171 		}
   21172 		break;
   21173 	    default:
   21174 		break;
   21175 	}
   21176     }
   21177     if (pctxt->nberrors != 0)
   21178 	goto exit_error;
   21179 
   21180     /*
   21181     * Apply constraints for attribute group definitions.
   21182     */
   21183     for (i = 0; i < nbItems; i++) {
   21184 	item = items[i];
   21185 	switch (item->type) {
   21186 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
   21187 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
   21188 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
   21189 	    {
   21190 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
   21191 		FIXHFAILURE;
   21192 	    }
   21193 	    break;
   21194 	default:
   21195 	    break;
   21196 	}
   21197     }
   21198     if (pctxt->nberrors != 0)
   21199 	goto exit_error;
   21200 
   21201     /*
   21202     * Apply constraints for redefinitions.
   21203     */
   21204     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
   21205 	xmlSchemaCheckSRCRedefineSecond(pctxt);
   21206     if (pctxt->nberrors != 0)
   21207 	goto exit_error;
   21208 
   21209     /*
   21210     * Complex types are builded and checked.
   21211     */
   21212     for (i = 0; i < nbItems; i++) {
   21213 	item = con->pending->items[i];
   21214 	switch (item->type) {
   21215 	    case XML_SCHEMA_TYPE_COMPLEX:
   21216 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
   21217 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
   21218 		    FIXHFAILURE;
   21219 		}
   21220 		break;
   21221 	    default:
   21222 		break;
   21223 	}
   21224     }
   21225     if (pctxt->nberrors != 0)
   21226 	goto exit_error;
   21227 
   21228     /*
   21229     * The list could have changed, since xmlSchemaFixupComplexType()
   21230     * will create particles and model groups in some cases.
   21231     */
   21232     items = (xmlSchemaTreeItemPtr *) con->pending->items;
   21233     nbItems = con->pending->nbItems;
   21234 
   21235     /*
   21236     * Apply some constraints for element declarations.
   21237     */
   21238     for (i = 0; i < nbItems; i++) {
   21239 	item = items[i];
   21240 	switch (item->type) {
   21241 	    case XML_SCHEMA_TYPE_ELEMENT:
   21242 		elemDecl = (xmlSchemaElementPtr) item;
   21243 
   21244 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
   21245 		{
   21246 		    xmlSchemaCheckElementDeclComponent(
   21247 			(xmlSchemaElementPtr) elemDecl, pctxt);
   21248 		    FIXHFAILURE;
   21249 		}
   21250 
   21251 #ifdef WXS_ELEM_DECL_CONS_ENABLED
   21252 		/*
   21253 		* Schema Component Constraint: Element Declarations Consistent
   21254 		* Apply this constraint to local types of element declarations.
   21255 		*/
   21256 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
   21257 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
   21258 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
   21259 		{
   21260 		    xmlSchemaCheckElementDeclConsistent(pctxt,
   21261 			WXS_BASIC_CAST elemDecl,
   21262 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
   21263 			NULL, NULL, 0);
   21264 		}
   21265 #endif
   21266 		break;
   21267 	    default:
   21268 		break;
   21269 	}
   21270     }
   21271     if (pctxt->nberrors != 0)
   21272 	goto exit_error;
   21273 
   21274     /*
   21275     * Finally we can build the automaton from the content model of
   21276     * complex types.
   21277     */
   21278 
   21279     for (i = 0; i < nbItems; i++) {
   21280 	item = items[i];
   21281 	switch (item->type) {
   21282 	    case XML_SCHEMA_TYPE_COMPLEX:
   21283 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
   21284 		/* FIXHFAILURE; */
   21285 		break;
   21286 	    default:
   21287 		break;
   21288 	}
   21289     }
   21290     if (pctxt->nberrors != 0)
   21291 	goto exit_error;
   21292     /*
   21293     * URGENT TODO: cos-element-consistent
   21294     */
   21295     goto exit;
   21296 
   21297 exit_error:
   21298     ret = pctxt->err;
   21299     goto exit;
   21300 
   21301 exit_failure:
   21302     ret = -1;
   21303 
   21304 exit:
   21305     /*
   21306     * Reset the constructor. This is needed for XSI acquisition, since
   21307     * those items will be processed over and over again for every XSI
   21308     * if not cleared here.
   21309     */
   21310     con->bucket = oldbucket;
   21311     con->pending->nbItems = 0;
   21312     if (con->substGroups != NULL) {
   21313 	xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
   21314 	con->substGroups = NULL;
   21315     }
   21316     if (con->redefs != NULL) {
   21317 	xmlSchemaRedefListFree(con->redefs);
   21318 	con->redefs = NULL;
   21319     }
   21320     return(ret);
   21321 }
   21322 /**
   21323  * xmlSchemaParse:
   21324  * @ctxt:  a schema validation context
   21325  *
   21326  * parse a schema definition resource and build an internal
   21327  * XML Shema struture which can be used to validate instances.
   21328  *
   21329  * Returns the internal XML Schema structure built from the resource or
   21330  *         NULL in case of error
   21331  */
   21332 xmlSchemaPtr
   21333 xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
   21334 {
   21335     xmlSchemaPtr mainSchema = NULL;
   21336     xmlSchemaBucketPtr bucket = NULL;
   21337     int res;
   21338 
   21339     /*
   21340     * This one is used if the schema to be parsed was specified via
   21341     * the API; i.e. not automatically by the validated instance document.
   21342     */
   21343 
   21344     xmlSchemaInitTypes();
   21345 
   21346     if (ctxt == NULL)
   21347         return (NULL);
   21348 
   21349     /* TODO: Init the context. Is this all we need?*/
   21350     ctxt->nberrors = 0;
   21351     ctxt->err = 0;
   21352     ctxt->counter = 0;
   21353 
   21354     /* Create the *main* schema. */
   21355     mainSchema = xmlSchemaNewSchema(ctxt);
   21356     if (mainSchema == NULL)
   21357 	goto exit_failure;
   21358     /*
   21359     * Create the schema constructor.
   21360     */
   21361     if (ctxt->constructor == NULL) {
   21362 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
   21363 	if (ctxt->constructor == NULL)
   21364 	    return(NULL);
   21365 	/* Take ownership of the constructor to be able to free it. */
   21366 	ctxt->ownsConstructor = 1;
   21367     }
   21368     ctxt->constructor->mainSchema = mainSchema;
   21369     /*
   21370     * Locate and add the schema document.
   21371     */
   21372     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
   21373 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
   21374 	NULL, NULL, &bucket);
   21375     if (res == -1)
   21376 	goto exit_failure;
   21377     if (res != 0)
   21378 	goto exit;
   21379 
   21380     if (bucket == NULL) {
   21381 	/* TODO: Error code, actually we failed to *locate* the schema. */
   21382 	if (ctxt->URL)
   21383 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21384 		NULL, NULL,
   21385 		"Failed to locate the main schema resource at '%s'",
   21386 		ctxt->URL, NULL);
   21387 	else
   21388 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
   21389 		NULL, NULL,
   21390 		"Failed to locate the main schema resource",
   21391 		    NULL, NULL);
   21392 	goto exit;
   21393     }
   21394     /* Then do the parsing for good. */
   21395     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
   21396 	goto exit_failure;
   21397     if (ctxt->nberrors != 0)
   21398 	goto exit;
   21399 
   21400     mainSchema->doc = bucket->doc;
   21401     mainSchema->preserve = ctxt->preserve;
   21402 
   21403     ctxt->schema = mainSchema;
   21404 
   21405     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
   21406 	goto exit_failure;
   21407 
   21408     /*
   21409     * TODO: This is not nice, since we cannot distinguish from the
   21410     * result if there was an internal error or not.
   21411     */
   21412 exit:
   21413     if (ctxt->nberrors != 0) {
   21414 	if (mainSchema) {
   21415 	    xmlSchemaFree(mainSchema);
   21416 	    mainSchema = NULL;
   21417 	}
   21418 	if (ctxt->constructor) {
   21419 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21420 	    ctxt->constructor = NULL;
   21421 	    ctxt->ownsConstructor = 0;
   21422 	}
   21423     }
   21424     ctxt->schema = NULL;
   21425     return(mainSchema);
   21426 exit_failure:
   21427     /*
   21428     * Quite verbose, but should catch internal errors, which were
   21429     * not communitated.
   21430     */
   21431     if (mainSchema) {
   21432         xmlSchemaFree(mainSchema);
   21433 	mainSchema = NULL;
   21434     }
   21435     if (ctxt->constructor) {
   21436 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
   21437 	ctxt->constructor = NULL;
   21438 	ctxt->ownsConstructor = 0;
   21439     }
   21440     PERROR_INT2("xmlSchemaParse",
   21441 	"An internal error occurred");
   21442     ctxt->schema = NULL;
   21443     return(NULL);
   21444 }
   21445 
   21446 /**
   21447  * xmlSchemaSetParserErrors:
   21448  * @ctxt:  a schema validation context
   21449  * @err:  the error callback
   21450  * @warn:  the warning callback
   21451  * @ctx:  contextual data for the callbacks
   21452  *
   21453  * Set the callback functions used to handle errors for a validation context
   21454  */
   21455 void
   21456 xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21457                          xmlSchemaValidityErrorFunc err,
   21458                          xmlSchemaValidityWarningFunc warn, void *ctx)
   21459 {
   21460     if (ctxt == NULL)
   21461         return;
   21462     ctxt->error = err;
   21463     ctxt->warning = warn;
   21464     ctxt->errCtxt = ctx;
   21465     if (ctxt->vctxt != NULL)
   21466 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
   21467 }
   21468 
   21469 /**
   21470  * xmlSchemaSetParserStructuredErrors:
   21471  * @ctxt:  a schema parser context
   21472  * @serror:  the structured error function
   21473  * @ctx: the functions context
   21474  *
   21475  * Set the structured error callback
   21476  */
   21477 void
   21478 xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
   21479 				   xmlStructuredErrorFunc serror,
   21480 				   void *ctx)
   21481 {
   21482     if (ctxt == NULL)
   21483 	return;
   21484     ctxt->serror = serror;
   21485     ctxt->errCtxt = ctx;
   21486     if (ctxt->vctxt != NULL)
   21487 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
   21488 }
   21489 
   21490 /**
   21491  * xmlSchemaGetParserErrors:
   21492  * @ctxt:  a XMl-Schema parser context
   21493  * @err: the error callback result
   21494  * @warn: the warning callback result
   21495  * @ctx: contextual data for the callbacks result
   21496  *
   21497  * Get the callback information used to handle errors for a parser context
   21498  *
   21499  * Returns -1 in case of failure, 0 otherwise
   21500  */
   21501 int
   21502 xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
   21503 			 xmlSchemaValidityErrorFunc * err,
   21504 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
   21505 {
   21506 	if (ctxt == NULL)
   21507 		return(-1);
   21508 	if (err != NULL)
   21509 		*err = ctxt->error;
   21510 	if (warn != NULL)
   21511 		*warn = ctxt->warning;
   21512 	if (ctx != NULL)
   21513 		*ctx = ctxt->errCtxt;
   21514 	return(0);
   21515 }
   21516 
   21517 /**
   21518  * xmlSchemaFacetTypeToString:
   21519  * @type:  the facet type
   21520  *
   21521  * Convert the xmlSchemaTypeType to a char string.
   21522  *
   21523  * Returns the char string representation of the facet type if the
   21524  *     type is a facet and an "Internal Error" string otherwise.
   21525  */
   21526 static const xmlChar *
   21527 xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
   21528 {
   21529     switch (type) {
   21530         case XML_SCHEMA_FACET_PATTERN:
   21531             return (BAD_CAST "pattern");
   21532         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
   21533             return (BAD_CAST "maxExclusive");
   21534         case XML_SCHEMA_FACET_MAXINCLUSIVE:
   21535             return (BAD_CAST "maxInclusive");
   21536         case XML_SCHEMA_FACET_MINEXCLUSIVE:
   21537             return (BAD_CAST "minExclusive");
   21538         case XML_SCHEMA_FACET_MININCLUSIVE:
   21539             return (BAD_CAST "minInclusive");
   21540         case XML_SCHEMA_FACET_WHITESPACE:
   21541             return (BAD_CAST "whiteSpace");
   21542         case XML_SCHEMA_FACET_ENUMERATION:
   21543             return (BAD_CAST "enumeration");
   21544         case XML_SCHEMA_FACET_LENGTH:
   21545             return (BAD_CAST "length");
   21546         case XML_SCHEMA_FACET_MAXLENGTH:
   21547             return (BAD_CAST "maxLength");
   21548         case XML_SCHEMA_FACET_MINLENGTH:
   21549             return (BAD_CAST "minLength");
   21550         case XML_SCHEMA_FACET_TOTALDIGITS:
   21551             return (BAD_CAST "totalDigits");
   21552         case XML_SCHEMA_FACET_FRACTIONDIGITS:
   21553             return (BAD_CAST "fractionDigits");
   21554         default:
   21555             break;
   21556     }
   21557     return (BAD_CAST "Internal Error");
   21558 }
   21559 
   21560 static xmlSchemaWhitespaceValueType
   21561 xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
   21562 {
   21563     /*
   21564     * The normalization type can be changed only for types which are derived
   21565     * from xsd:string.
   21566     */
   21567     if (type->type == XML_SCHEMA_TYPE_BASIC) {
   21568 	/*
   21569 	* Note that we assume a whitespace of preserve for anySimpleType.
   21570 	*/
   21571 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
   21572 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
   21573 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
   21574 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
   21575 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
   21576 	else {
   21577 	    /*
   21578 	    * For all `atomic` datatypes other than string (and types `derived`
   21579 	    * by `restriction` from it) the value of whiteSpace is fixed to
   21580 	    * collapse
   21581 	    * Note that this includes built-in list datatypes.
   21582 	    */
   21583 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
   21584 	}
   21585     } else if (WXS_IS_LIST(type)) {
   21586 	/*
   21587 	* For list types the facet "whiteSpace" is fixed to "collapse".
   21588 	*/
   21589 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21590     } else if (WXS_IS_UNION(type)) {
   21591 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
   21592     } else if (WXS_IS_ATOMIC(type)) {
   21593 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
   21594 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
   21595 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
   21596 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
   21597 	else
   21598 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
   21599     }
   21600     return (-1);
   21601 }
   21602 
   21603 /************************************************************************
   21604  *									*
   21605  *			Simple type validation				*
   21606  *									*
   21607  ************************************************************************/
   21608 
   21609 
   21610 /************************************************************************
   21611  *									*
   21612  *			DOM Validation code				*
   21613  *									*
   21614  ************************************************************************/
   21615 
   21616 /**
   21617  * xmlSchemaAssembleByLocation:
   21618  * @pctxt:  a schema parser context
   21619  * @vctxt:  a schema validation context
   21620  * @schema: the existing schema
   21621  * @node: the node that fired the assembling
   21622  * @nsName: the namespace name of the new schema
   21623  * @location: the location of the schema
   21624  *
   21625  * Expands an existing schema by an additional schema.
   21626  *
   21627  * Returns 0 if the new schema is correct, a positive error code
   21628  * number otherwise and -1 in case of an internal or API error.
   21629  */
   21630 static int
   21631 xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
   21632 			    xmlSchemaPtr schema,
   21633 			    xmlNodePtr node,
   21634 			    const xmlChar *nsName,
   21635 			    const xmlChar *location)
   21636 {
   21637     int ret = 0;
   21638     xmlSchemaParserCtxtPtr pctxt;
   21639     xmlSchemaBucketPtr bucket = NULL;
   21640 
   21641     if ((vctxt == NULL) || (schema == NULL))
   21642 	return (-1);
   21643 
   21644     if (vctxt->pctxt == NULL) {
   21645 	VERROR_INT("xmlSchemaAssembleByLocation",
   21646 	    "no parser context available");
   21647 	return(-1);
   21648     }
   21649     pctxt = vctxt->pctxt;
   21650     if (pctxt->constructor == NULL) {
   21651 	PERROR_INT("xmlSchemaAssembleByLocation",
   21652 	    "no constructor");
   21653 	return(-1);
   21654     }
   21655     /*
   21656     * Acquire the schema document.
   21657     */
   21658     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
   21659 	location, node);
   21660     /*
   21661     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
   21662     * the process will automatically change this to
   21663     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
   21664     */
   21665     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
   21666 	location, NULL, NULL, 0, node, NULL, nsName,
   21667 	&bucket);
   21668     if (ret != 0)
   21669 	return(ret);
   21670     if (bucket == NULL) {
   21671 	/*
   21672 	* Generate a warning that the document could not be located.
   21673 	*/
   21674 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21675 	    node, NULL,
   21676 	    "The document at location '%s' could not be acquired",
   21677 	    location, NULL, NULL);
   21678 	return(ret);
   21679     }
   21680     /*
   21681     * The first located schema will be handled as if all other
   21682     * schemas imported by XSI were imported by this first schema.
   21683     */
   21684     if ((bucket != NULL) &&
   21685 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
   21686 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
   21687     /*
   21688     * TODO: Is this handled like an import? I.e. is it not an error
   21689     * if the schema cannot be located?
   21690     */
   21691     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
   21692 	return(0);
   21693     /*
   21694     * We will reuse the parser context for every schema imported
   21695     * directly via XSI. So reset the context.
   21696     */
   21697     pctxt->nberrors = 0;
   21698     pctxt->err = 0;
   21699     pctxt->doc = bucket->doc;
   21700 
   21701     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
   21702     if (ret == -1) {
   21703 	pctxt->doc = NULL;
   21704 	goto exit_failure;
   21705     }
   21706     /* Paranoid error channelling. */
   21707     if ((ret == 0) && (pctxt->nberrors != 0))
   21708 	ret = pctxt->err;
   21709     if (pctxt->nberrors == 0) {
   21710 	/*
   21711 	* Only bother to fixup pending components, if there was
   21712 	* no error yet.
   21713 	* For every XSI acquired schema (and its sub-schemata) we will
   21714 	* fixup the components.
   21715 	*/
   21716 	xmlSchemaFixupComponents(pctxt, bucket);
   21717 	ret = pctxt->err;
   21718 	/*
   21719 	* Not nice, but we need somehow to channel the schema parser
   21720 	* error to the validation context.
   21721 	*/
   21722 	if ((ret != 0) && (vctxt->err == 0))
   21723 	    vctxt->err = ret;
   21724 	vctxt->nberrors += pctxt->nberrors;
   21725     } else {
   21726 	/* Add to validation error sum. */
   21727 	vctxt->nberrors += pctxt->nberrors;
   21728     }
   21729     pctxt->doc = NULL;
   21730     return(ret);
   21731 exit_failure:
   21732     pctxt->doc = NULL;
   21733     return (-1);
   21734 }
   21735 
   21736 static xmlSchemaAttrInfoPtr
   21737 xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
   21738 			 int metaType)
   21739 {
   21740     if (vctxt->nbAttrInfos == 0)
   21741 	return (NULL);
   21742     {
   21743 	int i;
   21744 	xmlSchemaAttrInfoPtr iattr;
   21745 
   21746 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
   21747 	    iattr = vctxt->attrInfos[i];
   21748 	    if (iattr->metaType == metaType)
   21749 		return (iattr);
   21750 	}
   21751 
   21752     }
   21753     return (NULL);
   21754 }
   21755 
   21756 /**
   21757  * xmlSchemaAssembleByXSI:
   21758  * @vctxt:  a schema validation context
   21759  *
   21760  * Expands an existing schema by an additional schema using
   21761  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
   21762  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
   21763  * must be set to 1.
   21764  *
   21765  * Returns 0 if the new schema is correct, a positive error code
   21766  * number otherwise and -1 in case of an internal or API error.
   21767  */
   21768 static int
   21769 xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
   21770 {
   21771     const xmlChar *cur, *end;
   21772     const xmlChar *nsname = NULL, *location;
   21773     int count = 0;
   21774     int ret = 0;
   21775     xmlSchemaAttrInfoPtr iattr;
   21776 
   21777     /*
   21778     * Parse the value; we will assume an even number of values
   21779     * to be given (this is how Xerces and XSV work).
   21780     *
   21781     * URGENT TODO: !! This needs to work for both
   21782     * @noNamespaceSchemaLocation AND @schemaLocation on the same
   21783     * element !!
   21784     */
   21785     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21786 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
   21787     if (iattr == NULL)
   21788 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   21789 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
   21790     if (iattr == NULL)
   21791 	return (0);
   21792     cur = iattr->value;
   21793     do {
   21794 	/*
   21795 	* TODO: Move the string parsing mechanism away from here.
   21796 	*/
   21797 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
   21798 	    /*
   21799 	    * Get the namespace name.
   21800 	    */
   21801 	    while (IS_BLANK_CH(*cur))
   21802 		cur++;
   21803 	    end = cur;
   21804 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21805 		end++;
   21806 	    if (end == cur)
   21807 		break;
   21808 	    count++; /* TODO: Don't use the schema's dict. */
   21809 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21810 	    cur = end;
   21811 	}
   21812 	/*
   21813 	* Get the URI.
   21814 	*/
   21815 	while (IS_BLANK_CH(*cur))
   21816 	    cur++;
   21817 	end = cur;
   21818 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   21819 	    end++;
   21820 	if (end == cur) {
   21821 	    if (iattr->metaType ==
   21822 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
   21823 	    {
   21824 		/*
   21825 		* If using @schemaLocation then tuples are expected.
   21826 		* I.e. the namespace name *and* the document's URI.
   21827 		*/
   21828 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
   21829 		    iattr->node, NULL,
   21830 		    "The value must consist of tuples: the target namespace "
   21831 		    "name and the document's URI", NULL, NULL, NULL);
   21832 	    }
   21833 	    break;
   21834 	}
   21835 	count++; /* TODO: Don't use the schema's dict. */
   21836 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
   21837 	cur = end;
   21838 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
   21839 	    iattr->node, nsname, location);
   21840 	if (ret == -1) {
   21841 	    VERROR_INT("xmlSchemaAssembleByXSI",
   21842 		"assembling schemata");
   21843 	    return (-1);
   21844 	}
   21845     } while (*cur != 0);
   21846     return (ret);
   21847 }
   21848 
   21849 static const xmlChar *
   21850 xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
   21851 			 const xmlChar *prefix)
   21852 {
   21853     if (vctxt->sax != NULL) {
   21854 	int i, j;
   21855 	xmlSchemaNodeInfoPtr inode;
   21856 
   21857 	for (i = vctxt->depth; i >= 0; i--) {
   21858 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
   21859 		inode = vctxt->elemInfos[i];
   21860 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
   21861 		    if (((prefix == NULL) &&
   21862 			    (inode->nsBindings[j] == NULL)) ||
   21863 			((prefix != NULL) && xmlStrEqual(prefix,
   21864 			    inode->nsBindings[j]))) {
   21865 
   21866 			/*
   21867 			* Note that the namespace bindings are already
   21868 			* in a string dict.
   21869 			*/
   21870 			return (inode->nsBindings[j+1]);
   21871 		    }
   21872 		}
   21873 	    }
   21874 	}
   21875 	return (NULL);
   21876 #ifdef LIBXML_READER_ENABLED
   21877     } else if (vctxt->reader != NULL) {
   21878 	xmlChar *nsName;
   21879 
   21880 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
   21881 	if (nsName != NULL) {
   21882 	    const xmlChar *ret;
   21883 
   21884 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
   21885 	    xmlFree(nsName);
   21886 	    return (ret);
   21887 	} else
   21888 	    return (NULL);
   21889 #endif
   21890     } else {
   21891 	xmlNsPtr ns;
   21892 
   21893 	if ((vctxt->inode->node == NULL) ||
   21894 	    (vctxt->inode->node->doc == NULL)) {
   21895 	    VERROR_INT("xmlSchemaLookupNamespace",
   21896 		"no node or node's doc avaliable");
   21897 	    return (NULL);
   21898 	}
   21899 	ns = xmlSearchNs(vctxt->inode->node->doc,
   21900 	    vctxt->inode->node, prefix);
   21901 	if (ns != NULL)
   21902 	    return (ns->href);
   21903 	return (NULL);
   21904     }
   21905 }
   21906 
   21907 /*
   21908 * This one works on the schema of the validation context.
   21909 */
   21910 static int
   21911 xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
   21912 			  xmlSchemaPtr schema,
   21913 			  xmlNodePtr node,
   21914 			  const xmlChar *value,
   21915 			  xmlSchemaValPtr *val,
   21916 			  int valNeeded)
   21917 {
   21918     int ret;
   21919 
   21920     if (vctxt && (vctxt->schema == NULL)) {
   21921 	VERROR_INT("xmlSchemaValidateNotation",
   21922 	    "a schema is needed on the validation context");
   21923 	return (-1);
   21924     }
   21925     ret = xmlValidateQName(value, 1);
   21926     if (ret != 0)
   21927 	return (ret);
   21928     {
   21929 	xmlChar *localName = NULL;
   21930 	xmlChar *prefix = NULL;
   21931 
   21932 	localName = xmlSplitQName2(value, &prefix);
   21933 	if (prefix != NULL) {
   21934 	    const xmlChar *nsName = NULL;
   21935 
   21936 	    if (vctxt != NULL)
   21937 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
   21938 	    else if (node != NULL) {
   21939 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
   21940 		if (ns != NULL)
   21941 		    nsName = ns->href;
   21942 	    } else {
   21943 		xmlFree(prefix);
   21944 		xmlFree(localName);
   21945 		return (1);
   21946 	    }
   21947 	    if (nsName == NULL) {
   21948 		xmlFree(prefix);
   21949 		xmlFree(localName);
   21950 		return (1);
   21951 	    }
   21952 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
   21953 		if ((valNeeded) && (val != NULL)) {
   21954 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
   21955 						       xmlStrdup(nsName));
   21956 		    if (*val == NULL)
   21957 			ret = -1;
   21958 		}
   21959 	    } else
   21960 		ret = 1;
   21961 	    xmlFree(prefix);
   21962 	    xmlFree(localName);
   21963 	} else {
   21964 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
   21965 		if (valNeeded && (val != NULL)) {
   21966 		    (*val) = xmlSchemaNewNOTATIONValue(
   21967 			BAD_CAST xmlStrdup(value), NULL);
   21968 		    if (*val == NULL)
   21969 			ret = -1;
   21970 		}
   21971 	    } else
   21972 		return (1);
   21973 	}
   21974     }
   21975     return (ret);
   21976 }
   21977 
   21978 static int
   21979 xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
   21980 		       const xmlChar* lname,
   21981 		       const xmlChar* nsname)
   21982 {
   21983     int i;
   21984 
   21985     lname = xmlDictLookup(vctxt->dict, lname, -1);
   21986     if (lname == NULL)
   21987 	return(-1);
   21988     if (nsname != NULL) {
   21989 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
   21990 	if (nsname == NULL)
   21991 	    return(-1);
   21992     }
   21993     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
   21994 	if ((vctxt->nodeQNames->items [i] == lname) &&
   21995 	    (vctxt->nodeQNames->items[i +1] == nsname))
   21996 	    /* Already there */
   21997 	    return(i);
   21998     }
   21999     /* Add new entry. */
   22000     i = vctxt->nodeQNames->nbItems;
   22001     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
   22002     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
   22003     return(i);
   22004 }
   22005 
   22006 /************************************************************************
   22007  *									*
   22008  *  Validation of identity-constraints (IDC)                            *
   22009  *									*
   22010  ************************************************************************/
   22011 
   22012 /**
   22013  * xmlSchemaAugmentIDC:
   22014  * @idcDef: the IDC definition
   22015  *
   22016  * Creates an augmented IDC definition item.
   22017  *
   22018  * Returns the item, or NULL on internal errors.
   22019  */
   22020 static void
   22021 xmlSchemaAugmentIDC(void *payload, void *data,
   22022                     const xmlChar *name ATTRIBUTE_UNUSED)
   22023 {
   22024     xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
   22025     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
   22026     xmlSchemaIDCAugPtr aidc;
   22027 
   22028     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
   22029     if (aidc == NULL) {
   22030 	xmlSchemaVErrMemory(vctxt,
   22031 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
   22032 	    NULL);
   22033 	return;
   22034     }
   22035     aidc->keyrefDepth = -1;
   22036     aidc->def = idcDef;
   22037     aidc->next = NULL;
   22038     if (vctxt->aidcs == NULL)
   22039 	vctxt->aidcs = aidc;
   22040     else {
   22041 	aidc->next = vctxt->aidcs;
   22042 	vctxt->aidcs = aidc;
   22043     }
   22044     /*
   22045     * Save if we have keyrefs at all.
   22046     */
   22047     if ((vctxt->hasKeyrefs == 0) &&
   22048 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
   22049 	vctxt->hasKeyrefs = 1;
   22050 }
   22051 
   22052 /**
   22053  * xmlSchemaAugmentImportedIDC:
   22054  * @imported: the imported schema
   22055  *
   22056  * Creates an augmented IDC definition for the imported schema.
   22057  */
   22058 static void
   22059 xmlSchemaAugmentImportedIDC(void *payload, void *data,
   22060                             const xmlChar *name ATTRIBUTE_UNUSED) {
   22061     xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
   22062     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
   22063     if (imported->schema->idcDef != NULL) {
   22064 	    xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
   22065     }
   22066 }
   22067 
   22068 /**
   22069  * xmlSchemaIDCNewBinding:
   22070  * @idcDef: the IDC definition of this binding
   22071  *
   22072  * Creates a new IDC binding.
   22073  *
   22074  * Returns the new IDC binding, NULL on internal errors.
   22075  */
   22076 static xmlSchemaPSVIIDCBindingPtr
   22077 xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
   22078 {
   22079     xmlSchemaPSVIIDCBindingPtr ret;
   22080 
   22081     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
   22082 	    sizeof(xmlSchemaPSVIIDCBinding));
   22083     if (ret == NULL) {
   22084 	xmlSchemaVErrMemory(NULL,
   22085 	    "allocating a PSVI IDC binding item", NULL);
   22086 	return (NULL);
   22087     }
   22088     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
   22089     ret->definition = idcDef;
   22090     return (ret);
   22091 }
   22092 
   22093 /**
   22094  * xmlSchemaIDCStoreNodeTableItem:
   22095  * @vctxt: the WXS validation context
   22096  * @item: the IDC node table item
   22097  *
   22098  * The validation context is used to store IDC node table items.
   22099  * They are stored to avoid copying them if IDC node-tables are merged
   22100  * with corresponding parent IDC node-tables (bubbling).
   22101  *
   22102  * Returns 0 if succeeded, -1 on internal errors.
   22103  */
   22104 static int
   22105 xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
   22106 			       xmlSchemaPSVIIDCNodePtr item)
   22107 {
   22108     /*
   22109     * Add to gobal list.
   22110     */
   22111     if (vctxt->idcNodes == NULL) {
   22112 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22113 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22114 	if (vctxt->idcNodes == NULL) {
   22115 	    xmlSchemaVErrMemory(vctxt,
   22116 		"allocating the IDC node table item list", NULL);
   22117 	    return (-1);
   22118 	}
   22119 	vctxt->sizeIdcNodes = 20;
   22120     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
   22121 	vctxt->sizeIdcNodes *= 2;
   22122 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
   22123 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
   22124 	    sizeof(xmlSchemaPSVIIDCNodePtr));
   22125 	if (vctxt->idcNodes == NULL) {
   22126 	    xmlSchemaVErrMemory(vctxt,
   22127 		"re-allocating the IDC node table item list", NULL);
   22128 	    return (-1);
   22129 	}
   22130     }
   22131     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
   22132 
   22133     return (0);
   22134 }
   22135 
   22136 /**
   22137  * xmlSchemaIDCStoreKey:
   22138  * @vctxt: the WXS validation context
   22139  * @item: the IDC key
   22140  *
   22141  * The validation context is used to store an IDC key.
   22142  *
   22143  * Returns 0 if succeeded, -1 on internal errors.
   22144  */
   22145 static int
   22146 xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
   22147 		     xmlSchemaPSVIIDCKeyPtr key)
   22148 {
   22149     /*
   22150     * Add to gobal list.
   22151     */
   22152     if (vctxt->idcKeys == NULL) {
   22153 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22154 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
   22155 	if (vctxt->idcKeys == NULL) {
   22156 	    xmlSchemaVErrMemory(vctxt,
   22157 		"allocating the IDC key storage list", NULL);
   22158 	    return (-1);
   22159 	}
   22160 	vctxt->sizeIdcKeys = 40;
   22161     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
   22162 	vctxt->sizeIdcKeys *= 2;
   22163 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
   22164 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
   22165 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22166 	if (vctxt->idcKeys == NULL) {
   22167 	    xmlSchemaVErrMemory(vctxt,
   22168 		"re-allocating the IDC key storage list", NULL);
   22169 	    return (-1);
   22170 	}
   22171     }
   22172     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
   22173 
   22174     return (0);
   22175 }
   22176 
   22177 /**
   22178  * xmlSchemaIDCAppendNodeTableItem:
   22179  * @bind: the IDC binding
   22180  * @ntItem: the node-table item
   22181  *
   22182  * Appends the IDC node-table item to the binding.
   22183  *
   22184  * Returns 0 on success and -1 on internal errors.
   22185  */
   22186 static int
   22187 xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
   22188 				xmlSchemaPSVIIDCNodePtr ntItem)
   22189 {
   22190     if (bind->nodeTable == NULL) {
   22191 	bind->sizeNodes = 10;
   22192 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22193 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   22194 	if (bind->nodeTable == NULL) {
   22195 	    xmlSchemaVErrMemory(NULL,
   22196 		"allocating an array of IDC node-table items", NULL);
   22197 	    return(-1);
   22198 	}
   22199     } else if (bind->sizeNodes <= bind->nbNodes) {
   22200 	bind->sizeNodes *= 2;
   22201 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   22202 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
   22203 		sizeof(xmlSchemaPSVIIDCNodePtr));
   22204 	if (bind->nodeTable == NULL) {
   22205 	    xmlSchemaVErrMemory(NULL,
   22206 		"re-allocating an array of IDC node-table items", NULL);
   22207 	    return(-1);
   22208 	}
   22209     }
   22210     bind->nodeTable[bind->nbNodes++] = ntItem;
   22211     return(0);
   22212 }
   22213 
   22214 /**
   22215  * xmlSchemaIDCAcquireBinding:
   22216  * @vctxt: the WXS validation context
   22217  * @matcher: the IDC matcher
   22218  *
   22219  * Looks up an PSVI IDC binding, for the IDC definition and
   22220  * of the given matcher. If none found, a new one is created
   22221  * and added to the IDC table.
   22222  *
   22223  * Returns an IDC binding or NULL on internal errors.
   22224  */
   22225 static xmlSchemaPSVIIDCBindingPtr
   22226 xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
   22227 			  xmlSchemaIDCMatcherPtr matcher)
   22228 {
   22229     xmlSchemaNodeInfoPtr ielem;
   22230 
   22231     ielem = vctxt->elemInfos[matcher->depth];
   22232 
   22233     if (ielem->idcTable == NULL) {
   22234 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22235 	if (ielem->idcTable == NULL)
   22236 	    return (NULL);
   22237 	return(ielem->idcTable);
   22238     } else {
   22239 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
   22240 
   22241 	bind = ielem->idcTable;
   22242 	do {
   22243 	    if (bind->definition == matcher->aidc->def)
   22244 		return(bind);
   22245 	    if (bind->next == NULL) {
   22246 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
   22247 		if (bind->next == NULL)
   22248 		    return (NULL);
   22249 		return(bind->next);
   22250 	    }
   22251 	    bind = bind->next;
   22252 	} while (bind != NULL);
   22253     }
   22254     return (NULL);
   22255 }
   22256 
   22257 static xmlSchemaItemListPtr
   22258 xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
   22259 			     xmlSchemaIDCMatcherPtr matcher)
   22260 {
   22261     if (matcher->targets == NULL)
   22262 	matcher->targets = xmlSchemaItemListCreate();
   22263     return(matcher->targets);
   22264 }
   22265 
   22266 /**
   22267  * xmlSchemaIDCFreeKey:
   22268  * @key: the IDC key
   22269  *
   22270  * Frees an IDC key together with its compiled value.
   22271  */
   22272 static void
   22273 xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
   22274 {
   22275     if (key->val != NULL)
   22276 	xmlSchemaFreeValue(key->val);
   22277     xmlFree(key);
   22278 }
   22279 
   22280 /**
   22281  * xmlSchemaIDCFreeBinding:
   22282  *
   22283  * Frees an IDC binding. Note that the node table-items
   22284  * are not freed.
   22285  */
   22286 static void
   22287 xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
   22288 {
   22289     if (bind->nodeTable != NULL)
   22290 	xmlFree(bind->nodeTable);
   22291     if (bind->dupls != NULL)
   22292 	xmlSchemaItemListFree(bind->dupls);
   22293     xmlFree(bind);
   22294 }
   22295 
   22296 /**
   22297  * xmlSchemaIDCFreeIDCTable:
   22298  * @bind: the first IDC binding in the list
   22299  *
   22300  * Frees an IDC table, i.e. all the IDC bindings in the list.
   22301  */
   22302 static void
   22303 xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
   22304 {
   22305     xmlSchemaPSVIIDCBindingPtr prev;
   22306 
   22307     while (bind != NULL) {
   22308 	prev = bind;
   22309 	bind = bind->next;
   22310 	xmlSchemaIDCFreeBinding(prev);
   22311     }
   22312 }
   22313 
   22314 /**
   22315  * xmlSchemaIDCFreeMatcherList:
   22316  * @matcher: the first IDC matcher in the list
   22317  *
   22318  * Frees a list of IDC matchers.
   22319  */
   22320 static void
   22321 xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
   22322 {
   22323     xmlSchemaIDCMatcherPtr next;
   22324 
   22325     while (matcher != NULL) {
   22326 	next = matcher->next;
   22327 	if (matcher->keySeqs != NULL) {
   22328 	    int i;
   22329 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22330 		if (matcher->keySeqs[i] != NULL)
   22331 		    xmlFree(matcher->keySeqs[i]);
   22332 	    xmlFree(matcher->keySeqs);
   22333 	}
   22334 	if (matcher->targets != NULL) {
   22335 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22336 		int i;
   22337 		xmlSchemaPSVIIDCNodePtr idcNode;
   22338 		/*
   22339 		* Node-table items for keyrefs are not stored globally
   22340 		* to the validation context, since they are not bubbled.
   22341 		* We need to free them here.
   22342 		*/
   22343 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22344 		    idcNode =
   22345 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22346 		    xmlFree(idcNode->keys);
   22347 		    xmlFree(idcNode);
   22348 		}
   22349 	    }
   22350 	    xmlSchemaItemListFree(matcher->targets);
   22351 	}
   22352 	xmlFree(matcher);
   22353 	matcher = next;
   22354     }
   22355 }
   22356 
   22357 /**
   22358  * xmlSchemaIDCReleaseMatcherList:
   22359  * @vctxt: the WXS validation context
   22360  * @matcher: the first IDC matcher in the list
   22361  *
   22362  * Caches a list of IDC matchers for reuse.
   22363  */
   22364 static void
   22365 xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
   22366 			       xmlSchemaIDCMatcherPtr matcher)
   22367 {
   22368     xmlSchemaIDCMatcherPtr next;
   22369 
   22370     while (matcher != NULL) {
   22371 	next = matcher->next;
   22372 	if (matcher->keySeqs != NULL) {
   22373 	    int i;
   22374 	    /*
   22375 	    * Don't free the array, but only the content.
   22376 	    */
   22377 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
   22378 		if (matcher->keySeqs[i] != NULL) {
   22379 		    xmlFree(matcher->keySeqs[i]);
   22380 		    matcher->keySeqs[i] = NULL;
   22381 		}
   22382 	}
   22383 	if (matcher->targets) {
   22384 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
   22385 		int i;
   22386 		xmlSchemaPSVIIDCNodePtr idcNode;
   22387 		/*
   22388 		* Node-table items for keyrefs are not stored globally
   22389 		* to the validation context, since they are not bubbled.
   22390 		* We need to free them here.
   22391 		*/
   22392 		for (i = 0; i < matcher->targets->nbItems; i++) {
   22393 		    idcNode =
   22394 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
   22395 		    xmlFree(idcNode->keys);
   22396 		    xmlFree(idcNode);
   22397 		}
   22398 	    }
   22399 	    xmlSchemaItemListFree(matcher->targets);
   22400 	    matcher->targets = NULL;
   22401 	}
   22402 	matcher->next = NULL;
   22403 	/*
   22404 	* Cache the matcher.
   22405 	*/
   22406 	if (vctxt->idcMatcherCache != NULL)
   22407 	    matcher->nextCached = vctxt->idcMatcherCache;
   22408 	vctxt->idcMatcherCache = matcher;
   22409 
   22410 	matcher = next;
   22411     }
   22412 }
   22413 
   22414 /**
   22415  * xmlSchemaIDCAddStateObject:
   22416  * @vctxt: the WXS validation context
   22417  * @matcher: the IDC matcher
   22418  * @sel: the XPath information
   22419  * @parent: the parent "selector" state object if any
   22420  * @type: "selector" or "field"
   22421  *
   22422  * Creates/reuses and activates state objects for the given
   22423  * XPath information; if the XPath expression consists of unions,
   22424  * multiple state objects are created for every unioned expression.
   22425  *
   22426  * Returns 0 on success and -1 on internal errors.
   22427  */
   22428 static int
   22429 xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
   22430 			xmlSchemaIDCMatcherPtr matcher,
   22431 			xmlSchemaIDCSelectPtr sel,
   22432 			int type)
   22433 {
   22434     xmlSchemaIDCStateObjPtr sto;
   22435 
   22436     /*
   22437     * Reuse the state objects from the pool.
   22438     */
   22439     if (vctxt->xpathStatePool != NULL) {
   22440 	sto = vctxt->xpathStatePool;
   22441 	vctxt->xpathStatePool = sto->next;
   22442 	sto->next = NULL;
   22443     } else {
   22444 	/*
   22445 	* Create a new state object.
   22446 	*/
   22447 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
   22448 	if (sto == NULL) {
   22449 	    xmlSchemaVErrMemory(NULL,
   22450 		"allocating an IDC state object", NULL);
   22451 	    return (-1);
   22452 	}
   22453 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
   22454     }
   22455     /*
   22456     * Add to global list.
   22457     */
   22458     if (vctxt->xpathStates != NULL)
   22459 	sto->next = vctxt->xpathStates;
   22460     vctxt->xpathStates = sto;
   22461 
   22462     /*
   22463     * Free the old xpath validation context.
   22464     */
   22465     if (sto->xpathCtxt != NULL)
   22466 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
   22467 
   22468     /*
   22469     * Create a new XPath (pattern) validation context.
   22470     */
   22471     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
   22472 	(xmlPatternPtr) sel->xpathComp);
   22473     if (sto->xpathCtxt == NULL) {
   22474 	VERROR_INT("xmlSchemaIDCAddStateObject",
   22475 	    "failed to create an XPath validation context");
   22476 	return (-1);
   22477     }
   22478     sto->type = type;
   22479     sto->depth = vctxt->depth;
   22480     sto->matcher = matcher;
   22481     sto->sel = sel;
   22482     sto->nbHistory = 0;
   22483 
   22484 #ifdef DEBUG_IDC
   22485     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
   22486 	sto->sel->xpath);
   22487 #endif
   22488     return (0);
   22489 }
   22490 
   22491 /**
   22492  * xmlSchemaXPathEvaluate:
   22493  * @vctxt: the WXS validation context
   22494  * @nodeType: the nodeType of the current node
   22495  *
   22496  * Evaluates all active XPath state objects.
   22497  *
   22498  * Returns the number of IC "field" state objects which resolved to
   22499  * this node, 0 if none resolved and -1 on internal errors.
   22500  */
   22501 static int
   22502 xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
   22503 		       xmlElementType nodeType)
   22504 {
   22505     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
   22506     int res, resolved = 0, depth = vctxt->depth;
   22507 
   22508     if (vctxt->xpathStates == NULL)
   22509 	return (0);
   22510 
   22511     if (nodeType == XML_ATTRIBUTE_NODE)
   22512 	depth++;
   22513 #ifdef DEBUG_IDC
   22514     {
   22515 	xmlChar *str = NULL;
   22516 	xmlGenericError(xmlGenericErrorContext,
   22517 	    "IDC: EVAL on %s, depth %d, type %d\n",
   22518 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22519 		vctxt->inode->localName), depth, nodeType);
   22520 	FREE_AND_NULL(str)
   22521     }
   22522 #endif
   22523     /*
   22524     * Process all active XPath state objects.
   22525     */
   22526     first = vctxt->xpathStates;
   22527     sto = first;
   22528     while (sto != head) {
   22529 #ifdef DEBUG_IDC
   22530 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
   22531 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
   22532 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22533 	else
   22534 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
   22535 		sto->matcher->aidc->def->name, sto->sel->xpath);
   22536 #endif
   22537 	if (nodeType == XML_ELEMENT_NODE)
   22538 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
   22539 		vctxt->inode->localName, vctxt->inode->nsName);
   22540 	else
   22541 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
   22542 		vctxt->inode->localName, vctxt->inode->nsName);
   22543 
   22544 	if (res == -1) {
   22545 	    VERROR_INT("xmlSchemaXPathEvaluate",
   22546 		"calling xmlStreamPush()");
   22547 	    return (-1);
   22548 	}
   22549 	if (res == 0)
   22550 	    goto next_sto;
   22551 	/*
   22552 	* Full match.
   22553 	*/
   22554 #ifdef DEBUG_IDC
   22555 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22556 	    "MATCH\n");
   22557 #endif
   22558 	/*
   22559 	* Register a match in the state object history.
   22560 	*/
   22561 	if (sto->history == NULL) {
   22562 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
   22563 	    if (sto->history == NULL) {
   22564 		xmlSchemaVErrMemory(NULL,
   22565 		    "allocating the state object history", NULL);
   22566 		return(-1);
   22567 	    }
   22568 	    sto->sizeHistory = 5;
   22569 	} else if (sto->sizeHistory <= sto->nbHistory) {
   22570 	    sto->sizeHistory *= 2;
   22571 	    sto->history = (int *) xmlRealloc(sto->history,
   22572 		sto->sizeHistory * sizeof(int));
   22573 	    if (sto->history == NULL) {
   22574 		xmlSchemaVErrMemory(NULL,
   22575 		    "re-allocating the state object history", NULL);
   22576 		return(-1);
   22577 	    }
   22578 	}
   22579 	sto->history[sto->nbHistory++] = depth;
   22580 
   22581 #ifdef DEBUG_IDC
   22582 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
   22583 	    vctxt->depth);
   22584 #endif
   22585 
   22586 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22587 	    xmlSchemaIDCSelectPtr sel;
   22588 	    /*
   22589 	    * Activate state objects for the IDC fields of
   22590 	    * the IDC selector.
   22591 	    */
   22592 #ifdef DEBUG_IDC
   22593 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
   22594 		"activating field states\n");
   22595 #endif
   22596 	    sel = sto->matcher->aidc->def->fields;
   22597 	    while (sel != NULL) {
   22598 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
   22599 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
   22600 		    return (-1);
   22601 		sel = sel->next;
   22602 	    }
   22603 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22604 	    /*
   22605 	    * An IDC key node was found by the IDC field.
   22606 	    */
   22607 #ifdef DEBUG_IDC
   22608 	    xmlGenericError(xmlGenericErrorContext,
   22609 		"IDC:     key found\n");
   22610 #endif
   22611 	    /*
   22612 	    * Notify that the character value of this node is
   22613 	    * needed.
   22614 	    */
   22615 	    if (resolved == 0) {
   22616 		if ((vctxt->inode->flags &
   22617 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
   22618 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   22619 	    }
   22620 	    resolved++;
   22621 	}
   22622 next_sto:
   22623 	if (sto->next == NULL) {
   22624 	    /*
   22625 	    * Evaluate field state objects created on this node as well.
   22626 	    */
   22627 	    head = first;
   22628 	    sto = vctxt->xpathStates;
   22629 	} else
   22630 	    sto = sto->next;
   22631     }
   22632     return (resolved);
   22633 }
   22634 
   22635 static const xmlChar *
   22636 xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
   22637 			      xmlChar **buf,
   22638 			      xmlSchemaPSVIIDCKeyPtr *seq,
   22639 			      int count)
   22640 {
   22641     int i, res;
   22642     xmlChar *value = NULL;
   22643 
   22644     *buf = xmlStrdup(BAD_CAST "[");
   22645     for (i = 0; i < count; i++) {
   22646 	*buf = xmlStrcat(*buf, BAD_CAST "'");
   22647 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
   22648 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
   22649 	    &value);
   22650 	if (res == 0)
   22651 	    *buf = xmlStrcat(*buf, BAD_CAST value);
   22652 	else {
   22653 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
   22654 		"failed to compute a canonical value");
   22655 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
   22656 	}
   22657 	if (i < count -1)
   22658 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
   22659 	else
   22660 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
   22661 	if (value != NULL) {
   22662 	    xmlFree(value);
   22663 	    value = NULL;
   22664 	}
   22665     }
   22666     *buf = xmlStrcat(*buf, BAD_CAST "]");
   22667 
   22668     return (BAD_CAST *buf);
   22669 }
   22670 
   22671 /**
   22672  * xmlSchemaXPathPop:
   22673  * @vctxt: the WXS validation context
   22674  *
   22675  * Pops all XPath states.
   22676  *
   22677  * Returns 0 on success and -1 on internal errors.
   22678  */
   22679 static int
   22680 xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
   22681 {
   22682     xmlSchemaIDCStateObjPtr sto;
   22683     int res;
   22684 
   22685     if (vctxt->xpathStates == NULL)
   22686 	return(0);
   22687     sto = vctxt->xpathStates;
   22688     do {
   22689 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22690 	if (res == -1)
   22691 	    return (-1);
   22692 	sto = sto->next;
   22693     } while (sto != NULL);
   22694     return(0);
   22695 }
   22696 
   22697 /**
   22698  * xmlSchemaXPathProcessHistory:
   22699  * @vctxt: the WXS validation context
   22700  * @type: the simple/complex type of the current node if any at all
   22701  * @val: the precompiled value
   22702  *
   22703  * Processes and pops the history items of the IDC state objects.
   22704  * IDC key-sequences are validated/created on IDC bindings.
   22705  *
   22706  * Returns 0 on success and -1 on internal errors.
   22707  */
   22708 static int
   22709 xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
   22710 			     int depth)
   22711 {
   22712     xmlSchemaIDCStateObjPtr sto, nextsto;
   22713     int res, matchDepth;
   22714     xmlSchemaPSVIIDCKeyPtr key = NULL;
   22715     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
   22716 
   22717     if (vctxt->xpathStates == NULL)
   22718 	return (0);
   22719     sto = vctxt->xpathStates;
   22720 
   22721 #ifdef DEBUG_IDC
   22722     {
   22723 	xmlChar *str = NULL;
   22724 	xmlGenericError(xmlGenericErrorContext,
   22725 	    "IDC: BACK on %s, depth %d\n",
   22726 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   22727 		vctxt->inode->localName), vctxt->depth);
   22728 	FREE_AND_NULL(str)
   22729     }
   22730 #endif
   22731     /*
   22732     * Evaluate the state objects.
   22733     */
   22734     while (sto != NULL) {
   22735 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
   22736 	if (res == -1) {
   22737 	    VERROR_INT("xmlSchemaXPathProcessHistory",
   22738 		"calling xmlStreamPop()");
   22739 	    return (-1);
   22740 	}
   22741 #ifdef DEBUG_IDC
   22742 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
   22743 	    sto->sel->xpath);
   22744 #endif
   22745 	if (sto->nbHistory == 0)
   22746 	    goto deregister_check;
   22747 
   22748 	matchDepth = sto->history[sto->nbHistory -1];
   22749 
   22750 	/*
   22751 	* Only matches at the current depth are of interest.
   22752 	*/
   22753 	if (matchDepth != depth) {
   22754 	    sto = sto->next;
   22755 	    continue;
   22756 	}
   22757 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
   22758 	    /*
   22759 	    * NOTE: According to
   22760 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
   22761 	    *   ... the simple-content of complex types is also allowed.
   22762 	    */
   22763 
   22764 	    if (WXS_IS_COMPLEX(type)) {
   22765 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
   22766 		    /*
   22767 		    * Sanity check for complex types with simple content.
   22768 		    */
   22769 		    simpleType = type->contentTypeDef;
   22770 		    if (simpleType == NULL) {
   22771 			VERROR_INT("xmlSchemaXPathProcessHistory",
   22772 			    "field resolves to a CT with simple content "
   22773 			    "but the CT is missing the ST definition");
   22774 			return (-1);
   22775 		    }
   22776 		} else
   22777 		    simpleType = NULL;
   22778 	    } else
   22779 		simpleType = type;
   22780 	    if (simpleType == NULL) {
   22781 		xmlChar *str = NULL;
   22782 
   22783 		/*
   22784 		* Not qualified if the field resolves to a node of non
   22785 		* simple type.
   22786 		*/
   22787 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22788 		    XML_SCHEMAV_CVC_IDC, NULL,
   22789 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22790 		    "The XPath '%s' of a field of %s does evaluate to a node of "
   22791 		    "non-simple type",
   22792 		    sto->sel->xpath,
   22793 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
   22794 		FREE_AND_NULL(str);
   22795 		sto->nbHistory--;
   22796 		goto deregister_check;
   22797 	    }
   22798 
   22799 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
   22800 		/*
   22801 		* Failed to provide the normalized value; maybe
   22802 		* the value was invalid.
   22803 		*/
   22804 		VERROR(XML_SCHEMAV_CVC_IDC,
   22805 		    WXS_BASIC_CAST sto->matcher->aidc->def,
   22806 		    "Warning: No precomputed value available, the value "
   22807 		    "was either invalid or something strange happend");
   22808 		sto->nbHistory--;
   22809 		goto deregister_check;
   22810 	    } else {
   22811 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
   22812 		xmlSchemaPSVIIDCKeyPtr *keySeq;
   22813 		int pos, idx;
   22814 
   22815 		/*
   22816 		* The key will be anchored on the matcher's list of
   22817 		* key-sequences. The position in this list is determined
   22818 		* by the target node's depth relative to the matcher's
   22819 		* depth of creation (i.e. the depth of the scope element).
   22820 		*
   22821 		* Element        Depth    Pos   List-entries
   22822 		* <scope>          0              NULL
   22823 		*   <bar>          1              NULL
   22824 		*     <target/>    2       2      target
   22825 		*   <bar>
   22826                 * </scope>
   22827 		*
   22828 		* The size of the list is only dependant on the depth of
   22829 		* the tree.
   22830 		* An entry will be NULLed in selector_leave, i.e. when
   22831 		* we hit the target's
   22832 		*/
   22833 		pos = sto->depth - matcher->depth;
   22834 		idx = sto->sel->index;
   22835 
   22836 		/*
   22837 		* Create/grow the array of key-sequences.
   22838 		*/
   22839 		if (matcher->keySeqs == NULL) {
   22840 		    if (pos > 9)
   22841 			matcher->sizeKeySeqs = pos * 2;
   22842 		    else
   22843 			matcher->sizeKeySeqs = 10;
   22844 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22845 			xmlMalloc(matcher->sizeKeySeqs *
   22846 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22847 		    if (matcher->keySeqs == NULL) {
   22848 			xmlSchemaVErrMemory(NULL,
   22849 			    "allocating an array of key-sequences",
   22850 			    NULL);
   22851 			return(-1);
   22852 		    }
   22853 		    memset(matcher->keySeqs, 0,
   22854 			matcher->sizeKeySeqs *
   22855 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22856 		} else if (pos >= matcher->sizeKeySeqs) {
   22857 		    int i = matcher->sizeKeySeqs;
   22858 
   22859 		    matcher->sizeKeySeqs *= 2;
   22860 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
   22861 			xmlRealloc(matcher->keySeqs,
   22862 			matcher->sizeKeySeqs *
   22863 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
   22864 		    if (matcher->keySeqs == NULL) {
   22865 			xmlSchemaVErrMemory(NULL,
   22866 			    "reallocating an array of key-sequences",
   22867 			    NULL);
   22868 			return (-1);
   22869 		    }
   22870 		    /*
   22871 		    * The array needs to be NULLed.
   22872 		    * TODO: Use memset?
   22873 		    */
   22874 		    for (; i < matcher->sizeKeySeqs; i++)
   22875 			matcher->keySeqs[i] = NULL;
   22876 		}
   22877 
   22878 		/*
   22879 		* Get/create the key-sequence.
   22880 		*/
   22881 		keySeq = matcher->keySeqs[pos];
   22882 		if (keySeq == NULL) {
   22883 		    goto create_sequence;
   22884 		} else if (keySeq[idx] != NULL) {
   22885 		    xmlChar *str = NULL;
   22886 		    /*
   22887 		    * cvc-identity-constraint:
   22888 		    * 3 For each node in the `target node set` all
   22889 		    * of the {fields}, with that node as the context
   22890 		    * node, evaluate to either an empty node-set or
   22891 		    * a node-set with exactly one member, which must
   22892 		    * have a simple type.
   22893 		    *
   22894 		    * The key was already set; report an error.
   22895 		    */
   22896 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   22897 			XML_SCHEMAV_CVC_IDC, NULL,
   22898 			WXS_BASIC_CAST matcher->aidc->def,
   22899 			"The XPath '%s' of a field of %s evaluates to a "
   22900 			"node-set with more than one member",
   22901 			sto->sel->xpath,
   22902 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
   22903 		    FREE_AND_NULL(str);
   22904 		    sto->nbHistory--;
   22905 		    goto deregister_check;
   22906 		} else
   22907 		    goto create_key;
   22908 
   22909 create_sequence:
   22910 		/*
   22911 		* Create a key-sequence.
   22912 		*/
   22913 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
   22914 		    matcher->aidc->def->nbFields *
   22915 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22916 		if (keySeq == NULL) {
   22917 		    xmlSchemaVErrMemory(NULL,
   22918 			"allocating an IDC key-sequence", NULL);
   22919 		    return(-1);
   22920 		}
   22921 		memset(keySeq, 0, matcher->aidc->def->nbFields *
   22922 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
   22923 		matcher->keySeqs[pos] = keySeq;
   22924 create_key:
   22925 		/*
   22926 		* Create a key once per node only.
   22927 		*/
   22928 		if (key == NULL) {
   22929 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
   22930 			sizeof(xmlSchemaPSVIIDCKey));
   22931 		    if (key == NULL) {
   22932 			xmlSchemaVErrMemory(NULL,
   22933 			    "allocating a IDC key", NULL);
   22934 			xmlFree(keySeq);
   22935 			matcher->keySeqs[pos] = NULL;
   22936 			return(-1);
   22937 		    }
   22938 		    /*
   22939 		    * Consume the compiled value.
   22940 		    */
   22941 		    key->type = simpleType;
   22942 		    key->val = vctxt->inode->val;
   22943 		    vctxt->inode->val = NULL;
   22944 		    /*
   22945 		    * Store the key in a global list.
   22946 		    */
   22947 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
   22948 			xmlSchemaIDCFreeKey(key);
   22949 			return (-1);
   22950 		    }
   22951 		}
   22952 		keySeq[idx] = key;
   22953 	    }
   22954 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
   22955 
   22956 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
   22957 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
   22958 	    xmlSchemaPSVIIDCNodePtr ntItem;
   22959 	    xmlSchemaIDCMatcherPtr matcher;
   22960 	    xmlSchemaIDCPtr idc;
   22961 	    xmlSchemaItemListPtr targets;
   22962 	    int pos, i, j, nbKeys;
   22963 	    /*
   22964 	    * Here we have the following scenario:
   22965 	    * An IDC 'selector' state object resolved to a target node,
   22966 	    * during the time this target node was in the
   22967 	    * ancestor-or-self axis, the 'field' state object(s) looked
   22968 	    * out for matching nodes to create a key-sequence for this
   22969 	    * target node. Now we are back to this target node and need
   22970 	    * to put the key-sequence, together with the target node
   22971 	    * itself, into the node-table of the corresponding IDC
   22972 	    * binding.
   22973 	    */
   22974 	    matcher = sto->matcher;
   22975 	    idc = matcher->aidc->def;
   22976 	    nbKeys = idc->nbFields;
   22977 	    pos = depth - matcher->depth;
   22978 	    /*
   22979 	    * Check if the matcher has any key-sequences at all, plus
   22980 	    * if it has a key-sequence for the current target node.
   22981 	    */
   22982 	    if ((matcher->keySeqs == NULL) ||
   22983 		(matcher->sizeKeySeqs <= pos)) {
   22984 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22985 		    goto selector_key_error;
   22986 		else
   22987 		    goto selector_leave;
   22988 	    }
   22989 
   22990 	    keySeq = &(matcher->keySeqs[pos]);
   22991 	    if (*keySeq == NULL) {
   22992 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
   22993 		    goto selector_key_error;
   22994 		else
   22995 		    goto selector_leave;
   22996 	    }
   22997 
   22998 	    for (i = 0; i < nbKeys; i++) {
   22999 		if ((*keySeq)[i] == NULL) {
   23000 		    /*
   23001 		    * Not qualified, if not all fields did resolve.
   23002 		    */
   23003 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
   23004 			/*
   23005 			* All fields of a "key" IDC must resolve.
   23006 			*/
   23007 			goto selector_key_error;
   23008 		    }
   23009 		    goto selector_leave;
   23010 		}
   23011 	    }
   23012 	    /*
   23013 	    * All fields did resolve.
   23014 	    */
   23015 
   23016 	    /*
   23017 	    * 4.1 If the {identity-constraint category} is unique(/key),
   23018 	    * then no two members of the `qualified node set` have
   23019 	    * `key-sequences` whose members are pairwise equal, as
   23020 	    * defined by Equal in [XML Schemas: Datatypes].
   23021 	    *
   23022 	    * Get the IDC binding from the matcher and check for
   23023 	    * duplicate key-sequences.
   23024 	    */
   23025 #if 0
   23026 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   23027 #endif
   23028 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
   23029 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
   23030 		(targets->nbItems != 0)) {
   23031 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
   23032 
   23033 		i = 0;
   23034 		res = 0;
   23035 		/*
   23036 		* Compare the key-sequences, key by key.
   23037 		*/
   23038 		do {
   23039 		    bkeySeq =
   23040 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
   23041 		    for (j = 0; j < nbKeys; j++) {
   23042 			ckey = (*keySeq)[j];
   23043 			bkey = bkeySeq[j];
   23044 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
   23045 			if (res == -1) {
   23046 			    return (-1);
   23047 			} else if (res == 0) {
   23048 			    /*
   23049 			    * One of the keys differs, so the key-sequence
   23050 			    * won't be equal; get out.
   23051 			    */
   23052 			    break;
   23053 			}
   23054 		    }
   23055 		    if (res == 1) {
   23056 			/*
   23057 			* Duplicate key-sequence found.
   23058 			*/
   23059 			break;
   23060 		    }
   23061 		    i++;
   23062 		} while (i < targets->nbItems);
   23063 		if (i != targets->nbItems) {
   23064 		    xmlChar *str = NULL, *strB = NULL;
   23065 		    /*
   23066 		    * TODO: Try to report the key-sequence.
   23067 		    */
   23068 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23069 			XML_SCHEMAV_CVC_IDC, NULL,
   23070 			WXS_BASIC_CAST idc,
   23071 			"Duplicate key-sequence %s in %s",
   23072 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23073 			    (*keySeq), nbKeys),
   23074 			xmlSchemaGetIDCDesignation(&strB, idc));
   23075 		    FREE_AND_NULL(str);
   23076 		    FREE_AND_NULL(strB);
   23077 		    goto selector_leave;
   23078 		}
   23079 	    }
   23080 	    /*
   23081 	    * Add a node-table item to the IDC binding.
   23082 	    */
   23083 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
   23084 		sizeof(xmlSchemaPSVIIDCNode));
   23085 	    if (ntItem == NULL) {
   23086 		xmlSchemaVErrMemory(NULL,
   23087 		    "allocating an IDC node-table item", NULL);
   23088 		xmlFree(*keySeq);
   23089 		*keySeq = NULL;
   23090 		return(-1);
   23091 	    }
   23092 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
   23093 
   23094 	    /*
   23095 	    * Store the node-table item in a global list.
   23096 	    */
   23097 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
   23098 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
   23099 		    xmlFree(ntItem);
   23100 		    xmlFree(*keySeq);
   23101 		    *keySeq = NULL;
   23102 		    return (-1);
   23103 		}
   23104 		ntItem->nodeQNameID = -1;
   23105 	    } else {
   23106 		/*
   23107 		* Save a cached QName for this node on the IDC node, to be
   23108 		* able to report it, even if the node is not saved.
   23109 		*/
   23110 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
   23111 		    vctxt->inode->localName, vctxt->inode->nsName);
   23112 		if (ntItem->nodeQNameID == -1) {
   23113 		    xmlFree(ntItem);
   23114 		    xmlFree(*keySeq);
   23115 		    *keySeq = NULL;
   23116 		    return (-1);
   23117 		}
   23118 	    }
   23119 	    /*
   23120 	    * Init the node-table item: Save the node, position and
   23121 	    * consume the key-sequence.
   23122 	    */
   23123 	    ntItem->node = vctxt->node;
   23124 	    ntItem->nodeLine = vctxt->inode->nodeLine;
   23125 	    ntItem->keys = *keySeq;
   23126 	    *keySeq = NULL;
   23127 #if 0
   23128 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
   23129 #endif
   23130 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
   23131 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23132 		    /*
   23133 		    * Free the item, since keyref items won't be
   23134 		    * put on a global list.
   23135 		    */
   23136 		    xmlFree(ntItem->keys);
   23137 		    xmlFree(ntItem);
   23138 		}
   23139 		return (-1);
   23140 	    }
   23141 
   23142 	    goto selector_leave;
   23143 selector_key_error:
   23144 	    {
   23145 		xmlChar *str = NULL;
   23146 		/*
   23147 		* 4.2.1 (KEY) The `target node set` and the
   23148 		* `qualified node set` are equal, that is, every
   23149 		* member of the `target node set` is also a member
   23150 		* of the `qualified node set` and vice versa.
   23151 		*/
   23152 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   23153 		    XML_SCHEMAV_CVC_IDC, NULL,
   23154 		    WXS_BASIC_CAST idc,
   23155 		    "Not all fields of %s evaluate to a node",
   23156 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
   23157 		FREE_AND_NULL(str);
   23158 	    }
   23159 selector_leave:
   23160 	    /*
   23161 	    * Free the key-sequence if not added to the IDC table.
   23162 	    */
   23163 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
   23164 		xmlFree(*keySeq);
   23165 		*keySeq = NULL;
   23166 	    }
   23167 	} /* if selector */
   23168 
   23169 	sto->nbHistory--;
   23170 
   23171 deregister_check:
   23172 	/*
   23173 	* Deregister state objects if they reach the depth of creation.
   23174 	*/
   23175 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
   23176 #ifdef DEBUG_IDC
   23177 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
   23178 		sto->sel->xpath);
   23179 #endif
   23180 	    if (vctxt->xpathStates != sto) {
   23181 		VERROR_INT("xmlSchemaXPathProcessHistory",
   23182 		    "The state object to be removed is not the first "
   23183 		    "in the list");
   23184 	    }
   23185 	    nextsto = sto->next;
   23186 	    /*
   23187 	    * Unlink from the list of active XPath state objects.
   23188 	    */
   23189 	    vctxt->xpathStates = sto->next;
   23190 	    sto->next = vctxt->xpathStatePool;
   23191 	    /*
   23192 	    * Link it to the pool of reusable state objects.
   23193 	    */
   23194 	    vctxt->xpathStatePool = sto;
   23195 	    sto = nextsto;
   23196 	} else
   23197 	    sto = sto->next;
   23198     } /* while (sto != NULL) */
   23199     return (0);
   23200 }
   23201 
   23202 /**
   23203  * xmlSchemaIDCRegisterMatchers:
   23204  * @vctxt: the WXS validation context
   23205  * @elemDecl: the element declaration
   23206  *
   23207  * Creates helper objects to evaluate IDC selectors/fields
   23208  * successively.
   23209  *
   23210  * Returns 0 if OK and -1 on internal errors.
   23211  */
   23212 static int
   23213 xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
   23214 			     xmlSchemaElementPtr elemDecl)
   23215 {
   23216     xmlSchemaIDCMatcherPtr matcher, last = NULL;
   23217     xmlSchemaIDCPtr idc, refIdc;
   23218     xmlSchemaIDCAugPtr aidc;
   23219 
   23220     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
   23221     if (idc == NULL)
   23222 	return (0);
   23223 
   23224 #ifdef DEBUG_IDC
   23225     {
   23226 	xmlChar *str = NULL;
   23227 	xmlGenericError(xmlGenericErrorContext,
   23228 	    "IDC: REGISTER on %s, depth %d\n",
   23229 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
   23230 		vctxt->inode->localName), vctxt->depth);
   23231 	FREE_AND_NULL(str)
   23232     }
   23233 #endif
   23234     if (vctxt->inode->idcMatchers != NULL) {
   23235 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23236 	    "The chain of IDC matchers is expected to be empty");
   23237 	return (-1);
   23238     }
   23239     do {
   23240 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
   23241 	    /*
   23242 	    * Since IDCs bubbles are expensive we need to know the
   23243 	    * depth at which the bubbles should stop; this will be
   23244 	    * the depth of the top-most keyref IDC. If no keyref
   23245 	    * references a key/unique IDC, the keyrefDepth will
   23246 	    * be -1, indicating that no bubbles are needed.
   23247 	    */
   23248 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
   23249 	    if (refIdc != NULL) {
   23250 		/*
   23251 		* Remember that we have keyrefs on this node.
   23252 		*/
   23253 		vctxt->inode->hasKeyrefs = 1;
   23254 		/*
   23255 		* Lookup the referenced augmented IDC info.
   23256 		*/
   23257 		aidc = vctxt->aidcs;
   23258 		while (aidc != NULL) {
   23259 		    if (aidc->def == refIdc)
   23260 			break;
   23261 		    aidc = aidc->next;
   23262 		}
   23263 		if (aidc == NULL) {
   23264 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23265 			"Could not find an augmented IDC item for an IDC "
   23266 			"definition");
   23267 		    return (-1);
   23268 		}
   23269 		if ((aidc->keyrefDepth == -1) ||
   23270 		    (vctxt->depth < aidc->keyrefDepth))
   23271 		    aidc->keyrefDepth = vctxt->depth;
   23272 	    }
   23273 	}
   23274 	/*
   23275 	* Lookup the augmented IDC item for the IDC definition.
   23276 	*/
   23277 	aidc = vctxt->aidcs;
   23278 	while (aidc != NULL) {
   23279 	    if (aidc->def == idc)
   23280 		break;
   23281 	    aidc = aidc->next;
   23282 	}
   23283 	if (aidc == NULL) {
   23284 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
   23285 		"Could not find an augmented IDC item for an IDC definition");
   23286 	    return (-1);
   23287 	}
   23288 	/*
   23289 	* Create an IDC matcher for every IDC definition.
   23290 	*/
   23291 	if (vctxt->idcMatcherCache != NULL) {
   23292 	    /*
   23293 	    * Reuse a cached matcher.
   23294 	    */
   23295 	    matcher = vctxt->idcMatcherCache;
   23296 	    vctxt->idcMatcherCache = matcher->nextCached;
   23297 	    matcher->nextCached = NULL;
   23298 	} else {
   23299 	    matcher = (xmlSchemaIDCMatcherPtr)
   23300 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
   23301 	    if (matcher == NULL) {
   23302 		xmlSchemaVErrMemory(vctxt,
   23303 		    "allocating an IDC matcher", NULL);
   23304 		return (-1);
   23305 	    }
   23306 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
   23307 	}
   23308 	if (last == NULL)
   23309 	    vctxt->inode->idcMatchers = matcher;
   23310 	else
   23311 	    last->next = matcher;
   23312 	last = matcher;
   23313 
   23314 	matcher->type = IDC_MATCHER;
   23315 	matcher->depth = vctxt->depth;
   23316 	matcher->aidc = aidc;
   23317 	matcher->idcType = aidc->def->type;
   23318 #ifdef DEBUG_IDC
   23319 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
   23320 #endif
   23321 	/*
   23322 	* Init the automaton state object.
   23323 	*/
   23324 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
   23325 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
   23326 	    return (-1);
   23327 
   23328 	idc = idc->next;
   23329     } while (idc != NULL);
   23330     return (0);
   23331 }
   23332 
   23333 static int
   23334 xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
   23335 			   xmlSchemaNodeInfoPtr ielem)
   23336 {
   23337     xmlSchemaPSVIIDCBindingPtr bind;
   23338     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
   23339     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
   23340     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
   23341 
   23342     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
   23343     /* vctxt->createIDCNodeTables */
   23344     while (matcher != NULL) {
   23345 	/*
   23346 	* Skip keyref IDCs and empty IDC target-lists.
   23347 	*/
   23348 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
   23349 	    WXS_ILIST_IS_EMPTY(matcher->targets))
   23350 	{
   23351 	    matcher = matcher->next;
   23352 	    continue;
   23353 	}
   23354 	/*
   23355 	* If we _want_ the IDC node-table to be created in any case
   23356 	* then do so. Otherwise create them only if keyrefs need them.
   23357 	*/
   23358 	if ((! vctxt->createIDCNodeTables) &&
   23359 	    ((matcher->aidc->keyrefDepth == -1) ||
   23360 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
   23361 	{
   23362 	    matcher = matcher->next;
   23363 	    continue;
   23364 	}
   23365 	/*
   23366 	* Get/create the IDC binding on this element for the IDC definition.
   23367 	*/
   23368 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
   23369 
   23370 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
   23371 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
   23372 	    nbDupls = bind->dupls->nbItems;
   23373 	} else {
   23374 	    dupls = NULL;
   23375 	    nbDupls = 0;
   23376 	}
   23377 	if (bind->nodeTable != NULL) {
   23378 	    nbNodeTable = bind->nbNodes;
   23379 	} else {
   23380 	    nbNodeTable = 0;
   23381 	}
   23382 
   23383 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
   23384 	    /*
   23385 	    * Transfer all IDC target-nodes to the IDC node-table.
   23386 	    */
   23387 	    bind->nodeTable =
   23388 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23389 	    bind->sizeNodes = matcher->targets->sizeItems;
   23390 	    bind->nbNodes = matcher->targets->nbItems;
   23391 
   23392 	    matcher->targets->items = NULL;
   23393 	    matcher->targets->sizeItems = 0;
   23394 	    matcher->targets->nbItems = 0;
   23395 	} else {
   23396 	    /*
   23397 	    * Compare the key-sequences and add to the IDC node-table.
   23398 	    */
   23399 	    nbTargets = matcher->targets->nbItems;
   23400 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
   23401 	    nbFields = matcher->aidc->def->nbFields;
   23402 	    i = 0;
   23403 	    do {
   23404 		keys = targets[i]->keys;
   23405 		if (nbDupls) {
   23406 		    /*
   23407 		    * Search in already found duplicates first.
   23408 		    */
   23409 		    j = 0;
   23410 		    do {
   23411 			if (nbFields == 1) {
   23412 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23413 				dupls[j]->keys[0]->val);
   23414 			    if (res == -1)
   23415 				goto internal_error;
   23416 			    if (res == 1) {
   23417 				/*
   23418 				* Equal key-sequence.
   23419 				*/
   23420 				goto next_target;
   23421 			    }
   23422 			} else {
   23423 			    res = 0;
   23424 			    ntkeys = dupls[j]->keys;
   23425 			    for (k = 0; k < nbFields; k++) {
   23426 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23427 				    ntkeys[k]->val);
   23428 				if (res == -1)
   23429 				    goto internal_error;
   23430 				if (res == 0) {
   23431 				    /*
   23432 				    * One of the keys differs.
   23433 				    */
   23434 				    break;
   23435 				}
   23436 			    }
   23437 			    if (res == 1) {
   23438 				/*
   23439 				* Equal key-sequence found.
   23440 				*/
   23441 				goto next_target;
   23442 			    }
   23443 			}
   23444 			j++;
   23445 		    } while (j < nbDupls);
   23446 		}
   23447 		if (nbNodeTable) {
   23448 		    j = 0;
   23449 		    do {
   23450 			if (nbFields == 1) {
   23451 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
   23452 				bind->nodeTable[j]->keys[0]->val);
   23453 			    if (res == -1)
   23454 				goto internal_error;
   23455 			    if (res == 0) {
   23456 				/*
   23457 				* The key-sequence differs.
   23458 				*/
   23459 				goto next_node_table_entry;
   23460 			    }
   23461 			} else {
   23462 			    res = 0;
   23463 			    ntkeys = bind->nodeTable[j]->keys;
   23464 			    for (k = 0; k < nbFields; k++) {
   23465 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23466 				    ntkeys[k]->val);
   23467 				if (res == -1)
   23468 				    goto internal_error;
   23469 				if (res == 0) {
   23470 				    /*
   23471 				    * One of the keys differs.
   23472 				    */
   23473 				    goto next_node_table_entry;
   23474 				}
   23475 			    }
   23476 			}
   23477 			/*
   23478 			* Add the duplicate to the list of duplicates.
   23479 			*/
   23480 			if (bind->dupls == NULL) {
   23481 			    bind->dupls = xmlSchemaItemListCreate();
   23482 			    if (bind->dupls == NULL)
   23483 				goto internal_error;
   23484 			}
   23485 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
   23486 			    goto internal_error;
   23487 			/*
   23488 			* Remove the duplicate entry from the IDC node-table.
   23489 			*/
   23490 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
   23491 			bind->nbNodes--;
   23492 
   23493 			goto next_target;
   23494 
   23495 next_node_table_entry:
   23496 			j++;
   23497 		    } while (j < nbNodeTable);
   23498 		}
   23499 		/*
   23500 		* If everything is fine, then add the IDC target-node to
   23501 		* the IDC node-table.
   23502 		*/
   23503 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
   23504 		    goto internal_error;
   23505 
   23506 next_target:
   23507 		i++;
   23508 	    } while (i < nbTargets);
   23509 	}
   23510 	matcher = matcher->next;
   23511     }
   23512     return(0);
   23513 
   23514 internal_error:
   23515     return(-1);
   23516 }
   23517 
   23518 /**
   23519  * xmlSchemaBubbleIDCNodeTables:
   23520  * @depth: the current tree depth
   23521  *
   23522  * Merges IDC bindings of an element at @depth into the corresponding IDC
   23523  * bindings of its parent element. If a duplicate note-table entry is found,
   23524  * both, the parent node-table entry and child entry are discarded from the
   23525  * node-table of the parent.
   23526  *
   23527  * Returns 0 if OK and -1 on internal errors.
   23528  */
   23529 static int
   23530 xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
   23531 {
   23532     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
   23533     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
   23534     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
   23535     xmlSchemaIDCAugPtr aidc;
   23536     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
   23537 
   23538     bind = vctxt->inode->idcTable;
   23539     if (bind == NULL) {
   23540 	/* Fine, no table, no bubbles. */
   23541 	return (0);
   23542     }
   23543 
   23544     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
   23545     /*
   23546     * Walk all bindings; create new or add to existing bindings.
   23547     * Remove duplicate key-sequences.
   23548     */
   23549     while (bind != NULL) {
   23550 
   23551 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
   23552 	    goto next_binding;
   23553 	/*
   23554 	* Check if the key/unique IDC table needs to be bubbled.
   23555 	*/
   23556 	if (! vctxt->createIDCNodeTables) {
   23557 	    aidc = vctxt->aidcs;
   23558 	    do {
   23559 		if (aidc->def == bind->definition) {
   23560 		    if ((aidc->keyrefDepth == -1) ||
   23561 			(aidc->keyrefDepth >= vctxt->depth)) {
   23562 			goto next_binding;
   23563 		    }
   23564 		    break;
   23565 		}
   23566 		aidc = aidc->next;
   23567 	    } while (aidc != NULL);
   23568 	}
   23569 
   23570 	if (parTable != NULL)
   23571 	    parBind = *parTable;
   23572 	/*
   23573 	* Search a matching parent binding for the
   23574 	* IDC definition.
   23575 	*/
   23576 	while (parBind != NULL) {
   23577 	    if (parBind->definition == bind->definition)
   23578 		break;
   23579 	    parBind = parBind->next;
   23580 	}
   23581 
   23582 	if (parBind != NULL) {
   23583 	    /*
   23584 	    * Compare every node-table entry of the child node,
   23585 	    * i.e. the key-sequence within, ...
   23586 	    */
   23587 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
   23588 
   23589 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
   23590 		oldDupls = parBind->dupls->nbItems;
   23591 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
   23592 	    } else {
   23593 		dupls = NULL;
   23594 		oldDupls = 0;
   23595 	    }
   23596 
   23597 	    parNodes = parBind->nodeTable;
   23598 	    nbFields = bind->definition->nbFields;
   23599 
   23600 	    for (i = 0; i < bind->nbNodes; i++) {
   23601 		node = bind->nodeTable[i];
   23602 		if (node == NULL)
   23603 		    continue;
   23604 		/*
   23605 		* ...with every key-sequence of the parent node, already
   23606 		* evaluated to be a duplicate key-sequence.
   23607 		*/
   23608 		if (oldDupls) {
   23609 		    j = 0;
   23610 		    while (j < oldDupls) {
   23611 			if (nbFields == 1) {
   23612 			    ret = xmlSchemaAreValuesEqual(
   23613 				node->keys[0]->val,
   23614 				dupls[j]->keys[0]->val);
   23615 			    if (ret == -1)
   23616 				goto internal_error;
   23617 			    if (ret == 0) {
   23618 				j++;
   23619 				continue;
   23620 			    }
   23621 			} else {
   23622 			    parNode = dupls[j];
   23623 			    for (k = 0; k < nbFields; k++) {
   23624 				ret = xmlSchemaAreValuesEqual(
   23625 				    node->keys[k]->val,
   23626 				    parNode->keys[k]->val);
   23627 				if (ret == -1)
   23628 				    goto internal_error;
   23629 				if (ret == 0)
   23630 				    break;
   23631 			    }
   23632 			}
   23633 			if (ret == 1)
   23634 			    /* Duplicate found. */
   23635 			    break;
   23636 			j++;
   23637 		    }
   23638 		    if (j != oldDupls) {
   23639 			/* Duplicate found. Skip this entry. */
   23640 			continue;
   23641 		    }
   23642 		}
   23643 		/*
   23644 		* ... and with every key-sequence of the parent node.
   23645 		*/
   23646 		if (oldNum) {
   23647 		    j = 0;
   23648 		    while (j < oldNum) {
   23649 			parNode = parNodes[j];
   23650 			if (nbFields == 1) {
   23651 			    ret = xmlSchemaAreValuesEqual(
   23652 				node->keys[0]->val,
   23653 				parNode->keys[0]->val);
   23654 			    if (ret == -1)
   23655 				goto internal_error;
   23656 			    if (ret == 0) {
   23657 				j++;
   23658 				continue;
   23659 			    }
   23660 			} else {
   23661 			    for (k = 0; k < nbFields; k++) {
   23662 				ret = xmlSchemaAreValuesEqual(
   23663 				    node->keys[k]->val,
   23664 				    parNode->keys[k]->val);
   23665 				if (ret == -1)
   23666 				    goto internal_error;
   23667 				if (ret == 0)
   23668 				    break;
   23669 			    }
   23670 			}
   23671 			if (ret == 1)
   23672 			    /* Duplicate found. */
   23673 			    break;
   23674 			j++;
   23675 		    }
   23676 		    if (j != oldNum) {
   23677 			/*
   23678 			* Handle duplicates. Move the duplicate in
   23679 			* the parent's node-table to the list of
   23680 			* duplicates.
   23681 			*/
   23682 			oldNum--;
   23683 			parBind->nbNodes--;
   23684 			/*
   23685 			* Move last old item to pos of duplicate.
   23686 			*/
   23687 			parNodes[j] = parNodes[oldNum];
   23688 
   23689 			if (parBind->nbNodes != oldNum) {
   23690 			    /*
   23691 			    * If new items exist, move last new item to
   23692 			    * last of old items.
   23693 			    */
   23694 			    parNodes[oldNum] =
   23695 				parNodes[parBind->nbNodes];
   23696 			}
   23697 			if (parBind->dupls == NULL) {
   23698 			    parBind->dupls = xmlSchemaItemListCreate();
   23699 			    if (parBind->dupls == NULL)
   23700 				goto internal_error;
   23701 			}
   23702 			xmlSchemaItemListAdd(parBind->dupls, parNode);
   23703 		    } else {
   23704 			/*
   23705 			* Add the node-table entry (node and key-sequence) of
   23706 			* the child node to the node table of the parent node.
   23707 			*/
   23708 			if (parBind->nodeTable == NULL) {
   23709 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23710 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
   23711 			    if (parBind->nodeTable == NULL) {
   23712 				xmlSchemaVErrMemory(NULL,
   23713 				    "allocating IDC list of node-table items", NULL);
   23714 				goto internal_error;
   23715 			    }
   23716 			    parBind->sizeNodes = 1;
   23717 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
   23718 			    parBind->sizeNodes *= 2;
   23719 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23720 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
   23721 				sizeof(xmlSchemaPSVIIDCNodePtr));
   23722 			    if (parBind->nodeTable == NULL) {
   23723 				xmlSchemaVErrMemory(NULL,
   23724 				    "re-allocating IDC list of node-table items", NULL);
   23725 				goto internal_error;
   23726 			    }
   23727 			}
   23728 			parNodes = parBind->nodeTable;
   23729 			/*
   23730 			* Append the new node-table entry to the 'new node-table
   23731 			* entries' section.
   23732 			*/
   23733 			parNodes[parBind->nbNodes++] = node;
   23734 		    }
   23735 
   23736 		}
   23737 
   23738 	    }
   23739 	} else {
   23740 	    /*
   23741 	    * No binding for the IDC was found: create a new one and
   23742 	    * copy all node-tables.
   23743 	    */
   23744 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
   23745 	    if (parBind == NULL)
   23746 		goto internal_error;
   23747 
   23748 	    /*
   23749 	    * TODO: Hmm, how to optimize the initial number of
   23750 	    * allocated entries?
   23751 	    */
   23752 	    if (bind->nbNodes != 0) {
   23753 		/*
   23754 		* Add all IDC node-table entries.
   23755 		*/
   23756 		if (! vctxt->psviExposeIDCNodeTables) {
   23757 		    /*
   23758 		    * Just move the entries.
   23759 		    * NOTE: this is quite save here, since
   23760 		    * all the keyref lookups have already been
   23761 		    * performed.
   23762 		    */
   23763 		    parBind->nodeTable = bind->nodeTable;
   23764 		    bind->nodeTable = NULL;
   23765 		    parBind->sizeNodes = bind->sizeNodes;
   23766 		    bind->sizeNodes = 0;
   23767 		    parBind->nbNodes = bind->nbNodes;
   23768 		    bind->nbNodes = 0;
   23769 		} else {
   23770 		    /*
   23771 		    * Copy the entries.
   23772 		    */
   23773 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
   23774 			xmlMalloc(bind->nbNodes *
   23775 			sizeof(xmlSchemaPSVIIDCNodePtr));
   23776 		    if (parBind->nodeTable == NULL) {
   23777 			xmlSchemaVErrMemory(NULL,
   23778 			    "allocating an array of IDC node-table "
   23779 			    "items", NULL);
   23780 			xmlSchemaIDCFreeBinding(parBind);
   23781 			goto internal_error;
   23782 		    }
   23783 		    parBind->sizeNodes = bind->nbNodes;
   23784 		    parBind->nbNodes = bind->nbNodes;
   23785 		    memcpy(parBind->nodeTable, bind->nodeTable,
   23786 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
   23787 		}
   23788 	    }
   23789 	    if (bind->dupls) {
   23790 		/*
   23791 		* Move the duplicates.
   23792 		*/
   23793 		if (parBind->dupls != NULL)
   23794 		    xmlSchemaItemListFree(parBind->dupls);
   23795 		parBind->dupls = bind->dupls;
   23796 		bind->dupls = NULL;
   23797 	    }
   23798             if (parTable != NULL) {
   23799                 if (*parTable == NULL)
   23800                     *parTable = parBind;
   23801                 else {
   23802                     parBind->next = *parTable;
   23803                     *parTable = parBind;
   23804                 }
   23805             }
   23806 	}
   23807 
   23808 next_binding:
   23809 	bind = bind->next;
   23810     }
   23811     return (0);
   23812 
   23813 internal_error:
   23814     return(-1);
   23815 }
   23816 
   23817 /**
   23818  * xmlSchemaCheckCVCIDCKeyRef:
   23819  * @vctxt: the WXS validation context
   23820  * @elemDecl: the element declaration
   23821  *
   23822  * Check the cvc-idc-keyref constraints.
   23823  */
   23824 static int
   23825 xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
   23826 {
   23827     xmlSchemaIDCMatcherPtr matcher;
   23828     xmlSchemaPSVIIDCBindingPtr bind;
   23829 
   23830     matcher = vctxt->inode->idcMatchers;
   23831     /*
   23832     * Find a keyref.
   23833     */
   23834     while (matcher != NULL) {
   23835 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
   23836 	    matcher->targets &&
   23837 	    matcher->targets->nbItems)
   23838 	{
   23839 	    int i, j, k, res, nbFields, hasDupls;
   23840 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
   23841 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
   23842 
   23843 	    nbFields = matcher->aidc->def->nbFields;
   23844 
   23845 	    /*
   23846 	    * Find the IDC node-table for the referenced IDC key/unique.
   23847 	    */
   23848 	    bind = vctxt->inode->idcTable;
   23849 	    while (bind != NULL) {
   23850 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
   23851 		    bind->definition)
   23852 		    break;
   23853 		bind = bind->next;
   23854 	    }
   23855 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
   23856 	    /*
   23857 	    * Search for a matching key-sequences.
   23858 	    */
   23859 	    for (i = 0; i < matcher->targets->nbItems; i++) {
   23860 		res = 0;
   23861 		refNode = matcher->targets->items[i];
   23862 		if (bind != NULL) {
   23863 		    refKeys = refNode->keys;
   23864 		    for (j = 0; j < bind->nbNodes; j++) {
   23865 			keys = bind->nodeTable[j]->keys;
   23866 			for (k = 0; k < nbFields; k++) {
   23867 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
   23868 				refKeys[k]->val);
   23869 			    if (res == 0)
   23870 				break;
   23871 			    else if (res == -1) {
   23872 				return (-1);
   23873 			    }
   23874 			}
   23875 			if (res == 1) {
   23876 			    /*
   23877 			    * Match found.
   23878 			    */
   23879 			    break;
   23880 			}
   23881 		    }
   23882 		    if ((res == 0) && hasDupls) {
   23883 			/*
   23884 			* Search in duplicates
   23885 			*/
   23886 			for (j = 0; j < bind->dupls->nbItems; j++) {
   23887 			    keys = ((xmlSchemaPSVIIDCNodePtr)
   23888 				bind->dupls->items[j])->keys;
   23889 			    for (k = 0; k < nbFields; k++) {
   23890 				res = xmlSchemaAreValuesEqual(keys[k]->val,
   23891 				    refKeys[k]->val);
   23892 				if (res == 0)
   23893 				    break;
   23894 				else if (res == -1) {
   23895 				    return (-1);
   23896 				}
   23897 			    }
   23898 			    if (res == 1) {
   23899 				/*
   23900 				* Match in duplicates found.
   23901 				*/
   23902 				xmlChar *str = NULL, *strB = NULL;
   23903 				xmlSchemaKeyrefErr(vctxt,
   23904 				    XML_SCHEMAV_CVC_IDC, refNode,
   23905 				    (xmlSchemaTypePtr) matcher->aidc->def,
   23906 				    "More than one match found for "
   23907 				    "key-sequence %s of keyref '%s'",
   23908 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23909 					refNode->keys, nbFields),
   23910 				    xmlSchemaGetComponentQName(&strB,
   23911 					matcher->aidc->def));
   23912 				FREE_AND_NULL(str);
   23913 				FREE_AND_NULL(strB);
   23914 				break;
   23915 			    }
   23916 			}
   23917 		    }
   23918 		}
   23919 
   23920 		if (res == 0) {
   23921 		    xmlChar *str = NULL, *strB = NULL;
   23922 		    xmlSchemaKeyrefErr(vctxt,
   23923 			XML_SCHEMAV_CVC_IDC, refNode,
   23924 			(xmlSchemaTypePtr) matcher->aidc->def,
   23925 			"No match found for key-sequence %s of keyref '%s'",
   23926 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
   23927 			    refNode->keys, nbFields),
   23928 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
   23929 		    FREE_AND_NULL(str);
   23930 		    FREE_AND_NULL(strB);
   23931 		}
   23932 	    }
   23933 	}
   23934 	matcher = matcher->next;
   23935     }
   23936     /* TODO: Return an error if any error encountered. */
   23937     return (0);
   23938 }
   23939 
   23940 /************************************************************************
   23941  *									*
   23942  *			XML Reader validation code                      *
   23943  *									*
   23944  ************************************************************************/
   23945 
   23946 static xmlSchemaAttrInfoPtr
   23947 xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
   23948 {
   23949     xmlSchemaAttrInfoPtr iattr;
   23950     /*
   23951     * Grow/create list of attribute infos.
   23952     */
   23953     if (vctxt->attrInfos == NULL) {
   23954 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23955 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
   23956 	vctxt->sizeAttrInfos = 1;
   23957 	if (vctxt->attrInfos == NULL) {
   23958 	    xmlSchemaVErrMemory(vctxt,
   23959 		"allocating attribute info list", NULL);
   23960 	    return (NULL);
   23961 	}
   23962     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
   23963 	vctxt->sizeAttrInfos++;
   23964 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
   23965 	    xmlRealloc(vctxt->attrInfos,
   23966 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
   23967 	if (vctxt->attrInfos == NULL) {
   23968 	    xmlSchemaVErrMemory(vctxt,
   23969 		"re-allocating attribute info list", NULL);
   23970 	    return (NULL);
   23971 	}
   23972     } else {
   23973 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
   23974 	if (iattr->localName != NULL) {
   23975 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
   23976 		"attr info not cleared");
   23977 	    return (NULL);
   23978 	}
   23979 	iattr->nodeType = XML_ATTRIBUTE_NODE;
   23980 	return (iattr);
   23981     }
   23982     /*
   23983     * Create an attribute info.
   23984     */
   23985     iattr = (xmlSchemaAttrInfoPtr)
   23986 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
   23987     if (iattr == NULL) {
   23988 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
   23989 	return (NULL);
   23990     }
   23991     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
   23992     iattr->nodeType = XML_ATTRIBUTE_NODE;
   23993     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
   23994 
   23995     return (iattr);
   23996 }
   23997 
   23998 static int
   23999 xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
   24000 			xmlNodePtr attrNode,
   24001 			int nodeLine,
   24002 			const xmlChar *localName,
   24003 			const xmlChar *nsName,
   24004 			int ownedNames,
   24005 			xmlChar *value,
   24006 			int ownedValue)
   24007 {
   24008     xmlSchemaAttrInfoPtr attr;
   24009 
   24010     attr = xmlSchemaGetFreshAttrInfo(vctxt);
   24011     if (attr == NULL) {
   24012 	VERROR_INT("xmlSchemaPushAttribute",
   24013 	    "calling xmlSchemaGetFreshAttrInfo()");
   24014 	return (-1);
   24015     }
   24016     attr->node = attrNode;
   24017     attr->nodeLine = nodeLine;
   24018     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
   24019     attr->localName = localName;
   24020     attr->nsName = nsName;
   24021     if (ownedNames)
   24022 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   24023     /*
   24024     * Evaluate if it's an XSI attribute.
   24025     */
   24026     if (nsName != NULL) {
   24027 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
   24028 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24029 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
   24030 	    }
   24031 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
   24032 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24033 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
   24034 	    }
   24035 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
   24036 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24037 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
   24038 	    }
   24039 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
   24040 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
   24041 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
   24042 	    }
   24043 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
   24044 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
   24045 	}
   24046     }
   24047     attr->value = value;
   24048     if (ownedValue)
   24049 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   24050     if (attr->metaType != 0)
   24051 	attr->state = XML_SCHEMAS_ATTR_META;
   24052     return (0);
   24053 }
   24054 
   24055 /**
   24056  * xmlSchemaClearElemInfo:
   24057  * @vctxt: the WXS validation context
   24058  * @ielem: the element information item
   24059  */
   24060 static void
   24061 xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
   24062 		       xmlSchemaNodeInfoPtr ielem)
   24063 {
   24064     ielem->hasKeyrefs = 0;
   24065     ielem->appliedXPath = 0;
   24066     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   24067 	FREE_AND_NULL(ielem->localName);
   24068 	FREE_AND_NULL(ielem->nsName);
   24069     } else {
   24070 	ielem->localName = NULL;
   24071 	ielem->nsName = NULL;
   24072     }
   24073     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   24074 	FREE_AND_NULL(ielem->value);
   24075     } else {
   24076 	ielem->value = NULL;
   24077     }
   24078     if (ielem->val != NULL) {
   24079 	/*
   24080 	* PSVI TODO: Be careful not to free it when the value is
   24081 	* exposed via PSVI.
   24082 	*/
   24083 	xmlSchemaFreeValue(ielem->val);
   24084 	ielem->val = NULL;
   24085     }
   24086     if (ielem->idcMatchers != NULL) {
   24087 	/*
   24088 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
   24089 	*   Does it work?
   24090 	*/
   24091 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
   24092 #if 0
   24093 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
   24094 #endif
   24095 	ielem->idcMatchers = NULL;
   24096     }
   24097     if (ielem->idcTable != NULL) {
   24098 	/*
   24099 	* OPTIMIZE TODO: Use a pool of IDC tables??.
   24100 	*/
   24101 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
   24102 	ielem->idcTable = NULL;
   24103     }
   24104     if (ielem->regexCtxt != NULL) {
   24105 	xmlRegFreeExecCtxt(ielem->regexCtxt);
   24106 	ielem->regexCtxt = NULL;
   24107     }
   24108     if (ielem->nsBindings != NULL) {
   24109 	xmlFree((xmlChar **)ielem->nsBindings);
   24110 	ielem->nsBindings = NULL;
   24111 	ielem->nbNsBindings = 0;
   24112 	ielem->sizeNsBindings = 0;
   24113     }
   24114 }
   24115 
   24116 /**
   24117  * xmlSchemaGetFreshElemInfo:
   24118  * @vctxt: the schema validation context
   24119  *
   24120  * Creates/reuses and initializes the element info item for
   24121  * the currect tree depth.
   24122  *
   24123  * Returns the element info item or NULL on API or internal errors.
   24124  */
   24125 static xmlSchemaNodeInfoPtr
   24126 xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
   24127 {
   24128     xmlSchemaNodeInfoPtr info = NULL;
   24129 
   24130     if (vctxt->depth > vctxt->sizeElemInfos) {
   24131 	VERROR_INT("xmlSchemaGetFreshElemInfo",
   24132 	    "inconsistent depth encountered");
   24133 	return (NULL);
   24134     }
   24135     if (vctxt->elemInfos == NULL) {
   24136 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24137 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
   24138 	if (vctxt->elemInfos == NULL) {
   24139 	    xmlSchemaVErrMemory(vctxt,
   24140 		"allocating the element info array", NULL);
   24141 	    return (NULL);
   24142 	}
   24143 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
   24144 	vctxt->sizeElemInfos = 10;
   24145     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
   24146 	int i = vctxt->sizeElemInfos;
   24147 
   24148 	vctxt->sizeElemInfos *= 2;
   24149 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
   24150 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
   24151 	    sizeof(xmlSchemaNodeInfoPtr));
   24152 	if (vctxt->elemInfos == NULL) {
   24153 	    xmlSchemaVErrMemory(vctxt,
   24154 		"re-allocating the element info array", NULL);
   24155 	    return (NULL);
   24156 	}
   24157 	/*
   24158 	* We need the new memory to be NULLed.
   24159 	* TODO: Use memset instead?
   24160 	*/
   24161 	for (; i < vctxt->sizeElemInfos; i++)
   24162 	    vctxt->elemInfos[i] = NULL;
   24163     } else
   24164 	info = vctxt->elemInfos[vctxt->depth];
   24165 
   24166     if (info == NULL) {
   24167 	info = (xmlSchemaNodeInfoPtr)
   24168 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
   24169 	if (info == NULL) {
   24170 	    xmlSchemaVErrMemory(vctxt,
   24171 		"allocating an element info", NULL);
   24172 	    return (NULL);
   24173 	}
   24174 	vctxt->elemInfos[vctxt->depth] = info;
   24175     } else {
   24176 	if (info->localName != NULL) {
   24177 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
   24178 		"elem info has not been cleared");
   24179 	    return (NULL);
   24180 	}
   24181     }
   24182     memset(info, 0, sizeof(xmlSchemaNodeInfo));
   24183     info->nodeType = XML_ELEMENT_NODE;
   24184     info->depth = vctxt->depth;
   24185 
   24186     return (info);
   24187 }
   24188 
   24189 #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
   24190 #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
   24191 #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
   24192 
   24193 static int
   24194 xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
   24195 			xmlNodePtr node,
   24196 			xmlSchemaTypePtr type,
   24197 			xmlSchemaValType valType,
   24198 			const xmlChar * value,
   24199 			xmlSchemaValPtr val,
   24200 			unsigned long length,
   24201 			int fireErrors)
   24202 {
   24203     int ret, error = 0;
   24204 
   24205     xmlSchemaTypePtr tmpType;
   24206     xmlSchemaFacetLinkPtr facetLink;
   24207     xmlSchemaFacetPtr facet;
   24208     unsigned long len = 0;
   24209     xmlSchemaWhitespaceValueType ws;
   24210 
   24211     /*
   24212     * In Libxml2, derived built-in types have currently no explicit facets.
   24213     */
   24214     if (type->type == XML_SCHEMA_TYPE_BASIC)
   24215 	return (0);
   24216 
   24217     /*
   24218     * NOTE: Do not jump away, if the facetSet of the given type is
   24219     * empty: until now, "pattern" and "enumeration" facets of the
   24220     * *base types* need to be checked as well.
   24221     */
   24222     if (type->facetSet == NULL)
   24223 	goto pattern_and_enum;
   24224 
   24225     if (! WXS_IS_ATOMIC(type)) {
   24226 	if (WXS_IS_LIST(type))
   24227 	    goto WXS_IS_LIST;
   24228 	else
   24229 	    goto pattern_and_enum;
   24230     }
   24231 
   24232     /*
   24233     * Whitespace handling is only of importance for string-based
   24234     * types.
   24235     */
   24236     tmpType = xmlSchemaGetPrimitiveType(type);
   24237     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
   24238 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
   24239 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
   24240     } else
   24241 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
   24242 
   24243     /*
   24244     * If the value was not computed (for string or
   24245     * anySimpleType based types), then use the provided
   24246     * type.
   24247     */
   24248     if (val != NULL)
   24249 	valType = xmlSchemaGetValType(val);
   24250 
   24251     ret = 0;
   24252     for (facetLink = type->facetSet; facetLink != NULL;
   24253 	facetLink = facetLink->next) {
   24254 	/*
   24255 	* Skip the pattern "whiteSpace": it is used to
   24256 	* format the character content beforehand.
   24257 	*/
   24258 	switch (facetLink->facet->type) {
   24259 	    case XML_SCHEMA_FACET_WHITESPACE:
   24260 	    case XML_SCHEMA_FACET_PATTERN:
   24261 	    case XML_SCHEMA_FACET_ENUMERATION:
   24262 		continue;
   24263 	    case XML_SCHEMA_FACET_LENGTH:
   24264 	    case XML_SCHEMA_FACET_MINLENGTH:
   24265 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24266 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
   24267 		    valType, value, val, &len, ws);
   24268 		break;
   24269 	    default:
   24270 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
   24271 		    valType, value, val, ws);
   24272 		break;
   24273 	}
   24274 	if (ret < 0) {
   24275 	    AERROR_INT("xmlSchemaValidateFacets",
   24276 		"validating against a atomic type facet");
   24277 	    return (-1);
   24278 	} else if (ret > 0) {
   24279 	    if (fireErrors)
   24280 		xmlSchemaFacetErr(actxt, ret, node,
   24281 		value, len, type, facetLink->facet, NULL, NULL, NULL);
   24282 	    else
   24283 		return (ret);
   24284 	    if (error == 0)
   24285 		error = ret;
   24286 	}
   24287 	ret = 0;
   24288     }
   24289 
   24290 WXS_IS_LIST:
   24291     if (! WXS_IS_LIST(type))
   24292 	goto pattern_and_enum;
   24293     /*
   24294     * "length", "minLength" and "maxLength" of list types.
   24295     */
   24296     ret = 0;
   24297     for (facetLink = type->facetSet; facetLink != NULL;
   24298 	facetLink = facetLink->next) {
   24299 
   24300 	switch (facetLink->facet->type) {
   24301 	    case XML_SCHEMA_FACET_LENGTH:
   24302 	    case XML_SCHEMA_FACET_MINLENGTH:
   24303 	    case XML_SCHEMA_FACET_MAXLENGTH:
   24304 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
   24305 		    value, length, NULL);
   24306 		break;
   24307 	    default:
   24308 		continue;
   24309 	}
   24310 	if (ret < 0) {
   24311 	    AERROR_INT("xmlSchemaValidateFacets",
   24312 		"validating against a list type facet");
   24313 	    return (-1);
   24314 	} else if (ret > 0) {
   24315 	    if (fireErrors)
   24316 		xmlSchemaFacetErr(actxt, ret, node,
   24317 		value, length, type, facetLink->facet, NULL, NULL, NULL);
   24318 	    else
   24319 		return (ret);
   24320 	    if (error == 0)
   24321 		error = ret;
   24322 	}
   24323 	ret = 0;
   24324     }
   24325 
   24326 pattern_and_enum:
   24327     if (error >= 0) {
   24328 	int found = 0;
   24329 	/*
   24330 	* Process enumerations. Facet values are in the value space
   24331 	* of the defining type's base type. This seems to be a bug in the
   24332 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
   24333 	* Only the first set of enumerations in the ancestor-or-self axis
   24334 	* is used for validation.
   24335 	*/
   24336 	ret = 0;
   24337 	tmpType = type;
   24338 	do {
   24339 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
   24340 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
   24341 		    continue;
   24342 		found = 1;
   24343 		ret = xmlSchemaAreValuesEqual(facet->val, val);
   24344 		if (ret == 1)
   24345 		    break;
   24346 		else if (ret < 0) {
   24347 		    AERROR_INT("xmlSchemaValidateFacets",
   24348 			"validating against an enumeration facet");
   24349 		    return (-1);
   24350 		}
   24351 	    }
   24352 	    if (ret != 0)
   24353 		break;
   24354 	    /*
   24355 	    * Break on the first set of enumerations. Any additional
   24356 	    *  enumerations which might be existent on the ancestors
   24357 	    *  of the current type are restricted by this set; thus
   24358 	    *  *must* *not* be taken into account.
   24359 	    */
   24360 	    if (found)
   24361 		break;
   24362 	    tmpType = tmpType->baseType;
   24363 	} while ((tmpType != NULL) &&
   24364 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24365 	if (found && (ret == 0)) {
   24366 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
   24367 	    if (fireErrors) {
   24368 		xmlSchemaFacetErr(actxt, ret, node,
   24369 		    value, 0, type, NULL, NULL, NULL, NULL);
   24370 	    } else
   24371 		return (ret);
   24372 	    if (error == 0)
   24373 		error = ret;
   24374 	}
   24375     }
   24376 
   24377     if (error >= 0) {
   24378 	int found;
   24379 	/*
   24380 	* Process patters. Pattern facets are ORed at type level
   24381 	* and ANDed if derived. Walk the base type axis.
   24382 	*/
   24383 	tmpType = type;
   24384 	facet = NULL;
   24385 	do {
   24386 	    found = 0;
   24387 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
   24388 		facetLink = facetLink->next) {
   24389 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
   24390 		    continue;
   24391 		found = 1;
   24392 		/*
   24393 		* NOTE that for patterns, @value needs to be the
   24394 		* normalized vaule.
   24395 		*/
   24396 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
   24397 		if (ret == 1)
   24398 		    break;
   24399 		else if (ret < 0) {
   24400 		    AERROR_INT("xmlSchemaValidateFacets",
   24401 			"validating against a pattern facet");
   24402 		    return (-1);
   24403 		} else {
   24404 		    /*
   24405 		    * Save the last non-validating facet.
   24406 		    */
   24407 		    facet = facetLink->facet;
   24408 		}
   24409 	    }
   24410 	    if (found && (ret != 1)) {
   24411 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
   24412 		if (fireErrors) {
   24413 		    xmlSchemaFacetErr(actxt, ret, node,
   24414 			value, 0, type, facet, NULL, NULL, NULL);
   24415 		} else
   24416 		    return (ret);
   24417 		if (error == 0)
   24418 		    error = ret;
   24419 		break;
   24420 	    }
   24421 	    tmpType = tmpType->baseType;
   24422 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
   24423     }
   24424 
   24425     return (error);
   24426 }
   24427 
   24428 static xmlChar *
   24429 xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
   24430 			const xmlChar *value)
   24431 {
   24432     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
   24433 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
   24434 	    return (xmlSchemaCollapseString(value));
   24435 	case XML_SCHEMA_WHITESPACE_REPLACE:
   24436 	    return (xmlSchemaWhiteSpaceReplace(value));
   24437 	default:
   24438 	    return (NULL);
   24439     }
   24440 }
   24441 
   24442 static int
   24443 xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
   24444 		       const xmlChar *value,
   24445 		       xmlSchemaValPtr *val,
   24446 		       int valNeeded)
   24447 {
   24448     int ret;
   24449     const xmlChar *nsName;
   24450     xmlChar *local, *prefix = NULL;
   24451 
   24452     ret = xmlValidateQName(value, 1);
   24453     if (ret != 0) {
   24454 	if (ret == -1) {
   24455 	    VERROR_INT("xmlSchemaValidateQName",
   24456 		"calling xmlValidateQName()");
   24457 	    return (-1);
   24458 	}
   24459 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
   24460     }
   24461     /*
   24462     * NOTE: xmlSplitQName2 will always return a duplicated
   24463     * strings.
   24464     */
   24465     local = xmlSplitQName2(value, &prefix);
   24466     if (local == NULL)
   24467 	local = xmlStrdup(value);
   24468     /*
   24469     * OPTIMIZE TODO: Use flags for:
   24470     *  - is there any namespace binding?
   24471     *  - is there a default namespace?
   24472     */
   24473     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24474 
   24475     if (prefix != NULL) {
   24476 	xmlFree(prefix);
   24477 	/*
   24478 	* A namespace must be found if the prefix is
   24479 	* NOT NULL.
   24480 	*/
   24481 	if (nsName == NULL) {
   24482 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24483 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
   24484 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24485 		"The QName value '%s' has no "
   24486 		"corresponding namespace declaration in "
   24487 		"scope", value, NULL);
   24488 	    if (local != NULL)
   24489 		xmlFree(local);
   24490 	    return (ret);
   24491 	}
   24492     }
   24493     if (valNeeded && val) {
   24494 	if (nsName != NULL)
   24495 	    *val = xmlSchemaNewQNameValue(
   24496 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
   24497 	else
   24498 	    *val = xmlSchemaNewQNameValue(NULL,
   24499 		BAD_CAST local);
   24500     } else
   24501 	xmlFree(local);
   24502     return (0);
   24503 }
   24504 
   24505 /*
   24506 * cvc-simple-type
   24507 */
   24508 static int
   24509 xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
   24510 			     xmlNodePtr node,
   24511 			     xmlSchemaTypePtr type,
   24512 			     const xmlChar *value,
   24513 			     xmlSchemaValPtr *retVal,
   24514 			     int fireErrors,
   24515 			     int normalize,
   24516 			     int isNormalized)
   24517 {
   24518     int ret = 0, valNeeded = (retVal) ? 1 : 0;
   24519     xmlSchemaValPtr val = NULL;
   24520     /* xmlSchemaWhitespaceValueType ws; */
   24521     xmlChar *normValue = NULL;
   24522 
   24523 #define NORMALIZE(atype) \
   24524     if ((! isNormalized) && \
   24525     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
   24526 	normValue = xmlSchemaNormalizeValue(atype, value); \
   24527 	if (normValue != NULL) \
   24528 	    value = normValue; \
   24529 	isNormalized = 1; \
   24530     }
   24531 
   24532     if ((retVal != NULL) && (*retVal != NULL)) {
   24533 	xmlSchemaFreeValue(*retVal);
   24534 	*retVal = NULL;
   24535     }
   24536     /*
   24537     * 3.14.4 Simple Type Definition Validation Rules
   24538     * Validation Rule: String Valid
   24539     */
   24540     /*
   24541     * 1 It is schema-valid with respect to that definition as defined
   24542     * by Datatype Valid in [XML Schemas: Datatypes].
   24543     */
   24544     /*
   24545     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
   24546     * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
   24547     * the string must be a `declared entity name`.
   24548     */
   24549     /*
   24550     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
   24551     * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
   24552     * then every whitespace-delimited substring of the string must be a `declared
   24553     * entity name`.
   24554     */
   24555     /*
   24556     * 2.3 otherwise no further condition applies.
   24557     */
   24558     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
   24559 	valNeeded = 1;
   24560     if (value == NULL)
   24561 	value = BAD_CAST "";
   24562     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
   24563 	xmlSchemaTypePtr biType; /* The built-in type. */
   24564 	/*
   24565 	* SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
   24566 	* a literal in the `lexical space` of {base type definition}"
   24567 	*/
   24568 	/*
   24569 	* Whitespace-normalize.
   24570 	*/
   24571 	NORMALIZE(type);
   24572 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
   24573 	    /*
   24574 	    * Get the built-in type.
   24575 	    */
   24576 	    biType = type->baseType;
   24577 	    while ((biType != NULL) &&
   24578 		(biType->type != XML_SCHEMA_TYPE_BASIC))
   24579 		biType = biType->baseType;
   24580 
   24581 	    if (biType == NULL) {
   24582 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24583 		    "could not get the built-in type");
   24584 		goto internal_error;
   24585 	    }
   24586 	} else
   24587 	    biType = type;
   24588 	/*
   24589 	* NOTATIONs need to be processed here, since they need
   24590 	* to lookup in the hashtable of NOTATION declarations of the schema.
   24591 	*/
   24592 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
   24593 	    switch (biType->builtInType) {
   24594 		case XML_SCHEMAS_NOTATION:
   24595 		    ret = xmlSchemaValidateNotation(
   24596 			(xmlSchemaValidCtxtPtr) actxt,
   24597 			((xmlSchemaValidCtxtPtr) actxt)->schema,
   24598 			NULL, value, &val, valNeeded);
   24599 		    break;
   24600 		case XML_SCHEMAS_QNAME:
   24601 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
   24602 			value, &val, valNeeded);
   24603 		    break;
   24604 		default:
   24605 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24606 		    if (valNeeded)
   24607 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24608 			    value, &val, node);
   24609 		    else
   24610 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24611 			    value, NULL, node);
   24612 		    break;
   24613 	    }
   24614 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
   24615 	    switch (biType->builtInType) {
   24616 		case XML_SCHEMAS_NOTATION:
   24617 		    ret = xmlSchemaValidateNotation(NULL,
   24618 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
   24619 			value, &val, valNeeded);
   24620 		    break;
   24621 		default:
   24622 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
   24623 		    if (valNeeded)
   24624 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24625 			    value, &val, node);
   24626 		    else
   24627 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
   24628 			    value, NULL, node);
   24629 		    break;
   24630 	    }
   24631 	} else {
   24632 	    /*
   24633 	    * Validation via a public API is not implemented yet.
   24634 	    */
   24635 	    TODO
   24636 	    goto internal_error;
   24637 	}
   24638 	if (ret != 0) {
   24639 	    if (ret < 0) {
   24640 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24641 		    "validating against a built-in type");
   24642 		goto internal_error;
   24643 	    }
   24644 	    if (WXS_IS_LIST(type))
   24645 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24646 	    else
   24647 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24648 	}
   24649 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24650 	    /*
   24651 	    * Check facets.
   24652 	    */
   24653 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24654 		(xmlSchemaValType) biType->builtInType, value, val,
   24655 		0, fireErrors);
   24656 	    if (ret != 0) {
   24657 		if (ret < 0) {
   24658 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24659 			"validating facets of atomic simple type");
   24660 		    goto internal_error;
   24661 		}
   24662 		if (WXS_IS_LIST(type))
   24663 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24664 		else
   24665 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
   24666 	    }
   24667 	}
   24668 	if (fireErrors && (ret > 0))
   24669 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24670     } else if (WXS_IS_LIST(type)) {
   24671 
   24672 	xmlSchemaTypePtr itemType;
   24673 	const xmlChar *cur, *end;
   24674 	xmlChar *tmpValue = NULL;
   24675 	unsigned long len = 0;
   24676 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
   24677 	/* 1.2.2 if {variety} is `list` then the string must be a sequence
   24678 	* of white space separated tokens, each of which `match`es a literal
   24679 	* in the `lexical space` of {item type definition}
   24680 	*/
   24681 	/*
   24682 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
   24683 	* the list type has an enum or pattern facet.
   24684 	*/
   24685 	NORMALIZE(type);
   24686 	/*
   24687 	* VAL TODO: Optimize validation of empty values.
   24688 	* VAL TODO: We do not have computed values for lists.
   24689 	*/
   24690 	itemType = WXS_LIST_ITEMTYPE(type);
   24691 	cur = value;
   24692 	do {
   24693 	    while (IS_BLANK_CH(*cur))
   24694 		cur++;
   24695 	    end = cur;
   24696 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
   24697 		end++;
   24698 	    if (end == cur)
   24699 		break;
   24700 	    tmpValue = xmlStrndup(cur, end - cur);
   24701 	    len++;
   24702 
   24703 	    if (valNeeded)
   24704 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24705 		    tmpValue, &curVal, fireErrors, 0, 1);
   24706 	    else
   24707 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
   24708 		    tmpValue, NULL, fireErrors, 0, 1);
   24709 	    FREE_AND_NULL(tmpValue);
   24710 	    if (curVal != NULL) {
   24711 		/*
   24712 		* Add to list of computed values.
   24713 		*/
   24714 		if (val == NULL)
   24715 		    val = curVal;
   24716 		else
   24717 		    xmlSchemaValueAppend(prevVal, curVal);
   24718 		prevVal = curVal;
   24719 		curVal = NULL;
   24720 	    }
   24721 	    if (ret != 0) {
   24722 		if (ret < 0) {
   24723 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24724 			"validating an item of list simple type");
   24725 		    goto internal_error;
   24726 		}
   24727 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24728 		break;
   24729 	    }
   24730 	    cur = end;
   24731 	} while (*cur != 0);
   24732 	FREE_AND_NULL(tmpValue);
   24733 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24734 	    /*
   24735 	    * Apply facets (pattern, enumeration).
   24736 	    */
   24737 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24738 		XML_SCHEMAS_UNKNOWN, value, val,
   24739 		len, fireErrors);
   24740 	    if (ret != 0) {
   24741 		if (ret < 0) {
   24742 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24743 			"validating facets of list simple type");
   24744 		    goto internal_error;
   24745 		}
   24746 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
   24747 	    }
   24748 	}
   24749 	if (fireErrors && (ret > 0)) {
   24750 	    /*
   24751 	    * Report the normalized value.
   24752 	    */
   24753 	    normalize = 1;
   24754 	    NORMALIZE(type);
   24755 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24756 	}
   24757     } else if (WXS_IS_UNION(type)) {
   24758 	xmlSchemaTypeLinkPtr memberLink;
   24759 	/*
   24760 	* TODO: For all datatypes `derived` by `union`  whiteSpace does
   24761 	* not apply directly; however, the normalization behavior of `union`
   24762 	* types is controlled by the value of whiteSpace on that one of the
   24763 	* `memberTypes` against which the `union` is successfully validated.
   24764 	*
   24765 	* This means that the value is normalized by the first validating
   24766 	* member type, then the facets of the union type are applied. This
   24767 	* needs changing of the value!
   24768 	*/
   24769 
   24770 	/*
   24771 	* 1.2.3 if {variety} is `union` then the string must `match` a
   24772 	* literal in the `lexical space` of at least one member of
   24773 	* {member type definitions}
   24774 	*/
   24775 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
   24776 	if (memberLink == NULL) {
   24777 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24778 		"union simple type has no member types");
   24779 	    goto internal_error;
   24780 	}
   24781 	/*
   24782 	* Always normalize union type values, since we currently
   24783 	* cannot store the whitespace information with the value
   24784 	* itself; otherwise a later value-comparison would be
   24785 	* not possible.
   24786 	*/
   24787 	while (memberLink != NULL) {
   24788 	    if (valNeeded)
   24789 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24790 		    memberLink->type, value, &val, 0, 1, 0);
   24791 	    else
   24792 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
   24793 		    memberLink->type, value, NULL, 0, 1, 0);
   24794 	    if (ret <= 0)
   24795 		break;
   24796 	    memberLink = memberLink->next;
   24797 	}
   24798 	if (ret != 0) {
   24799 	    if (ret < 0) {
   24800 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24801 		    "validating members of union simple type");
   24802 		goto internal_error;
   24803 	    }
   24804 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24805 	}
   24806 	/*
   24807 	* Apply facets (pattern, enumeration).
   24808 	*/
   24809 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
   24810 	    /*
   24811 	    * The normalization behavior of `union` types is controlled by
   24812 	    * the value of whiteSpace on that one of the `memberTypes`
   24813 	    * against which the `union` is successfully validated.
   24814 	    */
   24815 	    NORMALIZE(memberLink->type);
   24816 	    ret = xmlSchemaValidateFacets(actxt, node, type,
   24817 		XML_SCHEMAS_UNKNOWN, value, val,
   24818 		0, fireErrors);
   24819 	    if (ret != 0) {
   24820 		if (ret < 0) {
   24821 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
   24822 			"validating facets of union simple type");
   24823 		    goto internal_error;
   24824 		}
   24825 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
   24826 	    }
   24827 	}
   24828 	if (fireErrors && (ret > 0))
   24829 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
   24830     }
   24831 
   24832     if (normValue != NULL)
   24833 	xmlFree(normValue);
   24834     if (ret == 0) {
   24835 	if (retVal != NULL)
   24836 	    *retVal = val;
   24837 	else if (val != NULL)
   24838 	    xmlSchemaFreeValue(val);
   24839     } else if (val != NULL)
   24840 	xmlSchemaFreeValue(val);
   24841     return (ret);
   24842 internal_error:
   24843     if (normValue != NULL)
   24844 	xmlFree(normValue);
   24845     if (val != NULL)
   24846 	xmlSchemaFreeValue(val);
   24847     return (-1);
   24848 }
   24849 
   24850 static int
   24851 xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
   24852 			   const xmlChar *value,
   24853 			   const xmlChar **nsName,
   24854 			   const xmlChar **localName)
   24855 {
   24856     int ret = 0;
   24857 
   24858     if ((nsName == NULL) || (localName == NULL))
   24859 	return (-1);
   24860     *nsName = NULL;
   24861     *localName = NULL;
   24862 
   24863     ret = xmlValidateQName(value, 1);
   24864     if (ret == -1)
   24865 	return (-1);
   24866     if (ret > 0) {
   24867 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
   24868 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24869 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
   24870 	return (1);
   24871     }
   24872     {
   24873 	xmlChar *local = NULL;
   24874 	xmlChar *prefix;
   24875 
   24876 	/*
   24877 	* NOTE: xmlSplitQName2 will return a duplicated
   24878 	* string.
   24879 	*/
   24880 	local = xmlSplitQName2(value, &prefix);
   24881 	if (local == NULL)
   24882 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
   24883 	else {
   24884 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
   24885 	    xmlFree(local);
   24886 	}
   24887 
   24888 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
   24889 
   24890 	if (prefix != NULL) {
   24891 	    xmlFree(prefix);
   24892 	    /*
   24893 	    * A namespace must be found if the prefix is NOT NULL.
   24894 	    */
   24895 	    if (*nsName == NULL) {
   24896 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24897 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
   24898 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24899 		    "The QName value '%s' has no "
   24900 		    "corresponding namespace declaration in scope",
   24901 		    value, NULL);
   24902 		return (2);
   24903 	    }
   24904 	}
   24905     }
   24906     return (0);
   24907 }
   24908 
   24909 static int
   24910 xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
   24911 			xmlSchemaAttrInfoPtr iattr,
   24912 			xmlSchemaTypePtr *localType,
   24913 			xmlSchemaElementPtr elemDecl)
   24914 {
   24915     int ret = 0;
   24916     /*
   24917     * cvc-elt (3.3.4) : (4)
   24918     * AND
   24919     * Schema-Validity Assessment (Element) (cvc-assess-elt)
   24920     *   (1.2.1.2.1) - (1.2.1.2.4)
   24921     * Handle 'xsi:type'.
   24922     */
   24923     if (localType == NULL)
   24924 	return (-1);
   24925     *localType = NULL;
   24926     if (iattr == NULL)
   24927 	return (0);
   24928     else {
   24929 	const xmlChar *nsName = NULL, *local = NULL;
   24930 	/*
   24931 	* TODO: We should report a *warning* that the type was overriden
   24932 	* by the instance.
   24933 	*/
   24934 	ACTIVATE_ATTRIBUTE(iattr);
   24935 	/*
   24936 	* (cvc-elt) (3.3.4) : (4.1)
   24937 	* (cvc-assess-elt) (1.2.1.2.2)
   24938 	*/
   24939 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
   24940 	    &nsName, &local);
   24941 	if (ret != 0) {
   24942 	    if (ret < 0) {
   24943 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
   24944 		    "calling xmlSchemaQNameExpand() to validate the "
   24945 		    "attribute 'xsi:type'");
   24946 		goto internal_error;
   24947 	    }
   24948 	    goto exit;
   24949 	}
   24950 	/*
   24951 	* (cvc-elt) (3.3.4) : (4.2)
   24952 	* (cvc-assess-elt) (1.2.1.2.3)
   24953 	*/
   24954 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
   24955 	if (*localType == NULL) {
   24956 	    xmlChar *str = NULL;
   24957 
   24958 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   24959 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
   24960 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
   24961 		"The QName value '%s' of the xsi:type attribute does not "
   24962 		"resolve to a type definition",
   24963 		xmlSchemaFormatQName(&str, nsName, local), NULL);
   24964 	    FREE_AND_NULL(str);
   24965 	    ret = vctxt->err;
   24966 	    goto exit;
   24967 	}
   24968 	if (elemDecl != NULL) {
   24969 	    int set = 0;
   24970 
   24971 	    /*
   24972 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
   24973 	    * "The `local type definition` must be validly
   24974 	    * derived from the {type definition} given the union of
   24975 	    * the {disallowed substitutions} and the {type definition}'s
   24976 	    * {prohibited substitutions}, as defined in
   24977 	    * Type Derivation OK (Complex) ($3.4.6)
   24978 	    * (if it is a complex type definition),
   24979 	    * or given {disallowed substitutions} as defined in Type
   24980 	    * Derivation OK (Simple) ($3.14.6) (if it is a simple type
   24981 	    * definition)."
   24982 	    *
   24983 	    * {disallowed substitutions}: the "block" on the element decl.
   24984 	    * {prohibited substitutions}: the "block" on the type def.
   24985 	    */
   24986 	    /*
   24987 	    * OPTIMIZE TODO: We could map types already evaluated
   24988 	    * to be validly derived from other types to avoid checking
   24989 	    * this over and over for the same types.
   24990 	    */
   24991 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
   24992 		(elemDecl->subtypes->flags &
   24993 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
   24994 		set |= SUBSET_EXTENSION;
   24995 
   24996 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
   24997 		(elemDecl->subtypes->flags &
   24998 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
   24999 		set |= SUBSET_RESTRICTION;
   25000 
   25001 	    /*
   25002 	    * REMOVED and CHANGED since this produced a parser context
   25003 	    * which adds to the string dict of the schema. So this would
   25004 	    * change the schema and we don't want this. We don't need
   25005 	    * the parser context anymore.
   25006 	    *
   25007 	    * if ((vctxt->pctxt == NULL) &&
   25008 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   25009 	    *	    return (-1);
   25010 	    */
   25011 
   25012 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
   25013 		elemDecl->subtypes, set) != 0) {
   25014 		xmlChar *str = NULL;
   25015 
   25016 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25017 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
   25018 		    "The type definition '%s', specified by xsi:type, is "
   25019 		    "blocked or not validly derived from the type definition "
   25020 		    "of the element declaration",
   25021 		    xmlSchemaFormatQName(&str,
   25022 			(*localType)->targetNamespace,
   25023 			(*localType)->name),
   25024 		    NULL);
   25025 		FREE_AND_NULL(str);
   25026 		ret = vctxt->err;
   25027 		*localType = NULL;
   25028 	    }
   25029 	}
   25030     }
   25031 exit:
   25032     ACTIVATE_ELEM;
   25033     return (ret);
   25034 internal_error:
   25035     ACTIVATE_ELEM;
   25036     return (-1);
   25037 }
   25038 
   25039 static int
   25040 xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
   25041 {
   25042     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
   25043     xmlSchemaTypePtr actualType;
   25044 
   25045     /*
   25046     * cvc-elt (3.3.4) : 1
   25047     */
   25048     if (elemDecl == NULL) {
   25049 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
   25050 	    "No matching declaration available");
   25051         return (vctxt->err);
   25052     }
   25053     actualType = WXS_ELEM_TYPEDEF(elemDecl);
   25054     /*
   25055     * cvc-elt (3.3.4) : 2
   25056     */
   25057     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
   25058 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
   25059 	    "The element declaration is abstract");
   25060         return (vctxt->err);
   25061     }
   25062     if (actualType == NULL) {
   25063 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25064 	    "The type definition is absent");
   25065 	return (XML_SCHEMAV_CVC_TYPE_1);
   25066     }
   25067     if (vctxt->nbAttrInfos != 0) {
   25068 	int ret;
   25069 	xmlSchemaAttrInfoPtr iattr;
   25070 	/*
   25071 	* cvc-elt (3.3.4) : 3
   25072 	* Handle 'xsi:nil'.
   25073 	*/
   25074 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25075 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
   25076 	if (iattr) {
   25077 	    ACTIVATE_ATTRIBUTE(iattr);
   25078 	    /*
   25079 	    * Validate the value.
   25080 	    */
   25081 	    ret = xmlSchemaVCheckCVCSimpleType(
   25082 		ACTXT_CAST vctxt, NULL,
   25083 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
   25084 		iattr->value, &(iattr->val), 1, 0, 0);
   25085 	    ACTIVATE_ELEM;
   25086 	    if (ret < 0) {
   25087 		VERROR_INT("xmlSchemaValidateElemDecl",
   25088 		    "calling xmlSchemaVCheckCVCSimpleType() to "
   25089 		    "validate the attribute 'xsi:nil'");
   25090 		return (-1);
   25091 	    }
   25092 	    if (ret == 0) {
   25093 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
   25094 		    /*
   25095 		    * cvc-elt (3.3.4) : 3.1
   25096 		    */
   25097 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
   25098 			"The element is not 'nillable'");
   25099 		    /* Does not return an error on purpose. */
   25100 		} else {
   25101 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
   25102 			/*
   25103 			* cvc-elt (3.3.4) : 3.2.2
   25104 			*/
   25105 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
   25106 			    (elemDecl->value != NULL)) {
   25107 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
   25108 				"The element cannot be 'nilled' because "
   25109 				"there is a fixed value constraint defined "
   25110 				"for it");
   25111 			     /* Does not return an error on purpose. */
   25112 			} else
   25113 			    vctxt->inode->flags |=
   25114 				XML_SCHEMA_ELEM_INFO_NILLED;
   25115 		    }
   25116 		}
   25117 	    }
   25118 	}
   25119 	/*
   25120 	* cvc-elt (3.3.4) : 4
   25121 	* Handle 'xsi:type'.
   25122 	*/
   25123 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25124 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25125 	if (iattr) {
   25126 	    xmlSchemaTypePtr localType = NULL;
   25127 
   25128 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
   25129 		elemDecl);
   25130 	    if (ret != 0) {
   25131 		if (ret == -1) {
   25132 		    VERROR_INT("xmlSchemaValidateElemDecl",
   25133 			"calling xmlSchemaProcessXSIType() to "
   25134 			"process the attribute 'xsi:type'");
   25135 		    return (-1);
   25136 		}
   25137 		/* Does not return an error on purpose. */
   25138 	    }
   25139 	    if (localType != NULL) {
   25140 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
   25141 		actualType = localType;
   25142 	    }
   25143 	}
   25144     }
   25145     /*
   25146     * IDC: Register identity-constraint XPath matchers.
   25147     */
   25148     if ((elemDecl->idcs != NULL) &&
   25149 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
   25150 	    return (-1);
   25151     /*
   25152     * No actual type definition.
   25153     */
   25154     if (actualType == NULL) {
   25155 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
   25156 	    "The type definition is absent");
   25157 	return (XML_SCHEMAV_CVC_TYPE_1);
   25158     }
   25159     /*
   25160     * Remember the actual type definition.
   25161     */
   25162     vctxt->inode->typeDef = actualType;
   25163 
   25164     return (0);
   25165 }
   25166 
   25167 static int
   25168 xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
   25169 {
   25170     xmlSchemaAttrInfoPtr iattr;
   25171     int ret = 0, i;
   25172 
   25173     /*
   25174     * SPEC cvc-type (3.1.1)
   25175     * "The attributes of must be empty, excepting those whose namespace
   25176     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
   25177     * whose local name is one of type, nil, schemaLocation or
   25178     * noNamespaceSchemaLocation."
   25179     */
   25180     if (vctxt->nbAttrInfos == 0)
   25181 	return (0);
   25182     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25183 	iattr = vctxt->attrInfos[i];
   25184 	if (! iattr->metaType) {
   25185 	    ACTIVATE_ATTRIBUTE(iattr)
   25186 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25187 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
   25188 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
   25189         }
   25190     }
   25191     ACTIVATE_ELEM
   25192     return (ret);
   25193 }
   25194 
   25195 /*
   25196 * Cleanup currently used attribute infos.
   25197 */
   25198 static void
   25199 xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
   25200 {
   25201     int i;
   25202     xmlSchemaAttrInfoPtr attr;
   25203 
   25204     if (vctxt->nbAttrInfos == 0)
   25205 	return;
   25206     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25207 	attr = vctxt->attrInfos[i];
   25208 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
   25209 	    if (attr->localName != NULL)
   25210 		xmlFree((xmlChar *) attr->localName);
   25211 	    if (attr->nsName != NULL)
   25212 		xmlFree((xmlChar *) attr->nsName);
   25213 	}
   25214 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   25215 	    if (attr->value != NULL)
   25216 		xmlFree((xmlChar *) attr->value);
   25217 	}
   25218 	if (attr->val != NULL) {
   25219 	    xmlSchemaFreeValue(attr->val);
   25220 	    attr->val = NULL;
   25221 	}
   25222 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
   25223     }
   25224     vctxt->nbAttrInfos = 0;
   25225 }
   25226 
   25227 /*
   25228 * 3.4.4 Complex Type Definition Validation Rules
   25229 *   Element Locally Valid (Complex Type) (cvc-complex-type)
   25230 * 3.2.4 Attribute Declaration Validation Rules
   25231 *   Validation Rule: Attribute Locally Valid (cvc-attribute)
   25232 *   Attribute Locally Valid (Use) (cvc-au)
   25233 *
   25234 * Only "assessed" attribute information items will be visible to
   25235 * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
   25236 */
   25237 static int
   25238 xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
   25239 {
   25240     xmlSchemaTypePtr type = vctxt->inode->typeDef;
   25241     xmlSchemaItemListPtr attrUseList;
   25242     xmlSchemaAttributeUsePtr attrUse = NULL;
   25243     xmlSchemaAttributePtr attrDecl = NULL;
   25244     xmlSchemaAttrInfoPtr iattr, tmpiattr;
   25245     int i, j, found, nbAttrs, nbUses;
   25246     int xpathRes = 0, res, wildIDs = 0, fixed;
   25247     xmlNodePtr defAttrOwnerElem = NULL;
   25248 
   25249     /*
   25250     * SPEC (cvc-attribute)
   25251     * (1) "The declaration must not be `absent` (see Missing
   25252     * Sub-components ($5.3) for how this can fail to be
   25253     * the case)."
   25254     * (2) "Its {type definition} must not be absent."
   25255     *
   25256     * NOTE (1) + (2): This is not handled here, since we currently do not
   25257     * allow validation against schemas which have missing sub-components.
   25258     *
   25259     * SPEC (cvc-complex-type)
   25260     * (3) "For each attribute information item in the element information
   25261     * item's [attributes] excepting those whose [namespace name] is
   25262     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
   25263     * [local name] is one of type, nil, schemaLocation or
   25264     * noNamespaceSchemaLocation, the appropriate case among the following
   25265     * must be true:
   25266     *
   25267     */
   25268     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
   25269     /*
   25270     * @nbAttrs is the number of attributes present in the instance.
   25271     */
   25272     nbAttrs = vctxt->nbAttrInfos;
   25273     if (attrUseList != NULL)
   25274 	nbUses = attrUseList->nbItems;
   25275     else
   25276 	nbUses = 0;
   25277     for (i = 0; i < nbUses; i++) {
   25278         found = 0;
   25279 	attrUse = attrUseList->items[i];
   25280 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
   25281         for (j = 0; j < nbAttrs; j++) {
   25282 	    iattr = vctxt->attrInfos[j];
   25283 	    /*
   25284 	    * SPEC (cvc-complex-type) (3)
   25285 	    * Skip meta attributes.
   25286 	    */
   25287 	    if (iattr->metaType)
   25288 		continue;
   25289 	    if (iattr->localName[0] != attrDecl->name[0])
   25290 		continue;
   25291 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
   25292 		continue;
   25293 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
   25294 		continue;
   25295 	    found = 1;
   25296 	    /*
   25297 	    * SPEC (cvc-complex-type)
   25298 	    * (3.1) "If there is among the {attribute uses} an attribute
   25299 	    * use with an {attribute declaration} whose {name} matches
   25300 	    * the attribute information item's [local name] and whose
   25301 	    * {target namespace} is identical to the attribute information
   25302 	    * item's [namespace name] (where an `absent` {target namespace}
   25303 	    * is taken to be identical to a [namespace name] with no value),
   25304 	    * then the attribute information must be `valid` with respect
   25305 	    * to that attribute use as per Attribute Locally Valid (Use)
   25306 	    * ($3.5.4). In this case the {attribute declaration} of that
   25307 	    * attribute use is the `context-determined declaration` for the
   25308 	    * attribute information item with respect to Schema-Validity
   25309 	    * Assessment (Attribute) ($3.2.4) and
   25310 	    * Assessment Outcome (Attribute) ($3.2.5).
   25311 	    */
   25312 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25313 	    iattr->use = attrUse;
   25314 	    /*
   25315 	    * Context-determined declaration.
   25316 	    */
   25317 	    iattr->decl = attrDecl;
   25318 	    iattr->typeDef = attrDecl->subtypes;
   25319 	    break;
   25320 	}
   25321 
   25322 	if (found)
   25323 	    continue;
   25324 
   25325 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
   25326 	    /*
   25327 	    * Handle non-existent, required attributes.
   25328 	    *
   25329 	    * SPEC (cvc-complex-type)
   25330 	    * (4) "The {attribute declaration} of each attribute use in
   25331 	    * the {attribute uses} whose {required} is true matches one
   25332 	    * of the attribute information items in the element information
   25333 	    * item's [attributes] as per clause 3.1 above."
   25334 	    */
   25335 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25336 	    if (tmpiattr == NULL) {
   25337 		VERROR_INT(
   25338 		    "xmlSchemaVAttributesComplex",
   25339 		    "calling xmlSchemaGetFreshAttrInfo()");
   25340 		return (-1);
   25341 	    }
   25342 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
   25343 	    tmpiattr->use = attrUse;
   25344 	    tmpiattr->decl = attrDecl;
   25345 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
   25346 	    ((attrUse->defValue != NULL) ||
   25347 	     (attrDecl->defValue != NULL))) {
   25348 	    /*
   25349 	    * Handle non-existent, optional, default/fixed attributes.
   25350 	    */
   25351 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
   25352 	    if (tmpiattr == NULL) {
   25353 		VERROR_INT(
   25354 		    "xmlSchemaVAttributesComplex",
   25355 		    "calling xmlSchemaGetFreshAttrInfo()");
   25356 		return (-1);
   25357 	    }
   25358 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
   25359 	    tmpiattr->use = attrUse;
   25360 	    tmpiattr->decl = attrDecl;
   25361 	    tmpiattr->typeDef = attrDecl->subtypes;
   25362 	    tmpiattr->localName = attrDecl->name;
   25363 	    tmpiattr->nsName = attrDecl->targetNamespace;
   25364 	}
   25365     }
   25366 
   25367     if (vctxt->nbAttrInfos == 0)
   25368 	return (0);
   25369     /*
   25370     * Validate against the wildcard.
   25371     */
   25372     if (type->attributeWildcard != NULL) {
   25373 	/*
   25374 	* SPEC (cvc-complex-type)
   25375 	* (3.2.1) "There must be an {attribute wildcard}."
   25376 	*/
   25377 	for (i = 0; i < nbAttrs; i++) {
   25378 	    iattr = vctxt->attrInfos[i];
   25379 	    /*
   25380 	    * SPEC (cvc-complex-type) (3)
   25381 	    * Skip meta attributes.
   25382 	    */
   25383 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
   25384 		continue;
   25385 	    /*
   25386 	    * SPEC (cvc-complex-type)
   25387 	    * (3.2.2) "The attribute information item must be `valid` with
   25388 	    * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
   25389 	    *
   25390 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
   25391 	    * "... its [namespace name] must be `valid` with respect to
   25392 	    * the wildcard constraint, as defined in Wildcard allows
   25393 	    * Namespace Name ($3.10.4)."
   25394 	    */
   25395 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
   25396 		    iattr->nsName) == 0) {
   25397 		/*
   25398 		* Handle processContents.
   25399 		*
   25400 		* SPEC (cvc-wildcard):
   25401 		* processContents | context-determined declaration:
   25402 		* "strict"          "mustFind"
   25403 		* "lax"             "none"
   25404 		* "skip"            "skip"
   25405 		*/
   25406 		if (type->attributeWildcard->processContents ==
   25407 		    XML_SCHEMAS_ANY_SKIP) {
   25408 		     /*
   25409 		    * context-determined declaration = "skip"
   25410 		    *
   25411 		    * SPEC PSVI Assessment Outcome (Attribute)
   25412 		    * [validity] = "notKnown"
   25413 		    * [validation attempted] = "none"
   25414 		    */
   25415 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
   25416 		    continue;
   25417 		}
   25418 		/*
   25419 		* Find an attribute declaration.
   25420 		*/
   25421 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
   25422 		    iattr->localName, iattr->nsName);
   25423 		if (iattr->decl != NULL) {
   25424 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
   25425 		    /*
   25426 		    * SPEC (cvc-complex-type)
   25427 		    * (5) "Let [Definition:]  the wild IDs be the set of
   25428 		    * all attribute information item to which clause 3.2
   25429 		    * applied and whose `validation` resulted in a
   25430 		    * `context-determined declaration` of mustFind or no
   25431 		    * `context-determined declaration` at all, and whose
   25432 		    * [local name] and [namespace name] resolve (as
   25433 		    * defined by QName resolution (Instance) ($3.15.4)) to
   25434 		    * an attribute declaration whose {type definition} is
   25435 		    * or is derived from ID. Then all of the following
   25436 		    * must be true:"
   25437 		    */
   25438 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
   25439 		    if (xmlSchemaIsDerivedFromBuiltInType(
   25440 			iattr->typeDef, XML_SCHEMAS_ID)) {
   25441 			/*
   25442 			* SPEC (5.1) "There must be no more than one
   25443 			* item in `wild IDs`."
   25444 			*/
   25445 			if (wildIDs != 0) {
   25446 			    /* VAL TODO */
   25447 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
   25448 			    TODO
   25449 			    continue;
   25450 			}
   25451 			wildIDs++;
   25452 			/*
   25453 			* SPEC (cvc-complex-type)
   25454 			* (5.2) "If `wild IDs` is non-empty, there must not
   25455 			* be any attribute uses among the {attribute uses}
   25456 			* whose {attribute declaration}'s {type definition}
   25457 			* is or is derived from ID."
   25458 			*/
   25459                         if (attrUseList != NULL) {
   25460                             for (j = 0; j < attrUseList->nbItems; j++) {
   25461                                 if (xmlSchemaIsDerivedFromBuiltInType(
   25462                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
   25463                                     XML_SCHEMAS_ID)) {
   25464                                     /* URGENT VAL TODO: implement */
   25465                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
   25466                                     TODO
   25467                                     break;
   25468                                 }
   25469                             }
   25470                         }
   25471 		    }
   25472 		} else if (type->attributeWildcard->processContents ==
   25473 		    XML_SCHEMAS_ANY_LAX) {
   25474 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
   25475 		    /*
   25476 		    * SPEC PSVI Assessment Outcome (Attribute)
   25477 		    * [validity] = "notKnown"
   25478 		    * [validation attempted] = "none"
   25479 		    */
   25480 		} else {
   25481 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
   25482 		}
   25483 	    }
   25484 	}
   25485     }
   25486 
   25487     if (vctxt->nbAttrInfos == 0)
   25488 	return (0);
   25489 
   25490     /*
   25491     * Get the owner element; needed for creation of default attributes.
   25492     * This fixes bug #341337, reported by David Grohmann.
   25493     */
   25494     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
   25495 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
   25496 	if (ielem && ielem->node && ielem->node->doc)
   25497 	    defAttrOwnerElem = ielem->node;
   25498     }
   25499     /*
   25500     * Validate values, create default attributes, evaluate IDCs.
   25501     */
   25502     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25503 	iattr = vctxt->attrInfos[i];
   25504 	/*
   25505 	* VAL TODO: Note that we won't try to resolve IDCs to
   25506 	* "lax" and "skip" validated attributes. Check what to
   25507 	* do in this case.
   25508 	*/
   25509 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
   25510 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
   25511 	    continue;
   25512 	/*
   25513 	* VAL TODO: What to do if the type definition is missing?
   25514 	*/
   25515 	if (iattr->typeDef == NULL) {
   25516 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
   25517 	    continue;
   25518 	}
   25519 
   25520 	ACTIVATE_ATTRIBUTE(iattr);
   25521 	fixed = 0;
   25522 	xpathRes = 0;
   25523 
   25524 	if (vctxt->xpathStates != NULL) {
   25525 	    /*
   25526 	    * Evaluate IDCs.
   25527 	    */
   25528 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
   25529 		XML_ATTRIBUTE_NODE);
   25530 	    if (xpathRes == -1) {
   25531 		VERROR_INT("xmlSchemaVAttributesComplex",
   25532 		    "calling xmlSchemaXPathEvaluate()");
   25533 		goto internal_error;
   25534 	    }
   25535 	}
   25536 
   25537 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
   25538 	    /*
   25539 	    * Default/fixed attributes.
   25540 	    * We need the value only if we need to resolve IDCs or
   25541 	    * will create default attributes.
   25542 	    */
   25543 	    if ((xpathRes) || (defAttrOwnerElem)) {
   25544 		if (iattr->use->defValue != NULL) {
   25545 		    iattr->value = (xmlChar *) iattr->use->defValue;
   25546 		    iattr->val = iattr->use->defVal;
   25547 		} else {
   25548 		    iattr->value = (xmlChar *) iattr->decl->defValue;
   25549 		    iattr->val = iattr->decl->defVal;
   25550 		}
   25551 		/*
   25552 		* IDCs will consume the precomputed default value,
   25553 		* so we need to clone it.
   25554 		*/
   25555 		if (iattr->val == NULL) {
   25556 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25557 			"default/fixed value on an attribute use was "
   25558 			"not precomputed");
   25559 		    goto internal_error;
   25560 		}
   25561 		iattr->val = xmlSchemaCopyValue(iattr->val);
   25562 		if (iattr->val == NULL) {
   25563 		    VERROR_INT("xmlSchemaVAttributesComplex",
   25564 			"calling xmlSchemaCopyValue()");
   25565 		    goto internal_error;
   25566 		}
   25567 	    }
   25568 	    /*
   25569 	    * PSVI: Add the default attribute to the current element.
   25570 	    * VAL TODO: Should we use the *normalized* value? This currently
   25571 	    *   uses the *initial* value.
   25572 	    */
   25573 
   25574 	    if (defAttrOwnerElem) {
   25575 		xmlChar *normValue;
   25576 		const xmlChar *value;
   25577 
   25578 		value = iattr->value;
   25579 		/*
   25580 		* Normalize the value.
   25581 		*/
   25582 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
   25583 		    iattr->value);
   25584 		if (normValue != NULL)
   25585 		    value = BAD_CAST normValue;
   25586 
   25587 		if (iattr->nsName == NULL) {
   25588 		    if (xmlNewProp(defAttrOwnerElem,
   25589 			iattr->localName, value) == NULL) {
   25590 			VERROR_INT("xmlSchemaVAttributesComplex",
   25591 			    "calling xmlNewProp()");
   25592 			if (normValue != NULL)
   25593 			    xmlFree(normValue);
   25594 			goto internal_error;
   25595 		    }
   25596 		} else {
   25597 		    xmlNsPtr ns;
   25598 
   25599 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
   25600 			defAttrOwnerElem, iattr->nsName);
   25601 		    if (ns == NULL) {
   25602 			xmlChar prefix[12];
   25603 			int counter = 0;
   25604 
   25605 			/*
   25606 			* Create a namespace declaration on the validation
   25607 			* root node if no namespace declaration is in scope.
   25608 			*/
   25609 			do {
   25610 			    snprintf((char *) prefix, 12, "p%d", counter++);
   25611 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
   25612 				defAttrOwnerElem, BAD_CAST prefix);
   25613 			    if (counter > 1000) {
   25614 				VERROR_INT(
   25615 				    "xmlSchemaVAttributesComplex",
   25616 				    "could not compute a ns prefix for a "
   25617 				    "default/fixed attribute");
   25618 				if (normValue != NULL)
   25619 				    xmlFree(normValue);
   25620 				goto internal_error;
   25621 			    }
   25622 			} while (ns != NULL);
   25623 			ns = xmlNewNs(vctxt->validationRoot,
   25624 			    iattr->nsName, BAD_CAST prefix);
   25625 		    }
   25626 		    /*
   25627 		    * TODO:
   25628 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
   25629 		    * If we have QNames: do we need to ensure there's a
   25630 		    * prefix defined for the QName?
   25631 		    */
   25632 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
   25633 		}
   25634 		if (normValue != NULL)
   25635 		    xmlFree(normValue);
   25636 	    }
   25637 	    /*
   25638 	    * Go directly to IDC evaluation.
   25639 	    */
   25640 	    goto eval_idcs;
   25641 	}
   25642 	/*
   25643 	* Validate the value.
   25644 	*/
   25645 	if (vctxt->value != NULL) {
   25646 	    /*
   25647 	    * Free last computed value; just for safety reasons.
   25648 	    */
   25649 	    xmlSchemaFreeValue(vctxt->value);
   25650 	    vctxt->value = NULL;
   25651 	}
   25652 	/*
   25653 	* Note that the attribute *use* can be unavailable, if
   25654 	* the attribute was a wild attribute.
   25655 	*/
   25656 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
   25657 	    ((iattr->use != NULL) &&
   25658 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
   25659 	    fixed = 1;
   25660 	else
   25661 	    fixed = 0;
   25662 	/*
   25663 	* SPEC (cvc-attribute)
   25664 	* (3) "The item's `normalized value` must be locally `valid`
   25665 	* with respect to that {type definition} as per
   25666 	* String Valid ($3.14.4)."
   25667 	*
   25668 	* VAL TODO: Do we already have the
   25669 	* "normalized attribute value" here?
   25670 	*/
   25671 	if (xpathRes || fixed) {
   25672 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
   25673 	    /*
   25674 	    * Request a computed value.
   25675 	    */
   25676 	    res = xmlSchemaVCheckCVCSimpleType(
   25677 		ACTXT_CAST vctxt,
   25678 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
   25679 		1, 1, 0);
   25680 	} else {
   25681 	    res = xmlSchemaVCheckCVCSimpleType(
   25682 		ACTXT_CAST vctxt,
   25683 		iattr->node, iattr->typeDef, iattr->value, NULL,
   25684 		1, 0, 0);
   25685 	}
   25686 
   25687 	if (res != 0) {
   25688 	    if (res == -1) {
   25689 		VERROR_INT("xmlSchemaVAttributesComplex",
   25690 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
   25691 		goto internal_error;
   25692 	    }
   25693 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
   25694 	    /*
   25695 	    * SPEC PSVI Assessment Outcome (Attribute)
   25696 	    * [validity] = "invalid"
   25697 	    */
   25698 	    goto eval_idcs;
   25699 	}
   25700 
   25701 	if (fixed) {
   25702 	    /*
   25703 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
   25704 	    * "For an attribute information item to be `valid`
   25705 	    * with respect to an attribute use its *normalized*
   25706 	    * value must match the *canonical* lexical
   25707 	    * representation of the attribute use's {value
   25708 	    * constraint}value, if it is present and fixed."
   25709 	    *
   25710 	    * VAL TODO: The requirement for the *canonical* value
   25711 	    * will be removed in XML Schema 1.1.
   25712 	    */
   25713 	    /*
   25714 	    * SPEC Attribute Locally Valid (cvc-attribute)
   25715 	    * (4) "The item's *actual* value must match the *value* of
   25716 	    * the {value constraint}, if it is present and fixed."
   25717 	    */
   25718 	    if (iattr->val == NULL) {
   25719 		/* VAL TODO: A value was not precomputed. */
   25720 		TODO
   25721 		goto eval_idcs;
   25722 	    }
   25723 	    if ((iattr->use != NULL) &&
   25724 		(iattr->use->defValue != NULL)) {
   25725 		if (iattr->use->defVal == NULL) {
   25726 		    /* VAL TODO: A default value was not precomputed. */
   25727 		    TODO
   25728 		    goto eval_idcs;
   25729 		}
   25730 		iattr->vcValue = iattr->use->defValue;
   25731 		/*
   25732 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25733 		    (xmlSchemaWhitespaceValueType) ws,
   25734 		    attr->use->defVal,
   25735 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25736 		*/
   25737 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
   25738 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25739 	    } else {
   25740 		if (iattr->decl->defVal == NULL) {
   25741 		    /* VAL TODO: A default value was not precomputed. */
   25742 		    TODO
   25743 		    goto eval_idcs;
   25744 		}
   25745 		iattr->vcValue = iattr->decl->defValue;
   25746 		/*
   25747 		if (xmlSchemaCompareValuesWhtsp(attr->val,
   25748 		    (xmlSchemaWhitespaceValueType) ws,
   25749 		    attrDecl->defVal,
   25750 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
   25751 		*/
   25752 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
   25753 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
   25754 	    }
   25755 	    /*
   25756 	    * [validity] = "valid"
   25757 	    */
   25758 	}
   25759 eval_idcs:
   25760 	/*
   25761 	* Evaluate IDCs.
   25762 	*/
   25763 	if (xpathRes) {
   25764 	    if (xmlSchemaXPathProcessHistory(vctxt,
   25765 		vctxt->depth +1) == -1) {
   25766 		VERROR_INT("xmlSchemaVAttributesComplex",
   25767 		    "calling xmlSchemaXPathEvaluate()");
   25768 		goto internal_error;
   25769 	    }
   25770 	} else if (vctxt->xpathStates != NULL)
   25771 	    xmlSchemaXPathPop(vctxt);
   25772     }
   25773 
   25774     /*
   25775     * Report errors.
   25776     */
   25777     for (i = 0; i < vctxt->nbAttrInfos; i++) {
   25778 	iattr = vctxt->attrInfos[i];
   25779 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
   25780 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
   25781 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
   25782 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
   25783 	    continue;
   25784 	ACTIVATE_ATTRIBUTE(iattr);
   25785 	switch (iattr->state) {
   25786 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
   25787 		    xmlChar *str = NULL;
   25788 		    ACTIVATE_ELEM;
   25789 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25790 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
   25791 			"The attribute '%s' is required but missing",
   25792 			xmlSchemaFormatQName(&str,
   25793 			    iattr->decl->targetNamespace,
   25794 			    iattr->decl->name),
   25795 			NULL);
   25796 		    FREE_AND_NULL(str)
   25797 		    break;
   25798 		}
   25799 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
   25800 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
   25801 		    "The type definition is absent");
   25802 		break;
   25803 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
   25804 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
   25805 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
   25806 		    "The value '%s' does not match the fixed "
   25807 		    "value constraint '%s'",
   25808 		    iattr->value, iattr->vcValue);
   25809 		break;
   25810 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
   25811 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
   25812 		    "No matching global attribute declaration available, but "
   25813 		    "demanded by the strict wildcard");
   25814 		break;
   25815 	    case XML_SCHEMAS_ATTR_UNKNOWN:
   25816 		if (iattr->metaType)
   25817 		    break;
   25818 		/*
   25819 		* MAYBE VAL TODO: One might report different error messages
   25820 		* for the following errors.
   25821 		*/
   25822 		if (type->attributeWildcard == NULL) {
   25823 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25824 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
   25825 		} else {
   25826 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
   25827 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
   25828 		}
   25829 		break;
   25830 	    default:
   25831 		break;
   25832 	}
   25833     }
   25834 
   25835     ACTIVATE_ELEM;
   25836     return (0);
   25837 internal_error:
   25838     ACTIVATE_ELEM;
   25839     return (-1);
   25840 }
   25841 
   25842 static int
   25843 xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
   25844 			      int *skip)
   25845 {
   25846     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
   25847     /*
   25848     * The namespace of the element was already identified to be
   25849     * matching the wildcard.
   25850     */
   25851     if ((skip == NULL) || (wild == NULL) ||
   25852 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
   25853 	VERROR_INT("xmlSchemaValidateElemWildcard",
   25854 	    "bad arguments");
   25855 	return (-1);
   25856     }
   25857     *skip = 0;
   25858     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
   25859 	/*
   25860 	* URGENT VAL TODO: Either we need to position the stream to the
   25861 	* next sibling, or walk the whole subtree.
   25862 	*/
   25863 	*skip = 1;
   25864 	return (0);
   25865     }
   25866     {
   25867 	xmlSchemaElementPtr decl = NULL;
   25868 
   25869 	decl = xmlSchemaGetElem(vctxt->schema,
   25870 	    vctxt->inode->localName, vctxt->inode->nsName);
   25871 	if (decl != NULL) {
   25872 	    vctxt->inode->decl = decl;
   25873 	    return (0);
   25874 	}
   25875     }
   25876     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
   25877 	/* VAL TODO: Change to proper error code. */
   25878 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
   25879 	    "No matching global element declaration available, but "
   25880 	    "demanded by the strict wildcard");
   25881 	return (vctxt->err);
   25882     }
   25883     if (vctxt->nbAttrInfos != 0) {
   25884 	xmlSchemaAttrInfoPtr iattr;
   25885 	/*
   25886 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
   25887 	* (1.2.1.2.1) - (1.2.1.2.3 )
   25888 	*
   25889 	* Use the xsi:type attribute for the type definition.
   25890 	*/
   25891 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   25892 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   25893 	if (iattr != NULL) {
   25894 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
   25895 		&(vctxt->inode->typeDef), NULL) == -1) {
   25896 		VERROR_INT("xmlSchemaValidateElemWildcard",
   25897 		    "calling xmlSchemaProcessXSIType() to "
   25898 		    "process the attribute 'xsi:nil'");
   25899 		return (-1);
   25900 	    }
   25901 	    /*
   25902 	    * Don't return an error on purpose.
   25903 	    */
   25904 	    return (0);
   25905 	}
   25906     }
   25907     /*
   25908     * SPEC Validation Rule: Schema-Validity Assessment (Element)
   25909     *
   25910     * Fallback to "anyType".
   25911     */
   25912     vctxt->inode->typeDef =
   25913 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   25914     return (0);
   25915 }
   25916 
   25917 /*
   25918 * xmlSchemaCheckCOSValidDefault:
   25919 *
   25920 * This will be called if: not nilled, no content and a default/fixed
   25921 * value is provided.
   25922 */
   25923 
   25924 static int
   25925 xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
   25926 			      const xmlChar *value,
   25927 			      xmlSchemaValPtr *val)
   25928 {
   25929     int ret = 0;
   25930     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   25931 
   25932     /*
   25933     * cos-valid-default:
   25934     * Schema Component Constraint: Element Default Valid (Immediate)
   25935     * For a string to be a valid default with respect to a type
   25936     * definition the appropriate case among the following must be true:
   25937     */
   25938     if WXS_IS_COMPLEX(inode->typeDef) {
   25939 	/*
   25940 	* Complex type.
   25941 	*
   25942 	* SPEC (2.1) "its {content type} must be a simple type definition
   25943 	* or mixed."
   25944 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
   25945 	* type}'s particle must be `emptiable` as defined by
   25946 	* Particle Emptiable ($3.9.6)."
   25947 	*/
   25948 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
   25949 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
   25950 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
   25951 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
   25952 	    /* NOTE that this covers (2.2.2) as well. */
   25953 	    VERROR(ret, NULL,
   25954 		"For a string to be a valid default, the type definition "
   25955 		"must be a simple type or a complex type with simple content "
   25956 		"or mixed content and a particle emptiable");
   25957 	    return(ret);
   25958 	}
   25959     }
   25960     /*
   25961     * 1 If the type definition is a simple type definition, then the string
   25962     * must be `valid` with respect to that definition as defined by String
   25963     * Valid ($3.14.4).
   25964     *
   25965     * AND
   25966     *
   25967     * 2.2.1 If the {content type} is a simple type definition, then the
   25968     * string must be `valid` with respect to that simple type definition
   25969     * as defined by String Valid ($3.14.4).
   25970     */
   25971     if (WXS_IS_SIMPLE(inode->typeDef)) {
   25972 
   25973 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25974 	    NULL, inode->typeDef, value, val, 1, 1, 0);
   25975 
   25976     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   25977 
   25978 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
   25979 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
   25980     }
   25981     if (ret < 0) {
   25982 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
   25983 	    "calling xmlSchemaVCheckCVCSimpleType()");
   25984     }
   25985     return (ret);
   25986 }
   25987 
   25988 static void
   25989 xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
   25990 			       const xmlChar * name ATTRIBUTE_UNUSED,
   25991 			       void *transdata, void *inputdata)
   25992 {
   25993     xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
   25994     xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
   25995     inode->decl = item;
   25996 #ifdef DEBUG_CONTENT
   25997     {
   25998 	xmlChar *str = NULL;
   25999 
   26000 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
   26001 	    xmlGenericError(xmlGenericErrorContext,
   26002 		"AUTOMATON callback for '%s' [declaration]\n",
   26003 		xmlSchemaFormatQName(&str,
   26004 		inode->localName, inode->nsName));
   26005 	} else {
   26006 	    xmlGenericError(xmlGenericErrorContext,
   26007 		    "AUTOMATON callback for '%s' [wildcard]\n",
   26008 		    xmlSchemaFormatQName(&str,
   26009 		    inode->localName, inode->nsName));
   26010 
   26011 	}
   26012 	FREE_AND_NULL(str)
   26013     }
   26014 #endif
   26015 }
   26016 
   26017 static int
   26018 xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
   26019 {
   26020     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
   26021     if (vctxt->inode == NULL) {
   26022 	VERROR_INT("xmlSchemaValidatorPushElem",
   26023 	    "calling xmlSchemaGetFreshElemInfo()");
   26024 	return (-1);
   26025     }
   26026     vctxt->nbAttrInfos = 0;
   26027     return (0);
   26028 }
   26029 
   26030 static int
   26031 xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
   26032 			     xmlSchemaNodeInfoPtr inode,
   26033 			     xmlSchemaTypePtr type,
   26034 			     const xmlChar *value)
   26035 {
   26036     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
   26037 	return (xmlSchemaVCheckCVCSimpleType(
   26038 	    ACTXT_CAST vctxt, NULL,
   26039 	    type, value, &(inode->val), 1, 1, 0));
   26040     else
   26041 	return (xmlSchemaVCheckCVCSimpleType(
   26042 	    ACTXT_CAST vctxt, NULL,
   26043 	    type, value, NULL, 1, 0, 0));
   26044 }
   26045 
   26046 
   26047 
   26048 /*
   26049 * Process END of element.
   26050 */
   26051 static int
   26052 xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
   26053 {
   26054     int ret = 0;
   26055     xmlSchemaNodeInfoPtr inode = vctxt->inode;
   26056 
   26057     if (vctxt->nbAttrInfos != 0)
   26058 	xmlSchemaClearAttrInfos(vctxt);
   26059     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
   26060 	/*
   26061 	* This element was not expected;
   26062 	* we will not validate child elements of broken parents.
   26063 	* Skip validation of all content of the parent.
   26064 	*/
   26065 	vctxt->skipDepth = vctxt->depth -1;
   26066 	goto end_elem;
   26067     }
   26068     if ((inode->typeDef == NULL) ||
   26069 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
   26070 	/*
   26071 	* 1. the type definition might be missing if the element was
   26072 	*    error prone
   26073 	* 2. it might be abstract.
   26074 	*/
   26075 	goto end_elem;
   26076     }
   26077     /*
   26078     * Check the content model.
   26079     */
   26080     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
   26081 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
   26082 
   26083 	/*
   26084 	* Workaround for "anyType".
   26085 	*/
   26086 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
   26087 	    goto character_content;
   26088 
   26089 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
   26090 	    xmlChar *values[10];
   26091 	    int terminal, nbval = 10, nbneg;
   26092 
   26093 	    if (inode->regexCtxt == NULL) {
   26094 		/*
   26095 		* Create the regex context.
   26096 		*/
   26097 		inode->regexCtxt =
   26098 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
   26099 		    xmlSchemaVContentModelCallback, vctxt);
   26100 		if (inode->regexCtxt == NULL) {
   26101 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26102 			"failed to create a regex context");
   26103 		    goto internal_error;
   26104 		}
   26105 #ifdef DEBUG_AUTOMATA
   26106 		xmlGenericError(xmlGenericErrorContext,
   26107 		    "AUTOMATON create on '%s'\n", inode->localName);
   26108 #endif
   26109 	    }
   26110 
   26111 	    /*
   26112 	     * Do not check further content if the node has been nilled
   26113 	     */
   26114 	    if (INODE_NILLED(inode)) {
   26115 		ret = 0;
   26116 #ifdef DEBUG_AUTOMATA
   26117 		xmlGenericError(xmlGenericErrorContext,
   26118 		    "AUTOMATON succeeded on nilled '%s'\n",
   26119 		    inode->localName);
   26120 #endif
   26121                 goto skip_nilled;
   26122 	    }
   26123 
   26124 	    /*
   26125 	    * Get hold of the still expected content, since a further
   26126 	    * call to xmlRegExecPushString() will lose this information.
   26127 	    */
   26128 	    xmlRegExecNextValues(inode->regexCtxt,
   26129 		&nbval, &nbneg, &values[0], &terminal);
   26130 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
   26131 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
   26132 		/*
   26133 		* Still missing something.
   26134 		*/
   26135 		ret = 1;
   26136 		inode->flags |=
   26137 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26138 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26139 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
   26140 		    "Missing child element(s)",
   26141 		    nbval, nbneg, values);
   26142 #ifdef DEBUG_AUTOMATA
   26143 		xmlGenericError(xmlGenericErrorContext,
   26144 		    "AUTOMATON missing ERROR on '%s'\n",
   26145 		    inode->localName);
   26146 #endif
   26147 	    } else {
   26148 		/*
   26149 		* Content model is satisfied.
   26150 		*/
   26151 		ret = 0;
   26152 #ifdef DEBUG_AUTOMATA
   26153 		xmlGenericError(xmlGenericErrorContext,
   26154 		    "AUTOMATON succeeded on '%s'\n",
   26155 		    inode->localName);
   26156 #endif
   26157 	    }
   26158 
   26159 	}
   26160     }
   26161 
   26162 skip_nilled:
   26163 
   26164     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
   26165 	goto end_elem;
   26166 
   26167 character_content:
   26168 
   26169     if (vctxt->value != NULL) {
   26170 	xmlSchemaFreeValue(vctxt->value);
   26171 	vctxt->value = NULL;
   26172     }
   26173     /*
   26174     * Check character content.
   26175     */
   26176     if (inode->decl == NULL) {
   26177 	/*
   26178 	* Speedup if no declaration exists.
   26179 	*/
   26180 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26181 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26182 		inode, inode->typeDef, inode->value);
   26183 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26184 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26185 		inode, inode->typeDef->contentTypeDef,
   26186 		inode->value);
   26187 	}
   26188 	if (ret < 0) {
   26189 	    VERROR_INT("xmlSchemaValidatorPopElem",
   26190 		"calling xmlSchemaVCheckCVCSimpleType()");
   26191 	    goto internal_error;
   26192 	}
   26193 	goto end_elem;
   26194     }
   26195     /*
   26196     * cvc-elt (3.3.4) : 5
   26197     * The appropriate case among the following must be true:
   26198     */
   26199     /*
   26200     * cvc-elt (3.3.4) : 5.1
   26201     * If the declaration has a {value constraint},
   26202     * the item has neither element nor character [children] and
   26203     * clause 3.2 has not applied, then all of the following must be true:
   26204     */
   26205     if ((inode->decl->value != NULL) &&
   26206 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
   26207 	(! INODE_NILLED(inode))) {
   26208 	/*
   26209 	* cvc-elt (3.3.4) : 5.1.1
   26210 	* If the `actual type definition` is a `local type definition`
   26211 	* then the canonical lexical representation of the {value constraint}
   26212 	* value must be a valid default for the `actual type definition` as
   26213 	* defined in Element Default Valid (Immediate) ($3.3.6).
   26214 	*/
   26215 	/*
   26216 	* NOTE: 'local' above means types acquired by xsi:type.
   26217 	* NOTE: Although the *canonical* value is stated, it is not
   26218 	* relevant if canonical or not. Additionally XML Schema 1.1
   26219 	* will removed this requirement as well.
   26220 	*/
   26221 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
   26222 
   26223 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
   26224 		inode->decl->value, &(inode->val));
   26225 	    if (ret != 0) {
   26226 		if (ret < 0) {
   26227 		    VERROR_INT("xmlSchemaValidatorPopElem",
   26228 			"calling xmlSchemaCheckCOSValidDefault()");
   26229 		    goto internal_error;
   26230 		}
   26231 		goto end_elem;
   26232 	    }
   26233 	    /*
   26234 	    * Stop here, to avoid redundant validation of the value
   26235 	    * (see following).
   26236 	    */
   26237 	    goto default_psvi;
   26238 	}
   26239 	/*
   26240 	* cvc-elt (3.3.4) : 5.1.2
   26241 	* The element information item with the canonical lexical
   26242 	* representation of the {value constraint} value used as its
   26243 	* `normalized value` must be `valid` with respect to the
   26244 	* `actual type definition` as defined by Element Locally Valid (Type)
   26245 	* ($3.3.4).
   26246 	*/
   26247 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26248 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26249 		inode, inode->typeDef, inode->decl->value);
   26250 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26251 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26252 		inode, inode->typeDef->contentTypeDef,
   26253 		inode->decl->value);
   26254 	}
   26255 	if (ret != 0) {
   26256 	    if (ret < 0) {
   26257 		VERROR_INT("xmlSchemaValidatorPopElem",
   26258 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26259 		goto internal_error;
   26260 	    }
   26261 	    goto end_elem;
   26262 	}
   26263 
   26264 default_psvi:
   26265 	/*
   26266 	* PSVI: Create a text node on the instance element.
   26267 	*/
   26268 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
   26269 	    (inode->node != NULL)) {
   26270 	    xmlNodePtr textChild;
   26271 	    xmlChar *normValue;
   26272 	    /*
   26273 	    * VAL TODO: Normalize the value.
   26274 	    */
   26275 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
   26276 		inode->decl->value);
   26277 	    if (normValue != NULL) {
   26278 		textChild = xmlNewText(BAD_CAST normValue);
   26279 		xmlFree(normValue);
   26280 	    } else
   26281 		textChild = xmlNewText(inode->decl->value);
   26282 	    if (textChild == NULL) {
   26283 		VERROR_INT("xmlSchemaValidatorPopElem",
   26284 		    "calling xmlNewText()");
   26285 		goto internal_error;
   26286 	    } else
   26287 		xmlAddChild(inode->node, textChild);
   26288 	}
   26289 
   26290     } else if (! INODE_NILLED(inode)) {
   26291 	/*
   26292 	* 5.2.1 The element information item must be `valid` with respect
   26293 	* to the `actual type definition` as defined by Element Locally
   26294 	* Valid (Type) ($3.3.4).
   26295 	*/
   26296 	if (WXS_IS_SIMPLE(inode->typeDef)) {
   26297 	     /*
   26298 	    * SPEC (cvc-type) (3.1)
   26299 	    * "If the type definition is a simple type definition, ..."
   26300 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
   26301 	    * (Element) ($3.3.4) did not apply, then the `normalized value`
   26302 	    * must be `valid` with respect to the type definition as defined
   26303 	    * by String Valid ($3.14.4).
   26304 	    */
   26305 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26306 		    inode, inode->typeDef, inode->value);
   26307 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26308 	    /*
   26309 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
   26310 	    * definition, then the element information item must be
   26311 	    * `valid` with respect to the type definition as per
   26312 	    * Element Locally Valid (Complex Type) ($3.4.4);"
   26313 	    *
   26314 	    * SPEC (cvc-complex-type) (2.2)
   26315 	    * "If the {content type} is a simple type definition, ...
   26316 	    * the `normalized value` of the element information item is
   26317 	    * `valid` with respect to that simple type definition as
   26318 	    * defined by String Valid ($3.14.4)."
   26319 	    */
   26320 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
   26321 		inode, inode->typeDef->contentTypeDef, inode->value);
   26322 	}
   26323 	if (ret != 0) {
   26324 	    if (ret < 0) {
   26325 		VERROR_INT("xmlSchemaValidatorPopElem",
   26326 		    "calling xmlSchemaVCheckCVCSimpleType()");
   26327 		goto internal_error;
   26328 	    }
   26329 	    goto end_elem;
   26330 	}
   26331 	/*
   26332 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
   26333 	* not applied, all of the following must be true:
   26334 	*/
   26335 	if ((inode->decl->value != NULL) &&
   26336 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
   26337 
   26338 	    /*
   26339 	    * TODO: We will need a computed value, when comparison is
   26340 	    * done on computed values.
   26341 	    */
   26342 	    /*
   26343 	    * 5.2.2.1 The element information item must have no element
   26344 	    * information item [children].
   26345 	    */
   26346 	    if (inode->flags &
   26347 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
   26348 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
   26349 		VERROR(ret, NULL,
   26350 		    "The content must not containt element nodes since "
   26351 		    "there is a fixed value constraint");
   26352 		goto end_elem;
   26353 	    } else {
   26354 		/*
   26355 		* 5.2.2.2 The appropriate case among the following must
   26356 		* be true:
   26357 		*/
   26358 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
   26359 		    /*
   26360 		    * 5.2.2.2.1 If the {content type} of the `actual type
   26361 		    * definition` is mixed, then the *initial value* of the
   26362 		    * item must match the canonical lexical representation
   26363 		    * of the {value constraint} value.
   26364 		    *
   26365 		    * ... the *initial value* of an element information
   26366 		    * item is the string composed of, in order, the
   26367 		    * [character code] of each character information item in
   26368 		    * the [children] of that element information item.
   26369 		    */
   26370 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
   26371 			/*
   26372 			* VAL TODO: Report invalid & expected values as well.
   26373 			* VAL TODO: Implement the canonical stuff.
   26374 			*/
   26375 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
   26376 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26377 			    ret, NULL, NULL,
   26378 			    "The initial value '%s' does not match the fixed "
   26379 			    "value constraint '%s'",
   26380 			    inode->value, inode->decl->value);
   26381 			goto end_elem;
   26382 		    }
   26383 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
   26384 		    /*
   26385 		    * 5.2.2.2.2 If the {content type} of the `actual type
   26386 		    * definition` is a simple type definition, then the
   26387 		    * *actual value* of the item must match the canonical
   26388 		    * lexical representation of the {value constraint} value.
   26389 		    */
   26390 		    /*
   26391 		    * VAL TODO: *actual value* is the normalized value, impl.
   26392 		    *           this.
   26393 		    * VAL TODO: Report invalid & expected values as well.
   26394 		    * VAL TODO: Implement a comparison with the computed values.
   26395 		    */
   26396 		    if (! xmlStrEqual(inode->value,
   26397 			    inode->decl->value)) {
   26398 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
   26399 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
   26400 			    ret, NULL, NULL,
   26401 			    "The actual value '%s' does not match the fixed "
   26402 			    "value constraint '%s'",
   26403 			    inode->value,
   26404 			    inode->decl->value);
   26405 			goto end_elem;
   26406 		    }
   26407 		}
   26408 	    }
   26409 	}
   26410     }
   26411 
   26412 end_elem:
   26413     if (vctxt->depth < 0) {
   26414 	/* TODO: raise error? */
   26415 	return (0);
   26416     }
   26417     if (vctxt->depth == vctxt->skipDepth)
   26418 	vctxt->skipDepth = -1;
   26419     /*
   26420     * Evaluate the history of XPath state objects.
   26421     */
   26422     if (inode->appliedXPath &&
   26423 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
   26424 	goto internal_error;
   26425     /*
   26426     * MAYBE TODO:
   26427     * SPEC (6) "The element information item must be `valid` with
   26428     * respect to each of the {identity-constraint definitions} as per
   26429     * Identity-constraint Satisfied ($3.11.4)."
   26430     */
   26431     /*
   26432     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
   26433     *   need to be built in any case.
   26434     *   We will currently build IDC node-tables and bubble them only if
   26435     *   keyrefs do exist.
   26436     */
   26437 
   26438     /*
   26439     * Add the current IDC target-nodes to the IDC node-tables.
   26440     */
   26441     if ((inode->idcMatchers != NULL) &&
   26442 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26443     {
   26444 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
   26445 	    goto internal_error;
   26446     }
   26447     /*
   26448     * Validate IDC keyrefs.
   26449     */
   26450     if (vctxt->inode->hasKeyrefs)
   26451 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
   26452 	    goto internal_error;
   26453     /*
   26454     * Merge/free the IDC table.
   26455     */
   26456     if (inode->idcTable != NULL) {
   26457 #ifdef DEBUG_IDC_NODE_TABLE
   26458 	xmlSchemaDebugDumpIDCTable(stdout,
   26459 	    inode->nsName,
   26460 	    inode->localName,
   26461 	    inode->idcTable);
   26462 #endif
   26463 	if ((vctxt->depth > 0) &&
   26464 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
   26465 	{
   26466 	    /*
   26467 	    * Merge the IDC node table with the table of the parent node.
   26468 	    */
   26469 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
   26470 		goto internal_error;
   26471 	}
   26472     }
   26473     /*
   26474     * Clear the current ielem.
   26475     * VAL TODO: Don't free the PSVI IDC tables if they are
   26476     * requested for the PSVI.
   26477     */
   26478     xmlSchemaClearElemInfo(vctxt, inode);
   26479     /*
   26480     * Skip further processing if we are on the validation root.
   26481     */
   26482     if (vctxt->depth == 0) {
   26483 	vctxt->depth--;
   26484 	vctxt->inode = NULL;
   26485 	return (0);
   26486     }
   26487     /*
   26488     * Reset the keyrefDepth if needed.
   26489     */
   26490     if (vctxt->aidcs != NULL) {
   26491 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
   26492 	do {
   26493 	    if (aidc->keyrefDepth == vctxt->depth) {
   26494 		/*
   26495 		* A 'keyrefDepth' of a key/unique IDC matches the current
   26496 		* depth, this means that we are leaving the scope of the
   26497 		* top-most keyref IDC which refers to this IDC.
   26498 		*/
   26499 		aidc->keyrefDepth = -1;
   26500 	    }
   26501 	    aidc = aidc->next;
   26502 	} while (aidc != NULL);
   26503     }
   26504     vctxt->depth--;
   26505     vctxt->inode = vctxt->elemInfos[vctxt->depth];
   26506     /*
   26507     * VAL TODO: 7 If the element information item is the `validation root`, it must be
   26508     * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
   26509     */
   26510     return (ret);
   26511 
   26512 internal_error:
   26513     vctxt->err = -1;
   26514     return (-1);
   26515 }
   26516 
   26517 /*
   26518 * 3.4.4 Complex Type Definition Validation Rules
   26519 * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
   26520 */
   26521 static int
   26522 xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
   26523 {
   26524     xmlSchemaNodeInfoPtr pielem;
   26525     xmlSchemaTypePtr ptype;
   26526     int ret = 0;
   26527 
   26528     if (vctxt->depth <= 0) {
   26529 	VERROR_INT("xmlSchemaValidateChildElem",
   26530 	    "not intended for the validation root");
   26531 	return (-1);
   26532     }
   26533     pielem = vctxt->elemInfos[vctxt->depth -1];
   26534     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   26535 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   26536     /*
   26537     * Handle 'nilled' elements.
   26538     */
   26539     if (INODE_NILLED(pielem)) {
   26540 	/*
   26541 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
   26542 	*/
   26543 	ACTIVATE_PARENT_ELEM;
   26544 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
   26545 	VERROR(ret, NULL,
   26546 	    "Neither character nor element content is allowed, "
   26547 	    "because the element was 'nilled'");
   26548 	ACTIVATE_ELEM;
   26549 	goto unexpected_elem;
   26550     }
   26551 
   26552     ptype = pielem->typeDef;
   26553 
   26554     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
   26555 	/*
   26556 	* Workaround for "anyType": we have currently no content model
   26557 	* assigned for "anyType", so handle it explicitely.
   26558 	* "anyType" has an unbounded, lax "any" wildcard.
   26559 	*/
   26560 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26561 	    vctxt->inode->localName,
   26562 	    vctxt->inode->nsName);
   26563 
   26564 	if (vctxt->inode->decl == NULL) {
   26565 	    xmlSchemaAttrInfoPtr iattr;
   26566 	    /*
   26567 	    * Process "xsi:type".
   26568 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
   26569 	    */
   26570 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
   26571 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
   26572 	    if (iattr != NULL) {
   26573 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
   26574 		    &(vctxt->inode->typeDef), NULL);
   26575 		if (ret != 0) {
   26576 		    if (ret == -1) {
   26577 			VERROR_INT("xmlSchemaValidateChildElem",
   26578 			    "calling xmlSchemaProcessXSIType() to "
   26579 			    "process the attribute 'xsi:nil'");
   26580 			return (-1);
   26581 		    }
   26582 		    return (ret);
   26583 		}
   26584 	    } else {
   26585 		 /*
   26586 		 * Fallback to "anyType".
   26587 		 *
   26588 		 * SPEC (cvc-assess-elt)
   26589 		 * "If the item cannot be `strictly assessed`, [...]
   26590 		 * an element information item's schema validity may be laxly
   26591 		 * assessed if its `context-determined declaration` is not
   26592 		 * skip by `validating` with respect to the `ur-type
   26593 		 * definition` as per Element Locally Valid (Type) ($3.3.4)."
   26594 		*/
   26595 		vctxt->inode->typeDef =
   26596 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
   26597 	    }
   26598 	}
   26599 	return (0);
   26600     }
   26601 
   26602     switch (ptype->contentType) {
   26603 	case XML_SCHEMA_CONTENT_EMPTY:
   26604 	    /*
   26605 	    * SPEC (2.1) "If the {content type} is empty, then the
   26606 	    * element information item has no character or element
   26607 	    * information item [children]."
   26608 	    */
   26609 	    ACTIVATE_PARENT_ELEM
   26610 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
   26611 	    VERROR(ret, NULL,
   26612 		"Element content is not allowed, "
   26613 		"because the content type is empty");
   26614 	    ACTIVATE_ELEM
   26615 	    goto unexpected_elem;
   26616 	    break;
   26617 
   26618 	case XML_SCHEMA_CONTENT_MIXED:
   26619         case XML_SCHEMA_CONTENT_ELEMENTS: {
   26620 	    xmlRegExecCtxtPtr regexCtxt;
   26621 	    xmlChar *values[10];
   26622 	    int terminal, nbval = 10, nbneg;
   26623 
   26624 	    /* VAL TODO: Optimized "anyType" validation.*/
   26625 
   26626 	    if (ptype->contModel == NULL) {
   26627 		VERROR_INT("xmlSchemaValidateChildElem",
   26628 		    "type has elem content but no content model");
   26629 		return (-1);
   26630 	    }
   26631 	    /*
   26632 	    * Safety belf for evaluation if the cont. model was already
   26633 	    * examined to be invalid.
   26634 	    */
   26635 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
   26636 		VERROR_INT("xmlSchemaValidateChildElem",
   26637 		    "validating elem, but elem content is already invalid");
   26638 		return (-1);
   26639 	    }
   26640 
   26641 	    regexCtxt = pielem->regexCtxt;
   26642 	    if (regexCtxt == NULL) {
   26643 		/*
   26644 		* Create the regex context.
   26645 		*/
   26646 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
   26647 		    xmlSchemaVContentModelCallback, vctxt);
   26648 		if (regexCtxt == NULL) {
   26649 		    VERROR_INT("xmlSchemaValidateChildElem",
   26650 			"failed to create a regex context");
   26651 		    return (-1);
   26652 		}
   26653 		pielem->regexCtxt = regexCtxt;
   26654 #ifdef DEBUG_AUTOMATA
   26655 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
   26656 		    pielem->localName);
   26657 #endif
   26658 	    }
   26659 
   26660 	    /*
   26661 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
   26662 	    * then the sequence of the element information item's
   26663 	    * element information item [children], if any, taken in
   26664 	    * order, is `valid` with respect to the {content type}'s
   26665 	    * particle, as defined in Element Sequence Locally Valid
   26666 	    * (Particle) ($3.9.4)."
   26667 	    */
   26668 	    ret = xmlRegExecPushString2(regexCtxt,
   26669 		vctxt->inode->localName,
   26670 		vctxt->inode->nsName,
   26671 		vctxt->inode);
   26672 #ifdef DEBUG_AUTOMATA
   26673 	    if (ret < 0)
   26674 		xmlGenericError(xmlGenericErrorContext,
   26675 		"AUTOMATON push ERROR for '%s' on '%s'\n",
   26676 		vctxt->inode->localName, pielem->localName);
   26677 	    else
   26678 		xmlGenericError(xmlGenericErrorContext,
   26679 		"AUTOMATON push OK for '%s' on '%s'\n",
   26680 		vctxt->inode->localName, pielem->localName);
   26681 #endif
   26682 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
   26683 		VERROR_INT("xmlSchemaValidateChildElem",
   26684 		    "calling xmlRegExecPushString2()");
   26685 		return (-1);
   26686 	    }
   26687 	    if (ret < 0) {
   26688 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
   26689 		    &values[0], &terminal);
   26690 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
   26691 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
   26692 		    "This element is not expected",
   26693 		    nbval, nbneg, values);
   26694 		ret = vctxt->err;
   26695 		goto unexpected_elem;
   26696 	    } else
   26697 		ret = 0;
   26698 	}
   26699 	    break;
   26700 	case XML_SCHEMA_CONTENT_SIMPLE:
   26701 	case XML_SCHEMA_CONTENT_BASIC:
   26702 	    ACTIVATE_PARENT_ELEM
   26703 	    if (WXS_IS_COMPLEX(ptype)) {
   26704 		/*
   26705 		* SPEC (cvc-complex-type) (2.2)
   26706 		* "If the {content type} is a simple type definition, then
   26707 		* the element information item has no element information
   26708 		* item [children], ..."
   26709 		*/
   26710 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
   26711 		VERROR(ret, NULL, "Element content is not allowed, "
   26712 		    "because the content type is a simple type definition");
   26713 	    } else {
   26714 		/*
   26715 		* SPEC (cvc-type) (3.1.2) "The element information item must
   26716 		* have no element information item [children]."
   26717 		*/
   26718 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
   26719 		VERROR(ret, NULL, "Element content is not allowed, "
   26720 		    "because the type definition is simple");
   26721 	    }
   26722 	    ACTIVATE_ELEM
   26723 	    ret = vctxt->err;
   26724 	    goto unexpected_elem;
   26725 	    break;
   26726 
   26727 	default:
   26728 	    break;
   26729     }
   26730     return (ret);
   26731 unexpected_elem:
   26732     /*
   26733     * Pop this element and set the skipDepth to skip
   26734     * all further content of the parent element.
   26735     */
   26736     vctxt->skipDepth = vctxt->depth;
   26737     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
   26738     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
   26739     return (ret);
   26740 }
   26741 
   26742 #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
   26743 #define XML_SCHEMA_PUSH_TEXT_CREATED 2
   26744 #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
   26745 
   26746 static int
   26747 xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
   26748 		  int nodeType, const xmlChar *value, int len,
   26749 		  int mode, int *consumed)
   26750 {
   26751     /*
   26752     * Unfortunately we have to duplicate the text sometimes.
   26753     * OPTIMIZE: Maybe we could skip it, if:
   26754     *   1. content type is simple
   26755     *   2. whitespace is "collapse"
   26756     *   3. it consists of whitespace only
   26757     *
   26758     * Process character content.
   26759     */
   26760     if (consumed != NULL)
   26761 	*consumed = 0;
   26762     if (INODE_NILLED(vctxt->inode)) {
   26763 	/*
   26764 	* SPEC cvc-elt (3.3.4 - 3.2.1)
   26765 	* "The element information item must have no character or
   26766 	* element information item [children]."
   26767 	*/
   26768 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
   26769 	    "Neither character nor element content is allowed "
   26770 	    "because the element is 'nilled'");
   26771 	return (vctxt->err);
   26772     }
   26773     /*
   26774     * SPEC (2.1) "If the {content type} is empty, then the
   26775     * element information item has no character or element
   26776     * information item [children]."
   26777     */
   26778     if (vctxt->inode->typeDef->contentType ==
   26779 	    XML_SCHEMA_CONTENT_EMPTY) {
   26780 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
   26781 	    "Character content is not allowed, "
   26782 	    "because the content type is empty");
   26783 	return (vctxt->err);
   26784     }
   26785 
   26786     if (vctxt->inode->typeDef->contentType ==
   26787 	    XML_SCHEMA_CONTENT_ELEMENTS) {
   26788 	if ((nodeType != XML_TEXT_NODE) ||
   26789 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
   26790 	    /*
   26791 	    * SPEC cvc-complex-type (2.3)
   26792 	    * "If the {content type} is element-only, then the
   26793 	    * element information item has no character information
   26794 	    * item [children] other than those whose [character
   26795 	    * code] is defined as a white space in [XML 1.0 (Second
   26796 	    * Edition)]."
   26797 	    */
   26798 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
   26799 		"Character content other than whitespace is not allowed "
   26800 		"because the content type is 'element-only'");
   26801 	    return (vctxt->err);
   26802 	}
   26803 	return (0);
   26804     }
   26805 
   26806     if ((value == NULL) || (value[0] == 0))
   26807 	return (0);
   26808     /*
   26809     * Save the value.
   26810     * NOTE that even if the content type is *mixed*, we need the
   26811     * *initial value* for default/fixed value constraints.
   26812     */
   26813     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
   26814 	((vctxt->inode->decl == NULL) ||
   26815 	(vctxt->inode->decl->value == NULL)))
   26816 	return (0);
   26817 
   26818     if (vctxt->inode->value == NULL) {
   26819 	/*
   26820 	* Set the value.
   26821 	*/
   26822 	switch (mode) {
   26823 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
   26824 		/*
   26825 		* When working on a tree.
   26826 		*/
   26827 		vctxt->inode->value = value;
   26828 		break;
   26829 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
   26830 		/*
   26831 		* When working with the reader.
   26832 		* The value will be freed by the element info.
   26833 		*/
   26834 		vctxt->inode->value = value;
   26835 		if (consumed != NULL)
   26836 		    *consumed = 1;
   26837 		vctxt->inode->flags |=
   26838 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26839 		break;
   26840 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
   26841 		/*
   26842 		* When working with SAX.
   26843 		* The value will be freed by the element info.
   26844 		*/
   26845 		if (len != -1)
   26846 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
   26847 		else
   26848 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
   26849 		vctxt->inode->flags |=
   26850 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26851 		break;
   26852 	    default:
   26853 		break;
   26854 	}
   26855     } else {
   26856 	if (len < 0)
   26857 	    len = xmlStrlen(value);
   26858 	/*
   26859 	* Concat the value.
   26860 	*/
   26861 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
   26862 	    vctxt->inode->value = BAD_CAST xmlStrncat(
   26863 		(xmlChar *) vctxt->inode->value, value, len);
   26864 	} else {
   26865 	    vctxt->inode->value =
   26866 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
   26867 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
   26868 	}
   26869     }
   26870 
   26871     return (0);
   26872 }
   26873 
   26874 static int
   26875 xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
   26876 {
   26877     int ret = 0;
   26878 
   26879     if ((vctxt->skipDepth != -1) &&
   26880 	(vctxt->depth >= vctxt->skipDepth)) {
   26881 	VERROR_INT("xmlSchemaValidateElem",
   26882 	    "in skip-state");
   26883 	goto internal_error;
   26884     }
   26885     if (vctxt->xsiAssemble) {
   26886 	/*
   26887 	* We will stop validation if there was an error during
   26888 	* dynamic schema construction.
   26889 	* Note that we simply set @skipDepth to 0, this could
   26890 	* mean that a streaming document via SAX would be
   26891 	* still read to the end but it won't be validated any more.
   26892 	* TODO: If we are sure how to stop the validation at once
   26893 	*   for all input scenarios, then this should be changed to
   26894 	*   instantly stop the validation.
   26895 	*/
   26896 	ret = xmlSchemaAssembleByXSI(vctxt);
   26897 	if (ret != 0) {
   26898 	    if (ret == -1)
   26899 		goto internal_error;
   26900 	    vctxt->skipDepth = 0;
   26901 	    return(ret);
   26902 	}
   26903         /*
   26904          * Augment the IDC definitions for the main schema and all imported ones
   26905          * NOTE: main schema is the first in the imported list
   26906          */
   26907         xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
   26908                     vctxt);
   26909     }
   26910     if (vctxt->depth > 0) {
   26911 	/*
   26912 	* Validate this element against the content model
   26913 	* of the parent.
   26914 	*/
   26915 	ret = xmlSchemaValidateChildElem(vctxt);
   26916 	if (ret != 0) {
   26917 	    if (ret < 0) {
   26918 		VERROR_INT("xmlSchemaValidateElem",
   26919 		    "calling xmlSchemaStreamValidateChildElement()");
   26920 		goto internal_error;
   26921 	    }
   26922 	    goto exit;
   26923 	}
   26924 	if (vctxt->depth == vctxt->skipDepth)
   26925 	    goto exit;
   26926 	if ((vctxt->inode->decl == NULL) &&
   26927 	    (vctxt->inode->typeDef == NULL)) {
   26928 	    VERROR_INT("xmlSchemaValidateElem",
   26929 		"the child element was valid but neither the "
   26930 		"declaration nor the type was set");
   26931 	    goto internal_error;
   26932 	}
   26933     } else {
   26934 	/*
   26935 	* Get the declaration of the validation root.
   26936 	*/
   26937 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
   26938 	    vctxt->inode->localName,
   26939 	    vctxt->inode->nsName);
   26940 	if (vctxt->inode->decl == NULL) {
   26941 	    ret = XML_SCHEMAV_CVC_ELT_1;
   26942 	    VERROR(ret, NULL,
   26943 		"No matching global declaration available "
   26944 		"for the validation root");
   26945 	    goto exit;
   26946 	}
   26947     }
   26948 
   26949     if (vctxt->inode->decl == NULL)
   26950 	goto type_validation;
   26951 
   26952     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
   26953 	int skip;
   26954 	/*
   26955 	* Wildcards.
   26956 	*/
   26957 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
   26958 	if (ret != 0) {
   26959 	    if (ret < 0) {
   26960 		VERROR_INT("xmlSchemaValidateElem",
   26961 		    "calling xmlSchemaValidateElemWildcard()");
   26962 		goto internal_error;
   26963 	    }
   26964 	    goto exit;
   26965 	}
   26966 	if (skip) {
   26967 	    vctxt->skipDepth = vctxt->depth;
   26968 	    goto exit;
   26969 	}
   26970 	/*
   26971 	* The declaration might be set by the wildcard validation,
   26972 	* when the processContents is "lax" or "strict".
   26973 	*/
   26974 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
   26975 	    /*
   26976 	    * Clear the "decl" field to not confuse further processing.
   26977 	    */
   26978 	    vctxt->inode->decl = NULL;
   26979 	    goto type_validation;
   26980 	}
   26981     }
   26982     /*
   26983     * Validate against the declaration.
   26984     */
   26985     ret = xmlSchemaValidateElemDecl(vctxt);
   26986     if (ret != 0) {
   26987 	if (ret < 0) {
   26988 	    VERROR_INT("xmlSchemaValidateElem",
   26989 		"calling xmlSchemaValidateElemDecl()");
   26990 	    goto internal_error;
   26991 	}
   26992 	goto exit;
   26993     }
   26994     /*
   26995     * Validate against the type definition.
   26996     */
   26997 type_validation:
   26998 
   26999     if (vctxt->inode->typeDef == NULL) {
   27000 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   27001 	ret = XML_SCHEMAV_CVC_TYPE_1;
   27002 	VERROR(ret, NULL,
   27003 	    "The type definition is absent");
   27004 	goto exit;
   27005     }
   27006     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
   27007 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
   27008 	ret = XML_SCHEMAV_CVC_TYPE_2;
   27009 	    VERROR(ret, NULL,
   27010 	    "The type definition is abstract");
   27011 	goto exit;
   27012     }
   27013     /*
   27014     * Evaluate IDCs. Do it here, since new IDC matchers are registered
   27015     * during validation against the declaration. This must be done
   27016     * _before_ attribute validation.
   27017     */
   27018     if (vctxt->xpathStates != NULL) {
   27019 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
   27020 	vctxt->inode->appliedXPath = 1;
   27021 	if (ret == -1) {
   27022 	    VERROR_INT("xmlSchemaValidateElem",
   27023 		"calling xmlSchemaXPathEvaluate()");
   27024 	    goto internal_error;
   27025 	}
   27026     }
   27027     /*
   27028     * Validate attributes.
   27029     */
   27030     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
   27031 	if ((vctxt->nbAttrInfos != 0) ||
   27032 	    (vctxt->inode->typeDef->attrUses != NULL)) {
   27033 
   27034 	    ret = xmlSchemaVAttributesComplex(vctxt);
   27035 	}
   27036     } else if (vctxt->nbAttrInfos != 0) {
   27037 
   27038 	ret = xmlSchemaVAttributesSimple(vctxt);
   27039     }
   27040     /*
   27041     * Clear registered attributes.
   27042     */
   27043     if (vctxt->nbAttrInfos != 0)
   27044 	xmlSchemaClearAttrInfos(vctxt);
   27045     if (ret == -1) {
   27046 	VERROR_INT("xmlSchemaValidateElem",
   27047 	    "calling attributes validation");
   27048 	goto internal_error;
   27049     }
   27050     /*
   27051     * Don't return an error if attributes are invalid on purpose.
   27052     */
   27053     ret = 0;
   27054 
   27055 exit:
   27056     if (ret != 0)
   27057 	vctxt->skipDepth = vctxt->depth;
   27058     return (ret);
   27059 internal_error:
   27060     return (-1);
   27061 }
   27062 
   27063 #ifdef XML_SCHEMA_READER_ENABLED
   27064 static int
   27065 xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
   27066 {
   27067     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
   27068     int depth, nodeType, ret = 0, consumed;
   27069     xmlSchemaNodeInfoPtr ielem;
   27070 
   27071     vctxt->depth = -1;
   27072     ret = xmlTextReaderRead(vctxt->reader);
   27073     /*
   27074     * Move to the document element.
   27075     */
   27076     while (ret == 1) {
   27077 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27078 	if (nodeType == XML_ELEMENT_NODE)
   27079 	    goto root_found;
   27080 	ret = xmlTextReaderRead(vctxt->reader);
   27081     }
   27082     goto exit;
   27083 
   27084 root_found:
   27085 
   27086     do {
   27087 	depth = xmlTextReaderDepth(vctxt->reader);
   27088 	nodeType = xmlTextReaderNodeType(vctxt->reader);
   27089 
   27090 	if (nodeType == XML_ELEMENT_NODE) {
   27091 
   27092 	    vctxt->depth++;
   27093 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27094 		VERROR_INT("xmlSchemaVReaderWalk",
   27095 		    "calling xmlSchemaValidatorPushElem()");
   27096 		goto internal_error;
   27097 	    }
   27098 	    ielem = vctxt->inode;
   27099 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
   27100 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
   27101 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
   27102 	    /*
   27103 	    * Is the element empty?
   27104 	    */
   27105 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
   27106 	    if (ret == -1) {
   27107 		VERROR_INT("xmlSchemaVReaderWalk",
   27108 		    "calling xmlTextReaderIsEmptyElement()");
   27109 		goto internal_error;
   27110 	    }
   27111 	    if (ret) {
   27112 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27113 	    }
   27114 	    /*
   27115 	    * Register attributes.
   27116 	    */
   27117 	    vctxt->nbAttrInfos = 0;
   27118 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
   27119 	    if (ret == -1) {
   27120 		VERROR_INT("xmlSchemaVReaderWalk",
   27121 		    "calling xmlTextReaderMoveToFirstAttribute()");
   27122 		goto internal_error;
   27123 	    }
   27124 	    if (ret == 1) {
   27125 		do {
   27126 		    /*
   27127 		    * VAL TODO: How do we know that the reader works on a
   27128 		    * node tree, to be able to pass a node here?
   27129 		    */
   27130 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
   27131 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
   27132 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
   27133 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
   27134 
   27135 			VERROR_INT("xmlSchemaVReaderWalk",
   27136 			    "calling xmlSchemaValidatorPushAttribute()");
   27137 			goto internal_error;
   27138 		    }
   27139 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
   27140 		    if (ret == -1) {
   27141 			VERROR_INT("xmlSchemaVReaderWalk",
   27142 			    "calling xmlTextReaderMoveToFirstAttribute()");
   27143 			goto internal_error;
   27144 		    }
   27145 		} while (ret == 1);
   27146 		/*
   27147 		* Back to element position.
   27148 		*/
   27149 		ret = xmlTextReaderMoveToElement(vctxt->reader);
   27150 		if (ret == -1) {
   27151 		    VERROR_INT("xmlSchemaVReaderWalk",
   27152 			"calling xmlTextReaderMoveToElement()");
   27153 		    goto internal_error;
   27154 		}
   27155 	    }
   27156 	    /*
   27157 	    * Validate the element.
   27158 	    */
   27159 	    ret= xmlSchemaValidateElem(vctxt);
   27160 	    if (ret != 0) {
   27161 		if (ret == -1) {
   27162 		    VERROR_INT("xmlSchemaVReaderWalk",
   27163 			"calling xmlSchemaValidateElem()");
   27164 		    goto internal_error;
   27165 		}
   27166 		goto exit;
   27167 	    }
   27168 	    if (vctxt->depth == vctxt->skipDepth) {
   27169 		int curDepth;
   27170 		/*
   27171 		* Skip all content.
   27172 		*/
   27173 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
   27174 		    ret = xmlTextReaderRead(vctxt->reader);
   27175 		    curDepth = xmlTextReaderDepth(vctxt->reader);
   27176 		    while ((ret == 1) && (curDepth != depth)) {
   27177 			ret = xmlTextReaderRead(vctxt->reader);
   27178 			curDepth = xmlTextReaderDepth(vctxt->reader);
   27179 		    }
   27180 		    if (ret < 0) {
   27181 			/*
   27182 			* VAL TODO: A reader error occurred; what to do here?
   27183 			*/
   27184 			ret = 1;
   27185 			goto exit;
   27186 		    }
   27187 		}
   27188 		goto leave_elem;
   27189 	    }
   27190 	    /*
   27191 	    * READER VAL TODO: Is an END_ELEM really never called
   27192 	    * if the elem is empty?
   27193 	    */
   27194 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27195 		goto leave_elem;
   27196 	} else if (nodeType == END_ELEM) {
   27197 	    /*
   27198 	    * Process END of element.
   27199 	    */
   27200 leave_elem:
   27201 	    ret = xmlSchemaValidatorPopElem(vctxt);
   27202 	    if (ret != 0) {
   27203 		if (ret < 0) {
   27204 		    VERROR_INT("xmlSchemaVReaderWalk",
   27205 			"calling xmlSchemaValidatorPopElem()");
   27206 		    goto internal_error;
   27207 		}
   27208 		goto exit;
   27209 	    }
   27210 	    if (vctxt->depth >= 0)
   27211 		ielem = vctxt->inode;
   27212 	    else
   27213 		ielem = NULL;
   27214 	} else if ((nodeType == XML_TEXT_NODE) ||
   27215 	    (nodeType == XML_CDATA_SECTION_NODE) ||
   27216 	    (nodeType == WHTSP) ||
   27217 	    (nodeType == SIGN_WHTSP)) {
   27218 	    /*
   27219 	    * Process character content.
   27220 	    */
   27221 	    xmlChar *value;
   27222 
   27223 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
   27224 		nodeType = XML_TEXT_NODE;
   27225 
   27226 	    value = xmlTextReaderValue(vctxt->reader);
   27227 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
   27228 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
   27229 	    if (! consumed)
   27230 		xmlFree(value);
   27231 	    if (ret == -1) {
   27232 		VERROR_INT("xmlSchemaVReaderWalk",
   27233 		    "calling xmlSchemaVPushText()");
   27234 		goto internal_error;
   27235 	    }
   27236 	} else if ((nodeType == XML_ENTITY_NODE) ||
   27237 	    (nodeType == XML_ENTITY_REF_NODE)) {
   27238 	    /*
   27239 	    * VAL TODO: What to do with entities?
   27240 	    */
   27241 	    TODO
   27242 	}
   27243 	/*
   27244 	* Read next node.
   27245 	*/
   27246 	ret = xmlTextReaderRead(vctxt->reader);
   27247     } while (ret == 1);
   27248 
   27249 exit:
   27250     return (ret);
   27251 internal_error:
   27252     return (-1);
   27253 }
   27254 #endif
   27255 
   27256 /************************************************************************
   27257  *									*
   27258  *			SAX validation handlers				*
   27259  *									*
   27260  ************************************************************************/
   27261 
   27262 /*
   27263 * Process text content.
   27264 */
   27265 static void
   27266 xmlSchemaSAXHandleText(void *ctx,
   27267 		       const xmlChar * ch,
   27268 		       int len)
   27269 {
   27270     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27271 
   27272     if (vctxt->depth < 0)
   27273 	return;
   27274     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27275 	return;
   27276     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27277 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27278     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
   27279 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27280 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27281 	    "calling xmlSchemaVPushText()");
   27282 	vctxt->err = -1;
   27283 	xmlStopParser(vctxt->parserCtxt);
   27284     }
   27285 }
   27286 
   27287 /*
   27288 * Process CDATA content.
   27289 */
   27290 static void
   27291 xmlSchemaSAXHandleCDataSection(void *ctx,
   27292 			     const xmlChar * ch,
   27293 			     int len)
   27294 {
   27295     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27296 
   27297     if (vctxt->depth < 0)
   27298 	return;
   27299     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27300 	return;
   27301     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
   27302 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   27303     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
   27304 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
   27305 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
   27306 	    "calling xmlSchemaVPushText()");
   27307 	vctxt->err = -1;
   27308 	xmlStopParser(vctxt->parserCtxt);
   27309     }
   27310 }
   27311 
   27312 static void
   27313 xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
   27314 			    const xmlChar * name ATTRIBUTE_UNUSED)
   27315 {
   27316     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27317 
   27318     if (vctxt->depth < 0)
   27319 	return;
   27320     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27321 	return;
   27322     /* SAX VAL TODO: What to do here? */
   27323     TODO
   27324 }
   27325 
   27326 static void
   27327 xmlSchemaSAXHandleStartElementNs(void *ctx,
   27328 				 const xmlChar * localname,
   27329 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
   27330 				 const xmlChar * URI,
   27331 				 int nb_namespaces,
   27332 				 const xmlChar ** namespaces,
   27333 				 int nb_attributes,
   27334 				 int nb_defaulted ATTRIBUTE_UNUSED,
   27335 				 const xmlChar ** attributes)
   27336 {
   27337     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27338     int ret;
   27339     xmlSchemaNodeInfoPtr ielem;
   27340     int i, j;
   27341 
   27342     /*
   27343     * SAX VAL TODO: What to do with nb_defaulted?
   27344     */
   27345     /*
   27346     * Skip elements if inside a "skip" wildcard or invalid.
   27347     */
   27348     vctxt->depth++;
   27349     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27350 	return;
   27351     /*
   27352     * Push the element.
   27353     */
   27354     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
   27355 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27356 	    "calling xmlSchemaValidatorPushElem()");
   27357 	goto internal_error;
   27358     }
   27359     ielem = vctxt->inode;
   27360     /*
   27361     * TODO: Is this OK?
   27362     */
   27363     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
   27364     ielem->localName = localname;
   27365     ielem->nsName = URI;
   27366     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27367     /*
   27368     * Register namespaces on the elem info.
   27369     */
   27370     if (nb_namespaces != 0) {
   27371 	/*
   27372 	* Although the parser builds its own namespace list,
   27373 	* we have no access to it, so we'll use an own one.
   27374 	*/
   27375         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
   27376 	    /*
   27377 	    * Store prefix and namespace name.
   27378 	    */
   27379 	    if (ielem->nsBindings == NULL) {
   27380 		ielem->nsBindings =
   27381 		    (const xmlChar **) xmlMalloc(10 *
   27382 			sizeof(const xmlChar *));
   27383 		if (ielem->nsBindings == NULL) {
   27384 		    xmlSchemaVErrMemory(vctxt,
   27385 			"allocating namespace bindings for SAX validation",
   27386 			NULL);
   27387 		    goto internal_error;
   27388 		}
   27389 		ielem->nbNsBindings = 0;
   27390 		ielem->sizeNsBindings = 5;
   27391 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
   27392 		ielem->sizeNsBindings *= 2;
   27393 		ielem->nsBindings =
   27394 		    (const xmlChar **) xmlRealloc(
   27395 			(void *) ielem->nsBindings,
   27396 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
   27397 		if (ielem->nsBindings == NULL) {
   27398 		    xmlSchemaVErrMemory(vctxt,
   27399 			"re-allocating namespace bindings for SAX validation",
   27400 			NULL);
   27401 		    goto internal_error;
   27402 		}
   27403 	    }
   27404 
   27405 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
   27406 	    if (namespaces[j+1][0] == 0) {
   27407 		/*
   27408 		* Handle xmlns="".
   27409 		*/
   27410 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
   27411 	    } else
   27412 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
   27413 		    namespaces[j+1];
   27414 	    ielem->nbNsBindings++;
   27415 	}
   27416     }
   27417     /*
   27418     * Register attributes.
   27419     * SAX VAL TODO: We are not adding namespace declaration
   27420     * attributes yet.
   27421     */
   27422     if (nb_attributes != 0) {
   27423 	int valueLen, k, l;
   27424 	xmlChar *value;
   27425 
   27426         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
   27427 	    /*
   27428 	    * Duplicate the value, changing any &#38; to a literal ampersand.
   27429 	    *
   27430 	    * libxml2 differs from normal SAX here in that it escapes all ampersands
   27431 	    * as &#38; instead of delivering the raw converted string. Changing the
   27432 	    * behavior at this point would break applications that use this API, so
   27433 	    * we are forced to work around it.
   27434 	    */
   27435 	    valueLen = attributes[j+4] - attributes[j+3];
   27436 	    value = xmlMallocAtomic(valueLen + 1);
   27437 	    if (value == NULL) {
   27438 		xmlSchemaVErrMemory(vctxt,
   27439 		    "allocating string for decoded attribute",
   27440 		    NULL);
   27441 		goto internal_error;
   27442 	    }
   27443 	    for (k = 0, l = 0; k < valueLen; l++) {
   27444 		if (k < valueLen - 4 &&
   27445 		    attributes[j+3][k+0] == '&' &&
   27446 		    attributes[j+3][k+1] == '#' &&
   27447 		    attributes[j+3][k+2] == '3' &&
   27448 		    attributes[j+3][k+3] == '8' &&
   27449 		    attributes[j+3][k+4] == ';') {
   27450 		    value[l] = '&';
   27451 		    k += 5;
   27452 		} else {
   27453 		    value[l] = attributes[j+3][k];
   27454 		    k++;
   27455 		}
   27456 	    }
   27457 	    value[l] = '\0';
   27458 	    /*
   27459 	    * TODO: Set the node line.
   27460 	    */
   27461 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27462 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
   27463 		value, 1);
   27464 	    if (ret == -1) {
   27465 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27466 		    "calling xmlSchemaValidatorPushAttribute()");
   27467 		goto internal_error;
   27468 	    }
   27469 	}
   27470     }
   27471     /*
   27472     * Validate the element.
   27473     */
   27474     ret = xmlSchemaValidateElem(vctxt);
   27475     if (ret != 0) {
   27476 	if (ret == -1) {
   27477 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
   27478 		"calling xmlSchemaValidateElem()");
   27479 	    goto internal_error;
   27480 	}
   27481 	goto exit;
   27482     }
   27483 
   27484 exit:
   27485     return;
   27486 internal_error:
   27487     vctxt->err = -1;
   27488     xmlStopParser(vctxt->parserCtxt);
   27489     return;
   27490 }
   27491 
   27492 static void
   27493 xmlSchemaSAXHandleEndElementNs(void *ctx,
   27494 			       const xmlChar * localname ATTRIBUTE_UNUSED,
   27495 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
   27496 			       const xmlChar * URI ATTRIBUTE_UNUSED)
   27497 {
   27498     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
   27499     int res;
   27500 
   27501     /*
   27502     * Skip elements if inside a "skip" wildcard or if invalid.
   27503     */
   27504     if (vctxt->skipDepth != -1) {
   27505 	if (vctxt->depth > vctxt->skipDepth) {
   27506 	    vctxt->depth--;
   27507 	    return;
   27508 	} else
   27509 	    vctxt->skipDepth = -1;
   27510     }
   27511     /*
   27512     * SAX VAL TODO: Just a temporary check.
   27513     */
   27514     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
   27515 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
   27516 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27517 	    "elem pop mismatch");
   27518     }
   27519     res = xmlSchemaValidatorPopElem(vctxt);
   27520     if (res != 0) {
   27521 	if (res < 0) {
   27522 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
   27523 		"calling xmlSchemaValidatorPopElem()");
   27524 	    goto internal_error;
   27525 	}
   27526 	goto exit;
   27527     }
   27528 exit:
   27529     return;
   27530 internal_error:
   27531     vctxt->err = -1;
   27532     xmlStopParser(vctxt->parserCtxt);
   27533     return;
   27534 }
   27535 
   27536 /************************************************************************
   27537  *									*
   27538  *			Validation interfaces				*
   27539  *									*
   27540  ************************************************************************/
   27541 
   27542 /**
   27543  * xmlSchemaNewValidCtxt:
   27544  * @schema:  a precompiled XML Schemas
   27545  *
   27546  * Create an XML Schemas validation context based on the given schema.
   27547  *
   27548  * Returns the validation context or NULL in case of error
   27549  */
   27550 xmlSchemaValidCtxtPtr
   27551 xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
   27552 {
   27553     xmlSchemaValidCtxtPtr ret;
   27554 
   27555     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
   27556     if (ret == NULL) {
   27557         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
   27558         return (NULL);
   27559     }
   27560     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
   27561     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
   27562     ret->dict = xmlDictCreate();
   27563     ret->nodeQNames = xmlSchemaItemListCreate();
   27564     ret->schema = schema;
   27565     return (ret);
   27566 }
   27567 
   27568 /**
   27569  * xmlSchemaValidateSetFilename:
   27570  * @vctxt: the schema validation context
   27571  * @filename: the file name
   27572  *
   27573  * Workaround to provide file error reporting information when this is
   27574  * not provided by current APIs
   27575  */
   27576 void
   27577 xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
   27578     if (vctxt == NULL)
   27579         return;
   27580     if (vctxt->filename != NULL)
   27581         xmlFree(vctxt->filename);
   27582     if (filename != NULL)
   27583         vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
   27584     else
   27585         vctxt->filename = NULL;
   27586 }
   27587 
   27588 /**
   27589  * xmlSchemaClearValidCtxt:
   27590  * @vctxt: the schema validation context
   27591  *
   27592  * Free the resources associated to the schema validation context;
   27593  * leaves some fields alive intended for reuse of the context.
   27594  */
   27595 static void
   27596 xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
   27597 {
   27598     if (vctxt == NULL)
   27599         return;
   27600 
   27601     /*
   27602     * TODO: Should we clear the flags?
   27603     *   Might be problematic if one reuses the context
   27604     *   and assumes that the options remain the same.
   27605     */
   27606     vctxt->flags = 0;
   27607     vctxt->validationRoot = NULL;
   27608     vctxt->doc = NULL;
   27609 #ifdef LIBXML_READER_ENABLED
   27610     vctxt->reader = NULL;
   27611 #endif
   27612     vctxt->hasKeyrefs = 0;
   27613 
   27614     if (vctxt->value != NULL) {
   27615         xmlSchemaFreeValue(vctxt->value);
   27616 	vctxt->value = NULL;
   27617     }
   27618     /*
   27619     * Augmented IDC information.
   27620     */
   27621     if (vctxt->aidcs != NULL) {
   27622 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
   27623 	do {
   27624 	    next = cur->next;
   27625 	    xmlFree(cur);
   27626 	    cur = next;
   27627 	} while (cur != NULL);
   27628 	vctxt->aidcs = NULL;
   27629     }
   27630     if (vctxt->idcMatcherCache != NULL) {
   27631 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
   27632 
   27633 	while (matcher) {
   27634 	    tmp = matcher;
   27635 	    matcher = matcher->nextCached;
   27636 	    xmlSchemaIDCFreeMatcherList(tmp);
   27637 	}
   27638 	vctxt->idcMatcherCache = NULL;
   27639     }
   27640 
   27641 
   27642     if (vctxt->idcNodes != NULL) {
   27643 	int i;
   27644 	xmlSchemaPSVIIDCNodePtr item;
   27645 
   27646 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
   27647 	    item = vctxt->idcNodes[i];
   27648 	    xmlFree(item->keys);
   27649 	    xmlFree(item);
   27650 	}
   27651 	xmlFree(vctxt->idcNodes);
   27652 	vctxt->idcNodes = NULL;
   27653 	vctxt->nbIdcNodes = 0;
   27654 	vctxt->sizeIdcNodes = 0;
   27655     }
   27656     /*
   27657     * Note that we won't delete the XPath state pool here.
   27658     */
   27659     if (vctxt->xpathStates != NULL) {
   27660 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
   27661 	vctxt->xpathStates = NULL;
   27662     }
   27663     /*
   27664     * Attribute info.
   27665     */
   27666     if (vctxt->nbAttrInfos != 0) {
   27667 	xmlSchemaClearAttrInfos(vctxt);
   27668     }
   27669     /*
   27670     * Element info.
   27671     */
   27672     if (vctxt->elemInfos != NULL) {
   27673 	int i;
   27674 	xmlSchemaNodeInfoPtr ei;
   27675 
   27676 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
   27677 	    ei = vctxt->elemInfos[i];
   27678 	    if (ei == NULL)
   27679 		break;
   27680 	    xmlSchemaClearElemInfo(vctxt, ei);
   27681 	}
   27682     }
   27683     xmlSchemaItemListClear(vctxt->nodeQNames);
   27684     /* Recreate the dict. */
   27685     xmlDictFree(vctxt->dict);
   27686     /*
   27687     * TODO: Is is save to recreate it? Do we have a scenario
   27688     * where the user provides the dict?
   27689     */
   27690     vctxt->dict = xmlDictCreate();
   27691 
   27692     if (vctxt->filename != NULL) {
   27693         xmlFree(vctxt->filename);
   27694 	vctxt->filename = NULL;
   27695     }
   27696 }
   27697 
   27698 /**
   27699  * xmlSchemaFreeValidCtxt:
   27700  * @ctxt:  the schema validation context
   27701  *
   27702  * Free the resources associated to the schema validation context
   27703  */
   27704 void
   27705 xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
   27706 {
   27707     if (ctxt == NULL)
   27708         return;
   27709     if (ctxt->value != NULL)
   27710         xmlSchemaFreeValue(ctxt->value);
   27711     if (ctxt->pctxt != NULL)
   27712 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
   27713     if (ctxt->idcNodes != NULL) {
   27714 	int i;
   27715 	xmlSchemaPSVIIDCNodePtr item;
   27716 
   27717 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
   27718 	    item = ctxt->idcNodes[i];
   27719 	    xmlFree(item->keys);
   27720 	    xmlFree(item);
   27721 	}
   27722 	xmlFree(ctxt->idcNodes);
   27723     }
   27724     if (ctxt->idcKeys != NULL) {
   27725 	int i;
   27726 	for (i = 0; i < ctxt->nbIdcKeys; i++)
   27727 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
   27728 	xmlFree(ctxt->idcKeys);
   27729     }
   27730 
   27731     if (ctxt->xpathStates != NULL) {
   27732 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
   27733 	ctxt->xpathStates = NULL;
   27734     }
   27735     if (ctxt->xpathStatePool != NULL) {
   27736 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
   27737 	ctxt->xpathStatePool = NULL;
   27738     }
   27739 
   27740     /*
   27741     * Augmented IDC information.
   27742     */
   27743     if (ctxt->aidcs != NULL) {
   27744 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
   27745 	do {
   27746 	    next = cur->next;
   27747 	    xmlFree(cur);
   27748 	    cur = next;
   27749 	} while (cur != NULL);
   27750     }
   27751     if (ctxt->attrInfos != NULL) {
   27752 	int i;
   27753 	xmlSchemaAttrInfoPtr attr;
   27754 
   27755 	/* Just a paranoid call to the cleanup. */
   27756 	if (ctxt->nbAttrInfos != 0)
   27757 	    xmlSchemaClearAttrInfos(ctxt);
   27758 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
   27759 	    attr = ctxt->attrInfos[i];
   27760 	    xmlFree(attr);
   27761 	}
   27762 	xmlFree(ctxt->attrInfos);
   27763     }
   27764     if (ctxt->elemInfos != NULL) {
   27765 	int i;
   27766 	xmlSchemaNodeInfoPtr ei;
   27767 
   27768 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
   27769 	    ei = ctxt->elemInfos[i];
   27770 	    if (ei == NULL)
   27771 		break;
   27772 	    xmlSchemaClearElemInfo(ctxt, ei);
   27773 	    xmlFree(ei);
   27774 	}
   27775 	xmlFree(ctxt->elemInfos);
   27776     }
   27777     if (ctxt->nodeQNames != NULL)
   27778 	xmlSchemaItemListFree(ctxt->nodeQNames);
   27779     if (ctxt->dict != NULL)
   27780 	xmlDictFree(ctxt->dict);
   27781     if (ctxt->filename != NULL)
   27782 	xmlFree(ctxt->filename);
   27783     xmlFree(ctxt);
   27784 }
   27785 
   27786 /**
   27787  * xmlSchemaIsValid:
   27788  * @ctxt: the schema validation context
   27789  *
   27790  * Check if any error was detected during validation.
   27791  *
   27792  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
   27793  *         of internal error.
   27794  */
   27795 int
   27796 xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
   27797 {
   27798     if (ctxt == NULL)
   27799         return(-1);
   27800     return(ctxt->err == 0);
   27801 }
   27802 
   27803 /**
   27804  * xmlSchemaSetValidErrors:
   27805  * @ctxt:  a schema validation context
   27806  * @err:  the error function
   27807  * @warn: the warning function
   27808  * @ctx: the functions context
   27809  *
   27810  * Set the error and warning callback informations
   27811  */
   27812 void
   27813 xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27814                         xmlSchemaValidityErrorFunc err,
   27815                         xmlSchemaValidityWarningFunc warn, void *ctx)
   27816 {
   27817     if (ctxt == NULL)
   27818         return;
   27819     ctxt->error = err;
   27820     ctxt->warning = warn;
   27821     ctxt->errCtxt = ctx;
   27822     if (ctxt->pctxt != NULL)
   27823 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
   27824 }
   27825 
   27826 /**
   27827  * xmlSchemaSetValidStructuredErrors:
   27828  * @ctxt:  a schema validation context
   27829  * @serror:  the structured error function
   27830  * @ctx: the functions context
   27831  *
   27832  * Set the structured error callback
   27833  */
   27834 void
   27835 xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
   27836 				  xmlStructuredErrorFunc serror, void *ctx)
   27837 {
   27838     if (ctxt == NULL)
   27839         return;
   27840     ctxt->serror = serror;
   27841     ctxt->error = NULL;
   27842     ctxt->warning = NULL;
   27843     ctxt->errCtxt = ctx;
   27844     if (ctxt->pctxt != NULL)
   27845 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
   27846 }
   27847 
   27848 /**
   27849  * xmlSchemaGetValidErrors:
   27850  * @ctxt: a XML-Schema validation context
   27851  * @err: the error function result
   27852  * @warn: the warning function result
   27853  * @ctx: the functions context result
   27854  *
   27855  * Get the error and warning callback informations
   27856  *
   27857  * Returns -1 in case of error and 0 otherwise
   27858  */
   27859 int
   27860 xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
   27861 			xmlSchemaValidityErrorFunc * err,
   27862 			xmlSchemaValidityWarningFunc * warn, void **ctx)
   27863 {
   27864 	if (ctxt == NULL)
   27865 		return (-1);
   27866 	if (err != NULL)
   27867 		*err = ctxt->error;
   27868 	if (warn != NULL)
   27869 		*warn = ctxt->warning;
   27870 	if (ctx != NULL)
   27871 		*ctx = ctxt->errCtxt;
   27872 	return (0);
   27873 }
   27874 
   27875 
   27876 /**
   27877  * xmlSchemaSetValidOptions:
   27878  * @ctxt:	a schema validation context
   27879  * @options: a combination of xmlSchemaValidOption
   27880  *
   27881  * Sets the options to be used during the validation.
   27882  *
   27883  * Returns 0 in case of success, -1 in case of an
   27884  * API error.
   27885  */
   27886 int
   27887 xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
   27888 			 int options)
   27889 
   27890 {
   27891     int i;
   27892 
   27893     if (ctxt == NULL)
   27894 	return (-1);
   27895     /*
   27896     * WARNING: Change the start value if adding to the
   27897     * xmlSchemaValidOption.
   27898     * TODO: Is there an other, more easy to maintain,
   27899     * way?
   27900     */
   27901     for (i = 1; i < (int) sizeof(int) * 8; i++) {
   27902         if (options & 1<<i)
   27903 	    return (-1);
   27904     }
   27905     ctxt->options = options;
   27906     return (0);
   27907 }
   27908 
   27909 /**
   27910  * xmlSchemaValidCtxtGetOptions:
   27911  * @ctxt: a schema validation context
   27912  *
   27913  * Get the validation context options.
   27914  *
   27915  * Returns the option combination or -1 on error.
   27916  */
   27917 int
   27918 xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
   27919 
   27920 {
   27921     if (ctxt == NULL)
   27922 	return (-1);
   27923     else
   27924 	return (ctxt->options);
   27925 }
   27926 
   27927 static int
   27928 xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
   27929 {
   27930     xmlAttrPtr attr;
   27931     int ret = 0;
   27932     xmlSchemaNodeInfoPtr ielem = NULL;
   27933     xmlNodePtr node, valRoot;
   27934     const xmlChar *nsName;
   27935 
   27936     /* DOC VAL TODO: Move this to the start function. */
   27937     if (vctxt->validationRoot != NULL)
   27938         valRoot = vctxt->validationRoot;
   27939     else
   27940 	valRoot = xmlDocGetRootElement(vctxt->doc);
   27941     if (valRoot == NULL) {
   27942 	/* VAL TODO: Error code? */
   27943 	VERROR(1, NULL, "The document has no document element");
   27944 	return (1);
   27945     }
   27946     vctxt->depth = -1;
   27947     vctxt->validationRoot = valRoot;
   27948     node = valRoot;
   27949     while (node != NULL) {
   27950 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
   27951 	    goto next_sibling;
   27952 	if (node->type == XML_ELEMENT_NODE) {
   27953 
   27954 	    /*
   27955 	    * Init the node-info.
   27956 	    */
   27957 	    vctxt->depth++;
   27958 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
   27959 		goto internal_error;
   27960 	    ielem = vctxt->inode;
   27961 	    ielem->node = node;
   27962 	    ielem->nodeLine = node->line;
   27963 	    ielem->localName = node->name;
   27964 	    if (node->ns != NULL)
   27965 		ielem->nsName = node->ns->href;
   27966 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
   27967 	    /*
   27968 	    * Register attributes.
   27969 	    * DOC VAL TODO: We do not register namespace declaration
   27970 	    * attributes yet.
   27971 	    */
   27972 	    vctxt->nbAttrInfos = 0;
   27973 	    if (node->properties != NULL) {
   27974 		attr = node->properties;
   27975 		do {
   27976 		    if (attr->ns != NULL)
   27977 			nsName = attr->ns->href;
   27978 		    else
   27979 			nsName = NULL;
   27980 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
   27981 			(xmlNodePtr) attr,
   27982 			/*
   27983 			* Note that we give it the line number of the
   27984 			* parent element.
   27985 			*/
   27986 			ielem->nodeLine,
   27987 			attr->name, nsName, 0,
   27988 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
   27989 		    if (ret == -1) {
   27990 			VERROR_INT("xmlSchemaDocWalk",
   27991 			    "calling xmlSchemaValidatorPushAttribute()");
   27992 			goto internal_error;
   27993 		    }
   27994 		    attr = attr->next;
   27995 		} while (attr);
   27996 	    }
   27997 	    /*
   27998 	    * Validate the element.
   27999 	    */
   28000 	    ret = xmlSchemaValidateElem(vctxt);
   28001 	    if (ret != 0) {
   28002 		if (ret == -1) {
   28003 		    VERROR_INT("xmlSchemaDocWalk",
   28004 			"calling xmlSchemaValidateElem()");
   28005 		    goto internal_error;
   28006 		}
   28007 		/*
   28008 		* Don't stop validation; just skip the content
   28009 		* of this element.
   28010 		*/
   28011 		goto leave_node;
   28012 	    }
   28013 	    if ((vctxt->skipDepth != -1) &&
   28014 		(vctxt->depth >= vctxt->skipDepth))
   28015 		goto leave_node;
   28016 	} else if ((node->type == XML_TEXT_NODE) ||
   28017 	    (node->type == XML_CDATA_SECTION_NODE)) {
   28018 	    /*
   28019 	    * Process character content.
   28020 	    */
   28021 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
   28022 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
   28023 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
   28024 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
   28025 	    if (ret < 0) {
   28026 		VERROR_INT("xmlSchemaVDocWalk",
   28027 		    "calling xmlSchemaVPushText()");
   28028 		goto internal_error;
   28029 	    }
   28030 	    /*
   28031 	    * DOC VAL TODO: Should we skip further validation of the
   28032 	    * element content here?
   28033 	    */
   28034 	} else if ((node->type == XML_ENTITY_NODE) ||
   28035 	    (node->type == XML_ENTITY_REF_NODE)) {
   28036 	    /*
   28037 	    * DOC VAL TODO: What to do with entities?
   28038 	    */
   28039 	    VERROR_INT("xmlSchemaVDocWalk",
   28040 		"there is at least one entity reference in the node-tree "
   28041 		"currently being validated. Processing of entities with "
   28042 		"this XML Schema processor is not supported (yet). Please "
   28043 		"substitute entities before validation.");
   28044 	    goto internal_error;
   28045 	} else {
   28046 	    goto leave_node;
   28047 	    /*
   28048 	    * DOC VAL TODO: XInclude nodes, etc.
   28049 	    */
   28050 	}
   28051 	/*
   28052 	* Walk the doc.
   28053 	*/
   28054 	if (node->children != NULL) {
   28055 	    node = node->children;
   28056 	    continue;
   28057 	}
   28058 leave_node:
   28059 	if (node->type == XML_ELEMENT_NODE) {
   28060 	    /*
   28061 	    * Leaving the scope of an element.
   28062 	    */
   28063 	    if (node != vctxt->inode->node) {
   28064 		VERROR_INT("xmlSchemaVDocWalk",
   28065 		    "element position mismatch");
   28066 		goto internal_error;
   28067 	    }
   28068 	    ret = xmlSchemaValidatorPopElem(vctxt);
   28069 	    if (ret != 0) {
   28070 		if (ret < 0) {
   28071 		    VERROR_INT("xmlSchemaVDocWalk",
   28072 			"calling xmlSchemaValidatorPopElem()");
   28073 		    goto internal_error;
   28074 		}
   28075 	    }
   28076 	    if (node == valRoot)
   28077 		goto exit;
   28078 	}
   28079 next_sibling:
   28080 	if (node->next != NULL)
   28081 	    node = node->next;
   28082 	else {
   28083 	    node = node->parent;
   28084 	    goto leave_node;
   28085 	}
   28086     }
   28087 
   28088 exit:
   28089     return (ret);
   28090 internal_error:
   28091     return (-1);
   28092 }
   28093 
   28094 static int
   28095 xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
   28096     /*
   28097     * Some initialization.
   28098     */
   28099     vctxt->err = 0;
   28100     vctxt->nberrors = 0;
   28101     vctxt->depth = -1;
   28102     vctxt->skipDepth = -1;
   28103     vctxt->xsiAssemble = 0;
   28104     vctxt->hasKeyrefs = 0;
   28105 #ifdef ENABLE_IDC_NODE_TABLES_TEST
   28106     vctxt->createIDCNodeTables = 1;
   28107 #else
   28108     vctxt->createIDCNodeTables = 0;
   28109 #endif
   28110     /*
   28111     * Create a schema + parser if necessary.
   28112     */
   28113     if (vctxt->schema == NULL) {
   28114 	xmlSchemaParserCtxtPtr pctxt;
   28115 
   28116 	vctxt->xsiAssemble = 1;
   28117 	/*
   28118 	* If not schema was given then we will create a schema
   28119 	* dynamically using XSI schema locations.
   28120 	*
   28121 	* Create the schema parser context.
   28122 	*/
   28123 	if ((vctxt->pctxt == NULL) &&
   28124 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
   28125 	   return (-1);
   28126 	pctxt = vctxt->pctxt;
   28127 	pctxt->xsiAssemble = 1;
   28128 	/*
   28129 	* Create the schema.
   28130 	*/
   28131 	vctxt->schema = xmlSchemaNewSchema(pctxt);
   28132 	if (vctxt->schema == NULL)
   28133 	    return (-1);
   28134 	/*
   28135 	* Create the schema construction context.
   28136 	*/
   28137 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
   28138 	if (pctxt->constructor == NULL)
   28139 	    return(-1);
   28140 	pctxt->constructor->mainSchema = vctxt->schema;
   28141 	/*
   28142 	* Take ownership of the constructor to be able to free it.
   28143 	*/
   28144 	pctxt->ownsConstructor = 1;
   28145     }
   28146     /*
   28147     * Augment the IDC definitions for the main schema and all imported ones
   28148     * NOTE: main schema if the first in the imported list
   28149     */
   28150     xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
   28151                 vctxt);
   28152 
   28153     return(0);
   28154 }
   28155 
   28156 static void
   28157 xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
   28158     if (vctxt->xsiAssemble) {
   28159 	if (vctxt->schema != NULL) {
   28160 	    xmlSchemaFree(vctxt->schema);
   28161 	    vctxt->schema = NULL;
   28162 	}
   28163     }
   28164     xmlSchemaClearValidCtxt(vctxt);
   28165 }
   28166 
   28167 static int
   28168 xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
   28169 {
   28170     int ret = 0;
   28171 
   28172     if (xmlSchemaPreRun(vctxt) < 0)
   28173         return(-1);
   28174 
   28175     if (vctxt->doc != NULL) {
   28176 	/*
   28177 	 * Tree validation.
   28178 	 */
   28179 	ret = xmlSchemaVDocWalk(vctxt);
   28180 #ifdef LIBXML_READER_ENABLED
   28181     } else if (vctxt->reader != NULL) {
   28182 	/*
   28183 	 * XML Reader validation.
   28184 	 */
   28185 #ifdef XML_SCHEMA_READER_ENABLED
   28186 	ret = xmlSchemaVReaderWalk(vctxt);
   28187 #endif
   28188 #endif
   28189     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
   28190 	/*
   28191 	 * SAX validation.
   28192 	 */
   28193 	ret = xmlParseDocument(vctxt->parserCtxt);
   28194     } else {
   28195 	VERROR_INT("xmlSchemaVStart",
   28196 	    "no instance to validate");
   28197 	ret = -1;
   28198     }
   28199 
   28200     xmlSchemaPostRun(vctxt);
   28201     if (ret == 0)
   28202 	ret = vctxt->err;
   28203     return (ret);
   28204 }
   28205 
   28206 /**
   28207  * xmlSchemaValidateOneElement:
   28208  * @ctxt:  a schema validation context
   28209  * @elem:  an element node
   28210  *
   28211  * Validate a branch of a tree, starting with the given @elem.
   28212  *
   28213  * Returns 0 if the element and its subtree is valid, a positive error
   28214  * code number otherwise and -1 in case of an internal or API error.
   28215  */
   28216 int
   28217 xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
   28218 {
   28219     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
   28220 	return (-1);
   28221 
   28222     if (ctxt->schema == NULL)
   28223 	return (-1);
   28224 
   28225     ctxt->doc = elem->doc;
   28226     ctxt->node = elem;
   28227     ctxt->validationRoot = elem;
   28228     return(xmlSchemaVStart(ctxt));
   28229 }
   28230 
   28231 /**
   28232  * xmlSchemaValidateDoc:
   28233  * @ctxt:  a schema validation context
   28234  * @doc:  a parsed document tree
   28235  *
   28236  * Validate a document tree in memory.
   28237  *
   28238  * Returns 0 if the document is schemas valid, a positive error code
   28239  *     number otherwise and -1 in case of internal or API error.
   28240  */
   28241 int
   28242 xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
   28243 {
   28244     if ((ctxt == NULL) || (doc == NULL))
   28245         return (-1);
   28246 
   28247     ctxt->doc = doc;
   28248     ctxt->node = xmlDocGetRootElement(doc);
   28249     if (ctxt->node == NULL) {
   28250         xmlSchemaCustomErr(ACTXT_CAST ctxt,
   28251 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
   28252 	    (xmlNodePtr) doc, NULL,
   28253 	    "The document has no document element", NULL, NULL);
   28254         return (ctxt->err);
   28255     }
   28256     ctxt->validationRoot = ctxt->node;
   28257     return (xmlSchemaVStart(ctxt));
   28258 }
   28259 
   28260 
   28261 /************************************************************************
   28262  *									*
   28263  *		Function and data for SAX streaming API			*
   28264  *									*
   28265  ************************************************************************/
   28266 typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
   28267 typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
   28268 
   28269 struct _xmlSchemaSplitSAXData {
   28270     xmlSAXHandlerPtr      user_sax;
   28271     void                 *user_data;
   28272     xmlSchemaValidCtxtPtr ctxt;
   28273     xmlSAXHandlerPtr      schemas_sax;
   28274 };
   28275 
   28276 #define XML_SAX_PLUG_MAGIC 0xdc43ba21
   28277 
   28278 struct _xmlSchemaSAXPlug {
   28279     unsigned int magic;
   28280 
   28281     /* the original callbacks informations */
   28282     xmlSAXHandlerPtr     *user_sax_ptr;
   28283     xmlSAXHandlerPtr      user_sax;
   28284     void                **user_data_ptr;
   28285     void                 *user_data;
   28286 
   28287     /* the block plugged back and validation informations */
   28288     xmlSAXHandler         schemas_sax;
   28289     xmlSchemaValidCtxtPtr ctxt;
   28290 };
   28291 
   28292 /* All those functions just bounces to the user provided SAX handlers */
   28293 static void
   28294 internalSubsetSplit(void *ctx, const xmlChar *name,
   28295 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28296 {
   28297     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28298     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28299         (ctxt->user_sax->internalSubset != NULL))
   28300 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
   28301 	                               SystemID);
   28302 }
   28303 
   28304 static int
   28305 isStandaloneSplit(void *ctx)
   28306 {
   28307     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28308     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28309         (ctxt->user_sax->isStandalone != NULL))
   28310 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
   28311     return(0);
   28312 }
   28313 
   28314 static int
   28315 hasInternalSubsetSplit(void *ctx)
   28316 {
   28317     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28318     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28319         (ctxt->user_sax->hasInternalSubset != NULL))
   28320 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
   28321     return(0);
   28322 }
   28323 
   28324 static int
   28325 hasExternalSubsetSplit(void *ctx)
   28326 {
   28327     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28328     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28329         (ctxt->user_sax->hasExternalSubset != NULL))
   28330 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
   28331     return(0);
   28332 }
   28333 
   28334 static void
   28335 externalSubsetSplit(void *ctx, const xmlChar *name,
   28336 	       const xmlChar *ExternalID, const xmlChar *SystemID)
   28337 {
   28338     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28339     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28340         (ctxt->user_sax->externalSubset != NULL))
   28341 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
   28342 	                               SystemID);
   28343 }
   28344 
   28345 static xmlParserInputPtr
   28346 resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
   28347 {
   28348     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28349     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28350         (ctxt->user_sax->resolveEntity != NULL))
   28351 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
   28352 	                                     systemId));
   28353     return(NULL);
   28354 }
   28355 
   28356 static xmlEntityPtr
   28357 getEntitySplit(void *ctx, const xmlChar *name)
   28358 {
   28359     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28360     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28361         (ctxt->user_sax->getEntity != NULL))
   28362 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
   28363     return(NULL);
   28364 }
   28365 
   28366 static xmlEntityPtr
   28367 getParameterEntitySplit(void *ctx, const xmlChar *name)
   28368 {
   28369     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28370     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28371         (ctxt->user_sax->getParameterEntity != NULL))
   28372 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
   28373     return(NULL);
   28374 }
   28375 
   28376 
   28377 static void
   28378 entityDeclSplit(void *ctx, const xmlChar *name, int type,
   28379           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
   28380 {
   28381     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28382     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28383         (ctxt->user_sax->entityDecl != NULL))
   28384 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
   28385 	                           systemId, content);
   28386 }
   28387 
   28388 static void
   28389 attributeDeclSplit(void *ctx, const xmlChar * elem,
   28390                    const xmlChar * name, int type, int def,
   28391                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
   28392 {
   28393     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28394     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28395         (ctxt->user_sax->attributeDecl != NULL)) {
   28396 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
   28397 	                              def, defaultValue, tree);
   28398     } else {
   28399 	xmlFreeEnumeration(tree);
   28400     }
   28401 }
   28402 
   28403 static void
   28404 elementDeclSplit(void *ctx, const xmlChar *name, int type,
   28405 	    xmlElementContentPtr content)
   28406 {
   28407     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28408     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28409         (ctxt->user_sax->elementDecl != NULL))
   28410 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
   28411 }
   28412 
   28413 static void
   28414 notationDeclSplit(void *ctx, const xmlChar *name,
   28415 	     const xmlChar *publicId, const xmlChar *systemId)
   28416 {
   28417     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28418     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28419         (ctxt->user_sax->notationDecl != NULL))
   28420 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
   28421 	                             systemId);
   28422 }
   28423 
   28424 static void
   28425 unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
   28426 		   const xmlChar *publicId, const xmlChar *systemId,
   28427 		   const xmlChar *notationName)
   28428 {
   28429     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28430     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28431         (ctxt->user_sax->unparsedEntityDecl != NULL))
   28432 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
   28433 	                                   systemId, notationName);
   28434 }
   28435 
   28436 static void
   28437 setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
   28438 {
   28439     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28440     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28441         (ctxt->user_sax->setDocumentLocator != NULL))
   28442 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
   28443 }
   28444 
   28445 static void
   28446 startDocumentSplit(void *ctx)
   28447 {
   28448     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28449     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28450         (ctxt->user_sax->startDocument != NULL))
   28451 	ctxt->user_sax->startDocument(ctxt->user_data);
   28452 }
   28453 
   28454 static void
   28455 endDocumentSplit(void *ctx)
   28456 {
   28457     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28458     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28459         (ctxt->user_sax->endDocument != NULL))
   28460 	ctxt->user_sax->endDocument(ctxt->user_data);
   28461 }
   28462 
   28463 static void
   28464 processingInstructionSplit(void *ctx, const xmlChar *target,
   28465                       const xmlChar *data)
   28466 {
   28467     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28468     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28469         (ctxt->user_sax->processingInstruction != NULL))
   28470 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
   28471 }
   28472 
   28473 static void
   28474 commentSplit(void *ctx, const xmlChar *value)
   28475 {
   28476     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28477     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28478         (ctxt->user_sax->comment != NULL))
   28479 	ctxt->user_sax->comment(ctxt->user_data, value);
   28480 }
   28481 
   28482 /*
   28483  * Varargs error callbacks to the user application, harder ...
   28484  */
   28485 
   28486 static void XMLCDECL
   28487 warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28488     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28489     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28490         (ctxt->user_sax->warning != NULL)) {
   28491 	TODO
   28492     }
   28493 }
   28494 static void XMLCDECL
   28495 errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28496     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28497     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28498         (ctxt->user_sax->error != NULL)) {
   28499 	TODO
   28500     }
   28501 }
   28502 static void XMLCDECL
   28503 fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
   28504     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28505     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28506         (ctxt->user_sax->fatalError != NULL)) {
   28507 	TODO
   28508     }
   28509 }
   28510 
   28511 /*
   28512  * Those are function where both the user handler and the schemas handler
   28513  * need to be called.
   28514  */
   28515 static void
   28516 charactersSplit(void *ctx, const xmlChar *ch, int len)
   28517 {
   28518     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28519     if (ctxt == NULL)
   28520         return;
   28521     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
   28522 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
   28523     if (ctxt->ctxt != NULL)
   28524 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28525 }
   28526 
   28527 static void
   28528 ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
   28529 {
   28530     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28531     if (ctxt == NULL)
   28532         return;
   28533     if ((ctxt->user_sax != NULL) &&
   28534         (ctxt->user_sax->ignorableWhitespace != NULL))
   28535 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
   28536     if (ctxt->ctxt != NULL)
   28537 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
   28538 }
   28539 
   28540 static void
   28541 cdataBlockSplit(void *ctx, const xmlChar *value, int len)
   28542 {
   28543     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28544     if (ctxt == NULL)
   28545         return;
   28546     if ((ctxt->user_sax != NULL) &&
   28547         (ctxt->user_sax->cdataBlock != NULL))
   28548 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
   28549     if (ctxt->ctxt != NULL)
   28550 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
   28551 }
   28552 
   28553 static void
   28554 referenceSplit(void *ctx, const xmlChar *name)
   28555 {
   28556     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28557     if (ctxt == NULL)
   28558         return;
   28559     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
   28560         (ctxt->user_sax->reference != NULL))
   28561 	ctxt->user_sax->reference(ctxt->user_data, name);
   28562     if (ctxt->ctxt != NULL)
   28563         xmlSchemaSAXHandleReference(ctxt->user_data, name);
   28564 }
   28565 
   28566 static void
   28567 startElementNsSplit(void *ctx, const xmlChar * localname,
   28568 		    const xmlChar * prefix, const xmlChar * URI,
   28569 		    int nb_namespaces, const xmlChar ** namespaces,
   28570 		    int nb_attributes, int nb_defaulted,
   28571 		    const xmlChar ** attributes) {
   28572     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28573     if (ctxt == NULL)
   28574         return;
   28575     if ((ctxt->user_sax != NULL) &&
   28576         (ctxt->user_sax->startElementNs != NULL))
   28577 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
   28578 	                               URI, nb_namespaces, namespaces,
   28579 				       nb_attributes, nb_defaulted,
   28580 				       attributes);
   28581     if (ctxt->ctxt != NULL)
   28582 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
   28583 	                                 URI, nb_namespaces, namespaces,
   28584 					 nb_attributes, nb_defaulted,
   28585 					 attributes);
   28586 }
   28587 
   28588 static void
   28589 endElementNsSplit(void *ctx, const xmlChar * localname,
   28590 		    const xmlChar * prefix, const xmlChar * URI) {
   28591     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
   28592     if (ctxt == NULL)
   28593         return;
   28594     if ((ctxt->user_sax != NULL) &&
   28595         (ctxt->user_sax->endElementNs != NULL))
   28596 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
   28597     if (ctxt->ctxt != NULL)
   28598 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
   28599 }
   28600 
   28601 /**
   28602  * xmlSchemaSAXPlug:
   28603  * @ctxt:  a schema validation context
   28604  * @sax:  a pointer to the original xmlSAXHandlerPtr
   28605  * @user_data:  a pointer to the original SAX user data pointer
   28606  *
   28607  * Plug a SAX based validation layer in a SAX parsing event flow.
   28608  * The original @saxptr and @dataptr data are replaced by new pointers
   28609  * but the calls to the original will be maintained.
   28610  *
   28611  * Returns a pointer to a data structure needed to unplug the validation layer
   28612  *         or NULL in case of errors.
   28613  */
   28614 xmlSchemaSAXPlugPtr
   28615 xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
   28616 		 xmlSAXHandlerPtr *sax, void **user_data)
   28617 {
   28618     xmlSchemaSAXPlugPtr ret;
   28619     xmlSAXHandlerPtr old_sax;
   28620 
   28621     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
   28622         return(NULL);
   28623 
   28624     /*
   28625      * We only allow to plug into SAX2 event streams
   28626      */
   28627     old_sax = *sax;
   28628     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
   28629         return(NULL);
   28630     if ((old_sax != NULL) &&
   28631         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
   28632         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
   28633         return(NULL);
   28634 
   28635     /*
   28636      * everything seems right allocate the local data needed for that layer
   28637      */
   28638     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
   28639     if (ret == NULL) {
   28640         return(NULL);
   28641     }
   28642     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
   28643     ret->magic = XML_SAX_PLUG_MAGIC;
   28644     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
   28645     ret->ctxt = ctxt;
   28646     ret->user_sax_ptr = sax;
   28647     ret->user_sax = old_sax;
   28648     if (old_sax == NULL) {
   28649         /*
   28650 	 * go direct, no need for the split block and functions.
   28651 	 */
   28652 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
   28653 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
   28654 	/*
   28655 	 * Note that we use the same text-function for both, to prevent
   28656 	 * the parser from testing for ignorable whitespace.
   28657 	 */
   28658 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
   28659 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
   28660 
   28661 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
   28662 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
   28663 
   28664 	ret->user_data = ctxt;
   28665 	*user_data = ctxt;
   28666     } else {
   28667        /*
   28668         * for each callback unused by Schemas initialize it to the Split
   28669 	* routine only if non NULL in the user block, this can speed up
   28670 	* things at the SAX level.
   28671 	*/
   28672         if (old_sax->internalSubset != NULL)
   28673             ret->schemas_sax.internalSubset = internalSubsetSplit;
   28674         if (old_sax->isStandalone != NULL)
   28675             ret->schemas_sax.isStandalone = isStandaloneSplit;
   28676         if (old_sax->hasInternalSubset != NULL)
   28677             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
   28678         if (old_sax->hasExternalSubset != NULL)
   28679             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
   28680         if (old_sax->resolveEntity != NULL)
   28681             ret->schemas_sax.resolveEntity = resolveEntitySplit;
   28682         if (old_sax->getEntity != NULL)
   28683             ret->schemas_sax.getEntity = getEntitySplit;
   28684         if (old_sax->entityDecl != NULL)
   28685             ret->schemas_sax.entityDecl = entityDeclSplit;
   28686         if (old_sax->notationDecl != NULL)
   28687             ret->schemas_sax.notationDecl = notationDeclSplit;
   28688         if (old_sax->attributeDecl != NULL)
   28689             ret->schemas_sax.attributeDecl = attributeDeclSplit;
   28690         if (old_sax->elementDecl != NULL)
   28691             ret->schemas_sax.elementDecl = elementDeclSplit;
   28692         if (old_sax->unparsedEntityDecl != NULL)
   28693             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
   28694         if (old_sax->setDocumentLocator != NULL)
   28695             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
   28696         if (old_sax->startDocument != NULL)
   28697             ret->schemas_sax.startDocument = startDocumentSplit;
   28698         if (old_sax->endDocument != NULL)
   28699             ret->schemas_sax.endDocument = endDocumentSplit;
   28700         if (old_sax->processingInstruction != NULL)
   28701             ret->schemas_sax.processingInstruction = processingInstructionSplit;
   28702         if (old_sax->comment != NULL)
   28703             ret->schemas_sax.comment = commentSplit;
   28704         if (old_sax->warning != NULL)
   28705             ret->schemas_sax.warning = warningSplit;
   28706         if (old_sax->error != NULL)
   28707             ret->schemas_sax.error = errorSplit;
   28708         if (old_sax->fatalError != NULL)
   28709             ret->schemas_sax.fatalError = fatalErrorSplit;
   28710         if (old_sax->getParameterEntity != NULL)
   28711             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
   28712         if (old_sax->externalSubset != NULL)
   28713             ret->schemas_sax.externalSubset = externalSubsetSplit;
   28714 
   28715 	/*
   28716 	 * the 6 schemas callback have to go to the splitter functions
   28717 	 * Note that we use the same text-function for ignorableWhitespace
   28718 	 * if possible, to prevent the parser from testing for ignorable
   28719 	 * whitespace.
   28720 	 */
   28721         ret->schemas_sax.characters = charactersSplit;
   28722 	if ((old_sax->ignorableWhitespace != NULL) &&
   28723 	    (old_sax->ignorableWhitespace != old_sax->characters))
   28724 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
   28725 	else
   28726 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
   28727         ret->schemas_sax.cdataBlock = cdataBlockSplit;
   28728         ret->schemas_sax.reference = referenceSplit;
   28729         ret->schemas_sax.startElementNs = startElementNsSplit;
   28730         ret->schemas_sax.endElementNs = endElementNsSplit;
   28731 
   28732 	ret->user_data_ptr = user_data;
   28733 	ret->user_data = *user_data;
   28734 	*user_data = ret;
   28735     }
   28736 
   28737     /*
   28738      * plug the pointers back.
   28739      */
   28740     *sax = &(ret->schemas_sax);
   28741     ctxt->sax = *sax;
   28742     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28743     xmlSchemaPreRun(ctxt);
   28744     return(ret);
   28745 }
   28746 
   28747 /**
   28748  * xmlSchemaSAXUnplug:
   28749  * @plug:  a data structure returned by xmlSchemaSAXPlug
   28750  *
   28751  * Unplug a SAX based validation layer in a SAX parsing event flow.
   28752  * The original pointers used in the call are restored.
   28753  *
   28754  * Returns 0 in case of success and -1 in case of failure.
   28755  */
   28756 int
   28757 xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
   28758 {
   28759     xmlSAXHandlerPtr *sax;
   28760     void **user_data;
   28761 
   28762     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
   28763         return(-1);
   28764     plug->magic = 0;
   28765 
   28766     xmlSchemaPostRun(plug->ctxt);
   28767     /* restore the data */
   28768     sax = plug->user_sax_ptr;
   28769     *sax = plug->user_sax;
   28770     if (plug->user_sax != NULL) {
   28771 	user_data = plug->user_data_ptr;
   28772 	*user_data = plug->user_data;
   28773     }
   28774 
   28775     /* free and return */
   28776     xmlFree(plug);
   28777     return(0);
   28778 }
   28779 
   28780 /**
   28781  * xmlSchemaValidateSetLocator:
   28782  * @vctxt: a schema validation context
   28783  * @f: the locator function pointer
   28784  * @ctxt: the locator context
   28785  *
   28786  * Allows to set a locator function to the validation context,
   28787  * which will be used to provide file and line information since
   28788  * those are not provided as part of the SAX validation flow
   28789  * Setting @f to NULL disable the locator.
   28790  */
   28791 
   28792 void
   28793 xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
   28794                             xmlSchemaValidityLocatorFunc f,
   28795 			    void *ctxt)
   28796 {
   28797     if (vctxt == NULL) return;
   28798     vctxt->locFunc = f;
   28799     vctxt->locCtxt = ctxt;
   28800 }
   28801 
   28802 /**
   28803  * xmlSchemaValidateStreamLocator:
   28804  * @ctx: the xmlTextReaderPtr used
   28805  * @file: returned file information
   28806  * @line: returned line information
   28807  *
   28808  * Internal locator function for the readers
   28809  *
   28810  * Returns 0 in case the Schema validation could be (des)activated and
   28811  *         -1 in case of error.
   28812  */
   28813 static int
   28814 xmlSchemaValidateStreamLocator(void *ctx, const char **file,
   28815                                unsigned long *line) {
   28816     xmlParserCtxtPtr ctxt;
   28817 
   28818     if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
   28819         return(-1);
   28820 
   28821     if (file != NULL)
   28822         *file = NULL;
   28823     if (line != NULL)
   28824         *line = 0;
   28825 
   28826     ctxt = (xmlParserCtxtPtr) ctx;
   28827     if (ctxt->input != NULL) {
   28828        if (file != NULL)
   28829            *file = ctxt->input->filename;
   28830        if (line != NULL)
   28831            *line = ctxt->input->line;
   28832        return(0);
   28833     }
   28834     return(-1);
   28835 }
   28836 
   28837 /**
   28838  * xmlSchemaValidateStream:
   28839  * @ctxt:  a schema validation context
   28840  * @input:  the input to use for reading the data
   28841  * @enc:  an optional encoding information
   28842  * @sax:  a SAX handler for the resulting events
   28843  * @user_data:  the context to provide to the SAX handler.
   28844  *
   28845  * Validate an input based on a flow of SAX event from the parser
   28846  * and forward the events to the @sax handler with the provided @user_data
   28847  * the user provided @sax handler must be a SAX2 one.
   28848  *
   28849  * Returns 0 if the document is schemas valid, a positive error code
   28850  *     number otherwise and -1 in case of internal or API error.
   28851  */
   28852 int
   28853 xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
   28854                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
   28855                         xmlSAXHandlerPtr sax, void *user_data)
   28856 {
   28857     xmlSchemaSAXPlugPtr plug = NULL;
   28858     xmlSAXHandlerPtr old_sax = NULL;
   28859     xmlParserCtxtPtr pctxt = NULL;
   28860     xmlParserInputPtr inputStream = NULL;
   28861     int ret;
   28862 
   28863     if ((ctxt == NULL) || (input == NULL))
   28864         return (-1);
   28865 
   28866     /*
   28867      * prepare the parser
   28868      */
   28869     pctxt = xmlNewParserCtxt();
   28870     if (pctxt == NULL)
   28871         return (-1);
   28872     old_sax = pctxt->sax;
   28873     pctxt->sax = sax;
   28874     pctxt->userData = user_data;
   28875 #if 0
   28876     if (options)
   28877         xmlCtxtUseOptions(pctxt, options);
   28878 #endif
   28879     pctxt->linenumbers = 1;
   28880     xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
   28881 
   28882     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
   28883     if (inputStream == NULL) {
   28884         ret = -1;
   28885 	goto done;
   28886     }
   28887     inputPush(pctxt, inputStream);
   28888     ctxt->parserCtxt = pctxt;
   28889     ctxt->input = input;
   28890 
   28891     /*
   28892      * Plug the validation and launch the parsing
   28893      */
   28894     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
   28895     if (plug == NULL) {
   28896         ret = -1;
   28897 	goto done;
   28898     }
   28899     ctxt->input = input;
   28900     ctxt->enc = enc;
   28901     ctxt->sax = pctxt->sax;
   28902     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
   28903     ret = xmlSchemaVStart(ctxt);
   28904 
   28905     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
   28906 	ret = ctxt->parserCtxt->errNo;
   28907 	if (ret == 0)
   28908 	    ret = 1;
   28909     }
   28910 
   28911 done:
   28912     ctxt->parserCtxt = NULL;
   28913     ctxt->sax = NULL;
   28914     ctxt->input = NULL;
   28915     if (plug != NULL) {
   28916         xmlSchemaSAXUnplug(plug);
   28917     }
   28918     /* cleanup */
   28919     if (pctxt != NULL) {
   28920 	pctxt->sax = old_sax;
   28921 	xmlFreeParserCtxt(pctxt);
   28922     }
   28923     return (ret);
   28924 }
   28925 
   28926 /**
   28927  * xmlSchemaValidateFile:
   28928  * @ctxt: a schema validation context
   28929  * @filename: the URI of the instance
   28930  * @options: a future set of options, currently unused
   28931  *
   28932  * Do a schemas validation of the given resource, it will use the
   28933  * SAX streamable validation internally.
   28934  *
   28935  * Returns 0 if the document is valid, a positive error code
   28936  *     number otherwise and -1 in case of an internal or API error.
   28937  */
   28938 int
   28939 xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
   28940                       const char * filename,
   28941 		      int options ATTRIBUTE_UNUSED)
   28942 {
   28943     int ret;
   28944     xmlParserInputBufferPtr input;
   28945 
   28946     if ((ctxt == NULL) || (filename == NULL))
   28947         return (-1);
   28948 
   28949     input = xmlParserInputBufferCreateFilename(filename,
   28950 	XML_CHAR_ENCODING_NONE);
   28951     if (input == NULL)
   28952 	return (-1);
   28953     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
   28954 	NULL, NULL);
   28955     return (ret);
   28956 }
   28957 
   28958 /**
   28959  * xmlSchemaValidCtxtGetParserCtxt:
   28960  * @ctxt: a schema validation context
   28961  *
   28962  * allow access to the parser context of the schema validation context
   28963  *
   28964  * Returns the parser context of the schema validation context or NULL
   28965  *         in case of error.
   28966  */
   28967 xmlParserCtxtPtr
   28968 xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
   28969 {
   28970     if (ctxt == NULL)
   28971         return(NULL);
   28972     return (ctxt->parserCtxt);
   28973 }
   28974 
   28975 #define bottom_xmlschemas
   28976 #include "elfgcchack.h"
   28977 #endif /* LIBXML_SCHEMAS_ENABLED */
   28978