File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / xmlschemas.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:37:58 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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@redhat.com>
    8:  */
    9: 
   10: /*
   11:  * TODO:
   12:  *   - when types are redefined in includes, check that all
   13:  *     types in the redef list are equal
   14:  *     -> need a type equality operation.
   15:  *   - if we don't intend to use the schema for schemas, we
   16:  *     need to validate all schema attributes (ref, type, name)
   17:  *     against their types.
   18:  *   - Eliminate item creation for: ??
   19:  *
   20:  * URGENT TODO:
   21:  *   - For xsi-driven schema acquisition, augment the IDCs after every
   22:  *     acquisition episode (xmlSchemaAugmentIDC).
   23:  *
   24:  * NOTES:
   25:  *   - Elimated item creation for: <restriction>, <extension>,
   26:  *     <simpleContent>, <complexContent>, <list>, <union>
   27:  *
   28:  * PROBLEMS:
   29:  *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
   30:  *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
   31:  *     XPath will have trouble to resolve to this namespace, since not known.
   32:  *
   33:  *
   34:  * CONSTRAINTS:
   35:  *
   36:  * Schema Component Constraint:
   37:  *   All Group Limited (cos-all-limited)
   38:  *   Status: complete
   39:  *   (1.2)
   40:  *     In xmlSchemaGroupDefReferenceTermFixup() and
   41:  *   (2)
   42:  *     In xmlSchemaParseModelGroup()
   43:  *     TODO: Actually this should go to component-level checks,
   44:  *     but is done here due to performance. Move it to an other layer
   45:  *     is schema construction via an API is implemented.
   46:  */
   47: #define IN_LIBXML
   48: #include "libxml.h"
   49: 
   50: #ifdef LIBXML_SCHEMAS_ENABLED
   51: 
   52: #include <string.h>
   53: #include <libxml/xmlmemory.h>
   54: #include <libxml/parser.h>
   55: #include <libxml/parserInternals.h>
   56: #include <libxml/hash.h>
   57: #include <libxml/uri.h>
   58: #include <libxml/xmlschemas.h>
   59: #include <libxml/schemasInternals.h>
   60: #include <libxml/xmlschemastypes.h>
   61: #include <libxml/xmlautomata.h>
   62: #include <libxml/xmlregexp.h>
   63: #include <libxml/dict.h>
   64: #include <libxml/encoding.h>
   65: #include <libxml/xmlIO.h>
   66: #ifdef LIBXML_PATTERN_ENABLED
   67: #include <libxml/pattern.h>
   68: #endif
   69: #ifdef LIBXML_READER_ENABLED
   70: #include <libxml/xmlreader.h>
   71: #endif
   72: 
   73: /* #define DEBUG 1 */
   74: 
   75: /* #define DEBUG_CONTENT 1 */
   76: 
   77: /* #define DEBUG_TYPE 1 */
   78: 
   79: /* #define DEBUG_CONTENT_REGEXP 1 */
   80: 
   81: /* #define DEBUG_AUTOMATA 1 */
   82: 
   83: /* #define DEBUG_IDC */
   84: 
   85: /* #define DEBUG_IDC_NODE_TABLE */
   86: 
   87: /* #define WXS_ELEM_DECL_CONS_ENABLED */
   88: 
   89: #ifdef DEBUG_IDC
   90:  #ifndef DEBUG_IDC_NODE_TABLE
   91:   #define DEBUG_IDC_NODE_TABLE
   92:  #endif
   93: #endif
   94: 
   95: /* #define ENABLE_PARTICLE_RESTRICTION 1 */
   96: 
   97: #define ENABLE_REDEFINE
   98: 
   99: /* #define ENABLE_NAMED_LOCALS */
  100: 
  101: /* #define ENABLE_IDC_NODE_TABLES_TEST */
  102: 
  103: #define DUMP_CONTENT_MODEL
  104: 
  105: #ifdef LIBXML_READER_ENABLED
  106: /* #define XML_SCHEMA_READER_ENABLED */
  107: #endif
  108: 
  109: #define UNBOUNDED (1 << 30)
  110: #define TODO 								\
  111:     xmlGenericError(xmlGenericErrorContext,				\
  112: 	    "Unimplemented block at %s:%d\n",				\
  113:             __FILE__, __LINE__);
  114: 
  115: #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  116: 
  117: /*
  118:  * The XML Schemas namespaces
  119:  */
  120: static const xmlChar *xmlSchemaNs = (const xmlChar *)
  121:     "http://www.w3.org/2001/XMLSchema";
  122: 
  123: static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  124:     "http://www.w3.org/2001/XMLSchema-instance";
  125: 
  126: static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  127:     "http://www.w3.org/2000/xmlns/";
  128: 
  129: /*
  130: * Come casting macros.
  131: */
  132: #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  133: #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  134: #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  135: #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  136: #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  137: #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  138: #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  139: #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  140: #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  141: #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  142: #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  143: #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  144: #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  145: #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  146: #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  147: #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  148: #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  149: 
  150: /*
  151: * Macros to query common properties of components.
  152: */
  153: #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  154: 
  155: #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  156: /*
  157: * Macros for element declarations.
  158: */
  159: #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  160: 
  161: #define WXS_SUBST_HEAD(item) (item)->refDecl
  162: /*
  163: * Macros for attribute declarations.
  164: */
  165: #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  166: /*
  167: * Macros for attribute uses.
  168: */
  169: #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
  170: 
  171: #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  172: 
  173: #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  174: 
  175: #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  176: /*
  177: * Macros for attribute groups.
  178: */
  179: #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  180: #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  181: /*
  182: * Macros for particles.
  183: */
  184: #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  185: 
  186: #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  187: 
  188: #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  189: 
  190: #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  191: /*
  192: * Macros for model groups definitions.
  193: */
  194: #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  195: /*
  196: * Macros for model groups.
  197: */
  198: #define WXS_IS_MODEL_GROUP(i) \
  199:     (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  200:      ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  201:      ((i)->type == XML_SCHEMA_TYPE_ALL))
  202: 
  203: #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  204: /*
  205: * Macros for schema buckets.
  206: */
  207: #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  208:     ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  209: 
  210: #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  211:     ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  212: 
  213: #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  214: 
  215: #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  216: /*
  217: * Macros for complex/simple types.
  218: */
  219: #define WXS_IS_ANYTYPE(i) \
  220:      (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  221:       ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  222: 
  223: #define WXS_IS_COMPLEX(i) \
  224:     (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  225:      ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  226: 
  227: #define WXS_IS_SIMPLE(item) \
  228:     ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  229:      ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  230:       (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  231: 
  232: #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  233:     (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  234:       ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  235: 
  236: #define WXS_IS_RESTRICTION(t) \
  237:     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  238: 
  239: #define WXS_IS_EXTENSION(t) \
  240:     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  241: 
  242: #define WXS_IS_TYPE_NOT_FIXED(i) \
  243:     (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  244:      (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  245: 
  246: #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  247:     (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  248:      (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  249: 
  250: #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  251: 
  252: #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  253: /*
  254: * Macros for exclusively for complex types.
  255: */
  256: #define WXS_HAS_COMPLEX_CONTENT(item) \
  257:     ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  258:      (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  259:      (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  260: 
  261: #define WXS_HAS_SIMPLE_CONTENT(item) \
  262:     ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  263:      (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  264: 
  265: #define WXS_HAS_MIXED_CONTENT(item) \
  266:     (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  267: 
  268: #define WXS_EMPTIABLE(t) \
  269:     (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  270: 
  271: #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  272: 
  273: #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  274: 
  275: #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  276: /*
  277: * Macros for exclusively for simple types.
  278: */
  279: #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  280: 
  281: #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  282: 
  283: #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  284: 
  285: #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  286: /*
  287: * Misc parser context macros.
  288: */
  289: #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  290: 
  291: #define WXS_HAS_BUCKETS(ctx) \
  292: ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  293: (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  294: 
  295: #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  296: 
  297: #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  298: 
  299: #define WXS_SCHEMA(ctx) (ctx)->schema
  300: 
  301: #define WXS_ADD_LOCAL(ctx, item) \
  302:     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
  303: 
  304: #define WXS_ADD_GLOBAL(ctx, item) \
  305:     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
  306: 
  307: #define WXS_ADD_PENDING(ctx, item) \
  308:     xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  309: /*
  310: * xmlSchemaItemList macros.
  311: */
  312: #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  313: /*
  314: * Misc macros.
  315: */
  316: #define IS_SCHEMA(node, type) \
  317:    ((node != NULL) && (node->ns != NULL) && \
  318:     (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  319:     (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  320: 
  321: #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  322: 
  323: /*
  324: * Since we put the default/fixed values into the dict, we can
  325: * use pointer comparison for those values.
  326: * REMOVED: (xmlStrEqual((v1), (v2)))
  327: */
  328: #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  329: 
  330: #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  331: 
  332: #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  333: 
  334: #define HFAILURE if (res == -1) goto exit_failure;
  335: 
  336: #define HERROR if (res != 0) goto exit_error;
  337: 
  338: #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  339: /*
  340: * Some flags used for various schema constraints.
  341: */
  342: #define SUBSET_RESTRICTION  1<<0
  343: #define SUBSET_EXTENSION    1<<1
  344: #define SUBSET_SUBSTITUTION 1<<2
  345: #define SUBSET_LIST         1<<3
  346: #define SUBSET_UNION        1<<4
  347: 
  348: typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  349: typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  350: 
  351: typedef struct _xmlSchemaItemList xmlSchemaItemList;
  352: typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  353: struct _xmlSchemaItemList {
  354:     void **items;  /* used for dynamic addition of schemata */
  355:     int nbItems; /* used for dynamic addition of schemata */
  356:     int sizeItems; /* used for dynamic addition of schemata */
  357: };
  358: 
  359: #define XML_SCHEMA_CTXT_PARSER 1
  360: #define XML_SCHEMA_CTXT_VALIDATOR 2
  361: 
  362: typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  363: typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  364: struct _xmlSchemaAbstractCtxt {
  365:     int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  366: };
  367: 
  368: typedef struct _xmlSchemaBucket xmlSchemaBucket;
  369: typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  370: 
  371: #define XML_SCHEMA_SCHEMA_MAIN 0
  372: #define XML_SCHEMA_SCHEMA_IMPORT 1
  373: #define XML_SCHEMA_SCHEMA_INCLUDE 2
  374: #define XML_SCHEMA_SCHEMA_REDEFINE 3
  375: 
  376: /**
  377:  * xmlSchemaSchemaRelation:
  378:  *
  379:  * Used to create a graph of schema relationships.
  380:  */
  381: typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  382: typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  383: struct _xmlSchemaSchemaRelation {
  384:     xmlSchemaSchemaRelationPtr next;
  385:     int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  386:     const xmlChar *importNamespace;
  387:     xmlSchemaBucketPtr bucket;
  388: };
  389: 
  390: #define XML_SCHEMA_BUCKET_MARKED 1<<0
  391: #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  392: 
  393: struct _xmlSchemaBucket {
  394:     int type;
  395:     int flags;
  396:     const xmlChar *schemaLocation;
  397:     const xmlChar *origTargetNamespace;
  398:     const xmlChar *targetNamespace;
  399:     xmlDocPtr doc;
  400:     xmlSchemaSchemaRelationPtr relations;
  401:     int located;
  402:     int parsed;
  403:     int imported;
  404:     int preserveDoc;
  405:     xmlSchemaItemListPtr globals; /* Global components. */
  406:     xmlSchemaItemListPtr locals; /* Local components. */
  407: };
  408: 
  409: /**
  410:  * xmlSchemaImport:
  411:  * (extends xmlSchemaBucket)
  412:  *
  413:  * Reflects a schema. Holds some information
  414:  * about the schema and its toplevel components. Duplicate
  415:  * toplevel components are not checked at this level.
  416:  */
  417: typedef struct _xmlSchemaImport xmlSchemaImport;
  418: typedef xmlSchemaImport *xmlSchemaImportPtr;
  419: struct _xmlSchemaImport {
  420:     int type; /* Main OR import OR include. */
  421:     int flags;
  422:     const xmlChar *schemaLocation; /* The URI of the schema document. */
  423:     /* For chameleon includes, @origTargetNamespace will be NULL */
  424:     const xmlChar *origTargetNamespace;
  425:     /*
  426:     * For chameleon includes, @targetNamespace will be the
  427:     * targetNamespace of the including schema.
  428:     */
  429:     const xmlChar *targetNamespace;
  430:     xmlDocPtr doc; /* The schema node-tree. */
  431:     /* @relations will hold any included/imported/redefined schemas. */
  432:     xmlSchemaSchemaRelationPtr relations;
  433:     int located;
  434:     int parsed;
  435:     int imported;
  436:     int preserveDoc;
  437:     xmlSchemaItemListPtr globals;
  438:     xmlSchemaItemListPtr locals;
  439:     /* The imported schema. */
  440:     xmlSchemaPtr schema;
  441: };
  442: 
  443: /*
  444: * (extends xmlSchemaBucket)
  445: */
  446: typedef struct _xmlSchemaInclude xmlSchemaInclude;
  447: typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  448: struct _xmlSchemaInclude {
  449:     int type;
  450:     int flags;
  451:     const xmlChar *schemaLocation;
  452:     const xmlChar *origTargetNamespace;
  453:     const xmlChar *targetNamespace;
  454:     xmlDocPtr doc;
  455:     xmlSchemaSchemaRelationPtr relations;
  456:     int located;
  457:     int parsed;
  458:     int imported;
  459:     int preserveDoc;
  460:     xmlSchemaItemListPtr globals; /* Global components. */
  461:     xmlSchemaItemListPtr locals; /* Local components. */
  462: 
  463:     /* The owning main or import schema bucket. */
  464:     xmlSchemaImportPtr ownerImport;
  465: };
  466: 
  467: /**
  468:  * xmlSchemaBasicItem:
  469:  *
  470:  * The abstract base type for schema components.
  471:  */
  472: typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  473: typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  474: struct _xmlSchemaBasicItem {
  475:     xmlSchemaTypeType type;
  476: };
  477: 
  478: /**
  479:  * xmlSchemaAnnotItem:
  480:  *
  481:  * The abstract base type for annotated schema components.
  482:  * (Extends xmlSchemaBasicItem)
  483:  */
  484: typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  485: typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  486: struct _xmlSchemaAnnotItem {
  487:     xmlSchemaTypeType type;
  488:     xmlSchemaAnnotPtr annot;
  489: };
  490: 
  491: /**
  492:  * xmlSchemaTreeItem:
  493:  *
  494:  * The abstract base type for tree-like structured schema components.
  495:  * (Extends xmlSchemaAnnotItem)
  496:  */
  497: typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  498: typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  499: struct _xmlSchemaTreeItem {
  500:     xmlSchemaTypeType type;
  501:     xmlSchemaAnnotPtr annot;
  502:     xmlSchemaTreeItemPtr next;
  503:     xmlSchemaTreeItemPtr children;
  504: };
  505: 
  506: 
  507: #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  508: /**
  509:  * xmlSchemaAttributeUsePtr:
  510:  *
  511:  * The abstract base type for tree-like structured schema components.
  512:  * (Extends xmlSchemaTreeItem)
  513:  */
  514: typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  515: typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  516: struct _xmlSchemaAttributeUse {
  517:     xmlSchemaTypeType type;
  518:     xmlSchemaAnnotPtr annot;
  519:     xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  520:     /*
  521:     * The attr. decl. OR a QName-ref. to an attr. decl. OR
  522:     * a QName-ref. to an attribute group definition.
  523:     */
  524:     xmlSchemaAttributePtr attrDecl;
  525: 
  526:     int flags;
  527:     xmlNodePtr node;
  528:     int occurs; /* required, optional */
  529:     const xmlChar * defValue;
  530:     xmlSchemaValPtr defVal;
  531: };
  532: 
  533: /**
  534:  * xmlSchemaAttributeUseProhibPtr:
  535:  *
  536:  * A helper component to reflect attribute prohibitions.
  537:  * (Extends xmlSchemaBasicItem)
  538:  */
  539: typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  540: typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  541: struct _xmlSchemaAttributeUseProhib {
  542:     xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  543:     xmlNodePtr node;
  544:     const xmlChar *name;
  545:     const xmlChar *targetNamespace;
  546:     int isRef;
  547: };
  548: 
  549: /**
  550:  * xmlSchemaRedef:
  551:  */
  552: typedef struct _xmlSchemaRedef xmlSchemaRedef;
  553: typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  554: struct _xmlSchemaRedef {
  555:     xmlSchemaRedefPtr next;
  556:     xmlSchemaBasicItemPtr item; /* The redefining component. */
  557:     xmlSchemaBasicItemPtr reference; /* The referencing component. */
  558:     xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  559:     const xmlChar *refName; /* The name of the to-be-redefined component. */
  560:     const xmlChar *refTargetNs; /* The target namespace of the
  561:                                    to-be-redefined comp. */
  562:     xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  563: };
  564: 
  565: /**
  566:  * xmlSchemaConstructionCtxt:
  567:  */
  568: typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  569: typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  570: struct _xmlSchemaConstructionCtxt {
  571:     xmlSchemaPtr mainSchema; /* The main schema. */
  572:     xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  573:     xmlDictPtr dict;
  574:     xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  575:     /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  576:     xmlSchemaBucketPtr bucket; /* The current schema bucket */
  577:     xmlSchemaItemListPtr pending; /* All Components of all schemas that
  578:                                      need to be fixed. */
  579:     xmlHashTablePtr substGroups;
  580:     xmlSchemaRedefPtr redefs;
  581:     xmlSchemaRedefPtr lastRedef;
  582: };
  583: 
  584: #define XML_SCHEMAS_PARSE_ERROR		1
  585: #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  586: 
  587: struct _xmlSchemaParserCtxt {
  588:     int type;
  589:     void *errCtxt;             /* user specific error context */
  590:     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
  591:     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
  592:     int err;
  593:     int nberrors;
  594:     xmlStructuredErrorFunc serror;
  595: 
  596:     xmlSchemaConstructionCtxtPtr constructor;
  597:     int ownsConstructor; /* TODO: Move this to parser *flags*. */
  598: 
  599:     /* xmlSchemaPtr topschema;	*/
  600:     /* xmlHashTablePtr namespaces;  */
  601: 
  602:     xmlSchemaPtr schema;        /* The main schema in use */
  603:     int counter;
  604: 
  605:     const xmlChar *URL;
  606:     xmlDocPtr doc;
  607:     int preserve;		/* Whether the doc should be freed  */
  608: 
  609:     const char *buffer;
  610:     int size;
  611: 
  612:     /*
  613:      * Used to build complex element content models
  614:      */
  615:     xmlAutomataPtr am;
  616:     xmlAutomataStatePtr start;
  617:     xmlAutomataStatePtr end;
  618:     xmlAutomataStatePtr state;
  619: 
  620:     xmlDictPtr dict;		/* dictionnary for interned string names */
  621:     xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  622:     int options;
  623:     xmlSchemaValidCtxtPtr vctxt;
  624:     int isS4S;
  625:     int isRedefine;
  626:     int xsiAssemble;
  627:     int stop; /* If the parser should stop; i.e. a critical error. */
  628:     const xmlChar *targetNamespace;
  629:     xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  630: 
  631:     xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  632:     int redefCounter; /* Used for redefinitions. */
  633:     xmlSchemaItemListPtr attrProhibs;
  634: };
  635: 
  636: /**
  637:  * xmlSchemaQNameRef:
  638:  *
  639:  * A component reference item (not a schema component)
  640:  * (Extends xmlSchemaBasicItem)
  641:  */
  642: typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  643: typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  644: struct _xmlSchemaQNameRef {
  645:     xmlSchemaTypeType type;
  646:     xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  647:     xmlSchemaTypeType itemType;
  648:     const xmlChar *name;
  649:     const xmlChar *targetNamespace;
  650:     xmlNodePtr node;
  651: };
  652: 
  653: /**
  654:  * xmlSchemaParticle:
  655:  *
  656:  * A particle component.
  657:  * (Extends xmlSchemaTreeItem)
  658:  */
  659: typedef struct _xmlSchemaParticle xmlSchemaParticle;
  660: typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  661: struct _xmlSchemaParticle {
  662:     xmlSchemaTypeType type;
  663:     xmlSchemaAnnotPtr annot;
  664:     xmlSchemaTreeItemPtr next; /* next particle */
  665:     xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  666: 	a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  667:         etc.) */
  668:     int minOccurs;
  669:     int maxOccurs;
  670:     xmlNodePtr node;
  671: };
  672: 
  673: /**
  674:  * xmlSchemaModelGroup:
  675:  *
  676:  * A model group component.
  677:  * (Extends xmlSchemaTreeItem)
  678:  */
  679: typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  680: typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  681: struct _xmlSchemaModelGroup {
  682:     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  683:     xmlSchemaAnnotPtr annot;
  684:     xmlSchemaTreeItemPtr next; /* not used */
  685:     xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  686:     xmlNodePtr node;
  687: };
  688: 
  689: #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  690: #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  691: /**
  692:  * xmlSchemaModelGroupDef:
  693:  *
  694:  * A model group definition component.
  695:  * (Extends xmlSchemaTreeItem)
  696:  */
  697: typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  698: typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  699: struct _xmlSchemaModelGroupDef {
  700:     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  701:     xmlSchemaAnnotPtr annot;
  702:     xmlSchemaTreeItemPtr next; /* not used */
  703:     xmlSchemaTreeItemPtr children; /* the "model group" */
  704:     const xmlChar *name;
  705:     const xmlChar *targetNamespace;
  706:     xmlNodePtr node;
  707:     int flags;
  708: };
  709: 
  710: typedef struct _xmlSchemaIDC xmlSchemaIDC;
  711: typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  712: 
  713: /**
  714:  * xmlSchemaIDCSelect:
  715:  *
  716:  * The identity-constraint "field" and "selector" item, holding the
  717:  * XPath expression.
  718:  */
  719: typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  720: typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  721: struct _xmlSchemaIDCSelect {
  722:     xmlSchemaIDCSelectPtr next;
  723:     xmlSchemaIDCPtr idc;
  724:     int index; /* an index position if significant for IDC key-sequences */
  725:     const xmlChar *xpath; /* the XPath expression */
  726:     void *xpathComp; /* the compiled XPath expression */
  727: };
  728: 
  729: /**
  730:  * xmlSchemaIDC:
  731:  *
  732:  * The identity-constraint definition component.
  733:  * (Extends xmlSchemaAnnotItem)
  734:  */
  735: 
  736: struct _xmlSchemaIDC {
  737:     xmlSchemaTypeType type;
  738:     xmlSchemaAnnotPtr annot;
  739:     xmlSchemaIDCPtr next;
  740:     xmlNodePtr node;
  741:     const xmlChar *name;
  742:     const xmlChar *targetNamespace;
  743:     xmlSchemaIDCSelectPtr selector;
  744:     xmlSchemaIDCSelectPtr fields;
  745:     int nbFields;
  746:     xmlSchemaQNameRefPtr ref;
  747: };
  748: 
  749: /**
  750:  * xmlSchemaIDCAug:
  751:  *
  752:  * The augmented IDC information used for validation.
  753:  */
  754: typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  755: typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  756: struct _xmlSchemaIDCAug {
  757:     xmlSchemaIDCAugPtr next; /* next in a list */
  758:     xmlSchemaIDCPtr def; /* the IDC definition */
  759:     int keyrefDepth; /* the lowest tree level to which IDC
  760:                         tables need to be bubbled upwards */
  761: };
  762: 
  763: /**
  764:  * xmlSchemaPSVIIDCKeySequence:
  765:  *
  766:  * The key sequence of a node table item.
  767:  */
  768: typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  769: typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  770: struct _xmlSchemaPSVIIDCKey {
  771:     xmlSchemaTypePtr type;
  772:     xmlSchemaValPtr val;
  773: };
  774: 
  775: /**
  776:  * xmlSchemaPSVIIDCNode:
  777:  *
  778:  * The node table item of a node table.
  779:  */
  780: typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  781: typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  782: struct _xmlSchemaPSVIIDCNode {
  783:     xmlNodePtr node;
  784:     xmlSchemaPSVIIDCKeyPtr *keys;
  785:     int nodeLine;
  786:     int nodeQNameID;
  787: 
  788: };
  789: 
  790: /**
  791:  * xmlSchemaPSVIIDCBinding:
  792:  *
  793:  * The identity-constraint binding item of the [identity-constraint table].
  794:  */
  795: typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  796: typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  797: struct _xmlSchemaPSVIIDCBinding {
  798:     xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  799:     xmlSchemaIDCPtr definition; /* the IDC definition */
  800:     xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  801:     int nbNodes; /* number of entries in the node table */
  802:     int sizeNodes; /* size of the node table */
  803:     xmlSchemaItemListPtr dupls;
  804: };
  805: 
  806: 
  807: #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  808: #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  809: 
  810: #define XPATH_STATE_OBJ_MATCHES -2
  811: #define XPATH_STATE_OBJ_BLOCKED -3
  812: 
  813: typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  814: typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  815: 
  816: /**
  817:  * xmlSchemaIDCStateObj:
  818:  *
  819:  * The state object used to evaluate XPath expressions.
  820:  */
  821: typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  822: typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  823: struct _xmlSchemaIDCStateObj {
  824:     int type;
  825:     xmlSchemaIDCStateObjPtr next; /* next if in a list */
  826:     int depth; /* depth of creation */
  827:     int *history; /* list of (depth, state-id) tuples */
  828:     int nbHistory;
  829:     int sizeHistory;
  830:     xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  831:                                        matcher */
  832:     xmlSchemaIDCSelectPtr sel;
  833:     void *xpathCtxt;
  834: };
  835: 
  836: #define IDC_MATCHER 0
  837: 
  838: /**
  839:  * xmlSchemaIDCMatcher:
  840:  *
  841:  * Used to evaluate IDC selectors (and fields).
  842:  */
  843: struct _xmlSchemaIDCMatcher {
  844:     int type;
  845:     int depth; /* the tree depth at creation time */
  846:     xmlSchemaIDCMatcherPtr next; /* next in the list */
  847:     xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  848:     xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  849:     int idcType;
  850:     xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  851:                                          elements */
  852:     int sizeKeySeqs;
  853:     xmlSchemaItemListPtr targets; /* list of target-node
  854:                                      (xmlSchemaPSVIIDCNodePtr) entries */
  855: };
  856: 
  857: /*
  858: * Element info flags.
  859: */
  860: #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
  861: #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  862: #define XML_SCHEMA_ELEM_INFO_NILLED	       1<<2
  863: #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE	       1<<3
  864: 
  865: #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
  866: #define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
  867: #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
  868: 
  869: #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
  870: #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
  871: #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
  872: #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
  873: 
  874: /**
  875:  * xmlSchemaNodeInfo:
  876:  *
  877:  * Holds information of an element node.
  878:  */
  879: struct _xmlSchemaNodeInfo {
  880:     int nodeType;
  881:     xmlNodePtr node;
  882:     int nodeLine;
  883:     const xmlChar *localName;
  884:     const xmlChar *nsName;
  885:     const xmlChar *value;
  886:     xmlSchemaValPtr val; /* the pre-computed value if any */
  887:     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  888: 
  889:     int flags; /* combination of node info flags */
  890: 
  891:     int valNeeded;
  892:     int normVal;
  893: 
  894:     xmlSchemaElementPtr decl; /* the element/attribute declaration */
  895:     int depth;
  896:     xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  897:                                             for the scope element*/
  898:     xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  899:                                            element */
  900:     xmlRegExecCtxtPtr regexCtxt;
  901: 
  902:     const xmlChar **nsBindings; /* Namespace bindings on this element */
  903:     int nbNsBindings;
  904:     int sizeNsBindings;
  905: 
  906:     int hasKeyrefs;
  907:     int appliedXPath; /* Indicates that an XPath has been applied. */
  908: };
  909: 
  910: #define XML_SCHEMAS_ATTR_UNKNOWN 1
  911: #define XML_SCHEMAS_ATTR_ASSESSED 2
  912: #define XML_SCHEMAS_ATTR_PROHIBITED 3
  913: #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  914: #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  915: #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  916: #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  917: #define XML_SCHEMAS_ATTR_DEFAULT 8
  918: #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  919: #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  920: #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  921: #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  922: #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  923: #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  924: #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  925: #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  926: #define XML_SCHEMAS_ATTR_META 17
  927: /*
  928: * @metaType values of xmlSchemaAttrInfo.
  929: */
  930: #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  931: #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  932: #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  933: #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  934: #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  935: 
  936: typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  937: typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  938: struct _xmlSchemaAttrInfo {
  939:     int nodeType;
  940:     xmlNodePtr node;
  941:     int nodeLine;
  942:     const xmlChar *localName;
  943:     const xmlChar *nsName;
  944:     const xmlChar *value;
  945:     xmlSchemaValPtr val; /* the pre-computed value if any */
  946:     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  947:     int flags; /* combination of node info flags */
  948: 
  949:     xmlSchemaAttributePtr decl; /* the attribute declaration */
  950:     xmlSchemaAttributeUsePtr use;  /* the attribute use */
  951:     int state;
  952:     int metaType;
  953:     const xmlChar *vcValue; /* the value constraint value */
  954:     xmlSchemaNodeInfoPtr parent;
  955: };
  956: 
  957: 
  958: #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  959: /**
  960:  * xmlSchemaValidCtxt:
  961:  *
  962:  * A Schemas validation context
  963:  */
  964: struct _xmlSchemaValidCtxt {
  965:     int type;
  966:     void *errCtxt;             /* user specific data block */
  967:     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
  968:     xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  969:     xmlStructuredErrorFunc serror;
  970: 
  971:     xmlSchemaPtr schema;        /* The schema in use */
  972:     xmlDocPtr doc;
  973:     xmlParserInputBufferPtr input;
  974:     xmlCharEncoding enc;
  975:     xmlSAXHandlerPtr sax;
  976:     xmlParserCtxtPtr parserCtxt;
  977:     void *user_data; /* TODO: What is this for? */
  978: 
  979:     int err;
  980:     int nberrors;
  981: 
  982:     xmlNodePtr node;
  983:     xmlNodePtr cur;
  984:     /* xmlSchemaTypePtr type; */
  985: 
  986:     xmlRegExecCtxtPtr regexp;
  987:     xmlSchemaValPtr value;
  988: 
  989:     int valueWS;
  990:     int options;
  991:     xmlNodePtr validationRoot;
  992:     xmlSchemaParserCtxtPtr pctxt;
  993:     int xsiAssemble;
  994: 
  995:     int depth;
  996:     xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
  997:     int sizeElemInfos;
  998:     xmlSchemaNodeInfoPtr inode; /* the current element information */
  999: 
 1000:     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
 1001: 
 1002:     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
 1003:     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
 1004:     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
 1005: 
 1006:     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
 1007:     int nbIdcNodes;
 1008:     int sizeIdcNodes;
 1009: 
 1010:     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
 1011:     int nbIdcKeys;
 1012:     int sizeIdcKeys;
 1013: 
 1014:     int flags;
 1015: 
 1016:     xmlDictPtr dict;
 1017: 
 1018: #ifdef LIBXML_READER_ENABLED
 1019:     xmlTextReaderPtr reader;
 1020: #endif
 1021: 
 1022:     xmlSchemaAttrInfoPtr *attrInfos;
 1023:     int nbAttrInfos;
 1024:     int sizeAttrInfos;
 1025: 
 1026:     int skipDepth;
 1027:     xmlSchemaItemListPtr nodeQNames;
 1028:     int hasKeyrefs;
 1029:     int createIDCNodeTables;
 1030:     int psviExposeIDCNodeTables;
 1031: };
 1032: 
 1033: /**
 1034:  * xmlSchemaSubstGroup:
 1035:  *
 1036:  *
 1037:  */
 1038: typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
 1039: typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
 1040: struct _xmlSchemaSubstGroup {
 1041:     xmlSchemaElementPtr head;
 1042:     xmlSchemaItemListPtr members;
 1043: };
 1044: 
 1045: /************************************************************************
 1046:  * 									*
 1047:  * 			Some predeclarations				*
 1048:  * 									*
 1049:  ************************************************************************/
 1050: 
 1051: static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
 1052:                                  xmlSchemaPtr schema,
 1053:                                  xmlNodePtr node);
 1054: static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
 1055:                                  xmlSchemaPtr schema,
 1056:                                  xmlNodePtr node);
 1057: static int
 1058: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
 1059:                    xmlSchemaAbstractCtxtPtr ctxt);
 1060: static const xmlChar *
 1061: xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
 1062: static int
 1063: xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 1064:                      xmlNodePtr node);
 1065: static int
 1066: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
 1067:                        xmlSchemaParserCtxtPtr ctxt);
 1068: static void
 1069: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
 1070: static xmlSchemaWhitespaceValueType
 1071: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
 1072: static xmlSchemaTreeItemPtr
 1073: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 1074: 			 xmlNodePtr node, xmlSchemaTypeType type,
 1075: 			 int withParticle);
 1076: static const xmlChar *
 1077: xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
 1078: static xmlSchemaTypeLinkPtr
 1079: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
 1080: static void
 1081: xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 1082: 		     const char *funcName,
 1083: 		     const char *message);
 1084: static int
 1085: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
 1086: 			     xmlSchemaTypePtr type,
 1087: 			     xmlSchemaTypePtr baseType,
 1088: 			     int subset);
 1089: static void
 1090: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
 1091: 				   xmlSchemaParserCtxtPtr ctxt);
 1092: static void
 1093: xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
 1094: static xmlSchemaQNameRefPtr
 1095: xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 1096: 				xmlSchemaPtr schema,
 1097: 				xmlNodePtr node);
 1098: 
 1099: /************************************************************************
 1100:  *									*
 1101:  * 			Helper functions			        *
 1102:  *									*
 1103:  ************************************************************************/
 1104: 
 1105: /**
 1106:  * xmlSchemaItemTypeToStr:
 1107:  * @type: the type of the schema item
 1108:  *
 1109:  * Returns the component name of a schema item.
 1110:  */
 1111: static const xmlChar *
 1112: xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
 1113: {
 1114:     switch (type) {
 1115: 	case XML_SCHEMA_TYPE_BASIC:
 1116: 	    return(BAD_CAST "simple type definition");
 1117: 	case XML_SCHEMA_TYPE_SIMPLE:
 1118: 	    return(BAD_CAST "simple type definition");
 1119: 	case XML_SCHEMA_TYPE_COMPLEX:
 1120: 	    return(BAD_CAST "complex type definition");
 1121: 	case XML_SCHEMA_TYPE_ELEMENT:
 1122: 	    return(BAD_CAST "element declaration");
 1123: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1124: 	    return(BAD_CAST "attribute use");
 1125: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1126: 	    return(BAD_CAST "attribute declaration");
 1127: 	case XML_SCHEMA_TYPE_GROUP:
 1128: 	    return(BAD_CAST "model group definition");
 1129: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1130: 	    return(BAD_CAST "attribute group definition");
 1131: 	case XML_SCHEMA_TYPE_NOTATION:
 1132: 	    return(BAD_CAST "notation declaration");
 1133: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1134: 	    return(BAD_CAST "model group (sequence)");
 1135: 	case XML_SCHEMA_TYPE_CHOICE:
 1136: 	    return(BAD_CAST "model group (choice)");
 1137: 	case XML_SCHEMA_TYPE_ALL:
 1138: 	    return(BAD_CAST "model group (all)");
 1139: 	case XML_SCHEMA_TYPE_PARTICLE:
 1140: 	    return(BAD_CAST "particle");
 1141: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1142: 	    return(BAD_CAST "unique identity-constraint");
 1143: 	    /* return(BAD_CAST "IDC (unique)"); */
 1144: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1145: 	    return(BAD_CAST "key identity-constraint");
 1146: 	    /* return(BAD_CAST "IDC (key)"); */
 1147: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1148: 	    return(BAD_CAST "keyref identity-constraint");
 1149: 	    /* return(BAD_CAST "IDC (keyref)"); */
 1150: 	case XML_SCHEMA_TYPE_ANY:
 1151: 	    return(BAD_CAST "wildcard (any)");
 1152: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1153: 	    return(BAD_CAST "[helper component] QName reference");
 1154: 	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 1155: 	    return(BAD_CAST "[helper component] attribute use prohibition");
 1156: 	default:
 1157: 	    return(BAD_CAST "Not a schema component");
 1158:     }
 1159: }
 1160: 
 1161: /**
 1162:  * xmlSchemaGetComponentTypeStr:
 1163:  * @type: the type of the schema item
 1164:  *
 1165:  * Returns the component name of a schema item.
 1166:  */
 1167: static const xmlChar *
 1168: xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
 1169: {
 1170:     switch (item->type) {
 1171: 	case XML_SCHEMA_TYPE_BASIC:
 1172: 	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
 1173: 		return(BAD_CAST "complex type definition");
 1174: 	    else
 1175: 		return(BAD_CAST "simple type definition");
 1176: 	default:
 1177: 	    return(xmlSchemaItemTypeToStr(item->type));
 1178:     }
 1179: }
 1180: 
 1181: /**
 1182:  * xmlSchemaGetComponentNode:
 1183:  * @item: a schema component
 1184:  *
 1185:  * Returns node associated with the schema component.
 1186:  * NOTE that such a node need not be available; plus, a component's
 1187:  * node need not to reflect the component directly, since there is no
 1188:  * one-to-one relationship between the XML Schema representation and
 1189:  * the component representation.
 1190:  */
 1191: static xmlNodePtr
 1192: xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
 1193: {
 1194:     switch (item->type) {
 1195: 	case XML_SCHEMA_TYPE_ELEMENT:
 1196: 	    return (((xmlSchemaElementPtr) item)->node);
 1197: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1198: 	    return (((xmlSchemaAttributePtr) item)->node);
 1199: 	case XML_SCHEMA_TYPE_COMPLEX:
 1200: 	case XML_SCHEMA_TYPE_SIMPLE:
 1201: 	    return (((xmlSchemaTypePtr) item)->node);
 1202: 	case XML_SCHEMA_TYPE_ANY:
 1203: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1204: 	    return (((xmlSchemaWildcardPtr) item)->node);
 1205: 	case XML_SCHEMA_TYPE_PARTICLE:
 1206: 	    return (((xmlSchemaParticlePtr) item)->node);
 1207: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1208: 	case XML_SCHEMA_TYPE_CHOICE:
 1209: 	case XML_SCHEMA_TYPE_ALL:
 1210: 	    return (((xmlSchemaModelGroupPtr) item)->node);
 1211: 	case XML_SCHEMA_TYPE_GROUP:
 1212: 	    return (((xmlSchemaModelGroupDefPtr) item)->node);
 1213: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1214: 	    return (((xmlSchemaAttributeGroupPtr) item)->node);
 1215: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1216: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1217: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1218: 	    return (((xmlSchemaIDCPtr) item)->node);
 1219: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1220: 	    return(((xmlSchemaQNameRefPtr) item)->node);
 1221: 	/* TODO: What to do with NOTATIONs?
 1222: 	case XML_SCHEMA_TYPE_NOTATION:
 1223: 	    return (((xmlSchemaNotationPtr) item)->node);
 1224: 	*/
 1225: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1226: 	    return (((xmlSchemaAttributeUsePtr) item)->node);
 1227: 	default:
 1228: 	    return (NULL);
 1229:     }
 1230: }
 1231: 
 1232: #if 0
 1233: /**
 1234:  * xmlSchemaGetNextComponent:
 1235:  * @item: a schema component
 1236:  *
 1237:  * Returns the next sibling of the schema component.
 1238:  */
 1239: static xmlSchemaBasicItemPtr
 1240: xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
 1241: {
 1242:     switch (item->type) {
 1243: 	case XML_SCHEMA_TYPE_ELEMENT:
 1244: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
 1245: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1246: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
 1247: 	case XML_SCHEMA_TYPE_COMPLEX:
 1248: 	case XML_SCHEMA_TYPE_SIMPLE:
 1249: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
 1250: 	case XML_SCHEMA_TYPE_ANY:
 1251: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1252: 	    return (NULL);
 1253: 	case XML_SCHEMA_TYPE_PARTICLE:
 1254: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
 1255: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1256: 	case XML_SCHEMA_TYPE_CHOICE:
 1257: 	case XML_SCHEMA_TYPE_ALL:
 1258: 	    return (NULL);
 1259: 	case XML_SCHEMA_TYPE_GROUP:
 1260: 	    return (NULL);
 1261: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1262: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
 1263: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1264: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1265: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1266: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
 1267: 	default:
 1268: 	    return (NULL);
 1269:     }
 1270: }
 1271: #endif
 1272: 
 1273: 
 1274: /**
 1275:  * xmlSchemaFormatQName:
 1276:  * @buf: the string buffer
 1277:  * @namespaceName:  the namespace name
 1278:  * @localName: the local name
 1279:  *
 1280:  * Returns the given QName in the format "{namespaceName}localName" or
 1281:  * just "localName" if @namespaceName is NULL.
 1282:  *
 1283:  * Returns the localName if @namespaceName is NULL, a formatted
 1284:  * string otherwise.
 1285:  */
 1286: static const xmlChar*
 1287: xmlSchemaFormatQName(xmlChar **buf,
 1288: 		     const xmlChar *namespaceName,
 1289: 		     const xmlChar *localName)
 1290: {
 1291:     FREE_AND_NULL(*buf)
 1292:     if (namespaceName != NULL) {
 1293: 	*buf = xmlStrdup(BAD_CAST "{");
 1294: 	*buf = xmlStrcat(*buf, namespaceName);
 1295: 	*buf = xmlStrcat(*buf, BAD_CAST "}");
 1296:     }
 1297:     if (localName != NULL) {
 1298: 	if (namespaceName == NULL)
 1299: 	    return(localName);
 1300: 	*buf = xmlStrcat(*buf, localName);
 1301:     } else {
 1302: 	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
 1303:     }
 1304:     return ((const xmlChar *) *buf);
 1305: }
 1306: 
 1307: static const xmlChar*
 1308: xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
 1309: {
 1310:     if (ns != NULL)
 1311: 	return (xmlSchemaFormatQName(buf, ns->href, localName));
 1312:     else
 1313: 	return (xmlSchemaFormatQName(buf, NULL, localName));
 1314: }
 1315: 
 1316: static const xmlChar *
 1317: xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
 1318: {
 1319:     switch (item->type) {
 1320: 	case XML_SCHEMA_TYPE_ELEMENT:
 1321: 	    return (((xmlSchemaElementPtr) item)->name);
 1322: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1323: 	    return (((xmlSchemaAttributePtr) item)->name);
 1324: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1325: 	    return (((xmlSchemaAttributeGroupPtr) item)->name);
 1326: 	case XML_SCHEMA_TYPE_BASIC:
 1327: 	case XML_SCHEMA_TYPE_SIMPLE:
 1328: 	case XML_SCHEMA_TYPE_COMPLEX:
 1329: 	    return (((xmlSchemaTypePtr) item)->name);
 1330: 	case XML_SCHEMA_TYPE_GROUP:
 1331: 	    return (((xmlSchemaModelGroupDefPtr) item)->name);
 1332: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1333: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1334: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1335: 	    return (((xmlSchemaIDCPtr) item)->name);
 1336: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1337: 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
 1338: 		return(xmlSchemaGetComponentName(
 1339: 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 1340: 	    } else
 1341: 		return(NULL);
 1342: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1343: 	    return (((xmlSchemaQNameRefPtr) item)->name);
 1344: 	case XML_SCHEMA_TYPE_NOTATION:
 1345: 	    return (((xmlSchemaNotationPtr) item)->name);
 1346: 	default:
 1347: 	    /*
 1348: 	    * Other components cannot have names.
 1349: 	    */
 1350: 	    break;
 1351:     }
 1352:     return (NULL);
 1353: }
 1354: 
 1355: #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
 1356: #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
 1357: /*
 1358: static const xmlChar *
 1359: xmlSchemaGetQNameRefName(void *ref)
 1360: {
 1361:     return(((xmlSchemaQNameRefPtr) ref)->name);
 1362: }
 1363: 
 1364: static const xmlChar *
 1365: xmlSchemaGetQNameRefTargetNs(void *ref)
 1366: {
 1367:     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
 1368: }
 1369: */
 1370: 
 1371: static const xmlChar *
 1372: xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
 1373: {
 1374:     switch (item->type) {
 1375: 	case XML_SCHEMA_TYPE_ELEMENT:
 1376: 	    return (((xmlSchemaElementPtr) item)->targetNamespace);
 1377: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1378: 	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
 1379: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1380: 	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
 1381: 	case XML_SCHEMA_TYPE_BASIC:
 1382: 	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
 1383: 	case XML_SCHEMA_TYPE_SIMPLE:
 1384: 	case XML_SCHEMA_TYPE_COMPLEX:
 1385: 	    return (((xmlSchemaTypePtr) item)->targetNamespace);
 1386: 	case XML_SCHEMA_TYPE_GROUP:
 1387: 	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
 1388: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1389: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1390: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1391: 	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
 1392: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1393: 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
 1394: 		return(xmlSchemaGetComponentTargetNs(
 1395: 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 1396: 	    }
 1397: 	    /* TODO: Will returning NULL break something? */
 1398: 	    break;
 1399: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1400: 	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
 1401: 	case XML_SCHEMA_TYPE_NOTATION:
 1402: 	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
 1403: 	default:
 1404: 	    /*
 1405: 	    * Other components cannot have names.
 1406: 	    */
 1407: 	    break;
 1408:     }
 1409:     return (NULL);
 1410: }
 1411: 
 1412: static const xmlChar*
 1413: xmlSchemaGetComponentQName(xmlChar **buf,
 1414: 			   void *item)
 1415: {
 1416:     return (xmlSchemaFormatQName(buf,
 1417: 	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
 1418: 	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
 1419: }
 1420: 
 1421: static const xmlChar*
 1422: xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
 1423: {
 1424:     xmlChar *str = NULL;
 1425: 
 1426:     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
 1427:     *buf = xmlStrcat(*buf, BAD_CAST " '");
 1428:     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
 1429: 	(xmlSchemaBasicItemPtr) item));
 1430:     *buf = xmlStrcat(*buf, BAD_CAST "'");
 1431:     FREE_AND_NULL(str);
 1432:     return(*buf);
 1433: }
 1434: 
 1435: static const xmlChar*
 1436: xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
 1437: {
 1438:     return(xmlSchemaGetComponentDesignation(buf, idc));
 1439: }
 1440: 
 1441: /**
 1442:  * xmlSchemaWildcardPCToString:
 1443:  * @pc: the type of processContents
 1444:  *
 1445:  * Returns a string representation of the type of
 1446:  * processContents.
 1447:  */
 1448: static const xmlChar *
 1449: xmlSchemaWildcardPCToString(int pc)
 1450: {
 1451:     switch (pc) {
 1452: 	case XML_SCHEMAS_ANY_SKIP:
 1453: 	    return (BAD_CAST "skip");
 1454: 	case XML_SCHEMAS_ANY_LAX:
 1455: 	    return (BAD_CAST "lax");
 1456: 	case XML_SCHEMAS_ANY_STRICT:
 1457: 	    return (BAD_CAST "strict");
 1458: 	default:
 1459: 	    return (BAD_CAST "invalid process contents");
 1460:     }
 1461: }
 1462: 
 1463: /**
 1464:  * xmlSchemaGetCanonValueWhtspExt:
 1465:  * @val: the precomputed value
 1466:  * @retValue: the returned value
 1467:  * @ws: the whitespace type of the value
 1468:  *
 1469:  * Get a the cononical representation of the value.
 1470:  * The caller has to free the returned retValue.
 1471:  *
 1472:  * Returns 0 if the value could be built and -1 in case of
 1473:  *         API errors or if the value type is not supported yet.
 1474:  */
 1475: static int
 1476: xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
 1477: 			       xmlSchemaWhitespaceValueType ws,
 1478: 			       xmlChar **retValue)
 1479: {
 1480:     int list;
 1481:     xmlSchemaValType valType;
 1482:     const xmlChar *value, *value2 = NULL;
 1483: 
 1484: 
 1485:     if ((retValue == NULL) || (val == NULL))
 1486: 	return (-1);
 1487:     list = xmlSchemaValueGetNext(val) ? 1 : 0;
 1488:     *retValue = NULL;
 1489:     do {
 1490: 	value = NULL;
 1491: 	valType = xmlSchemaGetValType(val);
 1492: 	switch (valType) {
 1493: 	    case XML_SCHEMAS_STRING:
 1494: 	    case XML_SCHEMAS_NORMSTRING:
 1495: 	    case XML_SCHEMAS_ANYSIMPLETYPE:
 1496: 		value = xmlSchemaValueGetAsString(val);
 1497: 		if (value != NULL) {
 1498: 		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
 1499: 			value2 = xmlSchemaCollapseString(value);
 1500: 		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
 1501: 			value2 = xmlSchemaWhiteSpaceReplace(value);
 1502: 		    if (value2 != NULL)
 1503: 			value = value2;
 1504: 		}
 1505: 		break;
 1506: 	    default:
 1507: 		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
 1508: 		    if (value2 != NULL)
 1509: 			xmlFree((xmlChar *) value2);
 1510: 		    goto internal_error;
 1511: 		}
 1512: 		value = value2;
 1513: 	}
 1514: 	if (*retValue == NULL)
 1515: 	    if (value == NULL) {
 1516: 		if (! list)
 1517: 		    *retValue = xmlStrdup(BAD_CAST "");
 1518: 	    } else
 1519: 		*retValue = xmlStrdup(value);
 1520: 	else if (value != NULL) {
 1521: 	    /* List. */
 1522: 	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
 1523: 	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
 1524: 	}
 1525: 	FREE_AND_NULL(value2)
 1526: 	val = xmlSchemaValueGetNext(val);
 1527:     } while (val != NULL);
 1528: 
 1529:     return (0);
 1530: internal_error:
 1531:     if (*retValue != NULL)
 1532: 	xmlFree((xmlChar *) (*retValue));
 1533:     if (value2 != NULL)
 1534: 	xmlFree((xmlChar *) value2);
 1535:     return (-1);
 1536: }
 1537: 
 1538: /**
 1539:  * xmlSchemaFormatItemForReport:
 1540:  * @buf: the string buffer
 1541:  * @itemDes: the designation of the item
 1542:  * @itemName: the name of the item
 1543:  * @item: the item as an object
 1544:  * @itemNode: the node of the item
 1545:  * @local: the local name
 1546:  * @parsing: if the function is used during the parse
 1547:  *
 1548:  * Returns a representation of the given item used
 1549:  * for error reports.
 1550:  *
 1551:  * The following order is used to build the resulting
 1552:  * designation if the arguments are not NULL:
 1553:  * 1a. If itemDes not NULL -> itemDes
 1554:  * 1b. If (itemDes not NULL) and (itemName not NULL)
 1555:  *     -> itemDes + itemName
 1556:  * 2. If the preceding was NULL and (item not NULL) -> item
 1557:  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
 1558:  *
 1559:  * If the itemNode is an attribute node, the name of the attribute
 1560:  * will be appended to the result.
 1561:  *
 1562:  * Returns the formatted string and sets @buf to the resulting value.
 1563:  */
 1564: static xmlChar*
 1565: xmlSchemaFormatItemForReport(xmlChar **buf,
 1566: 		     const xmlChar *itemDes,
 1567: 		     xmlSchemaBasicItemPtr item,
 1568: 		     xmlNodePtr itemNode)
 1569: {
 1570:     xmlChar *str = NULL;
 1571:     int named = 1;
 1572: 
 1573:     if (*buf != NULL) {
 1574: 	xmlFree(*buf);
 1575: 	*buf = NULL;
 1576:     }
 1577: 
 1578:     if (itemDes != NULL) {
 1579: 	*buf = xmlStrdup(itemDes);
 1580:     } else if (item != NULL) {
 1581: 	switch (item->type) {
 1582: 	case XML_SCHEMA_TYPE_BASIC: {
 1583: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1584: 
 1585: 	    if (WXS_IS_ATOMIC(type))
 1586: 		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
 1587: 	    else if (WXS_IS_LIST(type))
 1588: 		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
 1589: 	    else if (WXS_IS_UNION(type))
 1590: 		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
 1591: 	    else
 1592: 		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
 1593: 	    *buf = xmlStrcat(*buf, type->name);
 1594: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1595: 	    }
 1596: 	    break;
 1597: 	case XML_SCHEMA_TYPE_SIMPLE: {
 1598: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1599: 
 1600: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1601: 		*buf = xmlStrdup(BAD_CAST"");
 1602: 	    } else {
 1603: 		*buf = xmlStrdup(BAD_CAST "local ");
 1604: 	    }
 1605: 	    if (WXS_IS_ATOMIC(type))
 1606: 		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
 1607: 	    else if (WXS_IS_LIST(type))
 1608: 		*buf = xmlStrcat(*buf, BAD_CAST "list type");
 1609: 	    else if (WXS_IS_UNION(type))
 1610: 		*buf = xmlStrcat(*buf, BAD_CAST "union type");
 1611: 	    else
 1612: 		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
 1613: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1614: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1615: 		*buf = xmlStrcat(*buf, type->name);
 1616: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1617: 	    }
 1618: 	    }
 1619: 	    break;
 1620: 	case XML_SCHEMA_TYPE_COMPLEX: {
 1621: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1622: 
 1623: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
 1624: 		*buf = xmlStrdup(BAD_CAST "");
 1625: 	    else
 1626: 		*buf = xmlStrdup(BAD_CAST "local ");
 1627: 	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
 1628: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1629: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1630: 		*buf = xmlStrcat(*buf, type->name);
 1631: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1632: 	    }
 1633: 	    }
 1634: 	    break;
 1635: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
 1636: 		xmlSchemaAttributeUsePtr ause;
 1637: 
 1638: 		ause = WXS_ATTR_USE_CAST item;
 1639: 		*buf = xmlStrdup(BAD_CAST "attribute use ");
 1640: 		if (WXS_ATTRUSE_DECL(ause) != NULL) {
 1641: 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1642: 		    *buf = xmlStrcat(*buf,
 1643: 			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
 1644: 		    FREE_AND_NULL(str)
 1645: 			*buf = xmlStrcat(*buf, BAD_CAST "'");
 1646: 		} else {
 1647: 		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
 1648: 		}
 1649: 	    }
 1650: 	    break;
 1651: 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
 1652: 		xmlSchemaAttributePtr attr;
 1653: 
 1654: 		attr = (xmlSchemaAttributePtr) item;
 1655: 		*buf = xmlStrdup(BAD_CAST "attribute decl.");
 1656: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1657: 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1658: 		    attr->targetNamespace, attr->name));
 1659: 		FREE_AND_NULL(str)
 1660: 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1661: 	    }
 1662: 	    break;
 1663: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1664: 	    xmlSchemaGetComponentDesignation(buf, item);
 1665: 	    break;
 1666: 	case XML_SCHEMA_TYPE_ELEMENT: {
 1667: 		xmlSchemaElementPtr elem;
 1668: 
 1669: 		elem = (xmlSchemaElementPtr) item;
 1670: 		*buf = xmlStrdup(BAD_CAST "element decl.");
 1671: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1672: 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1673: 		    elem->targetNamespace, elem->name));
 1674: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1675: 	    }
 1676: 	    break;
 1677: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1678: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1679: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1680: 	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
 1681: 		*buf = xmlStrdup(BAD_CAST "unique '");
 1682: 	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
 1683: 		*buf = xmlStrdup(BAD_CAST "key '");
 1684: 	    else
 1685: 		*buf = xmlStrdup(BAD_CAST "keyRef '");
 1686: 	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
 1687: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1688: 	    break;
 1689: 	case XML_SCHEMA_TYPE_ANY:
 1690: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1691: 	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
 1692: 		    ((xmlSchemaWildcardPtr) item)->processContents));
 1693: 	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
 1694: 	    break;
 1695: 	case XML_SCHEMA_FACET_MININCLUSIVE:
 1696: 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 1697: 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 1698: 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 1699: 	case XML_SCHEMA_FACET_TOTALDIGITS:
 1700: 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
 1701: 	case XML_SCHEMA_FACET_PATTERN:
 1702: 	case XML_SCHEMA_FACET_ENUMERATION:
 1703: 	case XML_SCHEMA_FACET_WHITESPACE:
 1704: 	case XML_SCHEMA_FACET_LENGTH:
 1705: 	case XML_SCHEMA_FACET_MAXLENGTH:
 1706: 	case XML_SCHEMA_FACET_MINLENGTH:
 1707: 	    *buf = xmlStrdup(BAD_CAST "facet '");
 1708: 	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
 1709: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1710: 	    break;
 1711: 	case XML_SCHEMA_TYPE_GROUP: {
 1712: 		*buf = xmlStrdup(BAD_CAST "model group def.");
 1713: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1714: 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 1715: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1716: 		FREE_AND_NULL(str)
 1717: 	    }
 1718: 	    break;
 1719: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1720: 	case XML_SCHEMA_TYPE_CHOICE:
 1721: 	case XML_SCHEMA_TYPE_ALL:
 1722: 	case XML_SCHEMA_TYPE_PARTICLE:
 1723: 	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 1724: 	    break;
 1725: 	case XML_SCHEMA_TYPE_NOTATION: {
 1726: 		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 1727: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1728: 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 1729: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1730: 		FREE_AND_NULL(str);
 1731: 	    }
 1732: 	default:
 1733: 	    named = 0;
 1734: 	}
 1735:     } else
 1736: 	named = 0;
 1737: 
 1738:     if ((named == 0) && (itemNode != NULL)) {
 1739: 	xmlNodePtr elem;
 1740: 
 1741: 	if (itemNode->type == XML_ATTRIBUTE_NODE)
 1742: 	    elem = itemNode->parent;
 1743: 	else
 1744: 	    elem = itemNode;
 1745: 	*buf = xmlStrdup(BAD_CAST "Element '");
 1746: 	if (elem->ns != NULL) {
 1747: 	    *buf = xmlStrcat(*buf,
 1748: 		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
 1749: 	    FREE_AND_NULL(str)
 1750: 	} else
 1751: 	    *buf = xmlStrcat(*buf, elem->name);
 1752: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
 1753: 
 1754:     }
 1755:     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
 1756: 	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
 1757: 	if (itemNode->ns != NULL) {
 1758: 	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1759: 		itemNode->ns->href, itemNode->name));
 1760: 	    FREE_AND_NULL(str)
 1761: 	} else
 1762: 	    *buf = xmlStrcat(*buf, itemNode->name);
 1763: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
 1764:     }
 1765:     FREE_AND_NULL(str)
 1766: 
 1767:     return (*buf);
 1768: }
 1769: 
 1770: /**
 1771:  * xmlSchemaFormatFacetEnumSet:
 1772:  * @buf: the string buffer
 1773:  * @type: the type holding the enumeration facets
 1774:  *
 1775:  * Builds a string consisting of all enumeration elements.
 1776:  *
 1777:  * Returns a string of all enumeration elements.
 1778:  */
 1779: static const xmlChar *
 1780: xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
 1781: 			    xmlChar **buf, xmlSchemaTypePtr type)
 1782: {
 1783:     xmlSchemaFacetPtr facet;
 1784:     xmlSchemaWhitespaceValueType ws;
 1785:     xmlChar *value = NULL;
 1786:     int res, found = 0;
 1787: 
 1788:     if (*buf != NULL)
 1789: 	xmlFree(*buf);
 1790:     *buf = NULL;
 1791: 
 1792:     do {
 1793: 	/*
 1794: 	* Use the whitespace type of the base type.
 1795: 	*/
 1796: 	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
 1797: 	for (facet = type->facets; facet != NULL; facet = facet->next) {
 1798: 	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
 1799: 		continue;
 1800: 	    found = 1;
 1801: 	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
 1802: 		ws, &value);
 1803: 	    if (res == -1) {
 1804: 		xmlSchemaInternalErr(actxt,
 1805: 		    "xmlSchemaFormatFacetEnumSet",
 1806: 		    "compute the canonical lexical representation");
 1807: 		if (*buf != NULL)
 1808: 		    xmlFree(*buf);
 1809: 		*buf = NULL;
 1810: 		return (NULL);
 1811: 	    }
 1812: 	    if (*buf == NULL)
 1813: 		*buf = xmlStrdup(BAD_CAST "'");
 1814: 	    else
 1815: 		*buf = xmlStrcat(*buf, BAD_CAST ", '");
 1816: 	    *buf = xmlStrcat(*buf, BAD_CAST value);
 1817: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1818: 	    if (value != NULL) {
 1819: 		xmlFree((xmlChar *)value);
 1820: 		value = NULL;
 1821: 	    }
 1822: 	}
 1823: 	/*
 1824: 	* The enumeration facet of a type restricts the enumeration
 1825: 	* facet of the ancestor type; i.e., such restricted enumerations
 1826: 	* do not belong to the set of the given type. Thus we break
 1827: 	* on the first found enumeration.
 1828: 	*/
 1829: 	if (found)
 1830: 	    break;
 1831: 	type = type->baseType;
 1832:     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
 1833: 
 1834:     return ((const xmlChar *) *buf);
 1835: }
 1836: 
 1837: /************************************************************************
 1838:  *									*
 1839:  * 			Error functions				        *
 1840:  *									*
 1841:  ************************************************************************/
 1842: 
 1843: #if 0
 1844: static void
 1845: xmlSchemaErrMemory(const char *msg)
 1846: {
 1847:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 1848:                      msg);
 1849: }
 1850: #endif
 1851: 
 1852: static void
 1853: xmlSchemaPSimpleErr(const char *msg)
 1854: {
 1855:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 1856:                      msg);
 1857: }
 1858: 
 1859: /**
 1860:  * xmlSchemaPErrMemory:
 1861:  * @node: a context node
 1862:  * @extra:  extra informations
 1863:  *
 1864:  * Handle an out of memory condition
 1865:  */
 1866: static void
 1867: xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
 1868:                     const char *extra, xmlNodePtr node)
 1869: {
 1870:     if (ctxt != NULL)
 1871:         ctxt->nberrors++;
 1872:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
 1873:                      extra);
 1874: }
 1875: 
 1876: /**
 1877:  * xmlSchemaPErr:
 1878:  * @ctxt: the parsing context
 1879:  * @node: the context node
 1880:  * @error: the error code
 1881:  * @msg: the error message
 1882:  * @str1: extra data
 1883:  * @str2: extra data
 1884:  *
 1885:  * Handle a parser error
 1886:  */
 1887: static void
 1888: xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 1889:               const char *msg, const xmlChar * str1, const xmlChar * str2)
 1890: {
 1891:     xmlGenericErrorFunc channel = NULL;
 1892:     xmlStructuredErrorFunc schannel = NULL;
 1893:     void *data = NULL;
 1894: 
 1895:     if (ctxt != NULL) {
 1896:         ctxt->nberrors++;
 1897: 	ctxt->err = error;
 1898:         channel = ctxt->error;
 1899:         data = ctxt->errCtxt;
 1900: 	schannel = ctxt->serror;
 1901:     }
 1902:     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 1903:                     error, XML_ERR_ERROR, NULL, 0,
 1904:                     (const char *) str1, (const char *) str2, NULL, 0, 0,
 1905:                     msg, str1, str2);
 1906: }
 1907: 
 1908: /**
 1909:  * xmlSchemaPErr2:
 1910:  * @ctxt: the parsing context
 1911:  * @node: the context node
 1912:  * @node: the current child
 1913:  * @error: the error code
 1914:  * @msg: the error message
 1915:  * @str1: extra data
 1916:  * @str2: extra data
 1917:  *
 1918:  * Handle a parser error
 1919:  */
 1920: static void
 1921: xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 1922:                xmlNodePtr child, int error,
 1923:                const char *msg, const xmlChar * str1, const xmlChar * str2)
 1924: {
 1925:     if (child != NULL)
 1926:         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
 1927:     else
 1928:         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
 1929: }
 1930: 
 1931: 
 1932: /**
 1933:  * xmlSchemaPErrExt:
 1934:  * @ctxt: the parsing context
 1935:  * @node: the context node
 1936:  * @error: the error code
 1937:  * @strData1: extra data
 1938:  * @strData2: extra data
 1939:  * @strData3: extra data
 1940:  * @msg: the message
 1941:  * @str1:  extra parameter for the message display
 1942:  * @str2:  extra parameter for the message display
 1943:  * @str3:  extra parameter for the message display
 1944:  * @str4:  extra parameter for the message display
 1945:  * @str5:  extra parameter for the message display
 1946:  *
 1947:  * Handle a parser error
 1948:  */
 1949: static void
 1950: xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 1951: 		const xmlChar * strData1, const xmlChar * strData2,
 1952: 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
 1953: 		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
 1954: 		const xmlChar * str5)
 1955: {
 1956: 
 1957:     xmlGenericErrorFunc channel = NULL;
 1958:     xmlStructuredErrorFunc schannel = NULL;
 1959:     void *data = NULL;
 1960: 
 1961:     if (ctxt != NULL) {
 1962:         ctxt->nberrors++;
 1963: 	ctxt->err = error;
 1964:         channel = ctxt->error;
 1965:         data = ctxt->errCtxt;
 1966: 	schannel = ctxt->serror;
 1967:     }
 1968:     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 1969:                     error, XML_ERR_ERROR, NULL, 0,
 1970:                     (const char *) strData1, (const char *) strData2,
 1971: 		    (const char *) strData3, 0, 0, msg, str1, str2,
 1972: 		    str3, str4, str5);
 1973: }
 1974: 
 1975: /************************************************************************
 1976:  *									*
 1977:  * 			Allround error functions			*
 1978:  *									*
 1979:  ************************************************************************/
 1980: 
 1981: /**
 1982:  * xmlSchemaVTypeErrMemory:
 1983:  * @node: a context node
 1984:  * @extra:  extra informations
 1985:  *
 1986:  * Handle an out of memory condition
 1987:  */
 1988: static void
 1989: xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
 1990:                     const char *extra, xmlNodePtr node)
 1991: {
 1992:     if (ctxt != NULL) {
 1993:         ctxt->nberrors++;
 1994:         ctxt->err = XML_SCHEMAV_INTERNAL;
 1995:     }
 1996:     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
 1997:                      extra);
 1998: }
 1999: 
 2000: static void
 2001: xmlSchemaPSimpleInternalErr(xmlNodePtr node,
 2002: 			    const char *msg, const xmlChar *str)
 2003: {
 2004:      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
 2005: 	 msg, (const char *) str);
 2006: }
 2007: 
 2008: #define WXS_ERROR_TYPE_ERROR 1
 2009: #define WXS_ERROR_TYPE_WARNING 2
 2010: /**
 2011:  * xmlSchemaErr3:
 2012:  * @ctxt: the validation context
 2013:  * @node: the context node
 2014:  * @error: the error code
 2015:  * @msg: the error message
 2016:  * @str1: extra data
 2017:  * @str2: extra data
 2018:  * @str3: extra data
 2019:  *
 2020:  * Handle a validation error
 2021:  */
 2022: static void
 2023: xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
 2024: 		  xmlErrorLevel errorLevel,
 2025: 		  int error, xmlNodePtr node, int line, const char *msg,
 2026: 		  const xmlChar *str1, const xmlChar *str2,
 2027: 		  const xmlChar *str3, const xmlChar *str4)
 2028: {
 2029:     xmlStructuredErrorFunc schannel = NULL;
 2030:     xmlGenericErrorFunc channel = NULL;
 2031:     void *data = NULL;
 2032: 
 2033:     if (ctxt != NULL) {
 2034: 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 2035: 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
 2036: 	    const char *file = NULL;
 2037: 	    if (errorLevel != XML_ERR_WARNING) {
 2038: 		vctxt->nberrors++;
 2039: 		vctxt->err = error;
 2040: 		channel = vctxt->error;
 2041: 	    } else {
 2042: 		channel = vctxt->warning;
 2043: 	    }
 2044: 	    schannel = vctxt->serror;
 2045: 	    data = vctxt->errCtxt;
 2046: 
 2047: 	    /*
 2048: 	    * Error node. If we specify a line number, then
 2049: 	    * do not channel any node to the error function.
 2050: 	    */
 2051: 	    if (line == 0) {
 2052: 		if ((node == NULL) &&
 2053: 		    (vctxt->depth >= 0) &&
 2054: 		    (vctxt->inode != NULL)) {
 2055: 		    node = vctxt->inode->node;
 2056: 		}
 2057: 		/*
 2058: 		* Get filename and line if no node-tree.
 2059: 		*/
 2060: 		if ((node == NULL) &&
 2061: 		    (vctxt->parserCtxt != NULL) &&
 2062: 		    (vctxt->parserCtxt->input != NULL)) {
 2063: 		    file = vctxt->parserCtxt->input->filename;
 2064: 		    line = vctxt->parserCtxt->input->line;
 2065: 		}
 2066: 	    } else {
 2067: 		/*
 2068: 		* Override the given node's (if any) position
 2069: 		* and channel only the given line number.
 2070: 		*/
 2071: 		node = NULL;
 2072: 		/*
 2073: 		* Get filename.
 2074: 		*/
 2075: 		if (vctxt->doc != NULL)
 2076: 		    file = (const char *) vctxt->doc->URL;
 2077: 		else if ((vctxt->parserCtxt != NULL) &&
 2078: 		    (vctxt->parserCtxt->input != NULL))
 2079: 		    file = vctxt->parserCtxt->input->filename;
 2080: 	    }
 2081: 	    __xmlRaiseError(schannel, channel, data, ctxt,
 2082: 		node, XML_FROM_SCHEMASV,
 2083: 		error, errorLevel, file, line,
 2084: 		(const char *) str1, (const char *) str2,
 2085: 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 2086: 
 2087: 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
 2088: 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
 2089: 	    if (errorLevel != XML_ERR_WARNING) {
 2090: 		pctxt->nberrors++;
 2091: 		pctxt->err = error;
 2092: 		channel = pctxt->error;
 2093: 	    } else {
 2094: 		channel = pctxt->warning;
 2095: 	    }
 2096: 	    schannel = pctxt->serror;
 2097: 	    data = pctxt->errCtxt;
 2098: 	    __xmlRaiseError(schannel, channel, data, ctxt,
 2099: 		node, XML_FROM_SCHEMASP, error,
 2100: 		errorLevel, NULL, 0,
 2101: 		(const char *) str1, (const char *) str2,
 2102: 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 2103: 	} else {
 2104: 	    TODO
 2105: 	}
 2106:     }
 2107: }
 2108: 
 2109: /**
 2110:  * xmlSchemaErr3:
 2111:  * @ctxt: the validation context
 2112:  * @node: the context node
 2113:  * @error: the error code
 2114:  * @msg: the error message
 2115:  * @str1: extra data
 2116:  * @str2: extra data
 2117:  * @str3: extra data
 2118:  *
 2119:  * Handle a validation error
 2120:  */
 2121: static void
 2122: xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
 2123: 	      int error, xmlNodePtr node, const char *msg,
 2124: 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
 2125: {
 2126:     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 2127: 	msg, str1, str2, str3, NULL);
 2128: }
 2129: 
 2130: static void
 2131: xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
 2132: 	      int error, xmlNodePtr node, const char *msg,
 2133: 	      const xmlChar *str1, const xmlChar *str2,
 2134: 	      const xmlChar *str3, const xmlChar *str4)
 2135: {
 2136:     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 2137: 	msg, str1, str2, str3, str4);
 2138: }
 2139: 
 2140: static void
 2141: xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
 2142: 	     int error, xmlNodePtr node, const char *msg,
 2143: 	     const xmlChar *str1, const xmlChar *str2)
 2144: {
 2145:     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
 2146: }
 2147: 
 2148: static xmlChar *
 2149: xmlSchemaFormatNodeForError(xmlChar ** msg,
 2150: 			    xmlSchemaAbstractCtxtPtr actxt,
 2151: 			    xmlNodePtr node)
 2152: {
 2153:     xmlChar *str = NULL;
 2154: 
 2155:     *msg = NULL;
 2156:     if ((node != NULL) &&
 2157: 	(node->type != XML_ELEMENT_NODE) &&
 2158: 	(node->type != XML_ATTRIBUTE_NODE))
 2159:     {
 2160: 	/*
 2161: 	* Don't try to format other nodes than element and
 2162: 	* attribute nodes.
 2163: 	* Play save and return an empty string.
 2164: 	*/
 2165: 	*msg = xmlStrdup(BAD_CAST "");
 2166: 	return(*msg);
 2167:     }
 2168:     if (node != NULL) {
 2169: 	/*
 2170: 	* Work on tree nodes.
 2171: 	*/
 2172: 	if (node->type == XML_ATTRIBUTE_NODE) {
 2173: 	    xmlNodePtr elem = node->parent;
 2174: 
 2175: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2176: 	    if (elem->ns != NULL)
 2177: 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2178: 		    elem->ns->href, elem->name));
 2179: 	    else
 2180: 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2181: 		    NULL, elem->name));
 2182: 	    FREE_AND_NULL(str);
 2183: 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
 2184: 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
 2185: 	} else {
 2186: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2187: 	}
 2188: 	if (node->ns != NULL)
 2189: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2190: 	    node->ns->href, node->name));
 2191: 	else
 2192: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2193: 	    NULL, node->name));
 2194: 	FREE_AND_NULL(str);
 2195: 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
 2196:     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 2197: 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
 2198: 	/*
 2199: 	* Work on node infos.
 2200: 	*/
 2201: 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
 2202: 	    xmlSchemaNodeInfoPtr ielem =
 2203: 		vctxt->elemInfos[vctxt->depth];
 2204: 
 2205: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2206: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2207: 		ielem->nsName, ielem->localName));
 2208: 	    FREE_AND_NULL(str);
 2209: 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
 2210: 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
 2211: 	} else {
 2212: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2213: 	}
 2214: 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2215: 	    vctxt->inode->nsName, vctxt->inode->localName));
 2216: 	FREE_AND_NULL(str);
 2217: 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
 2218:     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
 2219: 	/*
 2220: 	* Hmm, no node while parsing?
 2221: 	* Return an empty string, in case NULL will break something.
 2222: 	*/
 2223: 	*msg = xmlStrdup(BAD_CAST "");
 2224:     } else {
 2225: 	TODO
 2226: 	return (NULL);
 2227:     }
 2228:     /*
 2229:     * VAL TODO: The output of the given schema component is currently
 2230:     * disabled.
 2231:     */
 2232: #if 0
 2233:     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
 2234: 	*msg = xmlStrcat(*msg, BAD_CAST " [");
 2235: 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
 2236: 	    NULL, type, NULL, 0));
 2237: 	FREE_AND_NULL(str)
 2238: 	*msg = xmlStrcat(*msg, BAD_CAST "]");
 2239:     }
 2240: #endif
 2241:     return (*msg);
 2242: }
 2243: 
 2244: static void
 2245: xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
 2246: 		     const char *funcName,
 2247: 		     const char *message,
 2248: 		     const xmlChar *str1,
 2249: 		     const xmlChar *str2)
 2250: {
 2251:     xmlChar *msg = NULL;
 2252: 
 2253:     if (actxt == NULL)
 2254:         return;
 2255:     msg = xmlStrdup(BAD_CAST "Internal error: ");
 2256:     msg = xmlStrcat(msg, BAD_CAST funcName);
 2257:     msg = xmlStrcat(msg, BAD_CAST ", ");
 2258:     msg = xmlStrcat(msg, BAD_CAST message);
 2259:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2260: 
 2261:     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
 2262: 	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
 2263: 	    (const char *) msg, str1, str2);
 2264: 
 2265:     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
 2266: 	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
 2267: 	    (const char *) msg, str1, str2);
 2268: 
 2269:     FREE_AND_NULL(msg)
 2270: }
 2271: 
 2272: static void
 2273: xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 2274: 		     const char *funcName,
 2275: 		     const char *message)
 2276: {
 2277:     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
 2278: }
 2279: 
 2280: #if 0
 2281: static void
 2282: xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
 2283: 		     const char *funcName,
 2284: 		     const char *message,
 2285: 		     const xmlChar *str1,
 2286: 		     const xmlChar *str2)
 2287: {
 2288:     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
 2289: 	str1, str2);
 2290: }
 2291: #endif
 2292: 
 2293: static void
 2294: xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
 2295: 		   xmlParserErrors error,
 2296: 		   xmlNodePtr node,
 2297: 		   xmlSchemaBasicItemPtr item,
 2298: 		   const char *message,
 2299: 		   const xmlChar *str1, const xmlChar *str2,
 2300: 		   const xmlChar *str3, const xmlChar *str4)
 2301: {
 2302:     xmlChar *msg = NULL;
 2303: 
 2304:     if ((node == NULL) && (item != NULL) &&
 2305: 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
 2306: 	node = WXS_ITEM_NODE(item);
 2307: 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
 2308: 	msg = xmlStrcat(msg, BAD_CAST ": ");
 2309:     } else
 2310: 	xmlSchemaFormatNodeForError(&msg, actxt, node);
 2311:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2312:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2313:     xmlSchemaErr4(actxt, error, node,
 2314: 	(const char *) msg, str1, str2, str3, str4);
 2315:     FREE_AND_NULL(msg)
 2316: }
 2317: 
 2318: static void
 2319: xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
 2320: 		   xmlParserErrors error,
 2321: 		   xmlNodePtr node,
 2322: 		   xmlSchemaBasicItemPtr item,
 2323: 		   const char *message,
 2324: 		   const xmlChar *str1,
 2325: 		   const xmlChar *str2)
 2326: {
 2327:     xmlSchemaCustomErr4(actxt, error, node, item,
 2328: 	message, str1, str2, NULL, NULL);
 2329: }
 2330: 
 2331: 
 2332: 
 2333: static void
 2334: xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
 2335: 		   xmlParserErrors error,
 2336: 		   xmlNodePtr node,
 2337: 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2338: 		   const char *message,
 2339: 		   const xmlChar *str1,
 2340: 		   const xmlChar *str2,
 2341: 		   const xmlChar *str3)
 2342: {
 2343:     xmlChar *msg = NULL;
 2344: 
 2345:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2346:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2347:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2348: 
 2349:     /* URGENT TODO: Set the error code to something sane. */
 2350:     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
 2351: 	(const char *) msg, str1, str2, str3, NULL);
 2352: 
 2353:     FREE_AND_NULL(msg)
 2354: }
 2355: 
 2356: 
 2357: 
 2358: static void
 2359: xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
 2360: 		   xmlParserErrors error,
 2361: 		   xmlSchemaPSVIIDCNodePtr idcNode,
 2362: 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2363: 		   const char *message,
 2364: 		   const xmlChar *str1,
 2365: 		   const xmlChar *str2)
 2366: {
 2367:     xmlChar *msg = NULL, *qname = NULL;
 2368: 
 2369:     msg = xmlStrdup(BAD_CAST "Element '%s': ");
 2370:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2371:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2372:     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
 2373: 	error, NULL, idcNode->nodeLine, (const char *) msg,
 2374: 	xmlSchemaFormatQName(&qname,
 2375: 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
 2376: 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
 2377: 	str1, str2, NULL);
 2378:     FREE_AND_NULL(qname);
 2379:     FREE_AND_NULL(msg);
 2380: }
 2381: 
 2382: static int
 2383: xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
 2384: 			   xmlNodePtr node)
 2385: {
 2386:     if (node != NULL)
 2387: 	return (node->type);
 2388:     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
 2389: 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
 2390: 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
 2391:     return (-1);
 2392: }
 2393: 
 2394: static int
 2395: xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
 2396: {
 2397:     switch (item->type) {
 2398: 	case XML_SCHEMA_TYPE_COMPLEX:
 2399: 	case XML_SCHEMA_TYPE_SIMPLE:
 2400: 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
 2401: 		return(1);
 2402: 	    break;
 2403: 	case XML_SCHEMA_TYPE_GROUP:
 2404: 	    return (1);
 2405: 	case XML_SCHEMA_TYPE_ELEMENT:
 2406: 	    if ( ((xmlSchemaElementPtr) item)->flags &
 2407: 		XML_SCHEMAS_ELEM_GLOBAL)
 2408: 		return(1);
 2409: 	    break;
 2410: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 2411: 	    if ( ((xmlSchemaAttributePtr) item)->flags &
 2412: 		XML_SCHEMAS_ATTR_GLOBAL)
 2413: 		return(1);
 2414: 	    break;
 2415: 	/* Note that attribute groups are always global. */
 2416: 	default:
 2417: 	    return(1);
 2418:     }
 2419:     return (0);
 2420: }
 2421: 
 2422: static void
 2423: xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 2424: 		       xmlParserErrors error,
 2425: 		       xmlNodePtr node,
 2426: 		       const xmlChar *value,
 2427: 		       xmlSchemaTypePtr type,
 2428: 		       int displayValue)
 2429: {
 2430:     xmlChar *msg = NULL;
 2431: 
 2432:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2433: 
 2434:     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 2435: 	    XML_ATTRIBUTE_NODE))
 2436: 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 2437:     else
 2438: 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
 2439: 	    "value of ");
 2440: 
 2441:     if (! xmlSchemaIsGlobalItem(type))
 2442: 	msg = xmlStrcat(msg, BAD_CAST "the local ");
 2443:     else
 2444: 	msg = xmlStrcat(msg, BAD_CAST "the ");
 2445: 
 2446:     if (WXS_IS_ATOMIC(type))
 2447: 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
 2448:     else if (WXS_IS_LIST(type))
 2449: 	msg = xmlStrcat(msg, BAD_CAST "list type");
 2450:     else if (WXS_IS_UNION(type))
 2451: 	msg = xmlStrcat(msg, BAD_CAST "union type");
 2452: 
 2453:     if (xmlSchemaIsGlobalItem(type)) {
 2454: 	xmlChar *str = NULL;
 2455: 	msg = xmlStrcat(msg, BAD_CAST " '");
 2456: 	if (type->builtInType != 0) {
 2457: 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
 2458: 	    msg = xmlStrcat(msg, type->name);
 2459: 	} else
 2460: 	    msg = xmlStrcat(msg,
 2461: 		xmlSchemaFormatQName(&str,
 2462: 		    type->targetNamespace, type->name));
 2463: 	msg = xmlStrcat(msg, BAD_CAST "'");
 2464: 	FREE_AND_NULL(str);
 2465:     }
 2466:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2467:     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 2468: 	    XML_ATTRIBUTE_NODE))
 2469: 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 2470:     else
 2471: 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2472:     FREE_AND_NULL(msg)
 2473: }
 2474: 
 2475: static const xmlChar *
 2476: xmlSchemaFormatErrorNodeQName(xmlChar ** str,
 2477: 			      xmlSchemaNodeInfoPtr ni,
 2478: 			      xmlNodePtr node)
 2479: {
 2480:     if (node != NULL) {
 2481: 	if (node->ns != NULL)
 2482: 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
 2483: 	else
 2484: 	    return (xmlSchemaFormatQName(str, NULL, node->name));
 2485:     } else if (ni != NULL)
 2486: 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
 2487:     return (NULL);
 2488: }
 2489: 
 2490: static void
 2491: xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
 2492: 			xmlParserErrors error,
 2493: 			xmlSchemaAttrInfoPtr ni,
 2494: 			xmlNodePtr node)
 2495: {
 2496:     xmlChar *msg = NULL, *str = NULL;
 2497: 
 2498:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2499:     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
 2500:     xmlSchemaErr(actxt, error, node, (const char *) msg,
 2501: 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
 2502: 	NULL);
 2503:     FREE_AND_NULL(str)
 2504:     FREE_AND_NULL(msg)
 2505: }
 2506: 
 2507: static void
 2508: xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 2509: 		        xmlParserErrors error,
 2510: 		        xmlNodePtr node,
 2511: 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2512: 			const char *message,
 2513: 			int nbval,
 2514: 			int nbneg,
 2515: 			xmlChar **values)
 2516: {
 2517:     xmlChar *str = NULL, *msg = NULL;
 2518:     xmlChar *localName, *nsName;
 2519:     const xmlChar *cur, *end;
 2520:     int i;
 2521: 
 2522:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2523:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2524:     msg = xmlStrcat(msg, BAD_CAST ".");
 2525:     /*
 2526:     * Note that is does not make sense to report that we have a
 2527:     * wildcard here, since the wildcard might be unfolded into
 2528:     * multiple transitions.
 2529:     */
 2530:     if (nbval + nbneg > 0) {
 2531: 	if (nbval + nbneg > 1) {
 2532: 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
 2533: 	} else
 2534: 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
 2535: 	nsName = NULL;
 2536: 
 2537: 	for (i = 0; i < nbval + nbneg; i++) {
 2538: 	    cur = values[i];
 2539: 	    if (cur == NULL)
 2540: 	        continue;
 2541: 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
 2542: 	        (cur[3] == ' ')) {
 2543: 		cur += 4;
 2544: 		str = xmlStrcat(str, BAD_CAST "##other");
 2545: 	    }
 2546: 	    /*
 2547: 	    * Get the local name.
 2548: 	    */
 2549: 	    localName = NULL;
 2550: 
 2551: 	    end = cur;
 2552: 	    if (*end == '*') {
 2553: 		localName = xmlStrdup(BAD_CAST "*");
 2554: 		end++;
 2555: 	    } else {
 2556: 		while ((*end != 0) && (*end != '|'))
 2557: 		    end++;
 2558: 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
 2559: 	    }
 2560: 	    if (*end != 0) {
 2561: 		end++;
 2562: 		/*
 2563: 		* Skip "*|*" if they come with negated expressions, since
 2564: 		* they represent the same negated wildcard.
 2565: 		*/
 2566: 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
 2567: 		    /*
 2568: 		    * Get the namespace name.
 2569: 		    */
 2570: 		    cur = end;
 2571: 		    if (*end == '*') {
 2572: 			nsName = xmlStrdup(BAD_CAST "{*}");
 2573: 		    } else {
 2574: 			while (*end != 0)
 2575: 			    end++;
 2576: 
 2577: 			if (i >= nbval)
 2578: 			    nsName = xmlStrdup(BAD_CAST "{##other:");
 2579: 			else
 2580: 			    nsName = xmlStrdup(BAD_CAST "{");
 2581: 
 2582: 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
 2583: 			nsName = xmlStrcat(nsName, BAD_CAST "}");
 2584: 		    }
 2585: 		    str = xmlStrcat(str, BAD_CAST nsName);
 2586: 		    FREE_AND_NULL(nsName)
 2587: 		} else {
 2588: 		    FREE_AND_NULL(localName);
 2589: 		    continue;
 2590: 		}
 2591: 	    }
 2592: 	    str = xmlStrcat(str, BAD_CAST localName);
 2593: 	    FREE_AND_NULL(localName);
 2594: 
 2595: 	    if (i < nbval + nbneg -1)
 2596: 		str = xmlStrcat(str, BAD_CAST ", ");
 2597: 	}
 2598: 	str = xmlStrcat(str, BAD_CAST " ).\n");
 2599: 	msg = xmlStrcat(msg, BAD_CAST str);
 2600: 	FREE_AND_NULL(str)
 2601:     } else
 2602:       msg = xmlStrcat(msg, BAD_CAST "\n");
 2603:     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2604:     xmlFree(msg);
 2605: }
 2606: 
 2607: static void
 2608: xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
 2609: 		  xmlParserErrors error,
 2610: 		  xmlNodePtr node,
 2611: 		  const xmlChar *value,
 2612: 		  unsigned long length,
 2613: 		  xmlSchemaTypePtr type,
 2614: 		  xmlSchemaFacetPtr facet,
 2615: 		  const char *message,
 2616: 		  const xmlChar *str1,
 2617: 		  const xmlChar *str2)
 2618: {
 2619:     xmlChar *str = NULL, *msg = NULL;
 2620:     xmlSchemaTypeType facetType;
 2621:     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
 2622: 
 2623:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2624:     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
 2625: 	facetType = XML_SCHEMA_FACET_ENUMERATION;
 2626: 	/*
 2627: 	* If enumerations are validated, one must not expect the
 2628: 	* facet to be given.
 2629: 	*/
 2630:     } else
 2631: 	facetType = facet->type;
 2632:     msg = xmlStrcat(msg, BAD_CAST "[");
 2633:     msg = xmlStrcat(msg, BAD_CAST "facet '");
 2634:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
 2635:     msg = xmlStrcat(msg, BAD_CAST "'] ");
 2636:     if (message == NULL) {
 2637: 	/*
 2638: 	* Use a default message.
 2639: 	*/
 2640: 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
 2641: 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
 2642: 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
 2643: 
 2644: 	    char len[25], actLen[25];
 2645: 
 2646: 	    /* FIXME, TODO: What is the max expected string length of the
 2647: 	    * this value?
 2648: 	    */
 2649: 	    if (nodeType == XML_ATTRIBUTE_NODE)
 2650: 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
 2651: 	    else
 2652: 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
 2653: 
 2654: 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
 2655: 	    snprintf(actLen, 24, "%lu", length);
 2656: 
 2657: 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
 2658: 		msg = xmlStrcat(msg,
 2659: 		BAD_CAST "this differs from the allowed length of '%s'.\n");
 2660: 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
 2661: 		msg = xmlStrcat(msg,
 2662: 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
 2663: 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
 2664: 		msg = xmlStrcat(msg,
 2665: 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
 2666: 
 2667: 	    if (nodeType == XML_ATTRIBUTE_NODE)
 2668: 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
 2669: 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
 2670: 	    else
 2671: 		xmlSchemaErr(actxt, error, node, (const char *) msg,
 2672: 		    (const xmlChar *) actLen, (const xmlChar *) len);
 2673: 
 2674: 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
 2675: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
 2676: 		"of the set {%s}.\n");
 2677: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2678: 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
 2679: 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
 2680: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
 2681: 		"by the pattern '%s'.\n");
 2682: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2683: 		facet->value);
 2684: 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
 2685: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
 2686: 		"minimum value allowed ('%s').\n");
 2687: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2688: 		facet->value);
 2689: 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
 2690: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
 2691: 		"maximum value allowed ('%s').\n");
 2692: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2693: 		facet->value);
 2694: 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
 2695: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
 2696: 		"'%s'.\n");
 2697: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2698: 		facet->value);
 2699: 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
 2700: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
 2701: 		"'%s'.\n");
 2702: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2703: 		facet->value);
 2704: 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
 2705: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
 2706: 		"digits than are allowed ('%s').\n");
 2707: 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 2708: 		facet->value);
 2709: 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
 2710: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
 2711: 		"digits than are allowed ('%s').\n");
 2712: 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 2713: 		facet->value);
 2714: 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
 2715: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
 2716: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 2717: 	} else {
 2718: 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
 2719: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2720: 	}
 2721:     } else {
 2722: 	msg = xmlStrcat(msg, (const xmlChar *) message);
 2723: 	msg = xmlStrcat(msg, BAD_CAST ".\n");
 2724: 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
 2725:     }
 2726:     FREE_AND_NULL(str)
 2727:     xmlFree(msg);
 2728: }
 2729: 
 2730: #define VERROR(err, type, msg) \
 2731:     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
 2732: 
 2733: #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
 2734: 
 2735: #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
 2736: #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
 2737: 
 2738: #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
 2739: 
 2740: 
 2741: /**
 2742:  * xmlSchemaPMissingAttrErr:
 2743:  * @ctxt: the schema validation context
 2744:  * @ownerDes: the designation of  the owner
 2745:  * @ownerName: the name of the owner
 2746:  * @ownerItem: the owner as a schema object
 2747:  * @ownerElem: the owner as an element node
 2748:  * @node: the parent element node of the missing attribute node
 2749:  * @type: the corresponding type of the attribute node
 2750:  *
 2751:  * Reports an illegal attribute.
 2752:  */
 2753: static void
 2754: xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2755: 			 xmlParserErrors error,
 2756: 			 xmlSchemaBasicItemPtr ownerItem,
 2757: 			 xmlNodePtr ownerElem,
 2758: 			 const char *name,
 2759: 			 const char *message)
 2760: {
 2761:     xmlChar *des = NULL;
 2762: 
 2763:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 2764: 
 2765:     if (message != NULL)
 2766: 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
 2767:     else
 2768: 	xmlSchemaPErr(ctxt, ownerElem, error,
 2769: 	    "%s: The attribute '%s' is required but missing.\n",
 2770: 	    BAD_CAST des, BAD_CAST name);
 2771:     FREE_AND_NULL(des);
 2772: }
 2773: 
 2774: 
 2775: /**
 2776:  * xmlSchemaPResCompAttrErr:
 2777:  * @ctxt: the schema validation context
 2778:  * @error: the error code
 2779:  * @ownerDes: the designation of  the owner
 2780:  * @ownerItem: the owner as a schema object
 2781:  * @ownerElem: the owner as an element node
 2782:  * @name: the name of the attribute holding the QName
 2783:  * @refName: the referenced local name
 2784:  * @refURI: the referenced namespace URI
 2785:  * @message: optional message
 2786:  *
 2787:  * Used to report QName attribute values that failed to resolve
 2788:  * to schema components.
 2789:  */
 2790: static void
 2791: xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2792: 			 xmlParserErrors error,
 2793: 			 xmlSchemaBasicItemPtr ownerItem,
 2794: 			 xmlNodePtr ownerElem,
 2795: 			 const char *name,
 2796: 			 const xmlChar *refName,
 2797: 			 const xmlChar *refURI,
 2798: 			 xmlSchemaTypeType refType,
 2799: 			 const char *refTypeStr)
 2800: {
 2801:     xmlChar *des = NULL, *strA = NULL;
 2802: 
 2803:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 2804:     if (refTypeStr == NULL)
 2805: 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
 2806: 	xmlSchemaPErrExt(ctxt, ownerElem, error,
 2807: 	    NULL, NULL, NULL,
 2808: 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
 2809: 	    "%s.\n", BAD_CAST des, BAD_CAST name,
 2810: 	    xmlSchemaFormatQName(&strA, refURI, refName),
 2811: 	    BAD_CAST refTypeStr, NULL);
 2812:     FREE_AND_NULL(des)
 2813:     FREE_AND_NULL(strA)
 2814: }
 2815: 
 2816: /**
 2817:  * xmlSchemaPCustomAttrErr:
 2818:  * @ctxt: the schema parser context
 2819:  * @error: the error code
 2820:  * @ownerDes: the designation of the owner
 2821:  * @ownerItem: the owner as a schema object
 2822:  * @attr: the illegal attribute node
 2823:  *
 2824:  * Reports an illegal attribute during the parse.
 2825:  */
 2826: static void
 2827: xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2828: 			xmlParserErrors error,
 2829: 			xmlChar **ownerDes,
 2830: 			xmlSchemaBasicItemPtr ownerItem,
 2831: 			xmlAttrPtr attr,
 2832: 			const char *msg)
 2833: {
 2834:     xmlChar *des = NULL;
 2835: 
 2836:     if (ownerDes == NULL)
 2837: 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
 2838:     else if (*ownerDes == NULL) {
 2839: 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
 2840: 	des = *ownerDes;
 2841:     } else
 2842: 	des = *ownerDes;
 2843:     if (attr == NULL) {
 2844: 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
 2845: 	    "%s, attribute '%s': %s.\n",
 2846: 	    BAD_CAST des, (const xmlChar *) "Unknown",
 2847: 	    (const xmlChar *) msg, NULL, NULL);
 2848:     } else {
 2849: 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 2850: 	    "%s, attribute '%s': %s.\n",
 2851: 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
 2852:     }
 2853:     if (ownerDes == NULL)
 2854: 	FREE_AND_NULL(des);
 2855: }
 2856: 
 2857: /**
 2858:  * xmlSchemaPIllegalAttrErr:
 2859:  * @ctxt: the schema parser context
 2860:  * @error: the error code
 2861:  * @ownerDes: the designation of the attribute's owner
 2862:  * @ownerItem: the attribute's owner item
 2863:  * @attr: the illegal attribute node
 2864:  *
 2865:  * Reports an illegal attribute during the parse.
 2866:  */
 2867: static void
 2868: xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2869: 			 xmlParserErrors error,
 2870: 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
 2871: 			 xmlAttrPtr attr)
 2872: {
 2873:     xmlChar *strA = NULL, *strB = NULL;
 2874: 
 2875:     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
 2876:     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
 2877: 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
 2878: 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
 2879: 	NULL, NULL);
 2880:     FREE_AND_NULL(strA);
 2881:     FREE_AND_NULL(strB);
 2882: }
 2883: 
 2884: /**
 2885:  * xmlSchemaPCustomErr:
 2886:  * @ctxt: the schema parser context
 2887:  * @error: the error code
 2888:  * @itemDes: the designation of the schema item
 2889:  * @item: the schema item
 2890:  * @itemElem: the node of the schema item
 2891:  * @message: the error message
 2892:  * @str1: an optional param for the error message
 2893:  * @str2: an optional param for the error message
 2894:  * @str3: an optional param for the error message
 2895:  *
 2896:  * Reports an error during parsing.
 2897:  */
 2898: static void
 2899: xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
 2900: 		    xmlParserErrors error,
 2901: 		    xmlSchemaBasicItemPtr item,
 2902: 		    xmlNodePtr itemElem,
 2903: 		    const char *message,
 2904: 		    const xmlChar *str1,
 2905: 		    const xmlChar *str2,
 2906: 		    const xmlChar *str3)
 2907: {
 2908:     xmlChar *des = NULL, *msg = NULL;
 2909: 
 2910:     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
 2911:     msg = xmlStrdup(BAD_CAST "%s: ");
 2912:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2913:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2914:     if ((itemElem == NULL) && (item != NULL))
 2915: 	itemElem = WXS_ITEM_NODE(item);
 2916:     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
 2917: 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
 2918:     FREE_AND_NULL(des);
 2919:     FREE_AND_NULL(msg);
 2920: }
 2921: 
 2922: /**
 2923:  * xmlSchemaPCustomErr:
 2924:  * @ctxt: the schema parser context
 2925:  * @error: the error code
 2926:  * @itemDes: the designation of the schema item
 2927:  * @item: the schema item
 2928:  * @itemElem: the node of the schema item
 2929:  * @message: the error message
 2930:  * @str1: the optional param for the error message
 2931:  *
 2932:  * Reports an error during parsing.
 2933:  */
 2934: static void
 2935: xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
 2936: 		    xmlParserErrors error,
 2937: 		    xmlSchemaBasicItemPtr item,
 2938: 		    xmlNodePtr itemElem,
 2939: 		    const char *message,
 2940: 		    const xmlChar *str1)
 2941: {
 2942:     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
 2943: 	str1, NULL, NULL);
 2944: }
 2945: 
 2946: /**
 2947:  * xmlSchemaPAttrUseErr:
 2948:  * @ctxt: the schema parser context
 2949:  * @error: the error code
 2950:  * @itemDes: the designation of the schema type
 2951:  * @item: the schema type
 2952:  * @itemElem: the node of the schema type
 2953:  * @attr: the invalid schema attribute
 2954:  * @message: the error message
 2955:  * @str1: the optional param for the error message
 2956:  *
 2957:  * Reports an attribute use error during parsing.
 2958:  */
 2959: static void
 2960: xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
 2961: 		    xmlParserErrors error,
 2962: 		    xmlNodePtr node,
 2963: 		    xmlSchemaBasicItemPtr ownerItem,
 2964: 		    const xmlSchemaAttributeUsePtr attruse,
 2965: 		    const char *message,
 2966: 		    const xmlChar *str1, const xmlChar *str2,
 2967: 		    const xmlChar *str3,const xmlChar *str4)
 2968: {
 2969:     xmlChar *str = NULL, *msg = NULL;
 2970: 
 2971:     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
 2972:     msg = xmlStrcat(msg, BAD_CAST ", ");
 2973:     msg = xmlStrcat(msg,
 2974: 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
 2975: 	WXS_BASIC_CAST attruse, NULL));
 2976:     FREE_AND_NULL(str);
 2977:     msg = xmlStrcat(msg, BAD_CAST ": ");
 2978:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2979:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2980:     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
 2981: 	(const char *) msg, str1, str2, str3, str4);
 2982:     xmlFree(msg);
 2983: }
 2984: 
 2985: /**
 2986:  * xmlSchemaPIllegalFacetAtomicErr:
 2987:  * @ctxt: the schema parser context
 2988:  * @error: the error code
 2989:  * @type: the schema type
 2990:  * @baseType: the base type of type
 2991:  * @facet: the illegal facet
 2992:  *
 2993:  * Reports an illegal facet for atomic simple types.
 2994:  */
 2995: static void
 2996: xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
 2997: 			  xmlParserErrors error,
 2998: 			  xmlSchemaTypePtr type,
 2999: 			  xmlSchemaTypePtr baseType,
 3000: 			  xmlSchemaFacetPtr facet)
 3001: {
 3002:     xmlChar *des = NULL, *strT = NULL;
 3003: 
 3004:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
 3005:     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
 3006: 	"%s: The facet '%s' is not allowed on types derived from the "
 3007: 	"type %s.\n",
 3008: 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
 3009: 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
 3010: 	NULL, NULL);
 3011:     FREE_AND_NULL(des);
 3012:     FREE_AND_NULL(strT);
 3013: }
 3014: 
 3015: /**
 3016:  * xmlSchemaPIllegalFacetListUnionErr:
 3017:  * @ctxt: the schema parser context
 3018:  * @error: the error code
 3019:  * @itemDes: the designation of the schema item involved
 3020:  * @item: the schema item involved
 3021:  * @facet: the illegal facet
 3022:  *
 3023:  * Reports an illegal facet for <list> and <union>.
 3024:  */
 3025: static void
 3026: xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
 3027: 			  xmlParserErrors error,
 3028: 			  xmlSchemaTypePtr type,
 3029: 			  xmlSchemaFacetPtr facet)
 3030: {
 3031:     xmlChar *des = NULL;
 3032: 
 3033:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
 3034: 	type->node);
 3035:     xmlSchemaPErr(ctxt, type->node, error,
 3036: 	"%s: The facet '%s' is not allowed.\n",
 3037: 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
 3038:     FREE_AND_NULL(des);
 3039: }
 3040: 
 3041: /**
 3042:  * xmlSchemaPMutualExclAttrErr:
 3043:  * @ctxt: the schema validation context
 3044:  * @error: the error code
 3045:  * @elemDes: the designation of the parent element node
 3046:  * @attr: the bad attribute node
 3047:  * @type: the corresponding type of the attribute node
 3048:  *
 3049:  * Reports an illegal attribute.
 3050:  */
 3051: static void
 3052: xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
 3053: 			 xmlParserErrors error,
 3054: 			 xmlSchemaBasicItemPtr ownerItem,
 3055: 			 xmlAttrPtr attr,
 3056: 			 const char *name1,
 3057: 			 const char *name2)
 3058: {
 3059:     xmlChar *des = NULL;
 3060: 
 3061:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
 3062:     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 3063: 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
 3064: 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
 3065:     FREE_AND_NULL(des);
 3066: }
 3067: 
 3068: /**
 3069:  * xmlSchemaPSimpleTypeErr:
 3070:  * @ctxt:  the schema validation context
 3071:  * @error: the error code
 3072:  * @type: the type specifier
 3073:  * @ownerDes: the designation of the owner
 3074:  * @ownerItem: the schema object if existent
 3075:  * @node: the validated node
 3076:  * @value: the validated value
 3077:  *
 3078:  * Reports a simple type validation error.
 3079:  * TODO: Should this report the value of an element as well?
 3080:  */
 3081: static void
 3082: xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
 3083: 			xmlParserErrors error,
 3084: 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
 3085: 			xmlNodePtr node,
 3086: 			xmlSchemaTypePtr type,
 3087: 			const char *expected,
 3088: 			const xmlChar *value,
 3089: 			const char *message,
 3090: 			const xmlChar *str1,
 3091: 			const xmlChar *str2)
 3092: {
 3093:     xmlChar *msg = NULL;
 3094: 
 3095:     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
 3096:     if (message == NULL) {
 3097: 	/*
 3098: 	* Use default messages.
 3099: 	*/
 3100: 	if (type != NULL) {
 3101: 	    if (node->type == XML_ATTRIBUTE_NODE)
 3102: 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 3103: 	    else
 3104: 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
 3105: 		"valid value of ");
 3106: 	    if (! xmlSchemaIsGlobalItem(type))
 3107: 		msg = xmlStrcat(msg, BAD_CAST "the local ");
 3108: 	    else
 3109: 		msg = xmlStrcat(msg, BAD_CAST "the ");
 3110: 
 3111: 	    if (WXS_IS_ATOMIC(type))
 3112: 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
 3113: 	    else if (WXS_IS_LIST(type))
 3114: 		msg = xmlStrcat(msg, BAD_CAST "list type");
 3115: 	    else if (WXS_IS_UNION(type))
 3116: 		msg = xmlStrcat(msg, BAD_CAST "union type");
 3117: 
 3118: 	    if (xmlSchemaIsGlobalItem(type)) {
 3119: 		xmlChar *str = NULL;
 3120: 		msg = xmlStrcat(msg, BAD_CAST " '");
 3121: 		if (type->builtInType != 0) {
 3122: 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
 3123: 		    msg = xmlStrcat(msg, type->name);
 3124: 		} else
 3125: 		    msg = xmlStrcat(msg,
 3126: 			xmlSchemaFormatQName(&str,
 3127: 			    type->targetNamespace, type->name));
 3128: 		msg = xmlStrcat(msg, BAD_CAST "'.");
 3129: 		FREE_AND_NULL(str);
 3130: 	    }
 3131: 	} else {
 3132: 	    if (node->type == XML_ATTRIBUTE_NODE)
 3133: 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
 3134: 	    else
 3135: 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
 3136: 		"valid.");
 3137: 	}
 3138: 	if (expected) {
 3139: 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
 3140: 	    msg = xmlStrcat(msg, BAD_CAST expected);
 3141: 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
 3142: 	} else
 3143: 	    msg = xmlStrcat(msg, BAD_CAST "\n");
 3144: 	if (node->type == XML_ATTRIBUTE_NODE)
 3145: 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
 3146: 	else
 3147: 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
 3148:     } else {
 3149: 	msg = xmlStrcat(msg, BAD_CAST message);
 3150: 	msg = xmlStrcat(msg, BAD_CAST ".\n");
 3151: 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
 3152: 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
 3153:     }
 3154:     /* Cleanup. */
 3155:     FREE_AND_NULL(msg)
 3156: }
 3157: 
 3158: /**
 3159:  * xmlSchemaPContentErr:
 3160:  * @ctxt: the schema parser context
 3161:  * @error: the error code
 3162:  * @onwerDes: the designation of the holder of the content
 3163:  * @ownerItem: the owner item of the holder of the content
 3164:  * @ownerElem: the node of the holder of the content
 3165:  * @child: the invalid child node
 3166:  * @message: the optional error message
 3167:  * @content: the optional string describing the correct content
 3168:  *
 3169:  * Reports an error concerning the content of a schema element.
 3170:  */
 3171: static void
 3172: xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
 3173: 		     xmlParserErrors error,
 3174: 		     xmlSchemaBasicItemPtr ownerItem,
 3175: 		     xmlNodePtr ownerElem,
 3176: 		     xmlNodePtr child,
 3177: 		     const char *message,
 3178: 		     const char *content)
 3179: {
 3180:     xmlChar *des = NULL;
 3181: 
 3182:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 3183:     if (message != NULL)
 3184: 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3185: 	    "%s: %s.\n",
 3186: 	    BAD_CAST des, BAD_CAST message);
 3187:     else {
 3188: 	if (content != NULL) {
 3189: 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3190: 		"%s: The content is not valid. Expected is %s.\n",
 3191: 		BAD_CAST des, BAD_CAST content);
 3192: 	} else {
 3193: 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3194: 		"%s: The content is not valid.\n",
 3195: 		BAD_CAST des, NULL);
 3196: 	}
 3197:     }
 3198:     FREE_AND_NULL(des)
 3199: }
 3200: 
 3201: /************************************************************************
 3202:  * 									*
 3203:  * 			Streamable error functions                      *
 3204:  * 									*
 3205:  ************************************************************************/
 3206: 
 3207: 
 3208: 
 3209: 
 3210: /************************************************************************
 3211:  * 									*
 3212:  * 			Validation helper functions			*
 3213:  * 									*
 3214:  ************************************************************************/
 3215: 
 3216: 
 3217: /************************************************************************
 3218:  * 									*
 3219:  * 			Allocation functions				*
 3220:  * 									*
 3221:  ************************************************************************/
 3222: 
 3223: /**
 3224:  * xmlSchemaNewSchemaForParserCtxt:
 3225:  * @ctxt:  a schema validation context
 3226:  *
 3227:  * Allocate a new Schema structure.
 3228:  *
 3229:  * Returns the newly allocated structure or NULL in case or error
 3230:  */
 3231: static xmlSchemaPtr
 3232: xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
 3233: {
 3234:     xmlSchemaPtr ret;
 3235: 
 3236:     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
 3237:     if (ret == NULL) {
 3238:         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
 3239:         return (NULL);
 3240:     }
 3241:     memset(ret, 0, sizeof(xmlSchema));
 3242:     ret->dict = ctxt->dict;
 3243:     xmlDictReference(ret->dict);
 3244: 
 3245:     return (ret);
 3246: }
 3247: 
 3248: /**
 3249:  * xmlSchemaNewFacet:
 3250:  *
 3251:  * Allocate a new Facet structure.
 3252:  *
 3253:  * Returns the newly allocated structure or NULL in case or error
 3254:  */
 3255: xmlSchemaFacetPtr
 3256: xmlSchemaNewFacet(void)
 3257: {
 3258:     xmlSchemaFacetPtr ret;
 3259: 
 3260:     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
 3261:     if (ret == NULL) {
 3262:         return (NULL);
 3263:     }
 3264:     memset(ret, 0, sizeof(xmlSchemaFacet));
 3265: 
 3266:     return (ret);
 3267: }
 3268: 
 3269: /**
 3270:  * xmlSchemaNewAnnot:
 3271:  * @ctxt:  a schema validation context
 3272:  * @node:  a node
 3273:  *
 3274:  * Allocate a new annotation structure.
 3275:  *
 3276:  * Returns the newly allocated structure or NULL in case or error
 3277:  */
 3278: static xmlSchemaAnnotPtr
 3279: xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 3280: {
 3281:     xmlSchemaAnnotPtr ret;
 3282: 
 3283:     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
 3284:     if (ret == NULL) {
 3285:         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
 3286:         return (NULL);
 3287:     }
 3288:     memset(ret, 0, sizeof(xmlSchemaAnnot));
 3289:     ret->content = node;
 3290:     return (ret);
 3291: }
 3292: 
 3293: static xmlSchemaItemListPtr
 3294: xmlSchemaItemListCreate(void)
 3295: {
 3296:     xmlSchemaItemListPtr ret;
 3297: 
 3298:     ret = xmlMalloc(sizeof(xmlSchemaItemList));
 3299:     if (ret == NULL) {
 3300: 	xmlSchemaPErrMemory(NULL,
 3301: 	    "allocating an item list structure", NULL);
 3302: 	return (NULL);
 3303:     }
 3304:     memset(ret, 0, sizeof(xmlSchemaItemList));
 3305:     return (ret);
 3306: }
 3307: 
 3308: static void
 3309: xmlSchemaItemListClear(xmlSchemaItemListPtr list)
 3310: {
 3311:     if (list->items != NULL) {
 3312: 	xmlFree(list->items);
 3313: 	list->items = NULL;
 3314:     }
 3315:     list->nbItems = 0;
 3316:     list->sizeItems = 0;
 3317: }
 3318: 
 3319: static int
 3320: xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
 3321: {
 3322:     if (list->items == NULL) {
 3323: 	list->items = (void **) xmlMalloc(
 3324: 	    20 * sizeof(void *));
 3325: 	if (list->items == NULL) {
 3326: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3327: 	    return(-1);
 3328: 	}
 3329: 	list->sizeItems = 20;
 3330:     } else if (list->sizeItems <= list->nbItems) {
 3331: 	list->sizeItems *= 2;
 3332: 	list->items = (void **) xmlRealloc(list->items,
 3333: 	    list->sizeItems * sizeof(void *));
 3334: 	if (list->items == NULL) {
 3335: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3336: 	    list->sizeItems = 0;
 3337: 	    return(-1);
 3338: 	}
 3339:     }
 3340:     list->items[list->nbItems++] = item;
 3341:     return(0);
 3342: }
 3343: 
 3344: static int
 3345: xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
 3346: 			 int initialSize,
 3347: 			 void *item)
 3348: {
 3349:     if (list->items == NULL) {
 3350: 	if (initialSize <= 0)
 3351: 	    initialSize = 1;
 3352: 	list->items = (void **) xmlMalloc(
 3353: 	    initialSize * sizeof(void *));
 3354: 	if (list->items == NULL) {
 3355: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3356: 	    return(-1);
 3357: 	}
 3358: 	list->sizeItems = initialSize;
 3359:     } else if (list->sizeItems <= list->nbItems) {
 3360: 	list->sizeItems *= 2;
 3361: 	list->items = (void **) xmlRealloc(list->items,
 3362: 	    list->sizeItems * sizeof(void *));
 3363: 	if (list->items == NULL) {
 3364: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3365: 	    list->sizeItems = 0;
 3366: 	    return(-1);
 3367: 	}
 3368:     }
 3369:     list->items[list->nbItems++] = item;
 3370:     return(0);
 3371: }
 3372: 
 3373: static int
 3374: xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
 3375: {
 3376:     if (list->items == NULL) {
 3377: 	list->items = (void **) xmlMalloc(
 3378: 	    20 * sizeof(void *));
 3379: 	if (list->items == NULL) {
 3380: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3381: 	    return(-1);
 3382: 	}
 3383: 	list->sizeItems = 20;
 3384:     } else if (list->sizeItems <= list->nbItems) {
 3385: 	list->sizeItems *= 2;
 3386: 	list->items = (void **) xmlRealloc(list->items,
 3387: 	    list->sizeItems * sizeof(void *));
 3388: 	if (list->items == NULL) {
 3389: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3390: 	    list->sizeItems = 0;
 3391: 	    return(-1);
 3392: 	}
 3393:     }
 3394:     /*
 3395:     * Just append if the index is greater/equal than the item count.
 3396:     */
 3397:     if (idx >= list->nbItems) {
 3398: 	list->items[list->nbItems++] = item;
 3399:     } else {
 3400: 	int i;
 3401: 	for (i = list->nbItems; i > idx; i--)
 3402: 	    list->items[i] = list->items[i-1];
 3403: 	list->items[idx] = item;
 3404: 	list->nbItems++;
 3405:     }
 3406:     return(0);
 3407: }
 3408: 
 3409: #if 0 /* enable if ever needed */
 3410: static int
 3411: xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
 3412: 			    int initialSize,
 3413: 			    void *item,
 3414: 			    int idx)
 3415: {
 3416:     if (list->items == NULL) {
 3417: 	if (initialSize <= 0)
 3418: 	    initialSize = 1;
 3419: 	list->items = (void **) xmlMalloc(
 3420: 	    initialSize * sizeof(void *));
 3421: 	if (list->items == NULL) {
 3422: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3423: 	    return(-1);
 3424: 	}
 3425: 	list->sizeItems = initialSize;
 3426:     } else if (list->sizeItems <= list->nbItems) {
 3427: 	list->sizeItems *= 2;
 3428: 	list->items = (void **) xmlRealloc(list->items,
 3429: 	    list->sizeItems * sizeof(void *));
 3430: 	if (list->items == NULL) {
 3431: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3432: 	    list->sizeItems = 0;
 3433: 	    return(-1);
 3434: 	}
 3435:     }
 3436:     /*
 3437:     * Just append if the index is greater/equal than the item count.
 3438:     */
 3439:     if (idx >= list->nbItems) {
 3440: 	list->items[list->nbItems++] = item;
 3441:     } else {
 3442: 	int i;
 3443: 	for (i = list->nbItems; i > idx; i--)
 3444: 	    list->items[i] = list->items[i-1];
 3445: 	list->items[idx] = item;
 3446: 	list->nbItems++;
 3447:     }
 3448:     return(0);
 3449: }
 3450: #endif
 3451: 
 3452: static int
 3453: xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
 3454: {
 3455:     int i;
 3456:     if ((list->items == NULL) || (idx >= list->nbItems)) {
 3457: 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
 3458: 	    "index error.\n");
 3459: 	return(-1);
 3460:     }
 3461: 
 3462:     if (list->nbItems == 1) {
 3463: 	/* TODO: Really free the list? */
 3464: 	xmlFree(list->items);
 3465: 	list->items = NULL;
 3466: 	list->nbItems = 0;
 3467: 	list->sizeItems = 0;
 3468:     } else if (list->nbItems -1 == idx) {
 3469: 	list->nbItems--;
 3470:     } else {
 3471: 	for (i = idx; i < list->nbItems -1; i++)
 3472: 	    list->items[i] = list->items[i+1];
 3473: 	list->nbItems--;
 3474:     }
 3475:     return(0);
 3476: }
 3477: 
 3478: /**
 3479:  * xmlSchemaItemListFree:
 3480:  * @annot:  a schema type structure
 3481:  *
 3482:  * Deallocate a annotation structure
 3483:  */
 3484: static void
 3485: xmlSchemaItemListFree(xmlSchemaItemListPtr list)
 3486: {
 3487:     if (list == NULL)
 3488: 	return;
 3489:     if (list->items != NULL)
 3490: 	xmlFree(list->items);
 3491:     xmlFree(list);
 3492: }
 3493: 
 3494: static void
 3495: xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
 3496: {
 3497:     if (bucket == NULL)
 3498: 	return;
 3499:     if (bucket->globals != NULL) {
 3500: 	xmlSchemaComponentListFree(bucket->globals);
 3501: 	xmlSchemaItemListFree(bucket->globals);
 3502:     }
 3503:     if (bucket->locals != NULL) {
 3504: 	xmlSchemaComponentListFree(bucket->locals);
 3505: 	xmlSchemaItemListFree(bucket->locals);
 3506:     }
 3507:     if (bucket->relations != NULL) {
 3508: 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
 3509: 	do {
 3510: 	    prev = cur;
 3511: 	    cur = cur->next;
 3512: 	    xmlFree(prev);
 3513: 	} while (cur != NULL);
 3514:     }
 3515:     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
 3516: 	xmlFreeDoc(bucket->doc);
 3517:     }
 3518:     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
 3519: 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
 3520: 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
 3521:     }
 3522:     xmlFree(bucket);
 3523: }
 3524: 
 3525: static xmlSchemaBucketPtr
 3526: xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
 3527: 			 int type, const xmlChar *targetNamespace)
 3528: {
 3529:     xmlSchemaBucketPtr ret;
 3530:     int size;
 3531:     xmlSchemaPtr mainSchema;
 3532: 
 3533:     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
 3534: 	PERROR_INT("xmlSchemaBucketCreate",
 3535: 	    "no main schema on constructor");
 3536: 	return(NULL);
 3537:     }
 3538:     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
 3539:     /* Create the schema bucket. */
 3540:     if (WXS_IS_BUCKET_INCREDEF(type))
 3541: 	size = sizeof(xmlSchemaInclude);
 3542:     else
 3543: 	size = sizeof(xmlSchemaImport);
 3544:     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
 3545:     if (ret == NULL) {
 3546: 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
 3547: 	return(NULL);
 3548:     }
 3549:     memset(ret, 0, size);
 3550:     ret->targetNamespace = targetNamespace;
 3551:     ret->type = type;
 3552:     ret->globals = xmlSchemaItemListCreate();
 3553:     if (ret->globals == NULL) {
 3554: 	xmlFree(ret);
 3555: 	return(NULL);
 3556:     }
 3557:     ret->locals = xmlSchemaItemListCreate();
 3558:     if (ret->locals == NULL) {
 3559: 	xmlFree(ret);
 3560: 	return(NULL);
 3561:     }
 3562:     /*
 3563:     * The following will assure that only the first bucket is marked as
 3564:     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
 3565:     * For each following import buckets an xmlSchema will be created.
 3566:     * An xmlSchema will be created for every distinct targetNamespace.
 3567:     * We assign the targetNamespace to the schemata here.
 3568:     */
 3569:     if (! WXS_HAS_BUCKETS(pctxt)) {
 3570: 	if (WXS_IS_BUCKET_INCREDEF(type)) {
 3571: 	    PERROR_INT("xmlSchemaBucketCreate",
 3572: 		"first bucket but it's an include or redefine");
 3573: 	    xmlSchemaBucketFree(ret);
 3574: 	    return(NULL);
 3575: 	}
 3576: 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
 3577: 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
 3578: 	/* Point to the *main* schema. */
 3579: 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
 3580: 	WXS_IMPBUCKET(ret)->schema = mainSchema;
 3581: 	/*
 3582: 	* Ensure that the main schema gets a targetNamespace.
 3583: 	*/
 3584: 	mainSchema->targetNamespace = targetNamespace;
 3585:     } else {
 3586: 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
 3587: 	    PERROR_INT("xmlSchemaBucketCreate",
 3588: 		"main bucket but it's not the first one");
 3589: 	    xmlSchemaBucketFree(ret);
 3590: 	    return(NULL);
 3591: 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
 3592: 	    /*
 3593: 	    * Create a schema for imports and assign the
 3594: 	    * targetNamespace.
 3595: 	    */
 3596: 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
 3597: 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
 3598: 		xmlSchemaBucketFree(ret);
 3599: 		return(NULL);
 3600: 	    }
 3601: 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
 3602: 	}
 3603:     }
 3604:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
 3605: 	int res;
 3606: 	/*
 3607: 	* Imports go into the "schemasImports" slot of the main *schema*.
 3608: 	* Note that we create an import entry for the main schema as well; i.e.,
 3609: 	* even if there's only one schema, we'll get an import.
 3610: 	*/
 3611: 	if (mainSchema->schemasImports == NULL) {
 3612: 	    mainSchema->schemasImports = xmlHashCreateDict(5,
 3613: 		WXS_CONSTRUCTOR(pctxt)->dict);
 3614: 	    if (mainSchema->schemasImports == NULL) {
 3615: 		xmlSchemaBucketFree(ret);
 3616: 		return(NULL);
 3617: 	    }
 3618: 	}
 3619: 	if (targetNamespace == NULL)
 3620: 	    res = xmlHashAddEntry(mainSchema->schemasImports,
 3621: 		XML_SCHEMAS_NO_NAMESPACE, ret);
 3622: 	else
 3623: 	    res = xmlHashAddEntry(mainSchema->schemasImports,
 3624: 		targetNamespace, ret);
 3625: 	if (res != 0) {
 3626: 	    PERROR_INT("xmlSchemaBucketCreate",
 3627: 		"failed to add the schema bucket to the hash");
 3628: 	    xmlSchemaBucketFree(ret);
 3629: 	    return(NULL);
 3630: 	}
 3631:     } else {
 3632: 	/* Set the @ownerImport of an include bucket. */
 3633: 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
 3634: 	    WXS_INCBUCKET(ret)->ownerImport =
 3635: 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
 3636: 	else
 3637: 	    WXS_INCBUCKET(ret)->ownerImport =
 3638: 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
 3639: 
 3640: 	/* Includes got into the "includes" slot of the *main* schema. */
 3641: 	if (mainSchema->includes == NULL) {
 3642: 	    mainSchema->includes = xmlSchemaItemListCreate();
 3643: 	    if (mainSchema->includes == NULL) {
 3644: 		xmlSchemaBucketFree(ret);
 3645: 		return(NULL);
 3646: 	    }
 3647: 	}
 3648: 	xmlSchemaItemListAdd(mainSchema->includes, ret);
 3649:     }
 3650:     /*
 3651:     * Add to list of all buckets; this is used for lookup
 3652:     * during schema construction time only.
 3653:     */
 3654:     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
 3655: 	return(NULL);
 3656:     return(ret);
 3657: }
 3658: 
 3659: static int
 3660: xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
 3661: {
 3662:     if (*list == NULL) {
 3663: 	*list = xmlSchemaItemListCreate();
 3664: 	if (*list == NULL)
 3665: 	    return(-1);
 3666:     }
 3667:     xmlSchemaItemListAddSize(*list, initialSize, item);
 3668:     return(0);
 3669: }
 3670: 
 3671: /**
 3672:  * xmlSchemaFreeAnnot:
 3673:  * @annot:  a schema type structure
 3674:  *
 3675:  * Deallocate a annotation structure
 3676:  */
 3677: static void
 3678: xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
 3679: {
 3680:     if (annot == NULL)
 3681:         return;
 3682:     if (annot->next == NULL) {
 3683: 	xmlFree(annot);
 3684:     } else {
 3685: 	xmlSchemaAnnotPtr prev;
 3686: 
 3687: 	do {
 3688: 	    prev = annot;
 3689: 	    annot = annot->next;
 3690: 	    xmlFree(prev);
 3691: 	} while (annot != NULL);
 3692:     }
 3693: }
 3694: 
 3695: /**
 3696:  * xmlSchemaFreeNotation:
 3697:  * @schema:  a schema notation structure
 3698:  *
 3699:  * Deallocate a Schema Notation structure.
 3700:  */
 3701: static void
 3702: xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
 3703: {
 3704:     if (nota == NULL)
 3705:         return;
 3706:     xmlFree(nota);
 3707: }
 3708: 
 3709: /**
 3710:  * xmlSchemaFreeAttribute:
 3711:  * @attr:  an attribute declaration
 3712:  *
 3713:  * Deallocates an attribute declaration structure.
 3714:  */
 3715: static void
 3716: xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
 3717: {
 3718:     if (attr == NULL)
 3719:         return;
 3720:     if (attr->annot != NULL)
 3721: 	xmlSchemaFreeAnnot(attr->annot);
 3722:     if (attr->defVal != NULL)
 3723: 	xmlSchemaFreeValue(attr->defVal);
 3724:     xmlFree(attr);
 3725: }
 3726: 
 3727: /**
 3728:  * xmlSchemaFreeAttributeUse:
 3729:  * @use:  an attribute use
 3730:  *
 3731:  * Deallocates an attribute use structure.
 3732:  */
 3733: static void
 3734: xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
 3735: {
 3736:     if (use == NULL)
 3737:         return;
 3738:     if (use->annot != NULL)
 3739: 	xmlSchemaFreeAnnot(use->annot);
 3740:     if (use->defVal != NULL)
 3741: 	xmlSchemaFreeValue(use->defVal);
 3742:     xmlFree(use);
 3743: }
 3744: 
 3745: /**
 3746:  * xmlSchemaFreeAttributeUseProhib:
 3747:  * @prohib:  an attribute use prohibition
 3748:  *
 3749:  * Deallocates an attribute use structure.
 3750:  */
 3751: static void
 3752: xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
 3753: {
 3754:     if (prohib == NULL)
 3755:         return;
 3756:     xmlFree(prohib);
 3757: }
 3758: 
 3759: /**
 3760:  * xmlSchemaFreeWildcardNsSet:
 3761:  * set:  a schema wildcard namespace
 3762:  *
 3763:  * Deallocates a list of wildcard constraint structures.
 3764:  */
 3765: static void
 3766: xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
 3767: {
 3768:     xmlSchemaWildcardNsPtr next;
 3769: 
 3770:     while (set != NULL) {
 3771: 	next = set->next;
 3772: 	xmlFree(set);
 3773: 	set = next;
 3774:     }
 3775: }
 3776: 
 3777: /**
 3778:  * xmlSchemaFreeWildcard:
 3779:  * @wildcard:  a wildcard structure
 3780:  *
 3781:  * Deallocates a wildcard structure.
 3782:  */
 3783: void
 3784: xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
 3785: {
 3786:     if (wildcard == NULL)
 3787:         return;
 3788:     if (wildcard->annot != NULL)
 3789:         xmlSchemaFreeAnnot(wildcard->annot);
 3790:     if (wildcard->nsSet != NULL)
 3791: 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
 3792:     if (wildcard->negNsSet != NULL)
 3793: 	xmlFree(wildcard->negNsSet);
 3794:     xmlFree(wildcard);
 3795: }
 3796: 
 3797: /**
 3798:  * xmlSchemaFreeAttributeGroup:
 3799:  * @schema:  a schema attribute group structure
 3800:  *
 3801:  * Deallocate a Schema Attribute Group structure.
 3802:  */
 3803: static void
 3804: xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
 3805: {
 3806:     if (attrGr == NULL)
 3807:         return;
 3808:     if (attrGr->annot != NULL)
 3809:         xmlSchemaFreeAnnot(attrGr->annot);
 3810:     if (attrGr->attrUses != NULL)
 3811: 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
 3812:     xmlFree(attrGr);
 3813: }
 3814: 
 3815: /**
 3816:  * xmlSchemaFreeQNameRef:
 3817:  * @item: a QName reference structure
 3818:  *
 3819:  * Deallocatea a QName reference structure.
 3820:  */
 3821: static void
 3822: xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
 3823: {
 3824:     xmlFree(item);
 3825: }
 3826: 
 3827: /**
 3828:  * xmlSchemaFreeTypeLinkList:
 3829:  * @alink: a type link
 3830:  *
 3831:  * Deallocate a list of types.
 3832:  */
 3833: static void
 3834: xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
 3835: {
 3836:     xmlSchemaTypeLinkPtr next;
 3837: 
 3838:     while (link != NULL) {
 3839: 	next = link->next;
 3840: 	xmlFree(link);
 3841: 	link = next;
 3842:     }
 3843: }
 3844: 
 3845: static void
 3846: xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
 3847: {
 3848:     xmlSchemaIDCStateObjPtr next;
 3849:     while (sto != NULL) {
 3850: 	next = sto->next;
 3851: 	if (sto->history != NULL)
 3852: 	    xmlFree(sto->history);
 3853: 	if (sto->xpathCtxt != NULL)
 3854: 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
 3855: 	xmlFree(sto);
 3856: 	sto = next;
 3857:     }
 3858: }
 3859: 
 3860: /**
 3861:  * xmlSchemaFreeIDC:
 3862:  * @idc: a identity-constraint definition
 3863:  *
 3864:  * Deallocates an identity-constraint definition.
 3865:  */
 3866: static void
 3867: xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
 3868: {
 3869:     xmlSchemaIDCSelectPtr cur, prev;
 3870: 
 3871:     if (idcDef == NULL)
 3872: 	return;
 3873:     if (idcDef->annot != NULL)
 3874:         xmlSchemaFreeAnnot(idcDef->annot);
 3875:     /* Selector */
 3876:     if (idcDef->selector != NULL) {
 3877: 	if (idcDef->selector->xpathComp != NULL)
 3878: 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
 3879: 	xmlFree(idcDef->selector);
 3880:     }
 3881:     /* Fields */
 3882:     if (idcDef->fields != NULL) {
 3883: 	cur = idcDef->fields;
 3884: 	do {
 3885: 	    prev = cur;
 3886: 	    cur = cur->next;
 3887: 	    if (prev->xpathComp != NULL)
 3888: 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
 3889: 	    xmlFree(prev);
 3890: 	} while (cur != NULL);
 3891:     }
 3892:     xmlFree(idcDef);
 3893: }
 3894: 
 3895: /**
 3896:  * xmlSchemaFreeElement:
 3897:  * @schema:  a schema element structure
 3898:  *
 3899:  * Deallocate a Schema Element structure.
 3900:  */
 3901: static void
 3902: xmlSchemaFreeElement(xmlSchemaElementPtr elem)
 3903: {
 3904:     if (elem == NULL)
 3905:         return;
 3906:     if (elem->annot != NULL)
 3907:         xmlSchemaFreeAnnot(elem->annot);
 3908:     if (elem->contModel != NULL)
 3909:         xmlRegFreeRegexp(elem->contModel);
 3910:     if (elem->defVal != NULL)
 3911: 	xmlSchemaFreeValue(elem->defVal);
 3912:     xmlFree(elem);
 3913: }
 3914: 
 3915: /**
 3916:  * xmlSchemaFreeFacet:
 3917:  * @facet:  a schema facet structure
 3918:  *
 3919:  * Deallocate a Schema Facet structure.
 3920:  */
 3921: void
 3922: xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
 3923: {
 3924:     if (facet == NULL)
 3925:         return;
 3926:     if (facet->val != NULL)
 3927:         xmlSchemaFreeValue(facet->val);
 3928:     if (facet->regexp != NULL)
 3929:         xmlRegFreeRegexp(facet->regexp);
 3930:     if (facet->annot != NULL)
 3931:         xmlSchemaFreeAnnot(facet->annot);
 3932:     xmlFree(facet);
 3933: }
 3934: 
 3935: /**
 3936:  * xmlSchemaFreeType:
 3937:  * @type:  a schema type structure
 3938:  *
 3939:  * Deallocate a Schema Type structure.
 3940:  */
 3941: void
 3942: xmlSchemaFreeType(xmlSchemaTypePtr type)
 3943: {
 3944:     if (type == NULL)
 3945:         return;
 3946:     if (type->annot != NULL)
 3947:         xmlSchemaFreeAnnot(type->annot);
 3948:     if (type->facets != NULL) {
 3949:         xmlSchemaFacetPtr facet, next;
 3950: 
 3951:         facet = type->facets;
 3952:         while (facet != NULL) {
 3953:             next = facet->next;
 3954:             xmlSchemaFreeFacet(facet);
 3955:             facet = next;
 3956:         }
 3957:     }
 3958:     if (type->attrUses != NULL)
 3959: 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
 3960:     if (type->memberTypes != NULL)
 3961: 	xmlSchemaFreeTypeLinkList(type->memberTypes);
 3962:     if (type->facetSet != NULL) {
 3963: 	xmlSchemaFacetLinkPtr next, link;
 3964: 
 3965: 	link = type->facetSet;
 3966: 	do {
 3967: 	    next = link->next;
 3968: 	    xmlFree(link);
 3969: 	    link = next;
 3970: 	} while (link != NULL);
 3971:     }
 3972:     if (type->contModel != NULL)
 3973:         xmlRegFreeRegexp(type->contModel);
 3974:     xmlFree(type);
 3975: }
 3976: 
 3977: /**
 3978:  * xmlSchemaFreeModelGroupDef:
 3979:  * @item:  a schema model group definition
 3980:  *
 3981:  * Deallocates a schema model group definition.
 3982:  */
 3983: static void
 3984: xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
 3985: {
 3986:     if (item->annot != NULL)
 3987: 	xmlSchemaFreeAnnot(item->annot);
 3988:     xmlFree(item);
 3989: }
 3990: 
 3991: /**
 3992:  * xmlSchemaFreeModelGroup:
 3993:  * @item:  a schema model group
 3994:  *
 3995:  * Deallocates a schema model group structure.
 3996:  */
 3997: static void
 3998: xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
 3999: {
 4000:     if (item->annot != NULL)
 4001: 	xmlSchemaFreeAnnot(item->annot);
 4002:     xmlFree(item);
 4003: }
 4004: 
 4005: static void
 4006: xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
 4007: {
 4008:     if ((list == NULL) || (list->nbItems == 0))
 4009: 	return;
 4010:     {
 4011: 	xmlSchemaTreeItemPtr item;
 4012: 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
 4013: 	int i;
 4014: 
 4015: 	for (i = 0; i < list->nbItems; i++) {
 4016: 	    item = items[i];
 4017: 	    if (item == NULL)
 4018: 		continue;
 4019: 	    switch (item->type) {
 4020: 		case XML_SCHEMA_TYPE_SIMPLE:
 4021: 		case XML_SCHEMA_TYPE_COMPLEX:
 4022: 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
 4023: 		    break;
 4024: 		case XML_SCHEMA_TYPE_ATTRIBUTE:
 4025: 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
 4026: 		    break;
 4027: 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 4028: 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
 4029: 		    break;
 4030: 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 4031: 		    xmlSchemaFreeAttributeUseProhib(
 4032: 			(xmlSchemaAttributeUseProhibPtr) item);
 4033: 		    break;
 4034: 		case XML_SCHEMA_TYPE_ELEMENT:
 4035: 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
 4036: 		    break;
 4037: 		case XML_SCHEMA_TYPE_PARTICLE:
 4038: 		    if (item->annot != NULL)
 4039: 			xmlSchemaFreeAnnot(item->annot);
 4040: 		    xmlFree(item);
 4041: 		    break;
 4042: 		case XML_SCHEMA_TYPE_SEQUENCE:
 4043: 		case XML_SCHEMA_TYPE_CHOICE:
 4044: 		case XML_SCHEMA_TYPE_ALL:
 4045: 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
 4046: 		    break;
 4047: 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 4048: 		    xmlSchemaFreeAttributeGroup(
 4049: 			(xmlSchemaAttributeGroupPtr) item);
 4050: 		    break;
 4051: 		case XML_SCHEMA_TYPE_GROUP:
 4052: 		    xmlSchemaFreeModelGroupDef(
 4053: 			(xmlSchemaModelGroupDefPtr) item);
 4054: 		    break;
 4055: 		case XML_SCHEMA_TYPE_ANY:
 4056: 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 4057: 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
 4058: 		    break;
 4059: 		case XML_SCHEMA_TYPE_IDC_KEY:
 4060: 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
 4061: 		case XML_SCHEMA_TYPE_IDC_KEYREF:
 4062: 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
 4063: 		    break;
 4064: 		case XML_SCHEMA_TYPE_NOTATION:
 4065: 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
 4066: 		    break;
 4067: 		case XML_SCHEMA_EXTRA_QNAMEREF:
 4068: 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
 4069: 		    break;
 4070: 		default: {
 4071: 		    /* TODO: This should never be hit. */
 4072: 		    xmlSchemaPSimpleInternalErr(NULL,
 4073: 			"Internal error: xmlSchemaComponentListFree, "
 4074: 			"unexpected component type '%s'\n",
 4075: 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
 4076: 			 }
 4077: 		    break;
 4078: 	    }
 4079: 	}
 4080: 	list->nbItems = 0;
 4081:     }
 4082: }
 4083: 
 4084: /**
 4085:  * xmlSchemaFree:
 4086:  * @schema:  a schema structure
 4087:  *
 4088:  * Deallocate a Schema structure.
 4089:  */
 4090: void
 4091: xmlSchemaFree(xmlSchemaPtr schema)
 4092: {
 4093:     if (schema == NULL)
 4094:         return;
 4095:     /* @volatiles is not used anymore :-/ */
 4096:     if (schema->volatiles != NULL)
 4097: 	TODO
 4098:     /*
 4099:     * Note that those slots are not responsible for freeing
 4100:     * schema components anymore; this will now be done by
 4101:     * the schema buckets.
 4102:     */
 4103:     if (schema->notaDecl != NULL)
 4104:         xmlHashFree(schema->notaDecl, NULL);
 4105:     if (schema->attrDecl != NULL)
 4106:         xmlHashFree(schema->attrDecl, NULL);
 4107:     if (schema->attrgrpDecl != NULL)
 4108:         xmlHashFree(schema->attrgrpDecl, NULL);
 4109:     if (schema->elemDecl != NULL)
 4110:         xmlHashFree(schema->elemDecl, NULL);
 4111:     if (schema->typeDecl != NULL)
 4112:         xmlHashFree(schema->typeDecl, NULL);
 4113:     if (schema->groupDecl != NULL)
 4114:         xmlHashFree(schema->groupDecl, NULL);
 4115:     if (schema->idcDef != NULL)
 4116:         xmlHashFree(schema->idcDef, NULL);
 4117: 
 4118:     if (schema->schemasImports != NULL)
 4119: 	xmlHashFree(schema->schemasImports,
 4120: 		    (xmlHashDeallocator) xmlSchemaBucketFree);
 4121:     if (schema->includes != NULL) {
 4122: 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
 4123: 	int i;
 4124: 	for (i = 0; i < list->nbItems; i++) {
 4125: 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
 4126: 	}
 4127: 	xmlSchemaItemListFree(list);
 4128:     }
 4129:     if (schema->annot != NULL)
 4130:         xmlSchemaFreeAnnot(schema->annot);
 4131:     /* Never free the doc here, since this will be done by the buckets. */
 4132: 
 4133:     xmlDictFree(schema->dict);
 4134:     xmlFree(schema);
 4135: }
 4136: 
 4137: /************************************************************************
 4138:  * 									*
 4139:  * 			Debug functions					*
 4140:  * 									*
 4141:  ************************************************************************/
 4142: 
 4143: #ifdef LIBXML_OUTPUT_ENABLED
 4144: 
 4145: static void
 4146: xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
 4147: 
 4148: /**
 4149:  * xmlSchemaElementDump:
 4150:  * @elem:  an element
 4151:  * @output:  the file output
 4152:  *
 4153:  * Dump the element
 4154:  */
 4155: static void
 4156: xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
 4157:                      const xmlChar * name ATTRIBUTE_UNUSED,
 4158: 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
 4159:                      const xmlChar * context ATTRIBUTE_UNUSED)
 4160: {
 4161:     if (elem == NULL)
 4162:         return;
 4163: 
 4164: 
 4165:     fprintf(output, "Element");
 4166:     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
 4167: 	fprintf(output, " (global)");
 4168:     fprintf(output, ": '%s' ", elem->name);
 4169:     if (namespace != NULL)
 4170: 	fprintf(output, "ns '%s'", namespace);
 4171:     fprintf(output, "\n");
 4172: #if 0
 4173:     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
 4174: 	fprintf(output, "  min %d ", elem->minOccurs);
 4175:         if (elem->maxOccurs >= UNBOUNDED)
 4176:             fprintf(output, "max: unbounded\n");
 4177:         else if (elem->maxOccurs != 1)
 4178:             fprintf(output, "max: %d\n", elem->maxOccurs);
 4179:         else
 4180:             fprintf(output, "\n");
 4181:     }
 4182: #endif
 4183:     /*
 4184:     * Misc other properties.
 4185:     */
 4186:     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
 4187: 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
 4188: 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
 4189: 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
 4190: 	fprintf(output, "  props: ");
 4191: 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
 4192: 	    fprintf(output, "[fixed] ");
 4193: 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
 4194: 	    fprintf(output, "[default] ");
 4195: 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
 4196: 	    fprintf(output, "[abstract] ");
 4197: 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
 4198: 	    fprintf(output, "[nillable] ");
 4199: 	fprintf(output, "\n");
 4200:     }
 4201:     /*
 4202:     * Default/fixed value.
 4203:     */
 4204:     if (elem->value != NULL)
 4205: 	fprintf(output, "  value: '%s'\n", elem->value);
 4206:     /*
 4207:     * Type.
 4208:     */
 4209:     if (elem->namedType != NULL) {
 4210: 	fprintf(output, "  type: '%s' ", elem->namedType);
 4211: 	if (elem->namedTypeNs != NULL)
 4212: 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
 4213: 	else
 4214: 	    fprintf(output, "\n");
 4215:     } else if (elem->subtypes != NULL) {
 4216: 	/*
 4217: 	* Dump local types.
 4218: 	*/
 4219: 	xmlSchemaTypeDump(elem->subtypes, output);
 4220:     }
 4221:     /*
 4222:     * Substitution group.
 4223:     */
 4224:     if (elem->substGroup != NULL) {
 4225: 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
 4226: 	if (elem->substGroupNs != NULL)
 4227: 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
 4228: 	else
 4229: 	    fprintf(output, "\n");
 4230:     }
 4231: }
 4232: 
 4233: /**
 4234:  * xmlSchemaAnnotDump:
 4235:  * @output:  the file output
 4236:  * @annot:  a annotation
 4237:  *
 4238:  * Dump the annotation
 4239:  */
 4240: static void
 4241: xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
 4242: {
 4243:     xmlChar *content;
 4244: 
 4245:     if (annot == NULL)
 4246:         return;
 4247: 
 4248:     content = xmlNodeGetContent(annot->content);
 4249:     if (content != NULL) {
 4250:         fprintf(output, "  Annot: %s\n", content);
 4251:         xmlFree(content);
 4252:     } else
 4253:         fprintf(output, "  Annot: empty\n");
 4254: }
 4255: 
 4256: /**
 4257:  * xmlSchemaContentModelDump:
 4258:  * @particle: the schema particle
 4259:  * @output: the file output
 4260:  * @depth: the depth used for intentation
 4261:  *
 4262:  * Dump a SchemaType structure
 4263:  */
 4264: static void
 4265: xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
 4266: {
 4267:     xmlChar *str = NULL;
 4268:     xmlSchemaTreeItemPtr term;
 4269:     char shift[100];
 4270:     int i;
 4271: 
 4272:     if (particle == NULL)
 4273: 	return;
 4274:     for (i = 0;((i < depth) && (i < 25));i++)
 4275:         shift[2 * i] = shift[2 * i + 1] = ' ';
 4276:     shift[2 * i] = shift[2 * i + 1] = 0;
 4277:     fprintf(output, "%s", shift);
 4278:     if (particle->children == NULL) {
 4279: 	fprintf(output, "MISSING particle term\n");
 4280: 	return;
 4281:     }
 4282:     term = particle->children;
 4283:     if (term == NULL) {
 4284: 	fprintf(output, "(NULL)");
 4285:     } else {
 4286: 	switch (term->type) {
 4287: 	    case XML_SCHEMA_TYPE_ELEMENT:
 4288: 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
 4289: 		    ((xmlSchemaElementPtr)term)->targetNamespace,
 4290: 		    ((xmlSchemaElementPtr)term)->name));
 4291: 		FREE_AND_NULL(str);
 4292: 		break;
 4293: 	    case XML_SCHEMA_TYPE_SEQUENCE:
 4294: 		fprintf(output, "SEQUENCE");
 4295: 		break;
 4296: 	    case XML_SCHEMA_TYPE_CHOICE:
 4297: 		fprintf(output, "CHOICE");
 4298: 		break;
 4299: 	    case XML_SCHEMA_TYPE_ALL:
 4300: 		fprintf(output, "ALL");
 4301: 		break;
 4302: 	    case XML_SCHEMA_TYPE_ANY:
 4303: 		fprintf(output, "ANY");
 4304: 		break;
 4305: 	    default:
 4306: 		fprintf(output, "UNKNOWN\n");
 4307: 		return;
 4308: 	}
 4309:     }
 4310:     if (particle->minOccurs != 1)
 4311: 	fprintf(output, " min: %d", particle->minOccurs);
 4312:     if (particle->maxOccurs >= UNBOUNDED)
 4313: 	fprintf(output, " max: unbounded");
 4314:     else if (particle->maxOccurs != 1)
 4315: 	fprintf(output, " max: %d", particle->maxOccurs);
 4316:     fprintf(output, "\n");
 4317:     if (term &&
 4318: 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
 4319: 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
 4320: 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
 4321: 	 (term->children != NULL)) {
 4322: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
 4323: 	    output, depth +1);
 4324:     }
 4325:     if (particle->next != NULL)
 4326: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
 4327: 		output, depth);
 4328: }
 4329: 
 4330: /**
 4331:  * xmlSchemaAttrUsesDump:
 4332:  * @uses:  attribute uses list
 4333:  * @output:  the file output
 4334:  *
 4335:  * Dumps a list of attribute use components.
 4336:  */
 4337: static void
 4338: xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
 4339: {
 4340:     xmlSchemaAttributeUsePtr use;
 4341:     xmlSchemaAttributeUseProhibPtr prohib;
 4342:     xmlSchemaQNameRefPtr ref;
 4343:     const xmlChar *name, *tns;
 4344:     xmlChar *str = NULL;
 4345:     int i;
 4346: 
 4347:     if ((uses == NULL) || (uses->nbItems == 0))
 4348:         return;
 4349: 
 4350:     fprintf(output, "  attributes:\n");
 4351:     for (i = 0; i < uses->nbItems; i++) {
 4352: 	use = uses->items[i];
 4353: 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
 4354: 	    fprintf(output, "  [prohibition] ");
 4355: 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
 4356: 	    name = prohib->name;
 4357: 	    tns = prohib->targetNamespace;
 4358: 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
 4359: 	    fprintf(output, "  [reference] ");
 4360: 	    ref = (xmlSchemaQNameRefPtr) use;
 4361: 	    name = ref->name;
 4362: 	    tns = ref->targetNamespace;
 4363: 	} else {
 4364: 	    fprintf(output, "  [use] ");
 4365: 	    name = WXS_ATTRUSE_DECL_NAME(use);
 4366: 	    tns = WXS_ATTRUSE_DECL_TNS(use);
 4367: 	}
 4368: 	fprintf(output, "'%s'\n",
 4369: 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
 4370: 	FREE_AND_NULL(str);
 4371:     }
 4372: }
 4373: 
 4374: /**
 4375:  * xmlSchemaTypeDump:
 4376:  * @output:  the file output
 4377:  * @type:  a type structure
 4378:  *
 4379:  * Dump a SchemaType structure
 4380:  */
 4381: static void
 4382: xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
 4383: {
 4384:     if (type == NULL) {
 4385:         fprintf(output, "Type: NULL\n");
 4386:         return;
 4387:     }
 4388:     fprintf(output, "Type: ");
 4389:     if (type->name != NULL)
 4390:         fprintf(output, "'%s' ", type->name);
 4391:     else
 4392:         fprintf(output, "(no name) ");
 4393:     if (type->targetNamespace != NULL)
 4394: 	fprintf(output, "ns '%s' ", type->targetNamespace);
 4395:     switch (type->type) {
 4396:         case XML_SCHEMA_TYPE_BASIC:
 4397:             fprintf(output, "[basic] ");
 4398:             break;
 4399:         case XML_SCHEMA_TYPE_SIMPLE:
 4400:             fprintf(output, "[simple] ");
 4401:             break;
 4402:         case XML_SCHEMA_TYPE_COMPLEX:
 4403:             fprintf(output, "[complex] ");
 4404:             break;
 4405:         case XML_SCHEMA_TYPE_SEQUENCE:
 4406:             fprintf(output, "[sequence] ");
 4407:             break;
 4408:         case XML_SCHEMA_TYPE_CHOICE:
 4409:             fprintf(output, "[choice] ");
 4410:             break;
 4411:         case XML_SCHEMA_TYPE_ALL:
 4412:             fprintf(output, "[all] ");
 4413:             break;
 4414:         case XML_SCHEMA_TYPE_UR:
 4415:             fprintf(output, "[ur] ");
 4416:             break;
 4417:         case XML_SCHEMA_TYPE_RESTRICTION:
 4418:             fprintf(output, "[restriction] ");
 4419:             break;
 4420:         case XML_SCHEMA_TYPE_EXTENSION:
 4421:             fprintf(output, "[extension] ");
 4422:             break;
 4423:         default:
 4424:             fprintf(output, "[unknown type %d] ", type->type);
 4425:             break;
 4426:     }
 4427:     fprintf(output, "content: ");
 4428:     switch (type->contentType) {
 4429:         case XML_SCHEMA_CONTENT_UNKNOWN:
 4430:             fprintf(output, "[unknown] ");
 4431:             break;
 4432:         case XML_SCHEMA_CONTENT_EMPTY:
 4433:             fprintf(output, "[empty] ");
 4434:             break;
 4435:         case XML_SCHEMA_CONTENT_ELEMENTS:
 4436:             fprintf(output, "[element] ");
 4437:             break;
 4438:         case XML_SCHEMA_CONTENT_MIXED:
 4439:             fprintf(output, "[mixed] ");
 4440:             break;
 4441:         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
 4442: 	/* not used. */
 4443:             break;
 4444:         case XML_SCHEMA_CONTENT_BASIC:
 4445:             fprintf(output, "[basic] ");
 4446:             break;
 4447:         case XML_SCHEMA_CONTENT_SIMPLE:
 4448:             fprintf(output, "[simple] ");
 4449:             break;
 4450:         case XML_SCHEMA_CONTENT_ANY:
 4451:             fprintf(output, "[any] ");
 4452:             break;
 4453:     }
 4454:     fprintf(output, "\n");
 4455:     if (type->base != NULL) {
 4456:         fprintf(output, "  base type: '%s'", type->base);
 4457: 	if (type->baseNs != NULL)
 4458: 	    fprintf(output, " ns '%s'\n", type->baseNs);
 4459: 	else
 4460: 	    fprintf(output, "\n");
 4461:     }
 4462:     if (type->attrUses != NULL)
 4463: 	xmlSchemaAttrUsesDump(type->attrUses, output);
 4464:     if (type->annot != NULL)
 4465:         xmlSchemaAnnotDump(output, type->annot);
 4466: #ifdef DUMP_CONTENT_MODEL
 4467:     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
 4468: 	(type->subtypes != NULL)) {
 4469: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
 4470: 	    output, 1);
 4471:     }
 4472: #endif
 4473: }
 4474: 
 4475: /**
 4476:  * xmlSchemaDump:
 4477:  * @output:  the file output
 4478:  * @schema:  a schema structure
 4479:  *
 4480:  * Dump a Schema structure.
 4481:  */
 4482: void
 4483: xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
 4484: {
 4485:     if (output == NULL)
 4486:         return;
 4487:     if (schema == NULL) {
 4488:         fprintf(output, "Schemas: NULL\n");
 4489:         return;
 4490:     }
 4491:     fprintf(output, "Schemas: ");
 4492:     if (schema->name != NULL)
 4493:         fprintf(output, "%s, ", schema->name);
 4494:     else
 4495:         fprintf(output, "no name, ");
 4496:     if (schema->targetNamespace != NULL)
 4497:         fprintf(output, "%s", (const char *) schema->targetNamespace);
 4498:     else
 4499:         fprintf(output, "no target namespace");
 4500:     fprintf(output, "\n");
 4501:     if (schema->annot != NULL)
 4502:         xmlSchemaAnnotDump(output, schema->annot);
 4503:     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
 4504:                 output);
 4505:     xmlHashScanFull(schema->elemDecl,
 4506:                     (xmlHashScannerFull) xmlSchemaElementDump, output);
 4507: }
 4508: 
 4509: #ifdef DEBUG_IDC_NODE_TABLE
 4510: /**
 4511:  * xmlSchemaDebugDumpIDCTable:
 4512:  * @vctxt: the WXS validation context
 4513:  *
 4514:  * Displays the current IDC table for debug purposes.
 4515:  */
 4516: static void
 4517: xmlSchemaDebugDumpIDCTable(FILE * output,
 4518: 			   const xmlChar *namespaceName,
 4519: 			   const xmlChar *localName,
 4520: 			   xmlSchemaPSVIIDCBindingPtr bind)
 4521: {
 4522:     xmlChar *str = NULL;
 4523:     const xmlChar *value;
 4524:     xmlSchemaPSVIIDCNodePtr tab;
 4525:     xmlSchemaPSVIIDCKeyPtr key;
 4526:     int i, j, res;
 4527: 
 4528:     fprintf(output, "IDC: TABLES on '%s'\n",
 4529: 	xmlSchemaFormatQName(&str, namespaceName, localName));
 4530:     FREE_AND_NULL(str)
 4531: 
 4532:     if (bind == NULL)
 4533: 	return;
 4534:     do {
 4535: 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
 4536: 	    xmlSchemaGetComponentQName(&str,
 4537: 		bind->definition), bind->nbNodes);
 4538: 	FREE_AND_NULL(str)
 4539: 	for (i = 0; i < bind->nbNodes; i++) {
 4540: 	    tab = bind->nodeTable[i];
 4541: 	    fprintf(output, "         ( ");
 4542: 	    for (j = 0; j < bind->definition->nbFields; j++) {
 4543: 		key = tab->keys[j];
 4544: 		if ((key != NULL) && (key->val != NULL)) {
 4545: 		    res = xmlSchemaGetCanonValue(key->val, &value);
 4546: 		    if (res >= 0)
 4547: 			fprintf(output, "'%s' ", value);
 4548: 		    else
 4549: 			fprintf(output, "CANON-VALUE-FAILED ");
 4550: 		    if (res == 0)
 4551: 			FREE_AND_NULL(value)
 4552: 		} else if (key != NULL)
 4553: 		    fprintf(output, "(no val), ");
 4554: 		else
 4555: 		    fprintf(output, "(key missing), ");
 4556: 	    }
 4557: 	    fprintf(output, ")\n");
 4558: 	}
 4559: 	if (bind->dupls && bind->dupls->nbItems) {
 4560: 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
 4561: 	    for (i = 0; i < bind->dupls->nbItems; i++) {
 4562: 		tab = bind->dupls->items[i];
 4563: 		fprintf(output, "         ( ");
 4564: 		for (j = 0; j < bind->definition->nbFields; j++) {
 4565: 		    key = tab->keys[j];
 4566: 		    if ((key != NULL) && (key->val != NULL)) {
 4567: 			res = xmlSchemaGetCanonValue(key->val, &value);
 4568: 			if (res >= 0)
 4569: 			    fprintf(output, "'%s' ", value);
 4570: 			else
 4571: 			    fprintf(output, "CANON-VALUE-FAILED ");
 4572: 			if (res == 0)
 4573: 			    FREE_AND_NULL(value)
 4574: 		    } else if (key != NULL)
 4575: 		    fprintf(output, "(no val), ");
 4576: 			else
 4577: 			    fprintf(output, "(key missing), ");
 4578: 		}
 4579: 		fprintf(output, ")\n");
 4580: 	    }
 4581: 	}
 4582: 	bind = bind->next;
 4583:     } while (bind != NULL);
 4584: }
 4585: #endif /* DEBUG_IDC */
 4586: #endif /* LIBXML_OUTPUT_ENABLED */
 4587: 
 4588: /************************************************************************
 4589:  *									*
 4590:  * 			Utilities					*
 4591:  *									*
 4592:  ************************************************************************/
 4593: 
 4594: /**
 4595:  * xmlSchemaGetPropNode:
 4596:  * @node: the element node
 4597:  * @name: the name of the attribute
 4598:  *
 4599:  * Seeks an attribute with a name of @name in
 4600:  * no namespace.
 4601:  *
 4602:  * Returns the attribute or NULL if not present.
 4603:  */
 4604: static xmlAttrPtr
 4605: xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
 4606: {
 4607:     xmlAttrPtr prop;
 4608: 
 4609:     if ((node == NULL) || (name == NULL))
 4610: 	return(NULL);
 4611:     prop = node->properties;
 4612:     while (prop != NULL) {
 4613:         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
 4614: 	    return(prop);
 4615: 	prop = prop->next;
 4616:     }
 4617:     return (NULL);
 4618: }
 4619: 
 4620: /**
 4621:  * xmlSchemaGetPropNodeNs:
 4622:  * @node: the element node
 4623:  * @uri: the uri
 4624:  * @name: the name of the attribute
 4625:  *
 4626:  * Seeks an attribute with a local name of @name and
 4627:  * a namespace URI of @uri.
 4628:  *
 4629:  * Returns the attribute or NULL if not present.
 4630:  */
 4631: static xmlAttrPtr
 4632: xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
 4633: {
 4634:     xmlAttrPtr prop;
 4635: 
 4636:     if ((node == NULL) || (name == NULL))
 4637: 	return(NULL);
 4638:     prop = node->properties;
 4639:     while (prop != NULL) {
 4640: 	if ((prop->ns != NULL) &&
 4641: 	    xmlStrEqual(prop->name, BAD_CAST name) &&
 4642: 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
 4643: 	    return(prop);
 4644: 	prop = prop->next;
 4645:     }
 4646:     return (NULL);
 4647: }
 4648: 
 4649: static const xmlChar *
 4650: xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 4651: {
 4652:     xmlChar *val;
 4653:     const xmlChar *ret;
 4654: 
 4655:     val = xmlNodeGetContent(node);
 4656:     if (val == NULL)
 4657: 	val = xmlStrdup((xmlChar *)"");
 4658:     ret = xmlDictLookup(ctxt->dict, val, -1);
 4659:     xmlFree(val);
 4660:     return(ret);
 4661: }
 4662: 
 4663: static const xmlChar *
 4664: xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
 4665: {
 4666:     return((const xmlChar*) xmlNodeGetContent(node));
 4667: }
 4668: 
 4669: /**
 4670:  * xmlSchemaGetProp:
 4671:  * @ctxt: the parser context
 4672:  * @node: the node
 4673:  * @name: the property name
 4674:  *
 4675:  * Read a attribute value and internalize the string
 4676:  *
 4677:  * Returns the string or NULL if not present.
 4678:  */
 4679: static const xmlChar *
 4680: xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 4681:                  const char *name)
 4682: {
 4683:     xmlChar *val;
 4684:     const xmlChar *ret;
 4685: 
 4686:     val = xmlGetNoNsProp(node, BAD_CAST name);
 4687:     if (val == NULL)
 4688:         return(NULL);
 4689:     ret = xmlDictLookup(ctxt->dict, val, -1);
 4690:     xmlFree(val);
 4691:     return(ret);
 4692: }
 4693: 
 4694: /************************************************************************
 4695:  * 									*
 4696:  * 			Parsing functions				*
 4697:  * 									*
 4698:  ************************************************************************/
 4699: 
 4700: #define WXS_FIND_GLOBAL_ITEM(slot)			\
 4701:     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
 4702: 	ret = xmlHashLookup(schema->slot, name); \
 4703: 	if (ret != NULL) goto exit; \
 4704:     } \
 4705:     if (xmlHashSize(schema->schemasImports) > 1) { \
 4706: 	xmlSchemaImportPtr import; \
 4707: 	if (nsName == NULL) \
 4708: 	    import = xmlHashLookup(schema->schemasImports, \
 4709: 		XML_SCHEMAS_NO_NAMESPACE); \
 4710: 	else \
 4711: 	    import = xmlHashLookup(schema->schemasImports, nsName); \
 4712: 	if (import == NULL) \
 4713: 	    goto exit; \
 4714: 	ret = xmlHashLookup(import->schema->slot, name); \
 4715:     }
 4716: 
 4717: /**
 4718:  * xmlSchemaGetElem:
 4719:  * @schema:  the schema context
 4720:  * @name:  the element name
 4721:  * @ns:  the element namespace
 4722:  *
 4723:  * Lookup a global element declaration in the schema.
 4724:  *
 4725:  * Returns the element declaration or NULL if not found.
 4726:  */
 4727: static xmlSchemaElementPtr
 4728: xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
 4729:                  const xmlChar * nsName)
 4730: {
 4731:     xmlSchemaElementPtr ret = NULL;
 4732: 
 4733:     if ((name == NULL) || (schema == NULL))
 4734:         return(NULL);
 4735:     if (schema != NULL) {
 4736: 	WXS_FIND_GLOBAL_ITEM(elemDecl)
 4737:     }
 4738: exit:
 4739: #ifdef DEBUG
 4740:     if (ret == NULL) {
 4741:         if (nsName == NULL)
 4742:             fprintf(stderr, "Unable to lookup element decl. %s", name);
 4743:         else
 4744:             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
 4745:                     nsName);
 4746:     }
 4747: #endif
 4748:     return (ret);
 4749: }
 4750: 
 4751: /**
 4752:  * xmlSchemaGetType:
 4753:  * @schema:  the main schema
 4754:  * @name:  the type's name
 4755:  * nsName:  the type's namespace
 4756:  *
 4757:  * Lookup a type in the schemas or the predefined types
 4758:  *
 4759:  * Returns the group definition or NULL if not found.
 4760:  */
 4761: static xmlSchemaTypePtr
 4762: xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
 4763:                  const xmlChar * nsName)
 4764: {
 4765:     xmlSchemaTypePtr ret = NULL;
 4766: 
 4767:     if (name == NULL)
 4768:         return (NULL);
 4769:     /* First try the built-in types. */
 4770:     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
 4771: 	ret = xmlSchemaGetPredefinedType(name, nsName);
 4772: 	if (ret != NULL)
 4773: 	    goto exit;
 4774: 	/*
 4775: 	* Note that we try the parsed schemas as well here
 4776: 	* since one might have parsed the S4S, which contain more
 4777: 	* than the built-in types.
 4778: 	* TODO: Can we optimize this?
 4779: 	*/
 4780:     }
 4781:     if (schema != NULL) {
 4782: 	WXS_FIND_GLOBAL_ITEM(typeDecl)
 4783:     }
 4784: exit:
 4785: 
 4786: #ifdef DEBUG
 4787:     if (ret == NULL) {
 4788:         if (nsName == NULL)
 4789:             fprintf(stderr, "Unable to lookup type %s", name);
 4790:         else
 4791:             fprintf(stderr, "Unable to lookup type %s:%s", name,
 4792:                     nsName);
 4793:     }
 4794: #endif
 4795:     return (ret);
 4796: }
 4797: 
 4798: /**
 4799:  * xmlSchemaGetAttributeDecl:
 4800:  * @schema:  the context of the schema
 4801:  * @name:  the name of the attribute
 4802:  * @ns:  the target namespace of the attribute
 4803:  *
 4804:  * Lookup a an attribute in the schema or imported schemas
 4805:  *
 4806:  * Returns the attribute declaration or NULL if not found.
 4807:  */
 4808: static xmlSchemaAttributePtr
 4809: xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
 4810:                  const xmlChar * nsName)
 4811: {
 4812:     xmlSchemaAttributePtr ret = NULL;
 4813: 
 4814:     if ((name == NULL) || (schema == NULL))
 4815:         return (NULL);
 4816:     if (schema != NULL) {
 4817: 	WXS_FIND_GLOBAL_ITEM(attrDecl)
 4818:     }
 4819: exit:
 4820: #ifdef DEBUG
 4821:     if (ret == NULL) {
 4822:         if (nsName == NULL)
 4823:             fprintf(stderr, "Unable to lookup attribute %s", name);
 4824:         else
 4825:             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
 4826:                     nsName);
 4827:     }
 4828: #endif
 4829:     return (ret);
 4830: }
 4831: 
 4832: /**
 4833:  * xmlSchemaGetAttributeGroup:
 4834:  * @schema:  the context of the schema
 4835:  * @name:  the name of the attribute group
 4836:  * @ns:  the target namespace of the attribute group
 4837:  *
 4838:  * Lookup a an attribute group in the schema or imported schemas
 4839:  *
 4840:  * Returns the attribute group definition or NULL if not found.
 4841:  */
 4842: static xmlSchemaAttributeGroupPtr
 4843: xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
 4844:                  const xmlChar * nsName)
 4845: {
 4846:     xmlSchemaAttributeGroupPtr ret = NULL;
 4847: 
 4848:     if ((name == NULL) || (schema == NULL))
 4849:         return (NULL);
 4850:     if (schema != NULL) {
 4851: 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
 4852:     }
 4853: exit:
 4854:     /* TODO:
 4855:     if ((ret != NULL) && (ret->redef != NULL)) {
 4856: 	* Return the last redefinition. *
 4857: 	ret = ret->redef;
 4858:     }
 4859:     */
 4860: #ifdef DEBUG
 4861:     if (ret == NULL) {
 4862:         if (nsName == NULL)
 4863:             fprintf(stderr, "Unable to lookup attribute group %s", name);
 4864:         else
 4865:             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
 4866:                     nsName);
 4867:     }
 4868: #endif
 4869:     return (ret);
 4870: }
 4871: 
 4872: /**
 4873:  * xmlSchemaGetGroup:
 4874:  * @schema:  the context of the schema
 4875:  * @name:  the name of the group
 4876:  * @ns:  the target namespace of the group
 4877:  *
 4878:  * Lookup a group in the schema or imported schemas
 4879:  *
 4880:  * Returns the group definition or NULL if not found.
 4881:  */
 4882: static xmlSchemaModelGroupDefPtr
 4883: xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
 4884:                  const xmlChar * nsName)
 4885: {
 4886:     xmlSchemaModelGroupDefPtr ret = NULL;
 4887: 
 4888:     if ((name == NULL) || (schema == NULL))
 4889:         return (NULL);
 4890:     if (schema != NULL) {
 4891: 	WXS_FIND_GLOBAL_ITEM(groupDecl)
 4892:     }
 4893: exit:
 4894: 
 4895: #ifdef DEBUG
 4896:     if (ret == NULL) {
 4897:         if (nsName == NULL)
 4898:             fprintf(stderr, "Unable to lookup group %s", name);
 4899:         else
 4900:             fprintf(stderr, "Unable to lookup group %s:%s", name,
 4901:                     nsName);
 4902:     }
 4903: #endif
 4904:     return (ret);
 4905: }
 4906: 
 4907: static xmlSchemaNotationPtr
 4908: xmlSchemaGetNotation(xmlSchemaPtr schema,
 4909: 		     const xmlChar *name,
 4910: 		     const xmlChar *nsName)
 4911: {
 4912:     xmlSchemaNotationPtr ret = NULL;
 4913: 
 4914:     if ((name == NULL) || (schema == NULL))
 4915:         return (NULL);
 4916:     if (schema != NULL) {
 4917: 	WXS_FIND_GLOBAL_ITEM(notaDecl)
 4918:     }
 4919: exit:
 4920:     return (ret);
 4921: }
 4922: 
 4923: static xmlSchemaIDCPtr
 4924: xmlSchemaGetIDC(xmlSchemaPtr schema,
 4925: 		const xmlChar *name,
 4926: 		const xmlChar *nsName)
 4927: {
 4928:     xmlSchemaIDCPtr ret = NULL;
 4929: 
 4930:     if ((name == NULL) || (schema == NULL))
 4931:         return (NULL);
 4932:     if (schema != NULL) {
 4933: 	WXS_FIND_GLOBAL_ITEM(idcDef)
 4934:     }
 4935: exit:
 4936:     return (ret);
 4937: }
 4938: 
 4939: /**
 4940:  * xmlSchemaGetNamedComponent:
 4941:  * @schema:  the schema
 4942:  * @name:  the name of the group
 4943:  * @ns:  the target namespace of the group
 4944:  *
 4945:  * Lookup a group in the schema or imported schemas
 4946:  *
 4947:  * Returns the group definition or NULL if not found.
 4948:  */
 4949: static xmlSchemaBasicItemPtr
 4950: xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
 4951: 			   xmlSchemaTypeType itemType,
 4952: 			   const xmlChar *name,
 4953: 			   const xmlChar *targetNs)
 4954: {
 4955:     switch (itemType) {
 4956: 	case XML_SCHEMA_TYPE_GROUP:
 4957: 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
 4958: 		name, targetNs));
 4959: 	case XML_SCHEMA_TYPE_ELEMENT:
 4960: 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
 4961: 		name, targetNs));
 4962: 	default:
 4963: 	    TODO
 4964: 	    return (NULL);
 4965:     }
 4966: }
 4967: 
 4968: /************************************************************************
 4969:  * 									*
 4970:  * 			Parsing functions				*
 4971:  * 									*
 4972:  ************************************************************************/
 4973: 
 4974: #define IS_BLANK_NODE(n)						\
 4975:     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
 4976: 
 4977: /**
 4978:  * xmlSchemaIsBlank:
 4979:  * @str:  a string
 4980:  * @len: the length of the string or -1
 4981:  *
 4982:  * Check if a string is ignorable
 4983:  *
 4984:  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
 4985:  */
 4986: static int
 4987: xmlSchemaIsBlank(xmlChar * str, int len)
 4988: {
 4989:     if (str == NULL)
 4990:         return (1);
 4991:     if (len < 0) {
 4992: 	while (*str != 0) {
 4993: 	    if (!(IS_BLANK_CH(*str)))
 4994: 		return (0);
 4995: 	    str++;
 4996: 	}
 4997:     } else while ((*str != 0) && (len != 0)) {
 4998: 	if (!(IS_BLANK_CH(*str)))
 4999: 	    return (0);
 5000: 	str++;
 5001: 	len--;
 5002:     }
 5003: 
 5004:     return (1);
 5005: }
 5006: 
 5007: #define WXS_COMP_NAME(c, t) ((t) (c))->name
 5008: #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
 5009: /*
 5010: * xmlSchemaFindRedefCompInGraph:
 5011: * ATTENTION TODO: This uses pointer comp. for strings.
 5012: */
 5013: static xmlSchemaBasicItemPtr
 5014: xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
 5015: 			      xmlSchemaTypeType type,
 5016: 			      const xmlChar *name,
 5017: 			      const xmlChar *nsName)
 5018: {
 5019:     xmlSchemaBasicItemPtr ret;
 5020:     int i;
 5021: 
 5022:     if ((bucket == NULL) || (name == NULL))
 5023: 	return(NULL);
 5024:     if ((bucket->globals == NULL) ||
 5025: 	(bucket->globals->nbItems == 0))
 5026: 	goto subschemas;
 5027:     /*
 5028:     * Search in global components.
 5029:     */
 5030:     for (i = 0; i < bucket->globals->nbItems; i++) {
 5031: 	ret = bucket->globals->items[i];
 5032: 	if (ret->type == type) {
 5033: 	    switch (type) {
 5034: 		case XML_SCHEMA_TYPE_COMPLEX:
 5035: 		case XML_SCHEMA_TYPE_SIMPLE:
 5036: 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
 5037: 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
 5038: 			nsName))
 5039: 		    {
 5040: 			return(ret);
 5041: 		    }
 5042: 		    break;
 5043: 		case XML_SCHEMA_TYPE_GROUP:
 5044: 		    if ((WXS_COMP_NAME(ret,
 5045: 			    xmlSchemaModelGroupDefPtr) == name) &&
 5046: 			(WXS_COMP_TNS(ret,
 5047: 			    xmlSchemaModelGroupDefPtr) == nsName))
 5048: 		    {
 5049: 			return(ret);
 5050: 		    }
 5051: 		    break;
 5052: 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 5053: 		    if ((WXS_COMP_NAME(ret,
 5054: 			    xmlSchemaAttributeGroupPtr) == name) &&
 5055: 			(WXS_COMP_TNS(ret,
 5056: 			    xmlSchemaAttributeGroupPtr) == nsName))
 5057: 		    {
 5058: 			return(ret);
 5059: 		    }
 5060: 		    break;
 5061: 		default:
 5062: 		    /* Should not be hit. */
 5063: 		    return(NULL);
 5064: 	    }
 5065: 	}
 5066:     }
 5067: subschemas:
 5068:     /*
 5069:     * Process imported/included schemas.
 5070:     */
 5071:     if (bucket->relations != NULL) {
 5072: 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
 5073: 
 5074: 	/*
 5075: 	* TODO: Marking the bucket will not avoid multiple searches
 5076: 	* in the same schema, but avoids at least circularity.
 5077: 	*/
 5078: 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
 5079: 	do {
 5080: 	    if ((rel->bucket != NULL) &&
 5081: 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
 5082: 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
 5083: 		    type, name, nsName);
 5084: 		if (ret != NULL)
 5085: 		    return(ret);
 5086: 	    }
 5087: 	    rel = rel->next;
 5088: 	} while (rel != NULL);
 5089: 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
 5090:     }
 5091:     return(NULL);
 5092: }
 5093: 
 5094: /**
 5095:  * xmlSchemaAddNotation:
 5096:  * @ctxt:  a schema parser context
 5097:  * @schema:  the schema being built
 5098:  * @name:  the item name
 5099:  *
 5100:  * Add an XML schema annotation declaration
 5101:  * *WARNING* this interface is highly subject to change
 5102:  *
 5103:  * Returns the new struture or NULL in case of error
 5104:  */
 5105: static xmlSchemaNotationPtr
 5106: xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5107:                      const xmlChar *name, const xmlChar *nsName,
 5108: 		     xmlNodePtr node ATTRIBUTE_UNUSED)
 5109: {
 5110:     xmlSchemaNotationPtr ret = NULL;
 5111: 
 5112:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5113:         return (NULL);
 5114: 
 5115:     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
 5116:     if (ret == NULL) {
 5117:         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
 5118:         return (NULL);
 5119:     }
 5120:     memset(ret, 0, sizeof(xmlSchemaNotation));
 5121:     ret->type = XML_SCHEMA_TYPE_NOTATION;
 5122:     ret->name = name;
 5123:     ret->targetNamespace = nsName;
 5124:     /* TODO: do we need the node to be set?
 5125:     * ret->node = node;*/
 5126:     WXS_ADD_GLOBAL(ctxt, ret);
 5127:     return (ret);
 5128: }
 5129: 
 5130: /**
 5131:  * xmlSchemaAddAttribute:
 5132:  * @ctxt:  a schema parser context
 5133:  * @schema:  the schema being built
 5134:  * @name:  the item name
 5135:  * @namespace:  the namespace
 5136:  *
 5137:  * Add an XML schema Attrribute declaration
 5138:  * *WARNING* this interface is highly subject to change
 5139:  *
 5140:  * Returns the new struture or NULL in case of error
 5141:  */
 5142: static xmlSchemaAttributePtr
 5143: xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5144:                       const xmlChar * name, const xmlChar * nsName,
 5145: 		      xmlNodePtr node, int topLevel)
 5146: {
 5147:     xmlSchemaAttributePtr ret = NULL;
 5148: 
 5149:     if ((ctxt == NULL) || (schema == NULL))
 5150:         return (NULL);
 5151: 
 5152:     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
 5153:     if (ret == NULL) {
 5154:         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
 5155:         return (NULL);
 5156:     }
 5157:     memset(ret, 0, sizeof(xmlSchemaAttribute));
 5158:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
 5159:     ret->node = node;
 5160:     ret->name = name;
 5161:     ret->targetNamespace = nsName;
 5162: 
 5163:     if (topLevel)
 5164: 	WXS_ADD_GLOBAL(ctxt, ret);
 5165:     else
 5166: 	WXS_ADD_LOCAL(ctxt, ret);
 5167:     WXS_ADD_PENDING(ctxt, ret);
 5168:     return (ret);
 5169: }
 5170: 
 5171: /**
 5172:  * xmlSchemaAddAttributeUse:
 5173:  * @ctxt:  a schema parser context
 5174:  * @schema:  the schema being built
 5175:  * @name:  the item name
 5176:  * @namespace:  the namespace
 5177:  *
 5178:  * Add an XML schema Attrribute declaration
 5179:  * *WARNING* this interface is highly subject to change
 5180:  *
 5181:  * Returns the new struture or NULL in case of error
 5182:  */
 5183: static xmlSchemaAttributeUsePtr
 5184: xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
 5185: 			 xmlNodePtr node)
 5186: {
 5187:     xmlSchemaAttributeUsePtr ret = NULL;
 5188: 
 5189:     if (pctxt == NULL)
 5190:         return (NULL);
 5191: 
 5192:     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
 5193:     if (ret == NULL) {
 5194:         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
 5195:         return (NULL);
 5196:     }
 5197:     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
 5198:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
 5199:     ret->node = node;
 5200: 
 5201:     WXS_ADD_LOCAL(pctxt, ret);
 5202:     return (ret);
 5203: }
 5204: 
 5205: /*
 5206: * xmlSchemaAddRedef:
 5207: *
 5208: * Adds a redefinition information. This is used at a later stage to:
 5209: * resolve references to the redefined components and to check constraints.
 5210: */
 5211: static xmlSchemaRedefPtr
 5212: xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
 5213: 		  xmlSchemaBucketPtr targetBucket,
 5214: 		  void *item,
 5215: 		  const xmlChar *refName,
 5216: 		  const xmlChar *refTargetNs)
 5217: {
 5218:     xmlSchemaRedefPtr ret;
 5219: 
 5220:     ret = (xmlSchemaRedefPtr)
 5221: 	xmlMalloc(sizeof(xmlSchemaRedef));
 5222:     if (ret == NULL) {
 5223: 	xmlSchemaPErrMemory(pctxt,
 5224: 	    "allocating redefinition info", NULL);
 5225: 	return (NULL);
 5226:     }
 5227:     memset(ret, 0, sizeof(xmlSchemaRedef));
 5228:     ret->item = item;
 5229:     ret->targetBucket = targetBucket;
 5230:     ret->refName = refName;
 5231:     ret->refTargetNs = refTargetNs;
 5232:     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
 5233: 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
 5234:     else
 5235: 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
 5236:     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
 5237: 
 5238:     return (ret);
 5239: }
 5240: 
 5241: /**
 5242:  * xmlSchemaAddAttributeGroupDefinition:
 5243:  * @ctxt:  a schema parser context
 5244:  * @schema:  the schema being built
 5245:  * @name:  the item name
 5246:  * @nsName:  the target namespace
 5247:  * @node: the corresponding node
 5248:  *
 5249:  * Add an XML schema Attrribute Group definition.
 5250:  *
 5251:  * Returns the new struture or NULL in case of error
 5252:  */
 5253: static xmlSchemaAttributeGroupPtr
 5254: xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 5255:                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 5256: 			   const xmlChar *name,
 5257: 			   const xmlChar *nsName,
 5258: 			   xmlNodePtr node)
 5259: {
 5260:     xmlSchemaAttributeGroupPtr ret = NULL;
 5261: 
 5262:     if ((pctxt == NULL) || (name == NULL))
 5263:         return (NULL);
 5264: 
 5265:     ret = (xmlSchemaAttributeGroupPtr)
 5266:         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
 5267:     if (ret == NULL) {
 5268: 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
 5269: 	return (NULL);
 5270:     }
 5271:     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
 5272:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
 5273:     ret->name = name;
 5274:     ret->targetNamespace = nsName;
 5275:     ret->node = node;
 5276: 
 5277:     /* TODO: Remove the flag. */
 5278:     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
 5279:     if (pctxt->isRedefine) {
 5280: 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
 5281: 	    ret, name, nsName);
 5282: 	if (pctxt->redef == NULL) {
 5283: 	    xmlFree(ret);
 5284: 	    return(NULL);
 5285: 	}
 5286: 	pctxt->redefCounter = 0;
 5287:     }
 5288:     WXS_ADD_GLOBAL(pctxt, ret);
 5289:     WXS_ADD_PENDING(pctxt, ret);
 5290:     return (ret);
 5291: }
 5292: 
 5293: /**
 5294:  * xmlSchemaAddElement:
 5295:  * @ctxt:  a schema parser context
 5296:  * @schema:  the schema being built
 5297:  * @name:  the type name
 5298:  * @namespace:  the type namespace
 5299:  *
 5300:  * Add an XML schema Element declaration
 5301:  * *WARNING* this interface is highly subject to change
 5302:  *
 5303:  * Returns the new struture or NULL in case of error
 5304:  */
 5305: static xmlSchemaElementPtr
 5306: xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
 5307:                     const xmlChar * name, const xmlChar * nsName,
 5308: 		    xmlNodePtr node, int topLevel)
 5309: {
 5310:     xmlSchemaElementPtr ret = NULL;
 5311: 
 5312:     if ((ctxt == NULL) || (name == NULL))
 5313:         return (NULL);
 5314: 
 5315:     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
 5316:     if (ret == NULL) {
 5317:         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
 5318:         return (NULL);
 5319:     }
 5320:     memset(ret, 0, sizeof(xmlSchemaElement));
 5321:     ret->type = XML_SCHEMA_TYPE_ELEMENT;
 5322:     ret->name = name;
 5323:     ret->targetNamespace = nsName;
 5324:     ret->node = node;
 5325: 
 5326:     if (topLevel)
 5327: 	WXS_ADD_GLOBAL(ctxt, ret);
 5328:     else
 5329: 	WXS_ADD_LOCAL(ctxt, ret);
 5330:     WXS_ADD_PENDING(ctxt, ret);
 5331:     return (ret);
 5332: }
 5333: 
 5334: /**
 5335:  * xmlSchemaAddType:
 5336:  * @ctxt:  a schema parser context
 5337:  * @schema:  the schema being built
 5338:  * @name:  the item name
 5339:  * @namespace:  the namespace
 5340:  *
 5341:  * Add an XML schema item
 5342:  * *WARNING* this interface is highly subject to change
 5343:  *
 5344:  * Returns the new struture or NULL in case of error
 5345:  */
 5346: static xmlSchemaTypePtr
 5347: xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5348: 		 xmlSchemaTypeType type,
 5349:                  const xmlChar * name, const xmlChar * nsName,
 5350: 		 xmlNodePtr node, int topLevel)
 5351: {
 5352:     xmlSchemaTypePtr ret = NULL;
 5353: 
 5354:     if ((ctxt == NULL) || (schema == NULL))
 5355:         return (NULL);
 5356: 
 5357:     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
 5358:     if (ret == NULL) {
 5359:         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
 5360:         return (NULL);
 5361:     }
 5362:     memset(ret, 0, sizeof(xmlSchemaType));
 5363:     ret->type = type;
 5364:     ret->name = name;
 5365:     ret->targetNamespace = nsName;
 5366:     ret->node = node;
 5367:     if (topLevel) {
 5368: 	if (ctxt->isRedefine) {
 5369: 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 5370: 		ret, name, nsName);
 5371: 	    if (ctxt->redef == NULL) {
 5372: 		xmlFree(ret);
 5373: 		return(NULL);
 5374: 	    }
 5375: 	    ctxt->redefCounter = 0;
 5376: 	}
 5377: 	WXS_ADD_GLOBAL(ctxt, ret);
 5378:     } else
 5379: 	WXS_ADD_LOCAL(ctxt, ret);
 5380:     WXS_ADD_PENDING(ctxt, ret);
 5381:     return (ret);
 5382: }
 5383: 
 5384: static xmlSchemaQNameRefPtr
 5385: xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
 5386: 		     xmlSchemaTypeType refType,
 5387: 		     const xmlChar *refName,
 5388: 		     const xmlChar *refNs)
 5389: {
 5390:     xmlSchemaQNameRefPtr ret;
 5391: 
 5392:     ret = (xmlSchemaQNameRefPtr)
 5393: 	xmlMalloc(sizeof(xmlSchemaQNameRef));
 5394:     if (ret == NULL) {
 5395: 	xmlSchemaPErrMemory(pctxt,
 5396: 	    "allocating QName reference item", NULL);
 5397: 	return (NULL);
 5398:     }
 5399:     ret->node = NULL;
 5400:     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
 5401:     ret->name = refName;
 5402:     ret->targetNamespace = refNs;
 5403:     ret->item = NULL;
 5404:     ret->itemType = refType;
 5405:     /*
 5406:     * Store the reference item in the schema.
 5407:     */
 5408:     WXS_ADD_LOCAL(pctxt, ret);
 5409:     return (ret);
 5410: }
 5411: 
 5412: static xmlSchemaAttributeUseProhibPtr
 5413: xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
 5414: {
 5415:     xmlSchemaAttributeUseProhibPtr ret;
 5416: 
 5417:     ret = (xmlSchemaAttributeUseProhibPtr)
 5418: 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
 5419:     if (ret == NULL) {
 5420: 	xmlSchemaPErrMemory(pctxt,
 5421: 	    "allocating attribute use prohibition", NULL);
 5422: 	return (NULL);
 5423:     }
 5424:     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
 5425:     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
 5426:     WXS_ADD_LOCAL(pctxt, ret);
 5427:     return (ret);
 5428: }
 5429: 
 5430: 
 5431: /**
 5432:  * xmlSchemaAddModelGroup:
 5433:  * @ctxt:  a schema parser context
 5434:  * @schema:  the schema being built
 5435:  * @type: the "compositor" type of the model group
 5436:  * @node: the node in the schema doc
 5437:  *
 5438:  * Adds a schema model group
 5439:  * *WARNING* this interface is highly subject to change
 5440:  *
 5441:  * Returns the new struture or NULL in case of error
 5442:  */
 5443: static xmlSchemaModelGroupPtr
 5444: xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
 5445: 		       xmlSchemaPtr schema,
 5446: 		       xmlSchemaTypeType type,
 5447: 		       xmlNodePtr node)
 5448: {
 5449:     xmlSchemaModelGroupPtr ret = NULL;
 5450: 
 5451:     if ((ctxt == NULL) || (schema == NULL))
 5452:         return (NULL);
 5453: 
 5454:     ret = (xmlSchemaModelGroupPtr)
 5455: 	xmlMalloc(sizeof(xmlSchemaModelGroup));
 5456:     if (ret == NULL) {
 5457: 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
 5458: 	    NULL);
 5459: 	return (NULL);
 5460:     }
 5461:     memset(ret, 0, sizeof(xmlSchemaModelGroup));
 5462:     ret->type = type;
 5463:     ret->node = node;
 5464:     WXS_ADD_LOCAL(ctxt, ret);
 5465:     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
 5466: 	(type == XML_SCHEMA_TYPE_CHOICE))
 5467: 	WXS_ADD_PENDING(ctxt, ret);
 5468:     return (ret);
 5469: }
 5470: 
 5471: 
 5472: /**
 5473:  * xmlSchemaAddParticle:
 5474:  * @ctxt:  a schema parser context
 5475:  * @schema:  the schema being built
 5476:  * @node: the corresponding node in the schema doc
 5477:  * @min: the minOccurs
 5478:  * @max: the maxOccurs
 5479:  *
 5480:  * Adds an XML schema particle component.
 5481:  * *WARNING* this interface is highly subject to change
 5482:  *
 5483:  * Returns the new struture or NULL in case of error
 5484:  */
 5485: static xmlSchemaParticlePtr
 5486: xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
 5487: 		     xmlNodePtr node, int min, int max)
 5488: {
 5489:     xmlSchemaParticlePtr ret = NULL;
 5490:     if (ctxt == NULL)
 5491:         return (NULL);
 5492: 
 5493: #ifdef DEBUG
 5494:     fprintf(stderr, "Adding particle component\n");
 5495: #endif
 5496:     ret = (xmlSchemaParticlePtr)
 5497: 	xmlMalloc(sizeof(xmlSchemaParticle));
 5498:     if (ret == NULL) {
 5499: 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
 5500: 	    NULL);
 5501: 	return (NULL);
 5502:     }
 5503:     ret->type = XML_SCHEMA_TYPE_PARTICLE;
 5504:     ret->annot = NULL;
 5505:     ret->node = node;
 5506:     ret->minOccurs = min;
 5507:     ret->maxOccurs = max;
 5508:     ret->next = NULL;
 5509:     ret->children = NULL;
 5510: 
 5511:     WXS_ADD_LOCAL(ctxt, ret);
 5512:     /*
 5513:     * Note that addition to pending components will be done locally
 5514:     * to the specific parsing function, since the most particles
 5515:     * need not to be fixed up (i.e. the reference to be resolved).
 5516:     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
 5517:     */
 5518:     return (ret);
 5519: }
 5520: 
 5521: /**
 5522:  * xmlSchemaAddModelGroupDefinition:
 5523:  * @ctxt:  a schema validation context
 5524:  * @schema:  the schema being built
 5525:  * @name:  the group name
 5526:  *
 5527:  * Add an XML schema Group definition
 5528:  *
 5529:  * Returns the new struture or NULL in case of error
 5530:  */
 5531: static xmlSchemaModelGroupDefPtr
 5532: xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 5533: 				 xmlSchemaPtr schema,
 5534: 				 const xmlChar *name,
 5535: 				 const xmlChar *nsName,
 5536: 				 xmlNodePtr node)
 5537: {
 5538:     xmlSchemaModelGroupDefPtr ret = NULL;
 5539: 
 5540:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5541:         return (NULL);
 5542: 
 5543:     ret = (xmlSchemaModelGroupDefPtr)
 5544: 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
 5545:     if (ret == NULL) {
 5546:         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
 5547:         return (NULL);
 5548:     }
 5549:     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
 5550:     ret->name = name;
 5551:     ret->type = XML_SCHEMA_TYPE_GROUP;
 5552:     ret->node = node;
 5553:     ret->targetNamespace = nsName;
 5554: 
 5555:     if (ctxt->isRedefine) {
 5556: 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 5557: 	    ret, name, nsName);
 5558: 	if (ctxt->redef == NULL) {
 5559: 	    xmlFree(ret);
 5560: 	    return(NULL);
 5561: 	}
 5562: 	ctxt->redefCounter = 0;
 5563:     }
 5564:     WXS_ADD_GLOBAL(ctxt, ret);
 5565:     WXS_ADD_PENDING(ctxt, ret);
 5566:     return (ret);
 5567: }
 5568: 
 5569: /**
 5570:  * xmlSchemaNewWildcardNs:
 5571:  * @ctxt:  a schema validation context
 5572:  *
 5573:  * Creates a new wildcard namespace constraint.
 5574:  *
 5575:  * Returns the new struture or NULL in case of error
 5576:  */
 5577: static xmlSchemaWildcardNsPtr
 5578: xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
 5579: {
 5580:     xmlSchemaWildcardNsPtr ret;
 5581: 
 5582:     ret = (xmlSchemaWildcardNsPtr)
 5583: 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
 5584:     if (ret == NULL) {
 5585: 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
 5586: 	return (NULL);
 5587:     }
 5588:     ret->value = NULL;
 5589:     ret->next = NULL;
 5590:     return (ret);
 5591: }
 5592: 
 5593: static xmlSchemaIDCPtr
 5594: xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5595:                   const xmlChar *name, const xmlChar *nsName,
 5596: 		  int category, xmlNodePtr node)
 5597: {
 5598:     xmlSchemaIDCPtr ret = NULL;
 5599: 
 5600:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5601:         return (NULL);
 5602: 
 5603:     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
 5604:     if (ret == NULL) {
 5605:         xmlSchemaPErrMemory(ctxt,
 5606: 	    "allocating an identity-constraint definition", NULL);
 5607:         return (NULL);
 5608:     }
 5609:     memset(ret, 0, sizeof(xmlSchemaIDC));
 5610:     /* The target namespace of the parent element declaration. */
 5611:     ret->targetNamespace = nsName;
 5612:     ret->name = name;
 5613:     ret->type = category;
 5614:     ret->node = node;
 5615: 
 5616:     WXS_ADD_GLOBAL(ctxt, ret);
 5617:     /*
 5618:     * Only keyrefs need to be fixup up.
 5619:     */
 5620:     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
 5621: 	WXS_ADD_PENDING(ctxt, ret);
 5622:     return (ret);
 5623: }
 5624: 
 5625: /**
 5626:  * xmlSchemaAddWildcard:
 5627:  * @ctxt:  a schema validation context
 5628:  * @schema: a schema
 5629:  *
 5630:  * Adds a wildcard.
 5631:  * It corresponds to a xsd:anyAttribute and xsd:any.
 5632:  *
 5633:  * Returns the new struture or NULL in case of error
 5634:  */
 5635: static xmlSchemaWildcardPtr
 5636: xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5637: 		     xmlSchemaTypeType type, xmlNodePtr node)
 5638: {
 5639:     xmlSchemaWildcardPtr ret = NULL;
 5640: 
 5641:     if ((ctxt == NULL) || (schema == NULL))
 5642:         return (NULL);
 5643: 
 5644:     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
 5645:     if (ret == NULL) {
 5646:         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
 5647:         return (NULL);
 5648:     }
 5649:     memset(ret, 0, sizeof(xmlSchemaWildcard));
 5650:     ret->type = type;
 5651:     ret->node = node;
 5652:     WXS_ADD_LOCAL(ctxt, ret);
 5653:     return (ret);
 5654: }
 5655: 
 5656: static void
 5657: xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
 5658: {
 5659:     if (group == NULL)
 5660: 	return;
 5661:     if (group->members != NULL)
 5662: 	xmlSchemaItemListFree(group->members);
 5663:     xmlFree(group);
 5664: }
 5665: 
 5666: static xmlSchemaSubstGroupPtr
 5667: xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
 5668: 		       xmlSchemaElementPtr head)
 5669: {
 5670:     xmlSchemaSubstGroupPtr ret;
 5671: 
 5672:     /* Init subst group hash. */
 5673:     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
 5674: 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
 5675: 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
 5676: 	    return(NULL);
 5677:     }
 5678:     /* Create a new substitution group. */
 5679:     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
 5680:     if (ret == NULL) {
 5681: 	xmlSchemaPErrMemory(NULL,
 5682: 	    "allocating a substitution group container", NULL);
 5683: 	return(NULL);
 5684:     }
 5685:     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
 5686:     ret->head = head;
 5687:     /* Create list of members. */
 5688:     ret->members = xmlSchemaItemListCreate();
 5689:     if (ret->members == NULL) {
 5690: 	xmlSchemaSubstGroupFree(ret);
 5691: 	return(NULL);
 5692:     }
 5693:     /* Add subst group to hash. */
 5694:     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
 5695: 	head->name, head->targetNamespace, ret) != 0) {
 5696: 	PERROR_INT("xmlSchemaSubstGroupAdd",
 5697: 	    "failed to add a new substitution container");
 5698: 	xmlSchemaSubstGroupFree(ret);
 5699: 	return(NULL);
 5700:     }
 5701:     return(ret);
 5702: }
 5703: 
 5704: static xmlSchemaSubstGroupPtr
 5705: xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
 5706: 		       xmlSchemaElementPtr head)
 5707: {
 5708:     if (WXS_SUBST_GROUPS(pctxt) == NULL)
 5709: 	return(NULL);
 5710:     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
 5711: 	head->name, head->targetNamespace));
 5712: 
 5713: }
 5714: 
 5715: /**
 5716:  * xmlSchemaAddElementSubstitutionMember:
 5717:  * @pctxt:  a schema parser context
 5718:  * @head:  the head of the substitution group
 5719:  * @member: the new member of the substitution group
 5720:  *
 5721:  * Allocate a new annotation structure.
 5722:  *
 5723:  * Returns the newly allocated structure or NULL in case or error
 5724:  */
 5725: static int
 5726: xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
 5727: 				      xmlSchemaElementPtr head,
 5728: 				      xmlSchemaElementPtr member)
 5729: {
 5730:     xmlSchemaSubstGroupPtr substGroup = NULL;
 5731: 
 5732:     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
 5733: 	return (-1);
 5734: 
 5735:     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
 5736:     if (substGroup == NULL)
 5737: 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
 5738:     if (substGroup == NULL)
 5739: 	return(-1);
 5740:     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
 5741: 	return(-1);
 5742:     return(0);
 5743: }
 5744: 
 5745: /************************************************************************
 5746:  * 									*
 5747:  *		Utilities for parsing					*
 5748:  * 									*
 5749:  ************************************************************************/
 5750: 
 5751: /**
 5752:  * xmlSchemaPValAttrNodeQNameValue:
 5753:  * @ctxt:  a schema parser context
 5754:  * @schema: the schema context
 5755:  * @ownerDes: the designation of the parent element
 5756:  * @ownerItem: the parent as a schema object
 5757:  * @value:  the QName value
 5758:  * @local: the resulting local part if found, the attribute value otherwise
 5759:  * @uri:  the resulting namespace URI if found
 5760:  *
 5761:  * Extracts the local name and the URI of a QName value and validates it.
 5762:  * This one is intended to be used on attribute values that
 5763:  * should resolve to schema components.
 5764:  *
 5765:  * Returns 0, in case the QName is valid, a positive error code
 5766:  * if not valid and -1 if an internal error occurs.
 5767:  */
 5768: static int
 5769: xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
 5770: 				       xmlSchemaPtr schema,
 5771: 				       xmlSchemaBasicItemPtr ownerItem,
 5772: 				       xmlAttrPtr attr,
 5773: 				       const xmlChar *value,
 5774: 				       const xmlChar **uri,
 5775: 				       const xmlChar **local)
 5776: {
 5777:     const xmlChar *pref;
 5778:     xmlNsPtr ns;
 5779:     int len, ret;
 5780: 
 5781:     *uri = NULL;
 5782:     *local = NULL;
 5783:     ret = xmlValidateQName(value, 1);
 5784:     if (ret > 0) {
 5785: 	xmlSchemaPSimpleTypeErr(ctxt,
 5786: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5787: 	    ownerItem, (xmlNodePtr) attr,
 5788: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 5789: 	    NULL, value, NULL, NULL, NULL);
 5790: 	*local = value;
 5791: 	return (ctxt->err);
 5792:     } else if (ret < 0)
 5793: 	return (-1);
 5794: 
 5795:     if (!strchr((char *) value, ':')) {
 5796: 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
 5797: 	if (ns)
 5798: 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 5799: 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
 5800: 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
 5801: 	    * parser context. */
 5802: 	    /*
 5803: 	    * This one takes care of included schemas with no
 5804: 	    * target namespace.
 5805: 	    */
 5806: 	    *uri = ctxt->targetNamespace;
 5807: 	}
 5808: 	*local = xmlDictLookup(ctxt->dict, value, -1);
 5809: 	return (0);
 5810:     }
 5811:     /*
 5812:     * At this point xmlSplitQName3 has to return a local name.
 5813:     */
 5814:     *local = xmlSplitQName3(value, &len);
 5815:     *local = xmlDictLookup(ctxt->dict, *local, -1);
 5816:     pref = xmlDictLookup(ctxt->dict, value, len);
 5817:     ns = xmlSearchNs(attr->doc, attr->parent, pref);
 5818:     if (ns == NULL) {
 5819: 	xmlSchemaPSimpleTypeErr(ctxt,
 5820: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5821: 	    ownerItem, (xmlNodePtr) attr,
 5822: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
 5823: 	    "The value '%s' of simple type 'xs:QName' has no "
 5824: 	    "corresponding namespace declaration in scope", value, NULL);
 5825: 	return (ctxt->err);
 5826:     } else {
 5827:         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 5828:     }
 5829:     return (0);
 5830: }
 5831: 
 5832: /**
 5833:  * xmlSchemaPValAttrNodeQName:
 5834:  * @ctxt:  a schema parser context
 5835:  * @schema: the schema context
 5836:  * @ownerDes: the designation of the owner element
 5837:  * @ownerItem: the owner as a schema object
 5838:  * @attr:  the attribute node
 5839:  * @local: the resulting local part if found, the attribute value otherwise
 5840:  * @uri:  the resulting namespace URI if found
 5841:  *
 5842:  * Extracts and validates the QName of an attribute value.
 5843:  * This one is intended to be used on attribute values that
 5844:  * should resolve to schema components.
 5845:  *
 5846:  * Returns 0, in case the QName is valid, a positive error code
 5847:  * if not valid and -1 if an internal error occurs.
 5848:  */
 5849: static int
 5850: xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
 5851: 				       xmlSchemaPtr schema,
 5852: 				       xmlSchemaBasicItemPtr ownerItem,
 5853: 				       xmlAttrPtr attr,
 5854: 				       const xmlChar **uri,
 5855: 				       const xmlChar **local)
 5856: {
 5857:     const xmlChar *value;
 5858: 
 5859:     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 5860:     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 5861: 	ownerItem, attr, value, uri, local));
 5862: }
 5863: 
 5864: /**
 5865:  * xmlSchemaPValAttrQName:
 5866:  * @ctxt:  a schema parser context
 5867:  * @schema: the schema context
 5868:  * @ownerDes: the designation of the parent element
 5869:  * @ownerItem: the owner as a schema object
 5870:  * @ownerElem:  the parent node of the attribute
 5871:  * @name:  the name of the attribute
 5872:  * @local: the resulting local part if found, the attribute value otherwise
 5873:  * @uri:  the resulting namespace URI if found
 5874:  *
 5875:  * Extracts and validates the QName of an attribute value.
 5876:  *
 5877:  * Returns 0, in case the QName is valid, a positive error code
 5878:  * if not valid and -1 if an internal error occurs.
 5879:  */
 5880: static int
 5881: xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
 5882: 				   xmlSchemaPtr schema,
 5883: 				   xmlSchemaBasicItemPtr ownerItem,
 5884: 				   xmlNodePtr ownerElem,
 5885: 				   const char *name,
 5886: 				   const xmlChar **uri,
 5887: 				   const xmlChar **local)
 5888: {
 5889:     xmlAttrPtr attr;
 5890: 
 5891:     attr = xmlSchemaGetPropNode(ownerElem, name);
 5892:     if (attr == NULL) {
 5893: 	*local = NULL;
 5894: 	*uri = NULL;
 5895: 	return (0);
 5896:     }
 5897:     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
 5898: 	ownerItem, attr, uri, local));
 5899: }
 5900: 
 5901: /**
 5902:  * xmlSchemaPValAttrID:
 5903:  * @ctxt:  a schema parser context
 5904:  * @schema: the schema context
 5905:  * @ownerDes: the designation of the parent element
 5906:  * @ownerItem: the owner as a schema object
 5907:  * @ownerElem:  the parent node of the attribute
 5908:  * @name:  the name of the attribute
 5909:  *
 5910:  * Extracts and validates the ID of an attribute value.
 5911:  *
 5912:  * Returns 0, in case the ID is valid, a positive error code
 5913:  * if not valid and -1 if an internal error occurs.
 5914:  */
 5915: static int
 5916: xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
 5917: {
 5918:     int ret;
 5919:     const xmlChar *value;
 5920: 
 5921:     if (attr == NULL)
 5922: 	return(0);
 5923:     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
 5924:     ret = xmlValidateNCName(value, 1);
 5925:     if (ret == 0) {
 5926: 	/*
 5927: 	* NOTE: the IDness might have already be declared in the DTD
 5928: 	*/
 5929: 	if (attr->atype != XML_ATTRIBUTE_ID) {
 5930: 	    xmlIDPtr res;
 5931: 	    xmlChar *strip;
 5932: 
 5933: 	    /*
 5934: 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
 5935: 	    * moment.
 5936: 	    */
 5937: 	    strip = xmlSchemaCollapseString(value);
 5938: 	    if (strip != NULL) {
 5939: 		xmlFree((xmlChar *) value);
 5940: 		value = strip;
 5941: 	    }
 5942:     	    res = xmlAddID(NULL, attr->doc, value, attr);
 5943: 	    if (res == NULL) {
 5944: 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 5945: 		xmlSchemaPSimpleTypeErr(ctxt,
 5946: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5947: 		    NULL, (xmlNodePtr) attr,
 5948: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 5949: 		    NULL, NULL, "Duplicate value '%s' of simple "
 5950: 		    "type 'xs:ID'", value, NULL);
 5951: 	    } else
 5952: 		attr->atype = XML_ATTRIBUTE_ID;
 5953: 	}
 5954:     } else if (ret > 0) {
 5955: 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 5956: 	xmlSchemaPSimpleTypeErr(ctxt,
 5957: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5958: 	    NULL, (xmlNodePtr) attr,
 5959: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 5960: 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
 5961: 	    "not a valid 'xs:NCName'",
 5962: 	    value, NULL);
 5963:     }
 5964:     if (value != NULL)
 5965: 	xmlFree((xmlChar *)value);
 5966: 
 5967:     return (ret);
 5968: }
 5969: 
 5970: static int
 5971: xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
 5972: 		    xmlNodePtr ownerElem,
 5973: 		    const xmlChar *name)
 5974: {
 5975:     xmlAttrPtr attr;
 5976: 
 5977:     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
 5978:     if (attr == NULL)
 5979: 	return(0);
 5980:     return(xmlSchemaPValAttrNodeID(ctxt, attr));
 5981: 
 5982: }
 5983: 
 5984: /**
 5985:  * xmlGetMaxOccurs:
 5986:  * @ctxt:  a schema validation context
 5987:  * @node:  a subtree containing XML Schema informations
 5988:  *
 5989:  * Get the maxOccurs property
 5990:  *
 5991:  * Returns the default if not found, or the value
 5992:  */
 5993: static int
 5994: xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 5995: 		int min, int max, int def, const char *expected)
 5996: {
 5997:     const xmlChar *val, *cur;
 5998:     int ret = 0;
 5999:     xmlAttrPtr attr;
 6000: 
 6001:     attr = xmlSchemaGetPropNode(node, "maxOccurs");
 6002:     if (attr == NULL)
 6003: 	return (def);
 6004:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6005: 
 6006:     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
 6007: 	if (max != UNBOUNDED) {
 6008: 	    xmlSchemaPSimpleTypeErr(ctxt,
 6009: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6010: 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
 6011: 		NULL, (xmlNodePtr) attr, NULL, expected,
 6012: 		val, NULL, NULL, NULL);
 6013: 	    return (def);
 6014: 	} else
 6015: 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
 6016:     }
 6017: 
 6018:     cur = val;
 6019:     while (IS_BLANK_CH(*cur))
 6020:         cur++;
 6021:     if (*cur == 0) {
 6022:         xmlSchemaPSimpleTypeErr(ctxt,
 6023: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6024: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6025: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6026: 	    val, NULL, NULL, NULL);
 6027: 	return (def);
 6028:     }
 6029:     while ((*cur >= '0') && (*cur <= '9')) {
 6030:         ret = ret * 10 + (*cur - '0');
 6031:         cur++;
 6032:     }
 6033:     while (IS_BLANK_CH(*cur))
 6034:         cur++;
 6035:     /*
 6036:     * TODO: Restrict the maximal value to Integer.
 6037:     */
 6038:     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 6039: 	xmlSchemaPSimpleTypeErr(ctxt,
 6040: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6041: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6042: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6043: 	    val, NULL, NULL, NULL);
 6044:         return (def);
 6045:     }
 6046:     return (ret);
 6047: }
 6048: 
 6049: /**
 6050:  * xmlGetMinOccurs:
 6051:  * @ctxt:  a schema validation context
 6052:  * @node:  a subtree containing XML Schema informations
 6053:  *
 6054:  * Get the minOccurs property
 6055:  *
 6056:  * Returns the default if not found, or the value
 6057:  */
 6058: static int
 6059: xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 6060: 		int min, int max, int def, const char *expected)
 6061: {
 6062:     const xmlChar *val, *cur;
 6063:     int ret = 0;
 6064:     xmlAttrPtr attr;
 6065: 
 6066:     attr = xmlSchemaGetPropNode(node, "minOccurs");
 6067:     if (attr == NULL)
 6068: 	return (def);
 6069:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6070:     cur = val;
 6071:     while (IS_BLANK_CH(*cur))
 6072:         cur++;
 6073:     if (*cur == 0) {
 6074:         xmlSchemaPSimpleTypeErr(ctxt,
 6075: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6076: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6077: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6078: 	    val, NULL, NULL, NULL);
 6079:         return (def);
 6080:     }
 6081:     while ((*cur >= '0') && (*cur <= '9')) {
 6082:         ret = ret * 10 + (*cur - '0');
 6083:         cur++;
 6084:     }
 6085:     while (IS_BLANK_CH(*cur))
 6086:         cur++;
 6087:     /*
 6088:     * TODO: Restrict the maximal value to Integer.
 6089:     */
 6090:     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 6091: 	xmlSchemaPSimpleTypeErr(ctxt,
 6092: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6093: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6094: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6095: 	    val, NULL, NULL, NULL);
 6096:         return (def);
 6097:     }
 6098:     return (ret);
 6099: }
 6100: 
 6101: /**
 6102:  * xmlSchemaPGetBoolNodeValue:
 6103:  * @ctxt:  a schema validation context
 6104:  * @ownerDes:  owner designation
 6105:  * @ownerItem:  the owner as a schema item
 6106:  * @node: the node holding the value
 6107:  *
 6108:  * Converts a boolean string value into 1 or 0.
 6109:  *
 6110:  * Returns 0 or 1.
 6111:  */
 6112: static int
 6113: xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
 6114: 			   xmlSchemaBasicItemPtr ownerItem,
 6115: 			   xmlNodePtr node)
 6116: {
 6117:     xmlChar *value = NULL;
 6118:     int res = 0;
 6119: 
 6120:     value = xmlNodeGetContent(node);
 6121:     /*
 6122:     * 3.2.2.1 Lexical representation
 6123:     * An instance of a datatype that is defined as �boolean�
 6124:     * can have the following legal literals {true, false, 1, 0}.
 6125:     */
 6126:     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
 6127:         res = 1;
 6128:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
 6129:         res = 0;
 6130:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
 6131: 	res = 1;
 6132:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
 6133:         res = 0;
 6134:     else {
 6135:         xmlSchemaPSimpleTypeErr(ctxt,
 6136: 	    XML_SCHEMAP_INVALID_BOOLEAN,
 6137: 	    ownerItem, node,
 6138: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 6139: 	    NULL, BAD_CAST value,
 6140: 	    NULL, NULL, NULL);
 6141:     }
 6142:     if (value != NULL)
 6143: 	xmlFree(value);
 6144:     return (res);
 6145: }
 6146: 
 6147: /**
 6148:  * xmlGetBooleanProp:
 6149:  * @ctxt:  a schema validation context
 6150:  * @node:  a subtree containing XML Schema informations
 6151:  * @name:  the attribute name
 6152:  * @def:  the default value
 6153:  *
 6154:  * Evaluate if a boolean property is set
 6155:  *
 6156:  * Returns the default if not found, 0 if found to be false,
 6157:  * 1 if found to be true
 6158:  */
 6159: static int
 6160: xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
 6161: 		  xmlNodePtr node,
 6162:                   const char *name, int def)
 6163: {
 6164:     const xmlChar *val;
 6165: 
 6166:     val = xmlSchemaGetProp(ctxt, node, name);
 6167:     if (val == NULL)
 6168:         return (def);
 6169:     /*
 6170:     * 3.2.2.1 Lexical representation
 6171:     * An instance of a datatype that is defined as �boolean�
 6172:     * can have the following legal literals {true, false, 1, 0}.
 6173:     */
 6174:     if (xmlStrEqual(val, BAD_CAST "true"))
 6175:         def = 1;
 6176:     else if (xmlStrEqual(val, BAD_CAST "false"))
 6177:         def = 0;
 6178:     else if (xmlStrEqual(val, BAD_CAST "1"))
 6179: 	def = 1;
 6180:     else if (xmlStrEqual(val, BAD_CAST "0"))
 6181:         def = 0;
 6182:     else {
 6183:         xmlSchemaPSimpleTypeErr(ctxt,
 6184: 	    XML_SCHEMAP_INVALID_BOOLEAN,
 6185: 	    NULL,
 6186: 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
 6187: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 6188: 	    NULL, val, NULL, NULL, NULL);
 6189:     }
 6190:     return (def);
 6191: }
 6192: 
 6193: /************************************************************************
 6194:  * 									*
 6195:  *		Shema extraction from an Infoset			*
 6196:  * 									*
 6197:  ************************************************************************/
 6198: static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
 6199:                                                  ctxt, xmlSchemaPtr schema,
 6200:                                                  xmlNodePtr node,
 6201: 						 int topLevel);
 6202: static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
 6203:                                                   ctxt,
 6204:                                                   xmlSchemaPtr schema,
 6205:                                                   xmlNodePtr node,
 6206: 						  int topLevel);
 6207: static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
 6208:                                                   ctxt,
 6209:                                                   xmlSchemaPtr schema,
 6210:                                                   xmlNodePtr node,
 6211: 						  xmlSchemaTypeType parentType);
 6212: static xmlSchemaBasicItemPtr
 6213: xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 6214: 			     xmlSchemaPtr schema,
 6215: 			     xmlNodePtr node,
 6216: 			     xmlSchemaItemListPtr uses,
 6217: 			     int parentType);
 6218: static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
 6219:                                            xmlSchemaPtr schema,
 6220:                                            xmlNodePtr node);
 6221: static xmlSchemaWildcardPtr
 6222: xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 6223:                            xmlSchemaPtr schema, xmlNodePtr node);
 6224: 
 6225: /**
 6226:  * xmlSchemaPValAttrNodeValue:
 6227:  *
 6228:  * @ctxt:  a schema parser context
 6229:  * @ownerDes: the designation of the parent element
 6230:  * @ownerItem: the schema object owner if existent
 6231:  * @attr:  the schema attribute node being validated
 6232:  * @value: the value
 6233:  * @type: the built-in type to be validated against
 6234:  *
 6235:  * Validates a value against the given built-in type.
 6236:  * This one is intended to be used internally for validation
 6237:  * of schema attribute values during parsing of the schema.
 6238:  *
 6239:  * Returns 0 if the value is valid, a positive error code
 6240:  * number otherwise and -1 in case of an internal or API error.
 6241:  */
 6242: static int
 6243: xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
 6244: 			   xmlSchemaBasicItemPtr ownerItem,
 6245: 			   xmlAttrPtr attr,
 6246: 			   const xmlChar *value,
 6247: 			   xmlSchemaTypePtr type)
 6248: {
 6249: 
 6250:     int ret = 0;
 6251: 
 6252:     /*
 6253:     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
 6254:     * one is really meant to be used internally, so better not.
 6255:     */
 6256:     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
 6257: 	return (-1);
 6258:     if (type->type != XML_SCHEMA_TYPE_BASIC) {
 6259: 	PERROR_INT("xmlSchemaPValAttrNodeValue",
 6260: 	    "the given type is not a built-in type");
 6261: 	return (-1);
 6262:     }
 6263:     switch (type->builtInType) {
 6264: 	case XML_SCHEMAS_NCNAME:
 6265: 	case XML_SCHEMAS_QNAME:
 6266: 	case XML_SCHEMAS_ANYURI:
 6267: 	case XML_SCHEMAS_TOKEN:
 6268: 	case XML_SCHEMAS_LANGUAGE:
 6269: 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
 6270: 		(xmlNodePtr) attr);
 6271: 	    break;
 6272: 	default: {
 6273: 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
 6274: 		"validation using the given type is not supported while "
 6275: 		"parsing a schema");
 6276: 	    return (-1);
 6277: 	}
 6278:     }
 6279:     /*
 6280:     * TODO: Should we use the S4S error codes instead?
 6281:     */
 6282:     if (ret < 0) {
 6283: 	PERROR_INT("xmlSchemaPValAttrNodeValue",
 6284: 	    "failed to validate a schema attribute value");
 6285: 	return (-1);
 6286:     } else if (ret > 0) {
 6287: 	if (WXS_IS_LIST(type))
 6288: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 6289: 	else
 6290: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
 6291: 	xmlSchemaPSimpleTypeErr(pctxt,
 6292: 	    ret, ownerItem, (xmlNodePtr) attr,
 6293: 	    type, NULL, value, NULL, NULL, NULL);
 6294:     }
 6295:     return (ret);
 6296: }
 6297: 
 6298: /**
 6299:  * xmlSchemaPValAttrNode:
 6300:  *
 6301:  * @ctxt:  a schema parser context
 6302:  * @ownerDes: the designation of the parent element
 6303:  * @ownerItem: the schema object owner if existent
 6304:  * @attr:  the schema attribute node being validated
 6305:  * @type: the built-in type to be validated against
 6306:  * @value: the resulting value if any
 6307:  *
 6308:  * Extracts and validates a value against the given built-in type.
 6309:  * This one is intended to be used internally for validation
 6310:  * of schema attribute values during parsing of the schema.
 6311:  *
 6312:  * Returns 0 if the value is valid, a positive error code
 6313:  * number otherwise and -1 in case of an internal or API error.
 6314:  */
 6315: static int
 6316: xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
 6317: 			   xmlSchemaBasicItemPtr ownerItem,
 6318: 			   xmlAttrPtr attr,
 6319: 			   xmlSchemaTypePtr type,
 6320: 			   const xmlChar **value)
 6321: {
 6322:     const xmlChar *val;
 6323: 
 6324:     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
 6325: 	return (-1);
 6326: 
 6327:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6328:     if (value != NULL)
 6329: 	*value = val;
 6330: 
 6331:     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
 6332: 	val, type));
 6333: }
 6334: 
 6335: /**
 6336:  * xmlSchemaPValAttr:
 6337:  *
 6338:  * @ctxt:  a schema parser context
 6339:  * @node: the element node of the attribute
 6340:  * @ownerDes: the designation of the parent element
 6341:  * @ownerItem: the schema object owner if existent
 6342:  * @ownerElem: the owner element node
 6343:  * @name:  the name of the schema attribute node
 6344:  * @type: the built-in type to be validated against
 6345:  * @value: the resulting value if any
 6346:  *
 6347:  * Extracts and validates a value against the given built-in type.
 6348:  * This one is intended to be used internally for validation
 6349:  * of schema attribute values during parsing of the schema.
 6350:  *
 6351:  * Returns 0 if the value is valid, a positive error code
 6352:  * number otherwise and -1 in case of an internal or API error.
 6353:  */
 6354: static int
 6355: xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
 6356: 		       xmlSchemaBasicItemPtr ownerItem,
 6357: 		       xmlNodePtr ownerElem,
 6358: 		       const char *name,
 6359: 		       xmlSchemaTypePtr type,
 6360: 		       const xmlChar **value)
 6361: {
 6362:     xmlAttrPtr attr;
 6363: 
 6364:     if ((ctxt == NULL) || (type == NULL)) {
 6365: 	if (value != NULL)
 6366: 	    *value = NULL;
 6367: 	return (-1);
 6368:     }
 6369:     if (type->type != XML_SCHEMA_TYPE_BASIC) {
 6370: 	if (value != NULL)
 6371: 	    *value = NULL;
 6372: 	xmlSchemaPErr(ctxt, ownerElem,
 6373: 	    XML_SCHEMAP_INTERNAL,
 6374: 	    "Internal error: xmlSchemaPValAttr, the given "
 6375: 	    "type '%s' is not a built-in type.\n",
 6376: 	    type->name, NULL);
 6377: 	return (-1);
 6378:     }
 6379:     attr = xmlSchemaGetPropNode(ownerElem, name);
 6380:     if (attr == NULL) {
 6381: 	if (value != NULL)
 6382: 	    *value = NULL;
 6383: 	return (0);
 6384:     }
 6385:     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
 6386: 	type, value));
 6387: }
 6388: 
 6389: static int
 6390: xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
 6391: 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 6392: 		  xmlNodePtr node,
 6393: 		  xmlAttrPtr attr,
 6394: 		  const xmlChar *namespaceName)
 6395: {
 6396:     /* TODO: Pointer comparison instead? */
 6397:     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
 6398: 	return (0);
 6399:     if (xmlStrEqual(xmlSchemaNs, namespaceName))
 6400: 	return (0);
 6401:     /*
 6402:     * Check if the referenced namespace was <import>ed.
 6403:     */
 6404:     if (WXS_BUCKET(pctxt)->relations != NULL) {
 6405: 	xmlSchemaSchemaRelationPtr rel;
 6406: 
 6407: 	rel = WXS_BUCKET(pctxt)->relations;
 6408: 	do {
 6409: 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
 6410: 		xmlStrEqual(namespaceName, rel->importNamespace))
 6411: 		return (0);
 6412: 	    rel = rel->next;
 6413: 	} while (rel != NULL);
 6414:     }
 6415:     /*
 6416:     * No matching <import>ed namespace found.
 6417:     */
 6418:     {
 6419: 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
 6420: 
 6421: 	if (namespaceName == NULL)
 6422: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 6423: 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 6424: 		"References from this schema to components in no "
 6425: 		"namespace are not allowed, since not indicated by an "
 6426: 		"import statement", NULL, NULL);
 6427: 	else
 6428: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 6429: 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 6430: 		"References from this schema to components in the "
 6431: 		"namespace '%s' are not allowed, since not indicated by an "
 6432: 		"import statement", namespaceName, NULL);
 6433:     }
 6434:     return (XML_SCHEMAP_SRC_RESOLVE);
 6435: }
 6436: 
 6437: /**
 6438:  * xmlSchemaParseLocalAttributes:
 6439:  * @ctxt:  a schema validation context
 6440:  * @schema:  the schema being built
 6441:  * @node:  a subtree containing XML Schema informations
 6442:  * @type:  the hosting type where the attributes will be anchored
 6443:  *
 6444:  * Parses attribute uses and attribute declarations and
 6445:  * attribute group references.
 6446:  */
 6447: static int
 6448: xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6449:                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
 6450: 			int parentType, int *hasRefs)
 6451: {
 6452:     void *item;
 6453: 
 6454:     while ((IS_SCHEMA((*child), "attribute")) ||
 6455:            (IS_SCHEMA((*child), "attributeGroup"))) {
 6456:         if (IS_SCHEMA((*child), "attribute")) {
 6457: 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
 6458: 		*list, parentType);
 6459:         } else {
 6460:             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
 6461: 	    if ((item != NULL) && (hasRefs != NULL))
 6462: 		*hasRefs = 1;
 6463:         }
 6464: 	if (item != NULL) {
 6465: 	    if (*list == NULL) {
 6466: 		/* TODO: Customize grow factor. */
 6467: 		*list = xmlSchemaItemListCreate();
 6468: 		if (*list == NULL)
 6469: 		    return(-1);
 6470: 	    }
 6471: 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
 6472: 		return(-1);
 6473: 	}
 6474:         *child = (*child)->next;
 6475:     }
 6476:     return (0);
 6477: }
 6478: 
 6479: /**
 6480:  * xmlSchemaParseAnnotation:
 6481:  * @ctxt:  a schema validation context
 6482:  * @schema:  the schema being built
 6483:  * @node:  a subtree containing XML Schema informations
 6484:  *
 6485:  * parse a XML schema Attrribute declaration
 6486:  * *WARNING* this interface is highly subject to change
 6487:  *
 6488:  * Returns -1 in case of error, 0 if the declaration is improper and
 6489:  *         1 in case of success.
 6490:  */
 6491: static xmlSchemaAnnotPtr
 6492: xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
 6493: {
 6494:     xmlSchemaAnnotPtr ret;
 6495:     xmlNodePtr child = NULL;
 6496:     xmlAttrPtr attr;
 6497:     int barked = 0;
 6498: 
 6499:     /*
 6500:     * INFO: S4S completed.
 6501:     */
 6502:     /*
 6503:     * id = ID
 6504:     * {any attributes with non-schema namespace . . .}>
 6505:     * Content: (appinfo | documentation)*
 6506:     */
 6507:     if ((ctxt == NULL) || (node == NULL))
 6508:         return (NULL);
 6509:     if (needed)
 6510: 	ret = xmlSchemaNewAnnot(ctxt, node);
 6511:     else
 6512: 	ret = NULL;
 6513:     attr = node->properties;
 6514:     while (attr != NULL) {
 6515: 	if (((attr->ns == NULL) &&
 6516: 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
 6517: 	    ((attr->ns != NULL) &&
 6518: 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 6519: 
 6520: 	    xmlSchemaPIllegalAttrErr(ctxt,
 6521: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6522: 	}
 6523: 	attr = attr->next;
 6524:     }
 6525:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6526:     /*
 6527:     * And now for the children...
 6528:     */
 6529:     child = node->children;
 6530:     while (child != NULL) {
 6531: 	if (IS_SCHEMA(child, "appinfo")) {
 6532: 	    /* TODO: make available the content of "appinfo". */
 6533: 	    /*
 6534: 	    * source = anyURI
 6535: 	    * {any attributes with non-schema namespace . . .}>
 6536: 	    * Content: ({any})*
 6537: 	    */
 6538: 	    attr = child->properties;
 6539: 	    while (attr != NULL) {
 6540: 		if (((attr->ns == NULL) &&
 6541: 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
 6542: 		     ((attr->ns != NULL) &&
 6543: 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 6544: 
 6545: 		    xmlSchemaPIllegalAttrErr(ctxt,
 6546: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6547: 		}
 6548: 		attr = attr->next;
 6549: 	    }
 6550: 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
 6551: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 6552: 	    child = child->next;
 6553: 	} else if (IS_SCHEMA(child, "documentation")) {
 6554: 	    /* TODO: make available the content of "documentation". */
 6555: 	    /*
 6556: 	    * source = anyURI
 6557: 	    * {any attributes with non-schema namespace . . .}>
 6558: 	    * Content: ({any})*
 6559: 	    */
 6560: 	    attr = child->properties;
 6561: 	    while (attr != NULL) {
 6562: 		if (attr->ns == NULL) {
 6563: 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
 6564: 			xmlSchemaPIllegalAttrErr(ctxt,
 6565: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6566: 		    }
 6567: 		} else {
 6568: 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
 6569: 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
 6570: 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
 6571: 
 6572: 			xmlSchemaPIllegalAttrErr(ctxt,
 6573: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6574: 		    }
 6575: 		}
 6576: 		attr = attr->next;
 6577: 	    }
 6578: 	    /*
 6579: 	    * Attribute "xml:lang".
 6580: 	    */
 6581: 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
 6582: 	    if (attr != NULL)
 6583: 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
 6584: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
 6585: 	    child = child->next;
 6586: 	} else {
 6587: 	    if (!barked)
 6588: 		xmlSchemaPContentErr(ctxt,
 6589: 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6590: 		    NULL, node, child, NULL, "(appinfo | documentation)*");
 6591: 	    barked = 1;
 6592: 	    child = child->next;
 6593: 	}
 6594:     }
 6595: 
 6596:     return (ret);
 6597: }
 6598: 
 6599: /**
 6600:  * xmlSchemaParseFacet:
 6601:  * @ctxt:  a schema validation context
 6602:  * @schema:  the schema being built
 6603:  * @node:  a subtree containing XML Schema informations
 6604:  *
 6605:  * parse a XML schema Facet declaration
 6606:  * *WARNING* this interface is highly subject to change
 6607:  *
 6608:  * Returns the new type structure or NULL in case of error
 6609:  */
 6610: static xmlSchemaFacetPtr
 6611: xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6612:                     xmlNodePtr node)
 6613: {
 6614:     xmlSchemaFacetPtr facet;
 6615:     xmlNodePtr child = NULL;
 6616:     const xmlChar *value;
 6617: 
 6618:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6619:         return (NULL);
 6620: 
 6621:     facet = xmlSchemaNewFacet();
 6622:     if (facet == NULL) {
 6623:         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
 6624:         return (NULL);
 6625:     }
 6626:     facet->node = node;
 6627:     value = xmlSchemaGetProp(ctxt, node, "value");
 6628:     if (value == NULL) {
 6629:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
 6630:                        "Facet %s has no value\n", node->name, NULL);
 6631:         xmlSchemaFreeFacet(facet);
 6632:         return (NULL);
 6633:     }
 6634:     if (IS_SCHEMA(node, "minInclusive")) {
 6635:         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
 6636:     } else if (IS_SCHEMA(node, "minExclusive")) {
 6637:         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
 6638:     } else if (IS_SCHEMA(node, "maxInclusive")) {
 6639:         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
 6640:     } else if (IS_SCHEMA(node, "maxExclusive")) {
 6641:         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
 6642:     } else if (IS_SCHEMA(node, "totalDigits")) {
 6643:         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
 6644:     } else if (IS_SCHEMA(node, "fractionDigits")) {
 6645:         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
 6646:     } else if (IS_SCHEMA(node, "pattern")) {
 6647:         facet->type = XML_SCHEMA_FACET_PATTERN;
 6648:     } else if (IS_SCHEMA(node, "enumeration")) {
 6649:         facet->type = XML_SCHEMA_FACET_ENUMERATION;
 6650:     } else if (IS_SCHEMA(node, "whiteSpace")) {
 6651:         facet->type = XML_SCHEMA_FACET_WHITESPACE;
 6652:     } else if (IS_SCHEMA(node, "length")) {
 6653:         facet->type = XML_SCHEMA_FACET_LENGTH;
 6654:     } else if (IS_SCHEMA(node, "maxLength")) {
 6655:         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
 6656:     } else if (IS_SCHEMA(node, "minLength")) {
 6657:         facet->type = XML_SCHEMA_FACET_MINLENGTH;
 6658:     } else {
 6659:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
 6660:                        "Unknown facet type %s\n", node->name, NULL);
 6661:         xmlSchemaFreeFacet(facet);
 6662:         return (NULL);
 6663:     }
 6664:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6665:     facet->value = value;
 6666:     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
 6667: 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
 6668: 	const xmlChar *fixed;
 6669: 
 6670: 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
 6671: 	if (fixed != NULL) {
 6672: 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
 6673: 		facet->fixed = 1;
 6674: 	}
 6675:     }
 6676:     child = node->children;
 6677: 
 6678:     if (IS_SCHEMA(child, "annotation")) {
 6679:         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6680:         child = child->next;
 6681:     }
 6682:     if (child != NULL) {
 6683:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
 6684:                        "Facet %s has unexpected child content\n",
 6685:                        node->name, NULL);
 6686:     }
 6687:     return (facet);
 6688: }
 6689: 
 6690: /**
 6691:  * xmlSchemaParseWildcardNs:
 6692:  * @ctxt:  a schema parser context
 6693:  * @wildc:  the wildcard, already created
 6694:  * @node:  a subtree containing XML Schema informations
 6695:  *
 6696:  * Parses the attribute "processContents" and "namespace"
 6697:  * of a xsd:anyAttribute and xsd:any.
 6698:  * *WARNING* this interface is highly subject to change
 6699:  *
 6700:  * Returns 0 if everything goes fine, a positive error code
 6701:  * if something is not valid and -1 if an internal error occurs.
 6702:  */
 6703: static int
 6704: xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
 6705: 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 6706: 			 xmlSchemaWildcardPtr wildc,
 6707: 			 xmlNodePtr node)
 6708: {
 6709:     const xmlChar *pc, *ns, *dictnsItem;
 6710:     int ret = 0;
 6711:     xmlChar *nsItem;
 6712:     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
 6713:     xmlAttrPtr attr;
 6714: 
 6715:     pc = xmlSchemaGetProp(ctxt, node, "processContents");
 6716:     if ((pc == NULL)
 6717:         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
 6718:         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 6719:     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
 6720:         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
 6721:     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
 6722:         wildc->processContents = XML_SCHEMAS_ANY_LAX;
 6723:     } else {
 6724:         xmlSchemaPSimpleTypeErr(ctxt,
 6725: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6726: 	    NULL, node,
 6727: 	    NULL, "(strict | skip | lax)", pc,
 6728: 	    NULL, NULL, NULL);
 6729:         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 6730: 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 6731:     }
 6732:     /*
 6733:      * Build the namespace constraints.
 6734:      */
 6735:     attr = xmlSchemaGetPropNode(node, "namespace");
 6736:     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6737:     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
 6738: 	wildc->any = 1;
 6739:     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
 6740: 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 6741: 	if (wildc->negNsSet == NULL) {
 6742: 	    return (-1);
 6743: 	}
 6744: 	wildc->negNsSet->value = ctxt->targetNamespace;
 6745:     } else {
 6746: 	const xmlChar *end, *cur;
 6747: 
 6748: 	cur = ns;
 6749: 	do {
 6750: 	    while (IS_BLANK_CH(*cur))
 6751: 		cur++;
 6752: 	    end = cur;
 6753: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 6754: 		end++;
 6755: 	    if (end == cur)
 6756: 		break;
 6757: 	    nsItem = xmlStrndup(cur, end - cur);
 6758: 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
 6759: 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
 6760: 		xmlSchemaPSimpleTypeErr(ctxt,
 6761: 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
 6762: 		    NULL, (xmlNodePtr) attr,
 6763: 		    NULL,
 6764: 		    "((##any | ##other) | List of (xs:anyURI | "
 6765: 		    "(##targetNamespace | ##local)))",
 6766: 		    nsItem, NULL, NULL, NULL);
 6767: 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
 6768: 	    } else {
 6769: 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
 6770: 		    dictnsItem = ctxt->targetNamespace;
 6771: 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
 6772: 		    dictnsItem = NULL;
 6773: 		} else {
 6774: 		    /*
 6775: 		    * Validate the item (anyURI).
 6776: 		    */
 6777: 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
 6778: 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
 6779: 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
 6780: 		}
 6781: 		/*
 6782: 		* Avoid dublicate namespaces.
 6783: 		*/
 6784: 		tmp = wildc->nsSet;
 6785: 		while (tmp != NULL) {
 6786: 		    if (dictnsItem == tmp->value)
 6787: 			break;
 6788: 		    tmp = tmp->next;
 6789: 		}
 6790: 		if (tmp == NULL) {
 6791: 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
 6792: 		    if (tmp == NULL) {
 6793: 			xmlFree(nsItem);
 6794: 			return (-1);
 6795: 		    }
 6796: 		    tmp->value = dictnsItem;
 6797: 		    tmp->next = NULL;
 6798: 		    if (wildc->nsSet == NULL)
 6799: 			wildc->nsSet = tmp;
 6800: 		    else if (lastNs != NULL)
 6801: 			lastNs->next = tmp;
 6802: 		    lastNs = tmp;
 6803: 		}
 6804: 
 6805: 	    }
 6806: 	    xmlFree(nsItem);
 6807: 	    cur = end;
 6808: 	} while (*cur != 0);
 6809:     }
 6810:     return (ret);
 6811: }
 6812: 
 6813: static int
 6814: xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
 6815: 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
 6816: 				 xmlNodePtr node,
 6817: 				 int minOccurs,
 6818: 				 int maxOccurs) {
 6819: 
 6820:     if ((maxOccurs == 0) && ( minOccurs == 0))
 6821: 	return (0);
 6822:     if (maxOccurs != UNBOUNDED) {
 6823: 	/*
 6824: 	* TODO: Maybe we should better not create the particle,
 6825: 	* if min/max is invalid, since it could confuse the build of the
 6826: 	* content model.
 6827: 	*/
 6828: 	/*
 6829: 	* 3.9.6 Schema Component Constraint: Particle Correct
 6830: 	*
 6831: 	*/
 6832: 	if (maxOccurs < 1) {
 6833: 	    /*
 6834: 	    * 2.2 {max occurs} must be greater than or equal to 1.
 6835: 	    */
 6836: 	    xmlSchemaPCustomAttrErr(ctxt,
 6837: 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
 6838: 		NULL, NULL,
 6839: 		xmlSchemaGetPropNode(node, "maxOccurs"),
 6840: 		"The value must be greater than or equal to 1");
 6841: 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
 6842: 	} else if (minOccurs > maxOccurs) {
 6843: 	    /*
 6844: 	    * 2.1 {min occurs} must not be greater than {max occurs}.
 6845: 	    */
 6846: 	    xmlSchemaPCustomAttrErr(ctxt,
 6847: 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
 6848: 		NULL, NULL,
 6849: 		xmlSchemaGetPropNode(node, "minOccurs"),
 6850: 		"The value must not be greater than the value of 'maxOccurs'");
 6851: 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
 6852: 	}
 6853:     }
 6854:     return (0);
 6855: }
 6856: 
 6857: /**
 6858:  * xmlSchemaParseAny:
 6859:  * @ctxt:  a schema validation context
 6860:  * @schema:  the schema being built
 6861:  * @node:  a subtree containing XML Schema informations
 6862:  *
 6863:  * Parsea a XML schema <any> element. A particle and wildcard
 6864:  * will be created (except if minOccurs==maxOccurs==0, in this case
 6865:  * nothing will be created).
 6866:  * *WARNING* this interface is highly subject to change
 6867:  *
 6868:  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
 6869:  */
 6870: static xmlSchemaParticlePtr
 6871: xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6872:                   xmlNodePtr node)
 6873: {
 6874:     xmlSchemaParticlePtr particle;
 6875:     xmlNodePtr child = NULL;
 6876:     xmlSchemaWildcardPtr wild;
 6877:     int min, max;
 6878:     xmlAttrPtr attr;
 6879:     xmlSchemaAnnotPtr annot = NULL;
 6880: 
 6881:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6882:         return (NULL);
 6883:     /*
 6884:     * Check for illegal attributes.
 6885:     */
 6886:     attr = node->properties;
 6887:     while (attr != NULL) {
 6888: 	if (attr->ns == NULL) {
 6889: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 6890: 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 6891: 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 6892: 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 6893: 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 6894: 		xmlSchemaPIllegalAttrErr(ctxt,
 6895: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6896: 	    }
 6897: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 6898: 	    xmlSchemaPIllegalAttrErr(ctxt,
 6899: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6900: 	}
 6901: 	attr = attr->next;
 6902:     }
 6903:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6904:     /*
 6905:     * minOccurs/maxOccurs.
 6906:     */
 6907:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 6908: 	"(xs:nonNegativeInteger | unbounded)");
 6909:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
 6910: 	"xs:nonNegativeInteger");
 6911:     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 6912:     /*
 6913:     * Create & parse the wildcard.
 6914:     */
 6915:     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
 6916:     if (wild == NULL)
 6917: 	return (NULL);
 6918:     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
 6919:     /*
 6920:     * And now for the children...
 6921:     */
 6922:     child = node->children;
 6923:     if (IS_SCHEMA(child, "annotation")) {
 6924:         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6925:         child = child->next;
 6926:     }
 6927:     if (child != NULL) {
 6928: 	xmlSchemaPContentErr(ctxt,
 6929: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6930: 	    NULL, node, child,
 6931: 	    NULL, "(annotation?)");
 6932:     }
 6933:     /*
 6934:     * No component if minOccurs==maxOccurs==0.
 6935:     */
 6936:     if ((min == 0) && (max == 0)) {
 6937: 	/* Don't free the wildcard, since it's already on the list. */
 6938: 	return (NULL);
 6939:     }
 6940:     /*
 6941:     * Create the particle.
 6942:     */
 6943:     particle = xmlSchemaAddParticle(ctxt, node, min, max);
 6944:     if (particle == NULL)
 6945:         return (NULL);
 6946:     particle->annot = annot;
 6947:     particle->children = (xmlSchemaTreeItemPtr) wild;
 6948: 
 6949:     return (particle);
 6950: }
 6951: 
 6952: /**
 6953:  * xmlSchemaParseNotation:
 6954:  * @ctxt:  a schema validation context
 6955:  * @schema:  the schema being built
 6956:  * @node:  a subtree containing XML Schema informations
 6957:  *
 6958:  * parse a XML schema Notation declaration
 6959:  *
 6960:  * Returns the new structure or NULL in case of error
 6961:  */
 6962: static xmlSchemaNotationPtr
 6963: xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6964:                        xmlNodePtr node)
 6965: {
 6966:     const xmlChar *name;
 6967:     xmlSchemaNotationPtr ret;
 6968:     xmlNodePtr child = NULL;
 6969: 
 6970:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6971:         return (NULL);
 6972:     name = xmlSchemaGetProp(ctxt, node, "name");
 6973:     if (name == NULL) {
 6974:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
 6975:                        "Notation has no name\n", NULL, NULL);
 6976:         return (NULL);
 6977:     }
 6978:     ret = xmlSchemaAddNotation(ctxt, schema, name,
 6979: 	ctxt->targetNamespace, node);
 6980:     if (ret == NULL)
 6981:         return (NULL);
 6982:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6983: 
 6984:     child = node->children;
 6985:     if (IS_SCHEMA(child, "annotation")) {
 6986:         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6987:         child = child->next;
 6988:     }
 6989:     if (child != NULL) {
 6990: 	xmlSchemaPContentErr(ctxt,
 6991: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6992: 	    NULL, node, child,
 6993: 	    NULL, "(annotation?)");
 6994:     }
 6995: 
 6996:     return (ret);
 6997: }
 6998: 
 6999: /**
 7000:  * xmlSchemaParseAnyAttribute:
 7001:  * @ctxt:  a schema validation context
 7002:  * @schema:  the schema being built
 7003:  * @node:  a subtree containing XML Schema informations
 7004:  *
 7005:  * parse a XML schema AnyAttrribute declaration
 7006:  * *WARNING* this interface is highly subject to change
 7007:  *
 7008:  * Returns a wildcard or NULL.
 7009:  */
 7010: static xmlSchemaWildcardPtr
 7011: xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 7012:                            xmlSchemaPtr schema, xmlNodePtr node)
 7013: {
 7014:     xmlSchemaWildcardPtr ret;
 7015:     xmlNodePtr child = NULL;
 7016:     xmlAttrPtr attr;
 7017: 
 7018:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 7019:         return (NULL);
 7020: 
 7021:     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
 7022: 	node);
 7023:     if (ret == NULL) {
 7024:         return (NULL);
 7025:     }
 7026:     /*
 7027:     * Check for illegal attributes.
 7028:     */
 7029:     attr = node->properties;
 7030:     while (attr != NULL) {
 7031: 	if (attr->ns == NULL) {
 7032: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 7033: 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 7034: 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 7035: 		xmlSchemaPIllegalAttrErr(ctxt,
 7036: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7037: 	    }
 7038: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7039: 	    xmlSchemaPIllegalAttrErr(ctxt,
 7040: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7041: 	}
 7042: 	attr = attr->next;
 7043:     }
 7044:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 7045:     /*
 7046:     * Parse the namespace list.
 7047:     */
 7048:     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
 7049: 	return (NULL);
 7050:     /*
 7051:     * And now for the children...
 7052:     */
 7053:     child = node->children;
 7054:     if (IS_SCHEMA(child, "annotation")) {
 7055:         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 7056:         child = child->next;
 7057:     }
 7058:     if (child != NULL) {
 7059: 	xmlSchemaPContentErr(ctxt,
 7060: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7061: 	    NULL, node, child,
 7062: 	    NULL, "(annotation?)");
 7063:     }
 7064: 
 7065:     return (ret);
 7066: }
 7067: 
 7068: 
 7069: /**
 7070:  * xmlSchemaParseAttribute:
 7071:  * @ctxt:  a schema validation context
 7072:  * @schema:  the schema being built
 7073:  * @node:  a subtree containing XML Schema informations
 7074:  *
 7075:  * parse a XML schema Attrribute declaration
 7076:  * *WARNING* this interface is highly subject to change
 7077:  *
 7078:  * Returns the attribute declaration.
 7079:  */
 7080: static xmlSchemaBasicItemPtr
 7081: xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 7082: 			     xmlSchemaPtr schema,
 7083: 			     xmlNodePtr node,
 7084: 			     xmlSchemaItemListPtr uses,
 7085: 			     int parentType)
 7086: {
 7087:     const xmlChar *attrValue, *name = NULL, *ns = NULL;
 7088:     xmlSchemaAttributeUsePtr use = NULL;
 7089:     xmlNodePtr child = NULL;
 7090:     xmlAttrPtr attr;
 7091:     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
 7092:     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 7093:     int	nberrors, hasForm = 0, defValueType = 0;
 7094: 
 7095: #define WXS_ATTR_DEF_VAL_DEFAULT 1
 7096: #define WXS_ATTR_DEF_VAL_FIXED 2
 7097: 
 7098:     /*
 7099:      * 3.2.3 Constraints on XML Representations of Attribute Declarations
 7100:      */
 7101: 
 7102:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7103:         return (NULL);
 7104:     attr = xmlSchemaGetPropNode(node, "ref");
 7105:     if (attr != NULL) {
 7106: 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
 7107: 	    NULL, attr, &tmpNs, &tmpName) != 0) {
 7108: 	    return (NULL);
 7109: 	}
 7110: 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
 7111: 	    return(NULL);
 7112: 	isRef = 1;
 7113:     }
 7114:     nberrors = pctxt->nberrors;
 7115:     /*
 7116:     * Check for illegal attributes.
 7117:     */
 7118:     attr = node->properties;
 7119:     while (attr != NULL) {
 7120: 	if (attr->ns == NULL) {
 7121: 	    if (isRef) {
 7122: 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 7123: 		    xmlSchemaPValAttrNodeID(pctxt, attr);
 7124: 		    goto attr_next;
 7125: 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
 7126: 		    goto attr_next;
 7127: 		}
 7128: 	    } else {
 7129: 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
 7130: 		    goto attr_next;
 7131: 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 7132: 		    xmlSchemaPValAttrNodeID(pctxt, attr);
 7133: 		    goto attr_next;
 7134: 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
 7135: 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
 7136: 			attr, &tmpNs, &tmpName);
 7137: 		    goto attr_next;
 7138: 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
 7139: 		    /*
 7140: 		    * Evaluate the target namespace
 7141: 		    */
 7142: 		    hasForm = 1;
 7143: 		    attrValue = xmlSchemaGetNodeContent(pctxt,
 7144: 			(xmlNodePtr) attr);
 7145: 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 7146: 			ns = pctxt->targetNamespace;
 7147: 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
 7148: 		    {
 7149: 			xmlSchemaPSimpleTypeErr(pctxt,
 7150: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 7151: 			    NULL, (xmlNodePtr) attr,
 7152: 			    NULL, "(qualified | unqualified)",
 7153: 			    attrValue, NULL, NULL, NULL);
 7154: 		    }
 7155: 		    goto attr_next;
 7156: 		}
 7157: 	    }
 7158: 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
 7159: 
 7160: 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7161: 		/* TODO: Maybe we need to normalize the value beforehand. */
 7162: 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
 7163: 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 7164: 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
 7165: 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
 7166: 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
 7167: 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
 7168: 		else {
 7169: 		    xmlSchemaPSimpleTypeErr(pctxt,
 7170: 			XML_SCHEMAP_INVALID_ATTR_USE,
 7171: 			NULL, (xmlNodePtr) attr,
 7172: 			NULL, "(optional | prohibited | required)",
 7173: 			attrValue, NULL, NULL, NULL);
 7174: 		}
 7175: 		goto attr_next;
 7176: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
 7177: 		/*
 7178: 		* 3.2.3 : 1
 7179: 		* default and fixed must not both be present.
 7180: 		*/
 7181: 		if (defValue) {
 7182: 		    xmlSchemaPMutualExclAttrErr(pctxt,
 7183: 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7184: 			NULL, attr, "default", "fixed");
 7185: 		} else {
 7186: 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7187: 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
 7188: 		}
 7189: 		goto attr_next;
 7190: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
 7191: 		/*
 7192: 		* 3.2.3 : 1
 7193: 		* default and fixed must not both be present.
 7194: 		*/
 7195: 		if (defValue) {
 7196: 		    xmlSchemaPMutualExclAttrErr(pctxt,
 7197: 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7198: 			NULL, attr, "default", "fixed");
 7199: 		} else {
 7200: 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7201: 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
 7202: 		}
 7203: 		goto attr_next;
 7204: 	    }
 7205: 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
 7206: 	    goto attr_next;
 7207: 
 7208: 	xmlSchemaPIllegalAttrErr(pctxt,
 7209: 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7210: 
 7211: attr_next:
 7212: 	attr = attr->next;
 7213:     }
 7214:     /*
 7215:     * 3.2.3 : 2
 7216:     * If default and use are both present, use must have
 7217:     * the actual value optional.
 7218:     */
 7219:     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
 7220: 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
 7221: 	xmlSchemaPSimpleTypeErr(pctxt,
 7222: 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
 7223: 	    NULL, node, NULL,
 7224: 	    "(optional | prohibited | required)", NULL,
 7225: 	    "The value of the attribute 'use' must be 'optional' "
 7226: 	    "if the attribute 'default' is present",
 7227: 	    NULL, NULL);
 7228:     }
 7229:     /*
 7230:     * We want correct attributes.
 7231:     */
 7232:     if (nberrors != pctxt->nberrors)
 7233: 	return(NULL);
 7234:     if (! isRef) {
 7235: 	xmlSchemaAttributePtr attrDecl;
 7236: 
 7237: 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
 7238: 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
 7239: 	    ns = pctxt->targetNamespace;
 7240: 	/*
 7241: 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
 7242: 	* TODO: Move this to the component layer.
 7243: 	*/
 7244: 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
 7245: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7246: 		XML_SCHEMAP_NO_XSI,
 7247: 		node, NULL,
 7248: 		"The target namespace must not match '%s'",
 7249: 		xmlSchemaInstanceNs, NULL);
 7250: 	}
 7251: 	attr = xmlSchemaGetPropNode(node, "name");
 7252: 	if (attr == NULL) {
 7253: 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 7254: 		NULL, node, "name", NULL);
 7255: 	    return (NULL);
 7256: 	}
 7257: 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 7258: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 7259: 	    return (NULL);
 7260: 	}
 7261: 	/*
 7262: 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
 7263: 	* TODO: Move this to the component layer.
 7264: 	*/
 7265: 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
 7266: 	    xmlSchemaPSimpleTypeErr(pctxt,
 7267: 		XML_SCHEMAP_NO_XMLNS,
 7268: 		NULL, (xmlNodePtr) attr,
 7269: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 7270: 		"The value of the attribute must not match 'xmlns'",
 7271: 		NULL, NULL);
 7272: 	    return (NULL);
 7273: 	}
 7274: 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
 7275: 	    goto check_children;
 7276: 	/*
 7277: 	* Create the attribute use component.
 7278: 	*/
 7279: 	use = xmlSchemaAddAttributeUse(pctxt, node);
 7280: 	if (use == NULL)
 7281: 	    return(NULL);
 7282: 	use->occurs = occurs;
 7283: 	/*
 7284: 	* Create the attribute declaration.
 7285: 	*/
 7286: 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
 7287: 	if (attrDecl == NULL)
 7288: 	    return (NULL);
 7289: 	if (tmpName != NULL) {
 7290: 	    attrDecl->typeName = tmpName;
 7291: 	    attrDecl->typeNs = tmpNs;
 7292: 	}
 7293: 	use->attrDecl = attrDecl;
 7294: 	/*
 7295: 	* Value constraint.
 7296: 	*/
 7297: 	if (defValue != NULL) {
 7298: 	    attrDecl->defValue = defValue;
 7299: 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 7300: 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
 7301: 	}
 7302:     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 7303: 	xmlSchemaQNameRefPtr ref;
 7304: 
 7305: 	/*
 7306: 	* Create the attribute use component.
 7307: 	*/
 7308: 	use = xmlSchemaAddAttributeUse(pctxt, node);
 7309: 	if (use == NULL)
 7310: 	    return(NULL);
 7311: 	/*
 7312: 	* We need to resolve the reference at later stage.
 7313: 	*/
 7314: 	WXS_ADD_PENDING(pctxt, use);
 7315: 	use->occurs = occurs;
 7316: 	/*
 7317: 	* Create a QName reference to the attribute declaration.
 7318: 	*/
 7319: 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
 7320: 	    tmpName, tmpNs);
 7321: 	if (ref == NULL)
 7322: 	    return(NULL);
 7323: 	/*
 7324: 	* Assign the reference. This will be substituted for the
 7325: 	* referenced attribute declaration when the QName is resolved.
 7326: 	*/
 7327: 	use->attrDecl = WXS_ATTR_CAST ref;
 7328: 	/*
 7329: 	* Value constraint.
 7330: 	*/
 7331: 	if (defValue != NULL)
 7332: 	    use->defValue = defValue;
 7333: 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 7334: 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
 7335:     }
 7336: 
 7337: check_children:
 7338:     /*
 7339:     * And now for the children...
 7340:     */
 7341:     child = node->children;
 7342:     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 7343: 	xmlSchemaAttributeUseProhibPtr prohib;
 7344: 
 7345: 	if (IS_SCHEMA(child, "annotation")) {
 7346: 	    xmlSchemaParseAnnotation(pctxt, child, 0);
 7347: 	    child = child->next;
 7348: 	}
 7349: 	if (child != NULL) {
 7350: 	    xmlSchemaPContentErr(pctxt,
 7351: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7352: 		NULL, node, child, NULL,
 7353: 		"(annotation?)");
 7354: 	}
 7355: 	/*
 7356: 	* Check for pointlessness of attribute prohibitions.
 7357: 	*/
 7358: 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
 7359: 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7360: 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7361: 		node, NULL,
 7362: 		"Skipping attribute use prohibition, since it is "
 7363: 		"pointless inside an <attributeGroup>",
 7364: 		NULL, NULL, NULL);
 7365: 	    return(NULL);
 7366: 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
 7367: 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7368: 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7369: 		node, NULL,
 7370: 		"Skipping attribute use prohibition, since it is "
 7371: 		"pointless when extending a type",
 7372: 		NULL, NULL, NULL);
 7373: 	    return(NULL);
 7374: 	}
 7375: 	if (! isRef) {
 7376: 	    tmpName = name;
 7377: 	    tmpNs = ns;
 7378: 	}
 7379: 	/*
 7380: 	* Check for duplicate attribute prohibitions.
 7381: 	*/
 7382: 	if (uses) {
 7383: 	    int i;
 7384: 
 7385: 	    for (i = 0; i < uses->nbItems; i++) {
 7386: 		use = uses->items[i];
 7387: 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
 7388: 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
 7389: 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
 7390: 		{
 7391: 		    xmlChar *str = NULL;
 7392: 
 7393: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7394: 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7395: 			node, NULL,
 7396: 			"Skipping duplicate attribute use prohibition '%s'",
 7397: 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
 7398: 			NULL, NULL);
 7399: 		    FREE_AND_NULL(str)
 7400: 		    return(NULL);
 7401: 		}
 7402: 	    }
 7403: 	}
 7404: 	/*
 7405: 	* Create the attribute prohibition helper component.
 7406: 	*/
 7407: 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
 7408: 	if (prohib == NULL)
 7409: 	    return(NULL);
 7410: 	prohib->node = node;
 7411: 	prohib->name = tmpName;
 7412: 	prohib->targetNamespace = tmpNs;
 7413: 	if (isRef) {
 7414: 	    /*
 7415: 	    * We need at least to resolve to the attribute declaration.
 7416: 	    */
 7417: 	    WXS_ADD_PENDING(pctxt, prohib);
 7418: 	}
 7419: 	return(WXS_BASIC_CAST prohib);
 7420:     } else {
 7421: 	if (IS_SCHEMA(child, "annotation")) {
 7422: 	    /*
 7423: 	    * TODO: Should this go into the attr decl?
 7424: 	    */
 7425: 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7426: 	    child = child->next;
 7427: 	}
 7428: 	if (isRef) {
 7429: 	    if (child != NULL) {
 7430: 		if (IS_SCHEMA(child, "simpleType"))
 7431: 		    /*
 7432: 		    * 3.2.3 : 3.2
 7433: 		    * If ref is present, then all of <simpleType>,
 7434: 		    * form and type must be absent.
 7435: 		    */
 7436: 		    xmlSchemaPContentErr(pctxt,
 7437: 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
 7438: 			NULL, node, child, NULL,
 7439: 			"(annotation?)");
 7440: 		else
 7441: 		    xmlSchemaPContentErr(pctxt,
 7442: 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7443: 			NULL, node, child, NULL,
 7444: 			"(annotation?)");
 7445: 	    }
 7446: 	} else {
 7447: 	    if (IS_SCHEMA(child, "simpleType")) {
 7448: 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
 7449: 		    /*
 7450: 		    * 3.2.3 : 4
 7451: 		    * type and <simpleType> must not both be present.
 7452: 		    */
 7453: 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 7454: 			NULL, node, child,
 7455: 			"The attribute 'type' and the <simpleType> child "
 7456: 			"are mutually exclusive", NULL);
 7457: 		} else
 7458: 		    WXS_ATTRUSE_TYPEDEF(use) =
 7459: 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 7460: 		child = child->next;
 7461: 	    }
 7462: 	    if (child != NULL)
 7463: 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7464: 		NULL, node, child, NULL,
 7465: 		"(annotation?, simpleType?)");
 7466: 	}
 7467:     }
 7468:     return (WXS_BASIC_CAST use);
 7469: }
 7470: 
 7471: 
 7472: static xmlSchemaAttributePtr
 7473: xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
 7474: 			      xmlSchemaPtr schema,
 7475: 			      xmlNodePtr node)
 7476: {
 7477:     const xmlChar *attrValue;
 7478:     xmlSchemaAttributePtr ret;
 7479:     xmlNodePtr child = NULL;
 7480:     xmlAttrPtr attr;
 7481: 
 7482:     /*
 7483:      * Note that the w3c spec assumes the schema to be validated with schema
 7484:      * for schemas beforehand.
 7485:      *
 7486:      * 3.2.3 Constraints on XML Representations of Attribute Declarations
 7487:      */
 7488:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7489:         return (NULL);
 7490:     /*
 7491:     * 3.2.3 : 3.1
 7492:     * One of ref or name must be present, but not both
 7493:     */
 7494:     attr = xmlSchemaGetPropNode(node, "name");
 7495:     if (attr == NULL) {
 7496: 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 7497: 	    NULL, node, "name", NULL);
 7498: 	return (NULL);
 7499:     }
 7500:     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 7501: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
 7502: 	return (NULL);
 7503:     }
 7504:     /*
 7505:     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
 7506:     * TODO: Move this to the component layer.
 7507:     */
 7508:     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
 7509: 	xmlSchemaPSimpleTypeErr(pctxt,
 7510: 	    XML_SCHEMAP_NO_XMLNS,
 7511: 	    NULL, (xmlNodePtr) attr,
 7512: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 7513: 	    "The value of the attribute must not match 'xmlns'",
 7514: 	    NULL, NULL);
 7515: 	return (NULL);
 7516:     }
 7517:     /*
 7518:     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
 7519:     * TODO: Move this to the component layer.
 7520:     *       Or better leave it here and add it to the component layer
 7521:     *       if we have a schema construction API.
 7522:     */
 7523:     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
 7524: 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7525: 	    XML_SCHEMAP_NO_XSI, node, NULL,
 7526: 	    "The target namespace must not match '%s'",
 7527: 	    xmlSchemaInstanceNs, NULL);
 7528:     }
 7529: 
 7530:     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
 7531: 	pctxt->targetNamespace, node, 1);
 7532:     if (ret == NULL)
 7533: 	return (NULL);
 7534:     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
 7535: 
 7536:     /*
 7537:     * Check for illegal attributes.
 7538:     */
 7539:     attr = node->properties;
 7540:     while (attr != NULL) {
 7541: 	if (attr->ns == NULL) {
 7542: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 7543: 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 7544: 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 7545: 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 7546: 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
 7547: 	    {
 7548: 		xmlSchemaPIllegalAttrErr(pctxt,
 7549: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7550: 	    }
 7551: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7552: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7553: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7554: 	}
 7555: 	attr = attr->next;
 7556:     }
 7557:     xmlSchemaPValAttrQName(pctxt, schema, NULL,
 7558: 	node, "type", &ret->typeNs, &ret->typeName);
 7559: 
 7560:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7561:     /*
 7562:     * Attribute "fixed".
 7563:     */
 7564:     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
 7565:     if (ret->defValue != NULL)
 7566: 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
 7567:     /*
 7568:     * Attribute "default".
 7569:     */
 7570:     attr = xmlSchemaGetPropNode(node, "default");
 7571:     if (attr != NULL) {
 7572: 	/*
 7573: 	* 3.2.3 : 1
 7574: 	* default and fixed must not both be present.
 7575: 	*/
 7576: 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
 7577: 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7578: 		WXS_BASIC_CAST ret, attr, "default", "fixed");
 7579: 	} else
 7580: 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7581:     }
 7582:     /*
 7583:     * And now for the children...
 7584:     */
 7585:     child = node->children;
 7586:     if (IS_SCHEMA(child, "annotation")) {
 7587:         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7588:         child = child->next;
 7589:     }
 7590:     if (IS_SCHEMA(child, "simpleType")) {
 7591: 	if (ret->typeName != NULL) {
 7592: 	    /*
 7593: 	    * 3.2.3 : 4
 7594: 	    * type and <simpleType> must not both be present.
 7595: 	    */
 7596: 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 7597: 		NULL, node, child,
 7598: 		"The attribute 'type' and the <simpleType> child "
 7599: 		"are mutually exclusive", NULL);
 7600: 	} else
 7601: 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 7602: 	child = child->next;
 7603:     }
 7604:     if (child != NULL)
 7605: 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7606: 	    NULL, node, child, NULL,
 7607: 	    "(annotation?, simpleType?)");
 7608: 
 7609:     return (ret);
 7610: }
 7611: 
 7612: /**
 7613:  * xmlSchemaParseAttributeGroupRef:
 7614:  * @ctxt:  a schema validation context
 7615:  * @schema:  the schema being built
 7616:  * @node:  a subtree containing XML Schema informations
 7617:  *
 7618:  * Parse an attribute group definition reference.
 7619:  * Note that a reference to an attribute group does not
 7620:  * correspond to any component at all.
 7621:  * *WARNING* this interface is highly subject to change
 7622:  *
 7623:  * Returns the attribute group or NULL in case of error.
 7624:  */
 7625: static xmlSchemaQNameRefPtr
 7626: xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 7627: 				xmlSchemaPtr schema,
 7628: 				xmlNodePtr node)
 7629: {
 7630:     xmlSchemaQNameRefPtr ret;
 7631:     xmlNodePtr child = NULL;
 7632:     xmlAttrPtr attr;
 7633:     const xmlChar *refNs = NULL, *ref = NULL;
 7634: 
 7635:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7636:         return (NULL);
 7637: 
 7638:     attr = xmlSchemaGetPropNode(node, "ref");
 7639:     if (attr == NULL) {
 7640: 	xmlSchemaPMissingAttrErr(pctxt,
 7641: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 7642: 	    NULL, node, "ref", NULL);
 7643: 	return (NULL);
 7644:     }
 7645:     xmlSchemaPValAttrNodeQName(pctxt, schema,
 7646: 	NULL, attr, &refNs, &ref);
 7647:     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
 7648: 	return(NULL);
 7649: 
 7650:     /*
 7651:     * Check for illegal attributes.
 7652:     */
 7653:     attr = node->properties;
 7654:     while (attr != NULL) {
 7655: 	if (attr->ns == NULL) {
 7656: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 7657: 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
 7658: 	    {
 7659: 		xmlSchemaPIllegalAttrErr(pctxt,
 7660: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7661: 	    }
 7662: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7663: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7664: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7665: 	}
 7666: 	attr = attr->next;
 7667:     }
 7668:     /* Attribute ID */
 7669:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7670: 
 7671:     /*
 7672:     * And now for the children...
 7673:     */
 7674:     child = node->children;
 7675:     if (IS_SCHEMA(child, "annotation")) {
 7676: 	/*
 7677: 	* TODO: We do not have a place to store the annotation, do we?
 7678: 	*/
 7679:         xmlSchemaParseAnnotation(pctxt, child, 0);
 7680:         child = child->next;
 7681:     }
 7682:     if (child != NULL) {
 7683: 	xmlSchemaPContentErr(pctxt,
 7684: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7685: 	    NULL, node, child, NULL,
 7686: 	    "(annotation?)");
 7687:     }
 7688: 
 7689:     /*
 7690:     * Handle attribute group redefinitions.
 7691:     */
 7692:     if (pctxt->isRedefine && pctxt->redef &&
 7693: 	(pctxt->redef->item->type ==
 7694: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
 7695: 	(ref == pctxt->redef->refName) &&
 7696: 	(refNs == pctxt->redef->refTargetNs))
 7697:     {
 7698: 	/*
 7699: 	* SPEC src-redefine:
 7700: 	* (7.1) "If it has an <attributeGroup> among its contents
 7701: 	* the �actual value� of whose ref [attribute] is the same
 7702: 	* as the �actual value� of its own name attribute plus
 7703: 	* target namespace, then it must have exactly one such group."
 7704: 	*/
 7705: 	if (pctxt->redefCounter != 0) {
 7706: 	    xmlChar *str = NULL;
 7707: 
 7708: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7709: 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
 7710: 		"The redefining attribute group definition "
 7711: 		"'%s' must not contain more than one "
 7712: 		"reference to the redefined definition",
 7713: 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
 7714: 	    FREE_AND_NULL(str);
 7715: 	    return(NULL);
 7716: 	}
 7717: 	pctxt->redefCounter++;
 7718: 	/*
 7719: 	* URGENT TODO: How to ensure that the reference will not be
 7720: 	* handled by the normal component resolution mechanism?
 7721: 	*/
 7722: 	ret = xmlSchemaNewQNameRef(pctxt,
 7723: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 7724: 	if (ret == NULL)
 7725: 	    return(NULL);
 7726: 	ret->node = node;
 7727: 	pctxt->redef->reference = WXS_BASIC_CAST ret;
 7728:     } else {
 7729: 	/*
 7730: 	* Create a QName-reference helper component. We will substitute this
 7731: 	* component for the attribute uses of the referenced attribute group
 7732: 	* definition.
 7733: 	*/
 7734: 	ret = xmlSchemaNewQNameRef(pctxt,
 7735: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 7736: 	if (ret == NULL)
 7737: 	    return(NULL);
 7738: 	ret->node = node;
 7739: 	/* Add to pending items, to be able to resolve the reference. */
 7740: 	WXS_ADD_PENDING(pctxt, ret);
 7741:     }
 7742:     return (ret);
 7743: }
 7744: 
 7745: /**
 7746:  * xmlSchemaParseAttributeGroupDefinition:
 7747:  * @pctxt:  a schema validation context
 7748:  * @schema:  the schema being built
 7749:  * @node:  a subtree containing XML Schema informations
 7750:  *
 7751:  * parse a XML schema Attribute Group declaration
 7752:  * *WARNING* this interface is highly subject to change
 7753:  *
 7754:  * Returns the attribute group definition or NULL in case of error.
 7755:  */
 7756: static xmlSchemaAttributeGroupPtr
 7757: xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 7758: 				       xmlSchemaPtr schema,
 7759: 				       xmlNodePtr node)
 7760: {
 7761:     const xmlChar *name;
 7762:     xmlSchemaAttributeGroupPtr ret;
 7763:     xmlNodePtr child = NULL;
 7764:     xmlAttrPtr attr;
 7765:     int hasRefs = 0;
 7766: 
 7767:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7768:         return (NULL);
 7769: 
 7770:     attr = xmlSchemaGetPropNode(node, "name");
 7771:     if (attr == NULL) {
 7772: 	xmlSchemaPMissingAttrErr(pctxt,
 7773: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 7774: 	    NULL, node, "name", NULL);
 7775: 	return (NULL);
 7776:     }
 7777:     /*
 7778:     * The name is crucial, exit if invalid.
 7779:     */
 7780:     if (xmlSchemaPValAttrNode(pctxt,
 7781: 	NULL, attr,
 7782: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 7783: 	return (NULL);
 7784:     }
 7785:     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
 7786: 	name, pctxt->targetNamespace, node);
 7787:     if (ret == NULL)
 7788: 	return (NULL);
 7789:     /*
 7790:     * Check for illegal attributes.
 7791:     */
 7792:     attr = node->properties;
 7793:     while (attr != NULL) {
 7794: 	if (attr->ns == NULL) {
 7795: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 7796: 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
 7797: 	    {
 7798: 		xmlSchemaPIllegalAttrErr(pctxt,
 7799: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7800: 	    }
 7801: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7802: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7803: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7804: 	}
 7805: 	attr = attr->next;
 7806:     }
 7807:     /* Attribute ID */
 7808:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7809:     /*
 7810:     * And now for the children...
 7811:     */
 7812:     child = node->children;
 7813:     if (IS_SCHEMA(child, "annotation")) {
 7814:         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7815:         child = child->next;
 7816:     }
 7817:     /*
 7818:     * Parse contained attribute decls/refs.
 7819:     */
 7820:     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
 7821: 	(xmlSchemaItemListPtr *) &(ret->attrUses),
 7822: 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
 7823: 	return(NULL);
 7824:     if (hasRefs)
 7825: 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
 7826:     /*
 7827:     * Parse the attribute wildcard.
 7828:     */
 7829:     if (IS_SCHEMA(child, "anyAttribute")) {
 7830: 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
 7831: 	    schema, child);
 7832: 	child = child->next;
 7833:     }
 7834:     if (child != NULL) {
 7835: 	xmlSchemaPContentErr(pctxt,
 7836: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7837: 	    NULL, node, child, NULL,
 7838: 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
 7839:     }
 7840:     return (ret);
 7841: }
 7842: 
 7843: /**
 7844:  * xmlSchemaPValAttrFormDefault:
 7845:  * @value:  the value
 7846:  * @flags: the flags to be modified
 7847:  * @flagQualified: the specific flag for "qualified"
 7848:  *
 7849:  * Returns 0 if the value is valid, 1 otherwise.
 7850:  */
 7851: static int
 7852: xmlSchemaPValAttrFormDefault(const xmlChar *value,
 7853: 			     int *flags,
 7854: 			     int flagQualified)
 7855: {
 7856:     if (xmlStrEqual(value, BAD_CAST "qualified")) {
 7857: 	if  ((*flags & flagQualified) == 0)
 7858: 	    *flags |= flagQualified;
 7859:     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
 7860: 	return (1);
 7861: 
 7862:     return (0);
 7863: }
 7864: 
 7865: /**
 7866:  * xmlSchemaPValAttrBlockFinal:
 7867:  * @value:  the value
 7868:  * @flags: the flags to be modified
 7869:  * @flagAll: the specific flag for "#all"
 7870:  * @flagExtension: the specific flag for "extension"
 7871:  * @flagRestriction: the specific flag for "restriction"
 7872:  * @flagSubstitution: the specific flag for "substitution"
 7873:  * @flagList: the specific flag for "list"
 7874:  * @flagUnion: the specific flag for "union"
 7875:  *
 7876:  * Validates the value of the attribute "final" and "block". The value
 7877:  * is converted into the specified flag values and returned in @flags.
 7878:  *
 7879:  * Returns 0 if the value is valid, 1 otherwise.
 7880:  */
 7881: 
 7882: static int
 7883: xmlSchemaPValAttrBlockFinal(const xmlChar *value,
 7884: 			    int *flags,
 7885: 			    int flagAll,
 7886: 			    int flagExtension,
 7887: 			    int flagRestriction,
 7888: 			    int flagSubstitution,
 7889: 			    int flagList,
 7890: 			    int flagUnion)
 7891: {
 7892:     int ret = 0;
 7893: 
 7894:     /*
 7895:     * TODO: This does not check for dublicate entries.
 7896:     */
 7897:     if ((flags == NULL) || (value == NULL))
 7898: 	return (-1);
 7899:     if (value[0] == 0)
 7900: 	return (0);
 7901:     if (xmlStrEqual(value, BAD_CAST "#all")) {
 7902: 	if (flagAll != -1)
 7903: 	    *flags |= flagAll;
 7904: 	else {
 7905: 	    if (flagExtension != -1)
 7906: 		*flags |= flagExtension;
 7907: 	    if (flagRestriction != -1)
 7908: 		*flags |= flagRestriction;
 7909: 	    if (flagSubstitution != -1)
 7910: 		*flags |= flagSubstitution;
 7911: 	    if (flagList != -1)
 7912: 		*flags |= flagList;
 7913: 	    if (flagUnion != -1)
 7914: 		*flags |= flagUnion;
 7915: 	}
 7916:     } else {
 7917: 	const xmlChar *end, *cur = value;
 7918: 	xmlChar *item;
 7919: 
 7920: 	do {
 7921: 	    while (IS_BLANK_CH(*cur))
 7922: 		cur++;
 7923: 	    end = cur;
 7924: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 7925: 		end++;
 7926: 	    if (end == cur)
 7927: 		break;
 7928: 	    item = xmlStrndup(cur, end - cur);
 7929: 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
 7930: 		if (flagExtension != -1) {
 7931: 		    if ((*flags & flagExtension) == 0)
 7932: 			*flags |= flagExtension;
 7933: 		} else
 7934: 		    ret = 1;
 7935: 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
 7936: 		if (flagRestriction != -1) {
 7937: 		    if ((*flags & flagRestriction) == 0)
 7938: 			*flags |= flagRestriction;
 7939: 		} else
 7940: 		    ret = 1;
 7941: 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
 7942: 		if (flagSubstitution != -1) {
 7943: 		    if ((*flags & flagSubstitution) == 0)
 7944: 			*flags |= flagSubstitution;
 7945: 		} else
 7946: 		    ret = 1;
 7947: 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
 7948: 		if (flagList != -1) {
 7949: 		    if ((*flags & flagList) == 0)
 7950: 			*flags |= flagList;
 7951: 		} else
 7952: 		    ret = 1;
 7953: 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
 7954: 		if (flagUnion != -1) {
 7955: 		    if ((*flags & flagUnion) == 0)
 7956: 			*flags |= flagUnion;
 7957: 		} else
 7958: 		    ret = 1;
 7959: 	    } else
 7960: 		ret = 1;
 7961: 	    if (item != NULL)
 7962: 		xmlFree(item);
 7963: 	    cur = end;
 7964: 	} while ((ret == 0) && (*cur != 0));
 7965:     }
 7966: 
 7967:     return (ret);
 7968: }
 7969: 
 7970: static int
 7971: xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
 7972: 			     xmlSchemaIDCPtr idc,
 7973: 			     xmlSchemaIDCSelectPtr selector,
 7974: 			     xmlAttrPtr attr,
 7975: 			     int isField)
 7976: {
 7977:     xmlNodePtr node;
 7978: 
 7979:     /*
 7980:     * c-selector-xpath:
 7981:     * Schema Component Constraint: Selector Value OK
 7982:     *
 7983:     * TODO: 1 The {selector} must be a valid XPath expression, as defined
 7984:     * in [XPath].
 7985:     */
 7986:     if (selector == NULL) {
 7987: 	xmlSchemaPErr(ctxt, idc->node,
 7988: 	    XML_SCHEMAP_INTERNAL,
 7989: 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
 7990: 	    "the selector is not specified.\n", NULL, NULL);
 7991: 	return (-1);
 7992:     }
 7993:     if (attr == NULL)
 7994: 	node = idc->node;
 7995:     else
 7996: 	node = (xmlNodePtr) attr;
 7997:     if (selector->xpath == NULL) {
 7998: 	xmlSchemaPCustomErr(ctxt,
 7999: 	    /* TODO: Adjust error code. */
 8000: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8001: 	    NULL, node,
 8002: 	    "The XPath expression of the selector is not valid", NULL);
 8003: 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 8004:     } else {
 8005: 	const xmlChar **nsArray = NULL;
 8006: 	xmlNsPtr *nsList = NULL;
 8007: 	/*
 8008: 	* Compile the XPath expression.
 8009: 	*/
 8010: 	/*
 8011: 	* TODO: We need the array of in-scope namespaces for compilation.
 8012: 	* TODO: Call xmlPatterncompile with different options for selector/
 8013: 	* field.
 8014: 	*/
 8015: 	if (attr == NULL)
 8016: 	    nsList = NULL;
 8017: 	else
 8018: 	    nsList = xmlGetNsList(attr->doc, attr->parent);
 8019: 	/*
 8020: 	* Build an array of prefixes and namespaces.
 8021: 	*/
 8022: 	if (nsList != NULL) {
 8023: 	    int i, count = 0;
 8024: 
 8025: 	    for (i = 0; nsList[i] != NULL; i++)
 8026: 		count++;
 8027: 
 8028: 	    nsArray = (const xmlChar **) xmlMalloc(
 8029: 		(count * 2 + 1) * sizeof(const xmlChar *));
 8030: 	    if (nsArray == NULL) {
 8031: 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
 8032: 		    NULL);
 8033: 		xmlFree(nsList);
 8034: 		return (-1);
 8035: 	    }
 8036: 	    for (i = 0; i < count; i++) {
 8037: 		nsArray[2 * i] = nsList[i]->href;
 8038: 		nsArray[2 * i + 1] = nsList[i]->prefix;
 8039: 	    }
 8040: 	    nsArray[count * 2] = NULL;
 8041: 	    xmlFree(nsList);
 8042: 	}
 8043: 	/*
 8044: 	* TODO: Differentiate between "selector" and "field".
 8045: 	*/
 8046: 	if (isField)
 8047: 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 8048: 		NULL, XML_PATTERN_XSFIELD, nsArray);
 8049: 	else
 8050: 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 8051: 		NULL, XML_PATTERN_XSSEL, nsArray);
 8052: 	if (nsArray != NULL)
 8053: 	    xmlFree((xmlChar **) nsArray);
 8054: 
 8055: 	if (selector->xpathComp == NULL) {
 8056: 	    xmlSchemaPCustomErr(ctxt,
 8057: 		/* TODO: Adjust error code? */
 8058: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8059: 		NULL, node,
 8060: 		"The XPath expression '%s' could not be "
 8061: 		"compiled", selector->xpath);
 8062: 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 8063: 	}
 8064:     }
 8065:     return (0);
 8066: }
 8067: 
 8068: #define ADD_ANNOTATION(annot)   \
 8069:     xmlSchemaAnnotPtr cur = item->annot; \
 8070:     if (item->annot == NULL) {  \
 8071: 	item->annot = annot;    \
 8072: 	return (annot);         \
 8073:     }                           \
 8074:     cur = item->annot;          \
 8075:     if (cur->next != NULL) {    \
 8076: 	cur = cur->next;	\
 8077:     }                           \
 8078:     cur->next = annot;
 8079: 
 8080: /**
 8081:  * xmlSchemaAssignAnnotation:
 8082:  * @item: the schema component
 8083:  * @annot: the annotation
 8084:  *
 8085:  * Adds the annotation to the given schema component.
 8086:  *
 8087:  * Returns the given annotaion.
 8088:  */
 8089: static xmlSchemaAnnotPtr
 8090: xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
 8091: 		       xmlSchemaAnnotPtr annot)
 8092: {
 8093:     if ((annItem == NULL) || (annot == NULL))
 8094: 	return (NULL);
 8095:     switch (annItem->type) {
 8096: 	case XML_SCHEMA_TYPE_ELEMENT: {
 8097: 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
 8098: 		ADD_ANNOTATION(annot)
 8099: 	    }
 8100: 	    break;
 8101: 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
 8102: 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
 8103: 		ADD_ANNOTATION(annot)
 8104: 	    }
 8105: 	    break;
 8106: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 8107: 	case XML_SCHEMA_TYPE_ANY: {
 8108: 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
 8109: 		ADD_ANNOTATION(annot)
 8110: 	    }
 8111: 	    break;
 8112: 	case XML_SCHEMA_TYPE_PARTICLE:
 8113: 	case XML_SCHEMA_TYPE_IDC_KEY:
 8114: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 8115: 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
 8116: 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
 8117: 		ADD_ANNOTATION(annot)
 8118: 	    }
 8119: 	    break;
 8120: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
 8121: 		xmlSchemaAttributeGroupPtr item =
 8122: 		    (xmlSchemaAttributeGroupPtr) annItem;
 8123: 		ADD_ANNOTATION(annot)
 8124: 	    }
 8125: 	    break;
 8126: 	case XML_SCHEMA_TYPE_NOTATION: {
 8127: 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
 8128: 		ADD_ANNOTATION(annot)
 8129: 	    }
 8130: 	    break;
 8131: 	case XML_SCHEMA_FACET_MININCLUSIVE:
 8132: 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 8133: 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 8134: 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 8135: 	case XML_SCHEMA_FACET_TOTALDIGITS:
 8136: 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
 8137: 	case XML_SCHEMA_FACET_PATTERN:
 8138: 	case XML_SCHEMA_FACET_ENUMERATION:
 8139: 	case XML_SCHEMA_FACET_WHITESPACE:
 8140: 	case XML_SCHEMA_FACET_LENGTH:
 8141: 	case XML_SCHEMA_FACET_MAXLENGTH:
 8142: 	case XML_SCHEMA_FACET_MINLENGTH: {
 8143: 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
 8144: 		ADD_ANNOTATION(annot)
 8145: 	    }
 8146: 	    break;
 8147: 	case XML_SCHEMA_TYPE_SIMPLE:
 8148: 	case XML_SCHEMA_TYPE_COMPLEX: {
 8149: 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
 8150: 		ADD_ANNOTATION(annot)
 8151: 	    }
 8152: 	    break;
 8153: 	case XML_SCHEMA_TYPE_GROUP: {
 8154: 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
 8155: 		ADD_ANNOTATION(annot)
 8156: 	    }
 8157: 	    break;
 8158: 	case XML_SCHEMA_TYPE_SEQUENCE:
 8159: 	case XML_SCHEMA_TYPE_CHOICE:
 8160: 	case XML_SCHEMA_TYPE_ALL: {
 8161: 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
 8162: 		ADD_ANNOTATION(annot)
 8163: 	    }
 8164: 	    break;
 8165: 	default:
 8166: 	     xmlSchemaPCustomErr(NULL,
 8167: 		XML_SCHEMAP_INTERNAL,
 8168: 		NULL, NULL,
 8169: 		"Internal error: xmlSchemaAddAnnotation, "
 8170: 		"The item is not a annotated schema component", NULL);
 8171: 	     break;
 8172:     }
 8173:     return (annot);
 8174: }
 8175: 
 8176: /**
 8177:  * xmlSchemaParseIDCSelectorAndField:
 8178:  * @ctxt:  a schema validation context
 8179:  * @schema:  the schema being built
 8180:  * @node:  a subtree containing XML Schema informations
 8181:  *
 8182:  * Parses a XML Schema identity-contraint definition's
 8183:  * <selector> and <field> elements.
 8184:  *
 8185:  * Returns the parsed identity-constraint definition.
 8186:  */
 8187: static xmlSchemaIDCSelectPtr
 8188: xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
 8189: 			  xmlSchemaIDCPtr idc,
 8190: 			  xmlNodePtr node,
 8191: 			  int isField)
 8192: {
 8193:     xmlSchemaIDCSelectPtr item;
 8194:     xmlNodePtr child = NULL;
 8195:     xmlAttrPtr attr;
 8196: 
 8197:     /*
 8198:     * Check for illegal attributes.
 8199:     */
 8200:     attr = node->properties;
 8201:     while (attr != NULL) {
 8202: 	if (attr->ns == NULL) {
 8203: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8204: 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
 8205: 		xmlSchemaPIllegalAttrErr(ctxt,
 8206: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8207: 	    }
 8208: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8209: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8210: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8211: 	}
 8212: 	attr = attr->next;
 8213:     }
 8214:     /*
 8215:     * Create the item.
 8216:     */
 8217:     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
 8218:     if (item == NULL) {
 8219:         xmlSchemaPErrMemory(ctxt,
 8220: 	    "allocating a 'selector' of an identity-constraint definition",
 8221: 	    NULL);
 8222:         return (NULL);
 8223:     }
 8224:     memset(item, 0, sizeof(xmlSchemaIDCSelect));
 8225:     /*
 8226:     * Attribute "xpath" (mandatory).
 8227:     */
 8228:     attr = xmlSchemaGetPropNode(node, "xpath");
 8229:     if (attr == NULL) {
 8230:     	xmlSchemaPMissingAttrErr(ctxt,
 8231: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 8232: 	    NULL, node,
 8233: 	    "name", NULL);
 8234:     } else {
 8235: 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8236: 	/*
 8237: 	* URGENT TODO: "field"s have an other syntax than "selector"s.
 8238: 	*/
 8239: 
 8240: 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
 8241: 	    isField) == -1) {
 8242: 	    xmlSchemaPErr(ctxt,
 8243: 		(xmlNodePtr) attr,
 8244: 		XML_SCHEMAP_INTERNAL,
 8245: 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
 8246: 		"validating the XPath expression of a IDC selector.\n",
 8247: 		NULL, NULL);
 8248: 	}
 8249: 
 8250:     }
 8251:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8252:     /*
 8253:     * And now for the children...
 8254:     */
 8255:     child = node->children;
 8256:     if (IS_SCHEMA(child, "annotation")) {
 8257: 	/*
 8258: 	* Add the annotation to the parent IDC.
 8259: 	*/
 8260: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
 8261: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 8262: 	child = child->next;
 8263:     }
 8264:     if (child != NULL) {
 8265: 	xmlSchemaPContentErr(ctxt,
 8266: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8267: 	    NULL, node, child,
 8268: 	    NULL, "(annotation?)");
 8269:     }
 8270: 
 8271:     return (item);
 8272: }
 8273: 
 8274: /**
 8275:  * xmlSchemaParseIDC:
 8276:  * @ctxt:  a schema validation context
 8277:  * @schema:  the schema being built
 8278:  * @node:  a subtree containing XML Schema informations
 8279:  *
 8280:  * Parses a XML Schema identity-contraint definition.
 8281:  *
 8282:  * Returns the parsed identity-constraint definition.
 8283:  */
 8284: static xmlSchemaIDCPtr
 8285: xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
 8286: 		  xmlSchemaPtr schema,
 8287: 		  xmlNodePtr node,
 8288: 		  xmlSchemaTypeType idcCategory,
 8289: 		  const xmlChar *targetNamespace)
 8290: {
 8291:     xmlSchemaIDCPtr item = NULL;
 8292:     xmlNodePtr child = NULL;
 8293:     xmlAttrPtr attr;
 8294:     const xmlChar *name = NULL;
 8295:     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
 8296: 
 8297:     /*
 8298:     * Check for illegal attributes.
 8299:     */
 8300:     attr = node->properties;
 8301:     while (attr != NULL) {
 8302: 	if (attr->ns == NULL) {
 8303: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8304: 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 8305: 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
 8306: 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
 8307: 		xmlSchemaPIllegalAttrErr(ctxt,
 8308: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8309: 	    }
 8310: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8311: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8312: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8313: 	}
 8314: 	attr = attr->next;
 8315:     }
 8316:     /*
 8317:     * Attribute "name" (mandatory).
 8318:     */
 8319:     attr = xmlSchemaGetPropNode(node, "name");
 8320:     if (attr == NULL) {
 8321: 	xmlSchemaPMissingAttrErr(ctxt,
 8322: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 8323: 	    NULL, node,
 8324: 	    "name", NULL);
 8325: 	return (NULL);
 8326:     } else if (xmlSchemaPValAttrNode(ctxt,
 8327: 	NULL, attr,
 8328: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 8329: 	return (NULL);
 8330:     }
 8331:     /* Create the component. */
 8332:     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
 8333: 	idcCategory, node);
 8334:     if (item == NULL)
 8335: 	return(NULL);
 8336: 
 8337:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8338:     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
 8339: 	/*
 8340: 	* Attribute "refer" (mandatory).
 8341: 	*/
 8342: 	attr = xmlSchemaGetPropNode(node, "refer");
 8343: 	if (attr == NULL) {
 8344: 	    xmlSchemaPMissingAttrErr(ctxt,
 8345: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 8346: 		NULL, node,
 8347: 		"refer", NULL);
 8348: 	} else {
 8349: 	    /*
 8350: 	    * Create a reference item.
 8351: 	    */
 8352: 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
 8353: 		NULL, NULL);
 8354: 	    if (item->ref == NULL)
 8355: 		return (NULL);
 8356: 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
 8357: 		NULL, attr,
 8358: 		&(item->ref->targetNamespace),
 8359: 		&(item->ref->name));
 8360: 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
 8361: 		item->ref->targetNamespace);
 8362: 	}
 8363:     }
 8364:     /*
 8365:     * And now for the children...
 8366:     */
 8367:     child = node->children;
 8368:     if (IS_SCHEMA(child, "annotation")) {
 8369: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 8370: 	child = child->next;
 8371:     }
 8372:     if (child == NULL) {
 8373: 	xmlSchemaPContentErr(ctxt,
 8374: 		XML_SCHEMAP_S4S_ELEM_MISSING,
 8375: 		NULL, node, child,
 8376: 		"A child element is missing",
 8377: 		"(annotation?, (selector, field+))");
 8378:     }
 8379:     /*
 8380:     * Child element <selector>.
 8381:     */
 8382:     if (IS_SCHEMA(child, "selector")) {
 8383: 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
 8384: 	    item, child, 0);
 8385: 	child = child->next;
 8386: 	/*
 8387: 	* Child elements <field>.
 8388: 	*/
 8389: 	if (IS_SCHEMA(child, "field")) {
 8390: 	    do {
 8391: 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
 8392: 		    item, child, 1);
 8393: 		if (field != NULL) {
 8394: 		    field->index = item->nbFields;
 8395: 		    item->nbFields++;
 8396: 		    if (lastField != NULL)
 8397: 			lastField->next = field;
 8398: 		    else
 8399: 			item->fields = field;
 8400: 		    lastField = field;
 8401: 		}
 8402: 		child = child->next;
 8403: 	    } while (IS_SCHEMA(child, "field"));
 8404: 	} else {
 8405: 	    xmlSchemaPContentErr(ctxt,
 8406: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8407: 		NULL, node, child,
 8408: 		NULL, "(annotation?, (selector, field+))");
 8409: 	}
 8410:     }
 8411:     if (child != NULL) {
 8412: 	xmlSchemaPContentErr(ctxt,
 8413: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8414: 	    NULL, node, child,
 8415: 	    NULL, "(annotation?, (selector, field+))");
 8416:     }
 8417: 
 8418:     return (item);
 8419: }
 8420: 
 8421: /**
 8422:  * xmlSchemaParseElement:
 8423:  * @ctxt:  a schema validation context
 8424:  * @schema:  the schema being built
 8425:  * @node:  a subtree containing XML Schema informations
 8426:  * @topLevel: indicates if this is global declaration
 8427:  *
 8428:  * Parses a XML schema element declaration.
 8429:  * *WARNING* this interface is highly subject to change
 8430:  *
 8431:  * Returns the element declaration or a particle; NULL in case
 8432:  * of an error or if the particle has minOccurs==maxOccurs==0.
 8433:  */
 8434: static xmlSchemaBasicItemPtr
 8435: xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 8436:                       xmlNodePtr node, int *isElemRef, int topLevel)
 8437: {
 8438:     xmlSchemaElementPtr decl = NULL;
 8439:     xmlSchemaParticlePtr particle = NULL;
 8440:     xmlSchemaAnnotPtr annot = NULL;
 8441:     xmlNodePtr child = NULL;
 8442:     xmlAttrPtr attr, nameAttr;
 8443:     int min, max, isRef = 0;
 8444:     xmlChar *des = NULL;
 8445: 
 8446:     /* 3.3.3 Constraints on XML Representations of Element Declarations */
 8447:     /* TODO: Complete implementation of 3.3.6 */
 8448: 
 8449:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 8450:         return (NULL);
 8451: 
 8452:     if (isElemRef != NULL)
 8453: 	*isElemRef = 0;
 8454:     /*
 8455:     * If we get a "ref" attribute on a local <element> we will assume it's
 8456:     * a reference - even if there's a "name" attribute; this seems to be more
 8457:     * robust.
 8458:     */
 8459:     nameAttr = xmlSchemaGetPropNode(node, "name");
 8460:     attr = xmlSchemaGetPropNode(node, "ref");
 8461:     if ((topLevel) || (attr == NULL)) {
 8462: 	if (nameAttr == NULL) {
 8463: 	    xmlSchemaPMissingAttrErr(ctxt,
 8464: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 8465: 		NULL, node, "name", NULL);
 8466: 	    return (NULL);
 8467: 	}
 8468:     } else
 8469: 	isRef = 1;
 8470: 
 8471:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8472:     child = node->children;
 8473:     if (IS_SCHEMA(child, "annotation")) {
 8474: 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 8475: 	child = child->next;
 8476:     }
 8477:     /*
 8478:     * Skip particle part if a global declaration.
 8479:     */
 8480:     if (topLevel)
 8481: 	goto declaration_part;
 8482:     /*
 8483:     * The particle part ==================================================
 8484:     */
 8485:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 8486:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
 8487:     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 8488:     particle = xmlSchemaAddParticle(ctxt, node, min, max);
 8489:     if (particle == NULL)
 8490: 	goto return_null;
 8491: 
 8492:     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
 8493: 
 8494:     if (isRef) {
 8495: 	const xmlChar *refNs = NULL, *ref = NULL;
 8496: 	xmlSchemaQNameRefPtr refer = NULL;
 8497: 	/*
 8498: 	* The reference part =============================================
 8499: 	*/
 8500: 	if (isElemRef != NULL)
 8501: 	    *isElemRef = 1;
 8502: 
 8503: 	xmlSchemaPValAttrNodeQName(ctxt, schema,
 8504: 	    NULL, attr, &refNs, &ref);
 8505: 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 8506: 	/*
 8507: 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
 8508: 	*/
 8509: 	if (nameAttr != NULL) {
 8510: 	    xmlSchemaPMutualExclAttrErr(ctxt,
 8511: 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
 8512: 	}
 8513: 	/*
 8514: 	* Check for illegal attributes.
 8515: 	*/
 8516: 	attr = node->properties;
 8517: 	while (attr != NULL) {
 8518: 	    if (attr->ns == NULL) {
 8519: 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
 8520: 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
 8521: 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
 8522: 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
 8523: 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
 8524: 		{
 8525: 		    attr = attr->next;
 8526: 		    continue;
 8527: 		} else {
 8528: 		    /* SPEC (3.3.3 : 2.2) */
 8529: 		    xmlSchemaPCustomAttrErr(ctxt,
 8530: 			XML_SCHEMAP_SRC_ELEMENT_2_2,
 8531: 			NULL, NULL, attr,
 8532: 			"Only the attributes 'minOccurs', 'maxOccurs' and "
 8533: 			"'id' are allowed in addition to 'ref'");
 8534: 		    break;
 8535: 		}
 8536: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8537: 		xmlSchemaPIllegalAttrErr(ctxt,
 8538: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8539: 	    }
 8540: 	    attr = attr->next;
 8541: 	}
 8542: 	/*
 8543: 	* No children except <annotation> expected.
 8544: 	*/
 8545: 	if (child != NULL) {
 8546: 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8547: 		NULL, node, child, NULL, "(annotation?)");
 8548: 	}
 8549: 	if ((min == 0) && (max == 0))
 8550: 	    goto return_null;
 8551: 	/*
 8552: 	* Create the reference item and attach it to the particle.
 8553: 	*/
 8554: 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
 8555: 	    ref, refNs);
 8556: 	if (refer == NULL)
 8557: 	    goto return_null;
 8558: 	particle->children = (xmlSchemaTreeItemPtr) refer;
 8559: 	particle->annot = annot;
 8560: 	/*
 8561: 	* Add the particle to pending components, since the reference
 8562: 	* need to be resolved.
 8563: 	*/
 8564: 	WXS_ADD_PENDING(ctxt, particle);
 8565: 	return ((xmlSchemaBasicItemPtr) particle);
 8566:     }
 8567:     /*
 8568:     * The declaration part ===============================================
 8569:     */
 8570: declaration_part:
 8571:     {
 8572: 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
 8573: 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
 8574: 
 8575: 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
 8576: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
 8577: 	    goto return_null;
 8578: 	/*
 8579: 	* Evaluate the target namespace.
 8580: 	*/
 8581: 	if (topLevel) {
 8582: 	    ns = ctxt->targetNamespace;
 8583: 	} else {
 8584: 	    attr = xmlSchemaGetPropNode(node, "form");
 8585: 	    if (attr != NULL) {
 8586: 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8587: 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 8588: 		    ns = ctxt->targetNamespace;
 8589: 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
 8590: 		    xmlSchemaPSimpleTypeErr(ctxt,
 8591: 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8592: 			NULL, (xmlNodePtr) attr,
 8593: 			NULL, "(qualified | unqualified)",
 8594: 			attrValue, NULL, NULL, NULL);
 8595: 		}
 8596: 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 8597: 		ns = ctxt->targetNamespace;
 8598: 	}
 8599: 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
 8600: 	if (decl == NULL) {
 8601: 	    goto return_null;
 8602: 	}
 8603: 	/*
 8604: 	* Check for illegal attributes.
 8605: 	*/
 8606: 	attr = node->properties;
 8607: 	while (attr != NULL) {
 8608: 	    if (attr->ns == NULL) {
 8609: 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 8610: 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
 8611: 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8612: 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 8613: 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 8614: 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
 8615: 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
 8616: 		{
 8617: 		    if (topLevel == 0) {
 8618: 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 8619: 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 8620: 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
 8621: 			{
 8622: 			    xmlSchemaPIllegalAttrErr(ctxt,
 8623: 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8624: 			}
 8625: 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
 8626: 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
 8627: 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
 8628: 
 8629: 			xmlSchemaPIllegalAttrErr(ctxt,
 8630: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8631: 		    }
 8632: 		}
 8633: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8634: 
 8635: 		xmlSchemaPIllegalAttrErr(ctxt,
 8636: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8637: 	    }
 8638: 	    attr = attr->next;
 8639: 	}
 8640: 	/*
 8641: 	* Extract/validate attributes.
 8642: 	*/
 8643: 	if (topLevel) {
 8644: 	    /*
 8645: 	    * Process top attributes of global element declarations here.
 8646: 	    */
 8647: 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
 8648: 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
 8649: 	    xmlSchemaPValAttrQName(ctxt, schema,
 8650: 		NULL, node, "substitutionGroup",
 8651: 		&(decl->substGroupNs), &(decl->substGroup));
 8652: 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
 8653: 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
 8654: 	    /*
 8655: 	    * Attribute "final".
 8656: 	    */
 8657: 	    attr = xmlSchemaGetPropNode(node, "final");
 8658: 	    if (attr == NULL) {
 8659: 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 8660: 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
 8661: 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 8662: 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
 8663: 	    } else {
 8664: 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8665: 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 8666: 		    -1,
 8667: 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
 8668: 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
 8669: 		    xmlSchemaPSimpleTypeErr(ctxt,
 8670: 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8671: 			NULL, (xmlNodePtr) attr,
 8672: 			NULL, "(#all | List of (extension | restriction))",
 8673: 			attrValue, NULL, NULL, NULL);
 8674: 		}
 8675: 	    }
 8676: 	}
 8677: 	/*
 8678: 	* Attribute "block".
 8679: 	*/
 8680: 	attr = xmlSchemaGetPropNode(node, "block");
 8681: 	if (attr == NULL) {
 8682: 	    /*
 8683: 	    * Apply default "block" values.
 8684: 	    */
 8685: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 8686: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
 8687: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 8688: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
 8689: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 8690: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
 8691: 	} else {
 8692: 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8693: 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 8694: 		-1,
 8695: 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
 8696: 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
 8697: 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
 8698: 		xmlSchemaPSimpleTypeErr(ctxt,
 8699: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8700: 		    NULL, (xmlNodePtr) attr,
 8701: 		    NULL, "(#all | List of (extension | "
 8702: 		    "restriction | substitution))", attrValue,
 8703: 		    NULL, NULL, NULL);
 8704: 	    }
 8705: 	}
 8706: 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
 8707: 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
 8708: 
 8709: 	attr = xmlSchemaGetPropNode(node, "type");
 8710: 	if (attr != NULL) {
 8711: 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
 8712: 		NULL, attr,
 8713: 		&(decl->namedTypeNs), &(decl->namedType));
 8714: 	    xmlSchemaCheckReference(ctxt, schema, node,
 8715: 		attr, decl->namedTypeNs);
 8716: 	}
 8717: 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
 8718: 	attr = xmlSchemaGetPropNode(node, "fixed");
 8719: 	if (attr != NULL) {
 8720: 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8721: 	    if (decl->value != NULL) {
 8722: 		/*
 8723: 		* 3.3.3 : 1
 8724: 		* default and fixed must not both be present.
 8725: 		*/
 8726: 		xmlSchemaPMutualExclAttrErr(ctxt,
 8727: 		    XML_SCHEMAP_SRC_ELEMENT_1,
 8728: 		    NULL, attr, "default", "fixed");
 8729: 	    } else {
 8730: 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
 8731: 		decl->value = fixed;
 8732: 	    }
 8733: 	}
 8734: 	/*
 8735: 	* And now for the children...
 8736: 	*/
 8737: 	if (IS_SCHEMA(child, "complexType")) {
 8738: 	    /*
 8739: 	    * 3.3.3 : 3
 8740: 	    * "type" and either <simpleType> or <complexType> are mutually
 8741: 	    * exclusive
 8742: 	    */
 8743: 	    if (decl->namedType != NULL) {
 8744: 		xmlSchemaPContentErr(ctxt,
 8745: 		    XML_SCHEMAP_SRC_ELEMENT_3,
 8746: 		    NULL, node, child,
 8747: 		    "The attribute 'type' and the <complexType> child are "
 8748: 		    "mutually exclusive", NULL);
 8749: 	    } else
 8750: 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
 8751: 	    child = child->next;
 8752: 	} else if (IS_SCHEMA(child, "simpleType")) {
 8753: 	    /*
 8754: 	    * 3.3.3 : 3
 8755: 	    * "type" and either <simpleType> or <complexType> are
 8756: 	    * mutually exclusive
 8757: 	    */
 8758: 	    if (decl->namedType != NULL) {
 8759: 		xmlSchemaPContentErr(ctxt,
 8760: 		    XML_SCHEMAP_SRC_ELEMENT_3,
 8761: 		    NULL, node, child,
 8762: 		    "The attribute 'type' and the <simpleType> child are "
 8763: 		    "mutually exclusive", NULL);
 8764: 	    } else
 8765: 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 8766: 	    child = child->next;
 8767: 	}
 8768: 	while ((IS_SCHEMA(child, "unique")) ||
 8769: 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
 8770: 	    if (IS_SCHEMA(child, "unique")) {
 8771: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8772: 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
 8773: 	    } else if (IS_SCHEMA(child, "key")) {
 8774: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8775: 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
 8776: 	    } else if (IS_SCHEMA(child, "keyref")) {
 8777: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8778: 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
 8779: 	    }
 8780: 	    if (lastIDC != NULL)
 8781: 		lastIDC->next = curIDC;
 8782: 	    else
 8783: 		decl->idcs = (void *) curIDC;
 8784: 	    lastIDC = curIDC;
 8785: 	    child = child->next;
 8786: 	}
 8787: 	if (child != NULL) {
 8788: 	    xmlSchemaPContentErr(ctxt,
 8789: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8790: 		NULL, node, child,
 8791: 		NULL, "(annotation?, ((simpleType | complexType)?, "
 8792: 		"(unique | key | keyref)*))");
 8793: 	}
 8794: 	decl->annot = annot;
 8795:     }
 8796:     /*
 8797:     * NOTE: Element Declaration Representation OK 4. will be checked at a
 8798:     * different layer.
 8799:     */
 8800:     FREE_AND_NULL(des)
 8801:     if (topLevel)
 8802: 	return ((xmlSchemaBasicItemPtr) decl);
 8803:     else {
 8804: 	particle->children = (xmlSchemaTreeItemPtr) decl;
 8805: 	return ((xmlSchemaBasicItemPtr) particle);
 8806:     }
 8807: 
 8808: return_null:
 8809:     FREE_AND_NULL(des);
 8810:     if (annot != NULL) {
 8811: 	if (particle != NULL)
 8812: 	    particle->annot = NULL;
 8813: 	if (decl != NULL)
 8814: 	    decl->annot = NULL;
 8815: 	xmlSchemaFreeAnnot(annot);
 8816:     }
 8817:     return (NULL);
 8818: }
 8819: 
 8820: /**
 8821:  * xmlSchemaParseUnion:
 8822:  * @ctxt:  a schema validation context
 8823:  * @schema:  the schema being built
 8824:  * @node:  a subtree containing XML Schema informations
 8825:  *
 8826:  * parse a XML schema Union definition
 8827:  * *WARNING* this interface is highly subject to change
 8828:  *
 8829:  * Returns -1 in case of internal error, 0 in case of success and a positive
 8830:  * error code otherwise.
 8831:  */
 8832: static int
 8833: xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 8834:                     xmlNodePtr node)
 8835: {
 8836:     xmlSchemaTypePtr type;
 8837:     xmlNodePtr child = NULL;
 8838:     xmlAttrPtr attr;
 8839:     const xmlChar *cur = NULL;
 8840: 
 8841:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 8842:         return (-1);
 8843:     /* Not a component, don't create it. */
 8844:     type = ctxt->ctxtType;
 8845:     /*
 8846:     * Mark the simple type as being of variety "union".
 8847:     */
 8848:     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
 8849:     /*
 8850:     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 8851:     * then the �simple ur-type definition�."
 8852:     */
 8853:     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 8854:     /*
 8855:     * Check for illegal attributes.
 8856:     */
 8857:     attr = node->properties;
 8858:     while (attr != NULL) {
 8859: 	if (attr->ns == NULL) {
 8860: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8861: 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
 8862: 		xmlSchemaPIllegalAttrErr(ctxt,
 8863: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8864: 	    }
 8865: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8866: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8867: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8868: 	}
 8869: 	attr = attr->next;
 8870:     }
 8871:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8872:     /*
 8873:     * Attribute "memberTypes". This is a list of QNames.
 8874:     * TODO: Check the value to contain anything.
 8875:     */
 8876:     attr = xmlSchemaGetPropNode(node, "memberTypes");
 8877:     if (attr != NULL) {
 8878: 	const xmlChar *end;
 8879: 	xmlChar *tmp;
 8880: 	const xmlChar *localName, *nsName;
 8881: 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
 8882: 	xmlSchemaQNameRefPtr ref;
 8883: 
 8884: 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8885: 	type->base = cur;
 8886: 	do {
 8887: 	    while (IS_BLANK_CH(*cur))
 8888: 		cur++;
 8889: 	    end = cur;
 8890: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 8891: 		end++;
 8892: 	    if (end == cur)
 8893: 		break;
 8894: 	    tmp = xmlStrndup(cur, end - cur);
 8895: 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 8896: 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
 8897: 		/*
 8898: 		* Create the member type link.
 8899: 		*/
 8900: 		link = (xmlSchemaTypeLinkPtr)
 8901: 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
 8902: 		if (link == NULL) {
 8903: 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
 8904: 			"allocating a type link", NULL);
 8905: 		    return (-1);
 8906: 		}
 8907: 		link->type = NULL;
 8908: 		link->next = NULL;
 8909: 		if (lastLink == NULL)
 8910: 		    type->memberTypes = link;
 8911: 		else
 8912: 		    lastLink->next = link;
 8913: 		lastLink = link;
 8914: 		/*
 8915: 		* Create a reference item.
 8916: 		*/
 8917: 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
 8918: 		    localName, nsName);
 8919: 		if (ref == NULL) {
 8920: 		    FREE_AND_NULL(tmp)
 8921: 		    return (-1);
 8922: 		}
 8923: 		/*
 8924: 		* Assign the reference to the link, it will be resolved
 8925: 		* later during fixup of the union simple type.
 8926: 		*/
 8927: 		link->type = (xmlSchemaTypePtr) ref;
 8928: 	    }
 8929: 	    FREE_AND_NULL(tmp)
 8930: 	    cur = end;
 8931: 	} while (*cur != 0);
 8932: 
 8933:     }
 8934:     /*
 8935:     * And now for the children...
 8936:     */
 8937:     child = node->children;
 8938:     if (IS_SCHEMA(child, "annotation")) {
 8939: 	/*
 8940: 	* Add the annotation to the simple type ancestor.
 8941: 	*/
 8942: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 8943: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 8944:         child = child->next;
 8945:     }
 8946:     if (IS_SCHEMA(child, "simpleType")) {
 8947: 	xmlSchemaTypePtr subtype, last = NULL;
 8948: 
 8949: 	/*
 8950: 	* Anchor the member types in the "subtypes" field of the
 8951: 	* simple type.
 8952: 	*/
 8953: 	while (IS_SCHEMA(child, "simpleType")) {
 8954: 	    subtype = (xmlSchemaTypePtr)
 8955: 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 8956: 	    if (subtype != NULL) {
 8957: 		if (last == NULL) {
 8958: 		    type->subtypes = subtype;
 8959: 		    last = subtype;
 8960: 		} else {
 8961: 		    last->next = subtype;
 8962: 		    last = subtype;
 8963: 		}
 8964: 		last->next = NULL;
 8965: 	    }
 8966: 	    child = child->next;
 8967: 	}
 8968:     }
 8969:     if (child != NULL) {
 8970: 	xmlSchemaPContentErr(ctxt,
 8971: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8972: 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
 8973:     }
 8974:     if ((attr == NULL) && (type->subtypes == NULL)) {
 8975: 	 /*
 8976: 	* src-union-memberTypes-or-simpleTypes
 8977: 	* Either the memberTypes [attribute] of the <union> element must
 8978: 	* be non-empty or there must be at least one simpleType [child].
 8979: 	*/
 8980: 	xmlSchemaPCustomErr(ctxt,
 8981: 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
 8982: 	    NULL, node,
 8983: 	    "Either the attribute 'memberTypes' or "
 8984: 	    "at least one <simpleType> child must be present", NULL);
 8985:     }
 8986:     return (0);
 8987: }
 8988: 
 8989: /**
 8990:  * xmlSchemaParseList:
 8991:  * @ctxt:  a schema validation context
 8992:  * @schema:  the schema being built
 8993:  * @node:  a subtree containing XML Schema informations
 8994:  *
 8995:  * parse a XML schema List definition
 8996:  * *WARNING* this interface is highly subject to change
 8997:  *
 8998:  * Returns -1 in case of error, 0 if the declaration is improper and
 8999:  *         1 in case of success.
 9000:  */
 9001: static xmlSchemaTypePtr
 9002: xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 9003:                    xmlNodePtr node)
 9004: {
 9005:     xmlSchemaTypePtr type;
 9006:     xmlNodePtr child = NULL;
 9007:     xmlAttrPtr attr;
 9008: 
 9009:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9010:         return (NULL);
 9011:     /* Not a component, don't create it. */
 9012:     type = ctxt->ctxtType;
 9013:     /*
 9014:     * Mark the type as being of variety "list".
 9015:     */
 9016:     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
 9017:     /*
 9018:     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 9019:     * then the �simple ur-type definition�."
 9020:     */
 9021:     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 9022:     /*
 9023:     * Check for illegal attributes.
 9024:     */
 9025:     attr = node->properties;
 9026:     while (attr != NULL) {
 9027: 	if (attr->ns == NULL) {
 9028: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9029: 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
 9030: 		xmlSchemaPIllegalAttrErr(ctxt,
 9031: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9032: 	    }
 9033: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9034: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9035: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9036: 	}
 9037: 	attr = attr->next;
 9038:     }
 9039: 
 9040:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9041: 
 9042:     /*
 9043:     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
 9044:     * fields for holding the reference to the itemType.
 9045:     *
 9046:     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
 9047:     * the "ref" fields.
 9048:     */
 9049:     xmlSchemaPValAttrQName(ctxt, schema, NULL,
 9050: 	node, "itemType", &(type->baseNs), &(type->base));
 9051:     /*
 9052:     * And now for the children...
 9053:     */
 9054:     child = node->children;
 9055:     if (IS_SCHEMA(child, "annotation")) {
 9056: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 9057: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 9058:         child = child->next;
 9059:     }
 9060:     if (IS_SCHEMA(child, "simpleType")) {
 9061: 	/*
 9062: 	* src-list-itemType-or-simpleType
 9063: 	* Either the itemType [attribute] or the <simpleType> [child] of
 9064: 	* the <list> element must be present, but not both.
 9065: 	*/
 9066: 	if (type->base != NULL) {
 9067: 	    xmlSchemaPCustomErr(ctxt,
 9068: 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9069: 		NULL, node,
 9070: 		"The attribute 'itemType' and the <simpleType> child "
 9071: 		"are mutually exclusive", NULL);
 9072: 	} else {
 9073: 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 9074: 	}
 9075:         child = child->next;
 9076:     } else if (type->base == NULL) {
 9077: 	xmlSchemaPCustomErr(ctxt,
 9078: 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9079: 	    NULL, node,
 9080: 	    "Either the attribute 'itemType' or the <simpleType> child "
 9081: 	    "must be present", NULL);
 9082:     }
 9083:     if (child != NULL) {
 9084: 	xmlSchemaPContentErr(ctxt,
 9085: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9086: 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
 9087:     }
 9088:     if ((type->base == NULL) &&
 9089: 	(type->subtypes == NULL) &&
 9090: 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
 9091: 	xmlSchemaPCustomErr(ctxt,
 9092: 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9093: 	    NULL, node,
 9094: 	    "Either the attribute 'itemType' or the <simpleType> child "
 9095: 	    "must be present", NULL);
 9096:     }
 9097:     return (NULL);
 9098: }
 9099: 
 9100: /**
 9101:  * xmlSchemaParseSimpleType:
 9102:  * @ctxt:  a schema validation context
 9103:  * @schema:  the schema being built
 9104:  * @node:  a subtree containing XML Schema informations
 9105:  *
 9106:  * parse a XML schema Simple Type definition
 9107:  * *WARNING* this interface is highly subject to change
 9108:  *
 9109:  * Returns -1 in case of error, 0 if the declaration is improper and
 9110:  * 1 in case of success.
 9111:  */
 9112: static xmlSchemaTypePtr
 9113: xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 9114:                          xmlNodePtr node, int topLevel)
 9115: {
 9116:     xmlSchemaTypePtr type, oldCtxtType;
 9117:     xmlNodePtr child = NULL;
 9118:     const xmlChar *attrValue = NULL;
 9119:     xmlAttrPtr attr;
 9120:     int hasRestriction = 0;
 9121: 
 9122:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9123:         return (NULL);
 9124: 
 9125:     if (topLevel) {
 9126: 	attr = xmlSchemaGetPropNode(node, "name");
 9127: 	if (attr == NULL) {
 9128: 	    xmlSchemaPMissingAttrErr(ctxt,
 9129: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 9130: 		NULL, node,
 9131: 		"name", NULL);
 9132: 	    return (NULL);
 9133: 	} else {
 9134: 	    if (xmlSchemaPValAttrNode(ctxt,
 9135: 		NULL, attr,
 9136: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
 9137: 		return (NULL);
 9138: 	    /*
 9139: 	    * Skip built-in types.
 9140: 	    */
 9141: 	    if (ctxt->isS4S) {
 9142: 		xmlSchemaTypePtr biType;
 9143: 
 9144: 		if (ctxt->isRedefine) {
 9145: 		    /*
 9146: 		    * REDEFINE: Disallow redefinition of built-in-types.
 9147: 		    * TODO: It seems that the spec does not say anything
 9148: 		    * about this case.
 9149: 		    */
 9150: 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 9151: 			NULL, node,
 9152: 			"Redefinition of built-in simple types is not "
 9153: 			"supported", NULL);
 9154: 		    return(NULL);
 9155: 		}
 9156: 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
 9157: 		if (biType != NULL)
 9158: 		    return (biType);
 9159: 	    }
 9160: 	}
 9161:     }
 9162:     /*
 9163:     * TargetNamespace:
 9164:     * SPEC "The �actual value� of the targetNamespace [attribute]
 9165:     * of the <schema> ancestor element information item if present,
 9166:     * otherwise �absent�.
 9167:     */
 9168:     if (topLevel == 0) {
 9169: #ifdef ENABLE_NAMED_LOCALS
 9170:         char buf[40];
 9171: #endif
 9172: 	/*
 9173: 	* Parse as local simple type definition.
 9174: 	*/
 9175: #ifdef ENABLE_NAMED_LOCALS
 9176:         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
 9177: 	type = xmlSchemaAddType(ctxt, schema,
 9178: 	    XML_SCHEMA_TYPE_SIMPLE,
 9179: 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
 9180: 	    ctxt->targetNamespace, node, 0);
 9181: #else
 9182: 	type = xmlSchemaAddType(ctxt, schema,
 9183: 	    XML_SCHEMA_TYPE_SIMPLE,
 9184: 	    NULL, ctxt->targetNamespace, node, 0);
 9185: #endif
 9186: 	if (type == NULL)
 9187: 	    return (NULL);
 9188: 	type->type = XML_SCHEMA_TYPE_SIMPLE;
 9189: 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 9190: 	/*
 9191: 	* Check for illegal attributes.
 9192: 	*/
 9193: 	attr = node->properties;
 9194: 	while (attr != NULL) {
 9195: 	    if (attr->ns == NULL) {
 9196: 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
 9197: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9198: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9199: 		}
 9200: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9201: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9202: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9203: 	    }
 9204: 	    attr = attr->next;
 9205: 	}
 9206:     } else {
 9207: 	/*
 9208: 	* Parse as global simple type definition.
 9209: 	*
 9210: 	* Note that attrValue is the value of the attribute "name" here.
 9211: 	*/
 9212: 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
 9213: 	    attrValue, ctxt->targetNamespace, node, 1);
 9214: 	if (type == NULL)
 9215: 	    return (NULL);
 9216: 	type->type = XML_SCHEMA_TYPE_SIMPLE;
 9217: 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 9218: 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
 9219: 	/*
 9220: 	* Check for illegal attributes.
 9221: 	*/
 9222: 	attr = node->properties;
 9223: 	while (attr != NULL) {
 9224: 	    if (attr->ns == NULL) {
 9225: 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9226: 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 9227: 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
 9228: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9229: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9230: 		}
 9231: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9232: 		xmlSchemaPIllegalAttrErr(ctxt,
 9233: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9234: 	    }
 9235: 	    attr = attr->next;
 9236: 	}
 9237: 	/*
 9238: 	* Attribute "final".
 9239: 	*/
 9240: 	attr = xmlSchemaGetPropNode(node, "final");
 9241: 	if (attr == NULL) {
 9242: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 9243: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
 9244: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 9245: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
 9246: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 9247: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
 9248: 	} else {
 9249: 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
 9250: 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
 9251: 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
 9252: 		XML_SCHEMAS_TYPE_FINAL_LIST,
 9253: 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
 9254: 
 9255: 		xmlSchemaPSimpleTypeErr(ctxt,
 9256: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9257: 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
 9258: 		    NULL, "(#all | List of (list | union | restriction)",
 9259: 		    attrValue, NULL, NULL, NULL);
 9260: 	    }
 9261: 	}
 9262:     }
 9263:     type->targetNamespace = ctxt->targetNamespace;
 9264:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9265:     /*
 9266:     * And now for the children...
 9267:     */
 9268:     oldCtxtType = ctxt->ctxtType;
 9269: 
 9270:     ctxt->ctxtType = type;
 9271: 
 9272:     child = node->children;
 9273:     if (IS_SCHEMA(child, "annotation")) {
 9274:         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9275:         child = child->next;
 9276:     }
 9277:     if (child == NULL) {
 9278: 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
 9279: 	    NULL, node, child, NULL,
 9280: 	    "(annotation?, (restriction | list | union))");
 9281:     } else if (IS_SCHEMA(child, "restriction")) {
 9282:         xmlSchemaParseRestriction(ctxt, schema, child,
 9283: 	    XML_SCHEMA_TYPE_SIMPLE);
 9284: 	hasRestriction = 1;
 9285:         child = child->next;
 9286:     } else if (IS_SCHEMA(child, "list")) {
 9287:         xmlSchemaParseList(ctxt, schema, child);
 9288:         child = child->next;
 9289:     } else if (IS_SCHEMA(child, "union")) {
 9290:         xmlSchemaParseUnion(ctxt, schema, child);
 9291:         child = child->next;
 9292:     }
 9293:     if (child != NULL) {
 9294: 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9295: 	    NULL, node, child, NULL,
 9296: 	    "(annotation?, (restriction | list | union))");
 9297:     }
 9298:     /*
 9299:     * REDEFINE: SPEC src-redefine (5)
 9300:     * "Within the [children], each <simpleType> must have a
 9301:     * <restriction> among its [children] ... the �actual value� of whose
 9302:     * base [attribute] must be the same as the �actual value� of its own
 9303:     * name attribute plus target namespace;"
 9304:     */
 9305:     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
 9306: 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 9307: 	    NULL, node, "This is a redefinition, thus the "
 9308: 	    "<simpleType> must have a <restriction> child", NULL);
 9309:     }
 9310: 
 9311:     ctxt->ctxtType = oldCtxtType;
 9312:     return (type);
 9313: }
 9314: 
 9315: /**
 9316:  * xmlSchemaParseModelGroupDefRef:
 9317:  * @ctxt:  the parser context
 9318:  * @schema: the schema being built
 9319:  * @node:  the node
 9320:  *
 9321:  * Parses a reference to a model group definition.
 9322:  *
 9323:  * We will return a particle component with a qname-component or
 9324:  * NULL in case of an error.
 9325:  */
 9326: static xmlSchemaTreeItemPtr
 9327: xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
 9328: 			       xmlSchemaPtr schema,
 9329: 			       xmlNodePtr node)
 9330: {
 9331:     xmlSchemaParticlePtr item;
 9332:     xmlNodePtr child = NULL;
 9333:     xmlAttrPtr attr;
 9334:     const xmlChar *ref = NULL, *refNs = NULL;
 9335:     int min, max;
 9336: 
 9337:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9338:         return (NULL);
 9339: 
 9340:     attr = xmlSchemaGetPropNode(node, "ref");
 9341:     if (attr == NULL) {
 9342: 	xmlSchemaPMissingAttrErr(ctxt,
 9343: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 9344: 	    NULL, node, "ref", NULL);
 9345: 	return (NULL);
 9346:     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
 9347: 	attr, &refNs, &ref) != 0) {
 9348: 	return (NULL);
 9349:     }
 9350:     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 9351:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 9352:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 9353: 	"(xs:nonNegativeInteger | unbounded)");
 9354:     /*
 9355:     * Check for illegal attributes.
 9356:     */
 9357:     attr = node->properties;
 9358:     while (attr != NULL) {
 9359: 	if (attr->ns == NULL) {
 9360: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 9361: 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9362: 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 9363: 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
 9364: 		xmlSchemaPIllegalAttrErr(ctxt,
 9365: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9366: 	    }
 9367: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9368: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9369: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9370: 	}
 9371: 	attr = attr->next;
 9372:     }
 9373:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9374:     item = xmlSchemaAddParticle(ctxt, node, min, max);
 9375:     if (item == NULL)
 9376: 	return (NULL);
 9377:     /*
 9378:     * Create a qname-reference and set as the term; it will be substituted
 9379:     * for the model group after the reference has been resolved.
 9380:     */
 9381:     item->children = (xmlSchemaTreeItemPtr)
 9382: 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
 9383:     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
 9384:     /*
 9385:     * And now for the children...
 9386:     */
 9387:     child = node->children;
 9388:     /* TODO: Is annotation even allowed for a model group reference? */
 9389:     if (IS_SCHEMA(child, "annotation")) {
 9390: 	/*
 9391: 	* TODO: What to do exactly with the annotation?
 9392: 	*/
 9393: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9394: 	child = child->next;
 9395:     }
 9396:     if (child != NULL) {
 9397: 	xmlSchemaPContentErr(ctxt,
 9398: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9399: 	    NULL, node, child, NULL,
 9400: 	    "(annotation?)");
 9401:     }
 9402:     /*
 9403:     * Corresponds to no component at all if minOccurs==maxOccurs==0.
 9404:     */
 9405:     if ((min == 0) && (max == 0))
 9406: 	return (NULL);
 9407: 
 9408:     return ((xmlSchemaTreeItemPtr) item);
 9409: }
 9410: 
 9411: /**
 9412:  * xmlSchemaParseModelGroupDefinition:
 9413:  * @ctxt:  a schema validation context
 9414:  * @schema:  the schema being built
 9415:  * @node:  a subtree containing XML Schema informations
 9416:  *
 9417:  * Parses a XML schema model group definition.
 9418:  *
 9419:  * Note that the contraint src-redefine (6.2) can't be applied until
 9420:  * references have been resolved. So we will do this at the
 9421:  * component fixup level.
 9422:  *
 9423:  * *WARNING* this interface is highly subject to change
 9424:  *
 9425:  * Returns -1 in case of error, 0 if the declaration is improper and
 9426:  *         1 in case of success.
 9427:  */
 9428: static xmlSchemaModelGroupDefPtr
 9429: xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 9430: 				   xmlSchemaPtr schema,
 9431: 				   xmlNodePtr node)
 9432: {
 9433:     xmlSchemaModelGroupDefPtr item;
 9434:     xmlNodePtr child = NULL;
 9435:     xmlAttrPtr attr;
 9436:     const xmlChar *name;
 9437: 
 9438:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9439:         return (NULL);
 9440: 
 9441:     attr = xmlSchemaGetPropNode(node, "name");
 9442:     if (attr == NULL) {
 9443: 	xmlSchemaPMissingAttrErr(ctxt,
 9444: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 9445: 	    NULL, node,
 9446: 	    "name", NULL);
 9447: 	return (NULL);
 9448:     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
 9449: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 9450: 	return (NULL);
 9451:     }
 9452:     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
 9453: 	ctxt->targetNamespace, node);
 9454:     if (item == NULL)
 9455: 	return (NULL);
 9456:     /*
 9457:     * Check for illegal attributes.
 9458:     */
 9459:     attr = node->properties;
 9460:     while (attr != NULL) {
 9461: 	if (attr->ns == NULL) {
 9462: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 9463: 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
 9464: 		xmlSchemaPIllegalAttrErr(ctxt,
 9465: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9466: 	    }
 9467: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9468: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9469: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9470: 	}
 9471: 	attr = attr->next;
 9472:     }
 9473:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9474:     /*
 9475:     * And now for the children...
 9476:     */
 9477:     child = node->children;
 9478:     if (IS_SCHEMA(child, "annotation")) {
 9479: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9480: 	child = child->next;
 9481:     }
 9482:     if (IS_SCHEMA(child, "all")) {
 9483: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9484: 	    XML_SCHEMA_TYPE_ALL, 0);
 9485: 	child = child->next;
 9486:     } else if (IS_SCHEMA(child, "choice")) {
 9487: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9488: 	    XML_SCHEMA_TYPE_CHOICE, 0);
 9489: 	child = child->next;
 9490:     } else if (IS_SCHEMA(child, "sequence")) {
 9491: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9492: 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
 9493: 	child = child->next;
 9494:     }
 9495: 
 9496: 
 9497: 
 9498:     if (child != NULL) {
 9499: 	xmlSchemaPContentErr(ctxt,
 9500: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9501: 	    NULL, node, child, NULL,
 9502: 	    "(annotation?, (all | choice | sequence)?)");
 9503:     }
 9504:     return (item);
 9505: }
 9506: 
 9507: /**
 9508:  * xmlSchemaCleanupDoc:
 9509:  * @ctxt:  a schema validation context
 9510:  * @node:  the root of the document.
 9511:  *
 9512:  * removes unwanted nodes in a schemas document tree
 9513:  */
 9514: static void
 9515: xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
 9516: {
 9517:     xmlNodePtr delete, cur;
 9518: 
 9519:     if ((ctxt == NULL) || (root == NULL)) return;
 9520: 
 9521:     /*
 9522:      * Remove all the blank text nodes
 9523:      */
 9524:     delete = NULL;
 9525:     cur = root;
 9526:     while (cur != NULL) {
 9527:         if (delete != NULL) {
 9528:             xmlUnlinkNode(delete);
 9529:             xmlFreeNode(delete);
 9530:             delete = NULL;
 9531:         }
 9532:         if (cur->type == XML_TEXT_NODE) {
 9533:             if (IS_BLANK_NODE(cur)) {
 9534:                 if (xmlNodeGetSpacePreserve(cur) != 1) {
 9535:                     delete = cur;
 9536:                 }
 9537:             }
 9538:         } else if ((cur->type != XML_ELEMENT_NODE) &&
 9539:                    (cur->type != XML_CDATA_SECTION_NODE)) {
 9540:             delete = cur;
 9541:             goto skip_children;
 9542:         }
 9543: 
 9544:         /*
 9545:          * Skip to next node
 9546:          */
 9547:         if (cur->children != NULL) {
 9548:             if ((cur->children->type != XML_ENTITY_DECL) &&
 9549:                 (cur->children->type != XML_ENTITY_REF_NODE) &&
 9550:                 (cur->children->type != XML_ENTITY_NODE)) {
 9551:                 cur = cur->children;
 9552:                 continue;
 9553:             }
 9554:         }
 9555:       skip_children:
 9556:         if (cur->next != NULL) {
 9557:             cur = cur->next;
 9558:             continue;
 9559:         }
 9560: 
 9561:         do {
 9562:             cur = cur->parent;
 9563:             if (cur == NULL)
 9564:                 break;
 9565:             if (cur == root) {
 9566:                 cur = NULL;
 9567:                 break;
 9568:             }
 9569:             if (cur->next != NULL) {
 9570:                 cur = cur->next;
 9571:                 break;
 9572:             }
 9573:         } while (cur != NULL);
 9574:     }
 9575:     if (delete != NULL) {
 9576:         xmlUnlinkNode(delete);
 9577:         xmlFreeNode(delete);
 9578:         delete = NULL;
 9579:     }
 9580: }
 9581: 
 9582: 
 9583: static void
 9584: xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
 9585: {
 9586:     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 9587: 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
 9588: 
 9589:     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
 9590: 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
 9591: 
 9592:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 9593: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
 9594:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 9595: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
 9596:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 9597: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
 9598:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 9599: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
 9600: 
 9601:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 9602: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
 9603:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 9604: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
 9605:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 9606: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
 9607: }
 9608: 
 9609: static int
 9610: xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
 9611: 			     xmlSchemaPtr schema,
 9612: 			     xmlNodePtr node)
 9613: {
 9614:     xmlAttrPtr attr;
 9615:     const xmlChar *val;
 9616:     int res = 0, oldErrs = ctxt->nberrors;
 9617: 
 9618:     /*
 9619:     * Those flags should be moved to the parser context flags,
 9620:     * since they are not visible at the component level. I.e.
 9621:     * they are used if processing schema *documents* only.
 9622:     */
 9623:     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9624:     HFAILURE;
 9625: 
 9626:     /*
 9627:     * Since the version is of type xs:token, we won't bother to
 9628:     * check it.
 9629:     */
 9630:     /* REMOVED:
 9631:     attr = xmlSchemaGetPropNode(node, "version");
 9632:     if (attr != NULL) {
 9633: 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
 9634: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
 9635: 	HFAILURE;
 9636:     }
 9637:     */
 9638:     attr = xmlSchemaGetPropNode(node, "targetNamespace");
 9639:     if (attr != NULL) {
 9640: 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
 9641: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 9642: 	HFAILURE;
 9643: 	if (res != 0) {
 9644: 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 9645: 	    goto exit;
 9646: 	}
 9647:     }
 9648:     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
 9649:     if (attr != NULL) {
 9650: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9651: 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 9652: 	    XML_SCHEMAS_QUALIF_ELEM);
 9653: 	HFAILURE;
 9654: 	if (res != 0) {
 9655: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9656: 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
 9657: 		NULL, (xmlNodePtr) attr, NULL,
 9658: 		"(qualified | unqualified)", val, NULL, NULL, NULL);
 9659: 	}
 9660:     }
 9661:     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
 9662:     if (attr != NULL) {
 9663: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9664: 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 9665: 	    XML_SCHEMAS_QUALIF_ATTR);
 9666: 	HFAILURE;
 9667: 	if (res != 0) {
 9668: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9669: 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
 9670: 		NULL, (xmlNodePtr) attr, NULL,
 9671: 		"(qualified | unqualified)", val, NULL, NULL, NULL);
 9672: 	}
 9673:     }
 9674:     attr = xmlSchemaGetPropNode(node, "finalDefault");
 9675:     if (attr != NULL) {
 9676: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9677: 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 9678: 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
 9679: 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
 9680: 	    -1,
 9681: 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
 9682: 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
 9683: 	HFAILURE;
 9684: 	if (res != 0) {
 9685: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9686: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9687: 		NULL, (xmlNodePtr) attr, NULL,
 9688: 		"(#all | List of (extension | restriction | list | union))",
 9689: 		val, NULL, NULL, NULL);
 9690: 	}
 9691:     }
 9692:     attr = xmlSchemaGetPropNode(node, "blockDefault");
 9693:     if (attr != NULL) {
 9694: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9695: 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 9696: 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
 9697: 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
 9698: 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
 9699: 	HFAILURE;
 9700: 	if (res != 0) {
 9701: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9702: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9703: 		NULL, (xmlNodePtr) attr, NULL,
 9704: 		"(#all | List of (extension | restriction | substitution))",
 9705: 		val, NULL, NULL, NULL);
 9706: 	}
 9707:     }
 9708: 
 9709: exit:
 9710:     if (oldErrs != ctxt->nberrors)
 9711: 	res = ctxt->err;
 9712:     return(res);
 9713: exit_failure:
 9714:     return(-1);
 9715: }
 9716: 
 9717: /**
 9718:  * xmlSchemaParseSchemaTopLevel:
 9719:  * @ctxt:  a schema validation context
 9720:  * @schema:  the schemas
 9721:  * @nodes:  the list of top level nodes
 9722:  *
 9723:  * Returns the internal XML Schema structure built from the resource or
 9724:  *         NULL in case of error
 9725:  */
 9726: static int
 9727: xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
 9728:                              xmlSchemaPtr schema, xmlNodePtr nodes)
 9729: {
 9730:     xmlNodePtr child;
 9731:     xmlSchemaAnnotPtr annot;
 9732:     int res = 0, oldErrs, tmpOldErrs;
 9733: 
 9734:     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
 9735:         return(-1);
 9736: 
 9737:     oldErrs = ctxt->nberrors;
 9738:     child = nodes;
 9739:     while ((IS_SCHEMA(child, "include")) ||
 9740: 	   (IS_SCHEMA(child, "import")) ||
 9741: 	   (IS_SCHEMA(child, "redefine")) ||
 9742: 	   (IS_SCHEMA(child, "annotation"))) {
 9743: 	if (IS_SCHEMA(child, "annotation")) {
 9744: 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9745: 	    if (schema->annot == NULL)
 9746: 		schema->annot = annot;
 9747: 	    else
 9748: 		xmlSchemaFreeAnnot(annot);
 9749: 	} else if (IS_SCHEMA(child, "import")) {
 9750: 	    tmpOldErrs = ctxt->nberrors;
 9751: 	    res = xmlSchemaParseImport(ctxt, schema, child);
 9752: 	    HFAILURE;
 9753: 	    HSTOP(ctxt);
 9754: 	    if (tmpOldErrs != ctxt->nberrors)
 9755: 		goto exit;
 9756: 	} else if (IS_SCHEMA(child, "include")) {
 9757: 	    tmpOldErrs = ctxt->nberrors;
 9758: 	    res = xmlSchemaParseInclude(ctxt, schema, child);
 9759: 	    HFAILURE;
 9760: 	    HSTOP(ctxt);
 9761: 	    if (tmpOldErrs != ctxt->nberrors)
 9762: 		goto exit;
 9763: 	} else if (IS_SCHEMA(child, "redefine")) {
 9764: 	    tmpOldErrs = ctxt->nberrors;
 9765: 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
 9766: 	    HFAILURE;
 9767: 	    HSTOP(ctxt);
 9768: 	    if (tmpOldErrs != ctxt->nberrors)
 9769: 		goto exit;
 9770: 	}
 9771: 	child = child->next;
 9772:     }
 9773:     /*
 9774:     * URGENT TODO: Change the functions to return int results.
 9775:     * We need especially to catch internal errors.
 9776:     */
 9777:     while (child != NULL) {
 9778: 	if (IS_SCHEMA(child, "complexType")) {
 9779: 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
 9780: 	    child = child->next;
 9781: 	} else if (IS_SCHEMA(child, "simpleType")) {
 9782: 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
 9783: 	    child = child->next;
 9784: 	} else if (IS_SCHEMA(child, "element")) {
 9785: 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
 9786: 	    child = child->next;
 9787: 	} else if (IS_SCHEMA(child, "attribute")) {
 9788: 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
 9789: 	    child = child->next;
 9790: 	} else if (IS_SCHEMA(child, "attributeGroup")) {
 9791: 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
 9792: 	    child = child->next;
 9793: 	} else if (IS_SCHEMA(child, "group")) {
 9794: 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
 9795: 	    child = child->next;
 9796: 	} else if (IS_SCHEMA(child, "notation")) {
 9797: 	    xmlSchemaParseNotation(ctxt, schema, child);
 9798: 	    child = child->next;
 9799: 	} else {
 9800: 	    xmlSchemaPContentErr(ctxt,
 9801: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9802: 		NULL, child->parent, child,
 9803: 		NULL, "((include | import | redefine | annotation)*, "
 9804: 		"(((simpleType | complexType | group | attributeGroup) "
 9805: 		"| element | attribute | notation), annotation*)*)");
 9806: 	    child = child->next;
 9807: 	}
 9808: 	while (IS_SCHEMA(child, "annotation")) {
 9809: 	    /*
 9810: 	    * TODO: We should add all annotations.
 9811: 	    */
 9812: 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9813: 	    if (schema->annot == NULL)
 9814: 		schema->annot = annot;
 9815: 	    else
 9816: 		xmlSchemaFreeAnnot(annot);
 9817: 	    child = child->next;
 9818: 	}
 9819:     }
 9820: exit:
 9821:     ctxt->ctxtType = NULL;
 9822:     if (oldErrs != ctxt->nberrors)
 9823: 	res = ctxt->err;
 9824:     return(res);
 9825: exit_failure:
 9826:     return(-1);
 9827: }
 9828: 
 9829: static xmlSchemaSchemaRelationPtr
 9830: xmlSchemaSchemaRelationCreate(void)
 9831: {
 9832:     xmlSchemaSchemaRelationPtr ret;
 9833: 
 9834:     ret = (xmlSchemaSchemaRelationPtr)
 9835: 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
 9836:     if (ret == NULL) {
 9837: 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
 9838: 	return(NULL);
 9839:     }
 9840:     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
 9841:     return(ret);
 9842: }
 9843: 
 9844: #if 0
 9845: static void
 9846: xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
 9847: {
 9848:     xmlFree(rel);
 9849: }
 9850: #endif
 9851: 
 9852: static void
 9853: xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
 9854: {
 9855:     xmlSchemaRedefPtr prev;
 9856: 
 9857:     while (redef != NULL) {
 9858: 	prev = redef;
 9859: 	redef = redef->next;
 9860: 	xmlFree(prev);
 9861:     }
 9862: }
 9863: 
 9864: static void
 9865: xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
 9866: {
 9867:     /*
 9868:     * After the construction context has been freed, there will be
 9869:     * no schema graph available any more. Only the schema buckets
 9870:     * will stay alive, which are put into the "schemasImports" and
 9871:     * "includes" slots of the xmlSchema.
 9872:     */
 9873:     if (con->buckets != NULL)
 9874: 	xmlSchemaItemListFree(con->buckets);
 9875:     if (con->pending != NULL)
 9876: 	xmlSchemaItemListFree(con->pending);
 9877:     if (con->substGroups != NULL)
 9878: 	xmlHashFree(con->substGroups,
 9879: 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
 9880:     if (con->redefs != NULL)
 9881: 	xmlSchemaRedefListFree(con->redefs);
 9882:     if (con->dict != NULL)
 9883: 	xmlDictFree(con->dict);
 9884:     xmlFree(con);
 9885: }
 9886: 
 9887: static xmlSchemaConstructionCtxtPtr
 9888: xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
 9889: {
 9890:     xmlSchemaConstructionCtxtPtr ret;
 9891: 
 9892:     ret = (xmlSchemaConstructionCtxtPtr)
 9893: 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
 9894:     if (ret == NULL) {
 9895:         xmlSchemaPErrMemory(NULL,
 9896: 	    "allocating schema construction context", NULL);
 9897:         return (NULL);
 9898:     }
 9899:     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
 9900: 
 9901:     ret->buckets = xmlSchemaItemListCreate();
 9902:     if (ret->buckets == NULL) {
 9903: 	xmlSchemaPErrMemory(NULL,
 9904: 	    "allocating list of schema buckets", NULL);
 9905: 	xmlFree(ret);
 9906:         return (NULL);
 9907:     }
 9908:     ret->pending = xmlSchemaItemListCreate();
 9909:     if (ret->pending == NULL) {
 9910: 	xmlSchemaPErrMemory(NULL,
 9911: 	    "allocating list of pending global components", NULL);
 9912: 	xmlSchemaConstructionCtxtFree(ret);
 9913:         return (NULL);
 9914:     }
 9915:     ret->dict = dict;
 9916:     xmlDictReference(dict);
 9917:     return(ret);
 9918: }
 9919: 
 9920: static xmlSchemaParserCtxtPtr
 9921: xmlSchemaParserCtxtCreate(void)
 9922: {
 9923:     xmlSchemaParserCtxtPtr ret;
 9924: 
 9925:     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
 9926:     if (ret == NULL) {
 9927:         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
 9928:                             NULL);
 9929:         return (NULL);
 9930:     }
 9931:     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
 9932:     ret->type = XML_SCHEMA_CTXT_PARSER;
 9933:     ret->attrProhibs = xmlSchemaItemListCreate();
 9934:     if (ret->attrProhibs == NULL) {
 9935: 	xmlFree(ret);
 9936: 	return(NULL);
 9937:     }
 9938:     return(ret);
 9939: }
 9940: 
 9941: /**
 9942:  * xmlSchemaNewParserCtxtUseDict:
 9943:  * @URL:  the location of the schema
 9944:  * @dict: the dictionary to be used
 9945:  *
 9946:  * Create an XML Schemas parse context for that file/resource expected
 9947:  * to contain an XML Schemas file.
 9948:  *
 9949:  * Returns the parser context or NULL in case of error
 9950:  */
 9951: static xmlSchemaParserCtxtPtr
 9952: xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
 9953: {
 9954:     xmlSchemaParserCtxtPtr ret;
 9955: 
 9956:     ret = xmlSchemaParserCtxtCreate();
 9957:     if (ret == NULL)
 9958:         return (NULL);
 9959:     ret->dict = dict;
 9960:     xmlDictReference(dict);
 9961:     if (URL != NULL)
 9962: 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
 9963:     return (ret);
 9964: }
 9965: 
 9966: static int
 9967: xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
 9968: {
 9969:     if (vctxt->pctxt == NULL) {
 9970:         if (vctxt->schema != NULL)
 9971: 	    vctxt->pctxt =
 9972: 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
 9973: 	else
 9974: 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
 9975: 	if (vctxt->pctxt == NULL) {
 9976: 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
 9977: 		"failed to create a temp. parser context");
 9978: 	    return (-1);
 9979: 	}
 9980: 	/* TODO: Pass user data. */
 9981: 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
 9982: 	    vctxt->warning, vctxt->errCtxt);
 9983: 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
 9984: 	    vctxt->errCtxt);
 9985:     }
 9986:     return (0);
 9987: }
 9988: 
 9989: /**
 9990:  * xmlSchemaGetSchemaBucket:
 9991:  * @pctxt: the schema parser context
 9992:  * @schemaLocation: the URI of the schema document
 9993:  *
 9994:  * Returns a schema bucket if it was already parsed.
 9995:  *
 9996:  * Returns a schema bucket if it was already parsed from
 9997:  *         @schemaLocation, NULL otherwise.
 9998:  */
 9999: static xmlSchemaBucketPtr
10000: xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10001: 			    const xmlChar *schemaLocation)
10002: {
10003:     xmlSchemaBucketPtr cur;
10004:     xmlSchemaItemListPtr list;
10005: 
10006:     list = pctxt->constructor->buckets;
10007:     if (list->nbItems == 0)
10008: 	return(NULL);
10009:     else {
10010: 	int i;
10011: 	for (i = 0; i < list->nbItems; i++) {
10012: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10013: 	    /* Pointer comparison! */
10014: 	    if (cur->schemaLocation == schemaLocation)
10015: 		return(cur);
10016: 	}
10017:     }
10018:     return(NULL);
10019: }
10020: 
10021: static xmlSchemaBucketPtr
10022: xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10023: 				     const xmlChar *schemaLocation,
10024: 				     const xmlChar *targetNamespace)
10025: {
10026:     xmlSchemaBucketPtr cur;
10027:     xmlSchemaItemListPtr list;
10028: 
10029:     list = pctxt->constructor->buckets;
10030:     if (list->nbItems == 0)
10031: 	return(NULL);
10032:     else {
10033: 	int i;
10034: 	for (i = 0; i < list->nbItems; i++) {
10035: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10036: 	    /* Pointer comparison! */
10037: 	    if ((cur->origTargetNamespace == NULL) &&
10038: 		(cur->schemaLocation == schemaLocation) &&
10039: 		(cur->targetNamespace == targetNamespace))
10040: 		return(cur);
10041: 	}
10042:     }
10043:     return(NULL);
10044: }
10045: 
10046: 
10047: #define IS_BAD_SCHEMA_DOC(b) \
10048:     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10049: 
10050: static xmlSchemaBucketPtr
10051: xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10052: 				 const xmlChar *targetNamespace,
10053: 				 int imported)
10054: {
10055:     xmlSchemaBucketPtr cur;
10056:     xmlSchemaItemListPtr list;
10057: 
10058:     list = pctxt->constructor->buckets;
10059:     if (list->nbItems == 0)
10060: 	return(NULL);
10061:     else {
10062: 	int i;
10063: 	for (i = 0; i < list->nbItems; i++) {
10064: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10065: 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10066: 		(cur->origTargetNamespace == targetNamespace) &&
10067: 		((imported && cur->imported) ||
10068: 		 ((!imported) && (!cur->imported))))
10069: 		return(cur);
10070: 	}
10071:     }
10072:     return(NULL);
10073: }
10074: 
10075: static int
10076: xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10077: 		     xmlSchemaPtr schema,
10078: 		     xmlSchemaBucketPtr bucket)
10079: {
10080:     int oldFlags;
10081:     xmlDocPtr oldDoc;
10082:     xmlNodePtr node;
10083:     int ret, oldErrs;
10084:     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10085: 
10086:     /*
10087:     * Save old values; reset the *main* schema.
10088:     * URGENT TODO: This is not good; move the per-document information
10089:     * to the parser. Get rid of passing the main schema to the
10090:     * parsing functions.
10091:     */
10092:     oldFlags = schema->flags;
10093:     oldDoc = schema->doc;
10094:     if (schema->flags != 0)
10095: 	xmlSchemaClearSchemaDefaults(schema);
10096:     schema->doc = bucket->doc;
10097:     pctxt->schema = schema;
10098:     /*
10099:     * Keep the current target namespace on the parser *not* on the
10100:     * main schema.
10101:     */
10102:     pctxt->targetNamespace = bucket->targetNamespace;
10103:     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10104: 
10105:     if ((bucket->targetNamespace != NULL) &&
10106: 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10107: 	/*
10108: 	* We are parsing the schema for schemas!
10109: 	*/
10110: 	pctxt->isS4S = 1;
10111:     }
10112:     /* Mark it as parsed, even if parsing fails. */
10113:     bucket->parsed++;
10114:     /* Compile the schema doc. */
10115:     node = xmlDocGetRootElement(bucket->doc);
10116:     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10117:     if (ret != 0)
10118: 	goto exit;
10119:     /* An empty schema; just get out. */
10120:     if (node->children == NULL)
10121: 	goto exit;
10122:     oldErrs = pctxt->nberrors;
10123:     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10124:     if (ret != 0)
10125: 	goto exit;
10126:     /*
10127:     * TODO: Not nice, but I'm not 100% sure we will get always an error
10128:     * as a result of the obove functions; so better rely on pctxt->err
10129:     * as well.
10130:     */
10131:     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10132: 	ret = pctxt->err;
10133: 	goto exit;
10134:     }
10135: 
10136: exit:
10137:     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10138:     /* Restore schema values. */
10139:     schema->doc = oldDoc;
10140:     schema->flags = oldFlags;
10141:     return(ret);
10142: }
10143: 
10144: static int
10145: xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10146: 		     xmlSchemaPtr schema,
10147: 		     xmlSchemaBucketPtr bucket)
10148: {
10149:     xmlSchemaParserCtxtPtr newpctxt;
10150:     int res = 0;
10151: 
10152:     if (bucket == NULL)
10153: 	return(0);
10154:     if (bucket->parsed) {
10155: 	PERROR_INT("xmlSchemaParseNewDoc",
10156: 	    "reparsing a schema doc");
10157: 	return(-1);
10158:     }
10159:     if (bucket->doc == NULL) {
10160: 	PERROR_INT("xmlSchemaParseNewDoc",
10161: 	    "parsing a schema doc, but there's no doc");
10162: 	return(-1);
10163:     }
10164:     if (pctxt->constructor == NULL) {
10165: 	PERROR_INT("xmlSchemaParseNewDoc",
10166: 	    "no constructor");
10167: 	return(-1);
10168:     }
10169:     /* Create and init the temporary parser context. */
10170:     newpctxt = xmlSchemaNewParserCtxtUseDict(
10171: 	(const char *) bucket->schemaLocation, pctxt->dict);
10172:     if (newpctxt == NULL)
10173: 	return(-1);
10174:     newpctxt->constructor = pctxt->constructor;
10175:     /*
10176:     * TODO: Can we avoid that the parser knows about the main schema?
10177:     * It would be better if he knows about the current schema bucket
10178:     * only.
10179:     */
10180:     newpctxt->schema = schema;
10181:     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10182: 	pctxt->errCtxt);
10183:     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10184: 	pctxt->errCtxt);
10185:     newpctxt->counter = pctxt->counter;
10186: 
10187: 
10188:     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10189: 
10190:     /* Channel back errors and cleanup the temporary parser context. */
10191:     if (res != 0)
10192: 	pctxt->err = res;
10193:     pctxt->nberrors += newpctxt->nberrors;
10194:     pctxt->counter = newpctxt->counter;
10195:     newpctxt->constructor = NULL;
10196:     /* Free the parser context. */
10197:     xmlSchemaFreeParserCtxt(newpctxt);
10198:     return(res);
10199: }
10200: 
10201: static void
10202: xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10203: 				xmlSchemaSchemaRelationPtr rel)
10204: {
10205:     xmlSchemaSchemaRelationPtr cur = bucket->relations;
10206: 
10207:     if (cur == NULL) {
10208: 	bucket->relations = rel;
10209: 	return;
10210:     }
10211:     while (cur->next != NULL)
10212: 	cur = cur->next;
10213:     cur->next = rel;
10214: }
10215: 
10216: 
10217: static const xmlChar *
10218: xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10219: 			  xmlNodePtr ctxtNode)
10220: {
10221:     /*
10222:     * Build an absolue location URI.
10223:     */
10224:     if (location != NULL) {
10225: 	if (ctxtNode == NULL)
10226: 	    return(location);
10227: 	else {
10228: 	    xmlChar *base, *URI;
10229: 	    const xmlChar *ret = NULL;
10230: 
10231: 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10232: 	    if (base == NULL) {
10233: 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
10234: 	    } else {
10235: 		URI = xmlBuildURI(location, base);
10236: 		xmlFree(base);
10237: 	    }
10238: 	    if (URI != NULL) {
10239: 		ret = xmlDictLookup(dict, URI, -1);
10240: 		xmlFree(URI);
10241: 		return(ret);
10242: 	    }
10243: 	}
10244:     }
10245:     return(NULL);
10246: }
10247: 
10248: 
10249: 
10250: /**
10251:  * xmlSchemaAddSchemaDoc:
10252:  * @pctxt:  a schema validation context
10253:  * @schema:  the schema being built
10254:  * @node:  a subtree containing XML Schema informations
10255:  *
10256:  * Parse an included (and to-be-redefined) XML schema document.
10257:  *
10258:  * Returns 0 on success, a positive error code on errors and
10259:  *         -1 in case of an internal or API error.
10260:  */
10261: 
10262: static int
10263: xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10264: 		int type, /* import or include or redefine */
10265: 		const xmlChar *schemaLocation,
10266: 		xmlDocPtr schemaDoc,
10267: 		const char *schemaBuffer,
10268: 		int schemaBufferLen,
10269: 		xmlNodePtr invokingNode,
10270: 		const xmlChar *sourceTargetNamespace,
10271: 		const xmlChar *importNamespace,
10272: 		xmlSchemaBucketPtr *bucket)
10273: {
10274:     const xmlChar *targetNamespace = NULL;
10275:     xmlSchemaSchemaRelationPtr relation = NULL;
10276:     xmlDocPtr doc = NULL;
10277:     int res = 0, err = 0, located = 0, preserveDoc = 0;
10278:     xmlSchemaBucketPtr bkt = NULL;
10279: 
10280:     if (bucket != NULL)
10281: 	*bucket = NULL;
10282: 
10283:     switch (type) {
10284: 	case XML_SCHEMA_SCHEMA_IMPORT:
10285: 	case XML_SCHEMA_SCHEMA_MAIN:
10286: 	    err = XML_SCHEMAP_SRC_IMPORT;
10287: 	    break;
10288: 	case XML_SCHEMA_SCHEMA_INCLUDE:
10289: 	    err = XML_SCHEMAP_SRC_INCLUDE;
10290: 	    break;
10291: 	case XML_SCHEMA_SCHEMA_REDEFINE:
10292: 	    err = XML_SCHEMAP_SRC_REDEFINE;
10293: 	    break;
10294:     }
10295: 
10296: 
10297:     /* Special handling for the main schema:
10298:     * skip the location and relation logic and just parse the doc.
10299:     * We need just a bucket to be returned in this case.
10300:     */
10301:     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10302: 	goto doc_load;
10303: 
10304:     /* Note that we expect the location to be an absulute URI. */
10305:     if (schemaLocation != NULL) {
10306: 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10307: 	if ((bkt != NULL) &&
10308: 	    (pctxt->constructor->bucket == bkt)) {
10309: 	    /* Report self-imports/inclusions/redefinitions. */
10310: 
10311: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10312: 		invokingNode, NULL,
10313: 		"The schema must not import/include/redefine itself",
10314: 		NULL, NULL);
10315: 	    goto exit;
10316: 	}
10317:     }
10318:     /*
10319:     * Create a relation for the graph of schemas.
10320:     */
10321:     relation = xmlSchemaSchemaRelationCreate();
10322:     if (relation == NULL)
10323: 	return(-1);
10324:     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10325: 	relation);
10326:     relation->type = type;
10327: 
10328:     /*
10329:     * Save the namespace import information.
10330:     */
10331:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
10332: 	relation->importNamespace = importNamespace;
10333: 	if (schemaLocation == NULL) {
10334: 	    /*
10335: 	    * No location; this is just an import of the namespace.
10336: 	    * Note that we don't assign a bucket to the relation
10337: 	    * in this case.
10338: 	    */
10339: 	    goto exit;
10340: 	}
10341: 	targetNamespace = importNamespace;
10342:     }
10343: 
10344:     /* Did we already fetch the doc? */
10345:     if (bkt != NULL) {
10346: 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10347: 	    /*
10348: 	    * We included/redefined and then try to import a schema,
10349: 	    * but the new location provided for import was different.
10350: 	    */
10351: 	    if (schemaLocation == NULL)
10352: 		schemaLocation = BAD_CAST "in_memory_buffer";
10353: 	    if (!xmlStrEqual(schemaLocation,
10354: 		bkt->schemaLocation)) {
10355: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10356: 		    invokingNode, NULL,
10357: 		    "The schema document '%s' cannot be imported, since "
10358: 		    "it was already included or redefined",
10359: 		    schemaLocation, NULL);
10360: 		goto exit;
10361: 	    }
10362: 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10363: 	    /*
10364: 	    * We imported and then try to include/redefine a schema,
10365: 	    * but the new location provided for the include/redefine
10366: 	    * was different.
10367: 	    */
10368: 	    if (schemaLocation == NULL)
10369: 		schemaLocation = BAD_CAST "in_memory_buffer";
10370: 	    if (!xmlStrEqual(schemaLocation,
10371: 		bkt->schemaLocation)) {
10372: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10373: 		    invokingNode, NULL,
10374: 		    "The schema document '%s' cannot be included or "
10375: 		    "redefined, since it was already imported",
10376: 		    schemaLocation, NULL);
10377: 		goto exit;
10378: 	    }
10379: 	}
10380:     }
10381: 
10382:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
10383: 	/*
10384: 	* Given that the schemaLocation [attribute] is only a hint, it is open
10385: 	* to applications to ignore all but the first <import> for a given
10386: 	* namespace, regardless of the �actual value� of schemaLocation, but
10387: 	* such a strategy risks missing useful information when new
10388: 	* schemaLocations are offered.
10389: 	*
10390: 	* We will use the first <import> that comes with a location.
10391: 	* Further <import>s *with* a location, will result in an error.
10392: 	* TODO: Better would be to just report a warning here, but
10393: 	* we'll try it this way until someone complains.
10394: 	*
10395: 	* Schema Document Location Strategy:
10396: 	* 3 Based on the namespace name, identify an existing schema document,
10397: 	* either as a resource which is an XML document or a <schema> element
10398: 	* information item, in some local schema repository;
10399: 	* 5 Attempt to resolve the namespace name to locate such a resource.
10400: 	*
10401: 	* NOTE: (3) and (5) are not supported.
10402: 	*/
10403: 	if (bkt != NULL) {
10404: 	    relation->bucket = bkt;
10405: 	    goto exit;
10406: 	}
10407: 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10408: 	    importNamespace, 1);
10409: 
10410: 	if (bkt != NULL) {
10411: 	    relation->bucket = bkt;
10412: 	    if (bkt->schemaLocation == NULL) {
10413: 		/* First given location of the schema; load the doc. */
10414: 		bkt->schemaLocation = schemaLocation;
10415: 	    } else {
10416: 		if (!xmlStrEqual(schemaLocation,
10417: 		    bkt->schemaLocation)) {
10418: 		    /*
10419: 		    * Additional location given; just skip it.
10420: 		    * URGENT TODO: We should report a warning here.
10421: 		    * res = XML_SCHEMAP_SRC_IMPORT;
10422: 		    */
10423: 		    if (schemaLocation == NULL)
10424: 			schemaLocation = BAD_CAST "in_memory_buffer";
10425: 
10426: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10427: 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
10428: 			invokingNode, NULL,
10429: 			"Skipping import of schema located at '%s' for the "
10430: 			"namespace '%s', since this namespace was already "
10431: 			"imported with the schema located at '%s'",
10432: 			schemaLocation, importNamespace, bkt->schemaLocation);
10433: 		}
10434: 		goto exit;
10435: 	    }
10436: 	}
10437: 	/*
10438: 	* No bucket + first location: load the doc and create a
10439: 	* bucket.
10440: 	*/
10441:     } else {
10442: 	/* <include> and <redefine> */
10443: 	if (bkt != NULL) {
10444: 
10445: 	    if ((bkt->origTargetNamespace == NULL) &&
10446: 		(bkt->targetNamespace != sourceTargetNamespace)) {
10447: 		xmlSchemaBucketPtr chamel;
10448: 
10449: 		/*
10450: 		* Chameleon include/redefine: skip loading only if it was
10451: 		* aleady build for the targetNamespace of the including
10452: 		* schema.
10453: 		*/
10454: 		/*
10455: 		* URGENT TODO: If the schema is a chameleon-include then copy
10456: 		* the components into the including schema and modify the
10457: 		* targetNamespace of those components, do nothing otherwise.
10458: 		* NOTE: This is currently worked-around by compiling the
10459: 		* chameleon for every destinct including targetNamespace; thus
10460: 		* not performant at the moment.
10461: 		* TODO: Check when the namespace in wildcards for chameleons
10462: 		* needs to be converted: before we built wildcard intersections
10463: 		* or after.
10464: 		*   Answer: after!
10465: 		*/
10466: 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10467: 		    schemaLocation, sourceTargetNamespace);
10468: 		if (chamel != NULL) {
10469: 		    /* A fitting chameleon was already parsed; NOP. */
10470: 		    relation->bucket = chamel;
10471: 		    goto exit;
10472: 		}
10473: 		/*
10474: 		* We need to parse the chameleon again for a different
10475: 		* targetNamespace.
10476: 		* CHAMELEON TODO: Optimize this by only parsing the
10477: 		* chameleon once, and then copying the components to
10478: 		* the new targetNamespace.
10479: 		*/
10480: 		bkt = NULL;
10481: 	    } else {
10482: 		relation->bucket = bkt;
10483: 		goto exit;
10484: 	    }
10485: 	}
10486:     }
10487:     if ((bkt != NULL) && (bkt->doc != NULL)) {
10488: 	PERROR_INT("xmlSchemaAddSchemaDoc",
10489: 	    "trying to load a schema doc, but a doc is already "
10490: 	    "assigned to the schema bucket");
10491: 	goto exit_failure;
10492:     }
10493: 
10494: doc_load:
10495:     /*
10496:     * Load the document.
10497:     */
10498:     if (schemaDoc != NULL) {
10499: 	doc = schemaDoc;
10500: 	/* Don' free this one, since it was provided by the caller. */
10501: 	preserveDoc = 1;
10502: 	/* TODO: Does the context or the doc hold the location? */
10503: 	if (schemaDoc->URL != NULL)
10504: 	    schemaLocation = xmlDictLookup(pctxt->dict,
10505: 		schemaDoc->URL, -1);
10506:         else
10507: 	    schemaLocation = BAD_CAST "in_memory_buffer";
10508:     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10509: 	xmlParserCtxtPtr parserCtxt;
10510: 
10511: 	parserCtxt = xmlNewParserCtxt();
10512: 	if (parserCtxt == NULL) {
10513: 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10514: 		"allocating a parser context", NULL);
10515: 	    goto exit_failure;
10516: 	}
10517: 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10518: 	    /*
10519: 	    * TODO: Do we have to burden the schema parser dict with all
10520: 	    * the content of the schema doc?
10521: 	    */
10522: 	    xmlDictFree(parserCtxt->dict);
10523: 	    parserCtxt->dict = pctxt->dict;
10524: 	    xmlDictReference(parserCtxt->dict);
10525: 	}
10526: 	if (schemaLocation != NULL) {
10527: 	    /* Parse from file. */
10528: 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10529: 		NULL, SCHEMAS_PARSE_OPTIONS);
10530: 	} else if (schemaBuffer != NULL) {
10531: 	    /* Parse from memory buffer. */
10532: 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10533: 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10534: 	    schemaLocation = BAD_CAST "in_memory_buffer";
10535: 	    if (doc != NULL)
10536: 		doc->URL = xmlStrdup(schemaLocation);
10537: 	}
10538: 	/*
10539: 	* For <import>:
10540: 	* 2.1 The referent is (a fragment of) a resource which is an
10541: 	* XML document (see clause 1.1), which in turn corresponds to
10542: 	* a <schema> element information item in a well-formed information
10543: 	* set, which in turn corresponds to a valid schema.
10544: 	* TODO: (2.1) fragments of XML documents are not supported.
10545: 	*
10546: 	* 2.2 The referent is a <schema> element information item in
10547: 	* a well-formed information set, which in turn corresponds
10548: 	* to a valid schema.
10549: 	* TODO: (2.2) is not supported.
10550: 	*/
10551: 	if (doc == NULL) {
10552: 	    xmlErrorPtr lerr;
10553: 	    lerr = xmlGetLastError();
10554: 	    /*
10555: 	    * Check if this a parser error, or if the document could
10556: 	    * just not be located.
10557: 	    * TODO: Try to find specific error codes to react only on
10558: 	    * localisation failures.
10559: 	    */
10560: 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10561: 		/*
10562: 		* We assume a parser error here.
10563: 		*/
10564: 		located = 1;
10565: 		/* TODO: Error code ?? */
10566: 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
10567: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10568: 		    invokingNode, NULL,
10569: 		    "Failed to parse the XML resource '%s'",
10570: 		    schemaLocation, NULL);
10571: 	    }
10572: 	}
10573: 	xmlFreeParserCtxt(parserCtxt);
10574: 	if ((doc == NULL) && located)
10575: 	    goto exit_error;
10576:     } else {
10577: 	xmlSchemaPErr(pctxt, NULL,
10578: 	    XML_SCHEMAP_NOTHING_TO_PARSE,
10579: 	    "No information for parsing was provided with the "
10580: 	    "given schema parser context.\n",
10581: 	    NULL, NULL);
10582: 	goto exit_failure;
10583:     }
10584:     /*
10585:     * Preprocess the document.
10586:     */
10587:     if (doc != NULL) {
10588: 	xmlNodePtr docElem = NULL;
10589: 
10590: 	located = 1;
10591: 	docElem = xmlDocGetRootElement(doc);
10592: 	if (docElem == NULL) {
10593: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10594: 		invokingNode, NULL,
10595: 		"The document '%s' has no document element",
10596: 		schemaLocation, NULL);
10597: 	    goto exit_error;
10598: 	}
10599: 	/*
10600: 	* Remove all the blank text nodes.
10601: 	*/
10602: 	xmlSchemaCleanupDoc(pctxt, docElem);
10603: 	/*
10604: 	* Check the schema's top level element.
10605: 	*/
10606: 	if (!IS_SCHEMA(docElem, "schema")) {
10607: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10608: 		invokingNode, NULL,
10609: 		"The XML document '%s' is not a schema document",
10610: 		schemaLocation, NULL);
10611: 	    goto exit_error;
10612: 	}
10613: 	/*
10614: 	* Note that we don't apply a type check for the
10615: 	* targetNamespace value here.
10616: 	*/
10617: 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10618: 	    "targetNamespace");
10619:     }
10620: 
10621: /* after_doc_loading: */
10622:     if ((bkt == NULL) && located) {
10623: 	/* Only create a bucket if the schema was located. */
10624:         bkt = xmlSchemaBucketCreate(pctxt, type,
10625: 	    targetNamespace);
10626: 	if (bkt == NULL)
10627: 	    goto exit_failure;
10628:     }
10629:     if (bkt != NULL) {
10630: 	bkt->schemaLocation = schemaLocation;
10631: 	bkt->located = located;
10632: 	if (doc != NULL) {
10633: 	    bkt->doc = doc;
10634: 	    bkt->targetNamespace = targetNamespace;
10635: 	    bkt->origTargetNamespace = targetNamespace;
10636: 	    if (preserveDoc)
10637: 		bkt->preserveDoc = 1;
10638: 	}
10639: 	if (WXS_IS_BUCKET_IMPMAIN(type))
10640: 	    bkt->imported++;
10641: 	    /*
10642: 	    * Add it to the graph of schemas.
10643: 	    */
10644: 	if (relation != NULL)
10645: 	    relation->bucket = bkt;
10646:     }
10647: 
10648: exit:
10649:     /*
10650:     * Return the bucket explicitely; this is needed for the
10651:     * main schema.
10652:     */
10653:     if (bucket != NULL)
10654: 	*bucket = bkt;
10655:     return (0);
10656: 
10657: exit_error:
10658:     if ((doc != NULL) && (! preserveDoc)) {
10659: 	xmlFreeDoc(doc);
10660: 	if (bkt != NULL)
10661: 	    bkt->doc = NULL;
10662:     }
10663:     return(pctxt->err);
10664: 
10665: exit_failure:
10666:     if ((doc != NULL) && (! preserveDoc)) {
10667: 	xmlFreeDoc(doc);
10668: 	if (bkt != NULL)
10669: 	    bkt->doc = NULL;
10670:     }
10671:     return (-1);
10672: }
10673: 
10674: /**
10675:  * xmlSchemaParseImport:
10676:  * @ctxt:  a schema validation context
10677:  * @schema:  the schema being built
10678:  * @node:  a subtree containing XML Schema informations
10679:  *
10680:  * parse a XML schema Import definition
10681:  * *WARNING* this interface is highly subject to change
10682:  *
10683:  * Returns 0 in case of success, a positive error code if
10684:  * not valid and -1 in case of an internal error.
10685:  */
10686: static int
10687: xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10688:                      xmlNodePtr node)
10689: {
10690:     xmlNodePtr child;
10691:     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10692:     const xmlChar *thisTargetNamespace;
10693:     xmlAttrPtr attr;
10694:     int ret = 0;
10695:     xmlSchemaBucketPtr bucket = NULL;
10696: 
10697:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10698:         return (-1);
10699: 
10700:     /*
10701:     * Check for illegal attributes.
10702:     */
10703:     attr = node->properties;
10704:     while (attr != NULL) {
10705: 	if (attr->ns == NULL) {
10706: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10707: 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10708: 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10709: 		xmlSchemaPIllegalAttrErr(pctxt,
10710: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10711: 	    }
10712: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10713: 	    xmlSchemaPIllegalAttrErr(pctxt,
10714: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10715: 	}
10716: 	attr = attr->next;
10717:     }
10718:     /*
10719:     * Extract and validate attributes.
10720:     */
10721:     if (xmlSchemaPValAttr(pctxt, NULL, node,
10722: 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10723: 	&namespaceName) != 0) {
10724: 	xmlSchemaPSimpleTypeErr(pctxt,
10725: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10726: 	    NULL, node,
10727: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10728: 	    NULL, namespaceName, NULL, NULL, NULL);
10729: 	return (pctxt->err);
10730:     }
10731: 
10732:     if (xmlSchemaPValAttr(pctxt, NULL, node,
10733: 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10734: 	&schemaLocation) != 0) {
10735: 	xmlSchemaPSimpleTypeErr(pctxt,
10736: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10737: 	    NULL, node,
10738: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10739: 	    NULL, namespaceName, NULL, NULL, NULL);
10740: 	return (pctxt->err);
10741:     }
10742:     /*
10743:     * And now for the children...
10744:     */
10745:     child = node->children;
10746:     if (IS_SCHEMA(child, "annotation")) {
10747:         /*
10748:          * the annotation here is simply discarded ...
10749: 	 * TODO: really?
10750:          */
10751:         child = child->next;
10752:     }
10753:     if (child != NULL) {
10754: 	xmlSchemaPContentErr(pctxt,
10755: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10756: 	    NULL, node, child, NULL,
10757: 	    "(annotation?)");
10758:     }
10759:     /*
10760:     * Apply additional constraints.
10761:     *
10762:     * Note that it is important to use the original @targetNamespace
10763:     * (or none at all), to rule out imports of schemas _with_ a
10764:     * @targetNamespace if the importing schema is a chameleon schema
10765:     * (with no @targetNamespace).
10766:     */
10767:     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10768:     if (namespaceName != NULL) {
10769: 	/*
10770: 	* 1.1 If the namespace [attribute] is present, then its �actual value�
10771: 	* must not match the �actual value� of the enclosing <schema>'s
10772: 	* targetNamespace [attribute].
10773: 	*/
10774: 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10775: 	    xmlSchemaPCustomErr(pctxt,
10776: 		XML_SCHEMAP_SRC_IMPORT_1_1,
10777: 		NULL, node,
10778: 		"The value of the attribute 'namespace' must not match "
10779: 		"the target namespace '%s' of the importing schema",
10780: 		thisTargetNamespace);
10781: 	    return (pctxt->err);
10782: 	}
10783:     } else {
10784: 	/*
10785: 	* 1.2 If the namespace [attribute] is not present, then the enclosing
10786: 	* <schema> must have a targetNamespace [attribute].
10787: 	*/
10788: 	if (thisTargetNamespace == NULL) {
10789: 	    xmlSchemaPCustomErr(pctxt,
10790: 		XML_SCHEMAP_SRC_IMPORT_1_2,
10791: 		NULL, node,
10792: 		"The attribute 'namespace' must be existent if "
10793: 		"the importing schema has no target namespace",
10794: 		NULL);
10795: 	    return (pctxt->err);
10796: 	}
10797:     }
10798:     /*
10799:     * Locate and acquire the schema document.
10800:     */
10801:     if (schemaLocation != NULL)
10802: 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10803: 	    schemaLocation, node);
10804:     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10805: 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10806: 	namespaceName, &bucket);
10807: 
10808:     if (ret != 0)
10809: 	return(ret);
10810: 
10811:     /*
10812:     * For <import>: "It is *not* an error for the application
10813:     * schema reference strategy to fail."
10814:     * So just don't parse if no schema document was found.
10815:     * Note that we will get no bucket if the schema could not be
10816:     * located or if there was no schemaLocation.
10817:     */
10818:     if ((bucket == NULL) && (schemaLocation != NULL)) {
10819: 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10820: 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10821: 	    node, NULL,
10822: 	    "Failed to locate a schema at location '%s'. "
10823: 	    "Skipping the import", schemaLocation, NULL, NULL);
10824:     }
10825: 
10826:     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10827: 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10828:     }
10829: 
10830:     return (ret);
10831: }
10832: 
10833: static int
10834: xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10835: 				     xmlSchemaPtr schema,
10836: 				     xmlNodePtr node,
10837: 				     xmlChar **schemaLocation,
10838: 				     int type)
10839: {
10840:     xmlAttrPtr attr;
10841: 
10842:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10843: 	(schemaLocation == NULL))
10844:         return (-1);
10845: 
10846:     *schemaLocation = NULL;
10847:     /*
10848:     * Check for illegal attributes.
10849:     * Applies for both <include> and <redefine>.
10850:     */
10851:     attr = node->properties;
10852:     while (attr != NULL) {
10853: 	if (attr->ns == NULL) {
10854: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10855: 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10856: 		xmlSchemaPIllegalAttrErr(pctxt,
10857: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10858: 	    }
10859: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10860: 	    xmlSchemaPIllegalAttrErr(pctxt,
10861: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10862: 	}
10863: 	attr = attr->next;
10864:     }
10865:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10866:     /*
10867:     * Preliminary step, extract the URI-Reference and make an URI
10868:     * from the base.
10869:     */
10870:     /*
10871:     * Attribute "schemaLocation" is mandatory.
10872:     */
10873:     attr = xmlSchemaGetPropNode(node, "schemaLocation");
10874:     if (attr != NULL) {
10875:         xmlChar *base = NULL;
10876:         xmlChar *uri = NULL;
10877: 
10878: 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10879: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10880: 	    (const xmlChar **) schemaLocation) != 0)
10881: 	    goto exit_error;
10882: 	base = xmlNodeGetBase(node->doc, node);
10883: 	if (base == NULL) {
10884: 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10885: 	} else {
10886: 	    uri = xmlBuildURI(*schemaLocation, base);
10887: 	    xmlFree(base);
10888: 	}
10889: 	if (uri == NULL) {
10890: 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10891: 		"could not build an URI from the schemaLocation")
10892: 	    goto exit_failure;
10893: 	}
10894: 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10895: 	xmlFree(uri);
10896:     } else {
10897: 	xmlSchemaPMissingAttrErr(pctxt,
10898: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
10899: 	    NULL, node, "schemaLocation", NULL);
10900: 	goto exit_error;
10901:     }
10902:     /*
10903:     * Report self-inclusion and self-redefinition.
10904:     */
10905:     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10906: 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10907: 	    xmlSchemaPCustomErr(pctxt,
10908: 		XML_SCHEMAP_SRC_REDEFINE,
10909: 		NULL, node,
10910: 		"The schema document '%s' cannot redefine itself.",
10911: 		*schemaLocation);
10912: 	} else {
10913: 	    xmlSchemaPCustomErr(pctxt,
10914: 		XML_SCHEMAP_SRC_INCLUDE,
10915: 		NULL, node,
10916: 		"The schema document '%s' cannot include itself.",
10917: 		*schemaLocation);
10918: 	}
10919: 	goto exit_error;
10920:     }
10921: 
10922:     return(0);
10923: exit_error:
10924:     return(pctxt->err);
10925: exit_failure:
10926:     return(-1);
10927: }
10928: 
10929: static int
10930: xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10931: 				xmlSchemaPtr schema,
10932: 				xmlNodePtr node,
10933: 				int type)
10934: {
10935:     xmlNodePtr child = NULL;
10936:     const xmlChar *schemaLocation = NULL;
10937:     int res = 0; /* hasRedefinitions = 0 */
10938:     int isChameleon = 0, wasChameleon = 0;
10939:     xmlSchemaBucketPtr bucket = NULL;
10940: 
10941:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10942:         return (-1);
10943: 
10944:     /*
10945:     * Parse attributes. Note that the returned schemaLocation will
10946:     * be already converted to an absolute URI.
10947:     */
10948:     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10949: 	node, (xmlChar **) (&schemaLocation), type);
10950:     if (res != 0)
10951: 	return(res);
10952:     /*
10953:     * Load and add the schema document.
10954:     */
10955:     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10956: 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10957:     if (res != 0)
10958: 	return(res);
10959:     /*
10960:     * If we get no schema bucket back, then this means that the schema
10961:     * document could not be located or was broken XML or was not
10962:     * a schema document.
10963:     */
10964:     if ((bucket == NULL) || (bucket->doc == NULL)) {
10965: 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10966: 	    /*
10967: 	    * WARNING for <include>:
10968: 	    * We will raise an error if the schema cannot be located
10969: 	    * for inclusions, since the that was the feedback from the
10970: 	    * schema people. I.e. the following spec piece will *not* be
10971: 	    * satisfied:
10972: 	    * SPEC src-include: "It is not an error for the �actual value� of the
10973: 	    * schemaLocation [attribute] to fail to resolve it all, in which
10974: 	    * case no corresponding inclusion is performed.
10975: 	    * So do we need a warning report here?"
10976: 	    */
10977: 	    res = XML_SCHEMAP_SRC_INCLUDE;
10978: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10979: 		node, NULL,
10980: 		"Failed to load the document '%s' for inclusion",
10981: 		schemaLocation, NULL);
10982: 	} else {
10983: 	    /*
10984: 	    * NOTE: This was changed to raise an error even if no redefinitions
10985: 	    * are specified.
10986: 	    *
10987: 	    * SPEC src-redefine (1)
10988: 	    * "If there are any element information items among the [children]
10989: 	    * other than <annotation> then the �actual value� of the
10990: 	    * schemaLocation [attribute] must successfully resolve."
10991: 	    * TODO: Ask the WG if a the location has always to resolve
10992: 	    * here as well!
10993: 	    */
10994: 	    res = XML_SCHEMAP_SRC_REDEFINE;
10995: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10996: 		node, NULL,
10997: 		"Failed to load the document '%s' for redefinition",
10998: 		schemaLocation, NULL);
10999: 	}
11000:     } else {
11001: 	/*
11002: 	* Check targetNamespace sanity before parsing the new schema.
11003: 	* TODO: Note that we won't check further content if the
11004: 	* targetNamespace was bad.
11005: 	*/
11006: 	if (bucket->origTargetNamespace != NULL) {
11007: 	    /*
11008: 	    * SPEC src-include (2.1)
11009: 	    * "SII has a targetNamespace [attribute], and its �actual
11010: 	    * value� is identical to the �actual value� of the targetNamespace
11011: 	    * [attribute] of SII� (which must have such an [attribute])."
11012: 	    */
11013: 	    if (pctxt->targetNamespace == NULL) {
11014: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
11015: 		    XML_SCHEMAP_SRC_INCLUDE,
11016: 		    node, NULL,
11017: 		    "The target namespace of the included/redefined schema "
11018: 		    "'%s' has to be absent, since the including/redefining "
11019: 		    "schema has no target namespace",
11020: 		    schemaLocation, NULL);
11021: 		goto exit_error;
11022: 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
11023: 		pctxt->targetNamespace)) {
11024: 		/* TODO: Change error function. */
11025: 		xmlSchemaPCustomErrExt(pctxt,
11026: 		    XML_SCHEMAP_SRC_INCLUDE,
11027: 		    NULL, node,
11028: 		    "The target namespace '%s' of the included/redefined "
11029: 		    "schema '%s' differs from '%s' of the "
11030: 		    "including/redefining schema",
11031: 		    bucket->origTargetNamespace, schemaLocation,
11032: 		    pctxt->targetNamespace);
11033: 		goto exit_error;
11034: 	    }
11035: 	} else if (pctxt->targetNamespace != NULL) {
11036: 	    /*
11037: 	    * Chameleons: the original target namespace will
11038: 	    * differ from the resulting namespace.
11039: 	    */
11040: 	    isChameleon = 1;
11041: 	    if (bucket->parsed &&
11042: 		bucket->origTargetNamespace != NULL) {
11043: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
11044: 		    XML_SCHEMAP_SRC_INCLUDE,
11045: 		    node, NULL,
11046: 		    "The target namespace of the included/redefined schema "
11047: 		    "'%s' has to be absent or the same as the "
11048: 		    "including/redefining schema's target namespace",
11049: 		    schemaLocation, NULL);
11050: 		goto exit_error;
11051: 	    }
11052: 	    bucket->targetNamespace = pctxt->targetNamespace;
11053: 	}
11054:     }
11055:     /*
11056:     * Parse the schema.
11057:     */
11058:     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11059: 	if (isChameleon) {
11060: 	    /* TODO: Get rid of this flag on the schema itself. */
11061: 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11062: 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11063: 	    } else
11064: 		wasChameleon = 1;
11065: 	}
11066: 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
11067: 	/* Restore chameleon flag. */
11068: 	if (isChameleon && (!wasChameleon))
11069: 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11070:     }
11071:     /*
11072:     * And now for the children...
11073:     */
11074:     child = node->children;
11075:     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11076: 	/*
11077: 	* Parse (simpleType | complexType | group | attributeGroup))*
11078: 	*/
11079: 	pctxt->redefined = bucket;
11080: 	/*
11081: 	* How to proceed if the redefined schema was not located?
11082: 	*/
11083: 	pctxt->isRedefine = 1;
11084: 	while (IS_SCHEMA(child, "annotation") ||
11085: 	    IS_SCHEMA(child, "simpleType") ||
11086: 	    IS_SCHEMA(child, "complexType") ||
11087: 	    IS_SCHEMA(child, "group") ||
11088: 	    IS_SCHEMA(child, "attributeGroup")) {
11089: 	    if (IS_SCHEMA(child, "annotation")) {
11090: 		/*
11091: 		* TODO: discard or not?
11092: 		*/
11093: 	    } else if (IS_SCHEMA(child, "simpleType")) {
11094: 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11095: 	    } else if (IS_SCHEMA(child, "complexType")) {
11096: 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
11097: 		/* hasRedefinitions = 1; */
11098: 	    } else if (IS_SCHEMA(child, "group")) {
11099: 		/* hasRedefinitions = 1; */
11100: 		xmlSchemaParseModelGroupDefinition(pctxt,
11101: 		    schema, child);
11102: 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
11103: 		/* hasRedefinitions = 1; */
11104: 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11105: 		    child);
11106: 	    }
11107: 	    child = child->next;
11108: 	}
11109: 	pctxt->redefined = NULL;
11110: 	pctxt->isRedefine = 0;
11111:     } else {
11112: 	if (IS_SCHEMA(child, "annotation")) {
11113: 	    /*
11114: 	    * TODO: discard or not?
11115: 	    */
11116: 	    child = child->next;
11117: 	}
11118:     }
11119:     if (child != NULL) {
11120: 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11121: 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11122: 	    xmlSchemaPContentErr(pctxt, res,
11123: 		NULL, node, child, NULL,
11124: 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
11125: 	} else {
11126: 	     xmlSchemaPContentErr(pctxt, res,
11127: 		NULL, node, child, NULL,
11128: 		"(annotation?)");
11129: 	}
11130:     }
11131:     return(res);
11132: 
11133: exit_error:
11134:     return(pctxt->err);
11135: }
11136: 
11137: static int
11138: xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11139:                        xmlNodePtr node)
11140: {
11141:     int res;
11142: #ifndef ENABLE_REDEFINE
11143:     TODO
11144:     return(0);
11145: #endif
11146:     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11147: 	XML_SCHEMA_SCHEMA_REDEFINE);
11148:     if (res != 0)
11149: 	return(res);
11150:     return(0);
11151: }
11152: 
11153: static int
11154: xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11155:                        xmlNodePtr node)
11156: {
11157:     int res;
11158: 
11159:     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11160: 	XML_SCHEMA_SCHEMA_INCLUDE);
11161:     if (res != 0)
11162: 	return(res);
11163:     return(0);
11164: }
11165: 
11166: /**
11167:  * xmlSchemaParseModelGroup:
11168:  * @ctxt:  a schema validation context
11169:  * @schema:  the schema being built
11170:  * @node:  a subtree containing XML Schema informations
11171:  * @type: the "compositor" type
11172:  * @particleNeeded: if a a model group with a particle
11173:  *
11174:  * parse a XML schema Sequence definition.
11175:  * Applies parts of:
11176:  *   Schema Representation Constraint:
11177:  *     Redefinition Constraints and Semantics (src-redefine)
11178:  *     (6.1), (6.1.1), (6.1.2)
11179:  *
11180:  *   Schema Component Constraint:
11181:  *     All Group Limited (cos-all-limited) (2)
11182:  *     TODO: Actually this should go to component-level checks,
11183:  *     but is done here due to performance. Move it to an other layer
11184:  *     is schema construction via an API is implemented.
11185:  *
11186:  * *WARNING* this interface is highly subject to change
11187:  *
11188:  * Returns -1 in case of error, 0 if the declaration is improper and
11189:  *         1 in case of success.
11190:  */
11191: static xmlSchemaTreeItemPtr
11192: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11193: 			 xmlNodePtr node, xmlSchemaTypeType type,
11194: 			 int withParticle)
11195: {
11196:     xmlSchemaModelGroupPtr item;
11197:     xmlSchemaParticlePtr particle = NULL;
11198:     xmlNodePtr child = NULL;
11199:     xmlAttrPtr attr;
11200:     int min = 1, max = 1, isElemRef, hasRefs = 0;
11201: 
11202:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11203:         return (NULL);
11204:     /*
11205:     * Create a model group with the given compositor.
11206:     */
11207:     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11208:     if (item == NULL)
11209: 	return (NULL);
11210: 
11211:     if (withParticle) {
11212: 	if (type == XML_SCHEMA_TYPE_ALL) {
11213: 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11214: 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11215: 	} else {
11216: 	    /* choice + sequence */
11217: 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11218: 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11219: 		"(xs:nonNegativeInteger | unbounded)");
11220: 	}
11221: 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11222: 	/*
11223: 	* Create a particle
11224: 	*/
11225: 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
11226: 	if (particle == NULL)
11227: 	    return (NULL);
11228: 	particle->children = (xmlSchemaTreeItemPtr) item;
11229: 	/*
11230: 	* Check for illegal attributes.
11231: 	*/
11232: 	attr = node->properties;
11233: 	while (attr != NULL) {
11234: 	    if (attr->ns == NULL) {
11235: 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11236: 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11237: 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11238: 		    xmlSchemaPIllegalAttrErr(ctxt,
11239: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11240: 		}
11241: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11242: 		xmlSchemaPIllegalAttrErr(ctxt,
11243: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11244: 	    }
11245: 	    attr = attr->next;
11246: 	}
11247:     } else {
11248: 	/*
11249: 	* Check for illegal attributes.
11250: 	*/
11251: 	attr = node->properties;
11252: 	while (attr != NULL) {
11253: 	    if (attr->ns == NULL) {
11254: 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11255: 		    xmlSchemaPIllegalAttrErr(ctxt,
11256: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11257: 		}
11258: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11259: 		xmlSchemaPIllegalAttrErr(ctxt,
11260: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11261: 	    }
11262: 	    attr = attr->next;
11263: 	}
11264:     }
11265: 
11266:     /*
11267:     * Extract and validate attributes.
11268:     */
11269:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11270:     /*
11271:     * And now for the children...
11272:     */
11273:     child = node->children;
11274:     if (IS_SCHEMA(child, "annotation")) {
11275:         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11276:         child = child->next;
11277:     }
11278:     if (type == XML_SCHEMA_TYPE_ALL) {
11279: 	xmlSchemaParticlePtr part, last = NULL;
11280: 
11281: 	while (IS_SCHEMA(child, "element")) {
11282: 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11283: 		schema, child, &isElemRef, 0);
11284: 	    /*
11285: 	    * SPEC cos-all-limited (2)
11286: 	    * "The {max occurs} of all the particles in the {particles}
11287: 	    * of the ('all') group must be 0 or 1.
11288: 	    */
11289: 	    if (part != NULL) {
11290: 		if (isElemRef)
11291: 		    hasRefs++;
11292: 		if (part->minOccurs > 1) {
11293: 		    xmlSchemaPCustomErr(ctxt,
11294: 			XML_SCHEMAP_COS_ALL_LIMITED,
11295: 			NULL, child,
11296: 			"Invalid value for minOccurs (must be 0 or 1)",
11297: 			NULL);
11298: 		    /* Reset to 1. */
11299: 		    part->minOccurs = 1;
11300: 		}
11301: 		if (part->maxOccurs > 1) {
11302: 		    xmlSchemaPCustomErr(ctxt,
11303: 			XML_SCHEMAP_COS_ALL_LIMITED,
11304: 			NULL, child,
11305: 			"Invalid value for maxOccurs (must be 0 or 1)",
11306: 			NULL);
11307: 		    /* Reset to 1. */
11308: 		    part->maxOccurs = 1;
11309: 		}
11310: 		if (last == NULL)
11311: 		    item->children = (xmlSchemaTreeItemPtr) part;
11312: 		else
11313: 		    last->next = (xmlSchemaTreeItemPtr) part;
11314: 		last = part;
11315: 	    }
11316: 	    child = child->next;
11317: 	}
11318: 	if (child != NULL) {
11319: 	    xmlSchemaPContentErr(ctxt,
11320: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11321: 		NULL, node, child, NULL,
11322: 		"(annotation?, (annotation?, element*)");
11323: 	}
11324:     } else {
11325: 	/* choice + sequence */
11326: 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
11327: 
11328: 	while ((IS_SCHEMA(child, "element")) ||
11329: 	    (IS_SCHEMA(child, "group")) ||
11330: 	    (IS_SCHEMA(child, "any")) ||
11331: 	    (IS_SCHEMA(child, "choice")) ||
11332: 	    (IS_SCHEMA(child, "sequence"))) {
11333: 
11334: 	    if (IS_SCHEMA(child, "element")) {
11335: 		part = (xmlSchemaTreeItemPtr)
11336: 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11337: 		if (part && isElemRef)
11338: 		    hasRefs++;
11339: 	    } else if (IS_SCHEMA(child, "group")) {
11340: 		part =
11341: 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11342: 		if (part != NULL)
11343: 		    hasRefs++;
11344: 		/*
11345: 		* Handle redefinitions.
11346: 		*/
11347: 		if (ctxt->isRedefine && ctxt->redef &&
11348: 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11349: 		    part && part->children)
11350: 		{
11351: 		    if ((xmlSchemaGetQNameRefName(part->children) ==
11352: 			    ctxt->redef->refName) &&
11353: 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
11354: 			    ctxt->redef->refTargetNs))
11355: 		    {
11356: 			/*
11357: 			* SPEC src-redefine:
11358: 			* (6.1) "If it has a <group> among its contents at
11359: 			* some level the �actual value� of whose ref
11360: 			* [attribute] is the same as the �actual value� of
11361: 			* its own name attribute plus target namespace, then
11362: 			* all of the following must be true:"
11363: 			* (6.1.1) "It must have exactly one such group."
11364: 			*/
11365: 			if (ctxt->redefCounter != 0) {
11366: 			    xmlChar *str = NULL;
11367: 
11368: 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
11369: 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11370: 				"The redefining model group definition "
11371: 				"'%s' must not contain more than one "
11372: 				"reference to the redefined definition",
11373: 				xmlSchemaFormatQName(&str,
11374: 				    ctxt->redef->refTargetNs,
11375: 				    ctxt->redef->refName),
11376: 				NULL);
11377: 			    FREE_AND_NULL(str)
11378: 			    part = NULL;
11379: 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11380: 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
11381: 			{
11382: 			    xmlChar *str = NULL;
11383: 			    /*
11384: 			    * SPEC src-redefine:
11385: 			    * (6.1.2) "The �actual value� of both that
11386: 			    * group's minOccurs and maxOccurs [attribute]
11387: 			    * must be 1 (or �absent�).
11388: 			    */
11389: 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
11390: 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11391: 				"The redefining model group definition "
11392: 				"'%s' must not contain a reference to the "
11393: 				"redefined definition with a "
11394: 				"maxOccurs/minOccurs other than 1",
11395: 				xmlSchemaFormatQName(&str,
11396: 				    ctxt->redef->refTargetNs,
11397: 				    ctxt->redef->refName),
11398: 				NULL);
11399: 			    FREE_AND_NULL(str)
11400: 			    part = NULL;
11401: 			}
11402: 			ctxt->redef->reference = WXS_BASIC_CAST part;
11403: 			ctxt->redefCounter++;
11404: 		    }
11405: 		}
11406: 	    } else if (IS_SCHEMA(child, "any")) {
11407: 		part = (xmlSchemaTreeItemPtr)
11408: 		    xmlSchemaParseAny(ctxt, schema, child);
11409: 	    } else if (IS_SCHEMA(child, "choice")) {
11410: 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
11411: 		    XML_SCHEMA_TYPE_CHOICE, 1);
11412: 	    } else if (IS_SCHEMA(child, "sequence")) {
11413: 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
11414: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
11415: 	    }
11416: 	    if (part != NULL) {
11417: 		if (last == NULL)
11418: 		    item->children = part;
11419: 		else
11420: 		    last->next = part;
11421: 		last = part;
11422: 	    }
11423: 	    child = child->next;
11424: 	}
11425: 	if (child != NULL) {
11426: 	    xmlSchemaPContentErr(ctxt,
11427: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11428: 		NULL, node, child, NULL,
11429: 		"(annotation?, (element | group | choice | sequence | any)*)");
11430: 	}
11431:     }
11432:     if ((max == 0) && (min == 0))
11433: 	return (NULL);
11434:     if (hasRefs) {
11435: 	/*
11436: 	* We need to resolve references.
11437: 	*/
11438: 	WXS_ADD_PENDING(ctxt, item);
11439:     }
11440:     if (withParticle)
11441: 	return ((xmlSchemaTreeItemPtr) particle);
11442:     else
11443: 	return ((xmlSchemaTreeItemPtr) item);
11444: }
11445: 
11446: /**
11447:  * xmlSchemaParseRestriction:
11448:  * @ctxt:  a schema validation context
11449:  * @schema:  the schema being built
11450:  * @node:  a subtree containing XML Schema informations
11451:  *
11452:  * parse a XML schema Restriction definition
11453:  * *WARNING* this interface is highly subject to change
11454:  *
11455:  * Returns the type definition or NULL in case of error
11456:  */
11457: static xmlSchemaTypePtr
11458: xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11459:                           xmlNodePtr node, xmlSchemaTypeType parentType)
11460: {
11461:     xmlSchemaTypePtr type;
11462:     xmlNodePtr child = NULL;
11463:     xmlAttrPtr attr;
11464: 
11465:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11466:         return (NULL);
11467:     /* Not a component, don't create it. */
11468:     type = ctxt->ctxtType;
11469:     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11470: 
11471:     /*
11472:     * Check for illegal attributes.
11473:     */
11474:     attr = node->properties;
11475:     while (attr != NULL) {
11476: 	if (attr->ns == NULL) {
11477: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11478: 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11479: 		xmlSchemaPIllegalAttrErr(ctxt,
11480: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11481: 	    }
11482: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11483: 	    xmlSchemaPIllegalAttrErr(ctxt,
11484: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11485: 	}
11486: 	attr = attr->next;
11487:     }
11488:     /*
11489:     * Extract and validate attributes.
11490:     */
11491:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11492:     /*
11493:     * Attribute
11494:     */
11495:     /*
11496:     * Extract the base type. The "base" attribute is mandatory if inside
11497:     * a complex type or if redefining.
11498:     *
11499:     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11500:     * among its [children]), the simple type definition which is
11501:     * the {content type} of the type definition �resolved� to by
11502:     * the �actual value� of the base [attribute]"
11503:     */
11504:     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11505: 	&(type->baseNs), &(type->base)) == 0)
11506:     {
11507: 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11508: 	    xmlSchemaPMissingAttrErr(ctxt,
11509: 		XML_SCHEMAP_S4S_ATTR_MISSING,
11510: 		NULL, node, "base", NULL);
11511: 	} else if ((ctxt->isRedefine) &&
11512: 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11513: 	{
11514: 	    if (type->base == NULL) {
11515: 		xmlSchemaPMissingAttrErr(ctxt,
11516: 		    XML_SCHEMAP_S4S_ATTR_MISSING,
11517: 		    NULL, node, "base", NULL);
11518: 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
11519: 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
11520: 	    {
11521: 		xmlChar *str1 = NULL, *str2 = NULL;
11522: 		/*
11523: 		* REDEFINE: SPEC src-redefine (5)
11524: 		* "Within the [children], each <simpleType> must have a
11525: 		* <restriction> among its [children] ... the �actual value� of
11526: 		* whose base [attribute] must be the same as the �actual value�
11527: 		* of its own name attribute plus target namespace;"
11528: 		*/
11529: 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11530: 		    NULL, node, "This is a redefinition, but the QName "
11531: 		    "value '%s' of the 'base' attribute does not match the "
11532: 		    "type's designation '%s'",
11533: 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11534: 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
11535: 			type->name), NULL);
11536: 		FREE_AND_NULL(str1);
11537: 		FREE_AND_NULL(str2);
11538: 		/* Avoid confusion and erase the values. */
11539: 		type->base = NULL;
11540: 		type->baseNs = NULL;
11541: 	    }
11542: 	}
11543:     }
11544:     /*
11545:     * And now for the children...
11546:     */
11547:     child = node->children;
11548:     if (IS_SCHEMA(child, "annotation")) {
11549: 	/*
11550: 	* Add the annotation to the simple type ancestor.
11551: 	*/
11552: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11553: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11554:         child = child->next;
11555:     }
11556:     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11557: 	/*
11558: 	* Corresponds to <simpleType><restriction><simpleType>.
11559: 	*/
11560: 	if (IS_SCHEMA(child, "simpleType")) {
11561: 	    if (type->base != NULL) {
11562: 		/*
11563: 		* src-restriction-base-or-simpleType
11564: 		* Either the base [attribute] or the simpleType [child] of the
11565: 		* <restriction> element must be present, but not both.
11566: 		*/
11567: 		xmlSchemaPContentErr(ctxt,
11568: 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11569: 		    NULL, node, child,
11570: 		    "The attribute 'base' and the <simpleType> child are "
11571: 		    "mutually exclusive", NULL);
11572: 	    } else {
11573: 		type->baseType = (xmlSchemaTypePtr)
11574: 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11575: 	    }
11576: 	    child = child->next;
11577: 	} else if (type->base == NULL) {
11578: 	    xmlSchemaPContentErr(ctxt,
11579: 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11580: 		NULL, node, child,
11581: 		"Either the attribute 'base' or a <simpleType> child "
11582: 		"must be present", NULL);
11583: 	}
11584:     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11585: 	/*
11586: 	* Corresponds to <complexType><complexContent><restriction>...
11587: 	* followed by:
11588: 	*
11589: 	* Model groups <all>, <choice> and <sequence>.
11590: 	*/
11591: 	if (IS_SCHEMA(child, "all")) {
11592: 	    type->subtypes = (xmlSchemaTypePtr)
11593: 		xmlSchemaParseModelGroup(ctxt, schema, child,
11594: 		    XML_SCHEMA_TYPE_ALL, 1);
11595: 	    child = child->next;
11596: 	} else if (IS_SCHEMA(child, "choice")) {
11597: 	    type->subtypes = (xmlSchemaTypePtr)
11598: 		xmlSchemaParseModelGroup(ctxt,
11599: 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11600: 	    child = child->next;
11601: 	} else if (IS_SCHEMA(child, "sequence")) {
11602: 	    type->subtypes = (xmlSchemaTypePtr)
11603: 		xmlSchemaParseModelGroup(ctxt, schema, child,
11604: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
11605: 	    child = child->next;
11606: 	/*
11607: 	* Model group reference <group>.
11608: 	*/
11609: 	} else if (IS_SCHEMA(child, "group")) {
11610: 	    type->subtypes = (xmlSchemaTypePtr)
11611: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11612: 	    /*
11613: 	    * Note that the reference will be resolved in
11614: 	    * xmlSchemaResolveTypeReferences();
11615: 	    */
11616: 	    child = child->next;
11617: 	}
11618:     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11619: 	/*
11620: 	* Corresponds to <complexType><simpleContent><restriction>...
11621: 	*
11622: 	* "1.1 the simple type definition corresponding to the <simpleType>
11623: 	* among the [children] of <restriction> if there is one;"
11624: 	*/
11625: 	if (IS_SCHEMA(child, "simpleType")) {
11626: 	    /*
11627: 	    * We will store the to-be-restricted simple type in
11628: 	    * type->contentTypeDef *temporarily*.
11629: 	    */
11630: 	    type->contentTypeDef = (xmlSchemaTypePtr)
11631: 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11632: 	    if ( type->contentTypeDef == NULL)
11633: 		return (NULL);
11634: 	    child = child->next;
11635: 	}
11636:     }
11637: 
11638:     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11639: 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11640: 	xmlSchemaFacetPtr facet, lastfacet = NULL;
11641: 	/*
11642: 	* Corresponds to <complexType><simpleContent><restriction>...
11643: 	* <simpleType><restriction>...
11644: 	*/
11645: 
11646: 	/*
11647: 	* Add the facets to the simple type ancestor.
11648: 	*/
11649: 	/*
11650: 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11651: 	* Simple Type Definition Schema Representation Constraint:
11652: 	* *Single Facet Value*
11653: 	*/
11654: 	while ((IS_SCHEMA(child, "minInclusive")) ||
11655: 	    (IS_SCHEMA(child, "minExclusive")) ||
11656: 	    (IS_SCHEMA(child, "maxInclusive")) ||
11657: 	    (IS_SCHEMA(child, "maxExclusive")) ||
11658: 	    (IS_SCHEMA(child, "totalDigits")) ||
11659: 	    (IS_SCHEMA(child, "fractionDigits")) ||
11660: 	    (IS_SCHEMA(child, "pattern")) ||
11661: 	    (IS_SCHEMA(child, "enumeration")) ||
11662: 	    (IS_SCHEMA(child, "whiteSpace")) ||
11663: 	    (IS_SCHEMA(child, "length")) ||
11664: 	    (IS_SCHEMA(child, "maxLength")) ||
11665: 	    (IS_SCHEMA(child, "minLength"))) {
11666: 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
11667: 	    if (facet != NULL) {
11668: 		if (lastfacet == NULL)
11669: 		    type->facets = facet;
11670: 		else
11671: 		    lastfacet->next = facet;
11672: 		lastfacet = facet;
11673: 		lastfacet->next = NULL;
11674: 	    }
11675: 	    child = child->next;
11676: 	}
11677: 	/*
11678: 	* Create links for derivation and validation.
11679: 	*/
11680: 	if (type->facets != NULL) {
11681: 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11682: 
11683: 	    facet = type->facets;
11684: 	    do {
11685: 		facetLink = (xmlSchemaFacetLinkPtr)
11686: 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
11687: 		if (facetLink == NULL) {
11688: 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11689: 		    xmlFree(facetLink);
11690: 		    return (NULL);
11691: 		}
11692: 		facetLink->facet = facet;
11693: 		facetLink->next = NULL;
11694: 		if (lastFacetLink == NULL)
11695: 		    type->facetSet = facetLink;
11696: 		else
11697: 		    lastFacetLink->next = facetLink;
11698: 		lastFacetLink = facetLink;
11699: 		facet = facet->next;
11700: 	    } while (facet != NULL);
11701: 	}
11702:     }
11703:     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11704: 	/*
11705: 	* Attribute uses/declarations.
11706: 	*/
11707: 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11708: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
11709: 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11710: 	    return(NULL);
11711: 	/*
11712: 	* Attribute wildcard.
11713: 	*/
11714: 	if (IS_SCHEMA(child, "anyAttribute")) {
11715: 	    type->attributeWildcard =
11716: 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
11717: 	    child = child->next;
11718: 	}
11719:     }
11720:     if (child != NULL) {
11721: 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11722: 	    xmlSchemaPContentErr(ctxt,
11723: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11724: 		NULL, node, child, NULL,
11725: 		"annotation?, (group | all | choice | sequence)?, "
11726: 		"((attribute | attributeGroup)*, anyAttribute?))");
11727: 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11728: 	     xmlSchemaPContentErr(ctxt,
11729: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11730: 		NULL, node, child, NULL,
11731: 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11732: 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11733: 		"length | minLength | maxLength | enumeration | whiteSpace | "
11734: 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11735: 	} else {
11736: 	    /* Simple type */
11737: 	    xmlSchemaPContentErr(ctxt,
11738: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11739: 		NULL, node, child, NULL,
11740: 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11741: 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11742: 		"length | minLength | maxLength | enumeration | whiteSpace | "
11743: 		"pattern)*))");
11744: 	}
11745:     }
11746:     return (NULL);
11747: }
11748: 
11749: /**
11750:  * xmlSchemaParseExtension:
11751:  * @ctxt:  a schema validation context
11752:  * @schema:  the schema being built
11753:  * @node:  a subtree containing XML Schema informations
11754:  *
11755:  * Parses an <extension>, which is found inside a
11756:  * <simpleContent> or <complexContent>.
11757:  * *WARNING* this interface is highly subject to change.
11758:  *
11759:  * TODO: Returns the type definition or NULL in case of error
11760:  */
11761: static xmlSchemaTypePtr
11762: xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11763:                         xmlNodePtr node, xmlSchemaTypeType parentType)
11764: {
11765:     xmlSchemaTypePtr type;
11766:     xmlNodePtr child = NULL;
11767:     xmlAttrPtr attr;
11768: 
11769:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11770:         return (NULL);
11771:     /* Not a component, don't create it. */
11772:     type = ctxt->ctxtType;
11773:     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11774: 
11775:     /*
11776:     * Check for illegal attributes.
11777:     */
11778:     attr = node->properties;
11779:     while (attr != NULL) {
11780: 	if (attr->ns == NULL) {
11781: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11782: 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11783: 		xmlSchemaPIllegalAttrErr(ctxt,
11784: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11785: 	    }
11786: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11787: 	    xmlSchemaPIllegalAttrErr(ctxt,
11788: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11789: 	}
11790: 	attr = attr->next;
11791:     }
11792: 
11793:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11794: 
11795:     /*
11796:     * Attribute "base" - mandatory.
11797:     */
11798:     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11799: 	"base", &(type->baseNs), &(type->base)) == 0) &&
11800: 	(type->base == NULL)) {
11801: 	xmlSchemaPMissingAttrErr(ctxt,
11802: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
11803: 	    NULL, node, "base", NULL);
11804:     }
11805:     /*
11806:     * And now for the children...
11807:     */
11808:     child = node->children;
11809:     if (IS_SCHEMA(child, "annotation")) {
11810: 	/*
11811: 	* Add the annotation to the type ancestor.
11812: 	*/
11813: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11814: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11815:         child = child->next;
11816:     }
11817:     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11818: 	/*
11819: 	* Corresponds to <complexType><complexContent><extension>... and:
11820: 	*
11821: 	* Model groups <all>, <choice>, <sequence> and <group>.
11822: 	*/
11823: 	if (IS_SCHEMA(child, "all")) {
11824: 	    type->subtypes = (xmlSchemaTypePtr)
11825: 		xmlSchemaParseModelGroup(ctxt, schema,
11826: 		    child, XML_SCHEMA_TYPE_ALL, 1);
11827: 	    child = child->next;
11828: 	} else if (IS_SCHEMA(child, "choice")) {
11829: 	    type->subtypes = (xmlSchemaTypePtr)
11830: 		xmlSchemaParseModelGroup(ctxt, schema,
11831: 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
11832: 	    child = child->next;
11833: 	} else if (IS_SCHEMA(child, "sequence")) {
11834: 	    type->subtypes = (xmlSchemaTypePtr)
11835: 		xmlSchemaParseModelGroup(ctxt, schema,
11836: 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11837: 	    child = child->next;
11838: 	} else if (IS_SCHEMA(child, "group")) {
11839: 	    type->subtypes = (xmlSchemaTypePtr)
11840: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11841: 	    /*
11842: 	    * Note that the reference will be resolved in
11843: 	    * xmlSchemaResolveTypeReferences();
11844: 	    */
11845: 	    child = child->next;
11846: 	}
11847:     }
11848:     if (child != NULL) {
11849: 	/*
11850: 	* Attribute uses/declarations.
11851: 	*/
11852: 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11853: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
11854: 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11855: 	    return(NULL);
11856: 	/*
11857: 	* Attribute wildcard.
11858: 	*/
11859: 	if (IS_SCHEMA(child, "anyAttribute")) {
11860: 	    ctxt->ctxtType->attributeWildcard =
11861: 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
11862: 	    child = child->next;
11863: 	}
11864:     }
11865:     if (child != NULL) {
11866: 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11867: 	    /* Complex content extension. */
11868: 	    xmlSchemaPContentErr(ctxt,
11869: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11870: 		NULL, node, child, NULL,
11871: 		"(annotation?, ((group | all | choice | sequence)?, "
11872: 		"((attribute | attributeGroup)*, anyAttribute?)))");
11873: 	} else {
11874: 	    /* Simple content extension. */
11875: 	    xmlSchemaPContentErr(ctxt,
11876: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11877: 		NULL, node, child, NULL,
11878: 		"(annotation?, ((attribute | attributeGroup)*, "
11879: 		"anyAttribute?))");
11880: 	}
11881:     }
11882:     return (NULL);
11883: }
11884: 
11885: /**
11886:  * xmlSchemaParseSimpleContent:
11887:  * @ctxt:  a schema validation context
11888:  * @schema:  the schema being built
11889:  * @node:  a subtree containing XML Schema informations
11890:  *
11891:  * parse a XML schema SimpleContent definition
11892:  * *WARNING* this interface is highly subject to change
11893:  *
11894:  * Returns the type definition or NULL in case of error
11895:  */
11896: static int
11897: xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11898:                             xmlSchemaPtr schema, xmlNodePtr node,
11899: 			    int *hasRestrictionOrExtension)
11900: {
11901:     xmlSchemaTypePtr type;
11902:     xmlNodePtr child = NULL;
11903:     xmlAttrPtr attr;
11904: 
11905:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11906: 	(hasRestrictionOrExtension == NULL))
11907:         return (-1);
11908:     *hasRestrictionOrExtension = 0;
11909:     /* Not a component, don't create it. */
11910:     type = ctxt->ctxtType;
11911:     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11912:     /*
11913:     * Check for illegal attributes.
11914:     */
11915:     attr = node->properties;
11916:     while (attr != NULL) {
11917: 	if (attr->ns == NULL) {
11918: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11919: 		xmlSchemaPIllegalAttrErr(ctxt,
11920: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11921: 	    }
11922: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11923: 	    xmlSchemaPIllegalAttrErr(ctxt,
11924: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11925: 	}
11926: 	attr = attr->next;
11927:     }
11928: 
11929:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11930: 
11931:     /*
11932:     * And now for the children...
11933:     */
11934:     child = node->children;
11935:     if (IS_SCHEMA(child, "annotation")) {
11936: 	/*
11937: 	* Add the annotation to the complex type ancestor.
11938: 	*/
11939: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11940: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11941:         child = child->next;
11942:     }
11943:     if (child == NULL) {
11944: 	xmlSchemaPContentErr(ctxt,
11945: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
11946: 	    NULL, node, NULL, NULL,
11947: 	    "(annotation?, (restriction | extension))");
11948:     }
11949:     if (child == NULL) {
11950: 	xmlSchemaPContentErr(ctxt,
11951: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
11952: 	    NULL, node, NULL, NULL,
11953: 	    "(annotation?, (restriction | extension))");
11954:     }
11955:     if (IS_SCHEMA(child, "restriction")) {
11956:         xmlSchemaParseRestriction(ctxt, schema, child,
11957: 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11958: 	(*hasRestrictionOrExtension) = 1;
11959:         child = child->next;
11960:     } else if (IS_SCHEMA(child, "extension")) {
11961:         xmlSchemaParseExtension(ctxt, schema, child,
11962: 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11963: 	(*hasRestrictionOrExtension) = 1;
11964:         child = child->next;
11965:     }
11966:     if (child != NULL) {
11967: 	xmlSchemaPContentErr(ctxt,
11968: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11969: 	    NULL, node, child, NULL,
11970: 	    "(annotation?, (restriction | extension))");
11971:     }
11972:     return (0);
11973: }
11974: 
11975: /**
11976:  * xmlSchemaParseComplexContent:
11977:  * @ctxt:  a schema validation context
11978:  * @schema:  the schema being built
11979:  * @node:  a subtree containing XML Schema informations
11980:  *
11981:  * parse a XML schema ComplexContent definition
11982:  * *WARNING* this interface is highly subject to change
11983:  *
11984:  * Returns the type definition or NULL in case of error
11985:  */
11986: static int
11987: xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11988:                              xmlSchemaPtr schema, xmlNodePtr node,
11989: 			     int *hasRestrictionOrExtension)
11990: {
11991:     xmlSchemaTypePtr type;
11992:     xmlNodePtr child = NULL;
11993:     xmlAttrPtr attr;
11994: 
11995:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11996: 	(hasRestrictionOrExtension == NULL))
11997:         return (-1);
11998:     *hasRestrictionOrExtension = 0;
11999:     /* Not a component, don't create it. */
12000:     type = ctxt->ctxtType;
12001:     /*
12002:     * Check for illegal attributes.
12003:     */
12004:     attr = node->properties;
12005:     while (attr != NULL) {
12006: 	if (attr->ns == NULL) {
12007: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
12008: 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
12009: 	    {
12010: 		xmlSchemaPIllegalAttrErr(ctxt,
12011: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12012: 	    }
12013: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12014: 	    xmlSchemaPIllegalAttrErr(ctxt,
12015: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12016: 	}
12017: 	attr = attr->next;
12018:     }
12019: 
12020:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12021: 
12022:     /*
12023:     * Set the 'mixed' on the complex type ancestor.
12024:     */
12025:     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12026: 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12027: 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
12028:     }
12029:     child = node->children;
12030:     if (IS_SCHEMA(child, "annotation")) {
12031: 	/*
12032: 	* Add the annotation to the complex type ancestor.
12033: 	*/
12034: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12035: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
12036:         child = child->next;
12037:     }
12038:     if (child == NULL) {
12039: 	xmlSchemaPContentErr(ctxt,
12040: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
12041: 	    NULL, node, NULL,
12042: 	    NULL, "(annotation?, (restriction | extension))");
12043:     }
12044:     if (child == NULL) {
12045: 	xmlSchemaPContentErr(ctxt,
12046: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
12047: 	    NULL, node, NULL,
12048: 	    NULL, "(annotation?, (restriction | extension))");
12049:     }
12050:     if (IS_SCHEMA(child, "restriction")) {
12051:         xmlSchemaParseRestriction(ctxt, schema, child,
12052: 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12053: 	(*hasRestrictionOrExtension) = 1;
12054:         child = child->next;
12055:     } else if (IS_SCHEMA(child, "extension")) {
12056:         xmlSchemaParseExtension(ctxt, schema, child,
12057: 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12058: 	(*hasRestrictionOrExtension) = 1;
12059:         child = child->next;
12060:     }
12061:     if (child != NULL) {
12062: 	xmlSchemaPContentErr(ctxt,
12063: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12064: 	    NULL, node, child,
12065: 	    NULL, "(annotation?, (restriction | extension))");
12066:     }
12067:     return (0);
12068: }
12069: 
12070: /**
12071:  * xmlSchemaParseComplexType:
12072:  * @ctxt:  a schema validation context
12073:  * @schema:  the schema being built
12074:  * @node:  a subtree containing XML Schema informations
12075:  *
12076:  * parse a XML schema Complex Type definition
12077:  * *WARNING* this interface is highly subject to change
12078:  *
12079:  * Returns the type definition or NULL in case of error
12080:  */
12081: static xmlSchemaTypePtr
12082: xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12083:                           xmlNodePtr node, int topLevel)
12084: {
12085:     xmlSchemaTypePtr type, ctxtType;
12086:     xmlNodePtr child = NULL;
12087:     const xmlChar *name = NULL;
12088:     xmlAttrPtr attr;
12089:     const xmlChar *attrValue;
12090: #ifdef ENABLE_NAMED_LOCALS
12091:     char buf[40];
12092: #endif
12093:     int final = 0, block = 0, hasRestrictionOrExtension = 0;
12094: 
12095: 
12096:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12097:         return (NULL);
12098: 
12099:     ctxtType = ctxt->ctxtType;
12100: 
12101:     if (topLevel) {
12102: 	attr = xmlSchemaGetPropNode(node, "name");
12103: 	if (attr == NULL) {
12104: 	    xmlSchemaPMissingAttrErr(ctxt,
12105: 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12106: 	    return (NULL);
12107: 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12108: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12109: 	    return (NULL);
12110: 	}
12111:     }
12112: 
12113:     if (topLevel == 0) {
12114: 	/*
12115: 	* Parse as local complex type definition.
12116: 	*/
12117: #ifdef ENABLE_NAMED_LOCALS
12118:         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12119: 	type = xmlSchemaAddType(ctxt, schema,
12120: 	    XML_SCHEMA_TYPE_COMPLEX,
12121: 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12122: 	    ctxt->targetNamespace, node, 0);
12123: #else
12124: 	type = xmlSchemaAddType(ctxt, schema,
12125: 	    XML_SCHEMA_TYPE_COMPLEX,
12126: 	    NULL, ctxt->targetNamespace, node, 0);
12127: #endif
12128: 	if (type == NULL)
12129: 	    return (NULL);
12130: 	name = type->name;
12131: 	type->node = node;
12132: 	type->type = XML_SCHEMA_TYPE_COMPLEX;
12133: 	/*
12134: 	* TODO: We need the target namespace.
12135: 	*/
12136:     } else {
12137: 	/*
12138: 	* Parse as global complex type definition.
12139: 	*/
12140: 	type = xmlSchemaAddType(ctxt, schema,
12141: 	    XML_SCHEMA_TYPE_COMPLEX,
12142: 	    name, ctxt->targetNamespace, node, 1);
12143: 	if (type == NULL)
12144: 	    return (NULL);
12145: 	type->node = node;
12146: 	type->type = XML_SCHEMA_TYPE_COMPLEX;
12147: 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12148:     }
12149:     type->targetNamespace = ctxt->targetNamespace;
12150:     /*
12151:     * Handle attributes.
12152:     */
12153:     attr = node->properties;
12154:     while (attr != NULL) {
12155: 	if (attr->ns == NULL) {
12156: 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12157: 		/*
12158: 		* Attribute "id".
12159: 		*/
12160: 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12161: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12162: 		/*
12163: 		* Attribute "mixed".
12164: 		*/
12165: 		if (xmlSchemaPGetBoolNodeValue(ctxt,
12166: 			NULL, (xmlNodePtr) attr))
12167: 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
12168: 	    } else if (topLevel) {
12169: 		/*
12170: 		* Attributes of global complex type definitions.
12171: 		*/
12172: 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12173: 		    /* Pass. */
12174: 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12175: 		    /*
12176: 		    * Attribute "abstract".
12177: 		    */
12178: 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
12179: 			    NULL, (xmlNodePtr) attr))
12180: 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12181: 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12182: 		    /*
12183: 		    * Attribute "final".
12184: 		    */
12185: 		    attrValue = xmlSchemaGetNodeContent(ctxt,
12186: 			(xmlNodePtr) attr);
12187: 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
12188: 			&(type->flags),
12189: 			-1,
12190: 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12191: 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12192: 			-1, -1, -1) != 0)
12193: 		    {
12194: 			xmlSchemaPSimpleTypeErr(ctxt,
12195: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12196: 			    NULL, (xmlNodePtr) attr, NULL,
12197: 			    "(#all | List of (extension | restriction))",
12198: 			    attrValue, NULL, NULL, NULL);
12199: 		    } else
12200: 			final = 1;
12201: 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12202: 		    /*
12203: 		    * Attribute "block".
12204: 		    */
12205: 		    attrValue = xmlSchemaGetNodeContent(ctxt,
12206: 			(xmlNodePtr) attr);
12207: 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12208: 			-1,
12209: 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12210: 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12211: 			-1, -1, -1) != 0) {
12212: 			xmlSchemaPSimpleTypeErr(ctxt,
12213: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12214: 			    NULL, (xmlNodePtr) attr, NULL,
12215: 			    "(#all | List of (extension | restriction)) ",
12216: 			    attrValue, NULL, NULL, NULL);
12217: 		    } else
12218: 			block = 1;
12219: 		} else {
12220: 			xmlSchemaPIllegalAttrErr(ctxt,
12221: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12222: 		}
12223: 	    } else {
12224: 		xmlSchemaPIllegalAttrErr(ctxt,
12225: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12226: 	    }
12227: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12228: 	    xmlSchemaPIllegalAttrErr(ctxt,
12229: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12230: 	}
12231: 	attr = attr->next;
12232:     }
12233:     if (! block) {
12234: 	/*
12235: 	* Apply default "block" values.
12236: 	*/
12237: 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12238: 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12239: 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12240: 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12241:     }
12242:     if (! final) {
12243: 	/*
12244: 	* Apply default "block" values.
12245: 	*/
12246: 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12247: 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12248: 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12249: 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12250:     }
12251:     /*
12252:     * And now for the children...
12253:     */
12254:     child = node->children;
12255:     if (IS_SCHEMA(child, "annotation")) {
12256:         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12257:         child = child->next;
12258:     }
12259:     ctxt->ctxtType = type;
12260:     if (IS_SCHEMA(child, "simpleContent")) {
12261: 	/*
12262: 	* <complexType><simpleContent>...
12263: 	* 3.4.3 : 2.2
12264: 	* Specifying mixed='true' when the <simpleContent>
12265: 	* alternative is chosen has no effect
12266: 	*/
12267: 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12268: 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12269:         xmlSchemaParseSimpleContent(ctxt, schema, child,
12270: 	    &hasRestrictionOrExtension);
12271:         child = child->next;
12272:     } else if (IS_SCHEMA(child, "complexContent")) {
12273: 	/*
12274: 	* <complexType><complexContent>...
12275: 	*/
12276: 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12277:         xmlSchemaParseComplexContent(ctxt, schema, child,
12278: 	    &hasRestrictionOrExtension);
12279:         child = child->next;
12280:     } else {
12281: 	/*
12282: 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
12283: 	*
12284: 	* SPEC
12285: 	* "...the third alternative (neither <simpleContent> nor
12286: 	* <complexContent>) is chosen. This case is understood as shorthand
12287: 	* for complex content restricting the �ur-type definition�, and the
12288: 	* details of the mappings should be modified as necessary.
12289: 	*/
12290: 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12291: 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12292: 	/*
12293: 	* Parse model groups.
12294: 	*/
12295:         if (IS_SCHEMA(child, "all")) {
12296:             type->subtypes = (xmlSchemaTypePtr)
12297: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12298: 		    XML_SCHEMA_TYPE_ALL, 1);
12299:             child = child->next;
12300:         } else if (IS_SCHEMA(child, "choice")) {
12301:             type->subtypes = (xmlSchemaTypePtr)
12302: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12303: 		    XML_SCHEMA_TYPE_CHOICE, 1);
12304:             child = child->next;
12305:         } else if (IS_SCHEMA(child, "sequence")) {
12306:             type->subtypes = (xmlSchemaTypePtr)
12307: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12308: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
12309:             child = child->next;
12310:         } else if (IS_SCHEMA(child, "group")) {
12311:             type->subtypes = (xmlSchemaTypePtr)
12312: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12313: 	    /*
12314: 	    * Note that the reference will be resolved in
12315: 	    * xmlSchemaResolveTypeReferences();
12316: 	    */
12317:             child = child->next;
12318:         }
12319: 	/*
12320: 	* Parse attribute decls/refs.
12321: 	*/
12322:         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12323: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
12324: 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12325: 	    return(NULL);
12326: 	/*
12327: 	* Parse attribute wildcard.
12328: 	*/
12329: 	if (IS_SCHEMA(child, "anyAttribute")) {
12330: 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12331: 	    child = child->next;
12332: 	}
12333:     }
12334:     if (child != NULL) {
12335: 	xmlSchemaPContentErr(ctxt,
12336: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12337: 	    NULL, node, child,
12338: 	    NULL, "(annotation?, (simpleContent | complexContent | "
12339: 	    "((group | all | choice | sequence)?, ((attribute | "
12340: 	    "attributeGroup)*, anyAttribute?))))");
12341:     }
12342:     /*
12343:     * REDEFINE: SPEC src-redefine (5)
12344:     */
12345:     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12346: 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12347: 	    NULL, node, "This is a redefinition, thus the "
12348: 	    "<complexType> must have a <restriction> or <extension> "
12349: 	    "grand-child", NULL);
12350:     }
12351:     ctxt->ctxtType = ctxtType;
12352:     return (type);
12353: }
12354: 
12355: /************************************************************************
12356:  * 									*
12357:  * 			Validating using Schemas			*
12358:  * 									*
12359:  ************************************************************************/
12360: 
12361: /************************************************************************
12362:  * 									*
12363:  * 			Reading/Writing Schemas				*
12364:  * 									*
12365:  ************************************************************************/
12366: 
12367: #if 0 /* Will be enabled if it is clear what options are needed. */
12368: /**
12369:  * xmlSchemaParserCtxtSetOptions:
12370:  * @ctxt:	a schema parser context
12371:  * @options: a combination of xmlSchemaParserOption
12372:  *
12373:  * Sets the options to be used during the parse.
12374:  *
12375:  * Returns 0 in case of success, -1 in case of an
12376:  * API error.
12377:  */
12378: static int
12379: xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12380: 			      int options)
12381: 
12382: {
12383:     int i;
12384: 
12385:     if (ctxt == NULL)
12386: 	return (-1);
12387:     /*
12388:     * WARNING: Change the start value if adding to the
12389:     * xmlSchemaParseOption.
12390:     */
12391:     for (i = 1; i < (int) sizeof(int) * 8; i++) {
12392:         if (options & 1<<i) {
12393: 	    return (-1);
12394:         }
12395:     }
12396:     ctxt->options = options;
12397:     return (0);
12398: }
12399: 
12400: /**
12401:  * xmlSchemaValidCtxtGetOptions:
12402:  * @ctxt: a schema parser context
12403:  *
12404:  * Returns the option combination of the parser context.
12405:  */
12406: static int
12407: xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12408: 
12409: {
12410:     if (ctxt == NULL)
12411: 	return (-1);
12412:     else
12413: 	return (ctxt->options);
12414: }
12415: #endif
12416: 
12417: /**
12418:  * xmlSchemaNewParserCtxt:
12419:  * @URL:  the location of the schema
12420:  *
12421:  * Create an XML Schemas parse context for that file/resource expected
12422:  * to contain an XML Schemas file.
12423:  *
12424:  * Returns the parser context or NULL in case of error
12425:  */
12426: xmlSchemaParserCtxtPtr
12427: xmlSchemaNewParserCtxt(const char *URL)
12428: {
12429:     xmlSchemaParserCtxtPtr ret;
12430: 
12431:     if (URL == NULL)
12432:         return (NULL);
12433: 
12434:     ret = xmlSchemaParserCtxtCreate();
12435:     if (ret == NULL)
12436: 	return(NULL);
12437:     ret->dict = xmlDictCreate();
12438:     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12439:     return (ret);
12440: }
12441: 
12442: /**
12443:  * xmlSchemaNewMemParserCtxt:
12444:  * @buffer:  a pointer to a char array containing the schemas
12445:  * @size:  the size of the array
12446:  *
12447:  * Create an XML Schemas parse context for that memory buffer expected
12448:  * to contain an XML Schemas file.
12449:  *
12450:  * Returns the parser context or NULL in case of error
12451:  */
12452: xmlSchemaParserCtxtPtr
12453: xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12454: {
12455:     xmlSchemaParserCtxtPtr ret;
12456: 
12457:     if ((buffer == NULL) || (size <= 0))
12458:         return (NULL);
12459:     ret = xmlSchemaParserCtxtCreate();
12460:     if (ret == NULL)
12461: 	return(NULL);
12462:     ret->buffer = buffer;
12463:     ret->size = size;
12464:     ret->dict = xmlDictCreate();
12465:     return (ret);
12466: }
12467: 
12468: /**
12469:  * xmlSchemaNewDocParserCtxt:
12470:  * @doc:  a preparsed document tree
12471:  *
12472:  * Create an XML Schemas parse context for that document.
12473:  * NB. The document may be modified during the parsing process.
12474:  *
12475:  * Returns the parser context or NULL in case of error
12476:  */
12477: xmlSchemaParserCtxtPtr
12478: xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12479: {
12480:     xmlSchemaParserCtxtPtr ret;
12481: 
12482:     if (doc == NULL)
12483:       return (NULL);
12484:     ret = xmlSchemaParserCtxtCreate();
12485:     if (ret == NULL)
12486: 	return(NULL);
12487:     ret->doc = doc;
12488:     ret->dict = xmlDictCreate();
12489:     /* The application has responsibility for the document */
12490:     ret->preserve = 1;
12491: 
12492:     return (ret);
12493: }
12494: 
12495: /**
12496:  * xmlSchemaFreeParserCtxt:
12497:  * @ctxt:  the schema parser context
12498:  *
12499:  * Free the resources associated to the schema parser context
12500:  */
12501: void
12502: xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12503: {
12504:     if (ctxt == NULL)
12505:         return;
12506:     if (ctxt->doc != NULL && !ctxt->preserve)
12507:         xmlFreeDoc(ctxt->doc);
12508:     if (ctxt->vctxt != NULL) {
12509: 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
12510:     }
12511:     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12512: 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
12513: 	ctxt->constructor = NULL;
12514: 	ctxt->ownsConstructor = 0;
12515:     }
12516:     if (ctxt->attrProhibs != NULL)
12517: 	xmlSchemaItemListFree(ctxt->attrProhibs);
12518:     xmlDictFree(ctxt->dict);
12519:     xmlFree(ctxt);
12520: }
12521: 
12522: /************************************************************************
12523:  *									*
12524:  *			Building the content models			*
12525:  *									*
12526:  ************************************************************************/
12527: 
12528: /**
12529:  * xmlSchemaBuildContentModelForSubstGroup:
12530:  *
12531:  * Returns 1 if nillable, 0 otherwise
12532:  */
12533: static int
12534: xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12535: 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12536: {
12537:     xmlAutomataStatePtr start, tmp;
12538:     xmlSchemaElementPtr elemDecl, member;
12539:     xmlSchemaSubstGroupPtr substGroup;
12540:     int i;
12541:     int ret = 0;
12542: 
12543:     elemDecl = (xmlSchemaElementPtr) particle->children;
12544:     /*
12545:     * Wrap the substitution group with a CHOICE.
12546:     */
12547:     start = pctxt->state;
12548:     if (end == NULL)
12549: 	end = xmlAutomataNewState(pctxt->am);
12550:     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12551:     if (substGroup == NULL) {
12552: 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12553: 	    XML_SCHEMAP_INTERNAL,
12554: 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12555: 	    "declaration is marked having a subst. group but none "
12556: 	    "available.\n", elemDecl->name, NULL);
12557: 	return(0);
12558:     }
12559:     if (counter >= 0) {
12560: 	/*
12561: 	* NOTE that we put the declaration in, even if it's abstract.
12562: 	* However, an error will be raised during *validation* if an element
12563: 	* information item shall be validated against an abstract element
12564: 	* declaration.
12565: 	*/
12566: 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12567:         xmlAutomataNewTransition2(pctxt->am, tmp, end,
12568: 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
12569: 	/*
12570: 	* Add subst. group members.
12571: 	*/
12572: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12573: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12574:             xmlAutomataNewTransition2(pctxt->am, tmp, end,
12575: 		               member->name, member->targetNamespace, member);
12576: 	}
12577:     } else if (particle->maxOccurs == 1) {
12578: 	/*
12579: 	* NOTE that we put the declaration in, even if it's abstract,
12580: 	*/
12581: 	xmlAutomataNewEpsilon(pctxt->am,
12582: 	    xmlAutomataNewTransition2(pctxt->am,
12583: 	    start, NULL,
12584: 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12585: 	/*
12586: 	* Add subst. group members.
12587: 	*/
12588: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12589: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12590: 	    /*
12591: 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12592: 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
12593: 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12594: 	    *  section in xmlSchemaBuildAContentModel() ).
12595: 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12596: 	    *  intended for the above "counter" section originally. I.e.,
12597: 	    *  check xs:all with subst-groups.
12598: 	    *
12599: 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12600: 	    *	               member->name, member->targetNamespace,
12601: 	    *		       1, 1, member);
12602: 	    */
12603: 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12604: 		member->name, member->targetNamespace, member);
12605: 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12606: 	}
12607:     } else {
12608: 	xmlAutomataStatePtr hop;
12609: 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12610: 	    UNBOUNDED : particle->maxOccurs - 1;
12611: 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12612: 
12613: 	counter =
12614: 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
12615: 	    maxOccurs);
12616: 	hop = xmlAutomataNewState(pctxt->am);
12617: 
12618: 	xmlAutomataNewEpsilon(pctxt->am,
12619: 	    xmlAutomataNewTransition2(pctxt->am,
12620: 	    start, NULL,
12621: 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
12622: 	    hop);
12623: 	/*
12624: 	 * Add subst. group members.
12625: 	 */
12626: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12627: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12628: 	    xmlAutomataNewEpsilon(pctxt->am,
12629: 		xmlAutomataNewTransition2(pctxt->am,
12630: 		start, NULL,
12631: 		member->name, member->targetNamespace, member),
12632: 		hop);
12633: 	}
12634: 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12635: 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12636:     }
12637:     if (particle->minOccurs == 0) {
12638: 	xmlAutomataNewEpsilon(pctxt->am, start, end);
12639:         ret = 1;
12640:     }
12641:     pctxt->state = end;
12642:     return(ret);
12643: }
12644: 
12645: /**
12646:  * xmlSchemaBuildContentModelForElement:
12647:  *
12648:  * Returns 1 if nillable, 0 otherwise
12649:  */
12650: static int
12651: xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12652: 				     xmlSchemaParticlePtr particle)
12653: {
12654:     int ret = 0;
12655: 
12656:     if (((xmlSchemaElementPtr) particle->children)->flags &
12657: 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12658: 	/*
12659: 	* Substitution groups.
12660: 	*/
12661: 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12662:     } else {
12663: 	xmlSchemaElementPtr elemDecl;
12664: 	xmlAutomataStatePtr start;
12665: 
12666: 	elemDecl = (xmlSchemaElementPtr) particle->children;
12667: 
12668: 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12669: 	    return(0);
12670: 	if (particle->maxOccurs == 1) {
12671: 	    start = ctxt->state;
12672: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12673: 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12674: 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
12675: 	           (particle->minOccurs < 2)) {
12676: 	    /* Special case. */
12677: 	    start = ctxt->state;
12678: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12679: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12680: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12681: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12682: 	} else {
12683: 	    int counter;
12684: 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12685: 			    UNBOUNDED : particle->maxOccurs - 1;
12686: 	    int minOccurs = particle->minOccurs < 1 ?
12687: 			    0 : particle->minOccurs - 1;
12688: 
12689: 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12690: 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12691: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12692: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12693: 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12694: 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12695: 		NULL, counter);
12696: 	}
12697: 	if (particle->minOccurs == 0) {
12698: 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12699:             ret = 1;
12700:         }
12701:     }
12702:     return(ret);
12703: }
12704: 
12705: /**
12706:  * xmlSchemaBuildAContentModel:
12707:  * @ctxt:  the schema parser context
12708:  * @particle:  the particle component
12709:  * @name:  the complex type's name whose content is being built
12710:  *
12711:  * Create the automaton for the {content type} of a complex type.
12712:  *
12713:  * Returns 1 if the content is nillable, 0 otherwise
12714:  */
12715: static int
12716: xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12717: 			    xmlSchemaParticlePtr particle)
12718: {
12719:     int ret = 0, tmp2;
12720: 
12721:     if (particle == NULL) {
12722: 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12723: 	return(1);
12724:     }
12725:     if (particle->children == NULL) {
12726: 	/*
12727: 	* Just return in this case. A missing "term" of the particle
12728: 	* might arise due to an invalid "term" component.
12729: 	*/
12730: 	return(1);
12731:     }
12732: 
12733:     switch (particle->children->type) {
12734: 	case XML_SCHEMA_TYPE_ANY: {
12735: 	    xmlAutomataStatePtr start, end;
12736: 	    xmlSchemaWildcardPtr wild;
12737: 	    xmlSchemaWildcardNsPtr ns;
12738: 
12739: 	    wild = (xmlSchemaWildcardPtr) particle->children;
12740: 
12741: 	    start = pctxt->state;
12742: 	    end = xmlAutomataNewState(pctxt->am);
12743: 
12744: 	    if (particle->maxOccurs == 1) {
12745: 		if (wild->any == 1) {
12746: 		    /*
12747: 		    * We need to add both transitions:
12748: 		    *
12749: 		    * 1. the {"*", "*"} for elements in a namespace.
12750: 		    */
12751: 		    pctxt->state =
12752: 			xmlAutomataNewTransition2(pctxt->am,
12753: 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12754: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12755: 		    /*
12756: 		    * 2. the {"*"} for elements in no namespace.
12757: 		    */
12758: 		    pctxt->state =
12759: 			xmlAutomataNewTransition2(pctxt->am,
12760: 			start, NULL, BAD_CAST "*", NULL, wild);
12761: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12762: 
12763: 		} else if (wild->nsSet != NULL) {
12764: 		    ns = wild->nsSet;
12765: 		    do {
12766: 			pctxt->state = start;
12767: 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12768: 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12769: 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12770: 			ns = ns->next;
12771: 		    } while (ns != NULL);
12772: 
12773: 		} else if (wild->negNsSet != NULL) {
12774: 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12775: 			start, end, BAD_CAST "*", wild->negNsSet->value,
12776: 			wild);
12777: 		}
12778: 	    } else {
12779: 		int counter;
12780: 		xmlAutomataStatePtr hop;
12781: 		int maxOccurs =
12782: 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12783:                                            particle->maxOccurs - 1;
12784: 		int minOccurs =
12785: 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12786: 
12787: 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12788: 		hop = xmlAutomataNewState(pctxt->am);
12789: 		if (wild->any == 1) {
12790: 		    pctxt->state =
12791: 			xmlAutomataNewTransition2(pctxt->am,
12792: 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12793: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12794: 		    pctxt->state =
12795: 			xmlAutomataNewTransition2(pctxt->am,
12796: 			start, NULL, BAD_CAST "*", NULL, wild);
12797: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12798: 		} else if (wild->nsSet != NULL) {
12799: 		    ns = wild->nsSet;
12800: 		    do {
12801: 			pctxt->state =
12802: 			    xmlAutomataNewTransition2(pctxt->am,
12803: 				start, NULL, BAD_CAST "*", ns->value, wild);
12804: 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12805: 			ns = ns->next;
12806: 		    } while (ns != NULL);
12807: 
12808: 		} else if (wild->negNsSet != NULL) {
12809: 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12810: 			start, hop, BAD_CAST "*", wild->negNsSet->value,
12811: 			wild);
12812: 		}
12813: 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12814: 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12815: 	    }
12816: 	    if (particle->minOccurs == 0) {
12817: 		xmlAutomataNewEpsilon(pctxt->am, start, end);
12818:                 ret = 1;
12819: 	    }
12820: 	    pctxt->state = end;
12821:             break;
12822: 	}
12823:         case XML_SCHEMA_TYPE_ELEMENT:
12824: 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12825: 	    break;
12826:         case XML_SCHEMA_TYPE_SEQUENCE:{
12827:             xmlSchemaTreeItemPtr sub;
12828: 
12829:             ret = 1;
12830:             /*
12831:              * If max and min occurances are default (1) then
12832:              * simply iterate over the particles of the <sequence>.
12833:              */
12834:             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12835:                 sub = particle->children->children;
12836: 
12837:                 while (sub != NULL) {
12838:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12839:                                         (xmlSchemaParticlePtr) sub);
12840:                     if (tmp2 != 1) ret = 0;
12841:                     sub = sub->next;
12842:                 }
12843:             } else {
12844:                 xmlAutomataStatePtr oldstate = pctxt->state;
12845: 
12846:                 if (particle->maxOccurs >= UNBOUNDED) {
12847:                     if (particle->minOccurs > 1) {
12848:                         xmlAutomataStatePtr tmp;
12849:                         int counter;
12850: 
12851:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12852:                             oldstate, NULL);
12853:                         oldstate = pctxt->state;
12854: 
12855:                         counter = xmlAutomataNewCounter(pctxt->am,
12856:                             particle->minOccurs - 1, UNBOUNDED);
12857: 
12858:                         sub = particle->children->children;
12859:                         while (sub != NULL) {
12860:                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
12861:                                             (xmlSchemaParticlePtr) sub);
12862:                             if (tmp2 != 1) ret = 0;
12863:                             sub = sub->next;
12864:                         }
12865:                         tmp = pctxt->state;
12866:                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
12867:                                                    oldstate, counter);
12868:                         pctxt->state =
12869:                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
12870:                                                        NULL, counter);
12871:                         if (ret == 1)
12872:                             xmlAutomataNewEpsilon(pctxt->am,
12873:                                                 oldstate, pctxt->state);
12874: 
12875:                     } else {
12876:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12877:                             oldstate, NULL);
12878:                         oldstate = pctxt->state;
12879: 
12880:                         sub = particle->children->children;
12881:                         while (sub != NULL) {
12882:                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
12883:                                         (xmlSchemaParticlePtr) sub);
12884:                             if (tmp2 != 1) ret = 0;
12885:                             sub = sub->next;
12886:                         }
12887:                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12888:                                               oldstate);
12889:                         /*
12890:                          * epsilon needed to block previous trans from
12891:                          * being allowed to enter back from another
12892:                          * construct
12893:                          */
12894:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12895:                                             pctxt->state, NULL);
12896:                         if (particle->minOccurs == 0) {
12897:                             xmlAutomataNewEpsilon(pctxt->am,
12898:                                 oldstate, pctxt->state);
12899:                             ret = 1;
12900:                         }
12901:                     }
12902:                 } else if ((particle->maxOccurs > 1)
12903:                            || (particle->minOccurs > 1)) {
12904:                     xmlAutomataStatePtr tmp;
12905:                     int counter;
12906: 
12907:                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12908:                         oldstate, NULL);
12909:                     oldstate = pctxt->state;
12910: 
12911:                     counter = xmlAutomataNewCounter(pctxt->am,
12912:                         particle->minOccurs - 1,
12913:                         particle->maxOccurs - 1);
12914: 
12915:                     sub = particle->children->children;
12916:                     while (sub != NULL) {
12917:                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
12918:                                         (xmlSchemaParticlePtr) sub);
12919:                         if (tmp2 != 1) ret = 0;
12920:                         sub = sub->next;
12921:                     }
12922:                     tmp = pctxt->state;
12923:                     xmlAutomataNewCountedTrans(pctxt->am,
12924:                         tmp, oldstate, counter);
12925:                     pctxt->state =
12926:                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12927:                                                    counter);
12928:                     if ((particle->minOccurs == 0) || (ret == 1)) {
12929:                         xmlAutomataNewEpsilon(pctxt->am,
12930:                                             oldstate, pctxt->state);
12931:                         ret = 1;
12932:                     }
12933:                 } else {
12934:                     sub = particle->children->children;
12935:                     while (sub != NULL) {
12936:                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
12937:                                         (xmlSchemaParticlePtr) sub);
12938:                         if (tmp2 != 1) ret = 0;
12939:                         sub = sub->next;
12940:                     }
12941:                     if (particle->minOccurs == 0) {
12942:                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
12943:                                               pctxt->state);
12944:                         ret = 1;
12945:                     }
12946:                 }
12947:             }
12948:             break;
12949:         }
12950:         case XML_SCHEMA_TYPE_CHOICE:{
12951:             xmlSchemaTreeItemPtr sub;
12952:             xmlAutomataStatePtr start, end;
12953: 
12954:             ret = 0;
12955:             start = pctxt->state;
12956:             end = xmlAutomataNewState(pctxt->am);
12957: 
12958:             /*
12959:              * iterate over the subtypes and remerge the end with an
12960:              * epsilon transition
12961:              */
12962:             if (particle->maxOccurs == 1) {
12963:                 sub = particle->children->children;
12964:                 while (sub != NULL) {
12965:                     pctxt->state = start;
12966:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12967:                                         (xmlSchemaParticlePtr) sub);
12968:                     if (tmp2 == 1) ret = 1;
12969:                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12970:                     sub = sub->next;
12971:                 }
12972:             } else {
12973:                 int counter;
12974:                 xmlAutomataStatePtr hop, base;
12975:                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12976:                     UNBOUNDED : particle->maxOccurs - 1;
12977:                 int minOccurs =
12978:                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12979: 
12980:                 /*
12981:                  * use a counter to keep track of the number of transtions
12982:                  * which went through the choice.
12983:                  */
12984:                 counter =
12985:                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12986:                 hop = xmlAutomataNewState(pctxt->am);
12987:                 base = xmlAutomataNewState(pctxt->am);
12988: 
12989:                 sub = particle->children->children;
12990:                 while (sub != NULL) {
12991:                     pctxt->state = base;
12992:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12993:                                         (xmlSchemaParticlePtr) sub);
12994:                     if (tmp2 == 1) ret = 1;
12995:                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12996:                     sub = sub->next;
12997:                 }
12998:                 xmlAutomataNewEpsilon(pctxt->am, start, base);
12999:                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13000:                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13001:                 if (ret == 1)
13002:                     xmlAutomataNewEpsilon(pctxt->am, base, end);
13003:             }
13004:             if (particle->minOccurs == 0) {
13005:                 xmlAutomataNewEpsilon(pctxt->am, start, end);
13006:                 ret = 1;
13007:             }
13008:             pctxt->state = end;
13009:             break;
13010:         }
13011:         case XML_SCHEMA_TYPE_ALL:{
13012:             xmlAutomataStatePtr start, tmp;
13013:             xmlSchemaParticlePtr sub;
13014:             xmlSchemaElementPtr elemDecl;
13015: 
13016:             ret = 1;
13017: 
13018:             sub = (xmlSchemaParticlePtr) particle->children->children;
13019:             if (sub == NULL)
13020:                 break;
13021: 
13022:             ret = 0;
13023: 
13024:             start = pctxt->state;
13025:             tmp = xmlAutomataNewState(pctxt->am);
13026:             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13027:             pctxt->state = tmp;
13028:             while (sub != NULL) {
13029:                 pctxt->state = tmp;
13030: 
13031:                 elemDecl = (xmlSchemaElementPtr) sub->children;
13032:                 if (elemDecl == NULL) {
13033:                     PERROR_INT("xmlSchemaBuildAContentModel",
13034:                         "<element> particle has no term");
13035:                     return(ret);
13036:                 };
13037:                 /*
13038:                 * NOTE: The {max occurs} of all the particles in the
13039:                 * {particles} of the group must be 0 or 1; this is
13040:                 * already ensured during the parse of the content of
13041:                 * <all>.
13042:                 */
13043:                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13044:                     int counter;
13045: 
13046:                     /*
13047:                      * This is an abstract group, we need to share
13048:                      * the same counter for all the element transitions
13049:                      * derived from the group
13050:                      */
13051:                     counter = xmlAutomataNewCounter(pctxt->am,
13052:                                        sub->minOccurs, sub->maxOccurs);
13053:                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
13054:                                        sub, counter, pctxt->state);
13055:                 } else {
13056:                     if ((sub->minOccurs == 1) &&
13057:                         (sub->maxOccurs == 1)) {
13058:                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13059:                                                 pctxt->state,
13060:                                                 elemDecl->name,
13061:                                                 elemDecl->targetNamespace,
13062:                                                 1, 1, elemDecl);
13063:                     } else if ((sub->minOccurs == 0) &&
13064:                         (sub->maxOccurs == 1)) {
13065: 
13066:                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13067:                                                  pctxt->state,
13068:                                                  elemDecl->name,
13069:                                                  elemDecl->targetNamespace,
13070:                                                  0,
13071:                                                  1,
13072:                                                  elemDecl);
13073:                     }
13074:                 }
13075:                 sub = (xmlSchemaParticlePtr) sub->next;
13076:             }
13077:             pctxt->state =
13078:                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13079:             if (particle->minOccurs == 0) {
13080:                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13081:                 ret = 1;
13082:             }
13083:             break;
13084:         }
13085: 	case XML_SCHEMA_TYPE_GROUP:
13086: 	    /*
13087: 	    * If we hit a model group definition, then this means that
13088: 	    * it was empty, thus was not substituted for the containing
13089: 	    * model group. Just do nothing in this case.
13090: 	    * TODO: But the group should be substituted and not occur at
13091: 	    * all in the content model at this point. Fix this.
13092: 	    */
13093:             ret = 1;
13094: 	    break;
13095:         default:
13096: 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13097: 		"xmlSchemaBuildAContentModel",
13098: 		"found unexpected term of type '%s' in content model",
13099: 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
13100:             return(ret);
13101:     }
13102:     return(ret);
13103: }
13104: 
13105: /**
13106:  * xmlSchemaBuildContentModel:
13107:  * @ctxt:  the schema parser context
13108:  * @type:  the complex type definition
13109:  * @name:  the element name
13110:  *
13111:  * Builds the content model of the complex type.
13112:  */
13113: static void
13114: xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13115: 			   xmlSchemaParserCtxtPtr ctxt)
13116: {
13117:     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13118: 	(type->contModel != NULL) ||
13119: 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13120: 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13121: 	return;
13122: 
13123: #ifdef DEBUG_CONTENT
13124:     xmlGenericError(xmlGenericErrorContext,
13125:                     "Building content model for %s\n", name);
13126: #endif
13127:     ctxt->am = NULL;
13128:     ctxt->am = xmlNewAutomata();
13129:     if (ctxt->am == NULL) {
13130:         xmlGenericError(xmlGenericErrorContext,
13131: 	    "Cannot create automata for complex type %s\n", type->name);
13132:         return;
13133:     }
13134:     ctxt->state = xmlAutomataGetInitState(ctxt->am);
13135:     /*
13136:     * Build the automaton.
13137:     */
13138:     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13139:     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13140:     type->contModel = xmlAutomataCompile(ctxt->am);
13141:     if (type->contModel == NULL) {
13142:         xmlSchemaPCustomErr(ctxt,
13143: 	    XML_SCHEMAP_INTERNAL,
13144: 	    WXS_BASIC_CAST type, type->node,
13145: 	    "Failed to compile the content model", NULL);
13146:     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13147:         xmlSchemaPCustomErr(ctxt,
13148: 	    XML_SCHEMAP_NOT_DETERMINISTIC,
13149: 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13150: 	    WXS_BASIC_CAST type, type->node,
13151: 	    "The content model is not determinist", NULL);
13152:     } else {
13153: #ifdef DEBUG_CONTENT_REGEXP
13154:         xmlGenericError(xmlGenericErrorContext,
13155:                         "Content model of %s:\n", type->name);
13156:         xmlRegexpPrint(stderr, type->contModel);
13157: #endif
13158:     }
13159:     ctxt->state = NULL;
13160:     xmlFreeAutomata(ctxt->am);
13161:     ctxt->am = NULL;
13162: }
13163: 
13164: /**
13165:  * xmlSchemaResolveElementReferences:
13166:  * @elem:  the schema element context
13167:  * @ctxt:  the schema parser context
13168:  *
13169:  * Resolves the references of an element declaration
13170:  * or particle, which has an element declaration as it's
13171:  * term.
13172:  */
13173: static void
13174: xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13175: 				  xmlSchemaParserCtxtPtr ctxt)
13176: {
13177:     if ((ctxt == NULL) || (elemDecl == NULL) ||
13178: 	((elemDecl != NULL) &&
13179: 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13180:         return;
13181:     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13182: 
13183:     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13184: 	xmlSchemaTypePtr type;
13185: 
13186: 	/* (type definition) ... otherwise the type definition �resolved�
13187: 	* to by the �actual value� of the type [attribute] ...
13188: 	*/
13189: 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13190: 	    elemDecl->namedTypeNs);
13191: 	if (type == NULL) {
13192: 	    xmlSchemaPResCompAttrErr(ctxt,
13193: 		XML_SCHEMAP_SRC_RESOLVE,
13194: 		WXS_BASIC_CAST elemDecl, elemDecl->node,
13195: 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
13196: 		XML_SCHEMA_TYPE_BASIC, "type definition");
13197: 	} else
13198: 	    elemDecl->subtypes = type;
13199:     }
13200:     if (elemDecl->substGroup != NULL) {
13201: 	xmlSchemaElementPtr substHead;
13202: 
13203: 	/*
13204: 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
13205: 	* substitutionGroup?
13206: 	*/
13207: 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13208: 	    elemDecl->substGroupNs);
13209: 	if (substHead == NULL) {
13210: 	    xmlSchemaPResCompAttrErr(ctxt,
13211: 		XML_SCHEMAP_SRC_RESOLVE,
13212: 		WXS_BASIC_CAST elemDecl, NULL,
13213: 		"substitutionGroup", elemDecl->substGroup,
13214: 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13215: 	} else {
13216: 	    xmlSchemaResolveElementReferences(substHead, ctxt);
13217: 	    /*
13218: 	    * Set the "substitution group affiliation".
13219: 	    * NOTE that now we use the "refDecl" field for this.
13220: 	    */
13221: 	    WXS_SUBST_HEAD(elemDecl) = substHead;
13222: 	    /*
13223: 	    * The type definitions is set to:
13224: 	    * SPEC "...the {type definition} of the element
13225: 	    * declaration �resolved� to by the �actual value�
13226: 	    * of the substitutionGroup [attribute], if present"
13227: 	    */
13228: 	    if (elemDecl->subtypes == NULL)
13229: 		elemDecl->subtypes = substHead->subtypes;
13230: 	}
13231:     }
13232:     /*
13233:     * SPEC "The definition of anyType serves as the default type definition
13234:     * for element declarations whose XML representation does not specify one."
13235:     */
13236:     if ((elemDecl->subtypes == NULL) &&
13237: 	(elemDecl->namedType == NULL) &&
13238: 	(elemDecl->substGroup == NULL))
13239: 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13240: }
13241: 
13242: /**
13243:  * xmlSchemaResolveUnionMemberTypes:
13244:  * @ctxt:  the schema parser context
13245:  * @type:  the schema simple type definition
13246:  *
13247:  * Checks and builds the "member type definitions" property of the union
13248:  * simple type. This handles part (1), part (2) is done in
13249:  * xmlSchemaFinishMemberTypeDefinitionsProperty()
13250:  *
13251:  * Returns -1 in case of an internal error, 0 otherwise.
13252:  */
13253: static int
13254: xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13255: 				 xmlSchemaTypePtr type)
13256: {
13257: 
13258:     xmlSchemaTypeLinkPtr link, lastLink, newLink;
13259:     xmlSchemaTypePtr memberType;
13260: 
13261:     /*
13262:     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13263:     * define the explicit members as the type definitions �resolved�
13264:     * to by the items in the �actual value� of the memberTypes [attribute],
13265:     * if any, followed by the type definitions corresponding to the
13266:     * <simpleType>s among the [children] of <union>, if any."
13267:     */
13268:     /*
13269:     * Resolve references.
13270:     */
13271:     link = type->memberTypes;
13272:     lastLink = NULL;
13273:     while (link != NULL) {
13274: 	const xmlChar *name, *nsName;
13275: 
13276: 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
13277: 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13278: 
13279: 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13280: 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13281: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13282: 		WXS_BASIC_CAST type, type->node, "memberTypes",
13283: 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13284: 	    /*
13285: 	    * Remove the member type link.
13286: 	    */
13287: 	    if (lastLink == NULL)
13288: 		type->memberTypes = link->next;
13289: 	    else
13290: 		lastLink->next = link->next;
13291: 	    newLink = link;
13292: 	    link = link->next;
13293: 	    xmlFree(newLink);
13294: 	} else {
13295: 	    link->type = memberType;
13296: 	    lastLink = link;
13297: 	    link = link->next;
13298: 	}
13299:     }
13300:     /*
13301:     * Add local simple types,
13302:     */
13303:     memberType = type->subtypes;
13304:     while (memberType != NULL) {
13305: 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13306: 	if (link == NULL) {
13307: 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13308: 	    return (-1);
13309: 	}
13310: 	link->type = memberType;
13311: 	link->next = NULL;
13312: 	if (lastLink == NULL)
13313: 	    type->memberTypes = link;
13314: 	else
13315: 	    lastLink->next = link;
13316: 	lastLink = link;
13317: 	memberType = memberType->next;
13318:     }
13319:     return (0);
13320: }
13321: 
13322: /**
13323:  * xmlSchemaIsDerivedFromBuiltInType:
13324:  * @ctxt:  the schema parser context
13325:  * @type:  the type definition
13326:  * @valType: the value type
13327:  *
13328:  *
13329:  * Returns 1 if the type has the given value type, or
13330:  * is derived from such a type.
13331:  */
13332: static int
13333: xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13334: {
13335:     if (type == NULL)
13336: 	return (0);
13337:     if (WXS_IS_COMPLEX(type))
13338: 	return (0);
13339:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
13340: 	if (type->builtInType == valType)
13341: 	    return(1);
13342: 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13343: 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
13344: 	    return (0);
13345: 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13346:     }
13347:     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13348: }
13349: 
13350: #if 0
13351: /**
13352:  * xmlSchemaIsDerivedFromBuiltInType:
13353:  * @ctxt:  the schema parser context
13354:  * @type:  the type definition
13355:  * @valType: the value type
13356:  *
13357:  *
13358:  * Returns 1 if the type has the given value type, or
13359:  * is derived from such a type.
13360:  */
13361: static int
13362: xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13363: {
13364:     if (type == NULL)
13365: 	return (0);
13366:     if (WXS_IS_COMPLEX(type))
13367: 	return (0);
13368:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
13369: 	if (type->builtInType == valType)
13370: 	    return(1);
13371: 	return (0);
13372:     } else
13373: 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13374: 
13375:     return (0);
13376: }
13377: 
13378: static xmlSchemaTypePtr
13379: xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13380: {
13381:     if (type == NULL)
13382: 	return (NULL);
13383:     if (WXS_IS_COMPLEX(type))
13384: 	return (NULL);
13385:     if (type->type == XML_SCHEMA_TYPE_BASIC)
13386: 	return(type);
13387:     return(xmlSchemaQueryBuiltInType(type->subtypes));
13388: }
13389: #endif
13390: 
13391: /**
13392:  * xmlSchemaGetPrimitiveType:
13393:  * @type:  the simpleType definition
13394:  *
13395:  * Returns the primitive type of the given type or
13396:  * NULL in case of error.
13397:  */
13398: static xmlSchemaTypePtr
13399: xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13400: {
13401: 
13402:     while (type != NULL) {
13403: 	/*
13404: 	* Note that anySimpleType is actually not a primitive type
13405: 	* but we need that here.
13406: 	*/
13407: 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13408: 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13409: 	    return (type);
13410: 	type = type->baseType;
13411:     }
13412: 
13413:     return (NULL);
13414: }
13415: 
13416: #if 0
13417: /**
13418:  * xmlSchemaGetBuiltInTypeAncestor:
13419:  * @type:  the simpleType definition
13420:  *
13421:  * Returns the primitive type of the given type or
13422:  * NULL in case of error.
13423:  */
13424: static xmlSchemaTypePtr
13425: xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13426: {
13427:     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13428: 	return (0);
13429:     while (type != NULL) {
13430: 	if (type->type == XML_SCHEMA_TYPE_BASIC)
13431: 	    return (type);
13432: 	type = type->baseType;
13433:     }
13434: 
13435:     return (NULL);
13436: }
13437: #endif
13438: 
13439: /**
13440:  * xmlSchemaCloneWildcardNsConstraints:
13441:  * @ctxt:  the schema parser context
13442:  * @dest:  the destination wildcard
13443:  * @source: the source wildcard
13444:  *
13445:  * Clones the namespace constraints of source
13446:  * and assignes them to dest.
13447:  * Returns -1 on internal error, 0 otherwise.
13448:  */
13449: static int
13450: xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13451: 				    xmlSchemaWildcardPtr dest,
13452: 				    xmlSchemaWildcardPtr source)
13453: {
13454:     xmlSchemaWildcardNsPtr cur, tmp, last;
13455: 
13456:     if ((source == NULL) || (dest == NULL))
13457: 	return(-1);
13458:     dest->any = source->any;
13459:     cur = source->nsSet;
13460:     last = NULL;
13461:     while (cur != NULL) {
13462: 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13463: 	if (tmp == NULL)
13464: 	    return(-1);
13465: 	tmp->value = cur->value;
13466: 	if (last == NULL)
13467: 	    dest->nsSet = tmp;
13468: 	else
13469: 	    last->next = tmp;
13470: 	last = tmp;
13471: 	cur = cur->next;
13472:     }
13473:     if (dest->negNsSet != NULL)
13474: 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13475:     if (source->negNsSet != NULL) {
13476: 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13477: 	if (dest->negNsSet == NULL)
13478: 	    return(-1);
13479: 	dest->negNsSet->value = source->negNsSet->value;
13480:     } else
13481: 	dest->negNsSet = NULL;
13482:     return(0);
13483: }
13484: 
13485: /**
13486:  * xmlSchemaUnionWildcards:
13487:  * @ctxt:  the schema parser context
13488:  * @completeWild:  the first wildcard
13489:  * @curWild: the second wildcard
13490:  *
13491:  * Unions the namespace constraints of the given wildcards.
13492:  * @completeWild will hold the resulting union.
13493:  * Returns a positive error code on failure, -1 in case of an
13494:  * internal error, 0 otherwise.
13495:  */
13496: static int
13497: xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13498: 			    xmlSchemaWildcardPtr completeWild,
13499: 			    xmlSchemaWildcardPtr curWild)
13500: {
13501:     xmlSchemaWildcardNsPtr cur, curB, tmp;
13502: 
13503:     /*
13504:     * 1 If O1 and O2 are the same value, then that value must be the
13505:     * value.
13506:     */
13507:     if ((completeWild->any == curWild->any) &&
13508: 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13509: 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13510: 
13511: 	if ((completeWild->negNsSet == NULL) ||
13512: 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13513: 
13514: 	    if (completeWild->nsSet != NULL) {
13515: 		int found = 0;
13516: 
13517: 		/*
13518: 		* Check equality of sets.
13519: 		*/
13520: 		cur = completeWild->nsSet;
13521: 		while (cur != NULL) {
13522: 		    found = 0;
13523: 		    curB = curWild->nsSet;
13524: 		    while (curB != NULL) {
13525: 			if (cur->value == curB->value) {
13526: 			    found = 1;
13527: 			    break;
13528: 			}
13529: 			curB = curB->next;
13530: 		    }
13531: 		    if (!found)
13532: 			break;
13533: 		    cur = cur->next;
13534: 		}
13535: 		if (found)
13536: 		    return(0);
13537: 	    } else
13538: 		return(0);
13539: 	}
13540:     }
13541:     /*
13542:     * 2 If either O1 or O2 is any, then any must be the value
13543:     */
13544:     if (completeWild->any != curWild->any) {
13545: 	if (completeWild->any == 0) {
13546: 	    completeWild->any = 1;
13547: 	    if (completeWild->nsSet != NULL) {
13548: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13549: 		completeWild->nsSet = NULL;
13550: 	    }
13551: 	    if (completeWild->negNsSet != NULL) {
13552: 		xmlFree(completeWild->negNsSet);
13553: 		completeWild->negNsSet = NULL;
13554: 	    }
13555: 	}
13556: 	return (0);
13557:     }
13558:     /*
13559:     * 3 If both O1 and O2 are sets of (namespace names or �absent�),
13560:     * then the union of those sets must be the value.
13561:     */
13562:     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13563: 	int found;
13564: 	xmlSchemaWildcardNsPtr start;
13565: 
13566: 	cur = curWild->nsSet;
13567: 	start = completeWild->nsSet;
13568: 	while (cur != NULL) {
13569: 	    found = 0;
13570: 	    curB = start;
13571: 	    while (curB != NULL) {
13572: 		if (cur->value == curB->value) {
13573: 		    found = 1;
13574: 		    break;
13575: 		}
13576: 		curB = curB->next;
13577: 	    }
13578: 	    if (!found) {
13579: 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13580: 		if (tmp == NULL)
13581: 		    return (-1);
13582: 		tmp->value = cur->value;
13583: 		tmp->next = completeWild->nsSet;
13584: 		completeWild->nsSet = tmp;
13585: 	    }
13586: 	    cur = cur->next;
13587: 	}
13588: 
13589: 	return(0);
13590:     }
13591:     /*
13592:     * 4 If the two are negations of different values (namespace names
13593:     * or �absent�), then a pair of not and �absent� must be the value.
13594:     */
13595:     if ((completeWild->negNsSet != NULL) &&
13596: 	(curWild->negNsSet != NULL) &&
13597: 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
13598: 	completeWild->negNsSet->value = NULL;
13599: 
13600: 	return(0);
13601:     }
13602:     /*
13603:      * 5.
13604:      */
13605:     if (((completeWild->negNsSet != NULL) &&
13606: 	(completeWild->negNsSet->value != NULL) &&
13607: 	(curWild->nsSet != NULL)) ||
13608: 	((curWild->negNsSet != NULL) &&
13609: 	(curWild->negNsSet->value != NULL) &&
13610: 	(completeWild->nsSet != NULL))) {
13611: 
13612: 	int nsFound, absentFound = 0;
13613: 
13614: 	if (completeWild->nsSet != NULL) {
13615: 	    cur = completeWild->nsSet;
13616: 	    curB = curWild->negNsSet;
13617: 	} else {
13618: 	    cur = curWild->nsSet;
13619: 	    curB = completeWild->negNsSet;
13620: 	}
13621: 	nsFound = 0;
13622: 	while (cur != NULL) {
13623: 	    if (cur->value == NULL)
13624: 		absentFound = 1;
13625: 	    else if (cur->value == curB->value)
13626: 		nsFound = 1;
13627: 	    if (nsFound && absentFound)
13628: 		break;
13629: 	    cur = cur->next;
13630: 	}
13631: 
13632: 	if (nsFound && absentFound) {
13633: 	    /*
13634: 	    * 5.1 If the set S includes both the negated namespace
13635: 	    * name and �absent�, then any must be the value.
13636: 	    */
13637: 	    completeWild->any = 1;
13638: 	    if (completeWild->nsSet != NULL) {
13639: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13640: 		completeWild->nsSet = NULL;
13641: 	    }
13642: 	    if (completeWild->negNsSet != NULL) {
13643: 		xmlFree(completeWild->negNsSet);
13644: 		completeWild->negNsSet = NULL;
13645: 	    }
13646: 	} else if (nsFound && (!absentFound)) {
13647: 	    /*
13648: 	    * 5.2 If the set S includes the negated namespace name
13649: 	    * but not �absent�, then a pair of not and �absent� must
13650: 	    * be the value.
13651: 	    */
13652: 	    if (completeWild->nsSet != NULL) {
13653: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13654: 		completeWild->nsSet = NULL;
13655: 	    }
13656: 	    if (completeWild->negNsSet == NULL) {
13657: 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13658: 		if (completeWild->negNsSet == NULL)
13659: 		    return (-1);
13660: 	    }
13661: 	    completeWild->negNsSet->value = NULL;
13662: 	} else if ((!nsFound) && absentFound) {
13663: 	    /*
13664: 	    * 5.3 If the set S includes �absent� but not the negated
13665: 	    * namespace name, then the union is not expressible.
13666: 	    */
13667: 	    xmlSchemaPErr(ctxt, completeWild->node,
13668: 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13669: 		"The union of the wilcard is not expressible.\n",
13670: 		NULL, NULL);
13671: 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13672: 	} else if ((!nsFound) && (!absentFound)) {
13673: 	    /*
13674: 	    * 5.4 If the set S does not include either the negated namespace
13675: 	    * name or �absent�, then whichever of O1 or O2 is a pair of not
13676: 	    * and a namespace name must be the value.
13677: 	    */
13678: 	    if (completeWild->negNsSet == NULL) {
13679: 		if (completeWild->nsSet != NULL) {
13680: 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13681: 		    completeWild->nsSet = NULL;
13682: 		}
13683: 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13684: 		if (completeWild->negNsSet == NULL)
13685: 		    return (-1);
13686: 		completeWild->negNsSet->value = curWild->negNsSet->value;
13687: 	    }
13688: 	}
13689: 	return (0);
13690:     }
13691:     /*
13692:      * 6.
13693:      */
13694:     if (((completeWild->negNsSet != NULL) &&
13695: 	(completeWild->negNsSet->value == NULL) &&
13696: 	(curWild->nsSet != NULL)) ||
13697: 	((curWild->negNsSet != NULL) &&
13698: 	(curWild->negNsSet->value == NULL) &&
13699: 	(completeWild->nsSet != NULL))) {
13700: 
13701: 	if (completeWild->nsSet != NULL) {
13702: 	    cur = completeWild->nsSet;
13703: 	} else {
13704: 	    cur = curWild->nsSet;
13705: 	}
13706: 	while (cur != NULL) {
13707: 	    if (cur->value == NULL) {
13708: 		/*
13709: 		* 6.1 If the set S includes �absent�, then any must be the
13710: 		* value.
13711: 		*/
13712: 		completeWild->any = 1;
13713: 		if (completeWild->nsSet != NULL) {
13714: 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13715: 		    completeWild->nsSet = NULL;
13716: 		}
13717: 		if (completeWild->negNsSet != NULL) {
13718: 		    xmlFree(completeWild->negNsSet);
13719: 		    completeWild->negNsSet = NULL;
13720: 		}
13721: 		return (0);
13722: 	    }
13723: 	    cur = cur->next;
13724: 	}
13725: 	if (completeWild->negNsSet == NULL) {
13726: 	    /*
13727: 	    * 6.2 If the set S does not include �absent�, then a pair of not
13728: 	    * and �absent� must be the value.
13729: 	    */
13730: 	    if (completeWild->nsSet != NULL) {
13731: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13732: 		completeWild->nsSet = NULL;
13733: 	    }
13734: 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13735: 	    if (completeWild->negNsSet == NULL)
13736: 		return (-1);
13737: 	    completeWild->negNsSet->value = NULL;
13738: 	}
13739: 	return (0);
13740:     }
13741:     return (0);
13742: 
13743: }
13744: 
13745: /**
13746:  * xmlSchemaIntersectWildcards:
13747:  * @ctxt:  the schema parser context
13748:  * @completeWild:  the first wildcard
13749:  * @curWild: the second wildcard
13750:  *
13751:  * Intersects the namespace constraints of the given wildcards.
13752:  * @completeWild will hold the resulting intersection.
13753:  * Returns a positive error code on failure, -1 in case of an
13754:  * internal error, 0 otherwise.
13755:  */
13756: static int
13757: xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13758: 			    xmlSchemaWildcardPtr completeWild,
13759: 			    xmlSchemaWildcardPtr curWild)
13760: {
13761:     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13762: 
13763:     /*
13764:     * 1 If O1 and O2 are the same value, then that value must be the
13765:     * value.
13766:     */
13767:     if ((completeWild->any == curWild->any) &&
13768: 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13769: 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13770: 
13771: 	if ((completeWild->negNsSet == NULL) ||
13772: 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13773: 
13774: 	    if (completeWild->nsSet != NULL) {
13775: 		int found = 0;
13776: 
13777: 		/*
13778: 		* Check equality of sets.
13779: 		*/
13780: 		cur = completeWild->nsSet;
13781: 		while (cur != NULL) {
13782: 		    found = 0;
13783: 		    curB = curWild->nsSet;
13784: 		    while (curB != NULL) {
13785: 			if (cur->value == curB->value) {
13786: 			    found = 1;
13787: 			    break;
13788: 			}
13789: 			curB = curB->next;
13790: 		    }
13791: 		    if (!found)
13792: 			break;
13793: 		    cur = cur->next;
13794: 		}
13795: 		if (found)
13796: 		    return(0);
13797: 	    } else
13798: 		return(0);
13799: 	}
13800:     }
13801:     /*
13802:     * 2 If either O1 or O2 is any, then the other must be the value.
13803:     */
13804:     if ((completeWild->any != curWild->any) && (completeWild->any)) {
13805: 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13806: 	    return(-1);
13807: 	return(0);
13808:     }
13809:     /*
13810:     * 3 If either O1 or O2 is a pair of not and a value (a namespace
13811:     * name or �absent�) and the other is a set of (namespace names or
13812:     * �absent�), then that set, minus the negated value if it was in
13813:     * the set, minus �absent� if it was in the set, must be the value.
13814:     */
13815:     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13816: 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13817: 	const xmlChar *neg;
13818: 
13819: 	if (completeWild->nsSet == NULL) {
13820: 	    neg = completeWild->negNsSet->value;
13821: 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13822: 		return(-1);
13823: 	} else
13824: 	    neg = curWild->negNsSet->value;
13825: 	/*
13826: 	* Remove absent and negated.
13827: 	*/
13828: 	prev = NULL;
13829: 	cur = completeWild->nsSet;
13830: 	while (cur != NULL) {
13831: 	    if (cur->value == NULL) {
13832: 		if (prev == NULL)
13833: 		    completeWild->nsSet = cur->next;
13834: 		else
13835: 		    prev->next = cur->next;
13836: 		xmlFree(cur);
13837: 		break;
13838: 	    }
13839: 	    prev = cur;
13840: 	    cur = cur->next;
13841: 	}
13842: 	if (neg != NULL) {
13843: 	    prev = NULL;
13844: 	    cur = completeWild->nsSet;
13845: 	    while (cur != NULL) {
13846: 		if (cur->value == neg) {
13847: 		    if (prev == NULL)
13848: 			completeWild->nsSet = cur->next;
13849: 		    else
13850: 			prev->next = cur->next;
13851: 		    xmlFree(cur);
13852: 		    break;
13853: 		}
13854: 		prev = cur;
13855: 		cur = cur->next;
13856: 	    }
13857: 	}
13858: 
13859: 	return(0);
13860:     }
13861:     /*
13862:     * 4 If both O1 and O2 are sets of (namespace names or �absent�),
13863:     * then the intersection of those sets must be the value.
13864:     */
13865:     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13866: 	int found;
13867: 
13868: 	cur = completeWild->nsSet;
13869: 	prev = NULL;
13870: 	while (cur != NULL) {
13871: 	    found = 0;
13872: 	    curB = curWild->nsSet;
13873: 	    while (curB != NULL) {
13874: 		if (cur->value == curB->value) {
13875: 		    found = 1;
13876: 		    break;
13877: 		}
13878: 		curB = curB->next;
13879: 	    }
13880: 	    if (!found) {
13881: 		if (prev == NULL)
13882: 		    completeWild->nsSet = cur->next;
13883: 		else
13884: 		    prev->next = cur->next;
13885: 		tmp = cur->next;
13886: 		xmlFree(cur);
13887: 		cur = tmp;
13888: 		continue;
13889: 	    }
13890: 	    prev = cur;
13891: 	    cur = cur->next;
13892: 	}
13893: 
13894: 	return(0);
13895:     }
13896:     /* 5 If the two are negations of different namespace names,
13897:     * then the intersection is not expressible
13898:     */
13899:     if ((completeWild->negNsSet != NULL) &&
13900: 	(curWild->negNsSet != NULL) &&
13901: 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13902: 	(completeWild->negNsSet->value != NULL) &&
13903: 	(curWild->negNsSet->value != NULL)) {
13904: 
13905: 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13906: 	    "The intersection of the wilcard is not expressible.\n",
13907: 	    NULL, NULL);
13908: 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13909:     }
13910:     /*
13911:     * 6 If the one is a negation of a namespace name and the other
13912:     * is a negation of �absent�, then the one which is the negation
13913:     * of a namespace name must be the value.
13914:     */
13915:     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13916: 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13917: 	(completeWild->negNsSet->value == NULL)) {
13918: 	completeWild->negNsSet->value =  curWild->negNsSet->value;
13919:     }
13920:     return(0);
13921: }
13922: 
13923: /**
13924:  * xmlSchemaIsWildcardNsConstraintSubset:
13925:  * @ctxt:  the schema parser context
13926:  * @sub:  the first wildcard
13927:  * @super: the second wildcard
13928:  *
13929:  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13930:  *
13931:  * Returns 0 if the namespace constraint of @sub is an intensional
13932:  * subset of @super, 1 otherwise.
13933:  */
13934: static int
13935: xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13936: 			  xmlSchemaWildcardPtr super)
13937: {
13938:     /*
13939:     * 1 super must be any.
13940:     */
13941:     if (super->any)
13942: 	return (0);
13943:     /*
13944:     * 2.1 sub must be a pair of not and a namespace name or �absent�.
13945:     * 2.2 super must be a pair of not and the same value.
13946:     */
13947:     if ((sub->negNsSet != NULL) &&
13948: 	(super->negNsSet != NULL) &&
13949: 	(sub->negNsSet->value == sub->negNsSet->value))
13950: 	return (0);
13951:     /*
13952:     * 3.1 sub must be a set whose members are either namespace names or �absent�.
13953:     */
13954:     if (sub->nsSet != NULL) {
13955: 	/*
13956: 	* 3.2.1 super must be the same set or a superset thereof.
13957: 	*/
13958: 	if (super->nsSet != NULL) {
13959: 	    xmlSchemaWildcardNsPtr cur, curB;
13960: 	    int found = 0;
13961: 
13962: 	    cur = sub->nsSet;
13963: 	    while (cur != NULL) {
13964: 		found = 0;
13965: 		curB = super->nsSet;
13966: 		while (curB != NULL) {
13967: 		    if (cur->value == curB->value) {
13968: 			found = 1;
13969: 			break;
13970: 		    }
13971: 		    curB = curB->next;
13972: 		}
13973: 		if (!found)
13974: 		    return (1);
13975: 		cur = cur->next;
13976: 	    }
13977: 	    if (found)
13978: 		return (0);
13979: 	} else if (super->negNsSet != NULL) {
13980: 	    xmlSchemaWildcardNsPtr cur;
13981: 	    /*
13982: 	    * 3.2.2 super must be a pair of not and a namespace name or
13983: 	    * �absent� and that value must not be in sub's set.
13984: 	    */
13985: 	    cur = sub->nsSet;
13986: 	    while (cur != NULL) {
13987: 		if (cur->value == super->negNsSet->value)
13988: 		    return (1);
13989: 		cur = cur->next;
13990: 	    }
13991: 	    return (0);
13992: 	}
13993:     }
13994:     return (1);
13995: }
13996: 
13997: static int
13998: xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13999: 				     int *fixed,
14000: 				     const xmlChar **value,
14001: 				     xmlSchemaValPtr *val)
14002: {
14003:     *fixed = 0;
14004:     *value = NULL;
14005:     if (val != 0)
14006: 	*val = NULL;
14007: 
14008:     if (attruse->defValue != NULL) {
14009: 	*value = attruse->defValue;
14010: 	if (val != NULL)
14011: 	    *val = attruse->defVal;
14012: 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14013: 	    *fixed = 1;
14014: 	return(1);
14015:     } else if ((attruse->attrDecl != NULL) &&
14016: 	(attruse->attrDecl->defValue != NULL)) {
14017: 	*value = attruse->attrDecl->defValue;
14018: 	if (val != NULL)
14019: 	    *val = attruse->attrDecl->defVal;
14020: 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14021: 	    *fixed = 1;
14022: 	return(1);
14023:     }
14024:     return(0);
14025: }
14026: /**
14027:  * xmlSchemaCheckCVCWildcardNamespace:
14028:  * @wild:  the wildcard
14029:  * @ns:  the namespace
14030:  *
14031:  * Validation Rule: Wildcard allows Namespace Name
14032:  * (cvc-wildcard-namespace)
14033:  *
14034:  * Returns 0 if the given namespace matches the wildcard,
14035:  * 1 otherwise and -1 on API errors.
14036:  */
14037: static int
14038: xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14039: 				   const xmlChar* ns)
14040: {
14041:     if (wild == NULL)
14042: 	return(-1);
14043: 
14044:     if (wild->any)
14045: 	return(0);
14046:     else if (wild->nsSet != NULL) {
14047: 	xmlSchemaWildcardNsPtr cur;
14048: 
14049: 	cur = wild->nsSet;
14050: 	while (cur != NULL) {
14051: 	    if (xmlStrEqual(cur->value, ns))
14052: 		return(0);
14053: 	    cur = cur->next;
14054: 	}
14055:     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14056: 	(!xmlStrEqual(wild->negNsSet->value, ns)))
14057: 	return(0);
14058: 
14059:     return(1);
14060: }
14061: 
14062: #define XML_SCHEMA_ACTION_DERIVE 0
14063: #define XML_SCHEMA_ACTION_REDEFINE 1
14064: 
14065: #define WXS_ACTION_STR(a) \
14066: ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14067: 
14068: /*
14069: * Schema Component Constraint:
14070: *   Derivation Valid (Restriction, Complex)
14071: *   derivation-ok-restriction (2) - (4)
14072: *
14073: * ATTENTION:
14074: * In XML Schema 1.1 this will be:
14075: * Validation Rule:
14076: *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14077: *
14078: */
14079: static int
14080: xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14081: 				       int action,
14082: 				       xmlSchemaBasicItemPtr item,
14083: 				       xmlSchemaBasicItemPtr baseItem,
14084: 				       xmlSchemaItemListPtr uses,
14085: 				       xmlSchemaItemListPtr baseUses,
14086: 				       xmlSchemaWildcardPtr wild,
14087: 				       xmlSchemaWildcardPtr baseWild)
14088: {
14089:     xmlSchemaAttributeUsePtr cur = NULL, bcur;
14090:     int i, j, found; /* err = 0; */
14091:     const xmlChar *bEffValue;
14092:     int effFixed;
14093: 
14094:     if (uses != NULL) {
14095: 	for (i = 0; i < uses->nbItems; i++) {
14096: 	    cur = uses->items[i];
14097: 	    found = 0;
14098: 	    if (baseUses == NULL)
14099: 		goto not_found;
14100: 	    for (j = 0; j < baseUses->nbItems; j++) {
14101: 		bcur = baseUses->items[j];
14102: 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14103: 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
14104: 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
14105: 			WXS_ATTRUSE_DECL_TNS(bcur)))
14106: 		{
14107: 		    /*
14108: 		    * (2.1) "If there is an attribute use in the {attribute
14109: 		    * uses} of the {base type definition} (call this B) whose
14110: 		    * {attribute declaration} has the same {name} and {target
14111: 		    * namespace}, then  all of the following must be true:"
14112: 		    */
14113: 		    found = 1;
14114: 
14115: 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14116: 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14117: 		    {
14118: 			xmlChar *str = NULL;
14119: 			/*
14120: 			* (2.1.1) "one of the following must be true:"
14121: 			* (2.1.1.1) "B's {required} is false."
14122: 			* (2.1.1.2) "R's {required} is true."
14123: 			*/
14124: 			xmlSchemaPAttrUseErr4(pctxt,
14125: 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14126: 			    WXS_ITEM_NODE(item), item, cur,
14127: 			    "The 'optional' attribute use is inconsistent "
14128: 			    "with the corresponding 'required' attribute use of "
14129: 			    "the %s %s",
14130: 			    WXS_ACTION_STR(action),
14131: 			    xmlSchemaGetComponentDesignation(&str, baseItem),
14132: 			    NULL, NULL);
14133: 			FREE_AND_NULL(str);
14134: 			/* err = pctxt->err; */
14135: 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14136: 			WXS_ATTRUSE_TYPEDEF(cur),
14137: 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14138: 		    {
14139: 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14140: 
14141: 			/*
14142: 			* SPEC (2.1.2) "R's {attribute declaration}'s
14143: 			* {type definition} must be validly derived from
14144: 			* B's {type definition} given the empty set as
14145: 			* defined in Type Derivation OK (Simple) (�3.14.6)."
14146: 			*/
14147: 			xmlSchemaPAttrUseErr4(pctxt,
14148: 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14149: 			    WXS_ITEM_NODE(item), item, cur,
14150: 			    "The attribute declaration's %s "
14151: 			    "is not validly derived from "
14152: 			    "the corresponding %s of the "
14153: 			    "attribute declaration in the %s %s",
14154: 			    xmlSchemaGetComponentDesignation(&strA,
14155: 				WXS_ATTRUSE_TYPEDEF(cur)),
14156: 			    xmlSchemaGetComponentDesignation(&strB,
14157: 				WXS_ATTRUSE_TYPEDEF(bcur)),
14158: 			    WXS_ACTION_STR(action),
14159: 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
14160: 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14161: 			FREE_AND_NULL(strA);
14162: 			FREE_AND_NULL(strB);
14163: 			FREE_AND_NULL(strC);
14164: 			/* err = pctxt->err; */
14165: 		    } else {
14166: 			/*
14167: 			* 2.1.3 [Definition:]  Let the effective value
14168: 			* constraint of an attribute use be its {value
14169: 			* constraint}, if present, otherwise its {attribute
14170: 			* declaration}'s {value constraint} .
14171: 			*/
14172: 			xmlSchemaGetEffectiveValueConstraint(bcur,
14173: 			    &effFixed, &bEffValue, NULL);
14174: 			/*
14175: 			* 2.1.3 ... one of the following must be true
14176: 			*
14177: 			* 2.1.3.1 B's �effective value constraint� is
14178: 			* �absent� or default.
14179: 			*/
14180: 			if ((bEffValue != NULL) &&
14181: 			    (effFixed == 1)) {
14182: 			    const xmlChar *rEffValue = NULL;
14183: 
14184: 			    xmlSchemaGetEffectiveValueConstraint(bcur,
14185: 				&effFixed, &rEffValue, NULL);
14186: 			    /*
14187: 			    * 2.1.3.2 R's �effective value constraint� is
14188: 			    * fixed with the same string as B's.
14189: 			    * MAYBE TODO: Compare the computed values.
14190: 			    *       Hmm, it says "same string" so
14191: 			    *       string-equality might really be sufficient.
14192: 			    */
14193: 			    if ((effFixed == 0) ||
14194: 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14195: 			    {
14196: 				xmlChar *str = NULL;
14197: 
14198: 				xmlSchemaPAttrUseErr4(pctxt,
14199: 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14200: 				    WXS_ITEM_NODE(item), item, cur,
14201: 				    "The effective value constraint of the "
14202: 				    "attribute use is inconsistent with "
14203: 				    "its correspondent in the %s %s",
14204: 				    WXS_ACTION_STR(action),
14205: 				    xmlSchemaGetComponentDesignation(&str,
14206: 					baseItem),
14207: 				    NULL, NULL);
14208: 				FREE_AND_NULL(str);
14209: 				/* err = pctxt->err; */
14210: 			    }
14211: 			}
14212: 		    }
14213: 		    break;
14214: 		}
14215: 	    }
14216: not_found:
14217: 	    if (!found) {
14218: 		/*
14219: 		* (2.2) "otherwise the {base type definition} must have an
14220: 		* {attribute wildcard} and the {target namespace} of the
14221: 		* R's {attribute declaration} must be �valid� with respect
14222: 		* to that wildcard, as defined in Wildcard allows Namespace
14223: 		* Name (�3.10.4)."
14224: 		*/
14225: 		if ((baseWild == NULL) ||
14226: 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14227: 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14228: 		{
14229: 		    xmlChar *str = NULL;
14230: 
14231: 		    xmlSchemaPAttrUseErr4(pctxt,
14232: 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14233: 			WXS_ITEM_NODE(item), item, cur,
14234: 			"Neither a matching attribute use, "
14235: 			"nor a matching wildcard exists in the %s %s",
14236: 			WXS_ACTION_STR(action),
14237: 			xmlSchemaGetComponentDesignation(&str, baseItem),
14238: 			NULL, NULL);
14239: 		    FREE_AND_NULL(str);
14240: 		    /* err = pctxt->err; */
14241: 		}
14242: 	    }
14243: 	}
14244:     }
14245:     /*
14246:     * SPEC derivation-ok-restriction (3):
14247:     * (3) "For each attribute use in the {attribute uses} of the {base type
14248:     * definition} whose {required} is true, there must be an attribute
14249:     * use with an {attribute declaration} with the same {name} and
14250:     * {target namespace} as its {attribute declaration} in the {attribute
14251:     * uses} of the complex type definition itself whose {required} is true.
14252:     */
14253:     if (baseUses != NULL) {
14254: 	for (j = 0; j < baseUses->nbItems; j++) {
14255: 	    bcur = baseUses->items[j];
14256: 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14257: 		continue;
14258: 	    found = 0;
14259: 	    if (uses != NULL) {
14260: 		for (i = 0; i < uses->nbItems; i++) {
14261: 		    cur = uses->items[i];
14262: 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14263: 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
14264: 			(WXS_ATTRUSE_DECL_TNS(cur) ==
14265: 			WXS_ATTRUSE_DECL_TNS(bcur))) {
14266: 			found = 1;
14267: 			break;
14268: 		    }
14269: 		}
14270: 	    }
14271: 	    if (!found) {
14272: 		xmlChar *strA = NULL, *strB = NULL;
14273: 
14274: 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14275: 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14276: 		    NULL, item,
14277: 		    "A matching attribute use for the "
14278: 		    "'required' %s of the %s %s is missing",
14279: 		    xmlSchemaGetComponentDesignation(&strA, bcur),
14280: 		    WXS_ACTION_STR(action),
14281: 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
14282: 		    NULL);
14283: 		FREE_AND_NULL(strA);
14284: 		FREE_AND_NULL(strB);
14285: 	    }
14286: 	}
14287:     }
14288:     /*
14289:     * derivation-ok-restriction (4)
14290:     */
14291:     if (wild != NULL) {
14292: 	/*
14293: 	* (4) "If there is an {attribute wildcard}, all of the
14294: 	* following must be true:"
14295: 	*/
14296: 	if (baseWild == NULL) {
14297: 	    xmlChar *str = NULL;
14298: 
14299: 	    /*
14300: 	    * (4.1) "The {base type definition} must also have one."
14301: 	    */
14302: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14303: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14304: 		NULL, item,
14305: 		"The %s has an attribute wildcard, "
14306: 		"but the %s %s '%s' does not have one",
14307: 		WXS_ITEM_TYPE_NAME(item),
14308: 		WXS_ACTION_STR(action),
14309: 		WXS_ITEM_TYPE_NAME(baseItem),
14310: 		xmlSchemaGetComponentQName(&str, baseItem));
14311: 	    FREE_AND_NULL(str);
14312: 	    return(pctxt->err);
14313: 	} else if ((baseWild->any == 0) &&
14314: 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
14315: 	{
14316: 	    xmlChar *str = NULL;
14317: 	    /*
14318: 	    * (4.2) "The complex type definition's {attribute wildcard}'s
14319: 	    * {namespace constraint} must be a subset of the {base type
14320: 	    * definition}'s {attribute wildcard}'s {namespace constraint},
14321: 	    * as defined by Wildcard Subset (�3.10.6)."
14322: 	    */
14323: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14324: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14325: 		NULL, item,
14326: 		"The attribute wildcard is not a valid "
14327: 		"subset of the wildcard in the %s %s '%s'",
14328: 		WXS_ACTION_STR(action),
14329: 		WXS_ITEM_TYPE_NAME(baseItem),
14330: 		xmlSchemaGetComponentQName(&str, baseItem),
14331: 		NULL);
14332: 	    FREE_AND_NULL(str);
14333: 	    return(pctxt->err);
14334: 	}
14335: 	/* 4.3 Unless the {base type definition} is the �ur-type
14336: 	* definition�, the complex type definition's {attribute
14337: 	* wildcard}'s {process contents} must be identical to or
14338: 	* stronger than the {base type definition}'s {attribute
14339: 	* wildcard}'s {process contents}, where strict is stronger
14340: 	* than lax is stronger than skip.
14341: 	*/
14342: 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
14343: 	    (wild->processContents < baseWild->processContents)) {
14344: 	    xmlChar *str = NULL;
14345: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14346: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14347: 		NULL, baseItem,
14348: 		"The {process contents} of the attribute wildcard is "
14349: 		"weaker than the one in the %s %s '%s'",
14350: 		WXS_ACTION_STR(action),
14351: 		WXS_ITEM_TYPE_NAME(baseItem),
14352: 		xmlSchemaGetComponentQName(&str, baseItem),
14353: 		NULL);
14354: 	    FREE_AND_NULL(str)
14355: 		return(pctxt->err);
14356: 	}
14357:     }
14358:     return(0);
14359: }
14360: 
14361: 
14362: static int
14363: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14364: 				  xmlSchemaBasicItemPtr item,
14365: 				  xmlSchemaWildcardPtr *completeWild,
14366: 				  xmlSchemaItemListPtr list,
14367: 				  xmlSchemaItemListPtr prohibs);
14368: /**
14369:  * xmlSchemaFixupTypeAttributeUses:
14370:  * @ctxt:  the schema parser context
14371:  * @type:  the complex type definition
14372:  *
14373:  *
14374:  * Builds the wildcard and the attribute uses on the given complex type.
14375:  * Returns -1 if an internal error occurs, 0 otherwise.
14376:  *
14377:  * ATTENTION TODO: Experimantally this uses pointer comparisons for
14378:  * strings, so recheck this if we start to hardcode some schemata, since
14379:  * they might not be in the same dict.
14380:  * NOTE: It is allowed to "extend" the xs:anyType type.
14381:  */
14382: static int
14383: xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14384: 				  xmlSchemaTypePtr type)
14385: {
14386:     xmlSchemaTypePtr baseType = NULL;
14387:     xmlSchemaAttributeUsePtr use;
14388:     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14389: 
14390:     if (type->baseType == NULL) {
14391: 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14392: 	    "no base type");
14393:         return (-1);
14394:     }
14395:     baseType = type->baseType;
14396:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
14397: 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14398: 	    return(-1);
14399: 
14400:     uses = type->attrUses;
14401:     baseUses = baseType->attrUses;
14402:     /*
14403:     * Expand attribute group references. And build the 'complete'
14404:     * wildcard, i.e. intersect multiple wildcards.
14405:     * Move attribute prohibitions into a separate list.
14406:     */
14407:     if (uses != NULL) {
14408: 	if (WXS_IS_RESTRICTION(type)) {
14409: 	    /*
14410: 	    * This one will transfer all attr. prohibitions
14411: 	    * into pctxt->attrProhibs.
14412: 	    */
14413: 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14414: 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14415: 		pctxt->attrProhibs) == -1)
14416: 	    {
14417: 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14418: 		"failed to expand attributes");
14419: 	    }
14420: 	    if (pctxt->attrProhibs->nbItems != 0)
14421: 		prohibs = pctxt->attrProhibs;
14422: 	} else {
14423: 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14424: 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14425: 		NULL) == -1)
14426: 	    {
14427: 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14428: 		"failed to expand attributes");
14429: 	    }
14430: 	}
14431:     }
14432:     /*
14433:     * Inherit the attribute uses of the base type.
14434:     */
14435:     if (baseUses != NULL) {
14436: 	int i, j;
14437: 	xmlSchemaAttributeUseProhibPtr pro;
14438: 
14439: 	if (WXS_IS_RESTRICTION(type)) {
14440: 	    int usesCount;
14441: 	    xmlSchemaAttributeUsePtr tmp;
14442: 
14443: 	    if (uses != NULL)
14444: 		usesCount = uses->nbItems;
14445: 	    else
14446: 		usesCount = 0;
14447: 
14448: 	    /* Restriction. */
14449: 	    for (i = 0; i < baseUses->nbItems; i++) {
14450: 		use = baseUses->items[i];
14451: 		if (prohibs) {
14452: 		    /*
14453: 		    * Filter out prohibited uses.
14454: 		    */
14455: 		    for (j = 0; j < prohibs->nbItems; j++) {
14456: 			pro = prohibs->items[j];
14457: 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14458: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
14459: 				pro->targetNamespace))
14460: 			{
14461: 			    goto inherit_next;
14462: 			}
14463: 		    }
14464: 		}
14465: 		if (usesCount) {
14466: 		    /*
14467: 		    * Filter out existing uses.
14468: 		    */
14469: 		    for (j = 0; j < usesCount; j++) {
14470: 			tmp = uses->items[j];
14471: 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
14472: 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
14473: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
14474: 				WXS_ATTRUSE_DECL_TNS(tmp)))
14475: 			{
14476: 			    goto inherit_next;
14477: 			}
14478: 		    }
14479: 		}
14480: 		if (uses == NULL) {
14481: 		    type->attrUses = xmlSchemaItemListCreate();
14482: 		    if (type->attrUses == NULL)
14483: 			goto exit_failure;
14484: 		    uses = type->attrUses;
14485: 		}
14486: 		xmlSchemaItemListAddSize(uses, 2, use);
14487: inherit_next: {}
14488: 	    }
14489: 	} else {
14490: 	    /* Extension. */
14491: 	    for (i = 0; i < baseUses->nbItems; i++) {
14492: 		use = baseUses->items[i];
14493: 		if (uses == NULL) {
14494: 		    type->attrUses = xmlSchemaItemListCreate();
14495: 		    if (type->attrUses == NULL)
14496: 			goto exit_failure;
14497: 		    uses = type->attrUses;
14498: 		}
14499: 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14500: 	    }
14501: 	}
14502:     }
14503:     /*
14504:     * Shrink attr. uses.
14505:     */
14506:     if (uses) {
14507: 	if (uses->nbItems == 0) {
14508: 	    xmlSchemaItemListFree(uses);
14509: 	    type->attrUses = NULL;
14510: 	}
14511: 	/*
14512: 	* TODO: We could shrink the size of the array
14513: 	* to fit the actual number of items.
14514: 	*/
14515:     }
14516:     /*
14517:     * Compute the complete wildcard.
14518:     */
14519:     if (WXS_IS_EXTENSION(type)) {
14520: 	if (baseType->attributeWildcard != NULL) {
14521: 	    /*
14522: 	    * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
14523: 	    * the appropriate case among the following:"
14524: 	    */
14525: 	    if (type->attributeWildcard != NULL) {
14526: 		/*
14527: 		* Union the complete wildcard with the base wildcard.
14528: 		* SPEC {attribute wildcard}
14529: 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14530: 		* and {annotation} are those of the �complete wildcard�,
14531: 		* and whose {namespace constraint} is the intensional union
14532: 		* of the {namespace constraint} of the �complete wildcard�
14533: 		* and of the �base wildcard�, as defined in Attribute
14534: 		* Wildcard Union (�3.10.6)."
14535: 		*/
14536: 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14537: 		    baseType->attributeWildcard) == -1)
14538: 		    goto exit_failure;
14539: 	    } else {
14540: 		/*
14541: 		* (3.2.2.1.1) "If the �complete wildcard� is �absent�,
14542: 		* then the �base wildcard�."
14543: 		*/
14544: 		type->attributeWildcard = baseType->attributeWildcard;
14545: 	    }
14546: 	} else {
14547: 	    /*
14548: 	    * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
14549: 	    * �complete wildcard"
14550: 	    * NOOP
14551: 	    */
14552: 	}
14553:     } else {
14554: 	/*
14555: 	* SPEC {attribute wildcard}
14556: 	* (3.1) "If the <restriction> alternative is chosen, then the
14557: 	* �complete wildcard�;"
14558: 	* NOOP
14559: 	*/
14560:     }
14561: 
14562:     return (0);
14563: 
14564: exit_failure:
14565:     return(-1);
14566: }
14567: 
14568: /**
14569:  * xmlSchemaTypeFinalContains:
14570:  * @schema:  the schema
14571:  * @type:  the type definition
14572:  * @final: the final
14573:  *
14574:  * Evaluates if a type definition contains the given "final".
14575:  * This does take "finalDefault" into account as well.
14576:  *
14577:  * Returns 1 if the type does containt the given "final",
14578:  * 0 otherwise.
14579:  */
14580: static int
14581: xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14582: {
14583:     if (type == NULL)
14584: 	return (0);
14585:     if (type->flags & final)
14586: 	return (1);
14587:     else
14588: 	return (0);
14589: }
14590: 
14591: /**
14592:  * xmlSchemaGetUnionSimpleTypeMemberTypes:
14593:  * @type:  the Union Simple Type
14594:  *
14595:  * Returns a list of member types of @type if existing,
14596:  * returns NULL otherwise.
14597:  */
14598: static xmlSchemaTypeLinkPtr
14599: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14600: {
14601:     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14602: 	if (type->memberTypes != NULL)
14603: 	    return (type->memberTypes);
14604: 	else
14605: 	    type = type->baseType;
14606:     }
14607:     return (NULL);
14608: }
14609: 
14610: /**
14611:  * xmlSchemaGetParticleTotalRangeMin:
14612:  * @particle: the particle
14613:  *
14614:  * Schema Component Constraint: Effective Total Range
14615:  * (all and sequence) + (choice)
14616:  *
14617:  * Returns the minimun Effective Total Range.
14618:  */
14619: static int
14620: xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14621: {
14622:     if ((particle->children == NULL) ||
14623: 	(particle->minOccurs == 0))
14624: 	return (0);
14625:     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14626: 	int min = -1, cur;
14627: 	xmlSchemaParticlePtr part =
14628: 	    (xmlSchemaParticlePtr) particle->children->children;
14629: 
14630: 	if (part == NULL)
14631: 	    return (0);
14632: 	while (part != NULL) {
14633: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14634: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14635: 		cur = part->minOccurs;
14636: 	    else
14637: 		cur = xmlSchemaGetParticleTotalRangeMin(part);
14638: 	    if (cur == 0)
14639: 		return (0);
14640: 	    if ((min > cur) || (min == -1))
14641: 		min = cur;
14642: 	    part = (xmlSchemaParticlePtr) part->next;
14643: 	}
14644: 	return (particle->minOccurs * min);
14645:     } else {
14646: 	/* <all> and <sequence> */
14647: 	int sum = 0;
14648: 	xmlSchemaParticlePtr part =
14649: 	    (xmlSchemaParticlePtr) particle->children->children;
14650: 
14651: 	if (part == NULL)
14652: 	    return (0);
14653: 	do {
14654: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14655: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14656: 		sum += part->minOccurs;
14657: 	    else
14658: 		sum += xmlSchemaGetParticleTotalRangeMin(part);
14659: 	    part = (xmlSchemaParticlePtr) part->next;
14660: 	} while (part != NULL);
14661: 	return (particle->minOccurs * sum);
14662:     }
14663: }
14664: 
14665: #if 0
14666: /**
14667:  * xmlSchemaGetParticleTotalRangeMax:
14668:  * @particle: the particle
14669:  *
14670:  * Schema Component Constraint: Effective Total Range
14671:  * (all and sequence) + (choice)
14672:  *
14673:  * Returns the maximum Effective Total Range.
14674:  */
14675: static int
14676: xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14677: {
14678:     if ((particle->children == NULL) ||
14679: 	(particle->children->children == NULL))
14680: 	return (0);
14681:     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14682: 	int max = -1, cur;
14683: 	xmlSchemaParticlePtr part =
14684: 	    (xmlSchemaParticlePtr) particle->children->children;
14685: 
14686: 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14687: 	    if (part->children == NULL)
14688: 		continue;
14689: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14690: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14691: 		cur = part->maxOccurs;
14692: 	    else
14693: 		cur = xmlSchemaGetParticleTotalRangeMax(part);
14694: 	    if (cur == UNBOUNDED)
14695: 		return (UNBOUNDED);
14696: 	    if ((max < cur) || (max == -1))
14697: 		max = cur;
14698: 	}
14699: 	/* TODO: Handle overflows? */
14700: 	return (particle->maxOccurs * max);
14701:     } else {
14702: 	/* <all> and <sequence> */
14703: 	int sum = 0, cur;
14704: 	xmlSchemaParticlePtr part =
14705: 	    (xmlSchemaParticlePtr) particle->children->children;
14706: 
14707: 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14708: 	    if (part->children == NULL)
14709: 		continue;
14710: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14711: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14712: 		cur = part->maxOccurs;
14713: 	    else
14714: 		cur = xmlSchemaGetParticleTotalRangeMax(part);
14715: 	    if (cur == UNBOUNDED)
14716: 		return (UNBOUNDED);
14717: 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14718: 		return (UNBOUNDED);
14719: 	    sum += cur;
14720: 	}
14721: 	/* TODO: Handle overflows? */
14722: 	return (particle->maxOccurs * sum);
14723:     }
14724: }
14725: #endif
14726: 
14727: /**
14728:  * xmlSchemaIsParticleEmptiable:
14729:  * @particle: the particle
14730:  *
14731:  * Schema Component Constraint: Particle Emptiable
14732:  * Checks whether the given particle is emptiable.
14733:  *
14734:  * Returns 1 if emptiable, 0 otherwise.
14735:  */
14736: static int
14737: xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14738: {
14739:     /*
14740:     * SPEC (1) "Its {min occurs} is 0."
14741:     */
14742:     if ((particle == NULL) || (particle->minOccurs == 0) ||
14743: 	(particle->children == NULL))
14744: 	return (1);
14745:     /*
14746:     * SPEC (2) "Its {term} is a group and the minimum part of the
14747:     * effective total range of that group, [...] is 0."
14748:     */
14749:     if (WXS_IS_MODEL_GROUP(particle->children)) {
14750: 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
14751: 	    return (1);
14752:     }
14753:     return (0);
14754: }
14755: 
14756: /**
14757:  * xmlSchemaCheckCOSSTDerivedOK:
14758:  * @actxt: a context
14759:  * @type:  the derived simple type definition
14760:  * @baseType:  the base type definition
14761:  * @subset: the subset of ('restriction', ect.)
14762:  *
14763:  * Schema Component Constraint:
14764:  * Type Derivation OK (Simple) (cos-st-derived-OK)
14765:  *
14766:  * Checks wheter @type can be validly
14767:  * derived from @baseType.
14768:  *
14769:  * Returns 0 on success, an positive error code otherwise.
14770:  */
14771: static int
14772: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14773: 			     xmlSchemaTypePtr type,
14774: 			     xmlSchemaTypePtr baseType,
14775: 			     int subset)
14776: {
14777:     /*
14778:     * 1 They are the same type definition.
14779:     * TODO: The identy check might have to be more complex than this.
14780:     */
14781:     if (type == baseType)
14782: 	return (0);
14783:     /*
14784:     * 2.1 restriction is not in the subset, or in the {final}
14785:     * of its own {base type definition};
14786:     *
14787:     * NOTE that this will be used also via "xsi:type".
14788:     *
14789:     * TODO: Revise this, it looks strange. How can the "type"
14790:     * not be fixed or *in* fixing?
14791:     */
14792:     if (WXS_IS_TYPE_NOT_FIXED(type))
14793: 	if (xmlSchemaTypeFixup(type, actxt) == -1)
14794: 	    return(-1);
14795:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
14796: 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14797: 	    return(-1);
14798:     if ((subset & SUBSET_RESTRICTION) ||
14799: 	(xmlSchemaTypeFinalContains(type->baseType,
14800: 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14801: 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14802:     }
14803:     /* 2.2 */
14804:     if (type->baseType == baseType) {
14805: 	/*
14806: 	* 2.2.1 D's �base type definition� is B.
14807: 	*/
14808: 	return (0);
14809:     }
14810:     /*
14811:     * 2.2.2 D's �base type definition� is not the �ur-type definition�
14812:     * and is validly derived from B given the subset, as defined by this
14813:     * constraint.
14814:     */
14815:     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14816: 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14817: 	    baseType, subset) == 0)) {
14818: 	return (0);
14819:     }
14820:     /*
14821:     * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
14822:     * definition�.
14823:     */
14824:     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14825: 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14826: 	return (0);
14827:     }
14828:     /*
14829:     * 2.2.4 B's {variety} is union and D is validly derived from a type
14830:     * definition in B's {member type definitions} given the subset, as
14831:     * defined by this constraint.
14832:     *
14833:     * NOTE: This seems not to involve built-in types, since there is no
14834:     * built-in Union Simple Type.
14835:     */
14836:     if (WXS_IS_UNION(baseType)) {
14837: 	xmlSchemaTypeLinkPtr cur;
14838: 
14839: 	cur = baseType->memberTypes;
14840: 	while (cur != NULL) {
14841: 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14842: 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14843: 		    return(-1);
14844: 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14845: 		    type, cur->type, subset) == 0)
14846: 	    {
14847: 		/*
14848: 		* It just has to be validly derived from at least one
14849: 		* member-type.
14850: 		*/
14851: 		return (0);
14852: 	    }
14853: 	    cur = cur->next;
14854: 	}
14855:     }
14856:     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14857: }
14858: 
14859: /**
14860:  * xmlSchemaCheckTypeDefCircularInternal:
14861:  * @pctxt:  the schema parser context
14862:  * @ctxtType:  the type definition
14863:  * @ancestor: an ancestor of @ctxtType
14864:  *
14865:  * Checks st-props-correct (2) + ct-props-correct (3).
14866:  * Circular type definitions are not allowed.
14867:  *
14868:  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14869:  * circular, 0 otherwise.
14870:  */
14871: static int
14872: xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14873: 			   xmlSchemaTypePtr ctxtType,
14874: 			   xmlSchemaTypePtr ancestor)
14875: {
14876:     int ret;
14877: 
14878:     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14879: 	return (0);
14880: 
14881:     if (ctxtType == ancestor) {
14882: 	xmlSchemaPCustomErr(pctxt,
14883: 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
14884: 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14885: 	    "The definition is circular", NULL);
14886: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14887:     }
14888:     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14889: 	/*
14890: 	* Avoid inifinite recursion on circular types not yet checked.
14891: 	*/
14892: 	return (0);
14893:     }
14894:     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14895:     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14896: 	ancestor->baseType);
14897:     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14898:     return (ret);
14899: }
14900: 
14901: /**
14902:  * xmlSchemaCheckTypeDefCircular:
14903:  * @item:  the complex/simple type definition
14904:  * @ctxt:  the parser context
14905:  * @name:  the name
14906:  *
14907:  * Checks for circular type definitions.
14908:  */
14909: static void
14910: xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14911: 			      xmlSchemaParserCtxtPtr ctxt)
14912: {
14913:     if ((item == NULL) ||
14914: 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
14915: 	(item->baseType == NULL))
14916: 	return;
14917:     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14918: 	item->baseType);
14919: }
14920: 
14921: /*
14922: * Simple Type Definition Representation OK (src-simple-type) 4
14923: *
14924: * "4 Circular union type definition is disallowed. That is, if the
14925: * <union> alternative is chosen, there must not be any entries in the
14926: * memberTypes [attribute] at any depth which resolve to the component
14927: * corresponding to the <simpleType>."
14928: *
14929: * Note that this should work on the *representation* of a component,
14930: * thus assumes any union types in the member types not being yet
14931: * substituted. At this stage we need the variety of the types
14932: * to be already computed.
14933: */
14934: static int
14935: xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14936: 					xmlSchemaTypePtr ctxType,
14937: 					xmlSchemaTypeLinkPtr members)
14938: {
14939:     xmlSchemaTypeLinkPtr member;
14940:     xmlSchemaTypePtr memberType;
14941: 
14942:     member = members;
14943:     while (member != NULL) {
14944: 	memberType = member->type;
14945: 	while ((memberType != NULL) &&
14946: 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14947: 	    if (memberType == ctxType) {
14948: 		xmlSchemaPCustomErr(pctxt,
14949: 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14950: 		    WXS_BASIC_CAST ctxType, NULL,
14951: 		    "The union type definition is circular", NULL);
14952: 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14953: 	    }
14954: 	    if ((WXS_IS_UNION(memberType)) &&
14955: 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14956: 	    {
14957: 		int res;
14958: 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14959: 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14960: 		    ctxType,
14961: 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14962: 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14963: 		if (res != 0)
14964: 		    return(res);
14965: 	    }
14966: 	    memberType = memberType->baseType;
14967: 	}
14968: 	member = member->next;
14969:     }
14970:     return(0);
14971: }
14972: 
14973: static int
14974: xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
14975: 				   xmlSchemaTypePtr type)
14976: {
14977:     if (! WXS_IS_UNION(type))
14978: 	return(0);
14979:     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
14980: 	type->memberTypes));
14981: }
14982: 
14983: /**
14984:  * xmlSchemaResolveTypeReferences:
14985:  * @item:  the complex/simple type definition
14986:  * @ctxt:  the parser context
14987:  * @name:  the name
14988:  *
14989:  * Resolvese type definition references
14990:  */
14991: static void
14992: xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
14993: 			 xmlSchemaParserCtxtPtr ctxt)
14994: {
14995:     if (typeDef == NULL)
14996: 	return;
14997: 
14998:     /*
14999:     * Resolve the base type.
15000:     */
15001:     if (typeDef->baseType == NULL) {
15002: 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15003: 	    typeDef->base, typeDef->baseNs);
15004: 	if (typeDef->baseType == NULL) {
15005: 	    xmlSchemaPResCompAttrErr(ctxt,
15006: 		XML_SCHEMAP_SRC_RESOLVE,
15007: 		WXS_BASIC_CAST typeDef, typeDef->node,
15008: 		"base", typeDef->base, typeDef->baseNs,
15009: 		XML_SCHEMA_TYPE_SIMPLE, NULL);
15010: 	    return;
15011: 	}
15012:     }
15013:     if (WXS_IS_SIMPLE(typeDef)) {
15014: 	if (WXS_IS_UNION(typeDef)) {
15015: 	    /*
15016: 	    * Resolve the memberTypes.
15017: 	    */
15018: 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15019: 	    return;
15020: 	} else if (WXS_IS_LIST(typeDef)) {
15021: 	    /*
15022: 	    * Resolve the itemType.
15023: 	    */
15024: 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15025: 
15026: 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15027: 		    typeDef->base, typeDef->baseNs);
15028: 
15029: 		if ((typeDef->subtypes == NULL) ||
15030: 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
15031: 		{
15032: 		    typeDef->subtypes = NULL;
15033: 		    xmlSchemaPResCompAttrErr(ctxt,
15034: 			XML_SCHEMAP_SRC_RESOLVE,
15035: 			WXS_BASIC_CAST typeDef, typeDef->node,
15036: 			"itemType", typeDef->base, typeDef->baseNs,
15037: 			XML_SCHEMA_TYPE_SIMPLE, NULL);
15038: 		}
15039: 	    }
15040: 	    return;
15041: 	}
15042:     }
15043:     /*
15044:     * The ball of letters below means, that if we have a particle
15045:     * which has a QName-helper component as its {term}, we want
15046:     * to resolve it...
15047:     */
15048:     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15049: 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15050: 	    XML_SCHEMA_TYPE_PARTICLE) &&
15051: 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15052: 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15053: 	    XML_SCHEMA_EXTRA_QNAMEREF))
15054:     {
15055: 	xmlSchemaQNameRefPtr ref =
15056: 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15057: 	xmlSchemaModelGroupDefPtr groupDef;
15058: 
15059: 	/*
15060: 	* URGENT TODO: Test this.
15061: 	*/
15062: 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15063: 	/*
15064: 	* Resolve the MG definition reference.
15065: 	*/
15066: 	groupDef =
15067: 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15068: 		ref->itemType, ref->name, ref->targetNamespace);
15069: 	if (groupDef == NULL) {
15070: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15071: 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15072: 		"ref", ref->name, ref->targetNamespace, ref->itemType,
15073: 		NULL);
15074: 	    /* Remove the particle. */
15075: 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15076: 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15077: 	    /* Remove the particle. */
15078: 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15079: 	else {
15080: 	    /*
15081: 	    * Assign the MG definition's {model group} to the
15082: 	    * particle's {term}.
15083: 	    */
15084: 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15085: 
15086: 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15087: 		/*
15088: 		* SPEC cos-all-limited (1.2)
15089: 		* "1.2 the {term} property of a particle with
15090: 		* {max occurs}=1 which is part of a pair which constitutes
15091: 		* the {content type} of a complex type definition."
15092: 		*/
15093: 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15094: 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
15095: 			/* TODO: error code */
15096: 			XML_SCHEMAP_COS_ALL_LIMITED,
15097: 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15098: 			"The particle's {max occurs} must be 1, since the "
15099: 			"reference resolves to an 'all' model group",
15100: 			NULL, NULL);
15101: 		}
15102: 	    }
15103: 	}
15104:     }
15105: }
15106: 
15107: 
15108: 
15109: /**
15110:  * xmlSchemaCheckSTPropsCorrect:
15111:  * @ctxt:  the schema parser context
15112:  * @type:  the simple type definition
15113:  *
15114:  * Checks st-props-correct.
15115:  *
15116:  * Returns 0 if the properties are correct,
15117:  * if not, a positive error code and -1 on internal
15118:  * errors.
15119:  */
15120: static int
15121: xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15122: 			     xmlSchemaTypePtr type)
15123: {
15124:     xmlSchemaTypePtr baseType = type->baseType;
15125:     xmlChar *str = NULL;
15126: 
15127:     /* STATE: error funcs converted. */
15128:     /*
15129:     * Schema Component Constraint: Simple Type Definition Properties Correct
15130:     *
15131:     * NOTE: This is somehow redundant, since we actually built a simple type
15132:     * to have all the needed information; this acts as an self test.
15133:     */
15134:     /* Base type: If the datatype has been �derived� by �restriction�
15135:     * then the Simple Type Definition component from which it is �derived�,
15136:     * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
15137:     */
15138:     if (baseType == NULL) {
15139: 	/*
15140: 	* TODO: Think about: "modulo the impact of Missing
15141: 	* Sub-components (�5.3)."
15142: 	*/
15143: 	xmlSchemaPCustomErr(ctxt,
15144: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15145: 	    WXS_BASIC_CAST type, NULL,
15146: 	    "No base type existent", NULL);
15147: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15148: 
15149:     }
15150:     if (! WXS_IS_SIMPLE(baseType)) {
15151: 	xmlSchemaPCustomErr(ctxt,
15152: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15153: 	    WXS_BASIC_CAST type, NULL,
15154: 	    "The base type '%s' is not a simple type",
15155: 	    xmlSchemaGetComponentQName(&str, baseType));
15156: 	FREE_AND_NULL(str)
15157: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15158:     }
15159:     if ( (WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15160: 	 (WXS_IS_RESTRICTION(type) == 0) &&
15161: 	 (! WXS_IS_ANY_SIMPLE_TYPE(baseType))) {
15162: 	xmlSchemaPCustomErr(ctxt,
15163: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15164: 	    WXS_BASIC_CAST type, NULL,
15165: 	    "A type, derived by list or union, must have "
15166: 	    "the simple ur-type definition as base type, not '%s'",
15167: 	    xmlSchemaGetComponentQName(&str, baseType));
15168: 	FREE_AND_NULL(str)
15169: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15170:     }
15171:     /*
15172:     * Variety: One of {atomic, list, union}.
15173:     */
15174:     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15175: 	(! WXS_IS_LIST(type))) {
15176: 	xmlSchemaPCustomErr(ctxt,
15177: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15178: 	    WXS_BASIC_CAST type, NULL,
15179: 	    "The variety is absent", NULL);
15180: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15181:     }
15182:     /* TODO: Finish this. Hmm, is this finished? */
15183: 
15184:     /*
15185:     * 3 The {final} of the {base type definition} must not contain restriction.
15186:     */
15187:     if (xmlSchemaTypeFinalContains(baseType,
15188: 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15189: 	xmlSchemaPCustomErr(ctxt,
15190: 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
15191: 	    WXS_BASIC_CAST type, NULL,
15192: 	    "The 'final' of its base type '%s' must not contain "
15193: 	    "'restriction'",
15194: 	    xmlSchemaGetComponentQName(&str, baseType));
15195: 	FREE_AND_NULL(str)
15196: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15197:     }
15198: 
15199:     /*
15200:     * 2 All simple type definitions must be derived ultimately from the �simple
15201:     * ur-type definition (so� circular definitions are disallowed). That is, it
15202:     * must be possible to reach a built-in primitive datatype or the �simple
15203:     * ur-type definition� by repeatedly following the {base type definition}.
15204:     *
15205:     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15206:     */
15207:     return (0);
15208: }
15209: 
15210: /**
15211:  * xmlSchemaCheckCOSSTRestricts:
15212:  * @ctxt:  the schema parser context
15213:  * @type:  the simple type definition
15214:  *
15215:  * Schema Component Constraint:
15216:  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15217: 
15218:  * Checks if the given @type (simpleType) is derived validly by restriction.
15219:  * STATUS:
15220:  *
15221:  * Returns -1 on internal errors, 0 if the type is validly derived,
15222:  * a positive error code otherwise.
15223:  */
15224: static int
15225: xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15226: 			     xmlSchemaTypePtr type)
15227: {
15228:     xmlChar *str = NULL;
15229: 
15230:     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15231: 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15232: 	    "given type is not a user-derived simpleType");
15233: 	return (-1);
15234:     }
15235: 
15236:     if (WXS_IS_ATOMIC(type)) {
15237: 	xmlSchemaTypePtr primitive;
15238: 	/*
15239: 	* 1.1 The {base type definition} must be an atomic simple
15240: 	* type definition or a built-in primitive datatype.
15241: 	*/
15242: 	if (! WXS_IS_ATOMIC(type->baseType)) {
15243: 	    xmlSchemaPCustomErr(pctxt,
15244: 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15245: 		WXS_BASIC_CAST type, NULL,
15246: 		"The base type '%s' is not an atomic simple type",
15247: 		xmlSchemaGetComponentQName(&str, type->baseType));
15248: 	    FREE_AND_NULL(str)
15249: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15250: 	}
15251: 	/* 1.2 The {final} of the {base type definition} must not contain
15252: 	* restriction.
15253: 	*/
15254: 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15255: 	if (xmlSchemaTypeFinalContains(type->baseType,
15256: 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15257: 	    xmlSchemaPCustomErr(pctxt,
15258: 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15259: 		WXS_BASIC_CAST type, NULL,
15260: 		"The final of its base type '%s' must not contain 'restriction'",
15261: 		xmlSchemaGetComponentQName(&str, type->baseType));
15262: 	    FREE_AND_NULL(str)
15263: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15264: 	}
15265: 
15266: 	/*
15267: 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
15268: 	* type definition}, as specified in the appropriate subsection of 3.2
15269: 	* Primitive datatypes.
15270: 	*/
15271: 	if (type->facets != NULL) {
15272: 	    xmlSchemaFacetPtr facet;
15273: 	    int ok = 1;
15274: 
15275: 	    primitive = xmlSchemaGetPrimitiveType(type);
15276: 	    if (primitive == NULL) {
15277: 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15278: 		    "failed to get primitive type");
15279: 		return (-1);
15280: 	    }
15281: 	    facet = type->facets;
15282: 	    do {
15283: 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15284: 		    ok = 0;
15285: 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
15286: 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15287: 			type, primitive, facet);
15288: 		}
15289: 		facet = facet->next;
15290: 	    } while (facet != NULL);
15291: 	    if (ok == 0)
15292: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15293: 	}
15294: 	/*
15295: 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15296: 	* of the {base type definition} (call this BF),then the DF's {value}
15297: 	* must be a valid restriction of BF's {value} as defined in
15298: 	* [XML Schemas: Datatypes]."
15299: 	*
15300: 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
15301: 	* xmlSchemaDeriveAndValidateFacets()
15302: 	*/
15303:     } else if (WXS_IS_LIST(type)) {
15304: 	xmlSchemaTypePtr itemType = NULL;
15305: 
15306: 	itemType = type->subtypes;
15307: 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15308: 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15309: 		"failed to evaluate the item type");
15310: 	    return (-1);
15311: 	}
15312: 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
15313: 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15314: 	/*
15315: 	* 2.1 The {item type definition} must have a {variety} of atomic or
15316: 	* union (in which case all the {member type definitions}
15317: 	* must be atomic).
15318: 	*/
15319: 	if ((! WXS_IS_ATOMIC(itemType)) &&
15320: 	    (! WXS_IS_UNION(itemType))) {
15321: 	    xmlSchemaPCustomErr(pctxt,
15322: 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15323: 		WXS_BASIC_CAST type, NULL,
15324: 		"The item type '%s' does not have a variety of atomic or union",
15325: 		xmlSchemaGetComponentQName(&str, itemType));
15326: 	    FREE_AND_NULL(str)
15327: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15328: 	} else if (WXS_IS_UNION(itemType)) {
15329: 	    xmlSchemaTypeLinkPtr member;
15330: 
15331: 	    member = itemType->memberTypes;
15332: 	    while (member != NULL) {
15333: 		if (! WXS_IS_ATOMIC(member->type)) {
15334: 		    xmlSchemaPCustomErr(pctxt,
15335: 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15336: 			WXS_BASIC_CAST type, NULL,
15337: 			"The item type is a union type, but the "
15338: 			"member type '%s' of this item type is not atomic",
15339: 			xmlSchemaGetComponentQName(&str, member->type));
15340: 		    FREE_AND_NULL(str)
15341: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15342: 		}
15343: 		member = member->next;
15344: 	    }
15345: 	}
15346: 
15347: 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15348: 	    xmlSchemaFacetPtr facet;
15349: 	    /*
15350: 	    * This is the case if we have: <simpleType><list ..
15351: 	    */
15352: 	    /*
15353: 	    * 2.3.1
15354: 	    * 2.3.1.1 The {final} of the {item type definition} must not
15355: 	    * contain list.
15356: 	    */
15357: 	    if (xmlSchemaTypeFinalContains(itemType,
15358: 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
15359: 		xmlSchemaPCustomErr(pctxt,
15360: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15361: 		    WXS_BASIC_CAST type, NULL,
15362: 		    "The final of its item type '%s' must not contain 'list'",
15363: 		    xmlSchemaGetComponentQName(&str, itemType));
15364: 		FREE_AND_NULL(str)
15365: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15366: 	    }
15367: 	    /*
15368: 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
15369: 	    * facet component.
15370: 	    * OPTIMIZE TODO: the S4S already disallows any facet
15371: 	    * to be specified.
15372: 	    */
15373: 	    if (type->facets != NULL) {
15374: 		facet = type->facets;
15375: 		do {
15376: 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15377: 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
15378: 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15379: 			    type, facet);
15380: 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15381: 		    }
15382: 		    facet = facet->next;
15383: 		} while (facet != NULL);
15384: 	    }
15385: 	    /*
15386: 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
15387: 	    * A �list� datatype can be �derived� from an �atomic� datatype
15388: 	    * whose �lexical space� allows space (such as string or anyURI)or
15389: 	    * a �union� datatype any of whose {member type definitions}'s
15390: 	    * �lexical space� allows space.
15391: 	    */
15392: 	} else {
15393: 	    /*
15394: 	    * This is the case if we have: <simpleType><restriction ...
15395: 	    * I.e. the variety of "list" is inherited.
15396: 	    */
15397: 	    /*
15398: 	    * 2.3.2
15399: 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
15400: 	    */
15401: 	    if (! WXS_IS_LIST(type->baseType)) {
15402: 		xmlSchemaPCustomErr(pctxt,
15403: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15404: 		    WXS_BASIC_CAST type, NULL,
15405: 		    "The base type '%s' must be a list type",
15406: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15407: 		FREE_AND_NULL(str)
15408: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15409: 	    }
15410: 	    /*
15411: 	    * 2.3.2.2 The {final} of the {base type definition} must not
15412: 	    * contain restriction.
15413: 	    */
15414: 	    if (xmlSchemaTypeFinalContains(type->baseType,
15415: 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15416: 		xmlSchemaPCustomErr(pctxt,
15417: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15418: 		    WXS_BASIC_CAST type, NULL,
15419: 		    "The 'final' of the base type '%s' must not contain 'restriction'",
15420: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15421: 		FREE_AND_NULL(str)
15422: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15423: 	    }
15424: 	    /*
15425: 	    * 2.3.2.3 The {item type definition} must be validly derived
15426: 	    * from the {base type definition}'s {item type definition} given
15427: 	    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
15428: 	    */
15429: 	    {
15430: 		xmlSchemaTypePtr baseItemType;
15431: 
15432: 		baseItemType = type->baseType->subtypes;
15433: 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15434: 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15435: 			"failed to eval the item type of a base type");
15436: 		    return (-1);
15437: 		}
15438: 		if ((itemType != baseItemType) &&
15439: 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15440: 			baseItemType, 0) != 0)) {
15441: 		    xmlChar *strBIT = NULL, *strBT = NULL;
15442: 		    xmlSchemaPCustomErrExt(pctxt,
15443: 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15444: 			WXS_BASIC_CAST type, NULL,
15445: 			"The item type '%s' is not validly derived from "
15446: 			"the item type '%s' of the base type '%s'",
15447: 			xmlSchemaGetComponentQName(&str, itemType),
15448: 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
15449: 			xmlSchemaGetComponentQName(&strBT, type->baseType));
15450: 
15451: 		    FREE_AND_NULL(str)
15452: 		    FREE_AND_NULL(strBIT)
15453: 		    FREE_AND_NULL(strBT)
15454: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15455: 		}
15456: 	    }
15457: 
15458: 	    if (type->facets != NULL) {
15459: 		xmlSchemaFacetPtr facet;
15460: 		int ok = 1;
15461: 		/*
15462: 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15463: 		* and enumeration facet components are allowed among the {facets}.
15464: 		*/
15465: 		facet = type->facets;
15466: 		do {
15467: 		    switch (facet->type) {
15468: 			case XML_SCHEMA_FACET_LENGTH:
15469: 			case XML_SCHEMA_FACET_MINLENGTH:
15470: 			case XML_SCHEMA_FACET_MAXLENGTH:
15471: 			case XML_SCHEMA_FACET_WHITESPACE:
15472: 			    /*
15473: 			    * TODO: 2.5.1.2 List datatypes
15474: 			    * The value of �whiteSpace� is fixed to the value collapse.
15475: 			    */
15476: 			case XML_SCHEMA_FACET_PATTERN:
15477: 			case XML_SCHEMA_FACET_ENUMERATION:
15478: 			    break;
15479: 			default: {
15480: 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
15481: 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15482: 				type, facet);
15483: 			    /*
15484: 			    * We could return, but it's nicer to report all
15485: 			    * invalid facets.
15486: 			    */
15487: 			    ok = 0;
15488: 			}
15489: 		    }
15490: 		    facet = facet->next;
15491: 		} while (facet != NULL);
15492: 		if (ok == 0)
15493: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15494: 		/*
15495: 		* SPEC (2.3.2.5) (same as 1.3.2)
15496: 		*
15497: 		* NOTE (2.3.2.5) This is currently done in
15498: 		* xmlSchemaDeriveAndValidateFacets()
15499: 		*/
15500: 	    }
15501: 	}
15502:     } else if (WXS_IS_UNION(type)) {
15503: 	/*
15504: 	* 3.1 The {member type definitions} must all have {variety} of
15505: 	* atomic or list.
15506: 	*/
15507: 	xmlSchemaTypeLinkPtr member;
15508: 
15509: 	member = type->memberTypes;
15510: 	while (member != NULL) {
15511: 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
15512: 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15513: 
15514: 	    if ((! WXS_IS_ATOMIC(member->type)) &&
15515: 		(! WXS_IS_LIST(member->type))) {
15516: 		xmlSchemaPCustomErr(pctxt,
15517: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15518: 		    WXS_BASIC_CAST type, NULL,
15519: 		    "The member type '%s' is neither an atomic, nor a list type",
15520: 		    xmlSchemaGetComponentQName(&str, member->type));
15521: 		FREE_AND_NULL(str)
15522: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15523: 	    }
15524: 	    member = member->next;
15525: 	}
15526: 	/*
15527: 	* 3.3.1 If the {base type definition} is the �simple ur-type
15528: 	* definition�
15529: 	*/
15530: 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15531: 	    /*
15532: 	    * 3.3.1.1 All of the {member type definitions} must have a
15533: 	    * {final} which does not contain union.
15534: 	    */
15535: 	    member = type->memberTypes;
15536: 	    while (member != NULL) {
15537: 		if (xmlSchemaTypeFinalContains(member->type,
15538: 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
15539: 		    xmlSchemaPCustomErr(pctxt,
15540: 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15541: 			WXS_BASIC_CAST type, NULL,
15542: 			"The 'final' of member type '%s' contains 'union'",
15543: 			xmlSchemaGetComponentQName(&str, member->type));
15544: 		    FREE_AND_NULL(str)
15545: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15546: 		}
15547: 		member = member->next;
15548: 	    }
15549: 	    /*
15550: 	    * 3.3.1.2 The {facets} must be empty.
15551: 	    */
15552: 	    if (type->facetSet != NULL) {
15553: 		xmlSchemaPCustomErr(pctxt,
15554: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15555: 		    WXS_BASIC_CAST type, NULL,
15556: 		    "No facets allowed", NULL);
15557: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15558: 	    }
15559: 	} else {
15560: 	    /*
15561: 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
15562: 	    * I.e. the variety of "list" is inherited.
15563: 	    */
15564: 	    if (! WXS_IS_UNION(type->baseType)) {
15565: 		xmlSchemaPCustomErr(pctxt,
15566: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15567: 		    WXS_BASIC_CAST type, NULL,
15568: 		    "The base type '%s' is not a union type",
15569: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15570: 		FREE_AND_NULL(str)
15571: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15572: 	    }
15573: 	    /*
15574: 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15575: 	    */
15576: 	    if (xmlSchemaTypeFinalContains(type->baseType,
15577: 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15578: 		xmlSchemaPCustomErr(pctxt,
15579: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15580: 		    WXS_BASIC_CAST type, NULL,
15581: 		    "The 'final' of its base type '%s' must not contain 'restriction'",
15582: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15583: 		FREE_AND_NULL(str)
15584: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15585: 	    }
15586: 	    /*
15587: 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
15588: 	    * derived from the corresponding type definitions in the {base
15589: 	    * type definition}'s {member type definitions} given the empty set,
15590: 	    * as defined in Type Derivation OK (Simple) (�3.14.6).
15591: 	    */
15592: 	    {
15593: 		xmlSchemaTypeLinkPtr baseMember;
15594: 
15595: 		/*
15596: 		* OPTIMIZE: if the type is restricting, it has no local defined
15597: 		* member types and inherits the member types of the base type;
15598: 		* thus a check for equality can be skipped.
15599: 		*/
15600: 		/*
15601: 		* Even worse: I cannot see a scenario where a restricting
15602: 		* union simple type can have other member types as the member
15603: 		* types of it's base type. This check seems not necessary with
15604: 		* respect to the derivation process in libxml2.
15605: 		* But necessary if constructing types with an API.
15606: 		*/
15607: 		if (type->memberTypes != NULL) {
15608: 		    member = type->memberTypes;
15609: 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15610: 		    if ((member == NULL) && (baseMember != NULL)) {
15611: 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15612: 			    "different number of member types in base");
15613: 		    }
15614: 		    while (member != NULL) {
15615: 			if (baseMember == NULL) {
15616: 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15617: 			    "different number of member types in base");
15618: 			} else if ((member->type != baseMember->type) &&
15619: 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15620: 				member->type, baseMember->type, 0) != 0)) {
15621: 			    xmlChar *strBMT = NULL, *strBT = NULL;
15622: 
15623: 			    xmlSchemaPCustomErrExt(pctxt,
15624: 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15625: 				WXS_BASIC_CAST type, NULL,
15626: 				"The member type %s is not validly "
15627: 				"derived from its corresponding member "
15628: 				"type %s of the base type %s",
15629: 				xmlSchemaGetComponentQName(&str, member->type),
15630: 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15631: 				xmlSchemaGetComponentQName(&strBT, type->baseType));
15632: 			    FREE_AND_NULL(str)
15633: 			    FREE_AND_NULL(strBMT)
15634: 			    FREE_AND_NULL(strBT)
15635: 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15636: 			}
15637: 			member = member->next;
15638:                         if (baseMember != NULL)
15639:                             baseMember = baseMember->next;
15640: 		    }
15641: 		}
15642: 	    }
15643: 	    /*
15644: 	    * 3.3.2.4 Only pattern and enumeration facet components are
15645: 	    * allowed among the {facets}.
15646: 	    */
15647: 	    if (type->facets != NULL) {
15648: 		xmlSchemaFacetPtr facet;
15649: 		int ok = 1;
15650: 
15651: 		facet = type->facets;
15652: 		do {
15653: 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15654: 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15655: 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
15656: 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15657: 				type, facet);
15658: 			ok = 0;
15659: 		    }
15660: 		    facet = facet->next;
15661: 		} while (facet != NULL);
15662: 		if (ok == 0)
15663: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15664: 
15665: 	    }
15666: 	    /*
15667: 	    * SPEC (3.3.2.5) (same as 1.3.2)
15668: 	    *
15669: 	    * NOTE (3.3.2.5) This is currently done in
15670: 	    * xmlSchemaDeriveAndValidateFacets()
15671: 	    */
15672: 	}
15673:     }
15674: 
15675:     return (0);
15676: }
15677: 
15678: /**
15679:  * xmlSchemaCheckSRCSimpleType:
15680:  * @ctxt:  the schema parser context
15681:  * @type:  the simple type definition
15682:  *
15683:  * Checks crc-simple-type constraints.
15684:  *
15685:  * Returns 0 if the constraints are satisfied,
15686:  * if not a positive error code and -1 on internal
15687:  * errors.
15688:  */
15689: #if 0
15690: static int
15691: xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15692: 			    xmlSchemaTypePtr type)
15693: {
15694:     /*
15695:     * src-simple-type.1 The corresponding simple type definition, if any,
15696:     * must satisfy the conditions set out in Constraints on Simple Type
15697:     * Definition Schema Components (�3.14.6).
15698:     */
15699:     if (WXS_IS_RESTRICTION(type)) {
15700: 	/*
15701: 	* src-simple-type.2 "If the <restriction> alternative is chosen,
15702: 	* either it must have a base [attribute] or a <simpleType> among its
15703: 	* [children], but not both."
15704: 	* NOTE: This is checked in the parse function of <restriction>.
15705: 	*/
15706: 	/*
15707: 	*
15708: 	*/
15709:     } else if (WXS_IS_LIST(type)) {
15710: 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15711: 	* an itemType [attribute] or a <simpleType> among its [children],
15712: 	* but not both."
15713: 	*
15714: 	* NOTE: This is checked in the parse function of <list>.
15715: 	*/
15716:     } else if (WXS_IS_UNION(type)) {
15717: 	/*
15718: 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15719: 	*/
15720:     }
15721:     return (0);
15722: }
15723: #endif
15724: 
15725: static int
15726: xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15727: {
15728:    if (ctxt->vctxt == NULL) {
15729: 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15730: 	if (ctxt->vctxt == NULL) {
15731: 	    xmlSchemaPErr(ctxt, NULL,
15732: 		XML_SCHEMAP_INTERNAL,
15733: 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15734: 		"failed to create a temp. validation context.\n",
15735: 		NULL, NULL);
15736: 	    return (-1);
15737: 	}
15738: 	/* TODO: Pass user data. */
15739: 	xmlSchemaSetValidErrors(ctxt->vctxt,
15740: 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
15741: 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15742: 	    ctxt->serror, ctxt->errCtxt);
15743:     }
15744:     return (0);
15745: }
15746: 
15747: static int
15748: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15749: 			     xmlNodePtr node,
15750: 			     xmlSchemaTypePtr type,
15751: 			     const xmlChar *value,
15752: 			     xmlSchemaValPtr *retVal,
15753: 			     int fireErrors,
15754: 			     int normalize,
15755: 			     int isNormalized);
15756: 
15757: /**
15758:  * xmlSchemaParseCheckCOSValidDefault:
15759:  * @pctxt:  the schema parser context
15760:  * @type:  the simple type definition
15761:  * @value: the default value
15762:  * @node: an optional node (the holder of the value)
15763:  *
15764:  * Schema Component Constraint: Element Default Valid (Immediate)
15765:  * (cos-valid-default)
15766:  * This will be used by the parser only. For the validator there's
15767:  * an other version.
15768:  *
15769:  * Returns 0 if the constraints are satisfied,
15770:  * if not, a positive error code and -1 on internal
15771:  * errors.
15772:  */
15773: static int
15774: xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15775: 				   xmlNodePtr node,
15776: 				   xmlSchemaTypePtr type,
15777: 				   const xmlChar *value,
15778: 				   xmlSchemaValPtr *val)
15779: {
15780:     int ret = 0;
15781: 
15782:     /*
15783:     * cos-valid-default:
15784:     * Schema Component Constraint: Element Default Valid (Immediate)
15785:     * For a string to be a valid default with respect to a type
15786:     * definition the appropriate case among the following must be true:
15787:     */
15788:     if WXS_IS_COMPLEX(type) {
15789: 	/*
15790: 	* Complex type.
15791: 	*
15792: 	* SPEC (2.1) "its {content type} must be a simple type definition
15793: 	* or mixed."
15794: 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
15795: 	* type}'s particle must be �emptiable� as defined by
15796: 	* Particle Emptiable (�3.9.6)."
15797: 	*/
15798: 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15799: 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15800: 	    /* NOTE that this covers (2.2.2) as well. */
15801: 	    xmlSchemaPCustomErr(pctxt,
15802: 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15803: 		WXS_BASIC_CAST type, type->node,
15804: 		"For a string to be a valid default, the type definition "
15805: 		"must be a simple type or a complex type with mixed content "
15806: 		"and a particle emptiable", NULL);
15807: 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15808: 	}
15809:     }
15810:     /*
15811:     * 1 If the type definition is a simple type definition, then the string
15812:     * must be �valid� with respect to that definition as defined by String
15813:     * Valid (�3.14.4).
15814:     *
15815:     * AND
15816:     *
15817:     * 2.2.1 If the {content type} is a simple type definition, then the
15818:     * string must be �valid� with respect to that simple type definition
15819:     * as defined by String Valid (�3.14.4).
15820:     */
15821:     if (WXS_IS_SIMPLE(type))
15822: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15823: 	    type, value, val, 1, 1, 0);
15824:     else if (WXS_HAS_SIMPLE_CONTENT(type))
15825: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15826: 	    type->contentTypeDef, value, val, 1, 1, 0);
15827:     else
15828: 	return (ret);
15829: 
15830:     if (ret < 0) {
15831: 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15832: 	    "calling xmlSchemaVCheckCVCSimpleType()");
15833:     }
15834: 
15835:     return (ret);
15836: }
15837: 
15838: /**
15839:  * xmlSchemaCheckCTPropsCorrect:
15840:  * @ctxt:  the schema parser context
15841:  * @type:  the complex type definition
15842:  *
15843:  *.(4.6) Constraints on Complex Type Definition Schema Components
15844:  * Schema Component Constraint:
15845:  * Complex Type Definition Properties Correct (ct-props-correct)
15846:  * STATUS: (seems) complete
15847:  *
15848:  * Returns 0 if the constraints are satisfied, a positive
15849:  * error code if not and -1 if an internal error occured.
15850:  */
15851: static int
15852: xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15853: 			     xmlSchemaTypePtr type)
15854: {
15855:     /*
15856:     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15857:     *
15858:     * SPEC (1) "The values of the properties of a complex type definition must
15859:     * be as described in the property tableau in The Complex Type Definition
15860:     * Schema Component (�3.4.1), modulo the impact of Missing
15861:     * Sub-components (�5.3)."
15862:     */
15863:     if ((type->baseType != NULL) &&
15864: 	(WXS_IS_SIMPLE(type->baseType)) &&
15865: 	(WXS_IS_EXTENSION(type) == 0)) {
15866: 	/*
15867: 	* SPEC (2) "If the {base type definition} is a simple type definition,
15868: 	* the {derivation method} must be extension."
15869: 	*/
15870: 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
15871: 	    XML_SCHEMAP_SRC_CT_1,
15872: 	    NULL, WXS_BASIC_CAST type,
15873: 	    "If the base type is a simple type, the derivation method must be "
15874: 	    "'extension'", NULL, NULL);
15875: 	return (XML_SCHEMAP_SRC_CT_1);
15876:     }
15877:     /*
15878:     * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
15879:     * definition�. That is, it must be possible to reach the �ur-type
15880:     * definition by repeatedly following the {base type definition}."
15881:     *
15882:     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15883:     */
15884:     /*
15885:     * NOTE that (4) and (5) need the following:
15886:     *   - attribute uses need to be already inherited (apply attr. prohibitions)
15887:     *   - attribute group references need to be expanded already
15888:     *   - simple types need to be typefixed already
15889:     */
15890:     if (type->attrUses &&
15891: 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15892:     {
15893: 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15894: 	xmlSchemaAttributeUsePtr use, tmp;
15895: 	int i, j, hasId = 0;
15896: 
15897: 	for (i = uses->nbItems -1; i >= 0; i--) {
15898: 	    use = uses->items[i];
15899: 
15900: 	    /*
15901: 	    * SPEC ct-props-correct
15902: 	    * (4) "Two distinct attribute declarations in the
15903: 	    * {attribute uses} must not have identical {name}s and
15904: 	    * {target namespace}s."
15905: 	    */
15906: 	    if (i > 0) {
15907: 		for (j = i -1; j >= 0; j--) {
15908: 		    tmp = uses->items[j];
15909: 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
15910: 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
15911: 			(WXS_ATTRUSE_DECL_TNS(use) ==
15912: 			WXS_ATTRUSE_DECL_TNS(tmp)))
15913: 		    {
15914: 			xmlChar *str = NULL;
15915: 
15916: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
15917: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
15918: 			    NULL, WXS_BASIC_CAST type,
15919: 			    "Duplicate %s",
15920: 			    xmlSchemaGetComponentDesignation(&str, use),
15921: 			    NULL);
15922: 			FREE_AND_NULL(str);
15923: 			/*
15924: 			* Remove the duplicate.
15925: 			*/
15926: 			if (xmlSchemaItemListRemove(uses, i) == -1)
15927: 			    goto exit_failure;
15928: 			goto next_use;
15929: 		    }
15930: 		}
15931: 	    }
15932: 	    /*
15933: 	    * SPEC ct-props-correct
15934: 	    * (5) "Two distinct attribute declarations in the
15935: 	    * {attribute uses} must not have {type definition}s which
15936: 	    * are or are derived from ID."
15937: 	    */
15938: 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15939: 		if (xmlSchemaIsDerivedFromBuiltInType(
15940: 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15941: 		{
15942: 		    if (hasId) {
15943: 			xmlChar *str = NULL;
15944: 
15945: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
15946: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
15947: 			    NULL, WXS_BASIC_CAST type,
15948: 			    "There must not exist more than one attribute "
15949: 			    "declaration of type 'xs:ID' "
15950: 			    "(or derived from 'xs:ID'). The %s violates this "
15951: 			    "constraint",
15952: 			    xmlSchemaGetComponentDesignation(&str, use),
15953: 			    NULL);
15954: 			FREE_AND_NULL(str);
15955: 			if (xmlSchemaItemListRemove(uses, i) == -1)
15956: 			    goto exit_failure;
15957: 		    }
15958: 
15959: 		    hasId = 1;
15960: 		}
15961: 	    }
15962: next_use: {}
15963: 	}
15964:     }
15965:     return (0);
15966: exit_failure:
15967:     return(-1);
15968: }
15969: 
15970: static int
15971: xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
15972: 		       xmlSchemaTypePtr typeB)
15973: {
15974:     /*
15975:     * TODO: This should implement component-identity
15976:     * in the future.
15977:     */
15978:     if ((typeA == NULL) || (typeB == NULL))
15979: 	return (0);
15980:     return (typeA == typeB);
15981: }
15982: 
15983: /**
15984:  * xmlSchemaCheckCOSCTDerivedOK:
15985:  * @ctxt:  the schema parser context
15986:  * @type:  the to-be derived complex type definition
15987:  * @baseType:  the base complex type definition
15988:  * @set: the given set
15989:  *
15990:  * Schema Component Constraint:
15991:  * Type Derivation OK (Complex) (cos-ct-derived-ok)
15992:  *
15993:  * STATUS: completed
15994:  *
15995:  * Returns 0 if the constraints are satisfied, or 1
15996:  * if not.
15997:  */
15998: static int
15999: xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16000: 			     xmlSchemaTypePtr type,
16001: 			     xmlSchemaTypePtr baseType,
16002: 			     int set)
16003: {
16004:     int equal = xmlSchemaAreEqualTypes(type, baseType);
16005:     /* TODO: Error codes. */
16006:     /*
16007:     * SPEC "For a complex type definition (call it D, for derived)
16008:     * to be validly derived from a type definition (call this
16009:     * B, for base) given a subset of {extension, restriction}
16010:     * all of the following must be true:"
16011:     */
16012:     if (! equal) {
16013: 	/*
16014: 	* SPEC (1) "If B and D are not the same type definition, then the
16015: 	* {derivation method} of D must not be in the subset."
16016: 	*/
16017: 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16018: 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16019: 	    return (1);
16020:     } else {
16021: 	/*
16022: 	* SPEC (2.1) "B and D must be the same type definition."
16023: 	*/
16024: 	return (0);
16025:     }
16026:     /*
16027:     * SPEC (2.2) "B must be D's {base type definition}."
16028:     */
16029:     if (type->baseType == baseType)
16030: 	return (0);
16031:     /*
16032:     * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
16033:     * definition�."
16034:     */
16035:     if (WXS_IS_ANYTYPE(type->baseType))
16036: 	return (1);
16037: 
16038:     if (WXS_IS_COMPLEX(type->baseType)) {
16039: 	/*
16040: 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16041: 	* must be validly derived from B given the subset as defined by this
16042: 	* constraint."
16043: 	*/
16044: 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16045: 	    baseType, set));
16046:     } else {
16047: 	/*
16048: 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16049: 	* must be validly derived from B given the subset as defined in Type
16050: 	* Derivation OK (Simple) (�3.14.6).
16051: 	*/
16052: 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16053: 	    baseType, set));
16054:     }
16055: }
16056: 
16057: /**
16058:  * xmlSchemaCheckCOSDerivedOK:
16059:  * @type:  the derived simple type definition
16060:  * @baseType:  the base type definition
16061:  *
16062:  * Calls:
16063:  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16064:  *
16065:  * Checks wheter @type can be validly derived from @baseType.
16066:  *
16067:  * Returns 0 on success, an positive error code otherwise.
16068:  */
16069: static int
16070: xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16071: 			   xmlSchemaTypePtr type,
16072: 			   xmlSchemaTypePtr baseType,
16073: 			   int set)
16074: {
16075:     if (WXS_IS_SIMPLE(type))
16076: 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16077:     else
16078: 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16079: }
16080: 
16081: /**
16082:  * xmlSchemaCheckCOSCTExtends:
16083:  * @ctxt:  the schema parser context
16084:  * @type:  the complex type definition
16085:  *
16086:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16087:  * Schema Component Constraint:
16088:  * Derivation Valid (Extension) (cos-ct-extends)
16089:  *
16090:  * STATUS:
16091:  *   missing:
16092:  *     (1.5)
16093:  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16094:  *
16095:  * Returns 0 if the constraints are satisfied, a positive
16096:  * error code if not and -1 if an internal error occured.
16097:  */
16098: static int
16099: xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16100: 			   xmlSchemaTypePtr type)
16101: {
16102:     xmlSchemaTypePtr base = type->baseType;
16103:     /*
16104:     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16105:     * temporarily only.
16106:     */
16107:     /*
16108:     * SPEC (1) "If the {base type definition} is a complex type definition,
16109:     * then all of the following must be true:"
16110:     */
16111:     if (WXS_IS_COMPLEX(base)) {
16112: 	/*
16113: 	* SPEC (1.1) "The {final} of the {base type definition} must not
16114: 	* contain extension."
16115: 	*/
16116: 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16117: 	    xmlSchemaPCustomErr(ctxt,
16118: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16119: 		WXS_BASIC_CAST type, NULL,
16120: 		"The 'final' of the base type definition "
16121: 		"contains 'extension'", NULL);
16122: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16123: 	}
16124: 
16125: 	/*
16126: 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
16127: 	* since they are automatically satisfied through the
16128: 	* inheriting mechanism.
16129: 	* Note that even if redefining components, the inheriting mechanism
16130: 	* is used.
16131: 	*/
16132: #if 0
16133: 	/*
16134: 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16135: 	* uses}
16136: 	* of the complex type definition itself, that is, for every attribute
16137: 	* use in the {attribute uses} of the {base type definition}, there
16138: 	* must be an attribute use in the {attribute uses} of the complex
16139: 	* type definition itself whose {attribute declaration} has the same
16140: 	* {name}, {target namespace} and {type definition} as its attribute
16141: 	* declaration"
16142: 	*/
16143: 	if (base->attrUses != NULL) {
16144: 	    int i, j, found;
16145: 	    xmlSchemaAttributeUsePtr use, buse;
16146: 
16147: 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16148: 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
16149: 		found = 0;
16150: 		if (type->attrUses != NULL) {
16151: 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
16152: 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16153: 		    {
16154: 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
16155: 				WXS_ATTRUSE_DECL_NAME(buse)) &&
16156: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
16157: 				WXS_ATTRUSE_DECL_TNS(buse)) &&
16158: 			    (WXS_ATTRUSE_TYPEDEF(use) ==
16159: 				WXS_ATTRUSE_TYPEDEF(buse))
16160: 			{
16161: 			    found = 1;
16162: 			    break;
16163: 			}
16164: 		    }
16165: 		}
16166: 		if (! found) {
16167: 		    xmlChar *str = NULL;
16168: 
16169: 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16170: 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16171: 			NULL, WXS_BASIC_CAST type,
16172: 			/*
16173: 			* TODO: The report does not indicate that also the
16174: 			* type needs to be the same.
16175: 			*/
16176: 			"This type is missing a matching correspondent "
16177: 			"for its {base type}'s %s in its {attribute uses}",
16178: 			xmlSchemaGetComponentDesignation(&str,
16179: 			    buse->children),
16180: 			NULL);
16181: 		    FREE_AND_NULL(str)
16182: 		}
16183: 	    }
16184: 	}
16185: 	/*
16186: 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16187: 	* definition must also have one, and the base type definition's
16188: 	* {attribute  wildcard}'s {namespace constraint} must be a subset
16189: 	* of the complex  type definition's {attribute wildcard}'s {namespace
16190: 	* constraint}, as defined by Wildcard Subset (�3.10.6)."
16191: 	*/
16192: 
16193: 	/*
16194: 	* MAYBE TODO: Enable if ever needed. But this will be needed only
16195: 	* if created the type via a schema construction API.
16196: 	*/
16197: 	if (base->attributeWildcard != NULL) {
16198: 	    if (type->attributeWilcard == NULL) {
16199: 		xmlChar *str = NULL;
16200: 
16201: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
16202: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16203: 		    NULL, type,
16204: 		    "The base %s has an attribute wildcard, "
16205: 		    "but this type is missing an attribute wildcard",
16206: 		    xmlSchemaGetComponentDesignation(&str, base));
16207: 		FREE_AND_NULL(str)
16208: 
16209: 	    } else if (xmlSchemaCheckCOSNSSubset(
16210: 		base->attributeWildcard, type->attributeWildcard))
16211: 	    {
16212: 		xmlChar *str = NULL;
16213: 
16214: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
16215: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16216: 		    NULL, type,
16217: 		    "The attribute wildcard is not a valid "
16218: 		    "superset of the one in the base %s",
16219: 		    xmlSchemaGetComponentDesignation(&str, base));
16220: 		FREE_AND_NULL(str)
16221: 	    }
16222: 	}
16223: #endif
16224: 	/*
16225: 	* SPEC (1.4) "One of the following must be true:"
16226: 	*/
16227: 	if ((type->contentTypeDef != NULL) &&
16228: 	    (type->contentTypeDef == base->contentTypeDef)) {
16229: 	    /*
16230: 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
16231: 	    * and the {content type} of the complex type definition itself
16232: 	    * must be the same simple type definition"
16233: 	    * PASS
16234: 	    */
16235: 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16236: 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16237: 	    /*
16238: 	    * SPEC (1.4.2) "The {content type} of both the {base type
16239: 	    * definition} and the complex type definition itself must
16240: 	    * be empty."
16241: 	    * PASS
16242: 	    */
16243: 	} else {
16244: 	    /*
16245: 	    * SPEC (1.4.3) "All of the following must be true:"
16246: 	    */
16247: 	    if (type->subtypes == NULL) {
16248: 		/*
16249: 		* SPEC 1.4.3.1 The {content type} of the complex type
16250: 		* definition itself must specify a particle.
16251: 		*/
16252: 		xmlSchemaPCustomErr(ctxt,
16253: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16254: 		    WXS_BASIC_CAST type, NULL,
16255: 		    "The content type must specify a particle", NULL);
16256: 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16257: 	    }
16258: 	    /*
16259: 	    * SPEC (1.4.3.2) "One of the following must be true:"
16260: 	    */
16261: 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16262: 		/*
16263: 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
16264: 		* definition} must be empty.
16265: 		* PASS
16266: 		*/
16267: 	    } else {
16268: 		/*
16269: 		* SPEC (1.4.3.2.2) "All of the following must be true:"
16270: 		*/
16271: 		if ((type->contentType != base->contentType) ||
16272: 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16273: 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16274: 		    /*
16275: 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16276: 		    * or both must be element-only."
16277: 		    */
16278: 		    xmlSchemaPCustomErr(ctxt,
16279: 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16280: 			WXS_BASIC_CAST type, NULL,
16281: 			"The content type of both, the type and its base "
16282: 			"type, must either 'mixed' or 'element-only'", NULL);
16283: 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16284: 		}
16285: 		/*
16286: 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16287: 		* complex type definition must be a �valid extension�
16288: 		* of the {base type definition}'s particle, as defined
16289: 		* in Particle Valid (Extension) (�3.9.6)."
16290: 		*
16291: 		* NOTE that we won't check "Particle Valid (Extension)",
16292: 		* since it is ensured by the derivation process in
16293: 		* xmlSchemaTypeFixup(). We need to implement this when heading
16294: 		* for a construction API
16295: 		* TODO: !! This is needed to be checked if redefining a type !!
16296: 		*/
16297: 	    }
16298: 	    /*
16299: 	    * URGENT TODO (1.5)
16300: 	    */
16301: 	}
16302:     } else {
16303: 	/*
16304: 	* SPEC (2) "If the {base type definition} is a simple type definition,
16305: 	* then all of the following must be true:"
16306: 	*/
16307: 	if (type->contentTypeDef != base) {
16308: 	    /*
16309: 	    * SPEC (2.1) "The {content type} must be the same simple type
16310: 	    * definition."
16311: 	    */
16312: 	    xmlSchemaPCustomErr(ctxt,
16313: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16314: 		WXS_BASIC_CAST type, NULL,
16315: 		"The content type must be the simple base type", NULL);
16316: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16317: 	}
16318: 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16319: 	    /*
16320: 	    * SPEC (2.2) "The {final} of the {base type definition} must not
16321: 	    * contain extension"
16322: 	    * NOTE that this is the same as (1.1).
16323: 	    */
16324: 	    xmlSchemaPCustomErr(ctxt,
16325: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16326: 		WXS_BASIC_CAST type, NULL,
16327: 		"The 'final' of the base type definition "
16328: 		"contains 'extension'", NULL);
16329: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16330: 	}
16331:     }
16332:     return (0);
16333: }
16334: 
16335: /**
16336:  * xmlSchemaCheckDerivationOKRestriction:
16337:  * @ctxt:  the schema parser context
16338:  * @type:  the complex type definition
16339:  *
16340:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16341:  * Schema Component Constraint:
16342:  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16343:  *
16344:  * STATUS:
16345:  *   missing:
16346:  *     (5.4.2) ???
16347:  *
16348:  * ATTENTION:
16349:  * In XML Schema 1.1 this will be:
16350:  * Validation Rule: Checking complex type subsumption
16351:  *
16352:  * Returns 0 if the constraints are satisfied, a positive
16353:  * error code if not and -1 if an internal error occured.
16354:  */
16355: static int
16356: xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16357: 				      xmlSchemaTypePtr type)
16358: {
16359:     xmlSchemaTypePtr base;
16360: 
16361:     /*
16362:     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16363:     * temporarily only.
16364:     */
16365:     base = type->baseType;
16366:     if (! WXS_IS_COMPLEX(base)) {
16367: 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
16368: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16369: 	    type->node, WXS_BASIC_CAST type,
16370: 	    "The base type must be a complex type", NULL, NULL);
16371: 	return(ctxt->err);
16372:     }
16373:     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16374: 	/*
16375: 	* SPEC (1) "The {base type definition} must be a complex type
16376: 	* definition whose {final} does not contain restriction."
16377: 	*/
16378: 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
16379: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16380: 	    type->node, WXS_BASIC_CAST type,
16381: 	    "The 'final' of the base type definition "
16382: 	    "contains 'restriction'", NULL, NULL);
16383: 	return (ctxt->err);
16384:     }
16385:     /*
16386:     * SPEC (2), (3) and (4)
16387:     * Those are handled in a separate function, since the
16388:     * same constraints are needed for redefinition of
16389:     * attribute groups as well.
16390:     */
16391:     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16392: 	XML_SCHEMA_ACTION_DERIVE,
16393: 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16394: 	type->attrUses, base->attrUses,
16395: 	type->attributeWildcard,
16396: 	base->attributeWildcard) == -1)
16397:     {
16398: 	return(-1);
16399:     }
16400:     /*
16401:     * SPEC (5) "One of the following must be true:"
16402:     */
16403:     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16404: 	/*
16405: 	* SPEC (5.1) "The {base type definition} must be the
16406: 	* �ur-type definition�."
16407: 	* PASS
16408: 	*/
16409:     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16410: 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16411: 	/*
16412: 	* SPEC (5.2.1) "The {content type} of the complex type definition
16413: 	* must be a simple type definition"
16414: 	*
16415: 	* SPEC (5.2.2) "One of the following must be true:"
16416: 	*/
16417: 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16418: 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16419: 	{
16420: 	    int err;
16421: 	    /*
16422: 	    * SPEC (5.2.2.1) "The {content type} of the {base type
16423: 	    * definition} must be a simple type definition from which
16424: 	    * the {content type} is validly derived given the empty
16425: 	    * set as defined in Type Derivation OK (Simple) (�3.14.6)."
16426: 	    *
16427: 	    * ATTENTION TODO: This seems not needed if the type implicitely
16428: 	    * derived from the base type.
16429: 	    *
16430: 	    */
16431: 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16432: 		type->contentTypeDef, base->contentTypeDef, 0);
16433: 	    if (err != 0) {
16434: 		xmlChar *strA = NULL, *strB = NULL;
16435: 
16436: 		if (err == -1)
16437: 		    return(-1);
16438: 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
16439: 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16440: 		    NULL, WXS_BASIC_CAST type,
16441: 		    "The {content type} %s is not validly derived from the "
16442: 		    "base type's {content type} %s",
16443: 		    xmlSchemaGetComponentDesignation(&strA,
16444: 			type->contentTypeDef),
16445: 		    xmlSchemaGetComponentDesignation(&strB,
16446: 			base->contentTypeDef));
16447: 		FREE_AND_NULL(strA);
16448: 		FREE_AND_NULL(strB);
16449: 		return(ctxt->err);
16450: 	    }
16451: 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16452: 	    (xmlSchemaIsParticleEmptiable(
16453: 		(xmlSchemaParticlePtr) base->subtypes))) {
16454: 	    /*
16455: 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
16456: 	    * and have a particle which is �emptiable� as defined in
16457: 	    * Particle Emptiable (�3.9.6)."
16458: 	    * PASS
16459: 	    */
16460: 	} else {
16461: 	    xmlSchemaPCustomErr(ctxt,
16462: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16463: 		WXS_BASIC_CAST type, NULL,
16464: 		"The content type of the base type must be either "
16465: 		"a simple type or 'mixed' and an emptiable particle", NULL);
16466: 	    return (ctxt->err);
16467: 	}
16468:     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16469: 	/*
16470: 	* SPEC (5.3.1) "The {content type} of the complex type itself must
16471: 	* be empty"
16472: 	*/
16473: 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16474: 	    /*
16475: 	    * SPEC (5.3.2.1) "The {content type} of the {base type
16476: 	    * definition} must also be empty."
16477: 	    * PASS
16478: 	    */
16479: 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16480: 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16481: 	    xmlSchemaIsParticleEmptiable(
16482: 		(xmlSchemaParticlePtr) base->subtypes)) {
16483: 	    /*
16484: 	    * SPEC (5.3.2.2) "The {content type} of the {base type
16485: 	    * definition} must be elementOnly or mixed and have a particle
16486: 	    * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
16487: 	    * PASS
16488: 	    */
16489: 	} else {
16490: 	    xmlSchemaPCustomErr(ctxt,
16491: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16492: 		WXS_BASIC_CAST type, NULL,
16493: 		"The content type of the base type must be either "
16494: 		"empty or 'mixed' (or 'elements-only') and an emptiable "
16495: 		"particle", NULL);
16496: 	    return (ctxt->err);
16497: 	}
16498:     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16499: 	WXS_HAS_MIXED_CONTENT(type)) {
16500: 	/*
16501: 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
16502: 	* itself must be element-only"
16503: 	*/
16504: 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16505: 	    /*
16506: 	    * SPEC (5.4.1.2) "The {content type} of the complex type
16507: 	    * definition itself and of the {base type definition} must be
16508: 	    * mixed"
16509: 	    */
16510: 	    xmlSchemaPCustomErr(ctxt,
16511: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16512: 		WXS_BASIC_CAST type, NULL,
16513: 		"If the content type is 'mixed', then the content type of the "
16514: 		"base type must also be 'mixed'", NULL);
16515: 	    return (ctxt->err);
16516: 	}
16517: 	/*
16518: 	* SPEC (5.4.2) "The particle of the complex type definition itself
16519: 	* must be a �valid restriction� of the particle of the {content
16520: 	* type} of the {base type definition} as defined in Particle Valid
16521: 	* (Restriction) (�3.9.6).
16522: 	*
16523: 	* URGENT TODO: (5.4.2)
16524: 	*/
16525:     } else {
16526: 	xmlSchemaPCustomErr(ctxt,
16527: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16528: 	    WXS_BASIC_CAST type, NULL,
16529: 	    "The type is not a valid restriction of its base type", NULL);
16530: 	return (ctxt->err);
16531:     }
16532:     return (0);
16533: }
16534: 
16535: /**
16536:  * xmlSchemaCheckCTComponent:
16537:  * @ctxt:  the schema parser context
16538:  * @type:  the complex type definition
16539:  *
16540:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16541:  *
16542:  * Returns 0 if the constraints are satisfied, a positive
16543:  * error code if not and -1 if an internal error occured.
16544:  */
16545: static int
16546: xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16547: 			  xmlSchemaTypePtr type)
16548: {
16549:     int ret;
16550:     /*
16551:     * Complex Type Definition Properties Correct
16552:     */
16553:     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16554:     if (ret != 0)
16555: 	return (ret);
16556:     if (WXS_IS_EXTENSION(type))
16557: 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16558:     else
16559: 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16560:     return (ret);
16561: }
16562: 
16563: /**
16564:  * xmlSchemaCheckSRCCT:
16565:  * @ctxt:  the schema parser context
16566:  * @type:  the complex type definition
16567:  *
16568:  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16569:  * Schema Representation Constraint:
16570:  * Complex Type Definition Representation OK (src-ct)
16571:  *
16572:  * Returns 0 if the constraints are satisfied, a positive
16573:  * error code if not and -1 if an internal error occured.
16574:  */
16575: static int
16576: xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16577: 		    xmlSchemaTypePtr type)
16578: {
16579:     xmlSchemaTypePtr base;
16580:     int ret = 0;
16581: 
16582:     /*
16583:     * TODO: Adjust the error codes here, as I used
16584:     * XML_SCHEMAP_SRC_CT_1 only yet.
16585:     */
16586:     base = type->baseType;
16587:     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16588: 	/*
16589: 	* 1 If the <complexContent> alternative is chosen, the type definition
16590: 	* �resolved� to by the �actual value� of the base [attribute]
16591: 	* must be a complex type definition;
16592: 	*/
16593: 	if (! WXS_IS_COMPLEX(base)) {
16594: 	    xmlChar *str = NULL;
16595: 	    xmlSchemaPCustomErr(ctxt,
16596: 		XML_SCHEMAP_SRC_CT_1,
16597: 		WXS_BASIC_CAST type, type->node,
16598: 		"If using <complexContent>, the base type is expected to be "
16599: 		"a complex type. The base type '%s' is a simple type",
16600: 		xmlSchemaFormatQName(&str, base->targetNamespace,
16601: 		base->name));
16602: 	    FREE_AND_NULL(str)
16603: 	    return (XML_SCHEMAP_SRC_CT_1);
16604: 	}
16605:     } else {
16606: 	/*
16607: 	* SPEC
16608: 	* 2 If the <simpleContent> alternative is chosen, all of the
16609: 	* following must be true:
16610: 	* 2.1 The type definition �resolved� to by the �actual value� of the
16611: 	* base [attribute] must be one of the following:
16612: 	*/
16613: 	if (WXS_IS_SIMPLE(base)) {
16614: 	    if (WXS_IS_EXTENSION(type) == 0) {
16615: 		xmlChar *str = NULL;
16616: 		/*
16617: 		* 2.1.3 only if the <extension> alternative is also
16618: 		* chosen, a simple type definition.
16619: 		*/
16620: 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
16621: 		xmlSchemaPCustomErr(ctxt,
16622: 		    XML_SCHEMAP_SRC_CT_1,
16623: 		    WXS_BASIC_CAST type, NULL,
16624: 		    "If using <simpleContent> and <restriction>, the base "
16625: 		    "type must be a complex type. The base type '%s' is "
16626: 		    "a simple type",
16627: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16628: 			base->name));
16629: 		FREE_AND_NULL(str)
16630: 		return (XML_SCHEMAP_SRC_CT_1);
16631: 	    }
16632: 	} else {
16633: 	    /* Base type is a complex type. */
16634: 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16635: 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16636: 		/*
16637: 		* 2.1.1 a complex type definition whose {content type} is a
16638: 		* simple type definition;
16639: 		* PASS
16640: 		*/
16641: 		if (base->contentTypeDef == NULL) {
16642: 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16643: 			WXS_BASIC_CAST type, NULL,
16644: 			"Internal error: xmlSchemaCheckSRCCT, "
16645: 			"'%s', base type has no content type",
16646: 			type->name);
16647: 		    return (-1);
16648: 		}
16649: 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16650: 		(WXS_IS_RESTRICTION(type))) {
16651: 
16652: 		/*
16653: 		* 2.1.2 only if the <restriction> alternative is also
16654: 		* chosen, a complex type definition whose {content type}
16655: 		* is mixed and a particle emptiable.
16656: 		*/
16657: 		if (! xmlSchemaIsParticleEmptiable(
16658: 		    (xmlSchemaParticlePtr) base->subtypes)) {
16659: 		    ret = XML_SCHEMAP_SRC_CT_1;
16660: 		} else
16661: 		    /*
16662: 		    * Attention: at this point the <simpleType> child is in
16663: 		    * ->contentTypeDef (put there during parsing).
16664: 		    */
16665: 		    if (type->contentTypeDef == NULL) {
16666: 		    xmlChar *str = NULL;
16667: 		    /*
16668: 		    * 2.2 If clause 2.1.2 above is satisfied, then there
16669: 		    * must be a <simpleType> among the [children] of
16670: 		    * <restriction>.
16671: 		    */
16672: 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
16673: 		    xmlSchemaPCustomErr(ctxt,
16674: 			XML_SCHEMAP_SRC_CT_1,
16675: 			WXS_BASIC_CAST type, NULL,
16676: 			"A <simpleType> is expected among the children "
16677: 			"of <restriction>, if <simpleContent> is used and "
16678: 			"the base type '%s' is a complex type",
16679: 			xmlSchemaFormatQName(&str, base->targetNamespace,
16680: 			base->name));
16681: 		    FREE_AND_NULL(str)
16682: 		    return (XML_SCHEMAP_SRC_CT_1);
16683: 		}
16684: 	    } else {
16685: 		ret = XML_SCHEMAP_SRC_CT_1;
16686: 	    }
16687: 	}
16688: 	if (ret > 0) {
16689: 	    xmlChar *str = NULL;
16690: 	    if (WXS_IS_RESTRICTION(type)) {
16691: 		xmlSchemaPCustomErr(ctxt,
16692: 		    XML_SCHEMAP_SRC_CT_1,
16693: 		    WXS_BASIC_CAST type, NULL,
16694: 		    "If <simpleContent> and <restriction> is used, the "
16695: 		    "base type must be a simple type or a complex type with "
16696: 		    "mixed content and particle emptiable. The base type "
16697: 		    "'%s' is none of those",
16698: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16699: 		    base->name));
16700: 	    } else {
16701: 		xmlSchemaPCustomErr(ctxt,
16702: 		    XML_SCHEMAP_SRC_CT_1,
16703: 		    WXS_BASIC_CAST type, NULL,
16704: 		    "If <simpleContent> and <extension> is used, the "
16705: 		    "base type must be a simple type. The base type '%s' "
16706: 		    "is a complex type",
16707: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16708: 		    base->name));
16709: 	    }
16710: 	    FREE_AND_NULL(str)
16711: 	}
16712:     }
16713:     /*
16714:     * SPEC (3) "The corresponding complex type definition component must
16715:     * satisfy the conditions set out in Constraints on Complex Type
16716:     * Definition Schema Components (�3.4.6);"
16717:     * NOTE (3) will be done in xmlSchemaTypeFixup().
16718:     */
16719:     /*
16720:     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16721:     * above for {attribute wildcard} is satisfied, the intensional
16722:     * intersection must be expressible, as defined in Attribute Wildcard
16723:     * Intersection (�3.10.6).
16724:     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16725:     */
16726:     return (ret);
16727: }
16728: 
16729: #ifdef ENABLE_PARTICLE_RESTRICTION
16730: /**
16731:  * xmlSchemaCheckParticleRangeOK:
16732:  * @ctxt:  the schema parser context
16733:  * @type:  the complex type definition
16734:  *
16735:  * (3.9.6) Constraints on Particle Schema Components
16736:  * Schema Component Constraint:
16737:  * Occurrence Range OK (range-ok)
16738:  *
16739:  * STATUS: complete
16740:  *
16741:  * Returns 0 if the constraints are satisfied, a positive
16742:  * error code if not and -1 if an internal error occured.
16743:  */
16744: static int
16745: xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16746: 			      int bmin, int bmax)
16747: {
16748:     if (rmin < bmin)
16749: 	return (1);
16750:     if ((bmax != UNBOUNDED) &&
16751: 	(rmax > bmax))
16752: 	return (1);
16753:     return (0);
16754: }
16755: 
16756: /**
16757:  * xmlSchemaCheckRCaseNameAndTypeOK:
16758:  * @ctxt:  the schema parser context
16759:  * @r: the restricting element declaration particle
16760:  * @b: the base element declaration particle
16761:  *
16762:  * (3.9.6) Constraints on Particle Schema Components
16763:  * Schema Component Constraint:
16764:  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16765:  * (rcase-NameAndTypeOK)
16766:  *
16767:  * STATUS:
16768:  *   MISSING (3.2.3)
16769:  *   CLARIFY: (3.2.2)
16770:  *
16771:  * Returns 0 if the constraints are satisfied, a positive
16772:  * error code if not and -1 if an internal error occured.
16773:  */
16774: static int
16775: xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16776: 				 xmlSchemaParticlePtr r,
16777: 				 xmlSchemaParticlePtr b)
16778: {
16779:     xmlSchemaElementPtr elemR, elemB;
16780: 
16781:     /* TODO: Error codes (rcase-NameAndTypeOK). */
16782:     elemR = (xmlSchemaElementPtr) r->children;
16783:     elemB = (xmlSchemaElementPtr) b->children;
16784:     /*
16785:     * SPEC (1) "The declarations' {name}s and {target namespace}s are
16786:     * the same."
16787:     */
16788:     if ((elemR != elemB) &&
16789: 	((! xmlStrEqual(elemR->name, elemB->name)) ||
16790: 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16791: 	return (1);
16792:     /*
16793:     * SPEC (2) "R's occurrence range is a valid restriction of B's
16794:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16795:     */
16796:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16797: 	    b->minOccurs, b->maxOccurs) != 0)
16798: 	return (1);
16799:     /*
16800:     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16801:     * {scope} are global."
16802:     */
16803:     if (elemR == elemB)
16804: 	return (0);
16805:     /*
16806:     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16807:     */
16808:     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16809: 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16810: 	 return (1);
16811:     /*
16812:     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16813:     * or is not fixed, or R's declaration's {value constraint} is fixed
16814:     * with the same value."
16815:     */
16816:     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16817: 	((elemR->value == NULL) ||
16818: 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16819: 	 /* TODO: Equality of the initial value or normalized or canonical? */
16820: 	 (! xmlStrEqual(elemR->value, elemB->value))))
16821: 	 return (1);
16822:     /*
16823:     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16824:     * definitions} is a subset of B's declaration's {identity-constraint
16825:     * definitions}, if any."
16826:     */
16827:     if (elemB->idcs != NULL) {
16828: 	/* TODO */
16829:     }
16830:     /*
16831:     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16832:     * superset of B's declaration's {disallowed substitutions}."
16833:     */
16834:     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16835: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16836: 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16837: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16838: 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16839: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16840: 	 return (1);
16841:     /*
16842:     * SPEC (3.2.5) "R's {type definition} is validly derived given
16843:     * {extension, list, union} from B's {type definition}"
16844:     *
16845:     * BADSPEC TODO: What's the point of adding "list" and "union" to the
16846:     * set, if the corresponding constraints handle "restriction" and
16847:     * "extension" only?
16848:     *
16849:     */
16850:     {
16851: 	int set = 0;
16852: 
16853: 	set |= SUBSET_EXTENSION;
16854: 	set |= SUBSET_LIST;
16855: 	set |= SUBSET_UNION;
16856: 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16857: 	    elemB->subtypes, set) != 0)
16858: 	    return (1);
16859:     }
16860:     return (0);
16861: }
16862: 
16863: /**
16864:  * xmlSchemaCheckRCaseNSCompat:
16865:  * @ctxt:  the schema parser context
16866:  * @r: the restricting element declaration particle
16867:  * @b: the base wildcard particle
16868:  *
16869:  * (3.9.6) Constraints on Particle Schema Components
16870:  * Schema Component Constraint:
16871:  * Particle Derivation OK (Elt:Any -- NSCompat)
16872:  * (rcase-NSCompat)
16873:  *
16874:  * STATUS: complete
16875:  *
16876:  * Returns 0 if the constraints are satisfied, a positive
16877:  * error code if not and -1 if an internal error occured.
16878:  */
16879: static int
16880: xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16881: 			    xmlSchemaParticlePtr r,
16882: 			    xmlSchemaParticlePtr b)
16883: {
16884:     /* TODO:Error codes (rcase-NSCompat). */
16885:     /*
16886:     * SPEC "For an element declaration particle to be a �valid restriction�
16887:     * of a wildcard particle all of the following must be true:"
16888:     *
16889:     * SPEC (1) "The element declaration's {target namespace} is �valid�
16890:     * with respect to the wildcard's {namespace constraint} as defined by
16891:     * Wildcard allows Namespace Name (�3.10.4)."
16892:     */
16893:     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16894: 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16895: 	return (1);
16896:     /*
16897:     * SPEC (2) "R's occurrence range is a valid restriction of B's
16898:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16899:     */
16900:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16901: 	    b->minOccurs, b->maxOccurs) != 0)
16902: 	return (1);
16903: 
16904:     return (0);
16905: }
16906: 
16907: /**
16908:  * xmlSchemaCheckRCaseRecurseAsIfGroup:
16909:  * @ctxt:  the schema parser context
16910:  * @r: the restricting element declaration particle
16911:  * @b: the base model group particle
16912:  *
16913:  * (3.9.6) Constraints on Particle Schema Components
16914:  * Schema Component Constraint:
16915:  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16916:  * (rcase-RecurseAsIfGroup)
16917:  *
16918:  * STATUS: TODO
16919:  *
16920:  * Returns 0 if the constraints are satisfied, a positive
16921:  * error code if not and -1 if an internal error occured.
16922:  */
16923: static int
16924: xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16925: 				    xmlSchemaParticlePtr r,
16926: 				    xmlSchemaParticlePtr b)
16927: {
16928:     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16929:     TODO
16930:     return (0);
16931: }
16932: 
16933: /**
16934:  * xmlSchemaCheckRCaseNSSubset:
16935:  * @ctxt:  the schema parser context
16936:  * @r: the restricting wildcard 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 (Any:Any -- NSSubset)
16942:  * (rcase-NSSubset)
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 occured.
16948:  */
16949: static int
16950: xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16951: 				    xmlSchemaParticlePtr r,
16952: 				    xmlSchemaParticlePtr b,
16953: 				    int isAnyTypeBase)
16954: {
16955:     /* TODO: Error codes (rcase-NSSubset). */
16956:     /*
16957:     * SPEC (1) "R's occurrence range is a valid restriction of B's
16958:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16959:     */
16960:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16961: 	    b->minOccurs, b->maxOccurs))
16962: 	return (1);
16963:     /*
16964:     * SPEC (2) "R's {namespace constraint} must be an intensional subset
16965:     * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
16966:     */
16967:     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16968: 	(xmlSchemaWildcardPtr) b->children))
16969: 	return (1);
16970:     /*
16971:     * SPEC (3) "Unless B is the content model wildcard of the �ur-type
16972:     * definition�, R's {process contents} must be identical to or stronger
16973:     * than B's {process contents}, where strict is stronger than lax is
16974:     * stronger than skip."
16975:     */
16976:     if (! isAnyTypeBase) {
16977: 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
16978: 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
16979: 	    return (1);
16980:     }
16981: 
16982:     return (0);
16983: }
16984: 
16985: /**
16986:  * xmlSchemaCheckCOSParticleRestrict:
16987:  * @ctxt:  the schema parser context
16988:  * @type:  the complex type definition
16989:  *
16990:  * (3.9.6) Constraints on Particle Schema Components
16991:  * Schema Component Constraint:
16992:  * Particle Valid (Restriction) (cos-particle-restrict)
16993:  *
16994:  * STATUS: TODO
16995:  *
16996:  * Returns 0 if the constraints are satisfied, a positive
16997:  * error code if not and -1 if an internal error occured.
16998:  */
16999: static int
17000: xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17001: 				  xmlSchemaParticlePtr r,
17002: 				  xmlSchemaParticlePtr b)
17003: {
17004:     int ret = 0;
17005: 
17006:     /*part = WXS_TYPE_PARTICLE(type);
17007:     basePart = WXS_TYPE_PARTICLE(base);
17008:     */
17009: 
17010:     TODO
17011: 
17012:     /*
17013:     * SPEC (1) "They are the same particle."
17014:     */
17015:     if (r == b)
17016: 	return (0);
17017: 
17018: 
17019:     return (0);
17020: }
17021: 
17022: #if 0
17023: /**
17024:  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17025:  * @ctxt:  the schema parser context
17026:  * @r: the model group particle
17027:  * @b: the base wildcard particle
17028:  *
17029:  * (3.9.6) Constraints on Particle Schema Components
17030:  * Schema Component Constraint:
17031:  * Particle Derivation OK (All/Choice/Sequence:Any --
17032:  *                         NSRecurseCheckCardinality)
17033:  * (rcase-NSRecurseCheckCardinality)
17034:  *
17035:  * STATUS: TODO: subst-groups
17036:  *
17037:  * Returns 0 if the constraints are satisfied, a positive
17038:  * error code if not and -1 if an internal error occured.
17039:  */
17040: static int
17041: xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17042: 					     xmlSchemaParticlePtr r,
17043: 					     xmlSchemaParticlePtr b)
17044: {
17045:     xmlSchemaParticlePtr part;
17046:     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17047:     if ((r->children == NULL) || (r->children->children == NULL))
17048: 	return (-1);
17049:     /*
17050:     * SPEC "For a group particle to be a �valid restriction� of a
17051:     * wildcard particle..."
17052:     *
17053:     * SPEC (1) "Every member of the {particles} of the group is a �valid
17054:     * restriction� of the wildcard as defined by
17055:     * Particle Valid (Restriction) (�3.9.6)."
17056:     */
17057:     part = (xmlSchemaParticlePtr) r->children->children;
17058:     do {
17059: 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17060: 	    return (1);
17061: 	part = (xmlSchemaParticlePtr) part->next;
17062:     } while (part != NULL);
17063:     /*
17064:     * SPEC (2) "The effective total range of the group [...] is a
17065:     * valid restriction of B's occurrence range as defined by
17066:     * Occurrence Range OK (�3.9.6)."
17067:     */
17068:     if (xmlSchemaCheckParticleRangeOK(
17069: 	    xmlSchemaGetParticleTotalRangeMin(r),
17070: 	    xmlSchemaGetParticleTotalRangeMax(r),
17071: 	    b->minOccurs, b->maxOccurs) != 0)
17072: 	return (1);
17073:     return (0);
17074: }
17075: #endif
17076: 
17077: /**
17078:  * xmlSchemaCheckRCaseRecurse:
17079:  * @ctxt:  the schema parser context
17080:  * @r: the <all> or <sequence> model group particle
17081:  * @b: the base <all> or <sequence> model group particle
17082:  *
17083:  * (3.9.6) Constraints on Particle Schema Components
17084:  * Schema Component Constraint:
17085:  * Particle Derivation OK (All:All,Sequence:Sequence --
17086:                            Recurse)
17087:  * (rcase-Recurse)
17088:  *
17089:  * STATUS:  ?
17090:  * TODO: subst-groups
17091:  *
17092:  * Returns 0 if the constraints are satisfied, a positive
17093:  * error code if not and -1 if an internal error occured.
17094:  */
17095: static int
17096: xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17097: 			   xmlSchemaParticlePtr r,
17098: 			   xmlSchemaParticlePtr b)
17099: {
17100:     /* xmlSchemaParticlePtr part; */
17101:     /* TODO: Error codes (rcase-Recurse). */
17102:     if ((r->children == NULL) || (b->children == NULL) ||
17103: 	(r->children->type != b->children->type))
17104: 	return (-1);
17105:     /*
17106:     * SPEC "For an all or sequence group particle to be a �valid
17107:     * restriction� of another group particle with the same {compositor}..."
17108:     *
17109:     * SPEC (1) "R's occurrence range is a valid restriction of B's
17110:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
17111:     */
17112:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17113: 	    b->minOccurs, b->maxOccurs))
17114: 	return (1);
17115: 
17116: 
17117:     return (0);
17118: }
17119: 
17120: #endif
17121: 
17122: #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17123:     xmlSchemaPCustomErrExt(pctxt,      \
17124: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17125: 	WXS_BASIC_CAST fac1, fac1->node, \
17126: 	"It is an error for both '%s' and '%s' to be specified on the "\
17127: 	"same type definition", \
17128: 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17129: 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17130: 
17131: #define FACET_RESTR_ERR(fac1, msg) \
17132:     xmlSchemaPCustomErr(pctxt,      \
17133: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17134: 	WXS_BASIC_CAST fac1, fac1->node, \
17135: 	msg, NULL);
17136: 
17137: #define FACET_RESTR_FIXED_ERR(fac) \
17138:     xmlSchemaPCustomErr(pctxt, \
17139: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17140: 	WXS_BASIC_CAST fac, fac->node, \
17141: 	"The base type's facet is 'fixed', thus the value must not " \
17142: 	"differ", NULL);
17143: 
17144: static void
17145: xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17146: 			xmlSchemaFacetPtr facet1,
17147: 			xmlSchemaFacetPtr facet2,
17148: 			int lessGreater,
17149: 			int orEqual,
17150: 			int ofBase)
17151: {
17152:     xmlChar *msg = NULL;
17153: 
17154:     msg = xmlStrdup(BAD_CAST "'");
17155:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17156:     msg = xmlStrcat(msg, BAD_CAST "' has to be");
17157:     if (lessGreater == 0)
17158: 	msg = xmlStrcat(msg, BAD_CAST " equal to");
17159:     if (lessGreater == 1)
17160: 	msg = xmlStrcat(msg, BAD_CAST " greater than");
17161:     else
17162: 	msg = xmlStrcat(msg, BAD_CAST " less than");
17163: 
17164:     if (orEqual)
17165: 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
17166:     msg = xmlStrcat(msg, BAD_CAST " '");
17167:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17168:     if (ofBase)
17169: 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17170:     else
17171: 	msg = xmlStrcat(msg, BAD_CAST "'");
17172: 
17173:     xmlSchemaPCustomErr(pctxt,
17174: 	XML_SCHEMAP_INVALID_FACET_VALUE,
17175: 	WXS_BASIC_CAST facet1, NULL,
17176: 	(const char *) msg, NULL);
17177: 
17178:     if (msg != NULL)
17179: 	xmlFree(msg);
17180: }
17181: 
17182: /*
17183: * xmlSchemaDeriveAndValidateFacets:
17184: *
17185: * Schema Component Constraint: Simple Type Restriction (Facets)
17186: * (st-restrict-facets)
17187: */
17188: static int
17189: xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17190: 				 xmlSchemaTypePtr type)
17191: {
17192:     xmlSchemaTypePtr base = type->baseType;
17193:     xmlSchemaFacetLinkPtr link, cur, last = NULL;
17194:     xmlSchemaFacetPtr facet, bfacet,
17195: 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
17196: 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17197: 	fmininc = NULL, fmaxinc = NULL,
17198: 	fminexc = NULL, fmaxexc = NULL,
17199: 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17200: 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17201: 	bfmininc = NULL, bfmaxinc = NULL,
17202: 	bfminexc = NULL, bfmaxexc = NULL;
17203:     int res; /* err = 0, fixedErr; */
17204: 
17205:     /*
17206:     * SPEC st-restrict-facets 1:
17207:     * "The {variety} of R is the same as that of B."
17208:     */
17209:     /*
17210:     * SPEC st-restrict-facets 2:
17211:     * "If {variety} is atomic, the {primitive type definition}
17212:     * of R is the same as that of B."
17213:     *
17214:     * NOTE: we leave 1 & 2 out for now, since this will be
17215:     * satisfied by the derivation process.
17216:     * CONSTRUCTION TODO: Maybe needed if using a construction API.
17217:     */
17218:     /*
17219:     * SPEC st-restrict-facets 3:
17220:     * "The {facets} of R are the union of S and the {facets}
17221:     * of B, eliminating duplicates. To eliminate duplicates,
17222:     * when a facet of the same kind occurs in both S and the
17223:     * {facets} of B, the one in the {facets} of B is not
17224:     * included, with the exception of enumeration and pattern
17225:     * facets, for which multiple occurrences with distinct values
17226:     * are allowed."
17227:     */
17228: 
17229:     if ((type->facetSet == NULL) && (base->facetSet == NULL))
17230: 	return (0);
17231: 
17232:     last = type->facetSet;
17233:     if (last != NULL)
17234: 	while (last->next != NULL)
17235: 	    last = last->next;
17236: 
17237:     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17238: 	facet = cur->facet;
17239: 	switch (facet->type) {
17240: 	    case XML_SCHEMA_FACET_LENGTH:
17241: 		flength = facet; break;
17242: 	    case XML_SCHEMA_FACET_MINLENGTH:
17243: 		fminlen = facet; break;
17244: 	    case XML_SCHEMA_FACET_MININCLUSIVE:
17245: 		fmininc = facet; break;
17246: 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
17247: 		fminexc = facet; break;
17248: 	    case XML_SCHEMA_FACET_MAXLENGTH:
17249: 		fmaxlen = facet; break;
17250: 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
17251: 		fmaxinc = facet; break;
17252: 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17253: 		fmaxexc = facet; break;
17254: 	    case XML_SCHEMA_FACET_TOTALDIGITS:
17255: 		ftotdig = facet; break;
17256: 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
17257: 		ffracdig = facet; break;
17258: 	    default:
17259: 		break;
17260: 	}
17261:     }
17262:     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17263: 	facet = cur->facet;
17264: 	switch (facet->type) {
17265: 	    case XML_SCHEMA_FACET_LENGTH:
17266: 		bflength = facet; break;
17267: 	    case XML_SCHEMA_FACET_MINLENGTH:
17268: 		bfminlen = facet; break;
17269: 	    case XML_SCHEMA_FACET_MININCLUSIVE:
17270: 		bfmininc = facet; break;
17271: 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
17272: 		bfminexc = facet; break;
17273: 	    case XML_SCHEMA_FACET_MAXLENGTH:
17274: 		bfmaxlen = facet; break;
17275: 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
17276: 		bfmaxinc = facet; break;
17277: 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17278: 		bfmaxexc = facet; break;
17279: 	    case XML_SCHEMA_FACET_TOTALDIGITS:
17280: 		bftotdig = facet; break;
17281: 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
17282: 		bffracdig = facet; break;
17283: 	    default:
17284: 		break;
17285: 	}
17286:     }
17287:     /*
17288:     * length and minLength or maxLength (2.2) + (3.2)
17289:     */
17290:     if (flength && (fminlen || fmaxlen)) {
17291: 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17292: 	    "either of 'minLength' or 'maxLength' to be specified on "
17293: 	    "the same type definition")
17294:     }
17295:     /*
17296:     * Mutual exclusions in the same derivation step.
17297:     */
17298:     if ((fmaxinc) && (fmaxexc)) {
17299: 	/*
17300: 	* SCC "maxInclusive and maxExclusive"
17301: 	*/
17302: 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17303:     }
17304:     if ((fmininc) && (fminexc)) {
17305: 	/*
17306: 	* SCC "minInclusive and minExclusive"
17307: 	*/
17308: 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17309:     }
17310: 
17311:     if (flength && bflength) {
17312: 	/*
17313: 	* SCC "length valid restriction"
17314: 	* The values have to be equal.
17315: 	*/
17316: 	res = xmlSchemaCompareValues(flength->val, bflength->val);
17317: 	if (res == -2)
17318: 	    goto internal_error;
17319: 	if (res != 0)
17320: 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17321: 	if ((res != 0) && (bflength->fixed)) {
17322: 	    FACET_RESTR_FIXED_ERR(flength)
17323: 	}
17324: 
17325:     }
17326:     if (fminlen && bfminlen) {
17327: 	/*
17328: 	* SCC "minLength valid restriction"
17329: 	* minLength >= BASE minLength
17330: 	*/
17331: 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17332: 	if (res == -2)
17333: 	    goto internal_error;
17334: 	if (res == -1)
17335: 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17336: 	if ((res != 0) && (bfminlen->fixed)) {
17337: 	    FACET_RESTR_FIXED_ERR(fminlen)
17338: 	}
17339:     }
17340:     if (fmaxlen && bfmaxlen) {
17341: 	/*
17342: 	* SCC "maxLength valid restriction"
17343: 	* maxLength <= BASE minLength
17344: 	*/
17345: 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17346: 	if (res == -2)
17347: 	    goto internal_error;
17348: 	if (res == 1)
17349: 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17350: 	if ((res != 0) && (bfmaxlen->fixed)) {
17351: 	    FACET_RESTR_FIXED_ERR(fmaxlen)
17352: 	}
17353:     }
17354:     /*
17355:     * SCC "length and minLength or maxLength"
17356:     */
17357:     if (! flength)
17358: 	flength = bflength;
17359:     if (flength) {
17360: 	if (! fminlen)
17361: 	    fminlen = bfminlen;
17362: 	if (fminlen) {
17363: 	    /* (1.1) length >= minLength */
17364: 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
17365: 	    if (res == -2)
17366: 		goto internal_error;
17367: 	    if (res == -1)
17368: 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17369: 	}
17370: 	if (! fmaxlen)
17371: 	    fmaxlen = bfmaxlen;
17372: 	if (fmaxlen) {
17373: 	    /* (2.1) length <= maxLength */
17374: 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17375: 	    if (res == -2)
17376: 		goto internal_error;
17377: 	    if (res == 1)
17378: 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17379: 	}
17380:     }
17381:     if (fmaxinc) {
17382: 	/*
17383: 	* "maxInclusive"
17384: 	*/
17385: 	if (fmininc) {
17386: 	    /* SCC "maxInclusive >= minInclusive" */
17387: 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17388: 	    if (res == -2)
17389: 		goto internal_error;
17390: 	    if (res == -1) {
17391: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17392: 	    }
17393: 	}
17394: 	/*
17395: 	* SCC "maxInclusive valid restriction"
17396: 	*/
17397: 	if (bfmaxinc) {
17398: 	    /* maxInclusive <= BASE maxInclusive */
17399: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17400: 	    if (res == -2)
17401: 		goto internal_error;
17402: 	    if (res == 1)
17403: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17404: 	    if ((res != 0) && (bfmaxinc->fixed)) {
17405: 		FACET_RESTR_FIXED_ERR(fmaxinc)
17406: 	    }
17407: 	}
17408: 	if (bfmaxexc) {
17409: 	    /* maxInclusive < BASE maxExclusive */
17410: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17411: 	    if (res == -2)
17412: 		goto internal_error;
17413: 	    if (res != -1) {
17414: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17415: 	    }
17416: 	}
17417: 	if (bfmininc) {
17418: 	    /* maxInclusive >= BASE minInclusive */
17419: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17420: 	    if (res == -2)
17421: 		goto internal_error;
17422: 	    if (res == -1) {
17423: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17424: 	    }
17425: 	}
17426: 	if (bfminexc) {
17427: 	    /* maxInclusive > BASE minExclusive */
17428: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17429: 	    if (res == -2)
17430: 		goto internal_error;
17431: 	    if (res != 1) {
17432: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17433: 	    }
17434: 	}
17435:     }
17436:     if (fmaxexc) {
17437: 	/*
17438: 	* "maxExclusive >= minExclusive"
17439: 	*/
17440: 	if (fminexc) {
17441: 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17442: 	    if (res == -2)
17443: 		goto internal_error;
17444: 	    if (res == -1) {
17445: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17446: 	    }
17447: 	}
17448: 	/*
17449: 	* "maxExclusive valid restriction"
17450: 	*/
17451: 	if (bfmaxexc) {
17452: 	    /* maxExclusive <= BASE maxExclusive */
17453: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17454: 	    if (res == -2)
17455: 		goto internal_error;
17456: 	    if (res == 1) {
17457: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17458: 	    }
17459: 	    if ((res != 0) && (bfmaxexc->fixed)) {
17460: 		FACET_RESTR_FIXED_ERR(fmaxexc)
17461: 	    }
17462: 	}
17463: 	if (bfmaxinc) {
17464: 	    /* maxExclusive <= BASE maxInclusive */
17465: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17466: 	    if (res == -2)
17467: 		goto internal_error;
17468: 	    if (res == 1) {
17469: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17470: 	    }
17471: 	}
17472: 	if (bfmininc) {
17473: 	    /* maxExclusive > BASE minInclusive */
17474: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17475: 	    if (res == -2)
17476: 		goto internal_error;
17477: 	    if (res != 1) {
17478: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17479: 	    }
17480: 	}
17481: 	if (bfminexc) {
17482: 	    /* maxExclusive > BASE minExclusive */
17483: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17484: 	    if (res == -2)
17485: 		goto internal_error;
17486: 	    if (res != 1) {
17487: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17488: 	    }
17489: 	}
17490:     }
17491:     if (fminexc) {
17492: 	/*
17493: 	* "minExclusive < maxInclusive"
17494: 	*/
17495: 	if (fmaxinc) {
17496: 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17497: 	    if (res == -2)
17498: 		goto internal_error;
17499: 	    if (res != -1) {
17500: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17501: 	    }
17502: 	}
17503: 	/*
17504: 	* "minExclusive valid restriction"
17505: 	*/
17506: 	if (bfminexc) {
17507: 	    /* minExclusive >= BASE minExclusive */
17508: 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17509: 	    if (res == -2)
17510: 		goto internal_error;
17511: 	    if (res == -1) {
17512: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17513: 	    }
17514: 	    if ((res != 0) && (bfminexc->fixed)) {
17515: 		FACET_RESTR_FIXED_ERR(fminexc)
17516: 	    }
17517: 	}
17518: 	if (bfmaxinc) {
17519: 	    /* minExclusive <= BASE maxInclusive */
17520: 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17521: 	    if (res == -2)
17522: 		goto internal_error;
17523: 	    if (res == 1) {
17524: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17525: 	    }
17526: 	}
17527: 	if (bfmininc) {
17528: 	    /* minExclusive >= BASE minInclusive */
17529: 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17530: 	    if (res == -2)
17531: 		goto internal_error;
17532: 	    if (res == -1) {
17533: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17534: 	    }
17535: 	}
17536: 	if (bfmaxexc) {
17537: 	    /* minExclusive < BASE maxExclusive */
17538: 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17539: 	    if (res == -2)
17540: 		goto internal_error;
17541: 	    if (res != -1) {
17542: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17543: 	    }
17544: 	}
17545:     }
17546:     if (fmininc) {
17547: 	/*
17548: 	* "minInclusive < maxExclusive"
17549: 	*/
17550: 	if (fmaxexc) {
17551: 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17552: 	    if (res == -2)
17553: 		goto internal_error;
17554: 	    if (res != -1) {
17555: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17556: 	    }
17557: 	}
17558: 	/*
17559: 	* "minExclusive valid restriction"
17560: 	*/
17561: 	if (bfmininc) {
17562: 	    /* minInclusive >= BASE minInclusive */
17563: 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17564: 	    if (res == -2)
17565: 		goto internal_error;
17566: 	    if (res == -1) {
17567: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17568: 	    }
17569: 	    if ((res != 0) && (bfmininc->fixed)) {
17570: 		FACET_RESTR_FIXED_ERR(fmininc)
17571: 	    }
17572: 	}
17573: 	if (bfmaxinc) {
17574: 	    /* minInclusive <= BASE maxInclusive */
17575: 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17576: 	    if (res == -2)
17577: 		goto internal_error;
17578: 	    if (res == 1) {
17579: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17580: 	    }
17581: 	}
17582: 	if (bfminexc) {
17583: 	    /* minInclusive > BASE minExclusive */
17584: 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17585: 	    if (res == -2)
17586: 		goto internal_error;
17587: 	    if (res != 1)
17588: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17589: 	}
17590: 	if (bfmaxexc) {
17591: 	    /* minInclusive < BASE maxExclusive */
17592: 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17593: 	    if (res == -2)
17594: 		goto internal_error;
17595: 	    if (res != -1)
17596: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17597: 	}
17598:     }
17599:     if (ftotdig && bftotdig) {
17600: 	/*
17601: 	* SCC " totalDigits valid restriction"
17602: 	* totalDigits <= BASE totalDigits
17603: 	*/
17604: 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17605: 	if (res == -2)
17606: 	    goto internal_error;
17607: 	if (res == 1)
17608: 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17609: 	    -1, 1, 1);
17610: 	if ((res != 0) && (bftotdig->fixed)) {
17611: 	    FACET_RESTR_FIXED_ERR(ftotdig)
17612: 	}
17613:     }
17614:     if (ffracdig && bffracdig) {
17615: 	/*
17616: 	* SCC  "fractionDigits valid restriction"
17617: 	* fractionDigits <= BASE fractionDigits
17618: 	*/
17619: 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17620: 	if (res == -2)
17621: 	    goto internal_error;
17622: 	if (res == 1)
17623: 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17624: 	    -1, 1, 1);
17625: 	if ((res != 0) && (bffracdig->fixed)) {
17626: 	    FACET_RESTR_FIXED_ERR(ffracdig)
17627: 	}
17628:     }
17629:     /*
17630:     * SCC "fractionDigits less than or equal to totalDigits"
17631:     */
17632:     if (! ftotdig)
17633: 	ftotdig = bftotdig;
17634:     if (! ffracdig)
17635: 	ffracdig = bffracdig;
17636:     if (ftotdig && ffracdig) {
17637: 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17638: 	if (res == -2)
17639: 	    goto internal_error;
17640: 	if (res == 1)
17641: 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17642: 		-1, 1, 0);
17643:     }
17644:     /*
17645:     * *Enumerations* won' be added here, since only the first set
17646:     * of enumerations in the ancestor-or-self axis is used
17647:     * for validation, plus we need to use the base type of those
17648:     * enumerations for whitespace.
17649:     *
17650:     * *Patterns*: won't be add here, since they are ORed at
17651:     * type level and ANDed at ancestor level. This will
17652:     * happed during validation by walking the base axis
17653:     * of the type.
17654:     */
17655:     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17656: 	bfacet = cur->facet;
17657: 	/*
17658: 	* Special handling of enumerations and patterns.
17659: 	* TODO: hmm, they should not appear in the set, so remove this.
17660: 	*/
17661: 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17662: 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17663: 	    continue;
17664: 	/*
17665: 	* Search for a duplicate facet in the current type.
17666: 	*/
17667: 	link = type->facetSet;
17668: 	/* err = 0; */
17669: 	/* fixedErr = 0; */
17670: 	while (link != NULL) {
17671: 	    facet = link->facet;
17672: 	    if (facet->type == bfacet->type) {
17673: 		switch (facet->type) {
17674: 		    case XML_SCHEMA_FACET_WHITESPACE:
17675: 			/*
17676: 			* The whitespace must be stronger.
17677: 			*/
17678: 			if (facet->whitespace < bfacet->whitespace) {
17679: 			    FACET_RESTR_ERR(facet,
17680: 				"The 'whitespace' value has to be equal to "
17681: 				"or stronger than the 'whitespace' value of "
17682: 				"the base type")
17683: 			}
17684: 			if ((bfacet->fixed) &&
17685: 			    (facet->whitespace != bfacet->whitespace)) {
17686: 			    FACET_RESTR_FIXED_ERR(facet)
17687: 			}
17688: 			break;
17689: 		    default:
17690: 			break;
17691: 		}
17692: 		/* Duplicate found. */
17693: 		break;
17694: 	    }
17695: 	    link = link->next;
17696: 	}
17697: 	/*
17698: 	* If no duplicate was found: add the base types's facet
17699: 	* to the set.
17700: 	*/
17701: 	if (link == NULL) {
17702: 	    link = (xmlSchemaFacetLinkPtr)
17703: 		xmlMalloc(sizeof(xmlSchemaFacetLink));
17704: 	    if (link == NULL) {
17705: 		xmlSchemaPErrMemory(pctxt,
17706: 		    "deriving facets, creating a facet link", NULL);
17707: 		return (-1);
17708: 	    }
17709: 	    link->facet = cur->facet;
17710: 	    link->next = NULL;
17711: 	    if (last == NULL)
17712: 		type->facetSet = link;
17713: 	    else
17714: 		last->next = link;
17715: 	    last = link;
17716: 	}
17717: 
17718:     }
17719: 
17720:     return (0);
17721: internal_error:
17722:     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17723: 	"an error occured");
17724:     return (-1);
17725: }
17726: 
17727: static int
17728: xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17729: 					     xmlSchemaTypePtr type)
17730: {
17731:     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17732:     /*
17733:     * The actual value is then formed by replacing any union type
17734:     * definition in the �explicit members� with the members of their
17735:     * {member type definitions}, in order.
17736:     *
17737:     * TODO: There's a bug entry at
17738:     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17739:     * which indicates that we'll keep the union types the future.
17740:     */
17741:     link = type->memberTypes;
17742:     while (link != NULL) {
17743: 
17744: 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
17745: 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17746: 
17747: 	if (WXS_IS_UNION(link->type)) {
17748: 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17749: 	    if (subLink != NULL) {
17750: 		link->type = subLink->type;
17751: 		if (subLink->next != NULL) {
17752: 		    lastLink = link->next;
17753: 		    subLink = subLink->next;
17754: 		    prevLink = link;
17755: 		    while (subLink != NULL) {
17756: 			newLink = (xmlSchemaTypeLinkPtr)
17757: 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
17758: 			if (newLink == NULL) {
17759: 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
17760: 				NULL);
17761: 			    return (-1);
17762: 			}
17763: 			newLink->type = subLink->type;
17764: 			prevLink->next = newLink;
17765: 			prevLink = newLink;
17766: 			newLink->next = lastLink;
17767: 
17768: 			subLink = subLink->next;
17769: 		    }
17770: 		}
17771: 	    }
17772: 	}
17773: 	link = link->next;
17774:     }
17775:     return (0);
17776: }
17777: 
17778: static void
17779: xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17780: {
17781:     int has = 0, needVal = 0, normVal = 0;
17782: 
17783:     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17784:     if (has) {
17785: 	needVal = (type->baseType->flags &
17786: 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17787: 	normVal = (type->baseType->flags &
17788: 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17789:     }
17790:     if (type->facets != NULL) {
17791: 	xmlSchemaFacetPtr fac;
17792: 
17793: 	for (fac = type->facets; fac != NULL; fac = fac->next) {
17794: 	    switch (fac->type) {
17795: 		case XML_SCHEMA_FACET_WHITESPACE:
17796: 		    break;
17797: 		case XML_SCHEMA_FACET_PATTERN:
17798: 		    normVal = 1;
17799: 		    has = 1;
17800: 		    break;
17801: 		case XML_SCHEMA_FACET_ENUMERATION:
17802: 		    needVal = 1;
17803: 		    normVal = 1;
17804: 		    has = 1;
17805: 		    break;
17806: 		default:
17807: 		    has = 1;
17808: 		    break;
17809: 	    }
17810: 	}
17811:     }
17812:     if (normVal)
17813: 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17814:     if (needVal)
17815: 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17816:     if (has)
17817: 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17818: 
17819:     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17820: 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17821: 	/*
17822: 	* OPTIMIZE VAL TODO: Some facets need a computed value.
17823: 	*/
17824: 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17825: 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
17826: 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17827: 	}
17828:     }
17829: }
17830: 
17831: static int
17832: xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17833: {
17834: 
17835: 
17836:     /*
17837:     * Evaluate the whitespace-facet value.
17838:     */
17839:     if (WXS_IS_LIST(type)) {
17840: 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17841: 	return (0);
17842:     } else if (WXS_IS_UNION(type))
17843: 	return (0);
17844: 
17845:     if (type->facetSet != NULL) {
17846: 	xmlSchemaFacetLinkPtr lin;
17847: 
17848: 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17849: 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17850: 		switch (lin->facet->whitespace) {
17851: 		case XML_SCHEMAS_FACET_PRESERVE:
17852: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17853: 		    break;
17854: 		case XML_SCHEMAS_FACET_REPLACE:
17855: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17856: 		    break;
17857: 		case XML_SCHEMAS_FACET_COLLAPSE:
17858: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17859: 		    break;
17860: 		default:
17861: 		    return (-1);
17862: 		}
17863: 		return (0);
17864: 	    }
17865: 	}
17866:     }
17867:     /*
17868:     * For all �atomic� datatypes other than string (and types �derived�
17869:     * by �restriction� from it) the value of whiteSpace is fixed to
17870:     * collapse
17871:     */
17872:     {
17873: 	xmlSchemaTypePtr anc;
17874: 
17875: 	for (anc = type->baseType; anc != NULL &&
17876: 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
17877: 		anc = anc->baseType) {
17878: 
17879: 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17880: 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17881: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17882: 
17883: 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17884: 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17885: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17886: 
17887: 		} else
17888: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17889: 		break;
17890: 	    }
17891: 	}
17892:     }
17893:     return (0);
17894: }
17895: 
17896: static int
17897: xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17898: 			  xmlSchemaTypePtr type)
17899: {
17900:     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17901: 	return(0);
17902:     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17903: 	return(0);
17904:     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17905: 
17906:     if (WXS_IS_LIST(type)) {
17907: 	/*
17908: 	* Corresponds to <simpleType><list>...
17909: 	*/
17910: 	if (type->subtypes == NULL) {
17911: 	    /*
17912: 	    * This one is really needed, so get out.
17913: 	    */
17914: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17915: 		"list type has no item-type assigned");
17916: 	    return(-1);
17917: 	}
17918:     } else if (WXS_IS_UNION(type)) {
17919: 	/*
17920: 	* Corresponds to <simpleType><union>...
17921: 	*/
17922: 	if (type->memberTypes == NULL) {
17923: 	    /*
17924: 	    * This one is really needed, so get out.
17925: 	    */
17926: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17927: 		"union type has no member-types assigned");
17928: 	    return(-1);
17929: 	}
17930:     } else {
17931: 	/*
17932: 	* Corresponds to <simpleType><restriction>...
17933: 	*/
17934: 	if (type->baseType == NULL) {
17935: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17936: 		"type has no base-type assigned");
17937: 	    return(-1);
17938: 	}
17939: 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17940: 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17941: 		return(-1);
17942: 	/*
17943: 	* Variety
17944: 	* If the <restriction> alternative is chosen, then the
17945: 	* {variety} of the {base type definition}.
17946: 	*/
17947: 	if (WXS_IS_ATOMIC(type->baseType))
17948: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17949: 	else if (WXS_IS_LIST(type->baseType)) {
17950: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17951: 	    /*
17952: 	    * Inherit the itemType.
17953: 	    */
17954: 	    type->subtypes = type->baseType->subtypes;
17955: 	} else if (WXS_IS_UNION(type->baseType)) {
17956: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17957: 	    /*
17958: 	    * NOTE that we won't assign the memberTypes of the base,
17959: 	    * since this will make trouble when freeing them; we will
17960: 	    * use a lookup function to access them instead.
17961: 	    */
17962: 	}
17963:     }
17964:     return(0);
17965: }
17966: 
17967: #ifdef DEBUG_TYPE
17968: static void
17969: xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
17970: 		       xmlSchemaTypePtr type)
17971: {
17972:     if (type->node != NULL) {
17973:         xmlGenericError(xmlGenericErrorContext,
17974:                         "Type of %s : %s:%d :", name,
17975:                         type->node->doc->URL,
17976:                         xmlGetLineNo(type->node));
17977:     } else {
17978:         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
17979:     }
17980:     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
17981: 	switch (type->contentType) {
17982: 	    case XML_SCHEMA_CONTENT_SIMPLE:
17983: 		xmlGenericError(xmlGenericErrorContext, "simple\n");
17984: 		break;
17985: 	    case XML_SCHEMA_CONTENT_ELEMENTS:
17986: 		xmlGenericError(xmlGenericErrorContext, "elements\n");
17987: 		break;
17988: 	    case XML_SCHEMA_CONTENT_UNKNOWN:
17989: 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
17990: 		break;
17991: 	    case XML_SCHEMA_CONTENT_EMPTY:
17992: 		xmlGenericError(xmlGenericErrorContext, "empty\n");
17993: 		break;
17994: 	    case XML_SCHEMA_CONTENT_MIXED:
17995: 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
17996: 		    type->subtypes))
17997: 		    xmlGenericError(xmlGenericErrorContext,
17998: 			"mixed as emptiable particle\n");
17999: 		else
18000: 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
18001: 		break;
18002: 		/* Removed, since not used. */
18003: 		/*
18004: 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18005: 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18006: 		break;
18007: 		*/
18008: 	    case XML_SCHEMA_CONTENT_BASIC:
18009: 		xmlGenericError(xmlGenericErrorContext, "basic\n");
18010: 		break;
18011: 	    default:
18012: 		xmlGenericError(xmlGenericErrorContext,
18013: 		    "not registered !!!\n");
18014: 		break;
18015: 	}
18016:     }
18017: }
18018: #endif
18019: 
18020: /*
18021: * 3.14.6 Constraints on Simple Type Definition Schema Components
18022: */
18023: static int
18024: xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18025: 				 xmlSchemaTypePtr type)
18026: {
18027:     int res, olderrs = pctxt->nberrors;
18028: 
18029:     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18030: 	return(-1);
18031: 
18032:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18033: 	return(0);
18034: 
18035:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18036:     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18037: 
18038:     if (type->baseType == NULL) {
18039: 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18040: 	    "missing baseType");
18041: 	goto exit_failure;
18042:     }
18043:     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18044: 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18045:     /*
18046:     * If a member type of a union is a union itself, we need to substitute
18047:     * that member type for its member types.
18048:     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18049:     * types in WXS 1.1.
18050:     */
18051:     if ((type->memberTypes != NULL) &&
18052: 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18053: 	return(-1);
18054:     /*
18055:     * SPEC src-simple-type 1
18056:     * "The corresponding simple type definition, if any, must satisfy
18057:     * the conditions set out in Constraints on Simple Type Definition
18058:     * Schema Components (�3.14.6)."
18059:     */
18060:     /*
18061:     * Schema Component Constraint: Simple Type Definition Properties Correct
18062:     * (st-props-correct)
18063:     */
18064:     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18065:     HFAILURE HERROR
18066:     /*
18067:     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18068:     * (cos-st-restricts)
18069:     */
18070:     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18071:     HFAILURE HERROR
18072:     /*
18073:     * TODO: Removed the error report, since it got annoying to get an
18074:     * extra error report, if anything failed until now.
18075:     * Enable this if needed.
18076:     *
18077:     * xmlSchemaPErr(ctxt, type->node,
18078:     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18079:     *    "Simple type '%s' does not satisfy the constraints "
18080:     *    "on simple type definitions.\n",
18081:     *    type->name, NULL);
18082:     */
18083:     /*
18084:     * Schema Component Constraint: Simple Type Restriction (Facets)
18085:     * (st-restrict-facets)
18086:     */
18087:     res = xmlSchemaCheckFacetValues(type, pctxt);
18088:     HFAILURE HERROR
18089:     if ((type->facetSet != NULL) ||
18090: 	(type->baseType->facetSet != NULL)) {
18091: 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18092: 	HFAILURE HERROR
18093:     }
18094:     /*
18095:     * Whitespace value.
18096:     */
18097:     res = xmlSchemaTypeFixupWhitespace(type);
18098:     HFAILURE HERROR
18099:     xmlSchemaTypeFixupOptimFacets(type);
18100: 
18101: exit_error:
18102: #ifdef DEBUG_TYPE
18103:     xmlSchemaDebugFixedType(pctxt, type);
18104: #endif
18105:     if (olderrs != pctxt->nberrors)
18106: 	return(pctxt->err);
18107:     return(0);
18108: 
18109: exit_failure:
18110: #ifdef DEBUG_TYPE
18111:     xmlSchemaDebugFixedType(pctxt, type);
18112: #endif
18113:     return(-1);
18114: }
18115: 
18116: static int
18117: xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18118: 			  xmlSchemaTypePtr type)
18119: {
18120:     int res = 0, olderrs = pctxt->nberrors;
18121:     xmlSchemaTypePtr baseType = type->baseType;
18122: 
18123:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18124: 	return(0);
18125:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18126:     if (baseType == NULL) {
18127: 	PERROR_INT("xmlSchemaFixupComplexType",
18128: 	    "missing baseType");
18129: 	goto exit_failure;
18130:     }
18131:     /*
18132:     * Fixup the base type.
18133:     */
18134:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
18135: 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18136:     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18137: 	/*
18138: 	* Skip fixup if the base type is invalid.
18139: 	* TODO: Generate a warning!
18140: 	*/
18141: 	return(0);
18142:     }
18143:     /*
18144:     * This basically checks if the base type can be derived.
18145:     */
18146:     res = xmlSchemaCheckSRCCT(pctxt, type);
18147:     HFAILURE HERROR
18148:     /*
18149:     * Fixup the content type.
18150:     */
18151:     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18152: 	/*
18153: 	* Corresponds to <complexType><simpleContent>...
18154: 	*/
18155: 	if ((WXS_IS_COMPLEX(baseType)) &&
18156: 	    (baseType->contentTypeDef != NULL) &&
18157: 	    (WXS_IS_RESTRICTION(type))) {
18158: 	    xmlSchemaTypePtr contentBase, content;
18159: #ifdef ENABLE_NAMED_LOCALS
18160: 	    char buf[30];
18161: 	    const xmlChar *tmpname;
18162: #endif
18163: 	    /*
18164: 	    * SPEC (1) If <restriction> + base type is <complexType>,
18165: 	    * "whose own {content type} is a simple type..."
18166: 	    */
18167: 	    if (type->contentTypeDef != NULL) {
18168: 		/*
18169: 		* SPEC (1.1) "the simple type definition corresponding to the
18170: 		* <simpleType> among the [children] of <restriction> if there
18171: 		* is one;"
18172: 		* Note that this "<simpleType> among the [children]" was put
18173: 		* into ->contentTypeDef during parsing.
18174: 		*/
18175: 		contentBase = type->contentTypeDef;
18176: 		type->contentTypeDef = NULL;
18177: 	    } else {
18178: 		/*
18179: 		* (1.2) "...otherwise (<restriction> has no <simpleType>
18180: 		* among its [children]), the simple type definition which
18181: 		* is the {content type} of the ... base type."
18182: 		*/
18183: 		contentBase = baseType->contentTypeDef;
18184: 	    }
18185: 	    /*
18186: 	    * SPEC
18187: 	    * "... a simple type definition which restricts the simple
18188: 	    * type definition identified in clause 1.1 or clause 1.2
18189: 	    * with a set of facet components"
18190: 	    *
18191: 	    * Create the anonymous simple type, which will be the content
18192: 	    * type of the complex type.
18193: 	    */
18194: #ifdef ENABLE_NAMED_LOCALS
18195: 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18196: 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18197: 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
18198: 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18199: 		type->node, 0);
18200: #else
18201: 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
18202: 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18203: 		type->node, 0);
18204: #endif
18205: 	    if (content == NULL)
18206: 		goto exit_failure;
18207: 	    /*
18208: 	    * We will use the same node as for the <complexType>
18209: 	    * to have it somehow anchored in the schema doc.
18210: 	    */
18211: 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
18212: 	    content->baseType = contentBase;
18213: 	    /*
18214: 	    * Move the facets, previously anchored on the
18215: 	    * complexType during parsing.
18216: 	    */
18217: 	    content->facets = type->facets;
18218: 	    type->facets = NULL;
18219: 	    content->facetSet = type->facetSet;
18220: 	    type->facetSet = NULL;
18221: 
18222: 	    type->contentTypeDef = content;
18223: 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18224: 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18225: 	    /*
18226: 	    * Fixup the newly created type. We don't need to check
18227: 	    * for circularity here.
18228: 	    */
18229: 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18230: 	    HFAILURE HERROR
18231: 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18232: 	    HFAILURE HERROR
18233: 
18234: 	} else if ((WXS_IS_COMPLEX(baseType)) &&
18235: 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18236: 	    (WXS_IS_RESTRICTION(type))) {
18237: 	    /*
18238: 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
18239: 	    * an emptiable particle, then a simple type definition which
18240: 	    * restricts the <restriction>'s <simpleType> child.
18241: 	    */
18242: 	    if ((type->contentTypeDef == NULL) ||
18243: 		(type->contentTypeDef->baseType == NULL)) {
18244: 		/*
18245: 		* TODO: Check if this ever happens.
18246: 		*/
18247: 		xmlSchemaPCustomErr(pctxt,
18248: 		    XML_SCHEMAP_INTERNAL,
18249: 		    WXS_BASIC_CAST type, NULL,
18250: 		    "Internal error: xmlSchemaTypeFixup, "
18251: 		    "complex type '%s': the <simpleContent><restriction> "
18252: 		    "is missing a <simpleType> child, but was not catched "
18253: 		    "by xmlSchemaCheckSRCCT()", type->name);
18254: 		goto exit_failure;
18255: 	    }
18256: 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18257: 	    /*
18258: 	    * SPEC (3) If <extension> + base is <complexType> with
18259: 	    * <simpleType> content, "...then the {content type} of that
18260: 	    * complex type definition"
18261: 	    */
18262: 	    if (baseType->contentTypeDef == NULL) {
18263: 		/*
18264: 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18265: 		* should have catched this already.
18266: 		*/
18267: 		xmlSchemaPCustomErr(pctxt,
18268: 		    XML_SCHEMAP_INTERNAL,
18269: 		    WXS_BASIC_CAST type, NULL,
18270: 		    "Internal error: xmlSchemaTypeFixup, "
18271: 		    "complex type '%s': the <extension>ed base type is "
18272: 		    "a complex type with no simple content type",
18273: 		    type->name);
18274: 		goto exit_failure;
18275: 	    }
18276: 	    type->contentTypeDef = baseType->contentTypeDef;
18277: 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18278: 	    /*
18279: 	    * SPEC (4) <extension> + base is <simpleType>
18280: 	    * "... then that simple type definition"
18281: 	    */
18282: 	    type->contentTypeDef = baseType;
18283: 	} else {
18284: 	    /*
18285: 	    * TODO: Check if this ever happens.
18286: 	    */
18287: 	    xmlSchemaPCustomErr(pctxt,
18288: 		XML_SCHEMAP_INTERNAL,
18289: 		WXS_BASIC_CAST type, NULL,
18290: 		"Internal error: xmlSchemaTypeFixup, "
18291: 		"complex type '%s' with <simpleContent>: unhandled "
18292: 		"derivation case", type->name);
18293: 	    goto exit_failure;
18294: 	}
18295:     } else {
18296: 	int dummySequence = 0;
18297: 	xmlSchemaParticlePtr particle =
18298: 	    (xmlSchemaParticlePtr) type->subtypes;
18299: 	/*
18300: 	* Corresponds to <complexType><complexContent>...
18301: 	*
18302: 	* NOTE that the effective mixed was already set during parsing of
18303: 	* <complexType> and <complexContent>; its flag value is
18304: 	* XML_SCHEMAS_TYPE_MIXED.
18305: 	*
18306: 	* Compute the "effective content":
18307: 	* (2.1.1) + (2.1.2) + (2.1.3)
18308: 	*/
18309: 	if ((particle == NULL) ||
18310: 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18311: 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18312: 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18313: 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18314: 	    (particle->minOccurs == 0))) &&
18315: 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18316: 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18317: 		/*
18318: 		* SPEC (2.1.4) "If the �effective mixed� is true, then
18319: 		* a particle whose properties are as follows:..."
18320: 		*
18321: 		* Empty sequence model group with
18322: 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18323: 		* NOTE that we sill assign it the <complexType> node to
18324: 		* somehow anchor it in the doc.
18325: 		*/
18326: 		if ((particle == NULL) ||
18327: 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18328: 		    /*
18329: 		    * Create the particle.
18330: 		    */
18331: 		    particle = xmlSchemaAddParticle(pctxt,
18332: 			type->node, 1, 1);
18333: 		    if (particle == NULL)
18334: 			goto exit_failure;
18335: 		    /*
18336: 		    * Create the model group.
18337: 		    */ /* URGENT TODO: avoid adding to pending items. */
18338: 		    particle->children = (xmlSchemaTreeItemPtr)
18339: 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18340: 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
18341: 		    if (particle->children == NULL)
18342: 			goto exit_failure;
18343: 
18344: 		    type->subtypes = (xmlSchemaTypePtr) particle;
18345: 		}
18346: 		dummySequence = 1;
18347: 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18348: 	    } else {
18349: 		/*
18350: 		* SPEC (2.1.5) "otherwise empty"
18351: 		*/
18352: 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18353: 	    }
18354: 	} else {
18355: 	    /*
18356: 	    * SPEC (2.2) "otherwise the particle corresponding to the
18357: 	    * <all>, <choice>, <group> or <sequence> among the
18358: 	    * [children]."
18359: 	    */
18360: 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18361: 	}
18362: 	/*
18363: 	* Compute the "content type".
18364: 	*/
18365: 	if (WXS_IS_RESTRICTION(type)) {
18366: 	    /*
18367: 	    * SPEC (3.1) "If <restriction>..."
18368: 	    * (3.1.1) + (3.1.2) */
18369: 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18370: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18371: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18372: 	    }
18373: 	} else {
18374: 	    /*
18375: 	    * SPEC (3.2) "If <extension>..."
18376: 	    */
18377: 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18378: 		/*
18379: 		* SPEC (3.2.1)
18380: 		* "If the �effective content� is empty, then the
18381: 		*  {content type} of the [...] base ..."
18382: 		*/
18383: 		type->contentType = baseType->contentType;
18384: 		type->subtypes = baseType->subtypes;
18385: 		/*
18386: 		* Fixes bug #347316:
18387: 		* This is the case when the base type has a simple
18388: 		* type definition as content.
18389: 		*/
18390: 		type->contentTypeDef = baseType->contentTypeDef;
18391: 		/*
18392: 		* NOTE that the effective mixed is ignored here.
18393: 		*/
18394: 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18395: 		/*
18396: 		* SPEC (3.2.2)
18397: 		*/
18398: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18399: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18400: 	    } else {
18401: 		/*
18402: 		* SPEC (3.2.3)
18403: 		*/
18404: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18405: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18406: 		    /*
18407: 		    * "A model group whose {compositor} is sequence and whose
18408: 		    * {particles} are..."
18409: 		    */
18410: 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18411: 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18412: 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18413: 			XML_SCHEMA_TYPE_ALL))
18414: 		{
18415: 		    /*
18416: 		    * SPEC cos-all-limited (1)
18417: 		    */
18418: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18419: 			/* TODO: error code */
18420: 			XML_SCHEMAP_COS_ALL_LIMITED,
18421: 			WXS_ITEM_NODE(type), NULL,
18422: 			"The type has an 'all' model group in its "
18423: 			"{content type} and thus cannot be derived from "
18424: 			"a non-empty type, since this would produce a "
18425: 			"'sequence' model group containing the 'all' "
18426: 			"model group; 'all' model groups are not "
18427: 			"allowed to appear inside other model groups",
18428: 			NULL, NULL);
18429: 
18430: 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18431: 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18432: 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18433: 			XML_SCHEMA_TYPE_ALL))
18434: 		{
18435: 		    /*
18436: 		    * SPEC cos-all-limited (1)
18437: 		    */
18438: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18439: 			/* TODO: error code */
18440: 			XML_SCHEMAP_COS_ALL_LIMITED,
18441: 			WXS_ITEM_NODE(type), NULL,
18442: 			"A type cannot be derived by extension from a type "
18443: 			"which has an 'all' model group in its "
18444: 			"{content type}, since this would produce a "
18445: 			"'sequence' model group containing the 'all' "
18446: 			"model group; 'all' model groups are not "
18447: 			"allowed to appear inside other model groups",
18448: 			NULL, NULL);
18449: 
18450: 		} else if (! dummySequence) {
18451: 		    xmlSchemaTreeItemPtr effectiveContent =
18452: 			(xmlSchemaTreeItemPtr) type->subtypes;
18453: 		    /*
18454: 		    * Create the particle.
18455: 		    */
18456: 		    particle = xmlSchemaAddParticle(pctxt,
18457: 			type->node, 1, 1);
18458: 		    if (particle == NULL)
18459: 			goto exit_failure;
18460: 		    /*
18461: 		    * Create the "sequence" model group.
18462: 		    */
18463: 		    particle->children = (xmlSchemaTreeItemPtr)
18464: 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18465: 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
18466: 		    if (particle->children == NULL)
18467: 			goto exit_failure;
18468: 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18469: 		    /*
18470: 		    * SPEC "the particle of the {content type} of
18471: 		    * the ... base ..."
18472: 		    * Create a duplicate of the base type's particle
18473: 		    * and assign its "term" to it.
18474: 		    */
18475: 		    particle->children->children =
18476: 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18477: 			type->node,
18478: 			((xmlSchemaParticlePtr) type->subtypes)->minOccurs,
18479: 			((xmlSchemaParticlePtr) type->subtypes)->maxOccurs);
18480: 		    if (particle->children->children == NULL)
18481: 			goto exit_failure;
18482: 		    particle = (xmlSchemaParticlePtr)
18483: 			particle->children->children;
18484: 		    particle->children =
18485: 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
18486: 		    /*
18487: 		    * SPEC "followed by the �effective content�."
18488: 		    */
18489: 		    particle->next = effectiveContent;
18490: 		    /*
18491: 		    * This all will result in:
18492: 		    * new-particle
18493: 		    *   --> new-sequence(
18494: 		    *         new-particle
18495: 		    *           --> base-model,
18496: 		    *         this-particle
18497: 		    *	        --> this-model
18498: 		    *	    )
18499: 		    */
18500: 		} else {
18501: 		    /*
18502: 		    * This is the case when there is already an empty
18503: 		    * <sequence> with minOccurs==maxOccurs==1.
18504: 		    * Just add the base types's content type.
18505: 		    * NOTE that, although we miss to add an intermediate
18506: 		    * <sequence>, this should produce no difference to
18507: 		    * neither the regex compilation of the content model,
18508: 		    * nor to the complex type contraints.
18509: 		    */
18510: 		    particle->children->children =
18511: 			(xmlSchemaTreeItemPtr) baseType->subtypes;
18512: 		}
18513: 	    }
18514: 	}
18515:     }
18516:     /*
18517:     * Now fixup attribute uses:
18518:     *   - expand attr. group references
18519:     *     - intersect attribute wildcards
18520:     *   - inherit attribute uses of the base type
18521:     *   - inherit or union attr. wildcards if extending
18522:     *   - apply attr. use prohibitions if restricting
18523:     */
18524:     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18525:     HFAILURE HERROR
18526:     /*
18527:     * Apply the complex type component constraints; this will not
18528:     * check attributes, since this is done in
18529:     * xmlSchemaFixupTypeAttributeUses().
18530:     */
18531:     res = xmlSchemaCheckCTComponent(pctxt, type);
18532:     HFAILURE HERROR
18533: 
18534: #ifdef DEBUG_TYPE
18535:     xmlSchemaDebugFixedType(pctxt, type);
18536: #endif
18537:     if (olderrs != pctxt->nberrors)
18538: 	return(pctxt->err);
18539:     else
18540: 	return(0);
18541: 
18542: exit_error:
18543:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18544: #ifdef DEBUG_TYPE
18545:     xmlSchemaDebugFixedType(pctxt, type);
18546: #endif
18547:     return(pctxt->err);
18548: 
18549: exit_failure:
18550:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18551: #ifdef DEBUG_TYPE
18552:     xmlSchemaDebugFixedType(pctxt, type);
18553: #endif
18554:     return(-1);
18555: }
18556: 
18557: 
18558: /**
18559:  * xmlSchemaTypeFixup:
18560:  * @typeDecl:  the schema type definition
18561:  * @ctxt:  the schema parser context
18562:  *
18563:  * Fixes the content model of the type.
18564:  * URGENT TODO: We need an int result!
18565:  */
18566: static int
18567: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18568:                    xmlSchemaAbstractCtxtPtr actxt)
18569: {
18570:     if (type == NULL)
18571:         return(0);
18572:     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18573: 	AERROR_INT("xmlSchemaTypeFixup",
18574: 	    "this function needs a parser context");
18575: 	return(-1);
18576:     }
18577:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18578: 	return(0);
18579:     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18580: 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18581:     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18582: 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18583:     return(0);
18584: }
18585: 
18586: /**
18587:  * xmlSchemaCheckFacet:
18588:  * @facet:  the facet
18589:  * @typeDecl:  the schema type definition
18590:  * @pctxt:  the schema parser context or NULL
18591:  * @name: the optional name of the type
18592:  *
18593:  * Checks and computes the values of facets.
18594:  *
18595:  * Returns 0 if valid, a positive error code if not valid and
18596:  *         -1 in case of an internal or API error.
18597:  */
18598: int
18599: xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18600:                     xmlSchemaTypePtr typeDecl,
18601:                     xmlSchemaParserCtxtPtr pctxt,
18602: 		    const xmlChar * name ATTRIBUTE_UNUSED)
18603: {
18604:     int ret = 0, ctxtGiven;
18605: 
18606:     if ((facet == NULL) || (typeDecl == NULL))
18607:         return(-1);
18608:     /*
18609:     * TODO: will the parser context be given if used from
18610:     * the relaxNG module?
18611:     */
18612:     if (pctxt == NULL)
18613: 	ctxtGiven = 0;
18614:     else
18615: 	ctxtGiven = 1;
18616: 
18617:     switch (facet->type) {
18618:         case XML_SCHEMA_FACET_MININCLUSIVE:
18619:         case XML_SCHEMA_FACET_MINEXCLUSIVE:
18620:         case XML_SCHEMA_FACET_MAXINCLUSIVE:
18621:         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18622: 	case XML_SCHEMA_FACET_ENUMERATION: {
18623:                 /*
18624:                  * Okay we need to validate the value
18625:                  * at that point.
18626:                  */
18627: 		xmlSchemaTypePtr base;
18628: 
18629: 		/* 4.3.5.5 Constraints on enumeration Schema Components
18630: 		* Schema Component Constraint: enumeration valid restriction
18631: 		* It is an �error� if any member of {value} is not in the
18632: 		* �value space� of {base type definition}.
18633: 		*
18634: 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
18635: 		* The value �must� be in the
18636: 		* �value space� of the �base type�.
18637: 		*/
18638: 		/*
18639: 		* This function is intended to deliver a compiled value
18640: 		* on the facet. In this implementation of XML Schemata the
18641: 		* type holding a facet, won't be a built-in type.
18642: 		* Thus to ensure that other API
18643: 		* calls (relaxng) do work, if the given type is a built-in
18644: 		* type, we will assume that the given built-in type *is
18645: 		* already* the base type.
18646: 		*/
18647: 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18648: 		    base = typeDecl->baseType;
18649: 		    if (base == NULL) {
18650: 			PERROR_INT("xmlSchemaCheckFacet",
18651: 			    "a type user derived type has no base type");
18652: 			return (-1);
18653: 		    }
18654: 		} else
18655: 		    base = typeDecl;
18656: 
18657: 		if (! ctxtGiven) {
18658: 		    /*
18659: 		    * A context is needed if called from RelaxNG.
18660: 		    */
18661: 		    pctxt = xmlSchemaNewParserCtxt("*");
18662: 		    if (pctxt == NULL)
18663: 			return (-1);
18664: 		}
18665: 		/*
18666: 		* NOTE: This call does not check the content nodes,
18667: 		* since they are not available:
18668: 		* facet->node is just the node holding the facet
18669: 		* definition, *not* the attribute holding the *value*
18670: 		* of the facet.
18671: 		*/
18672: 		ret = xmlSchemaVCheckCVCSimpleType(
18673: 		    ACTXT_CAST pctxt, facet->node, base,
18674: 		    facet->value, &(facet->val), 1, 1, 0);
18675:                 if (ret != 0) {
18676: 		    if (ret < 0) {
18677: 			/* No error message for RelaxNG. */
18678: 			if (ctxtGiven) {
18679: 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18680: 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
18681: 				"Internal error: xmlSchemaCheckFacet, "
18682: 				"failed to validate the value '%s' of the "
18683: 				"facet '%s' against the base type",
18684: 				facet->value, xmlSchemaFacetTypeToString(facet->type));
18685: 			}
18686: 			goto internal_error;
18687: 		    }
18688: 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18689: 		    /* No error message for RelaxNG. */
18690: 		    if (ctxtGiven) {
18691: 			xmlChar *str = NULL;
18692: 
18693: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
18694: 			    ret, facet->node, WXS_BASIC_CAST facet,
18695: 			    "The value '%s' of the facet does not validate "
18696: 			    "against the base type '%s'",
18697: 			    facet->value,
18698: 			    xmlSchemaFormatQName(&str,
18699: 				base->targetNamespace, base->name));
18700: 			FREE_AND_NULL(str);
18701: 		    }
18702: 		    goto exit;
18703:                 } else if (facet->val == NULL) {
18704: 		    if (ctxtGiven) {
18705: 			PERROR_INT("xmlSchemaCheckFacet",
18706: 			    "value was not computed");
18707: 		    }
18708: 		    TODO
18709: 		}
18710:                 break;
18711:             }
18712:         case XML_SCHEMA_FACET_PATTERN:
18713:             facet->regexp = xmlRegexpCompile(facet->value);
18714:             if (facet->regexp == NULL) {
18715: 		ret = XML_SCHEMAP_REGEXP_INVALID;
18716: 		/* No error message for RelaxNG. */
18717: 		if (ctxtGiven) {
18718: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18719: 			ret, facet->node, WXS_BASIC_CAST typeDecl,
18720: 			"The value '%s' of the facet 'pattern' is not a "
18721: 			"valid regular expression",
18722: 			facet->value, NULL);
18723: 		}
18724:             }
18725:             break;
18726:         case XML_SCHEMA_FACET_TOTALDIGITS:
18727:         case XML_SCHEMA_FACET_FRACTIONDIGITS:
18728:         case XML_SCHEMA_FACET_LENGTH:
18729:         case XML_SCHEMA_FACET_MAXLENGTH:
18730:         case XML_SCHEMA_FACET_MINLENGTH:
18731: 
18732: 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18733: 		ret = xmlSchemaValidatePredefinedType(
18734: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18735: 		    facet->value, &(facet->val));
18736: 	    } else {
18737: 		ret = xmlSchemaValidatePredefinedType(
18738: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18739: 		    facet->value, &(facet->val));
18740: 	    }
18741: 	    if (ret != 0) {
18742: 		if (ret < 0) {
18743: 		    /* No error message for RelaxNG. */
18744: 		    if (ctxtGiven) {
18745: 			PERROR_INT("xmlSchemaCheckFacet",
18746: 			    "validating facet value");
18747: 		    }
18748: 		    goto internal_error;
18749: 		}
18750: 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18751: 		/* No error message for RelaxNG. */
18752: 		if (ctxtGiven) {
18753: 		    /* error code */
18754: 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18755: 			ret, facet->node, WXS_BASIC_CAST typeDecl,
18756: 			"The value '%s' of the facet '%s' is not a valid '%s'",
18757: 			facet->value,
18758: 			xmlSchemaFacetTypeToString(facet->type),
18759: 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18760: 			    BAD_CAST "nonNegativeInteger" :
18761: 			    BAD_CAST "positiveInteger",
18762: 			NULL);
18763: 		}
18764: 	    }
18765: 	    break;
18766: 
18767:         case XML_SCHEMA_FACET_WHITESPACE:{
18768:                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18769:                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18770:                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18771:                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18772:                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18773:                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18774:                 } else {
18775: 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18776:                     /* No error message for RelaxNG. */
18777: 		    if (ctxtGiven) {
18778: 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18779: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
18780: 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
18781: 			    "The value '%s' of the facet 'whitespace' is not "
18782: 			    "valid", facet->value, NULL);
18783:                     }
18784:                 }
18785:             }
18786:         default:
18787:             break;
18788:     }
18789: exit:
18790:     if ((! ctxtGiven) && (pctxt != NULL))
18791: 	xmlSchemaFreeParserCtxt(pctxt);
18792:     return (ret);
18793: internal_error:
18794:     if ((! ctxtGiven) && (pctxt != NULL))
18795: 	xmlSchemaFreeParserCtxt(pctxt);
18796:     return (-1);
18797: }
18798: 
18799: /**
18800:  * xmlSchemaCheckFacetValues:
18801:  * @typeDecl:  the schema type definition
18802:  * @ctxt:  the schema parser context
18803:  *
18804:  * Checks the default values types, especially for facets
18805:  */
18806: static int
18807: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18808: 			  xmlSchemaParserCtxtPtr pctxt)
18809: {
18810:     int res, olderrs = pctxt->nberrors;
18811:     const xmlChar *name = typeDecl->name;
18812:     /*
18813:     * NOTE: It is intended to use the facets list, instead
18814:     * of facetSet.
18815:     */
18816:     if (typeDecl->facets != NULL) {
18817: 	xmlSchemaFacetPtr facet = typeDecl->facets;
18818: 
18819: 	/*
18820: 	* Temporarily assign the "schema" to the validation context
18821: 	* of the parser context. This is needed for NOTATION validation.
18822: 	*/
18823: 	if (pctxt->vctxt == NULL) {
18824: 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18825: 		return(-1);
18826: 	}
18827: 	pctxt->vctxt->schema = pctxt->schema;
18828: 	while (facet != NULL) {
18829: 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18830: 	    HFAILURE
18831: 	    facet = facet->next;
18832: 	}
18833: 	pctxt->vctxt->schema = NULL;
18834:     }
18835:     if (olderrs != pctxt->nberrors)
18836: 	return(pctxt->err);
18837:     return(0);
18838: exit_failure:
18839:     return(-1);
18840: }
18841: 
18842: /**
18843:  * xmlSchemaGetCircModelGrDefRef:
18844:  * @ctxtMGroup: the searched model group
18845:  * @selfMGroup: the second searched model group
18846:  * @particle: the first particle
18847:  *
18848:  * This one is intended to be used by
18849:  * xmlSchemaCheckGroupDefCircular only.
18850:  *
18851:  * Returns the particle with the circular model group definition reference,
18852:  * otherwise NULL.
18853:  */
18854: static xmlSchemaTreeItemPtr
18855: xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18856: 			      xmlSchemaTreeItemPtr particle)
18857: {
18858:     xmlSchemaTreeItemPtr circ = NULL;
18859:     xmlSchemaTreeItemPtr term;
18860:     xmlSchemaModelGroupDefPtr gdef;
18861: 
18862:     for (; particle != NULL; particle = particle->next) {
18863: 	term = particle->children;
18864: 	if (term == NULL)
18865: 	    continue;
18866: 	switch (term->type) {
18867: 	    case XML_SCHEMA_TYPE_GROUP:
18868: 		gdef = (xmlSchemaModelGroupDefPtr) term;
18869: 		if (gdef == groupDef)
18870: 		    return (particle);
18871: 		/*
18872: 		* Mark this model group definition to avoid infinite
18873: 		* recursion on circular references not yet examined.
18874: 		*/
18875: 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18876: 		    continue;
18877: 		if (gdef->children != NULL) {
18878: 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18879: 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18880: 			gdef->children->children);
18881: 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18882: 		    if (circ != NULL)
18883: 			return (circ);
18884: 		}
18885: 		break;
18886: 	    case XML_SCHEMA_TYPE_SEQUENCE:
18887: 	    case XML_SCHEMA_TYPE_CHOICE:
18888: 	    case XML_SCHEMA_TYPE_ALL:
18889: 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18890: 		if (circ != NULL)
18891: 		    return (circ);
18892: 		break;
18893: 	    default:
18894: 		break;
18895: 	}
18896:     }
18897:     return (NULL);
18898: }
18899: 
18900: /**
18901:  * xmlSchemaCheckGroupDefCircular:
18902:  * @item:  the model group definition
18903:  * @ctxt:  the parser context
18904:  * @name:  the name
18905:  *
18906:  * Checks for circular references to model group definitions.
18907:  */
18908: static void
18909: xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18910: 			       xmlSchemaParserCtxtPtr ctxt)
18911: {
18912:     /*
18913:     * Schema Component Constraint: Model Group Correct
18914:     * 2 Circular groups are disallowed. That is, within the {particles}
18915:     * of a group there must not be at any depth a particle whose {term}
18916:     * is the group itself.
18917:     */
18918:     if ((item == NULL) ||
18919: 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
18920: 	(item->children == NULL))
18921: 	return;
18922:     {
18923: 	xmlSchemaTreeItemPtr circ;
18924: 
18925: 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18926: 	if (circ != NULL) {
18927: 	    xmlChar *str = NULL;
18928: 	    /*
18929: 	    * TODO: The error report is not adequate: this constraint
18930: 	    * is defined for model groups but not definitions, but since
18931: 	    * there cannot be any circular model groups without a model group
18932: 	    * definition (if not using a construction API), we check those
18933: 	    * defintions only.
18934: 	    */
18935: 	    xmlSchemaPCustomErr(ctxt,
18936: 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
18937: 		NULL, WXS_ITEM_NODE(circ),
18938: 		"Circular reference to the model group definition '%s' "
18939: 		"defined", xmlSchemaFormatQName(&str,
18940: 		    item->targetNamespace, item->name));
18941: 	    FREE_AND_NULL(str)
18942: 	    /*
18943: 	    * NOTE: We will cut the reference to avoid further
18944: 	    * confusion of the processor. This is a fatal error.
18945: 	    */
18946: 	    circ->children = NULL;
18947: 	}
18948:     }
18949: }
18950: 
18951: /**
18952:  * xmlSchemaModelGroupToModelGroupDefFixup:
18953:  * @ctxt:  the parser context
18954:  * @mg:  the model group
18955:  *
18956:  * Assigns the model group of model group definitions to the "term"
18957:  * of the referencing particle.
18958:  * In xmlSchemaResolveModelGroupParticleReferences the model group
18959:  * definitions were assigned to the "term", since needed for the
18960:  * circularity check.
18961:  *
18962:  * Schema Component Constraint:
18963:  *     All Group Limited (cos-all-limited) (1.2)
18964:  */
18965: static void
18966: xmlSchemaModelGroupToModelGroupDefFixup(
18967:     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18968:     xmlSchemaModelGroupPtr mg)
18969: {
18970:     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18971: 
18972:     while (particle != NULL) {
18973: 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18974: 	    ((WXS_PARTICLE_TERM(particle))->type !=
18975: 		XML_SCHEMA_TYPE_GROUP))
18976: 	{
18977: 	    particle = WXS_PTC_CAST particle->next;
18978: 	    continue;
18979: 	}
18980: 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18981: 	    /*
18982: 	    * TODO: Remove the particle.
18983: 	    */
18984: 	    WXS_PARTICLE_TERM(particle) = NULL;
18985: 	    particle = WXS_PTC_CAST particle->next;
18986: 	    continue;
18987: 	}
18988: 	/*
18989: 	* Assign the model group to the {term} of the particle.
18990: 	*/
18991: 	WXS_PARTICLE_TERM(particle) =
18992: 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18993: 
18994: 	particle = WXS_PTC_CAST particle->next;
18995:     }
18996: }
18997: 
18998: /**
18999:  * xmlSchemaCheckAttrGroupCircularRecur:
19000:  * @ctxtGr: the searched attribute group
19001:  * @attr: the current attribute list to be processed
19002:  *
19003:  * This one is intended to be used by
19004:  * xmlSchemaCheckAttrGroupCircular only.
19005:  *
19006:  * Returns the circular attribute grou reference, otherwise NULL.
19007:  */
19008: static xmlSchemaQNameRefPtr
19009: xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19010: 				     xmlSchemaItemListPtr list)
19011: {
19012:     xmlSchemaAttributeGroupPtr gr;
19013:     xmlSchemaQNameRefPtr ref, circ;
19014:     int i;
19015:     /*
19016:     * We will search for an attribute group reference which
19017:     * references the context attribute group.
19018:     */
19019:     for (i = 0; i < list->nbItems; i++) {
19020: 	ref = list->items[i];
19021: 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19022: 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19023: 	    (ref->item != NULL))
19024: 	{
19025: 	    gr = WXS_ATTR_GROUP_CAST ref->item;
19026: 	    if (gr == ctxtGr)
19027: 		return(ref);
19028: 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19029: 		continue;
19030: 	    /*
19031: 	    * Mark as visited to avoid infinite recursion on
19032: 	    * circular references not yet examined.
19033: 	    */
19034: 	    if ((gr->attrUses) &&
19035: 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19036: 	    {
19037: 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19038: 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19039: 		    (xmlSchemaItemListPtr) gr->attrUses);
19040: 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19041: 		if (circ != NULL)
19042: 		    return (circ);
19043: 	    }
19044: 
19045: 	}
19046:     }
19047:     return (NULL);
19048: }
19049: 
19050: /**
19051:  * xmlSchemaCheckAttrGroupCircular:
19052:  * attrGr:  the attribute group definition
19053:  * @ctxt:  the parser context
19054:  * @name:  the name
19055:  *
19056:  * Checks for circular references of attribute groups.
19057:  */
19058: static int
19059: xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19060: 				xmlSchemaParserCtxtPtr ctxt)
19061: {
19062:     /*
19063:     * Schema Representation Constraint:
19064:     * Attribute Group Definition Representation OK
19065:     * 3 Circular group reference is disallowed outside <redefine>.
19066:     * That is, unless this element information item's parent is
19067:     * <redefine>, then among the [children], if any, there must
19068:     * not be an <attributeGroup> with ref [attribute] which resolves
19069:     * to the component corresponding to this <attributeGroup>. Indirect
19070:     * circularity is also ruled out. That is, when QName resolution
19071:     * (Schema Document) (�3.15.3) is applied to a �QName� arising from
19072:     * any <attributeGroup>s with a ref [attribute] among the [children],
19073:     * it must not be the case that a �QName� is encountered at any depth
19074:     * which resolves to the component corresponding to this <attributeGroup>.
19075:     */
19076:     if (attrGr->attrUses == NULL)
19077: 	return(0);
19078:     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19079: 	return(0);
19080:     else {
19081: 	xmlSchemaQNameRefPtr circ;
19082: 
19083: 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19084: 	    (xmlSchemaItemListPtr) attrGr->attrUses);
19085: 	if (circ != NULL) {
19086: 	    xmlChar *str = NULL;
19087: 	    /*
19088: 	    * TODO: Report the referenced attr group as QName.
19089: 	    */
19090: 	    xmlSchemaPCustomErr(ctxt,
19091: 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19092: 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19093: 		"Circular reference to the attribute group '%s' "
19094: 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
19095: 	    FREE_AND_NULL(str);
19096: 	    /*
19097: 	    * NOTE: We will cut the reference to avoid further
19098: 	    * confusion of the processor.
19099: 	    * BADSPEC TODO: The spec should define how to process in this case.
19100: 	    */
19101: 	    circ->item = NULL;
19102: 	    return(ctxt->err);
19103: 	}
19104:     }
19105:     return(0);
19106: }
19107: 
19108: static int
19109: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19110: 				  xmlSchemaAttributeGroupPtr attrGr);
19111: 
19112: /**
19113:  * xmlSchemaExpandAttributeGroupRefs:
19114:  * @pctxt: the parser context
19115:  * @node: the node of the component holding the attribute uses
19116:  * @completeWild: the intersected wildcard to be returned
19117:  * @list: the attribute uses
19118:  *
19119:  * Substitutes contained attribute group references
19120:  * for their attribute uses. Wilcards are intersected.
19121:  * Attribute use prohibitions are removed from the list
19122:  * and returned via the @prohibs list.
19123:  * Pointlessness of attr. prohibs, if a matching attr. decl
19124:  * is existent a well, are checked.
19125:  */
19126: static int
19127: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19128: 				  xmlSchemaBasicItemPtr item,
19129: 				  xmlSchemaWildcardPtr *completeWild,
19130: 				  xmlSchemaItemListPtr list,
19131: 				  xmlSchemaItemListPtr prohibs)
19132: {
19133:     xmlSchemaAttributeGroupPtr gr;
19134:     xmlSchemaAttributeUsePtr use;
19135:     xmlSchemaItemListPtr sublist;
19136:     int i, j;
19137:     int created = (*completeWild == NULL) ? 0 : 1;
19138: 
19139:     if (prohibs)
19140: 	prohibs->nbItems = 0;
19141: 
19142:     for (i = 0; i < list->nbItems; i++) {
19143: 	use = list->items[i];
19144: 
19145: 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19146: 	    if (prohibs == NULL) {
19147: 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19148: 		    "unexpected attr prohibition found");
19149: 		return(-1);
19150: 	    }
19151: 	    /*
19152: 	    * Remove from attribute uses.
19153: 	    */
19154: 	    if (xmlSchemaItemListRemove(list, i) == -1)
19155: 		return(-1);
19156: 	    i--;
19157: 	    /*
19158: 	    * Note that duplicate prohibitions were already
19159: 	    * handled at parsing time.
19160: 	    */
19161: 	    /*
19162: 	    * Add to list of prohibitions.
19163: 	    */
19164: 	    xmlSchemaItemListAddSize(prohibs, 2, use);
19165: 	    continue;
19166: 	}
19167: 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19168: 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19169: 	{
19170: 	    if ((WXS_QNAME_CAST use)->item == NULL)
19171: 		return(-1);
19172: 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19173: 	    /*
19174: 	    * Expand the referenced attr. group.
19175: 	    * TODO: remove this, this is done in a previous step, so
19176: 	    * already done here.
19177: 	    */
19178: 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19179: 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19180: 		    return(-1);
19181: 	    }
19182: 	    /*
19183: 	    * Build the 'complete' wildcard; i.e. intersect multiple
19184: 	    * wildcards.
19185: 	    */
19186: 	    if (gr->attributeWildcard != NULL) {
19187: 		if (*completeWild == NULL) {
19188: 		    *completeWild = gr->attributeWildcard;
19189: 		} else {
19190: 		    if (! created) {
19191: 			xmlSchemaWildcardPtr tmpWild;
19192: 
19193: 			 /*
19194: 			* Copy the first encountered wildcard as context,
19195: 			* except for the annotation.
19196: 			*
19197: 			* Although the complete wildcard might not correspond
19198: 			* to any node in the schema, we will anchor it on
19199: 			* the node of the owner component.
19200: 			*/
19201: 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19202: 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19203: 			    WXS_ITEM_NODE(item));
19204: 			if (tmpWild == NULL)
19205: 			    return(-1);
19206: 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19207: 			    tmpWild, *completeWild) == -1)
19208: 			    return (-1);
19209: 			tmpWild->processContents = (*completeWild)->processContents;
19210: 			*completeWild = tmpWild;
19211: 			created = 1;
19212: 		    }
19213: 
19214: 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19215: 			gr->attributeWildcard) == -1)
19216: 			return(-1);
19217: 		}
19218: 	    }
19219: 	    /*
19220: 	    * Just remove the reference if the referenced group does not
19221: 	    * contain any attribute uses.
19222: 	    */
19223: 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19224: 	    if ((sublist == NULL) || sublist->nbItems == 0) {
19225: 		if (xmlSchemaItemListRemove(list, i) == -1)
19226: 		    return(-1);
19227: 		i--;
19228: 		continue;
19229: 	    }
19230: 	    /*
19231: 	    * Add the attribute uses.
19232: 	    */
19233: 	    list->items[i] = sublist->items[0];
19234: 	    if (sublist->nbItems != 1) {
19235: 		for (j = 1; j < sublist->nbItems; j++) {
19236: 		    i++;
19237: 		    if (xmlSchemaItemListInsert(list,
19238: 			    sublist->items[j], i) == -1)
19239: 			return(-1);
19240: 		}
19241: 	    }
19242: 	}
19243: 
19244:     }
19245:     /*
19246:     * Handle pointless prohibitions of declared attributes.
19247:     */
19248:     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19249: 	xmlSchemaAttributeUseProhibPtr prohib;
19250: 
19251: 	for (i = prohibs->nbItems -1; i >= 0; i--) {
19252: 	    prohib = prohibs->items[i];
19253: 	    for (j = 0; j < list->nbItems; j++) {
19254: 		use = list->items[j];
19255: 
19256: 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19257: 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19258: 		{
19259: 		    xmlChar *str = NULL;
19260: 
19261: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19262: 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19263: 			prohib->node, NULL,
19264: 			"Skipping pointless attribute use prohibition "
19265: 			"'%s', since a corresponding attribute use "
19266: 			"exists already in the type definition",
19267: 			xmlSchemaFormatQName(&str,
19268: 			    prohib->targetNamespace, prohib->name),
19269: 			NULL, NULL);
19270: 		    FREE_AND_NULL(str);
19271: 		    /*
19272: 		    * Remove the prohibition.
19273: 		    */
19274: 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
19275: 			return(-1);
19276: 		    break;
19277: 		}
19278: 	    }
19279: 	}
19280:     }
19281:     return(0);
19282: }
19283: 
19284: /**
19285:  * xmlSchemaAttributeGroupExpandRefs:
19286:  * @pctxt:  the parser context
19287:  * @attrGr:  the attribute group definition
19288:  *
19289:  * Computation of:
19290:  * {attribute uses} property
19291:  * {attribute wildcard} property
19292:  *
19293:  * Substitutes contained attribute group references
19294:  * for their attribute uses. Wilcards are intersected.
19295:  */
19296: static int
19297: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19298: 				  xmlSchemaAttributeGroupPtr attrGr)
19299: {
19300:     if ((attrGr->attrUses == NULL) ||
19301: 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19302: 	return(0);
19303: 
19304:     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19305:     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19306: 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19307: 	return(-1);
19308:     return(0);
19309: }
19310: 
19311: /**
19312:  * xmlSchemaAttributeGroupExpandRefs:
19313:  * @pctxt:  the parser context
19314:  * @attrGr:  the attribute group definition
19315:  *
19316:  * Substitutes contained attribute group references
19317:  * for their attribute uses. Wilcards are intersected.
19318:  *
19319:  * Schema Component Constraint:
19320:  *    Attribute Group Definition Properties Correct (ag-props-correct)
19321:  */
19322: static int
19323: xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19324: 				  xmlSchemaAttributeGroupPtr attrGr)
19325: {
19326:     /*
19327:     * SPEC ag-props-correct
19328:     * (1) "The values of the properties of an attribute group definition
19329:     * must be as described in the property tableau in The Attribute
19330:     * Group Definition Schema Component (�3.6.1), modulo the impact of
19331:     * Missing Sub-components (�5.3);"
19332:     */
19333: 
19334:     if ((attrGr->attrUses != NULL) &&
19335: 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19336:     {
19337: 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19338: 	xmlSchemaAttributeUsePtr use, tmp;
19339: 	int i, j, hasId = 0;
19340: 
19341: 	for (i = uses->nbItems -1; i >= 0; i--) {
19342: 	    use = uses->items[i];
19343: 	    /*
19344: 	    * SPEC ag-props-correct
19345: 	    * (2) "Two distinct members of the {attribute uses} must not have
19346: 	    * {attribute declaration}s both of whose {name}s match and whose
19347: 	    * {target namespace}s are identical."
19348: 	    */
19349: 	    if (i > 0) {
19350: 		for (j = i -1; j >= 0; j--) {
19351: 		    tmp = uses->items[j];
19352: 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
19353: 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
19354: 			(WXS_ATTRUSE_DECL_TNS(use) ==
19355: 			WXS_ATTRUSE_DECL_TNS(tmp)))
19356: 		    {
19357: 			xmlChar *str = NULL;
19358: 
19359: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19360: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
19361: 			    attrGr->node, WXS_BASIC_CAST attrGr,
19362: 			    "Duplicate %s",
19363: 			    xmlSchemaGetComponentDesignation(&str, use),
19364: 			    NULL);
19365: 			FREE_AND_NULL(str);
19366: 			/*
19367: 			* Remove the duplicate.
19368: 			*/
19369: 			if (xmlSchemaItemListRemove(uses, i) == -1)
19370: 			    return(-1);
19371: 			goto next_use;
19372: 		    }
19373: 		}
19374: 	    }
19375: 	    /*
19376: 	    * SPEC ag-props-correct
19377: 	    * (3) "Two distinct members of the {attribute uses} must not have
19378: 	    * {attribute declaration}s both of whose {type definition}s are or
19379: 	    * are derived from ID."
19380: 	    * TODO: Does 'derived' include member-types of unions?
19381: 	    */
19382: 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19383: 		if (xmlSchemaIsDerivedFromBuiltInType(
19384: 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19385: 		{
19386: 		    if (hasId) {
19387: 			xmlChar *str = NULL;
19388: 
19389: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19390: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
19391: 			    attrGr->node, WXS_BASIC_CAST attrGr,
19392: 			    "There must not exist more than one attribute "
19393: 			    "declaration of type 'xs:ID' "
19394: 			    "(or derived from 'xs:ID'). The %s violates this "
19395: 			    "constraint",
19396: 			    xmlSchemaGetComponentDesignation(&str, use),
19397: 			    NULL);
19398: 			FREE_AND_NULL(str);
19399: 			if (xmlSchemaItemListRemove(uses, i) == -1)
19400: 			    return(-1);
19401: 		    }
19402: 		    hasId = 1;
19403: 		}
19404: 	    }
19405: next_use: {}
19406: 	}
19407:     }
19408:     return(0);
19409: }
19410: 
19411: /**
19412:  * xmlSchemaResolveAttrGroupReferences:
19413:  * @attrgrpDecl:  the schema attribute definition
19414:  * @ctxt:  the schema parser context
19415:  * @name:  the attribute name
19416:  *
19417:  * Resolves references to attribute group definitions.
19418:  */
19419: static int
19420: xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19421: 				    xmlSchemaParserCtxtPtr ctxt)
19422: {
19423:     xmlSchemaAttributeGroupPtr group;
19424: 
19425:     if (ref->item != NULL)
19426:         return(0);
19427:     group = xmlSchemaGetAttributeGroup(ctxt->schema,
19428: 	ref->name,
19429: 	ref->targetNamespace);
19430:     if (group == NULL) {
19431: 	xmlSchemaPResCompAttrErr(ctxt,
19432: 	    XML_SCHEMAP_SRC_RESOLVE,
19433: 	    NULL, ref->node,
19434: 	    "ref", ref->name, ref->targetNamespace,
19435: 	    ref->itemType, NULL);
19436: 	return(ctxt->err);
19437:     }
19438:     ref->item = WXS_BASIC_CAST group;
19439:     return(0);
19440: }
19441: 
19442: /**
19443:  * xmlSchemaCheckAttrPropsCorrect:
19444:  * @item:  an schema attribute declaration/use
19445:  * @ctxt:  a schema parser context
19446:  * @name:  the name of the attribute
19447:  *
19448:  *
19449:  * Schema Component Constraint:
19450:  *    Attribute Declaration Properties Correct (a-props-correct)
19451:  *
19452:  * Validates the value constraints of an attribute declaration/use.
19453:  * NOTE that this needs the simle type definitions to be already
19454:  *   builded and checked.
19455:  */
19456: static int
19457: xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19458: 			       xmlSchemaAttributePtr attr)
19459: {
19460: 
19461:     /*
19462:     * SPEC a-props-correct (1)
19463:     * "The values of the properties of an attribute declaration must
19464:     * be as described in the property tableau in The Attribute
19465:     * Declaration Schema Component (�3.2.1), modulo the impact of
19466:     * Missing Sub-components (�5.3)."
19467:     */
19468: 
19469:     if (WXS_ATTR_TYPEDEF(attr) == NULL)
19470: 	return(0);
19471: 
19472:     if (attr->defValue != NULL) {
19473: 	int ret;
19474: 
19475: 	/*
19476: 	* SPEC a-props-correct (3)
19477: 	* "If the {type definition} is or is derived from ID then there
19478: 	* must not be a {value constraint}."
19479: 	*/
19480: 	if (xmlSchemaIsDerivedFromBuiltInType(
19481: 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19482: 	{
19483: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19484: 		XML_SCHEMAP_A_PROPS_CORRECT_3,
19485: 		NULL, WXS_BASIC_CAST attr,
19486: 		"Value constraints are not allowed if the type definition "
19487: 		"is or is derived from xs:ID",
19488: 		NULL, NULL);
19489: 	    return(pctxt->err);
19490: 	}
19491: 	/*
19492: 	* SPEC a-props-correct (2)
19493: 	* "if there is a {value constraint}, the canonical lexical
19494: 	* representation of its value must be �valid� with respect
19495: 	* to the {type definition} as defined in String Valid (�3.14.4)."
19496: 	* TODO: Don't care about the *cononical* stuff here, this requirement
19497: 	* will be removed in WXS 1.1 anyway.
19498: 	*/
19499: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19500: 	    attr->node, WXS_ATTR_TYPEDEF(attr),
19501: 	    attr->defValue, &(attr->defVal),
19502: 	    1, 1, 0);
19503: 	if (ret != 0) {
19504: 	    if (ret < 0) {
19505: 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19506: 		    "calling xmlSchemaVCheckCVCSimpleType()");
19507: 		return(-1);
19508: 	    }
19509: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19510: 		XML_SCHEMAP_A_PROPS_CORRECT_2,
19511: 		NULL, WXS_BASIC_CAST attr,
19512: 		"The value of the value constraint is not valid",
19513: 		NULL, NULL);
19514: 	    return(pctxt->err);
19515: 	}
19516:     }
19517: 
19518:     return(0);
19519: }
19520: 
19521: static xmlSchemaElementPtr
19522: xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19523: 				 xmlSchemaElementPtr ancestor)
19524: {
19525:     xmlSchemaElementPtr ret;
19526: 
19527:     if (WXS_SUBST_HEAD(ancestor) == NULL)
19528: 	return (NULL);
19529:     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19530: 	return (ancestor);
19531: 
19532:     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19533: 	return (NULL);
19534:     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19535:     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19536: 	WXS_SUBST_HEAD(ancestor));
19537:     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19538: 
19539:     return (ret);
19540: }
19541: 
19542: /**
19543:  * xmlSchemaCheckElemPropsCorrect:
19544:  * @ctxt:  a schema parser context
19545:  * @decl: the element declaration
19546:  * @name:  the name of the attribute
19547:  *
19548:  * Schema Component Constraint:
19549:  * Element Declaration Properties Correct (e-props-correct)
19550:  *
19551:  * STATUS:
19552:  *   missing: (6)
19553:  */
19554: static int
19555: xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19556: 			       xmlSchemaElementPtr elemDecl)
19557: {
19558:     int ret = 0;
19559:     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19560:     /*
19561:     * SPEC (1) "The values of the properties of an element declaration
19562:     * must be as described in the property tableau in The Element
19563:     * Declaration Schema Component (�3.3.1), modulo the impact of Missing
19564:     * Sub-components (�5.3)."
19565:     */
19566:     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19567: 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19568: 
19569: 	xmlSchemaCheckElementDeclComponent(head, pctxt);
19570: 	/*
19571: 	* SPEC (3) "If there is a non-�absent� {substitution group
19572: 	* affiliation}, then {scope} must be global."
19573: 	*/
19574: 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19575: 	    xmlSchemaPCustomErr(pctxt,
19576: 		XML_SCHEMAP_E_PROPS_CORRECT_3,
19577: 		WXS_BASIC_CAST elemDecl, NULL,
19578: 		"Only global element declarations can have a "
19579: 		"substitution group affiliation", NULL);
19580: 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19581: 	}
19582: 	/*
19583: 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
19584: 	* That is, it must not be possible to return to an element declaration
19585: 	* by repeatedly following the {substitution group affiliation}
19586: 	* property."
19587: 	*/
19588: 	if (head == elemDecl)
19589: 	    circ = head;
19590: 	else if (WXS_SUBST_HEAD(head) != NULL)
19591: 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
19592: 	else
19593: 	    circ = NULL;
19594: 	if (circ != NULL) {
19595: 	    xmlChar *strA = NULL, *strB = NULL;
19596: 
19597: 	    xmlSchemaPCustomErrExt(pctxt,
19598: 		XML_SCHEMAP_E_PROPS_CORRECT_6,
19599: 		WXS_BASIC_CAST circ, NULL,
19600: 		"The element declaration '%s' defines a circular "
19601: 		"substitution group to element declaration '%s'",
19602: 		xmlSchemaGetComponentQName(&strA, circ),
19603: 		xmlSchemaGetComponentQName(&strB, head),
19604: 		NULL);
19605: 	    FREE_AND_NULL(strA)
19606: 	    FREE_AND_NULL(strB)
19607: 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19608: 	}
19609: 	/*
19610: 	* SPEC (4) "If there is a {substitution group affiliation},
19611: 	* the {type definition}
19612: 	* of the element declaration must be validly derived from the {type
19613: 	* definition} of the {substitution group affiliation}, given the value
19614: 	* of the {substitution group exclusions} of the {substitution group
19615: 	* affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
19616: 	* (if the {type definition} is complex) or as defined in
19617: 	* Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
19618: 	* simple)."
19619: 	*
19620: 	* NOTE: {substitution group exclusions} means the values of the
19621: 	* attribute "final".
19622: 	*/
19623: 
19624: 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19625: 	    int set = 0;
19626: 
19627: 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19628: 		set |= SUBSET_EXTENSION;
19629: 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19630: 		set |= SUBSET_RESTRICTION;
19631: 
19632: 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19633: 		WXS_ELEM_TYPEDEF(head), set) != 0) {
19634: 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19635: 
19636: 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19637: 		xmlSchemaPCustomErrExt(pctxt,
19638: 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
19639: 		    WXS_BASIC_CAST elemDecl, NULL,
19640: 		    "The type definition '%s' was "
19641: 		    "either rejected by the substitution group "
19642: 		    "affiliation '%s', or not validly derived from its type "
19643: 		    "definition '%s'",
19644: 		    xmlSchemaGetComponentQName(&strA, typeDef),
19645: 		    xmlSchemaGetComponentQName(&strB, head),
19646: 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19647: 		FREE_AND_NULL(strA)
19648: 		FREE_AND_NULL(strB)
19649: 		FREE_AND_NULL(strC)
19650: 	    }
19651: 	}
19652:     }
19653:     /*
19654:     * SPEC (5) "If the {type definition} or {type definition}'s
19655:     * {content type}
19656:     * is or is derived from ID then there must not be a {value constraint}.
19657:     * Note: The use of ID as a type definition for elements goes beyond
19658:     * XML 1.0, and should be avoided if backwards compatibility is desired"
19659:     */
19660:     if ((elemDecl->value != NULL) &&
19661: 	((WXS_IS_SIMPLE(typeDef) &&
19662: 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19663: 	 (WXS_IS_COMPLEX(typeDef) &&
19664: 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19665: 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19666: 	    XML_SCHEMAS_ID)))) {
19667: 
19668: 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19669: 	xmlSchemaPCustomErr(pctxt,
19670: 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
19671: 	    WXS_BASIC_CAST elemDecl, NULL,
19672: 	    "The type definition (or type definition's content type) is or "
19673: 	    "is derived from ID; value constraints are not allowed in "
19674: 	    "conjunction with such a type definition", NULL);
19675:     } else if (elemDecl->value != NULL) {
19676: 	int vcret;
19677: 	xmlNodePtr node = NULL;
19678: 
19679: 	/*
19680: 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
19681: 	* representation of its value must be �valid� with respect to the
19682: 	* {type definition} as defined in Element Default Valid (Immediate)
19683: 	* (�3.3.6)."
19684: 	*/
19685: 	if (typeDef == NULL) {
19686: 	    xmlSchemaPErr(pctxt, elemDecl->node,
19687: 		XML_SCHEMAP_INTERNAL,
19688: 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
19689: 		"type is missing... skipping validation of "
19690: 		"the value constraint", NULL, NULL);
19691: 	    return (-1);
19692: 	}
19693: 	if (elemDecl->node != NULL) {
19694: 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19695: 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19696: 		    BAD_CAST "fixed");
19697: 	    else
19698: 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19699: 		    BAD_CAST "default");
19700: 	}
19701: 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19702: 	    typeDef, elemDecl->value, &(elemDecl->defVal));
19703: 	if (vcret != 0) {
19704: 	    if (vcret < 0) {
19705: 		PERROR_INT("xmlSchemaElemCheckValConstr",
19706: 		    "failed to validate the value constraint of an "
19707: 		    "element declaration");
19708: 		return (-1);
19709: 	    }
19710: 	    return (vcret);
19711: 	}
19712:     }
19713: 
19714:     return (ret);
19715: }
19716: 
19717: /**
19718:  * xmlSchemaCheckElemSubstGroup:
19719:  * @ctxt:  a schema parser context
19720:  * @decl: the element declaration
19721:  * @name:  the name of the attribute
19722:  *
19723:  * Schema Component Constraint:
19724:  * Substitution Group (cos-equiv-class)
19725:  *
19726:  * In Libxml2 the subst. groups will be precomputed, in terms of that
19727:  * a list will be built for each subst. group head, holding all direct
19728:  * referents to this head.
19729:  * NOTE that this function needs:
19730:  *   1. circular subst. groups to be checked beforehand
19731:  *   2. the declaration's type to be derived from the head's type
19732:  *
19733:  * STATUS:
19734:  *
19735:  */
19736: static void
19737: xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19738: 			     xmlSchemaElementPtr elemDecl)
19739: {
19740:     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19741: 	/* SPEC (1) "Its {abstract} is false." */
19742: 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19743: 	return;
19744:     {
19745: 	xmlSchemaElementPtr head;
19746: 	xmlSchemaTypePtr headType, type;
19747: 	int set, methSet;
19748: 	/*
19749: 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19750: 	* {disallowed substitutions} as the blocking constraint, as defined in
19751: 	* Substitution Group OK (Transitive) (�3.3.6)."
19752: 	*/
19753: 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19754: 	    head = WXS_SUBST_HEAD(head)) {
19755: 	    set = 0;
19756: 	    methSet = 0;
19757: 	    /*
19758: 	    * The blocking constraints.
19759: 	    */
19760: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19761: 		continue;
19762: 	    headType = head->subtypes;
19763: 	    type = elemDecl->subtypes;
19764: 	    if (headType == type)
19765: 		goto add_member;
19766: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19767: 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19768: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19769: 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19770: 	    /*
19771: 	    * SPEC: Substitution Group OK (Transitive) (2.3)
19772: 	    * "The set of all {derivation method}s involved in the
19773: 	    * derivation of D's {type definition} from C's {type definition}
19774: 	    * does not intersect with the union of the blocking constraint,
19775: 	    * C's {prohibited substitutions} (if C is complex, otherwise the
19776: 	    * empty set) and the {prohibited substitutions} (respectively the
19777: 	    * empty set) of any intermediate {type definition}s in the
19778: 	    * derivation of D's {type definition} from C's {type definition}."
19779: 	    */
19780: 	    /*
19781: 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19782: 	    * subst.head axis, the methSet does not need to be computed for
19783: 	    * the full depth over and over.
19784: 	    */
19785: 	    /*
19786: 	    * The set of all {derivation method}s involved in the derivation
19787: 	    */
19788: 	    while ((type != NULL) && (type != headType)) {
19789: 		if ((WXS_IS_EXTENSION(type)) &&
19790: 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19791: 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19792: 
19793: 		if (WXS_IS_RESTRICTION(type) &&
19794: 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19795: 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19796: 
19797: 		type = type->baseType;
19798: 	    }
19799: 	    /*
19800: 	    * The {prohibited substitutions} of all intermediate types +
19801: 	    * the head's type.
19802: 	    */
19803: 	    type = elemDecl->subtypes->baseType;
19804: 	    while (type != NULL) {
19805: 		if (WXS_IS_COMPLEX(type)) {
19806: 		    if ((type->flags &
19807: 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19808: 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19809: 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19810: 		    if ((type->flags &
19811: 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19812: 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19813: 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19814: 		} else
19815: 		    break;
19816: 		if (type == headType)
19817: 		    break;
19818: 		type = type->baseType;
19819: 	    }
19820: 	    if ((set != 0) &&
19821: 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19822: 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19823: 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19824: 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19825: 		continue;
19826: 	    }
19827: add_member:
19828: 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19829: 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19830: 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19831: 	}
19832:     }
19833: }
19834: 
19835: #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19836: /**
19837:  * xmlSchemaCheckElementDeclComponent
19838:  * @pctxt: the schema parser context
19839:  * @ctxtComponent: the context component (an element declaration)
19840:  * @ctxtParticle: the first particle of the context component
19841:  * @searchParticle: the element declaration particle to be analysed
19842:  *
19843:  * Schema Component Constraint: Element Declarations Consistent
19844:  */
19845: static int
19846: xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19847: 				    xmlSchemaBasicItemPtr ctxtComponent,
19848: 				    xmlSchemaParticlePtr ctxtParticle,
19849: 				    xmlSchemaParticlePtr searchParticle,
19850: 				    xmlSchemaParticlePtr curParticle,
19851: 				    int search)
19852: {
19853:     return(0);
19854: 
19855:     int ret = 0;
19856:     xmlSchemaParticlePtr cur = curParticle;
19857:     if (curParticle == NULL) {
19858: 	return(0);
19859:     }
19860:     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19861: 	/*
19862: 	* Just return in this case. A missing "term" of the particle
19863: 	* might arise due to an invalid "term" component.
19864: 	*/
19865: 	return(0);
19866:     }
19867:     while (cur != NULL) {
19868: 	switch (WXS_PARTICLE_TERM(cur)->type) {
19869: 	    case XML_SCHEMA_TYPE_ANY:
19870: 		break;
19871: 	    case XML_SCHEMA_TYPE_ELEMENT:
19872: 		if (search == 0) {
19873: 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19874: 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19875: 		    if (ret != 0)
19876: 			return(ret);
19877: 		} else {
19878: 		    xmlSchemaElementPtr elem =
19879: 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19880: 		    /*
19881: 		    * SPEC Element Declarations Consistent:
19882: 		    * "If the {particles} contains, either directly,
19883: 		    * indirectly (that is, within the {particles} of a
19884: 		    * contained model group, recursively) or �implicitly�
19885: 		    * two or more element declaration particles with
19886: 		    * the same {name} and {target namespace}, then
19887: 		    * all their type definitions must be the same
19888: 		    * top-level definition [...]"
19889: 		    */
19890: 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19891: 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19892: 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19893: 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19894: 		    {
19895: 			xmlChar *strA = NULL, *strB = NULL;
19896: 
19897: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19898: 			    /* TODO: error code */
19899: 			    XML_SCHEMAP_COS_NONAMBIG,
19900: 			    WXS_ITEM_NODE(cur), NULL,
19901: 			    "In the content model of %s, there are multiple "
19902: 			    "element declarations for '%s' with different "
19903: 			    "type definitions",
19904: 			    xmlSchemaGetComponentDesignation(&strA,
19905: 				ctxtComponent),
19906: 			    xmlSchemaFormatQName(&strB,
19907: 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19908: 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19909: 			FREE_AND_NULL(strA);
19910: 			FREE_AND_NULL(strB);
19911: 			return(XML_SCHEMAP_COS_NONAMBIG);
19912: 		    }
19913: 		}
19914: 		break;
19915: 	    case XML_SCHEMA_TYPE_SEQUENCE: {
19916: 		break;
19917: 		}
19918: 	    case XML_SCHEMA_TYPE_CHOICE:{
19919: 		/*
19920: 		xmlSchemaTreeItemPtr sub;
19921: 
19922: 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19923: 		while (sub != NULL) {
19924: 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19925: 			ctxtParticle, ctxtElem);
19926: 		    if (ret != 0)
19927: 			return(ret);
19928: 		    sub = sub->next;
19929: 		}
19930: 		*/
19931: 		break;
19932: 		}
19933: 	    case XML_SCHEMA_TYPE_ALL:
19934: 		break;
19935: 	    case XML_SCHEMA_TYPE_GROUP:
19936: 		break;
19937: 	    default:
19938: 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19939: 		    "xmlSchemaCheckElementDeclConsistent",
19940: 		    "found unexpected term of type '%s' in content model",
19941: 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19942: 		return(-1);
19943: 	}
19944: 	cur = (xmlSchemaParticlePtr) cur->next;
19945:     }
19946: 
19947: exit:
19948:     return(ret);
19949: }
19950: #endif
19951: 
19952: /**
19953:  * xmlSchemaCheckElementDeclComponent
19954:  * @item:  an schema element declaration/particle
19955:  * @ctxt:  a schema parser context
19956:  * @name:  the name of the attribute
19957:  *
19958:  * Validates the value constraints of an element declaration.
19959:  * Adds substitution group members.
19960:  */
19961: static void
19962: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19963: 				   xmlSchemaParserCtxtPtr ctxt)
19964: {
19965:     if (elemDecl == NULL)
19966: 	return;
19967:     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19968: 	return;
19969:     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19970:     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19971: 	/*
19972: 	* Adds substitution group members.
19973: 	*/
19974: 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19975:     }
19976: }
19977: 
19978: /**
19979:  * xmlSchemaResolveModelGroupParticleReferences:
19980:  * @particle:  a particle component
19981:  * @ctxt:  a parser context
19982:  *
19983:  * Resolves references of a model group's {particles} to
19984:  * model group definitions and to element declarations.
19985:  */
19986: static void
19987: xmlSchemaResolveModelGroupParticleReferences(
19988:     xmlSchemaParserCtxtPtr ctxt,
19989:     xmlSchemaModelGroupPtr mg)
19990: {
19991:     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19992:     xmlSchemaQNameRefPtr ref;
19993:     xmlSchemaBasicItemPtr refItem;
19994: 
19995:     /*
19996:     * URGENT TODO: Test this.
19997:     */
19998:     while (particle != NULL) {
19999: 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20000: 	    ((WXS_PARTICLE_TERM(particle))->type !=
20001: 		XML_SCHEMA_EXTRA_QNAMEREF))
20002: 	{
20003: 	    goto next_particle;
20004: 	}
20005: 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20006: 	/*
20007: 	* Resolve the reference.
20008: 	* NULL the {term} by default.
20009: 	*/
20010: 	particle->children = NULL;
20011: 
20012: 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20013: 	    ref->itemType, ref->name, ref->targetNamespace);
20014: 	if (refItem == NULL) {
20015: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20016: 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20017: 		ref->targetNamespace, ref->itemType, NULL);
20018: 	    /* TODO: remove the particle. */
20019: 	    goto next_particle;
20020: 	}
20021: 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20022: 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20023: 		/* TODO: remove the particle. */
20024: 		goto next_particle;
20025: 	    /*
20026: 	    * NOTE that we will assign the model group definition
20027: 	    * itself to the "term" of the particle. This will ease
20028: 	    * the check for circular model group definitions. After
20029: 	    * that the "term" will be assigned the model group of the
20030: 	    * model group definition.
20031: 	    */
20032: 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20033: 		    XML_SCHEMA_TYPE_ALL) {
20034: 		/*
20035: 		* SPEC cos-all-limited (1)
20036: 		* SPEC cos-all-limited (1.2)
20037: 		* "It appears only as the value of one or both of the
20038: 		* following properties:"
20039: 		* (1.1) "the {model group} property of a model group
20040: 		*        definition."
20041: 		* (1.2) "the {term} property of a particle [... of] the "
20042: 		* {content type} of a complex type definition."
20043: 		*/
20044: 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
20045: 		    /* TODO: error code */
20046: 		    XML_SCHEMAP_COS_ALL_LIMITED,
20047: 		    WXS_ITEM_NODE(particle), NULL,
20048: 		    "A model group definition is referenced, but "
20049: 		    "it contains an 'all' model group, which "
20050: 		    "cannot be contained by model groups",
20051: 		    NULL, NULL);
20052: 		/* TODO: remove the particle. */
20053: 		goto next_particle;
20054: 	    }
20055: 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
20056: 	} else {
20057: 	    /*
20058: 	    * TODO: Are referenced element declarations the only
20059: 	    * other components we expect here?
20060: 	    */
20061: 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
20062: 	}
20063: next_particle:
20064: 	particle = WXS_PTC_CAST particle->next;
20065:     }
20066: }
20067: 
20068: static int
20069: xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20070: 		       xmlSchemaValPtr y)
20071: {
20072:     xmlSchemaTypePtr tx, ty, ptx, pty;
20073:     int ret;
20074: 
20075:     while (x != NULL) {
20076: 	/* Same types. */
20077: 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20078: 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20079: 	ptx = xmlSchemaGetPrimitiveType(tx);
20080: 	pty = xmlSchemaGetPrimitiveType(ty);
20081: 	/*
20082: 	* (1) if a datatype T' is �derived� by �restriction� from an
20083: 	* atomic datatype T then the �value space� of T' is a subset of
20084: 	* the �value space� of T. */
20085: 	/*
20086: 	* (2) if datatypes T' and T'' are �derived� by �restriction�
20087: 	* from a common atomic ancestor T then the �value space�s of T'
20088: 	* and T'' may overlap.
20089: 	*/
20090: 	if (ptx != pty)
20091: 	    return(0);
20092: 	/*
20093: 	* We assume computed values to be normalized, so do a fast
20094: 	* string comparison for string based types.
20095: 	*/
20096: 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20097: 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20098: 	    if (! xmlStrEqual(
20099: 		xmlSchemaValueGetAsString(x),
20100: 		xmlSchemaValueGetAsString(y)))
20101: 		return (0);
20102: 	} else {
20103: 	    ret = xmlSchemaCompareValuesWhtsp(
20104: 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
20105: 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
20106: 	    if (ret == -2)
20107: 		return(-1);
20108: 	    if (ret != 0)
20109: 		return(0);
20110: 	}
20111: 	/*
20112: 	* Lists.
20113: 	*/
20114: 	x = xmlSchemaValueGetNext(x);
20115: 	if (x != NULL) {
20116: 	    y = xmlSchemaValueGetNext(y);
20117: 	    if (y == NULL)
20118: 		return (0);
20119: 	} else if (xmlSchemaValueGetNext(y) != NULL)
20120: 	    return (0);
20121: 	else
20122: 	    return (1);
20123:     }
20124:     return (0);
20125: }
20126: 
20127: /**
20128:  * xmlSchemaResolveAttrUseReferences:
20129:  * @item:  an attribute use
20130:  * @ctxt:  a parser context
20131:  *
20132:  * Resolves the referenced attribute declaration.
20133:  */
20134: static int
20135: xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20136: 				  xmlSchemaParserCtxtPtr ctxt)
20137: {
20138:     if ((ctxt == NULL) || (ause == NULL))
20139: 	return(-1);
20140:     if ((ause->attrDecl == NULL) ||
20141: 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20142: 	return(0);
20143: 
20144:     {
20145: 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20146: 
20147: 	/*
20148: 	* TODO: Evaluate, what errors could occur if the declaration is not
20149: 	* found.
20150: 	*/
20151: 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20152: 	    ref->name, ref->targetNamespace);
20153:         if (ause->attrDecl == NULL) {
20154: 	    xmlSchemaPResCompAttrErr(ctxt,
20155: 	    	XML_SCHEMAP_SRC_RESOLVE,
20156: 		WXS_BASIC_CAST ause, ause->node,
20157: 		"ref", ref->name, ref->targetNamespace,
20158: 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20159:             return(ctxt->err);;
20160:         }
20161:     }
20162:     return(0);
20163: }
20164: 
20165: /**
20166:  * xmlSchemaCheckAttrUsePropsCorrect:
20167:  * @ctxt:  a parser context
20168:  * @use:  an attribute use
20169:  *
20170:  * Schema Component Constraint:
20171:  * Attribute Use Correct (au-props-correct)
20172:  *
20173:  */
20174: static int
20175: xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20176: 			     xmlSchemaAttributeUsePtr use)
20177: {
20178:     if ((ctxt == NULL) || (use == NULL))
20179: 	return(-1);
20180:     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20181: 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20182: 	return(0);
20183: 
20184:     /*
20185:     * SPEC au-props-correct (1)
20186:     * "The values of the properties of an attribute use must be as
20187:     * described in the property tableau in The Attribute Use Schema
20188:     * Component (�3.5.1), modulo the impact of Missing
20189:     * Sub-components (�5.3)."
20190:     */
20191: 
20192:     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20193: 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20194:         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20195:     {
20196: 	xmlSchemaPCustomErr(ctxt,
20197: 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20198: 	    WXS_BASIC_CAST use, NULL,
20199: 	    "The attribute declaration has a 'fixed' value constraint "
20200: 	    ", thus the attribute use must also have a 'fixed' value "
20201: 	    "constraint",
20202: 	    NULL);
20203: 	return(ctxt->err);
20204:     }
20205:     /*
20206:     * Compute and check the value constraint's value.
20207:     */
20208:     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20209: 	int ret;
20210: 	/*
20211: 	* TODO: The spec seems to be missing a check of the
20212: 	* value constraint of the attribute use. We will do it here.
20213: 	*/
20214: 	/*
20215: 	* SPEC a-props-correct (3)
20216: 	*/
20217: 	if (xmlSchemaIsDerivedFromBuiltInType(
20218: 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20219: 	{
20220: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20221: 		XML_SCHEMAP_AU_PROPS_CORRECT,
20222: 		NULL, WXS_BASIC_CAST use,
20223: 		"Value constraints are not allowed if the type definition "
20224: 		"is or is derived from xs:ID",
20225: 		NULL, NULL);
20226: 	    return(ctxt->err);
20227: 	}
20228: 
20229: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20230: 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
20231: 	    use->defValue, &(use->defVal),
20232: 	    1, 1, 0);
20233: 	if (ret != 0) {
20234: 	    if (ret < 0) {
20235: 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20236: 		    "calling xmlSchemaVCheckCVCSimpleType()");
20237: 		return(-1);
20238: 	    }
20239: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20240: 		XML_SCHEMAP_AU_PROPS_CORRECT,
20241: 		NULL, WXS_BASIC_CAST use,
20242: 		"The value of the value constraint is not valid",
20243: 		NULL, NULL);
20244: 	    return(ctxt->err);
20245: 	}
20246:     }
20247:     /*
20248:     * SPEC au-props-correct (2)
20249:     * "If the {attribute declaration} has a fixed
20250:     * {value constraint}, then if the attribute use itself has a
20251:     * {value constraint}, it must also be fixed and its value must match
20252:     * that of the {attribute declaration}'s {value constraint}."
20253:     */
20254:     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20255: 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20256:     {
20257: 	if (! xmlSchemaAreValuesEqual(use->defVal,
20258: 		(WXS_ATTRUSE_DECL(use))->defVal))
20259: 	{
20260: 	    xmlSchemaPCustomErr(ctxt,
20261: 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
20262: 		WXS_BASIC_CAST use, NULL,
20263: 		"The 'fixed' value constraint of the attribute use "
20264: 		"must match the attribute declaration's value "
20265: 		"constraint '%s'",
20266: 		(WXS_ATTRUSE_DECL(use))->defValue);
20267: 	}
20268: 	return(ctxt->err);
20269:     }
20270:     return(0);
20271: }
20272: 
20273: 
20274: 
20275: 
20276: /**
20277:  * xmlSchemaResolveAttrTypeReferences:
20278:  * @item:  an attribute declaration
20279:  * @ctxt:  a parser context
20280:  *
20281:  * Resolves the referenced type definition component.
20282:  */
20283: static int
20284: xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20285: 				   xmlSchemaParserCtxtPtr ctxt)
20286: {
20287:     /*
20288:     * The simple type definition corresponding to the <simpleType> element
20289:     * information item in the [children], if present, otherwise the simple
20290:     * type definition �resolved� to by the �actual value� of the type
20291:     * [attribute], if present, otherwise the �simple ur-type definition�.
20292:     */
20293:     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20294: 	return(0);
20295:     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20296:     if (item->subtypes != NULL)
20297:         return(0);
20298:     if (item->typeName != NULL) {
20299:         xmlSchemaTypePtr type;
20300: 
20301: 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
20302: 	    item->typeNs);
20303: 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20304: 	    xmlSchemaPResCompAttrErr(ctxt,
20305: 		XML_SCHEMAP_SRC_RESOLVE,
20306: 		WXS_BASIC_CAST item, item->node,
20307: 		"type", item->typeName, item->typeNs,
20308: 		XML_SCHEMA_TYPE_SIMPLE, NULL);
20309: 	    return(ctxt->err);
20310: 	} else
20311: 	    item->subtypes = type;
20312: 
20313:     } else {
20314: 	/*
20315: 	* The type defaults to the xs:anySimpleType.
20316: 	*/
20317: 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20318:     }
20319:     return(0);
20320: }
20321: 
20322: /**
20323:  * xmlSchemaResolveIDCKeyReferences:
20324:  * @idc:  the identity-constraint definition
20325:  * @ctxt:  the schema parser context
20326:  * @name:  the attribute name
20327:  *
20328:  * Resolve keyRef references to key/unique IDCs.
20329:  * Schema Component Constraint:
20330:  *   Identity-constraint Definition Properties Correct (c-props-correct)
20331:  */
20332: static int
20333: xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20334: 			  xmlSchemaParserCtxtPtr pctxt)
20335: {
20336:     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20337:         return(0);
20338:     if (idc->ref->name != NULL) {
20339: 	idc->ref->item = (xmlSchemaBasicItemPtr)
20340: 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20341: 		idc->ref->targetNamespace);
20342:         if (idc->ref->item == NULL) {
20343: 	    /*
20344: 	    * TODO: It is actually not an error to fail to resolve
20345: 	    * at this stage. BUT we need to be that strict!
20346: 	    */
20347: 	    xmlSchemaPResCompAttrErr(pctxt,
20348: 		XML_SCHEMAP_SRC_RESOLVE,
20349: 		WXS_BASIC_CAST idc, idc->node,
20350: 		"refer", idc->ref->name,
20351: 		idc->ref->targetNamespace,
20352: 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
20353:             return(pctxt->err);
20354: 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20355: 	    /*
20356: 	    * SPEC c-props-correct (1)
20357: 	    */
20358: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20359: 		XML_SCHEMAP_C_PROPS_CORRECT,
20360: 		NULL, WXS_BASIC_CAST idc,
20361: 		"The keyref references a keyref",
20362: 		NULL, NULL);
20363: 	    idc->ref->item = NULL;
20364: 	    return(pctxt->err);
20365: 	} else {
20366: 	    if (idc->nbFields !=
20367: 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20368: 		xmlChar *str = NULL;
20369: 		xmlSchemaIDCPtr refer;
20370: 
20371: 		refer = (xmlSchemaIDCPtr) idc->ref->item;
20372: 		/*
20373: 		* SPEC c-props-correct(2)
20374: 		* "If the {identity-constraint category} is keyref,
20375: 		* the cardinality of the {fields} must equal that of
20376: 		* the {fields} of the {referenced key}.
20377: 		*/
20378: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
20379: 		    XML_SCHEMAP_C_PROPS_CORRECT,
20380: 		    NULL, WXS_BASIC_CAST idc,
20381: 		    "The cardinality of the keyref differs from the "
20382: 		    "cardinality of the referenced key/unique '%s'",
20383: 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
20384: 			refer->name),
20385: 		    NULL);
20386: 		FREE_AND_NULL(str)
20387: 		return(pctxt->err);
20388: 	    }
20389: 	}
20390:     }
20391:     return(0);
20392: }
20393: 
20394: static int
20395: xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20396: 				       xmlSchemaParserCtxtPtr pctxt)
20397: {
20398:     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20399: 	prohib->targetNamespace) == NULL) {
20400: 
20401: 	xmlSchemaPResCompAttrErr(pctxt,
20402: 	    XML_SCHEMAP_SRC_RESOLVE,
20403: 	    NULL, prohib->node,
20404: 	    "ref", prohib->name, prohib->targetNamespace,
20405: 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20406: 	return(XML_SCHEMAP_SRC_RESOLVE);
20407:     }
20408:     return(0);
20409: }
20410: 
20411: #define WXS_REDEFINED_TYPE(c) \
20412: (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20413: 
20414: #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20415: (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20416: 
20417: #define WXS_REDEFINED_ATTR_GROUP(c) \
20418: (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20419: 
20420: static int
20421: xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20422: {
20423:     int err = 0;
20424:     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20425:     xmlSchemaBasicItemPtr prev, item;
20426:     int wasRedefined;
20427: 
20428:     if (redef == NULL)
20429: 	return(0);
20430: 
20431:     do {
20432: 	item = redef->item;
20433: 	/*
20434: 	* First try to locate the redefined component in the
20435: 	* schema graph starting with the redefined schema.
20436: 	* NOTE: According to this schema bug entry:
20437: 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20438: 	*   it's not clear if the referenced component needs to originate
20439: 	*   from the <redefine>d schema _document_ or the schema; the latter
20440: 	*   would include all imported and included sub-schemas of the
20441: 	*   <redefine>d schema. Currenlty we latter approach is used.
20442: 	*   SUPPLEMENT: It seems that the WG moves towards the latter
20443: 	*   approach, so we are doing it right.
20444: 	*
20445: 	*/
20446: 	prev = xmlSchemaFindRedefCompInGraph(
20447: 	    redef->targetBucket, item->type,
20448: 	    redef->refName, redef->refTargetNs);
20449: 	if (prev == NULL) {
20450: 	    xmlChar *str = NULL;
20451: 	    xmlNodePtr node;
20452: 
20453: 	    /*
20454: 	    * SPEC src-redefine:
20455: 	    * (6.2.1) "The �actual value� of its own name attribute plus
20456: 	    * target namespace must successfully �resolve� to a model
20457: 	    * group definition in I."
20458: 	    * (7.2.1) "The �actual value� of its own name attribute plus
20459: 	    * target namespace must successfully �resolve� to an attribute
20460: 	    * group definition in I."
20461: 
20462: 	    *
20463: 	    * Note that, if we are redefining with the use of references
20464: 	    * to components, the spec assumes the src-resolve to be used;
20465: 	    * but this won't assure that we search only *inside* the
20466: 	    * redefined schema.
20467: 	    */
20468: 	    if (redef->reference)
20469: 		node = WXS_ITEM_NODE(redef->reference);
20470: 	    else
20471: 		node = WXS_ITEM_NODE(item);
20472: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20473: 		/*
20474: 		* TODO: error code.
20475: 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20476: 		* reference kind.
20477: 		*/
20478: 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20479: 		"The %s '%s' to be redefined could not be found in "
20480: 		"the redefined schema",
20481: 		WXS_ITEM_TYPE_NAME(item),
20482: 		xmlSchemaFormatQName(&str, redef->refTargetNs,
20483: 		    redef->refName));
20484: 	    FREE_AND_NULL(str);
20485: 	    err = pctxt->err;
20486: 	    redef = redef->next;
20487: 	    continue;
20488: 	}
20489: 	/*
20490: 	* TODO: Obtaining and setting the redefinition state is really
20491: 	* clumsy.
20492: 	*/
20493: 	wasRedefined = 0;
20494: 	switch (item->type) {
20495: 	    case XML_SCHEMA_TYPE_COMPLEX:
20496: 	    case XML_SCHEMA_TYPE_SIMPLE:
20497: 		if ((WXS_TYPE_CAST prev)->flags &
20498: 		    XML_SCHEMAS_TYPE_REDEFINED)
20499: 		{
20500: 		    wasRedefined = 1;
20501: 		    break;
20502: 		}
20503: 		/* Mark it as redefined. */
20504: 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20505: 		/*
20506: 		* Assign the redefined type to the
20507: 		* base type of the redefining type.
20508: 		* TODO: How
20509: 		*/
20510: 		((xmlSchemaTypePtr) item)->baseType =
20511: 		    (xmlSchemaTypePtr) prev;
20512: 		break;
20513: 	    case XML_SCHEMA_TYPE_GROUP:
20514: 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20515: 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20516: 		{
20517: 		    wasRedefined = 1;
20518: 		    break;
20519: 		}
20520: 		/* Mark it as redefined. */
20521: 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20522: 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20523: 		if (redef->reference != NULL) {
20524: 		    /*
20525: 		    * Overwrite the QName-reference with the
20526: 		    * referenced model group def.
20527: 		    */
20528: 		    (WXS_PTC_CAST redef->reference)->children =
20529: 			WXS_TREE_CAST prev;
20530: 		}
20531: 		redef->target = prev;
20532: 		break;
20533: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20534: 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
20535: 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
20536: 		{
20537: 		    wasRedefined = 1;
20538: 		    break;
20539: 		}
20540: 		(WXS_ATTR_GROUP_CAST prev)->flags |=
20541: 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
20542: 		if (redef->reference != NULL) {
20543: 		    /*
20544: 		    * Assign the redefined attribute group to the
20545: 		    * QName-reference component.
20546: 		    * This is the easy case, since we will just
20547: 		    * expand the redefined group.
20548: 		    */
20549: 		    (WXS_QNAME_CAST redef->reference)->item = prev;
20550: 		    redef->target = NULL;
20551: 		} else {
20552: 		    /*
20553: 		    * This is the complicated case: we need
20554: 		    * to apply src-redefine (7.2.2) at a later
20555: 		    * stage, i.e. when attribute group references
20556: 		    * have beed expanded and simple types have
20557: 		    * beed fixed.
20558: 		    */
20559: 		    redef->target = prev;
20560: 		}
20561: 		break;
20562: 	    default:
20563: 		PERROR_INT("xmlSchemaResolveRedefReferences",
20564: 		    "Unexpected redefined component type");
20565: 		return(-1);
20566: 	}
20567: 	if (wasRedefined) {
20568: 	    xmlChar *str = NULL;
20569: 	    xmlNodePtr node;
20570: 
20571: 	    if (redef->reference)
20572: 		node = WXS_ITEM_NODE(redef->reference);
20573: 	    else
20574: 		node = WXS_ITEM_NODE(redef->item);
20575: 
20576: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20577: 		/* TODO: error code. */
20578: 		XML_SCHEMAP_SRC_REDEFINE,
20579: 		node, NULL,
20580: 		"The referenced %s was already redefined. Multiple "
20581: 		"redefinition of the same component is not supported",
20582: 		xmlSchemaGetComponentDesignation(&str, prev),
20583: 		NULL);
20584: 	    FREE_AND_NULL(str)
20585: 	    err = pctxt->err;
20586: 	    redef = redef->next;
20587: 	    continue;
20588: 	}
20589: 	redef = redef->next;
20590:     } while (redef != NULL);
20591: 
20592:     return(err);
20593: }
20594: 
20595: static int
20596: xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20597: {
20598:     int err = 0;
20599:     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20600:     xmlSchemaBasicItemPtr item;
20601: 
20602:     if (redef == NULL)
20603: 	return(0);
20604: 
20605:     do {
20606: 	if (redef->target == NULL) {
20607: 	    redef = redef->next;
20608: 	    continue;
20609: 	}
20610: 	item = redef->item;
20611: 
20612: 	switch (item->type) {
20613: 	    case XML_SCHEMA_TYPE_SIMPLE:
20614: 	    case XML_SCHEMA_TYPE_COMPLEX:
20615: 		/*
20616: 		* Since the spec wants the {name} of the redefined
20617: 		* type to be 'absent', we'll NULL it.
20618: 		*/
20619: 		(WXS_TYPE_CAST redef->target)->name = NULL;
20620: 
20621: 		/*
20622: 		* TODO: Seems like there's nothing more to do. The normal
20623: 		* inheritance mechanism is used. But not 100% sure.
20624: 		*/
20625: 		break;
20626: 	    case XML_SCHEMA_TYPE_GROUP:
20627: 		/*
20628: 		* URGENT TODO:
20629: 		* SPEC src-redefine:
20630: 		* (6.2.2) "The {model group} of the model group definition
20631: 		* which corresponds to it per XML Representation of Model
20632: 		* Group Definition Schema Components (�3.7.2) must be a
20633: 		* �valid restriction� of the {model group} of that model
20634: 		* group definition in I, as defined in Particle Valid
20635: 		* (Restriction) (�3.9.6)."
20636: 		*/
20637: 		break;
20638: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20639: 		/*
20640: 		* SPEC src-redefine:
20641: 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
20642: 		* the attribute group definition which corresponds to it
20643: 		* per XML Representation of Attribute Group Definition Schema
20644: 		* Components (�3.6.2) must be �valid restrictions� of the
20645: 		* {attribute uses} and {attribute wildcard} of that attribute
20646: 		* group definition in I, as defined in clause 2, clause 3 and
20647: 		* clause 4 of Derivation Valid (Restriction, Complex)
20648: 		* (�3.4.6) (where references to the base type definition are
20649: 		* understood as references to the attribute group definition
20650: 		* in I)."
20651: 		*/
20652: 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20653: 		    XML_SCHEMA_ACTION_REDEFINE,
20654: 		    item, redef->target,
20655: 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
20656: 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20657: 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20658: 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20659: 		if (err == -1)
20660: 		    return(-1);
20661: 		break;
20662: 	    default:
20663: 		break;
20664: 	}
20665: 	redef = redef->next;
20666:     } while (redef != NULL);
20667:     return(0);
20668: }
20669: 
20670: 
20671: static int
20672: xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20673: 		       xmlSchemaBucketPtr bucket)
20674: {
20675:     xmlSchemaBasicItemPtr item;
20676:     int err;
20677:     xmlHashTablePtr *table;
20678:     const xmlChar *name;
20679:     int i;
20680: 
20681: #define WXS_GET_GLOBAL_HASH(c, slot) { \
20682:     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20683: 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
20684:     else \
20685: 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20686: 
20687:     /*
20688:     * Add global components to the schema's hash tables.
20689:     * This is the place where duplicate components will be
20690:     * detected.
20691:     * TODO: I think normally we should support imports of the
20692:     *   same namespace from multiple locations. We don't do currently,
20693:     *   but if we do then according to:
20694:     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20695:     *   we would need, if imported directly, to import redefined
20696:     *   components as well to be able to catch clashing components.
20697:     *   (I hope I'll still know what this means after some months :-()
20698:     */
20699:     if (bucket == NULL)
20700: 	return(-1);
20701:     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20702: 	return(0);
20703:     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20704: 
20705:     for (i = 0; i < bucket->globals->nbItems; i++) {
20706: 	item = bucket->globals->items[i];
20707: 	table = NULL;
20708: 	switch (item->type) {
20709: 	    case XML_SCHEMA_TYPE_COMPLEX:
20710: 	    case XML_SCHEMA_TYPE_SIMPLE:
20711: 		if (WXS_REDEFINED_TYPE(item))
20712: 		    continue;
20713: 		name = (WXS_TYPE_CAST item)->name;
20714: 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20715: 		break;
20716: 	    case XML_SCHEMA_TYPE_ELEMENT:
20717: 		name = (WXS_ELEM_CAST item)->name;
20718: 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20719: 		break;
20720: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
20721: 		name = (WXS_ATTR_CAST item)->name;
20722: 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20723: 		break;
20724: 	    case XML_SCHEMA_TYPE_GROUP:
20725: 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20726: 		    continue;
20727: 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20728: 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20729: 		break;
20730: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20731: 		if (WXS_REDEFINED_ATTR_GROUP(item))
20732: 		    continue;
20733: 		name = (WXS_ATTR_GROUP_CAST item)->name;
20734: 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20735: 		break;
20736: 	    case XML_SCHEMA_TYPE_IDC_KEY:
20737: 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
20738: 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
20739: 		name = (WXS_IDC_CAST item)->name;
20740: 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
20741: 		break;
20742: 	    case XML_SCHEMA_TYPE_NOTATION:
20743: 		name = ((xmlSchemaNotationPtr) item)->name;
20744: 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20745: 		break;
20746: 	    default:
20747: 		PERROR_INT("xmlSchemaAddComponents",
20748: 		    "Unexpected global component type");
20749: 		continue;
20750: 	}
20751: 	if (*table == NULL) {
20752: 	    *table = xmlHashCreateDict(10, pctxt->dict);
20753: 	    if (*table == NULL) {
20754: 		PERROR_INT("xmlSchemaAddComponents",
20755: 		    "failed to create a component hash table");
20756: 		return(-1);
20757: 	    }
20758: 	}
20759: 	err = xmlHashAddEntry(*table, name, item);
20760: 	if (err != 0) {
20761: 	    xmlChar *str = NULL;
20762: 
20763: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20764: 		XML_SCHEMAP_REDEFINED_TYPE,
20765: 		WXS_ITEM_NODE(item),
20766: 		WXS_BASIC_CAST item,
20767: 		"A global %s '%s' does already exist",
20768: 		WXS_ITEM_TYPE_NAME(item),
20769: 		xmlSchemaGetComponentQName(&str, item));
20770: 	    FREE_AND_NULL(str);
20771: 	}
20772:     }
20773:     /*
20774:     * Process imported/included schemas.
20775:     */
20776:     if (bucket->relations != NULL) {
20777: 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
20778: 	do {
20779: 	    if ((rel->bucket != NULL) &&
20780: 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20781: 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20782: 		    return(-1);
20783: 	    }
20784: 	    rel = rel->next;
20785: 	} while (rel != NULL);
20786:     }
20787:     return(0);
20788: }
20789: 
20790: static int
20791: xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20792: 			 xmlSchemaBucketPtr rootBucket)
20793: {
20794:     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20795:     xmlSchemaTreeItemPtr item, *items;
20796:     int nbItems, i, ret = 0;
20797:     xmlSchemaBucketPtr oldbucket = con->bucket;
20798:     xmlSchemaElementPtr elemDecl;
20799: 
20800: #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20801: 
20802:     if ((con->pending == NULL) ||
20803: 	(con->pending->nbItems == 0))
20804: 	return(0);
20805: 
20806:     /*
20807:     * Since xmlSchemaFixupComplexType() will create new particles
20808:     * (local components), and those particle components need a bucket
20809:     * on the constructor, we'll assure here that the constructor has
20810:     * a bucket.
20811:     * TODO: Think about storing locals _only_ on the main bucket.
20812:     */
20813:     if (con->bucket == NULL)
20814: 	con->bucket = rootBucket;
20815: 
20816:     /* TODO:
20817:     * SPEC (src-redefine):
20818:     * (6.2) "If it has no such self-reference, then all of the
20819:     * following must be true:"
20820: 
20821:     * (6.2.2) The {model group} of the model group definition which
20822:     * corresponds to it per XML Representation of Model Group
20823:     * Definition Schema Components (�3.7.2) must be a �valid
20824:     * restriction� of the {model group} of that model group definition
20825:     * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
20826:     */
20827:     xmlSchemaCheckSRCRedefineFirst(pctxt);
20828: 
20829:     /*
20830:     * Add global components to the schemata's hash tables.
20831:     */
20832:     xmlSchemaAddComponents(pctxt, rootBucket);
20833: 
20834:     pctxt->ctxtType = NULL;
20835:     items = (xmlSchemaTreeItemPtr *) con->pending->items;
20836:     nbItems = con->pending->nbItems;
20837:     /*
20838:     * Now that we have parsed *all* the schema document(s) and converted
20839:     * them to schema components, we can resolve references, apply component
20840:     * constraints, create the FSA from the content model, etc.
20841:     */
20842:     /*
20843:     * Resolve references of..
20844:     *
20845:     * 1. element declarations:
20846:     *   - the type definition
20847:     *   - the substitution group affiliation
20848:     * 2. simple/complex types:
20849:     *   - the base type definition
20850:     *   - the memberTypes of union types
20851:     *   - the itemType of list types
20852:     * 3. attributes declarations and attribute uses:
20853:     *   - the type definition
20854:     *   - if an attribute use, then the attribute declaration
20855:     * 4. attribute group references:
20856:     *   - the attribute group definition
20857:     * 5. particles:
20858:     *   - the term of the particle (e.g. a model group)
20859:     * 6. IDC key-references:
20860:     *   - the referenced IDC 'key' or 'unique' definition
20861:     * 7. Attribute prohibitions which had a "ref" attribute.
20862:     */
20863:     for (i = 0; i < nbItems; i++) {
20864: 	item = items[i];
20865: 	switch (item->type) {
20866: 	    case XML_SCHEMA_TYPE_ELEMENT:
20867: 		xmlSchemaResolveElementReferences(
20868: 		    (xmlSchemaElementPtr) item, pctxt);
20869: 		FIXHFAILURE;
20870: 		break;
20871: 	    case XML_SCHEMA_TYPE_COMPLEX:
20872: 	    case XML_SCHEMA_TYPE_SIMPLE:
20873: 		xmlSchemaResolveTypeReferences(
20874: 		    (xmlSchemaTypePtr) item, pctxt);
20875: 		FIXHFAILURE;
20876: 		break;
20877: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
20878: 		xmlSchemaResolveAttrTypeReferences(
20879: 		    (xmlSchemaAttributePtr) item, pctxt);
20880: 		FIXHFAILURE;
20881: 		break;
20882: 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20883: 		xmlSchemaResolveAttrUseReferences(
20884: 		    (xmlSchemaAttributeUsePtr) item, pctxt);
20885: 		FIXHFAILURE;
20886: 		break;
20887: 	    case XML_SCHEMA_EXTRA_QNAMEREF:
20888: 		if ((WXS_QNAME_CAST item)->itemType ==
20889: 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20890: 		{
20891: 		    xmlSchemaResolveAttrGroupReferences(
20892: 			WXS_QNAME_CAST item, pctxt);
20893: 		}
20894: 		FIXHFAILURE;
20895: 		break;
20896: 	    case XML_SCHEMA_TYPE_SEQUENCE:
20897: 	    case XML_SCHEMA_TYPE_CHOICE:
20898: 	    case XML_SCHEMA_TYPE_ALL:
20899: 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
20900: 		    WXS_MODEL_GROUP_CAST item);
20901: 		FIXHFAILURE;
20902: 		break;
20903: 	    case XML_SCHEMA_TYPE_IDC_KEY:
20904: 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
20905: 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
20906: 		xmlSchemaResolveIDCKeyReferences(
20907: 		    (xmlSchemaIDCPtr) item, pctxt);
20908: 		FIXHFAILURE;
20909: 		break;
20910: 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20911: 		/*
20912: 		* Handle attribue prohibition which had a
20913: 		* "ref" attribute.
20914: 		*/
20915: 		xmlSchemaResolveAttrUseProhibReferences(
20916: 		    WXS_ATTR_PROHIB_CAST item, pctxt);
20917: 		FIXHFAILURE;
20918: 		break;
20919: 	    default:
20920: 		break;
20921: 	}
20922:     }
20923:     if (pctxt->nberrors != 0)
20924: 	goto exit_error;
20925: 
20926:     /*
20927:     * Now that all references are resolved we
20928:     * can check for circularity of...
20929:     * 1. the base axis of type definitions
20930:     * 2. nested model group definitions
20931:     * 3. nested attribute group definitions
20932:     * TODO: check for circual substitution groups.
20933:     */
20934:     for (i = 0; i < nbItems; i++) {
20935: 	item = items[i];
20936: 	/*
20937: 	* Let's better stop on the first error here.
20938: 	*/
20939: 	switch (item->type) {
20940: 	    case XML_SCHEMA_TYPE_COMPLEX:
20941: 	    case XML_SCHEMA_TYPE_SIMPLE:
20942: 		xmlSchemaCheckTypeDefCircular(
20943: 		    (xmlSchemaTypePtr) item, pctxt);
20944: 		FIXHFAILURE;
20945: 		if (pctxt->nberrors != 0)
20946: 		    goto exit_error;
20947: 		break;
20948: 	    case XML_SCHEMA_TYPE_GROUP:
20949: 		xmlSchemaCheckGroupDefCircular(
20950: 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
20951: 		FIXHFAILURE;
20952: 		if (pctxt->nberrors != 0)
20953: 		    goto exit_error;
20954: 		break;
20955: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20956: 		xmlSchemaCheckAttrGroupCircular(
20957: 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
20958: 		FIXHFAILURE;
20959: 		if (pctxt->nberrors != 0)
20960: 		    goto exit_error;
20961: 		break;
20962: 	    default:
20963: 		break;
20964: 	}
20965:     }
20966:     if (pctxt->nberrors != 0)
20967: 	goto exit_error;
20968:     /*
20969:     * Model group definition references:
20970:     * Such a reference is reflected by a particle at the component
20971:     * level. Until now the 'term' of such particles pointed
20972:     * to the model group definition; this was done, in order to
20973:     * ease circularity checks. Now we need to set the 'term' of
20974:     * such particles to the model group of the model group definition.
20975:     */
20976:     for (i = 0; i < nbItems; i++) {
20977: 	item = items[i];
20978: 	switch (item->type) {
20979: 	    case XML_SCHEMA_TYPE_SEQUENCE:
20980: 	    case XML_SCHEMA_TYPE_CHOICE:
20981: 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20982: 		    WXS_MODEL_GROUP_CAST item);
20983: 		break;
20984: 	    default:
20985: 		break;
20986: 	}
20987:     }
20988:     if (pctxt->nberrors != 0)
20989: 	goto exit_error;
20990:     /*
20991:     * Expand attribute group references of attribute group definitions.
20992:     */
20993:     for (i = 0; i < nbItems; i++) {
20994: 	item = items[i];
20995: 	switch (item->type) {
20996:             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20997: 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20998: 		    WXS_ATTR_GROUP_HAS_REFS(item))
20999: 		{
21000: 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
21001: 			WXS_ATTR_GROUP_CAST item);
21002: 		    FIXHFAILURE;
21003: 		}
21004: 		break;
21005: 	    default:
21006: 		break;
21007: 	}
21008:     }
21009:     if (pctxt->nberrors != 0)
21010: 	goto exit_error;
21011:     /*
21012:     * First compute the variety of simple types. This is needed as
21013:     * a seperate step, since otherwise we won't be able to detect
21014:     * circular union types in all cases.
21015:     */
21016:     for (i = 0; i < nbItems; i++) {
21017: 	item = items[i];
21018: 	switch (item->type) {
21019:             case XML_SCHEMA_TYPE_SIMPLE:
21020: 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21021: 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
21022: 			(xmlSchemaTypePtr) item);
21023: 		    FIXHFAILURE;
21024: 		}
21025: 		break;
21026: 	    default:
21027: 		break;
21028: 	}
21029:     }
21030:     if (pctxt->nberrors != 0)
21031: 	goto exit_error;
21032:     /*
21033:     * Detect circular union types. Note that this needs the variety to
21034:     * be already computed.
21035:     */
21036:     for (i = 0; i < nbItems; i++) {
21037: 	item = items[i];
21038: 	switch (item->type) {
21039:             case XML_SCHEMA_TYPE_SIMPLE:
21040: 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21041: 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
21042: 			(xmlSchemaTypePtr) item);
21043: 		    FIXHFAILURE;
21044: 		}
21045: 		break;
21046: 	    default:
21047: 		break;
21048: 	}
21049:     }
21050:     if (pctxt->nberrors != 0)
21051: 	goto exit_error;
21052: 
21053:     /*
21054:     * Do the complete type fixup for simple types.
21055:     */
21056:     for (i = 0; i < nbItems; i++) {
21057: 	item = items[i];
21058: 	switch (item->type) {
21059:             case XML_SCHEMA_TYPE_SIMPLE:
21060: 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21061: 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21062: 		    FIXHFAILURE;
21063: 		}
21064: 		break;
21065: 	    default:
21066: 		break;
21067: 	}
21068:     }
21069:     if (pctxt->nberrors != 0)
21070: 	goto exit_error;
21071:     /*
21072:     * At this point we need build and check all simple types.
21073:     */
21074:     /*
21075:     * Apply contraints for attribute declarations.
21076:     */
21077:     for (i = 0; i < nbItems; i++) {
21078: 	item = items[i];
21079: 	switch (item->type) {
21080: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
21081: 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21082: 		FIXHFAILURE;
21083: 		break;
21084: 	    default:
21085: 		break;
21086: 	}
21087:     }
21088:     if (pctxt->nberrors != 0)
21089: 	goto exit_error;
21090:     /*
21091:     * Apply constraints for attribute uses.
21092:     */
21093:     for (i = 0; i < nbItems; i++) {
21094: 	item = items[i];
21095: 	switch (item->type) {
21096: 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21097: 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21098: 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21099: 			WXS_ATTR_USE_CAST item);
21100: 		    FIXHFAILURE;
21101: 		}
21102: 		break;
21103: 	    default:
21104: 		break;
21105: 	}
21106:     }
21107:     if (pctxt->nberrors != 0)
21108: 	goto exit_error;
21109: 
21110:     /*
21111:     * Apply constraints for attribute group definitions.
21112:     */
21113:     for (i = 0; i < nbItems; i++) {
21114: 	item = items[i];
21115: 	switch (item->type) {
21116: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21117: 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21118: 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21119: 	    {
21120: 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21121: 		FIXHFAILURE;
21122: 	    }
21123: 	    break;
21124: 	default:
21125: 	    break;
21126: 	}
21127:     }
21128:     if (pctxt->nberrors != 0)
21129: 	goto exit_error;
21130: 
21131:     /*
21132:     * Apply constraints for redefinitions.
21133:     */
21134:     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21135: 	xmlSchemaCheckSRCRedefineSecond(pctxt);
21136:     if (pctxt->nberrors != 0)
21137: 	goto exit_error;
21138: 
21139:     /*
21140:     * Complex types are builded and checked.
21141:     */
21142:     for (i = 0; i < nbItems; i++) {
21143: 	item = con->pending->items[i];
21144: 	switch (item->type) {
21145: 	    case XML_SCHEMA_TYPE_COMPLEX:
21146: 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21147: 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21148: 		    FIXHFAILURE;
21149: 		}
21150: 		break;
21151: 	    default:
21152: 		break;
21153: 	}
21154:     }
21155:     if (pctxt->nberrors != 0)
21156: 	goto exit_error;
21157: 
21158:     /*
21159:     * The list could have changed, since xmlSchemaFixupComplexType()
21160:     * will create particles and model groups in some cases.
21161:     */
21162:     items = (xmlSchemaTreeItemPtr *) con->pending->items;
21163:     nbItems = con->pending->nbItems;
21164: 
21165:     /*
21166:     * Apply some constraints for element declarations.
21167:     */
21168:     for (i = 0; i < nbItems; i++) {
21169: 	item = items[i];
21170: 	switch (item->type) {
21171: 	    case XML_SCHEMA_TYPE_ELEMENT:
21172: 		elemDecl = (xmlSchemaElementPtr) item;
21173: 
21174: 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21175: 		{
21176: 		    xmlSchemaCheckElementDeclComponent(
21177: 			(xmlSchemaElementPtr) elemDecl, pctxt);
21178: 		    FIXHFAILURE;
21179: 		}
21180: 
21181: #ifdef WXS_ELEM_DECL_CONS_ENABLED
21182: 		/*
21183: 		* Schema Component Constraint: Element Declarations Consistent
21184: 		* Apply this constraint to local types of element declarations.
21185: 		*/
21186: 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21187: 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21188: 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21189: 		{
21190: 		    xmlSchemaCheckElementDeclConsistent(pctxt,
21191: 			WXS_BASIC_CAST elemDecl,
21192: 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21193: 			NULL, NULL, 0);
21194: 		}
21195: #endif
21196: 		break;
21197: 	    default:
21198: 		break;
21199: 	}
21200:     }
21201:     if (pctxt->nberrors != 0)
21202: 	goto exit_error;
21203: 
21204:     /*
21205:     * Finally we can build the automaton from the content model of
21206:     * complex types.
21207:     */
21208: 
21209:     for (i = 0; i < nbItems; i++) {
21210: 	item = items[i];
21211: 	switch (item->type) {
21212: 	    case XML_SCHEMA_TYPE_COMPLEX:
21213: 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21214: 		/* FIXHFAILURE; */
21215: 		break;
21216: 	    default:
21217: 		break;
21218: 	}
21219:     }
21220:     if (pctxt->nberrors != 0)
21221: 	goto exit_error;
21222:     /*
21223:     * URGENT TODO: cos-element-consistent
21224:     */
21225:     goto exit;
21226: 
21227: exit_error:
21228:     ret = pctxt->err;
21229:     goto exit;
21230: 
21231: exit_failure:
21232:     ret = -1;
21233: 
21234: exit:
21235:     /*
21236:     * Reset the constructor. This is needed for XSI acquisition, since
21237:     * those items will be processed over and over again for every XSI
21238:     * if not cleared here.
21239:     */
21240:     con->bucket = oldbucket;
21241:     con->pending->nbItems = 0;
21242:     if (con->substGroups != NULL) {
21243: 	xmlHashFree(con->substGroups,
21244: 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
21245: 	con->substGroups = NULL;
21246:     }
21247:     if (con->redefs != NULL) {
21248: 	xmlSchemaRedefListFree(con->redefs);
21249: 	con->redefs = NULL;
21250:     }
21251:     return(ret);
21252: }
21253: /**
21254:  * xmlSchemaParse:
21255:  * @ctxt:  a schema validation context
21256:  *
21257:  * parse a schema definition resource and build an internal
21258:  * XML Shema struture which can be used to validate instances.
21259:  *
21260:  * Returns the internal XML Schema structure built from the resource or
21261:  *         NULL in case of error
21262:  */
21263: xmlSchemaPtr
21264: xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21265: {
21266:     xmlSchemaPtr mainSchema = NULL;
21267:     xmlSchemaBucketPtr bucket = NULL;
21268:     int res;
21269: 
21270:     /*
21271:     * This one is used if the schema to be parsed was specified via
21272:     * the API; i.e. not automatically by the validated instance document.
21273:     */
21274: 
21275:     xmlSchemaInitTypes();
21276: 
21277:     if (ctxt == NULL)
21278:         return (NULL);
21279: 
21280:     /* TODO: Init the context. Is this all we need?*/
21281:     ctxt->nberrors = 0;
21282:     ctxt->err = 0;
21283:     ctxt->counter = 0;
21284: 
21285:     /* Create the *main* schema. */
21286:     mainSchema = xmlSchemaNewSchema(ctxt);
21287:     if (mainSchema == NULL)
21288: 	goto exit_failure;
21289:     /*
21290:     * Create the schema constructor.
21291:     */
21292:     if (ctxt->constructor == NULL) {
21293: 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21294: 	if (ctxt->constructor == NULL)
21295: 	    return(NULL);
21296: 	/* Take ownership of the constructor to be able to free it. */
21297: 	ctxt->ownsConstructor = 1;
21298:     }
21299:     ctxt->constructor->mainSchema = mainSchema;
21300:     /*
21301:     * Locate and add the schema document.
21302:     */
21303:     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21304: 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21305: 	NULL, NULL, &bucket);
21306:     if (res == -1)
21307: 	goto exit_failure;
21308:     if (res != 0)
21309: 	goto exit;
21310: 
21311:     if (bucket == NULL) {
21312: 	/* TODO: Error code, actually we failed to *locate* the schema. */
21313: 	if (ctxt->URL)
21314: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21315: 		NULL, NULL,
21316: 		"Failed to locate the main schema resource at '%s'",
21317: 		ctxt->URL, NULL);
21318: 	else
21319: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21320: 		NULL, NULL,
21321: 		"Failed to locate the main schema resource",
21322: 		    NULL, NULL);
21323: 	goto exit;
21324:     }
21325:     /* Then do the parsing for good. */
21326:     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21327: 	goto exit_failure;
21328:     if (ctxt->nberrors != 0)
21329: 	goto exit;
21330: 
21331:     mainSchema->doc = bucket->doc;
21332:     mainSchema->preserve = ctxt->preserve;
21333: 
21334:     ctxt->schema = mainSchema;
21335: 
21336:     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21337: 	goto exit_failure;
21338: 
21339:     /*
21340:     * TODO: This is not nice, since we cannot distinguish from the
21341:     * result if there was an internal error or not.
21342:     */
21343: exit:
21344:     if (ctxt->nberrors != 0) {
21345: 	if (mainSchema) {
21346: 	    xmlSchemaFree(mainSchema);
21347: 	    mainSchema = NULL;
21348: 	}
21349: 	if (ctxt->constructor) {
21350: 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
21351: 	    ctxt->constructor = NULL;
21352: 	    ctxt->ownsConstructor = 0;
21353: 	}
21354:     }
21355:     ctxt->schema = NULL;
21356:     return(mainSchema);
21357: exit_failure:
21358:     /*
21359:     * Quite verbose, but should catch internal errors, which were
21360:     * not communitated.
21361:     */
21362:     if (mainSchema) {
21363:         xmlSchemaFree(mainSchema);
21364: 	mainSchema = NULL;
21365:     }
21366:     if (ctxt->constructor) {
21367: 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
21368: 	ctxt->constructor = NULL;
21369: 	ctxt->ownsConstructor = 0;
21370:     }
21371:     PERROR_INT2("xmlSchemaParse",
21372: 	"An internal error occured");
21373:     ctxt->schema = NULL;
21374:     return(NULL);
21375: }
21376: 
21377: /**
21378:  * xmlSchemaSetParserErrors:
21379:  * @ctxt:  a schema validation context
21380:  * @err:  the error callback
21381:  * @warn:  the warning callback
21382:  * @ctx:  contextual data for the callbacks
21383:  *
21384:  * Set the callback functions used to handle errors for a validation context
21385:  */
21386: void
21387: xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21388:                          xmlSchemaValidityErrorFunc err,
21389:                          xmlSchemaValidityWarningFunc warn, void *ctx)
21390: {
21391:     if (ctxt == NULL)
21392:         return;
21393:     ctxt->error = err;
21394:     ctxt->warning = warn;
21395:     ctxt->errCtxt = ctx;
21396:     if (ctxt->vctxt != NULL)
21397: 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21398: }
21399: 
21400: /**
21401:  * xmlSchemaSetParserStructuredErrors:
21402:  * @ctxt:  a schema parser context
21403:  * @serror:  the structured error function
21404:  * @ctx: the functions context
21405:  *
21406:  * Set the structured error callback
21407:  */
21408: void
21409: xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21410: 				   xmlStructuredErrorFunc serror,
21411: 				   void *ctx)
21412: {
21413:     if (ctxt == NULL)
21414: 	return;
21415:     ctxt->serror = serror;
21416:     ctxt->errCtxt = ctx;
21417:     if (ctxt->vctxt != NULL)
21418: 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21419: }
21420: 
21421: /**
21422:  * xmlSchemaGetParserErrors:
21423:  * @ctxt:  a XMl-Schema parser context
21424:  * @err: the error callback result
21425:  * @warn: the warning callback result
21426:  * @ctx: contextual data for the callbacks result
21427:  *
21428:  * Get the callback information used to handle errors for a parser context
21429:  *
21430:  * Returns -1 in case of failure, 0 otherwise
21431:  */
21432: int
21433: xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21434: 			 xmlSchemaValidityErrorFunc * err,
21435: 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
21436: {
21437: 	if (ctxt == NULL)
21438: 		return(-1);
21439: 	if (err != NULL)
21440: 		*err = ctxt->error;
21441: 	if (warn != NULL)
21442: 		*warn = ctxt->warning;
21443: 	if (ctx != NULL)
21444: 		*ctx = ctxt->errCtxt;
21445: 	return(0);
21446: }
21447: 
21448: /**
21449:  * xmlSchemaFacetTypeToString:
21450:  * @type:  the facet type
21451:  *
21452:  * Convert the xmlSchemaTypeType to a char string.
21453:  *
21454:  * Returns the char string representation of the facet type if the
21455:  *     type is a facet and an "Internal Error" string otherwise.
21456:  */
21457: static const xmlChar *
21458: xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21459: {
21460:     switch (type) {
21461:         case XML_SCHEMA_FACET_PATTERN:
21462:             return (BAD_CAST "pattern");
21463:         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21464:             return (BAD_CAST "maxExclusive");
21465:         case XML_SCHEMA_FACET_MAXINCLUSIVE:
21466:             return (BAD_CAST "maxInclusive");
21467:         case XML_SCHEMA_FACET_MINEXCLUSIVE:
21468:             return (BAD_CAST "minExclusive");
21469:         case XML_SCHEMA_FACET_MININCLUSIVE:
21470:             return (BAD_CAST "minInclusive");
21471:         case XML_SCHEMA_FACET_WHITESPACE:
21472:             return (BAD_CAST "whiteSpace");
21473:         case XML_SCHEMA_FACET_ENUMERATION:
21474:             return (BAD_CAST "enumeration");
21475:         case XML_SCHEMA_FACET_LENGTH:
21476:             return (BAD_CAST "length");
21477:         case XML_SCHEMA_FACET_MAXLENGTH:
21478:             return (BAD_CAST "maxLength");
21479:         case XML_SCHEMA_FACET_MINLENGTH:
21480:             return (BAD_CAST "minLength");
21481:         case XML_SCHEMA_FACET_TOTALDIGITS:
21482:             return (BAD_CAST "totalDigits");
21483:         case XML_SCHEMA_FACET_FRACTIONDIGITS:
21484:             return (BAD_CAST "fractionDigits");
21485:         default:
21486:             break;
21487:     }
21488:     return (BAD_CAST "Internal Error");
21489: }
21490: 
21491: static xmlSchemaWhitespaceValueType
21492: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21493: {
21494:     /*
21495:     * The normalization type can be changed only for types which are derived
21496:     * from xsd:string.
21497:     */
21498:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
21499: 	/*
21500: 	* Note that we assume a whitespace of preserve for anySimpleType.
21501: 	*/
21502: 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
21503: 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21504: 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
21505: 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21506: 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
21507: 	else {
21508: 	    /*
21509: 	    * For all �atomic� datatypes other than string (and types �derived�
21510: 	    * by �restriction� from it) the value of whiteSpace is fixed to
21511: 	    * collapse
21512: 	    * Note that this includes built-in list datatypes.
21513: 	    */
21514: 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21515: 	}
21516:     } else if (WXS_IS_LIST(type)) {
21517: 	/*
21518: 	* For list types the facet "whiteSpace" is fixed to "collapse".
21519: 	*/
21520: 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21521:     } else if (WXS_IS_UNION(type)) {
21522: 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21523:     } else if (WXS_IS_ATOMIC(type)) {
21524: 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21525: 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
21526: 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21527: 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
21528: 	else
21529: 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21530:     }
21531:     return (-1);
21532: }
21533: 
21534: /************************************************************************
21535:  * 									*
21536:  * 			Simple type validation				*
21537:  * 									*
21538:  ************************************************************************/
21539: 
21540: 
21541: /************************************************************************
21542:  * 									*
21543:  * 			DOM Validation code				*
21544:  * 									*
21545:  ************************************************************************/
21546: 
21547: /**
21548:  * xmlSchemaAssembleByLocation:
21549:  * @pctxt:  a schema parser context
21550:  * @vctxt:  a schema validation context
21551:  * @schema: the existing schema
21552:  * @node: the node that fired the assembling
21553:  * @nsName: the namespace name of the new schema
21554:  * @location: the location of the schema
21555:  *
21556:  * Expands an existing schema by an additional schema.
21557:  *
21558:  * Returns 0 if the new schema is correct, a positive error code
21559:  * number otherwise and -1 in case of an internal or API error.
21560:  */
21561: static int
21562: xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21563: 			    xmlSchemaPtr schema,
21564: 			    xmlNodePtr node,
21565: 			    const xmlChar *nsName,
21566: 			    const xmlChar *location)
21567: {
21568:     int ret = 0;
21569:     xmlSchemaParserCtxtPtr pctxt;
21570:     xmlSchemaBucketPtr bucket = NULL;
21571: 
21572:     if ((vctxt == NULL) || (schema == NULL))
21573: 	return (-1);
21574: 
21575:     if (vctxt->pctxt == NULL) {
21576: 	VERROR_INT("xmlSchemaAssembleByLocation",
21577: 	    "no parser context available");
21578: 	return(-1);
21579:     }
21580:     pctxt = vctxt->pctxt;
21581:     if (pctxt->constructor == NULL) {
21582: 	PERROR_INT("xmlSchemaAssembleByLocation",
21583: 	    "no constructor");
21584: 	return(-1);
21585:     }
21586:     /*
21587:     * Acquire the schema document.
21588:     */
21589:     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21590: 	location, node);
21591:     /*
21592:     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21593:     * the process will automatically change this to
21594:     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21595:     */
21596:     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21597: 	location, NULL, NULL, 0, node, NULL, nsName,
21598: 	&bucket);
21599:     if (ret != 0)
21600: 	return(ret);
21601:     if (bucket == NULL) {
21602: 	/*
21603: 	* Generate a warning that the document could not be located.
21604: 	*/
21605: 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21606: 	    node, NULL,
21607: 	    "The document at location '%s' could not be acquired",
21608: 	    location, NULL, NULL);
21609: 	return(ret);
21610:     }
21611:     /*
21612:     * The first located schema will be handled as if all other
21613:     * schemas imported by XSI were imported by this first schema.
21614:     */
21615:     if ((bucket != NULL) &&
21616: 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21617: 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21618:     /*
21619:     * TODO: Is this handled like an import? I.e. is it not an error
21620:     * if the schema cannot be located?
21621:     */
21622:     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21623: 	return(0);
21624:     /*
21625:     * We will reuse the parser context for every schema imported
21626:     * directly via XSI. So reset the context.
21627:     */
21628:     pctxt->nberrors = 0;
21629:     pctxt->err = 0;
21630:     pctxt->doc = bucket->doc;
21631: 
21632:     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21633:     if (ret == -1) {
21634: 	pctxt->doc = NULL;
21635: 	goto exit_failure;
21636:     }
21637:     /* Paranoid error channelling. */
21638:     if ((ret == 0) && (pctxt->nberrors != 0))
21639: 	ret = pctxt->err;
21640:     if (pctxt->nberrors == 0) {
21641: 	/*
21642: 	* Only bother to fixup pending components, if there was
21643: 	* no error yet.
21644: 	* For every XSI acquired schema (and its sub-schemata) we will
21645: 	* fixup the components.
21646: 	*/
21647: 	xmlSchemaFixupComponents(pctxt, bucket);
21648: 	ret = pctxt->err;
21649: 	/*
21650: 	* Not nice, but we need somehow to channel the schema parser
21651: 	* error to the validation context.
21652: 	*/
21653: 	if ((ret != 0) && (vctxt->err == 0))
21654: 	    vctxt->err = ret;
21655: 	vctxt->nberrors += pctxt->nberrors;
21656:     } else {
21657: 	/* Add to validation error sum. */
21658: 	vctxt->nberrors += pctxt->nberrors;
21659:     }
21660:     pctxt->doc = NULL;
21661:     return(ret);
21662: exit_failure:
21663:     pctxt->doc = NULL;
21664:     return (-1);
21665: }
21666: 
21667: static xmlSchemaAttrInfoPtr
21668: xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21669: 			 int metaType)
21670: {
21671:     if (vctxt->nbAttrInfos == 0)
21672: 	return (NULL);
21673:     {
21674: 	int i;
21675: 	xmlSchemaAttrInfoPtr iattr;
21676: 
21677: 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
21678: 	    iattr = vctxt->attrInfos[i];
21679: 	    if (iattr->metaType == metaType)
21680: 		return (iattr);
21681: 	}
21682: 
21683:     }
21684:     return (NULL);
21685: }
21686: 
21687: /**
21688:  * xmlSchemaAssembleByXSI:
21689:  * @vctxt:  a schema validation context
21690:  *
21691:  * Expands an existing schema by an additional schema using
21692:  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21693:  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21694:  * must be set to 1.
21695:  *
21696:  * Returns 0 if the new schema is correct, a positive error code
21697:  * number otherwise and -1 in case of an internal or API error.
21698:  */
21699: static int
21700: xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21701: {
21702:     const xmlChar *cur, *end;
21703:     const xmlChar *nsname = NULL, *location;
21704:     int count = 0;
21705:     int ret = 0;
21706:     xmlSchemaAttrInfoPtr iattr;
21707: 
21708:     /*
21709:     * Parse the value; we will assume an even number of values
21710:     * to be given (this is how Xerces and XSV work).
21711:     *
21712:     * URGENT TODO: !! This needs to work for both
21713:     * @noNamespaceSchemaLocation AND @schemaLocation on the same
21714:     * element !!
21715:     */
21716:     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21717: 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21718:     if (iattr == NULL)
21719: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21720: 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21721:     if (iattr == NULL)
21722: 	return (0);
21723:     cur = iattr->value;
21724:     do {
21725: 	/*
21726: 	* TODO: Move the string parsing mechanism away from here.
21727: 	*/
21728: 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21729: 	    /*
21730: 	    * Get the namespace name.
21731: 	    */
21732: 	    while (IS_BLANK_CH(*cur))
21733: 		cur++;
21734: 	    end = cur;
21735: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21736: 		end++;
21737: 	    if (end == cur)
21738: 		break;
21739: 	    count++; /* TODO: Don't use the schema's dict. */
21740: 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21741: 	    cur = end;
21742: 	}
21743: 	/*
21744: 	* Get the URI.
21745: 	*/
21746: 	while (IS_BLANK_CH(*cur))
21747: 	    cur++;
21748: 	end = cur;
21749: 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21750: 	    end++;
21751: 	if (end == cur) {
21752: 	    if (iattr->metaType ==
21753: 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21754: 	    {
21755: 		/*
21756: 		* If using @schemaLocation then tuples are expected.
21757: 		* I.e. the namespace name *and* the document's URI.
21758: 		*/
21759: 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21760: 		    iattr->node, NULL,
21761: 		    "The value must consist of tuples: the target namespace "
21762: 		    "name and the document's URI", NULL, NULL, NULL);
21763: 	    }
21764: 	    break;
21765: 	}
21766: 	count++; /* TODO: Don't use the schema's dict. */
21767: 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21768: 	cur = end;
21769: 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21770: 	    iattr->node, nsname, location);
21771: 	if (ret == -1) {
21772: 	    VERROR_INT("xmlSchemaAssembleByXSI",
21773: 		"assembling schemata");
21774: 	    return (-1);
21775: 	}
21776:     } while (*cur != 0);
21777:     return (ret);
21778: }
21779: 
21780: static const xmlChar *
21781: xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21782: 			 const xmlChar *prefix)
21783: {
21784:     if (vctxt->sax != NULL) {
21785: 	int i, j;
21786: 	xmlSchemaNodeInfoPtr inode;
21787: 
21788: 	for (i = vctxt->depth; i >= 0; i--) {
21789: 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21790: 		inode = vctxt->elemInfos[i];
21791: 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21792: 		    if (((prefix == NULL) &&
21793: 			    (inode->nsBindings[j] == NULL)) ||
21794: 			((prefix != NULL) && xmlStrEqual(prefix,
21795: 			    inode->nsBindings[j]))) {
21796: 
21797: 			/*
21798: 			* Note that the namespace bindings are already
21799: 			* in a string dict.
21800: 			*/
21801: 			return (inode->nsBindings[j+1]);
21802: 		    }
21803: 		}
21804: 	    }
21805: 	}
21806: 	return (NULL);
21807: #ifdef LIBXML_READER_ENABLED
21808:     } else if (vctxt->reader != NULL) {
21809: 	xmlChar *nsName;
21810: 
21811: 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21812: 	if (nsName != NULL) {
21813: 	    const xmlChar *ret;
21814: 
21815: 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
21816: 	    xmlFree(nsName);
21817: 	    return (ret);
21818: 	} else
21819: 	    return (NULL);
21820: #endif
21821:     } else {
21822: 	xmlNsPtr ns;
21823: 
21824: 	if ((vctxt->inode->node == NULL) ||
21825: 	    (vctxt->inode->node->doc == NULL)) {
21826: 	    VERROR_INT("xmlSchemaLookupNamespace",
21827: 		"no node or node's doc avaliable");
21828: 	    return (NULL);
21829: 	}
21830: 	ns = xmlSearchNs(vctxt->inode->node->doc,
21831: 	    vctxt->inode->node, prefix);
21832: 	if (ns != NULL)
21833: 	    return (ns->href);
21834: 	return (NULL);
21835:     }
21836: }
21837: 
21838: /*
21839: * This one works on the schema of the validation context.
21840: */
21841: static int
21842: xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21843: 			  xmlSchemaPtr schema,
21844: 			  xmlNodePtr node,
21845: 			  const xmlChar *value,
21846: 			  xmlSchemaValPtr *val,
21847: 			  int valNeeded)
21848: {
21849:     int ret;
21850: 
21851:     if (vctxt && (vctxt->schema == NULL)) {
21852: 	VERROR_INT("xmlSchemaValidateNotation",
21853: 	    "a schema is needed on the validation context");
21854: 	return (-1);
21855:     }
21856:     ret = xmlValidateQName(value, 1);
21857:     if (ret != 0)
21858: 	return (ret);
21859:     {
21860: 	xmlChar *localName = NULL;
21861: 	xmlChar *prefix = NULL;
21862: 
21863: 	localName = xmlSplitQName2(value, &prefix);
21864: 	if (prefix != NULL) {
21865: 	    const xmlChar *nsName = NULL;
21866: 
21867: 	    if (vctxt != NULL)
21868: 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21869: 	    else if (node != NULL) {
21870: 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21871: 		if (ns != NULL)
21872: 		    nsName = ns->href;
21873: 	    } else {
21874: 		xmlFree(prefix);
21875: 		xmlFree(localName);
21876: 		return (1);
21877: 	    }
21878: 	    if (nsName == NULL) {
21879: 		xmlFree(prefix);
21880: 		xmlFree(localName);
21881: 		return (1);
21882: 	    }
21883: 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21884: 		if ((valNeeded) && (val != NULL)) {
21885: 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21886: 						       xmlStrdup(nsName));
21887: 		    if (*val == NULL)
21888: 			ret = -1;
21889: 		}
21890: 	    } else
21891: 		ret = 1;
21892: 	    xmlFree(prefix);
21893: 	    xmlFree(localName);
21894: 	} else {
21895: 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21896: 		if (valNeeded && (val != NULL)) {
21897: 		    (*val) = xmlSchemaNewNOTATIONValue(
21898: 			BAD_CAST xmlStrdup(value), NULL);
21899: 		    if (*val == NULL)
21900: 			ret = -1;
21901: 		}
21902: 	    } else
21903: 		return (1);
21904: 	}
21905:     }
21906:     return (ret);
21907: }
21908: 
21909: static int
21910: xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21911: 		       const xmlChar* lname,
21912: 		       const xmlChar* nsname)
21913: {
21914:     int i;
21915: 
21916:     lname = xmlDictLookup(vctxt->dict, lname, -1);
21917:     if (lname == NULL)
21918: 	return(-1);
21919:     if (nsname != NULL) {
21920: 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21921: 	if (nsname == NULL)
21922: 	    return(-1);
21923:     }
21924:     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21925: 	if ((vctxt->nodeQNames->items [i] == lname) &&
21926: 	    (vctxt->nodeQNames->items[i +1] == nsname))
21927: 	    /* Already there */
21928: 	    return(i);
21929:     }
21930:     /* Add new entry. */
21931:     i = vctxt->nodeQNames->nbItems;
21932:     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21933:     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21934:     return(i);
21935: }
21936: 
21937: /************************************************************************
21938:  * 									*
21939:  *  Validation of identity-constraints (IDC)                            *
21940:  * 									*
21941:  ************************************************************************/
21942: 
21943: /**
21944:  * xmlSchemaAugmentIDC:
21945:  * @idcDef: the IDC definition
21946:  *
21947:  * Creates an augmented IDC definition item.
21948:  *
21949:  * Returns the item, or NULL on internal errors.
21950:  */
21951: static void
21952: xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
21953: 		    xmlSchemaValidCtxtPtr vctxt)
21954: {
21955:     xmlSchemaIDCAugPtr aidc;
21956: 
21957:     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21958:     if (aidc == NULL) {
21959: 	xmlSchemaVErrMemory(vctxt,
21960: 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
21961: 	    NULL);
21962: 	return;
21963:     }
21964:     aidc->keyrefDepth = -1;
21965:     aidc->def = idcDef;
21966:     aidc->next = NULL;
21967:     if (vctxt->aidcs == NULL)
21968: 	vctxt->aidcs = aidc;
21969:     else {
21970: 	aidc->next = vctxt->aidcs;
21971: 	vctxt->aidcs = aidc;
21972:     }
21973:     /*
21974:     * Save if we have keyrefs at all.
21975:     */
21976:     if ((vctxt->hasKeyrefs == 0) &&
21977: 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21978: 	vctxt->hasKeyrefs = 1;
21979: }
21980: 
21981: /**
21982:  * xmlSchemaAugmentImportedIDC:
21983:  * @imported: the imported schema
21984:  *
21985:  * Creates an augmented IDC definition for the imported schema.
21986:  */
21987: static void
21988: xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
21989:     if (imported->schema->idcDef != NULL) {
21990: 	    xmlHashScan(imported->schema->idcDef ,
21991: 	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
21992:     }
21993: }
21994: 
21995: /**
21996:  * xmlSchemaIDCNewBinding:
21997:  * @idcDef: the IDC definition of this binding
21998:  *
21999:  * Creates a new IDC binding.
22000:  *
22001:  * Returns the new IDC binding, NULL on internal errors.
22002:  */
22003: static xmlSchemaPSVIIDCBindingPtr
22004: xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22005: {
22006:     xmlSchemaPSVIIDCBindingPtr ret;
22007: 
22008:     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22009: 	    sizeof(xmlSchemaPSVIIDCBinding));
22010:     if (ret == NULL) {
22011: 	xmlSchemaVErrMemory(NULL,
22012: 	    "allocating a PSVI IDC binding item", NULL);
22013: 	return (NULL);
22014:     }
22015:     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22016:     ret->definition = idcDef;
22017:     return (ret);
22018: }
22019: 
22020: /**
22021:  * xmlSchemaIDCStoreNodeTableItem:
22022:  * @vctxt: the WXS validation context
22023:  * @item: the IDC node table item
22024:  *
22025:  * The validation context is used to store IDC node table items.
22026:  * They are stored to avoid copying them if IDC node-tables are merged
22027:  * with corresponding parent IDC node-tables (bubbling).
22028:  *
22029:  * Returns 0 if succeeded, -1 on internal errors.
22030:  */
22031: static int
22032: xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22033: 			       xmlSchemaPSVIIDCNodePtr item)
22034: {
22035:     /*
22036:     * Add to gobal list.
22037:     */
22038:     if (vctxt->idcNodes == NULL) {
22039: 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22040: 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22041: 	if (vctxt->idcNodes == NULL) {
22042: 	    xmlSchemaVErrMemory(vctxt,
22043: 		"allocating the IDC node table item list", NULL);
22044: 	    return (-1);
22045: 	}
22046: 	vctxt->sizeIdcNodes = 20;
22047:     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22048: 	vctxt->sizeIdcNodes *= 2;
22049: 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22050: 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22051: 	    sizeof(xmlSchemaPSVIIDCNodePtr));
22052: 	if (vctxt->idcNodes == NULL) {
22053: 	    xmlSchemaVErrMemory(vctxt,
22054: 		"re-allocating the IDC node table item list", NULL);
22055: 	    return (-1);
22056: 	}
22057:     }
22058:     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22059: 
22060:     return (0);
22061: }
22062: 
22063: /**
22064:  * xmlSchemaIDCStoreKey:
22065:  * @vctxt: the WXS validation context
22066:  * @item: the IDC key
22067:  *
22068:  * The validation context is used to store an IDC key.
22069:  *
22070:  * Returns 0 if succeeded, -1 on internal errors.
22071:  */
22072: static int
22073: xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22074: 		     xmlSchemaPSVIIDCKeyPtr key)
22075: {
22076:     /*
22077:     * Add to gobal list.
22078:     */
22079:     if (vctxt->idcKeys == NULL) {
22080: 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22081: 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22082: 	if (vctxt->idcKeys == NULL) {
22083: 	    xmlSchemaVErrMemory(vctxt,
22084: 		"allocating the IDC key storage list", NULL);
22085: 	    return (-1);
22086: 	}
22087: 	vctxt->sizeIdcKeys = 40;
22088:     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22089: 	vctxt->sizeIdcKeys *= 2;
22090: 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22091: 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22092: 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
22093: 	if (vctxt->idcKeys == NULL) {
22094: 	    xmlSchemaVErrMemory(vctxt,
22095: 		"re-allocating the IDC key storage list", NULL);
22096: 	    return (-1);
22097: 	}
22098:     }
22099:     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22100: 
22101:     return (0);
22102: }
22103: 
22104: /**
22105:  * xmlSchemaIDCAppendNodeTableItem:
22106:  * @bind: the IDC binding
22107:  * @ntItem: the node-table item
22108:  *
22109:  * Appends the IDC node-table item to the binding.
22110:  *
22111:  * Returns 0 on success and -1 on internal errors.
22112:  */
22113: static int
22114: xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22115: 				xmlSchemaPSVIIDCNodePtr ntItem)
22116: {
22117:     if (bind->nodeTable == NULL) {
22118: 	bind->sizeNodes = 10;
22119: 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22120: 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22121: 	if (bind->nodeTable == NULL) {
22122: 	    xmlSchemaVErrMemory(NULL,
22123: 		"allocating an array of IDC node-table items", NULL);
22124: 	    return(-1);
22125: 	}
22126:     } else if (bind->sizeNodes <= bind->nbNodes) {
22127: 	bind->sizeNodes *= 2;
22128: 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22129: 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
22130: 		sizeof(xmlSchemaPSVIIDCNodePtr));
22131: 	if (bind->nodeTable == NULL) {
22132: 	    xmlSchemaVErrMemory(NULL,
22133: 		"re-allocating an array of IDC node-table items", NULL);
22134: 	    return(-1);
22135: 	}
22136:     }
22137:     bind->nodeTable[bind->nbNodes++] = ntItem;
22138:     return(0);
22139: }
22140: 
22141: /**
22142:  * xmlSchemaIDCAcquireBinding:
22143:  * @vctxt: the WXS validation context
22144:  * @matcher: the IDC matcher
22145:  *
22146:  * Looks up an PSVI IDC binding, for the IDC definition and
22147:  * of the given matcher. If none found, a new one is created
22148:  * and added to the IDC table.
22149:  *
22150:  * Returns an IDC binding or NULL on internal errors.
22151:  */
22152: static xmlSchemaPSVIIDCBindingPtr
22153: xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22154: 			  xmlSchemaIDCMatcherPtr matcher)
22155: {
22156:     xmlSchemaNodeInfoPtr ielem;
22157: 
22158:     ielem = vctxt->elemInfos[matcher->depth];
22159: 
22160:     if (ielem->idcTable == NULL) {
22161: 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22162: 	if (ielem->idcTable == NULL)
22163: 	    return (NULL);
22164: 	return(ielem->idcTable);
22165:     } else {
22166: 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
22167: 
22168: 	bind = ielem->idcTable;
22169: 	do {
22170: 	    if (bind->definition == matcher->aidc->def)
22171: 		return(bind);
22172: 	    if (bind->next == NULL) {
22173: 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22174: 		if (bind->next == NULL)
22175: 		    return (NULL);
22176: 		return(bind->next);
22177: 	    }
22178: 	    bind = bind->next;
22179: 	} while (bind != NULL);
22180:     }
22181:     return (NULL);
22182: }
22183: 
22184: static xmlSchemaItemListPtr
22185: xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22186: 			     xmlSchemaIDCMatcherPtr matcher)
22187: {
22188:     if (matcher->targets == NULL)
22189: 	matcher->targets = xmlSchemaItemListCreate();
22190:     return(matcher->targets);
22191: }
22192: 
22193: /**
22194:  * xmlSchemaIDCFreeKey:
22195:  * @key: the IDC key
22196:  *
22197:  * Frees an IDC key together with its compiled value.
22198:  */
22199: static void
22200: xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22201: {
22202:     if (key->val != NULL)
22203: 	xmlSchemaFreeValue(key->val);
22204:     xmlFree(key);
22205: }
22206: 
22207: /**
22208:  * xmlSchemaIDCFreeBinding:
22209:  *
22210:  * Frees an IDC binding. Note that the node table-items
22211:  * are not freed.
22212:  */
22213: static void
22214: xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22215: {
22216:     if (bind->nodeTable != NULL)
22217: 	xmlFree(bind->nodeTable);
22218:     if (bind->dupls != NULL)
22219: 	xmlSchemaItemListFree(bind->dupls);
22220:     xmlFree(bind);
22221: }
22222: 
22223: /**
22224:  * xmlSchemaIDCFreeIDCTable:
22225:  * @bind: the first IDC binding in the list
22226:  *
22227:  * Frees an IDC table, i.e. all the IDC bindings in the list.
22228:  */
22229: static void
22230: xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22231: {
22232:     xmlSchemaPSVIIDCBindingPtr prev;
22233: 
22234:     while (bind != NULL) {
22235: 	prev = bind;
22236: 	bind = bind->next;
22237: 	xmlSchemaIDCFreeBinding(prev);
22238:     }
22239: }
22240: 
22241: /**
22242:  * xmlSchemaIDCFreeMatcherList:
22243:  * @matcher: the first IDC matcher in the list
22244:  *
22245:  * Frees a list of IDC matchers.
22246:  */
22247: static void
22248: xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22249: {
22250:     xmlSchemaIDCMatcherPtr next;
22251: 
22252:     while (matcher != NULL) {
22253: 	next = matcher->next;
22254: 	if (matcher->keySeqs != NULL) {
22255: 	    int i;
22256: 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
22257: 		if (matcher->keySeqs[i] != NULL)
22258: 		    xmlFree(matcher->keySeqs[i]);
22259: 	    xmlFree(matcher->keySeqs);
22260: 	}
22261: 	if (matcher->targets != NULL) {
22262: 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22263: 		int i;
22264: 		xmlSchemaPSVIIDCNodePtr idcNode;
22265: 		/*
22266: 		* Node-table items for keyrefs are not stored globally
22267: 		* to the validation context, since they are not bubbled.
22268: 		* We need to free them here.
22269: 		*/
22270: 		for (i = 0; i < matcher->targets->nbItems; i++) {
22271: 		    idcNode =
22272: 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22273: 		    xmlFree(idcNode->keys);
22274: 		    xmlFree(idcNode);
22275: 		}
22276: 	    }
22277: 	    xmlSchemaItemListFree(matcher->targets);
22278: 	}
22279: 	xmlFree(matcher);
22280: 	matcher = next;
22281:     }
22282: }
22283: 
22284: /**
22285:  * xmlSchemaIDCReleaseMatcherList:
22286:  * @vctxt: the WXS validation context
22287:  * @matcher: the first IDC matcher in the list
22288:  *
22289:  * Caches a list of IDC matchers for reuse.
22290:  */
22291: static void
22292: xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22293: 			       xmlSchemaIDCMatcherPtr matcher)
22294: {
22295:     xmlSchemaIDCMatcherPtr next;
22296: 
22297:     while (matcher != NULL) {
22298: 	next = matcher->next;
22299: 	if (matcher->keySeqs != NULL) {
22300: 	    int i;
22301: 	    /*
22302: 	    * Don't free the array, but only the content.
22303: 	    */
22304: 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
22305: 		if (matcher->keySeqs[i] != NULL) {
22306: 		    xmlFree(matcher->keySeqs[i]);
22307: 		    matcher->keySeqs[i] = NULL;
22308: 		}
22309: 	}
22310: 	if (matcher->targets) {
22311: 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22312: 		int i;
22313: 		xmlSchemaPSVIIDCNodePtr idcNode;
22314: 		/*
22315: 		* Node-table items for keyrefs are not stored globally
22316: 		* to the validation context, since they are not bubbled.
22317: 		* We need to free them here.
22318: 		*/
22319: 		for (i = 0; i < matcher->targets->nbItems; i++) {
22320: 		    idcNode =
22321: 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22322: 		    xmlFree(idcNode->keys);
22323: 		    xmlFree(idcNode);
22324: 		}
22325: 	    }
22326: 	    xmlSchemaItemListFree(matcher->targets);
22327: 	    matcher->targets = NULL;
22328: 	}
22329: 	matcher->next = NULL;
22330: 	/*
22331: 	* Cache the matcher.
22332: 	*/
22333: 	if (vctxt->idcMatcherCache != NULL)
22334: 	    matcher->nextCached = vctxt->idcMatcherCache;
22335: 	vctxt->idcMatcherCache = matcher;
22336: 
22337: 	matcher = next;
22338:     }
22339: }
22340: 
22341: /**
22342:  * xmlSchemaIDCAddStateObject:
22343:  * @vctxt: the WXS validation context
22344:  * @matcher: the IDC matcher
22345:  * @sel: the XPath information
22346:  * @parent: the parent "selector" state object if any
22347:  * @type: "selector" or "field"
22348:  *
22349:  * Creates/reuses and activates state objects for the given
22350:  * XPath information; if the XPath expression consists of unions,
22351:  * multiple state objects are created for every unioned expression.
22352:  *
22353:  * Returns 0 on success and -1 on internal errors.
22354:  */
22355: static int
22356: xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22357: 			xmlSchemaIDCMatcherPtr matcher,
22358: 			xmlSchemaIDCSelectPtr sel,
22359: 			int type)
22360: {
22361:     xmlSchemaIDCStateObjPtr sto;
22362: 
22363:     /*
22364:     * Reuse the state objects from the pool.
22365:     */
22366:     if (vctxt->xpathStatePool != NULL) {
22367: 	sto = vctxt->xpathStatePool;
22368: 	vctxt->xpathStatePool = sto->next;
22369: 	sto->next = NULL;
22370:     } else {
22371: 	/*
22372: 	* Create a new state object.
22373: 	*/
22374: 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22375: 	if (sto == NULL) {
22376: 	    xmlSchemaVErrMemory(NULL,
22377: 		"allocating an IDC state object", NULL);
22378: 	    return (-1);
22379: 	}
22380: 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22381:     }
22382:     /*
22383:     * Add to global list.
22384:     */
22385:     if (vctxt->xpathStates != NULL)
22386: 	sto->next = vctxt->xpathStates;
22387:     vctxt->xpathStates = sto;
22388: 
22389:     /*
22390:     * Free the old xpath validation context.
22391:     */
22392:     if (sto->xpathCtxt != NULL)
22393: 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22394: 
22395:     /*
22396:     * Create a new XPath (pattern) validation context.
22397:     */
22398:     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22399: 	(xmlPatternPtr) sel->xpathComp);
22400:     if (sto->xpathCtxt == NULL) {
22401: 	VERROR_INT("xmlSchemaIDCAddStateObject",
22402: 	    "failed to create an XPath validation context");
22403: 	return (-1);
22404:     }
22405:     sto->type = type;
22406:     sto->depth = vctxt->depth;
22407:     sto->matcher = matcher;
22408:     sto->sel = sel;
22409:     sto->nbHistory = 0;
22410: 
22411: #ifdef DEBUG_IDC
22412:     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
22413: 	sto->sel->xpath);
22414: #endif
22415:     return (0);
22416: }
22417: 
22418: /**
22419:  * xmlSchemaXPathEvaluate:
22420:  * @vctxt: the WXS validation context
22421:  * @nodeType: the nodeType of the current node
22422:  *
22423:  * Evaluates all active XPath state objects.
22424:  *
22425:  * Returns the number of IC "field" state objects which resolved to
22426:  * this node, 0 if none resolved and -1 on internal errors.
22427:  */
22428: static int
22429: xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22430: 		       xmlElementType nodeType)
22431: {
22432:     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22433:     int res, resolved = 0, depth = vctxt->depth;
22434: 
22435:     if (vctxt->xpathStates == NULL)
22436: 	return (0);
22437: 
22438:     if (nodeType == XML_ATTRIBUTE_NODE)
22439: 	depth++;
22440: #ifdef DEBUG_IDC
22441:     {
22442: 	xmlChar *str = NULL;
22443: 	xmlGenericError(xmlGenericErrorContext,
22444: 	    "IDC: EVAL on %s, depth %d, type %d\n",
22445: 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22446: 		vctxt->inode->localName), depth, nodeType);
22447: 	FREE_AND_NULL(str)
22448:     }
22449: #endif
22450:     /*
22451:     * Process all active XPath state objects.
22452:     */
22453:     first = vctxt->xpathStates;
22454:     sto = first;
22455:     while (sto != head) {
22456: #ifdef DEBUG_IDC
22457: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22458: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
22459: 		sto->matcher->aidc->def->name, sto->sel->xpath);
22460: 	else
22461: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
22462: 		sto->matcher->aidc->def->name, sto->sel->xpath);
22463: #endif
22464: 	if (nodeType == XML_ELEMENT_NODE)
22465: 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22466: 		vctxt->inode->localName, vctxt->inode->nsName);
22467: 	else
22468: 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22469: 		vctxt->inode->localName, vctxt->inode->nsName);
22470: 
22471: 	if (res == -1) {
22472: 	    VERROR_INT("xmlSchemaXPathEvaluate",
22473: 		"calling xmlStreamPush()");
22474: 	    return (-1);
22475: 	}
22476: 	if (res == 0)
22477: 	    goto next_sto;
22478: 	/*
22479: 	* Full match.
22480: 	*/
22481: #ifdef DEBUG_IDC
22482: 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
22483: 	    "MATCH\n");
22484: #endif
22485: 	/*
22486: 	* Register a match in the state object history.
22487: 	*/
22488: 	if (sto->history == NULL) {
22489: 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
22490: 	    if (sto->history == NULL) {
22491: 		xmlSchemaVErrMemory(NULL,
22492: 		    "allocating the state object history", NULL);
22493: 		return(-1);
22494: 	    }
22495: 	    sto->sizeHistory = 5;
22496: 	} else if (sto->sizeHistory <= sto->nbHistory) {
22497: 	    sto->sizeHistory *= 2;
22498: 	    sto->history = (int *) xmlRealloc(sto->history,
22499: 		sto->sizeHistory * sizeof(int));
22500: 	    if (sto->history == NULL) {
22501: 		xmlSchemaVErrMemory(NULL,
22502: 		    "re-allocating the state object history", NULL);
22503: 		return(-1);
22504: 	    }
22505: 	}
22506: 	sto->history[sto->nbHistory++] = depth;
22507: 
22508: #ifdef DEBUG_IDC
22509: 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
22510: 	    vctxt->depth);
22511: #endif
22512: 
22513: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22514: 	    xmlSchemaIDCSelectPtr sel;
22515: 	    /*
22516: 	    * Activate state objects for the IDC fields of
22517: 	    * the IDC selector.
22518: 	    */
22519: #ifdef DEBUG_IDC
22520: 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
22521: 		"activating field states\n");
22522: #endif
22523: 	    sel = sto->matcher->aidc->def->fields;
22524: 	    while (sel != NULL) {
22525: 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22526: 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22527: 		    return (-1);
22528: 		sel = sel->next;
22529: 	    }
22530: 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22531: 	    /*
22532: 	    * An IDC key node was found by the IDC field.
22533: 	    */
22534: #ifdef DEBUG_IDC
22535: 	    xmlGenericError(xmlGenericErrorContext,
22536: 		"IDC:     key found\n");
22537: #endif
22538: 	    /*
22539: 	    * Notify that the character value of this node is
22540: 	    * needed.
22541: 	    */
22542: 	    if (resolved == 0) {
22543: 		if ((vctxt->inode->flags &
22544: 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22545: 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22546: 	    }
22547: 	    resolved++;
22548: 	}
22549: next_sto:
22550: 	if (sto->next == NULL) {
22551: 	    /*
22552: 	    * Evaluate field state objects created on this node as well.
22553: 	    */
22554: 	    head = first;
22555: 	    sto = vctxt->xpathStates;
22556: 	} else
22557: 	    sto = sto->next;
22558:     }
22559:     return (resolved);
22560: }
22561: 
22562: static const xmlChar *
22563: xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22564: 			      xmlChar **buf,
22565: 			      xmlSchemaPSVIIDCKeyPtr *seq,
22566: 			      int count)
22567: {
22568:     int i, res;
22569:     xmlChar *value = NULL;
22570: 
22571:     *buf = xmlStrdup(BAD_CAST "[");
22572:     for (i = 0; i < count; i++) {
22573: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
22574: 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22575: 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22576: 	    &value);
22577: 	if (res == 0)
22578: 	    *buf = xmlStrcat(*buf, BAD_CAST value);
22579: 	else {
22580: 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
22581: 		"failed to compute a canonical value");
22582: 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
22583: 	}
22584: 	if (i < count -1)
22585: 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
22586: 	else
22587: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
22588: 	if (value != NULL) {
22589: 	    xmlFree(value);
22590: 	    value = NULL;
22591: 	}
22592:     }
22593:     *buf = xmlStrcat(*buf, BAD_CAST "]");
22594: 
22595:     return (BAD_CAST *buf);
22596: }
22597: 
22598: /**
22599:  * xmlSchemaXPathPop:
22600:  * @vctxt: the WXS validation context
22601:  *
22602:  * Pops all XPath states.
22603:  *
22604:  * Returns 0 on success and -1 on internal errors.
22605:  */
22606: static int
22607: xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22608: {
22609:     xmlSchemaIDCStateObjPtr sto;
22610:     int res;
22611: 
22612:     if (vctxt->xpathStates == NULL)
22613: 	return(0);
22614:     sto = vctxt->xpathStates;
22615:     do {
22616: 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22617: 	if (res == -1)
22618: 	    return (-1);
22619: 	sto = sto->next;
22620:     } while (sto != NULL);
22621:     return(0);
22622: }
22623: 
22624: /**
22625:  * xmlSchemaXPathProcessHistory:
22626:  * @vctxt: the WXS validation context
22627:  * @type: the simple/complex type of the current node if any at all
22628:  * @val: the precompiled value
22629:  *
22630:  * Processes and pops the history items of the IDC state objects.
22631:  * IDC key-sequences are validated/created on IDC bindings.
22632:  *
22633:  * Returns 0 on success and -1 on internal errors.
22634:  */
22635: static int
22636: xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22637: 			     int depth)
22638: {
22639:     xmlSchemaIDCStateObjPtr sto, nextsto;
22640:     int res, matchDepth;
22641:     xmlSchemaPSVIIDCKeyPtr key = NULL;
22642:     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22643: 
22644:     if (vctxt->xpathStates == NULL)
22645: 	return (0);
22646:     sto = vctxt->xpathStates;
22647: 
22648: #ifdef DEBUG_IDC
22649:     {
22650: 	xmlChar *str = NULL;
22651: 	xmlGenericError(xmlGenericErrorContext,
22652: 	    "IDC: BACK on %s, depth %d\n",
22653: 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22654: 		vctxt->inode->localName), vctxt->depth);
22655: 	FREE_AND_NULL(str)
22656:     }
22657: #endif
22658:     /*
22659:     * Evaluate the state objects.
22660:     */
22661:     while (sto != NULL) {
22662: 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22663: 	if (res == -1) {
22664: 	    VERROR_INT("xmlSchemaXPathProcessHistory",
22665: 		"calling xmlStreamPop()");
22666: 	    return (-1);
22667: 	}
22668: #ifdef DEBUG_IDC
22669: 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
22670: 	    sto->sel->xpath);
22671: #endif
22672: 	if (sto->nbHistory == 0)
22673: 	    goto deregister_check;
22674: 
22675: 	matchDepth = sto->history[sto->nbHistory -1];
22676: 
22677: 	/*
22678: 	* Only matches at the current depth are of interest.
22679: 	*/
22680: 	if (matchDepth != depth) {
22681: 	    sto = sto->next;
22682: 	    continue;
22683: 	}
22684: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22685: 	    /*
22686: 	    * NOTE: According to
22687: 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22688: 	    *   ... the simple-content of complex types is also allowed.
22689: 	    */
22690: 
22691: 	    if (WXS_IS_COMPLEX(type)) {
22692: 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
22693: 		    /*
22694: 		    * Sanity check for complex types with simple content.
22695: 		    */
22696: 		    simpleType = type->contentTypeDef;
22697: 		    if (simpleType == NULL) {
22698: 			VERROR_INT("xmlSchemaXPathProcessHistory",
22699: 			    "field resolves to a CT with simple content "
22700: 			    "but the CT is missing the ST definition");
22701: 			return (-1);
22702: 		    }
22703: 		} else
22704: 		    simpleType = NULL;
22705: 	    } else
22706: 		simpleType = type;
22707: 	    if (simpleType == NULL) {
22708: 		xmlChar *str = NULL;
22709: 
22710: 		/*
22711: 		* Not qualified if the field resolves to a node of non
22712: 		* simple type.
22713: 		*/
22714: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
22715: 		    XML_SCHEMAV_CVC_IDC, NULL,
22716: 		    WXS_BASIC_CAST sto->matcher->aidc->def,
22717: 		    "The XPath '%s' of a field of %s does evaluate to a node of "
22718: 		    "non-simple type",
22719: 		    sto->sel->xpath,
22720: 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22721: 		FREE_AND_NULL(str);
22722: 		sto->nbHistory--;
22723: 		goto deregister_check;
22724: 	    }
22725: 
22726: 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
22727: 		/*
22728: 		* Failed to provide the normalized value; maybe
22729: 		* the value was invalid.
22730: 		*/
22731: 		VERROR(XML_SCHEMAV_CVC_IDC,
22732: 		    WXS_BASIC_CAST sto->matcher->aidc->def,
22733: 		    "Warning: No precomputed value available, the value "
22734: 		    "was either invalid or something strange happend");
22735: 		sto->nbHistory--;
22736: 		goto deregister_check;
22737: 	    } else {
22738: 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22739: 		xmlSchemaPSVIIDCKeyPtr *keySeq;
22740: 		int pos, idx;
22741: 
22742: 		/*
22743: 		* The key will be anchored on the matcher's list of
22744: 		* key-sequences. The position in this list is determined
22745: 		* by the target node's depth relative to the matcher's
22746: 		* depth of creation (i.e. the depth of the scope element).
22747: 		*
22748: 		* Element        Depth    Pos   List-entries
22749: 		* <scope>          0              NULL
22750: 		*   <bar>          1              NULL
22751: 		*     <target/>    2       2      target
22752: 		*   <bar>
22753:                 * </scope>
22754: 		*
22755: 		* The size of the list is only dependant on the depth of
22756: 		* the tree.
22757: 		* An entry will be NULLed in selector_leave, i.e. when
22758: 		* we hit the target's
22759: 		*/
22760: 		pos = sto->depth - matcher->depth;
22761: 		idx = sto->sel->index;
22762: 
22763: 		/*
22764: 		* Create/grow the array of key-sequences.
22765: 		*/
22766: 		if (matcher->keySeqs == NULL) {
22767: 		    if (pos > 9)
22768: 			matcher->sizeKeySeqs = pos * 2;
22769: 		    else
22770: 			matcher->sizeKeySeqs = 10;
22771: 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22772: 			xmlMalloc(matcher->sizeKeySeqs *
22773: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22774: 		    if (matcher->keySeqs == NULL) {
22775: 			xmlSchemaVErrMemory(NULL,
22776: 			    "allocating an array of key-sequences",
22777: 			    NULL);
22778: 			return(-1);
22779: 		    }
22780: 		    memset(matcher->keySeqs, 0,
22781: 			matcher->sizeKeySeqs *
22782: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22783: 		} else if (pos >= matcher->sizeKeySeqs) {
22784: 		    int i = matcher->sizeKeySeqs;
22785: 
22786: 		    matcher->sizeKeySeqs *= 2;
22787: 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22788: 			xmlRealloc(matcher->keySeqs,
22789: 			matcher->sizeKeySeqs *
22790: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22791: 		    if (matcher->keySeqs == NULL) {
22792: 			xmlSchemaVErrMemory(NULL,
22793: 			    "reallocating an array of key-sequences",
22794: 			    NULL);
22795: 			return (-1);
22796: 		    }
22797: 		    /*
22798: 		    * The array needs to be NULLed.
22799: 		    * TODO: Use memset?
22800: 		    */
22801: 		    for (; i < matcher->sizeKeySeqs; i++)
22802: 			matcher->keySeqs[i] = NULL;
22803: 		}
22804: 
22805: 		/*
22806: 		* Get/create the key-sequence.
22807: 		*/
22808: 		keySeq = matcher->keySeqs[pos];
22809: 		if (keySeq == NULL) {
22810: 		    goto create_sequence;
22811: 		} else if (keySeq[idx] != NULL) {
22812: 		    xmlChar *str = NULL;
22813: 		    /*
22814: 		    * cvc-identity-constraint:
22815: 		    * 3 For each node in the �target node set� all
22816: 		    * of the {fields}, with that node as the context
22817: 		    * node, evaluate to either an empty node-set or
22818: 		    * a node-set with exactly one member, which must
22819: 		    * have a simple type.
22820: 		    *
22821: 		    * The key was already set; report an error.
22822: 		    */
22823: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22824: 			XML_SCHEMAV_CVC_IDC, NULL,
22825: 			WXS_BASIC_CAST matcher->aidc->def,
22826: 			"The XPath '%s' of a field of %s evaluates to a "
22827: 			"node-set with more than one member",
22828: 			sto->sel->xpath,
22829: 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22830: 		    FREE_AND_NULL(str);
22831: 		    sto->nbHistory--;
22832: 		    goto deregister_check;
22833: 		} else
22834: 		    goto create_key;
22835: 
22836: create_sequence:
22837: 		/*
22838: 		* Create a key-sequence.
22839: 		*/
22840: 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22841: 		    matcher->aidc->def->nbFields *
22842: 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
22843: 		if (keySeq == NULL) {
22844: 		    xmlSchemaVErrMemory(NULL,
22845: 			"allocating an IDC key-sequence", NULL);
22846: 		    return(-1);
22847: 		}
22848: 		memset(keySeq, 0, matcher->aidc->def->nbFields *
22849: 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
22850: 		matcher->keySeqs[pos] = keySeq;
22851: create_key:
22852: 		/*
22853: 		* Create a key once per node only.
22854: 		*/
22855: 		if (key == NULL) {
22856: 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22857: 			sizeof(xmlSchemaPSVIIDCKey));
22858: 		    if (key == NULL) {
22859: 			xmlSchemaVErrMemory(NULL,
22860: 			    "allocating a IDC key", NULL);
22861: 			xmlFree(keySeq);
22862: 			matcher->keySeqs[pos] = NULL;
22863: 			return(-1);
22864: 		    }
22865: 		    /*
22866: 		    * Consume the compiled value.
22867: 		    */
22868: 		    key->type = simpleType;
22869: 		    key->val = vctxt->inode->val;
22870: 		    vctxt->inode->val = NULL;
22871: 		    /*
22872: 		    * Store the key in a global list.
22873: 		    */
22874: 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22875: 			xmlSchemaIDCFreeKey(key);
22876: 			return (-1);
22877: 		    }
22878: 		}
22879: 		keySeq[idx] = key;
22880: 	    }
22881: 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22882: 
22883: 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22884: 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
22885: 	    xmlSchemaPSVIIDCNodePtr ntItem;
22886: 	    xmlSchemaIDCMatcherPtr matcher;
22887: 	    xmlSchemaIDCPtr idc;
22888: 	    xmlSchemaItemListPtr targets;
22889: 	    int pos, i, j, nbKeys;
22890: 	    /*
22891: 	    * Here we have the following scenario:
22892: 	    * An IDC 'selector' state object resolved to a target node,
22893: 	    * during the time this target node was in the
22894: 	    * ancestor-or-self axis, the 'field' state object(s) looked
22895: 	    * out for matching nodes to create a key-sequence for this
22896: 	    * target node. Now we are back to this target node and need
22897: 	    * to put the key-sequence, together with the target node
22898: 	    * itself, into the node-table of the corresponding IDC
22899: 	    * binding.
22900: 	    */
22901: 	    matcher = sto->matcher;
22902: 	    idc = matcher->aidc->def;
22903: 	    nbKeys = idc->nbFields;
22904: 	    pos = depth - matcher->depth;
22905: 	    /*
22906: 	    * Check if the matcher has any key-sequences at all, plus
22907: 	    * if it has a key-sequence for the current target node.
22908: 	    */
22909: 	    if ((matcher->keySeqs == NULL) ||
22910: 		(matcher->sizeKeySeqs <= pos)) {
22911: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22912: 		    goto selector_key_error;
22913: 		else
22914: 		    goto selector_leave;
22915: 	    }
22916: 
22917: 	    keySeq = &(matcher->keySeqs[pos]);
22918: 	    if (*keySeq == NULL) {
22919: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22920: 		    goto selector_key_error;
22921: 		else
22922: 		    goto selector_leave;
22923: 	    }
22924: 
22925: 	    for (i = 0; i < nbKeys; i++) {
22926: 		if ((*keySeq)[i] == NULL) {
22927: 		    /*
22928: 		    * Not qualified, if not all fields did resolve.
22929: 		    */
22930: 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22931: 			/*
22932: 			* All fields of a "key" IDC must resolve.
22933: 			*/
22934: 			goto selector_key_error;
22935: 		    }
22936: 		    goto selector_leave;
22937: 		}
22938: 	    }
22939: 	    /*
22940: 	    * All fields did resolve.
22941: 	    */
22942: 
22943: 	    /*
22944: 	    * 4.1 If the {identity-constraint category} is unique(/key),
22945: 	    * then no two members of the �qualified node set� have
22946: 	    * �key-sequences� whose members are pairwise equal, as
22947: 	    * defined by Equal in [XML Schemas: Datatypes].
22948: 	    *
22949: 	    * Get the IDC binding from the matcher and check for
22950: 	    * duplicate key-sequences.
22951: 	    */
22952: #if 0
22953: 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22954: #endif
22955: 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22956: 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22957: 		(targets->nbItems != 0)) {
22958: 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22959: 
22960: 		i = 0;
22961: 		res = 0;
22962: 		/*
22963: 		* Compare the key-sequences, key by key.
22964: 		*/
22965: 		do {
22966: 		    bkeySeq =
22967: 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
22968: 		    for (j = 0; j < nbKeys; j++) {
22969: 			ckey = (*keySeq)[j];
22970: 			bkey = bkeySeq[j];
22971: 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22972: 			if (res == -1) {
22973: 			    return (-1);
22974: 			} else if (res == 0) {
22975: 			    /*
22976: 			    * One of the keys differs, so the key-sequence
22977: 			    * won't be equal; get out.
22978: 			    */
22979: 			    break;
22980: 			}
22981: 		    }
22982: 		    if (res == 1) {
22983: 			/*
22984: 			* Duplicate key-sequence found.
22985: 			*/
22986: 			break;
22987: 		    }
22988: 		    i++;
22989: 		} while (i < targets->nbItems);
22990: 		if (i != targets->nbItems) {
22991: 		    xmlChar *str = NULL, *strB = NULL;
22992: 		    /*
22993: 		    * TODO: Try to report the key-sequence.
22994: 		    */
22995: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22996: 			XML_SCHEMAV_CVC_IDC, NULL,
22997: 			WXS_BASIC_CAST idc,
22998: 			"Duplicate key-sequence %s in %s",
22999: 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
23000: 			    (*keySeq), nbKeys),
23001: 			xmlSchemaGetIDCDesignation(&strB, idc));
23002: 		    FREE_AND_NULL(str);
23003: 		    FREE_AND_NULL(strB);
23004: 		    goto selector_leave;
23005: 		}
23006: 	    }
23007: 	    /*
23008: 	    * Add a node-table item to the IDC binding.
23009: 	    */
23010: 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23011: 		sizeof(xmlSchemaPSVIIDCNode));
23012: 	    if (ntItem == NULL) {
23013: 		xmlSchemaVErrMemory(NULL,
23014: 		    "allocating an IDC node-table item", NULL);
23015: 		xmlFree(*keySeq);
23016: 		*keySeq = NULL;
23017: 		return(-1);
23018: 	    }
23019: 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23020: 
23021: 	    /*
23022: 	    * Store the node-table item in a global list.
23023: 	    */
23024: 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23025: 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23026: 		    xmlFree(ntItem);
23027: 		    xmlFree(*keySeq);
23028: 		    *keySeq = NULL;
23029: 		    return (-1);
23030: 		}
23031: 		ntItem->nodeQNameID = -1;
23032: 	    } else {
23033: 		/*
23034: 		* Save a cached QName for this node on the IDC node, to be
23035: 		* able to report it, even if the node is not saved.
23036: 		*/
23037: 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23038: 		    vctxt->inode->localName, vctxt->inode->nsName);
23039: 		if (ntItem->nodeQNameID == -1) {
23040: 		    xmlFree(ntItem);
23041: 		    xmlFree(*keySeq);
23042: 		    *keySeq = NULL;
23043: 		    return (-1);
23044: 		}
23045: 	    }
23046: 	    /*
23047: 	    * Init the node-table item: Save the node, position and
23048: 	    * consume the key-sequence.
23049: 	    */
23050: 	    ntItem->node = vctxt->node;
23051: 	    ntItem->nodeLine = vctxt->inode->nodeLine;
23052: 	    ntItem->keys = *keySeq;
23053: 	    *keySeq = NULL;
23054: #if 0
23055: 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23056: #endif
23057: 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23058: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23059: 		    /*
23060: 		    * Free the item, since keyref items won't be
23061: 		    * put on a global list.
23062: 		    */
23063: 		    xmlFree(ntItem->keys);
23064: 		    xmlFree(ntItem);
23065: 		}
23066: 		return (-1);
23067: 	    }
23068: 
23069: 	    goto selector_leave;
23070: selector_key_error:
23071: 	    {
23072: 		xmlChar *str = NULL;
23073: 		/*
23074: 		* 4.2.1 (KEY) The �target node set� and the
23075: 		* �qualified node set� are equal, that is, every
23076: 		* member of the �target node set� is also a member
23077: 		* of the �qualified node set� and vice versa.
23078: 		*/
23079: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
23080: 		    XML_SCHEMAV_CVC_IDC, NULL,
23081: 		    WXS_BASIC_CAST idc,
23082: 		    "Not all fields of %s evaluate to a node",
23083: 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
23084: 		FREE_AND_NULL(str);
23085: 	    }
23086: selector_leave:
23087: 	    /*
23088: 	    * Free the key-sequence if not added to the IDC table.
23089: 	    */
23090: 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
23091: 		xmlFree(*keySeq);
23092: 		*keySeq = NULL;
23093: 	    }
23094: 	} /* if selector */
23095: 
23096: 	sto->nbHistory--;
23097: 
23098: deregister_check:
23099: 	/*
23100: 	* Deregister state objects if they reach the depth of creation.
23101: 	*/
23102: 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23103: #ifdef DEBUG_IDC
23104: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
23105: 		sto->sel->xpath);
23106: #endif
23107: 	    if (vctxt->xpathStates != sto) {
23108: 		VERROR_INT("xmlSchemaXPathProcessHistory",
23109: 		    "The state object to be removed is not the first "
23110: 		    "in the list");
23111: 	    }
23112: 	    nextsto = sto->next;
23113: 	    /*
23114: 	    * Unlink from the list of active XPath state objects.
23115: 	    */
23116: 	    vctxt->xpathStates = sto->next;
23117: 	    sto->next = vctxt->xpathStatePool;
23118: 	    /*
23119: 	    * Link it to the pool of reusable state objects.
23120: 	    */
23121: 	    vctxt->xpathStatePool = sto;
23122: 	    sto = nextsto;
23123: 	} else
23124: 	    sto = sto->next;
23125:     } /* while (sto != NULL) */
23126:     return (0);
23127: }
23128: 
23129: /**
23130:  * xmlSchemaIDCRegisterMatchers:
23131:  * @vctxt: the WXS validation context
23132:  * @elemDecl: the element declaration
23133:  *
23134:  * Creates helper objects to evaluate IDC selectors/fields
23135:  * successively.
23136:  *
23137:  * Returns 0 if OK and -1 on internal errors.
23138:  */
23139: static int
23140: xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23141: 			     xmlSchemaElementPtr elemDecl)
23142: {
23143:     xmlSchemaIDCMatcherPtr matcher, last = NULL;
23144:     xmlSchemaIDCPtr idc, refIdc;
23145:     xmlSchemaIDCAugPtr aidc;
23146: 
23147:     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23148:     if (idc == NULL)
23149: 	return (0);
23150: 
23151: #ifdef DEBUG_IDC
23152:     {
23153: 	xmlChar *str = NULL;
23154: 	xmlGenericError(xmlGenericErrorContext,
23155: 	    "IDC: REGISTER on %s, depth %d\n",
23156: 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23157: 		vctxt->inode->localName), vctxt->depth);
23158: 	FREE_AND_NULL(str)
23159:     }
23160: #endif
23161:     if (vctxt->inode->idcMatchers != NULL) {
23162: 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
23163: 	    "The chain of IDC matchers is expected to be empty");
23164: 	return (-1);
23165:     }
23166:     do {
23167: 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23168: 	    /*
23169: 	    * Since IDCs bubbles are expensive we need to know the
23170: 	    * depth at which the bubbles should stop; this will be
23171: 	    * the depth of the top-most keyref IDC. If no keyref
23172: 	    * references a key/unique IDC, the keyrefDepth will
23173: 	    * be -1, indicating that no bubbles are needed.
23174: 	    */
23175: 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23176: 	    if (refIdc != NULL) {
23177: 		/*
23178: 		* Remember that we have keyrefs on this node.
23179: 		*/
23180: 		vctxt->inode->hasKeyrefs = 1;
23181: 		/*
23182: 		* Lookup the referenced augmented IDC info.
23183: 		*/
23184: 		aidc = vctxt->aidcs;
23185: 		while (aidc != NULL) {
23186: 		    if (aidc->def == refIdc)
23187: 			break;
23188: 		    aidc = aidc->next;
23189: 		}
23190: 		if (aidc == NULL) {
23191: 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
23192: 			"Could not find an augmented IDC item for an IDC "
23193: 			"definition");
23194: 		    return (-1);
23195: 		}
23196: 		if ((aidc->keyrefDepth == -1) ||
23197: 		    (vctxt->depth < aidc->keyrefDepth))
23198: 		    aidc->keyrefDepth = vctxt->depth;
23199: 	    }
23200: 	}
23201: 	/*
23202: 	* Lookup the augmented IDC item for the IDC definition.
23203: 	*/
23204: 	aidc = vctxt->aidcs;
23205: 	while (aidc != NULL) {
23206: 	    if (aidc->def == idc)
23207: 		break;
23208: 	    aidc = aidc->next;
23209: 	}
23210: 	if (aidc == NULL) {
23211: 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
23212: 		"Could not find an augmented IDC item for an IDC definition");
23213: 	    return (-1);
23214: 	}
23215: 	/*
23216: 	* Create an IDC matcher for every IDC definition.
23217: 	*/
23218: 	if (vctxt->idcMatcherCache != NULL) {
23219: 	    /*
23220: 	    * Reuse a cached matcher.
23221: 	    */
23222: 	    matcher = vctxt->idcMatcherCache;
23223: 	    vctxt->idcMatcherCache = matcher->nextCached;
23224: 	    matcher->nextCached = NULL;
23225: 	} else {
23226: 	    matcher = (xmlSchemaIDCMatcherPtr)
23227: 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23228: 	    if (matcher == NULL) {
23229: 		xmlSchemaVErrMemory(vctxt,
23230: 		    "allocating an IDC matcher", NULL);
23231: 		return (-1);
23232: 	    }
23233: 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23234: 	}
23235: 	if (last == NULL)
23236: 	    vctxt->inode->idcMatchers = matcher;
23237: 	else
23238: 	    last->next = matcher;
23239: 	last = matcher;
23240: 
23241: 	matcher->type = IDC_MATCHER;
23242: 	matcher->depth = vctxt->depth;
23243: 	matcher->aidc = aidc;
23244: 	matcher->idcType = aidc->def->type;
23245: #ifdef DEBUG_IDC
23246: 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
23247: #endif
23248: 	/*
23249: 	* Init the automaton state object.
23250: 	*/
23251: 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23252: 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23253: 	    return (-1);
23254: 
23255: 	idc = idc->next;
23256:     } while (idc != NULL);
23257:     return (0);
23258: }
23259: 
23260: static int
23261: xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23262: 			   xmlSchemaNodeInfoPtr ielem)
23263: {
23264:     xmlSchemaPSVIIDCBindingPtr bind;
23265:     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23266:     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23267:     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23268: 
23269:     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23270:     /* vctxt->createIDCNodeTables */
23271:     while (matcher != NULL) {
23272: 	/*
23273: 	* Skip keyref IDCs and empty IDC target-lists.
23274: 	*/
23275: 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23276: 	    WXS_ILIST_IS_EMPTY(matcher->targets))
23277: 	{
23278: 	    matcher = matcher->next;
23279: 	    continue;
23280: 	}
23281: 	/*
23282: 	* If we _want_ the IDC node-table to be created in any case
23283: 	* then do so. Otherwise create them only if keyrefs need them.
23284: 	*/
23285: 	if ((! vctxt->createIDCNodeTables) &&
23286: 	    ((matcher->aidc->keyrefDepth == -1) ||
23287: 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
23288: 	{
23289: 	    matcher = matcher->next;
23290: 	    continue;
23291: 	}
23292: 	/*
23293: 	* Get/create the IDC binding on this element for the IDC definition.
23294: 	*/
23295: 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23296: 
23297: 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23298: 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23299: 	    nbDupls = bind->dupls->nbItems;
23300: 	} else {
23301: 	    dupls = NULL;
23302: 	    nbDupls = 0;
23303: 	}
23304: 	if (bind->nodeTable != NULL) {
23305: 	    nbNodeTable = bind->nbNodes;
23306: 	} else {
23307: 	    nbNodeTable = 0;
23308: 	}
23309: 
23310: 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
23311: 	    /*
23312: 	    * Transfer all IDC target-nodes to the IDC node-table.
23313: 	    */
23314: 	    bind->nodeTable =
23315: 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23316: 	    bind->sizeNodes = matcher->targets->sizeItems;
23317: 	    bind->nbNodes = matcher->targets->nbItems;
23318: 
23319: 	    matcher->targets->items = NULL;
23320: 	    matcher->targets->sizeItems = 0;
23321: 	    matcher->targets->nbItems = 0;
23322: 	} else {
23323: 	    /*
23324: 	    * Compare the key-sequences and add to the IDC node-table.
23325: 	    */
23326: 	    nbTargets = matcher->targets->nbItems;
23327: 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23328: 	    nbFields = matcher->aidc->def->nbFields;
23329: 	    i = 0;
23330: 	    do {
23331: 		keys = targets[i]->keys;
23332: 		if (nbDupls) {
23333: 		    /*
23334: 		    * Search in already found duplicates first.
23335: 		    */
23336: 		    j = 0;
23337: 		    do {
23338: 			if (nbFields == 1) {
23339: 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
23340: 				dupls[j]->keys[0]->val);
23341: 			    if (res == -1)
23342: 				goto internal_error;
23343: 			    if (res == 1) {
23344: 				/*
23345: 				* Equal key-sequence.
23346: 				*/
23347: 				goto next_target;
23348: 			    }
23349: 			} else {
23350: 			    res = 0;
23351: 			    ntkeys = dupls[j]->keys;
23352: 			    for (k = 0; k < nbFields; k++) {
23353: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23354: 				    ntkeys[k]->val);
23355: 				if (res == -1)
23356: 				    goto internal_error;
23357: 				if (res == 0) {
23358: 				    /*
23359: 				    * One of the keys differs.
23360: 				    */
23361: 				    break;
23362: 				}
23363: 			    }
23364: 			    if (res == 1) {
23365: 				/*
23366: 				* Equal key-sequence found.
23367: 				*/
23368: 				goto next_target;
23369: 			    }
23370: 			}
23371: 			j++;
23372: 		    } while (j < nbDupls);
23373: 		}
23374: 		if (nbNodeTable) {
23375: 		    j = 0;
23376: 		    do {
23377: 			if (nbFields == 1) {
23378: 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
23379: 				bind->nodeTable[j]->keys[0]->val);
23380: 			    if (res == -1)
23381: 				goto internal_error;
23382: 			    if (res == 0) {
23383: 				/*
23384: 				* The key-sequence differs.
23385: 				*/
23386: 				goto next_node_table_entry;
23387: 			    }
23388: 			} else {
23389: 			    res = 0;
23390: 			    ntkeys = bind->nodeTable[j]->keys;
23391: 			    for (k = 0; k < nbFields; k++) {
23392: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23393: 				    ntkeys[k]->val);
23394: 				if (res == -1)
23395: 				    goto internal_error;
23396: 				if (res == 0) {
23397: 				    /*
23398: 				    * One of the keys differs.
23399: 				    */
23400: 				    goto next_node_table_entry;
23401: 				}
23402: 			    }
23403: 			}
23404: 			/*
23405: 			* Add the duplicate to the list of duplicates.
23406: 			*/
23407: 			if (bind->dupls == NULL) {
23408: 			    bind->dupls = xmlSchemaItemListCreate();
23409: 			    if (bind->dupls == NULL)
23410: 				goto internal_error;
23411: 			}
23412: 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23413: 			    goto internal_error;
23414: 			/*
23415: 			* Remove the duplicate entry from the IDC node-table.
23416: 			*/
23417: 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23418: 			bind->nbNodes--;
23419: 
23420: 			goto next_target;
23421: 
23422: next_node_table_entry:
23423: 			j++;
23424: 		    } while (j < nbNodeTable);
23425: 		}
23426: 		/*
23427: 		* If everything is fine, then add the IDC target-node to
23428: 		* the IDC node-table.
23429: 		*/
23430: 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23431: 		    goto internal_error;
23432: 
23433: next_target:
23434: 		i++;
23435: 	    } while (i < nbTargets);
23436: 	}
23437: 	matcher = matcher->next;
23438:     }
23439:     return(0);
23440: 
23441: internal_error:
23442:     return(-1);
23443: }
23444: 
23445: /**
23446:  * xmlSchemaBubbleIDCNodeTables:
23447:  * @depth: the current tree depth
23448:  *
23449:  * Merges IDC bindings of an element at @depth into the corresponding IDC
23450:  * bindings of its parent element. If a duplicate note-table entry is found,
23451:  * both, the parent node-table entry and child entry are discarded from the
23452:  * node-table of the parent.
23453:  *
23454:  * Returns 0 if OK and -1 on internal errors.
23455:  */
23456: static int
23457: xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23458: {
23459:     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23460:     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23461:     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23462:     xmlSchemaIDCAugPtr aidc;
23463:     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23464: 
23465:     bind = vctxt->inode->idcTable;
23466:     if (bind == NULL) {
23467: 	/* Fine, no table, no bubbles. */
23468: 	return (0);
23469:     }
23470: 
23471:     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23472:     /*
23473:     * Walk all bindings; create new or add to existing bindings.
23474:     * Remove duplicate key-sequences.
23475:     */
23476:     while (bind != NULL) {
23477: 
23478: 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23479: 	    goto next_binding;
23480: 	/*
23481: 	* Check if the key/unique IDC table needs to be bubbled.
23482: 	*/
23483: 	if (! vctxt->createIDCNodeTables) {
23484: 	    aidc = vctxt->aidcs;
23485: 	    do {
23486: 		if (aidc->def == bind->definition) {
23487: 		    if ((aidc->keyrefDepth == -1) ||
23488: 			(aidc->keyrefDepth >= vctxt->depth)) {
23489: 			goto next_binding;
23490: 		    }
23491: 		    break;
23492: 		}
23493: 		aidc = aidc->next;
23494: 	    } while (aidc != NULL);
23495: 	}
23496: 
23497: 	if (parTable != NULL)
23498: 	    parBind = *parTable;
23499: 	/*
23500: 	* Search a matching parent binding for the
23501: 	* IDC definition.
23502: 	*/
23503: 	while (parBind != NULL) {
23504: 	    if (parBind->definition == bind->definition)
23505: 		break;
23506: 	    parBind = parBind->next;
23507: 	}
23508: 
23509: 	if (parBind != NULL) {
23510: 	    /*
23511: 	    * Compare every node-table entry of the child node,
23512: 	    * i.e. the key-sequence within, ...
23513: 	    */
23514: 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
23515: 
23516: 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23517: 		oldDupls = parBind->dupls->nbItems;
23518: 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23519: 	    } else {
23520: 		dupls = NULL;
23521: 		oldDupls = 0;
23522: 	    }
23523: 
23524: 	    parNodes = parBind->nodeTable;
23525: 	    nbFields = bind->definition->nbFields;
23526: 
23527: 	    for (i = 0; i < bind->nbNodes; i++) {
23528: 		node = bind->nodeTable[i];
23529: 		if (node == NULL)
23530: 		    continue;
23531: 		/*
23532: 		* ...with every key-sequence of the parent node, already
23533: 		* evaluated to be a duplicate key-sequence.
23534: 		*/
23535: 		if (oldDupls) {
23536: 		    j = 0;
23537: 		    while (j < oldDupls) {
23538: 			if (nbFields == 1) {
23539: 			    ret = xmlSchemaAreValuesEqual(
23540: 				node->keys[0]->val,
23541: 				dupls[j]->keys[0]->val);
23542: 			    if (ret == -1)
23543: 				goto internal_error;
23544: 			    if (ret == 0) {
23545: 				j++;
23546: 				continue;
23547: 			    }
23548: 			} else {
23549: 			    parNode = dupls[j];
23550: 			    for (k = 0; k < nbFields; k++) {
23551: 				ret = xmlSchemaAreValuesEqual(
23552: 				    node->keys[k]->val,
23553: 				    parNode->keys[k]->val);
23554: 				if (ret == -1)
23555: 				    goto internal_error;
23556: 				if (ret == 0)
23557: 				    break;
23558: 			    }
23559: 			}
23560: 			if (ret == 1)
23561: 			    /* Duplicate found. */
23562: 			    break;
23563: 			j++;
23564: 		    }
23565: 		    if (j != oldDupls) {
23566: 			/* Duplicate found. Skip this entry. */
23567: 			continue;
23568: 		    }
23569: 		}
23570: 		/*
23571: 		* ... and with every key-sequence of the parent node.
23572: 		*/
23573: 		if (oldNum) {
23574: 		    j = 0;
23575: 		    while (j < oldNum) {
23576: 			parNode = parNodes[j];
23577: 			if (nbFields == 1) {
23578: 			    ret = xmlSchemaAreValuesEqual(
23579: 				node->keys[0]->val,
23580: 				parNode->keys[0]->val);
23581: 			    if (ret == -1)
23582: 				goto internal_error;
23583: 			    if (ret == 0) {
23584: 				j++;
23585: 				continue;
23586: 			    }
23587: 			} else {
23588: 			    for (k = 0; k < nbFields; k++) {
23589: 				ret = xmlSchemaAreValuesEqual(
23590: 				    node->keys[k]->val,
23591: 				    parNode->keys[k]->val);
23592: 				if (ret == -1)
23593: 				    goto internal_error;
23594: 				if (ret == 0)
23595: 				    break;
23596: 			    }
23597: 			}
23598: 			if (ret == 1)
23599: 			    /* Duplicate found. */
23600: 			    break;
23601: 			j++;
23602: 		    }
23603: 		    if (j != oldNum) {
23604: 			/*
23605: 			* Handle duplicates. Move the duplicate in
23606: 			* the parent's node-table to the list of
23607: 			* duplicates.
23608: 			*/
23609: 			oldNum--;
23610: 			parBind->nbNodes--;
23611: 			/*
23612: 			* Move last old item to pos of duplicate.
23613: 			*/
23614: 			parNodes[j] = parNodes[oldNum];
23615: 
23616: 			if (parBind->nbNodes != oldNum) {
23617: 			    /*
23618: 			    * If new items exist, move last new item to
23619: 			    * last of old items.
23620: 			    */
23621: 			    parNodes[oldNum] =
23622: 				parNodes[parBind->nbNodes];
23623: 			}
23624: 			if (parBind->dupls == NULL) {
23625: 			    parBind->dupls = xmlSchemaItemListCreate();
23626: 			    if (parBind->dupls == NULL)
23627: 				goto internal_error;
23628: 			}
23629: 			xmlSchemaItemListAdd(parBind->dupls, parNode);
23630: 		    } else {
23631: 			/*
23632: 			* Add the node-table entry (node and key-sequence) of
23633: 			* the child node to the node table of the parent node.
23634: 			*/
23635: 			if (parBind->nodeTable == NULL) {
23636: 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23637: 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23638: 			    if (parBind->nodeTable == NULL) {
23639: 				xmlSchemaVErrMemory(NULL,
23640: 				    "allocating IDC list of node-table items", NULL);
23641: 				goto internal_error;
23642: 			    }
23643: 			    parBind->sizeNodes = 1;
23644: 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
23645: 			    parBind->sizeNodes *= 2;
23646: 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23647: 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23648: 				sizeof(xmlSchemaPSVIIDCNodePtr));
23649: 			    if (parBind->nodeTable == NULL) {
23650: 				xmlSchemaVErrMemory(NULL,
23651: 				    "re-allocating IDC list of node-table items", NULL);
23652: 				goto internal_error;
23653: 			    }
23654: 			}
23655: 			parNodes = parBind->nodeTable;
23656: 			/*
23657: 			* Append the new node-table entry to the 'new node-table
23658: 			* entries' section.
23659: 			*/
23660: 			parNodes[parBind->nbNodes++] = node;
23661: 		    }
23662: 
23663: 		}
23664: 
23665: 	    }
23666: 	} else {
23667: 	    /*
23668: 	    * No binding for the IDC was found: create a new one and
23669: 	    * copy all node-tables.
23670: 	    */
23671: 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
23672: 	    if (parBind == NULL)
23673: 		goto internal_error;
23674: 
23675: 	    /*
23676: 	    * TODO: Hmm, how to optimize the initial number of
23677: 	    * allocated entries?
23678: 	    */
23679: 	    if (bind->nbNodes != 0) {
23680: 		/*
23681: 		* Add all IDC node-table entries.
23682: 		*/
23683: 		if (! vctxt->psviExposeIDCNodeTables) {
23684: 		    /*
23685: 		    * Just move the entries.
23686: 		    * NOTE: this is quite save here, since
23687: 		    * all the keyref lookups have already been
23688: 		    * performed.
23689: 		    */
23690: 		    parBind->nodeTable = bind->nodeTable;
23691: 		    bind->nodeTable = NULL;
23692: 		    parBind->sizeNodes = bind->sizeNodes;
23693: 		    bind->sizeNodes = 0;
23694: 		    parBind->nbNodes = bind->nbNodes;
23695: 		    bind->nbNodes = 0;
23696: 		} else {
23697: 		    /*
23698: 		    * Copy the entries.
23699: 		    */
23700: 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23701: 			xmlMalloc(bind->nbNodes *
23702: 			sizeof(xmlSchemaPSVIIDCNodePtr));
23703: 		    if (parBind->nodeTable == NULL) {
23704: 			xmlSchemaVErrMemory(NULL,
23705: 			    "allocating an array of IDC node-table "
23706: 			    "items", NULL);
23707: 			xmlSchemaIDCFreeBinding(parBind);
23708: 			goto internal_error;
23709: 		    }
23710: 		    parBind->sizeNodes = bind->nbNodes;
23711: 		    parBind->nbNodes = bind->nbNodes;
23712: 		    memcpy(parBind->nodeTable, bind->nodeTable,
23713: 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23714: 		}
23715: 	    }
23716: 	    if (bind->dupls) {
23717: 		/*
23718: 		* Move the duplicates.
23719: 		*/
23720: 		if (parBind->dupls != NULL)
23721: 		    xmlSchemaItemListFree(parBind->dupls);
23722: 		parBind->dupls = bind->dupls;
23723: 		bind->dupls = NULL;
23724: 	    }
23725:             if (parTable != NULL) {
23726:                 if (*parTable == NULL)
23727:                     *parTable = parBind;
23728:                 else {
23729:                     parBind->next = *parTable;
23730:                     *parTable = parBind;
23731:                 }
23732:             }
23733: 	}
23734: 
23735: next_binding:
23736: 	bind = bind->next;
23737:     }
23738:     return (0);
23739: 
23740: internal_error:
23741:     return(-1);
23742: }
23743: 
23744: /**
23745:  * xmlSchemaCheckCVCIDCKeyRef:
23746:  * @vctxt: the WXS validation context
23747:  * @elemDecl: the element declaration
23748:  *
23749:  * Check the cvc-idc-keyref constraints.
23750:  */
23751: static int
23752: xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23753: {
23754:     xmlSchemaIDCMatcherPtr matcher;
23755:     xmlSchemaPSVIIDCBindingPtr bind;
23756: 
23757:     matcher = vctxt->inode->idcMatchers;
23758:     /*
23759:     * Find a keyref.
23760:     */
23761:     while (matcher != NULL) {
23762: 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23763: 	    matcher->targets &&
23764: 	    matcher->targets->nbItems)
23765: 	{
23766: 	    int i, j, k, res, nbFields, hasDupls;
23767: 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23768: 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
23769: 
23770: 	    nbFields = matcher->aidc->def->nbFields;
23771: 
23772: 	    /*
23773: 	    * Find the IDC node-table for the referenced IDC key/unique.
23774: 	    */
23775: 	    bind = vctxt->inode->idcTable;
23776: 	    while (bind != NULL) {
23777: 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23778: 		    bind->definition)
23779: 		    break;
23780: 		bind = bind->next;
23781: 	    }
23782: 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23783: 	    /*
23784: 	    * Search for a matching key-sequences.
23785: 	    */
23786: 	    for (i = 0; i < matcher->targets->nbItems; i++) {
23787: 		res = 0;
23788: 		refNode = matcher->targets->items[i];
23789: 		if (bind != NULL) {
23790: 		    refKeys = refNode->keys;
23791: 		    for (j = 0; j < bind->nbNodes; j++) {
23792: 			keys = bind->nodeTable[j]->keys;
23793: 			for (k = 0; k < nbFields; k++) {
23794: 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
23795: 				refKeys[k]->val);
23796: 			    if (res == 0)
23797: 				break;
23798: 			    else if (res == -1) {
23799: 				return (-1);
23800: 			    }
23801: 			}
23802: 			if (res == 1) {
23803: 			    /*
23804: 			    * Match found.
23805: 			    */
23806: 			    break;
23807: 			}
23808: 		    }
23809: 		    if ((res == 0) && hasDupls) {
23810: 			/*
23811: 			* Search in duplicates
23812: 			*/
23813: 			for (j = 0; j < bind->dupls->nbItems; j++) {
23814: 			    keys = ((xmlSchemaPSVIIDCNodePtr)
23815: 				bind->dupls->items[j])->keys;
23816: 			    for (k = 0; k < nbFields; k++) {
23817: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23818: 				    refKeys[k]->val);
23819: 				if (res == 0)
23820: 				    break;
23821: 				else if (res == -1) {
23822: 				    return (-1);
23823: 				}
23824: 			    }
23825: 			    if (res == 1) {
23826: 				/*
23827: 				* Match in duplicates found.
23828: 				*/
23829: 				xmlChar *str = NULL, *strB = NULL;
23830: 				xmlSchemaKeyrefErr(vctxt,
23831: 				    XML_SCHEMAV_CVC_IDC, refNode,
23832: 				    (xmlSchemaTypePtr) matcher->aidc->def,
23833: 				    "More than one match found for "
23834: 				    "key-sequence %s of keyref '%s'",
23835: 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
23836: 					refNode->keys, nbFields),
23837: 				    xmlSchemaGetComponentQName(&strB,
23838: 					matcher->aidc->def));
23839: 				FREE_AND_NULL(str);
23840: 				FREE_AND_NULL(strB);
23841: 				break;
23842: 			    }
23843: 			}
23844: 		    }
23845: 		}
23846: 
23847: 		if (res == 0) {
23848: 		    xmlChar *str = NULL, *strB = NULL;
23849: 		    xmlSchemaKeyrefErr(vctxt,
23850: 			XML_SCHEMAV_CVC_IDC, refNode,
23851: 			(xmlSchemaTypePtr) matcher->aidc->def,
23852: 			"No match found for key-sequence %s of keyref '%s'",
23853: 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
23854: 			    refNode->keys, nbFields),
23855: 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23856: 		    FREE_AND_NULL(str);
23857: 		    FREE_AND_NULL(strB);
23858: 		}
23859: 	    }
23860: 	}
23861: 	matcher = matcher->next;
23862:     }
23863:     /* TODO: Return an error if any error encountered. */
23864:     return (0);
23865: }
23866: 
23867: /************************************************************************
23868:  * 									*
23869:  * 			XML Reader validation code                      *
23870:  * 									*
23871:  ************************************************************************/
23872: 
23873: static xmlSchemaAttrInfoPtr
23874: xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23875: {
23876:     xmlSchemaAttrInfoPtr iattr;
23877:     /*
23878:     * Grow/create list of attribute infos.
23879:     */
23880:     if (vctxt->attrInfos == NULL) {
23881: 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23882: 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23883: 	vctxt->sizeAttrInfos = 1;
23884: 	if (vctxt->attrInfos == NULL) {
23885: 	    xmlSchemaVErrMemory(vctxt,
23886: 		"allocating attribute info list", NULL);
23887: 	    return (NULL);
23888: 	}
23889:     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23890: 	vctxt->sizeAttrInfos++;
23891: 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23892: 	    xmlRealloc(vctxt->attrInfos,
23893: 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23894: 	if (vctxt->attrInfos == NULL) {
23895: 	    xmlSchemaVErrMemory(vctxt,
23896: 		"re-allocating attribute info list", NULL);
23897: 	    return (NULL);
23898: 	}
23899:     } else {
23900: 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23901: 	if (iattr->localName != NULL) {
23902: 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
23903: 		"attr info not cleared");
23904: 	    return (NULL);
23905: 	}
23906: 	iattr->nodeType = XML_ATTRIBUTE_NODE;
23907: 	return (iattr);
23908:     }
23909:     /*
23910:     * Create an attribute info.
23911:     */
23912:     iattr = (xmlSchemaAttrInfoPtr)
23913: 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
23914:     if (iattr == NULL) {
23915: 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
23916: 	return (NULL);
23917:     }
23918:     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23919:     iattr->nodeType = XML_ATTRIBUTE_NODE;
23920:     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23921: 
23922:     return (iattr);
23923: }
23924: 
23925: static int
23926: xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23927: 			xmlNodePtr attrNode,
23928: 			int nodeLine,
23929: 			const xmlChar *localName,
23930: 			const xmlChar *nsName,
23931: 			int ownedNames,
23932: 			xmlChar *value,
23933: 			int ownedValue)
23934: {
23935:     xmlSchemaAttrInfoPtr attr;
23936: 
23937:     attr = xmlSchemaGetFreshAttrInfo(vctxt);
23938:     if (attr == NULL) {
23939: 	VERROR_INT("xmlSchemaPushAttribute",
23940: 	    "calling xmlSchemaGetFreshAttrInfo()");
23941: 	return (-1);
23942:     }
23943:     attr->node = attrNode;
23944:     attr->nodeLine = nodeLine;
23945:     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23946:     attr->localName = localName;
23947:     attr->nsName = nsName;
23948:     if (ownedNames)
23949: 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23950:     /*
23951:     * Evaluate if it's an XSI attribute.
23952:     */
23953:     if (nsName != NULL) {
23954: 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
23955: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23956: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23957: 	    }
23958: 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
23959: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23960: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23961: 	    }
23962: 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23963: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23964: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23965: 	    }
23966: 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23967: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23968: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23969: 	    }
23970: 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23971: 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23972: 	}
23973:     }
23974:     attr->value = value;
23975:     if (ownedValue)
23976: 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23977:     if (attr->metaType != 0)
23978: 	attr->state = XML_SCHEMAS_ATTR_META;
23979:     return (0);
23980: }
23981: 
23982: /**
23983:  * xmlSchemaClearElemInfo:
23984:  * @vctxt: the WXS validation context
23985:  * @ielem: the element information item
23986:  */
23987: static void
23988: xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23989: 		       xmlSchemaNodeInfoPtr ielem)
23990: {
23991:     ielem->hasKeyrefs = 0;
23992:     ielem->appliedXPath = 0;
23993:     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23994: 	FREE_AND_NULL(ielem->localName);
23995: 	FREE_AND_NULL(ielem->nsName);
23996:     } else {
23997: 	ielem->localName = NULL;
23998: 	ielem->nsName = NULL;
23999:     }
24000:     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24001: 	FREE_AND_NULL(ielem->value);
24002:     } else {
24003: 	ielem->value = NULL;
24004:     }
24005:     if (ielem->val != NULL) {
24006: 	/*
24007: 	* PSVI TODO: Be careful not to free it when the value is
24008: 	* exposed via PSVI.
24009: 	*/
24010: 	xmlSchemaFreeValue(ielem->val);
24011: 	ielem->val = NULL;
24012:     }
24013:     if (ielem->idcMatchers != NULL) {
24014: 	/*
24015: 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24016: 	*   Does it work?
24017: 	*/
24018: 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24019: #if 0
24020: 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24021: #endif
24022: 	ielem->idcMatchers = NULL;
24023:     }
24024:     if (ielem->idcTable != NULL) {
24025: 	/*
24026: 	* OPTIMIZE TODO: Use a pool of IDC tables??.
24027: 	*/
24028: 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24029: 	ielem->idcTable = NULL;
24030:     }
24031:     if (ielem->regexCtxt != NULL) {
24032: 	xmlRegFreeExecCtxt(ielem->regexCtxt);
24033: 	ielem->regexCtxt = NULL;
24034:     }
24035:     if (ielem->nsBindings != NULL) {
24036: 	xmlFree((xmlChar **)ielem->nsBindings);
24037: 	ielem->nsBindings = NULL;
24038: 	ielem->nbNsBindings = 0;
24039: 	ielem->sizeNsBindings = 0;
24040:     }
24041: }
24042: 
24043: /**
24044:  * xmlSchemaGetFreshElemInfo:
24045:  * @vctxt: the schema validation context
24046:  *
24047:  * Creates/reuses and initializes the element info item for
24048:  * the currect tree depth.
24049:  *
24050:  * Returns the element info item or NULL on API or internal errors.
24051:  */
24052: static xmlSchemaNodeInfoPtr
24053: xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24054: {
24055:     xmlSchemaNodeInfoPtr info = NULL;
24056: 
24057:     if (vctxt->depth > vctxt->sizeElemInfos) {
24058: 	VERROR_INT("xmlSchemaGetFreshElemInfo",
24059: 	    "inconsistent depth encountered");
24060: 	return (NULL);
24061:     }
24062:     if (vctxt->elemInfos == NULL) {
24063: 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24064: 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24065: 	if (vctxt->elemInfos == NULL) {
24066: 	    xmlSchemaVErrMemory(vctxt,
24067: 		"allocating the element info array", NULL);
24068: 	    return (NULL);
24069: 	}
24070: 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24071: 	vctxt->sizeElemInfos = 10;
24072:     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24073: 	int i = vctxt->sizeElemInfos;
24074: 
24075: 	vctxt->sizeElemInfos *= 2;
24076: 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24077: 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24078: 	    sizeof(xmlSchemaNodeInfoPtr));
24079: 	if (vctxt->elemInfos == NULL) {
24080: 	    xmlSchemaVErrMemory(vctxt,
24081: 		"re-allocating the element info array", NULL);
24082: 	    return (NULL);
24083: 	}
24084: 	/*
24085: 	* We need the new memory to be NULLed.
24086: 	* TODO: Use memset instead?
24087: 	*/
24088: 	for (; i < vctxt->sizeElemInfos; i++)
24089: 	    vctxt->elemInfos[i] = NULL;
24090:     } else
24091: 	info = vctxt->elemInfos[vctxt->depth];
24092: 
24093:     if (info == NULL) {
24094: 	info = (xmlSchemaNodeInfoPtr)
24095: 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
24096: 	if (info == NULL) {
24097: 	    xmlSchemaVErrMemory(vctxt,
24098: 		"allocating an element info", NULL);
24099: 	    return (NULL);
24100: 	}
24101: 	vctxt->elemInfos[vctxt->depth] = info;
24102:     } else {
24103: 	if (info->localName != NULL) {
24104: 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
24105: 		"elem info has not been cleared");
24106: 	    return (NULL);
24107: 	}
24108:     }
24109:     memset(info, 0, sizeof(xmlSchemaNodeInfo));
24110:     info->nodeType = XML_ELEMENT_NODE;
24111:     info->depth = vctxt->depth;
24112: 
24113:     return (info);
24114: }
24115: 
24116: #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24117: #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24118: #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24119: 
24120: static int
24121: xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24122: 			xmlNodePtr node,
24123: 			xmlSchemaTypePtr type,
24124: 			xmlSchemaValType valType,
24125: 			const xmlChar * value,
24126: 			xmlSchemaValPtr val,
24127: 			unsigned long length,
24128: 			int fireErrors)
24129: {
24130:     int ret, error = 0;
24131: 
24132:     xmlSchemaTypePtr tmpType;
24133:     xmlSchemaFacetLinkPtr facetLink;
24134:     xmlSchemaFacetPtr facet;
24135:     unsigned long len = 0;
24136:     xmlSchemaWhitespaceValueType ws;
24137: 
24138:     /*
24139:     * In Libxml2, derived built-in types have currently no explicit facets.
24140:     */
24141:     if (type->type == XML_SCHEMA_TYPE_BASIC)
24142: 	return (0);
24143: 
24144:     /*
24145:     * NOTE: Do not jump away, if the facetSet of the given type is
24146:     * empty: until now, "pattern" and "enumeration" facets of the
24147:     * *base types* need to be checked as well.
24148:     */
24149:     if (type->facetSet == NULL)
24150: 	goto pattern_and_enum;
24151: 
24152:     if (! WXS_IS_ATOMIC(type)) {
24153: 	if (WXS_IS_LIST(type))
24154: 	    goto WXS_IS_LIST;
24155: 	else
24156: 	    goto pattern_and_enum;
24157:     }
24158:     /*
24159:     * Whitespace handling is only of importance for string-based
24160:     * types.
24161:     */
24162:     tmpType = xmlSchemaGetPrimitiveType(type);
24163:     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24164: 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24165: 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24166:     } else
24167: 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24168:     /*
24169:     * If the value was not computed (for string or
24170:     * anySimpleType based types), then use the provided
24171:     * type.
24172:     */
24173:     if (val == NULL)
24174: 	valType = valType;
24175:     else
24176: 	valType = xmlSchemaGetValType(val);
24177: 
24178:     ret = 0;
24179:     for (facetLink = type->facetSet; facetLink != NULL;
24180: 	facetLink = facetLink->next) {
24181: 	/*
24182: 	* Skip the pattern "whiteSpace": it is used to
24183: 	* format the character content beforehand.
24184: 	*/
24185: 	switch (facetLink->facet->type) {
24186: 	    case XML_SCHEMA_FACET_WHITESPACE:
24187: 	    case XML_SCHEMA_FACET_PATTERN:
24188: 	    case XML_SCHEMA_FACET_ENUMERATION:
24189: 		continue;
24190: 	    case XML_SCHEMA_FACET_LENGTH:
24191: 	    case XML_SCHEMA_FACET_MINLENGTH:
24192: 	    case XML_SCHEMA_FACET_MAXLENGTH:
24193: 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24194: 		    valType, value, val, &len, ws);
24195: 		break;
24196: 	    default:
24197: 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24198: 		    valType, value, val, ws);
24199: 		break;
24200: 	}
24201: 	if (ret < 0) {
24202: 	    AERROR_INT("xmlSchemaValidateFacets",
24203: 		"validating against a atomic type facet");
24204: 	    return (-1);
24205: 	} else if (ret > 0) {
24206: 	    if (fireErrors)
24207: 		xmlSchemaFacetErr(actxt, ret, node,
24208: 		value, len, type, facetLink->facet, NULL, NULL, NULL);
24209: 	    else
24210: 		return (ret);
24211: 	    if (error == 0)
24212: 		error = ret;
24213: 	}
24214: 	ret = 0;
24215:     }
24216: 
24217: WXS_IS_LIST:
24218:     if (! WXS_IS_LIST(type))
24219: 	goto pattern_and_enum;
24220:     /*
24221:     * "length", "minLength" and "maxLength" of list types.
24222:     */
24223:     ret = 0;
24224:     for (facetLink = type->facetSet; facetLink != NULL;
24225: 	facetLink = facetLink->next) {
24226: 
24227: 	switch (facetLink->facet->type) {
24228: 	    case XML_SCHEMA_FACET_LENGTH:
24229: 	    case XML_SCHEMA_FACET_MINLENGTH:
24230: 	    case XML_SCHEMA_FACET_MAXLENGTH:
24231: 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24232: 		    value, length, NULL);
24233: 		break;
24234: 	    default:
24235: 		continue;
24236: 	}
24237: 	if (ret < 0) {
24238: 	    AERROR_INT("xmlSchemaValidateFacets",
24239: 		"validating against a list type facet");
24240: 	    return (-1);
24241: 	} else if (ret > 0) {
24242: 	    if (fireErrors)
24243: 		xmlSchemaFacetErr(actxt, ret, node,
24244: 		value, length, type, facetLink->facet, NULL, NULL, NULL);
24245: 	    else
24246: 		return (ret);
24247: 	    if (error == 0)
24248: 		error = ret;
24249: 	}
24250: 	ret = 0;
24251:     }
24252: 
24253: pattern_and_enum:
24254:     if (error >= 0) {
24255: 	int found = 0;
24256: 	/*
24257: 	* Process enumerations. Facet values are in the value space
24258: 	* of the defining type's base type. This seems to be a bug in the
24259: 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
24260: 	* Only the first set of enumerations in the ancestor-or-self axis
24261: 	* is used for validation.
24262: 	*/
24263: 	ret = 0;
24264: 	tmpType = type;
24265: 	do {
24266: 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24267: 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24268: 		    continue;
24269: 		found = 1;
24270: 		ret = xmlSchemaAreValuesEqual(facet->val, val);
24271: 		if (ret == 1)
24272: 		    break;
24273: 		else if (ret < 0) {
24274: 		    AERROR_INT("xmlSchemaValidateFacets",
24275: 			"validating against an enumeration facet");
24276: 		    return (-1);
24277: 		}
24278: 	    }
24279: 	    if (ret != 0)
24280: 		break;
24281: 	    /*
24282: 	    * Break on the first set of enumerations. Any additional
24283: 	    *  enumerations which might be existent on the ancestors
24284: 	    *  of the current type are restricted by this set; thus
24285: 	    *  *must* *not* be taken into account.
24286: 	    */
24287: 	    if (found)
24288: 		break;
24289: 	    tmpType = tmpType->baseType;
24290: 	} while ((tmpType != NULL) &&
24291: 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24292: 	if (found && (ret == 0)) {
24293: 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24294: 	    if (fireErrors) {
24295: 		xmlSchemaFacetErr(actxt, ret, node,
24296: 		    value, 0, type, NULL, NULL, NULL, NULL);
24297: 	    } else
24298: 		return (ret);
24299: 	    if (error == 0)
24300: 		error = ret;
24301: 	}
24302:     }
24303: 
24304:     if (error >= 0) {
24305: 	int found;
24306: 	/*
24307: 	* Process patters. Pattern facets are ORed at type level
24308: 	* and ANDed if derived. Walk the base type axis.
24309: 	*/
24310: 	tmpType = type;
24311: 	facet = NULL;
24312: 	do {
24313: 	    found = 0;
24314: 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
24315: 		facetLink = facetLink->next) {
24316: 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24317: 		    continue;
24318: 		found = 1;
24319: 		/*
24320: 		* NOTE that for patterns, @value needs to be the
24321: 		* normalized vaule.
24322: 		*/
24323: 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
24324: 		if (ret == 1)
24325: 		    break;
24326: 		else if (ret < 0) {
24327: 		    AERROR_INT("xmlSchemaValidateFacets",
24328: 			"validating against a pattern facet");
24329: 		    return (-1);
24330: 		} else {
24331: 		    /*
24332: 		    * Save the last non-validating facet.
24333: 		    */
24334: 		    facet = facetLink->facet;
24335: 		}
24336: 	    }
24337: 	    if (found && (ret != 1)) {
24338: 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24339: 		if (fireErrors) {
24340: 		    xmlSchemaFacetErr(actxt, ret, node,
24341: 			value, 0, type, facet, NULL, NULL, NULL);
24342: 		} else
24343: 		    return (ret);
24344: 		if (error == 0)
24345: 		    error = ret;
24346: 		break;
24347: 	    }
24348: 	    tmpType = tmpType->baseType;
24349: 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24350:     }
24351: 
24352:     return (error);
24353: }
24354: 
24355: static xmlChar *
24356: xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24357: 			const xmlChar *value)
24358: {
24359:     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24360: 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
24361: 	    return (xmlSchemaCollapseString(value));
24362: 	case XML_SCHEMA_WHITESPACE_REPLACE:
24363: 	    return (xmlSchemaWhiteSpaceReplace(value));
24364: 	default:
24365: 	    return (NULL);
24366:     }
24367: }
24368: 
24369: static int
24370: xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24371: 		       const xmlChar *value,
24372: 		       xmlSchemaValPtr *val,
24373: 		       int valNeeded)
24374: {
24375:     int ret;
24376:     const xmlChar *nsName;
24377:     xmlChar *local, *prefix = NULL;
24378: 
24379:     ret = xmlValidateQName(value, 1);
24380:     if (ret != 0) {
24381: 	if (ret == -1) {
24382: 	    VERROR_INT("xmlSchemaValidateQName",
24383: 		"calling xmlValidateQName()");
24384: 	    return (-1);
24385: 	}
24386: 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24387:     }
24388:     /*
24389:     * NOTE: xmlSplitQName2 will always return a duplicated
24390:     * strings.
24391:     */
24392:     local = xmlSplitQName2(value, &prefix);
24393:     if (local == NULL)
24394: 	local = xmlStrdup(value);
24395:     /*
24396:     * OPTIMIZE TODO: Use flags for:
24397:     *  - is there any namespace binding?
24398:     *  - is there a default namespace?
24399:     */
24400:     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24401: 
24402:     if (prefix != NULL) {
24403: 	xmlFree(prefix);
24404: 	/*
24405: 	* A namespace must be found if the prefix is
24406: 	* NOT NULL.
24407: 	*/
24408: 	if (nsName == NULL) {
24409: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24410: 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24411: 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24412: 		"The QName value '%s' has no "
24413: 		"corresponding namespace declaration in "
24414: 		"scope", value, NULL);
24415: 	    if (local != NULL)
24416: 		xmlFree(local);
24417: 	    return (ret);
24418: 	}
24419:     }
24420:     if (valNeeded && val) {
24421: 	if (nsName != NULL)
24422: 	    *val = xmlSchemaNewQNameValue(
24423: 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24424: 	else
24425: 	    *val = xmlSchemaNewQNameValue(NULL,
24426: 		BAD_CAST local);
24427:     } else
24428: 	xmlFree(local);
24429:     return (0);
24430: }
24431: 
24432: /*
24433: * cvc-simple-type
24434: */
24435: static int
24436: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24437: 			     xmlNodePtr node,
24438: 			     xmlSchemaTypePtr type,
24439: 			     const xmlChar *value,
24440: 			     xmlSchemaValPtr *retVal,
24441: 			     int fireErrors,
24442: 			     int normalize,
24443: 			     int isNormalized)
24444: {
24445:     int ret = 0, valNeeded = (retVal) ? 1 : 0;
24446:     xmlSchemaValPtr val = NULL;
24447:     /* xmlSchemaWhitespaceValueType ws; */
24448:     xmlChar *normValue = NULL;
24449: 
24450: #define NORMALIZE(atype) \
24451:     if ((! isNormalized) && \
24452:     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24453: 	normValue = xmlSchemaNormalizeValue(atype, value); \
24454: 	if (normValue != NULL) \
24455: 	    value = normValue; \
24456: 	isNormalized = 1; \
24457:     }
24458: 
24459:     if ((retVal != NULL) && (*retVal != NULL)) {
24460: 	xmlSchemaFreeValue(*retVal);
24461: 	*retVal = NULL;
24462:     }
24463:     /*
24464:     * 3.14.4 Simple Type Definition Validation Rules
24465:     * Validation Rule: String Valid
24466:     */
24467:     /*
24468:     * 1 It is schema-valid with respect to that definition as defined
24469:     * by Datatype Valid in [XML Schemas: Datatypes].
24470:     */
24471:     /*
24472:     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24473:     * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
24474:     * the string must be a �declared entity name�.
24475:     */
24476:     /*
24477:     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24478:     * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
24479:     * then every whitespace-delimited substring of the string must be a �declared
24480:     * entity name�.
24481:     */
24482:     /*
24483:     * 2.3 otherwise no further condition applies.
24484:     */
24485:     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24486: 	valNeeded = 1;
24487:     if (value == NULL)
24488: 	value = BAD_CAST "";
24489:     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24490: 	xmlSchemaTypePtr biType; /* The built-in type. */
24491: 	/*
24492: 	* SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
24493: 	* a literal in the �lexical space� of {base type definition}"
24494: 	*/
24495: 	/*
24496: 	* Whitespace-normalize.
24497: 	*/
24498: 	NORMALIZE(type);
24499: 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
24500: 	    /*
24501: 	    * Get the built-in type.
24502: 	    */
24503: 	    biType = type->baseType;
24504: 	    while ((biType != NULL) &&
24505: 		(biType->type != XML_SCHEMA_TYPE_BASIC))
24506: 		biType = biType->baseType;
24507: 
24508: 	    if (biType == NULL) {
24509: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24510: 		    "could not get the built-in type");
24511: 		goto internal_error;
24512: 	    }
24513: 	} else
24514: 	    biType = type;
24515: 	/*
24516: 	* NOTATIONs need to be processed here, since they need
24517: 	* to lookup in the hashtable of NOTATION declarations of the schema.
24518: 	*/
24519: 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24520: 	    switch (biType->builtInType) {
24521: 		case XML_SCHEMAS_NOTATION:
24522: 		    ret = xmlSchemaValidateNotation(
24523: 			(xmlSchemaValidCtxtPtr) actxt,
24524: 			((xmlSchemaValidCtxtPtr) actxt)->schema,
24525: 			NULL, value, &val, valNeeded);
24526: 		    break;
24527: 		case XML_SCHEMAS_QNAME:
24528: 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24529: 			value, &val, valNeeded);
24530: 		    break;
24531: 		default:
24532: 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24533: 		    if (valNeeded)
24534: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24535: 			    value, &val, node);
24536: 		    else
24537: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24538: 			    value, NULL, node);
24539: 		    break;
24540: 	    }
24541: 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24542: 	    switch (biType->builtInType) {
24543: 		case XML_SCHEMAS_NOTATION:
24544: 		    ret = xmlSchemaValidateNotation(NULL,
24545: 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24546: 			value, &val, valNeeded);
24547: 		    break;
24548: 		default:
24549: 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24550: 		    if (valNeeded)
24551: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24552: 			    value, &val, node);
24553: 		    else
24554: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24555: 			    value, NULL, node);
24556: 		    break;
24557: 	    }
24558: 	} else {
24559: 	    /*
24560: 	    * Validation via a public API is not implemented yet.
24561: 	    */
24562: 	    TODO
24563: 	    goto internal_error;
24564: 	}
24565: 	if (ret != 0) {
24566: 	    if (ret < 0) {
24567: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24568: 		    "validating against a built-in type");
24569: 		goto internal_error;
24570: 	    }
24571: 	    if (WXS_IS_LIST(type))
24572: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24573: 	    else
24574: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24575: 	}
24576: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24577: 	    /*
24578: 	    * Check facets.
24579: 	    */
24580: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24581: 		(xmlSchemaValType) biType->builtInType, value, val,
24582: 		0, fireErrors);
24583: 	    if (ret != 0) {
24584: 		if (ret < 0) {
24585: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24586: 			"validating facets of atomic simple type");
24587: 		    goto internal_error;
24588: 		}
24589: 		if (WXS_IS_LIST(type))
24590: 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24591: 		else
24592: 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24593: 	    }
24594: 	}
24595: 	if (fireErrors && (ret > 0))
24596: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24597:     } else if (WXS_IS_LIST(type)) {
24598: 
24599: 	xmlSchemaTypePtr itemType;
24600: 	const xmlChar *cur, *end;
24601: 	xmlChar *tmpValue = NULL;
24602: 	unsigned long len = 0;
24603: 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24604: 	/* 1.2.2 if {variety} is �list� then the string must be a sequence
24605: 	* of white space separated tokens, each of which �match�es a literal
24606: 	* in the �lexical space� of {item type definition}
24607: 	*/
24608: 	/*
24609: 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24610: 	* the list type has an enum or pattern facet.
24611: 	*/
24612: 	NORMALIZE(type);
24613: 	/*
24614: 	* VAL TODO: Optimize validation of empty values.
24615: 	* VAL TODO: We do not have computed values for lists.
24616: 	*/
24617: 	itemType = WXS_LIST_ITEMTYPE(type);
24618: 	cur = value;
24619: 	do {
24620: 	    while (IS_BLANK_CH(*cur))
24621: 		cur++;
24622: 	    end = cur;
24623: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24624: 		end++;
24625: 	    if (end == cur)
24626: 		break;
24627: 	    tmpValue = xmlStrndup(cur, end - cur);
24628: 	    len++;
24629: 
24630: 	    if (valNeeded)
24631: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24632: 		    tmpValue, &curVal, fireErrors, 0, 1);
24633: 	    else
24634: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24635: 		    tmpValue, NULL, fireErrors, 0, 1);
24636: 	    FREE_AND_NULL(tmpValue);
24637: 	    if (curVal != NULL) {
24638: 		/*
24639: 		* Add to list of computed values.
24640: 		*/
24641: 		if (val == NULL)
24642: 		    val = curVal;
24643: 		else
24644: 		    xmlSchemaValueAppend(prevVal, curVal);
24645: 		prevVal = curVal;
24646: 		curVal = NULL;
24647: 	    }
24648: 	    if (ret != 0) {
24649: 		if (ret < 0) {
24650: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24651: 			"validating an item of list simple type");
24652: 		    goto internal_error;
24653: 		}
24654: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24655: 		break;
24656: 	    }
24657: 	    cur = end;
24658: 	} while (*cur != 0);
24659: 	FREE_AND_NULL(tmpValue);
24660: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24661: 	    /*
24662: 	    * Apply facets (pattern, enumeration).
24663: 	    */
24664: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24665: 		XML_SCHEMAS_UNKNOWN, value, val,
24666: 		len, fireErrors);
24667: 	    if (ret != 0) {
24668: 		if (ret < 0) {
24669: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24670: 			"validating facets of list simple type");
24671: 		    goto internal_error;
24672: 		}
24673: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24674: 	    }
24675: 	}
24676: 	if (fireErrors && (ret > 0)) {
24677: 	    /*
24678: 	    * Report the normalized value.
24679: 	    */
24680: 	    normalize = 1;
24681: 	    NORMALIZE(type);
24682: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24683: 	}
24684:     } else if (WXS_IS_UNION(type)) {
24685: 	xmlSchemaTypeLinkPtr memberLink;
24686: 	/*
24687: 	* TODO: For all datatypes �derived� by �union�  whiteSpace does
24688: 	* not apply directly; however, the normalization behavior of �union�
24689: 	* types is controlled by the value of whiteSpace on that one of the
24690: 	* �memberTypes� against which the �union� is successfully validated.
24691: 	*
24692: 	* This means that the value is normalized by the first validating
24693: 	* member type, then the facets of the union type are applied. This
24694: 	* needs changing of the value!
24695: 	*/
24696: 
24697: 	/*
24698: 	* 1.2.3 if {variety} is �union� then the string must �match� a
24699: 	* literal in the �lexical space� of at least one member of
24700: 	* {member type definitions}
24701: 	*/
24702: 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24703: 	if (memberLink == NULL) {
24704: 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24705: 		"union simple type has no member types");
24706: 	    goto internal_error;
24707: 	}
24708: 	/*
24709: 	* Always normalize union type values, since we currently
24710: 	* cannot store the whitespace information with the value
24711: 	* itself; otherwise a later value-comparison would be
24712: 	* not possible.
24713: 	*/
24714: 	while (memberLink != NULL) {
24715: 	    if (valNeeded)
24716: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24717: 		    memberLink->type, value, &val, 0, 1, 0);
24718: 	    else
24719: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24720: 		    memberLink->type, value, NULL, 0, 1, 0);
24721: 	    if (ret <= 0)
24722: 		break;
24723: 	    memberLink = memberLink->next;
24724: 	}
24725: 	if (ret != 0) {
24726: 	    if (ret < 0) {
24727: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24728: 		    "validating members of union simple type");
24729: 		goto internal_error;
24730: 	    }
24731: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24732: 	}
24733: 	/*
24734: 	* Apply facets (pattern, enumeration).
24735: 	*/
24736: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24737: 	    /*
24738: 	    * The normalization behavior of �union� types is controlled by
24739: 	    * the value of whiteSpace on that one of the �memberTypes�
24740: 	    * against which the �union� is successfully validated.
24741: 	    */
24742: 	    NORMALIZE(memberLink->type);
24743: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24744: 		XML_SCHEMAS_UNKNOWN, value, val,
24745: 		0, fireErrors);
24746: 	    if (ret != 0) {
24747: 		if (ret < 0) {
24748: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24749: 			"validating facets of union simple type");
24750: 		    goto internal_error;
24751: 		}
24752: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24753: 	    }
24754: 	}
24755: 	if (fireErrors && (ret > 0))
24756: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24757:     }
24758: 
24759:     if (normValue != NULL)
24760: 	xmlFree(normValue);
24761:     if (ret == 0) {
24762: 	if (retVal != NULL)
24763: 	    *retVal = val;
24764: 	else if (val != NULL)
24765: 	    xmlSchemaFreeValue(val);
24766:     } else if (val != NULL)
24767: 	xmlSchemaFreeValue(val);
24768:     return (ret);
24769: internal_error:
24770:     if (normValue != NULL)
24771: 	xmlFree(normValue);
24772:     if (val != NULL)
24773: 	xmlSchemaFreeValue(val);
24774:     return (-1);
24775: }
24776: 
24777: static int
24778: xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24779: 			   const xmlChar *value,
24780: 			   const xmlChar **nsName,
24781: 			   const xmlChar **localName)
24782: {
24783:     int ret = 0;
24784: 
24785:     if ((nsName == NULL) || (localName == NULL))
24786: 	return (-1);
24787:     *nsName = NULL;
24788:     *localName = NULL;
24789: 
24790:     ret = xmlValidateQName(value, 1);
24791:     if (ret == -1)
24792: 	return (-1);
24793:     if (ret > 0) {
24794: 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24795: 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24796: 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24797: 	return (1);
24798:     }
24799:     {
24800: 	xmlChar *local = NULL;
24801: 	xmlChar *prefix;
24802: 
24803: 	/*
24804: 	* NOTE: xmlSplitQName2 will return a duplicated
24805: 	* string.
24806: 	*/
24807: 	local = xmlSplitQName2(value, &prefix);
24808: 	if (local == NULL)
24809: 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
24810: 	else {
24811: 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
24812: 	    xmlFree(local);
24813: 	}
24814: 
24815: 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24816: 
24817: 	if (prefix != NULL) {
24818: 	    xmlFree(prefix);
24819: 	    /*
24820: 	    * A namespace must be found if the prefix is NOT NULL.
24821: 	    */
24822: 	    if (*nsName == NULL) {
24823: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
24824: 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24825: 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24826: 		    "The QName value '%s' has no "
24827: 		    "corresponding namespace declaration in scope",
24828: 		    value, NULL);
24829: 		return (2);
24830: 	    }
24831: 	}
24832:     }
24833:     return (0);
24834: }
24835: 
24836: static int
24837: xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24838: 			xmlSchemaAttrInfoPtr iattr,
24839: 			xmlSchemaTypePtr *localType,
24840: 			xmlSchemaElementPtr elemDecl)
24841: {
24842:     int ret = 0;
24843:     /*
24844:     * cvc-elt (3.3.4) : (4)
24845:     * AND
24846:     * Schema-Validity Assessment (Element) (cvc-assess-elt)
24847:     *   (1.2.1.2.1) - (1.2.1.2.4)
24848:     * Handle 'xsi:type'.
24849:     */
24850:     if (localType == NULL)
24851: 	return (-1);
24852:     *localType = NULL;
24853:     if (iattr == NULL)
24854: 	return (0);
24855:     else {
24856: 	const xmlChar *nsName = NULL, *local = NULL;
24857: 	/*
24858: 	* TODO: We should report a *warning* that the type was overriden
24859: 	* by the instance.
24860: 	*/
24861: 	ACTIVATE_ATTRIBUTE(iattr);
24862: 	/*
24863: 	* (cvc-elt) (3.3.4) : (4.1)
24864: 	* (cvc-assess-elt) (1.2.1.2.2)
24865: 	*/
24866: 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24867: 	    &nsName, &local);
24868: 	if (ret != 0) {
24869: 	    if (ret < 0) {
24870: 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
24871: 		    "calling xmlSchemaQNameExpand() to validate the "
24872: 		    "attribute 'xsi:type'");
24873: 		goto internal_error;
24874: 	    }
24875: 	    goto exit;
24876: 	}
24877: 	/*
24878: 	* (cvc-elt) (3.3.4) : (4.2)
24879: 	* (cvc-assess-elt) (1.2.1.2.3)
24880: 	*/
24881: 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24882: 	if (*localType == NULL) {
24883: 	    xmlChar *str = NULL;
24884: 
24885: 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24886: 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
24887: 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24888: 		"The QName value '%s' of the xsi:type attribute does not "
24889: 		"resolve to a type definition",
24890: 		xmlSchemaFormatQName(&str, nsName, local), NULL);
24891: 	    FREE_AND_NULL(str);
24892: 	    ret = vctxt->err;
24893: 	    goto exit;
24894: 	}
24895: 	if (elemDecl != NULL) {
24896: 	    int set = 0;
24897: 
24898: 	    /*
24899: 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24900: 	    * "The �local type definition� must be validly
24901: 	    * derived from the {type definition} given the union of
24902: 	    * the {disallowed substitutions} and the {type definition}'s
24903: 	    * {prohibited substitutions}, as defined in
24904: 	    * Type Derivation OK (Complex) (�3.4.6)
24905: 	    * (if it is a complex type definition),
24906: 	    * or given {disallowed substitutions} as defined in Type
24907: 	    * Derivation OK (Simple) (�3.14.6) (if it is a simple type
24908: 	    * definition)."
24909: 	    *
24910: 	    * {disallowed substitutions}: the "block" on the element decl.
24911: 	    * {prohibited substitutions}: the "block" on the type def.
24912: 	    */
24913: 	    /*
24914: 	    * OPTIMIZE TODO: We could map types already evaluated
24915: 	    * to be validly derived from other types to avoid checking
24916: 	    * this over and over for the same types.
24917: 	    */
24918: 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24919: 		(elemDecl->subtypes->flags &
24920: 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24921: 		set |= SUBSET_EXTENSION;
24922: 
24923: 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24924: 		(elemDecl->subtypes->flags &
24925: 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24926: 		set |= SUBSET_RESTRICTION;
24927: 
24928: 	    /*
24929: 	    * REMOVED and CHANGED since this produced a parser context
24930: 	    * which adds to the string dict of the schema. So this would
24931: 	    * change the schema and we don't want this. We don't need
24932: 	    * the parser context anymore.
24933: 	    *
24934: 	    * if ((vctxt->pctxt == NULL) &&
24935: 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24936: 	    *	    return (-1);
24937: 	    */
24938: 
24939: 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24940: 		elemDecl->subtypes, set) != 0) {
24941: 		xmlChar *str = NULL;
24942: 
24943: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
24944: 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24945: 		    "The type definition '%s', specified by xsi:type, is "
24946: 		    "blocked or not validly derived from the type definition "
24947: 		    "of the element declaration",
24948: 		    xmlSchemaFormatQName(&str,
24949: 			(*localType)->targetNamespace,
24950: 			(*localType)->name),
24951: 		    NULL);
24952: 		FREE_AND_NULL(str);
24953: 		ret = vctxt->err;
24954: 		*localType = NULL;
24955: 	    }
24956: 	}
24957:     }
24958: exit:
24959:     ACTIVATE_ELEM;
24960:     return (ret);
24961: internal_error:
24962:     ACTIVATE_ELEM;
24963:     return (-1);
24964: }
24965: 
24966: static int
24967: xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24968: {
24969:     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24970:     xmlSchemaTypePtr actualType;
24971: 
24972:     /*
24973:     * cvc-elt (3.3.4) : 1
24974:     */
24975:     if (elemDecl == NULL) {
24976: 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24977: 	    "No matching declaration available");
24978:         return (vctxt->err);
24979:     }
24980:     actualType = WXS_ELEM_TYPEDEF(elemDecl);
24981:     /*
24982:     * cvc-elt (3.3.4) : 2
24983:     */
24984:     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24985: 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24986: 	    "The element declaration is abstract");
24987:         return (vctxt->err);
24988:     }
24989:     if (actualType == NULL) {
24990:     	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24991:     	    "The type definition is absent");
24992:     	return (XML_SCHEMAV_CVC_TYPE_1);
24993:     }
24994:     if (vctxt->nbAttrInfos != 0) {
24995: 	int ret;
24996: 	xmlSchemaAttrInfoPtr iattr;
24997: 	/*
24998: 	* cvc-elt (3.3.4) : 3
24999: 	* Handle 'xsi:nil'.
25000: 	*/
25001: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25002: 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25003: 	if (iattr) {
25004: 	    ACTIVATE_ATTRIBUTE(iattr);
25005: 	    /*
25006: 	    * Validate the value.
25007: 	    */
25008: 	    ret = xmlSchemaVCheckCVCSimpleType(
25009: 		ACTXT_CAST vctxt, NULL,
25010: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25011: 		iattr->value, &(iattr->val), 1, 0, 0);
25012: 	    ACTIVATE_ELEM;
25013: 	    if (ret < 0) {
25014: 		VERROR_INT("xmlSchemaValidateElemDecl",
25015: 		    "calling xmlSchemaVCheckCVCSimpleType() to "
25016: 		    "validate the attribute 'xsi:nil'");
25017: 		return (-1);
25018: 	    }
25019: 	    if (ret == 0) {
25020: 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25021: 		    /*
25022: 		    * cvc-elt (3.3.4) : 3.1
25023: 		    */
25024: 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25025: 			"The element is not 'nillable'");
25026: 		    /* Does not return an error on purpose. */
25027: 		} else {
25028: 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25029: 			/*
25030: 			* cvc-elt (3.3.4) : 3.2.2
25031: 			*/
25032: 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25033: 			    (elemDecl->value != NULL)) {
25034: 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25035: 				"The element cannot be 'nilled' because "
25036: 				"there is a fixed value constraint defined "
25037: 				"for it");
25038: 			     /* Does not return an error on purpose. */
25039: 			} else
25040: 			    vctxt->inode->flags |=
25041: 				XML_SCHEMA_ELEM_INFO_NILLED;
25042: 		    }
25043: 		}
25044: 	    }
25045: 	}
25046: 	/*
25047: 	* cvc-elt (3.3.4) : 4
25048: 	* Handle 'xsi:type'.
25049: 	*/
25050: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25051: 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25052: 	if (iattr) {
25053: 	    xmlSchemaTypePtr localType = NULL;
25054: 
25055: 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25056: 		elemDecl);
25057: 	    if (ret != 0) {
25058: 		if (ret == -1) {
25059: 		    VERROR_INT("xmlSchemaValidateElemDecl",
25060: 			"calling xmlSchemaProcessXSIType() to "
25061: 			"process the attribute 'xsi:type'");
25062: 		    return (-1);
25063: 		}
25064: 		/* Does not return an error on purpose. */
25065: 	    }
25066: 	    if (localType != NULL) {
25067: 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25068: 		actualType = localType;
25069: 	    }
25070: 	}
25071:     }
25072:     /*
25073:     * IDC: Register identity-constraint XPath matchers.
25074:     */
25075:     if ((elemDecl->idcs != NULL) &&
25076: 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25077: 	    return (-1);
25078:     /*
25079:     * No actual type definition.
25080:     */
25081:     if (actualType == NULL) {
25082:     	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25083:     	    "The type definition is absent");
25084:     	return (XML_SCHEMAV_CVC_TYPE_1);
25085:     }
25086:     /*
25087:     * Remember the actual type definition.
25088:     */
25089:     vctxt->inode->typeDef = actualType;
25090: 
25091:     return (0);
25092: }
25093: 
25094: static int
25095: xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25096: {
25097:     xmlSchemaAttrInfoPtr iattr;
25098:     int ret = 0, i;
25099: 
25100:     /*
25101:     * SPEC cvc-type (3.1.1)
25102:     * "The attributes of must be empty, excepting those whose namespace
25103:     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25104:     * whose local name is one of type, nil, schemaLocation or
25105:     * noNamespaceSchemaLocation."
25106:     */
25107:     if (vctxt->nbAttrInfos == 0)
25108: 	return (0);
25109:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25110: 	iattr = vctxt->attrInfos[i];
25111: 	if (! iattr->metaType) {
25112: 	    ACTIVATE_ATTRIBUTE(iattr)
25113: 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25114: 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25115: 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25116:         }
25117:     }
25118:     ACTIVATE_ELEM
25119:     return (ret);
25120: }
25121: 
25122: /*
25123: * Cleanup currently used attribute infos.
25124: */
25125: static void
25126: xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25127: {
25128:     int i;
25129:     xmlSchemaAttrInfoPtr attr;
25130: 
25131:     if (vctxt->nbAttrInfos == 0)
25132: 	return;
25133:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25134: 	attr = vctxt->attrInfos[i];
25135: 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25136: 	    if (attr->localName != NULL)
25137: 		xmlFree((xmlChar *) attr->localName);
25138: 	    if (attr->nsName != NULL)
25139: 		xmlFree((xmlChar *) attr->nsName);
25140: 	}
25141: 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25142: 	    if (attr->value != NULL)
25143: 		xmlFree((xmlChar *) attr->value);
25144: 	}
25145: 	if (attr->val != NULL) {
25146: 	    xmlSchemaFreeValue(attr->val);
25147: 	    attr->val = NULL;
25148: 	}
25149: 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25150:     }
25151:     vctxt->nbAttrInfos = 0;
25152: }
25153: 
25154: /*
25155: * 3.4.4 Complex Type Definition Validation Rules
25156: *   Element Locally Valid (Complex Type) (cvc-complex-type)
25157: * 3.2.4 Attribute Declaration Validation Rules
25158: *   Validation Rule: Attribute Locally Valid (cvc-attribute)
25159: *   Attribute Locally Valid (Use) (cvc-au)
25160: *
25161: * Only "assessed" attribute information items will be visible to
25162: * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25163: */
25164: static int
25165: xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25166: {
25167:     xmlSchemaTypePtr type = vctxt->inode->typeDef;
25168:     xmlSchemaItemListPtr attrUseList;
25169:     xmlSchemaAttributeUsePtr attrUse = NULL;
25170:     xmlSchemaAttributePtr attrDecl = NULL;
25171:     xmlSchemaAttrInfoPtr iattr, tmpiattr;
25172:     int i, j, found, nbAttrs, nbUses;
25173:     int xpathRes = 0, res, wildIDs = 0, fixed;
25174:     xmlNodePtr defAttrOwnerElem = NULL;
25175: 
25176:     /*
25177:     * SPEC (cvc-attribute)
25178:     * (1) "The declaration must not be �absent� (see Missing
25179:     * Sub-components (�5.3) for how this can fail to be
25180:     * the case)."
25181:     * (2) "Its {type definition} must not be absent."
25182:     *
25183:     * NOTE (1) + (2): This is not handled here, since we currently do not
25184:     * allow validation against schemas which have missing sub-components.
25185:     *
25186:     * SPEC (cvc-complex-type)
25187:     * (3) "For each attribute information item in the element information
25188:     * item's [attributes] excepting those whose [namespace name] is
25189:     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25190:     * [local name] is one of type, nil, schemaLocation or
25191:     * noNamespaceSchemaLocation, the appropriate case among the following
25192:     * must be true:
25193:     *
25194:     */
25195:     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25196:     /*
25197:     * @nbAttrs is the number of attributes present in the instance.
25198:     */
25199:     nbAttrs = vctxt->nbAttrInfos;
25200:     if (attrUseList != NULL)
25201: 	nbUses = attrUseList->nbItems;
25202:     else
25203: 	nbUses = 0;
25204:     for (i = 0; i < nbUses; i++) {
25205:         found = 0;
25206: 	attrUse = attrUseList->items[i];
25207: 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
25208:         for (j = 0; j < nbAttrs; j++) {
25209: 	    iattr = vctxt->attrInfos[j];
25210: 	    /*
25211: 	    * SPEC (cvc-complex-type) (3)
25212: 	    * Skip meta attributes.
25213: 	    */
25214: 	    if (iattr->metaType)
25215: 		continue;
25216: 	    if (iattr->localName[0] != attrDecl->name[0])
25217: 		continue;
25218: 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
25219: 		continue;
25220: 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25221: 		continue;
25222: 	    found = 1;
25223: 	    /*
25224: 	    * SPEC (cvc-complex-type)
25225: 	    * (3.1) "If there is among the {attribute uses} an attribute
25226: 	    * use with an {attribute declaration} whose {name} matches
25227: 	    * the attribute information item's [local name] and whose
25228: 	    * {target namespace} is identical to the attribute information
25229: 	    * item's [namespace name] (where an �absent� {target namespace}
25230: 	    * is taken to be identical to a [namespace name] with no value),
25231: 	    * then the attribute information must be �valid� with respect
25232: 	    * to that attribute use as per Attribute Locally Valid (Use)
25233: 	    * (�3.5.4). In this case the {attribute declaration} of that
25234: 	    * attribute use is the �context-determined declaration� for the
25235: 	    * attribute information item with respect to Schema-Validity
25236: 	    * Assessment (Attribute) (�3.2.4) and
25237: 	    * Assessment Outcome (Attribute) (�3.2.5).
25238: 	    */
25239: 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25240: 	    iattr->use = attrUse;
25241: 	    /*
25242: 	    * Context-determined declaration.
25243: 	    */
25244: 	    iattr->decl = attrDecl;
25245: 	    iattr->typeDef = attrDecl->subtypes;
25246: 	    break;
25247: 	}
25248: 
25249: 	if (found)
25250: 	    continue;
25251: 
25252: 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25253: 	    /*
25254: 	    * Handle non-existent, required attributes.
25255: 	    *
25256: 	    * SPEC (cvc-complex-type)
25257: 	    * (4) "The {attribute declaration} of each attribute use in
25258: 	    * the {attribute uses} whose {required} is true matches one
25259: 	    * of the attribute information items in the element information
25260: 	    * item's [attributes] as per clause 3.1 above."
25261: 	    */
25262: 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25263: 	    if (tmpiattr == NULL) {
25264: 		VERROR_INT(
25265: 		    "xmlSchemaVAttributesComplex",
25266: 		    "calling xmlSchemaGetFreshAttrInfo()");
25267: 		return (-1);
25268: 	    }
25269: 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25270: 	    tmpiattr->use = attrUse;
25271: 	    tmpiattr->decl = attrDecl;
25272: 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25273: 	    ((attrUse->defValue != NULL) ||
25274: 	     (attrDecl->defValue != NULL))) {
25275: 	    /*
25276: 	    * Handle non-existent, optional, default/fixed attributes.
25277: 	    */
25278: 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25279: 	    if (tmpiattr == NULL) {
25280: 		VERROR_INT(
25281: 		    "xmlSchemaVAttributesComplex",
25282: 		    "calling xmlSchemaGetFreshAttrInfo()");
25283: 		return (-1);
25284: 	    }
25285: 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25286: 	    tmpiattr->use = attrUse;
25287: 	    tmpiattr->decl = attrDecl;
25288: 	    tmpiattr->typeDef = attrDecl->subtypes;
25289: 	    tmpiattr->localName = attrDecl->name;
25290: 	    tmpiattr->nsName = attrDecl->targetNamespace;
25291: 	}
25292:     }
25293: 
25294:     if (vctxt->nbAttrInfos == 0)
25295: 	return (0);
25296:     /*
25297:     * Validate against the wildcard.
25298:     */
25299:     if (type->attributeWildcard != NULL) {
25300: 	/*
25301: 	* SPEC (cvc-complex-type)
25302: 	* (3.2.1) "There must be an {attribute wildcard}."
25303: 	*/
25304: 	for (i = 0; i < nbAttrs; i++) {
25305: 	    iattr = vctxt->attrInfos[i];
25306: 	    /*
25307: 	    * SPEC (cvc-complex-type) (3)
25308: 	    * Skip meta attributes.
25309: 	    */
25310: 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25311: 		continue;
25312: 	    /*
25313: 	    * SPEC (cvc-complex-type)
25314: 	    * (3.2.2) "The attribute information item must be �valid� with
25315: 	    * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
25316: 	    *
25317: 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
25318: 	    * "... its [namespace name] must be �valid� with respect to
25319: 	    * the wildcard constraint, as defined in Wildcard allows
25320: 	    * Namespace Name (�3.10.4)."
25321: 	    */
25322: 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25323: 		    iattr->nsName) == 0) {
25324: 		/*
25325: 		* Handle processContents.
25326: 		*
25327: 		* SPEC (cvc-wildcard):
25328: 		* processContents | context-determined declaration:
25329: 		* "strict"          "mustFind"
25330: 		* "lax"             "none"
25331: 		* "skip"            "skip"
25332: 		*/
25333: 		if (type->attributeWildcard->processContents ==
25334: 		    XML_SCHEMAS_ANY_SKIP) {
25335: 		     /*
25336: 		    * context-determined declaration = "skip"
25337: 		    *
25338: 		    * SPEC PSVI Assessment Outcome (Attribute)
25339: 		    * [validity] = "notKnown"
25340: 		    * [validation attempted] = "none"
25341: 		    */
25342: 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25343: 		    continue;
25344: 		}
25345: 		/*
25346: 		* Find an attribute declaration.
25347: 		*/
25348: 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25349: 		    iattr->localName, iattr->nsName);
25350: 		if (iattr->decl != NULL) {
25351: 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25352: 		    /*
25353: 		    * SPEC (cvc-complex-type)
25354: 		    * (5) "Let [Definition:]  the wild IDs be the set of
25355: 		    * all attribute information item to which clause 3.2
25356: 		    * applied and whose �validation� resulted in a
25357: 		    * �context-determined declaration� of mustFind or no
25358: 		    * �context-determined declaration� at all, and whose
25359: 		    * [local name] and [namespace name] resolve (as
25360: 		    * defined by QName resolution (Instance) (�3.15.4)) to
25361: 		    * an attribute declaration whose {type definition} is
25362: 		    * or is derived from ID. Then all of the following
25363: 		    * must be true:"
25364: 		    */
25365: 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25366: 		    if (xmlSchemaIsDerivedFromBuiltInType(
25367: 			iattr->typeDef, XML_SCHEMAS_ID)) {
25368: 			/*
25369: 			* SPEC (5.1) "There must be no more than one
25370: 			* item in �wild IDs�."
25371: 			*/
25372: 			if (wildIDs != 0) {
25373: 			    /* VAL TODO */
25374: 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25375: 			    TODO
25376: 			    continue;
25377: 			}
25378: 			wildIDs++;
25379: 			/*
25380: 			* SPEC (cvc-complex-type)
25381: 			* (5.2) "If �wild IDs� is non-empty, there must not
25382: 			* be any attribute uses among the {attribute uses}
25383: 			* whose {attribute declaration}'s {type definition}
25384: 			* is or is derived from ID."
25385: 			*/
25386:                         if (attrUseList != NULL) {
25387:                             for (j = 0; j < attrUseList->nbItems; j++) {
25388:                                 if (xmlSchemaIsDerivedFromBuiltInType(
25389:                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25390:                                     XML_SCHEMAS_ID)) {
25391:                                     /* URGENT VAL TODO: implement */
25392:                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25393:                                     TODO
25394:                                     break;
25395:                                 }
25396:                             }
25397:                         }
25398: 		    }
25399: 		} else if (type->attributeWildcard->processContents ==
25400: 		    XML_SCHEMAS_ANY_LAX) {
25401: 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25402: 		    /*
25403: 		    * SPEC PSVI Assessment Outcome (Attribute)
25404: 		    * [validity] = "notKnown"
25405: 		    * [validation attempted] = "none"
25406: 		    */
25407: 		} else {
25408: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25409: 		}
25410: 	    }
25411: 	}
25412:     }
25413: 
25414:     if (vctxt->nbAttrInfos == 0)
25415: 	return (0);
25416: 
25417:     /*
25418:     * Get the owner element; needed for creation of default attributes.
25419:     * This fixes bug #341337, reported by David Grohmann.
25420:     */
25421:     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25422: 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25423: 	if (ielem && ielem->node && ielem->node->doc)
25424: 	    defAttrOwnerElem = ielem->node;
25425:     }
25426:     /*
25427:     * Validate values, create default attributes, evaluate IDCs.
25428:     */
25429:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25430: 	iattr = vctxt->attrInfos[i];
25431: 	/*
25432: 	* VAL TODO: Note that we won't try to resolve IDCs to
25433: 	* "lax" and "skip" validated attributes. Check what to
25434: 	* do in this case.
25435: 	*/
25436: 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25437: 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25438: 	    continue;
25439: 	/*
25440: 	* VAL TODO: What to do if the type definition is missing?
25441: 	*/
25442: 	if (iattr->typeDef == NULL) {
25443: 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25444: 	    continue;
25445: 	}
25446: 
25447: 	ACTIVATE_ATTRIBUTE(iattr);
25448: 	fixed = 0;
25449: 	xpathRes = 0;
25450: 
25451: 	if (vctxt->xpathStates != NULL) {
25452: 	    /*
25453: 	    * Evaluate IDCs.
25454: 	    */
25455: 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
25456: 		XML_ATTRIBUTE_NODE);
25457: 	    if (xpathRes == -1) {
25458: 		VERROR_INT("xmlSchemaVAttributesComplex",
25459: 		    "calling xmlSchemaXPathEvaluate()");
25460: 		goto internal_error;
25461: 	    }
25462: 	}
25463: 
25464: 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25465: 	    /*
25466: 	    * Default/fixed attributes.
25467: 	    * We need the value only if we need to resolve IDCs or
25468: 	    * will create default attributes.
25469: 	    */
25470: 	    if ((xpathRes) || (defAttrOwnerElem)) {
25471: 		if (iattr->use->defValue != NULL) {
25472: 		    iattr->value = (xmlChar *) iattr->use->defValue;
25473: 		    iattr->val = iattr->use->defVal;
25474: 		} else {
25475: 		    iattr->value = (xmlChar *) iattr->decl->defValue;
25476: 		    iattr->val = iattr->decl->defVal;
25477: 		}
25478: 		/*
25479: 		* IDCs will consume the precomputed default value,
25480: 		* so we need to clone it.
25481: 		*/
25482: 		if (iattr->val == NULL) {
25483: 		    VERROR_INT("xmlSchemaVAttributesComplex",
25484: 			"default/fixed value on an attribute use was "
25485: 			"not precomputed");
25486: 		    goto internal_error;
25487: 		}
25488: 		iattr->val = xmlSchemaCopyValue(iattr->val);
25489: 		if (iattr->val == NULL) {
25490: 		    VERROR_INT("xmlSchemaVAttributesComplex",
25491: 			"calling xmlSchemaCopyValue()");
25492: 		    goto internal_error;
25493: 		}
25494: 	    }
25495: 	    /*
25496: 	    * PSVI: Add the default attribute to the current element.
25497: 	    * VAL TODO: Should we use the *normalized* value? This currently
25498: 	    *   uses the *initial* value.
25499: 	    */
25500: 
25501: 	    if (defAttrOwnerElem) {
25502: 		xmlChar *normValue;
25503: 		const xmlChar *value;
25504: 
25505: 		value = iattr->value;
25506: 		/*
25507: 		* Normalize the value.
25508: 		*/
25509: 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25510: 		    iattr->value);
25511: 		if (normValue != NULL)
25512: 		    value = BAD_CAST normValue;
25513: 
25514: 		if (iattr->nsName == NULL) {
25515: 		    if (xmlNewProp(defAttrOwnerElem,
25516: 			iattr->localName, value) == NULL) {
25517: 			VERROR_INT("xmlSchemaVAttributesComplex",
25518: 			    "callling xmlNewProp()");
25519: 			if (normValue != NULL)
25520: 			    xmlFree(normValue);
25521: 			goto internal_error;
25522: 		    }
25523: 		} else {
25524: 		    xmlNsPtr ns;
25525: 
25526: 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25527: 			defAttrOwnerElem, iattr->nsName);
25528: 		    if (ns == NULL) {
25529: 			xmlChar prefix[12];
25530: 			int counter = 0;
25531: 
25532: 			/*
25533: 			* Create a namespace declaration on the validation
25534: 			* root node if no namespace declaration is in scope.
25535: 			*/
25536: 			do {
25537: 			    snprintf((char *) prefix, 12, "p%d", counter++);
25538: 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
25539: 				defAttrOwnerElem, BAD_CAST prefix);
25540: 			    if (counter > 1000) {
25541: 				VERROR_INT(
25542: 				    "xmlSchemaVAttributesComplex",
25543: 				    "could not compute a ns prefix for a "
25544: 				    "default/fixed attribute");
25545: 				if (normValue != NULL)
25546: 				    xmlFree(normValue);
25547: 				goto internal_error;
25548: 			    }
25549: 			} while (ns != NULL);
25550: 			ns = xmlNewNs(vctxt->validationRoot,
25551: 			    iattr->nsName, BAD_CAST prefix);
25552: 		    }
25553: 		    /*
25554: 		    * TODO:
25555: 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25556: 		    * If we have QNames: do we need to ensure there's a
25557: 		    * prefix defined for the QName?
25558: 		    */
25559: 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25560: 		}
25561: 		if (normValue != NULL)
25562: 		    xmlFree(normValue);
25563: 	    }
25564: 	    /*
25565: 	    * Go directly to IDC evaluation.
25566: 	    */
25567: 	    goto eval_idcs;
25568: 	}
25569: 	/*
25570: 	* Validate the value.
25571: 	*/
25572: 	if (vctxt->value != NULL) {
25573: 	    /*
25574: 	    * Free last computed value; just for safety reasons.
25575: 	    */
25576: 	    xmlSchemaFreeValue(vctxt->value);
25577: 	    vctxt->value = NULL;
25578: 	}
25579: 	/*
25580: 	* Note that the attribute *use* can be unavailable, if
25581: 	* the attribute was a wild attribute.
25582: 	*/
25583: 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25584: 	    ((iattr->use != NULL) &&
25585: 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25586: 	    fixed = 1;
25587: 	else
25588: 	    fixed = 0;
25589: 	/*
25590: 	* SPEC (cvc-attribute)
25591: 	* (3) "The item's �normalized value� must be locally �valid�
25592: 	* with respect to that {type definition} as per
25593: 	* String Valid (�3.14.4)."
25594: 	*
25595: 	* VAL TODO: Do we already have the
25596: 	* "normalized attribute value" here?
25597: 	*/
25598: 	if (xpathRes || fixed) {
25599: 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25600: 	    /*
25601: 	    * Request a computed value.
25602: 	    */
25603: 	    res = xmlSchemaVCheckCVCSimpleType(
25604: 		ACTXT_CAST vctxt,
25605: 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25606: 		1, 1, 0);
25607: 	} else {
25608: 	    res = xmlSchemaVCheckCVCSimpleType(
25609: 		ACTXT_CAST vctxt,
25610: 		iattr->node, iattr->typeDef, iattr->value, NULL,
25611: 		1, 0, 0);
25612: 	}
25613: 
25614: 	if (res != 0) {
25615: 	    if (res == -1) {
25616: 		VERROR_INT("xmlSchemaVAttributesComplex",
25617: 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
25618: 		goto internal_error;
25619: 	    }
25620: 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25621: 	    /*
25622: 	    * SPEC PSVI Assessment Outcome (Attribute)
25623: 	    * [validity] = "invalid"
25624: 	    */
25625: 	    goto eval_idcs;
25626: 	}
25627: 
25628: 	if (fixed) {
25629: 	    /*
25630: 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
25631: 	    * "For an attribute information item to be�valid�
25632: 	    * with respect to an attribute use its *normalized*
25633: 	    * value� must match the *canonical* lexical
25634: 	    * representation of the attribute use's {value
25635: 	    * constraint}value, if it is present and fixed."
25636: 	    *
25637: 	    * VAL TODO: The requirement for the *canonical* value
25638: 	    * will be removed in XML Schema 1.1.
25639: 	    */
25640: 	    /*
25641: 	    * SPEC Attribute Locally Valid (cvc-attribute)
25642: 	    * (4) "The item's *actual* value� must match the *value* of
25643: 	    * the {value constraint}, if it is present and fixed."
25644: 	    */
25645: 	    if (iattr->val == NULL) {
25646: 		/* VAL TODO: A value was not precomputed. */
25647: 		TODO
25648: 		goto eval_idcs;
25649: 	    }
25650: 	    if ((iattr->use != NULL) &&
25651: 		(iattr->use->defValue != NULL)) {
25652: 		if (iattr->use->defVal == NULL) {
25653: 		    /* VAL TODO: A default value was not precomputed. */
25654: 		    TODO
25655: 		    goto eval_idcs;
25656: 		}
25657: 		iattr->vcValue = iattr->use->defValue;
25658: 		/*
25659: 		if (xmlSchemaCompareValuesWhtsp(attr->val,
25660: 		    (xmlSchemaWhitespaceValueType) ws,
25661: 		    attr->use->defVal,
25662: 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
25663: 		*/
25664: 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25665: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25666: 	    } else {
25667: 		if (iattr->decl->defVal == NULL) {
25668: 		    /* VAL TODO: A default value was not precomputed. */
25669: 		    TODO
25670: 		    goto eval_idcs;
25671: 		}
25672: 		iattr->vcValue = iattr->decl->defValue;
25673: 		/*
25674: 		if (xmlSchemaCompareValuesWhtsp(attr->val,
25675: 		    (xmlSchemaWhitespaceValueType) ws,
25676: 		    attrDecl->defVal,
25677: 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
25678: 		*/
25679: 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25680: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25681: 	    }
25682: 	    /*
25683: 	    * [validity] = "valid"
25684: 	    */
25685: 	}
25686: eval_idcs:
25687: 	/*
25688: 	* Evaluate IDCs.
25689: 	*/
25690: 	if (xpathRes) {
25691: 	    if (xmlSchemaXPathProcessHistory(vctxt,
25692: 		vctxt->depth +1) == -1) {
25693: 		VERROR_INT("xmlSchemaVAttributesComplex",
25694: 		    "calling xmlSchemaXPathEvaluate()");
25695: 		goto internal_error;
25696: 	    }
25697: 	} else if (vctxt->xpathStates != NULL)
25698: 	    xmlSchemaXPathPop(vctxt);
25699:     }
25700: 
25701:     /*
25702:     * Report errors.
25703:     */
25704:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25705: 	iattr = vctxt->attrInfos[i];
25706: 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25707: 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25708: 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25709: 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25710: 	    continue;
25711: 	ACTIVATE_ATTRIBUTE(iattr);
25712: 	switch (iattr->state) {
25713: 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
25714: 		    xmlChar *str = NULL;
25715: 		    ACTIVATE_ELEM;
25716: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25717: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25718: 			"The attribute '%s' is required but missing",
25719: 			xmlSchemaFormatQName(&str,
25720: 			    iattr->decl->targetNamespace,
25721: 			    iattr->decl->name),
25722: 			NULL);
25723: 		    FREE_AND_NULL(str)
25724: 		    break;
25725: 		}
25726: 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25727: 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25728: 		    "The type definition is absent");
25729: 		break;
25730: 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25731: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
25732: 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
25733: 		    "The value '%s' does not match the fixed "
25734: 		    "value constraint '%s'",
25735: 		    iattr->value, iattr->vcValue);
25736: 		break;
25737: 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25738: 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25739: 		    "No matching global attribute declaration available, but "
25740: 		    "demanded by the strict wildcard");
25741: 		break;
25742: 	    case XML_SCHEMAS_ATTR_UNKNOWN:
25743: 		if (iattr->metaType)
25744: 		    break;
25745: 		/*
25746: 		* MAYBE VAL TODO: One might report different error messages
25747: 		* for the following errors.
25748: 		*/
25749: 		if (type->attributeWildcard == NULL) {
25750: 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25751: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25752: 		} else {
25753: 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25754: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25755: 		}
25756: 		break;
25757: 	    default:
25758: 		break;
25759: 	}
25760:     }
25761: 
25762:     ACTIVATE_ELEM;
25763:     return (0);
25764: internal_error:
25765:     ACTIVATE_ELEM;
25766:     return (-1);
25767: }
25768: 
25769: static int
25770: xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25771: 			      int *skip)
25772: {
25773:     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25774:     /*
25775:     * The namespace of the element was already identified to be
25776:     * matching the wildcard.
25777:     */
25778:     if ((skip == NULL) || (wild == NULL) ||
25779: 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
25780: 	VERROR_INT("xmlSchemaValidateElemWildcard",
25781: 	    "bad arguments");
25782: 	return (-1);
25783:     }
25784:     *skip = 0;
25785:     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25786: 	/*
25787: 	* URGENT VAL TODO: Either we need to position the stream to the
25788: 	* next sibling, or walk the whole subtree.
25789: 	*/
25790: 	*skip = 1;
25791: 	return (0);
25792:     }
25793:     {
25794: 	xmlSchemaElementPtr decl = NULL;
25795: 
25796: 	decl = xmlSchemaGetElem(vctxt->schema,
25797: 	    vctxt->inode->localName, vctxt->inode->nsName);
25798: 	if (decl != NULL) {
25799: 	    vctxt->inode->decl = decl;
25800: 	    return (0);
25801: 	}
25802:     }
25803:     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25804: 	/* VAL TODO: Change to proper error code. */
25805: 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25806: 	    "No matching global element declaration available, but "
25807: 	    "demanded by the strict wildcard");
25808: 	return (vctxt->err);
25809:     }
25810:     if (vctxt->nbAttrInfos != 0) {
25811: 	xmlSchemaAttrInfoPtr iattr;
25812: 	/*
25813: 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
25814: 	* (1.2.1.2.1) - (1.2.1.2.3 )
25815: 	*
25816: 	* Use the xsi:type attribute for the type definition.
25817: 	*/
25818: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25819: 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25820: 	if (iattr != NULL) {
25821: 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
25822: 		&(vctxt->inode->typeDef), NULL) == -1) {
25823: 		VERROR_INT("xmlSchemaValidateElemWildcard",
25824: 		    "calling xmlSchemaProcessXSIType() to "
25825: 		    "process the attribute 'xsi:nil'");
25826: 		return (-1);
25827: 	    }
25828: 	    /*
25829: 	    * Don't return an error on purpose.
25830: 	    */
25831: 	    return (0);
25832: 	}
25833:     }
25834:     /*
25835:     * SPEC Validation Rule: Schema-Validity Assessment (Element)
25836:     *
25837:     * Fallback to "anyType".
25838:     */
25839:     vctxt->inode->typeDef =
25840: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25841:     return (0);
25842: }
25843: 
25844: /*
25845: * xmlSchemaCheckCOSValidDefault:
25846: *
25847: * This will be called if: not nilled, no content and a default/fixed
25848: * value is provided.
25849: */
25850: 
25851: static int
25852: xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25853: 			      const xmlChar *value,
25854: 			      xmlSchemaValPtr *val)
25855: {
25856:     int ret = 0;
25857:     xmlSchemaNodeInfoPtr inode = vctxt->inode;
25858: 
25859:     /*
25860:     * cos-valid-default:
25861:     * Schema Component Constraint: Element Default Valid (Immediate)
25862:     * For a string to be a valid default with respect to a type
25863:     * definition the appropriate case among the following must be true:
25864:     */
25865:     if WXS_IS_COMPLEX(inode->typeDef) {
25866: 	/*
25867: 	* Complex type.
25868: 	*
25869: 	* SPEC (2.1) "its {content type} must be a simple type definition
25870: 	* or mixed."
25871: 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
25872: 	* type}'s particle must be �emptiable� as defined by
25873: 	* Particle Emptiable (�3.9.6)."
25874: 	*/
25875: 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25876: 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25877: 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
25878: 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25879: 	    /* NOTE that this covers (2.2.2) as well. */
25880: 	    VERROR(ret, NULL,
25881: 		"For a string to be a valid default, the type definition "
25882: 		"must be a simple type or a complex type with simple content "
25883: 		"or mixed content and a particle emptiable");
25884: 	    return(ret);
25885: 	}
25886:     }
25887:     /*
25888:     * 1 If the type definition is a simple type definition, then the string
25889:     * must be �valid� with respect to that definition as defined by String
25890:     * Valid (�3.14.4).
25891:     *
25892:     * AND
25893:     *
25894:     * 2.2.1 If the {content type} is a simple type definition, then the
25895:     * string must be �valid� with respect to that simple type definition
25896:     * as defined by String Valid (�3.14.4).
25897:     */
25898:     if (WXS_IS_SIMPLE(inode->typeDef)) {
25899: 
25900: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25901: 	    NULL, inode->typeDef, value, val, 1, 1, 0);
25902: 
25903:     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25904: 
25905: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25906: 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25907:     }
25908:     if (ret < 0) {
25909: 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
25910: 	    "calling xmlSchemaVCheckCVCSimpleType()");
25911:     }
25912:     return (ret);
25913: }
25914: 
25915: static void
25916: xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
25917: 			       const xmlChar * name ATTRIBUTE_UNUSED,
25918: 			       xmlSchemaElementPtr item,
25919: 			       xmlSchemaNodeInfoPtr inode)
25920: {
25921:     inode->decl = item;
25922: #ifdef DEBUG_CONTENT
25923:     {
25924: 	xmlChar *str = NULL;
25925: 
25926: 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
25927: 	    xmlGenericError(xmlGenericErrorContext,
25928: 		"AUTOMATON callback for '%s' [declaration]\n",
25929: 		xmlSchemaFormatQName(&str,
25930: 		inode->localName, inode->nsName));
25931: 	} else {
25932: 	    xmlGenericError(xmlGenericErrorContext,
25933: 		    "AUTOMATON callback for '%s' [wildcard]\n",
25934: 		    xmlSchemaFormatQName(&str,
25935: 		    inode->localName, inode->nsName));
25936: 
25937: 	}
25938: 	FREE_AND_NULL(str)
25939:     }
25940: #endif
25941: }
25942: 
25943: static int
25944: xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25945: {
25946:     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25947:     if (vctxt->inode == NULL) {
25948: 	VERROR_INT("xmlSchemaValidatorPushElem",
25949: 	    "calling xmlSchemaGetFreshElemInfo()");
25950: 	return (-1);
25951:     }
25952:     vctxt->nbAttrInfos = 0;
25953:     return (0);
25954: }
25955: 
25956: static int
25957: xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25958: 			     xmlSchemaNodeInfoPtr inode,
25959: 			     xmlSchemaTypePtr type,
25960: 			     const xmlChar *value)
25961: {
25962:     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25963: 	return (xmlSchemaVCheckCVCSimpleType(
25964: 	    ACTXT_CAST vctxt, NULL,
25965: 	    type, value, &(inode->val), 1, 1, 0));
25966:     else
25967: 	return (xmlSchemaVCheckCVCSimpleType(
25968: 	    ACTXT_CAST vctxt, NULL,
25969: 	    type, value, NULL, 1, 0, 0));
25970: }
25971: 
25972: 
25973: 
25974: /*
25975: * Process END of element.
25976: */
25977: static int
25978: xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25979: {
25980:     int ret = 0;
25981:     xmlSchemaNodeInfoPtr inode = vctxt->inode;
25982: 
25983:     if (vctxt->nbAttrInfos != 0)
25984: 	xmlSchemaClearAttrInfos(vctxt);
25985:     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25986: 	/*
25987: 	* This element was not expected;
25988: 	* we will not validate child elements of broken parents.
25989: 	* Skip validation of all content of the parent.
25990: 	*/
25991: 	vctxt->skipDepth = vctxt->depth -1;
25992: 	goto end_elem;
25993:     }
25994:     if ((inode->typeDef == NULL) ||
25995: 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25996: 	/*
25997: 	* 1. the type definition might be missing if the element was
25998: 	*    error prone
25999: 	* 2. it might be abstract.
26000: 	*/
26001: 	goto end_elem;
26002:     }
26003:     /*
26004:     * Check the content model.
26005:     */
26006:     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26007: 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26008: 
26009: 	/*
26010: 	* Workaround for "anyType".
26011: 	*/
26012: 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26013: 	    goto character_content;
26014: 
26015: 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26016: 	    xmlChar *values[10];
26017: 	    int terminal, nbval = 10, nbneg;
26018: 
26019: 	    if (inode->regexCtxt == NULL) {
26020: 		/*
26021: 		* Create the regex context.
26022: 		*/
26023: 		inode->regexCtxt =
26024: 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
26025: 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26026: 		    vctxt);
26027: 		if (inode->regexCtxt == NULL) {
26028: 		    VERROR_INT("xmlSchemaValidatorPopElem",
26029: 			"failed to create a regex context");
26030: 		    goto internal_error;
26031: 		}
26032: #ifdef DEBUG_AUTOMATA
26033: 		xmlGenericError(xmlGenericErrorContext,
26034: 		    "AUTOMATON create on '%s'\n", inode->localName);
26035: #endif
26036: 	    }
26037: 	    /*
26038: 	    * Get hold of the still expected content, since a further
26039: 	    * call to xmlRegExecPushString() will loose this information.
26040: 	    */
26041: 	    xmlRegExecNextValues(inode->regexCtxt,
26042: 		&nbval, &nbneg, &values[0], &terminal);
26043: 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26044: 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26045: 		/*
26046: 		* Still missing something.
26047: 		*/
26048: 		ret = 1;
26049: 		inode->flags |=
26050: 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26051: 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26052: 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26053: 		    "Missing child element(s)",
26054: 		    nbval, nbneg, values);
26055: #ifdef DEBUG_AUTOMATA
26056: 		xmlGenericError(xmlGenericErrorContext,
26057: 		    "AUTOMATON missing ERROR on '%s'\n",
26058: 		    inode->localName);
26059: #endif
26060: 	    } else {
26061: 		/*
26062: 		* Content model is satisfied.
26063: 		*/
26064: 		ret = 0;
26065: #ifdef DEBUG_AUTOMATA
26066: 		xmlGenericError(xmlGenericErrorContext,
26067: 		    "AUTOMATON succeeded on '%s'\n",
26068: 		    inode->localName);
26069: #endif
26070: 	    }
26071: 
26072: 	}
26073:     }
26074:     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26075: 	goto end_elem;
26076: 
26077: character_content:
26078: 
26079:     if (vctxt->value != NULL) {
26080: 	xmlSchemaFreeValue(vctxt->value);
26081: 	vctxt->value = NULL;
26082:     }
26083:     /*
26084:     * Check character content.
26085:     */
26086:     if (inode->decl == NULL) {
26087: 	/*
26088: 	* Speedup if no declaration exists.
26089: 	*/
26090: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26091: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26092: 		inode, inode->typeDef, inode->value);
26093: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26094: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26095: 		inode, inode->typeDef->contentTypeDef,
26096: 		inode->value);
26097: 	}
26098: 	if (ret < 0) {
26099: 	    VERROR_INT("xmlSchemaValidatorPopElem",
26100: 		"calling xmlSchemaVCheckCVCSimpleType()");
26101: 	    goto internal_error;
26102: 	}
26103: 	goto end_elem;
26104:     }
26105:     /*
26106:     * cvc-elt (3.3.4) : 5
26107:     * The appropriate case among the following must be true:
26108:     */
26109:     /*
26110:     * cvc-elt (3.3.4) : 5.1
26111:     * If the declaration has a {value constraint},
26112:     * the item has neither element nor character [children] and
26113:     * clause 3.2 has not applied, then all of the following must be true:
26114:     */
26115:     if ((inode->decl->value != NULL) &&
26116: 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26117: 	(! INODE_NILLED(inode))) {
26118: 	/*
26119: 	* cvc-elt (3.3.4) : 5.1.1
26120: 	* If the �actual type definition� is a �local type definition�
26121: 	* then the canonical lexical representation of the {value constraint}
26122: 	* value must be a valid default for the �actual type definition� as
26123: 	* defined in Element Default Valid (Immediate) (�3.3.6).
26124: 	*/
26125: 	/*
26126: 	* NOTE: 'local' above means types acquired by xsi:type.
26127: 	* NOTE: Although the *canonical* value is stated, it is not
26128: 	* relevant if canonical or not. Additionally XML Schema 1.1
26129: 	* will removed this requirement as well.
26130: 	*/
26131: 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26132: 
26133: 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
26134: 		inode->decl->value, &(inode->val));
26135: 	    if (ret != 0) {
26136: 		if (ret < 0) {
26137: 		    VERROR_INT("xmlSchemaValidatorPopElem",
26138: 			"calling xmlSchemaCheckCOSValidDefault()");
26139: 		    goto internal_error;
26140: 		}
26141: 		goto end_elem;
26142: 	    }
26143: 	    /*
26144: 	    * Stop here, to avoid redundant validation of the value
26145: 	    * (see following).
26146: 	    */
26147: 	    goto default_psvi;
26148: 	}
26149: 	/*
26150: 	* cvc-elt (3.3.4) : 5.1.2
26151: 	* The element information item with the canonical lexical
26152: 	* representation of the {value constraint} value used as its
26153: 	* �normalized value� must be �valid� with respect to the
26154: 	* �actual type definition� as defined by Element Locally Valid (Type)
26155: 	* (�3.3.4).
26156: 	*/
26157: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26158: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26159: 		inode, inode->typeDef, inode->decl->value);
26160: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26161: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26162: 		inode, inode->typeDef->contentTypeDef,
26163: 		inode->decl->value);
26164: 	}
26165: 	if (ret != 0) {
26166: 	    if (ret < 0) {
26167: 		VERROR_INT("xmlSchemaValidatorPopElem",
26168: 		    "calling xmlSchemaVCheckCVCSimpleType()");
26169: 		goto internal_error;
26170: 	    }
26171: 	    goto end_elem;
26172: 	}
26173: 
26174: default_psvi:
26175: 	/*
26176: 	* PSVI: Create a text node on the instance element.
26177: 	*/
26178: 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26179: 	    (inode->node != NULL)) {
26180: 	    xmlNodePtr textChild;
26181: 	    xmlChar *normValue;
26182: 	    /*
26183: 	    * VAL TODO: Normalize the value.
26184: 	    */
26185: 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
26186: 		inode->decl->value);
26187: 	    if (normValue != NULL) {
26188: 		textChild = xmlNewText(BAD_CAST normValue);
26189: 		xmlFree(normValue);
26190: 	    } else
26191: 		textChild = xmlNewText(inode->decl->value);
26192: 	    if (textChild == NULL) {
26193: 		VERROR_INT("xmlSchemaValidatorPopElem",
26194: 		    "calling xmlNewText()");
26195: 		goto internal_error;
26196: 	    } else
26197: 		xmlAddChild(inode->node, textChild);
26198: 	}
26199: 
26200:     } else if (! INODE_NILLED(inode)) {
26201: 	/*
26202: 	* 5.2.1 The element information item must be �valid� with respect
26203: 	* to the �actual type definition� as defined by Element Locally
26204: 	* Valid (Type) (�3.3.4).
26205: 	*/
26206: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26207: 	     /*
26208: 	    * SPEC (cvc-type) (3.1)
26209: 	    * "If the type definition is a simple type definition, ..."
26210: 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
26211: 	    * (Element) (�3.3.4) did not apply, then the �normalized value�
26212: 	    * must be �valid� with respect to the type definition as defined
26213: 	    * by String Valid (�3.14.4).
26214: 	    */
26215: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26216: 		    inode, inode->typeDef, inode->value);
26217: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26218: 	    /*
26219: 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26220: 	    * definition, then the element information item must be
26221: 	    * �valid� with respect to the type definition as per
26222: 	    * Element Locally Valid (Complex Type) (�3.4.4);"
26223: 	    *
26224: 	    * SPEC (cvc-complex-type) (2.2)
26225: 	    * "If the {content type} is a simple type definition, ...
26226: 	    * the �normalized value� of the element information item is
26227: 	    * �valid� with respect to that simple type definition as
26228: 	    * defined by String Valid (�3.14.4)."
26229: 	    */
26230: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26231: 		inode, inode->typeDef->contentTypeDef, inode->value);
26232: 	}
26233: 	if (ret != 0) {
26234: 	    if (ret < 0) {
26235: 		VERROR_INT("xmlSchemaValidatorPopElem",
26236: 		    "calling xmlSchemaVCheckCVCSimpleType()");
26237: 		goto internal_error;
26238: 	    }
26239: 	    goto end_elem;
26240: 	}
26241: 	/*
26242: 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26243: 	* not applied, all of the following must be true:
26244: 	*/
26245: 	if ((inode->decl->value != NULL) &&
26246: 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26247: 
26248: 	    /*
26249: 	    * TODO: We will need a computed value, when comparison is
26250: 	    * done on computed values.
26251: 	    */
26252: 	    /*
26253: 	    * 5.2.2.1 The element information item must have no element
26254: 	    * information item [children].
26255: 	    */
26256: 	    if (inode->flags &
26257: 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26258: 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26259: 		VERROR(ret, NULL,
26260: 		    "The content must not containt element nodes since "
26261: 		    "there is a fixed value constraint");
26262: 		goto end_elem;
26263: 	    } else {
26264: 		/*
26265: 		* 5.2.2.2 The appropriate case among the following must
26266: 		* be true:
26267: 		*/
26268: 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26269: 		    /*
26270: 		    * 5.2.2.2.1 If the {content type} of the �actual type
26271: 		    * definition� is mixed, then the *initial value* of the
26272: 		    * item must match the canonical lexical representation
26273: 		    * of the {value constraint} value.
26274: 		    *
26275: 		    * ... the *initial value* of an element information
26276: 		    * item is the string composed of, in order, the
26277: 		    * [character code] of each character information item in
26278: 		    * the [children] of that element information item.
26279: 		    */
26280: 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
26281: 			/*
26282: 			* VAL TODO: Report invalid & expected values as well.
26283: 			* VAL TODO: Implement the canonical stuff.
26284: 			*/
26285: 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26286: 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
26287: 			    ret, NULL, NULL,
26288: 			    "The initial value '%s' does not match the fixed "
26289: 			    "value constraint '%s'",
26290: 			    inode->value, inode->decl->value);
26291: 			goto end_elem;
26292: 		    }
26293: 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26294: 		    /*
26295: 		    * 5.2.2.2.2 If the {content type} of the �actual type
26296: 		    * definition� is a simple type definition, then the
26297: 		    * *actual value* of the item must match the canonical
26298: 		    * lexical representation of the {value constraint} value.
26299: 		    */
26300: 		    /*
26301: 		    * VAL TODO: *actual value* is the normalized value, impl.
26302: 		    *           this.
26303: 		    * VAL TODO: Report invalid & expected values as well.
26304: 		    * VAL TODO: Implement a comparison with the computed values.
26305: 		    */
26306: 		    if (! xmlStrEqual(inode->value,
26307: 			    inode->decl->value)) {
26308: 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26309: 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
26310: 			    ret, NULL, NULL,
26311: 			    "The actual value '%s' does not match the fixed "
26312: 			    "value constraint '%s'",
26313: 			    inode->value,
26314: 			    inode->decl->value);
26315: 			goto end_elem;
26316: 		    }
26317: 		}
26318: 	    }
26319: 	}
26320:     }
26321: 
26322: end_elem:
26323:     if (vctxt->depth < 0) {
26324: 	/* TODO: raise error? */
26325: 	return (0);
26326:     }
26327:     if (vctxt->depth == vctxt->skipDepth)
26328: 	vctxt->skipDepth = -1;
26329:     /*
26330:     * Evaluate the history of XPath state objects.
26331:     */
26332:     if (inode->appliedXPath &&
26333: 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26334: 	goto internal_error;
26335:     /*
26336:     * MAYBE TODO:
26337:     * SPEC (6) "The element information item must be �valid� with
26338:     * respect to each of the {identity-constraint definitions} as per
26339:     * Identity-constraint Satisfied (�3.11.4)."
26340:     */
26341:     /*
26342:     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26343:     *   need to be built in any case.
26344:     *   We will currently build IDC node-tables and bubble them only if
26345:     *   keyrefs do exist.
26346:     */
26347: 
26348:     /*
26349:     * Add the current IDC target-nodes to the IDC node-tables.
26350:     */
26351:     if ((inode->idcMatchers != NULL) &&
26352: 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26353:     {
26354: 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26355: 	    goto internal_error;
26356:     }
26357:     /*
26358:     * Validate IDC keyrefs.
26359:     */
26360:     if (vctxt->inode->hasKeyrefs)
26361: 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26362: 	    goto internal_error;
26363:     /*
26364:     * Merge/free the IDC table.
26365:     */
26366:     if (inode->idcTable != NULL) {
26367: #ifdef DEBUG_IDC_NODE_TABLE
26368: 	xmlSchemaDebugDumpIDCTable(stdout,
26369: 	    inode->nsName,
26370: 	    inode->localName,
26371: 	    inode->idcTable);
26372: #endif
26373: 	if ((vctxt->depth > 0) &&
26374: 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26375: 	{
26376: 	    /*
26377: 	    * Merge the IDC node table with the table of the parent node.
26378: 	    */
26379: 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26380: 		goto internal_error;
26381: 	}
26382:     }
26383:     /*
26384:     * Clear the current ielem.
26385:     * VAL TODO: Don't free the PSVI IDC tables if they are
26386:     * requested for the PSVI.
26387:     */
26388:     xmlSchemaClearElemInfo(vctxt, inode);
26389:     /*
26390:     * Skip further processing if we are on the validation root.
26391:     */
26392:     if (vctxt->depth == 0) {
26393: 	vctxt->depth--;
26394: 	vctxt->inode = NULL;
26395: 	return (0);
26396:     }
26397:     /*
26398:     * Reset the keyrefDepth if needed.
26399:     */
26400:     if (vctxt->aidcs != NULL) {
26401: 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26402: 	do {
26403: 	    if (aidc->keyrefDepth == vctxt->depth) {
26404: 		/*
26405: 		* A 'keyrefDepth' of a key/unique IDC matches the current
26406: 		* depth, this means that we are leaving the scope of the
26407: 		* top-most keyref IDC which refers to this IDC.
26408: 		*/
26409: 		aidc->keyrefDepth = -1;
26410: 	    }
26411: 	    aidc = aidc->next;
26412: 	} while (aidc != NULL);
26413:     }
26414:     vctxt->depth--;
26415:     vctxt->inode = vctxt->elemInfos[vctxt->depth];
26416:     /*
26417:     * VAL TODO: 7 If the element information item is the �validation root�, it must be
26418:     * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
26419:     */
26420:     return (ret);
26421: 
26422: internal_error:
26423:     vctxt->err = -1;
26424:     return (-1);
26425: }
26426: 
26427: /*
26428: * 3.4.4 Complex Type Definition Validation Rules
26429: * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26430: */
26431: static int
26432: xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26433: {
26434:     xmlSchemaNodeInfoPtr pielem;
26435:     xmlSchemaTypePtr ptype;
26436:     int ret = 0;
26437: 
26438:     if (vctxt->depth <= 0) {
26439: 	VERROR_INT("xmlSchemaValidateChildElem",
26440: 	    "not intended for the validation root");
26441: 	return (-1);
26442:     }
26443:     pielem = vctxt->elemInfos[vctxt->depth -1];
26444:     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26445: 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26446:     /*
26447:     * Handle 'nilled' elements.
26448:     */
26449:     if (INODE_NILLED(pielem)) {
26450: 	/*
26451: 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
26452: 	*/
26453: 	ACTIVATE_PARENT_ELEM;
26454: 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26455: 	VERROR(ret, NULL,
26456: 	    "Neither character nor element content is allowed, "
26457: 	    "because the element was 'nilled'");
26458: 	ACTIVATE_ELEM;
26459: 	goto unexpected_elem;
26460:     }
26461: 
26462:     ptype = pielem->typeDef;
26463: 
26464:     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26465: 	/*
26466: 	* Workaround for "anyType": we have currently no content model
26467: 	* assigned for "anyType", so handle it explicitely.
26468: 	* "anyType" has an unbounded, lax "any" wildcard.
26469: 	*/
26470: 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26471: 	    vctxt->inode->localName,
26472: 	    vctxt->inode->nsName);
26473: 
26474: 	if (vctxt->inode->decl == NULL) {
26475: 	    xmlSchemaAttrInfoPtr iattr;
26476: 	    /*
26477: 	    * Process "xsi:type".
26478: 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26479: 	    */
26480: 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26481: 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26482: 	    if (iattr != NULL) {
26483: 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
26484: 		    &(vctxt->inode->typeDef), NULL);
26485: 		if (ret != 0) {
26486: 		    if (ret == -1) {
26487: 			VERROR_INT("xmlSchemaValidateChildElem",
26488: 			    "calling xmlSchemaProcessXSIType() to "
26489: 			    "process the attribute 'xsi:nil'");
26490: 			return (-1);
26491: 		    }
26492: 		    return (ret);
26493: 		}
26494: 	    } else {
26495: 		 /*
26496: 		 * Fallback to "anyType".
26497: 		 *
26498: 		 * SPEC (cvc-assess-elt)
26499: 		 * "If the item cannot be �strictly assessed�, [...]
26500: 		 * an element information item's schema validity may be laxly
26501: 		 * assessed if its �context-determined declaration� is not
26502: 		 * skip by �validating� with respect to the �ur-type
26503: 		 * definition� as per Element Locally Valid (Type) (�3.3.4)."
26504: 		*/
26505: 		vctxt->inode->typeDef =
26506: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26507: 	    }
26508: 	}
26509: 	return (0);
26510:     }
26511: 
26512:     switch (ptype->contentType) {
26513: 	case XML_SCHEMA_CONTENT_EMPTY:
26514: 	    /*
26515: 	    * SPEC (2.1) "If the {content type} is empty, then the
26516: 	    * element information item has no character or element
26517: 	    * information item [children]."
26518: 	    */
26519: 	    ACTIVATE_PARENT_ELEM
26520: 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26521: 	    VERROR(ret, NULL,
26522: 		"Element content is not allowed, "
26523: 		"because the content type is empty");
26524: 	    ACTIVATE_ELEM
26525: 	    goto unexpected_elem;
26526: 	    break;
26527: 
26528: 	case XML_SCHEMA_CONTENT_MIXED:
26529:         case XML_SCHEMA_CONTENT_ELEMENTS: {
26530: 	    xmlRegExecCtxtPtr regexCtxt;
26531: 	    xmlChar *values[10];
26532: 	    int terminal, nbval = 10, nbneg;
26533: 
26534: 	    /* VAL TODO: Optimized "anyType" validation.*/
26535: 
26536: 	    if (ptype->contModel == NULL) {
26537: 		VERROR_INT("xmlSchemaValidateChildElem",
26538: 		    "type has elem content but no content model");
26539: 		return (-1);
26540: 	    }
26541: 	    /*
26542: 	    * Safety belf for evaluation if the cont. model was already
26543: 	    * examined to be invalid.
26544: 	    */
26545: 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26546: 		VERROR_INT("xmlSchemaValidateChildElem",
26547: 		    "validating elem, but elem content is already invalid");
26548: 		return (-1);
26549: 	    }
26550: 
26551: 	    regexCtxt = pielem->regexCtxt;
26552: 	    if (regexCtxt == NULL) {
26553: 		/*
26554: 		* Create the regex context.
26555: 		*/
26556: 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26557: 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26558: 		    vctxt);
26559: 		if (regexCtxt == NULL) {
26560: 		    VERROR_INT("xmlSchemaValidateChildElem",
26561: 			"failed to create a regex context");
26562: 		    return (-1);
26563: 		}
26564: 		pielem->regexCtxt = regexCtxt;
26565: #ifdef DEBUG_AUTOMATA
26566: 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26567: 		    pielem->localName);
26568: #endif
26569: 	    }
26570: 
26571: 	    /*
26572: 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
26573: 	    * then the sequence of the element information item's
26574: 	    * element information item [children], if any, taken in
26575: 	    * order, is �valid� with respect to the {content type}'s
26576: 	    * particle, as defined in Element Sequence Locally Valid
26577: 	    * (Particle) (�3.9.4)."
26578: 	    */
26579: 	    ret = xmlRegExecPushString2(regexCtxt,
26580: 		vctxt->inode->localName,
26581: 		vctxt->inode->nsName,
26582: 		vctxt->inode);
26583: #ifdef DEBUG_AUTOMATA
26584: 	    if (ret < 0)
26585: 		xmlGenericError(xmlGenericErrorContext,
26586: 		"AUTOMATON push ERROR for '%s' on '%s'\n",
26587: 		vctxt->inode->localName, pielem->localName);
26588: 	    else
26589: 		xmlGenericError(xmlGenericErrorContext,
26590: 		"AUTOMATON push OK for '%s' on '%s'\n",
26591: 		vctxt->inode->localName, pielem->localName);
26592: #endif
26593: 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26594: 		VERROR_INT("xmlSchemaValidateChildElem",
26595: 		    "calling xmlRegExecPushString2()");
26596: 		return (-1);
26597: 	    }
26598: 	    if (ret < 0) {
26599: 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26600: 		    &values[0], &terminal);
26601: 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26602: 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26603: 		    "This element is not expected",
26604: 		    nbval, nbneg, values);
26605: 		ret = vctxt->err;
26606: 		goto unexpected_elem;
26607: 	    } else
26608: 		ret = 0;
26609: 	}
26610: 	    break;
26611: 	case XML_SCHEMA_CONTENT_SIMPLE:
26612: 	case XML_SCHEMA_CONTENT_BASIC:
26613: 	    ACTIVATE_PARENT_ELEM
26614: 	    if (WXS_IS_COMPLEX(ptype)) {
26615: 		/*
26616: 		* SPEC (cvc-complex-type) (2.2)
26617: 		* "If the {content type} is a simple type definition, then
26618: 		* the element information item has no element information
26619: 		* item [children], ..."
26620: 		*/
26621: 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26622: 		VERROR(ret, NULL, "Element content is not allowed, "
26623: 		    "because the content type is a simple type definition");
26624: 	    } else {
26625: 		/*
26626: 		* SPEC (cvc-type) (3.1.2) "The element information item must
26627: 		* have no element information item [children]."
26628: 		*/
26629: 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26630: 		VERROR(ret, NULL, "Element content is not allowed, "
26631: 		    "because the type definition is simple");
26632: 	    }
26633: 	    ACTIVATE_ELEM
26634: 	    ret = vctxt->err;
26635: 	    goto unexpected_elem;
26636: 	    break;
26637: 
26638: 	default:
26639: 	    break;
26640:     }
26641:     return (ret);
26642: unexpected_elem:
26643:     /*
26644:     * Pop this element and set the skipDepth to skip
26645:     * all further content of the parent element.
26646:     */
26647:     vctxt->skipDepth = vctxt->depth;
26648:     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26649:     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26650:     return (ret);
26651: }
26652: 
26653: #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26654: #define XML_SCHEMA_PUSH_TEXT_CREATED 2
26655: #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26656: 
26657: static int
26658: xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26659: 		  int nodeType, const xmlChar *value, int len,
26660: 		  int mode, int *consumed)
26661: {
26662:     /*
26663:     * Unfortunately we have to duplicate the text sometimes.
26664:     * OPTIMIZE: Maybe we could skip it, if:
26665:     *   1. content type is simple
26666:     *   2. whitespace is "collapse"
26667:     *   3. it consists of whitespace only
26668:     *
26669:     * Process character content.
26670:     */
26671:     if (consumed != NULL)
26672: 	*consumed = 0;
26673:     if (INODE_NILLED(vctxt->inode)) {
26674: 	/*
26675: 	* SPEC cvc-elt (3.3.4 - 3.2.1)
26676: 	* "The element information item must have no character or
26677: 	* element information item [children]."
26678: 	*/
26679: 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26680: 	    "Neither character nor element content is allowed "
26681: 	    "because the element is 'nilled'");
26682: 	return (vctxt->err);
26683:     }
26684:     /*
26685:     * SPEC (2.1) "If the {content type} is empty, then the
26686:     * element information item has no character or element
26687:     * information item [children]."
26688:     */
26689:     if (vctxt->inode->typeDef->contentType ==
26690: 	    XML_SCHEMA_CONTENT_EMPTY) {
26691: 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26692: 	    "Character content is not allowed, "
26693: 	    "because the content type is empty");
26694: 	return (vctxt->err);
26695:     }
26696: 
26697:     if (vctxt->inode->typeDef->contentType ==
26698: 	    XML_SCHEMA_CONTENT_ELEMENTS) {
26699: 	if ((nodeType != XML_TEXT_NODE) ||
26700: 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26701: 	    /*
26702: 	    * SPEC cvc-complex-type (2.3)
26703: 	    * "If the {content type} is element-only, then the
26704: 	    * element information item has no character information
26705: 	    * item [children] other than those whose [character
26706: 	    * code] is defined as a white space in [XML 1.0 (Second
26707: 	    * Edition)]."
26708: 	    */
26709: 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26710: 		"Character content other than whitespace is not allowed "
26711: 		"because the content type is 'element-only'");
26712: 	    return (vctxt->err);
26713: 	}
26714: 	return (0);
26715:     }
26716: 
26717:     if ((value == NULL) || (value[0] == 0))
26718: 	return (0);
26719:     /*
26720:     * Save the value.
26721:     * NOTE that even if the content type is *mixed*, we need the
26722:     * *initial value* for default/fixed value constraints.
26723:     */
26724:     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26725: 	((vctxt->inode->decl == NULL) ||
26726: 	(vctxt->inode->decl->value == NULL)))
26727: 	return (0);
26728: 
26729:     if (vctxt->inode->value == NULL) {
26730: 	/*
26731: 	* Set the value.
26732: 	*/
26733: 	switch (mode) {
26734: 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
26735: 		/*
26736: 		* When working on a tree.
26737: 		*/
26738: 		vctxt->inode->value = value;
26739: 		break;
26740: 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
26741: 		/*
26742: 		* When working with the reader.
26743: 		* The value will be freed by the element info.
26744: 		*/
26745: 		vctxt->inode->value = value;
26746: 		if (consumed != NULL)
26747: 		    *consumed = 1;
26748: 		vctxt->inode->flags |=
26749: 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26750: 		break;
26751: 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26752: 		/*
26753: 		* When working with SAX.
26754: 		* The value will be freed by the element info.
26755: 		*/
26756: 		if (len != -1)
26757: 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26758: 		else
26759: 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
26760: 		vctxt->inode->flags |=
26761: 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26762: 		break;
26763: 	    default:
26764: 		break;
26765: 	}
26766:     } else {
26767: 	if (len < 0)
26768: 	    len = xmlStrlen(value);
26769: 	/*
26770: 	* Concat the value.
26771: 	*/
26772: 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26773: 	    vctxt->inode->value = BAD_CAST xmlStrncat(
26774: 		(xmlChar *) vctxt->inode->value, value, len);
26775: 	} else {
26776: 	    vctxt->inode->value =
26777: 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26778: 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26779: 	}
26780:     }
26781: 
26782:     return (0);
26783: }
26784: 
26785: static int
26786: xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26787: {
26788:     int ret = 0;
26789: 
26790:     if ((vctxt->skipDepth != -1) &&
26791: 	(vctxt->depth >= vctxt->skipDepth)) {
26792: 	VERROR_INT("xmlSchemaValidateElem",
26793: 	    "in skip-state");
26794: 	goto internal_error;
26795:     }
26796:     if (vctxt->xsiAssemble) {
26797: 	/*
26798: 	* We will stop validation if there was an error during
26799: 	* dynamic schema construction.
26800: 	* Note that we simply set @skipDepth to 0, this could
26801: 	* mean that a streaming document via SAX would be
26802: 	* still read to the end but it won't be validated any more.
26803: 	* TODO: If we are sure how to stop the validation at once
26804: 	*   for all input scenarios, then this should be changed to
26805: 	*   instantly stop the validation.
26806: 	*/
26807: 	ret = xmlSchemaAssembleByXSI(vctxt);
26808: 	if (ret != 0) {
26809: 	    if (ret == -1)
26810: 		goto internal_error;
26811: 	    vctxt->skipDepth = 0;
26812: 	    return(ret);
26813: 	}
26814:         /*
26815:          * Augment the IDC definitions for the main schema and all imported ones
26816:          * NOTE: main schema is the first in the imported list
26817:          */
26818:         xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
26819:     }
26820:     if (vctxt->depth > 0) {
26821: 	/*
26822: 	* Validate this element against the content model
26823: 	* of the parent.
26824: 	*/
26825: 	ret = xmlSchemaValidateChildElem(vctxt);
26826: 	if (ret != 0) {
26827: 	    if (ret < 0) {
26828: 		VERROR_INT("xmlSchemaValidateElem",
26829: 		    "calling xmlSchemaStreamValidateChildElement()");
26830: 		goto internal_error;
26831: 	    }
26832: 	    goto exit;
26833: 	}
26834: 	if (vctxt->depth == vctxt->skipDepth)
26835: 	    goto exit;
26836: 	if ((vctxt->inode->decl == NULL) &&
26837: 	    (vctxt->inode->typeDef == NULL)) {
26838: 	    VERROR_INT("xmlSchemaValidateElem",
26839: 		"the child element was valid but neither the "
26840: 		"declaration nor the type was set");
26841: 	    goto internal_error;
26842: 	}
26843:     } else {
26844: 	/*
26845: 	* Get the declaration of the validation root.
26846: 	*/
26847: 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26848: 	    vctxt->inode->localName,
26849: 	    vctxt->inode->nsName);
26850: 	if (vctxt->inode->decl == NULL) {
26851: 	    ret = XML_SCHEMAV_CVC_ELT_1;
26852: 	    VERROR(ret, NULL,
26853: 		"No matching global declaration available "
26854: 		"for the validation root");
26855: 	    goto exit;
26856: 	}
26857:     }
26858: 
26859:     if (vctxt->inode->decl == NULL)
26860: 	goto type_validation;
26861: 
26862:     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26863: 	int skip;
26864: 	/*
26865: 	* Wildcards.
26866: 	*/
26867: 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26868: 	if (ret != 0) {
26869: 	    if (ret < 0) {
26870: 		VERROR_INT("xmlSchemaValidateElem",
26871: 		    "calling xmlSchemaValidateElemWildcard()");
26872: 		goto internal_error;
26873: 	    }
26874: 	    goto exit;
26875: 	}
26876: 	if (skip) {
26877: 	    vctxt->skipDepth = vctxt->depth;
26878: 	    goto exit;
26879: 	}
26880: 	/*
26881: 	* The declaration might be set by the wildcard validation,
26882: 	* when the processContents is "lax" or "strict".
26883: 	*/
26884: 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26885: 	    /*
26886: 	    * Clear the "decl" field to not confuse further processing.
26887: 	    */
26888: 	    vctxt->inode->decl = NULL;
26889: 	    goto type_validation;
26890: 	}
26891:     }
26892:     /*
26893:     * Validate against the declaration.
26894:     */
26895:     ret = xmlSchemaValidateElemDecl(vctxt);
26896:     if (ret != 0) {
26897: 	if (ret < 0) {
26898: 	    VERROR_INT("xmlSchemaValidateElem",
26899: 		"calling xmlSchemaValidateElemDecl()");
26900: 	    goto internal_error;
26901: 	}
26902: 	goto exit;
26903:     }
26904:     /*
26905:     * Validate against the type definition.
26906:     */
26907: type_validation:
26908: 
26909:     if (vctxt->inode->typeDef == NULL) {
26910: 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26911: 	ret = XML_SCHEMAV_CVC_TYPE_1;
26912:     	VERROR(ret, NULL,
26913:     	    "The type definition is absent");
26914: 	goto exit;
26915:     }
26916:     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26917: 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26918: 	ret = XML_SCHEMAV_CVC_TYPE_2;
26919:     	    VERROR(ret, NULL,
26920:     	    "The type definition is abstract");
26921: 	goto exit;
26922:     }
26923:     /*
26924:     * Evaluate IDCs. Do it here, since new IDC matchers are registered
26925:     * during validation against the declaration. This must be done
26926:     * _before_ attribute validation.
26927:     */
26928:     if (vctxt->xpathStates != NULL) {
26929: 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26930: 	vctxt->inode->appliedXPath = 1;
26931: 	if (ret == -1) {
26932: 	    VERROR_INT("xmlSchemaValidateElem",
26933: 		"calling xmlSchemaXPathEvaluate()");
26934: 	    goto internal_error;
26935: 	}
26936:     }
26937:     /*
26938:     * Validate attributes.
26939:     */
26940:     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26941: 	if ((vctxt->nbAttrInfos != 0) ||
26942: 	    (vctxt->inode->typeDef->attrUses != NULL)) {
26943: 
26944: 	    ret = xmlSchemaVAttributesComplex(vctxt);
26945: 	}
26946:     } else if (vctxt->nbAttrInfos != 0) {
26947: 
26948: 	ret = xmlSchemaVAttributesSimple(vctxt);
26949:     }
26950:     /*
26951:     * Clear registered attributes.
26952:     */
26953:     if (vctxt->nbAttrInfos != 0)
26954: 	xmlSchemaClearAttrInfos(vctxt);
26955:     if (ret == -1) {
26956: 	VERROR_INT("xmlSchemaValidateElem",
26957: 	    "calling attributes validation");
26958: 	goto internal_error;
26959:     }
26960:     /*
26961:     * Don't return an error if attributes are invalid on purpose.
26962:     */
26963:     ret = 0;
26964: 
26965: exit:
26966:     if (ret != 0)
26967: 	vctxt->skipDepth = vctxt->depth;
26968:     return (ret);
26969: internal_error:
26970:     return (-1);
26971: }
26972: 
26973: #ifdef XML_SCHEMA_READER_ENABLED
26974: static int
26975: xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26976: {
26977:     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26978:     int depth, nodeType, ret = 0, consumed;
26979:     xmlSchemaNodeInfoPtr ielem;
26980: 
26981:     vctxt->depth = -1;
26982:     ret = xmlTextReaderRead(vctxt->reader);
26983:     /*
26984:     * Move to the document element.
26985:     */
26986:     while (ret == 1) {
26987: 	nodeType = xmlTextReaderNodeType(vctxt->reader);
26988: 	if (nodeType == XML_ELEMENT_NODE)
26989: 	    goto root_found;
26990: 	ret = xmlTextReaderRead(vctxt->reader);
26991:     }
26992:     goto exit;
26993: 
26994: root_found:
26995: 
26996:     do {
26997: 	depth = xmlTextReaderDepth(vctxt->reader);
26998: 	nodeType = xmlTextReaderNodeType(vctxt->reader);
26999: 
27000: 	if (nodeType == XML_ELEMENT_NODE) {
27001: 
27002: 	    vctxt->depth++;
27003: 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27004: 		VERROR_INT("xmlSchemaVReaderWalk",
27005: 		    "calling xmlSchemaValidatorPushElem()");
27006: 		goto internal_error;
27007: 	    }
27008: 	    ielem = vctxt->inode;
27009: 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27010: 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27011: 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27012: 	    /*
27013: 	    * Is the element empty?
27014: 	    */
27015: 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27016: 	    if (ret == -1) {
27017: 		VERROR_INT("xmlSchemaVReaderWalk",
27018: 		    "calling xmlTextReaderIsEmptyElement()");
27019: 		goto internal_error;
27020: 	    }
27021: 	    if (ret) {
27022: 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27023: 	    }
27024: 	    /*
27025: 	    * Register attributes.
27026: 	    */
27027: 	    vctxt->nbAttrInfos = 0;
27028: 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27029: 	    if (ret == -1) {
27030: 		VERROR_INT("xmlSchemaVReaderWalk",
27031: 		    "calling xmlTextReaderMoveToFirstAttribute()");
27032: 		goto internal_error;
27033: 	    }
27034: 	    if (ret == 1) {
27035: 		do {
27036: 		    /*
27037: 		    * VAL TODO: How do we know that the reader works on a
27038: 		    * node tree, to be able to pass a node here?
27039: 		    */
27040: 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27041: 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27042: 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
27043: 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
27044: 
27045: 			VERROR_INT("xmlSchemaVReaderWalk",
27046: 			    "calling xmlSchemaValidatorPushAttribute()");
27047: 			goto internal_error;
27048: 		    }
27049: 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27050: 		    if (ret == -1) {
27051: 			VERROR_INT("xmlSchemaVReaderWalk",
27052: 			    "calling xmlTextReaderMoveToFirstAttribute()");
27053: 			goto internal_error;
27054: 		    }
27055: 		} while (ret == 1);
27056: 		/*
27057: 		* Back to element position.
27058: 		*/
27059: 		ret = xmlTextReaderMoveToElement(vctxt->reader);
27060: 		if (ret == -1) {
27061: 		    VERROR_INT("xmlSchemaVReaderWalk",
27062: 			"calling xmlTextReaderMoveToElement()");
27063: 		    goto internal_error;
27064: 		}
27065: 	    }
27066: 	    /*
27067: 	    * Validate the element.
27068: 	    */
27069: 	    ret= xmlSchemaValidateElem(vctxt);
27070: 	    if (ret != 0) {
27071: 		if (ret == -1) {
27072: 		    VERROR_INT("xmlSchemaVReaderWalk",
27073: 			"calling xmlSchemaValidateElem()");
27074: 		    goto internal_error;
27075: 		}
27076: 		goto exit;
27077: 	    }
27078: 	    if (vctxt->depth == vctxt->skipDepth) {
27079: 		int curDepth;
27080: 		/*
27081: 		* Skip all content.
27082: 		*/
27083: 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27084: 		    ret = xmlTextReaderRead(vctxt->reader);
27085: 		    curDepth = xmlTextReaderDepth(vctxt->reader);
27086: 		    while ((ret == 1) && (curDepth != depth)) {
27087: 			ret = xmlTextReaderRead(vctxt->reader);
27088: 			curDepth = xmlTextReaderDepth(vctxt->reader);
27089: 		    }
27090: 		    if (ret < 0) {
27091: 			/*
27092: 			* VAL TODO: A reader error occured; what to do here?
27093: 			*/
27094: 			ret = 1;
27095: 			goto exit;
27096: 		    }
27097: 		}
27098: 		goto leave_elem;
27099: 	    }
27100: 	    /*
27101: 	    * READER VAL TODO: Is an END_ELEM really never called
27102: 	    * if the elem is empty?
27103: 	    */
27104: 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27105: 		goto leave_elem;
27106: 	} else if (nodeType == END_ELEM) {
27107: 	    /*
27108: 	    * Process END of element.
27109: 	    */
27110: leave_elem:
27111: 	    ret = xmlSchemaValidatorPopElem(vctxt);
27112: 	    if (ret != 0) {
27113: 		if (ret < 0) {
27114: 		    VERROR_INT("xmlSchemaVReaderWalk",
27115: 			"calling xmlSchemaValidatorPopElem()");
27116: 		    goto internal_error;
27117: 		}
27118: 		goto exit;
27119: 	    }
27120: 	    if (vctxt->depth >= 0)
27121: 		ielem = vctxt->inode;
27122: 	    else
27123: 		ielem = NULL;
27124: 	} else if ((nodeType == XML_TEXT_NODE) ||
27125: 	    (nodeType == XML_CDATA_SECTION_NODE) ||
27126: 	    (nodeType == WHTSP) ||
27127: 	    (nodeType == SIGN_WHTSP)) {
27128: 	    /*
27129: 	    * Process character content.
27130: 	    */
27131: 	    xmlChar *value;
27132: 
27133: 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27134: 		nodeType = XML_TEXT_NODE;
27135: 
27136: 	    value = xmlTextReaderValue(vctxt->reader);
27137: 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27138: 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27139: 	    if (! consumed)
27140: 		xmlFree(value);
27141: 	    if (ret == -1) {
27142: 		VERROR_INT("xmlSchemaVReaderWalk",
27143: 		    "calling xmlSchemaVPushText()");
27144: 		goto internal_error;
27145: 	    }
27146: 	} else if ((nodeType == XML_ENTITY_NODE) ||
27147: 	    (nodeType == XML_ENTITY_REF_NODE)) {
27148: 	    /*
27149: 	    * VAL TODO: What to do with entities?
27150: 	    */
27151: 	    TODO
27152: 	}
27153: 	/*
27154: 	* Read next node.
27155: 	*/
27156: 	ret = xmlTextReaderRead(vctxt->reader);
27157:     } while (ret == 1);
27158: 
27159: exit:
27160:     return (ret);
27161: internal_error:
27162:     return (-1);
27163: }
27164: #endif
27165: 
27166: /************************************************************************
27167:  * 									*
27168:  * 			SAX validation handlers				*
27169:  * 									*
27170:  ************************************************************************/
27171: 
27172: /*
27173: * Process text content.
27174: */
27175: static void
27176: xmlSchemaSAXHandleText(void *ctx,
27177: 		       const xmlChar * ch,
27178: 		       int len)
27179: {
27180:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27181: 
27182:     if (vctxt->depth < 0)
27183: 	return;
27184:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27185: 	return;
27186:     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27187: 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27188:     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27189: 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27190: 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
27191: 	    "calling xmlSchemaVPushText()");
27192: 	vctxt->err = -1;
27193: 	xmlStopParser(vctxt->parserCtxt);
27194:     }
27195: }
27196: 
27197: /*
27198: * Process CDATA content.
27199: */
27200: static void
27201: xmlSchemaSAXHandleCDataSection(void *ctx,
27202: 			     const xmlChar * ch,
27203: 			     int len)
27204: {
27205:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27206: 
27207:     if (vctxt->depth < 0)
27208: 	return;
27209:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27210: 	return;
27211:     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27212: 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27213:     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27214: 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27215: 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
27216: 	    "calling xmlSchemaVPushText()");
27217: 	vctxt->err = -1;
27218: 	xmlStopParser(vctxt->parserCtxt);
27219:     }
27220: }
27221: 
27222: static void
27223: xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27224: 			    const xmlChar * name ATTRIBUTE_UNUSED)
27225: {
27226:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27227: 
27228:     if (vctxt->depth < 0)
27229: 	return;
27230:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27231: 	return;
27232:     /* SAX VAL TODO: What to do here? */
27233:     TODO
27234: }
27235: 
27236: static void
27237: xmlSchemaSAXHandleStartElementNs(void *ctx,
27238: 				 const xmlChar * localname,
27239: 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
27240: 				 const xmlChar * URI,
27241: 				 int nb_namespaces,
27242: 				 const xmlChar ** namespaces,
27243: 				 int nb_attributes,
27244: 				 int nb_defaulted ATTRIBUTE_UNUSED,
27245: 				 const xmlChar ** attributes)
27246: {
27247:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27248:     int ret;
27249:     xmlSchemaNodeInfoPtr ielem;
27250:     int i, j;
27251: 
27252:     /*
27253:     * SAX VAL TODO: What to do with nb_defaulted?
27254:     */
27255:     /*
27256:     * Skip elements if inside a "skip" wildcard or invalid.
27257:     */
27258:     vctxt->depth++;
27259:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27260: 	return;
27261:     /*
27262:     * Push the element.
27263:     */
27264:     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27265: 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27266: 	    "calling xmlSchemaValidatorPushElem()");
27267: 	goto internal_error;
27268:     }
27269:     ielem = vctxt->inode;
27270:     /*
27271:     * TODO: Is this OK?
27272:     */
27273:     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27274:     ielem->localName = localname;
27275:     ielem->nsName = URI;
27276:     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27277:     /*
27278:     * Register namespaces on the elem info.
27279:     */
27280:     if (nb_namespaces != 0) {
27281: 	/*
27282: 	* Although the parser builds its own namespace list,
27283: 	* we have no access to it, so we'll use an own one.
27284: 	*/
27285:         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27286: 	    /*
27287: 	    * Store prefix and namespace name.
27288: 	    */
27289: 	    if (ielem->nsBindings == NULL) {
27290: 		ielem->nsBindings =
27291: 		    (const xmlChar **) xmlMalloc(10 *
27292: 			sizeof(const xmlChar *));
27293: 		if (ielem->nsBindings == NULL) {
27294: 		    xmlSchemaVErrMemory(vctxt,
27295: 			"allocating namespace bindings for SAX validation",
27296: 			NULL);
27297: 		    goto internal_error;
27298: 		}
27299: 		ielem->nbNsBindings = 0;
27300: 		ielem->sizeNsBindings = 5;
27301: 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27302: 		ielem->sizeNsBindings *= 2;
27303: 		ielem->nsBindings =
27304: 		    (const xmlChar **) xmlRealloc(
27305: 			(void *) ielem->nsBindings,
27306: 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27307: 		if (ielem->nsBindings == NULL) {
27308: 		    xmlSchemaVErrMemory(vctxt,
27309: 			"re-allocating namespace bindings for SAX validation",
27310: 			NULL);
27311: 		    goto internal_error;
27312: 		}
27313: 	    }
27314: 
27315: 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27316: 	    if (namespaces[j+1][0] == 0) {
27317: 		/*
27318: 		* Handle xmlns="".
27319: 		*/
27320: 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27321: 	    } else
27322: 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27323: 		    namespaces[j+1];
27324: 	    ielem->nbNsBindings++;
27325: 	}
27326:     }
27327:     /*
27328:     * Register attributes.
27329:     * SAX VAL TODO: We are not adding namespace declaration
27330:     * attributes yet.
27331:     */
27332:     if (nb_attributes != 0) {
27333: 	xmlChar *value;
27334: 
27335:         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27336: 	    /*
27337: 	    * Duplicate the value.
27338: 	    */
27339: 	    value = xmlStrndup(attributes[j+3],
27340: 		attributes[j+4] - attributes[j+3]);
27341: 	    /*
27342: 	    * TODO: Set the node line.
27343: 	    */
27344: 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
27345: 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27346: 		value, 1);
27347: 	    if (ret == -1) {
27348: 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27349: 		    "calling xmlSchemaValidatorPushAttribute()");
27350: 		goto internal_error;
27351: 	    }
27352: 	}
27353:     }
27354:     /*
27355:     * Validate the element.
27356:     */
27357:     ret = xmlSchemaValidateElem(vctxt);
27358:     if (ret != 0) {
27359: 	if (ret == -1) {
27360: 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27361: 		"calling xmlSchemaValidateElem()");
27362: 	    goto internal_error;
27363: 	}
27364: 	goto exit;
27365:     }
27366: 
27367: exit:
27368:     return;
27369: internal_error:
27370:     vctxt->err = -1;
27371:     xmlStopParser(vctxt->parserCtxt);
27372:     return;
27373: }
27374: 
27375: static void
27376: xmlSchemaSAXHandleEndElementNs(void *ctx,
27377: 			       const xmlChar * localname ATTRIBUTE_UNUSED,
27378: 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
27379: 			       const xmlChar * URI ATTRIBUTE_UNUSED)
27380: {
27381:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27382:     int res;
27383: 
27384:     /*
27385:     * Skip elements if inside a "skip" wildcard or if invalid.
27386:     */
27387:     if (vctxt->skipDepth != -1) {
27388: 	if (vctxt->depth > vctxt->skipDepth) {
27389: 	    vctxt->depth--;
27390: 	    return;
27391: 	} else
27392: 	    vctxt->skipDepth = -1;
27393:     }
27394:     /*
27395:     * SAX VAL TODO: Just a temporary check.
27396:     */
27397:     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27398: 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
27399: 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27400: 	    "elem pop mismatch");
27401:     }
27402:     res = xmlSchemaValidatorPopElem(vctxt);
27403:     if (res != 0) {
27404: 	if (res < 0) {
27405: 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27406: 		"calling xmlSchemaValidatorPopElem()");
27407: 	    goto internal_error;
27408: 	}
27409: 	goto exit;
27410:     }
27411: exit:
27412:     return;
27413: internal_error:
27414:     vctxt->err = -1;
27415:     xmlStopParser(vctxt->parserCtxt);
27416:     return;
27417: }
27418: 
27419: /************************************************************************
27420:  * 									*
27421:  * 			Validation interfaces				*
27422:  * 									*
27423:  ************************************************************************/
27424: 
27425: /**
27426:  * xmlSchemaNewValidCtxt:
27427:  * @schema:  a precompiled XML Schemas
27428:  *
27429:  * Create an XML Schemas validation context based on the given schema.
27430:  *
27431:  * Returns the validation context or NULL in case of error
27432:  */
27433: xmlSchemaValidCtxtPtr
27434: xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27435: {
27436:     xmlSchemaValidCtxtPtr ret;
27437: 
27438:     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27439:     if (ret == NULL) {
27440:         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27441:         return (NULL);
27442:     }
27443:     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27444:     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27445:     ret->dict = xmlDictCreate();
27446:     ret->nodeQNames = xmlSchemaItemListCreate();
27447:     ret->schema = schema;
27448:     return (ret);
27449: }
27450: 
27451: /**
27452:  * xmlSchemaClearValidCtxt:
27453:  * @ctxt: the schema validation context
27454:  *
27455:  * Free the resources associated to the schema validation context;
27456:  * leaves some fields alive intended for reuse of the context.
27457:  */
27458: static void
27459: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27460: {
27461:     if (vctxt == NULL)
27462:         return;
27463: 
27464:     /*
27465:     * TODO: Should we clear the flags?
27466:     *   Might be problematic if one reuses the context
27467:     *   and assumes that the options remain the same.
27468:     */
27469:     vctxt->flags = 0;
27470:     vctxt->validationRoot = NULL;
27471:     vctxt->doc = NULL;
27472: #ifdef LIBXML_READER_ENABLED
27473:     vctxt->reader = NULL;
27474: #endif
27475:     vctxt->hasKeyrefs = 0;
27476: 
27477:     if (vctxt->value != NULL) {
27478:         xmlSchemaFreeValue(vctxt->value);
27479: 	vctxt->value = NULL;
27480:     }
27481:     /*
27482:     * Augmented IDC information.
27483:     */
27484:     if (vctxt->aidcs != NULL) {
27485: 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27486: 	do {
27487: 	    next = cur->next;
27488: 	    xmlFree(cur);
27489: 	    cur = next;
27490: 	} while (cur != NULL);
27491: 	vctxt->aidcs = NULL;
27492:     }
27493:     if (vctxt->idcMatcherCache != NULL) {
27494: 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27495: 
27496: 	while (matcher) {
27497: 	    tmp = matcher;
27498: 	    matcher = matcher->nextCached;
27499: 	    xmlSchemaIDCFreeMatcherList(tmp);
27500: 	}
27501: 	vctxt->idcMatcherCache = NULL;
27502:     }
27503: 
27504: 
27505:     if (vctxt->idcNodes != NULL) {
27506: 	int i;
27507: 	xmlSchemaPSVIIDCNodePtr item;
27508: 
27509: 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
27510: 	    item = vctxt->idcNodes[i];
27511: 	    xmlFree(item->keys);
27512: 	    xmlFree(item);
27513: 	}
27514: 	xmlFree(vctxt->idcNodes);
27515: 	vctxt->idcNodes = NULL;
27516: 	vctxt->nbIdcNodes = 0;
27517: 	vctxt->sizeIdcNodes = 0;
27518:     }
27519:     /*
27520:     * Note that we won't delete the XPath state pool here.
27521:     */
27522:     if (vctxt->xpathStates != NULL) {
27523: 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27524: 	vctxt->xpathStates = NULL;
27525:     }
27526:     /*
27527:     * Attribute info.
27528:     */
27529:     if (vctxt->nbAttrInfos != 0) {
27530: 	xmlSchemaClearAttrInfos(vctxt);
27531:     }
27532:     /*
27533:     * Element info.
27534:     */
27535:     if (vctxt->elemInfos != NULL) {
27536: 	int i;
27537: 	xmlSchemaNodeInfoPtr ei;
27538: 
27539: 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
27540: 	    ei = vctxt->elemInfos[i];
27541: 	    if (ei == NULL)
27542: 		break;
27543: 	    xmlSchemaClearElemInfo(vctxt, ei);
27544: 	}
27545:     }
27546:     xmlSchemaItemListClear(vctxt->nodeQNames);
27547:     /* Recreate the dict. */
27548:     xmlDictFree(vctxt->dict);
27549:     /*
27550:     * TODO: Is is save to recreate it? Do we have a scenario
27551:     * where the user provides the dict?
27552:     */
27553:     vctxt->dict = xmlDictCreate();
27554: }
27555: 
27556: /**
27557:  * xmlSchemaFreeValidCtxt:
27558:  * @ctxt:  the schema validation context
27559:  *
27560:  * Free the resources associated to the schema validation context
27561:  */
27562: void
27563: xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27564: {
27565:     if (ctxt == NULL)
27566:         return;
27567:     if (ctxt->value != NULL)
27568:         xmlSchemaFreeValue(ctxt->value);
27569:     if (ctxt->pctxt != NULL)
27570: 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
27571:     if (ctxt->idcNodes != NULL) {
27572: 	int i;
27573: 	xmlSchemaPSVIIDCNodePtr item;
27574: 
27575: 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
27576: 	    item = ctxt->idcNodes[i];
27577: 	    xmlFree(item->keys);
27578: 	    xmlFree(item);
27579: 	}
27580: 	xmlFree(ctxt->idcNodes);
27581:     }
27582:     if (ctxt->idcKeys != NULL) {
27583: 	int i;
27584: 	for (i = 0; i < ctxt->nbIdcKeys; i++)
27585: 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27586: 	xmlFree(ctxt->idcKeys);
27587:     }
27588: 
27589:     if (ctxt->xpathStates != NULL) {
27590: 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27591: 	ctxt->xpathStates = NULL;
27592:     }
27593:     if (ctxt->xpathStatePool != NULL) {
27594: 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27595: 	ctxt->xpathStatePool = NULL;
27596:     }
27597: 
27598:     /*
27599:     * Augmented IDC information.
27600:     */
27601:     if (ctxt->aidcs != NULL) {
27602: 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27603: 	do {
27604: 	    next = cur->next;
27605: 	    xmlFree(cur);
27606: 	    cur = next;
27607: 	} while (cur != NULL);
27608:     }
27609:     if (ctxt->attrInfos != NULL) {
27610: 	int i;
27611: 	xmlSchemaAttrInfoPtr attr;
27612: 
27613: 	/* Just a paranoid call to the cleanup. */
27614: 	if (ctxt->nbAttrInfos != 0)
27615: 	    xmlSchemaClearAttrInfos(ctxt);
27616: 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27617: 	    attr = ctxt->attrInfos[i];
27618: 	    xmlFree(attr);
27619: 	}
27620: 	xmlFree(ctxt->attrInfos);
27621:     }
27622:     if (ctxt->elemInfos != NULL) {
27623: 	int i;
27624: 	xmlSchemaNodeInfoPtr ei;
27625: 
27626: 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
27627: 	    ei = ctxt->elemInfos[i];
27628: 	    if (ei == NULL)
27629: 		break;
27630: 	    xmlSchemaClearElemInfo(ctxt, ei);
27631: 	    xmlFree(ei);
27632: 	}
27633: 	xmlFree(ctxt->elemInfos);
27634:     }
27635:     if (ctxt->nodeQNames != NULL)
27636: 	xmlSchemaItemListFree(ctxt->nodeQNames);
27637:     if (ctxt->dict != NULL)
27638: 	xmlDictFree(ctxt->dict);
27639:     xmlFree(ctxt);
27640: }
27641: 
27642: /**
27643:  * xmlSchemaIsValid:
27644:  * @ctxt: the schema validation context
27645:  *
27646:  * Check if any error was detected during validation.
27647:  *
27648:  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27649:  *         of internal error.
27650:  */
27651: int
27652: xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27653: {
27654:     if (ctxt == NULL)
27655:         return(-1);
27656:     return(ctxt->err == 0);
27657: }
27658: 
27659: /**
27660:  * xmlSchemaSetValidErrors:
27661:  * @ctxt:  a schema validation context
27662:  * @err:  the error function
27663:  * @warn: the warning function
27664:  * @ctx: the functions context
27665:  *
27666:  * Set the error and warning callback informations
27667:  */
27668: void
27669: xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27670:                         xmlSchemaValidityErrorFunc err,
27671:                         xmlSchemaValidityWarningFunc warn, void *ctx)
27672: {
27673:     if (ctxt == NULL)
27674:         return;
27675:     ctxt->error = err;
27676:     ctxt->warning = warn;
27677:     ctxt->errCtxt = ctx;
27678:     if (ctxt->pctxt != NULL)
27679: 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27680: }
27681: 
27682: /**
27683:  * xmlSchemaSetValidStructuredErrors:
27684:  * @ctxt:  a schema validation context
27685:  * @serror:  the structured error function
27686:  * @ctx: the functions context
27687:  *
27688:  * Set the structured error callback
27689:  */
27690: void
27691: xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27692: 				  xmlStructuredErrorFunc serror, void *ctx)
27693: {
27694:     if (ctxt == NULL)
27695:         return;
27696: 	ctxt->serror = serror;
27697:     ctxt->error = NULL;
27698:     ctxt->warning = NULL;
27699:     ctxt->errCtxt = ctx;
27700:     if (ctxt->pctxt != NULL)
27701: 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27702: }
27703: 
27704: /**
27705:  * xmlSchemaGetValidErrors:
27706:  * @ctxt: a XML-Schema validation context
27707:  * @err: the error function result
27708:  * @warn: the warning function result
27709:  * @ctx: the functions context result
27710:  *
27711:  * Get the error and warning callback informations
27712:  *
27713:  * Returns -1 in case of error and 0 otherwise
27714:  */
27715: int
27716: xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27717: 			xmlSchemaValidityErrorFunc * err,
27718: 			xmlSchemaValidityWarningFunc * warn, void **ctx)
27719: {
27720: 	if (ctxt == NULL)
27721: 		return (-1);
27722: 	if (err != NULL)
27723: 		*err = ctxt->error;
27724: 	if (warn != NULL)
27725: 		*warn = ctxt->warning;
27726: 	if (ctx != NULL)
27727: 		*ctx = ctxt->errCtxt;
27728: 	return (0);
27729: }
27730: 
27731: 
27732: /**
27733:  * xmlSchemaSetValidOptions:
27734:  * @ctxt:	a schema validation context
27735:  * @options: a combination of xmlSchemaValidOption
27736:  *
27737:  * Sets the options to be used during the validation.
27738:  *
27739:  * Returns 0 in case of success, -1 in case of an
27740:  * API error.
27741:  */
27742: int
27743: xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27744: 			 int options)
27745: 
27746: {
27747:     int i;
27748: 
27749:     if (ctxt == NULL)
27750: 	return (-1);
27751:     /*
27752:     * WARNING: Change the start value if adding to the
27753:     * xmlSchemaValidOption.
27754:     * TODO: Is there an other, more easy to maintain,
27755:     * way?
27756:     */
27757:     for (i = 1; i < (int) sizeof(int) * 8; i++) {
27758:         if (options & 1<<i)
27759: 	    return (-1);
27760:     }
27761:     ctxt->options = options;
27762:     return (0);
27763: }
27764: 
27765: /**
27766:  * xmlSchemaValidCtxtGetOptions:
27767:  * @ctxt: a schema validation context
27768:  *
27769:  * Get the validation context options.
27770:  *
27771:  * Returns the option combination or -1 on error.
27772:  */
27773: int
27774: xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27775: 
27776: {
27777:     if (ctxt == NULL)
27778: 	return (-1);
27779:     else
27780: 	return (ctxt->options);
27781: }
27782: 
27783: static int
27784: xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27785: {
27786:     xmlAttrPtr attr;
27787:     int ret = 0;
27788:     xmlSchemaNodeInfoPtr ielem = NULL;
27789:     xmlNodePtr node, valRoot;
27790:     const xmlChar *nsName;
27791: 
27792:     /* DOC VAL TODO: Move this to the start function. */
27793:     valRoot = xmlDocGetRootElement(vctxt->doc);
27794:     if (valRoot == NULL) {
27795: 	/* VAL TODO: Error code? */
27796: 	VERROR(1, NULL, "The document has no document element");
27797: 	return (1);
27798:     }
27799:     vctxt->depth = -1;
27800:     vctxt->validationRoot = valRoot;
27801:     node = valRoot;
27802:     while (node != NULL) {
27803: 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27804: 	    goto next_sibling;
27805: 	if (node->type == XML_ELEMENT_NODE) {
27806: 
27807: 	    /*
27808: 	    * Init the node-info.
27809: 	    */
27810: 	    vctxt->depth++;
27811: 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
27812: 		goto internal_error;
27813: 	    ielem = vctxt->inode;
27814: 	    ielem->node = node;
27815: 	    ielem->nodeLine = node->line;
27816: 	    ielem->localName = node->name;
27817: 	    if (node->ns != NULL)
27818: 		ielem->nsName = node->ns->href;
27819: 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27820: 	    /*
27821: 	    * Register attributes.
27822: 	    * DOC VAL TODO: We do not register namespace declaration
27823: 	    * attributes yet.
27824: 	    */
27825: 	    vctxt->nbAttrInfos = 0;
27826: 	    if (node->properties != NULL) {
27827: 		attr = node->properties;
27828: 		do {
27829: 		    if (attr->ns != NULL)
27830: 			nsName = attr->ns->href;
27831: 		    else
27832: 			nsName = NULL;
27833: 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
27834: 			(xmlNodePtr) attr,
27835: 			/*
27836: 			* Note that we give it the line number of the
27837: 			* parent element.
27838: 			*/
27839: 			ielem->nodeLine,
27840: 			attr->name, nsName, 0,
27841: 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27842: 		    if (ret == -1) {
27843: 			VERROR_INT("xmlSchemaDocWalk",
27844: 			    "calling xmlSchemaValidatorPushAttribute()");
27845: 			goto internal_error;
27846: 		    }
27847: 		    attr = attr->next;
27848: 		} while (attr);
27849: 	    }
27850: 	    /*
27851: 	    * Validate the element.
27852: 	    */
27853: 	    ret = xmlSchemaValidateElem(vctxt);
27854: 	    if (ret != 0) {
27855: 		if (ret == -1) {
27856: 		    VERROR_INT("xmlSchemaDocWalk",
27857: 			"calling xmlSchemaValidateElem()");
27858: 		    goto internal_error;
27859: 		}
27860: 		/*
27861: 		* Don't stop validation; just skip the content
27862: 		* of this element.
27863: 		*/
27864: 		goto leave_node;
27865: 	    }
27866: 	    if ((vctxt->skipDepth != -1) &&
27867: 		(vctxt->depth >= vctxt->skipDepth))
27868: 		goto leave_node;
27869: 	} else if ((node->type == XML_TEXT_NODE) ||
27870: 	    (node->type == XML_CDATA_SECTION_NODE)) {
27871: 	    /*
27872: 	    * Process character content.
27873: 	    */
27874: 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27875: 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27876: 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27877: 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27878: 	    if (ret < 0) {
27879: 		VERROR_INT("xmlSchemaVDocWalk",
27880: 		    "calling xmlSchemaVPushText()");
27881: 		goto internal_error;
27882: 	    }
27883: 	    /*
27884: 	    * DOC VAL TODO: Should we skip further validation of the
27885: 	    * element content here?
27886: 	    */
27887: 	} else if ((node->type == XML_ENTITY_NODE) ||
27888: 	    (node->type == XML_ENTITY_REF_NODE)) {
27889: 	    /*
27890: 	    * DOC VAL TODO: What to do with entities?
27891: 	    */
27892: 	    VERROR_INT("xmlSchemaVDocWalk",
27893: 		"there is at least one entity reference in the node-tree "
27894: 		"currently being validated. Processing of entities with "
27895: 		"this XML Schema processor is not supported (yet). Please "
27896: 		"substitute entities before validation.");
27897: 	    goto internal_error;
27898: 	} else {
27899: 	    goto leave_node;
27900: 	    /*
27901: 	    * DOC VAL TODO: XInclude nodes, etc.
27902: 	    */
27903: 	}
27904: 	/*
27905: 	* Walk the doc.
27906: 	*/
27907: 	if (node->children != NULL) {
27908: 	    node = node->children;
27909: 	    continue;
27910: 	}
27911: leave_node:
27912: 	if (node->type == XML_ELEMENT_NODE) {
27913: 	    /*
27914: 	    * Leaving the scope of an element.
27915: 	    */
27916: 	    if (node != vctxt->inode->node) {
27917: 		VERROR_INT("xmlSchemaVDocWalk",
27918: 		    "element position mismatch");
27919: 		goto internal_error;
27920: 	    }
27921: 	    ret = xmlSchemaValidatorPopElem(vctxt);
27922: 	    if (ret != 0) {
27923: 		if (ret < 0) {
27924: 		    VERROR_INT("xmlSchemaVDocWalk",
27925: 			"calling xmlSchemaValidatorPopElem()");
27926: 		    goto internal_error;
27927: 		}
27928: 	    }
27929: 	    if (node == valRoot)
27930: 		goto exit;
27931: 	}
27932: next_sibling:
27933: 	if (node->next != NULL)
27934: 	    node = node->next;
27935: 	else {
27936: 	    node = node->parent;
27937: 	    goto leave_node;
27938: 	}
27939:     }
27940: 
27941: exit:
27942:     return (ret);
27943: internal_error:
27944:     return (-1);
27945: }
27946: 
27947: static int
27948: xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27949:     /*
27950:     * Some initialization.
27951:     */
27952:     vctxt->err = 0;
27953:     vctxt->nberrors = 0;
27954:     vctxt->depth = -1;
27955:     vctxt->skipDepth = -1;
27956:     vctxt->xsiAssemble = 0;
27957:     vctxt->hasKeyrefs = 0;
27958: #ifdef ENABLE_IDC_NODE_TABLES_TEST
27959:     vctxt->createIDCNodeTables = 1;
27960: #else
27961:     vctxt->createIDCNodeTables = 0;
27962: #endif
27963:     /*
27964:     * Create a schema + parser if necessary.
27965:     */
27966:     if (vctxt->schema == NULL) {
27967: 	xmlSchemaParserCtxtPtr pctxt;
27968: 
27969: 	vctxt->xsiAssemble = 1;
27970: 	/*
27971: 	* If not schema was given then we will create a schema
27972: 	* dynamically using XSI schema locations.
27973: 	*
27974: 	* Create the schema parser context.
27975: 	*/
27976: 	if ((vctxt->pctxt == NULL) &&
27977: 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27978: 	   return (-1);
27979: 	pctxt = vctxt->pctxt;
27980: 	pctxt->xsiAssemble = 1;
27981: 	/*
27982: 	* Create the schema.
27983: 	*/
27984: 	vctxt->schema = xmlSchemaNewSchema(pctxt);
27985: 	if (vctxt->schema == NULL)
27986: 	    return (-1);
27987: 	/*
27988: 	* Create the schema construction context.
27989: 	*/
27990: 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27991: 	if (pctxt->constructor == NULL)
27992: 	    return(-1);
27993: 	pctxt->constructor->mainSchema = vctxt->schema;
27994: 	/*
27995: 	* Take ownership of the constructor to be able to free it.
27996: 	*/
27997: 	pctxt->ownsConstructor = 1;
27998:     }
27999:     /*
28000:     * Augment the IDC definitions for the main schema and all imported ones
28001:     * NOTE: main schema if the first in the imported list
28002:     */
28003:     xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
28004: 
28005:     return(0);
28006: }
28007: 
28008: static void
28009: xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28010:     if (vctxt->xsiAssemble) {
28011: 	if (vctxt->schema != NULL) {
28012: 	    xmlSchemaFree(vctxt->schema);
28013: 	    vctxt->schema = NULL;
28014: 	}
28015:     }
28016:     xmlSchemaClearValidCtxt(vctxt);
28017: }
28018: 
28019: static int
28020: xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28021: {
28022:     int ret = 0;
28023: 
28024:     if (xmlSchemaPreRun(vctxt) < 0)
28025:         return(-1);
28026: 
28027:     if (vctxt->doc != NULL) {
28028: 	/*
28029: 	 * Tree validation.
28030: 	 */
28031: 	ret = xmlSchemaVDocWalk(vctxt);
28032: #ifdef LIBXML_READER_ENABLED
28033:     } else if (vctxt->reader != NULL) {
28034: 	/*
28035: 	 * XML Reader validation.
28036: 	 */
28037: #ifdef XML_SCHEMA_READER_ENABLED
28038: 	ret = xmlSchemaVReaderWalk(vctxt);
28039: #endif
28040: #endif
28041:     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28042: 	/*
28043: 	 * SAX validation.
28044: 	 */
28045: 	ret = xmlParseDocument(vctxt->parserCtxt);
28046:     } else {
28047: 	VERROR_INT("xmlSchemaVStart",
28048: 	    "no instance to validate");
28049: 	ret = -1;
28050:     }
28051: 
28052:     xmlSchemaPostRun(vctxt);
28053:     if (ret == 0)
28054: 	ret = vctxt->err;
28055:     return (ret);
28056: }
28057: 
28058: /**
28059:  * xmlSchemaValidateOneElement:
28060:  * @ctxt:  a schema validation context
28061:  * @elem:  an element node
28062:  *
28063:  * Validate a branch of a tree, starting with the given @elem.
28064:  *
28065:  * Returns 0 if the element and its subtree is valid, a positive error
28066:  * code number otherwise and -1 in case of an internal or API error.
28067:  */
28068: int
28069: xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28070: {
28071:     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28072: 	return (-1);
28073: 
28074:     if (ctxt->schema == NULL)
28075: 	return (-1);
28076: 
28077:     ctxt->doc = elem->doc;
28078:     ctxt->node = elem;
28079:     ctxt->validationRoot = elem;
28080:     return(xmlSchemaVStart(ctxt));
28081: }
28082: 
28083: /**
28084:  * xmlSchemaValidateDoc:
28085:  * @ctxt:  a schema validation context
28086:  * @doc:  a parsed document tree
28087:  *
28088:  * Validate a document tree in memory.
28089:  *
28090:  * Returns 0 if the document is schemas valid, a positive error code
28091:  *     number otherwise and -1 in case of internal or API error.
28092:  */
28093: int
28094: xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28095: {
28096:     if ((ctxt == NULL) || (doc == NULL))
28097:         return (-1);
28098: 
28099:     ctxt->doc = doc;
28100:     ctxt->node = xmlDocGetRootElement(doc);
28101:     if (ctxt->node == NULL) {
28102:         xmlSchemaCustomErr(ACTXT_CAST ctxt,
28103: 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28104: 	    (xmlNodePtr) doc, NULL,
28105: 	    "The document has no document element", NULL, NULL);
28106:         return (ctxt->err);
28107:     }
28108:     ctxt->validationRoot = ctxt->node;
28109:     return (xmlSchemaVStart(ctxt));
28110: }
28111: 
28112: 
28113: /************************************************************************
28114:  * 									*
28115:  * 		Function and data for SAX streaming API			*
28116:  * 									*
28117:  ************************************************************************/
28118: typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28119: typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28120: 
28121: struct _xmlSchemaSplitSAXData {
28122:     xmlSAXHandlerPtr      user_sax;
28123:     void                 *user_data;
28124:     xmlSchemaValidCtxtPtr ctxt;
28125:     xmlSAXHandlerPtr      schemas_sax;
28126: };
28127: 
28128: #define XML_SAX_PLUG_MAGIC 0xdc43ba21
28129: 
28130: struct _xmlSchemaSAXPlug {
28131:     unsigned int magic;
28132: 
28133:     /* the original callbacks informations */
28134:     xmlSAXHandlerPtr     *user_sax_ptr;
28135:     xmlSAXHandlerPtr      user_sax;
28136:     void                **user_data_ptr;
28137:     void                 *user_data;
28138: 
28139:     /* the block plugged back and validation informations */
28140:     xmlSAXHandler         schemas_sax;
28141:     xmlSchemaValidCtxtPtr ctxt;
28142: };
28143: 
28144: /* All those functions just bounces to the user provided SAX handlers */
28145: static void
28146: internalSubsetSplit(void *ctx, const xmlChar *name,
28147: 	       const xmlChar *ExternalID, const xmlChar *SystemID)
28148: {
28149:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28150:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28151:         (ctxt->user_sax->internalSubset != NULL))
28152: 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28153: 	                               SystemID);
28154: }
28155: 
28156: static int
28157: isStandaloneSplit(void *ctx)
28158: {
28159:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28160:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28161:         (ctxt->user_sax->isStandalone != NULL))
28162: 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
28163:     return(0);
28164: }
28165: 
28166: static int
28167: hasInternalSubsetSplit(void *ctx)
28168: {
28169:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28170:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28171:         (ctxt->user_sax->hasInternalSubset != NULL))
28172: 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28173:     return(0);
28174: }
28175: 
28176: static int
28177: hasExternalSubsetSplit(void *ctx)
28178: {
28179:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28180:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28181:         (ctxt->user_sax->hasExternalSubset != NULL))
28182: 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28183:     return(0);
28184: }
28185: 
28186: static void
28187: externalSubsetSplit(void *ctx, const xmlChar *name,
28188: 	       const xmlChar *ExternalID, const xmlChar *SystemID)
28189: {
28190:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28191:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28192:         (ctxt->user_sax->externalSubset != NULL))
28193: 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28194: 	                               SystemID);
28195: }
28196: 
28197: static xmlParserInputPtr
28198: resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28199: {
28200:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28201:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28202:         (ctxt->user_sax->resolveEntity != NULL))
28203: 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28204: 	                                     systemId));
28205:     return(NULL);
28206: }
28207: 
28208: static xmlEntityPtr
28209: getEntitySplit(void *ctx, const xmlChar *name)
28210: {
28211:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28212:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28213:         (ctxt->user_sax->getEntity != NULL))
28214: 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28215:     return(NULL);
28216: }
28217: 
28218: static xmlEntityPtr
28219: getParameterEntitySplit(void *ctx, const xmlChar *name)
28220: {
28221:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28222:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28223:         (ctxt->user_sax->getParameterEntity != NULL))
28224: 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28225:     return(NULL);
28226: }
28227: 
28228: 
28229: static void
28230: entityDeclSplit(void *ctx, const xmlChar *name, int type,
28231:           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28232: {
28233:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28234:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28235:         (ctxt->user_sax->entityDecl != NULL))
28236: 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28237: 	                           systemId, content);
28238: }
28239: 
28240: static void
28241: attributeDeclSplit(void *ctx, const xmlChar * elem,
28242:                    const xmlChar * name, int type, int def,
28243:                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
28244: {
28245:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28246:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28247:         (ctxt->user_sax->attributeDecl != NULL)) {
28248: 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28249: 	                              def, defaultValue, tree);
28250:     } else {
28251: 	xmlFreeEnumeration(tree);
28252:     }
28253: }
28254: 
28255: static void
28256: elementDeclSplit(void *ctx, const xmlChar *name, int type,
28257: 	    xmlElementContentPtr content)
28258: {
28259:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28260:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28261:         (ctxt->user_sax->elementDecl != NULL))
28262: 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28263: }
28264: 
28265: static void
28266: notationDeclSplit(void *ctx, const xmlChar *name,
28267: 	     const xmlChar *publicId, const xmlChar *systemId)
28268: {
28269:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28270:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28271:         (ctxt->user_sax->notationDecl != NULL))
28272: 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28273: 	                             systemId);
28274: }
28275: 
28276: static void
28277: unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28278: 		   const xmlChar *publicId, const xmlChar *systemId,
28279: 		   const xmlChar *notationName)
28280: {
28281:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28282:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28283:         (ctxt->user_sax->unparsedEntityDecl != NULL))
28284: 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28285: 	                                   systemId, notationName);
28286: }
28287: 
28288: static void
28289: setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28290: {
28291:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28292:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28293:         (ctxt->user_sax->setDocumentLocator != NULL))
28294: 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28295: }
28296: 
28297: static void
28298: startDocumentSplit(void *ctx)
28299: {
28300:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28301:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28302:         (ctxt->user_sax->startDocument != NULL))
28303: 	ctxt->user_sax->startDocument(ctxt->user_data);
28304: }
28305: 
28306: static void
28307: endDocumentSplit(void *ctx)
28308: {
28309:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28310:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28311:         (ctxt->user_sax->endDocument != NULL))
28312: 	ctxt->user_sax->endDocument(ctxt->user_data);
28313: }
28314: 
28315: static void
28316: processingInstructionSplit(void *ctx, const xmlChar *target,
28317:                       const xmlChar *data)
28318: {
28319:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28320:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28321:         (ctxt->user_sax->processingInstruction != NULL))
28322: 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28323: }
28324: 
28325: static void
28326: commentSplit(void *ctx, const xmlChar *value)
28327: {
28328:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28329:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28330:         (ctxt->user_sax->comment != NULL))
28331: 	ctxt->user_sax->comment(ctxt->user_data, value);
28332: }
28333: 
28334: /*
28335:  * Varargs error callbacks to the user application, harder ...
28336:  */
28337: 
28338: static void XMLCDECL
28339: warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28340:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28341:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28342:         (ctxt->user_sax->warning != NULL)) {
28343: 	TODO
28344:     }
28345: }
28346: static void XMLCDECL
28347: errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28348:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28349:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28350:         (ctxt->user_sax->error != NULL)) {
28351: 	TODO
28352:     }
28353: }
28354: static void XMLCDECL
28355: fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28356:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28357:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28358:         (ctxt->user_sax->fatalError != NULL)) {
28359: 	TODO
28360:     }
28361: }
28362: 
28363: /*
28364:  * Those are function where both the user handler and the schemas handler
28365:  * need to be called.
28366:  */
28367: static void
28368: charactersSplit(void *ctx, const xmlChar *ch, int len)
28369: {
28370:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28371:     if (ctxt == NULL)
28372:         return;
28373:     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28374: 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
28375:     if (ctxt->ctxt != NULL)
28376: 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28377: }
28378: 
28379: static void
28380: ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28381: {
28382:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28383:     if (ctxt == NULL)
28384:         return;
28385:     if ((ctxt->user_sax != NULL) &&
28386:         (ctxt->user_sax->ignorableWhitespace != NULL))
28387: 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28388:     if (ctxt->ctxt != NULL)
28389: 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28390: }
28391: 
28392: static void
28393: cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28394: {
28395:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28396:     if (ctxt == NULL)
28397:         return;
28398:     if ((ctxt->user_sax != NULL) &&
28399:         (ctxt->user_sax->cdataBlock != NULL))
28400: 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28401:     if (ctxt->ctxt != NULL)
28402: 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28403: }
28404: 
28405: static void
28406: referenceSplit(void *ctx, const xmlChar *name)
28407: {
28408:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28409:     if (ctxt == NULL)
28410:         return;
28411:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28412:         (ctxt->user_sax->reference != NULL))
28413: 	ctxt->user_sax->reference(ctxt->user_data, name);
28414:     if (ctxt->ctxt != NULL)
28415:         xmlSchemaSAXHandleReference(ctxt->user_data, name);
28416: }
28417: 
28418: static void
28419: startElementNsSplit(void *ctx, const xmlChar * localname,
28420: 		    const xmlChar * prefix, const xmlChar * URI,
28421: 		    int nb_namespaces, const xmlChar ** namespaces,
28422: 		    int nb_attributes, int nb_defaulted,
28423: 		    const xmlChar ** attributes) {
28424:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28425:     if (ctxt == NULL)
28426:         return;
28427:     if ((ctxt->user_sax != NULL) &&
28428:         (ctxt->user_sax->startElementNs != NULL))
28429: 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28430: 	                               URI, nb_namespaces, namespaces,
28431: 				       nb_attributes, nb_defaulted,
28432: 				       attributes);
28433:     if (ctxt->ctxt != NULL)
28434: 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28435: 	                                 URI, nb_namespaces, namespaces,
28436: 					 nb_attributes, nb_defaulted,
28437: 					 attributes);
28438: }
28439: 
28440: static void
28441: endElementNsSplit(void *ctx, const xmlChar * localname,
28442: 		    const xmlChar * prefix, const xmlChar * URI) {
28443:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28444:     if (ctxt == NULL)
28445:         return;
28446:     if ((ctxt->user_sax != NULL) &&
28447:         (ctxt->user_sax->endElementNs != NULL))
28448: 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28449:     if (ctxt->ctxt != NULL)
28450: 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28451: }
28452: 
28453: /**
28454:  * xmlSchemaSAXPlug:
28455:  * @ctxt:  a schema validation context
28456:  * @sax:  a pointer to the original xmlSAXHandlerPtr
28457:  * @user_data:  a pointer to the original SAX user data pointer
28458:  *
28459:  * Plug a SAX based validation layer in a SAX parsing event flow.
28460:  * The original @saxptr and @dataptr data are replaced by new pointers
28461:  * but the calls to the original will be maintained.
28462:  *
28463:  * Returns a pointer to a data structure needed to unplug the validation layer
28464:  *         or NULL in case of errors.
28465:  */
28466: xmlSchemaSAXPlugPtr
28467: xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28468: 		 xmlSAXHandlerPtr *sax, void **user_data)
28469: {
28470:     xmlSchemaSAXPlugPtr ret;
28471:     xmlSAXHandlerPtr old_sax;
28472: 
28473:     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28474:         return(NULL);
28475: 
28476:     /*
28477:      * We only allow to plug into SAX2 event streams
28478:      */
28479:     old_sax = *sax;
28480:     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28481:         return(NULL);
28482:     if ((old_sax != NULL) &&
28483:         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28484:         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28485:         return(NULL);
28486: 
28487:     /*
28488:      * everything seems right allocate the local data needed for that layer
28489:      */
28490:     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28491:     if (ret == NULL) {
28492:         return(NULL);
28493:     }
28494:     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28495:     ret->magic = XML_SAX_PLUG_MAGIC;
28496:     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28497:     ret->ctxt = ctxt;
28498:     ret->user_sax_ptr = sax;
28499:     ret->user_sax = old_sax;
28500:     if (old_sax == NULL) {
28501:         /*
28502: 	 * go direct, no need for the split block and functions.
28503: 	 */
28504: 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28505: 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28506: 	/*
28507: 	 * Note that we use the same text-function for both, to prevent
28508: 	 * the parser from testing for ignorable whitespace.
28509: 	 */
28510: 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28511: 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28512: 
28513: 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28514: 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28515: 
28516: 	ret->user_data = ctxt;
28517: 	*user_data = ctxt;
28518:     } else {
28519:        /*
28520:         * for each callback unused by Schemas initialize it to the Split
28521: 	* routine only if non NULL in the user block, this can speed up
28522: 	* things at the SAX level.
28523: 	*/
28524:         if (old_sax->internalSubset != NULL)
28525:             ret->schemas_sax.internalSubset = internalSubsetSplit;
28526:         if (old_sax->isStandalone != NULL)
28527:             ret->schemas_sax.isStandalone = isStandaloneSplit;
28528:         if (old_sax->hasInternalSubset != NULL)
28529:             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28530:         if (old_sax->hasExternalSubset != NULL)
28531:             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28532:         if (old_sax->resolveEntity != NULL)
28533:             ret->schemas_sax.resolveEntity = resolveEntitySplit;
28534:         if (old_sax->getEntity != NULL)
28535:             ret->schemas_sax.getEntity = getEntitySplit;
28536:         if (old_sax->entityDecl != NULL)
28537:             ret->schemas_sax.entityDecl = entityDeclSplit;
28538:         if (old_sax->notationDecl != NULL)
28539:             ret->schemas_sax.notationDecl = notationDeclSplit;
28540:         if (old_sax->attributeDecl != NULL)
28541:             ret->schemas_sax.attributeDecl = attributeDeclSplit;
28542:         if (old_sax->elementDecl != NULL)
28543:             ret->schemas_sax.elementDecl = elementDeclSplit;
28544:         if (old_sax->unparsedEntityDecl != NULL)
28545:             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28546:         if (old_sax->setDocumentLocator != NULL)
28547:             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28548:         if (old_sax->startDocument != NULL)
28549:             ret->schemas_sax.startDocument = startDocumentSplit;
28550:         if (old_sax->endDocument != NULL)
28551:             ret->schemas_sax.endDocument = endDocumentSplit;
28552:         if (old_sax->processingInstruction != NULL)
28553:             ret->schemas_sax.processingInstruction = processingInstructionSplit;
28554:         if (old_sax->comment != NULL)
28555:             ret->schemas_sax.comment = commentSplit;
28556:         if (old_sax->warning != NULL)
28557:             ret->schemas_sax.warning = warningSplit;
28558:         if (old_sax->error != NULL)
28559:             ret->schemas_sax.error = errorSplit;
28560:         if (old_sax->fatalError != NULL)
28561:             ret->schemas_sax.fatalError = fatalErrorSplit;
28562:         if (old_sax->getParameterEntity != NULL)
28563:             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28564:         if (old_sax->externalSubset != NULL)
28565:             ret->schemas_sax.externalSubset = externalSubsetSplit;
28566: 
28567: 	/*
28568: 	 * the 6 schemas callback have to go to the splitter functions
28569: 	 * Note that we use the same text-function for ignorableWhitespace
28570: 	 * if possible, to prevent the parser from testing for ignorable
28571: 	 * whitespace.
28572: 	 */
28573:         ret->schemas_sax.characters = charactersSplit;
28574: 	if ((old_sax->ignorableWhitespace != NULL) &&
28575: 	    (old_sax->ignorableWhitespace != old_sax->characters))
28576: 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28577: 	else
28578: 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
28579:         ret->schemas_sax.cdataBlock = cdataBlockSplit;
28580:         ret->schemas_sax.reference = referenceSplit;
28581:         ret->schemas_sax.startElementNs = startElementNsSplit;
28582:         ret->schemas_sax.endElementNs = endElementNsSplit;
28583: 
28584: 	ret->user_data_ptr = user_data;
28585: 	ret->user_data = *user_data;
28586: 	*user_data = ret;
28587:     }
28588: 
28589:     /*
28590:      * plug the pointers back.
28591:      */
28592:     *sax = &(ret->schemas_sax);
28593:     ctxt->sax = *sax;
28594:     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28595:     xmlSchemaPreRun(ctxt);
28596:     return(ret);
28597: }
28598: 
28599: /**
28600:  * xmlSchemaSAXUnplug:
28601:  * @plug:  a data structure returned by xmlSchemaSAXPlug
28602:  *
28603:  * Unplug a SAX based validation layer in a SAX parsing event flow.
28604:  * The original pointers used in the call are restored.
28605:  *
28606:  * Returns 0 in case of success and -1 in case of failure.
28607:  */
28608: int
28609: xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28610: {
28611:     xmlSAXHandlerPtr *sax;
28612:     void **user_data;
28613: 
28614:     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28615:         return(-1);
28616:     plug->magic = 0;
28617: 
28618:     xmlSchemaPostRun(plug->ctxt);
28619:     /* restore the data */
28620:     sax = plug->user_sax_ptr;
28621:     *sax = plug->user_sax;
28622:     if (plug->user_sax != NULL) {
28623: 	user_data = plug->user_data_ptr;
28624: 	*user_data = plug->user_data;
28625:     }
28626: 
28627:     /* free and return */
28628:     xmlFree(plug);
28629:     return(0);
28630: }
28631: 
28632: /**
28633:  * xmlSchemaValidateStream:
28634:  * @ctxt:  a schema validation context
28635:  * @input:  the input to use for reading the data
28636:  * @enc:  an optional encoding information
28637:  * @sax:  a SAX handler for the resulting events
28638:  * @user_data:  the context to provide to the SAX handler.
28639:  *
28640:  * Validate an input based on a flow of SAX event from the parser
28641:  * and forward the events to the @sax handler with the provided @user_data
28642:  * the user provided @sax handler must be a SAX2 one.
28643:  *
28644:  * Returns 0 if the document is schemas valid, a positive error code
28645:  *     number otherwise and -1 in case of internal or API error.
28646:  */
28647: int
28648: xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28649:                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
28650:                         xmlSAXHandlerPtr sax, void *user_data)
28651: {
28652:     xmlSchemaSAXPlugPtr plug = NULL;
28653:     xmlSAXHandlerPtr old_sax = NULL;
28654:     xmlParserCtxtPtr pctxt = NULL;
28655:     xmlParserInputPtr inputStream = NULL;
28656:     int ret;
28657: 
28658:     if ((ctxt == NULL) || (input == NULL))
28659:         return (-1);
28660: 
28661:     /*
28662:      * prepare the parser
28663:      */
28664:     pctxt = xmlNewParserCtxt();
28665:     if (pctxt == NULL)
28666:         return (-1);
28667:     old_sax = pctxt->sax;
28668:     pctxt->sax = sax;
28669:     pctxt->userData = user_data;
28670: #if 0
28671:     if (options)
28672:         xmlCtxtUseOptions(pctxt, options);
28673: #endif
28674:     pctxt->linenumbers = 1;
28675: 
28676:     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28677:     if (inputStream == NULL) {
28678:         ret = -1;
28679: 	goto done;
28680:     }
28681:     inputPush(pctxt, inputStream);
28682:     ctxt->parserCtxt = pctxt;
28683:     ctxt->input = input;
28684: 
28685:     /*
28686:      * Plug the validation and launch the parsing
28687:      */
28688:     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28689:     if (plug == NULL) {
28690:         ret = -1;
28691: 	goto done;
28692:     }
28693:     ctxt->input = input;
28694:     ctxt->enc = enc;
28695:     ctxt->sax = pctxt->sax;
28696:     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28697:     ret = xmlSchemaVStart(ctxt);
28698: 
28699:     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28700: 	ret = ctxt->parserCtxt->errNo;
28701: 	if (ret == 0)
28702: 	    ret = 1;
28703:     }
28704: 
28705: done:
28706:     ctxt->parserCtxt = NULL;
28707:     ctxt->sax = NULL;
28708:     ctxt->input = NULL;
28709:     if (plug != NULL) {
28710:         xmlSchemaSAXUnplug(plug);
28711:     }
28712:     /* cleanup */
28713:     if (pctxt != NULL) {
28714: 	pctxt->sax = old_sax;
28715: 	xmlFreeParserCtxt(pctxt);
28716:     }
28717:     return (ret);
28718: }
28719: 
28720: /**
28721:  * xmlSchemaValidateFile:
28722:  * @ctxt: a schema validation context
28723:  * @filename: the URI of the instance
28724:  * @options: a future set of options, currently unused
28725:  *
28726:  * Do a schemas validation of the given resource, it will use the
28727:  * SAX streamable validation internally.
28728:  *
28729:  * Returns 0 if the document is valid, a positive error code
28730:  *     number otherwise and -1 in case of an internal or API error.
28731:  */
28732: int
28733: xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28734:                       const char * filename,
28735: 		      int options ATTRIBUTE_UNUSED)
28736: {
28737:     int ret;
28738:     xmlParserInputBufferPtr input;
28739: 
28740:     if ((ctxt == NULL) || (filename == NULL))
28741:         return (-1);
28742: 
28743:     input = xmlParserInputBufferCreateFilename(filename,
28744: 	XML_CHAR_ENCODING_NONE);
28745:     if (input == NULL)
28746: 	return (-1);
28747:     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
28748: 	NULL, NULL);
28749:     return (ret);
28750: }
28751: 
28752: /**
28753:  * xmlSchemaValidCtxtGetParserCtxt:
28754:  * @ctxt: a schema validation context
28755:  *
28756:  * allow access to the parser context of the schema validation context
28757:  *
28758:  * Returns the parser context of the schema validation context or NULL
28759:  *         in case of error.
28760:  */
28761: xmlParserCtxtPtr
28762: xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28763: {
28764:     if (ctxt == NULL)
28765:         return(NULL);
28766:     return (ctxt->parserCtxt);
28767: }
28768: 
28769: #define bottom_xmlschemas
28770: #include "elfgcchack.h"
28771: #endif /* LIBXML_SCHEMAS_ENABLED */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>