File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / xmlschemas.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 19:53:31 2014 UTC (9 years, 11 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_9_1p0, v2_9_1, HEAD
libxml2 2.9.1

    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:     char *filename;
  979: 
  980:     int err;
  981:     int nberrors;
  982: 
  983:     xmlNodePtr node;
  984:     xmlNodePtr cur;
  985:     /* xmlSchemaTypePtr type; */
  986: 
  987:     xmlRegExecCtxtPtr regexp;
  988:     xmlSchemaValPtr value;
  989: 
  990:     int valueWS;
  991:     int options;
  992:     xmlNodePtr validationRoot;
  993:     xmlSchemaParserCtxtPtr pctxt;
  994:     int xsiAssemble;
  995: 
  996:     int depth;
  997:     xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
  998:     int sizeElemInfos;
  999:     xmlSchemaNodeInfoPtr inode; /* the current element information */
 1000: 
 1001:     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
 1002: 
 1003:     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
 1004:     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
 1005:     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
 1006: 
 1007:     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
 1008:     int nbIdcNodes;
 1009:     int sizeIdcNodes;
 1010: 
 1011:     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
 1012:     int nbIdcKeys;
 1013:     int sizeIdcKeys;
 1014: 
 1015:     int flags;
 1016: 
 1017:     xmlDictPtr dict;
 1018: 
 1019: #ifdef LIBXML_READER_ENABLED
 1020:     xmlTextReaderPtr reader;
 1021: #endif
 1022: 
 1023:     xmlSchemaAttrInfoPtr *attrInfos;
 1024:     int nbAttrInfos;
 1025:     int sizeAttrInfos;
 1026: 
 1027:     int skipDepth;
 1028:     xmlSchemaItemListPtr nodeQNames;
 1029:     int hasKeyrefs;
 1030:     int createIDCNodeTables;
 1031:     int psviExposeIDCNodeTables;
 1032: 
 1033:     /* Locator for error reporting in streaming mode */
 1034:     xmlSchemaValidityLocatorFunc locFunc;
 1035:     void *locCtxt;
 1036: };
 1037: 
 1038: /**
 1039:  * xmlSchemaSubstGroup:
 1040:  *
 1041:  *
 1042:  */
 1043: typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
 1044: typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
 1045: struct _xmlSchemaSubstGroup {
 1046:     xmlSchemaElementPtr head;
 1047:     xmlSchemaItemListPtr members;
 1048: };
 1049: 
 1050: /************************************************************************
 1051:  *									*
 1052:  *			Some predeclarations				*
 1053:  *									*
 1054:  ************************************************************************/
 1055: 
 1056: static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
 1057:                                  xmlSchemaPtr schema,
 1058:                                  xmlNodePtr node);
 1059: static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
 1060:                                  xmlSchemaPtr schema,
 1061:                                  xmlNodePtr node);
 1062: static int
 1063: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
 1064:                    xmlSchemaAbstractCtxtPtr ctxt);
 1065: static const xmlChar *
 1066: xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
 1067: static int
 1068: xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 1069:                      xmlNodePtr node);
 1070: static int
 1071: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
 1072:                        xmlSchemaParserCtxtPtr ctxt);
 1073: static void
 1074: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
 1075: static xmlSchemaWhitespaceValueType
 1076: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
 1077: static xmlSchemaTreeItemPtr
 1078: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 1079: 			 xmlNodePtr node, xmlSchemaTypeType type,
 1080: 			 int withParticle);
 1081: static const xmlChar *
 1082: xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
 1083: static xmlSchemaTypeLinkPtr
 1084: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
 1085: static void
 1086: xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 1087: 		     const char *funcName,
 1088: 		     const char *message);
 1089: static int
 1090: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
 1091: 			     xmlSchemaTypePtr type,
 1092: 			     xmlSchemaTypePtr baseType,
 1093: 			     int subset);
 1094: static void
 1095: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
 1096: 				   xmlSchemaParserCtxtPtr ctxt);
 1097: static void
 1098: xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
 1099: static xmlSchemaQNameRefPtr
 1100: xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 1101: 				xmlSchemaPtr schema,
 1102: 				xmlNodePtr node);
 1103: 
 1104: /************************************************************************
 1105:  *									*
 1106:  *			Helper functions			        *
 1107:  *									*
 1108:  ************************************************************************/
 1109: 
 1110: /**
 1111:  * xmlSchemaItemTypeToStr:
 1112:  * @type: the type of the schema item
 1113:  *
 1114:  * Returns the component name of a schema item.
 1115:  */
 1116: static const xmlChar *
 1117: xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
 1118: {
 1119:     switch (type) {
 1120: 	case XML_SCHEMA_TYPE_BASIC:
 1121: 	    return(BAD_CAST "simple type definition");
 1122: 	case XML_SCHEMA_TYPE_SIMPLE:
 1123: 	    return(BAD_CAST "simple type definition");
 1124: 	case XML_SCHEMA_TYPE_COMPLEX:
 1125: 	    return(BAD_CAST "complex type definition");
 1126: 	case XML_SCHEMA_TYPE_ELEMENT:
 1127: 	    return(BAD_CAST "element declaration");
 1128: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1129: 	    return(BAD_CAST "attribute use");
 1130: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1131: 	    return(BAD_CAST "attribute declaration");
 1132: 	case XML_SCHEMA_TYPE_GROUP:
 1133: 	    return(BAD_CAST "model group definition");
 1134: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1135: 	    return(BAD_CAST "attribute group definition");
 1136: 	case XML_SCHEMA_TYPE_NOTATION:
 1137: 	    return(BAD_CAST "notation declaration");
 1138: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1139: 	    return(BAD_CAST "model group (sequence)");
 1140: 	case XML_SCHEMA_TYPE_CHOICE:
 1141: 	    return(BAD_CAST "model group (choice)");
 1142: 	case XML_SCHEMA_TYPE_ALL:
 1143: 	    return(BAD_CAST "model group (all)");
 1144: 	case XML_SCHEMA_TYPE_PARTICLE:
 1145: 	    return(BAD_CAST "particle");
 1146: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1147: 	    return(BAD_CAST "unique identity-constraint");
 1148: 	    /* return(BAD_CAST "IDC (unique)"); */
 1149: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1150: 	    return(BAD_CAST "key identity-constraint");
 1151: 	    /* return(BAD_CAST "IDC (key)"); */
 1152: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1153: 	    return(BAD_CAST "keyref identity-constraint");
 1154: 	    /* return(BAD_CAST "IDC (keyref)"); */
 1155: 	case XML_SCHEMA_TYPE_ANY:
 1156: 	    return(BAD_CAST "wildcard (any)");
 1157: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1158: 	    return(BAD_CAST "[helper component] QName reference");
 1159: 	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 1160: 	    return(BAD_CAST "[helper component] attribute use prohibition");
 1161: 	default:
 1162: 	    return(BAD_CAST "Not a schema component");
 1163:     }
 1164: }
 1165: 
 1166: /**
 1167:  * xmlSchemaGetComponentTypeStr:
 1168:  * @type: the type of the schema item
 1169:  *
 1170:  * Returns the component name of a schema item.
 1171:  */
 1172: static const xmlChar *
 1173: xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
 1174: {
 1175:     switch (item->type) {
 1176: 	case XML_SCHEMA_TYPE_BASIC:
 1177: 	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
 1178: 		return(BAD_CAST "complex type definition");
 1179: 	    else
 1180: 		return(BAD_CAST "simple type definition");
 1181: 	default:
 1182: 	    return(xmlSchemaItemTypeToStr(item->type));
 1183:     }
 1184: }
 1185: 
 1186: /**
 1187:  * xmlSchemaGetComponentNode:
 1188:  * @item: a schema component
 1189:  *
 1190:  * Returns node associated with the schema component.
 1191:  * NOTE that such a node need not be available; plus, a component's
 1192:  * node need not to reflect the component directly, since there is no
 1193:  * one-to-one relationship between the XML Schema representation and
 1194:  * the component representation.
 1195:  */
 1196: static xmlNodePtr
 1197: xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
 1198: {
 1199:     switch (item->type) {
 1200: 	case XML_SCHEMA_TYPE_ELEMENT:
 1201: 	    return (((xmlSchemaElementPtr) item)->node);
 1202: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1203: 	    return (((xmlSchemaAttributePtr) item)->node);
 1204: 	case XML_SCHEMA_TYPE_COMPLEX:
 1205: 	case XML_SCHEMA_TYPE_SIMPLE:
 1206: 	    return (((xmlSchemaTypePtr) item)->node);
 1207: 	case XML_SCHEMA_TYPE_ANY:
 1208: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1209: 	    return (((xmlSchemaWildcardPtr) item)->node);
 1210: 	case XML_SCHEMA_TYPE_PARTICLE:
 1211: 	    return (((xmlSchemaParticlePtr) item)->node);
 1212: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1213: 	case XML_SCHEMA_TYPE_CHOICE:
 1214: 	case XML_SCHEMA_TYPE_ALL:
 1215: 	    return (((xmlSchemaModelGroupPtr) item)->node);
 1216: 	case XML_SCHEMA_TYPE_GROUP:
 1217: 	    return (((xmlSchemaModelGroupDefPtr) item)->node);
 1218: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1219: 	    return (((xmlSchemaAttributeGroupPtr) item)->node);
 1220: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1221: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1222: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1223: 	    return (((xmlSchemaIDCPtr) item)->node);
 1224: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1225: 	    return(((xmlSchemaQNameRefPtr) item)->node);
 1226: 	/* TODO: What to do with NOTATIONs?
 1227: 	case XML_SCHEMA_TYPE_NOTATION:
 1228: 	    return (((xmlSchemaNotationPtr) item)->node);
 1229: 	*/
 1230: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1231: 	    return (((xmlSchemaAttributeUsePtr) item)->node);
 1232: 	default:
 1233: 	    return (NULL);
 1234:     }
 1235: }
 1236: 
 1237: #if 0
 1238: /**
 1239:  * xmlSchemaGetNextComponent:
 1240:  * @item: a schema component
 1241:  *
 1242:  * Returns the next sibling of the schema component.
 1243:  */
 1244: static xmlSchemaBasicItemPtr
 1245: xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
 1246: {
 1247:     switch (item->type) {
 1248: 	case XML_SCHEMA_TYPE_ELEMENT:
 1249: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
 1250: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1251: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
 1252: 	case XML_SCHEMA_TYPE_COMPLEX:
 1253: 	case XML_SCHEMA_TYPE_SIMPLE:
 1254: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
 1255: 	case XML_SCHEMA_TYPE_ANY:
 1256: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1257: 	    return (NULL);
 1258: 	case XML_SCHEMA_TYPE_PARTICLE:
 1259: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
 1260: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1261: 	case XML_SCHEMA_TYPE_CHOICE:
 1262: 	case XML_SCHEMA_TYPE_ALL:
 1263: 	    return (NULL);
 1264: 	case XML_SCHEMA_TYPE_GROUP:
 1265: 	    return (NULL);
 1266: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1267: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
 1268: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1269: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1270: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1271: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
 1272: 	default:
 1273: 	    return (NULL);
 1274:     }
 1275: }
 1276: #endif
 1277: 
 1278: 
 1279: /**
 1280:  * xmlSchemaFormatQName:
 1281:  * @buf: the string buffer
 1282:  * @namespaceName:  the namespace name
 1283:  * @localName: the local name
 1284:  *
 1285:  * Returns the given QName in the format "{namespaceName}localName" or
 1286:  * just "localName" if @namespaceName is NULL.
 1287:  *
 1288:  * Returns the localName if @namespaceName is NULL, a formatted
 1289:  * string otherwise.
 1290:  */
 1291: static const xmlChar*
 1292: xmlSchemaFormatQName(xmlChar **buf,
 1293: 		     const xmlChar *namespaceName,
 1294: 		     const xmlChar *localName)
 1295: {
 1296:     FREE_AND_NULL(*buf)
 1297:     if (namespaceName != NULL) {
 1298: 	*buf = xmlStrdup(BAD_CAST "{");
 1299: 	*buf = xmlStrcat(*buf, namespaceName);
 1300: 	*buf = xmlStrcat(*buf, BAD_CAST "}");
 1301:     }
 1302:     if (localName != NULL) {
 1303: 	if (namespaceName == NULL)
 1304: 	    return(localName);
 1305: 	*buf = xmlStrcat(*buf, localName);
 1306:     } else {
 1307: 	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
 1308:     }
 1309:     return ((const xmlChar *) *buf);
 1310: }
 1311: 
 1312: static const xmlChar*
 1313: xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
 1314: {
 1315:     if (ns != NULL)
 1316: 	return (xmlSchemaFormatQName(buf, ns->href, localName));
 1317:     else
 1318: 	return (xmlSchemaFormatQName(buf, NULL, localName));
 1319: }
 1320: 
 1321: static const xmlChar *
 1322: xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
 1323: {
 1324:     switch (item->type) {
 1325: 	case XML_SCHEMA_TYPE_ELEMENT:
 1326: 	    return (((xmlSchemaElementPtr) item)->name);
 1327: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1328: 	    return (((xmlSchemaAttributePtr) item)->name);
 1329: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1330: 	    return (((xmlSchemaAttributeGroupPtr) item)->name);
 1331: 	case XML_SCHEMA_TYPE_BASIC:
 1332: 	case XML_SCHEMA_TYPE_SIMPLE:
 1333: 	case XML_SCHEMA_TYPE_COMPLEX:
 1334: 	    return (((xmlSchemaTypePtr) item)->name);
 1335: 	case XML_SCHEMA_TYPE_GROUP:
 1336: 	    return (((xmlSchemaModelGroupDefPtr) item)->name);
 1337: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1338: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1339: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1340: 	    return (((xmlSchemaIDCPtr) item)->name);
 1341: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1342: 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
 1343: 		return(xmlSchemaGetComponentName(
 1344: 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 1345: 	    } else
 1346: 		return(NULL);
 1347: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1348: 	    return (((xmlSchemaQNameRefPtr) item)->name);
 1349: 	case XML_SCHEMA_TYPE_NOTATION:
 1350: 	    return (((xmlSchemaNotationPtr) item)->name);
 1351: 	default:
 1352: 	    /*
 1353: 	    * Other components cannot have names.
 1354: 	    */
 1355: 	    break;
 1356:     }
 1357:     return (NULL);
 1358: }
 1359: 
 1360: #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
 1361: #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
 1362: /*
 1363: static const xmlChar *
 1364: xmlSchemaGetQNameRefName(void *ref)
 1365: {
 1366:     return(((xmlSchemaQNameRefPtr) ref)->name);
 1367: }
 1368: 
 1369: static const xmlChar *
 1370: xmlSchemaGetQNameRefTargetNs(void *ref)
 1371: {
 1372:     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
 1373: }
 1374: */
 1375: 
 1376: static const xmlChar *
 1377: xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
 1378: {
 1379:     switch (item->type) {
 1380: 	case XML_SCHEMA_TYPE_ELEMENT:
 1381: 	    return (((xmlSchemaElementPtr) item)->targetNamespace);
 1382: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1383: 	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
 1384: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1385: 	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
 1386: 	case XML_SCHEMA_TYPE_BASIC:
 1387: 	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
 1388: 	case XML_SCHEMA_TYPE_SIMPLE:
 1389: 	case XML_SCHEMA_TYPE_COMPLEX:
 1390: 	    return (((xmlSchemaTypePtr) item)->targetNamespace);
 1391: 	case XML_SCHEMA_TYPE_GROUP:
 1392: 	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
 1393: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1394: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1395: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1396: 	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
 1397: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1398: 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
 1399: 		return(xmlSchemaGetComponentTargetNs(
 1400: 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 1401: 	    }
 1402: 	    /* TODO: Will returning NULL break something? */
 1403: 	    break;
 1404: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1405: 	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
 1406: 	case XML_SCHEMA_TYPE_NOTATION:
 1407: 	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
 1408: 	default:
 1409: 	    /*
 1410: 	    * Other components cannot have names.
 1411: 	    */
 1412: 	    break;
 1413:     }
 1414:     return (NULL);
 1415: }
 1416: 
 1417: static const xmlChar*
 1418: xmlSchemaGetComponentQName(xmlChar **buf,
 1419: 			   void *item)
 1420: {
 1421:     return (xmlSchemaFormatQName(buf,
 1422: 	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
 1423: 	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
 1424: }
 1425: 
 1426: static const xmlChar*
 1427: xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
 1428: {
 1429:     xmlChar *str = NULL;
 1430: 
 1431:     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
 1432:     *buf = xmlStrcat(*buf, BAD_CAST " '");
 1433:     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
 1434: 	(xmlSchemaBasicItemPtr) item));
 1435:     *buf = xmlStrcat(*buf, BAD_CAST "'");
 1436:     FREE_AND_NULL(str);
 1437:     return(*buf);
 1438: }
 1439: 
 1440: static const xmlChar*
 1441: xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
 1442: {
 1443:     return(xmlSchemaGetComponentDesignation(buf, idc));
 1444: }
 1445: 
 1446: /**
 1447:  * xmlSchemaWildcardPCToString:
 1448:  * @pc: the type of processContents
 1449:  *
 1450:  * Returns a string representation of the type of
 1451:  * processContents.
 1452:  */
 1453: static const xmlChar *
 1454: xmlSchemaWildcardPCToString(int pc)
 1455: {
 1456:     switch (pc) {
 1457: 	case XML_SCHEMAS_ANY_SKIP:
 1458: 	    return (BAD_CAST "skip");
 1459: 	case XML_SCHEMAS_ANY_LAX:
 1460: 	    return (BAD_CAST "lax");
 1461: 	case XML_SCHEMAS_ANY_STRICT:
 1462: 	    return (BAD_CAST "strict");
 1463: 	default:
 1464: 	    return (BAD_CAST "invalid process contents");
 1465:     }
 1466: }
 1467: 
 1468: /**
 1469:  * xmlSchemaGetCanonValueWhtspExt:
 1470:  * @val: the precomputed value
 1471:  * @retValue: the returned value
 1472:  * @ws: the whitespace type of the value
 1473:  *
 1474:  * Get a the cononical representation of the value.
 1475:  * The caller has to free the returned retValue.
 1476:  *
 1477:  * Returns 0 if the value could be built and -1 in case of
 1478:  *         API errors or if the value type is not supported yet.
 1479:  */
 1480: static int
 1481: xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
 1482: 			       xmlSchemaWhitespaceValueType ws,
 1483: 			       xmlChar **retValue)
 1484: {
 1485:     int list;
 1486:     xmlSchemaValType valType;
 1487:     const xmlChar *value, *value2 = NULL;
 1488: 
 1489: 
 1490:     if ((retValue == NULL) || (val == NULL))
 1491: 	return (-1);
 1492:     list = xmlSchemaValueGetNext(val) ? 1 : 0;
 1493:     *retValue = NULL;
 1494:     do {
 1495: 	value = NULL;
 1496: 	valType = xmlSchemaGetValType(val);
 1497: 	switch (valType) {
 1498: 	    case XML_SCHEMAS_STRING:
 1499: 	    case XML_SCHEMAS_NORMSTRING:
 1500: 	    case XML_SCHEMAS_ANYSIMPLETYPE:
 1501: 		value = xmlSchemaValueGetAsString(val);
 1502: 		if (value != NULL) {
 1503: 		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
 1504: 			value2 = xmlSchemaCollapseString(value);
 1505: 		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
 1506: 			value2 = xmlSchemaWhiteSpaceReplace(value);
 1507: 		    if (value2 != NULL)
 1508: 			value = value2;
 1509: 		}
 1510: 		break;
 1511: 	    default:
 1512: 		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
 1513: 		    if (value2 != NULL)
 1514: 			xmlFree((xmlChar *) value2);
 1515: 		    goto internal_error;
 1516: 		}
 1517: 		value = value2;
 1518: 	}
 1519: 	if (*retValue == NULL)
 1520: 	    if (value == NULL) {
 1521: 		if (! list)
 1522: 		    *retValue = xmlStrdup(BAD_CAST "");
 1523: 	    } else
 1524: 		*retValue = xmlStrdup(value);
 1525: 	else if (value != NULL) {
 1526: 	    /* List. */
 1527: 	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
 1528: 	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
 1529: 	}
 1530: 	FREE_AND_NULL(value2)
 1531: 	val = xmlSchemaValueGetNext(val);
 1532:     } while (val != NULL);
 1533: 
 1534:     return (0);
 1535: internal_error:
 1536:     if (*retValue != NULL)
 1537: 	xmlFree((xmlChar *) (*retValue));
 1538:     if (value2 != NULL)
 1539: 	xmlFree((xmlChar *) value2);
 1540:     return (-1);
 1541: }
 1542: 
 1543: /**
 1544:  * xmlSchemaFormatItemForReport:
 1545:  * @buf: the string buffer
 1546:  * @itemDes: the designation of the item
 1547:  * @itemName: the name of the item
 1548:  * @item: the item as an object
 1549:  * @itemNode: the node of the item
 1550:  * @local: the local name
 1551:  * @parsing: if the function is used during the parse
 1552:  *
 1553:  * Returns a representation of the given item used
 1554:  * for error reports.
 1555:  *
 1556:  * The following order is used to build the resulting
 1557:  * designation if the arguments are not NULL:
 1558:  * 1a. If itemDes not NULL -> itemDes
 1559:  * 1b. If (itemDes not NULL) and (itemName not NULL)
 1560:  *     -> itemDes + itemName
 1561:  * 2. If the preceding was NULL and (item not NULL) -> item
 1562:  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
 1563:  *
 1564:  * If the itemNode is an attribute node, the name of the attribute
 1565:  * will be appended to the result.
 1566:  *
 1567:  * Returns the formatted string and sets @buf to the resulting value.
 1568:  */
 1569: static xmlChar*
 1570: xmlSchemaFormatItemForReport(xmlChar **buf,
 1571: 		     const xmlChar *itemDes,
 1572: 		     xmlSchemaBasicItemPtr item,
 1573: 		     xmlNodePtr itemNode)
 1574: {
 1575:     xmlChar *str = NULL;
 1576:     int named = 1;
 1577: 
 1578:     if (*buf != NULL) {
 1579: 	xmlFree(*buf);
 1580: 	*buf = NULL;
 1581:     }
 1582: 
 1583:     if (itemDes != NULL) {
 1584: 	*buf = xmlStrdup(itemDes);
 1585:     } else if (item != NULL) {
 1586: 	switch (item->type) {
 1587: 	case XML_SCHEMA_TYPE_BASIC: {
 1588: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1589: 
 1590: 	    if (WXS_IS_ATOMIC(type))
 1591: 		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
 1592: 	    else if (WXS_IS_LIST(type))
 1593: 		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
 1594: 	    else if (WXS_IS_UNION(type))
 1595: 		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
 1596: 	    else
 1597: 		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
 1598: 	    *buf = xmlStrcat(*buf, type->name);
 1599: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1600: 	    }
 1601: 	    break;
 1602: 	case XML_SCHEMA_TYPE_SIMPLE: {
 1603: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1604: 
 1605: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1606: 		*buf = xmlStrdup(BAD_CAST"");
 1607: 	    } else {
 1608: 		*buf = xmlStrdup(BAD_CAST "local ");
 1609: 	    }
 1610: 	    if (WXS_IS_ATOMIC(type))
 1611: 		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
 1612: 	    else if (WXS_IS_LIST(type))
 1613: 		*buf = xmlStrcat(*buf, BAD_CAST "list type");
 1614: 	    else if (WXS_IS_UNION(type))
 1615: 		*buf = xmlStrcat(*buf, BAD_CAST "union type");
 1616: 	    else
 1617: 		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
 1618: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1619: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1620: 		*buf = xmlStrcat(*buf, type->name);
 1621: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1622: 	    }
 1623: 	    }
 1624: 	    break;
 1625: 	case XML_SCHEMA_TYPE_COMPLEX: {
 1626: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1627: 
 1628: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
 1629: 		*buf = xmlStrdup(BAD_CAST "");
 1630: 	    else
 1631: 		*buf = xmlStrdup(BAD_CAST "local ");
 1632: 	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
 1633: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1634: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1635: 		*buf = xmlStrcat(*buf, type->name);
 1636: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1637: 	    }
 1638: 	    }
 1639: 	    break;
 1640: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
 1641: 		xmlSchemaAttributeUsePtr ause;
 1642: 
 1643: 		ause = WXS_ATTR_USE_CAST item;
 1644: 		*buf = xmlStrdup(BAD_CAST "attribute use ");
 1645: 		if (WXS_ATTRUSE_DECL(ause) != NULL) {
 1646: 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1647: 		    *buf = xmlStrcat(*buf,
 1648: 			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
 1649: 		    FREE_AND_NULL(str)
 1650: 			*buf = xmlStrcat(*buf, BAD_CAST "'");
 1651: 		} else {
 1652: 		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
 1653: 		}
 1654: 	    }
 1655: 	    break;
 1656: 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
 1657: 		xmlSchemaAttributePtr attr;
 1658: 
 1659: 		attr = (xmlSchemaAttributePtr) item;
 1660: 		*buf = xmlStrdup(BAD_CAST "attribute decl.");
 1661: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1662: 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1663: 		    attr->targetNamespace, attr->name));
 1664: 		FREE_AND_NULL(str)
 1665: 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1666: 	    }
 1667: 	    break;
 1668: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1669: 	    xmlSchemaGetComponentDesignation(buf, item);
 1670: 	    break;
 1671: 	case XML_SCHEMA_TYPE_ELEMENT: {
 1672: 		xmlSchemaElementPtr elem;
 1673: 
 1674: 		elem = (xmlSchemaElementPtr) item;
 1675: 		*buf = xmlStrdup(BAD_CAST "element decl.");
 1676: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1677: 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1678: 		    elem->targetNamespace, elem->name));
 1679: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1680: 	    }
 1681: 	    break;
 1682: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1683: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1684: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1685: 	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
 1686: 		*buf = xmlStrdup(BAD_CAST "unique '");
 1687: 	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
 1688: 		*buf = xmlStrdup(BAD_CAST "key '");
 1689: 	    else
 1690: 		*buf = xmlStrdup(BAD_CAST "keyRef '");
 1691: 	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
 1692: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1693: 	    break;
 1694: 	case XML_SCHEMA_TYPE_ANY:
 1695: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1696: 	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
 1697: 		    ((xmlSchemaWildcardPtr) item)->processContents));
 1698: 	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
 1699: 	    break;
 1700: 	case XML_SCHEMA_FACET_MININCLUSIVE:
 1701: 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 1702: 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 1703: 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 1704: 	case XML_SCHEMA_FACET_TOTALDIGITS:
 1705: 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
 1706: 	case XML_SCHEMA_FACET_PATTERN:
 1707: 	case XML_SCHEMA_FACET_ENUMERATION:
 1708: 	case XML_SCHEMA_FACET_WHITESPACE:
 1709: 	case XML_SCHEMA_FACET_LENGTH:
 1710: 	case XML_SCHEMA_FACET_MAXLENGTH:
 1711: 	case XML_SCHEMA_FACET_MINLENGTH:
 1712: 	    *buf = xmlStrdup(BAD_CAST "facet '");
 1713: 	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
 1714: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1715: 	    break;
 1716: 	case XML_SCHEMA_TYPE_GROUP: {
 1717: 		*buf = xmlStrdup(BAD_CAST "model group def.");
 1718: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1719: 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 1720: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1721: 		FREE_AND_NULL(str)
 1722: 	    }
 1723: 	    break;
 1724: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1725: 	case XML_SCHEMA_TYPE_CHOICE:
 1726: 	case XML_SCHEMA_TYPE_ALL:
 1727: 	case XML_SCHEMA_TYPE_PARTICLE:
 1728: 	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 1729: 	    break;
 1730: 	case XML_SCHEMA_TYPE_NOTATION: {
 1731: 		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 1732: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1733: 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 1734: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1735: 		FREE_AND_NULL(str);
 1736: 	    }
 1737: 	default:
 1738: 	    named = 0;
 1739: 	}
 1740:     } else
 1741: 	named = 0;
 1742: 
 1743:     if ((named == 0) && (itemNode != NULL)) {
 1744: 	xmlNodePtr elem;
 1745: 
 1746: 	if (itemNode->type == XML_ATTRIBUTE_NODE)
 1747: 	    elem = itemNode->parent;
 1748: 	else
 1749: 	    elem = itemNode;
 1750: 	*buf = xmlStrdup(BAD_CAST "Element '");
 1751: 	if (elem->ns != NULL) {
 1752: 	    *buf = xmlStrcat(*buf,
 1753: 		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
 1754: 	    FREE_AND_NULL(str)
 1755: 	} else
 1756: 	    *buf = xmlStrcat(*buf, elem->name);
 1757: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
 1758: 
 1759:     }
 1760:     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
 1761: 	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
 1762: 	if (itemNode->ns != NULL) {
 1763: 	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1764: 		itemNode->ns->href, itemNode->name));
 1765: 	    FREE_AND_NULL(str)
 1766: 	} else
 1767: 	    *buf = xmlStrcat(*buf, itemNode->name);
 1768: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
 1769:     }
 1770:     FREE_AND_NULL(str)
 1771: 
 1772:     return (*buf);
 1773: }
 1774: 
 1775: /**
 1776:  * xmlSchemaFormatFacetEnumSet:
 1777:  * @buf: the string buffer
 1778:  * @type: the type holding the enumeration facets
 1779:  *
 1780:  * Builds a string consisting of all enumeration elements.
 1781:  *
 1782:  * Returns a string of all enumeration elements.
 1783:  */
 1784: static const xmlChar *
 1785: xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
 1786: 			    xmlChar **buf, xmlSchemaTypePtr type)
 1787: {
 1788:     xmlSchemaFacetPtr facet;
 1789:     xmlSchemaWhitespaceValueType ws;
 1790:     xmlChar *value = NULL;
 1791:     int res, found = 0;
 1792: 
 1793:     if (*buf != NULL)
 1794: 	xmlFree(*buf);
 1795:     *buf = NULL;
 1796: 
 1797:     do {
 1798: 	/*
 1799: 	* Use the whitespace type of the base type.
 1800: 	*/
 1801: 	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
 1802: 	for (facet = type->facets; facet != NULL; facet = facet->next) {
 1803: 	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
 1804: 		continue;
 1805: 	    found = 1;
 1806: 	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
 1807: 		ws, &value);
 1808: 	    if (res == -1) {
 1809: 		xmlSchemaInternalErr(actxt,
 1810: 		    "xmlSchemaFormatFacetEnumSet",
 1811: 		    "compute the canonical lexical representation");
 1812: 		if (*buf != NULL)
 1813: 		    xmlFree(*buf);
 1814: 		*buf = NULL;
 1815: 		return (NULL);
 1816: 	    }
 1817: 	    if (*buf == NULL)
 1818: 		*buf = xmlStrdup(BAD_CAST "'");
 1819: 	    else
 1820: 		*buf = xmlStrcat(*buf, BAD_CAST ", '");
 1821: 	    *buf = xmlStrcat(*buf, BAD_CAST value);
 1822: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1823: 	    if (value != NULL) {
 1824: 		xmlFree((xmlChar *)value);
 1825: 		value = NULL;
 1826: 	    }
 1827: 	}
 1828: 	/*
 1829: 	* The enumeration facet of a type restricts the enumeration
 1830: 	* facet of the ancestor type; i.e., such restricted enumerations
 1831: 	* do not belong to the set of the given type. Thus we break
 1832: 	* on the first found enumeration.
 1833: 	*/
 1834: 	if (found)
 1835: 	    break;
 1836: 	type = type->baseType;
 1837:     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
 1838: 
 1839:     return ((const xmlChar *) *buf);
 1840: }
 1841: 
 1842: /************************************************************************
 1843:  *									*
 1844:  *			Error functions				        *
 1845:  *									*
 1846:  ************************************************************************/
 1847: 
 1848: #if 0
 1849: static void
 1850: xmlSchemaErrMemory(const char *msg)
 1851: {
 1852:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 1853:                      msg);
 1854: }
 1855: #endif
 1856: 
 1857: static void
 1858: xmlSchemaPSimpleErr(const char *msg)
 1859: {
 1860:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 1861:                      msg);
 1862: }
 1863: 
 1864: /**
 1865:  * xmlSchemaPErrMemory:
 1866:  * @node: a context node
 1867:  * @extra:  extra informations
 1868:  *
 1869:  * Handle an out of memory condition
 1870:  */
 1871: static void
 1872: xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
 1873:                     const char *extra, xmlNodePtr node)
 1874: {
 1875:     if (ctxt != NULL)
 1876:         ctxt->nberrors++;
 1877:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
 1878:                      extra);
 1879: }
 1880: 
 1881: /**
 1882:  * xmlSchemaPErr:
 1883:  * @ctxt: the parsing context
 1884:  * @node: the context node
 1885:  * @error: the error code
 1886:  * @msg: the error message
 1887:  * @str1: extra data
 1888:  * @str2: extra data
 1889:  *
 1890:  * Handle a parser error
 1891:  */
 1892: static void
 1893: xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 1894:               const char *msg, const xmlChar * str1, const xmlChar * str2)
 1895: {
 1896:     xmlGenericErrorFunc channel = NULL;
 1897:     xmlStructuredErrorFunc schannel = NULL;
 1898:     void *data = NULL;
 1899: 
 1900:     if (ctxt != NULL) {
 1901:         ctxt->nberrors++;
 1902: 	ctxt->err = error;
 1903:         channel = ctxt->error;
 1904:         data = ctxt->errCtxt;
 1905: 	schannel = ctxt->serror;
 1906:     }
 1907:     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 1908:                     error, XML_ERR_ERROR, NULL, 0,
 1909:                     (const char *) str1, (const char *) str2, NULL, 0, 0,
 1910:                     msg, str1, str2);
 1911: }
 1912: 
 1913: /**
 1914:  * xmlSchemaPErr2:
 1915:  * @ctxt: the parsing context
 1916:  * @node: the context node
 1917:  * @node: the current child
 1918:  * @error: the error code
 1919:  * @msg: the error message
 1920:  * @str1: extra data
 1921:  * @str2: extra data
 1922:  *
 1923:  * Handle a parser error
 1924:  */
 1925: static void
 1926: xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 1927:                xmlNodePtr child, int error,
 1928:                const char *msg, const xmlChar * str1, const xmlChar * str2)
 1929: {
 1930:     if (child != NULL)
 1931:         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
 1932:     else
 1933:         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
 1934: }
 1935: 
 1936: 
 1937: /**
 1938:  * xmlSchemaPErrExt:
 1939:  * @ctxt: the parsing context
 1940:  * @node: the context node
 1941:  * @error: the error code
 1942:  * @strData1: extra data
 1943:  * @strData2: extra data
 1944:  * @strData3: extra data
 1945:  * @msg: the message
 1946:  * @str1:  extra parameter for the message display
 1947:  * @str2:  extra parameter for the message display
 1948:  * @str3:  extra parameter for the message display
 1949:  * @str4:  extra parameter for the message display
 1950:  * @str5:  extra parameter for the message display
 1951:  *
 1952:  * Handle a parser error
 1953:  */
 1954: static void
 1955: xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 1956: 		const xmlChar * strData1, const xmlChar * strData2,
 1957: 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
 1958: 		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
 1959: 		const xmlChar * str5)
 1960: {
 1961: 
 1962:     xmlGenericErrorFunc channel = NULL;
 1963:     xmlStructuredErrorFunc schannel = NULL;
 1964:     void *data = NULL;
 1965: 
 1966:     if (ctxt != NULL) {
 1967:         ctxt->nberrors++;
 1968: 	ctxt->err = error;
 1969:         channel = ctxt->error;
 1970:         data = ctxt->errCtxt;
 1971: 	schannel = ctxt->serror;
 1972:     }
 1973:     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 1974:                     error, XML_ERR_ERROR, NULL, 0,
 1975:                     (const char *) strData1, (const char *) strData2,
 1976: 		    (const char *) strData3, 0, 0, msg, str1, str2,
 1977: 		    str3, str4, str5);
 1978: }
 1979: 
 1980: /************************************************************************
 1981:  *									*
 1982:  *			Allround error functions			*
 1983:  *									*
 1984:  ************************************************************************/
 1985: 
 1986: /**
 1987:  * xmlSchemaVTypeErrMemory:
 1988:  * @node: a context node
 1989:  * @extra:  extra informations
 1990:  *
 1991:  * Handle an out of memory condition
 1992:  */
 1993: static void
 1994: xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
 1995:                     const char *extra, xmlNodePtr node)
 1996: {
 1997:     if (ctxt != NULL) {
 1998:         ctxt->nberrors++;
 1999:         ctxt->err = XML_SCHEMAV_INTERNAL;
 2000:     }
 2001:     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
 2002:                      extra);
 2003: }
 2004: 
 2005: static void
 2006: xmlSchemaPSimpleInternalErr(xmlNodePtr node,
 2007: 			    const char *msg, const xmlChar *str)
 2008: {
 2009:      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
 2010: 	 msg, (const char *) str);
 2011: }
 2012: 
 2013: #define WXS_ERROR_TYPE_ERROR 1
 2014: #define WXS_ERROR_TYPE_WARNING 2
 2015: /**
 2016:  * xmlSchemaErr3:
 2017:  * @ctxt: the validation context
 2018:  * @node: the context node
 2019:  * @error: the error code
 2020:  * @msg: the error message
 2021:  * @str1: extra data
 2022:  * @str2: extra data
 2023:  * @str3: extra data
 2024:  *
 2025:  * Handle a validation error
 2026:  */
 2027: static void
 2028: xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
 2029: 		  xmlErrorLevel errorLevel,
 2030: 		  int error, xmlNodePtr node, int line, const char *msg,
 2031: 		  const xmlChar *str1, const xmlChar *str2,
 2032: 		  const xmlChar *str3, const xmlChar *str4)
 2033: {
 2034:     xmlStructuredErrorFunc schannel = NULL;
 2035:     xmlGenericErrorFunc channel = NULL;
 2036:     void *data = NULL;
 2037: 
 2038:     if (ctxt != NULL) {
 2039: 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 2040: 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
 2041: 	    const char *file = NULL;
 2042: 	    if (errorLevel != XML_ERR_WARNING) {
 2043: 		vctxt->nberrors++;
 2044: 		vctxt->err = error;
 2045: 		channel = vctxt->error;
 2046: 	    } else {
 2047: 		channel = vctxt->warning;
 2048: 	    }
 2049: 	    schannel = vctxt->serror;
 2050: 	    data = vctxt->errCtxt;
 2051: 
 2052: 	    /*
 2053: 	    * Error node. If we specify a line number, then
 2054: 	    * do not channel any node to the error function.
 2055: 	    */
 2056: 	    if (line == 0) {
 2057: 		if ((node == NULL) &&
 2058: 		    (vctxt->depth >= 0) &&
 2059: 		    (vctxt->inode != NULL)) {
 2060: 		    node = vctxt->inode->node;
 2061: 		}
 2062: 		/*
 2063: 		* Get filename and line if no node-tree.
 2064: 		*/
 2065: 		if ((node == NULL) &&
 2066: 		    (vctxt->parserCtxt != NULL) &&
 2067: 		    (vctxt->parserCtxt->input != NULL)) {
 2068: 		    file = vctxt->parserCtxt->input->filename;
 2069: 		    line = vctxt->parserCtxt->input->line;
 2070: 		}
 2071: 	    } else {
 2072: 		/*
 2073: 		* Override the given node's (if any) position
 2074: 		* and channel only the given line number.
 2075: 		*/
 2076: 		node = NULL;
 2077: 		/*
 2078: 		* Get filename.
 2079: 		*/
 2080: 		if (vctxt->doc != NULL)
 2081: 		    file = (const char *) vctxt->doc->URL;
 2082: 		else if ((vctxt->parserCtxt != NULL) &&
 2083: 		    (vctxt->parserCtxt->input != NULL))
 2084: 		    file = vctxt->parserCtxt->input->filename;
 2085: 	    }
 2086: 	    if (vctxt->locFunc != NULL) {
 2087: 	        if ((file == NULL) || (line == 0)) {
 2088: 		    unsigned long l;
 2089: 		    const char *f;
 2090: 		    vctxt->locFunc(vctxt->locCtxt, &f, &l);
 2091: 		    if (file == NULL)
 2092: 		        file = f;
 2093: 		    if (line == 0)
 2094: 		        line = (int) l;
 2095: 		}
 2096: 	    }
 2097: 	    if ((file == NULL) && (vctxt->filename != NULL))
 2098: 	        file = vctxt->filename;
 2099: 
 2100: 	    __xmlRaiseError(schannel, channel, data, ctxt,
 2101: 		node, XML_FROM_SCHEMASV,
 2102: 		error, errorLevel, file, line,
 2103: 		(const char *) str1, (const char *) str2,
 2104: 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 2105: 
 2106: 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
 2107: 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
 2108: 	    if (errorLevel != XML_ERR_WARNING) {
 2109: 		pctxt->nberrors++;
 2110: 		pctxt->err = error;
 2111: 		channel = pctxt->error;
 2112: 	    } else {
 2113: 		channel = pctxt->warning;
 2114: 	    }
 2115: 	    schannel = pctxt->serror;
 2116: 	    data = pctxt->errCtxt;
 2117: 	    __xmlRaiseError(schannel, channel, data, ctxt,
 2118: 		node, XML_FROM_SCHEMASP, error,
 2119: 		errorLevel, NULL, 0,
 2120: 		(const char *) str1, (const char *) str2,
 2121: 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 2122: 	} else {
 2123: 	    TODO
 2124: 	}
 2125:     }
 2126: }
 2127: 
 2128: /**
 2129:  * xmlSchemaErr3:
 2130:  * @ctxt: the validation context
 2131:  * @node: the context node
 2132:  * @error: the error code
 2133:  * @msg: the error message
 2134:  * @str1: extra data
 2135:  * @str2: extra data
 2136:  * @str3: extra data
 2137:  *
 2138:  * Handle a validation error
 2139:  */
 2140: static void
 2141: xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
 2142: 	      int error, xmlNodePtr node, const char *msg,
 2143: 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
 2144: {
 2145:     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 2146: 	msg, str1, str2, str3, NULL);
 2147: }
 2148: 
 2149: static void
 2150: xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
 2151: 	      int error, xmlNodePtr node, const char *msg,
 2152: 	      const xmlChar *str1, const xmlChar *str2,
 2153: 	      const xmlChar *str3, const xmlChar *str4)
 2154: {
 2155:     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 2156: 	msg, str1, str2, str3, str4);
 2157: }
 2158: 
 2159: static void
 2160: xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
 2161: 	     int error, xmlNodePtr node, const char *msg,
 2162: 	     const xmlChar *str1, const xmlChar *str2)
 2163: {
 2164:     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
 2165: }
 2166: 
 2167: static xmlChar *
 2168: xmlSchemaFormatNodeForError(xmlChar ** msg,
 2169: 			    xmlSchemaAbstractCtxtPtr actxt,
 2170: 			    xmlNodePtr node)
 2171: {
 2172:     xmlChar *str = NULL;
 2173: 
 2174:     *msg = NULL;
 2175:     if ((node != NULL) &&
 2176: 	(node->type != XML_ELEMENT_NODE) &&
 2177: 	(node->type != XML_ATTRIBUTE_NODE))
 2178:     {
 2179: 	/*
 2180: 	* Don't try to format other nodes than element and
 2181: 	* attribute nodes.
 2182: 	* Play save and return an empty string.
 2183: 	*/
 2184: 	*msg = xmlStrdup(BAD_CAST "");
 2185: 	return(*msg);
 2186:     }
 2187:     if (node != NULL) {
 2188: 	/*
 2189: 	* Work on tree nodes.
 2190: 	*/
 2191: 	if (node->type == XML_ATTRIBUTE_NODE) {
 2192: 	    xmlNodePtr elem = node->parent;
 2193: 
 2194: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2195: 	    if (elem->ns != NULL)
 2196: 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2197: 		    elem->ns->href, elem->name));
 2198: 	    else
 2199: 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2200: 		    NULL, elem->name));
 2201: 	    FREE_AND_NULL(str);
 2202: 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
 2203: 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
 2204: 	} else {
 2205: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2206: 	}
 2207: 	if (node->ns != NULL)
 2208: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2209: 	    node->ns->href, node->name));
 2210: 	else
 2211: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2212: 	    NULL, node->name));
 2213: 	FREE_AND_NULL(str);
 2214: 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
 2215:     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 2216: 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
 2217: 	/*
 2218: 	* Work on node infos.
 2219: 	*/
 2220: 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
 2221: 	    xmlSchemaNodeInfoPtr ielem =
 2222: 		vctxt->elemInfos[vctxt->depth];
 2223: 
 2224: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2225: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2226: 		ielem->nsName, ielem->localName));
 2227: 	    FREE_AND_NULL(str);
 2228: 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
 2229: 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
 2230: 	} else {
 2231: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2232: 	}
 2233: 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2234: 	    vctxt->inode->nsName, vctxt->inode->localName));
 2235: 	FREE_AND_NULL(str);
 2236: 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
 2237:     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
 2238: 	/*
 2239: 	* Hmm, no node while parsing?
 2240: 	* Return an empty string, in case NULL will break something.
 2241: 	*/
 2242: 	*msg = xmlStrdup(BAD_CAST "");
 2243:     } else {
 2244: 	TODO
 2245: 	return (NULL);
 2246:     }
 2247:     /*
 2248:     * VAL TODO: The output of the given schema component is currently
 2249:     * disabled.
 2250:     */
 2251: #if 0
 2252:     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
 2253: 	*msg = xmlStrcat(*msg, BAD_CAST " [");
 2254: 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
 2255: 	    NULL, type, NULL, 0));
 2256: 	FREE_AND_NULL(str)
 2257: 	*msg = xmlStrcat(*msg, BAD_CAST "]");
 2258:     }
 2259: #endif
 2260:     return (*msg);
 2261: }
 2262: 
 2263: static void
 2264: xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
 2265: 		     const char *funcName,
 2266: 		     const char *message,
 2267: 		     const xmlChar *str1,
 2268: 		     const xmlChar *str2)
 2269: {
 2270:     xmlChar *msg = NULL;
 2271: 
 2272:     if (actxt == NULL)
 2273:         return;
 2274:     msg = xmlStrdup(BAD_CAST "Internal error: ");
 2275:     msg = xmlStrcat(msg, BAD_CAST funcName);
 2276:     msg = xmlStrcat(msg, BAD_CAST ", ");
 2277:     msg = xmlStrcat(msg, BAD_CAST message);
 2278:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2279: 
 2280:     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
 2281: 	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
 2282: 	    (const char *) msg, str1, str2);
 2283: 
 2284:     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
 2285: 	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
 2286: 	    (const char *) msg, str1, str2);
 2287: 
 2288:     FREE_AND_NULL(msg)
 2289: }
 2290: 
 2291: static void
 2292: xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 2293: 		     const char *funcName,
 2294: 		     const char *message)
 2295: {
 2296:     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
 2297: }
 2298: 
 2299: #if 0
 2300: static void
 2301: xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
 2302: 		     const char *funcName,
 2303: 		     const char *message,
 2304: 		     const xmlChar *str1,
 2305: 		     const xmlChar *str2)
 2306: {
 2307:     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
 2308: 	str1, str2);
 2309: }
 2310: #endif
 2311: 
 2312: static void
 2313: xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
 2314: 		   xmlParserErrors error,
 2315: 		   xmlNodePtr node,
 2316: 		   xmlSchemaBasicItemPtr item,
 2317: 		   const char *message,
 2318: 		   const xmlChar *str1, const xmlChar *str2,
 2319: 		   const xmlChar *str3, const xmlChar *str4)
 2320: {
 2321:     xmlChar *msg = NULL;
 2322: 
 2323:     if ((node == NULL) && (item != NULL) &&
 2324: 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
 2325: 	node = WXS_ITEM_NODE(item);
 2326: 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
 2327: 	msg = xmlStrcat(msg, BAD_CAST ": ");
 2328:     } else
 2329: 	xmlSchemaFormatNodeForError(&msg, actxt, node);
 2330:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2331:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2332:     xmlSchemaErr4(actxt, error, node,
 2333: 	(const char *) msg, str1, str2, str3, str4);
 2334:     FREE_AND_NULL(msg)
 2335: }
 2336: 
 2337: static void
 2338: xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
 2339: 		   xmlParserErrors error,
 2340: 		   xmlNodePtr node,
 2341: 		   xmlSchemaBasicItemPtr item,
 2342: 		   const char *message,
 2343: 		   const xmlChar *str1,
 2344: 		   const xmlChar *str2)
 2345: {
 2346:     xmlSchemaCustomErr4(actxt, error, node, item,
 2347: 	message, str1, str2, NULL, NULL);
 2348: }
 2349: 
 2350: 
 2351: 
 2352: static void
 2353: xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
 2354: 		   xmlParserErrors error,
 2355: 		   xmlNodePtr node,
 2356: 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2357: 		   const char *message,
 2358: 		   const xmlChar *str1,
 2359: 		   const xmlChar *str2,
 2360: 		   const xmlChar *str3)
 2361: {
 2362:     xmlChar *msg = NULL;
 2363: 
 2364:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2365:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2366:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2367: 
 2368:     /* URGENT TODO: Set the error code to something sane. */
 2369:     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
 2370: 	(const char *) msg, str1, str2, str3, NULL);
 2371: 
 2372:     FREE_AND_NULL(msg)
 2373: }
 2374: 
 2375: 
 2376: 
 2377: static void
 2378: xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
 2379: 		   xmlParserErrors error,
 2380: 		   xmlSchemaPSVIIDCNodePtr idcNode,
 2381: 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2382: 		   const char *message,
 2383: 		   const xmlChar *str1,
 2384: 		   const xmlChar *str2)
 2385: {
 2386:     xmlChar *msg = NULL, *qname = NULL;
 2387: 
 2388:     msg = xmlStrdup(BAD_CAST "Element '%s': ");
 2389:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2390:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2391:     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
 2392: 	error, NULL, idcNode->nodeLine, (const char *) msg,
 2393: 	xmlSchemaFormatQName(&qname,
 2394: 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
 2395: 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
 2396: 	str1, str2, NULL);
 2397:     FREE_AND_NULL(qname);
 2398:     FREE_AND_NULL(msg);
 2399: }
 2400: 
 2401: static int
 2402: xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
 2403: 			   xmlNodePtr node)
 2404: {
 2405:     if (node != NULL)
 2406: 	return (node->type);
 2407:     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
 2408: 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
 2409: 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
 2410:     return (-1);
 2411: }
 2412: 
 2413: static int
 2414: xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
 2415: {
 2416:     switch (item->type) {
 2417: 	case XML_SCHEMA_TYPE_COMPLEX:
 2418: 	case XML_SCHEMA_TYPE_SIMPLE:
 2419: 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
 2420: 		return(1);
 2421: 	    break;
 2422: 	case XML_SCHEMA_TYPE_GROUP:
 2423: 	    return (1);
 2424: 	case XML_SCHEMA_TYPE_ELEMENT:
 2425: 	    if ( ((xmlSchemaElementPtr) item)->flags &
 2426: 		XML_SCHEMAS_ELEM_GLOBAL)
 2427: 		return(1);
 2428: 	    break;
 2429: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 2430: 	    if ( ((xmlSchemaAttributePtr) item)->flags &
 2431: 		XML_SCHEMAS_ATTR_GLOBAL)
 2432: 		return(1);
 2433: 	    break;
 2434: 	/* Note that attribute groups are always global. */
 2435: 	default:
 2436: 	    return(1);
 2437:     }
 2438:     return (0);
 2439: }
 2440: 
 2441: static void
 2442: xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 2443: 		       xmlParserErrors error,
 2444: 		       xmlNodePtr node,
 2445: 		       const xmlChar *value,
 2446: 		       xmlSchemaTypePtr type,
 2447: 		       int displayValue)
 2448: {
 2449:     xmlChar *msg = NULL;
 2450: 
 2451:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2452: 
 2453:     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 2454: 	    XML_ATTRIBUTE_NODE))
 2455: 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 2456:     else
 2457: 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
 2458: 	    "value of ");
 2459: 
 2460:     if (! xmlSchemaIsGlobalItem(type))
 2461: 	msg = xmlStrcat(msg, BAD_CAST "the local ");
 2462:     else
 2463: 	msg = xmlStrcat(msg, BAD_CAST "the ");
 2464: 
 2465:     if (WXS_IS_ATOMIC(type))
 2466: 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
 2467:     else if (WXS_IS_LIST(type))
 2468: 	msg = xmlStrcat(msg, BAD_CAST "list type");
 2469:     else if (WXS_IS_UNION(type))
 2470: 	msg = xmlStrcat(msg, BAD_CAST "union type");
 2471: 
 2472:     if (xmlSchemaIsGlobalItem(type)) {
 2473: 	xmlChar *str = NULL;
 2474: 	msg = xmlStrcat(msg, BAD_CAST " '");
 2475: 	if (type->builtInType != 0) {
 2476: 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
 2477: 	    msg = xmlStrcat(msg, type->name);
 2478: 	} else
 2479: 	    msg = xmlStrcat(msg,
 2480: 		xmlSchemaFormatQName(&str,
 2481: 		    type->targetNamespace, type->name));
 2482: 	msg = xmlStrcat(msg, BAD_CAST "'");
 2483: 	FREE_AND_NULL(str);
 2484:     }
 2485:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2486:     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 2487: 	    XML_ATTRIBUTE_NODE))
 2488: 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 2489:     else
 2490: 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2491:     FREE_AND_NULL(msg)
 2492: }
 2493: 
 2494: static const xmlChar *
 2495: xmlSchemaFormatErrorNodeQName(xmlChar ** str,
 2496: 			      xmlSchemaNodeInfoPtr ni,
 2497: 			      xmlNodePtr node)
 2498: {
 2499:     if (node != NULL) {
 2500: 	if (node->ns != NULL)
 2501: 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
 2502: 	else
 2503: 	    return (xmlSchemaFormatQName(str, NULL, node->name));
 2504:     } else if (ni != NULL)
 2505: 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
 2506:     return (NULL);
 2507: }
 2508: 
 2509: static void
 2510: xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
 2511: 			xmlParserErrors error,
 2512: 			xmlSchemaAttrInfoPtr ni,
 2513: 			xmlNodePtr node)
 2514: {
 2515:     xmlChar *msg = NULL, *str = NULL;
 2516: 
 2517:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2518:     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
 2519:     xmlSchemaErr(actxt, error, node, (const char *) msg,
 2520: 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
 2521: 	NULL);
 2522:     FREE_AND_NULL(str)
 2523:     FREE_AND_NULL(msg)
 2524: }
 2525: 
 2526: static void
 2527: xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 2528: 		        xmlParserErrors error,
 2529: 		        xmlNodePtr node,
 2530: 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2531: 			const char *message,
 2532: 			int nbval,
 2533: 			int nbneg,
 2534: 			xmlChar **values)
 2535: {
 2536:     xmlChar *str = NULL, *msg = NULL;
 2537:     xmlChar *localName, *nsName;
 2538:     const xmlChar *cur, *end;
 2539:     int i;
 2540: 
 2541:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2542:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2543:     msg = xmlStrcat(msg, BAD_CAST ".");
 2544:     /*
 2545:     * Note that is does not make sense to report that we have a
 2546:     * wildcard here, since the wildcard might be unfolded into
 2547:     * multiple transitions.
 2548:     */
 2549:     if (nbval + nbneg > 0) {
 2550: 	if (nbval + nbneg > 1) {
 2551: 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
 2552: 	} else
 2553: 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
 2554: 	nsName = NULL;
 2555: 
 2556: 	for (i = 0; i < nbval + nbneg; i++) {
 2557: 	    cur = values[i];
 2558: 	    if (cur == NULL)
 2559: 	        continue;
 2560: 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
 2561: 	        (cur[3] == ' ')) {
 2562: 		cur += 4;
 2563: 		str = xmlStrcat(str, BAD_CAST "##other");
 2564: 	    }
 2565: 	    /*
 2566: 	    * Get the local name.
 2567: 	    */
 2568: 	    localName = NULL;
 2569: 
 2570: 	    end = cur;
 2571: 	    if (*end == '*') {
 2572: 		localName = xmlStrdup(BAD_CAST "*");
 2573: 		end++;
 2574: 	    } else {
 2575: 		while ((*end != 0) && (*end != '|'))
 2576: 		    end++;
 2577: 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
 2578: 	    }
 2579: 	    if (*end != 0) {
 2580: 		end++;
 2581: 		/*
 2582: 		* Skip "*|*" if they come with negated expressions, since
 2583: 		* they represent the same negated wildcard.
 2584: 		*/
 2585: 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
 2586: 		    /*
 2587: 		    * Get the namespace name.
 2588: 		    */
 2589: 		    cur = end;
 2590: 		    if (*end == '*') {
 2591: 			nsName = xmlStrdup(BAD_CAST "{*}");
 2592: 		    } else {
 2593: 			while (*end != 0)
 2594: 			    end++;
 2595: 
 2596: 			if (i >= nbval)
 2597: 			    nsName = xmlStrdup(BAD_CAST "{##other:");
 2598: 			else
 2599: 			    nsName = xmlStrdup(BAD_CAST "{");
 2600: 
 2601: 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
 2602: 			nsName = xmlStrcat(nsName, BAD_CAST "}");
 2603: 		    }
 2604: 		    str = xmlStrcat(str, BAD_CAST nsName);
 2605: 		    FREE_AND_NULL(nsName)
 2606: 		} else {
 2607: 		    FREE_AND_NULL(localName);
 2608: 		    continue;
 2609: 		}
 2610: 	    }
 2611: 	    str = xmlStrcat(str, BAD_CAST localName);
 2612: 	    FREE_AND_NULL(localName);
 2613: 
 2614: 	    if (i < nbval + nbneg -1)
 2615: 		str = xmlStrcat(str, BAD_CAST ", ");
 2616: 	}
 2617: 	str = xmlStrcat(str, BAD_CAST " ).\n");
 2618: 	msg = xmlStrcat(msg, BAD_CAST str);
 2619: 	FREE_AND_NULL(str)
 2620:     } else
 2621:       msg = xmlStrcat(msg, BAD_CAST "\n");
 2622:     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2623:     xmlFree(msg);
 2624: }
 2625: 
 2626: static void
 2627: xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
 2628: 		  xmlParserErrors error,
 2629: 		  xmlNodePtr node,
 2630: 		  const xmlChar *value,
 2631: 		  unsigned long length,
 2632: 		  xmlSchemaTypePtr type,
 2633: 		  xmlSchemaFacetPtr facet,
 2634: 		  const char *message,
 2635: 		  const xmlChar *str1,
 2636: 		  const xmlChar *str2)
 2637: {
 2638:     xmlChar *str = NULL, *msg = NULL;
 2639:     xmlSchemaTypeType facetType;
 2640:     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
 2641: 
 2642:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2643:     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
 2644: 	facetType = XML_SCHEMA_FACET_ENUMERATION;
 2645: 	/*
 2646: 	* If enumerations are validated, one must not expect the
 2647: 	* facet to be given.
 2648: 	*/
 2649:     } else
 2650: 	facetType = facet->type;
 2651:     msg = xmlStrcat(msg, BAD_CAST "[");
 2652:     msg = xmlStrcat(msg, BAD_CAST "facet '");
 2653:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
 2654:     msg = xmlStrcat(msg, BAD_CAST "'] ");
 2655:     if (message == NULL) {
 2656: 	/*
 2657: 	* Use a default message.
 2658: 	*/
 2659: 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
 2660: 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
 2661: 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
 2662: 
 2663: 	    char len[25], actLen[25];
 2664: 
 2665: 	    /* FIXME, TODO: What is the max expected string length of the
 2666: 	    * this value?
 2667: 	    */
 2668: 	    if (nodeType == XML_ATTRIBUTE_NODE)
 2669: 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
 2670: 	    else
 2671: 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
 2672: 
 2673: 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
 2674: 	    snprintf(actLen, 24, "%lu", length);
 2675: 
 2676: 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
 2677: 		msg = xmlStrcat(msg,
 2678: 		BAD_CAST "this differs from the allowed length of '%s'.\n");
 2679: 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
 2680: 		msg = xmlStrcat(msg,
 2681: 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
 2682: 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
 2683: 		msg = xmlStrcat(msg,
 2684: 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
 2685: 
 2686: 	    if (nodeType == XML_ATTRIBUTE_NODE)
 2687: 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
 2688: 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
 2689: 	    else
 2690: 		xmlSchemaErr(actxt, error, node, (const char *) msg,
 2691: 		    (const xmlChar *) actLen, (const xmlChar *) len);
 2692: 
 2693: 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
 2694: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
 2695: 		"of the set {%s}.\n");
 2696: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2697: 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
 2698: 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
 2699: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
 2700: 		"by the pattern '%s'.\n");
 2701: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2702: 		facet->value);
 2703: 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
 2704: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
 2705: 		"minimum value allowed ('%s').\n");
 2706: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2707: 		facet->value);
 2708: 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
 2709: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
 2710: 		"maximum value allowed ('%s').\n");
 2711: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2712: 		facet->value);
 2713: 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
 2714: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
 2715: 		"'%s'.\n");
 2716: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2717: 		facet->value);
 2718: 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
 2719: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
 2720: 		"'%s'.\n");
 2721: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2722: 		facet->value);
 2723: 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
 2724: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
 2725: 		"digits than are allowed ('%s').\n");
 2726: 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 2727: 		facet->value);
 2728: 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
 2729: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
 2730: 		"digits than are allowed ('%s').\n");
 2731: 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 2732: 		facet->value);
 2733: 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
 2734: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
 2735: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 2736: 	} else {
 2737: 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
 2738: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2739: 	}
 2740:     } else {
 2741: 	msg = xmlStrcat(msg, (const xmlChar *) message);
 2742: 	msg = xmlStrcat(msg, BAD_CAST ".\n");
 2743: 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
 2744:     }
 2745:     FREE_AND_NULL(str)
 2746:     xmlFree(msg);
 2747: }
 2748: 
 2749: #define VERROR(err, type, msg) \
 2750:     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
 2751: 
 2752: #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
 2753: 
 2754: #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
 2755: #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
 2756: 
 2757: #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
 2758: 
 2759: 
 2760: /**
 2761:  * xmlSchemaPMissingAttrErr:
 2762:  * @ctxt: the schema validation context
 2763:  * @ownerDes: the designation of  the owner
 2764:  * @ownerName: the name of the owner
 2765:  * @ownerItem: the owner as a schema object
 2766:  * @ownerElem: the owner as an element node
 2767:  * @node: the parent element node of the missing attribute node
 2768:  * @type: the corresponding type of the attribute node
 2769:  *
 2770:  * Reports an illegal attribute.
 2771:  */
 2772: static void
 2773: xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2774: 			 xmlParserErrors error,
 2775: 			 xmlSchemaBasicItemPtr ownerItem,
 2776: 			 xmlNodePtr ownerElem,
 2777: 			 const char *name,
 2778: 			 const char *message)
 2779: {
 2780:     xmlChar *des = NULL;
 2781: 
 2782:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 2783: 
 2784:     if (message != NULL)
 2785: 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
 2786:     else
 2787: 	xmlSchemaPErr(ctxt, ownerElem, error,
 2788: 	    "%s: The attribute '%s' is required but missing.\n",
 2789: 	    BAD_CAST des, BAD_CAST name);
 2790:     FREE_AND_NULL(des);
 2791: }
 2792: 
 2793: 
 2794: /**
 2795:  * xmlSchemaPResCompAttrErr:
 2796:  * @ctxt: the schema validation context
 2797:  * @error: the error code
 2798:  * @ownerDes: the designation of  the owner
 2799:  * @ownerItem: the owner as a schema object
 2800:  * @ownerElem: the owner as an element node
 2801:  * @name: the name of the attribute holding the QName
 2802:  * @refName: the referenced local name
 2803:  * @refURI: the referenced namespace URI
 2804:  * @message: optional message
 2805:  *
 2806:  * Used to report QName attribute values that failed to resolve
 2807:  * to schema components.
 2808:  */
 2809: static void
 2810: xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2811: 			 xmlParserErrors error,
 2812: 			 xmlSchemaBasicItemPtr ownerItem,
 2813: 			 xmlNodePtr ownerElem,
 2814: 			 const char *name,
 2815: 			 const xmlChar *refName,
 2816: 			 const xmlChar *refURI,
 2817: 			 xmlSchemaTypeType refType,
 2818: 			 const char *refTypeStr)
 2819: {
 2820:     xmlChar *des = NULL, *strA = NULL;
 2821: 
 2822:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 2823:     if (refTypeStr == NULL)
 2824: 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
 2825: 	xmlSchemaPErrExt(ctxt, ownerElem, error,
 2826: 	    NULL, NULL, NULL,
 2827: 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
 2828: 	    "%s.\n", BAD_CAST des, BAD_CAST name,
 2829: 	    xmlSchemaFormatQName(&strA, refURI, refName),
 2830: 	    BAD_CAST refTypeStr, NULL);
 2831:     FREE_AND_NULL(des)
 2832:     FREE_AND_NULL(strA)
 2833: }
 2834: 
 2835: /**
 2836:  * xmlSchemaPCustomAttrErr:
 2837:  * @ctxt: the schema parser context
 2838:  * @error: the error code
 2839:  * @ownerDes: the designation of the owner
 2840:  * @ownerItem: the owner as a schema object
 2841:  * @attr: the illegal attribute node
 2842:  *
 2843:  * Reports an illegal attribute during the parse.
 2844:  */
 2845: static void
 2846: xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2847: 			xmlParserErrors error,
 2848: 			xmlChar **ownerDes,
 2849: 			xmlSchemaBasicItemPtr ownerItem,
 2850: 			xmlAttrPtr attr,
 2851: 			const char *msg)
 2852: {
 2853:     xmlChar *des = NULL;
 2854: 
 2855:     if (ownerDes == NULL)
 2856: 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
 2857:     else if (*ownerDes == NULL) {
 2858: 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
 2859: 	des = *ownerDes;
 2860:     } else
 2861: 	des = *ownerDes;
 2862:     if (attr == NULL) {
 2863: 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
 2864: 	    "%s, attribute '%s': %s.\n",
 2865: 	    BAD_CAST des, (const xmlChar *) "Unknown",
 2866: 	    (const xmlChar *) msg, NULL, NULL);
 2867:     } else {
 2868: 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 2869: 	    "%s, attribute '%s': %s.\n",
 2870: 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
 2871:     }
 2872:     if (ownerDes == NULL)
 2873: 	FREE_AND_NULL(des);
 2874: }
 2875: 
 2876: /**
 2877:  * xmlSchemaPIllegalAttrErr:
 2878:  * @ctxt: the schema parser context
 2879:  * @error: the error code
 2880:  * @ownerDes: the designation of the attribute's owner
 2881:  * @ownerItem: the attribute's owner item
 2882:  * @attr: the illegal attribute node
 2883:  *
 2884:  * Reports an illegal attribute during the parse.
 2885:  */
 2886: static void
 2887: xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2888: 			 xmlParserErrors error,
 2889: 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
 2890: 			 xmlAttrPtr attr)
 2891: {
 2892:     xmlChar *strA = NULL, *strB = NULL;
 2893: 
 2894:     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
 2895:     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
 2896: 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
 2897: 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
 2898: 	NULL, NULL);
 2899:     FREE_AND_NULL(strA);
 2900:     FREE_AND_NULL(strB);
 2901: }
 2902: 
 2903: /**
 2904:  * xmlSchemaPCustomErr:
 2905:  * @ctxt: the schema parser context
 2906:  * @error: the error code
 2907:  * @itemDes: the designation of the schema item
 2908:  * @item: the schema item
 2909:  * @itemElem: the node of the schema item
 2910:  * @message: the error message
 2911:  * @str1: an optional param for the error message
 2912:  * @str2: an optional param for the error message
 2913:  * @str3: an optional param for the error message
 2914:  *
 2915:  * Reports an error during parsing.
 2916:  */
 2917: static void
 2918: xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
 2919: 		    xmlParserErrors error,
 2920: 		    xmlSchemaBasicItemPtr item,
 2921: 		    xmlNodePtr itemElem,
 2922: 		    const char *message,
 2923: 		    const xmlChar *str1,
 2924: 		    const xmlChar *str2,
 2925: 		    const xmlChar *str3)
 2926: {
 2927:     xmlChar *des = NULL, *msg = NULL;
 2928: 
 2929:     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
 2930:     msg = xmlStrdup(BAD_CAST "%s: ");
 2931:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2932:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2933:     if ((itemElem == NULL) && (item != NULL))
 2934: 	itemElem = WXS_ITEM_NODE(item);
 2935:     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
 2936: 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
 2937:     FREE_AND_NULL(des);
 2938:     FREE_AND_NULL(msg);
 2939: }
 2940: 
 2941: /**
 2942:  * xmlSchemaPCustomErr:
 2943:  * @ctxt: the schema parser context
 2944:  * @error: the error code
 2945:  * @itemDes: the designation of the schema item
 2946:  * @item: the schema item
 2947:  * @itemElem: the node of the schema item
 2948:  * @message: the error message
 2949:  * @str1: the optional param for the error message
 2950:  *
 2951:  * Reports an error during parsing.
 2952:  */
 2953: static void
 2954: xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
 2955: 		    xmlParserErrors error,
 2956: 		    xmlSchemaBasicItemPtr item,
 2957: 		    xmlNodePtr itemElem,
 2958: 		    const char *message,
 2959: 		    const xmlChar *str1)
 2960: {
 2961:     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
 2962: 	str1, NULL, NULL);
 2963: }
 2964: 
 2965: /**
 2966:  * xmlSchemaPAttrUseErr:
 2967:  * @ctxt: the schema parser context
 2968:  * @error: the error code
 2969:  * @itemDes: the designation of the schema type
 2970:  * @item: the schema type
 2971:  * @itemElem: the node of the schema type
 2972:  * @attr: the invalid schema attribute
 2973:  * @message: the error message
 2974:  * @str1: the optional param for the error message
 2975:  *
 2976:  * Reports an attribute use error during parsing.
 2977:  */
 2978: static void
 2979: xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
 2980: 		    xmlParserErrors error,
 2981: 		    xmlNodePtr node,
 2982: 		    xmlSchemaBasicItemPtr ownerItem,
 2983: 		    const xmlSchemaAttributeUsePtr attruse,
 2984: 		    const char *message,
 2985: 		    const xmlChar *str1, const xmlChar *str2,
 2986: 		    const xmlChar *str3,const xmlChar *str4)
 2987: {
 2988:     xmlChar *str = NULL, *msg = NULL;
 2989: 
 2990:     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
 2991:     msg = xmlStrcat(msg, BAD_CAST ", ");
 2992:     msg = xmlStrcat(msg,
 2993: 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
 2994: 	WXS_BASIC_CAST attruse, NULL));
 2995:     FREE_AND_NULL(str);
 2996:     msg = xmlStrcat(msg, BAD_CAST ": ");
 2997:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2998:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2999:     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
 3000: 	(const char *) msg, str1, str2, str3, str4);
 3001:     xmlFree(msg);
 3002: }
 3003: 
 3004: /**
 3005:  * xmlSchemaPIllegalFacetAtomicErr:
 3006:  * @ctxt: the schema parser context
 3007:  * @error: the error code
 3008:  * @type: the schema type
 3009:  * @baseType: the base type of type
 3010:  * @facet: the illegal facet
 3011:  *
 3012:  * Reports an illegal facet for atomic simple types.
 3013:  */
 3014: static void
 3015: xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
 3016: 			  xmlParserErrors error,
 3017: 			  xmlSchemaTypePtr type,
 3018: 			  xmlSchemaTypePtr baseType,
 3019: 			  xmlSchemaFacetPtr facet)
 3020: {
 3021:     xmlChar *des = NULL, *strT = NULL;
 3022: 
 3023:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
 3024:     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
 3025: 	"%s: The facet '%s' is not allowed on types derived from the "
 3026: 	"type %s.\n",
 3027: 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
 3028: 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
 3029: 	NULL, NULL);
 3030:     FREE_AND_NULL(des);
 3031:     FREE_AND_NULL(strT);
 3032: }
 3033: 
 3034: /**
 3035:  * xmlSchemaPIllegalFacetListUnionErr:
 3036:  * @ctxt: the schema parser context
 3037:  * @error: the error code
 3038:  * @itemDes: the designation of the schema item involved
 3039:  * @item: the schema item involved
 3040:  * @facet: the illegal facet
 3041:  *
 3042:  * Reports an illegal facet for <list> and <union>.
 3043:  */
 3044: static void
 3045: xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
 3046: 			  xmlParserErrors error,
 3047: 			  xmlSchemaTypePtr type,
 3048: 			  xmlSchemaFacetPtr facet)
 3049: {
 3050:     xmlChar *des = NULL;
 3051: 
 3052:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
 3053: 	type->node);
 3054:     xmlSchemaPErr(ctxt, type->node, error,
 3055: 	"%s: The facet '%s' is not allowed.\n",
 3056: 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
 3057:     FREE_AND_NULL(des);
 3058: }
 3059: 
 3060: /**
 3061:  * xmlSchemaPMutualExclAttrErr:
 3062:  * @ctxt: the schema validation context
 3063:  * @error: the error code
 3064:  * @elemDes: the designation of the parent element node
 3065:  * @attr: the bad attribute node
 3066:  * @type: the corresponding type of the attribute node
 3067:  *
 3068:  * Reports an illegal attribute.
 3069:  */
 3070: static void
 3071: xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
 3072: 			 xmlParserErrors error,
 3073: 			 xmlSchemaBasicItemPtr ownerItem,
 3074: 			 xmlAttrPtr attr,
 3075: 			 const char *name1,
 3076: 			 const char *name2)
 3077: {
 3078:     xmlChar *des = NULL;
 3079: 
 3080:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
 3081:     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 3082: 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
 3083: 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
 3084:     FREE_AND_NULL(des);
 3085: }
 3086: 
 3087: /**
 3088:  * xmlSchemaPSimpleTypeErr:
 3089:  * @ctxt:  the schema validation context
 3090:  * @error: the error code
 3091:  * @type: the type specifier
 3092:  * @ownerDes: the designation of the owner
 3093:  * @ownerItem: the schema object if existent
 3094:  * @node: the validated node
 3095:  * @value: the validated value
 3096:  *
 3097:  * Reports a simple type validation error.
 3098:  * TODO: Should this report the value of an element as well?
 3099:  */
 3100: static void
 3101: xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
 3102: 			xmlParserErrors error,
 3103: 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
 3104: 			xmlNodePtr node,
 3105: 			xmlSchemaTypePtr type,
 3106: 			const char *expected,
 3107: 			const xmlChar *value,
 3108: 			const char *message,
 3109: 			const xmlChar *str1,
 3110: 			const xmlChar *str2)
 3111: {
 3112:     xmlChar *msg = NULL;
 3113: 
 3114:     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
 3115:     if (message == NULL) {
 3116: 	/*
 3117: 	* Use default messages.
 3118: 	*/
 3119: 	if (type != NULL) {
 3120: 	    if (node->type == XML_ATTRIBUTE_NODE)
 3121: 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 3122: 	    else
 3123: 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
 3124: 		"valid value of ");
 3125: 	    if (! xmlSchemaIsGlobalItem(type))
 3126: 		msg = xmlStrcat(msg, BAD_CAST "the local ");
 3127: 	    else
 3128: 		msg = xmlStrcat(msg, BAD_CAST "the ");
 3129: 
 3130: 	    if (WXS_IS_ATOMIC(type))
 3131: 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
 3132: 	    else if (WXS_IS_LIST(type))
 3133: 		msg = xmlStrcat(msg, BAD_CAST "list type");
 3134: 	    else if (WXS_IS_UNION(type))
 3135: 		msg = xmlStrcat(msg, BAD_CAST "union type");
 3136: 
 3137: 	    if (xmlSchemaIsGlobalItem(type)) {
 3138: 		xmlChar *str = NULL;
 3139: 		msg = xmlStrcat(msg, BAD_CAST " '");
 3140: 		if (type->builtInType != 0) {
 3141: 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
 3142: 		    msg = xmlStrcat(msg, type->name);
 3143: 		} else
 3144: 		    msg = xmlStrcat(msg,
 3145: 			xmlSchemaFormatQName(&str,
 3146: 			    type->targetNamespace, type->name));
 3147: 		msg = xmlStrcat(msg, BAD_CAST "'.");
 3148: 		FREE_AND_NULL(str);
 3149: 	    }
 3150: 	} else {
 3151: 	    if (node->type == XML_ATTRIBUTE_NODE)
 3152: 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
 3153: 	    else
 3154: 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
 3155: 		"valid.");
 3156: 	}
 3157: 	if (expected) {
 3158: 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
 3159: 	    msg = xmlStrcat(msg, BAD_CAST expected);
 3160: 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
 3161: 	} else
 3162: 	    msg = xmlStrcat(msg, BAD_CAST "\n");
 3163: 	if (node->type == XML_ATTRIBUTE_NODE)
 3164: 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
 3165: 	else
 3166: 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
 3167:     } else {
 3168: 	msg = xmlStrcat(msg, BAD_CAST message);
 3169: 	msg = xmlStrcat(msg, BAD_CAST ".\n");
 3170: 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
 3171: 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
 3172:     }
 3173:     /* Cleanup. */
 3174:     FREE_AND_NULL(msg)
 3175: }
 3176: 
 3177: /**
 3178:  * xmlSchemaPContentErr:
 3179:  * @ctxt: the schema parser context
 3180:  * @error: the error code
 3181:  * @onwerDes: the designation of the holder of the content
 3182:  * @ownerItem: the owner item of the holder of the content
 3183:  * @ownerElem: the node of the holder of the content
 3184:  * @child: the invalid child node
 3185:  * @message: the optional error message
 3186:  * @content: the optional string describing the correct content
 3187:  *
 3188:  * Reports an error concerning the content of a schema element.
 3189:  */
 3190: static void
 3191: xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
 3192: 		     xmlParserErrors error,
 3193: 		     xmlSchemaBasicItemPtr ownerItem,
 3194: 		     xmlNodePtr ownerElem,
 3195: 		     xmlNodePtr child,
 3196: 		     const char *message,
 3197: 		     const char *content)
 3198: {
 3199:     xmlChar *des = NULL;
 3200: 
 3201:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 3202:     if (message != NULL)
 3203: 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3204: 	    "%s: %s.\n",
 3205: 	    BAD_CAST des, BAD_CAST message);
 3206:     else {
 3207: 	if (content != NULL) {
 3208: 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3209: 		"%s: The content is not valid. Expected is %s.\n",
 3210: 		BAD_CAST des, BAD_CAST content);
 3211: 	} else {
 3212: 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3213: 		"%s: The content is not valid.\n",
 3214: 		BAD_CAST des, NULL);
 3215: 	}
 3216:     }
 3217:     FREE_AND_NULL(des)
 3218: }
 3219: 
 3220: /************************************************************************
 3221:  *									*
 3222:  *			Streamable error functions                      *
 3223:  *									*
 3224:  ************************************************************************/
 3225: 
 3226: 
 3227: 
 3228: 
 3229: /************************************************************************
 3230:  *									*
 3231:  *			Validation helper functions			*
 3232:  *									*
 3233:  ************************************************************************/
 3234: 
 3235: 
 3236: /************************************************************************
 3237:  *									*
 3238:  *			Allocation functions				*
 3239:  *									*
 3240:  ************************************************************************/
 3241: 
 3242: /**
 3243:  * xmlSchemaNewSchemaForParserCtxt:
 3244:  * @ctxt:  a schema validation context
 3245:  *
 3246:  * Allocate a new Schema structure.
 3247:  *
 3248:  * Returns the newly allocated structure or NULL in case or error
 3249:  */
 3250: static xmlSchemaPtr
 3251: xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
 3252: {
 3253:     xmlSchemaPtr ret;
 3254: 
 3255:     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
 3256:     if (ret == NULL) {
 3257:         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
 3258:         return (NULL);
 3259:     }
 3260:     memset(ret, 0, sizeof(xmlSchema));
 3261:     ret->dict = ctxt->dict;
 3262:     xmlDictReference(ret->dict);
 3263: 
 3264:     return (ret);
 3265: }
 3266: 
 3267: /**
 3268:  * xmlSchemaNewFacet:
 3269:  *
 3270:  * Allocate a new Facet structure.
 3271:  *
 3272:  * Returns the newly allocated structure or NULL in case or error
 3273:  */
 3274: xmlSchemaFacetPtr
 3275: xmlSchemaNewFacet(void)
 3276: {
 3277:     xmlSchemaFacetPtr ret;
 3278: 
 3279:     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
 3280:     if (ret == NULL) {
 3281:         return (NULL);
 3282:     }
 3283:     memset(ret, 0, sizeof(xmlSchemaFacet));
 3284: 
 3285:     return (ret);
 3286: }
 3287: 
 3288: /**
 3289:  * xmlSchemaNewAnnot:
 3290:  * @ctxt:  a schema validation context
 3291:  * @node:  a node
 3292:  *
 3293:  * Allocate a new annotation structure.
 3294:  *
 3295:  * Returns the newly allocated structure or NULL in case or error
 3296:  */
 3297: static xmlSchemaAnnotPtr
 3298: xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 3299: {
 3300:     xmlSchemaAnnotPtr ret;
 3301: 
 3302:     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
 3303:     if (ret == NULL) {
 3304:         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
 3305:         return (NULL);
 3306:     }
 3307:     memset(ret, 0, sizeof(xmlSchemaAnnot));
 3308:     ret->content = node;
 3309:     return (ret);
 3310: }
 3311: 
 3312: static xmlSchemaItemListPtr
 3313: xmlSchemaItemListCreate(void)
 3314: {
 3315:     xmlSchemaItemListPtr ret;
 3316: 
 3317:     ret = xmlMalloc(sizeof(xmlSchemaItemList));
 3318:     if (ret == NULL) {
 3319: 	xmlSchemaPErrMemory(NULL,
 3320: 	    "allocating an item list structure", NULL);
 3321: 	return (NULL);
 3322:     }
 3323:     memset(ret, 0, sizeof(xmlSchemaItemList));
 3324:     return (ret);
 3325: }
 3326: 
 3327: static void
 3328: xmlSchemaItemListClear(xmlSchemaItemListPtr list)
 3329: {
 3330:     if (list->items != NULL) {
 3331: 	xmlFree(list->items);
 3332: 	list->items = NULL;
 3333:     }
 3334:     list->nbItems = 0;
 3335:     list->sizeItems = 0;
 3336: }
 3337: 
 3338: static int
 3339: xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
 3340: {
 3341:     if (list->items == NULL) {
 3342: 	list->items = (void **) xmlMalloc(
 3343: 	    20 * sizeof(void *));
 3344: 	if (list->items == NULL) {
 3345: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3346: 	    return(-1);
 3347: 	}
 3348: 	list->sizeItems = 20;
 3349:     } else if (list->sizeItems <= list->nbItems) {
 3350: 	list->sizeItems *= 2;
 3351: 	list->items = (void **) xmlRealloc(list->items,
 3352: 	    list->sizeItems * sizeof(void *));
 3353: 	if (list->items == NULL) {
 3354: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3355: 	    list->sizeItems = 0;
 3356: 	    return(-1);
 3357: 	}
 3358:     }
 3359:     list->items[list->nbItems++] = item;
 3360:     return(0);
 3361: }
 3362: 
 3363: static int
 3364: xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
 3365: 			 int initialSize,
 3366: 			 void *item)
 3367: {
 3368:     if (list->items == NULL) {
 3369: 	if (initialSize <= 0)
 3370: 	    initialSize = 1;
 3371: 	list->items = (void **) xmlMalloc(
 3372: 	    initialSize * sizeof(void *));
 3373: 	if (list->items == NULL) {
 3374: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3375: 	    return(-1);
 3376: 	}
 3377: 	list->sizeItems = initialSize;
 3378:     } else if (list->sizeItems <= list->nbItems) {
 3379: 	list->sizeItems *= 2;
 3380: 	list->items = (void **) xmlRealloc(list->items,
 3381: 	    list->sizeItems * sizeof(void *));
 3382: 	if (list->items == NULL) {
 3383: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3384: 	    list->sizeItems = 0;
 3385: 	    return(-1);
 3386: 	}
 3387:     }
 3388:     list->items[list->nbItems++] = item;
 3389:     return(0);
 3390: }
 3391: 
 3392: static int
 3393: xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
 3394: {
 3395:     if (list->items == NULL) {
 3396: 	list->items = (void **) xmlMalloc(
 3397: 	    20 * sizeof(void *));
 3398: 	if (list->items == NULL) {
 3399: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3400: 	    return(-1);
 3401: 	}
 3402: 	list->sizeItems = 20;
 3403:     } else if (list->sizeItems <= list->nbItems) {
 3404: 	list->sizeItems *= 2;
 3405: 	list->items = (void **) xmlRealloc(list->items,
 3406: 	    list->sizeItems * sizeof(void *));
 3407: 	if (list->items == NULL) {
 3408: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3409: 	    list->sizeItems = 0;
 3410: 	    return(-1);
 3411: 	}
 3412:     }
 3413:     /*
 3414:     * Just append if the index is greater/equal than the item count.
 3415:     */
 3416:     if (idx >= list->nbItems) {
 3417: 	list->items[list->nbItems++] = item;
 3418:     } else {
 3419: 	int i;
 3420: 	for (i = list->nbItems; i > idx; i--)
 3421: 	    list->items[i] = list->items[i-1];
 3422: 	list->items[idx] = item;
 3423: 	list->nbItems++;
 3424:     }
 3425:     return(0);
 3426: }
 3427: 
 3428: #if 0 /* enable if ever needed */
 3429: static int
 3430: xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
 3431: 			    int initialSize,
 3432: 			    void *item,
 3433: 			    int idx)
 3434: {
 3435:     if (list->items == NULL) {
 3436: 	if (initialSize <= 0)
 3437: 	    initialSize = 1;
 3438: 	list->items = (void **) xmlMalloc(
 3439: 	    initialSize * sizeof(void *));
 3440: 	if (list->items == NULL) {
 3441: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3442: 	    return(-1);
 3443: 	}
 3444: 	list->sizeItems = initialSize;
 3445:     } else if (list->sizeItems <= list->nbItems) {
 3446: 	list->sizeItems *= 2;
 3447: 	list->items = (void **) xmlRealloc(list->items,
 3448: 	    list->sizeItems * sizeof(void *));
 3449: 	if (list->items == NULL) {
 3450: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3451: 	    list->sizeItems = 0;
 3452: 	    return(-1);
 3453: 	}
 3454:     }
 3455:     /*
 3456:     * Just append if the index is greater/equal than the item count.
 3457:     */
 3458:     if (idx >= list->nbItems) {
 3459: 	list->items[list->nbItems++] = item;
 3460:     } else {
 3461: 	int i;
 3462: 	for (i = list->nbItems; i > idx; i--)
 3463: 	    list->items[i] = list->items[i-1];
 3464: 	list->items[idx] = item;
 3465: 	list->nbItems++;
 3466:     }
 3467:     return(0);
 3468: }
 3469: #endif
 3470: 
 3471: static int
 3472: xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
 3473: {
 3474:     int i;
 3475:     if ((list->items == NULL) || (idx >= list->nbItems)) {
 3476: 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
 3477: 	    "index error.\n");
 3478: 	return(-1);
 3479:     }
 3480: 
 3481:     if (list->nbItems == 1) {
 3482: 	/* TODO: Really free the list? */
 3483: 	xmlFree(list->items);
 3484: 	list->items = NULL;
 3485: 	list->nbItems = 0;
 3486: 	list->sizeItems = 0;
 3487:     } else if (list->nbItems -1 == idx) {
 3488: 	list->nbItems--;
 3489:     } else {
 3490: 	for (i = idx; i < list->nbItems -1; i++)
 3491: 	    list->items[i] = list->items[i+1];
 3492: 	list->nbItems--;
 3493:     }
 3494:     return(0);
 3495: }
 3496: 
 3497: /**
 3498:  * xmlSchemaItemListFree:
 3499:  * @annot:  a schema type structure
 3500:  *
 3501:  * Deallocate a annotation structure
 3502:  */
 3503: static void
 3504: xmlSchemaItemListFree(xmlSchemaItemListPtr list)
 3505: {
 3506:     if (list == NULL)
 3507: 	return;
 3508:     if (list->items != NULL)
 3509: 	xmlFree(list->items);
 3510:     xmlFree(list);
 3511: }
 3512: 
 3513: static void
 3514: xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
 3515: {
 3516:     if (bucket == NULL)
 3517: 	return;
 3518:     if (bucket->globals != NULL) {
 3519: 	xmlSchemaComponentListFree(bucket->globals);
 3520: 	xmlSchemaItemListFree(bucket->globals);
 3521:     }
 3522:     if (bucket->locals != NULL) {
 3523: 	xmlSchemaComponentListFree(bucket->locals);
 3524: 	xmlSchemaItemListFree(bucket->locals);
 3525:     }
 3526:     if (bucket->relations != NULL) {
 3527: 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
 3528: 	do {
 3529: 	    prev = cur;
 3530: 	    cur = cur->next;
 3531: 	    xmlFree(prev);
 3532: 	} while (cur != NULL);
 3533:     }
 3534:     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
 3535: 	xmlFreeDoc(bucket->doc);
 3536:     }
 3537:     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
 3538: 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
 3539: 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
 3540:     }
 3541:     xmlFree(bucket);
 3542: }
 3543: 
 3544: static xmlSchemaBucketPtr
 3545: xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
 3546: 			 int type, const xmlChar *targetNamespace)
 3547: {
 3548:     xmlSchemaBucketPtr ret;
 3549:     int size;
 3550:     xmlSchemaPtr mainSchema;
 3551: 
 3552:     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
 3553: 	PERROR_INT("xmlSchemaBucketCreate",
 3554: 	    "no main schema on constructor");
 3555: 	return(NULL);
 3556:     }
 3557:     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
 3558:     /* Create the schema bucket. */
 3559:     if (WXS_IS_BUCKET_INCREDEF(type))
 3560: 	size = sizeof(xmlSchemaInclude);
 3561:     else
 3562: 	size = sizeof(xmlSchemaImport);
 3563:     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
 3564:     if (ret == NULL) {
 3565: 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
 3566: 	return(NULL);
 3567:     }
 3568:     memset(ret, 0, size);
 3569:     ret->targetNamespace = targetNamespace;
 3570:     ret->type = type;
 3571:     ret->globals = xmlSchemaItemListCreate();
 3572:     if (ret->globals == NULL) {
 3573: 	xmlFree(ret);
 3574: 	return(NULL);
 3575:     }
 3576:     ret->locals = xmlSchemaItemListCreate();
 3577:     if (ret->locals == NULL) {
 3578: 	xmlFree(ret);
 3579: 	return(NULL);
 3580:     }
 3581:     /*
 3582:     * The following will assure that only the first bucket is marked as
 3583:     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
 3584:     * For each following import buckets an xmlSchema will be created.
 3585:     * An xmlSchema will be created for every distinct targetNamespace.
 3586:     * We assign the targetNamespace to the schemata here.
 3587:     */
 3588:     if (! WXS_HAS_BUCKETS(pctxt)) {
 3589: 	if (WXS_IS_BUCKET_INCREDEF(type)) {
 3590: 	    PERROR_INT("xmlSchemaBucketCreate",
 3591: 		"first bucket but it's an include or redefine");
 3592: 	    xmlSchemaBucketFree(ret);
 3593: 	    return(NULL);
 3594: 	}
 3595: 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
 3596: 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
 3597: 	/* Point to the *main* schema. */
 3598: 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
 3599: 	WXS_IMPBUCKET(ret)->schema = mainSchema;
 3600: 	/*
 3601: 	* Ensure that the main schema gets a targetNamespace.
 3602: 	*/
 3603: 	mainSchema->targetNamespace = targetNamespace;
 3604:     } else {
 3605: 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
 3606: 	    PERROR_INT("xmlSchemaBucketCreate",
 3607: 		"main bucket but it's not the first one");
 3608: 	    xmlSchemaBucketFree(ret);
 3609: 	    return(NULL);
 3610: 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
 3611: 	    /*
 3612: 	    * Create a schema for imports and assign the
 3613: 	    * targetNamespace.
 3614: 	    */
 3615: 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
 3616: 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
 3617: 		xmlSchemaBucketFree(ret);
 3618: 		return(NULL);
 3619: 	    }
 3620: 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
 3621: 	}
 3622:     }
 3623:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
 3624: 	int res;
 3625: 	/*
 3626: 	* Imports go into the "schemasImports" slot of the main *schema*.
 3627: 	* Note that we create an import entry for the main schema as well; i.e.,
 3628: 	* even if there's only one schema, we'll get an import.
 3629: 	*/
 3630: 	if (mainSchema->schemasImports == NULL) {
 3631: 	    mainSchema->schemasImports = xmlHashCreateDict(5,
 3632: 		WXS_CONSTRUCTOR(pctxt)->dict);
 3633: 	    if (mainSchema->schemasImports == NULL) {
 3634: 		xmlSchemaBucketFree(ret);
 3635: 		return(NULL);
 3636: 	    }
 3637: 	}
 3638: 	if (targetNamespace == NULL)
 3639: 	    res = xmlHashAddEntry(mainSchema->schemasImports,
 3640: 		XML_SCHEMAS_NO_NAMESPACE, ret);
 3641: 	else
 3642: 	    res = xmlHashAddEntry(mainSchema->schemasImports,
 3643: 		targetNamespace, ret);
 3644: 	if (res != 0) {
 3645: 	    PERROR_INT("xmlSchemaBucketCreate",
 3646: 		"failed to add the schema bucket to the hash");
 3647: 	    xmlSchemaBucketFree(ret);
 3648: 	    return(NULL);
 3649: 	}
 3650:     } else {
 3651: 	/* Set the @ownerImport of an include bucket. */
 3652: 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
 3653: 	    WXS_INCBUCKET(ret)->ownerImport =
 3654: 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
 3655: 	else
 3656: 	    WXS_INCBUCKET(ret)->ownerImport =
 3657: 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
 3658: 
 3659: 	/* Includes got into the "includes" slot of the *main* schema. */
 3660: 	if (mainSchema->includes == NULL) {
 3661: 	    mainSchema->includes = xmlSchemaItemListCreate();
 3662: 	    if (mainSchema->includes == NULL) {
 3663: 		xmlSchemaBucketFree(ret);
 3664: 		return(NULL);
 3665: 	    }
 3666: 	}
 3667: 	xmlSchemaItemListAdd(mainSchema->includes, ret);
 3668:     }
 3669:     /*
 3670:     * Add to list of all buckets; this is used for lookup
 3671:     * during schema construction time only.
 3672:     */
 3673:     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
 3674: 	return(NULL);
 3675:     return(ret);
 3676: }
 3677: 
 3678: static int
 3679: xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
 3680: {
 3681:     if (*list == NULL) {
 3682: 	*list = xmlSchemaItemListCreate();
 3683: 	if (*list == NULL)
 3684: 	    return(-1);
 3685:     }
 3686:     xmlSchemaItemListAddSize(*list, initialSize, item);
 3687:     return(0);
 3688: }
 3689: 
 3690: /**
 3691:  * xmlSchemaFreeAnnot:
 3692:  * @annot:  a schema type structure
 3693:  *
 3694:  * Deallocate a annotation structure
 3695:  */
 3696: static void
 3697: xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
 3698: {
 3699:     if (annot == NULL)
 3700:         return;
 3701:     if (annot->next == NULL) {
 3702: 	xmlFree(annot);
 3703:     } else {
 3704: 	xmlSchemaAnnotPtr prev;
 3705: 
 3706: 	do {
 3707: 	    prev = annot;
 3708: 	    annot = annot->next;
 3709: 	    xmlFree(prev);
 3710: 	} while (annot != NULL);
 3711:     }
 3712: }
 3713: 
 3714: /**
 3715:  * xmlSchemaFreeNotation:
 3716:  * @schema:  a schema notation structure
 3717:  *
 3718:  * Deallocate a Schema Notation structure.
 3719:  */
 3720: static void
 3721: xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
 3722: {
 3723:     if (nota == NULL)
 3724:         return;
 3725:     xmlFree(nota);
 3726: }
 3727: 
 3728: /**
 3729:  * xmlSchemaFreeAttribute:
 3730:  * @attr:  an attribute declaration
 3731:  *
 3732:  * Deallocates an attribute declaration structure.
 3733:  */
 3734: static void
 3735: xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
 3736: {
 3737:     if (attr == NULL)
 3738:         return;
 3739:     if (attr->annot != NULL)
 3740: 	xmlSchemaFreeAnnot(attr->annot);
 3741:     if (attr->defVal != NULL)
 3742: 	xmlSchemaFreeValue(attr->defVal);
 3743:     xmlFree(attr);
 3744: }
 3745: 
 3746: /**
 3747:  * xmlSchemaFreeAttributeUse:
 3748:  * @use:  an attribute use
 3749:  *
 3750:  * Deallocates an attribute use structure.
 3751:  */
 3752: static void
 3753: xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
 3754: {
 3755:     if (use == NULL)
 3756:         return;
 3757:     if (use->annot != NULL)
 3758: 	xmlSchemaFreeAnnot(use->annot);
 3759:     if (use->defVal != NULL)
 3760: 	xmlSchemaFreeValue(use->defVal);
 3761:     xmlFree(use);
 3762: }
 3763: 
 3764: /**
 3765:  * xmlSchemaFreeAttributeUseProhib:
 3766:  * @prohib:  an attribute use prohibition
 3767:  *
 3768:  * Deallocates an attribute use structure.
 3769:  */
 3770: static void
 3771: xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
 3772: {
 3773:     if (prohib == NULL)
 3774:         return;
 3775:     xmlFree(prohib);
 3776: }
 3777: 
 3778: /**
 3779:  * xmlSchemaFreeWildcardNsSet:
 3780:  * set:  a schema wildcard namespace
 3781:  *
 3782:  * Deallocates a list of wildcard constraint structures.
 3783:  */
 3784: static void
 3785: xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
 3786: {
 3787:     xmlSchemaWildcardNsPtr next;
 3788: 
 3789:     while (set != NULL) {
 3790: 	next = set->next;
 3791: 	xmlFree(set);
 3792: 	set = next;
 3793:     }
 3794: }
 3795: 
 3796: /**
 3797:  * xmlSchemaFreeWildcard:
 3798:  * @wildcard:  a wildcard structure
 3799:  *
 3800:  * Deallocates a wildcard structure.
 3801:  */
 3802: void
 3803: xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
 3804: {
 3805:     if (wildcard == NULL)
 3806:         return;
 3807:     if (wildcard->annot != NULL)
 3808:         xmlSchemaFreeAnnot(wildcard->annot);
 3809:     if (wildcard->nsSet != NULL)
 3810: 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
 3811:     if (wildcard->negNsSet != NULL)
 3812: 	xmlFree(wildcard->negNsSet);
 3813:     xmlFree(wildcard);
 3814: }
 3815: 
 3816: /**
 3817:  * xmlSchemaFreeAttributeGroup:
 3818:  * @schema:  a schema attribute group structure
 3819:  *
 3820:  * Deallocate a Schema Attribute Group structure.
 3821:  */
 3822: static void
 3823: xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
 3824: {
 3825:     if (attrGr == NULL)
 3826:         return;
 3827:     if (attrGr->annot != NULL)
 3828:         xmlSchemaFreeAnnot(attrGr->annot);
 3829:     if (attrGr->attrUses != NULL)
 3830: 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
 3831:     xmlFree(attrGr);
 3832: }
 3833: 
 3834: /**
 3835:  * xmlSchemaFreeQNameRef:
 3836:  * @item: a QName reference structure
 3837:  *
 3838:  * Deallocatea a QName reference structure.
 3839:  */
 3840: static void
 3841: xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
 3842: {
 3843:     xmlFree(item);
 3844: }
 3845: 
 3846: /**
 3847:  * xmlSchemaFreeTypeLinkList:
 3848:  * @alink: a type link
 3849:  *
 3850:  * Deallocate a list of types.
 3851:  */
 3852: static void
 3853: xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
 3854: {
 3855:     xmlSchemaTypeLinkPtr next;
 3856: 
 3857:     while (link != NULL) {
 3858: 	next = link->next;
 3859: 	xmlFree(link);
 3860: 	link = next;
 3861:     }
 3862: }
 3863: 
 3864: static void
 3865: xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
 3866: {
 3867:     xmlSchemaIDCStateObjPtr next;
 3868:     while (sto != NULL) {
 3869: 	next = sto->next;
 3870: 	if (sto->history != NULL)
 3871: 	    xmlFree(sto->history);
 3872: 	if (sto->xpathCtxt != NULL)
 3873: 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
 3874: 	xmlFree(sto);
 3875: 	sto = next;
 3876:     }
 3877: }
 3878: 
 3879: /**
 3880:  * xmlSchemaFreeIDC:
 3881:  * @idc: a identity-constraint definition
 3882:  *
 3883:  * Deallocates an identity-constraint definition.
 3884:  */
 3885: static void
 3886: xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
 3887: {
 3888:     xmlSchemaIDCSelectPtr cur, prev;
 3889: 
 3890:     if (idcDef == NULL)
 3891: 	return;
 3892:     if (idcDef->annot != NULL)
 3893:         xmlSchemaFreeAnnot(idcDef->annot);
 3894:     /* Selector */
 3895:     if (idcDef->selector != NULL) {
 3896: 	if (idcDef->selector->xpathComp != NULL)
 3897: 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
 3898: 	xmlFree(idcDef->selector);
 3899:     }
 3900:     /* Fields */
 3901:     if (idcDef->fields != NULL) {
 3902: 	cur = idcDef->fields;
 3903: 	do {
 3904: 	    prev = cur;
 3905: 	    cur = cur->next;
 3906: 	    if (prev->xpathComp != NULL)
 3907: 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
 3908: 	    xmlFree(prev);
 3909: 	} while (cur != NULL);
 3910:     }
 3911:     xmlFree(idcDef);
 3912: }
 3913: 
 3914: /**
 3915:  * xmlSchemaFreeElement:
 3916:  * @schema:  a schema element structure
 3917:  *
 3918:  * Deallocate a Schema Element structure.
 3919:  */
 3920: static void
 3921: xmlSchemaFreeElement(xmlSchemaElementPtr elem)
 3922: {
 3923:     if (elem == NULL)
 3924:         return;
 3925:     if (elem->annot != NULL)
 3926:         xmlSchemaFreeAnnot(elem->annot);
 3927:     if (elem->contModel != NULL)
 3928:         xmlRegFreeRegexp(elem->contModel);
 3929:     if (elem->defVal != NULL)
 3930: 	xmlSchemaFreeValue(elem->defVal);
 3931:     xmlFree(elem);
 3932: }
 3933: 
 3934: /**
 3935:  * xmlSchemaFreeFacet:
 3936:  * @facet:  a schema facet structure
 3937:  *
 3938:  * Deallocate a Schema Facet structure.
 3939:  */
 3940: void
 3941: xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
 3942: {
 3943:     if (facet == NULL)
 3944:         return;
 3945:     if (facet->val != NULL)
 3946:         xmlSchemaFreeValue(facet->val);
 3947:     if (facet->regexp != NULL)
 3948:         xmlRegFreeRegexp(facet->regexp);
 3949:     if (facet->annot != NULL)
 3950:         xmlSchemaFreeAnnot(facet->annot);
 3951:     xmlFree(facet);
 3952: }
 3953: 
 3954: /**
 3955:  * xmlSchemaFreeType:
 3956:  * @type:  a schema type structure
 3957:  *
 3958:  * Deallocate a Schema Type structure.
 3959:  */
 3960: void
 3961: xmlSchemaFreeType(xmlSchemaTypePtr type)
 3962: {
 3963:     if (type == NULL)
 3964:         return;
 3965:     if (type->annot != NULL)
 3966:         xmlSchemaFreeAnnot(type->annot);
 3967:     if (type->facets != NULL) {
 3968:         xmlSchemaFacetPtr facet, next;
 3969: 
 3970:         facet = type->facets;
 3971:         while (facet != NULL) {
 3972:             next = facet->next;
 3973:             xmlSchemaFreeFacet(facet);
 3974:             facet = next;
 3975:         }
 3976:     }
 3977:     if (type->attrUses != NULL)
 3978: 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
 3979:     if (type->memberTypes != NULL)
 3980: 	xmlSchemaFreeTypeLinkList(type->memberTypes);
 3981:     if (type->facetSet != NULL) {
 3982: 	xmlSchemaFacetLinkPtr next, link;
 3983: 
 3984: 	link = type->facetSet;
 3985: 	do {
 3986: 	    next = link->next;
 3987: 	    xmlFree(link);
 3988: 	    link = next;
 3989: 	} while (link != NULL);
 3990:     }
 3991:     if (type->contModel != NULL)
 3992:         xmlRegFreeRegexp(type->contModel);
 3993:     xmlFree(type);
 3994: }
 3995: 
 3996: /**
 3997:  * xmlSchemaFreeModelGroupDef:
 3998:  * @item:  a schema model group definition
 3999:  *
 4000:  * Deallocates a schema model group definition.
 4001:  */
 4002: static void
 4003: xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
 4004: {
 4005:     if (item->annot != NULL)
 4006: 	xmlSchemaFreeAnnot(item->annot);
 4007:     xmlFree(item);
 4008: }
 4009: 
 4010: /**
 4011:  * xmlSchemaFreeModelGroup:
 4012:  * @item:  a schema model group
 4013:  *
 4014:  * Deallocates a schema model group structure.
 4015:  */
 4016: static void
 4017: xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
 4018: {
 4019:     if (item->annot != NULL)
 4020: 	xmlSchemaFreeAnnot(item->annot);
 4021:     xmlFree(item);
 4022: }
 4023: 
 4024: static void
 4025: xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
 4026: {
 4027:     if ((list == NULL) || (list->nbItems == 0))
 4028: 	return;
 4029:     {
 4030: 	xmlSchemaTreeItemPtr item;
 4031: 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
 4032: 	int i;
 4033: 
 4034: 	for (i = 0; i < list->nbItems; i++) {
 4035: 	    item = items[i];
 4036: 	    if (item == NULL)
 4037: 		continue;
 4038: 	    switch (item->type) {
 4039: 		case XML_SCHEMA_TYPE_SIMPLE:
 4040: 		case XML_SCHEMA_TYPE_COMPLEX:
 4041: 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
 4042: 		    break;
 4043: 		case XML_SCHEMA_TYPE_ATTRIBUTE:
 4044: 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
 4045: 		    break;
 4046: 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 4047: 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
 4048: 		    break;
 4049: 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 4050: 		    xmlSchemaFreeAttributeUseProhib(
 4051: 			(xmlSchemaAttributeUseProhibPtr) item);
 4052: 		    break;
 4053: 		case XML_SCHEMA_TYPE_ELEMENT:
 4054: 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
 4055: 		    break;
 4056: 		case XML_SCHEMA_TYPE_PARTICLE:
 4057: 		    if (item->annot != NULL)
 4058: 			xmlSchemaFreeAnnot(item->annot);
 4059: 		    xmlFree(item);
 4060: 		    break;
 4061: 		case XML_SCHEMA_TYPE_SEQUENCE:
 4062: 		case XML_SCHEMA_TYPE_CHOICE:
 4063: 		case XML_SCHEMA_TYPE_ALL:
 4064: 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
 4065: 		    break;
 4066: 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 4067: 		    xmlSchemaFreeAttributeGroup(
 4068: 			(xmlSchemaAttributeGroupPtr) item);
 4069: 		    break;
 4070: 		case XML_SCHEMA_TYPE_GROUP:
 4071: 		    xmlSchemaFreeModelGroupDef(
 4072: 			(xmlSchemaModelGroupDefPtr) item);
 4073: 		    break;
 4074: 		case XML_SCHEMA_TYPE_ANY:
 4075: 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 4076: 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
 4077: 		    break;
 4078: 		case XML_SCHEMA_TYPE_IDC_KEY:
 4079: 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
 4080: 		case XML_SCHEMA_TYPE_IDC_KEYREF:
 4081: 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
 4082: 		    break;
 4083: 		case XML_SCHEMA_TYPE_NOTATION:
 4084: 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
 4085: 		    break;
 4086: 		case XML_SCHEMA_EXTRA_QNAMEREF:
 4087: 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
 4088: 		    break;
 4089: 		default: {
 4090: 		    /* TODO: This should never be hit. */
 4091: 		    xmlSchemaPSimpleInternalErr(NULL,
 4092: 			"Internal error: xmlSchemaComponentListFree, "
 4093: 			"unexpected component type '%s'\n",
 4094: 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
 4095: 			 }
 4096: 		    break;
 4097: 	    }
 4098: 	}
 4099: 	list->nbItems = 0;
 4100:     }
 4101: }
 4102: 
 4103: /**
 4104:  * xmlSchemaFree:
 4105:  * @schema:  a schema structure
 4106:  *
 4107:  * Deallocate a Schema structure.
 4108:  */
 4109: void
 4110: xmlSchemaFree(xmlSchemaPtr schema)
 4111: {
 4112:     if (schema == NULL)
 4113:         return;
 4114:     /* @volatiles is not used anymore :-/ */
 4115:     if (schema->volatiles != NULL)
 4116: 	TODO
 4117:     /*
 4118:     * Note that those slots are not responsible for freeing
 4119:     * schema components anymore; this will now be done by
 4120:     * the schema buckets.
 4121:     */
 4122:     if (schema->notaDecl != NULL)
 4123:         xmlHashFree(schema->notaDecl, NULL);
 4124:     if (schema->attrDecl != NULL)
 4125:         xmlHashFree(schema->attrDecl, NULL);
 4126:     if (schema->attrgrpDecl != NULL)
 4127:         xmlHashFree(schema->attrgrpDecl, NULL);
 4128:     if (schema->elemDecl != NULL)
 4129:         xmlHashFree(schema->elemDecl, NULL);
 4130:     if (schema->typeDecl != NULL)
 4131:         xmlHashFree(schema->typeDecl, NULL);
 4132:     if (schema->groupDecl != NULL)
 4133:         xmlHashFree(schema->groupDecl, NULL);
 4134:     if (schema->idcDef != NULL)
 4135:         xmlHashFree(schema->idcDef, NULL);
 4136: 
 4137:     if (schema->schemasImports != NULL)
 4138: 	xmlHashFree(schema->schemasImports,
 4139: 		    (xmlHashDeallocator) xmlSchemaBucketFree);
 4140:     if (schema->includes != NULL) {
 4141: 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
 4142: 	int i;
 4143: 	for (i = 0; i < list->nbItems; i++) {
 4144: 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
 4145: 	}
 4146: 	xmlSchemaItemListFree(list);
 4147:     }
 4148:     if (schema->annot != NULL)
 4149:         xmlSchemaFreeAnnot(schema->annot);
 4150:     /* Never free the doc here, since this will be done by the buckets. */
 4151: 
 4152:     xmlDictFree(schema->dict);
 4153:     xmlFree(schema);
 4154: }
 4155: 
 4156: /************************************************************************
 4157:  *									*
 4158:  *			Debug functions					*
 4159:  *									*
 4160:  ************************************************************************/
 4161: 
 4162: #ifdef LIBXML_OUTPUT_ENABLED
 4163: 
 4164: static void
 4165: xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
 4166: 
 4167: /**
 4168:  * xmlSchemaElementDump:
 4169:  * @elem:  an element
 4170:  * @output:  the file output
 4171:  *
 4172:  * Dump the element
 4173:  */
 4174: static void
 4175: xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
 4176:                      const xmlChar * name ATTRIBUTE_UNUSED,
 4177: 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
 4178:                      const xmlChar * context ATTRIBUTE_UNUSED)
 4179: {
 4180:     if (elem == NULL)
 4181:         return;
 4182: 
 4183: 
 4184:     fprintf(output, "Element");
 4185:     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
 4186: 	fprintf(output, " (global)");
 4187:     fprintf(output, ": '%s' ", elem->name);
 4188:     if (namespace != NULL)
 4189: 	fprintf(output, "ns '%s'", namespace);
 4190:     fprintf(output, "\n");
 4191: #if 0
 4192:     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
 4193: 	fprintf(output, "  min %d ", elem->minOccurs);
 4194:         if (elem->maxOccurs >= UNBOUNDED)
 4195:             fprintf(output, "max: unbounded\n");
 4196:         else if (elem->maxOccurs != 1)
 4197:             fprintf(output, "max: %d\n", elem->maxOccurs);
 4198:         else
 4199:             fprintf(output, "\n");
 4200:     }
 4201: #endif
 4202:     /*
 4203:     * Misc other properties.
 4204:     */
 4205:     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
 4206: 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
 4207: 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
 4208: 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
 4209: 	fprintf(output, "  props: ");
 4210: 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
 4211: 	    fprintf(output, "[fixed] ");
 4212: 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
 4213: 	    fprintf(output, "[default] ");
 4214: 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
 4215: 	    fprintf(output, "[abstract] ");
 4216: 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
 4217: 	    fprintf(output, "[nillable] ");
 4218: 	fprintf(output, "\n");
 4219:     }
 4220:     /*
 4221:     * Default/fixed value.
 4222:     */
 4223:     if (elem->value != NULL)
 4224: 	fprintf(output, "  value: '%s'\n", elem->value);
 4225:     /*
 4226:     * Type.
 4227:     */
 4228:     if (elem->namedType != NULL) {
 4229: 	fprintf(output, "  type: '%s' ", elem->namedType);
 4230: 	if (elem->namedTypeNs != NULL)
 4231: 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
 4232: 	else
 4233: 	    fprintf(output, "\n");
 4234:     } else if (elem->subtypes != NULL) {
 4235: 	/*
 4236: 	* Dump local types.
 4237: 	*/
 4238: 	xmlSchemaTypeDump(elem->subtypes, output);
 4239:     }
 4240:     /*
 4241:     * Substitution group.
 4242:     */
 4243:     if (elem->substGroup != NULL) {
 4244: 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
 4245: 	if (elem->substGroupNs != NULL)
 4246: 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
 4247: 	else
 4248: 	    fprintf(output, "\n");
 4249:     }
 4250: }
 4251: 
 4252: /**
 4253:  * xmlSchemaAnnotDump:
 4254:  * @output:  the file output
 4255:  * @annot:  a annotation
 4256:  *
 4257:  * Dump the annotation
 4258:  */
 4259: static void
 4260: xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
 4261: {
 4262:     xmlChar *content;
 4263: 
 4264:     if (annot == NULL)
 4265:         return;
 4266: 
 4267:     content = xmlNodeGetContent(annot->content);
 4268:     if (content != NULL) {
 4269:         fprintf(output, "  Annot: %s\n", content);
 4270:         xmlFree(content);
 4271:     } else
 4272:         fprintf(output, "  Annot: empty\n");
 4273: }
 4274: 
 4275: /**
 4276:  * xmlSchemaContentModelDump:
 4277:  * @particle: the schema particle
 4278:  * @output: the file output
 4279:  * @depth: the depth used for intentation
 4280:  *
 4281:  * Dump a SchemaType structure
 4282:  */
 4283: static void
 4284: xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
 4285: {
 4286:     xmlChar *str = NULL;
 4287:     xmlSchemaTreeItemPtr term;
 4288:     char shift[100];
 4289:     int i;
 4290: 
 4291:     if (particle == NULL)
 4292: 	return;
 4293:     for (i = 0;((i < depth) && (i < 25));i++)
 4294:         shift[2 * i] = shift[2 * i + 1] = ' ';
 4295:     shift[2 * i] = shift[2 * i + 1] = 0;
 4296:     fprintf(output, "%s", shift);
 4297:     if (particle->children == NULL) {
 4298: 	fprintf(output, "MISSING particle term\n");
 4299: 	return;
 4300:     }
 4301:     term = particle->children;
 4302:     if (term == NULL) {
 4303: 	fprintf(output, "(NULL)");
 4304:     } else {
 4305: 	switch (term->type) {
 4306: 	    case XML_SCHEMA_TYPE_ELEMENT:
 4307: 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
 4308: 		    ((xmlSchemaElementPtr)term)->targetNamespace,
 4309: 		    ((xmlSchemaElementPtr)term)->name));
 4310: 		FREE_AND_NULL(str);
 4311: 		break;
 4312: 	    case XML_SCHEMA_TYPE_SEQUENCE:
 4313: 		fprintf(output, "SEQUENCE");
 4314: 		break;
 4315: 	    case XML_SCHEMA_TYPE_CHOICE:
 4316: 		fprintf(output, "CHOICE");
 4317: 		break;
 4318: 	    case XML_SCHEMA_TYPE_ALL:
 4319: 		fprintf(output, "ALL");
 4320: 		break;
 4321: 	    case XML_SCHEMA_TYPE_ANY:
 4322: 		fprintf(output, "ANY");
 4323: 		break;
 4324: 	    default:
 4325: 		fprintf(output, "UNKNOWN\n");
 4326: 		return;
 4327: 	}
 4328:     }
 4329:     if (particle->minOccurs != 1)
 4330: 	fprintf(output, " min: %d", particle->minOccurs);
 4331:     if (particle->maxOccurs >= UNBOUNDED)
 4332: 	fprintf(output, " max: unbounded");
 4333:     else if (particle->maxOccurs != 1)
 4334: 	fprintf(output, " max: %d", particle->maxOccurs);
 4335:     fprintf(output, "\n");
 4336:     if (term &&
 4337: 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
 4338: 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
 4339: 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
 4340: 	 (term->children != NULL)) {
 4341: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
 4342: 	    output, depth +1);
 4343:     }
 4344:     if (particle->next != NULL)
 4345: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
 4346: 		output, depth);
 4347: }
 4348: 
 4349: /**
 4350:  * xmlSchemaAttrUsesDump:
 4351:  * @uses:  attribute uses list
 4352:  * @output:  the file output
 4353:  *
 4354:  * Dumps a list of attribute use components.
 4355:  */
 4356: static void
 4357: xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
 4358: {
 4359:     xmlSchemaAttributeUsePtr use;
 4360:     xmlSchemaAttributeUseProhibPtr prohib;
 4361:     xmlSchemaQNameRefPtr ref;
 4362:     const xmlChar *name, *tns;
 4363:     xmlChar *str = NULL;
 4364:     int i;
 4365: 
 4366:     if ((uses == NULL) || (uses->nbItems == 0))
 4367:         return;
 4368: 
 4369:     fprintf(output, "  attributes:\n");
 4370:     for (i = 0; i < uses->nbItems; i++) {
 4371: 	use = uses->items[i];
 4372: 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
 4373: 	    fprintf(output, "  [prohibition] ");
 4374: 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
 4375: 	    name = prohib->name;
 4376: 	    tns = prohib->targetNamespace;
 4377: 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
 4378: 	    fprintf(output, "  [reference] ");
 4379: 	    ref = (xmlSchemaQNameRefPtr) use;
 4380: 	    name = ref->name;
 4381: 	    tns = ref->targetNamespace;
 4382: 	} else {
 4383: 	    fprintf(output, "  [use] ");
 4384: 	    name = WXS_ATTRUSE_DECL_NAME(use);
 4385: 	    tns = WXS_ATTRUSE_DECL_TNS(use);
 4386: 	}
 4387: 	fprintf(output, "'%s'\n",
 4388: 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
 4389: 	FREE_AND_NULL(str);
 4390:     }
 4391: }
 4392: 
 4393: /**
 4394:  * xmlSchemaTypeDump:
 4395:  * @output:  the file output
 4396:  * @type:  a type structure
 4397:  *
 4398:  * Dump a SchemaType structure
 4399:  */
 4400: static void
 4401: xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
 4402: {
 4403:     if (type == NULL) {
 4404:         fprintf(output, "Type: NULL\n");
 4405:         return;
 4406:     }
 4407:     fprintf(output, "Type: ");
 4408:     if (type->name != NULL)
 4409:         fprintf(output, "'%s' ", type->name);
 4410:     else
 4411:         fprintf(output, "(no name) ");
 4412:     if (type->targetNamespace != NULL)
 4413: 	fprintf(output, "ns '%s' ", type->targetNamespace);
 4414:     switch (type->type) {
 4415:         case XML_SCHEMA_TYPE_BASIC:
 4416:             fprintf(output, "[basic] ");
 4417:             break;
 4418:         case XML_SCHEMA_TYPE_SIMPLE:
 4419:             fprintf(output, "[simple] ");
 4420:             break;
 4421:         case XML_SCHEMA_TYPE_COMPLEX:
 4422:             fprintf(output, "[complex] ");
 4423:             break;
 4424:         case XML_SCHEMA_TYPE_SEQUENCE:
 4425:             fprintf(output, "[sequence] ");
 4426:             break;
 4427:         case XML_SCHEMA_TYPE_CHOICE:
 4428:             fprintf(output, "[choice] ");
 4429:             break;
 4430:         case XML_SCHEMA_TYPE_ALL:
 4431:             fprintf(output, "[all] ");
 4432:             break;
 4433:         case XML_SCHEMA_TYPE_UR:
 4434:             fprintf(output, "[ur] ");
 4435:             break;
 4436:         case XML_SCHEMA_TYPE_RESTRICTION:
 4437:             fprintf(output, "[restriction] ");
 4438:             break;
 4439:         case XML_SCHEMA_TYPE_EXTENSION:
 4440:             fprintf(output, "[extension] ");
 4441:             break;
 4442:         default:
 4443:             fprintf(output, "[unknown type %d] ", type->type);
 4444:             break;
 4445:     }
 4446:     fprintf(output, "content: ");
 4447:     switch (type->contentType) {
 4448:         case XML_SCHEMA_CONTENT_UNKNOWN:
 4449:             fprintf(output, "[unknown] ");
 4450:             break;
 4451:         case XML_SCHEMA_CONTENT_EMPTY:
 4452:             fprintf(output, "[empty] ");
 4453:             break;
 4454:         case XML_SCHEMA_CONTENT_ELEMENTS:
 4455:             fprintf(output, "[element] ");
 4456:             break;
 4457:         case XML_SCHEMA_CONTENT_MIXED:
 4458:             fprintf(output, "[mixed] ");
 4459:             break;
 4460:         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
 4461: 	/* not used. */
 4462:             break;
 4463:         case XML_SCHEMA_CONTENT_BASIC:
 4464:             fprintf(output, "[basic] ");
 4465:             break;
 4466:         case XML_SCHEMA_CONTENT_SIMPLE:
 4467:             fprintf(output, "[simple] ");
 4468:             break;
 4469:         case XML_SCHEMA_CONTENT_ANY:
 4470:             fprintf(output, "[any] ");
 4471:             break;
 4472:     }
 4473:     fprintf(output, "\n");
 4474:     if (type->base != NULL) {
 4475:         fprintf(output, "  base type: '%s'", type->base);
 4476: 	if (type->baseNs != NULL)
 4477: 	    fprintf(output, " ns '%s'\n", type->baseNs);
 4478: 	else
 4479: 	    fprintf(output, "\n");
 4480:     }
 4481:     if (type->attrUses != NULL)
 4482: 	xmlSchemaAttrUsesDump(type->attrUses, output);
 4483:     if (type->annot != NULL)
 4484:         xmlSchemaAnnotDump(output, type->annot);
 4485: #ifdef DUMP_CONTENT_MODEL
 4486:     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
 4487: 	(type->subtypes != NULL)) {
 4488: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
 4489: 	    output, 1);
 4490:     }
 4491: #endif
 4492: }
 4493: 
 4494: /**
 4495:  * xmlSchemaDump:
 4496:  * @output:  the file output
 4497:  * @schema:  a schema structure
 4498:  *
 4499:  * Dump a Schema structure.
 4500:  */
 4501: void
 4502: xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
 4503: {
 4504:     if (output == NULL)
 4505:         return;
 4506:     if (schema == NULL) {
 4507:         fprintf(output, "Schemas: NULL\n");
 4508:         return;
 4509:     }
 4510:     fprintf(output, "Schemas: ");
 4511:     if (schema->name != NULL)
 4512:         fprintf(output, "%s, ", schema->name);
 4513:     else
 4514:         fprintf(output, "no name, ");
 4515:     if (schema->targetNamespace != NULL)
 4516:         fprintf(output, "%s", (const char *) schema->targetNamespace);
 4517:     else
 4518:         fprintf(output, "no target namespace");
 4519:     fprintf(output, "\n");
 4520:     if (schema->annot != NULL)
 4521:         xmlSchemaAnnotDump(output, schema->annot);
 4522:     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
 4523:                 output);
 4524:     xmlHashScanFull(schema->elemDecl,
 4525:                     (xmlHashScannerFull) xmlSchemaElementDump, output);
 4526: }
 4527: 
 4528: #ifdef DEBUG_IDC_NODE_TABLE
 4529: /**
 4530:  * xmlSchemaDebugDumpIDCTable:
 4531:  * @vctxt: the WXS validation context
 4532:  *
 4533:  * Displays the current IDC table for debug purposes.
 4534:  */
 4535: static void
 4536: xmlSchemaDebugDumpIDCTable(FILE * output,
 4537: 			   const xmlChar *namespaceName,
 4538: 			   const xmlChar *localName,
 4539: 			   xmlSchemaPSVIIDCBindingPtr bind)
 4540: {
 4541:     xmlChar *str = NULL;
 4542:     const xmlChar *value;
 4543:     xmlSchemaPSVIIDCNodePtr tab;
 4544:     xmlSchemaPSVIIDCKeyPtr key;
 4545:     int i, j, res;
 4546: 
 4547:     fprintf(output, "IDC: TABLES on '%s'\n",
 4548: 	xmlSchemaFormatQName(&str, namespaceName, localName));
 4549:     FREE_AND_NULL(str)
 4550: 
 4551:     if (bind == NULL)
 4552: 	return;
 4553:     do {
 4554: 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
 4555: 	    xmlSchemaGetComponentQName(&str,
 4556: 		bind->definition), bind->nbNodes);
 4557: 	FREE_AND_NULL(str)
 4558: 	for (i = 0; i < bind->nbNodes; i++) {
 4559: 	    tab = bind->nodeTable[i];
 4560: 	    fprintf(output, "         ( ");
 4561: 	    for (j = 0; j < bind->definition->nbFields; j++) {
 4562: 		key = tab->keys[j];
 4563: 		if ((key != NULL) && (key->val != NULL)) {
 4564: 		    res = xmlSchemaGetCanonValue(key->val, &value);
 4565: 		    if (res >= 0)
 4566: 			fprintf(output, "'%s' ", value);
 4567: 		    else
 4568: 			fprintf(output, "CANON-VALUE-FAILED ");
 4569: 		    if (res == 0)
 4570: 			FREE_AND_NULL(value)
 4571: 		} else if (key != NULL)
 4572: 		    fprintf(output, "(no val), ");
 4573: 		else
 4574: 		    fprintf(output, "(key missing), ");
 4575: 	    }
 4576: 	    fprintf(output, ")\n");
 4577: 	}
 4578: 	if (bind->dupls && bind->dupls->nbItems) {
 4579: 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
 4580: 	    for (i = 0; i < bind->dupls->nbItems; i++) {
 4581: 		tab = bind->dupls->items[i];
 4582: 		fprintf(output, "         ( ");
 4583: 		for (j = 0; j < bind->definition->nbFields; j++) {
 4584: 		    key = tab->keys[j];
 4585: 		    if ((key != NULL) && (key->val != NULL)) {
 4586: 			res = xmlSchemaGetCanonValue(key->val, &value);
 4587: 			if (res >= 0)
 4588: 			    fprintf(output, "'%s' ", value);
 4589: 			else
 4590: 			    fprintf(output, "CANON-VALUE-FAILED ");
 4591: 			if (res == 0)
 4592: 			    FREE_AND_NULL(value)
 4593: 		    } else if (key != NULL)
 4594: 		    fprintf(output, "(no val), ");
 4595: 			else
 4596: 			    fprintf(output, "(key missing), ");
 4597: 		}
 4598: 		fprintf(output, ")\n");
 4599: 	    }
 4600: 	}
 4601: 	bind = bind->next;
 4602:     } while (bind != NULL);
 4603: }
 4604: #endif /* DEBUG_IDC */
 4605: #endif /* LIBXML_OUTPUT_ENABLED */
 4606: 
 4607: /************************************************************************
 4608:  *									*
 4609:  *			Utilities					*
 4610:  *									*
 4611:  ************************************************************************/
 4612: 
 4613: /**
 4614:  * xmlSchemaGetPropNode:
 4615:  * @node: the element node
 4616:  * @name: the name of the attribute
 4617:  *
 4618:  * Seeks an attribute with a name of @name in
 4619:  * no namespace.
 4620:  *
 4621:  * Returns the attribute or NULL if not present.
 4622:  */
 4623: static xmlAttrPtr
 4624: xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
 4625: {
 4626:     xmlAttrPtr prop;
 4627: 
 4628:     if ((node == NULL) || (name == NULL))
 4629: 	return(NULL);
 4630:     prop = node->properties;
 4631:     while (prop != NULL) {
 4632:         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
 4633: 	    return(prop);
 4634: 	prop = prop->next;
 4635:     }
 4636:     return (NULL);
 4637: }
 4638: 
 4639: /**
 4640:  * xmlSchemaGetPropNodeNs:
 4641:  * @node: the element node
 4642:  * @uri: the uri
 4643:  * @name: the name of the attribute
 4644:  *
 4645:  * Seeks an attribute with a local name of @name and
 4646:  * a namespace URI of @uri.
 4647:  *
 4648:  * Returns the attribute or NULL if not present.
 4649:  */
 4650: static xmlAttrPtr
 4651: xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
 4652: {
 4653:     xmlAttrPtr prop;
 4654: 
 4655:     if ((node == NULL) || (name == NULL))
 4656: 	return(NULL);
 4657:     prop = node->properties;
 4658:     while (prop != NULL) {
 4659: 	if ((prop->ns != NULL) &&
 4660: 	    xmlStrEqual(prop->name, BAD_CAST name) &&
 4661: 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
 4662: 	    return(prop);
 4663: 	prop = prop->next;
 4664:     }
 4665:     return (NULL);
 4666: }
 4667: 
 4668: static const xmlChar *
 4669: xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 4670: {
 4671:     xmlChar *val;
 4672:     const xmlChar *ret;
 4673: 
 4674:     val = xmlNodeGetContent(node);
 4675:     if (val == NULL)
 4676: 	val = xmlStrdup((xmlChar *)"");
 4677:     ret = xmlDictLookup(ctxt->dict, val, -1);
 4678:     xmlFree(val);
 4679:     return(ret);
 4680: }
 4681: 
 4682: static const xmlChar *
 4683: xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
 4684: {
 4685:     return((const xmlChar*) xmlNodeGetContent(node));
 4686: }
 4687: 
 4688: /**
 4689:  * xmlSchemaGetProp:
 4690:  * @ctxt: the parser context
 4691:  * @node: the node
 4692:  * @name: the property name
 4693:  *
 4694:  * Read a attribute value and internalize the string
 4695:  *
 4696:  * Returns the string or NULL if not present.
 4697:  */
 4698: static const xmlChar *
 4699: xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 4700:                  const char *name)
 4701: {
 4702:     xmlChar *val;
 4703:     const xmlChar *ret;
 4704: 
 4705:     val = xmlGetNoNsProp(node, BAD_CAST name);
 4706:     if (val == NULL)
 4707:         return(NULL);
 4708:     ret = xmlDictLookup(ctxt->dict, val, -1);
 4709:     xmlFree(val);
 4710:     return(ret);
 4711: }
 4712: 
 4713: /************************************************************************
 4714:  *									*
 4715:  *			Parsing functions				*
 4716:  *									*
 4717:  ************************************************************************/
 4718: 
 4719: #define WXS_FIND_GLOBAL_ITEM(slot)			\
 4720:     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
 4721: 	ret = xmlHashLookup(schema->slot, name); \
 4722: 	if (ret != NULL) goto exit; \
 4723:     } \
 4724:     if (xmlHashSize(schema->schemasImports) > 1) { \
 4725: 	xmlSchemaImportPtr import; \
 4726: 	if (nsName == NULL) \
 4727: 	    import = xmlHashLookup(schema->schemasImports, \
 4728: 		XML_SCHEMAS_NO_NAMESPACE); \
 4729: 	else \
 4730: 	    import = xmlHashLookup(schema->schemasImports, nsName); \
 4731: 	if (import == NULL) \
 4732: 	    goto exit; \
 4733: 	ret = xmlHashLookup(import->schema->slot, name); \
 4734:     }
 4735: 
 4736: /**
 4737:  * xmlSchemaGetElem:
 4738:  * @schema:  the schema context
 4739:  * @name:  the element name
 4740:  * @ns:  the element namespace
 4741:  *
 4742:  * Lookup a global element declaration in the schema.
 4743:  *
 4744:  * Returns the element declaration or NULL if not found.
 4745:  */
 4746: static xmlSchemaElementPtr
 4747: xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
 4748:                  const xmlChar * nsName)
 4749: {
 4750:     xmlSchemaElementPtr ret = NULL;
 4751: 
 4752:     if ((name == NULL) || (schema == NULL))
 4753:         return(NULL);
 4754:     if (schema != NULL) {
 4755: 	WXS_FIND_GLOBAL_ITEM(elemDecl)
 4756:     }
 4757: exit:
 4758: #ifdef DEBUG
 4759:     if (ret == NULL) {
 4760:         if (nsName == NULL)
 4761:             fprintf(stderr, "Unable to lookup element decl. %s", name);
 4762:         else
 4763:             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
 4764:                     nsName);
 4765:     }
 4766: #endif
 4767:     return (ret);
 4768: }
 4769: 
 4770: /**
 4771:  * xmlSchemaGetType:
 4772:  * @schema:  the main schema
 4773:  * @name:  the type's name
 4774:  * nsName:  the type's namespace
 4775:  *
 4776:  * Lookup a type in the schemas or the predefined types
 4777:  *
 4778:  * Returns the group definition or NULL if not found.
 4779:  */
 4780: static xmlSchemaTypePtr
 4781: xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
 4782:                  const xmlChar * nsName)
 4783: {
 4784:     xmlSchemaTypePtr ret = NULL;
 4785: 
 4786:     if (name == NULL)
 4787:         return (NULL);
 4788:     /* First try the built-in types. */
 4789:     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
 4790: 	ret = xmlSchemaGetPredefinedType(name, nsName);
 4791: 	if (ret != NULL)
 4792: 	    goto exit;
 4793: 	/*
 4794: 	* Note that we try the parsed schemas as well here
 4795: 	* since one might have parsed the S4S, which contain more
 4796: 	* than the built-in types.
 4797: 	* TODO: Can we optimize this?
 4798: 	*/
 4799:     }
 4800:     if (schema != NULL) {
 4801: 	WXS_FIND_GLOBAL_ITEM(typeDecl)
 4802:     }
 4803: exit:
 4804: 
 4805: #ifdef DEBUG
 4806:     if (ret == NULL) {
 4807:         if (nsName == NULL)
 4808:             fprintf(stderr, "Unable to lookup type %s", name);
 4809:         else
 4810:             fprintf(stderr, "Unable to lookup type %s:%s", name,
 4811:                     nsName);
 4812:     }
 4813: #endif
 4814:     return (ret);
 4815: }
 4816: 
 4817: /**
 4818:  * xmlSchemaGetAttributeDecl:
 4819:  * @schema:  the context of the schema
 4820:  * @name:  the name of the attribute
 4821:  * @ns:  the target namespace of the attribute
 4822:  *
 4823:  * Lookup a an attribute in the schema or imported schemas
 4824:  *
 4825:  * Returns the attribute declaration or NULL if not found.
 4826:  */
 4827: static xmlSchemaAttributePtr
 4828: xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
 4829:                  const xmlChar * nsName)
 4830: {
 4831:     xmlSchemaAttributePtr ret = NULL;
 4832: 
 4833:     if ((name == NULL) || (schema == NULL))
 4834:         return (NULL);
 4835:     if (schema != NULL) {
 4836: 	WXS_FIND_GLOBAL_ITEM(attrDecl)
 4837:     }
 4838: exit:
 4839: #ifdef DEBUG
 4840:     if (ret == NULL) {
 4841:         if (nsName == NULL)
 4842:             fprintf(stderr, "Unable to lookup attribute %s", name);
 4843:         else
 4844:             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
 4845:                     nsName);
 4846:     }
 4847: #endif
 4848:     return (ret);
 4849: }
 4850: 
 4851: /**
 4852:  * xmlSchemaGetAttributeGroup:
 4853:  * @schema:  the context of the schema
 4854:  * @name:  the name of the attribute group
 4855:  * @ns:  the target namespace of the attribute group
 4856:  *
 4857:  * Lookup a an attribute group in the schema or imported schemas
 4858:  *
 4859:  * Returns the attribute group definition or NULL if not found.
 4860:  */
 4861: static xmlSchemaAttributeGroupPtr
 4862: xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
 4863:                  const xmlChar * nsName)
 4864: {
 4865:     xmlSchemaAttributeGroupPtr ret = NULL;
 4866: 
 4867:     if ((name == NULL) || (schema == NULL))
 4868:         return (NULL);
 4869:     if (schema != NULL) {
 4870: 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
 4871:     }
 4872: exit:
 4873:     /* TODO:
 4874:     if ((ret != NULL) && (ret->redef != NULL)) {
 4875: 	* Return the last redefinition. *
 4876: 	ret = ret->redef;
 4877:     }
 4878:     */
 4879: #ifdef DEBUG
 4880:     if (ret == NULL) {
 4881:         if (nsName == NULL)
 4882:             fprintf(stderr, "Unable to lookup attribute group %s", name);
 4883:         else
 4884:             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
 4885:                     nsName);
 4886:     }
 4887: #endif
 4888:     return (ret);
 4889: }
 4890: 
 4891: /**
 4892:  * xmlSchemaGetGroup:
 4893:  * @schema:  the context of the schema
 4894:  * @name:  the name of the group
 4895:  * @ns:  the target namespace of the group
 4896:  *
 4897:  * Lookup a group in the schema or imported schemas
 4898:  *
 4899:  * Returns the group definition or NULL if not found.
 4900:  */
 4901: static xmlSchemaModelGroupDefPtr
 4902: xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
 4903:                  const xmlChar * nsName)
 4904: {
 4905:     xmlSchemaModelGroupDefPtr ret = NULL;
 4906: 
 4907:     if ((name == NULL) || (schema == NULL))
 4908:         return (NULL);
 4909:     if (schema != NULL) {
 4910: 	WXS_FIND_GLOBAL_ITEM(groupDecl)
 4911:     }
 4912: exit:
 4913: 
 4914: #ifdef DEBUG
 4915:     if (ret == NULL) {
 4916:         if (nsName == NULL)
 4917:             fprintf(stderr, "Unable to lookup group %s", name);
 4918:         else
 4919:             fprintf(stderr, "Unable to lookup group %s:%s", name,
 4920:                     nsName);
 4921:     }
 4922: #endif
 4923:     return (ret);
 4924: }
 4925: 
 4926: static xmlSchemaNotationPtr
 4927: xmlSchemaGetNotation(xmlSchemaPtr schema,
 4928: 		     const xmlChar *name,
 4929: 		     const xmlChar *nsName)
 4930: {
 4931:     xmlSchemaNotationPtr ret = NULL;
 4932: 
 4933:     if ((name == NULL) || (schema == NULL))
 4934:         return (NULL);
 4935:     if (schema != NULL) {
 4936: 	WXS_FIND_GLOBAL_ITEM(notaDecl)
 4937:     }
 4938: exit:
 4939:     return (ret);
 4940: }
 4941: 
 4942: static xmlSchemaIDCPtr
 4943: xmlSchemaGetIDC(xmlSchemaPtr schema,
 4944: 		const xmlChar *name,
 4945: 		const xmlChar *nsName)
 4946: {
 4947:     xmlSchemaIDCPtr ret = NULL;
 4948: 
 4949:     if ((name == NULL) || (schema == NULL))
 4950:         return (NULL);
 4951:     if (schema != NULL) {
 4952: 	WXS_FIND_GLOBAL_ITEM(idcDef)
 4953:     }
 4954: exit:
 4955:     return (ret);
 4956: }
 4957: 
 4958: /**
 4959:  * xmlSchemaGetNamedComponent:
 4960:  * @schema:  the schema
 4961:  * @name:  the name of the group
 4962:  * @ns:  the target namespace of the group
 4963:  *
 4964:  * Lookup a group in the schema or imported schemas
 4965:  *
 4966:  * Returns the group definition or NULL if not found.
 4967:  */
 4968: static xmlSchemaBasicItemPtr
 4969: xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
 4970: 			   xmlSchemaTypeType itemType,
 4971: 			   const xmlChar *name,
 4972: 			   const xmlChar *targetNs)
 4973: {
 4974:     switch (itemType) {
 4975: 	case XML_SCHEMA_TYPE_GROUP:
 4976: 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
 4977: 		name, targetNs));
 4978: 	case XML_SCHEMA_TYPE_ELEMENT:
 4979: 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
 4980: 		name, targetNs));
 4981: 	default:
 4982: 	    TODO
 4983: 	    return (NULL);
 4984:     }
 4985: }
 4986: 
 4987: /************************************************************************
 4988:  *									*
 4989:  *			Parsing functions				*
 4990:  *									*
 4991:  ************************************************************************/
 4992: 
 4993: #define IS_BLANK_NODE(n)						\
 4994:     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
 4995: 
 4996: /**
 4997:  * xmlSchemaIsBlank:
 4998:  * @str:  a string
 4999:  * @len: the length of the string or -1
 5000:  *
 5001:  * Check if a string is ignorable
 5002:  *
 5003:  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
 5004:  */
 5005: static int
 5006: xmlSchemaIsBlank(xmlChar * str, int len)
 5007: {
 5008:     if (str == NULL)
 5009:         return (1);
 5010:     if (len < 0) {
 5011: 	while (*str != 0) {
 5012: 	    if (!(IS_BLANK_CH(*str)))
 5013: 		return (0);
 5014: 	    str++;
 5015: 	}
 5016:     } else while ((*str != 0) && (len != 0)) {
 5017: 	if (!(IS_BLANK_CH(*str)))
 5018: 	    return (0);
 5019: 	str++;
 5020: 	len--;
 5021:     }
 5022: 
 5023:     return (1);
 5024: }
 5025: 
 5026: #define WXS_COMP_NAME(c, t) ((t) (c))->name
 5027: #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
 5028: /*
 5029: * xmlSchemaFindRedefCompInGraph:
 5030: * ATTENTION TODO: This uses pointer comp. for strings.
 5031: */
 5032: static xmlSchemaBasicItemPtr
 5033: xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
 5034: 			      xmlSchemaTypeType type,
 5035: 			      const xmlChar *name,
 5036: 			      const xmlChar *nsName)
 5037: {
 5038:     xmlSchemaBasicItemPtr ret;
 5039:     int i;
 5040: 
 5041:     if ((bucket == NULL) || (name == NULL))
 5042: 	return(NULL);
 5043:     if ((bucket->globals == NULL) ||
 5044: 	(bucket->globals->nbItems == 0))
 5045: 	goto subschemas;
 5046:     /*
 5047:     * Search in global components.
 5048:     */
 5049:     for (i = 0; i < bucket->globals->nbItems; i++) {
 5050: 	ret = bucket->globals->items[i];
 5051: 	if (ret->type == type) {
 5052: 	    switch (type) {
 5053: 		case XML_SCHEMA_TYPE_COMPLEX:
 5054: 		case XML_SCHEMA_TYPE_SIMPLE:
 5055: 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
 5056: 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
 5057: 			nsName))
 5058: 		    {
 5059: 			return(ret);
 5060: 		    }
 5061: 		    break;
 5062: 		case XML_SCHEMA_TYPE_GROUP:
 5063: 		    if ((WXS_COMP_NAME(ret,
 5064: 			    xmlSchemaModelGroupDefPtr) == name) &&
 5065: 			(WXS_COMP_TNS(ret,
 5066: 			    xmlSchemaModelGroupDefPtr) == nsName))
 5067: 		    {
 5068: 			return(ret);
 5069: 		    }
 5070: 		    break;
 5071: 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 5072: 		    if ((WXS_COMP_NAME(ret,
 5073: 			    xmlSchemaAttributeGroupPtr) == name) &&
 5074: 			(WXS_COMP_TNS(ret,
 5075: 			    xmlSchemaAttributeGroupPtr) == nsName))
 5076: 		    {
 5077: 			return(ret);
 5078: 		    }
 5079: 		    break;
 5080: 		default:
 5081: 		    /* Should not be hit. */
 5082: 		    return(NULL);
 5083: 	    }
 5084: 	}
 5085:     }
 5086: subschemas:
 5087:     /*
 5088:     * Process imported/included schemas.
 5089:     */
 5090:     if (bucket->relations != NULL) {
 5091: 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
 5092: 
 5093: 	/*
 5094: 	* TODO: Marking the bucket will not avoid multiple searches
 5095: 	* in the same schema, but avoids at least circularity.
 5096: 	*/
 5097: 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
 5098: 	do {
 5099: 	    if ((rel->bucket != NULL) &&
 5100: 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
 5101: 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
 5102: 		    type, name, nsName);
 5103: 		if (ret != NULL)
 5104: 		    return(ret);
 5105: 	    }
 5106: 	    rel = rel->next;
 5107: 	} while (rel != NULL);
 5108: 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
 5109:     }
 5110:     return(NULL);
 5111: }
 5112: 
 5113: /**
 5114:  * xmlSchemaAddNotation:
 5115:  * @ctxt:  a schema parser context
 5116:  * @schema:  the schema being built
 5117:  * @name:  the item name
 5118:  *
 5119:  * Add an XML schema annotation declaration
 5120:  * *WARNING* this interface is highly subject to change
 5121:  *
 5122:  * Returns the new struture or NULL in case of error
 5123:  */
 5124: static xmlSchemaNotationPtr
 5125: xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5126:                      const xmlChar *name, const xmlChar *nsName,
 5127: 		     xmlNodePtr node ATTRIBUTE_UNUSED)
 5128: {
 5129:     xmlSchemaNotationPtr ret = NULL;
 5130: 
 5131:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5132:         return (NULL);
 5133: 
 5134:     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
 5135:     if (ret == NULL) {
 5136:         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
 5137:         return (NULL);
 5138:     }
 5139:     memset(ret, 0, sizeof(xmlSchemaNotation));
 5140:     ret->type = XML_SCHEMA_TYPE_NOTATION;
 5141:     ret->name = name;
 5142:     ret->targetNamespace = nsName;
 5143:     /* TODO: do we need the node to be set?
 5144:     * ret->node = node;*/
 5145:     WXS_ADD_GLOBAL(ctxt, ret);
 5146:     return (ret);
 5147: }
 5148: 
 5149: /**
 5150:  * xmlSchemaAddAttribute:
 5151:  * @ctxt:  a schema parser context
 5152:  * @schema:  the schema being built
 5153:  * @name:  the item name
 5154:  * @namespace:  the namespace
 5155:  *
 5156:  * Add an XML schema Attrribute declaration
 5157:  * *WARNING* this interface is highly subject to change
 5158:  *
 5159:  * Returns the new struture or NULL in case of error
 5160:  */
 5161: static xmlSchemaAttributePtr
 5162: xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5163:                       const xmlChar * name, const xmlChar * nsName,
 5164: 		      xmlNodePtr node, int topLevel)
 5165: {
 5166:     xmlSchemaAttributePtr ret = NULL;
 5167: 
 5168:     if ((ctxt == NULL) || (schema == NULL))
 5169:         return (NULL);
 5170: 
 5171:     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
 5172:     if (ret == NULL) {
 5173:         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
 5174:         return (NULL);
 5175:     }
 5176:     memset(ret, 0, sizeof(xmlSchemaAttribute));
 5177:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
 5178:     ret->node = node;
 5179:     ret->name = name;
 5180:     ret->targetNamespace = nsName;
 5181: 
 5182:     if (topLevel)
 5183: 	WXS_ADD_GLOBAL(ctxt, ret);
 5184:     else
 5185: 	WXS_ADD_LOCAL(ctxt, ret);
 5186:     WXS_ADD_PENDING(ctxt, ret);
 5187:     return (ret);
 5188: }
 5189: 
 5190: /**
 5191:  * xmlSchemaAddAttributeUse:
 5192:  * @ctxt:  a schema parser context
 5193:  * @schema:  the schema being built
 5194:  * @name:  the item name
 5195:  * @namespace:  the namespace
 5196:  *
 5197:  * Add an XML schema Attrribute declaration
 5198:  * *WARNING* this interface is highly subject to change
 5199:  *
 5200:  * Returns the new struture or NULL in case of error
 5201:  */
 5202: static xmlSchemaAttributeUsePtr
 5203: xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
 5204: 			 xmlNodePtr node)
 5205: {
 5206:     xmlSchemaAttributeUsePtr ret = NULL;
 5207: 
 5208:     if (pctxt == NULL)
 5209:         return (NULL);
 5210: 
 5211:     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
 5212:     if (ret == NULL) {
 5213:         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
 5214:         return (NULL);
 5215:     }
 5216:     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
 5217:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
 5218:     ret->node = node;
 5219: 
 5220:     WXS_ADD_LOCAL(pctxt, ret);
 5221:     return (ret);
 5222: }
 5223: 
 5224: /*
 5225: * xmlSchemaAddRedef:
 5226: *
 5227: * Adds a redefinition information. This is used at a later stage to:
 5228: * resolve references to the redefined components and to check constraints.
 5229: */
 5230: static xmlSchemaRedefPtr
 5231: xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
 5232: 		  xmlSchemaBucketPtr targetBucket,
 5233: 		  void *item,
 5234: 		  const xmlChar *refName,
 5235: 		  const xmlChar *refTargetNs)
 5236: {
 5237:     xmlSchemaRedefPtr ret;
 5238: 
 5239:     ret = (xmlSchemaRedefPtr)
 5240: 	xmlMalloc(sizeof(xmlSchemaRedef));
 5241:     if (ret == NULL) {
 5242: 	xmlSchemaPErrMemory(pctxt,
 5243: 	    "allocating redefinition info", NULL);
 5244: 	return (NULL);
 5245:     }
 5246:     memset(ret, 0, sizeof(xmlSchemaRedef));
 5247:     ret->item = item;
 5248:     ret->targetBucket = targetBucket;
 5249:     ret->refName = refName;
 5250:     ret->refTargetNs = refTargetNs;
 5251:     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
 5252: 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
 5253:     else
 5254: 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
 5255:     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
 5256: 
 5257:     return (ret);
 5258: }
 5259: 
 5260: /**
 5261:  * xmlSchemaAddAttributeGroupDefinition:
 5262:  * @ctxt:  a schema parser context
 5263:  * @schema:  the schema being built
 5264:  * @name:  the item name
 5265:  * @nsName:  the target namespace
 5266:  * @node: the corresponding node
 5267:  *
 5268:  * Add an XML schema Attrribute Group definition.
 5269:  *
 5270:  * Returns the new struture or NULL in case of error
 5271:  */
 5272: static xmlSchemaAttributeGroupPtr
 5273: xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 5274:                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 5275: 			   const xmlChar *name,
 5276: 			   const xmlChar *nsName,
 5277: 			   xmlNodePtr node)
 5278: {
 5279:     xmlSchemaAttributeGroupPtr ret = NULL;
 5280: 
 5281:     if ((pctxt == NULL) || (name == NULL))
 5282:         return (NULL);
 5283: 
 5284:     ret = (xmlSchemaAttributeGroupPtr)
 5285:         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
 5286:     if (ret == NULL) {
 5287: 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
 5288: 	return (NULL);
 5289:     }
 5290:     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
 5291:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
 5292:     ret->name = name;
 5293:     ret->targetNamespace = nsName;
 5294:     ret->node = node;
 5295: 
 5296:     /* TODO: Remove the flag. */
 5297:     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
 5298:     if (pctxt->isRedefine) {
 5299: 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
 5300: 	    ret, name, nsName);
 5301: 	if (pctxt->redef == NULL) {
 5302: 	    xmlFree(ret);
 5303: 	    return(NULL);
 5304: 	}
 5305: 	pctxt->redefCounter = 0;
 5306:     }
 5307:     WXS_ADD_GLOBAL(pctxt, ret);
 5308:     WXS_ADD_PENDING(pctxt, ret);
 5309:     return (ret);
 5310: }
 5311: 
 5312: /**
 5313:  * xmlSchemaAddElement:
 5314:  * @ctxt:  a schema parser context
 5315:  * @schema:  the schema being built
 5316:  * @name:  the type name
 5317:  * @namespace:  the type namespace
 5318:  *
 5319:  * Add an XML schema Element declaration
 5320:  * *WARNING* this interface is highly subject to change
 5321:  *
 5322:  * Returns the new struture or NULL in case of error
 5323:  */
 5324: static xmlSchemaElementPtr
 5325: xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
 5326:                     const xmlChar * name, const xmlChar * nsName,
 5327: 		    xmlNodePtr node, int topLevel)
 5328: {
 5329:     xmlSchemaElementPtr ret = NULL;
 5330: 
 5331:     if ((ctxt == NULL) || (name == NULL))
 5332:         return (NULL);
 5333: 
 5334:     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
 5335:     if (ret == NULL) {
 5336:         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
 5337:         return (NULL);
 5338:     }
 5339:     memset(ret, 0, sizeof(xmlSchemaElement));
 5340:     ret->type = XML_SCHEMA_TYPE_ELEMENT;
 5341:     ret->name = name;
 5342:     ret->targetNamespace = nsName;
 5343:     ret->node = node;
 5344: 
 5345:     if (topLevel)
 5346: 	WXS_ADD_GLOBAL(ctxt, ret);
 5347:     else
 5348: 	WXS_ADD_LOCAL(ctxt, ret);
 5349:     WXS_ADD_PENDING(ctxt, ret);
 5350:     return (ret);
 5351: }
 5352: 
 5353: /**
 5354:  * xmlSchemaAddType:
 5355:  * @ctxt:  a schema parser context
 5356:  * @schema:  the schema being built
 5357:  * @name:  the item name
 5358:  * @namespace:  the namespace
 5359:  *
 5360:  * Add an XML schema item
 5361:  * *WARNING* this interface is highly subject to change
 5362:  *
 5363:  * Returns the new struture or NULL in case of error
 5364:  */
 5365: static xmlSchemaTypePtr
 5366: xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5367: 		 xmlSchemaTypeType type,
 5368:                  const xmlChar * name, const xmlChar * nsName,
 5369: 		 xmlNodePtr node, int topLevel)
 5370: {
 5371:     xmlSchemaTypePtr ret = NULL;
 5372: 
 5373:     if ((ctxt == NULL) || (schema == NULL))
 5374:         return (NULL);
 5375: 
 5376:     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
 5377:     if (ret == NULL) {
 5378:         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
 5379:         return (NULL);
 5380:     }
 5381:     memset(ret, 0, sizeof(xmlSchemaType));
 5382:     ret->type = type;
 5383:     ret->name = name;
 5384:     ret->targetNamespace = nsName;
 5385:     ret->node = node;
 5386:     if (topLevel) {
 5387: 	if (ctxt->isRedefine) {
 5388: 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 5389: 		ret, name, nsName);
 5390: 	    if (ctxt->redef == NULL) {
 5391: 		xmlFree(ret);
 5392: 		return(NULL);
 5393: 	    }
 5394: 	    ctxt->redefCounter = 0;
 5395: 	}
 5396: 	WXS_ADD_GLOBAL(ctxt, ret);
 5397:     } else
 5398: 	WXS_ADD_LOCAL(ctxt, ret);
 5399:     WXS_ADD_PENDING(ctxt, ret);
 5400:     return (ret);
 5401: }
 5402: 
 5403: static xmlSchemaQNameRefPtr
 5404: xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
 5405: 		     xmlSchemaTypeType refType,
 5406: 		     const xmlChar *refName,
 5407: 		     const xmlChar *refNs)
 5408: {
 5409:     xmlSchemaQNameRefPtr ret;
 5410: 
 5411:     ret = (xmlSchemaQNameRefPtr)
 5412: 	xmlMalloc(sizeof(xmlSchemaQNameRef));
 5413:     if (ret == NULL) {
 5414: 	xmlSchemaPErrMemory(pctxt,
 5415: 	    "allocating QName reference item", NULL);
 5416: 	return (NULL);
 5417:     }
 5418:     ret->node = NULL;
 5419:     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
 5420:     ret->name = refName;
 5421:     ret->targetNamespace = refNs;
 5422:     ret->item = NULL;
 5423:     ret->itemType = refType;
 5424:     /*
 5425:     * Store the reference item in the schema.
 5426:     */
 5427:     WXS_ADD_LOCAL(pctxt, ret);
 5428:     return (ret);
 5429: }
 5430: 
 5431: static xmlSchemaAttributeUseProhibPtr
 5432: xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
 5433: {
 5434:     xmlSchemaAttributeUseProhibPtr ret;
 5435: 
 5436:     ret = (xmlSchemaAttributeUseProhibPtr)
 5437: 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
 5438:     if (ret == NULL) {
 5439: 	xmlSchemaPErrMemory(pctxt,
 5440: 	    "allocating attribute use prohibition", NULL);
 5441: 	return (NULL);
 5442:     }
 5443:     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
 5444:     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
 5445:     WXS_ADD_LOCAL(pctxt, ret);
 5446:     return (ret);
 5447: }
 5448: 
 5449: 
 5450: /**
 5451:  * xmlSchemaAddModelGroup:
 5452:  * @ctxt:  a schema parser context
 5453:  * @schema:  the schema being built
 5454:  * @type: the "compositor" type of the model group
 5455:  * @node: the node in the schema doc
 5456:  *
 5457:  * Adds a schema model group
 5458:  * *WARNING* this interface is highly subject to change
 5459:  *
 5460:  * Returns the new struture or NULL in case of error
 5461:  */
 5462: static xmlSchemaModelGroupPtr
 5463: xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
 5464: 		       xmlSchemaPtr schema,
 5465: 		       xmlSchemaTypeType type,
 5466: 		       xmlNodePtr node)
 5467: {
 5468:     xmlSchemaModelGroupPtr ret = NULL;
 5469: 
 5470:     if ((ctxt == NULL) || (schema == NULL))
 5471:         return (NULL);
 5472: 
 5473:     ret = (xmlSchemaModelGroupPtr)
 5474: 	xmlMalloc(sizeof(xmlSchemaModelGroup));
 5475:     if (ret == NULL) {
 5476: 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
 5477: 	    NULL);
 5478: 	return (NULL);
 5479:     }
 5480:     memset(ret, 0, sizeof(xmlSchemaModelGroup));
 5481:     ret->type = type;
 5482:     ret->node = node;
 5483:     WXS_ADD_LOCAL(ctxt, ret);
 5484:     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
 5485: 	(type == XML_SCHEMA_TYPE_CHOICE))
 5486: 	WXS_ADD_PENDING(ctxt, ret);
 5487:     return (ret);
 5488: }
 5489: 
 5490: 
 5491: /**
 5492:  * xmlSchemaAddParticle:
 5493:  * @ctxt:  a schema parser context
 5494:  * @schema:  the schema being built
 5495:  * @node: the corresponding node in the schema doc
 5496:  * @min: the minOccurs
 5497:  * @max: the maxOccurs
 5498:  *
 5499:  * Adds an XML schema particle component.
 5500:  * *WARNING* this interface is highly subject to change
 5501:  *
 5502:  * Returns the new struture or NULL in case of error
 5503:  */
 5504: static xmlSchemaParticlePtr
 5505: xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
 5506: 		     xmlNodePtr node, int min, int max)
 5507: {
 5508:     xmlSchemaParticlePtr ret = NULL;
 5509:     if (ctxt == NULL)
 5510:         return (NULL);
 5511: 
 5512: #ifdef DEBUG
 5513:     fprintf(stderr, "Adding particle component\n");
 5514: #endif
 5515:     ret = (xmlSchemaParticlePtr)
 5516: 	xmlMalloc(sizeof(xmlSchemaParticle));
 5517:     if (ret == NULL) {
 5518: 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
 5519: 	    NULL);
 5520: 	return (NULL);
 5521:     }
 5522:     ret->type = XML_SCHEMA_TYPE_PARTICLE;
 5523:     ret->annot = NULL;
 5524:     ret->node = node;
 5525:     ret->minOccurs = min;
 5526:     ret->maxOccurs = max;
 5527:     ret->next = NULL;
 5528:     ret->children = NULL;
 5529: 
 5530:     WXS_ADD_LOCAL(ctxt, ret);
 5531:     /*
 5532:     * Note that addition to pending components will be done locally
 5533:     * to the specific parsing function, since the most particles
 5534:     * need not to be fixed up (i.e. the reference to be resolved).
 5535:     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
 5536:     */
 5537:     return (ret);
 5538: }
 5539: 
 5540: /**
 5541:  * xmlSchemaAddModelGroupDefinition:
 5542:  * @ctxt:  a schema validation context
 5543:  * @schema:  the schema being built
 5544:  * @name:  the group name
 5545:  *
 5546:  * Add an XML schema Group definition
 5547:  *
 5548:  * Returns the new struture or NULL in case of error
 5549:  */
 5550: static xmlSchemaModelGroupDefPtr
 5551: xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 5552: 				 xmlSchemaPtr schema,
 5553: 				 const xmlChar *name,
 5554: 				 const xmlChar *nsName,
 5555: 				 xmlNodePtr node)
 5556: {
 5557:     xmlSchemaModelGroupDefPtr ret = NULL;
 5558: 
 5559:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5560:         return (NULL);
 5561: 
 5562:     ret = (xmlSchemaModelGroupDefPtr)
 5563: 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
 5564:     if (ret == NULL) {
 5565:         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
 5566:         return (NULL);
 5567:     }
 5568:     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
 5569:     ret->name = name;
 5570:     ret->type = XML_SCHEMA_TYPE_GROUP;
 5571:     ret->node = node;
 5572:     ret->targetNamespace = nsName;
 5573: 
 5574:     if (ctxt->isRedefine) {
 5575: 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 5576: 	    ret, name, nsName);
 5577: 	if (ctxt->redef == NULL) {
 5578: 	    xmlFree(ret);
 5579: 	    return(NULL);
 5580: 	}
 5581: 	ctxt->redefCounter = 0;
 5582:     }
 5583:     WXS_ADD_GLOBAL(ctxt, ret);
 5584:     WXS_ADD_PENDING(ctxt, ret);
 5585:     return (ret);
 5586: }
 5587: 
 5588: /**
 5589:  * xmlSchemaNewWildcardNs:
 5590:  * @ctxt:  a schema validation context
 5591:  *
 5592:  * Creates a new wildcard namespace constraint.
 5593:  *
 5594:  * Returns the new struture or NULL in case of error
 5595:  */
 5596: static xmlSchemaWildcardNsPtr
 5597: xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
 5598: {
 5599:     xmlSchemaWildcardNsPtr ret;
 5600: 
 5601:     ret = (xmlSchemaWildcardNsPtr)
 5602: 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
 5603:     if (ret == NULL) {
 5604: 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
 5605: 	return (NULL);
 5606:     }
 5607:     ret->value = NULL;
 5608:     ret->next = NULL;
 5609:     return (ret);
 5610: }
 5611: 
 5612: static xmlSchemaIDCPtr
 5613: xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5614:                   const xmlChar *name, const xmlChar *nsName,
 5615: 		  int category, xmlNodePtr node)
 5616: {
 5617:     xmlSchemaIDCPtr ret = NULL;
 5618: 
 5619:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5620:         return (NULL);
 5621: 
 5622:     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
 5623:     if (ret == NULL) {
 5624:         xmlSchemaPErrMemory(ctxt,
 5625: 	    "allocating an identity-constraint definition", NULL);
 5626:         return (NULL);
 5627:     }
 5628:     memset(ret, 0, sizeof(xmlSchemaIDC));
 5629:     /* The target namespace of the parent element declaration. */
 5630:     ret->targetNamespace = nsName;
 5631:     ret->name = name;
 5632:     ret->type = category;
 5633:     ret->node = node;
 5634: 
 5635:     WXS_ADD_GLOBAL(ctxt, ret);
 5636:     /*
 5637:     * Only keyrefs need to be fixup up.
 5638:     */
 5639:     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
 5640: 	WXS_ADD_PENDING(ctxt, ret);
 5641:     return (ret);
 5642: }
 5643: 
 5644: /**
 5645:  * xmlSchemaAddWildcard:
 5646:  * @ctxt:  a schema validation context
 5647:  * @schema: a schema
 5648:  *
 5649:  * Adds a wildcard.
 5650:  * It corresponds to a xsd:anyAttribute and xsd:any.
 5651:  *
 5652:  * Returns the new struture or NULL in case of error
 5653:  */
 5654: static xmlSchemaWildcardPtr
 5655: xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5656: 		     xmlSchemaTypeType type, xmlNodePtr node)
 5657: {
 5658:     xmlSchemaWildcardPtr ret = NULL;
 5659: 
 5660:     if ((ctxt == NULL) || (schema == NULL))
 5661:         return (NULL);
 5662: 
 5663:     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
 5664:     if (ret == NULL) {
 5665:         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
 5666:         return (NULL);
 5667:     }
 5668:     memset(ret, 0, sizeof(xmlSchemaWildcard));
 5669:     ret->type = type;
 5670:     ret->node = node;
 5671:     WXS_ADD_LOCAL(ctxt, ret);
 5672:     return (ret);
 5673: }
 5674: 
 5675: static void
 5676: xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
 5677: {
 5678:     if (group == NULL)
 5679: 	return;
 5680:     if (group->members != NULL)
 5681: 	xmlSchemaItemListFree(group->members);
 5682:     xmlFree(group);
 5683: }
 5684: 
 5685: static xmlSchemaSubstGroupPtr
 5686: xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
 5687: 		       xmlSchemaElementPtr head)
 5688: {
 5689:     xmlSchemaSubstGroupPtr ret;
 5690: 
 5691:     /* Init subst group hash. */
 5692:     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
 5693: 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
 5694: 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
 5695: 	    return(NULL);
 5696:     }
 5697:     /* Create a new substitution group. */
 5698:     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
 5699:     if (ret == NULL) {
 5700: 	xmlSchemaPErrMemory(NULL,
 5701: 	    "allocating a substitution group container", NULL);
 5702: 	return(NULL);
 5703:     }
 5704:     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
 5705:     ret->head = head;
 5706:     /* Create list of members. */
 5707:     ret->members = xmlSchemaItemListCreate();
 5708:     if (ret->members == NULL) {
 5709: 	xmlSchemaSubstGroupFree(ret);
 5710: 	return(NULL);
 5711:     }
 5712:     /* Add subst group to hash. */
 5713:     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
 5714: 	head->name, head->targetNamespace, ret) != 0) {
 5715: 	PERROR_INT("xmlSchemaSubstGroupAdd",
 5716: 	    "failed to add a new substitution container");
 5717: 	xmlSchemaSubstGroupFree(ret);
 5718: 	return(NULL);
 5719:     }
 5720:     return(ret);
 5721: }
 5722: 
 5723: static xmlSchemaSubstGroupPtr
 5724: xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
 5725: 		       xmlSchemaElementPtr head)
 5726: {
 5727:     if (WXS_SUBST_GROUPS(pctxt) == NULL)
 5728: 	return(NULL);
 5729:     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
 5730: 	head->name, head->targetNamespace));
 5731: 
 5732: }
 5733: 
 5734: /**
 5735:  * xmlSchemaAddElementSubstitutionMember:
 5736:  * @pctxt:  a schema parser context
 5737:  * @head:  the head of the substitution group
 5738:  * @member: the new member of the substitution group
 5739:  *
 5740:  * Allocate a new annotation structure.
 5741:  *
 5742:  * Returns the newly allocated structure or NULL in case or error
 5743:  */
 5744: static int
 5745: xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
 5746: 				      xmlSchemaElementPtr head,
 5747: 				      xmlSchemaElementPtr member)
 5748: {
 5749:     xmlSchemaSubstGroupPtr substGroup = NULL;
 5750: 
 5751:     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
 5752: 	return (-1);
 5753: 
 5754:     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
 5755:     if (substGroup == NULL)
 5756: 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
 5757:     if (substGroup == NULL)
 5758: 	return(-1);
 5759:     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
 5760: 	return(-1);
 5761:     return(0);
 5762: }
 5763: 
 5764: /************************************************************************
 5765:  *									*
 5766:  *		Utilities for parsing					*
 5767:  *									*
 5768:  ************************************************************************/
 5769: 
 5770: /**
 5771:  * xmlSchemaPValAttrNodeQNameValue:
 5772:  * @ctxt:  a schema parser context
 5773:  * @schema: the schema context
 5774:  * @ownerDes: the designation of the parent element
 5775:  * @ownerItem: the parent as a schema object
 5776:  * @value:  the QName value
 5777:  * @local: the resulting local part if found, the attribute value otherwise
 5778:  * @uri:  the resulting namespace URI if found
 5779:  *
 5780:  * Extracts the local name and the URI of a QName value and validates it.
 5781:  * This one is intended to be used on attribute values that
 5782:  * should resolve to schema components.
 5783:  *
 5784:  * Returns 0, in case the QName is valid, a positive error code
 5785:  * if not valid and -1 if an internal error occurs.
 5786:  */
 5787: static int
 5788: xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
 5789: 				       xmlSchemaPtr schema,
 5790: 				       xmlSchemaBasicItemPtr ownerItem,
 5791: 				       xmlAttrPtr attr,
 5792: 				       const xmlChar *value,
 5793: 				       const xmlChar **uri,
 5794: 				       const xmlChar **local)
 5795: {
 5796:     const xmlChar *pref;
 5797:     xmlNsPtr ns;
 5798:     int len, ret;
 5799: 
 5800:     *uri = NULL;
 5801:     *local = NULL;
 5802:     ret = xmlValidateQName(value, 1);
 5803:     if (ret > 0) {
 5804: 	xmlSchemaPSimpleTypeErr(ctxt,
 5805: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5806: 	    ownerItem, (xmlNodePtr) attr,
 5807: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 5808: 	    NULL, value, NULL, NULL, NULL);
 5809: 	*local = value;
 5810: 	return (ctxt->err);
 5811:     } else if (ret < 0)
 5812: 	return (-1);
 5813: 
 5814:     if (!strchr((char *) value, ':')) {
 5815: 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
 5816: 	if (ns)
 5817: 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 5818: 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
 5819: 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
 5820: 	    * parser context. */
 5821: 	    /*
 5822: 	    * This one takes care of included schemas with no
 5823: 	    * target namespace.
 5824: 	    */
 5825: 	    *uri = ctxt->targetNamespace;
 5826: 	}
 5827: 	*local = xmlDictLookup(ctxt->dict, value, -1);
 5828: 	return (0);
 5829:     }
 5830:     /*
 5831:     * At this point xmlSplitQName3 has to return a local name.
 5832:     */
 5833:     *local = xmlSplitQName3(value, &len);
 5834:     *local = xmlDictLookup(ctxt->dict, *local, -1);
 5835:     pref = xmlDictLookup(ctxt->dict, value, len);
 5836:     ns = xmlSearchNs(attr->doc, attr->parent, pref);
 5837:     if (ns == NULL) {
 5838: 	xmlSchemaPSimpleTypeErr(ctxt,
 5839: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5840: 	    ownerItem, (xmlNodePtr) attr,
 5841: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
 5842: 	    "The value '%s' of simple type 'xs:QName' has no "
 5843: 	    "corresponding namespace declaration in scope", value, NULL);
 5844: 	return (ctxt->err);
 5845:     } else {
 5846:         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 5847:     }
 5848:     return (0);
 5849: }
 5850: 
 5851: /**
 5852:  * xmlSchemaPValAttrNodeQName:
 5853:  * @ctxt:  a schema parser context
 5854:  * @schema: the schema context
 5855:  * @ownerDes: the designation of the owner element
 5856:  * @ownerItem: the owner as a schema object
 5857:  * @attr:  the attribute node
 5858:  * @local: the resulting local part if found, the attribute value otherwise
 5859:  * @uri:  the resulting namespace URI if found
 5860:  *
 5861:  * Extracts and validates the QName of an attribute value.
 5862:  * This one is intended to be used on attribute values that
 5863:  * should resolve to schema components.
 5864:  *
 5865:  * Returns 0, in case the QName is valid, a positive error code
 5866:  * if not valid and -1 if an internal error occurs.
 5867:  */
 5868: static int
 5869: xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
 5870: 				       xmlSchemaPtr schema,
 5871: 				       xmlSchemaBasicItemPtr ownerItem,
 5872: 				       xmlAttrPtr attr,
 5873: 				       const xmlChar **uri,
 5874: 				       const xmlChar **local)
 5875: {
 5876:     const xmlChar *value;
 5877: 
 5878:     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 5879:     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 5880: 	ownerItem, attr, value, uri, local));
 5881: }
 5882: 
 5883: /**
 5884:  * xmlSchemaPValAttrQName:
 5885:  * @ctxt:  a schema parser context
 5886:  * @schema: the schema context
 5887:  * @ownerDes: the designation of the parent element
 5888:  * @ownerItem: the owner as a schema object
 5889:  * @ownerElem:  the parent node of the attribute
 5890:  * @name:  the name of the attribute
 5891:  * @local: the resulting local part if found, the attribute value otherwise
 5892:  * @uri:  the resulting namespace URI if found
 5893:  *
 5894:  * Extracts and validates the QName of an attribute value.
 5895:  *
 5896:  * Returns 0, in case the QName is valid, a positive error code
 5897:  * if not valid and -1 if an internal error occurs.
 5898:  */
 5899: static int
 5900: xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
 5901: 				   xmlSchemaPtr schema,
 5902: 				   xmlSchemaBasicItemPtr ownerItem,
 5903: 				   xmlNodePtr ownerElem,
 5904: 				   const char *name,
 5905: 				   const xmlChar **uri,
 5906: 				   const xmlChar **local)
 5907: {
 5908:     xmlAttrPtr attr;
 5909: 
 5910:     attr = xmlSchemaGetPropNode(ownerElem, name);
 5911:     if (attr == NULL) {
 5912: 	*local = NULL;
 5913: 	*uri = NULL;
 5914: 	return (0);
 5915:     }
 5916:     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
 5917: 	ownerItem, attr, uri, local));
 5918: }
 5919: 
 5920: /**
 5921:  * xmlSchemaPValAttrID:
 5922:  * @ctxt:  a schema parser context
 5923:  * @schema: the schema context
 5924:  * @ownerDes: the designation of the parent element
 5925:  * @ownerItem: the owner as a schema object
 5926:  * @ownerElem:  the parent node of the attribute
 5927:  * @name:  the name of the attribute
 5928:  *
 5929:  * Extracts and validates the ID of an attribute value.
 5930:  *
 5931:  * Returns 0, in case the ID is valid, a positive error code
 5932:  * if not valid and -1 if an internal error occurs.
 5933:  */
 5934: static int
 5935: xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
 5936: {
 5937:     int ret;
 5938:     const xmlChar *value;
 5939: 
 5940:     if (attr == NULL)
 5941: 	return(0);
 5942:     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
 5943:     ret = xmlValidateNCName(value, 1);
 5944:     if (ret == 0) {
 5945: 	/*
 5946: 	* NOTE: the IDness might have already be declared in the DTD
 5947: 	*/
 5948: 	if (attr->atype != XML_ATTRIBUTE_ID) {
 5949: 	    xmlIDPtr res;
 5950: 	    xmlChar *strip;
 5951: 
 5952: 	    /*
 5953: 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
 5954: 	    * moment.
 5955: 	    */
 5956: 	    strip = xmlSchemaCollapseString(value);
 5957: 	    if (strip != NULL) {
 5958: 		xmlFree((xmlChar *) value);
 5959: 		value = strip;
 5960: 	    }
 5961: 	    res = xmlAddID(NULL, attr->doc, value, attr);
 5962: 	    if (res == NULL) {
 5963: 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 5964: 		xmlSchemaPSimpleTypeErr(ctxt,
 5965: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5966: 		    NULL, (xmlNodePtr) attr,
 5967: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 5968: 		    NULL, NULL, "Duplicate value '%s' of simple "
 5969: 		    "type 'xs:ID'", value, NULL);
 5970: 	    } else
 5971: 		attr->atype = XML_ATTRIBUTE_ID;
 5972: 	}
 5973:     } else if (ret > 0) {
 5974: 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 5975: 	xmlSchemaPSimpleTypeErr(ctxt,
 5976: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5977: 	    NULL, (xmlNodePtr) attr,
 5978: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 5979: 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
 5980: 	    "not a valid 'xs:NCName'",
 5981: 	    value, NULL);
 5982:     }
 5983:     if (value != NULL)
 5984: 	xmlFree((xmlChar *)value);
 5985: 
 5986:     return (ret);
 5987: }
 5988: 
 5989: static int
 5990: xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
 5991: 		    xmlNodePtr ownerElem,
 5992: 		    const xmlChar *name)
 5993: {
 5994:     xmlAttrPtr attr;
 5995: 
 5996:     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
 5997:     if (attr == NULL)
 5998: 	return(0);
 5999:     return(xmlSchemaPValAttrNodeID(ctxt, attr));
 6000: 
 6001: }
 6002: 
 6003: /**
 6004:  * xmlGetMaxOccurs:
 6005:  * @ctxt:  a schema validation context
 6006:  * @node:  a subtree containing XML Schema informations
 6007:  *
 6008:  * Get the maxOccurs property
 6009:  *
 6010:  * Returns the default if not found, or the value
 6011:  */
 6012: static int
 6013: xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 6014: 		int min, int max, int def, const char *expected)
 6015: {
 6016:     const xmlChar *val, *cur;
 6017:     int ret = 0;
 6018:     xmlAttrPtr attr;
 6019: 
 6020:     attr = xmlSchemaGetPropNode(node, "maxOccurs");
 6021:     if (attr == NULL)
 6022: 	return (def);
 6023:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6024: 
 6025:     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
 6026: 	if (max != UNBOUNDED) {
 6027: 	    xmlSchemaPSimpleTypeErr(ctxt,
 6028: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6029: 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
 6030: 		NULL, (xmlNodePtr) attr, NULL, expected,
 6031: 		val, NULL, NULL, NULL);
 6032: 	    return (def);
 6033: 	} else
 6034: 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
 6035:     }
 6036: 
 6037:     cur = val;
 6038:     while (IS_BLANK_CH(*cur))
 6039:         cur++;
 6040:     if (*cur == 0) {
 6041:         xmlSchemaPSimpleTypeErr(ctxt,
 6042: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6043: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6044: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6045: 	    val, NULL, NULL, NULL);
 6046: 	return (def);
 6047:     }
 6048:     while ((*cur >= '0') && (*cur <= '9')) {
 6049:         ret = ret * 10 + (*cur - '0');
 6050:         cur++;
 6051:     }
 6052:     while (IS_BLANK_CH(*cur))
 6053:         cur++;
 6054:     /*
 6055:     * TODO: Restrict the maximal value to Integer.
 6056:     */
 6057:     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 6058: 	xmlSchemaPSimpleTypeErr(ctxt,
 6059: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6060: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6061: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6062: 	    val, NULL, NULL, NULL);
 6063:         return (def);
 6064:     }
 6065:     return (ret);
 6066: }
 6067: 
 6068: /**
 6069:  * xmlGetMinOccurs:
 6070:  * @ctxt:  a schema validation context
 6071:  * @node:  a subtree containing XML Schema informations
 6072:  *
 6073:  * Get the minOccurs property
 6074:  *
 6075:  * Returns the default if not found, or the value
 6076:  */
 6077: static int
 6078: xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 6079: 		int min, int max, int def, const char *expected)
 6080: {
 6081:     const xmlChar *val, *cur;
 6082:     int ret = 0;
 6083:     xmlAttrPtr attr;
 6084: 
 6085:     attr = xmlSchemaGetPropNode(node, "minOccurs");
 6086:     if (attr == NULL)
 6087: 	return (def);
 6088:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6089:     cur = val;
 6090:     while (IS_BLANK_CH(*cur))
 6091:         cur++;
 6092:     if (*cur == 0) {
 6093:         xmlSchemaPSimpleTypeErr(ctxt,
 6094: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6095: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6096: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6097: 	    val, NULL, NULL, NULL);
 6098:         return (def);
 6099:     }
 6100:     while ((*cur >= '0') && (*cur <= '9')) {
 6101:         ret = ret * 10 + (*cur - '0');
 6102:         cur++;
 6103:     }
 6104:     while (IS_BLANK_CH(*cur))
 6105:         cur++;
 6106:     /*
 6107:     * TODO: Restrict the maximal value to Integer.
 6108:     */
 6109:     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 6110: 	xmlSchemaPSimpleTypeErr(ctxt,
 6111: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6112: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6113: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6114: 	    val, NULL, NULL, NULL);
 6115:         return (def);
 6116:     }
 6117:     return (ret);
 6118: }
 6119: 
 6120: /**
 6121:  * xmlSchemaPGetBoolNodeValue:
 6122:  * @ctxt:  a schema validation context
 6123:  * @ownerDes:  owner designation
 6124:  * @ownerItem:  the owner as a schema item
 6125:  * @node: the node holding the value
 6126:  *
 6127:  * Converts a boolean string value into 1 or 0.
 6128:  *
 6129:  * Returns 0 or 1.
 6130:  */
 6131: static int
 6132: xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
 6133: 			   xmlSchemaBasicItemPtr ownerItem,
 6134: 			   xmlNodePtr node)
 6135: {
 6136:     xmlChar *value = NULL;
 6137:     int res = 0;
 6138: 
 6139:     value = xmlNodeGetContent(node);
 6140:     /*
 6141:     * 3.2.2.1 Lexical representation
 6142:     * An instance of a datatype that is defined as �boolean�
 6143:     * can have the following legal literals {true, false, 1, 0}.
 6144:     */
 6145:     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
 6146:         res = 1;
 6147:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
 6148:         res = 0;
 6149:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
 6150: 	res = 1;
 6151:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
 6152:         res = 0;
 6153:     else {
 6154:         xmlSchemaPSimpleTypeErr(ctxt,
 6155: 	    XML_SCHEMAP_INVALID_BOOLEAN,
 6156: 	    ownerItem, node,
 6157: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 6158: 	    NULL, BAD_CAST value,
 6159: 	    NULL, NULL, NULL);
 6160:     }
 6161:     if (value != NULL)
 6162: 	xmlFree(value);
 6163:     return (res);
 6164: }
 6165: 
 6166: /**
 6167:  * xmlGetBooleanProp:
 6168:  * @ctxt:  a schema validation context
 6169:  * @node:  a subtree containing XML Schema informations
 6170:  * @name:  the attribute name
 6171:  * @def:  the default value
 6172:  *
 6173:  * Evaluate if a boolean property is set
 6174:  *
 6175:  * Returns the default if not found, 0 if found to be false,
 6176:  * 1 if found to be true
 6177:  */
 6178: static int
 6179: xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
 6180: 		  xmlNodePtr node,
 6181:                   const char *name, int def)
 6182: {
 6183:     const xmlChar *val;
 6184: 
 6185:     val = xmlSchemaGetProp(ctxt, node, name);
 6186:     if (val == NULL)
 6187:         return (def);
 6188:     /*
 6189:     * 3.2.2.1 Lexical representation
 6190:     * An instance of a datatype that is defined as �boolean�
 6191:     * can have the following legal literals {true, false, 1, 0}.
 6192:     */
 6193:     if (xmlStrEqual(val, BAD_CAST "true"))
 6194:         def = 1;
 6195:     else if (xmlStrEqual(val, BAD_CAST "false"))
 6196:         def = 0;
 6197:     else if (xmlStrEqual(val, BAD_CAST "1"))
 6198: 	def = 1;
 6199:     else if (xmlStrEqual(val, BAD_CAST "0"))
 6200:         def = 0;
 6201:     else {
 6202:         xmlSchemaPSimpleTypeErr(ctxt,
 6203: 	    XML_SCHEMAP_INVALID_BOOLEAN,
 6204: 	    NULL,
 6205: 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
 6206: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 6207: 	    NULL, val, NULL, NULL, NULL);
 6208:     }
 6209:     return (def);
 6210: }
 6211: 
 6212: /************************************************************************
 6213:  *									*
 6214:  *		Shema extraction from an Infoset			*
 6215:  *									*
 6216:  ************************************************************************/
 6217: static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
 6218:                                                  ctxt, xmlSchemaPtr schema,
 6219:                                                  xmlNodePtr node,
 6220: 						 int topLevel);
 6221: static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
 6222:                                                   ctxt,
 6223:                                                   xmlSchemaPtr schema,
 6224:                                                   xmlNodePtr node,
 6225: 						  int topLevel);
 6226: static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
 6227:                                                   ctxt,
 6228:                                                   xmlSchemaPtr schema,
 6229:                                                   xmlNodePtr node,
 6230: 						  xmlSchemaTypeType parentType);
 6231: static xmlSchemaBasicItemPtr
 6232: xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 6233: 			     xmlSchemaPtr schema,
 6234: 			     xmlNodePtr node,
 6235: 			     xmlSchemaItemListPtr uses,
 6236: 			     int parentType);
 6237: static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
 6238:                                            xmlSchemaPtr schema,
 6239:                                            xmlNodePtr node);
 6240: static xmlSchemaWildcardPtr
 6241: xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 6242:                            xmlSchemaPtr schema, xmlNodePtr node);
 6243: 
 6244: /**
 6245:  * xmlSchemaPValAttrNodeValue:
 6246:  *
 6247:  * @ctxt:  a schema parser context
 6248:  * @ownerDes: the designation of the parent element
 6249:  * @ownerItem: the schema object owner if existent
 6250:  * @attr:  the schema attribute node being validated
 6251:  * @value: the value
 6252:  * @type: the built-in type to be validated against
 6253:  *
 6254:  * Validates a value against the given built-in type.
 6255:  * This one is intended to be used internally for validation
 6256:  * of schema attribute values during parsing of the schema.
 6257:  *
 6258:  * Returns 0 if the value is valid, a positive error code
 6259:  * number otherwise and -1 in case of an internal or API error.
 6260:  */
 6261: static int
 6262: xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
 6263: 			   xmlSchemaBasicItemPtr ownerItem,
 6264: 			   xmlAttrPtr attr,
 6265: 			   const xmlChar *value,
 6266: 			   xmlSchemaTypePtr type)
 6267: {
 6268: 
 6269:     int ret = 0;
 6270: 
 6271:     /*
 6272:     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
 6273:     * one is really meant to be used internally, so better not.
 6274:     */
 6275:     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
 6276: 	return (-1);
 6277:     if (type->type != XML_SCHEMA_TYPE_BASIC) {
 6278: 	PERROR_INT("xmlSchemaPValAttrNodeValue",
 6279: 	    "the given type is not a built-in type");
 6280: 	return (-1);
 6281:     }
 6282:     switch (type->builtInType) {
 6283: 	case XML_SCHEMAS_NCNAME:
 6284: 	case XML_SCHEMAS_QNAME:
 6285: 	case XML_SCHEMAS_ANYURI:
 6286: 	case XML_SCHEMAS_TOKEN:
 6287: 	case XML_SCHEMAS_LANGUAGE:
 6288: 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
 6289: 		(xmlNodePtr) attr);
 6290: 	    break;
 6291: 	default: {
 6292: 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
 6293: 		"validation using the given type is not supported while "
 6294: 		"parsing a schema");
 6295: 	    return (-1);
 6296: 	}
 6297:     }
 6298:     /*
 6299:     * TODO: Should we use the S4S error codes instead?
 6300:     */
 6301:     if (ret < 0) {
 6302: 	PERROR_INT("xmlSchemaPValAttrNodeValue",
 6303: 	    "failed to validate a schema attribute value");
 6304: 	return (-1);
 6305:     } else if (ret > 0) {
 6306: 	if (WXS_IS_LIST(type))
 6307: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 6308: 	else
 6309: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
 6310: 	xmlSchemaPSimpleTypeErr(pctxt,
 6311: 	    ret, ownerItem, (xmlNodePtr) attr,
 6312: 	    type, NULL, value, NULL, NULL, NULL);
 6313:     }
 6314:     return (ret);
 6315: }
 6316: 
 6317: /**
 6318:  * xmlSchemaPValAttrNode:
 6319:  *
 6320:  * @ctxt:  a schema parser context
 6321:  * @ownerDes: the designation of the parent element
 6322:  * @ownerItem: the schema object owner if existent
 6323:  * @attr:  the schema attribute node being validated
 6324:  * @type: the built-in type to be validated against
 6325:  * @value: the resulting value if any
 6326:  *
 6327:  * Extracts and validates a value against the given built-in type.
 6328:  * This one is intended to be used internally for validation
 6329:  * of schema attribute values during parsing of the schema.
 6330:  *
 6331:  * Returns 0 if the value is valid, a positive error code
 6332:  * number otherwise and -1 in case of an internal or API error.
 6333:  */
 6334: static int
 6335: xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
 6336: 			   xmlSchemaBasicItemPtr ownerItem,
 6337: 			   xmlAttrPtr attr,
 6338: 			   xmlSchemaTypePtr type,
 6339: 			   const xmlChar **value)
 6340: {
 6341:     const xmlChar *val;
 6342: 
 6343:     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
 6344: 	return (-1);
 6345: 
 6346:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6347:     if (value != NULL)
 6348: 	*value = val;
 6349: 
 6350:     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
 6351: 	val, type));
 6352: }
 6353: 
 6354: /**
 6355:  * xmlSchemaPValAttr:
 6356:  *
 6357:  * @ctxt:  a schema parser context
 6358:  * @node: the element node of the attribute
 6359:  * @ownerDes: the designation of the parent element
 6360:  * @ownerItem: the schema object owner if existent
 6361:  * @ownerElem: the owner element node
 6362:  * @name:  the name of the schema attribute node
 6363:  * @type: the built-in type to be validated against
 6364:  * @value: the resulting value if any
 6365:  *
 6366:  * Extracts and validates a value against the given built-in type.
 6367:  * This one is intended to be used internally for validation
 6368:  * of schema attribute values during parsing of the schema.
 6369:  *
 6370:  * Returns 0 if the value is valid, a positive error code
 6371:  * number otherwise and -1 in case of an internal or API error.
 6372:  */
 6373: static int
 6374: xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
 6375: 		       xmlSchemaBasicItemPtr ownerItem,
 6376: 		       xmlNodePtr ownerElem,
 6377: 		       const char *name,
 6378: 		       xmlSchemaTypePtr type,
 6379: 		       const xmlChar **value)
 6380: {
 6381:     xmlAttrPtr attr;
 6382: 
 6383:     if ((ctxt == NULL) || (type == NULL)) {
 6384: 	if (value != NULL)
 6385: 	    *value = NULL;
 6386: 	return (-1);
 6387:     }
 6388:     if (type->type != XML_SCHEMA_TYPE_BASIC) {
 6389: 	if (value != NULL)
 6390: 	    *value = NULL;
 6391: 	xmlSchemaPErr(ctxt, ownerElem,
 6392: 	    XML_SCHEMAP_INTERNAL,
 6393: 	    "Internal error: xmlSchemaPValAttr, the given "
 6394: 	    "type '%s' is not a built-in type.\n",
 6395: 	    type->name, NULL);
 6396: 	return (-1);
 6397:     }
 6398:     attr = xmlSchemaGetPropNode(ownerElem, name);
 6399:     if (attr == NULL) {
 6400: 	if (value != NULL)
 6401: 	    *value = NULL;
 6402: 	return (0);
 6403:     }
 6404:     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
 6405: 	type, value));
 6406: }
 6407: 
 6408: static int
 6409: xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
 6410: 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 6411: 		  xmlNodePtr node,
 6412: 		  xmlAttrPtr attr,
 6413: 		  const xmlChar *namespaceName)
 6414: {
 6415:     /* TODO: Pointer comparison instead? */
 6416:     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
 6417: 	return (0);
 6418:     if (xmlStrEqual(xmlSchemaNs, namespaceName))
 6419: 	return (0);
 6420:     /*
 6421:     * Check if the referenced namespace was <import>ed.
 6422:     */
 6423:     if (WXS_BUCKET(pctxt)->relations != NULL) {
 6424: 	xmlSchemaSchemaRelationPtr rel;
 6425: 
 6426: 	rel = WXS_BUCKET(pctxt)->relations;
 6427: 	do {
 6428: 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
 6429: 		xmlStrEqual(namespaceName, rel->importNamespace))
 6430: 		return (0);
 6431: 	    rel = rel->next;
 6432: 	} while (rel != NULL);
 6433:     }
 6434:     /*
 6435:     * No matching <import>ed namespace found.
 6436:     */
 6437:     {
 6438: 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
 6439: 
 6440: 	if (namespaceName == NULL)
 6441: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 6442: 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 6443: 		"References from this schema to components in no "
 6444: 		"namespace are not allowed, since not indicated by an "
 6445: 		"import statement", NULL, NULL);
 6446: 	else
 6447: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 6448: 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 6449: 		"References from this schema to components in the "
 6450: 		"namespace '%s' are not allowed, since not indicated by an "
 6451: 		"import statement", namespaceName, NULL);
 6452:     }
 6453:     return (XML_SCHEMAP_SRC_RESOLVE);
 6454: }
 6455: 
 6456: /**
 6457:  * xmlSchemaParseLocalAttributes:
 6458:  * @ctxt:  a schema validation context
 6459:  * @schema:  the schema being built
 6460:  * @node:  a subtree containing XML Schema informations
 6461:  * @type:  the hosting type where the attributes will be anchored
 6462:  *
 6463:  * Parses attribute uses and attribute declarations and
 6464:  * attribute group references.
 6465:  */
 6466: static int
 6467: xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6468:                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
 6469: 			int parentType, int *hasRefs)
 6470: {
 6471:     void *item;
 6472: 
 6473:     while ((IS_SCHEMA((*child), "attribute")) ||
 6474:            (IS_SCHEMA((*child), "attributeGroup"))) {
 6475:         if (IS_SCHEMA((*child), "attribute")) {
 6476: 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
 6477: 		*list, parentType);
 6478:         } else {
 6479:             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
 6480: 	    if ((item != NULL) && (hasRefs != NULL))
 6481: 		*hasRefs = 1;
 6482:         }
 6483: 	if (item != NULL) {
 6484: 	    if (*list == NULL) {
 6485: 		/* TODO: Customize grow factor. */
 6486: 		*list = xmlSchemaItemListCreate();
 6487: 		if (*list == NULL)
 6488: 		    return(-1);
 6489: 	    }
 6490: 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
 6491: 		return(-1);
 6492: 	}
 6493:         *child = (*child)->next;
 6494:     }
 6495:     return (0);
 6496: }
 6497: 
 6498: /**
 6499:  * xmlSchemaParseAnnotation:
 6500:  * @ctxt:  a schema validation context
 6501:  * @schema:  the schema being built
 6502:  * @node:  a subtree containing XML Schema informations
 6503:  *
 6504:  * parse a XML schema Attrribute declaration
 6505:  * *WARNING* this interface is highly subject to change
 6506:  *
 6507:  * Returns -1 in case of error, 0 if the declaration is improper and
 6508:  *         1 in case of success.
 6509:  */
 6510: static xmlSchemaAnnotPtr
 6511: xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
 6512: {
 6513:     xmlSchemaAnnotPtr ret;
 6514:     xmlNodePtr child = NULL;
 6515:     xmlAttrPtr attr;
 6516:     int barked = 0;
 6517: 
 6518:     /*
 6519:     * INFO: S4S completed.
 6520:     */
 6521:     /*
 6522:     * id = ID
 6523:     * {any attributes with non-schema namespace . . .}>
 6524:     * Content: (appinfo | documentation)*
 6525:     */
 6526:     if ((ctxt == NULL) || (node == NULL))
 6527:         return (NULL);
 6528:     if (needed)
 6529: 	ret = xmlSchemaNewAnnot(ctxt, node);
 6530:     else
 6531: 	ret = NULL;
 6532:     attr = node->properties;
 6533:     while (attr != NULL) {
 6534: 	if (((attr->ns == NULL) &&
 6535: 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
 6536: 	    ((attr->ns != NULL) &&
 6537: 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 6538: 
 6539: 	    xmlSchemaPIllegalAttrErr(ctxt,
 6540: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6541: 	}
 6542: 	attr = attr->next;
 6543:     }
 6544:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6545:     /*
 6546:     * And now for the children...
 6547:     */
 6548:     child = node->children;
 6549:     while (child != NULL) {
 6550: 	if (IS_SCHEMA(child, "appinfo")) {
 6551: 	    /* TODO: make available the content of "appinfo". */
 6552: 	    /*
 6553: 	    * source = anyURI
 6554: 	    * {any attributes with non-schema namespace . . .}>
 6555: 	    * Content: ({any})*
 6556: 	    */
 6557: 	    attr = child->properties;
 6558: 	    while (attr != NULL) {
 6559: 		if (((attr->ns == NULL) &&
 6560: 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
 6561: 		     ((attr->ns != NULL) &&
 6562: 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 6563: 
 6564: 		    xmlSchemaPIllegalAttrErr(ctxt,
 6565: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6566: 		}
 6567: 		attr = attr->next;
 6568: 	    }
 6569: 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
 6570: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 6571: 	    child = child->next;
 6572: 	} else if (IS_SCHEMA(child, "documentation")) {
 6573: 	    /* TODO: make available the content of "documentation". */
 6574: 	    /*
 6575: 	    * source = anyURI
 6576: 	    * {any attributes with non-schema namespace . . .}>
 6577: 	    * Content: ({any})*
 6578: 	    */
 6579: 	    attr = child->properties;
 6580: 	    while (attr != NULL) {
 6581: 		if (attr->ns == NULL) {
 6582: 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
 6583: 			xmlSchemaPIllegalAttrErr(ctxt,
 6584: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6585: 		    }
 6586: 		} else {
 6587: 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
 6588: 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
 6589: 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
 6590: 
 6591: 			xmlSchemaPIllegalAttrErr(ctxt,
 6592: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6593: 		    }
 6594: 		}
 6595: 		attr = attr->next;
 6596: 	    }
 6597: 	    /*
 6598: 	    * Attribute "xml:lang".
 6599: 	    */
 6600: 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
 6601: 	    if (attr != NULL)
 6602: 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
 6603: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
 6604: 	    child = child->next;
 6605: 	} else {
 6606: 	    if (!barked)
 6607: 		xmlSchemaPContentErr(ctxt,
 6608: 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6609: 		    NULL, node, child, NULL, "(appinfo | documentation)*");
 6610: 	    barked = 1;
 6611: 	    child = child->next;
 6612: 	}
 6613:     }
 6614: 
 6615:     return (ret);
 6616: }
 6617: 
 6618: /**
 6619:  * xmlSchemaParseFacet:
 6620:  * @ctxt:  a schema validation context
 6621:  * @schema:  the schema being built
 6622:  * @node:  a subtree containing XML Schema informations
 6623:  *
 6624:  * parse a XML schema Facet declaration
 6625:  * *WARNING* this interface is highly subject to change
 6626:  *
 6627:  * Returns the new type structure or NULL in case of error
 6628:  */
 6629: static xmlSchemaFacetPtr
 6630: xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6631:                     xmlNodePtr node)
 6632: {
 6633:     xmlSchemaFacetPtr facet;
 6634:     xmlNodePtr child = NULL;
 6635:     const xmlChar *value;
 6636: 
 6637:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6638:         return (NULL);
 6639: 
 6640:     facet = xmlSchemaNewFacet();
 6641:     if (facet == NULL) {
 6642:         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
 6643:         return (NULL);
 6644:     }
 6645:     facet->node = node;
 6646:     value = xmlSchemaGetProp(ctxt, node, "value");
 6647:     if (value == NULL) {
 6648:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
 6649:                        "Facet %s has no value\n", node->name, NULL);
 6650:         xmlSchemaFreeFacet(facet);
 6651:         return (NULL);
 6652:     }
 6653:     if (IS_SCHEMA(node, "minInclusive")) {
 6654:         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
 6655:     } else if (IS_SCHEMA(node, "minExclusive")) {
 6656:         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
 6657:     } else if (IS_SCHEMA(node, "maxInclusive")) {
 6658:         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
 6659:     } else if (IS_SCHEMA(node, "maxExclusive")) {
 6660:         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
 6661:     } else if (IS_SCHEMA(node, "totalDigits")) {
 6662:         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
 6663:     } else if (IS_SCHEMA(node, "fractionDigits")) {
 6664:         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
 6665:     } else if (IS_SCHEMA(node, "pattern")) {
 6666:         facet->type = XML_SCHEMA_FACET_PATTERN;
 6667:     } else if (IS_SCHEMA(node, "enumeration")) {
 6668:         facet->type = XML_SCHEMA_FACET_ENUMERATION;
 6669:     } else if (IS_SCHEMA(node, "whiteSpace")) {
 6670:         facet->type = XML_SCHEMA_FACET_WHITESPACE;
 6671:     } else if (IS_SCHEMA(node, "length")) {
 6672:         facet->type = XML_SCHEMA_FACET_LENGTH;
 6673:     } else if (IS_SCHEMA(node, "maxLength")) {
 6674:         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
 6675:     } else if (IS_SCHEMA(node, "minLength")) {
 6676:         facet->type = XML_SCHEMA_FACET_MINLENGTH;
 6677:     } else {
 6678:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
 6679:                        "Unknown facet type %s\n", node->name, NULL);
 6680:         xmlSchemaFreeFacet(facet);
 6681:         return (NULL);
 6682:     }
 6683:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6684:     facet->value = value;
 6685:     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
 6686: 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
 6687: 	const xmlChar *fixed;
 6688: 
 6689: 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
 6690: 	if (fixed != NULL) {
 6691: 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
 6692: 		facet->fixed = 1;
 6693: 	}
 6694:     }
 6695:     child = node->children;
 6696: 
 6697:     if (IS_SCHEMA(child, "annotation")) {
 6698:         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6699:         child = child->next;
 6700:     }
 6701:     if (child != NULL) {
 6702:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
 6703:                        "Facet %s has unexpected child content\n",
 6704:                        node->name, NULL);
 6705:     }
 6706:     return (facet);
 6707: }
 6708: 
 6709: /**
 6710:  * xmlSchemaParseWildcardNs:
 6711:  * @ctxt:  a schema parser context
 6712:  * @wildc:  the wildcard, already created
 6713:  * @node:  a subtree containing XML Schema informations
 6714:  *
 6715:  * Parses the attribute "processContents" and "namespace"
 6716:  * of a xsd:anyAttribute and xsd:any.
 6717:  * *WARNING* this interface is highly subject to change
 6718:  *
 6719:  * Returns 0 if everything goes fine, a positive error code
 6720:  * if something is not valid and -1 if an internal error occurs.
 6721:  */
 6722: static int
 6723: xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
 6724: 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 6725: 			 xmlSchemaWildcardPtr wildc,
 6726: 			 xmlNodePtr node)
 6727: {
 6728:     const xmlChar *pc, *ns, *dictnsItem;
 6729:     int ret = 0;
 6730:     xmlChar *nsItem;
 6731:     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
 6732:     xmlAttrPtr attr;
 6733: 
 6734:     pc = xmlSchemaGetProp(ctxt, node, "processContents");
 6735:     if ((pc == NULL)
 6736:         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
 6737:         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 6738:     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
 6739:         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
 6740:     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
 6741:         wildc->processContents = XML_SCHEMAS_ANY_LAX;
 6742:     } else {
 6743:         xmlSchemaPSimpleTypeErr(ctxt,
 6744: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6745: 	    NULL, node,
 6746: 	    NULL, "(strict | skip | lax)", pc,
 6747: 	    NULL, NULL, NULL);
 6748:         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 6749: 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 6750:     }
 6751:     /*
 6752:      * Build the namespace constraints.
 6753:      */
 6754:     attr = xmlSchemaGetPropNode(node, "namespace");
 6755:     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6756:     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
 6757: 	wildc->any = 1;
 6758:     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
 6759: 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 6760: 	if (wildc->negNsSet == NULL) {
 6761: 	    return (-1);
 6762: 	}
 6763: 	wildc->negNsSet->value = ctxt->targetNamespace;
 6764:     } else {
 6765: 	const xmlChar *end, *cur;
 6766: 
 6767: 	cur = ns;
 6768: 	do {
 6769: 	    while (IS_BLANK_CH(*cur))
 6770: 		cur++;
 6771: 	    end = cur;
 6772: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 6773: 		end++;
 6774: 	    if (end == cur)
 6775: 		break;
 6776: 	    nsItem = xmlStrndup(cur, end - cur);
 6777: 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
 6778: 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
 6779: 		xmlSchemaPSimpleTypeErr(ctxt,
 6780: 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
 6781: 		    NULL, (xmlNodePtr) attr,
 6782: 		    NULL,
 6783: 		    "((##any | ##other) | List of (xs:anyURI | "
 6784: 		    "(##targetNamespace | ##local)))",
 6785: 		    nsItem, NULL, NULL, NULL);
 6786: 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
 6787: 	    } else {
 6788: 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
 6789: 		    dictnsItem = ctxt->targetNamespace;
 6790: 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
 6791: 		    dictnsItem = NULL;
 6792: 		} else {
 6793: 		    /*
 6794: 		    * Validate the item (anyURI).
 6795: 		    */
 6796: 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
 6797: 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
 6798: 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
 6799: 		}
 6800: 		/*
 6801: 		* Avoid dublicate namespaces.
 6802: 		*/
 6803: 		tmp = wildc->nsSet;
 6804: 		while (tmp != NULL) {
 6805: 		    if (dictnsItem == tmp->value)
 6806: 			break;
 6807: 		    tmp = tmp->next;
 6808: 		}
 6809: 		if (tmp == NULL) {
 6810: 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
 6811: 		    if (tmp == NULL) {
 6812: 			xmlFree(nsItem);
 6813: 			return (-1);
 6814: 		    }
 6815: 		    tmp->value = dictnsItem;
 6816: 		    tmp->next = NULL;
 6817: 		    if (wildc->nsSet == NULL)
 6818: 			wildc->nsSet = tmp;
 6819: 		    else if (lastNs != NULL)
 6820: 			lastNs->next = tmp;
 6821: 		    lastNs = tmp;
 6822: 		}
 6823: 
 6824: 	    }
 6825: 	    xmlFree(nsItem);
 6826: 	    cur = end;
 6827: 	} while (*cur != 0);
 6828:     }
 6829:     return (ret);
 6830: }
 6831: 
 6832: static int
 6833: xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
 6834: 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
 6835: 				 xmlNodePtr node,
 6836: 				 int minOccurs,
 6837: 				 int maxOccurs) {
 6838: 
 6839:     if ((maxOccurs == 0) && ( minOccurs == 0))
 6840: 	return (0);
 6841:     if (maxOccurs != UNBOUNDED) {
 6842: 	/*
 6843: 	* TODO: Maybe we should better not create the particle,
 6844: 	* if min/max is invalid, since it could confuse the build of the
 6845: 	* content model.
 6846: 	*/
 6847: 	/*
 6848: 	* 3.9.6 Schema Component Constraint: Particle Correct
 6849: 	*
 6850: 	*/
 6851: 	if (maxOccurs < 1) {
 6852: 	    /*
 6853: 	    * 2.2 {max occurs} must be greater than or equal to 1.
 6854: 	    */
 6855: 	    xmlSchemaPCustomAttrErr(ctxt,
 6856: 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
 6857: 		NULL, NULL,
 6858: 		xmlSchemaGetPropNode(node, "maxOccurs"),
 6859: 		"The value must be greater than or equal to 1");
 6860: 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
 6861: 	} else if (minOccurs > maxOccurs) {
 6862: 	    /*
 6863: 	    * 2.1 {min occurs} must not be greater than {max occurs}.
 6864: 	    */
 6865: 	    xmlSchemaPCustomAttrErr(ctxt,
 6866: 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
 6867: 		NULL, NULL,
 6868: 		xmlSchemaGetPropNode(node, "minOccurs"),
 6869: 		"The value must not be greater than the value of 'maxOccurs'");
 6870: 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
 6871: 	}
 6872:     }
 6873:     return (0);
 6874: }
 6875: 
 6876: /**
 6877:  * xmlSchemaParseAny:
 6878:  * @ctxt:  a schema validation context
 6879:  * @schema:  the schema being built
 6880:  * @node:  a subtree containing XML Schema informations
 6881:  *
 6882:  * Parsea a XML schema <any> element. A particle and wildcard
 6883:  * will be created (except if minOccurs==maxOccurs==0, in this case
 6884:  * nothing will be created).
 6885:  * *WARNING* this interface is highly subject to change
 6886:  *
 6887:  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
 6888:  */
 6889: static xmlSchemaParticlePtr
 6890: xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6891:                   xmlNodePtr node)
 6892: {
 6893:     xmlSchemaParticlePtr particle;
 6894:     xmlNodePtr child = NULL;
 6895:     xmlSchemaWildcardPtr wild;
 6896:     int min, max;
 6897:     xmlAttrPtr attr;
 6898:     xmlSchemaAnnotPtr annot = NULL;
 6899: 
 6900:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6901:         return (NULL);
 6902:     /*
 6903:     * Check for illegal attributes.
 6904:     */
 6905:     attr = node->properties;
 6906:     while (attr != NULL) {
 6907: 	if (attr->ns == NULL) {
 6908: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 6909: 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 6910: 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 6911: 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 6912: 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 6913: 		xmlSchemaPIllegalAttrErr(ctxt,
 6914: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6915: 	    }
 6916: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 6917: 	    xmlSchemaPIllegalAttrErr(ctxt,
 6918: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6919: 	}
 6920: 	attr = attr->next;
 6921:     }
 6922:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6923:     /*
 6924:     * minOccurs/maxOccurs.
 6925:     */
 6926:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 6927: 	"(xs:nonNegativeInteger | unbounded)");
 6928:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
 6929: 	"xs:nonNegativeInteger");
 6930:     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 6931:     /*
 6932:     * Create & parse the wildcard.
 6933:     */
 6934:     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
 6935:     if (wild == NULL)
 6936: 	return (NULL);
 6937:     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
 6938:     /*
 6939:     * And now for the children...
 6940:     */
 6941:     child = node->children;
 6942:     if (IS_SCHEMA(child, "annotation")) {
 6943:         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6944:         child = child->next;
 6945:     }
 6946:     if (child != NULL) {
 6947: 	xmlSchemaPContentErr(ctxt,
 6948: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6949: 	    NULL, node, child,
 6950: 	    NULL, "(annotation?)");
 6951:     }
 6952:     /*
 6953:     * No component if minOccurs==maxOccurs==0.
 6954:     */
 6955:     if ((min == 0) && (max == 0)) {
 6956: 	/* Don't free the wildcard, since it's already on the list. */
 6957: 	return (NULL);
 6958:     }
 6959:     /*
 6960:     * Create the particle.
 6961:     */
 6962:     particle = xmlSchemaAddParticle(ctxt, node, min, max);
 6963:     if (particle == NULL)
 6964:         return (NULL);
 6965:     particle->annot = annot;
 6966:     particle->children = (xmlSchemaTreeItemPtr) wild;
 6967: 
 6968:     return (particle);
 6969: }
 6970: 
 6971: /**
 6972:  * xmlSchemaParseNotation:
 6973:  * @ctxt:  a schema validation context
 6974:  * @schema:  the schema being built
 6975:  * @node:  a subtree containing XML Schema informations
 6976:  *
 6977:  * parse a XML schema Notation declaration
 6978:  *
 6979:  * Returns the new structure or NULL in case of error
 6980:  */
 6981: static xmlSchemaNotationPtr
 6982: xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6983:                        xmlNodePtr node)
 6984: {
 6985:     const xmlChar *name;
 6986:     xmlSchemaNotationPtr ret;
 6987:     xmlNodePtr child = NULL;
 6988: 
 6989:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6990:         return (NULL);
 6991:     name = xmlSchemaGetProp(ctxt, node, "name");
 6992:     if (name == NULL) {
 6993:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
 6994:                        "Notation has no name\n", NULL, NULL);
 6995:         return (NULL);
 6996:     }
 6997:     ret = xmlSchemaAddNotation(ctxt, schema, name,
 6998: 	ctxt->targetNamespace, node);
 6999:     if (ret == NULL)
 7000:         return (NULL);
 7001:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 7002: 
 7003:     child = node->children;
 7004:     if (IS_SCHEMA(child, "annotation")) {
 7005:         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 7006:         child = child->next;
 7007:     }
 7008:     if (child != NULL) {
 7009: 	xmlSchemaPContentErr(ctxt,
 7010: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7011: 	    NULL, node, child,
 7012: 	    NULL, "(annotation?)");
 7013:     }
 7014: 
 7015:     return (ret);
 7016: }
 7017: 
 7018: /**
 7019:  * xmlSchemaParseAnyAttribute:
 7020:  * @ctxt:  a schema validation context
 7021:  * @schema:  the schema being built
 7022:  * @node:  a subtree containing XML Schema informations
 7023:  *
 7024:  * parse a XML schema AnyAttrribute declaration
 7025:  * *WARNING* this interface is highly subject to change
 7026:  *
 7027:  * Returns a wildcard or NULL.
 7028:  */
 7029: static xmlSchemaWildcardPtr
 7030: xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 7031:                            xmlSchemaPtr schema, xmlNodePtr node)
 7032: {
 7033:     xmlSchemaWildcardPtr ret;
 7034:     xmlNodePtr child = NULL;
 7035:     xmlAttrPtr attr;
 7036: 
 7037:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 7038:         return (NULL);
 7039: 
 7040:     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
 7041: 	node);
 7042:     if (ret == NULL) {
 7043:         return (NULL);
 7044:     }
 7045:     /*
 7046:     * Check for illegal attributes.
 7047:     */
 7048:     attr = node->properties;
 7049:     while (attr != NULL) {
 7050: 	if (attr->ns == NULL) {
 7051: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 7052: 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 7053: 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 7054: 		xmlSchemaPIllegalAttrErr(ctxt,
 7055: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7056: 	    }
 7057: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7058: 	    xmlSchemaPIllegalAttrErr(ctxt,
 7059: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7060: 	}
 7061: 	attr = attr->next;
 7062:     }
 7063:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 7064:     /*
 7065:     * Parse the namespace list.
 7066:     */
 7067:     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
 7068: 	return (NULL);
 7069:     /*
 7070:     * And now for the children...
 7071:     */
 7072:     child = node->children;
 7073:     if (IS_SCHEMA(child, "annotation")) {
 7074:         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 7075:         child = child->next;
 7076:     }
 7077:     if (child != NULL) {
 7078: 	xmlSchemaPContentErr(ctxt,
 7079: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7080: 	    NULL, node, child,
 7081: 	    NULL, "(annotation?)");
 7082:     }
 7083: 
 7084:     return (ret);
 7085: }
 7086: 
 7087: 
 7088: /**
 7089:  * xmlSchemaParseAttribute:
 7090:  * @ctxt:  a schema validation context
 7091:  * @schema:  the schema being built
 7092:  * @node:  a subtree containing XML Schema informations
 7093:  *
 7094:  * parse a XML schema Attrribute declaration
 7095:  * *WARNING* this interface is highly subject to change
 7096:  *
 7097:  * Returns the attribute declaration.
 7098:  */
 7099: static xmlSchemaBasicItemPtr
 7100: xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 7101: 			     xmlSchemaPtr schema,
 7102: 			     xmlNodePtr node,
 7103: 			     xmlSchemaItemListPtr uses,
 7104: 			     int parentType)
 7105: {
 7106:     const xmlChar *attrValue, *name = NULL, *ns = NULL;
 7107:     xmlSchemaAttributeUsePtr use = NULL;
 7108:     xmlNodePtr child = NULL;
 7109:     xmlAttrPtr attr;
 7110:     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
 7111:     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 7112:     int	nberrors, hasForm = 0, defValueType = 0;
 7113: 
 7114: #define WXS_ATTR_DEF_VAL_DEFAULT 1
 7115: #define WXS_ATTR_DEF_VAL_FIXED 2
 7116: 
 7117:     /*
 7118:      * 3.2.3 Constraints on XML Representations of Attribute Declarations
 7119:      */
 7120: 
 7121:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7122:         return (NULL);
 7123:     attr = xmlSchemaGetPropNode(node, "ref");
 7124:     if (attr != NULL) {
 7125: 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
 7126: 	    NULL, attr, &tmpNs, &tmpName) != 0) {
 7127: 	    return (NULL);
 7128: 	}
 7129: 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
 7130: 	    return(NULL);
 7131: 	isRef = 1;
 7132:     }
 7133:     nberrors = pctxt->nberrors;
 7134:     /*
 7135:     * Check for illegal attributes.
 7136:     */
 7137:     attr = node->properties;
 7138:     while (attr != NULL) {
 7139: 	if (attr->ns == NULL) {
 7140: 	    if (isRef) {
 7141: 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 7142: 		    xmlSchemaPValAttrNodeID(pctxt, attr);
 7143: 		    goto attr_next;
 7144: 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
 7145: 		    goto attr_next;
 7146: 		}
 7147: 	    } else {
 7148: 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
 7149: 		    goto attr_next;
 7150: 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 7151: 		    xmlSchemaPValAttrNodeID(pctxt, attr);
 7152: 		    goto attr_next;
 7153: 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
 7154: 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
 7155: 			attr, &tmpNs, &tmpName);
 7156: 		    goto attr_next;
 7157: 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
 7158: 		    /*
 7159: 		    * Evaluate the target namespace
 7160: 		    */
 7161: 		    hasForm = 1;
 7162: 		    attrValue = xmlSchemaGetNodeContent(pctxt,
 7163: 			(xmlNodePtr) attr);
 7164: 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 7165: 			ns = pctxt->targetNamespace;
 7166: 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
 7167: 		    {
 7168: 			xmlSchemaPSimpleTypeErr(pctxt,
 7169: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 7170: 			    NULL, (xmlNodePtr) attr,
 7171: 			    NULL, "(qualified | unqualified)",
 7172: 			    attrValue, NULL, NULL, NULL);
 7173: 		    }
 7174: 		    goto attr_next;
 7175: 		}
 7176: 	    }
 7177: 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
 7178: 
 7179: 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7180: 		/* TODO: Maybe we need to normalize the value beforehand. */
 7181: 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
 7182: 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 7183: 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
 7184: 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
 7185: 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
 7186: 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
 7187: 		else {
 7188: 		    xmlSchemaPSimpleTypeErr(pctxt,
 7189: 			XML_SCHEMAP_INVALID_ATTR_USE,
 7190: 			NULL, (xmlNodePtr) attr,
 7191: 			NULL, "(optional | prohibited | required)",
 7192: 			attrValue, NULL, NULL, NULL);
 7193: 		}
 7194: 		goto attr_next;
 7195: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
 7196: 		/*
 7197: 		* 3.2.3 : 1
 7198: 		* default and fixed must not both be present.
 7199: 		*/
 7200: 		if (defValue) {
 7201: 		    xmlSchemaPMutualExclAttrErr(pctxt,
 7202: 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7203: 			NULL, attr, "default", "fixed");
 7204: 		} else {
 7205: 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7206: 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
 7207: 		}
 7208: 		goto attr_next;
 7209: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
 7210: 		/*
 7211: 		* 3.2.3 : 1
 7212: 		* default and fixed must not both be present.
 7213: 		*/
 7214: 		if (defValue) {
 7215: 		    xmlSchemaPMutualExclAttrErr(pctxt,
 7216: 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7217: 			NULL, attr, "default", "fixed");
 7218: 		} else {
 7219: 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7220: 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
 7221: 		}
 7222: 		goto attr_next;
 7223: 	    }
 7224: 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
 7225: 	    goto attr_next;
 7226: 
 7227: 	xmlSchemaPIllegalAttrErr(pctxt,
 7228: 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7229: 
 7230: attr_next:
 7231: 	attr = attr->next;
 7232:     }
 7233:     /*
 7234:     * 3.2.3 : 2
 7235:     * If default and use are both present, use must have
 7236:     * the actual value optional.
 7237:     */
 7238:     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
 7239: 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
 7240: 	xmlSchemaPSimpleTypeErr(pctxt,
 7241: 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
 7242: 	    NULL, node, NULL,
 7243: 	    "(optional | prohibited | required)", NULL,
 7244: 	    "The value of the attribute 'use' must be 'optional' "
 7245: 	    "if the attribute 'default' is present",
 7246: 	    NULL, NULL);
 7247:     }
 7248:     /*
 7249:     * We want correct attributes.
 7250:     */
 7251:     if (nberrors != pctxt->nberrors)
 7252: 	return(NULL);
 7253:     if (! isRef) {
 7254: 	xmlSchemaAttributePtr attrDecl;
 7255: 
 7256: 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
 7257: 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
 7258: 	    ns = pctxt->targetNamespace;
 7259: 	/*
 7260: 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
 7261: 	* TODO: Move this to the component layer.
 7262: 	*/
 7263: 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
 7264: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7265: 		XML_SCHEMAP_NO_XSI,
 7266: 		node, NULL,
 7267: 		"The target namespace must not match '%s'",
 7268: 		xmlSchemaInstanceNs, NULL);
 7269: 	}
 7270: 	attr = xmlSchemaGetPropNode(node, "name");
 7271: 	if (attr == NULL) {
 7272: 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 7273: 		NULL, node, "name", NULL);
 7274: 	    return (NULL);
 7275: 	}
 7276: 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 7277: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 7278: 	    return (NULL);
 7279: 	}
 7280: 	/*
 7281: 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
 7282: 	* TODO: Move this to the component layer.
 7283: 	*/
 7284: 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
 7285: 	    xmlSchemaPSimpleTypeErr(pctxt,
 7286: 		XML_SCHEMAP_NO_XMLNS,
 7287: 		NULL, (xmlNodePtr) attr,
 7288: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 7289: 		"The value of the attribute must not match 'xmlns'",
 7290: 		NULL, NULL);
 7291: 	    return (NULL);
 7292: 	}
 7293: 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
 7294: 	    goto check_children;
 7295: 	/*
 7296: 	* Create the attribute use component.
 7297: 	*/
 7298: 	use = xmlSchemaAddAttributeUse(pctxt, node);
 7299: 	if (use == NULL)
 7300: 	    return(NULL);
 7301: 	use->occurs = occurs;
 7302: 	/*
 7303: 	* Create the attribute declaration.
 7304: 	*/
 7305: 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
 7306: 	if (attrDecl == NULL)
 7307: 	    return (NULL);
 7308: 	if (tmpName != NULL) {
 7309: 	    attrDecl->typeName = tmpName;
 7310: 	    attrDecl->typeNs = tmpNs;
 7311: 	}
 7312: 	use->attrDecl = attrDecl;
 7313: 	/*
 7314: 	* Value constraint.
 7315: 	*/
 7316: 	if (defValue != NULL) {
 7317: 	    attrDecl->defValue = defValue;
 7318: 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 7319: 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
 7320: 	}
 7321:     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 7322: 	xmlSchemaQNameRefPtr ref;
 7323: 
 7324: 	/*
 7325: 	* Create the attribute use component.
 7326: 	*/
 7327: 	use = xmlSchemaAddAttributeUse(pctxt, node);
 7328: 	if (use == NULL)
 7329: 	    return(NULL);
 7330: 	/*
 7331: 	* We need to resolve the reference at later stage.
 7332: 	*/
 7333: 	WXS_ADD_PENDING(pctxt, use);
 7334: 	use->occurs = occurs;
 7335: 	/*
 7336: 	* Create a QName reference to the attribute declaration.
 7337: 	*/
 7338: 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
 7339: 	    tmpName, tmpNs);
 7340: 	if (ref == NULL)
 7341: 	    return(NULL);
 7342: 	/*
 7343: 	* Assign the reference. This will be substituted for the
 7344: 	* referenced attribute declaration when the QName is resolved.
 7345: 	*/
 7346: 	use->attrDecl = WXS_ATTR_CAST ref;
 7347: 	/*
 7348: 	* Value constraint.
 7349: 	*/
 7350: 	if (defValue != NULL)
 7351: 	    use->defValue = defValue;
 7352: 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 7353: 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
 7354:     }
 7355: 
 7356: check_children:
 7357:     /*
 7358:     * And now for the children...
 7359:     */
 7360:     child = node->children;
 7361:     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 7362: 	xmlSchemaAttributeUseProhibPtr prohib;
 7363: 
 7364: 	if (IS_SCHEMA(child, "annotation")) {
 7365: 	    xmlSchemaParseAnnotation(pctxt, child, 0);
 7366: 	    child = child->next;
 7367: 	}
 7368: 	if (child != NULL) {
 7369: 	    xmlSchemaPContentErr(pctxt,
 7370: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7371: 		NULL, node, child, NULL,
 7372: 		"(annotation?)");
 7373: 	}
 7374: 	/*
 7375: 	* Check for pointlessness of attribute prohibitions.
 7376: 	*/
 7377: 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
 7378: 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7379: 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7380: 		node, NULL,
 7381: 		"Skipping attribute use prohibition, since it is "
 7382: 		"pointless inside an <attributeGroup>",
 7383: 		NULL, NULL, NULL);
 7384: 	    return(NULL);
 7385: 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
 7386: 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7387: 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7388: 		node, NULL,
 7389: 		"Skipping attribute use prohibition, since it is "
 7390: 		"pointless when extending a type",
 7391: 		NULL, NULL, NULL);
 7392: 	    return(NULL);
 7393: 	}
 7394: 	if (! isRef) {
 7395: 	    tmpName = name;
 7396: 	    tmpNs = ns;
 7397: 	}
 7398: 	/*
 7399: 	* Check for duplicate attribute prohibitions.
 7400: 	*/
 7401: 	if (uses) {
 7402: 	    int i;
 7403: 
 7404: 	    for (i = 0; i < uses->nbItems; i++) {
 7405: 		use = uses->items[i];
 7406: 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
 7407: 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
 7408: 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
 7409: 		{
 7410: 		    xmlChar *str = NULL;
 7411: 
 7412: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7413: 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7414: 			node, NULL,
 7415: 			"Skipping duplicate attribute use prohibition '%s'",
 7416: 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
 7417: 			NULL, NULL);
 7418: 		    FREE_AND_NULL(str)
 7419: 		    return(NULL);
 7420: 		}
 7421: 	    }
 7422: 	}
 7423: 	/*
 7424: 	* Create the attribute prohibition helper component.
 7425: 	*/
 7426: 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
 7427: 	if (prohib == NULL)
 7428: 	    return(NULL);
 7429: 	prohib->node = node;
 7430: 	prohib->name = tmpName;
 7431: 	prohib->targetNamespace = tmpNs;
 7432: 	if (isRef) {
 7433: 	    /*
 7434: 	    * We need at least to resolve to the attribute declaration.
 7435: 	    */
 7436: 	    WXS_ADD_PENDING(pctxt, prohib);
 7437: 	}
 7438: 	return(WXS_BASIC_CAST prohib);
 7439:     } else {
 7440: 	if (IS_SCHEMA(child, "annotation")) {
 7441: 	    /*
 7442: 	    * TODO: Should this go into the attr decl?
 7443: 	    */
 7444: 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7445: 	    child = child->next;
 7446: 	}
 7447: 	if (isRef) {
 7448: 	    if (child != NULL) {
 7449: 		if (IS_SCHEMA(child, "simpleType"))
 7450: 		    /*
 7451: 		    * 3.2.3 : 3.2
 7452: 		    * If ref is present, then all of <simpleType>,
 7453: 		    * form and type must be absent.
 7454: 		    */
 7455: 		    xmlSchemaPContentErr(pctxt,
 7456: 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
 7457: 			NULL, node, child, NULL,
 7458: 			"(annotation?)");
 7459: 		else
 7460: 		    xmlSchemaPContentErr(pctxt,
 7461: 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7462: 			NULL, node, child, NULL,
 7463: 			"(annotation?)");
 7464: 	    }
 7465: 	} else {
 7466: 	    if (IS_SCHEMA(child, "simpleType")) {
 7467: 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
 7468: 		    /*
 7469: 		    * 3.2.3 : 4
 7470: 		    * type and <simpleType> must not both be present.
 7471: 		    */
 7472: 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 7473: 			NULL, node, child,
 7474: 			"The attribute 'type' and the <simpleType> child "
 7475: 			"are mutually exclusive", NULL);
 7476: 		} else
 7477: 		    WXS_ATTRUSE_TYPEDEF(use) =
 7478: 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 7479: 		child = child->next;
 7480: 	    }
 7481: 	    if (child != NULL)
 7482: 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7483: 		NULL, node, child, NULL,
 7484: 		"(annotation?, simpleType?)");
 7485: 	}
 7486:     }
 7487:     return (WXS_BASIC_CAST use);
 7488: }
 7489: 
 7490: 
 7491: static xmlSchemaAttributePtr
 7492: xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
 7493: 			      xmlSchemaPtr schema,
 7494: 			      xmlNodePtr node)
 7495: {
 7496:     const xmlChar *attrValue;
 7497:     xmlSchemaAttributePtr ret;
 7498:     xmlNodePtr child = NULL;
 7499:     xmlAttrPtr attr;
 7500: 
 7501:     /*
 7502:      * Note that the w3c spec assumes the schema to be validated with schema
 7503:      * for schemas beforehand.
 7504:      *
 7505:      * 3.2.3 Constraints on XML Representations of Attribute Declarations
 7506:      */
 7507:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7508:         return (NULL);
 7509:     /*
 7510:     * 3.2.3 : 3.1
 7511:     * One of ref or name must be present, but not both
 7512:     */
 7513:     attr = xmlSchemaGetPropNode(node, "name");
 7514:     if (attr == NULL) {
 7515: 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 7516: 	    NULL, node, "name", NULL);
 7517: 	return (NULL);
 7518:     }
 7519:     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 7520: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
 7521: 	return (NULL);
 7522:     }
 7523:     /*
 7524:     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
 7525:     * TODO: Move this to the component layer.
 7526:     */
 7527:     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
 7528: 	xmlSchemaPSimpleTypeErr(pctxt,
 7529: 	    XML_SCHEMAP_NO_XMLNS,
 7530: 	    NULL, (xmlNodePtr) attr,
 7531: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 7532: 	    "The value of the attribute must not match 'xmlns'",
 7533: 	    NULL, NULL);
 7534: 	return (NULL);
 7535:     }
 7536:     /*
 7537:     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
 7538:     * TODO: Move this to the component layer.
 7539:     *       Or better leave it here and add it to the component layer
 7540:     *       if we have a schema construction API.
 7541:     */
 7542:     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
 7543: 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7544: 	    XML_SCHEMAP_NO_XSI, node, NULL,
 7545: 	    "The target namespace must not match '%s'",
 7546: 	    xmlSchemaInstanceNs, NULL);
 7547:     }
 7548: 
 7549:     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
 7550: 	pctxt->targetNamespace, node, 1);
 7551:     if (ret == NULL)
 7552: 	return (NULL);
 7553:     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
 7554: 
 7555:     /*
 7556:     * Check for illegal attributes.
 7557:     */
 7558:     attr = node->properties;
 7559:     while (attr != NULL) {
 7560: 	if (attr->ns == NULL) {
 7561: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 7562: 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 7563: 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 7564: 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 7565: 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
 7566: 	    {
 7567: 		xmlSchemaPIllegalAttrErr(pctxt,
 7568: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7569: 	    }
 7570: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7571: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7572: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7573: 	}
 7574: 	attr = attr->next;
 7575:     }
 7576:     xmlSchemaPValAttrQName(pctxt, schema, NULL,
 7577: 	node, "type", &ret->typeNs, &ret->typeName);
 7578: 
 7579:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7580:     /*
 7581:     * Attribute "fixed".
 7582:     */
 7583:     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
 7584:     if (ret->defValue != NULL)
 7585: 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
 7586:     /*
 7587:     * Attribute "default".
 7588:     */
 7589:     attr = xmlSchemaGetPropNode(node, "default");
 7590:     if (attr != NULL) {
 7591: 	/*
 7592: 	* 3.2.3 : 1
 7593: 	* default and fixed must not both be present.
 7594: 	*/
 7595: 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
 7596: 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7597: 		WXS_BASIC_CAST ret, attr, "default", "fixed");
 7598: 	} else
 7599: 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7600:     }
 7601:     /*
 7602:     * And now for the children...
 7603:     */
 7604:     child = node->children;
 7605:     if (IS_SCHEMA(child, "annotation")) {
 7606:         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7607:         child = child->next;
 7608:     }
 7609:     if (IS_SCHEMA(child, "simpleType")) {
 7610: 	if (ret->typeName != NULL) {
 7611: 	    /*
 7612: 	    * 3.2.3 : 4
 7613: 	    * type and <simpleType> must not both be present.
 7614: 	    */
 7615: 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 7616: 		NULL, node, child,
 7617: 		"The attribute 'type' and the <simpleType> child "
 7618: 		"are mutually exclusive", NULL);
 7619: 	} else
 7620: 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 7621: 	child = child->next;
 7622:     }
 7623:     if (child != NULL)
 7624: 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7625: 	    NULL, node, child, NULL,
 7626: 	    "(annotation?, simpleType?)");
 7627: 
 7628:     return (ret);
 7629: }
 7630: 
 7631: /**
 7632:  * xmlSchemaParseAttributeGroupRef:
 7633:  * @ctxt:  a schema validation context
 7634:  * @schema:  the schema being built
 7635:  * @node:  a subtree containing XML Schema informations
 7636:  *
 7637:  * Parse an attribute group definition reference.
 7638:  * Note that a reference to an attribute group does not
 7639:  * correspond to any component at all.
 7640:  * *WARNING* this interface is highly subject to change
 7641:  *
 7642:  * Returns the attribute group or NULL in case of error.
 7643:  */
 7644: static xmlSchemaQNameRefPtr
 7645: xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 7646: 				xmlSchemaPtr schema,
 7647: 				xmlNodePtr node)
 7648: {
 7649:     xmlSchemaQNameRefPtr ret;
 7650:     xmlNodePtr child = NULL;
 7651:     xmlAttrPtr attr;
 7652:     const xmlChar *refNs = NULL, *ref = NULL;
 7653: 
 7654:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7655:         return (NULL);
 7656: 
 7657:     attr = xmlSchemaGetPropNode(node, "ref");
 7658:     if (attr == NULL) {
 7659: 	xmlSchemaPMissingAttrErr(pctxt,
 7660: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 7661: 	    NULL, node, "ref", NULL);
 7662: 	return (NULL);
 7663:     }
 7664:     xmlSchemaPValAttrNodeQName(pctxt, schema,
 7665: 	NULL, attr, &refNs, &ref);
 7666:     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
 7667: 	return(NULL);
 7668: 
 7669:     /*
 7670:     * Check for illegal attributes.
 7671:     */
 7672:     attr = node->properties;
 7673:     while (attr != NULL) {
 7674: 	if (attr->ns == NULL) {
 7675: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 7676: 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
 7677: 	    {
 7678: 		xmlSchemaPIllegalAttrErr(pctxt,
 7679: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7680: 	    }
 7681: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7682: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7683: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7684: 	}
 7685: 	attr = attr->next;
 7686:     }
 7687:     /* Attribute ID */
 7688:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7689: 
 7690:     /*
 7691:     * And now for the children...
 7692:     */
 7693:     child = node->children;
 7694:     if (IS_SCHEMA(child, "annotation")) {
 7695: 	/*
 7696: 	* TODO: We do not have a place to store the annotation, do we?
 7697: 	*/
 7698:         xmlSchemaParseAnnotation(pctxt, child, 0);
 7699:         child = child->next;
 7700:     }
 7701:     if (child != NULL) {
 7702: 	xmlSchemaPContentErr(pctxt,
 7703: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7704: 	    NULL, node, child, NULL,
 7705: 	    "(annotation?)");
 7706:     }
 7707: 
 7708:     /*
 7709:     * Handle attribute group redefinitions.
 7710:     */
 7711:     if (pctxt->isRedefine && pctxt->redef &&
 7712: 	(pctxt->redef->item->type ==
 7713: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
 7714: 	(ref == pctxt->redef->refName) &&
 7715: 	(refNs == pctxt->redef->refTargetNs))
 7716:     {
 7717: 	/*
 7718: 	* SPEC src-redefine:
 7719: 	* (7.1) "If it has an <attributeGroup> among its contents
 7720: 	* the �actual value� of whose ref [attribute] is the same
 7721: 	* as the �actual value� of its own name attribute plus
 7722: 	* target namespace, then it must have exactly one such group."
 7723: 	*/
 7724: 	if (pctxt->redefCounter != 0) {
 7725: 	    xmlChar *str = NULL;
 7726: 
 7727: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7728: 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
 7729: 		"The redefining attribute group definition "
 7730: 		"'%s' must not contain more than one "
 7731: 		"reference to the redefined definition",
 7732: 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
 7733: 	    FREE_AND_NULL(str);
 7734: 	    return(NULL);
 7735: 	}
 7736: 	pctxt->redefCounter++;
 7737: 	/*
 7738: 	* URGENT TODO: How to ensure that the reference will not be
 7739: 	* handled by the normal component resolution mechanism?
 7740: 	*/
 7741: 	ret = xmlSchemaNewQNameRef(pctxt,
 7742: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 7743: 	if (ret == NULL)
 7744: 	    return(NULL);
 7745: 	ret->node = node;
 7746: 	pctxt->redef->reference = WXS_BASIC_CAST ret;
 7747:     } else {
 7748: 	/*
 7749: 	* Create a QName-reference helper component. We will substitute this
 7750: 	* component for the attribute uses of the referenced attribute group
 7751: 	* definition.
 7752: 	*/
 7753: 	ret = xmlSchemaNewQNameRef(pctxt,
 7754: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 7755: 	if (ret == NULL)
 7756: 	    return(NULL);
 7757: 	ret->node = node;
 7758: 	/* Add to pending items, to be able to resolve the reference. */
 7759: 	WXS_ADD_PENDING(pctxt, ret);
 7760:     }
 7761:     return (ret);
 7762: }
 7763: 
 7764: /**
 7765:  * xmlSchemaParseAttributeGroupDefinition:
 7766:  * @pctxt:  a schema validation context
 7767:  * @schema:  the schema being built
 7768:  * @node:  a subtree containing XML Schema informations
 7769:  *
 7770:  * parse a XML schema Attribute Group declaration
 7771:  * *WARNING* this interface is highly subject to change
 7772:  *
 7773:  * Returns the attribute group definition or NULL in case of error.
 7774:  */
 7775: static xmlSchemaAttributeGroupPtr
 7776: xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 7777: 				       xmlSchemaPtr schema,
 7778: 				       xmlNodePtr node)
 7779: {
 7780:     const xmlChar *name;
 7781:     xmlSchemaAttributeGroupPtr ret;
 7782:     xmlNodePtr child = NULL;
 7783:     xmlAttrPtr attr;
 7784:     int hasRefs = 0;
 7785: 
 7786:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7787:         return (NULL);
 7788: 
 7789:     attr = xmlSchemaGetPropNode(node, "name");
 7790:     if (attr == NULL) {
 7791: 	xmlSchemaPMissingAttrErr(pctxt,
 7792: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 7793: 	    NULL, node, "name", NULL);
 7794: 	return (NULL);
 7795:     }
 7796:     /*
 7797:     * The name is crucial, exit if invalid.
 7798:     */
 7799:     if (xmlSchemaPValAttrNode(pctxt,
 7800: 	NULL, attr,
 7801: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 7802: 	return (NULL);
 7803:     }
 7804:     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
 7805: 	name, pctxt->targetNamespace, node);
 7806:     if (ret == NULL)
 7807: 	return (NULL);
 7808:     /*
 7809:     * Check for illegal attributes.
 7810:     */
 7811:     attr = node->properties;
 7812:     while (attr != NULL) {
 7813: 	if (attr->ns == NULL) {
 7814: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 7815: 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
 7816: 	    {
 7817: 		xmlSchemaPIllegalAttrErr(pctxt,
 7818: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7819: 	    }
 7820: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7821: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7822: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7823: 	}
 7824: 	attr = attr->next;
 7825:     }
 7826:     /* Attribute ID */
 7827:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7828:     /*
 7829:     * And now for the children...
 7830:     */
 7831:     child = node->children;
 7832:     if (IS_SCHEMA(child, "annotation")) {
 7833:         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7834:         child = child->next;
 7835:     }
 7836:     /*
 7837:     * Parse contained attribute decls/refs.
 7838:     */
 7839:     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
 7840: 	(xmlSchemaItemListPtr *) &(ret->attrUses),
 7841: 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
 7842: 	return(NULL);
 7843:     if (hasRefs)
 7844: 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
 7845:     /*
 7846:     * Parse the attribute wildcard.
 7847:     */
 7848:     if (IS_SCHEMA(child, "anyAttribute")) {
 7849: 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
 7850: 	    schema, child);
 7851: 	child = child->next;
 7852:     }
 7853:     if (child != NULL) {
 7854: 	xmlSchemaPContentErr(pctxt,
 7855: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7856: 	    NULL, node, child, NULL,
 7857: 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
 7858:     }
 7859:     return (ret);
 7860: }
 7861: 
 7862: /**
 7863:  * xmlSchemaPValAttrFormDefault:
 7864:  * @value:  the value
 7865:  * @flags: the flags to be modified
 7866:  * @flagQualified: the specific flag for "qualified"
 7867:  *
 7868:  * Returns 0 if the value is valid, 1 otherwise.
 7869:  */
 7870: static int
 7871: xmlSchemaPValAttrFormDefault(const xmlChar *value,
 7872: 			     int *flags,
 7873: 			     int flagQualified)
 7874: {
 7875:     if (xmlStrEqual(value, BAD_CAST "qualified")) {
 7876: 	if  ((*flags & flagQualified) == 0)
 7877: 	    *flags |= flagQualified;
 7878:     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
 7879: 	return (1);
 7880: 
 7881:     return (0);
 7882: }
 7883: 
 7884: /**
 7885:  * xmlSchemaPValAttrBlockFinal:
 7886:  * @value:  the value
 7887:  * @flags: the flags to be modified
 7888:  * @flagAll: the specific flag for "#all"
 7889:  * @flagExtension: the specific flag for "extension"
 7890:  * @flagRestriction: the specific flag for "restriction"
 7891:  * @flagSubstitution: the specific flag for "substitution"
 7892:  * @flagList: the specific flag for "list"
 7893:  * @flagUnion: the specific flag for "union"
 7894:  *
 7895:  * Validates the value of the attribute "final" and "block". The value
 7896:  * is converted into the specified flag values and returned in @flags.
 7897:  *
 7898:  * Returns 0 if the value is valid, 1 otherwise.
 7899:  */
 7900: 
 7901: static int
 7902: xmlSchemaPValAttrBlockFinal(const xmlChar *value,
 7903: 			    int *flags,
 7904: 			    int flagAll,
 7905: 			    int flagExtension,
 7906: 			    int flagRestriction,
 7907: 			    int flagSubstitution,
 7908: 			    int flagList,
 7909: 			    int flagUnion)
 7910: {
 7911:     int ret = 0;
 7912: 
 7913:     /*
 7914:     * TODO: This does not check for dublicate entries.
 7915:     */
 7916:     if ((flags == NULL) || (value == NULL))
 7917: 	return (-1);
 7918:     if (value[0] == 0)
 7919: 	return (0);
 7920:     if (xmlStrEqual(value, BAD_CAST "#all")) {
 7921: 	if (flagAll != -1)
 7922: 	    *flags |= flagAll;
 7923: 	else {
 7924: 	    if (flagExtension != -1)
 7925: 		*flags |= flagExtension;
 7926: 	    if (flagRestriction != -1)
 7927: 		*flags |= flagRestriction;
 7928: 	    if (flagSubstitution != -1)
 7929: 		*flags |= flagSubstitution;
 7930: 	    if (flagList != -1)
 7931: 		*flags |= flagList;
 7932: 	    if (flagUnion != -1)
 7933: 		*flags |= flagUnion;
 7934: 	}
 7935:     } else {
 7936: 	const xmlChar *end, *cur = value;
 7937: 	xmlChar *item;
 7938: 
 7939: 	do {
 7940: 	    while (IS_BLANK_CH(*cur))
 7941: 		cur++;
 7942: 	    end = cur;
 7943: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 7944: 		end++;
 7945: 	    if (end == cur)
 7946: 		break;
 7947: 	    item = xmlStrndup(cur, end - cur);
 7948: 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
 7949: 		if (flagExtension != -1) {
 7950: 		    if ((*flags & flagExtension) == 0)
 7951: 			*flags |= flagExtension;
 7952: 		} else
 7953: 		    ret = 1;
 7954: 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
 7955: 		if (flagRestriction != -1) {
 7956: 		    if ((*flags & flagRestriction) == 0)
 7957: 			*flags |= flagRestriction;
 7958: 		} else
 7959: 		    ret = 1;
 7960: 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
 7961: 		if (flagSubstitution != -1) {
 7962: 		    if ((*flags & flagSubstitution) == 0)
 7963: 			*flags |= flagSubstitution;
 7964: 		} else
 7965: 		    ret = 1;
 7966: 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
 7967: 		if (flagList != -1) {
 7968: 		    if ((*flags & flagList) == 0)
 7969: 			*flags |= flagList;
 7970: 		} else
 7971: 		    ret = 1;
 7972: 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
 7973: 		if (flagUnion != -1) {
 7974: 		    if ((*flags & flagUnion) == 0)
 7975: 			*flags |= flagUnion;
 7976: 		} else
 7977: 		    ret = 1;
 7978: 	    } else
 7979: 		ret = 1;
 7980: 	    if (item != NULL)
 7981: 		xmlFree(item);
 7982: 	    cur = end;
 7983: 	} while ((ret == 0) && (*cur != 0));
 7984:     }
 7985: 
 7986:     return (ret);
 7987: }
 7988: 
 7989: static int
 7990: xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
 7991: 			     xmlSchemaIDCPtr idc,
 7992: 			     xmlSchemaIDCSelectPtr selector,
 7993: 			     xmlAttrPtr attr,
 7994: 			     int isField)
 7995: {
 7996:     xmlNodePtr node;
 7997: 
 7998:     /*
 7999:     * c-selector-xpath:
 8000:     * Schema Component Constraint: Selector Value OK
 8001:     *
 8002:     * TODO: 1 The {selector} must be a valid XPath expression, as defined
 8003:     * in [XPath].
 8004:     */
 8005:     if (selector == NULL) {
 8006: 	xmlSchemaPErr(ctxt, idc->node,
 8007: 	    XML_SCHEMAP_INTERNAL,
 8008: 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
 8009: 	    "the selector is not specified.\n", NULL, NULL);
 8010: 	return (-1);
 8011:     }
 8012:     if (attr == NULL)
 8013: 	node = idc->node;
 8014:     else
 8015: 	node = (xmlNodePtr) attr;
 8016:     if (selector->xpath == NULL) {
 8017: 	xmlSchemaPCustomErr(ctxt,
 8018: 	    /* TODO: Adjust error code. */
 8019: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8020: 	    NULL, node,
 8021: 	    "The XPath expression of the selector is not valid", NULL);
 8022: 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 8023:     } else {
 8024: 	const xmlChar **nsArray = NULL;
 8025: 	xmlNsPtr *nsList = NULL;
 8026: 	/*
 8027: 	* Compile the XPath expression.
 8028: 	*/
 8029: 	/*
 8030: 	* TODO: We need the array of in-scope namespaces for compilation.
 8031: 	* TODO: Call xmlPatterncompile with different options for selector/
 8032: 	* field.
 8033: 	*/
 8034: 	if (attr == NULL)
 8035: 	    nsList = NULL;
 8036: 	else
 8037: 	    nsList = xmlGetNsList(attr->doc, attr->parent);
 8038: 	/*
 8039: 	* Build an array of prefixes and namespaces.
 8040: 	*/
 8041: 	if (nsList != NULL) {
 8042: 	    int i, count = 0;
 8043: 
 8044: 	    for (i = 0; nsList[i] != NULL; i++)
 8045: 		count++;
 8046: 
 8047: 	    nsArray = (const xmlChar **) xmlMalloc(
 8048: 		(count * 2 + 1) * sizeof(const xmlChar *));
 8049: 	    if (nsArray == NULL) {
 8050: 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
 8051: 		    NULL);
 8052: 		xmlFree(nsList);
 8053: 		return (-1);
 8054: 	    }
 8055: 	    for (i = 0; i < count; i++) {
 8056: 		nsArray[2 * i] = nsList[i]->href;
 8057: 		nsArray[2 * i + 1] = nsList[i]->prefix;
 8058: 	    }
 8059: 	    nsArray[count * 2] = NULL;
 8060: 	    xmlFree(nsList);
 8061: 	}
 8062: 	/*
 8063: 	* TODO: Differentiate between "selector" and "field".
 8064: 	*/
 8065: 	if (isField)
 8066: 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 8067: 		NULL, XML_PATTERN_XSFIELD, nsArray);
 8068: 	else
 8069: 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 8070: 		NULL, XML_PATTERN_XSSEL, nsArray);
 8071: 	if (nsArray != NULL)
 8072: 	    xmlFree((xmlChar **) nsArray);
 8073: 
 8074: 	if (selector->xpathComp == NULL) {
 8075: 	    xmlSchemaPCustomErr(ctxt,
 8076: 		/* TODO: Adjust error code? */
 8077: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8078: 		NULL, node,
 8079: 		"The XPath expression '%s' could not be "
 8080: 		"compiled", selector->xpath);
 8081: 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 8082: 	}
 8083:     }
 8084:     return (0);
 8085: }
 8086: 
 8087: #define ADD_ANNOTATION(annot)   \
 8088:     xmlSchemaAnnotPtr cur = item->annot; \
 8089:     if (item->annot == NULL) {  \
 8090: 	item->annot = annot;    \
 8091: 	return (annot);         \
 8092:     }                           \
 8093:     cur = item->annot;          \
 8094:     if (cur->next != NULL) {    \
 8095: 	cur = cur->next;	\
 8096:     }                           \
 8097:     cur->next = annot;
 8098: 
 8099: /**
 8100:  * xmlSchemaAssignAnnotation:
 8101:  * @item: the schema component
 8102:  * @annot: the annotation
 8103:  *
 8104:  * Adds the annotation to the given schema component.
 8105:  *
 8106:  * Returns the given annotaion.
 8107:  */
 8108: static xmlSchemaAnnotPtr
 8109: xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
 8110: 		       xmlSchemaAnnotPtr annot)
 8111: {
 8112:     if ((annItem == NULL) || (annot == NULL))
 8113: 	return (NULL);
 8114:     switch (annItem->type) {
 8115: 	case XML_SCHEMA_TYPE_ELEMENT: {
 8116: 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
 8117: 		ADD_ANNOTATION(annot)
 8118: 	    }
 8119: 	    break;
 8120: 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
 8121: 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
 8122: 		ADD_ANNOTATION(annot)
 8123: 	    }
 8124: 	    break;
 8125: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 8126: 	case XML_SCHEMA_TYPE_ANY: {
 8127: 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
 8128: 		ADD_ANNOTATION(annot)
 8129: 	    }
 8130: 	    break;
 8131: 	case XML_SCHEMA_TYPE_PARTICLE:
 8132: 	case XML_SCHEMA_TYPE_IDC_KEY:
 8133: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 8134: 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
 8135: 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
 8136: 		ADD_ANNOTATION(annot)
 8137: 	    }
 8138: 	    break;
 8139: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
 8140: 		xmlSchemaAttributeGroupPtr item =
 8141: 		    (xmlSchemaAttributeGroupPtr) annItem;
 8142: 		ADD_ANNOTATION(annot)
 8143: 	    }
 8144: 	    break;
 8145: 	case XML_SCHEMA_TYPE_NOTATION: {
 8146: 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
 8147: 		ADD_ANNOTATION(annot)
 8148: 	    }
 8149: 	    break;
 8150: 	case XML_SCHEMA_FACET_MININCLUSIVE:
 8151: 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 8152: 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 8153: 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 8154: 	case XML_SCHEMA_FACET_TOTALDIGITS:
 8155: 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
 8156: 	case XML_SCHEMA_FACET_PATTERN:
 8157: 	case XML_SCHEMA_FACET_ENUMERATION:
 8158: 	case XML_SCHEMA_FACET_WHITESPACE:
 8159: 	case XML_SCHEMA_FACET_LENGTH:
 8160: 	case XML_SCHEMA_FACET_MAXLENGTH:
 8161: 	case XML_SCHEMA_FACET_MINLENGTH: {
 8162: 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
 8163: 		ADD_ANNOTATION(annot)
 8164: 	    }
 8165: 	    break;
 8166: 	case XML_SCHEMA_TYPE_SIMPLE:
 8167: 	case XML_SCHEMA_TYPE_COMPLEX: {
 8168: 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
 8169: 		ADD_ANNOTATION(annot)
 8170: 	    }
 8171: 	    break;
 8172: 	case XML_SCHEMA_TYPE_GROUP: {
 8173: 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
 8174: 		ADD_ANNOTATION(annot)
 8175: 	    }
 8176: 	    break;
 8177: 	case XML_SCHEMA_TYPE_SEQUENCE:
 8178: 	case XML_SCHEMA_TYPE_CHOICE:
 8179: 	case XML_SCHEMA_TYPE_ALL: {
 8180: 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
 8181: 		ADD_ANNOTATION(annot)
 8182: 	    }
 8183: 	    break;
 8184: 	default:
 8185: 	     xmlSchemaPCustomErr(NULL,
 8186: 		XML_SCHEMAP_INTERNAL,
 8187: 		NULL, NULL,
 8188: 		"Internal error: xmlSchemaAddAnnotation, "
 8189: 		"The item is not a annotated schema component", NULL);
 8190: 	     break;
 8191:     }
 8192:     return (annot);
 8193: }
 8194: 
 8195: /**
 8196:  * xmlSchemaParseIDCSelectorAndField:
 8197:  * @ctxt:  a schema validation context
 8198:  * @schema:  the schema being built
 8199:  * @node:  a subtree containing XML Schema informations
 8200:  *
 8201:  * Parses a XML Schema identity-contraint definition's
 8202:  * <selector> and <field> elements.
 8203:  *
 8204:  * Returns the parsed identity-constraint definition.
 8205:  */
 8206: static xmlSchemaIDCSelectPtr
 8207: xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
 8208: 			  xmlSchemaIDCPtr idc,
 8209: 			  xmlNodePtr node,
 8210: 			  int isField)
 8211: {
 8212:     xmlSchemaIDCSelectPtr item;
 8213:     xmlNodePtr child = NULL;
 8214:     xmlAttrPtr attr;
 8215: 
 8216:     /*
 8217:     * Check for illegal attributes.
 8218:     */
 8219:     attr = node->properties;
 8220:     while (attr != NULL) {
 8221: 	if (attr->ns == NULL) {
 8222: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8223: 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
 8224: 		xmlSchemaPIllegalAttrErr(ctxt,
 8225: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8226: 	    }
 8227: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8228: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8229: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8230: 	}
 8231: 	attr = attr->next;
 8232:     }
 8233:     /*
 8234:     * Create the item.
 8235:     */
 8236:     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
 8237:     if (item == NULL) {
 8238:         xmlSchemaPErrMemory(ctxt,
 8239: 	    "allocating a 'selector' of an identity-constraint definition",
 8240: 	    NULL);
 8241:         return (NULL);
 8242:     }
 8243:     memset(item, 0, sizeof(xmlSchemaIDCSelect));
 8244:     /*
 8245:     * Attribute "xpath" (mandatory).
 8246:     */
 8247:     attr = xmlSchemaGetPropNode(node, "xpath");
 8248:     if (attr == NULL) {
 8249: 	xmlSchemaPMissingAttrErr(ctxt,
 8250: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 8251: 	    NULL, node,
 8252: 	    "name", NULL);
 8253:     } else {
 8254: 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8255: 	/*
 8256: 	* URGENT TODO: "field"s have an other syntax than "selector"s.
 8257: 	*/
 8258: 
 8259: 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
 8260: 	    isField) == -1) {
 8261: 	    xmlSchemaPErr(ctxt,
 8262: 		(xmlNodePtr) attr,
 8263: 		XML_SCHEMAP_INTERNAL,
 8264: 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
 8265: 		"validating the XPath expression of a IDC selector.\n",
 8266: 		NULL, NULL);
 8267: 	}
 8268: 
 8269:     }
 8270:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8271:     /*
 8272:     * And now for the children...
 8273:     */
 8274:     child = node->children;
 8275:     if (IS_SCHEMA(child, "annotation")) {
 8276: 	/*
 8277: 	* Add the annotation to the parent IDC.
 8278: 	*/
 8279: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
 8280: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 8281: 	child = child->next;
 8282:     }
 8283:     if (child != NULL) {
 8284: 	xmlSchemaPContentErr(ctxt,
 8285: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8286: 	    NULL, node, child,
 8287: 	    NULL, "(annotation?)");
 8288:     }
 8289: 
 8290:     return (item);
 8291: }
 8292: 
 8293: /**
 8294:  * xmlSchemaParseIDC:
 8295:  * @ctxt:  a schema validation context
 8296:  * @schema:  the schema being built
 8297:  * @node:  a subtree containing XML Schema informations
 8298:  *
 8299:  * Parses a XML Schema identity-contraint definition.
 8300:  *
 8301:  * Returns the parsed identity-constraint definition.
 8302:  */
 8303: static xmlSchemaIDCPtr
 8304: xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
 8305: 		  xmlSchemaPtr schema,
 8306: 		  xmlNodePtr node,
 8307: 		  xmlSchemaTypeType idcCategory,
 8308: 		  const xmlChar *targetNamespace)
 8309: {
 8310:     xmlSchemaIDCPtr item = NULL;
 8311:     xmlNodePtr child = NULL;
 8312:     xmlAttrPtr attr;
 8313:     const xmlChar *name = NULL;
 8314:     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
 8315: 
 8316:     /*
 8317:     * Check for illegal attributes.
 8318:     */
 8319:     attr = node->properties;
 8320:     while (attr != NULL) {
 8321: 	if (attr->ns == NULL) {
 8322: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8323: 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 8324: 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
 8325: 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
 8326: 		xmlSchemaPIllegalAttrErr(ctxt,
 8327: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8328: 	    }
 8329: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8330: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8331: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8332: 	}
 8333: 	attr = attr->next;
 8334:     }
 8335:     /*
 8336:     * Attribute "name" (mandatory).
 8337:     */
 8338:     attr = xmlSchemaGetPropNode(node, "name");
 8339:     if (attr == NULL) {
 8340: 	xmlSchemaPMissingAttrErr(ctxt,
 8341: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 8342: 	    NULL, node,
 8343: 	    "name", NULL);
 8344: 	return (NULL);
 8345:     } else if (xmlSchemaPValAttrNode(ctxt,
 8346: 	NULL, attr,
 8347: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 8348: 	return (NULL);
 8349:     }
 8350:     /* Create the component. */
 8351:     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
 8352: 	idcCategory, node);
 8353:     if (item == NULL)
 8354: 	return(NULL);
 8355: 
 8356:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8357:     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
 8358: 	/*
 8359: 	* Attribute "refer" (mandatory).
 8360: 	*/
 8361: 	attr = xmlSchemaGetPropNode(node, "refer");
 8362: 	if (attr == NULL) {
 8363: 	    xmlSchemaPMissingAttrErr(ctxt,
 8364: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 8365: 		NULL, node,
 8366: 		"refer", NULL);
 8367: 	} else {
 8368: 	    /*
 8369: 	    * Create a reference item.
 8370: 	    */
 8371: 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
 8372: 		NULL, NULL);
 8373: 	    if (item->ref == NULL)
 8374: 		return (NULL);
 8375: 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
 8376: 		NULL, attr,
 8377: 		&(item->ref->targetNamespace),
 8378: 		&(item->ref->name));
 8379: 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
 8380: 		item->ref->targetNamespace);
 8381: 	}
 8382:     }
 8383:     /*
 8384:     * And now for the children...
 8385:     */
 8386:     child = node->children;
 8387:     if (IS_SCHEMA(child, "annotation")) {
 8388: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 8389: 	child = child->next;
 8390:     }
 8391:     if (child == NULL) {
 8392: 	xmlSchemaPContentErr(ctxt,
 8393: 		XML_SCHEMAP_S4S_ELEM_MISSING,
 8394: 		NULL, node, child,
 8395: 		"A child element is missing",
 8396: 		"(annotation?, (selector, field+))");
 8397:     }
 8398:     /*
 8399:     * Child element <selector>.
 8400:     */
 8401:     if (IS_SCHEMA(child, "selector")) {
 8402: 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
 8403: 	    item, child, 0);
 8404: 	child = child->next;
 8405: 	/*
 8406: 	* Child elements <field>.
 8407: 	*/
 8408: 	if (IS_SCHEMA(child, "field")) {
 8409: 	    do {
 8410: 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
 8411: 		    item, child, 1);
 8412: 		if (field != NULL) {
 8413: 		    field->index = item->nbFields;
 8414: 		    item->nbFields++;
 8415: 		    if (lastField != NULL)
 8416: 			lastField->next = field;
 8417: 		    else
 8418: 			item->fields = field;
 8419: 		    lastField = field;
 8420: 		}
 8421: 		child = child->next;
 8422: 	    } while (IS_SCHEMA(child, "field"));
 8423: 	} else {
 8424: 	    xmlSchemaPContentErr(ctxt,
 8425: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8426: 		NULL, node, child,
 8427: 		NULL, "(annotation?, (selector, field+))");
 8428: 	}
 8429:     }
 8430:     if (child != NULL) {
 8431: 	xmlSchemaPContentErr(ctxt,
 8432: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8433: 	    NULL, node, child,
 8434: 	    NULL, "(annotation?, (selector, field+))");
 8435:     }
 8436: 
 8437:     return (item);
 8438: }
 8439: 
 8440: /**
 8441:  * xmlSchemaParseElement:
 8442:  * @ctxt:  a schema validation context
 8443:  * @schema:  the schema being built
 8444:  * @node:  a subtree containing XML Schema informations
 8445:  * @topLevel: indicates if this is global declaration
 8446:  *
 8447:  * Parses a XML schema element declaration.
 8448:  * *WARNING* this interface is highly subject to change
 8449:  *
 8450:  * Returns the element declaration or a particle; NULL in case
 8451:  * of an error or if the particle has minOccurs==maxOccurs==0.
 8452:  */
 8453: static xmlSchemaBasicItemPtr
 8454: xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 8455:                       xmlNodePtr node, int *isElemRef, int topLevel)
 8456: {
 8457:     xmlSchemaElementPtr decl = NULL;
 8458:     xmlSchemaParticlePtr particle = NULL;
 8459:     xmlSchemaAnnotPtr annot = NULL;
 8460:     xmlNodePtr child = NULL;
 8461:     xmlAttrPtr attr, nameAttr;
 8462:     int min, max, isRef = 0;
 8463:     xmlChar *des = NULL;
 8464: 
 8465:     /* 3.3.3 Constraints on XML Representations of Element Declarations */
 8466:     /* TODO: Complete implementation of 3.3.6 */
 8467: 
 8468:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 8469:         return (NULL);
 8470: 
 8471:     if (isElemRef != NULL)
 8472: 	*isElemRef = 0;
 8473:     /*
 8474:     * If we get a "ref" attribute on a local <element> we will assume it's
 8475:     * a reference - even if there's a "name" attribute; this seems to be more
 8476:     * robust.
 8477:     */
 8478:     nameAttr = xmlSchemaGetPropNode(node, "name");
 8479:     attr = xmlSchemaGetPropNode(node, "ref");
 8480:     if ((topLevel) || (attr == NULL)) {
 8481: 	if (nameAttr == NULL) {
 8482: 	    xmlSchemaPMissingAttrErr(ctxt,
 8483: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 8484: 		NULL, node, "name", NULL);
 8485: 	    return (NULL);
 8486: 	}
 8487:     } else
 8488: 	isRef = 1;
 8489: 
 8490:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8491:     child = node->children;
 8492:     if (IS_SCHEMA(child, "annotation")) {
 8493: 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 8494: 	child = child->next;
 8495:     }
 8496:     /*
 8497:     * Skip particle part if a global declaration.
 8498:     */
 8499:     if (topLevel)
 8500: 	goto declaration_part;
 8501:     /*
 8502:     * The particle part ==================================================
 8503:     */
 8504:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 8505:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
 8506:     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 8507:     particle = xmlSchemaAddParticle(ctxt, node, min, max);
 8508:     if (particle == NULL)
 8509: 	goto return_null;
 8510: 
 8511:     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
 8512: 
 8513:     if (isRef) {
 8514: 	const xmlChar *refNs = NULL, *ref = NULL;
 8515: 	xmlSchemaQNameRefPtr refer = NULL;
 8516: 	/*
 8517: 	* The reference part =============================================
 8518: 	*/
 8519: 	if (isElemRef != NULL)
 8520: 	    *isElemRef = 1;
 8521: 
 8522: 	xmlSchemaPValAttrNodeQName(ctxt, schema,
 8523: 	    NULL, attr, &refNs, &ref);
 8524: 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 8525: 	/*
 8526: 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
 8527: 	*/
 8528: 	if (nameAttr != NULL) {
 8529: 	    xmlSchemaPMutualExclAttrErr(ctxt,
 8530: 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
 8531: 	}
 8532: 	/*
 8533: 	* Check for illegal attributes.
 8534: 	*/
 8535: 	attr = node->properties;
 8536: 	while (attr != NULL) {
 8537: 	    if (attr->ns == NULL) {
 8538: 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
 8539: 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
 8540: 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
 8541: 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
 8542: 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
 8543: 		{
 8544: 		    attr = attr->next;
 8545: 		    continue;
 8546: 		} else {
 8547: 		    /* SPEC (3.3.3 : 2.2) */
 8548: 		    xmlSchemaPCustomAttrErr(ctxt,
 8549: 			XML_SCHEMAP_SRC_ELEMENT_2_2,
 8550: 			NULL, NULL, attr,
 8551: 			"Only the attributes 'minOccurs', 'maxOccurs' and "
 8552: 			"'id' are allowed in addition to 'ref'");
 8553: 		    break;
 8554: 		}
 8555: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8556: 		xmlSchemaPIllegalAttrErr(ctxt,
 8557: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8558: 	    }
 8559: 	    attr = attr->next;
 8560: 	}
 8561: 	/*
 8562: 	* No children except <annotation> expected.
 8563: 	*/
 8564: 	if (child != NULL) {
 8565: 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8566: 		NULL, node, child, NULL, "(annotation?)");
 8567: 	}
 8568: 	if ((min == 0) && (max == 0))
 8569: 	    goto return_null;
 8570: 	/*
 8571: 	* Create the reference item and attach it to the particle.
 8572: 	*/
 8573: 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
 8574: 	    ref, refNs);
 8575: 	if (refer == NULL)
 8576: 	    goto return_null;
 8577: 	particle->children = (xmlSchemaTreeItemPtr) refer;
 8578: 	particle->annot = annot;
 8579: 	/*
 8580: 	* Add the particle to pending components, since the reference
 8581: 	* need to be resolved.
 8582: 	*/
 8583: 	WXS_ADD_PENDING(ctxt, particle);
 8584: 	return ((xmlSchemaBasicItemPtr) particle);
 8585:     }
 8586:     /*
 8587:     * The declaration part ===============================================
 8588:     */
 8589: declaration_part:
 8590:     {
 8591: 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
 8592: 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
 8593: 
 8594: 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
 8595: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
 8596: 	    goto return_null;
 8597: 	/*
 8598: 	* Evaluate the target namespace.
 8599: 	*/
 8600: 	if (topLevel) {
 8601: 	    ns = ctxt->targetNamespace;
 8602: 	} else {
 8603: 	    attr = xmlSchemaGetPropNode(node, "form");
 8604: 	    if (attr != NULL) {
 8605: 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8606: 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 8607: 		    ns = ctxt->targetNamespace;
 8608: 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
 8609: 		    xmlSchemaPSimpleTypeErr(ctxt,
 8610: 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8611: 			NULL, (xmlNodePtr) attr,
 8612: 			NULL, "(qualified | unqualified)",
 8613: 			attrValue, NULL, NULL, NULL);
 8614: 		}
 8615: 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 8616: 		ns = ctxt->targetNamespace;
 8617: 	}
 8618: 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
 8619: 	if (decl == NULL) {
 8620: 	    goto return_null;
 8621: 	}
 8622: 	/*
 8623: 	* Check for illegal attributes.
 8624: 	*/
 8625: 	attr = node->properties;
 8626: 	while (attr != NULL) {
 8627: 	    if (attr->ns == NULL) {
 8628: 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 8629: 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
 8630: 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8631: 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 8632: 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 8633: 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
 8634: 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
 8635: 		{
 8636: 		    if (topLevel == 0) {
 8637: 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 8638: 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 8639: 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
 8640: 			{
 8641: 			    xmlSchemaPIllegalAttrErr(ctxt,
 8642: 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8643: 			}
 8644: 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
 8645: 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
 8646: 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
 8647: 
 8648: 			xmlSchemaPIllegalAttrErr(ctxt,
 8649: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8650: 		    }
 8651: 		}
 8652: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8653: 
 8654: 		xmlSchemaPIllegalAttrErr(ctxt,
 8655: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8656: 	    }
 8657: 	    attr = attr->next;
 8658: 	}
 8659: 	/*
 8660: 	* Extract/validate attributes.
 8661: 	*/
 8662: 	if (topLevel) {
 8663: 	    /*
 8664: 	    * Process top attributes of global element declarations here.
 8665: 	    */
 8666: 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
 8667: 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
 8668: 	    xmlSchemaPValAttrQName(ctxt, schema,
 8669: 		NULL, node, "substitutionGroup",
 8670: 		&(decl->substGroupNs), &(decl->substGroup));
 8671: 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
 8672: 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
 8673: 	    /*
 8674: 	    * Attribute "final".
 8675: 	    */
 8676: 	    attr = xmlSchemaGetPropNode(node, "final");
 8677: 	    if (attr == NULL) {
 8678: 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 8679: 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
 8680: 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 8681: 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
 8682: 	    } else {
 8683: 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8684: 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 8685: 		    -1,
 8686: 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
 8687: 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
 8688: 		    xmlSchemaPSimpleTypeErr(ctxt,
 8689: 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8690: 			NULL, (xmlNodePtr) attr,
 8691: 			NULL, "(#all | List of (extension | restriction))",
 8692: 			attrValue, NULL, NULL, NULL);
 8693: 		}
 8694: 	    }
 8695: 	}
 8696: 	/*
 8697: 	* Attribute "block".
 8698: 	*/
 8699: 	attr = xmlSchemaGetPropNode(node, "block");
 8700: 	if (attr == NULL) {
 8701: 	    /*
 8702: 	    * Apply default "block" values.
 8703: 	    */
 8704: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 8705: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
 8706: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 8707: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
 8708: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 8709: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
 8710: 	} else {
 8711: 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8712: 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 8713: 		-1,
 8714: 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
 8715: 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
 8716: 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
 8717: 		xmlSchemaPSimpleTypeErr(ctxt,
 8718: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8719: 		    NULL, (xmlNodePtr) attr,
 8720: 		    NULL, "(#all | List of (extension | "
 8721: 		    "restriction | substitution))", attrValue,
 8722: 		    NULL, NULL, NULL);
 8723: 	    }
 8724: 	}
 8725: 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
 8726: 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
 8727: 
 8728: 	attr = xmlSchemaGetPropNode(node, "type");
 8729: 	if (attr != NULL) {
 8730: 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
 8731: 		NULL, attr,
 8732: 		&(decl->namedTypeNs), &(decl->namedType));
 8733: 	    xmlSchemaCheckReference(ctxt, schema, node,
 8734: 		attr, decl->namedTypeNs);
 8735: 	}
 8736: 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
 8737: 	attr = xmlSchemaGetPropNode(node, "fixed");
 8738: 	if (attr != NULL) {
 8739: 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8740: 	    if (decl->value != NULL) {
 8741: 		/*
 8742: 		* 3.3.3 : 1
 8743: 		* default and fixed must not both be present.
 8744: 		*/
 8745: 		xmlSchemaPMutualExclAttrErr(ctxt,
 8746: 		    XML_SCHEMAP_SRC_ELEMENT_1,
 8747: 		    NULL, attr, "default", "fixed");
 8748: 	    } else {
 8749: 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
 8750: 		decl->value = fixed;
 8751: 	    }
 8752: 	}
 8753: 	/*
 8754: 	* And now for the children...
 8755: 	*/
 8756: 	if (IS_SCHEMA(child, "complexType")) {
 8757: 	    /*
 8758: 	    * 3.3.3 : 3
 8759: 	    * "type" and either <simpleType> or <complexType> are mutually
 8760: 	    * exclusive
 8761: 	    */
 8762: 	    if (decl->namedType != NULL) {
 8763: 		xmlSchemaPContentErr(ctxt,
 8764: 		    XML_SCHEMAP_SRC_ELEMENT_3,
 8765: 		    NULL, node, child,
 8766: 		    "The attribute 'type' and the <complexType> child are "
 8767: 		    "mutually exclusive", NULL);
 8768: 	    } else
 8769: 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
 8770: 	    child = child->next;
 8771: 	} else if (IS_SCHEMA(child, "simpleType")) {
 8772: 	    /*
 8773: 	    * 3.3.3 : 3
 8774: 	    * "type" and either <simpleType> or <complexType> are
 8775: 	    * mutually exclusive
 8776: 	    */
 8777: 	    if (decl->namedType != NULL) {
 8778: 		xmlSchemaPContentErr(ctxt,
 8779: 		    XML_SCHEMAP_SRC_ELEMENT_3,
 8780: 		    NULL, node, child,
 8781: 		    "The attribute 'type' and the <simpleType> child are "
 8782: 		    "mutually exclusive", NULL);
 8783: 	    } else
 8784: 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 8785: 	    child = child->next;
 8786: 	}
 8787: 	while ((IS_SCHEMA(child, "unique")) ||
 8788: 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
 8789: 	    if (IS_SCHEMA(child, "unique")) {
 8790: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8791: 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
 8792: 	    } else if (IS_SCHEMA(child, "key")) {
 8793: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8794: 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
 8795: 	    } else if (IS_SCHEMA(child, "keyref")) {
 8796: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8797: 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
 8798: 	    }
 8799: 	    if (lastIDC != NULL)
 8800: 		lastIDC->next = curIDC;
 8801: 	    else
 8802: 		decl->idcs = (void *) curIDC;
 8803: 	    lastIDC = curIDC;
 8804: 	    child = child->next;
 8805: 	}
 8806: 	if (child != NULL) {
 8807: 	    xmlSchemaPContentErr(ctxt,
 8808: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8809: 		NULL, node, child,
 8810: 		NULL, "(annotation?, ((simpleType | complexType)?, "
 8811: 		"(unique | key | keyref)*))");
 8812: 	}
 8813: 	decl->annot = annot;
 8814:     }
 8815:     /*
 8816:     * NOTE: Element Declaration Representation OK 4. will be checked at a
 8817:     * different layer.
 8818:     */
 8819:     FREE_AND_NULL(des)
 8820:     if (topLevel)
 8821: 	return ((xmlSchemaBasicItemPtr) decl);
 8822:     else {
 8823: 	particle->children = (xmlSchemaTreeItemPtr) decl;
 8824: 	return ((xmlSchemaBasicItemPtr) particle);
 8825:     }
 8826: 
 8827: return_null:
 8828:     FREE_AND_NULL(des);
 8829:     if (annot != NULL) {
 8830: 	if (particle != NULL)
 8831: 	    particle->annot = NULL;
 8832: 	if (decl != NULL)
 8833: 	    decl->annot = NULL;
 8834: 	xmlSchemaFreeAnnot(annot);
 8835:     }
 8836:     return (NULL);
 8837: }
 8838: 
 8839: /**
 8840:  * xmlSchemaParseUnion:
 8841:  * @ctxt:  a schema validation context
 8842:  * @schema:  the schema being built
 8843:  * @node:  a subtree containing XML Schema informations
 8844:  *
 8845:  * parse a XML schema Union definition
 8846:  * *WARNING* this interface is highly subject to change
 8847:  *
 8848:  * Returns -1 in case of internal error, 0 in case of success and a positive
 8849:  * error code otherwise.
 8850:  */
 8851: static int
 8852: xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 8853:                     xmlNodePtr node)
 8854: {
 8855:     xmlSchemaTypePtr type;
 8856:     xmlNodePtr child = NULL;
 8857:     xmlAttrPtr attr;
 8858:     const xmlChar *cur = NULL;
 8859: 
 8860:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 8861:         return (-1);
 8862:     /* Not a component, don't create it. */
 8863:     type = ctxt->ctxtType;
 8864:     /*
 8865:     * Mark the simple type as being of variety "union".
 8866:     */
 8867:     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
 8868:     /*
 8869:     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 8870:     * then the �simple ur-type definition�."
 8871:     */
 8872:     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 8873:     /*
 8874:     * Check for illegal attributes.
 8875:     */
 8876:     attr = node->properties;
 8877:     while (attr != NULL) {
 8878: 	if (attr->ns == NULL) {
 8879: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8880: 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
 8881: 		xmlSchemaPIllegalAttrErr(ctxt,
 8882: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8883: 	    }
 8884: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8885: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8886: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8887: 	}
 8888: 	attr = attr->next;
 8889:     }
 8890:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8891:     /*
 8892:     * Attribute "memberTypes". This is a list of QNames.
 8893:     * TODO: Check the value to contain anything.
 8894:     */
 8895:     attr = xmlSchemaGetPropNode(node, "memberTypes");
 8896:     if (attr != NULL) {
 8897: 	const xmlChar *end;
 8898: 	xmlChar *tmp;
 8899: 	const xmlChar *localName, *nsName;
 8900: 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
 8901: 	xmlSchemaQNameRefPtr ref;
 8902: 
 8903: 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8904: 	type->base = cur;
 8905: 	do {
 8906: 	    while (IS_BLANK_CH(*cur))
 8907: 		cur++;
 8908: 	    end = cur;
 8909: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 8910: 		end++;
 8911: 	    if (end == cur)
 8912: 		break;
 8913: 	    tmp = xmlStrndup(cur, end - cur);
 8914: 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 8915: 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
 8916: 		/*
 8917: 		* Create the member type link.
 8918: 		*/
 8919: 		link = (xmlSchemaTypeLinkPtr)
 8920: 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
 8921: 		if (link == NULL) {
 8922: 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
 8923: 			"allocating a type link", NULL);
 8924: 		    return (-1);
 8925: 		}
 8926: 		link->type = NULL;
 8927: 		link->next = NULL;
 8928: 		if (lastLink == NULL)
 8929: 		    type->memberTypes = link;
 8930: 		else
 8931: 		    lastLink->next = link;
 8932: 		lastLink = link;
 8933: 		/*
 8934: 		* Create a reference item.
 8935: 		*/
 8936: 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
 8937: 		    localName, nsName);
 8938: 		if (ref == NULL) {
 8939: 		    FREE_AND_NULL(tmp)
 8940: 		    return (-1);
 8941: 		}
 8942: 		/*
 8943: 		* Assign the reference to the link, it will be resolved
 8944: 		* later during fixup of the union simple type.
 8945: 		*/
 8946: 		link->type = (xmlSchemaTypePtr) ref;
 8947: 	    }
 8948: 	    FREE_AND_NULL(tmp)
 8949: 	    cur = end;
 8950: 	} while (*cur != 0);
 8951: 
 8952:     }
 8953:     /*
 8954:     * And now for the children...
 8955:     */
 8956:     child = node->children;
 8957:     if (IS_SCHEMA(child, "annotation")) {
 8958: 	/*
 8959: 	* Add the annotation to the simple type ancestor.
 8960: 	*/
 8961: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 8962: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 8963:         child = child->next;
 8964:     }
 8965:     if (IS_SCHEMA(child, "simpleType")) {
 8966: 	xmlSchemaTypePtr subtype, last = NULL;
 8967: 
 8968: 	/*
 8969: 	* Anchor the member types in the "subtypes" field of the
 8970: 	* simple type.
 8971: 	*/
 8972: 	while (IS_SCHEMA(child, "simpleType")) {
 8973: 	    subtype = (xmlSchemaTypePtr)
 8974: 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 8975: 	    if (subtype != NULL) {
 8976: 		if (last == NULL) {
 8977: 		    type->subtypes = subtype;
 8978: 		    last = subtype;
 8979: 		} else {
 8980: 		    last->next = subtype;
 8981: 		    last = subtype;
 8982: 		}
 8983: 		last->next = NULL;
 8984: 	    }
 8985: 	    child = child->next;
 8986: 	}
 8987:     }
 8988:     if (child != NULL) {
 8989: 	xmlSchemaPContentErr(ctxt,
 8990: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8991: 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
 8992:     }
 8993:     if ((attr == NULL) && (type->subtypes == NULL)) {
 8994: 	 /*
 8995: 	* src-union-memberTypes-or-simpleTypes
 8996: 	* Either the memberTypes [attribute] of the <union> element must
 8997: 	* be non-empty or there must be at least one simpleType [child].
 8998: 	*/
 8999: 	xmlSchemaPCustomErr(ctxt,
 9000: 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
 9001: 	    NULL, node,
 9002: 	    "Either the attribute 'memberTypes' or "
 9003: 	    "at least one <simpleType> child must be present", NULL);
 9004:     }
 9005:     return (0);
 9006: }
 9007: 
 9008: /**
 9009:  * xmlSchemaParseList:
 9010:  * @ctxt:  a schema validation context
 9011:  * @schema:  the schema being built
 9012:  * @node:  a subtree containing XML Schema informations
 9013:  *
 9014:  * parse a XML schema List definition
 9015:  * *WARNING* this interface is highly subject to change
 9016:  *
 9017:  * Returns -1 in case of error, 0 if the declaration is improper and
 9018:  *         1 in case of success.
 9019:  */
 9020: static xmlSchemaTypePtr
 9021: xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 9022:                    xmlNodePtr node)
 9023: {
 9024:     xmlSchemaTypePtr type;
 9025:     xmlNodePtr child = NULL;
 9026:     xmlAttrPtr attr;
 9027: 
 9028:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9029:         return (NULL);
 9030:     /* Not a component, don't create it. */
 9031:     type = ctxt->ctxtType;
 9032:     /*
 9033:     * Mark the type as being of variety "list".
 9034:     */
 9035:     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
 9036:     /*
 9037:     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 9038:     * then the �simple ur-type definition�."
 9039:     */
 9040:     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 9041:     /*
 9042:     * Check for illegal attributes.
 9043:     */
 9044:     attr = node->properties;
 9045:     while (attr != NULL) {
 9046: 	if (attr->ns == NULL) {
 9047: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9048: 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
 9049: 		xmlSchemaPIllegalAttrErr(ctxt,
 9050: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9051: 	    }
 9052: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9053: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9054: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9055: 	}
 9056: 	attr = attr->next;
 9057:     }
 9058: 
 9059:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9060: 
 9061:     /*
 9062:     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
 9063:     * fields for holding the reference to the itemType.
 9064:     *
 9065:     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
 9066:     * the "ref" fields.
 9067:     */
 9068:     xmlSchemaPValAttrQName(ctxt, schema, NULL,
 9069: 	node, "itemType", &(type->baseNs), &(type->base));
 9070:     /*
 9071:     * And now for the children...
 9072:     */
 9073:     child = node->children;
 9074:     if (IS_SCHEMA(child, "annotation")) {
 9075: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 9076: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 9077:         child = child->next;
 9078:     }
 9079:     if (IS_SCHEMA(child, "simpleType")) {
 9080: 	/*
 9081: 	* src-list-itemType-or-simpleType
 9082: 	* Either the itemType [attribute] or the <simpleType> [child] of
 9083: 	* the <list> element must be present, but not both.
 9084: 	*/
 9085: 	if (type->base != NULL) {
 9086: 	    xmlSchemaPCustomErr(ctxt,
 9087: 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9088: 		NULL, node,
 9089: 		"The attribute 'itemType' and the <simpleType> child "
 9090: 		"are mutually exclusive", NULL);
 9091: 	} else {
 9092: 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 9093: 	}
 9094:         child = child->next;
 9095:     } else if (type->base == NULL) {
 9096: 	xmlSchemaPCustomErr(ctxt,
 9097: 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9098: 	    NULL, node,
 9099: 	    "Either the attribute 'itemType' or the <simpleType> child "
 9100: 	    "must be present", NULL);
 9101:     }
 9102:     if (child != NULL) {
 9103: 	xmlSchemaPContentErr(ctxt,
 9104: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9105: 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
 9106:     }
 9107:     if ((type->base == NULL) &&
 9108: 	(type->subtypes == NULL) &&
 9109: 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
 9110: 	xmlSchemaPCustomErr(ctxt,
 9111: 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9112: 	    NULL, node,
 9113: 	    "Either the attribute 'itemType' or the <simpleType> child "
 9114: 	    "must be present", NULL);
 9115:     }
 9116:     return (NULL);
 9117: }
 9118: 
 9119: /**
 9120:  * xmlSchemaParseSimpleType:
 9121:  * @ctxt:  a schema validation context
 9122:  * @schema:  the schema being built
 9123:  * @node:  a subtree containing XML Schema informations
 9124:  *
 9125:  * parse a XML schema Simple Type definition
 9126:  * *WARNING* this interface is highly subject to change
 9127:  *
 9128:  * Returns -1 in case of error, 0 if the declaration is improper and
 9129:  * 1 in case of success.
 9130:  */
 9131: static xmlSchemaTypePtr
 9132: xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 9133:                          xmlNodePtr node, int topLevel)
 9134: {
 9135:     xmlSchemaTypePtr type, oldCtxtType;
 9136:     xmlNodePtr child = NULL;
 9137:     const xmlChar *attrValue = NULL;
 9138:     xmlAttrPtr attr;
 9139:     int hasRestriction = 0;
 9140: 
 9141:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9142:         return (NULL);
 9143: 
 9144:     if (topLevel) {
 9145: 	attr = xmlSchemaGetPropNode(node, "name");
 9146: 	if (attr == NULL) {
 9147: 	    xmlSchemaPMissingAttrErr(ctxt,
 9148: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 9149: 		NULL, node,
 9150: 		"name", NULL);
 9151: 	    return (NULL);
 9152: 	} else {
 9153: 	    if (xmlSchemaPValAttrNode(ctxt,
 9154: 		NULL, attr,
 9155: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
 9156: 		return (NULL);
 9157: 	    /*
 9158: 	    * Skip built-in types.
 9159: 	    */
 9160: 	    if (ctxt->isS4S) {
 9161: 		xmlSchemaTypePtr biType;
 9162: 
 9163: 		if (ctxt->isRedefine) {
 9164: 		    /*
 9165: 		    * REDEFINE: Disallow redefinition of built-in-types.
 9166: 		    * TODO: It seems that the spec does not say anything
 9167: 		    * about this case.
 9168: 		    */
 9169: 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 9170: 			NULL, node,
 9171: 			"Redefinition of built-in simple types is not "
 9172: 			"supported", NULL);
 9173: 		    return(NULL);
 9174: 		}
 9175: 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
 9176: 		if (biType != NULL)
 9177: 		    return (biType);
 9178: 	    }
 9179: 	}
 9180:     }
 9181:     /*
 9182:     * TargetNamespace:
 9183:     * SPEC "The �actual value� of the targetNamespace [attribute]
 9184:     * of the <schema> ancestor element information item if present,
 9185:     * otherwise �absent�.
 9186:     */
 9187:     if (topLevel == 0) {
 9188: #ifdef ENABLE_NAMED_LOCALS
 9189:         char buf[40];
 9190: #endif
 9191: 	/*
 9192: 	* Parse as local simple type definition.
 9193: 	*/
 9194: #ifdef ENABLE_NAMED_LOCALS
 9195:         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
 9196: 	type = xmlSchemaAddType(ctxt, schema,
 9197: 	    XML_SCHEMA_TYPE_SIMPLE,
 9198: 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
 9199: 	    ctxt->targetNamespace, node, 0);
 9200: #else
 9201: 	type = xmlSchemaAddType(ctxt, schema,
 9202: 	    XML_SCHEMA_TYPE_SIMPLE,
 9203: 	    NULL, ctxt->targetNamespace, node, 0);
 9204: #endif
 9205: 	if (type == NULL)
 9206: 	    return (NULL);
 9207: 	type->type = XML_SCHEMA_TYPE_SIMPLE;
 9208: 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 9209: 	/*
 9210: 	* Check for illegal attributes.
 9211: 	*/
 9212: 	attr = node->properties;
 9213: 	while (attr != NULL) {
 9214: 	    if (attr->ns == NULL) {
 9215: 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
 9216: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9217: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9218: 		}
 9219: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9220: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9221: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9222: 	    }
 9223: 	    attr = attr->next;
 9224: 	}
 9225:     } else {
 9226: 	/*
 9227: 	* Parse as global simple type definition.
 9228: 	*
 9229: 	* Note that attrValue is the value of the attribute "name" here.
 9230: 	*/
 9231: 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
 9232: 	    attrValue, ctxt->targetNamespace, node, 1);
 9233: 	if (type == NULL)
 9234: 	    return (NULL);
 9235: 	type->type = XML_SCHEMA_TYPE_SIMPLE;
 9236: 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 9237: 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
 9238: 	/*
 9239: 	* Check for illegal attributes.
 9240: 	*/
 9241: 	attr = node->properties;
 9242: 	while (attr != NULL) {
 9243: 	    if (attr->ns == NULL) {
 9244: 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9245: 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 9246: 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
 9247: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9248: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9249: 		}
 9250: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9251: 		xmlSchemaPIllegalAttrErr(ctxt,
 9252: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9253: 	    }
 9254: 	    attr = attr->next;
 9255: 	}
 9256: 	/*
 9257: 	* Attribute "final".
 9258: 	*/
 9259: 	attr = xmlSchemaGetPropNode(node, "final");
 9260: 	if (attr == NULL) {
 9261: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 9262: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
 9263: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 9264: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
 9265: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 9266: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
 9267: 	} else {
 9268: 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
 9269: 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
 9270: 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
 9271: 		XML_SCHEMAS_TYPE_FINAL_LIST,
 9272: 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
 9273: 
 9274: 		xmlSchemaPSimpleTypeErr(ctxt,
 9275: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9276: 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
 9277: 		    NULL, "(#all | List of (list | union | restriction)",
 9278: 		    attrValue, NULL, NULL, NULL);
 9279: 	    }
 9280: 	}
 9281:     }
 9282:     type->targetNamespace = ctxt->targetNamespace;
 9283:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9284:     /*
 9285:     * And now for the children...
 9286:     */
 9287:     oldCtxtType = ctxt->ctxtType;
 9288: 
 9289:     ctxt->ctxtType = type;
 9290: 
 9291:     child = node->children;
 9292:     if (IS_SCHEMA(child, "annotation")) {
 9293:         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9294:         child = child->next;
 9295:     }
 9296:     if (child == NULL) {
 9297: 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
 9298: 	    NULL, node, child, NULL,
 9299: 	    "(annotation?, (restriction | list | union))");
 9300:     } else if (IS_SCHEMA(child, "restriction")) {
 9301:         xmlSchemaParseRestriction(ctxt, schema, child,
 9302: 	    XML_SCHEMA_TYPE_SIMPLE);
 9303: 	hasRestriction = 1;
 9304:         child = child->next;
 9305:     } else if (IS_SCHEMA(child, "list")) {
 9306:         xmlSchemaParseList(ctxt, schema, child);
 9307:         child = child->next;
 9308:     } else if (IS_SCHEMA(child, "union")) {
 9309:         xmlSchemaParseUnion(ctxt, schema, child);
 9310:         child = child->next;
 9311:     }
 9312:     if (child != NULL) {
 9313: 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9314: 	    NULL, node, child, NULL,
 9315: 	    "(annotation?, (restriction | list | union))");
 9316:     }
 9317:     /*
 9318:     * REDEFINE: SPEC src-redefine (5)
 9319:     * "Within the [children], each <simpleType> must have a
 9320:     * <restriction> among its [children] ... the �actual value� of whose
 9321:     * base [attribute] must be the same as the �actual value� of its own
 9322:     * name attribute plus target namespace;"
 9323:     */
 9324:     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
 9325: 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 9326: 	    NULL, node, "This is a redefinition, thus the "
 9327: 	    "<simpleType> must have a <restriction> child", NULL);
 9328:     }
 9329: 
 9330:     ctxt->ctxtType = oldCtxtType;
 9331:     return (type);
 9332: }
 9333: 
 9334: /**
 9335:  * xmlSchemaParseModelGroupDefRef:
 9336:  * @ctxt:  the parser context
 9337:  * @schema: the schema being built
 9338:  * @node:  the node
 9339:  *
 9340:  * Parses a reference to a model group definition.
 9341:  *
 9342:  * We will return a particle component with a qname-component or
 9343:  * NULL in case of an error.
 9344:  */
 9345: static xmlSchemaTreeItemPtr
 9346: xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
 9347: 			       xmlSchemaPtr schema,
 9348: 			       xmlNodePtr node)
 9349: {
 9350:     xmlSchemaParticlePtr item;
 9351:     xmlNodePtr child = NULL;
 9352:     xmlAttrPtr attr;
 9353:     const xmlChar *ref = NULL, *refNs = NULL;
 9354:     int min, max;
 9355: 
 9356:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9357:         return (NULL);
 9358: 
 9359:     attr = xmlSchemaGetPropNode(node, "ref");
 9360:     if (attr == NULL) {
 9361: 	xmlSchemaPMissingAttrErr(ctxt,
 9362: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 9363: 	    NULL, node, "ref", NULL);
 9364: 	return (NULL);
 9365:     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
 9366: 	attr, &refNs, &ref) != 0) {
 9367: 	return (NULL);
 9368:     }
 9369:     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 9370:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 9371:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 9372: 	"(xs:nonNegativeInteger | unbounded)");
 9373:     /*
 9374:     * Check for illegal attributes.
 9375:     */
 9376:     attr = node->properties;
 9377:     while (attr != NULL) {
 9378: 	if (attr->ns == NULL) {
 9379: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 9380: 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9381: 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 9382: 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
 9383: 		xmlSchemaPIllegalAttrErr(ctxt,
 9384: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9385: 	    }
 9386: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9387: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9388: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9389: 	}
 9390: 	attr = attr->next;
 9391:     }
 9392:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9393:     item = xmlSchemaAddParticle(ctxt, node, min, max);
 9394:     if (item == NULL)
 9395: 	return (NULL);
 9396:     /*
 9397:     * Create a qname-reference and set as the term; it will be substituted
 9398:     * for the model group after the reference has been resolved.
 9399:     */
 9400:     item->children = (xmlSchemaTreeItemPtr)
 9401: 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
 9402:     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
 9403:     /*
 9404:     * And now for the children...
 9405:     */
 9406:     child = node->children;
 9407:     /* TODO: Is annotation even allowed for a model group reference? */
 9408:     if (IS_SCHEMA(child, "annotation")) {
 9409: 	/*
 9410: 	* TODO: What to do exactly with the annotation?
 9411: 	*/
 9412: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9413: 	child = child->next;
 9414:     }
 9415:     if (child != NULL) {
 9416: 	xmlSchemaPContentErr(ctxt,
 9417: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9418: 	    NULL, node, child, NULL,
 9419: 	    "(annotation?)");
 9420:     }
 9421:     /*
 9422:     * Corresponds to no component at all if minOccurs==maxOccurs==0.
 9423:     */
 9424:     if ((min == 0) && (max == 0))
 9425: 	return (NULL);
 9426: 
 9427:     return ((xmlSchemaTreeItemPtr) item);
 9428: }
 9429: 
 9430: /**
 9431:  * xmlSchemaParseModelGroupDefinition:
 9432:  * @ctxt:  a schema validation context
 9433:  * @schema:  the schema being built
 9434:  * @node:  a subtree containing XML Schema informations
 9435:  *
 9436:  * Parses a XML schema model group definition.
 9437:  *
 9438:  * Note that the contraint src-redefine (6.2) can't be applied until
 9439:  * references have been resolved. So we will do this at the
 9440:  * component fixup level.
 9441:  *
 9442:  * *WARNING* this interface is highly subject to change
 9443:  *
 9444:  * Returns -1 in case of error, 0 if the declaration is improper and
 9445:  *         1 in case of success.
 9446:  */
 9447: static xmlSchemaModelGroupDefPtr
 9448: xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 9449: 				   xmlSchemaPtr schema,
 9450: 				   xmlNodePtr node)
 9451: {
 9452:     xmlSchemaModelGroupDefPtr item;
 9453:     xmlNodePtr child = NULL;
 9454:     xmlAttrPtr attr;
 9455:     const xmlChar *name;
 9456: 
 9457:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9458:         return (NULL);
 9459: 
 9460:     attr = xmlSchemaGetPropNode(node, "name");
 9461:     if (attr == NULL) {
 9462: 	xmlSchemaPMissingAttrErr(ctxt,
 9463: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 9464: 	    NULL, node,
 9465: 	    "name", NULL);
 9466: 	return (NULL);
 9467:     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
 9468: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 9469: 	return (NULL);
 9470:     }
 9471:     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
 9472: 	ctxt->targetNamespace, node);
 9473:     if (item == NULL)
 9474: 	return (NULL);
 9475:     /*
 9476:     * Check for illegal attributes.
 9477:     */
 9478:     attr = node->properties;
 9479:     while (attr != NULL) {
 9480: 	if (attr->ns == NULL) {
 9481: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 9482: 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
 9483: 		xmlSchemaPIllegalAttrErr(ctxt,
 9484: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9485: 	    }
 9486: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9487: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9488: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9489: 	}
 9490: 	attr = attr->next;
 9491:     }
 9492:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9493:     /*
 9494:     * And now for the children...
 9495:     */
 9496:     child = node->children;
 9497:     if (IS_SCHEMA(child, "annotation")) {
 9498: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9499: 	child = child->next;
 9500:     }
 9501:     if (IS_SCHEMA(child, "all")) {
 9502: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9503: 	    XML_SCHEMA_TYPE_ALL, 0);
 9504: 	child = child->next;
 9505:     } else if (IS_SCHEMA(child, "choice")) {
 9506: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9507: 	    XML_SCHEMA_TYPE_CHOICE, 0);
 9508: 	child = child->next;
 9509:     } else if (IS_SCHEMA(child, "sequence")) {
 9510: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9511: 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
 9512: 	child = child->next;
 9513:     }
 9514: 
 9515: 
 9516: 
 9517:     if (child != NULL) {
 9518: 	xmlSchemaPContentErr(ctxt,
 9519: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9520: 	    NULL, node, child, NULL,
 9521: 	    "(annotation?, (all | choice | sequence)?)");
 9522:     }
 9523:     return (item);
 9524: }
 9525: 
 9526: /**
 9527:  * xmlSchemaCleanupDoc:
 9528:  * @ctxt:  a schema validation context
 9529:  * @node:  the root of the document.
 9530:  *
 9531:  * removes unwanted nodes in a schemas document tree
 9532:  */
 9533: static void
 9534: xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
 9535: {
 9536:     xmlNodePtr delete, cur;
 9537: 
 9538:     if ((ctxt == NULL) || (root == NULL)) return;
 9539: 
 9540:     /*
 9541:      * Remove all the blank text nodes
 9542:      */
 9543:     delete = NULL;
 9544:     cur = root;
 9545:     while (cur != NULL) {
 9546:         if (delete != NULL) {
 9547:             xmlUnlinkNode(delete);
 9548:             xmlFreeNode(delete);
 9549:             delete = NULL;
 9550:         }
 9551:         if (cur->type == XML_TEXT_NODE) {
 9552:             if (IS_BLANK_NODE(cur)) {
 9553:                 if (xmlNodeGetSpacePreserve(cur) != 1) {
 9554:                     delete = cur;
 9555:                 }
 9556:             }
 9557:         } else if ((cur->type != XML_ELEMENT_NODE) &&
 9558:                    (cur->type != XML_CDATA_SECTION_NODE)) {
 9559:             delete = cur;
 9560:             goto skip_children;
 9561:         }
 9562: 
 9563:         /*
 9564:          * Skip to next node
 9565:          */
 9566:         if (cur->children != NULL) {
 9567:             if ((cur->children->type != XML_ENTITY_DECL) &&
 9568:                 (cur->children->type != XML_ENTITY_REF_NODE) &&
 9569:                 (cur->children->type != XML_ENTITY_NODE)) {
 9570:                 cur = cur->children;
 9571:                 continue;
 9572:             }
 9573:         }
 9574:       skip_children:
 9575:         if (cur->next != NULL) {
 9576:             cur = cur->next;
 9577:             continue;
 9578:         }
 9579: 
 9580:         do {
 9581:             cur = cur->parent;
 9582:             if (cur == NULL)
 9583:                 break;
 9584:             if (cur == root) {
 9585:                 cur = NULL;
 9586:                 break;
 9587:             }
 9588:             if (cur->next != NULL) {
 9589:                 cur = cur->next;
 9590:                 break;
 9591:             }
 9592:         } while (cur != NULL);
 9593:     }
 9594:     if (delete != NULL) {
 9595:         xmlUnlinkNode(delete);
 9596:         xmlFreeNode(delete);
 9597:         delete = NULL;
 9598:     }
 9599: }
 9600: 
 9601: 
 9602: static void
 9603: xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
 9604: {
 9605:     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 9606: 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
 9607: 
 9608:     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
 9609: 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
 9610: 
 9611:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 9612: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
 9613:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 9614: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
 9615:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 9616: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
 9617:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 9618: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
 9619: 
 9620:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 9621: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
 9622:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 9623: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
 9624:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 9625: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
 9626: }
 9627: 
 9628: static int
 9629: xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
 9630: 			     xmlSchemaPtr schema,
 9631: 			     xmlNodePtr node)
 9632: {
 9633:     xmlAttrPtr attr;
 9634:     const xmlChar *val;
 9635:     int res = 0, oldErrs = ctxt->nberrors;
 9636: 
 9637:     /*
 9638:     * Those flags should be moved to the parser context flags,
 9639:     * since they are not visible at the component level. I.e.
 9640:     * they are used if processing schema *documents* only.
 9641:     */
 9642:     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9643:     HFAILURE;
 9644: 
 9645:     /*
 9646:     * Since the version is of type xs:token, we won't bother to
 9647:     * check it.
 9648:     */
 9649:     /* REMOVED:
 9650:     attr = xmlSchemaGetPropNode(node, "version");
 9651:     if (attr != NULL) {
 9652: 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
 9653: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
 9654: 	HFAILURE;
 9655:     }
 9656:     */
 9657:     attr = xmlSchemaGetPropNode(node, "targetNamespace");
 9658:     if (attr != NULL) {
 9659: 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
 9660: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 9661: 	HFAILURE;
 9662: 	if (res != 0) {
 9663: 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 9664: 	    goto exit;
 9665: 	}
 9666:     }
 9667:     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
 9668:     if (attr != NULL) {
 9669: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9670: 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 9671: 	    XML_SCHEMAS_QUALIF_ELEM);
 9672: 	HFAILURE;
 9673: 	if (res != 0) {
 9674: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9675: 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
 9676: 		NULL, (xmlNodePtr) attr, NULL,
 9677: 		"(qualified | unqualified)", val, NULL, NULL, NULL);
 9678: 	}
 9679:     }
 9680:     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
 9681:     if (attr != NULL) {
 9682: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9683: 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 9684: 	    XML_SCHEMAS_QUALIF_ATTR);
 9685: 	HFAILURE;
 9686: 	if (res != 0) {
 9687: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9688: 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
 9689: 		NULL, (xmlNodePtr) attr, NULL,
 9690: 		"(qualified | unqualified)", val, NULL, NULL, NULL);
 9691: 	}
 9692:     }
 9693:     attr = xmlSchemaGetPropNode(node, "finalDefault");
 9694:     if (attr != NULL) {
 9695: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9696: 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 9697: 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
 9698: 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
 9699: 	    -1,
 9700: 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
 9701: 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
 9702: 	HFAILURE;
 9703: 	if (res != 0) {
 9704: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9705: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9706: 		NULL, (xmlNodePtr) attr, NULL,
 9707: 		"(#all | List of (extension | restriction | list | union))",
 9708: 		val, NULL, NULL, NULL);
 9709: 	}
 9710:     }
 9711:     attr = xmlSchemaGetPropNode(node, "blockDefault");
 9712:     if (attr != NULL) {
 9713: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9714: 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 9715: 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
 9716: 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
 9717: 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
 9718: 	HFAILURE;
 9719: 	if (res != 0) {
 9720: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9721: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9722: 		NULL, (xmlNodePtr) attr, NULL,
 9723: 		"(#all | List of (extension | restriction | substitution))",
 9724: 		val, NULL, NULL, NULL);
 9725: 	}
 9726:     }
 9727: 
 9728: exit:
 9729:     if (oldErrs != ctxt->nberrors)
 9730: 	res = ctxt->err;
 9731:     return(res);
 9732: exit_failure:
 9733:     return(-1);
 9734: }
 9735: 
 9736: /**
 9737:  * xmlSchemaParseSchemaTopLevel:
 9738:  * @ctxt:  a schema validation context
 9739:  * @schema:  the schemas
 9740:  * @nodes:  the list of top level nodes
 9741:  *
 9742:  * Returns the internal XML Schema structure built from the resource or
 9743:  *         NULL in case of error
 9744:  */
 9745: static int
 9746: xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
 9747:                              xmlSchemaPtr schema, xmlNodePtr nodes)
 9748: {
 9749:     xmlNodePtr child;
 9750:     xmlSchemaAnnotPtr annot;
 9751:     int res = 0, oldErrs, tmpOldErrs;
 9752: 
 9753:     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
 9754:         return(-1);
 9755: 
 9756:     oldErrs = ctxt->nberrors;
 9757:     child = nodes;
 9758:     while ((IS_SCHEMA(child, "include")) ||
 9759: 	   (IS_SCHEMA(child, "import")) ||
 9760: 	   (IS_SCHEMA(child, "redefine")) ||
 9761: 	   (IS_SCHEMA(child, "annotation"))) {
 9762: 	if (IS_SCHEMA(child, "annotation")) {
 9763: 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9764: 	    if (schema->annot == NULL)
 9765: 		schema->annot = annot;
 9766: 	    else
 9767: 		xmlSchemaFreeAnnot(annot);
 9768: 	} else if (IS_SCHEMA(child, "import")) {
 9769: 	    tmpOldErrs = ctxt->nberrors;
 9770: 	    res = xmlSchemaParseImport(ctxt, schema, child);
 9771: 	    HFAILURE;
 9772: 	    HSTOP(ctxt);
 9773: 	    if (tmpOldErrs != ctxt->nberrors)
 9774: 		goto exit;
 9775: 	} else if (IS_SCHEMA(child, "include")) {
 9776: 	    tmpOldErrs = ctxt->nberrors;
 9777: 	    res = xmlSchemaParseInclude(ctxt, schema, child);
 9778: 	    HFAILURE;
 9779: 	    HSTOP(ctxt);
 9780: 	    if (tmpOldErrs != ctxt->nberrors)
 9781: 		goto exit;
 9782: 	} else if (IS_SCHEMA(child, "redefine")) {
 9783: 	    tmpOldErrs = ctxt->nberrors;
 9784: 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
 9785: 	    HFAILURE;
 9786: 	    HSTOP(ctxt);
 9787: 	    if (tmpOldErrs != ctxt->nberrors)
 9788: 		goto exit;
 9789: 	}
 9790: 	child = child->next;
 9791:     }
 9792:     /*
 9793:     * URGENT TODO: Change the functions to return int results.
 9794:     * We need especially to catch internal errors.
 9795:     */
 9796:     while (child != NULL) {
 9797: 	if (IS_SCHEMA(child, "complexType")) {
 9798: 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
 9799: 	    child = child->next;
 9800: 	} else if (IS_SCHEMA(child, "simpleType")) {
 9801: 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
 9802: 	    child = child->next;
 9803: 	} else if (IS_SCHEMA(child, "element")) {
 9804: 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
 9805: 	    child = child->next;
 9806: 	} else if (IS_SCHEMA(child, "attribute")) {
 9807: 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
 9808: 	    child = child->next;
 9809: 	} else if (IS_SCHEMA(child, "attributeGroup")) {
 9810: 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
 9811: 	    child = child->next;
 9812: 	} else if (IS_SCHEMA(child, "group")) {
 9813: 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
 9814: 	    child = child->next;
 9815: 	} else if (IS_SCHEMA(child, "notation")) {
 9816: 	    xmlSchemaParseNotation(ctxt, schema, child);
 9817: 	    child = child->next;
 9818: 	} else {
 9819: 	    xmlSchemaPContentErr(ctxt,
 9820: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9821: 		NULL, child->parent, child,
 9822: 		NULL, "((include | import | redefine | annotation)*, "
 9823: 		"(((simpleType | complexType | group | attributeGroup) "
 9824: 		"| element | attribute | notation), annotation*)*)");
 9825: 	    child = child->next;
 9826: 	}
 9827: 	while (IS_SCHEMA(child, "annotation")) {
 9828: 	    /*
 9829: 	    * TODO: We should add all annotations.
 9830: 	    */
 9831: 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9832: 	    if (schema->annot == NULL)
 9833: 		schema->annot = annot;
 9834: 	    else
 9835: 		xmlSchemaFreeAnnot(annot);
 9836: 	    child = child->next;
 9837: 	}
 9838:     }
 9839: exit:
 9840:     ctxt->ctxtType = NULL;
 9841:     if (oldErrs != ctxt->nberrors)
 9842: 	res = ctxt->err;
 9843:     return(res);
 9844: exit_failure:
 9845:     return(-1);
 9846: }
 9847: 
 9848: static xmlSchemaSchemaRelationPtr
 9849: xmlSchemaSchemaRelationCreate(void)
 9850: {
 9851:     xmlSchemaSchemaRelationPtr ret;
 9852: 
 9853:     ret = (xmlSchemaSchemaRelationPtr)
 9854: 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
 9855:     if (ret == NULL) {
 9856: 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
 9857: 	return(NULL);
 9858:     }
 9859:     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
 9860:     return(ret);
 9861: }
 9862: 
 9863: #if 0
 9864: static void
 9865: xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
 9866: {
 9867:     xmlFree(rel);
 9868: }
 9869: #endif
 9870: 
 9871: static void
 9872: xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
 9873: {
 9874:     xmlSchemaRedefPtr prev;
 9875: 
 9876:     while (redef != NULL) {
 9877: 	prev = redef;
 9878: 	redef = redef->next;
 9879: 	xmlFree(prev);
 9880:     }
 9881: }
 9882: 
 9883: static void
 9884: xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
 9885: {
 9886:     /*
 9887:     * After the construction context has been freed, there will be
 9888:     * no schema graph available any more. Only the schema buckets
 9889:     * will stay alive, which are put into the "schemasImports" and
 9890:     * "includes" slots of the xmlSchema.
 9891:     */
 9892:     if (con->buckets != NULL)
 9893: 	xmlSchemaItemListFree(con->buckets);
 9894:     if (con->pending != NULL)
 9895: 	xmlSchemaItemListFree(con->pending);
 9896:     if (con->substGroups != NULL)
 9897: 	xmlHashFree(con->substGroups,
 9898: 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
 9899:     if (con->redefs != NULL)
 9900: 	xmlSchemaRedefListFree(con->redefs);
 9901:     if (con->dict != NULL)
 9902: 	xmlDictFree(con->dict);
 9903:     xmlFree(con);
 9904: }
 9905: 
 9906: static xmlSchemaConstructionCtxtPtr
 9907: xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
 9908: {
 9909:     xmlSchemaConstructionCtxtPtr ret;
 9910: 
 9911:     ret = (xmlSchemaConstructionCtxtPtr)
 9912: 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
 9913:     if (ret == NULL) {
 9914:         xmlSchemaPErrMemory(NULL,
 9915: 	    "allocating schema construction context", NULL);
 9916:         return (NULL);
 9917:     }
 9918:     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
 9919: 
 9920:     ret->buckets = xmlSchemaItemListCreate();
 9921:     if (ret->buckets == NULL) {
 9922: 	xmlSchemaPErrMemory(NULL,
 9923: 	    "allocating list of schema buckets", NULL);
 9924: 	xmlFree(ret);
 9925:         return (NULL);
 9926:     }
 9927:     ret->pending = xmlSchemaItemListCreate();
 9928:     if (ret->pending == NULL) {
 9929: 	xmlSchemaPErrMemory(NULL,
 9930: 	    "allocating list of pending global components", NULL);
 9931: 	xmlSchemaConstructionCtxtFree(ret);
 9932:         return (NULL);
 9933:     }
 9934:     ret->dict = dict;
 9935:     xmlDictReference(dict);
 9936:     return(ret);
 9937: }
 9938: 
 9939: static xmlSchemaParserCtxtPtr
 9940: xmlSchemaParserCtxtCreate(void)
 9941: {
 9942:     xmlSchemaParserCtxtPtr ret;
 9943: 
 9944:     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
 9945:     if (ret == NULL) {
 9946:         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
 9947:                             NULL);
 9948:         return (NULL);
 9949:     }
 9950:     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
 9951:     ret->type = XML_SCHEMA_CTXT_PARSER;
 9952:     ret->attrProhibs = xmlSchemaItemListCreate();
 9953:     if (ret->attrProhibs == NULL) {
 9954: 	xmlFree(ret);
 9955: 	return(NULL);
 9956:     }
 9957:     return(ret);
 9958: }
 9959: 
 9960: /**
 9961:  * xmlSchemaNewParserCtxtUseDict:
 9962:  * @URL:  the location of the schema
 9963:  * @dict: the dictionary to be used
 9964:  *
 9965:  * Create an XML Schemas parse context for that file/resource expected
 9966:  * to contain an XML Schemas file.
 9967:  *
 9968:  * Returns the parser context or NULL in case of error
 9969:  */
 9970: static xmlSchemaParserCtxtPtr
 9971: xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
 9972: {
 9973:     xmlSchemaParserCtxtPtr ret;
 9974: 
 9975:     ret = xmlSchemaParserCtxtCreate();
 9976:     if (ret == NULL)
 9977:         return (NULL);
 9978:     ret->dict = dict;
 9979:     xmlDictReference(dict);
 9980:     if (URL != NULL)
 9981: 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
 9982:     return (ret);
 9983: }
 9984: 
 9985: static int
 9986: xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
 9987: {
 9988:     if (vctxt->pctxt == NULL) {
 9989:         if (vctxt->schema != NULL)
 9990: 	    vctxt->pctxt =
 9991: 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
 9992: 	else
 9993: 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
 9994: 	if (vctxt->pctxt == NULL) {
 9995: 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
 9996: 		"failed to create a temp. parser context");
 9997: 	    return (-1);
 9998: 	}
 9999: 	/* TODO: Pass user data. */
10000: 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
10001: 	    vctxt->warning, vctxt->errCtxt);
10002: 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
10003: 	    vctxt->errCtxt);
10004:     }
10005:     return (0);
10006: }
10007: 
10008: /**
10009:  * xmlSchemaGetSchemaBucket:
10010:  * @pctxt: the schema parser context
10011:  * @schemaLocation: the URI of the schema document
10012:  *
10013:  * Returns a schema bucket if it was already parsed.
10014:  *
10015:  * Returns a schema bucket if it was already parsed from
10016:  *         @schemaLocation, NULL otherwise.
10017:  */
10018: static xmlSchemaBucketPtr
10019: xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10020: 			    const xmlChar *schemaLocation)
10021: {
10022:     xmlSchemaBucketPtr cur;
10023:     xmlSchemaItemListPtr list;
10024: 
10025:     list = pctxt->constructor->buckets;
10026:     if (list->nbItems == 0)
10027: 	return(NULL);
10028:     else {
10029: 	int i;
10030: 	for (i = 0; i < list->nbItems; i++) {
10031: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10032: 	    /* Pointer comparison! */
10033: 	    if (cur->schemaLocation == schemaLocation)
10034: 		return(cur);
10035: 	}
10036:     }
10037:     return(NULL);
10038: }
10039: 
10040: static xmlSchemaBucketPtr
10041: xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10042: 				     const xmlChar *schemaLocation,
10043: 				     const xmlChar *targetNamespace)
10044: {
10045:     xmlSchemaBucketPtr cur;
10046:     xmlSchemaItemListPtr list;
10047: 
10048:     list = pctxt->constructor->buckets;
10049:     if (list->nbItems == 0)
10050: 	return(NULL);
10051:     else {
10052: 	int i;
10053: 	for (i = 0; i < list->nbItems; i++) {
10054: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10055: 	    /* Pointer comparison! */
10056: 	    if ((cur->origTargetNamespace == NULL) &&
10057: 		(cur->schemaLocation == schemaLocation) &&
10058: 		(cur->targetNamespace == targetNamespace))
10059: 		return(cur);
10060: 	}
10061:     }
10062:     return(NULL);
10063: }
10064: 
10065: 
10066: #define IS_BAD_SCHEMA_DOC(b) \
10067:     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10068: 
10069: static xmlSchemaBucketPtr
10070: xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10071: 				 const xmlChar *targetNamespace,
10072: 				 int imported)
10073: {
10074:     xmlSchemaBucketPtr cur;
10075:     xmlSchemaItemListPtr list;
10076: 
10077:     list = pctxt->constructor->buckets;
10078:     if (list->nbItems == 0)
10079: 	return(NULL);
10080:     else {
10081: 	int i;
10082: 	for (i = 0; i < list->nbItems; i++) {
10083: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10084: 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10085: 		(cur->origTargetNamespace == targetNamespace) &&
10086: 		((imported && cur->imported) ||
10087: 		 ((!imported) && (!cur->imported))))
10088: 		return(cur);
10089: 	}
10090:     }
10091:     return(NULL);
10092: }
10093: 
10094: static int
10095: xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10096: 		     xmlSchemaPtr schema,
10097: 		     xmlSchemaBucketPtr bucket)
10098: {
10099:     int oldFlags;
10100:     xmlDocPtr oldDoc;
10101:     xmlNodePtr node;
10102:     int ret, oldErrs;
10103:     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10104: 
10105:     /*
10106:     * Save old values; reset the *main* schema.
10107:     * URGENT TODO: This is not good; move the per-document information
10108:     * to the parser. Get rid of passing the main schema to the
10109:     * parsing functions.
10110:     */
10111:     oldFlags = schema->flags;
10112:     oldDoc = schema->doc;
10113:     if (schema->flags != 0)
10114: 	xmlSchemaClearSchemaDefaults(schema);
10115:     schema->doc = bucket->doc;
10116:     pctxt->schema = schema;
10117:     /*
10118:     * Keep the current target namespace on the parser *not* on the
10119:     * main schema.
10120:     */
10121:     pctxt->targetNamespace = bucket->targetNamespace;
10122:     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10123: 
10124:     if ((bucket->targetNamespace != NULL) &&
10125: 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10126: 	/*
10127: 	* We are parsing the schema for schemas!
10128: 	*/
10129: 	pctxt->isS4S = 1;
10130:     }
10131:     /* Mark it as parsed, even if parsing fails. */
10132:     bucket->parsed++;
10133:     /* Compile the schema doc. */
10134:     node = xmlDocGetRootElement(bucket->doc);
10135:     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10136:     if (ret != 0)
10137: 	goto exit;
10138:     /* An empty schema; just get out. */
10139:     if (node->children == NULL)
10140: 	goto exit;
10141:     oldErrs = pctxt->nberrors;
10142:     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10143:     if (ret != 0)
10144: 	goto exit;
10145:     /*
10146:     * TODO: Not nice, but I'm not 100% sure we will get always an error
10147:     * as a result of the obove functions; so better rely on pctxt->err
10148:     * as well.
10149:     */
10150:     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10151: 	ret = pctxt->err;
10152: 	goto exit;
10153:     }
10154: 
10155: exit:
10156:     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10157:     /* Restore schema values. */
10158:     schema->doc = oldDoc;
10159:     schema->flags = oldFlags;
10160:     return(ret);
10161: }
10162: 
10163: static int
10164: xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10165: 		     xmlSchemaPtr schema,
10166: 		     xmlSchemaBucketPtr bucket)
10167: {
10168:     xmlSchemaParserCtxtPtr newpctxt;
10169:     int res = 0;
10170: 
10171:     if (bucket == NULL)
10172: 	return(0);
10173:     if (bucket->parsed) {
10174: 	PERROR_INT("xmlSchemaParseNewDoc",
10175: 	    "reparsing a schema doc");
10176: 	return(-1);
10177:     }
10178:     if (bucket->doc == NULL) {
10179: 	PERROR_INT("xmlSchemaParseNewDoc",
10180: 	    "parsing a schema doc, but there's no doc");
10181: 	return(-1);
10182:     }
10183:     if (pctxt->constructor == NULL) {
10184: 	PERROR_INT("xmlSchemaParseNewDoc",
10185: 	    "no constructor");
10186: 	return(-1);
10187:     }
10188:     /* Create and init the temporary parser context. */
10189:     newpctxt = xmlSchemaNewParserCtxtUseDict(
10190: 	(const char *) bucket->schemaLocation, pctxt->dict);
10191:     if (newpctxt == NULL)
10192: 	return(-1);
10193:     newpctxt->constructor = pctxt->constructor;
10194:     /*
10195:     * TODO: Can we avoid that the parser knows about the main schema?
10196:     * It would be better if he knows about the current schema bucket
10197:     * only.
10198:     */
10199:     newpctxt->schema = schema;
10200:     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10201: 	pctxt->errCtxt);
10202:     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10203: 	pctxt->errCtxt);
10204:     newpctxt->counter = pctxt->counter;
10205: 
10206: 
10207:     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10208: 
10209:     /* Channel back errors and cleanup the temporary parser context. */
10210:     if (res != 0)
10211: 	pctxt->err = res;
10212:     pctxt->nberrors += newpctxt->nberrors;
10213:     pctxt->counter = newpctxt->counter;
10214:     newpctxt->constructor = NULL;
10215:     /* Free the parser context. */
10216:     xmlSchemaFreeParserCtxt(newpctxt);
10217:     return(res);
10218: }
10219: 
10220: static void
10221: xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10222: 				xmlSchemaSchemaRelationPtr rel)
10223: {
10224:     xmlSchemaSchemaRelationPtr cur = bucket->relations;
10225: 
10226:     if (cur == NULL) {
10227: 	bucket->relations = rel;
10228: 	return;
10229:     }
10230:     while (cur->next != NULL)
10231: 	cur = cur->next;
10232:     cur->next = rel;
10233: }
10234: 
10235: 
10236: static const xmlChar *
10237: xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10238: 			  xmlNodePtr ctxtNode)
10239: {
10240:     /*
10241:     * Build an absolue location URI.
10242:     */
10243:     if (location != NULL) {
10244: 	if (ctxtNode == NULL)
10245: 	    return(location);
10246: 	else {
10247: 	    xmlChar *base, *URI;
10248: 	    const xmlChar *ret = NULL;
10249: 
10250: 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10251: 	    if (base == NULL) {
10252: 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
10253: 	    } else {
10254: 		URI = xmlBuildURI(location, base);
10255: 		xmlFree(base);
10256: 	    }
10257: 	    if (URI != NULL) {
10258: 		ret = xmlDictLookup(dict, URI, -1);
10259: 		xmlFree(URI);
10260: 		return(ret);
10261: 	    }
10262: 	}
10263:     }
10264:     return(NULL);
10265: }
10266: 
10267: 
10268: 
10269: /**
10270:  * xmlSchemaAddSchemaDoc:
10271:  * @pctxt:  a schema validation context
10272:  * @schema:  the schema being built
10273:  * @node:  a subtree containing XML Schema informations
10274:  *
10275:  * Parse an included (and to-be-redefined) XML schema document.
10276:  *
10277:  * Returns 0 on success, a positive error code on errors and
10278:  *         -1 in case of an internal or API error.
10279:  */
10280: 
10281: static int
10282: xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10283: 		int type, /* import or include or redefine */
10284: 		const xmlChar *schemaLocation,
10285: 		xmlDocPtr schemaDoc,
10286: 		const char *schemaBuffer,
10287: 		int schemaBufferLen,
10288: 		xmlNodePtr invokingNode,
10289: 		const xmlChar *sourceTargetNamespace,
10290: 		const xmlChar *importNamespace,
10291: 		xmlSchemaBucketPtr *bucket)
10292: {
10293:     const xmlChar *targetNamespace = NULL;
10294:     xmlSchemaSchemaRelationPtr relation = NULL;
10295:     xmlDocPtr doc = NULL;
10296:     int res = 0, err = 0, located = 0, preserveDoc = 0;
10297:     xmlSchemaBucketPtr bkt = NULL;
10298: 
10299:     if (bucket != NULL)
10300: 	*bucket = NULL;
10301: 
10302:     switch (type) {
10303: 	case XML_SCHEMA_SCHEMA_IMPORT:
10304: 	case XML_SCHEMA_SCHEMA_MAIN:
10305: 	    err = XML_SCHEMAP_SRC_IMPORT;
10306: 	    break;
10307: 	case XML_SCHEMA_SCHEMA_INCLUDE:
10308: 	    err = XML_SCHEMAP_SRC_INCLUDE;
10309: 	    break;
10310: 	case XML_SCHEMA_SCHEMA_REDEFINE:
10311: 	    err = XML_SCHEMAP_SRC_REDEFINE;
10312: 	    break;
10313:     }
10314: 
10315: 
10316:     /* Special handling for the main schema:
10317:     * skip the location and relation logic and just parse the doc.
10318:     * We need just a bucket to be returned in this case.
10319:     */
10320:     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10321: 	goto doc_load;
10322: 
10323:     /* Note that we expect the location to be an absulute URI. */
10324:     if (schemaLocation != NULL) {
10325: 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10326: 	if ((bkt != NULL) &&
10327: 	    (pctxt->constructor->bucket == bkt)) {
10328: 	    /* Report self-imports/inclusions/redefinitions. */
10329: 
10330: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10331: 		invokingNode, NULL,
10332: 		"The schema must not import/include/redefine itself",
10333: 		NULL, NULL);
10334: 	    goto exit;
10335: 	}
10336:     }
10337:     /*
10338:     * Create a relation for the graph of schemas.
10339:     */
10340:     relation = xmlSchemaSchemaRelationCreate();
10341:     if (relation == NULL)
10342: 	return(-1);
10343:     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10344: 	relation);
10345:     relation->type = type;
10346: 
10347:     /*
10348:     * Save the namespace import information.
10349:     */
10350:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
10351: 	relation->importNamespace = importNamespace;
10352: 	if (schemaLocation == NULL) {
10353: 	    /*
10354: 	    * No location; this is just an import of the namespace.
10355: 	    * Note that we don't assign a bucket to the relation
10356: 	    * in this case.
10357: 	    */
10358: 	    goto exit;
10359: 	}
10360: 	targetNamespace = importNamespace;
10361:     }
10362: 
10363:     /* Did we already fetch the doc? */
10364:     if (bkt != NULL) {
10365: 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10366: 	    /*
10367: 	    * We included/redefined and then try to import a schema,
10368: 	    * but the new location provided for import was different.
10369: 	    */
10370: 	    if (schemaLocation == NULL)
10371: 		schemaLocation = BAD_CAST "in_memory_buffer";
10372: 	    if (!xmlStrEqual(schemaLocation,
10373: 		bkt->schemaLocation)) {
10374: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10375: 		    invokingNode, NULL,
10376: 		    "The schema document '%s' cannot be imported, since "
10377: 		    "it was already included or redefined",
10378: 		    schemaLocation, NULL);
10379: 		goto exit;
10380: 	    }
10381: 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10382: 	    /*
10383: 	    * We imported and then try to include/redefine a schema,
10384: 	    * but the new location provided for the include/redefine
10385: 	    * was different.
10386: 	    */
10387: 	    if (schemaLocation == NULL)
10388: 		schemaLocation = BAD_CAST "in_memory_buffer";
10389: 	    if (!xmlStrEqual(schemaLocation,
10390: 		bkt->schemaLocation)) {
10391: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10392: 		    invokingNode, NULL,
10393: 		    "The schema document '%s' cannot be included or "
10394: 		    "redefined, since it was already imported",
10395: 		    schemaLocation, NULL);
10396: 		goto exit;
10397: 	    }
10398: 	}
10399:     }
10400: 
10401:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
10402: 	/*
10403: 	* Given that the schemaLocation [attribute] is only a hint, it is open
10404: 	* to applications to ignore all but the first <import> for a given
10405: 	* namespace, regardless of the �actual value� of schemaLocation, but
10406: 	* such a strategy risks missing useful information when new
10407: 	* schemaLocations are offered.
10408: 	*
10409: 	* We will use the first <import> that comes with a location.
10410: 	* Further <import>s *with* a location, will result in an error.
10411: 	* TODO: Better would be to just report a warning here, but
10412: 	* we'll try it this way until someone complains.
10413: 	*
10414: 	* Schema Document Location Strategy:
10415: 	* 3 Based on the namespace name, identify an existing schema document,
10416: 	* either as a resource which is an XML document or a <schema> element
10417: 	* information item, in some local schema repository;
10418: 	* 5 Attempt to resolve the namespace name to locate such a resource.
10419: 	*
10420: 	* NOTE: (3) and (5) are not supported.
10421: 	*/
10422: 	if (bkt != NULL) {
10423: 	    relation->bucket = bkt;
10424: 	    goto exit;
10425: 	}
10426: 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10427: 	    importNamespace, 1);
10428: 
10429: 	if (bkt != NULL) {
10430: 	    relation->bucket = bkt;
10431: 	    if (bkt->schemaLocation == NULL) {
10432: 		/* First given location of the schema; load the doc. */
10433: 		bkt->schemaLocation = schemaLocation;
10434: 	    } else {
10435: 		if (!xmlStrEqual(schemaLocation,
10436: 		    bkt->schemaLocation)) {
10437: 		    /*
10438: 		    * Additional location given; just skip it.
10439: 		    * URGENT TODO: We should report a warning here.
10440: 		    * res = XML_SCHEMAP_SRC_IMPORT;
10441: 		    */
10442: 		    if (schemaLocation == NULL)
10443: 			schemaLocation = BAD_CAST "in_memory_buffer";
10444: 
10445: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10446: 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
10447: 			invokingNode, NULL,
10448: 			"Skipping import of schema located at '%s' for the "
10449: 			"namespace '%s', since this namespace was already "
10450: 			"imported with the schema located at '%s'",
10451: 			schemaLocation, importNamespace, bkt->schemaLocation);
10452: 		}
10453: 		goto exit;
10454: 	    }
10455: 	}
10456: 	/*
10457: 	* No bucket + first location: load the doc and create a
10458: 	* bucket.
10459: 	*/
10460:     } else {
10461: 	/* <include> and <redefine> */
10462: 	if (bkt != NULL) {
10463: 
10464: 	    if ((bkt->origTargetNamespace == NULL) &&
10465: 		(bkt->targetNamespace != sourceTargetNamespace)) {
10466: 		xmlSchemaBucketPtr chamel;
10467: 
10468: 		/*
10469: 		* Chameleon include/redefine: skip loading only if it was
10470: 		* aleady build for the targetNamespace of the including
10471: 		* schema.
10472: 		*/
10473: 		/*
10474: 		* URGENT TODO: If the schema is a chameleon-include then copy
10475: 		* the components into the including schema and modify the
10476: 		* targetNamespace of those components, do nothing otherwise.
10477: 		* NOTE: This is currently worked-around by compiling the
10478: 		* chameleon for every destinct including targetNamespace; thus
10479: 		* not performant at the moment.
10480: 		* TODO: Check when the namespace in wildcards for chameleons
10481: 		* needs to be converted: before we built wildcard intersections
10482: 		* or after.
10483: 		*   Answer: after!
10484: 		*/
10485: 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10486: 		    schemaLocation, sourceTargetNamespace);
10487: 		if (chamel != NULL) {
10488: 		    /* A fitting chameleon was already parsed; NOP. */
10489: 		    relation->bucket = chamel;
10490: 		    goto exit;
10491: 		}
10492: 		/*
10493: 		* We need to parse the chameleon again for a different
10494: 		* targetNamespace.
10495: 		* CHAMELEON TODO: Optimize this by only parsing the
10496: 		* chameleon once, and then copying the components to
10497: 		* the new targetNamespace.
10498: 		*/
10499: 		bkt = NULL;
10500: 	    } else {
10501: 		relation->bucket = bkt;
10502: 		goto exit;
10503: 	    }
10504: 	}
10505:     }
10506:     if ((bkt != NULL) && (bkt->doc != NULL)) {
10507: 	PERROR_INT("xmlSchemaAddSchemaDoc",
10508: 	    "trying to load a schema doc, but a doc is already "
10509: 	    "assigned to the schema bucket");
10510: 	goto exit_failure;
10511:     }
10512: 
10513: doc_load:
10514:     /*
10515:     * Load the document.
10516:     */
10517:     if (schemaDoc != NULL) {
10518: 	doc = schemaDoc;
10519: 	/* Don' free this one, since it was provided by the caller. */
10520: 	preserveDoc = 1;
10521: 	/* TODO: Does the context or the doc hold the location? */
10522: 	if (schemaDoc->URL != NULL)
10523: 	    schemaLocation = xmlDictLookup(pctxt->dict,
10524: 		schemaDoc->URL, -1);
10525:         else
10526: 	    schemaLocation = BAD_CAST "in_memory_buffer";
10527:     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10528: 	xmlParserCtxtPtr parserCtxt;
10529: 
10530: 	parserCtxt = xmlNewParserCtxt();
10531: 	if (parserCtxt == NULL) {
10532: 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10533: 		"allocating a parser context", NULL);
10534: 	    goto exit_failure;
10535: 	}
10536: 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10537: 	    /*
10538: 	    * TODO: Do we have to burden the schema parser dict with all
10539: 	    * the content of the schema doc?
10540: 	    */
10541: 	    xmlDictFree(parserCtxt->dict);
10542: 	    parserCtxt->dict = pctxt->dict;
10543: 	    xmlDictReference(parserCtxt->dict);
10544: 	}
10545: 	if (schemaLocation != NULL) {
10546: 	    /* Parse from file. */
10547: 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10548: 		NULL, SCHEMAS_PARSE_OPTIONS);
10549: 	} else if (schemaBuffer != NULL) {
10550: 	    /* Parse from memory buffer. */
10551: 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10552: 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10553: 	    schemaLocation = BAD_CAST "in_memory_buffer";
10554: 	    if (doc != NULL)
10555: 		doc->URL = xmlStrdup(schemaLocation);
10556: 	}
10557: 	/*
10558: 	* For <import>:
10559: 	* 2.1 The referent is (a fragment of) a resource which is an
10560: 	* XML document (see clause 1.1), which in turn corresponds to
10561: 	* a <schema> element information item in a well-formed information
10562: 	* set, which in turn corresponds to a valid schema.
10563: 	* TODO: (2.1) fragments of XML documents are not supported.
10564: 	*
10565: 	* 2.2 The referent is a <schema> element information item in
10566: 	* a well-formed information set, which in turn corresponds
10567: 	* to a valid schema.
10568: 	* TODO: (2.2) is not supported.
10569: 	*/
10570: 	if (doc == NULL) {
10571: 	    xmlErrorPtr lerr;
10572: 	    lerr = xmlGetLastError();
10573: 	    /*
10574: 	    * Check if this a parser error, or if the document could
10575: 	    * just not be located.
10576: 	    * TODO: Try to find specific error codes to react only on
10577: 	    * localisation failures.
10578: 	    */
10579: 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10580: 		/*
10581: 		* We assume a parser error here.
10582: 		*/
10583: 		located = 1;
10584: 		/* TODO: Error code ?? */
10585: 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
10586: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10587: 		    invokingNode, NULL,
10588: 		    "Failed to parse the XML resource '%s'",
10589: 		    schemaLocation, NULL);
10590: 	    }
10591: 	}
10592: 	xmlFreeParserCtxt(parserCtxt);
10593: 	if ((doc == NULL) && located)
10594: 	    goto exit_error;
10595:     } else {
10596: 	xmlSchemaPErr(pctxt, NULL,
10597: 	    XML_SCHEMAP_NOTHING_TO_PARSE,
10598: 	    "No information for parsing was provided with the "
10599: 	    "given schema parser context.\n",
10600: 	    NULL, NULL);
10601: 	goto exit_failure;
10602:     }
10603:     /*
10604:     * Preprocess the document.
10605:     */
10606:     if (doc != NULL) {
10607: 	xmlNodePtr docElem = NULL;
10608: 
10609: 	located = 1;
10610: 	docElem = xmlDocGetRootElement(doc);
10611: 	if (docElem == NULL) {
10612: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10613: 		invokingNode, NULL,
10614: 		"The document '%s' has no document element",
10615: 		schemaLocation, NULL);
10616: 	    goto exit_error;
10617: 	}
10618: 	/*
10619: 	* Remove all the blank text nodes.
10620: 	*/
10621: 	xmlSchemaCleanupDoc(pctxt, docElem);
10622: 	/*
10623: 	* Check the schema's top level element.
10624: 	*/
10625: 	if (!IS_SCHEMA(docElem, "schema")) {
10626: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10627: 		invokingNode, NULL,
10628: 		"The XML document '%s' is not a schema document",
10629: 		schemaLocation, NULL);
10630: 	    goto exit_error;
10631: 	}
10632: 	/*
10633: 	* Note that we don't apply a type check for the
10634: 	* targetNamespace value here.
10635: 	*/
10636: 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10637: 	    "targetNamespace");
10638:     }
10639: 
10640: /* after_doc_loading: */
10641:     if ((bkt == NULL) && located) {
10642: 	/* Only create a bucket if the schema was located. */
10643:         bkt = xmlSchemaBucketCreate(pctxt, type,
10644: 	    targetNamespace);
10645: 	if (bkt == NULL)
10646: 	    goto exit_failure;
10647:     }
10648:     if (bkt != NULL) {
10649: 	bkt->schemaLocation = schemaLocation;
10650: 	bkt->located = located;
10651: 	if (doc != NULL) {
10652: 	    bkt->doc = doc;
10653: 	    bkt->targetNamespace = targetNamespace;
10654: 	    bkt->origTargetNamespace = targetNamespace;
10655: 	    if (preserveDoc)
10656: 		bkt->preserveDoc = 1;
10657: 	}
10658: 	if (WXS_IS_BUCKET_IMPMAIN(type))
10659: 	    bkt->imported++;
10660: 	    /*
10661: 	    * Add it to the graph of schemas.
10662: 	    */
10663: 	if (relation != NULL)
10664: 	    relation->bucket = bkt;
10665:     }
10666: 
10667: exit:
10668:     /*
10669:     * Return the bucket explicitely; this is needed for the
10670:     * main schema.
10671:     */
10672:     if (bucket != NULL)
10673: 	*bucket = bkt;
10674:     return (0);
10675: 
10676: exit_error:
10677:     if ((doc != NULL) && (! preserveDoc)) {
10678: 	xmlFreeDoc(doc);
10679: 	if (bkt != NULL)
10680: 	    bkt->doc = NULL;
10681:     }
10682:     return(pctxt->err);
10683: 
10684: exit_failure:
10685:     if ((doc != NULL) && (! preserveDoc)) {
10686: 	xmlFreeDoc(doc);
10687: 	if (bkt != NULL)
10688: 	    bkt->doc = NULL;
10689:     }
10690:     return (-1);
10691: }
10692: 
10693: /**
10694:  * xmlSchemaParseImport:
10695:  * @ctxt:  a schema validation context
10696:  * @schema:  the schema being built
10697:  * @node:  a subtree containing XML Schema informations
10698:  *
10699:  * parse a XML schema Import definition
10700:  * *WARNING* this interface is highly subject to change
10701:  *
10702:  * Returns 0 in case of success, a positive error code if
10703:  * not valid and -1 in case of an internal error.
10704:  */
10705: static int
10706: xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10707:                      xmlNodePtr node)
10708: {
10709:     xmlNodePtr child;
10710:     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10711:     const xmlChar *thisTargetNamespace;
10712:     xmlAttrPtr attr;
10713:     int ret = 0;
10714:     xmlSchemaBucketPtr bucket = NULL;
10715: 
10716:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10717:         return (-1);
10718: 
10719:     /*
10720:     * Check for illegal attributes.
10721:     */
10722:     attr = node->properties;
10723:     while (attr != NULL) {
10724: 	if (attr->ns == NULL) {
10725: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10726: 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10727: 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10728: 		xmlSchemaPIllegalAttrErr(pctxt,
10729: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10730: 	    }
10731: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10732: 	    xmlSchemaPIllegalAttrErr(pctxt,
10733: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10734: 	}
10735: 	attr = attr->next;
10736:     }
10737:     /*
10738:     * Extract and validate attributes.
10739:     */
10740:     if (xmlSchemaPValAttr(pctxt, NULL, node,
10741: 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10742: 	&namespaceName) != 0) {
10743: 	xmlSchemaPSimpleTypeErr(pctxt,
10744: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10745: 	    NULL, node,
10746: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10747: 	    NULL, namespaceName, NULL, NULL, NULL);
10748: 	return (pctxt->err);
10749:     }
10750: 
10751:     if (xmlSchemaPValAttr(pctxt, NULL, node,
10752: 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10753: 	&schemaLocation) != 0) {
10754: 	xmlSchemaPSimpleTypeErr(pctxt,
10755: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10756: 	    NULL, node,
10757: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10758: 	    NULL, namespaceName, NULL, NULL, NULL);
10759: 	return (pctxt->err);
10760:     }
10761:     /*
10762:     * And now for the children...
10763:     */
10764:     child = node->children;
10765:     if (IS_SCHEMA(child, "annotation")) {
10766:         /*
10767:          * the annotation here is simply discarded ...
10768: 	 * TODO: really?
10769:          */
10770:         child = child->next;
10771:     }
10772:     if (child != NULL) {
10773: 	xmlSchemaPContentErr(pctxt,
10774: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10775: 	    NULL, node, child, NULL,
10776: 	    "(annotation?)");
10777:     }
10778:     /*
10779:     * Apply additional constraints.
10780:     *
10781:     * Note that it is important to use the original @targetNamespace
10782:     * (or none at all), to rule out imports of schemas _with_ a
10783:     * @targetNamespace if the importing schema is a chameleon schema
10784:     * (with no @targetNamespace).
10785:     */
10786:     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10787:     if (namespaceName != NULL) {
10788: 	/*
10789: 	* 1.1 If the namespace [attribute] is present, then its �actual value�
10790: 	* must not match the �actual value� of the enclosing <schema>'s
10791: 	* targetNamespace [attribute].
10792: 	*/
10793: 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10794: 	    xmlSchemaPCustomErr(pctxt,
10795: 		XML_SCHEMAP_SRC_IMPORT_1_1,
10796: 		NULL, node,
10797: 		"The value of the attribute 'namespace' must not match "
10798: 		"the target namespace '%s' of the importing schema",
10799: 		thisTargetNamespace);
10800: 	    return (pctxt->err);
10801: 	}
10802:     } else {
10803: 	/*
10804: 	* 1.2 If the namespace [attribute] is not present, then the enclosing
10805: 	* <schema> must have a targetNamespace [attribute].
10806: 	*/
10807: 	if (thisTargetNamespace == NULL) {
10808: 	    xmlSchemaPCustomErr(pctxt,
10809: 		XML_SCHEMAP_SRC_IMPORT_1_2,
10810: 		NULL, node,
10811: 		"The attribute 'namespace' must be existent if "
10812: 		"the importing schema has no target namespace",
10813: 		NULL);
10814: 	    return (pctxt->err);
10815: 	}
10816:     }
10817:     /*
10818:     * Locate and acquire the schema document.
10819:     */
10820:     if (schemaLocation != NULL)
10821: 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10822: 	    schemaLocation, node);
10823:     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10824: 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10825: 	namespaceName, &bucket);
10826: 
10827:     if (ret != 0)
10828: 	return(ret);
10829: 
10830:     /*
10831:     * For <import>: "It is *not* an error for the application
10832:     * schema reference strategy to fail."
10833:     * So just don't parse if no schema document was found.
10834:     * Note that we will get no bucket if the schema could not be
10835:     * located or if there was no schemaLocation.
10836:     */
10837:     if ((bucket == NULL) && (schemaLocation != NULL)) {
10838: 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10839: 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10840: 	    node, NULL,
10841: 	    "Failed to locate a schema at location '%s'. "
10842: 	    "Skipping the import", schemaLocation, NULL, NULL);
10843:     }
10844: 
10845:     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10846: 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10847:     }
10848: 
10849:     return (ret);
10850: }
10851: 
10852: static int
10853: xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10854: 				     xmlSchemaPtr schema,
10855: 				     xmlNodePtr node,
10856: 				     xmlChar **schemaLocation,
10857: 				     int type)
10858: {
10859:     xmlAttrPtr attr;
10860: 
10861:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10862: 	(schemaLocation == NULL))
10863:         return (-1);
10864: 
10865:     *schemaLocation = NULL;
10866:     /*
10867:     * Check for illegal attributes.
10868:     * Applies for both <include> and <redefine>.
10869:     */
10870:     attr = node->properties;
10871:     while (attr != NULL) {
10872: 	if (attr->ns == NULL) {
10873: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10874: 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10875: 		xmlSchemaPIllegalAttrErr(pctxt,
10876: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10877: 	    }
10878: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10879: 	    xmlSchemaPIllegalAttrErr(pctxt,
10880: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10881: 	}
10882: 	attr = attr->next;
10883:     }
10884:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10885:     /*
10886:     * Preliminary step, extract the URI-Reference and make an URI
10887:     * from the base.
10888:     */
10889:     /*
10890:     * Attribute "schemaLocation" is mandatory.
10891:     */
10892:     attr = xmlSchemaGetPropNode(node, "schemaLocation");
10893:     if (attr != NULL) {
10894:         xmlChar *base = NULL;
10895:         xmlChar *uri = NULL;
10896: 
10897: 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10898: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10899: 	    (const xmlChar **) schemaLocation) != 0)
10900: 	    goto exit_error;
10901: 	base = xmlNodeGetBase(node->doc, node);
10902: 	if (base == NULL) {
10903: 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10904: 	} else {
10905: 	    uri = xmlBuildURI(*schemaLocation, base);
10906: 	    xmlFree(base);
10907: 	}
10908: 	if (uri == NULL) {
10909: 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10910: 		"could not build an URI from the schemaLocation")
10911: 	    goto exit_failure;
10912: 	}
10913: 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10914: 	xmlFree(uri);
10915:     } else {
10916: 	xmlSchemaPMissingAttrErr(pctxt,
10917: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
10918: 	    NULL, node, "schemaLocation", NULL);
10919: 	goto exit_error;
10920:     }
10921:     /*
10922:     * Report self-inclusion and self-redefinition.
10923:     */
10924:     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10925: 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10926: 	    xmlSchemaPCustomErr(pctxt,
10927: 		XML_SCHEMAP_SRC_REDEFINE,
10928: 		NULL, node,
10929: 		"The schema document '%s' cannot redefine itself.",
10930: 		*schemaLocation);
10931: 	} else {
10932: 	    xmlSchemaPCustomErr(pctxt,
10933: 		XML_SCHEMAP_SRC_INCLUDE,
10934: 		NULL, node,
10935: 		"The schema document '%s' cannot include itself.",
10936: 		*schemaLocation);
10937: 	}
10938: 	goto exit_error;
10939:     }
10940: 
10941:     return(0);
10942: exit_error:
10943:     return(pctxt->err);
10944: exit_failure:
10945:     return(-1);
10946: }
10947: 
10948: static int
10949: xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10950: 				xmlSchemaPtr schema,
10951: 				xmlNodePtr node,
10952: 				int type)
10953: {
10954:     xmlNodePtr child = NULL;
10955:     const xmlChar *schemaLocation = NULL;
10956:     int res = 0; /* hasRedefinitions = 0 */
10957:     int isChameleon = 0, wasChameleon = 0;
10958:     xmlSchemaBucketPtr bucket = NULL;
10959: 
10960:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10961:         return (-1);
10962: 
10963:     /*
10964:     * Parse attributes. Note that the returned schemaLocation will
10965:     * be already converted to an absolute URI.
10966:     */
10967:     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10968: 	node, (xmlChar **) (&schemaLocation), type);
10969:     if (res != 0)
10970: 	return(res);
10971:     /*
10972:     * Load and add the schema document.
10973:     */
10974:     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10975: 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10976:     if (res != 0)
10977: 	return(res);
10978:     /*
10979:     * If we get no schema bucket back, then this means that the schema
10980:     * document could not be located or was broken XML or was not
10981:     * a schema document.
10982:     */
10983:     if ((bucket == NULL) || (bucket->doc == NULL)) {
10984: 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10985: 	    /*
10986: 	    * WARNING for <include>:
10987: 	    * We will raise an error if the schema cannot be located
10988: 	    * for inclusions, since the that was the feedback from the
10989: 	    * schema people. I.e. the following spec piece will *not* be
10990: 	    * satisfied:
10991: 	    * SPEC src-include: "It is not an error for the �actual value� of the
10992: 	    * schemaLocation [attribute] to fail to resolve it all, in which
10993: 	    * case no corresponding inclusion is performed.
10994: 	    * So do we need a warning report here?"
10995: 	    */
10996: 	    res = XML_SCHEMAP_SRC_INCLUDE;
10997: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10998: 		node, NULL,
10999: 		"Failed to load the document '%s' for inclusion",
11000: 		schemaLocation, NULL);
11001: 	} else {
11002: 	    /*
11003: 	    * NOTE: This was changed to raise an error even if no redefinitions
11004: 	    * are specified.
11005: 	    *
11006: 	    * SPEC src-redefine (1)
11007: 	    * "If there are any element information items among the [children]
11008: 	    * other than <annotation> then the �actual value� of the
11009: 	    * schemaLocation [attribute] must successfully resolve."
11010: 	    * TODO: Ask the WG if a the location has always to resolve
11011: 	    * here as well!
11012: 	    */
11013: 	    res = XML_SCHEMAP_SRC_REDEFINE;
11014: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
11015: 		node, NULL,
11016: 		"Failed to load the document '%s' for redefinition",
11017: 		schemaLocation, NULL);
11018: 	}
11019:     } else {
11020: 	/*
11021: 	* Check targetNamespace sanity before parsing the new schema.
11022: 	* TODO: Note that we won't check further content if the
11023: 	* targetNamespace was bad.
11024: 	*/
11025: 	if (bucket->origTargetNamespace != NULL) {
11026: 	    /*
11027: 	    * SPEC src-include (2.1)
11028: 	    * "SII has a targetNamespace [attribute], and its �actual
11029: 	    * value� is identical to the �actual value� of the targetNamespace
11030: 	    * [attribute] of SII� (which must have such an [attribute])."
11031: 	    */
11032: 	    if (pctxt->targetNamespace == NULL) {
11033: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
11034: 		    XML_SCHEMAP_SRC_INCLUDE,
11035: 		    node, NULL,
11036: 		    "The target namespace of the included/redefined schema "
11037: 		    "'%s' has to be absent, since the including/redefining "
11038: 		    "schema has no target namespace",
11039: 		    schemaLocation, NULL);
11040: 		goto exit_error;
11041: 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
11042: 		pctxt->targetNamespace)) {
11043: 		/* TODO: Change error function. */
11044: 		xmlSchemaPCustomErrExt(pctxt,
11045: 		    XML_SCHEMAP_SRC_INCLUDE,
11046: 		    NULL, node,
11047: 		    "The target namespace '%s' of the included/redefined "
11048: 		    "schema '%s' differs from '%s' of the "
11049: 		    "including/redefining schema",
11050: 		    bucket->origTargetNamespace, schemaLocation,
11051: 		    pctxt->targetNamespace);
11052: 		goto exit_error;
11053: 	    }
11054: 	} else if (pctxt->targetNamespace != NULL) {
11055: 	    /*
11056: 	    * Chameleons: the original target namespace will
11057: 	    * differ from the resulting namespace.
11058: 	    */
11059: 	    isChameleon = 1;
11060: 	    if (bucket->parsed &&
11061: 		bucket->origTargetNamespace != NULL) {
11062: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
11063: 		    XML_SCHEMAP_SRC_INCLUDE,
11064: 		    node, NULL,
11065: 		    "The target namespace of the included/redefined schema "
11066: 		    "'%s' has to be absent or the same as the "
11067: 		    "including/redefining schema's target namespace",
11068: 		    schemaLocation, NULL);
11069: 		goto exit_error;
11070: 	    }
11071: 	    bucket->targetNamespace = pctxt->targetNamespace;
11072: 	}
11073:     }
11074:     /*
11075:     * Parse the schema.
11076:     */
11077:     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11078: 	if (isChameleon) {
11079: 	    /* TODO: Get rid of this flag on the schema itself. */
11080: 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11081: 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11082: 	    } else
11083: 		wasChameleon = 1;
11084: 	}
11085: 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
11086: 	/* Restore chameleon flag. */
11087: 	if (isChameleon && (!wasChameleon))
11088: 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11089:     }
11090:     /*
11091:     * And now for the children...
11092:     */
11093:     child = node->children;
11094:     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11095: 	/*
11096: 	* Parse (simpleType | complexType | group | attributeGroup))*
11097: 	*/
11098: 	pctxt->redefined = bucket;
11099: 	/*
11100: 	* How to proceed if the redefined schema was not located?
11101: 	*/
11102: 	pctxt->isRedefine = 1;
11103: 	while (IS_SCHEMA(child, "annotation") ||
11104: 	    IS_SCHEMA(child, "simpleType") ||
11105: 	    IS_SCHEMA(child, "complexType") ||
11106: 	    IS_SCHEMA(child, "group") ||
11107: 	    IS_SCHEMA(child, "attributeGroup")) {
11108: 	    if (IS_SCHEMA(child, "annotation")) {
11109: 		/*
11110: 		* TODO: discard or not?
11111: 		*/
11112: 	    } else if (IS_SCHEMA(child, "simpleType")) {
11113: 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11114: 	    } else if (IS_SCHEMA(child, "complexType")) {
11115: 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
11116: 		/* hasRedefinitions = 1; */
11117: 	    } else if (IS_SCHEMA(child, "group")) {
11118: 		/* hasRedefinitions = 1; */
11119: 		xmlSchemaParseModelGroupDefinition(pctxt,
11120: 		    schema, child);
11121: 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
11122: 		/* hasRedefinitions = 1; */
11123: 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11124: 		    child);
11125: 	    }
11126: 	    child = child->next;
11127: 	}
11128: 	pctxt->redefined = NULL;
11129: 	pctxt->isRedefine = 0;
11130:     } else {
11131: 	if (IS_SCHEMA(child, "annotation")) {
11132: 	    /*
11133: 	    * TODO: discard or not?
11134: 	    */
11135: 	    child = child->next;
11136: 	}
11137:     }
11138:     if (child != NULL) {
11139: 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11140: 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11141: 	    xmlSchemaPContentErr(pctxt, res,
11142: 		NULL, node, child, NULL,
11143: 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
11144: 	} else {
11145: 	     xmlSchemaPContentErr(pctxt, res,
11146: 		NULL, node, child, NULL,
11147: 		"(annotation?)");
11148: 	}
11149:     }
11150:     return(res);
11151: 
11152: exit_error:
11153:     return(pctxt->err);
11154: }
11155: 
11156: static int
11157: xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11158:                        xmlNodePtr node)
11159: {
11160:     int res;
11161: #ifndef ENABLE_REDEFINE
11162:     TODO
11163:     return(0);
11164: #endif
11165:     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11166: 	XML_SCHEMA_SCHEMA_REDEFINE);
11167:     if (res != 0)
11168: 	return(res);
11169:     return(0);
11170: }
11171: 
11172: static int
11173: xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11174:                        xmlNodePtr node)
11175: {
11176:     int res;
11177: 
11178:     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11179: 	XML_SCHEMA_SCHEMA_INCLUDE);
11180:     if (res != 0)
11181: 	return(res);
11182:     return(0);
11183: }
11184: 
11185: /**
11186:  * xmlSchemaParseModelGroup:
11187:  * @ctxt:  a schema validation context
11188:  * @schema:  the schema being built
11189:  * @node:  a subtree containing XML Schema informations
11190:  * @type: the "compositor" type
11191:  * @particleNeeded: if a a model group with a particle
11192:  *
11193:  * parse a XML schema Sequence definition.
11194:  * Applies parts of:
11195:  *   Schema Representation Constraint:
11196:  *     Redefinition Constraints and Semantics (src-redefine)
11197:  *     (6.1), (6.1.1), (6.1.2)
11198:  *
11199:  *   Schema Component Constraint:
11200:  *     All Group Limited (cos-all-limited) (2)
11201:  *     TODO: Actually this should go to component-level checks,
11202:  *     but is done here due to performance. Move it to an other layer
11203:  *     is schema construction via an API is implemented.
11204:  *
11205:  * *WARNING* this interface is highly subject to change
11206:  *
11207:  * Returns -1 in case of error, 0 if the declaration is improper and
11208:  *         1 in case of success.
11209:  */
11210: static xmlSchemaTreeItemPtr
11211: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11212: 			 xmlNodePtr node, xmlSchemaTypeType type,
11213: 			 int withParticle)
11214: {
11215:     xmlSchemaModelGroupPtr item;
11216:     xmlSchemaParticlePtr particle = NULL;
11217:     xmlNodePtr child = NULL;
11218:     xmlAttrPtr attr;
11219:     int min = 1, max = 1, isElemRef, hasRefs = 0;
11220: 
11221:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11222:         return (NULL);
11223:     /*
11224:     * Create a model group with the given compositor.
11225:     */
11226:     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11227:     if (item == NULL)
11228: 	return (NULL);
11229: 
11230:     if (withParticle) {
11231: 	if (type == XML_SCHEMA_TYPE_ALL) {
11232: 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11233: 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11234: 	} else {
11235: 	    /* choice + sequence */
11236: 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11237: 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11238: 		"(xs:nonNegativeInteger | unbounded)");
11239: 	}
11240: 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11241: 	/*
11242: 	* Create a particle
11243: 	*/
11244: 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
11245: 	if (particle == NULL)
11246: 	    return (NULL);
11247: 	particle->children = (xmlSchemaTreeItemPtr) item;
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: 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11256: 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11257: 		    xmlSchemaPIllegalAttrErr(ctxt,
11258: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11259: 		}
11260: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11261: 		xmlSchemaPIllegalAttrErr(ctxt,
11262: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11263: 	    }
11264: 	    attr = attr->next;
11265: 	}
11266:     } else {
11267: 	/*
11268: 	* Check for illegal attributes.
11269: 	*/
11270: 	attr = node->properties;
11271: 	while (attr != NULL) {
11272: 	    if (attr->ns == NULL) {
11273: 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11274: 		    xmlSchemaPIllegalAttrErr(ctxt,
11275: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11276: 		}
11277: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11278: 		xmlSchemaPIllegalAttrErr(ctxt,
11279: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11280: 	    }
11281: 	    attr = attr->next;
11282: 	}
11283:     }
11284: 
11285:     /*
11286:     * Extract and validate attributes.
11287:     */
11288:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11289:     /*
11290:     * And now for the children...
11291:     */
11292:     child = node->children;
11293:     if (IS_SCHEMA(child, "annotation")) {
11294:         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11295:         child = child->next;
11296:     }
11297:     if (type == XML_SCHEMA_TYPE_ALL) {
11298: 	xmlSchemaParticlePtr part, last = NULL;
11299: 
11300: 	while (IS_SCHEMA(child, "element")) {
11301: 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11302: 		schema, child, &isElemRef, 0);
11303: 	    /*
11304: 	    * SPEC cos-all-limited (2)
11305: 	    * "The {max occurs} of all the particles in the {particles}
11306: 	    * of the ('all') group must be 0 or 1.
11307: 	    */
11308: 	    if (part != NULL) {
11309: 		if (isElemRef)
11310: 		    hasRefs++;
11311: 		if (part->minOccurs > 1) {
11312: 		    xmlSchemaPCustomErr(ctxt,
11313: 			XML_SCHEMAP_COS_ALL_LIMITED,
11314: 			NULL, child,
11315: 			"Invalid value for minOccurs (must be 0 or 1)",
11316: 			NULL);
11317: 		    /* Reset to 1. */
11318: 		    part->minOccurs = 1;
11319: 		}
11320: 		if (part->maxOccurs > 1) {
11321: 		    xmlSchemaPCustomErr(ctxt,
11322: 			XML_SCHEMAP_COS_ALL_LIMITED,
11323: 			NULL, child,
11324: 			"Invalid value for maxOccurs (must be 0 or 1)",
11325: 			NULL);
11326: 		    /* Reset to 1. */
11327: 		    part->maxOccurs = 1;
11328: 		}
11329: 		if (last == NULL)
11330: 		    item->children = (xmlSchemaTreeItemPtr) part;
11331: 		else
11332: 		    last->next = (xmlSchemaTreeItemPtr) part;
11333: 		last = part;
11334: 	    }
11335: 	    child = child->next;
11336: 	}
11337: 	if (child != NULL) {
11338: 	    xmlSchemaPContentErr(ctxt,
11339: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11340: 		NULL, node, child, NULL,
11341: 		"(annotation?, (annotation?, element*)");
11342: 	}
11343:     } else {
11344: 	/* choice + sequence */
11345: 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
11346: 
11347: 	while ((IS_SCHEMA(child, "element")) ||
11348: 	    (IS_SCHEMA(child, "group")) ||
11349: 	    (IS_SCHEMA(child, "any")) ||
11350: 	    (IS_SCHEMA(child, "choice")) ||
11351: 	    (IS_SCHEMA(child, "sequence"))) {
11352: 
11353: 	    if (IS_SCHEMA(child, "element")) {
11354: 		part = (xmlSchemaTreeItemPtr)
11355: 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11356: 		if (part && isElemRef)
11357: 		    hasRefs++;
11358: 	    } else if (IS_SCHEMA(child, "group")) {
11359: 		part =
11360: 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11361: 		if (part != NULL)
11362: 		    hasRefs++;
11363: 		/*
11364: 		* Handle redefinitions.
11365: 		*/
11366: 		if (ctxt->isRedefine && ctxt->redef &&
11367: 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11368: 		    part && part->children)
11369: 		{
11370: 		    if ((xmlSchemaGetQNameRefName(part->children) ==
11371: 			    ctxt->redef->refName) &&
11372: 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
11373: 			    ctxt->redef->refTargetNs))
11374: 		    {
11375: 			/*
11376: 			* SPEC src-redefine:
11377: 			* (6.1) "If it has a <group> among its contents at
11378: 			* some level the �actual value� of whose ref
11379: 			* [attribute] is the same as the �actual value� of
11380: 			* its own name attribute plus target namespace, then
11381: 			* all of the following must be true:"
11382: 			* (6.1.1) "It must have exactly one such group."
11383: 			*/
11384: 			if (ctxt->redefCounter != 0) {
11385: 			    xmlChar *str = NULL;
11386: 
11387: 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
11388: 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11389: 				"The redefining model group definition "
11390: 				"'%s' must not contain more than one "
11391: 				"reference to the redefined definition",
11392: 				xmlSchemaFormatQName(&str,
11393: 				    ctxt->redef->refTargetNs,
11394: 				    ctxt->redef->refName),
11395: 				NULL);
11396: 			    FREE_AND_NULL(str)
11397: 			    part = NULL;
11398: 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11399: 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
11400: 			{
11401: 			    xmlChar *str = NULL;
11402: 			    /*
11403: 			    * SPEC src-redefine:
11404: 			    * (6.1.2) "The �actual value� of both that
11405: 			    * group's minOccurs and maxOccurs [attribute]
11406: 			    * must be 1 (or �absent�).
11407: 			    */
11408: 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
11409: 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11410: 				"The redefining model group definition "
11411: 				"'%s' must not contain a reference to the "
11412: 				"redefined definition with a "
11413: 				"maxOccurs/minOccurs other than 1",
11414: 				xmlSchemaFormatQName(&str,
11415: 				    ctxt->redef->refTargetNs,
11416: 				    ctxt->redef->refName),
11417: 				NULL);
11418: 			    FREE_AND_NULL(str)
11419: 			    part = NULL;
11420: 			}
11421: 			ctxt->redef->reference = WXS_BASIC_CAST part;
11422: 			ctxt->redefCounter++;
11423: 		    }
11424: 		}
11425: 	    } else if (IS_SCHEMA(child, "any")) {
11426: 		part = (xmlSchemaTreeItemPtr)
11427: 		    xmlSchemaParseAny(ctxt, schema, child);
11428: 	    } else if (IS_SCHEMA(child, "choice")) {
11429: 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
11430: 		    XML_SCHEMA_TYPE_CHOICE, 1);
11431: 	    } else if (IS_SCHEMA(child, "sequence")) {
11432: 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
11433: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
11434: 	    }
11435: 	    if (part != NULL) {
11436: 		if (last == NULL)
11437: 		    item->children = part;
11438: 		else
11439: 		    last->next = part;
11440: 		last = part;
11441: 	    }
11442: 	    child = child->next;
11443: 	}
11444: 	if (child != NULL) {
11445: 	    xmlSchemaPContentErr(ctxt,
11446: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11447: 		NULL, node, child, NULL,
11448: 		"(annotation?, (element | group | choice | sequence | any)*)");
11449: 	}
11450:     }
11451:     if ((max == 0) && (min == 0))
11452: 	return (NULL);
11453:     if (hasRefs) {
11454: 	/*
11455: 	* We need to resolve references.
11456: 	*/
11457: 	WXS_ADD_PENDING(ctxt, item);
11458:     }
11459:     if (withParticle)
11460: 	return ((xmlSchemaTreeItemPtr) particle);
11461:     else
11462: 	return ((xmlSchemaTreeItemPtr) item);
11463: }
11464: 
11465: /**
11466:  * xmlSchemaParseRestriction:
11467:  * @ctxt:  a schema validation context
11468:  * @schema:  the schema being built
11469:  * @node:  a subtree containing XML Schema informations
11470:  *
11471:  * parse a XML schema Restriction definition
11472:  * *WARNING* this interface is highly subject to change
11473:  *
11474:  * Returns the type definition or NULL in case of error
11475:  */
11476: static xmlSchemaTypePtr
11477: xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11478:                           xmlNodePtr node, xmlSchemaTypeType parentType)
11479: {
11480:     xmlSchemaTypePtr type;
11481:     xmlNodePtr child = NULL;
11482:     xmlAttrPtr attr;
11483: 
11484:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11485:         return (NULL);
11486:     /* Not a component, don't create it. */
11487:     type = ctxt->ctxtType;
11488:     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11489: 
11490:     /*
11491:     * Check for illegal attributes.
11492:     */
11493:     attr = node->properties;
11494:     while (attr != NULL) {
11495: 	if (attr->ns == NULL) {
11496: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11497: 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11498: 		xmlSchemaPIllegalAttrErr(ctxt,
11499: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11500: 	    }
11501: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11502: 	    xmlSchemaPIllegalAttrErr(ctxt,
11503: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11504: 	}
11505: 	attr = attr->next;
11506:     }
11507:     /*
11508:     * Extract and validate attributes.
11509:     */
11510:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11511:     /*
11512:     * Attribute
11513:     */
11514:     /*
11515:     * Extract the base type. The "base" attribute is mandatory if inside
11516:     * a complex type or if redefining.
11517:     *
11518:     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11519:     * among its [children]), the simple type definition which is
11520:     * the {content type} of the type definition �resolved� to by
11521:     * the �actual value� of the base [attribute]"
11522:     */
11523:     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11524: 	&(type->baseNs), &(type->base)) == 0)
11525:     {
11526: 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11527: 	    xmlSchemaPMissingAttrErr(ctxt,
11528: 		XML_SCHEMAP_S4S_ATTR_MISSING,
11529: 		NULL, node, "base", NULL);
11530: 	} else if ((ctxt->isRedefine) &&
11531: 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11532: 	{
11533: 	    if (type->base == NULL) {
11534: 		xmlSchemaPMissingAttrErr(ctxt,
11535: 		    XML_SCHEMAP_S4S_ATTR_MISSING,
11536: 		    NULL, node, "base", NULL);
11537: 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
11538: 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
11539: 	    {
11540: 		xmlChar *str1 = NULL, *str2 = NULL;
11541: 		/*
11542: 		* REDEFINE: SPEC src-redefine (5)
11543: 		* "Within the [children], each <simpleType> must have a
11544: 		* <restriction> among its [children] ... the �actual value� of
11545: 		* whose base [attribute] must be the same as the �actual value�
11546: 		* of its own name attribute plus target namespace;"
11547: 		*/
11548: 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11549: 		    NULL, node, "This is a redefinition, but the QName "
11550: 		    "value '%s' of the 'base' attribute does not match the "
11551: 		    "type's designation '%s'",
11552: 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11553: 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
11554: 			type->name), NULL);
11555: 		FREE_AND_NULL(str1);
11556: 		FREE_AND_NULL(str2);
11557: 		/* Avoid confusion and erase the values. */
11558: 		type->base = NULL;
11559: 		type->baseNs = NULL;
11560: 	    }
11561: 	}
11562:     }
11563:     /*
11564:     * And now for the children...
11565:     */
11566:     child = node->children;
11567:     if (IS_SCHEMA(child, "annotation")) {
11568: 	/*
11569: 	* Add the annotation to the simple type ancestor.
11570: 	*/
11571: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11572: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11573:         child = child->next;
11574:     }
11575:     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11576: 	/*
11577: 	* Corresponds to <simpleType><restriction><simpleType>.
11578: 	*/
11579: 	if (IS_SCHEMA(child, "simpleType")) {
11580: 	    if (type->base != NULL) {
11581: 		/*
11582: 		* src-restriction-base-or-simpleType
11583: 		* Either the base [attribute] or the simpleType [child] of the
11584: 		* <restriction> element must be present, but not both.
11585: 		*/
11586: 		xmlSchemaPContentErr(ctxt,
11587: 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11588: 		    NULL, node, child,
11589: 		    "The attribute 'base' and the <simpleType> child are "
11590: 		    "mutually exclusive", NULL);
11591: 	    } else {
11592: 		type->baseType = (xmlSchemaTypePtr)
11593: 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11594: 	    }
11595: 	    child = child->next;
11596: 	} else if (type->base == NULL) {
11597: 	    xmlSchemaPContentErr(ctxt,
11598: 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11599: 		NULL, node, child,
11600: 		"Either the attribute 'base' or a <simpleType> child "
11601: 		"must be present", NULL);
11602: 	}
11603:     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11604: 	/*
11605: 	* Corresponds to <complexType><complexContent><restriction>...
11606: 	* followed by:
11607: 	*
11608: 	* Model groups <all>, <choice> and <sequence>.
11609: 	*/
11610: 	if (IS_SCHEMA(child, "all")) {
11611: 	    type->subtypes = (xmlSchemaTypePtr)
11612: 		xmlSchemaParseModelGroup(ctxt, schema, child,
11613: 		    XML_SCHEMA_TYPE_ALL, 1);
11614: 	    child = child->next;
11615: 	} else if (IS_SCHEMA(child, "choice")) {
11616: 	    type->subtypes = (xmlSchemaTypePtr)
11617: 		xmlSchemaParseModelGroup(ctxt,
11618: 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11619: 	    child = child->next;
11620: 	} else if (IS_SCHEMA(child, "sequence")) {
11621: 	    type->subtypes = (xmlSchemaTypePtr)
11622: 		xmlSchemaParseModelGroup(ctxt, schema, child,
11623: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
11624: 	    child = child->next;
11625: 	/*
11626: 	* Model group reference <group>.
11627: 	*/
11628: 	} else if (IS_SCHEMA(child, "group")) {
11629: 	    type->subtypes = (xmlSchemaTypePtr)
11630: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11631: 	    /*
11632: 	    * Note that the reference will be resolved in
11633: 	    * xmlSchemaResolveTypeReferences();
11634: 	    */
11635: 	    child = child->next;
11636: 	}
11637:     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11638: 	/*
11639: 	* Corresponds to <complexType><simpleContent><restriction>...
11640: 	*
11641: 	* "1.1 the simple type definition corresponding to the <simpleType>
11642: 	* among the [children] of <restriction> if there is one;"
11643: 	*/
11644: 	if (IS_SCHEMA(child, "simpleType")) {
11645: 	    /*
11646: 	    * We will store the to-be-restricted simple type in
11647: 	    * type->contentTypeDef *temporarily*.
11648: 	    */
11649: 	    type->contentTypeDef = (xmlSchemaTypePtr)
11650: 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11651: 	    if ( type->contentTypeDef == NULL)
11652: 		return (NULL);
11653: 	    child = child->next;
11654: 	}
11655:     }
11656: 
11657:     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11658: 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11659: 	xmlSchemaFacetPtr facet, lastfacet = NULL;
11660: 	/*
11661: 	* Corresponds to <complexType><simpleContent><restriction>...
11662: 	* <simpleType><restriction>...
11663: 	*/
11664: 
11665: 	/*
11666: 	* Add the facets to the simple type ancestor.
11667: 	*/
11668: 	/*
11669: 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11670: 	* Simple Type Definition Schema Representation Constraint:
11671: 	* *Single Facet Value*
11672: 	*/
11673: 	while ((IS_SCHEMA(child, "minInclusive")) ||
11674: 	    (IS_SCHEMA(child, "minExclusive")) ||
11675: 	    (IS_SCHEMA(child, "maxInclusive")) ||
11676: 	    (IS_SCHEMA(child, "maxExclusive")) ||
11677: 	    (IS_SCHEMA(child, "totalDigits")) ||
11678: 	    (IS_SCHEMA(child, "fractionDigits")) ||
11679: 	    (IS_SCHEMA(child, "pattern")) ||
11680: 	    (IS_SCHEMA(child, "enumeration")) ||
11681: 	    (IS_SCHEMA(child, "whiteSpace")) ||
11682: 	    (IS_SCHEMA(child, "length")) ||
11683: 	    (IS_SCHEMA(child, "maxLength")) ||
11684: 	    (IS_SCHEMA(child, "minLength"))) {
11685: 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
11686: 	    if (facet != NULL) {
11687: 		if (lastfacet == NULL)
11688: 		    type->facets = facet;
11689: 		else
11690: 		    lastfacet->next = facet;
11691: 		lastfacet = facet;
11692: 		lastfacet->next = NULL;
11693: 	    }
11694: 	    child = child->next;
11695: 	}
11696: 	/*
11697: 	* Create links for derivation and validation.
11698: 	*/
11699: 	if (type->facets != NULL) {
11700: 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11701: 
11702: 	    facet = type->facets;
11703: 	    do {
11704: 		facetLink = (xmlSchemaFacetLinkPtr)
11705: 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
11706: 		if (facetLink == NULL) {
11707: 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11708: 		    xmlFree(facetLink);
11709: 		    return (NULL);
11710: 		}
11711: 		facetLink->facet = facet;
11712: 		facetLink->next = NULL;
11713: 		if (lastFacetLink == NULL)
11714: 		    type->facetSet = facetLink;
11715: 		else
11716: 		    lastFacetLink->next = facetLink;
11717: 		lastFacetLink = facetLink;
11718: 		facet = facet->next;
11719: 	    } while (facet != NULL);
11720: 	}
11721:     }
11722:     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11723: 	/*
11724: 	* Attribute uses/declarations.
11725: 	*/
11726: 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11727: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
11728: 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11729: 	    return(NULL);
11730: 	/*
11731: 	* Attribute wildcard.
11732: 	*/
11733: 	if (IS_SCHEMA(child, "anyAttribute")) {
11734: 	    type->attributeWildcard =
11735: 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
11736: 	    child = child->next;
11737: 	}
11738:     }
11739:     if (child != NULL) {
11740: 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11741: 	    xmlSchemaPContentErr(ctxt,
11742: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11743: 		NULL, node, child, NULL,
11744: 		"annotation?, (group | all | choice | sequence)?, "
11745: 		"((attribute | attributeGroup)*, anyAttribute?))");
11746: 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11747: 	     xmlSchemaPContentErr(ctxt,
11748: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11749: 		NULL, node, child, NULL,
11750: 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11751: 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11752: 		"length | minLength | maxLength | enumeration | whiteSpace | "
11753: 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11754: 	} else {
11755: 	    /* Simple type */
11756: 	    xmlSchemaPContentErr(ctxt,
11757: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11758: 		NULL, node, child, NULL,
11759: 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11760: 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11761: 		"length | minLength | maxLength | enumeration | whiteSpace | "
11762: 		"pattern)*))");
11763: 	}
11764:     }
11765:     return (NULL);
11766: }
11767: 
11768: /**
11769:  * xmlSchemaParseExtension:
11770:  * @ctxt:  a schema validation context
11771:  * @schema:  the schema being built
11772:  * @node:  a subtree containing XML Schema informations
11773:  *
11774:  * Parses an <extension>, which is found inside a
11775:  * <simpleContent> or <complexContent>.
11776:  * *WARNING* this interface is highly subject to change.
11777:  *
11778:  * TODO: Returns the type definition or NULL in case of error
11779:  */
11780: static xmlSchemaTypePtr
11781: xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11782:                         xmlNodePtr node, xmlSchemaTypeType parentType)
11783: {
11784:     xmlSchemaTypePtr type;
11785:     xmlNodePtr child = NULL;
11786:     xmlAttrPtr attr;
11787: 
11788:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11789:         return (NULL);
11790:     /* Not a component, don't create it. */
11791:     type = ctxt->ctxtType;
11792:     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11793: 
11794:     /*
11795:     * Check for illegal attributes.
11796:     */
11797:     attr = node->properties;
11798:     while (attr != NULL) {
11799: 	if (attr->ns == NULL) {
11800: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11801: 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11802: 		xmlSchemaPIllegalAttrErr(ctxt,
11803: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11804: 	    }
11805: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11806: 	    xmlSchemaPIllegalAttrErr(ctxt,
11807: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11808: 	}
11809: 	attr = attr->next;
11810:     }
11811: 
11812:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11813: 
11814:     /*
11815:     * Attribute "base" - mandatory.
11816:     */
11817:     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11818: 	"base", &(type->baseNs), &(type->base)) == 0) &&
11819: 	(type->base == NULL)) {
11820: 	xmlSchemaPMissingAttrErr(ctxt,
11821: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
11822: 	    NULL, node, "base", NULL);
11823:     }
11824:     /*
11825:     * And now for the children...
11826:     */
11827:     child = node->children;
11828:     if (IS_SCHEMA(child, "annotation")) {
11829: 	/*
11830: 	* Add the annotation to the type ancestor.
11831: 	*/
11832: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11833: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11834:         child = child->next;
11835:     }
11836:     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11837: 	/*
11838: 	* Corresponds to <complexType><complexContent><extension>... and:
11839: 	*
11840: 	* Model groups <all>, <choice>, <sequence> and <group>.
11841: 	*/
11842: 	if (IS_SCHEMA(child, "all")) {
11843: 	    type->subtypes = (xmlSchemaTypePtr)
11844: 		xmlSchemaParseModelGroup(ctxt, schema,
11845: 		    child, XML_SCHEMA_TYPE_ALL, 1);
11846: 	    child = child->next;
11847: 	} else if (IS_SCHEMA(child, "choice")) {
11848: 	    type->subtypes = (xmlSchemaTypePtr)
11849: 		xmlSchemaParseModelGroup(ctxt, schema,
11850: 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
11851: 	    child = child->next;
11852: 	} else if (IS_SCHEMA(child, "sequence")) {
11853: 	    type->subtypes = (xmlSchemaTypePtr)
11854: 		xmlSchemaParseModelGroup(ctxt, schema,
11855: 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11856: 	    child = child->next;
11857: 	} else if (IS_SCHEMA(child, "group")) {
11858: 	    type->subtypes = (xmlSchemaTypePtr)
11859: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11860: 	    /*
11861: 	    * Note that the reference will be resolved in
11862: 	    * xmlSchemaResolveTypeReferences();
11863: 	    */
11864: 	    child = child->next;
11865: 	}
11866:     }
11867:     if (child != NULL) {
11868: 	/*
11869: 	* Attribute uses/declarations.
11870: 	*/
11871: 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11872: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
11873: 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11874: 	    return(NULL);
11875: 	/*
11876: 	* Attribute wildcard.
11877: 	*/
11878: 	if (IS_SCHEMA(child, "anyAttribute")) {
11879: 	    ctxt->ctxtType->attributeWildcard =
11880: 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
11881: 	    child = child->next;
11882: 	}
11883:     }
11884:     if (child != NULL) {
11885: 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11886: 	    /* Complex content extension. */
11887: 	    xmlSchemaPContentErr(ctxt,
11888: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11889: 		NULL, node, child, NULL,
11890: 		"(annotation?, ((group | all | choice | sequence)?, "
11891: 		"((attribute | attributeGroup)*, anyAttribute?)))");
11892: 	} else {
11893: 	    /* Simple content extension. */
11894: 	    xmlSchemaPContentErr(ctxt,
11895: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11896: 		NULL, node, child, NULL,
11897: 		"(annotation?, ((attribute | attributeGroup)*, "
11898: 		"anyAttribute?))");
11899: 	}
11900:     }
11901:     return (NULL);
11902: }
11903: 
11904: /**
11905:  * xmlSchemaParseSimpleContent:
11906:  * @ctxt:  a schema validation context
11907:  * @schema:  the schema being built
11908:  * @node:  a subtree containing XML Schema informations
11909:  *
11910:  * parse a XML schema SimpleContent definition
11911:  * *WARNING* this interface is highly subject to change
11912:  *
11913:  * Returns the type definition or NULL in case of error
11914:  */
11915: static int
11916: xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11917:                             xmlSchemaPtr schema, xmlNodePtr node,
11918: 			    int *hasRestrictionOrExtension)
11919: {
11920:     xmlSchemaTypePtr type;
11921:     xmlNodePtr child = NULL;
11922:     xmlAttrPtr attr;
11923: 
11924:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11925: 	(hasRestrictionOrExtension == NULL))
11926:         return (-1);
11927:     *hasRestrictionOrExtension = 0;
11928:     /* Not a component, don't create it. */
11929:     type = ctxt->ctxtType;
11930:     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11931:     /*
11932:     * Check for illegal attributes.
11933:     */
11934:     attr = node->properties;
11935:     while (attr != NULL) {
11936: 	if (attr->ns == NULL) {
11937: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11938: 		xmlSchemaPIllegalAttrErr(ctxt,
11939: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11940: 	    }
11941: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11942: 	    xmlSchemaPIllegalAttrErr(ctxt,
11943: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11944: 	}
11945: 	attr = attr->next;
11946:     }
11947: 
11948:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11949: 
11950:     /*
11951:     * And now for the children...
11952:     */
11953:     child = node->children;
11954:     if (IS_SCHEMA(child, "annotation")) {
11955: 	/*
11956: 	* Add the annotation to the complex type ancestor.
11957: 	*/
11958: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11959: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11960:         child = child->next;
11961:     }
11962:     if (child == NULL) {
11963: 	xmlSchemaPContentErr(ctxt,
11964: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
11965: 	    NULL, node, NULL, NULL,
11966: 	    "(annotation?, (restriction | extension))");
11967:     }
11968:     if (child == NULL) {
11969: 	xmlSchemaPContentErr(ctxt,
11970: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
11971: 	    NULL, node, NULL, NULL,
11972: 	    "(annotation?, (restriction | extension))");
11973:     }
11974:     if (IS_SCHEMA(child, "restriction")) {
11975:         xmlSchemaParseRestriction(ctxt, schema, child,
11976: 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11977: 	(*hasRestrictionOrExtension) = 1;
11978:         child = child->next;
11979:     } else if (IS_SCHEMA(child, "extension")) {
11980:         xmlSchemaParseExtension(ctxt, schema, child,
11981: 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11982: 	(*hasRestrictionOrExtension) = 1;
11983:         child = child->next;
11984:     }
11985:     if (child != NULL) {
11986: 	xmlSchemaPContentErr(ctxt,
11987: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11988: 	    NULL, node, child, NULL,
11989: 	    "(annotation?, (restriction | extension))");
11990:     }
11991:     return (0);
11992: }
11993: 
11994: /**
11995:  * xmlSchemaParseComplexContent:
11996:  * @ctxt:  a schema validation context
11997:  * @schema:  the schema being built
11998:  * @node:  a subtree containing XML Schema informations
11999:  *
12000:  * parse a XML schema ComplexContent definition
12001:  * *WARNING* this interface is highly subject to change
12002:  *
12003:  * Returns the type definition or NULL in case of error
12004:  */
12005: static int
12006: xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
12007:                              xmlSchemaPtr schema, xmlNodePtr node,
12008: 			     int *hasRestrictionOrExtension)
12009: {
12010:     xmlSchemaTypePtr type;
12011:     xmlNodePtr child = NULL;
12012:     xmlAttrPtr attr;
12013: 
12014:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
12015: 	(hasRestrictionOrExtension == NULL))
12016:         return (-1);
12017:     *hasRestrictionOrExtension = 0;
12018:     /* Not a component, don't create it. */
12019:     type = ctxt->ctxtType;
12020:     /*
12021:     * Check for illegal attributes.
12022:     */
12023:     attr = node->properties;
12024:     while (attr != NULL) {
12025: 	if (attr->ns == NULL) {
12026: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
12027: 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
12028: 	    {
12029: 		xmlSchemaPIllegalAttrErr(ctxt,
12030: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12031: 	    }
12032: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12033: 	    xmlSchemaPIllegalAttrErr(ctxt,
12034: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12035: 	}
12036: 	attr = attr->next;
12037:     }
12038: 
12039:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12040: 
12041:     /*
12042:     * Set the 'mixed' on the complex type ancestor.
12043:     */
12044:     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12045: 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12046: 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
12047:     }
12048:     child = node->children;
12049:     if (IS_SCHEMA(child, "annotation")) {
12050: 	/*
12051: 	* Add the annotation to the complex type ancestor.
12052: 	*/
12053: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12054: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
12055:         child = child->next;
12056:     }
12057:     if (child == NULL) {
12058: 	xmlSchemaPContentErr(ctxt,
12059: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
12060: 	    NULL, node, NULL,
12061: 	    NULL, "(annotation?, (restriction | extension))");
12062:     }
12063:     if (child == NULL) {
12064: 	xmlSchemaPContentErr(ctxt,
12065: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
12066: 	    NULL, node, NULL,
12067: 	    NULL, "(annotation?, (restriction | extension))");
12068:     }
12069:     if (IS_SCHEMA(child, "restriction")) {
12070:         xmlSchemaParseRestriction(ctxt, schema, child,
12071: 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12072: 	(*hasRestrictionOrExtension) = 1;
12073:         child = child->next;
12074:     } else if (IS_SCHEMA(child, "extension")) {
12075:         xmlSchemaParseExtension(ctxt, schema, child,
12076: 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12077: 	(*hasRestrictionOrExtension) = 1;
12078:         child = child->next;
12079:     }
12080:     if (child != NULL) {
12081: 	xmlSchemaPContentErr(ctxt,
12082: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12083: 	    NULL, node, child,
12084: 	    NULL, "(annotation?, (restriction | extension))");
12085:     }
12086:     return (0);
12087: }
12088: 
12089: /**
12090:  * xmlSchemaParseComplexType:
12091:  * @ctxt:  a schema validation context
12092:  * @schema:  the schema being built
12093:  * @node:  a subtree containing XML Schema informations
12094:  *
12095:  * parse a XML schema Complex Type definition
12096:  * *WARNING* this interface is highly subject to change
12097:  *
12098:  * Returns the type definition or NULL in case of error
12099:  */
12100: static xmlSchemaTypePtr
12101: xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12102:                           xmlNodePtr node, int topLevel)
12103: {
12104:     xmlSchemaTypePtr type, ctxtType;
12105:     xmlNodePtr child = NULL;
12106:     const xmlChar *name = NULL;
12107:     xmlAttrPtr attr;
12108:     const xmlChar *attrValue;
12109: #ifdef ENABLE_NAMED_LOCALS
12110:     char buf[40];
12111: #endif
12112:     int final = 0, block = 0, hasRestrictionOrExtension = 0;
12113: 
12114: 
12115:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12116:         return (NULL);
12117: 
12118:     ctxtType = ctxt->ctxtType;
12119: 
12120:     if (topLevel) {
12121: 	attr = xmlSchemaGetPropNode(node, "name");
12122: 	if (attr == NULL) {
12123: 	    xmlSchemaPMissingAttrErr(ctxt,
12124: 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12125: 	    return (NULL);
12126: 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12127: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12128: 	    return (NULL);
12129: 	}
12130:     }
12131: 
12132:     if (topLevel == 0) {
12133: 	/*
12134: 	* Parse as local complex type definition.
12135: 	*/
12136: #ifdef ENABLE_NAMED_LOCALS
12137:         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12138: 	type = xmlSchemaAddType(ctxt, schema,
12139: 	    XML_SCHEMA_TYPE_COMPLEX,
12140: 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12141: 	    ctxt->targetNamespace, node, 0);
12142: #else
12143: 	type = xmlSchemaAddType(ctxt, schema,
12144: 	    XML_SCHEMA_TYPE_COMPLEX,
12145: 	    NULL, ctxt->targetNamespace, node, 0);
12146: #endif
12147: 	if (type == NULL)
12148: 	    return (NULL);
12149: 	name = type->name;
12150: 	type->node = node;
12151: 	type->type = XML_SCHEMA_TYPE_COMPLEX;
12152: 	/*
12153: 	* TODO: We need the target namespace.
12154: 	*/
12155:     } else {
12156: 	/*
12157: 	* Parse as global complex type definition.
12158: 	*/
12159: 	type = xmlSchemaAddType(ctxt, schema,
12160: 	    XML_SCHEMA_TYPE_COMPLEX,
12161: 	    name, ctxt->targetNamespace, node, 1);
12162: 	if (type == NULL)
12163: 	    return (NULL);
12164: 	type->node = node;
12165: 	type->type = XML_SCHEMA_TYPE_COMPLEX;
12166: 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12167:     }
12168:     type->targetNamespace = ctxt->targetNamespace;
12169:     /*
12170:     * Handle attributes.
12171:     */
12172:     attr = node->properties;
12173:     while (attr != NULL) {
12174: 	if (attr->ns == NULL) {
12175: 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12176: 		/*
12177: 		* Attribute "id".
12178: 		*/
12179: 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12180: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12181: 		/*
12182: 		* Attribute "mixed".
12183: 		*/
12184: 		if (xmlSchemaPGetBoolNodeValue(ctxt,
12185: 			NULL, (xmlNodePtr) attr))
12186: 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
12187: 	    } else if (topLevel) {
12188: 		/*
12189: 		* Attributes of global complex type definitions.
12190: 		*/
12191: 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12192: 		    /* Pass. */
12193: 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12194: 		    /*
12195: 		    * Attribute "abstract".
12196: 		    */
12197: 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
12198: 			    NULL, (xmlNodePtr) attr))
12199: 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12200: 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12201: 		    /*
12202: 		    * Attribute "final".
12203: 		    */
12204: 		    attrValue = xmlSchemaGetNodeContent(ctxt,
12205: 			(xmlNodePtr) attr);
12206: 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
12207: 			&(type->flags),
12208: 			-1,
12209: 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12210: 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12211: 			-1, -1, -1) != 0)
12212: 		    {
12213: 			xmlSchemaPSimpleTypeErr(ctxt,
12214: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12215: 			    NULL, (xmlNodePtr) attr, NULL,
12216: 			    "(#all | List of (extension | restriction))",
12217: 			    attrValue, NULL, NULL, NULL);
12218: 		    } else
12219: 			final = 1;
12220: 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12221: 		    /*
12222: 		    * Attribute "block".
12223: 		    */
12224: 		    attrValue = xmlSchemaGetNodeContent(ctxt,
12225: 			(xmlNodePtr) attr);
12226: 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12227: 			-1,
12228: 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12229: 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12230: 			-1, -1, -1) != 0) {
12231: 			xmlSchemaPSimpleTypeErr(ctxt,
12232: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12233: 			    NULL, (xmlNodePtr) attr, NULL,
12234: 			    "(#all | List of (extension | restriction)) ",
12235: 			    attrValue, NULL, NULL, NULL);
12236: 		    } else
12237: 			block = 1;
12238: 		} else {
12239: 			xmlSchemaPIllegalAttrErr(ctxt,
12240: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12241: 		}
12242: 	    } else {
12243: 		xmlSchemaPIllegalAttrErr(ctxt,
12244: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12245: 	    }
12246: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12247: 	    xmlSchemaPIllegalAttrErr(ctxt,
12248: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12249: 	}
12250: 	attr = attr->next;
12251:     }
12252:     if (! block) {
12253: 	/*
12254: 	* Apply default "block" values.
12255: 	*/
12256: 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12257: 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12258: 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12259: 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12260:     }
12261:     if (! final) {
12262: 	/*
12263: 	* Apply default "block" values.
12264: 	*/
12265: 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12266: 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12267: 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12268: 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12269:     }
12270:     /*
12271:     * And now for the children...
12272:     */
12273:     child = node->children;
12274:     if (IS_SCHEMA(child, "annotation")) {
12275:         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12276:         child = child->next;
12277:     }
12278:     ctxt->ctxtType = type;
12279:     if (IS_SCHEMA(child, "simpleContent")) {
12280: 	/*
12281: 	* <complexType><simpleContent>...
12282: 	* 3.4.3 : 2.2
12283: 	* Specifying mixed='true' when the <simpleContent>
12284: 	* alternative is chosen has no effect
12285: 	*/
12286: 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12287: 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12288:         xmlSchemaParseSimpleContent(ctxt, schema, child,
12289: 	    &hasRestrictionOrExtension);
12290:         child = child->next;
12291:     } else if (IS_SCHEMA(child, "complexContent")) {
12292: 	/*
12293: 	* <complexType><complexContent>...
12294: 	*/
12295: 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12296:         xmlSchemaParseComplexContent(ctxt, schema, child,
12297: 	    &hasRestrictionOrExtension);
12298:         child = child->next;
12299:     } else {
12300: 	/*
12301: 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
12302: 	*
12303: 	* SPEC
12304: 	* "...the third alternative (neither <simpleContent> nor
12305: 	* <complexContent>) is chosen. This case is understood as shorthand
12306: 	* for complex content restricting the �ur-type definition�, and the
12307: 	* details of the mappings should be modified as necessary.
12308: 	*/
12309: 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12310: 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12311: 	/*
12312: 	* Parse model groups.
12313: 	*/
12314:         if (IS_SCHEMA(child, "all")) {
12315:             type->subtypes = (xmlSchemaTypePtr)
12316: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12317: 		    XML_SCHEMA_TYPE_ALL, 1);
12318:             child = child->next;
12319:         } else if (IS_SCHEMA(child, "choice")) {
12320:             type->subtypes = (xmlSchemaTypePtr)
12321: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12322: 		    XML_SCHEMA_TYPE_CHOICE, 1);
12323:             child = child->next;
12324:         } else if (IS_SCHEMA(child, "sequence")) {
12325:             type->subtypes = (xmlSchemaTypePtr)
12326: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12327: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
12328:             child = child->next;
12329:         } else if (IS_SCHEMA(child, "group")) {
12330:             type->subtypes = (xmlSchemaTypePtr)
12331: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12332: 	    /*
12333: 	    * Note that the reference will be resolved in
12334: 	    * xmlSchemaResolveTypeReferences();
12335: 	    */
12336:             child = child->next;
12337:         }
12338: 	/*
12339: 	* Parse attribute decls/refs.
12340: 	*/
12341:         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12342: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
12343: 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12344: 	    return(NULL);
12345: 	/*
12346: 	* Parse attribute wildcard.
12347: 	*/
12348: 	if (IS_SCHEMA(child, "anyAttribute")) {
12349: 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12350: 	    child = child->next;
12351: 	}
12352:     }
12353:     if (child != NULL) {
12354: 	xmlSchemaPContentErr(ctxt,
12355: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12356: 	    NULL, node, child,
12357: 	    NULL, "(annotation?, (simpleContent | complexContent | "
12358: 	    "((group | all | choice | sequence)?, ((attribute | "
12359: 	    "attributeGroup)*, anyAttribute?))))");
12360:     }
12361:     /*
12362:     * REDEFINE: SPEC src-redefine (5)
12363:     */
12364:     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12365: 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12366: 	    NULL, node, "This is a redefinition, thus the "
12367: 	    "<complexType> must have a <restriction> or <extension> "
12368: 	    "grand-child", NULL);
12369:     }
12370:     ctxt->ctxtType = ctxtType;
12371:     return (type);
12372: }
12373: 
12374: /************************************************************************
12375:  *									*
12376:  *			Validating using Schemas			*
12377:  *									*
12378:  ************************************************************************/
12379: 
12380: /************************************************************************
12381:  *									*
12382:  *			Reading/Writing Schemas				*
12383:  *									*
12384:  ************************************************************************/
12385: 
12386: #if 0 /* Will be enabled if it is clear what options are needed. */
12387: /**
12388:  * xmlSchemaParserCtxtSetOptions:
12389:  * @ctxt:	a schema parser context
12390:  * @options: a combination of xmlSchemaParserOption
12391:  *
12392:  * Sets the options to be used during the parse.
12393:  *
12394:  * Returns 0 in case of success, -1 in case of an
12395:  * API error.
12396:  */
12397: static int
12398: xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12399: 			      int options)
12400: 
12401: {
12402:     int i;
12403: 
12404:     if (ctxt == NULL)
12405: 	return (-1);
12406:     /*
12407:     * WARNING: Change the start value if adding to the
12408:     * xmlSchemaParseOption.
12409:     */
12410:     for (i = 1; i < (int) sizeof(int) * 8; i++) {
12411:         if (options & 1<<i) {
12412: 	    return (-1);
12413:         }
12414:     }
12415:     ctxt->options = options;
12416:     return (0);
12417: }
12418: 
12419: /**
12420:  * xmlSchemaValidCtxtGetOptions:
12421:  * @ctxt: a schema parser context
12422:  *
12423:  * Returns the option combination of the parser context.
12424:  */
12425: static int
12426: xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12427: 
12428: {
12429:     if (ctxt == NULL)
12430: 	return (-1);
12431:     else
12432: 	return (ctxt->options);
12433: }
12434: #endif
12435: 
12436: /**
12437:  * xmlSchemaNewParserCtxt:
12438:  * @URL:  the location of the schema
12439:  *
12440:  * Create an XML Schemas parse context for that file/resource expected
12441:  * to contain an XML Schemas file.
12442:  *
12443:  * Returns the parser context or NULL in case of error
12444:  */
12445: xmlSchemaParserCtxtPtr
12446: xmlSchemaNewParserCtxt(const char *URL)
12447: {
12448:     xmlSchemaParserCtxtPtr ret;
12449: 
12450:     if (URL == NULL)
12451:         return (NULL);
12452: 
12453:     ret = xmlSchemaParserCtxtCreate();
12454:     if (ret == NULL)
12455: 	return(NULL);
12456:     ret->dict = xmlDictCreate();
12457:     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12458:     return (ret);
12459: }
12460: 
12461: /**
12462:  * xmlSchemaNewMemParserCtxt:
12463:  * @buffer:  a pointer to a char array containing the schemas
12464:  * @size:  the size of the array
12465:  *
12466:  * Create an XML Schemas parse context for that memory buffer expected
12467:  * to contain an XML Schemas file.
12468:  *
12469:  * Returns the parser context or NULL in case of error
12470:  */
12471: xmlSchemaParserCtxtPtr
12472: xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12473: {
12474:     xmlSchemaParserCtxtPtr ret;
12475: 
12476:     if ((buffer == NULL) || (size <= 0))
12477:         return (NULL);
12478:     ret = xmlSchemaParserCtxtCreate();
12479:     if (ret == NULL)
12480: 	return(NULL);
12481:     ret->buffer = buffer;
12482:     ret->size = size;
12483:     ret->dict = xmlDictCreate();
12484:     return (ret);
12485: }
12486: 
12487: /**
12488:  * xmlSchemaNewDocParserCtxt:
12489:  * @doc:  a preparsed document tree
12490:  *
12491:  * Create an XML Schemas parse context for that document.
12492:  * NB. The document may be modified during the parsing process.
12493:  *
12494:  * Returns the parser context or NULL in case of error
12495:  */
12496: xmlSchemaParserCtxtPtr
12497: xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12498: {
12499:     xmlSchemaParserCtxtPtr ret;
12500: 
12501:     if (doc == NULL)
12502:       return (NULL);
12503:     ret = xmlSchemaParserCtxtCreate();
12504:     if (ret == NULL)
12505: 	return(NULL);
12506:     ret->doc = doc;
12507:     ret->dict = xmlDictCreate();
12508:     /* The application has responsibility for the document */
12509:     ret->preserve = 1;
12510: 
12511:     return (ret);
12512: }
12513: 
12514: /**
12515:  * xmlSchemaFreeParserCtxt:
12516:  * @ctxt:  the schema parser context
12517:  *
12518:  * Free the resources associated to the schema parser context
12519:  */
12520: void
12521: xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12522: {
12523:     if (ctxt == NULL)
12524:         return;
12525:     if (ctxt->doc != NULL && !ctxt->preserve)
12526:         xmlFreeDoc(ctxt->doc);
12527:     if (ctxt->vctxt != NULL) {
12528: 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
12529:     }
12530:     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12531: 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
12532: 	ctxt->constructor = NULL;
12533: 	ctxt->ownsConstructor = 0;
12534:     }
12535:     if (ctxt->attrProhibs != NULL)
12536: 	xmlSchemaItemListFree(ctxt->attrProhibs);
12537:     xmlDictFree(ctxt->dict);
12538:     xmlFree(ctxt);
12539: }
12540: 
12541: /************************************************************************
12542:  *									*
12543:  *			Building the content models			*
12544:  *									*
12545:  ************************************************************************/
12546: 
12547: /**
12548:  * xmlSchemaBuildContentModelForSubstGroup:
12549:  *
12550:  * Returns 1 if nillable, 0 otherwise
12551:  */
12552: static int
12553: xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12554: 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12555: {
12556:     xmlAutomataStatePtr start, tmp;
12557:     xmlSchemaElementPtr elemDecl, member;
12558:     xmlSchemaSubstGroupPtr substGroup;
12559:     int i;
12560:     int ret = 0;
12561: 
12562:     elemDecl = (xmlSchemaElementPtr) particle->children;
12563:     /*
12564:     * Wrap the substitution group with a CHOICE.
12565:     */
12566:     start = pctxt->state;
12567:     if (end == NULL)
12568: 	end = xmlAutomataNewState(pctxt->am);
12569:     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12570:     if (substGroup == NULL) {
12571: 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12572: 	    XML_SCHEMAP_INTERNAL,
12573: 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12574: 	    "declaration is marked having a subst. group but none "
12575: 	    "available.\n", elemDecl->name, NULL);
12576: 	return(0);
12577:     }
12578:     if (counter >= 0) {
12579: 	/*
12580: 	* NOTE that we put the declaration in, even if it's abstract.
12581: 	* However, an error will be raised during *validation* if an element
12582: 	* information item shall be validated against an abstract element
12583: 	* declaration.
12584: 	*/
12585: 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12586:         xmlAutomataNewTransition2(pctxt->am, tmp, end,
12587: 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
12588: 	/*
12589: 	* Add subst. group members.
12590: 	*/
12591: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12592: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12593:             xmlAutomataNewTransition2(pctxt->am, tmp, end,
12594: 		               member->name, member->targetNamespace, member);
12595: 	}
12596:     } else if (particle->maxOccurs == 1) {
12597: 	/*
12598: 	* NOTE that we put the declaration in, even if it's abstract,
12599: 	*/
12600: 	xmlAutomataNewEpsilon(pctxt->am,
12601: 	    xmlAutomataNewTransition2(pctxt->am,
12602: 	    start, NULL,
12603: 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12604: 	/*
12605: 	* Add subst. group members.
12606: 	*/
12607: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12608: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12609: 	    /*
12610: 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12611: 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
12612: 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12613: 	    *  section in xmlSchemaBuildAContentModel() ).
12614: 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12615: 	    *  intended for the above "counter" section originally. I.e.,
12616: 	    *  check xs:all with subst-groups.
12617: 	    *
12618: 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12619: 	    *	               member->name, member->targetNamespace,
12620: 	    *		       1, 1, member);
12621: 	    */
12622: 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12623: 		member->name, member->targetNamespace, member);
12624: 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12625: 	}
12626:     } else {
12627: 	xmlAutomataStatePtr hop;
12628: 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12629: 	    UNBOUNDED : particle->maxOccurs - 1;
12630: 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12631: 
12632: 	counter =
12633: 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
12634: 	    maxOccurs);
12635: 	hop = xmlAutomataNewState(pctxt->am);
12636: 
12637: 	xmlAutomataNewEpsilon(pctxt->am,
12638: 	    xmlAutomataNewTransition2(pctxt->am,
12639: 	    start, NULL,
12640: 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
12641: 	    hop);
12642: 	/*
12643: 	 * Add subst. group members.
12644: 	 */
12645: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12646: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12647: 	    xmlAutomataNewEpsilon(pctxt->am,
12648: 		xmlAutomataNewTransition2(pctxt->am,
12649: 		start, NULL,
12650: 		member->name, member->targetNamespace, member),
12651: 		hop);
12652: 	}
12653: 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12654: 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12655:     }
12656:     if (particle->minOccurs == 0) {
12657: 	xmlAutomataNewEpsilon(pctxt->am, start, end);
12658:         ret = 1;
12659:     }
12660:     pctxt->state = end;
12661:     return(ret);
12662: }
12663: 
12664: /**
12665:  * xmlSchemaBuildContentModelForElement:
12666:  *
12667:  * Returns 1 if nillable, 0 otherwise
12668:  */
12669: static int
12670: xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12671: 				     xmlSchemaParticlePtr particle)
12672: {
12673:     int ret = 0;
12674: 
12675:     if (((xmlSchemaElementPtr) particle->children)->flags &
12676: 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12677: 	/*
12678: 	* Substitution groups.
12679: 	*/
12680: 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12681:     } else {
12682: 	xmlSchemaElementPtr elemDecl;
12683: 	xmlAutomataStatePtr start;
12684: 
12685: 	elemDecl = (xmlSchemaElementPtr) particle->children;
12686: 
12687: 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12688: 	    return(0);
12689: 	if (particle->maxOccurs == 1) {
12690: 	    start = ctxt->state;
12691: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12692: 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12693: 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
12694: 	           (particle->minOccurs < 2)) {
12695: 	    /* Special case. */
12696: 	    start = ctxt->state;
12697: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12698: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12699: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12700: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12701: 	} else {
12702: 	    int counter;
12703: 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12704: 			    UNBOUNDED : particle->maxOccurs - 1;
12705: 	    int minOccurs = particle->minOccurs < 1 ?
12706: 			    0 : particle->minOccurs - 1;
12707: 
12708: 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12709: 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12710: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12711: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12712: 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12713: 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12714: 		NULL, counter);
12715: 	}
12716: 	if (particle->minOccurs == 0) {
12717: 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12718:             ret = 1;
12719:         }
12720:     }
12721:     return(ret);
12722: }
12723: 
12724: /**
12725:  * xmlSchemaBuildAContentModel:
12726:  * @ctxt:  the schema parser context
12727:  * @particle:  the particle component
12728:  * @name:  the complex type's name whose content is being built
12729:  *
12730:  * Create the automaton for the {content type} of a complex type.
12731:  *
12732:  * Returns 1 if the content is nillable, 0 otherwise
12733:  */
12734: static int
12735: xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12736: 			    xmlSchemaParticlePtr particle)
12737: {
12738:     int ret = 0, tmp2;
12739: 
12740:     if (particle == NULL) {
12741: 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12742: 	return(1);
12743:     }
12744:     if (particle->children == NULL) {
12745: 	/*
12746: 	* Just return in this case. A missing "term" of the particle
12747: 	* might arise due to an invalid "term" component.
12748: 	*/
12749: 	return(1);
12750:     }
12751: 
12752:     switch (particle->children->type) {
12753: 	case XML_SCHEMA_TYPE_ANY: {
12754: 	    xmlAutomataStatePtr start, end;
12755: 	    xmlSchemaWildcardPtr wild;
12756: 	    xmlSchemaWildcardNsPtr ns;
12757: 
12758: 	    wild = (xmlSchemaWildcardPtr) particle->children;
12759: 
12760: 	    start = pctxt->state;
12761: 	    end = xmlAutomataNewState(pctxt->am);
12762: 
12763: 	    if (particle->maxOccurs == 1) {
12764: 		if (wild->any == 1) {
12765: 		    /*
12766: 		    * We need to add both transitions:
12767: 		    *
12768: 		    * 1. the {"*", "*"} for elements in a namespace.
12769: 		    */
12770: 		    pctxt->state =
12771: 			xmlAutomataNewTransition2(pctxt->am,
12772: 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12773: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12774: 		    /*
12775: 		    * 2. the {"*"} for elements in no namespace.
12776: 		    */
12777: 		    pctxt->state =
12778: 			xmlAutomataNewTransition2(pctxt->am,
12779: 			start, NULL, BAD_CAST "*", NULL, wild);
12780: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12781: 
12782: 		} else if (wild->nsSet != NULL) {
12783: 		    ns = wild->nsSet;
12784: 		    do {
12785: 			pctxt->state = start;
12786: 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12787: 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12788: 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12789: 			ns = ns->next;
12790: 		    } while (ns != NULL);
12791: 
12792: 		} else if (wild->negNsSet != NULL) {
12793: 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12794: 			start, end, BAD_CAST "*", wild->negNsSet->value,
12795: 			wild);
12796: 		}
12797: 	    } else {
12798: 		int counter;
12799: 		xmlAutomataStatePtr hop;
12800: 		int maxOccurs =
12801: 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12802:                                            particle->maxOccurs - 1;
12803: 		int minOccurs =
12804: 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12805: 
12806: 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12807: 		hop = xmlAutomataNewState(pctxt->am);
12808: 		if (wild->any == 1) {
12809: 		    pctxt->state =
12810: 			xmlAutomataNewTransition2(pctxt->am,
12811: 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12812: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12813: 		    pctxt->state =
12814: 			xmlAutomataNewTransition2(pctxt->am,
12815: 			start, NULL, BAD_CAST "*", NULL, wild);
12816: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12817: 		} else if (wild->nsSet != NULL) {
12818: 		    ns = wild->nsSet;
12819: 		    do {
12820: 			pctxt->state =
12821: 			    xmlAutomataNewTransition2(pctxt->am,
12822: 				start, NULL, BAD_CAST "*", ns->value, wild);
12823: 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12824: 			ns = ns->next;
12825: 		    } while (ns != NULL);
12826: 
12827: 		} else if (wild->negNsSet != NULL) {
12828: 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12829: 			start, hop, BAD_CAST "*", wild->negNsSet->value,
12830: 			wild);
12831: 		}
12832: 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12833: 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12834: 	    }
12835: 	    if (particle->minOccurs == 0) {
12836: 		xmlAutomataNewEpsilon(pctxt->am, start, end);
12837:                 ret = 1;
12838: 	    }
12839: 	    pctxt->state = end;
12840:             break;
12841: 	}
12842:         case XML_SCHEMA_TYPE_ELEMENT:
12843: 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12844: 	    break;
12845:         case XML_SCHEMA_TYPE_SEQUENCE:{
12846:             xmlSchemaTreeItemPtr sub;
12847: 
12848:             ret = 1;
12849:             /*
12850:              * If max and min occurances are default (1) then
12851:              * simply iterate over the particles of the <sequence>.
12852:              */
12853:             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12854:                 sub = particle->children->children;
12855: 
12856:                 while (sub != NULL) {
12857:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12858:                                         (xmlSchemaParticlePtr) sub);
12859:                     if (tmp2 != 1) ret = 0;
12860:                     sub = sub->next;
12861:                 }
12862:             } else {
12863:                 xmlAutomataStatePtr oldstate = pctxt->state;
12864: 
12865:                 if (particle->maxOccurs >= UNBOUNDED) {
12866:                     if (particle->minOccurs > 1) {
12867:                         xmlAutomataStatePtr tmp;
12868:                         int counter;
12869: 
12870:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12871:                             oldstate, NULL);
12872:                         oldstate = pctxt->state;
12873: 
12874:                         counter = xmlAutomataNewCounter(pctxt->am,
12875:                             particle->minOccurs - 1, UNBOUNDED);
12876: 
12877:                         sub = particle->children->children;
12878:                         while (sub != NULL) {
12879:                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
12880:                                             (xmlSchemaParticlePtr) sub);
12881:                             if (tmp2 != 1) ret = 0;
12882:                             sub = sub->next;
12883:                         }
12884:                         tmp = pctxt->state;
12885:                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
12886:                                                    oldstate, counter);
12887:                         pctxt->state =
12888:                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
12889:                                                        NULL, counter);
12890:                         if (ret == 1)
12891:                             xmlAutomataNewEpsilon(pctxt->am,
12892:                                                 oldstate, pctxt->state);
12893: 
12894:                     } else {
12895:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12896:                             oldstate, NULL);
12897:                         oldstate = pctxt->state;
12898: 
12899:                         sub = particle->children->children;
12900:                         while (sub != NULL) {
12901:                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
12902:                                         (xmlSchemaParticlePtr) sub);
12903:                             if (tmp2 != 1) ret = 0;
12904:                             sub = sub->next;
12905:                         }
12906:                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12907:                                               oldstate);
12908:                         /*
12909:                          * epsilon needed to block previous trans from
12910:                          * being allowed to enter back from another
12911:                          * construct
12912:                          */
12913:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12914:                                             pctxt->state, NULL);
12915:                         if (particle->minOccurs == 0) {
12916:                             xmlAutomataNewEpsilon(pctxt->am,
12917:                                 oldstate, pctxt->state);
12918:                             ret = 1;
12919:                         }
12920:                     }
12921:                 } else if ((particle->maxOccurs > 1)
12922:                            || (particle->minOccurs > 1)) {
12923:                     xmlAutomataStatePtr tmp;
12924:                     int counter;
12925: 
12926:                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12927:                         oldstate, NULL);
12928:                     oldstate = pctxt->state;
12929: 
12930:                     counter = xmlAutomataNewCounter(pctxt->am,
12931:                         particle->minOccurs - 1,
12932:                         particle->maxOccurs - 1);
12933: 
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:                     tmp = pctxt->state;
12942:                     xmlAutomataNewCountedTrans(pctxt->am,
12943:                         tmp, oldstate, counter);
12944:                     pctxt->state =
12945:                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12946:                                                    counter);
12947:                     if ((particle->minOccurs == 0) || (ret == 1)) {
12948:                         xmlAutomataNewEpsilon(pctxt->am,
12949:                                             oldstate, pctxt->state);
12950:                         ret = 1;
12951:                     }
12952:                 } else {
12953:                     sub = particle->children->children;
12954:                     while (sub != NULL) {
12955:                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
12956:                                         (xmlSchemaParticlePtr) sub);
12957:                         if (tmp2 != 1) ret = 0;
12958:                         sub = sub->next;
12959:                     }
12960: 
12961: 		    /*
12962: 		     * epsilon needed to block previous trans from
12963: 		     * being allowed to enter back from another
12964: 		     * construct
12965: 		     */
12966: 		    pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12967: 					pctxt->state, NULL);
12968: 
12969:                     if (particle->minOccurs == 0) {
12970:                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
12971:                                               pctxt->state);
12972:                         ret = 1;
12973:                     }
12974:                 }
12975:             }
12976:             break;
12977:         }
12978:         case XML_SCHEMA_TYPE_CHOICE:{
12979:             xmlSchemaTreeItemPtr sub;
12980:             xmlAutomataStatePtr start, end;
12981: 
12982:             ret = 0;
12983:             start = pctxt->state;
12984:             end = xmlAutomataNewState(pctxt->am);
12985: 
12986:             /*
12987:              * iterate over the subtypes and remerge the end with an
12988:              * epsilon transition
12989:              */
12990:             if (particle->maxOccurs == 1) {
12991:                 sub = particle->children->children;
12992:                 while (sub != NULL) {
12993:                     pctxt->state = start;
12994:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12995:                                         (xmlSchemaParticlePtr) sub);
12996:                     if (tmp2 == 1) ret = 1;
12997:                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12998:                     sub = sub->next;
12999:                 }
13000:             } else {
13001:                 int counter;
13002:                 xmlAutomataStatePtr hop, base;
13003:                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
13004:                     UNBOUNDED : particle->maxOccurs - 1;
13005:                 int minOccurs =
13006:                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
13007: 
13008:                 /*
13009:                  * use a counter to keep track of the number of transtions
13010:                  * which went through the choice.
13011:                  */
13012:                 counter =
13013:                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
13014:                 hop = xmlAutomataNewState(pctxt->am);
13015:                 base = xmlAutomataNewState(pctxt->am);
13016: 
13017:                 sub = particle->children->children;
13018:                 while (sub != NULL) {
13019:                     pctxt->state = base;
13020:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
13021:                                         (xmlSchemaParticlePtr) sub);
13022:                     if (tmp2 == 1) ret = 1;
13023:                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
13024:                     sub = sub->next;
13025:                 }
13026:                 xmlAutomataNewEpsilon(pctxt->am, start, base);
13027:                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13028:                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13029:                 if (ret == 1)
13030:                     xmlAutomataNewEpsilon(pctxt->am, base, end);
13031:             }
13032:             if (particle->minOccurs == 0) {
13033:                 xmlAutomataNewEpsilon(pctxt->am, start, end);
13034:                 ret = 1;
13035:             }
13036:             pctxt->state = end;
13037:             break;
13038:         }
13039:         case XML_SCHEMA_TYPE_ALL:{
13040:             xmlAutomataStatePtr start, tmp;
13041:             xmlSchemaParticlePtr sub;
13042:             xmlSchemaElementPtr elemDecl;
13043: 
13044:             ret = 1;
13045: 
13046:             sub = (xmlSchemaParticlePtr) particle->children->children;
13047:             if (sub == NULL)
13048:                 break;
13049: 
13050:             ret = 0;
13051: 
13052:             start = pctxt->state;
13053:             tmp = xmlAutomataNewState(pctxt->am);
13054:             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13055:             pctxt->state = tmp;
13056:             while (sub != NULL) {
13057:                 pctxt->state = tmp;
13058: 
13059:                 elemDecl = (xmlSchemaElementPtr) sub->children;
13060:                 if (elemDecl == NULL) {
13061:                     PERROR_INT("xmlSchemaBuildAContentModel",
13062:                         "<element> particle has no term");
13063:                     return(ret);
13064:                 };
13065:                 /*
13066:                 * NOTE: The {max occurs} of all the particles in the
13067:                 * {particles} of the group must be 0 or 1; this is
13068:                 * already ensured during the parse of the content of
13069:                 * <all>.
13070:                 */
13071:                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13072:                     int counter;
13073: 
13074:                     /*
13075:                      * This is an abstract group, we need to share
13076:                      * the same counter for all the element transitions
13077:                      * derived from the group
13078:                      */
13079:                     counter = xmlAutomataNewCounter(pctxt->am,
13080:                                        sub->minOccurs, sub->maxOccurs);
13081:                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
13082:                                        sub, counter, pctxt->state);
13083:                 } else {
13084:                     if ((sub->minOccurs == 1) &&
13085:                         (sub->maxOccurs == 1)) {
13086:                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13087:                                                 pctxt->state,
13088:                                                 elemDecl->name,
13089:                                                 elemDecl->targetNamespace,
13090:                                                 1, 1, elemDecl);
13091:                     } else if ((sub->minOccurs == 0) &&
13092:                         (sub->maxOccurs == 1)) {
13093: 
13094:                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13095:                                                  pctxt->state,
13096:                                                  elemDecl->name,
13097:                                                  elemDecl->targetNamespace,
13098:                                                  0,
13099:                                                  1,
13100:                                                  elemDecl);
13101:                     }
13102:                 }
13103:                 sub = (xmlSchemaParticlePtr) sub->next;
13104:             }
13105:             pctxt->state =
13106:                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13107:             if (particle->minOccurs == 0) {
13108:                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13109:                 ret = 1;
13110:             }
13111:             break;
13112:         }
13113: 	case XML_SCHEMA_TYPE_GROUP:
13114: 	    /*
13115: 	    * If we hit a model group definition, then this means that
13116: 	    * it was empty, thus was not substituted for the containing
13117: 	    * model group. Just do nothing in this case.
13118: 	    * TODO: But the group should be substituted and not occur at
13119: 	    * all in the content model at this point. Fix this.
13120: 	    */
13121:             ret = 1;
13122: 	    break;
13123:         default:
13124: 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13125: 		"xmlSchemaBuildAContentModel",
13126: 		"found unexpected term of type '%s' in content model",
13127: 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
13128:             return(ret);
13129:     }
13130:     return(ret);
13131: }
13132: 
13133: /**
13134:  * xmlSchemaBuildContentModel:
13135:  * @ctxt:  the schema parser context
13136:  * @type:  the complex type definition
13137:  * @name:  the element name
13138:  *
13139:  * Builds the content model of the complex type.
13140:  */
13141: static void
13142: xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13143: 			   xmlSchemaParserCtxtPtr ctxt)
13144: {
13145:     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13146: 	(type->contModel != NULL) ||
13147: 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13148: 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13149: 	return;
13150: 
13151: #ifdef DEBUG_CONTENT
13152:     xmlGenericError(xmlGenericErrorContext,
13153:                     "Building content model for %s\n", name);
13154: #endif
13155:     ctxt->am = NULL;
13156:     ctxt->am = xmlNewAutomata();
13157:     if (ctxt->am == NULL) {
13158:         xmlGenericError(xmlGenericErrorContext,
13159: 	    "Cannot create automata for complex type %s\n", type->name);
13160:         return;
13161:     }
13162:     ctxt->state = xmlAutomataGetInitState(ctxt->am);
13163:     /*
13164:     * Build the automaton.
13165:     */
13166:     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13167:     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13168:     type->contModel = xmlAutomataCompile(ctxt->am);
13169:     if (type->contModel == NULL) {
13170:         xmlSchemaPCustomErr(ctxt,
13171: 	    XML_SCHEMAP_INTERNAL,
13172: 	    WXS_BASIC_CAST type, type->node,
13173: 	    "Failed to compile the content model", NULL);
13174:     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13175:         xmlSchemaPCustomErr(ctxt,
13176: 	    XML_SCHEMAP_NOT_DETERMINISTIC,
13177: 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13178: 	    WXS_BASIC_CAST type, type->node,
13179: 	    "The content model is not determinist", NULL);
13180:     } else {
13181: #ifdef DEBUG_CONTENT_REGEXP
13182:         xmlGenericError(xmlGenericErrorContext,
13183:                         "Content model of %s:\n", type->name);
13184:         xmlRegexpPrint(stderr, type->contModel);
13185: #endif
13186:     }
13187:     ctxt->state = NULL;
13188:     xmlFreeAutomata(ctxt->am);
13189:     ctxt->am = NULL;
13190: }
13191: 
13192: /**
13193:  * xmlSchemaResolveElementReferences:
13194:  * @elem:  the schema element context
13195:  * @ctxt:  the schema parser context
13196:  *
13197:  * Resolves the references of an element declaration
13198:  * or particle, which has an element declaration as it's
13199:  * term.
13200:  */
13201: static void
13202: xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13203: 				  xmlSchemaParserCtxtPtr ctxt)
13204: {
13205:     if ((ctxt == NULL) || (elemDecl == NULL) ||
13206: 	((elemDecl != NULL) &&
13207: 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13208:         return;
13209:     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13210: 
13211:     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13212: 	xmlSchemaTypePtr type;
13213: 
13214: 	/* (type definition) ... otherwise the type definition �resolved�
13215: 	* to by the �actual value� of the type [attribute] ...
13216: 	*/
13217: 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13218: 	    elemDecl->namedTypeNs);
13219: 	if (type == NULL) {
13220: 	    xmlSchemaPResCompAttrErr(ctxt,
13221: 		XML_SCHEMAP_SRC_RESOLVE,
13222: 		WXS_BASIC_CAST elemDecl, elemDecl->node,
13223: 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
13224: 		XML_SCHEMA_TYPE_BASIC, "type definition");
13225: 	} else
13226: 	    elemDecl->subtypes = type;
13227:     }
13228:     if (elemDecl->substGroup != NULL) {
13229: 	xmlSchemaElementPtr substHead;
13230: 
13231: 	/*
13232: 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
13233: 	* substitutionGroup?
13234: 	*/
13235: 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13236: 	    elemDecl->substGroupNs);
13237: 	if (substHead == NULL) {
13238: 	    xmlSchemaPResCompAttrErr(ctxt,
13239: 		XML_SCHEMAP_SRC_RESOLVE,
13240: 		WXS_BASIC_CAST elemDecl, NULL,
13241: 		"substitutionGroup", elemDecl->substGroup,
13242: 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13243: 	} else {
13244: 	    xmlSchemaResolveElementReferences(substHead, ctxt);
13245: 	    /*
13246: 	    * Set the "substitution group affiliation".
13247: 	    * NOTE that now we use the "refDecl" field for this.
13248: 	    */
13249: 	    WXS_SUBST_HEAD(elemDecl) = substHead;
13250: 	    /*
13251: 	    * The type definitions is set to:
13252: 	    * SPEC "...the {type definition} of the element
13253: 	    * declaration �resolved� to by the �actual value�
13254: 	    * of the substitutionGroup [attribute], if present"
13255: 	    */
13256: 	    if (elemDecl->subtypes == NULL)
13257: 		elemDecl->subtypes = substHead->subtypes;
13258: 	}
13259:     }
13260:     /*
13261:     * SPEC "The definition of anyType serves as the default type definition
13262:     * for element declarations whose XML representation does not specify one."
13263:     */
13264:     if ((elemDecl->subtypes == NULL) &&
13265: 	(elemDecl->namedType == NULL) &&
13266: 	(elemDecl->substGroup == NULL))
13267: 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13268: }
13269: 
13270: /**
13271:  * xmlSchemaResolveUnionMemberTypes:
13272:  * @ctxt:  the schema parser context
13273:  * @type:  the schema simple type definition
13274:  *
13275:  * Checks and builds the "member type definitions" property of the union
13276:  * simple type. This handles part (1), part (2) is done in
13277:  * xmlSchemaFinishMemberTypeDefinitionsProperty()
13278:  *
13279:  * Returns -1 in case of an internal error, 0 otherwise.
13280:  */
13281: static int
13282: xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13283: 				 xmlSchemaTypePtr type)
13284: {
13285: 
13286:     xmlSchemaTypeLinkPtr link, lastLink, newLink;
13287:     xmlSchemaTypePtr memberType;
13288: 
13289:     /*
13290:     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13291:     * define the explicit members as the type definitions �resolved�
13292:     * to by the items in the �actual value� of the memberTypes [attribute],
13293:     * if any, followed by the type definitions corresponding to the
13294:     * <simpleType>s among the [children] of <union>, if any."
13295:     */
13296:     /*
13297:     * Resolve references.
13298:     */
13299:     link = type->memberTypes;
13300:     lastLink = NULL;
13301:     while (link != NULL) {
13302: 	const xmlChar *name, *nsName;
13303: 
13304: 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
13305: 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13306: 
13307: 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13308: 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13309: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13310: 		WXS_BASIC_CAST type, type->node, "memberTypes",
13311: 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13312: 	    /*
13313: 	    * Remove the member type link.
13314: 	    */
13315: 	    if (lastLink == NULL)
13316: 		type->memberTypes = link->next;
13317: 	    else
13318: 		lastLink->next = link->next;
13319: 	    newLink = link;
13320: 	    link = link->next;
13321: 	    xmlFree(newLink);
13322: 	} else {
13323: 	    link->type = memberType;
13324: 	    lastLink = link;
13325: 	    link = link->next;
13326: 	}
13327:     }
13328:     /*
13329:     * Add local simple types,
13330:     */
13331:     memberType = type->subtypes;
13332:     while (memberType != NULL) {
13333: 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13334: 	if (link == NULL) {
13335: 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13336: 	    return (-1);
13337: 	}
13338: 	link->type = memberType;
13339: 	link->next = NULL;
13340: 	if (lastLink == NULL)
13341: 	    type->memberTypes = link;
13342: 	else
13343: 	    lastLink->next = link;
13344: 	lastLink = link;
13345: 	memberType = memberType->next;
13346:     }
13347:     return (0);
13348: }
13349: 
13350: /**
13351:  * xmlSchemaIsDerivedFromBuiltInType:
13352:  * @ctxt:  the schema parser context
13353:  * @type:  the type definition
13354:  * @valType: the value type
13355:  *
13356:  *
13357:  * Returns 1 if the type has the given value type, or
13358:  * is derived from such a type.
13359:  */
13360: static int
13361: xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13362: {
13363:     if (type == NULL)
13364: 	return (0);
13365:     if (WXS_IS_COMPLEX(type))
13366: 	return (0);
13367:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
13368: 	if (type->builtInType == valType)
13369: 	    return(1);
13370: 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13371: 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
13372: 	    return (0);
13373: 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13374:     }
13375:     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13376: }
13377: 
13378: #if 0
13379: /**
13380:  * xmlSchemaIsDerivedFromBuiltInType:
13381:  * @ctxt:  the schema parser context
13382:  * @type:  the type definition
13383:  * @valType: the value type
13384:  *
13385:  *
13386:  * Returns 1 if the type has the given value type, or
13387:  * is derived from such a type.
13388:  */
13389: static int
13390: xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13391: {
13392:     if (type == NULL)
13393: 	return (0);
13394:     if (WXS_IS_COMPLEX(type))
13395: 	return (0);
13396:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
13397: 	if (type->builtInType == valType)
13398: 	    return(1);
13399: 	return (0);
13400:     } else
13401: 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13402: 
13403:     return (0);
13404: }
13405: 
13406: static xmlSchemaTypePtr
13407: xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13408: {
13409:     if (type == NULL)
13410: 	return (NULL);
13411:     if (WXS_IS_COMPLEX(type))
13412: 	return (NULL);
13413:     if (type->type == XML_SCHEMA_TYPE_BASIC)
13414: 	return(type);
13415:     return(xmlSchemaQueryBuiltInType(type->subtypes));
13416: }
13417: #endif
13418: 
13419: /**
13420:  * xmlSchemaGetPrimitiveType:
13421:  * @type:  the simpleType definition
13422:  *
13423:  * Returns the primitive type of the given type or
13424:  * NULL in case of error.
13425:  */
13426: static xmlSchemaTypePtr
13427: xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13428: {
13429: 
13430:     while (type != NULL) {
13431: 	/*
13432: 	* Note that anySimpleType is actually not a primitive type
13433: 	* but we need that here.
13434: 	*/
13435: 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13436: 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13437: 	    return (type);
13438: 	type = type->baseType;
13439:     }
13440: 
13441:     return (NULL);
13442: }
13443: 
13444: #if 0
13445: /**
13446:  * xmlSchemaGetBuiltInTypeAncestor:
13447:  * @type:  the simpleType definition
13448:  *
13449:  * Returns the primitive type of the given type or
13450:  * NULL in case of error.
13451:  */
13452: static xmlSchemaTypePtr
13453: xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13454: {
13455:     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13456: 	return (0);
13457:     while (type != NULL) {
13458: 	if (type->type == XML_SCHEMA_TYPE_BASIC)
13459: 	    return (type);
13460: 	type = type->baseType;
13461:     }
13462: 
13463:     return (NULL);
13464: }
13465: #endif
13466: 
13467: /**
13468:  * xmlSchemaCloneWildcardNsConstraints:
13469:  * @ctxt:  the schema parser context
13470:  * @dest:  the destination wildcard
13471:  * @source: the source wildcard
13472:  *
13473:  * Clones the namespace constraints of source
13474:  * and assignes them to dest.
13475:  * Returns -1 on internal error, 0 otherwise.
13476:  */
13477: static int
13478: xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13479: 				    xmlSchemaWildcardPtr dest,
13480: 				    xmlSchemaWildcardPtr source)
13481: {
13482:     xmlSchemaWildcardNsPtr cur, tmp, last;
13483: 
13484:     if ((source == NULL) || (dest == NULL))
13485: 	return(-1);
13486:     dest->any = source->any;
13487:     cur = source->nsSet;
13488:     last = NULL;
13489:     while (cur != NULL) {
13490: 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13491: 	if (tmp == NULL)
13492: 	    return(-1);
13493: 	tmp->value = cur->value;
13494: 	if (last == NULL)
13495: 	    dest->nsSet = tmp;
13496: 	else
13497: 	    last->next = tmp;
13498: 	last = tmp;
13499: 	cur = cur->next;
13500:     }
13501:     if (dest->negNsSet != NULL)
13502: 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13503:     if (source->negNsSet != NULL) {
13504: 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13505: 	if (dest->negNsSet == NULL)
13506: 	    return(-1);
13507: 	dest->negNsSet->value = source->negNsSet->value;
13508:     } else
13509: 	dest->negNsSet = NULL;
13510:     return(0);
13511: }
13512: 
13513: /**
13514:  * xmlSchemaUnionWildcards:
13515:  * @ctxt:  the schema parser context
13516:  * @completeWild:  the first wildcard
13517:  * @curWild: the second wildcard
13518:  *
13519:  * Unions the namespace constraints of the given wildcards.
13520:  * @completeWild will hold the resulting union.
13521:  * Returns a positive error code on failure, -1 in case of an
13522:  * internal error, 0 otherwise.
13523:  */
13524: static int
13525: xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13526: 			    xmlSchemaWildcardPtr completeWild,
13527: 			    xmlSchemaWildcardPtr curWild)
13528: {
13529:     xmlSchemaWildcardNsPtr cur, curB, tmp;
13530: 
13531:     /*
13532:     * 1 If O1 and O2 are the same value, then that value must be the
13533:     * value.
13534:     */
13535:     if ((completeWild->any == curWild->any) &&
13536: 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13537: 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13538: 
13539: 	if ((completeWild->negNsSet == NULL) ||
13540: 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13541: 
13542: 	    if (completeWild->nsSet != NULL) {
13543: 		int found = 0;
13544: 
13545: 		/*
13546: 		* Check equality of sets.
13547: 		*/
13548: 		cur = completeWild->nsSet;
13549: 		while (cur != NULL) {
13550: 		    found = 0;
13551: 		    curB = curWild->nsSet;
13552: 		    while (curB != NULL) {
13553: 			if (cur->value == curB->value) {
13554: 			    found = 1;
13555: 			    break;
13556: 			}
13557: 			curB = curB->next;
13558: 		    }
13559: 		    if (!found)
13560: 			break;
13561: 		    cur = cur->next;
13562: 		}
13563: 		if (found)
13564: 		    return(0);
13565: 	    } else
13566: 		return(0);
13567: 	}
13568:     }
13569:     /*
13570:     * 2 If either O1 or O2 is any, then any must be the value
13571:     */
13572:     if (completeWild->any != curWild->any) {
13573: 	if (completeWild->any == 0) {
13574: 	    completeWild->any = 1;
13575: 	    if (completeWild->nsSet != NULL) {
13576: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13577: 		completeWild->nsSet = NULL;
13578: 	    }
13579: 	    if (completeWild->negNsSet != NULL) {
13580: 		xmlFree(completeWild->negNsSet);
13581: 		completeWild->negNsSet = NULL;
13582: 	    }
13583: 	}
13584: 	return (0);
13585:     }
13586:     /*
13587:     * 3 If both O1 and O2 are sets of (namespace names or �absent�),
13588:     * then the union of those sets must be the value.
13589:     */
13590:     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13591: 	int found;
13592: 	xmlSchemaWildcardNsPtr start;
13593: 
13594: 	cur = curWild->nsSet;
13595: 	start = completeWild->nsSet;
13596: 	while (cur != NULL) {
13597: 	    found = 0;
13598: 	    curB = start;
13599: 	    while (curB != NULL) {
13600: 		if (cur->value == curB->value) {
13601: 		    found = 1;
13602: 		    break;
13603: 		}
13604: 		curB = curB->next;
13605: 	    }
13606: 	    if (!found) {
13607: 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13608: 		if (tmp == NULL)
13609: 		    return (-1);
13610: 		tmp->value = cur->value;
13611: 		tmp->next = completeWild->nsSet;
13612: 		completeWild->nsSet = tmp;
13613: 	    }
13614: 	    cur = cur->next;
13615: 	}
13616: 
13617: 	return(0);
13618:     }
13619:     /*
13620:     * 4 If the two are negations of different values (namespace names
13621:     * or �absent�), then a pair of not and �absent� must be the value.
13622:     */
13623:     if ((completeWild->negNsSet != NULL) &&
13624: 	(curWild->negNsSet != NULL) &&
13625: 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
13626: 	completeWild->negNsSet->value = NULL;
13627: 
13628: 	return(0);
13629:     }
13630:     /*
13631:      * 5.
13632:      */
13633:     if (((completeWild->negNsSet != NULL) &&
13634: 	(completeWild->negNsSet->value != NULL) &&
13635: 	(curWild->nsSet != NULL)) ||
13636: 	((curWild->negNsSet != NULL) &&
13637: 	(curWild->negNsSet->value != NULL) &&
13638: 	(completeWild->nsSet != NULL))) {
13639: 
13640: 	int nsFound, absentFound = 0;
13641: 
13642: 	if (completeWild->nsSet != NULL) {
13643: 	    cur = completeWild->nsSet;
13644: 	    curB = curWild->negNsSet;
13645: 	} else {
13646: 	    cur = curWild->nsSet;
13647: 	    curB = completeWild->negNsSet;
13648: 	}
13649: 	nsFound = 0;
13650: 	while (cur != NULL) {
13651: 	    if (cur->value == NULL)
13652: 		absentFound = 1;
13653: 	    else if (cur->value == curB->value)
13654: 		nsFound = 1;
13655: 	    if (nsFound && absentFound)
13656: 		break;
13657: 	    cur = cur->next;
13658: 	}
13659: 
13660: 	if (nsFound && absentFound) {
13661: 	    /*
13662: 	    * 5.1 If the set S includes both the negated namespace
13663: 	    * name and �absent�, then any must be the value.
13664: 	    */
13665: 	    completeWild->any = 1;
13666: 	    if (completeWild->nsSet != NULL) {
13667: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13668: 		completeWild->nsSet = NULL;
13669: 	    }
13670: 	    if (completeWild->negNsSet != NULL) {
13671: 		xmlFree(completeWild->negNsSet);
13672: 		completeWild->negNsSet = NULL;
13673: 	    }
13674: 	} else if (nsFound && (!absentFound)) {
13675: 	    /*
13676: 	    * 5.2 If the set S includes the negated namespace name
13677: 	    * but not �absent�, then a pair of not and �absent� must
13678: 	    * be the value.
13679: 	    */
13680: 	    if (completeWild->nsSet != NULL) {
13681: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13682: 		completeWild->nsSet = NULL;
13683: 	    }
13684: 	    if (completeWild->negNsSet == NULL) {
13685: 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13686: 		if (completeWild->negNsSet == NULL)
13687: 		    return (-1);
13688: 	    }
13689: 	    completeWild->negNsSet->value = NULL;
13690: 	} else if ((!nsFound) && absentFound) {
13691: 	    /*
13692: 	    * 5.3 If the set S includes �absent� but not the negated
13693: 	    * namespace name, then the union is not expressible.
13694: 	    */
13695: 	    xmlSchemaPErr(ctxt, completeWild->node,
13696: 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13697: 		"The union of the wilcard is not expressible.\n",
13698: 		NULL, NULL);
13699: 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13700: 	} else if ((!nsFound) && (!absentFound)) {
13701: 	    /*
13702: 	    * 5.4 If the set S does not include either the negated namespace
13703: 	    * name or �absent�, then whichever of O1 or O2 is a pair of not
13704: 	    * and a namespace name must be the value.
13705: 	    */
13706: 	    if (completeWild->negNsSet == NULL) {
13707: 		if (completeWild->nsSet != NULL) {
13708: 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13709: 		    completeWild->nsSet = NULL;
13710: 		}
13711: 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13712: 		if (completeWild->negNsSet == NULL)
13713: 		    return (-1);
13714: 		completeWild->negNsSet->value = curWild->negNsSet->value;
13715: 	    }
13716: 	}
13717: 	return (0);
13718:     }
13719:     /*
13720:      * 6.
13721:      */
13722:     if (((completeWild->negNsSet != NULL) &&
13723: 	(completeWild->negNsSet->value == NULL) &&
13724: 	(curWild->nsSet != NULL)) ||
13725: 	((curWild->negNsSet != NULL) &&
13726: 	(curWild->negNsSet->value == NULL) &&
13727: 	(completeWild->nsSet != NULL))) {
13728: 
13729: 	if (completeWild->nsSet != NULL) {
13730: 	    cur = completeWild->nsSet;
13731: 	} else {
13732: 	    cur = curWild->nsSet;
13733: 	}
13734: 	while (cur != NULL) {
13735: 	    if (cur->value == NULL) {
13736: 		/*
13737: 		* 6.1 If the set S includes �absent�, then any must be the
13738: 		* value.
13739: 		*/
13740: 		completeWild->any = 1;
13741: 		if (completeWild->nsSet != NULL) {
13742: 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13743: 		    completeWild->nsSet = NULL;
13744: 		}
13745: 		if (completeWild->negNsSet != NULL) {
13746: 		    xmlFree(completeWild->negNsSet);
13747: 		    completeWild->negNsSet = NULL;
13748: 		}
13749: 		return (0);
13750: 	    }
13751: 	    cur = cur->next;
13752: 	}
13753: 	if (completeWild->negNsSet == NULL) {
13754: 	    /*
13755: 	    * 6.2 If the set S does not include �absent�, then a pair of not
13756: 	    * and �absent� must be the value.
13757: 	    */
13758: 	    if (completeWild->nsSet != NULL) {
13759: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13760: 		completeWild->nsSet = NULL;
13761: 	    }
13762: 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13763: 	    if (completeWild->negNsSet == NULL)
13764: 		return (-1);
13765: 	    completeWild->negNsSet->value = NULL;
13766: 	}
13767: 	return (0);
13768:     }
13769:     return (0);
13770: 
13771: }
13772: 
13773: /**
13774:  * xmlSchemaIntersectWildcards:
13775:  * @ctxt:  the schema parser context
13776:  * @completeWild:  the first wildcard
13777:  * @curWild: the second wildcard
13778:  *
13779:  * Intersects the namespace constraints of the given wildcards.
13780:  * @completeWild will hold the resulting intersection.
13781:  * Returns a positive error code on failure, -1 in case of an
13782:  * internal error, 0 otherwise.
13783:  */
13784: static int
13785: xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13786: 			    xmlSchemaWildcardPtr completeWild,
13787: 			    xmlSchemaWildcardPtr curWild)
13788: {
13789:     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13790: 
13791:     /*
13792:     * 1 If O1 and O2 are the same value, then that value must be the
13793:     * value.
13794:     */
13795:     if ((completeWild->any == curWild->any) &&
13796: 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13797: 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13798: 
13799: 	if ((completeWild->negNsSet == NULL) ||
13800: 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13801: 
13802: 	    if (completeWild->nsSet != NULL) {
13803: 		int found = 0;
13804: 
13805: 		/*
13806: 		* Check equality of sets.
13807: 		*/
13808: 		cur = completeWild->nsSet;
13809: 		while (cur != NULL) {
13810: 		    found = 0;
13811: 		    curB = curWild->nsSet;
13812: 		    while (curB != NULL) {
13813: 			if (cur->value == curB->value) {
13814: 			    found = 1;
13815: 			    break;
13816: 			}
13817: 			curB = curB->next;
13818: 		    }
13819: 		    if (!found)
13820: 			break;
13821: 		    cur = cur->next;
13822: 		}
13823: 		if (found)
13824: 		    return(0);
13825: 	    } else
13826: 		return(0);
13827: 	}
13828:     }
13829:     /*
13830:     * 2 If either O1 or O2 is any, then the other must be the value.
13831:     */
13832:     if ((completeWild->any != curWild->any) && (completeWild->any)) {
13833: 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13834: 	    return(-1);
13835: 	return(0);
13836:     }
13837:     /*
13838:     * 3 If either O1 or O2 is a pair of not and a value (a namespace
13839:     * name or �absent�) and the other is a set of (namespace names or
13840:     * �absent�), then that set, minus the negated value if it was in
13841:     * the set, minus �absent� if it was in the set, must be the value.
13842:     */
13843:     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13844: 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13845: 	const xmlChar *neg;
13846: 
13847: 	if (completeWild->nsSet == NULL) {
13848: 	    neg = completeWild->negNsSet->value;
13849: 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13850: 		return(-1);
13851: 	} else
13852: 	    neg = curWild->negNsSet->value;
13853: 	/*
13854: 	* Remove absent and negated.
13855: 	*/
13856: 	prev = NULL;
13857: 	cur = completeWild->nsSet;
13858: 	while (cur != NULL) {
13859: 	    if (cur->value == NULL) {
13860: 		if (prev == NULL)
13861: 		    completeWild->nsSet = cur->next;
13862: 		else
13863: 		    prev->next = cur->next;
13864: 		xmlFree(cur);
13865: 		break;
13866: 	    }
13867: 	    prev = cur;
13868: 	    cur = cur->next;
13869: 	}
13870: 	if (neg != NULL) {
13871: 	    prev = NULL;
13872: 	    cur = completeWild->nsSet;
13873: 	    while (cur != NULL) {
13874: 		if (cur->value == neg) {
13875: 		    if (prev == NULL)
13876: 			completeWild->nsSet = cur->next;
13877: 		    else
13878: 			prev->next = cur->next;
13879: 		    xmlFree(cur);
13880: 		    break;
13881: 		}
13882: 		prev = cur;
13883: 		cur = cur->next;
13884: 	    }
13885: 	}
13886: 
13887: 	return(0);
13888:     }
13889:     /*
13890:     * 4 If both O1 and O2 are sets of (namespace names or �absent�),
13891:     * then the intersection of those sets must be the value.
13892:     */
13893:     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13894: 	int found;
13895: 
13896: 	cur = completeWild->nsSet;
13897: 	prev = NULL;
13898: 	while (cur != NULL) {
13899: 	    found = 0;
13900: 	    curB = curWild->nsSet;
13901: 	    while (curB != NULL) {
13902: 		if (cur->value == curB->value) {
13903: 		    found = 1;
13904: 		    break;
13905: 		}
13906: 		curB = curB->next;
13907: 	    }
13908: 	    if (!found) {
13909: 		if (prev == NULL)
13910: 		    completeWild->nsSet = cur->next;
13911: 		else
13912: 		    prev->next = cur->next;
13913: 		tmp = cur->next;
13914: 		xmlFree(cur);
13915: 		cur = tmp;
13916: 		continue;
13917: 	    }
13918: 	    prev = cur;
13919: 	    cur = cur->next;
13920: 	}
13921: 
13922: 	return(0);
13923:     }
13924:     /* 5 If the two are negations of different namespace names,
13925:     * then the intersection is not expressible
13926:     */
13927:     if ((completeWild->negNsSet != NULL) &&
13928: 	(curWild->negNsSet != NULL) &&
13929: 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13930: 	(completeWild->negNsSet->value != NULL) &&
13931: 	(curWild->negNsSet->value != NULL)) {
13932: 
13933: 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13934: 	    "The intersection of the wilcard is not expressible.\n",
13935: 	    NULL, NULL);
13936: 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13937:     }
13938:     /*
13939:     * 6 If the one is a negation of a namespace name and the other
13940:     * is a negation of �absent�, then the one which is the negation
13941:     * of a namespace name must be the value.
13942:     */
13943:     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13944: 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13945: 	(completeWild->negNsSet->value == NULL)) {
13946: 	completeWild->negNsSet->value =  curWild->negNsSet->value;
13947:     }
13948:     return(0);
13949: }
13950: 
13951: /**
13952:  * xmlSchemaIsWildcardNsConstraintSubset:
13953:  * @ctxt:  the schema parser context
13954:  * @sub:  the first wildcard
13955:  * @super: the second wildcard
13956:  *
13957:  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13958:  *
13959:  * Returns 0 if the namespace constraint of @sub is an intensional
13960:  * subset of @super, 1 otherwise.
13961:  */
13962: static int
13963: xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13964: 			  xmlSchemaWildcardPtr super)
13965: {
13966:     /*
13967:     * 1 super must be any.
13968:     */
13969:     if (super->any)
13970: 	return (0);
13971:     /*
13972:     * 2.1 sub must be a pair of not and a namespace name or �absent�.
13973:     * 2.2 super must be a pair of not and the same value.
13974:     */
13975:     if ((sub->negNsSet != NULL) &&
13976: 	(super->negNsSet != NULL) &&
13977: 	(sub->negNsSet->value == super->negNsSet->value))
13978: 	return (0);
13979:     /*
13980:     * 3.1 sub must be a set whose members are either namespace names or �absent�.
13981:     */
13982:     if (sub->nsSet != NULL) {
13983: 	/*
13984: 	* 3.2.1 super must be the same set or a superset thereof.
13985: 	*/
13986: 	if (super->nsSet != NULL) {
13987: 	    xmlSchemaWildcardNsPtr cur, curB;
13988: 	    int found = 0;
13989: 
13990: 	    cur = sub->nsSet;
13991: 	    while (cur != NULL) {
13992: 		found = 0;
13993: 		curB = super->nsSet;
13994: 		while (curB != NULL) {
13995: 		    if (cur->value == curB->value) {
13996: 			found = 1;
13997: 			break;
13998: 		    }
13999: 		    curB = curB->next;
14000: 		}
14001: 		if (!found)
14002: 		    return (1);
14003: 		cur = cur->next;
14004: 	    }
14005: 	    if (found)
14006: 		return (0);
14007: 	} else if (super->negNsSet != NULL) {
14008: 	    xmlSchemaWildcardNsPtr cur;
14009: 	    /*
14010: 	    * 3.2.2 super must be a pair of not and a namespace name or
14011: 	    * �absent� and that value must not be in sub's set.
14012: 	    */
14013: 	    cur = sub->nsSet;
14014: 	    while (cur != NULL) {
14015: 		if (cur->value == super->negNsSet->value)
14016: 		    return (1);
14017: 		cur = cur->next;
14018: 	    }
14019: 	    return (0);
14020: 	}
14021:     }
14022:     return (1);
14023: }
14024: 
14025: static int
14026: xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
14027: 				     int *fixed,
14028: 				     const xmlChar **value,
14029: 				     xmlSchemaValPtr *val)
14030: {
14031:     *fixed = 0;
14032:     *value = NULL;
14033:     if (val != 0)
14034: 	*val = NULL;
14035: 
14036:     if (attruse->defValue != NULL) {
14037: 	*value = attruse->defValue;
14038: 	if (val != NULL)
14039: 	    *val = attruse->defVal;
14040: 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14041: 	    *fixed = 1;
14042: 	return(1);
14043:     } else if ((attruse->attrDecl != NULL) &&
14044: 	(attruse->attrDecl->defValue != NULL)) {
14045: 	*value = attruse->attrDecl->defValue;
14046: 	if (val != NULL)
14047: 	    *val = attruse->attrDecl->defVal;
14048: 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14049: 	    *fixed = 1;
14050: 	return(1);
14051:     }
14052:     return(0);
14053: }
14054: /**
14055:  * xmlSchemaCheckCVCWildcardNamespace:
14056:  * @wild:  the wildcard
14057:  * @ns:  the namespace
14058:  *
14059:  * Validation Rule: Wildcard allows Namespace Name
14060:  * (cvc-wildcard-namespace)
14061:  *
14062:  * Returns 0 if the given namespace matches the wildcard,
14063:  * 1 otherwise and -1 on API errors.
14064:  */
14065: static int
14066: xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14067: 				   const xmlChar* ns)
14068: {
14069:     if (wild == NULL)
14070: 	return(-1);
14071: 
14072:     if (wild->any)
14073: 	return(0);
14074:     else if (wild->nsSet != NULL) {
14075: 	xmlSchemaWildcardNsPtr cur;
14076: 
14077: 	cur = wild->nsSet;
14078: 	while (cur != NULL) {
14079: 	    if (xmlStrEqual(cur->value, ns))
14080: 		return(0);
14081: 	    cur = cur->next;
14082: 	}
14083:     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14084: 	(!xmlStrEqual(wild->negNsSet->value, ns)))
14085: 	return(0);
14086: 
14087:     return(1);
14088: }
14089: 
14090: #define XML_SCHEMA_ACTION_DERIVE 0
14091: #define XML_SCHEMA_ACTION_REDEFINE 1
14092: 
14093: #define WXS_ACTION_STR(a) \
14094: ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14095: 
14096: /*
14097: * Schema Component Constraint:
14098: *   Derivation Valid (Restriction, Complex)
14099: *   derivation-ok-restriction (2) - (4)
14100: *
14101: * ATTENTION:
14102: * In XML Schema 1.1 this will be:
14103: * Validation Rule:
14104: *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14105: *
14106: */
14107: static int
14108: xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14109: 				       int action,
14110: 				       xmlSchemaBasicItemPtr item,
14111: 				       xmlSchemaBasicItemPtr baseItem,
14112: 				       xmlSchemaItemListPtr uses,
14113: 				       xmlSchemaItemListPtr baseUses,
14114: 				       xmlSchemaWildcardPtr wild,
14115: 				       xmlSchemaWildcardPtr baseWild)
14116: {
14117:     xmlSchemaAttributeUsePtr cur = NULL, bcur;
14118:     int i, j, found; /* err = 0; */
14119:     const xmlChar *bEffValue;
14120:     int effFixed;
14121: 
14122:     if (uses != NULL) {
14123: 	for (i = 0; i < uses->nbItems; i++) {
14124: 	    cur = uses->items[i];
14125: 	    found = 0;
14126: 	    if (baseUses == NULL)
14127: 		goto not_found;
14128: 	    for (j = 0; j < baseUses->nbItems; j++) {
14129: 		bcur = baseUses->items[j];
14130: 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14131: 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
14132: 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
14133: 			WXS_ATTRUSE_DECL_TNS(bcur)))
14134: 		{
14135: 		    /*
14136: 		    * (2.1) "If there is an attribute use in the {attribute
14137: 		    * uses} of the {base type definition} (call this B) whose
14138: 		    * {attribute declaration} has the same {name} and {target
14139: 		    * namespace}, then  all of the following must be true:"
14140: 		    */
14141: 		    found = 1;
14142: 
14143: 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14144: 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14145: 		    {
14146: 			xmlChar *str = NULL;
14147: 			/*
14148: 			* (2.1.1) "one of the following must be true:"
14149: 			* (2.1.1.1) "B's {required} is false."
14150: 			* (2.1.1.2) "R's {required} is true."
14151: 			*/
14152: 			xmlSchemaPAttrUseErr4(pctxt,
14153: 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14154: 			    WXS_ITEM_NODE(item), item, cur,
14155: 			    "The 'optional' attribute use is inconsistent "
14156: 			    "with the corresponding 'required' attribute use of "
14157: 			    "the %s %s",
14158: 			    WXS_ACTION_STR(action),
14159: 			    xmlSchemaGetComponentDesignation(&str, baseItem),
14160: 			    NULL, NULL);
14161: 			FREE_AND_NULL(str);
14162: 			/* err = pctxt->err; */
14163: 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14164: 			WXS_ATTRUSE_TYPEDEF(cur),
14165: 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14166: 		    {
14167: 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14168: 
14169: 			/*
14170: 			* SPEC (2.1.2) "R's {attribute declaration}'s
14171: 			* {type definition} must be validly derived from
14172: 			* B's {type definition} given the empty set as
14173: 			* defined in Type Derivation OK (Simple) (�3.14.6)."
14174: 			*/
14175: 			xmlSchemaPAttrUseErr4(pctxt,
14176: 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14177: 			    WXS_ITEM_NODE(item), item, cur,
14178: 			    "The attribute declaration's %s "
14179: 			    "is not validly derived from "
14180: 			    "the corresponding %s of the "
14181: 			    "attribute declaration in the %s %s",
14182: 			    xmlSchemaGetComponentDesignation(&strA,
14183: 				WXS_ATTRUSE_TYPEDEF(cur)),
14184: 			    xmlSchemaGetComponentDesignation(&strB,
14185: 				WXS_ATTRUSE_TYPEDEF(bcur)),
14186: 			    WXS_ACTION_STR(action),
14187: 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
14188: 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14189: 			FREE_AND_NULL(strA);
14190: 			FREE_AND_NULL(strB);
14191: 			FREE_AND_NULL(strC);
14192: 			/* err = pctxt->err; */
14193: 		    } else {
14194: 			/*
14195: 			* 2.1.3 [Definition:]  Let the effective value
14196: 			* constraint of an attribute use be its {value
14197: 			* constraint}, if present, otherwise its {attribute
14198: 			* declaration}'s {value constraint} .
14199: 			*/
14200: 			xmlSchemaGetEffectiveValueConstraint(bcur,
14201: 			    &effFixed, &bEffValue, NULL);
14202: 			/*
14203: 			* 2.1.3 ... one of the following must be true
14204: 			*
14205: 			* 2.1.3.1 B's �effective value constraint� is
14206: 			* �absent� or default.
14207: 			*/
14208: 			if ((bEffValue != NULL) &&
14209: 			    (effFixed == 1)) {
14210: 			    const xmlChar *rEffValue = NULL;
14211: 
14212: 			    xmlSchemaGetEffectiveValueConstraint(bcur,
14213: 				&effFixed, &rEffValue, NULL);
14214: 			    /*
14215: 			    * 2.1.3.2 R's �effective value constraint� is
14216: 			    * fixed with the same string as B's.
14217: 			    * MAYBE TODO: Compare the computed values.
14218: 			    *       Hmm, it says "same string" so
14219: 			    *       string-equality might really be sufficient.
14220: 			    */
14221: 			    if ((effFixed == 0) ||
14222: 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14223: 			    {
14224: 				xmlChar *str = NULL;
14225: 
14226: 				xmlSchemaPAttrUseErr4(pctxt,
14227: 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14228: 				    WXS_ITEM_NODE(item), item, cur,
14229: 				    "The effective value constraint of the "
14230: 				    "attribute use is inconsistent with "
14231: 				    "its correspondent in the %s %s",
14232: 				    WXS_ACTION_STR(action),
14233: 				    xmlSchemaGetComponentDesignation(&str,
14234: 					baseItem),
14235: 				    NULL, NULL);
14236: 				FREE_AND_NULL(str);
14237: 				/* err = pctxt->err; */
14238: 			    }
14239: 			}
14240: 		    }
14241: 		    break;
14242: 		}
14243: 	    }
14244: not_found:
14245: 	    if (!found) {
14246: 		/*
14247: 		* (2.2) "otherwise the {base type definition} must have an
14248: 		* {attribute wildcard} and the {target namespace} of the
14249: 		* R's {attribute declaration} must be �valid� with respect
14250: 		* to that wildcard, as defined in Wildcard allows Namespace
14251: 		* Name (�3.10.4)."
14252: 		*/
14253: 		if ((baseWild == NULL) ||
14254: 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14255: 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14256: 		{
14257: 		    xmlChar *str = NULL;
14258: 
14259: 		    xmlSchemaPAttrUseErr4(pctxt,
14260: 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14261: 			WXS_ITEM_NODE(item), item, cur,
14262: 			"Neither a matching attribute use, "
14263: 			"nor a matching wildcard exists in the %s %s",
14264: 			WXS_ACTION_STR(action),
14265: 			xmlSchemaGetComponentDesignation(&str, baseItem),
14266: 			NULL, NULL);
14267: 		    FREE_AND_NULL(str);
14268: 		    /* err = pctxt->err; */
14269: 		}
14270: 	    }
14271: 	}
14272:     }
14273:     /*
14274:     * SPEC derivation-ok-restriction (3):
14275:     * (3) "For each attribute use in the {attribute uses} of the {base type
14276:     * definition} whose {required} is true, there must be an attribute
14277:     * use with an {attribute declaration} with the same {name} and
14278:     * {target namespace} as its {attribute declaration} in the {attribute
14279:     * uses} of the complex type definition itself whose {required} is true.
14280:     */
14281:     if (baseUses != NULL) {
14282: 	for (j = 0; j < baseUses->nbItems; j++) {
14283: 	    bcur = baseUses->items[j];
14284: 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14285: 		continue;
14286: 	    found = 0;
14287: 	    if (uses != NULL) {
14288: 		for (i = 0; i < uses->nbItems; i++) {
14289: 		    cur = uses->items[i];
14290: 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14291: 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
14292: 			(WXS_ATTRUSE_DECL_TNS(cur) ==
14293: 			WXS_ATTRUSE_DECL_TNS(bcur))) {
14294: 			found = 1;
14295: 			break;
14296: 		    }
14297: 		}
14298: 	    }
14299: 	    if (!found) {
14300: 		xmlChar *strA = NULL, *strB = NULL;
14301: 
14302: 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14303: 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14304: 		    NULL, item,
14305: 		    "A matching attribute use for the "
14306: 		    "'required' %s of the %s %s is missing",
14307: 		    xmlSchemaGetComponentDesignation(&strA, bcur),
14308: 		    WXS_ACTION_STR(action),
14309: 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
14310: 		    NULL);
14311: 		FREE_AND_NULL(strA);
14312: 		FREE_AND_NULL(strB);
14313: 	    }
14314: 	}
14315:     }
14316:     /*
14317:     * derivation-ok-restriction (4)
14318:     */
14319:     if (wild != NULL) {
14320: 	/*
14321: 	* (4) "If there is an {attribute wildcard}, all of the
14322: 	* following must be true:"
14323: 	*/
14324: 	if (baseWild == NULL) {
14325: 	    xmlChar *str = NULL;
14326: 
14327: 	    /*
14328: 	    * (4.1) "The {base type definition} must also have one."
14329: 	    */
14330: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14331: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14332: 		NULL, item,
14333: 		"The %s has an attribute wildcard, "
14334: 		"but the %s %s '%s' does not have one",
14335: 		WXS_ITEM_TYPE_NAME(item),
14336: 		WXS_ACTION_STR(action),
14337: 		WXS_ITEM_TYPE_NAME(baseItem),
14338: 		xmlSchemaGetComponentQName(&str, baseItem));
14339: 	    FREE_AND_NULL(str);
14340: 	    return(pctxt->err);
14341: 	} else if ((baseWild->any == 0) &&
14342: 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
14343: 	{
14344: 	    xmlChar *str = NULL;
14345: 	    /*
14346: 	    * (4.2) "The complex type definition's {attribute wildcard}'s
14347: 	    * {namespace constraint} must be a subset of the {base type
14348: 	    * definition}'s {attribute wildcard}'s {namespace constraint},
14349: 	    * as defined by Wildcard Subset (�3.10.6)."
14350: 	    */
14351: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14352: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14353: 		NULL, item,
14354: 		"The attribute wildcard is not a valid "
14355: 		"subset of the wildcard in the %s %s '%s'",
14356: 		WXS_ACTION_STR(action),
14357: 		WXS_ITEM_TYPE_NAME(baseItem),
14358: 		xmlSchemaGetComponentQName(&str, baseItem),
14359: 		NULL);
14360: 	    FREE_AND_NULL(str);
14361: 	    return(pctxt->err);
14362: 	}
14363: 	/* 4.3 Unless the {base type definition} is the �ur-type
14364: 	* definition�, the complex type definition's {attribute
14365: 	* wildcard}'s {process contents} must be identical to or
14366: 	* stronger than the {base type definition}'s {attribute
14367: 	* wildcard}'s {process contents}, where strict is stronger
14368: 	* than lax is stronger than skip.
14369: 	*/
14370: 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
14371: 	    (wild->processContents < baseWild->processContents)) {
14372: 	    xmlChar *str = NULL;
14373: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14374: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14375: 		NULL, baseItem,
14376: 		"The {process contents} of the attribute wildcard is "
14377: 		"weaker than the one in the %s %s '%s'",
14378: 		WXS_ACTION_STR(action),
14379: 		WXS_ITEM_TYPE_NAME(baseItem),
14380: 		xmlSchemaGetComponentQName(&str, baseItem),
14381: 		NULL);
14382: 	    FREE_AND_NULL(str)
14383: 		return(pctxt->err);
14384: 	}
14385:     }
14386:     return(0);
14387: }
14388: 
14389: 
14390: static int
14391: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14392: 				  xmlSchemaBasicItemPtr item,
14393: 				  xmlSchemaWildcardPtr *completeWild,
14394: 				  xmlSchemaItemListPtr list,
14395: 				  xmlSchemaItemListPtr prohibs);
14396: /**
14397:  * xmlSchemaFixupTypeAttributeUses:
14398:  * @ctxt:  the schema parser context
14399:  * @type:  the complex type definition
14400:  *
14401:  *
14402:  * Builds the wildcard and the attribute uses on the given complex type.
14403:  * Returns -1 if an internal error occurs, 0 otherwise.
14404:  *
14405:  * ATTENTION TODO: Experimantally this uses pointer comparisons for
14406:  * strings, so recheck this if we start to hardcode some schemata, since
14407:  * they might not be in the same dict.
14408:  * NOTE: It is allowed to "extend" the xs:anyType type.
14409:  */
14410: static int
14411: xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14412: 				  xmlSchemaTypePtr type)
14413: {
14414:     xmlSchemaTypePtr baseType = NULL;
14415:     xmlSchemaAttributeUsePtr use;
14416:     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14417: 
14418:     if (type->baseType == NULL) {
14419: 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14420: 	    "no base type");
14421:         return (-1);
14422:     }
14423:     baseType = type->baseType;
14424:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
14425: 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14426: 	    return(-1);
14427: 
14428:     uses = type->attrUses;
14429:     baseUses = baseType->attrUses;
14430:     /*
14431:     * Expand attribute group references. And build the 'complete'
14432:     * wildcard, i.e. intersect multiple wildcards.
14433:     * Move attribute prohibitions into a separate list.
14434:     */
14435:     if (uses != NULL) {
14436: 	if (WXS_IS_RESTRICTION(type)) {
14437: 	    /*
14438: 	    * This one will transfer all attr. prohibitions
14439: 	    * into pctxt->attrProhibs.
14440: 	    */
14441: 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14442: 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14443: 		pctxt->attrProhibs) == -1)
14444: 	    {
14445: 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14446: 		"failed to expand attributes");
14447: 	    }
14448: 	    if (pctxt->attrProhibs->nbItems != 0)
14449: 		prohibs = pctxt->attrProhibs;
14450: 	} else {
14451: 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14452: 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14453: 		NULL) == -1)
14454: 	    {
14455: 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14456: 		"failed to expand attributes");
14457: 	    }
14458: 	}
14459:     }
14460:     /*
14461:     * Inherit the attribute uses of the base type.
14462:     */
14463:     if (baseUses != NULL) {
14464: 	int i, j;
14465: 	xmlSchemaAttributeUseProhibPtr pro;
14466: 
14467: 	if (WXS_IS_RESTRICTION(type)) {
14468: 	    int usesCount;
14469: 	    xmlSchemaAttributeUsePtr tmp;
14470: 
14471: 	    if (uses != NULL)
14472: 		usesCount = uses->nbItems;
14473: 	    else
14474: 		usesCount = 0;
14475: 
14476: 	    /* Restriction. */
14477: 	    for (i = 0; i < baseUses->nbItems; i++) {
14478: 		use = baseUses->items[i];
14479: 		if (prohibs) {
14480: 		    /*
14481: 		    * Filter out prohibited uses.
14482: 		    */
14483: 		    for (j = 0; j < prohibs->nbItems; j++) {
14484: 			pro = prohibs->items[j];
14485: 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14486: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
14487: 				pro->targetNamespace))
14488: 			{
14489: 			    goto inherit_next;
14490: 			}
14491: 		    }
14492: 		}
14493: 		if (usesCount) {
14494: 		    /*
14495: 		    * Filter out existing uses.
14496: 		    */
14497: 		    for (j = 0; j < usesCount; j++) {
14498: 			tmp = uses->items[j];
14499: 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
14500: 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
14501: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
14502: 				WXS_ATTRUSE_DECL_TNS(tmp)))
14503: 			{
14504: 			    goto inherit_next;
14505: 			}
14506: 		    }
14507: 		}
14508: 		if (uses == NULL) {
14509: 		    type->attrUses = xmlSchemaItemListCreate();
14510: 		    if (type->attrUses == NULL)
14511: 			goto exit_failure;
14512: 		    uses = type->attrUses;
14513: 		}
14514: 		xmlSchemaItemListAddSize(uses, 2, use);
14515: inherit_next: {}
14516: 	    }
14517: 	} else {
14518: 	    /* Extension. */
14519: 	    for (i = 0; i < baseUses->nbItems; i++) {
14520: 		use = baseUses->items[i];
14521: 		if (uses == NULL) {
14522: 		    type->attrUses = xmlSchemaItemListCreate();
14523: 		    if (type->attrUses == NULL)
14524: 			goto exit_failure;
14525: 		    uses = type->attrUses;
14526: 		}
14527: 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14528: 	    }
14529: 	}
14530:     }
14531:     /*
14532:     * Shrink attr. uses.
14533:     */
14534:     if (uses) {
14535: 	if (uses->nbItems == 0) {
14536: 	    xmlSchemaItemListFree(uses);
14537: 	    type->attrUses = NULL;
14538: 	}
14539: 	/*
14540: 	* TODO: We could shrink the size of the array
14541: 	* to fit the actual number of items.
14542: 	*/
14543:     }
14544:     /*
14545:     * Compute the complete wildcard.
14546:     */
14547:     if (WXS_IS_EXTENSION(type)) {
14548: 	if (baseType->attributeWildcard != NULL) {
14549: 	    /*
14550: 	    * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
14551: 	    * the appropriate case among the following:"
14552: 	    */
14553: 	    if (type->attributeWildcard != NULL) {
14554: 		/*
14555: 		* Union the complete wildcard with the base wildcard.
14556: 		* SPEC {attribute wildcard}
14557: 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14558: 		* and {annotation} are those of the �complete wildcard�,
14559: 		* and whose {namespace constraint} is the intensional union
14560: 		* of the {namespace constraint} of the �complete wildcard�
14561: 		* and of the �base wildcard�, as defined in Attribute
14562: 		* Wildcard Union (�3.10.6)."
14563: 		*/
14564: 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14565: 		    baseType->attributeWildcard) == -1)
14566: 		    goto exit_failure;
14567: 	    } else {
14568: 		/*
14569: 		* (3.2.2.1.1) "If the �complete wildcard� is �absent�,
14570: 		* then the �base wildcard�."
14571: 		*/
14572: 		type->attributeWildcard = baseType->attributeWildcard;
14573: 	    }
14574: 	} else {
14575: 	    /*
14576: 	    * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
14577: 	    * �complete wildcard"
14578: 	    * NOOP
14579: 	    */
14580: 	}
14581:     } else {
14582: 	/*
14583: 	* SPEC {attribute wildcard}
14584: 	* (3.1) "If the <restriction> alternative is chosen, then the
14585: 	* �complete wildcard�;"
14586: 	* NOOP
14587: 	*/
14588:     }
14589: 
14590:     return (0);
14591: 
14592: exit_failure:
14593:     return(-1);
14594: }
14595: 
14596: /**
14597:  * xmlSchemaTypeFinalContains:
14598:  * @schema:  the schema
14599:  * @type:  the type definition
14600:  * @final: the final
14601:  *
14602:  * Evaluates if a type definition contains the given "final".
14603:  * This does take "finalDefault" into account as well.
14604:  *
14605:  * Returns 1 if the type does containt the given "final",
14606:  * 0 otherwise.
14607:  */
14608: static int
14609: xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14610: {
14611:     if (type == NULL)
14612: 	return (0);
14613:     if (type->flags & final)
14614: 	return (1);
14615:     else
14616: 	return (0);
14617: }
14618: 
14619: /**
14620:  * xmlSchemaGetUnionSimpleTypeMemberTypes:
14621:  * @type:  the Union Simple Type
14622:  *
14623:  * Returns a list of member types of @type if existing,
14624:  * returns NULL otherwise.
14625:  */
14626: static xmlSchemaTypeLinkPtr
14627: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14628: {
14629:     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14630: 	if (type->memberTypes != NULL)
14631: 	    return (type->memberTypes);
14632: 	else
14633: 	    type = type->baseType;
14634:     }
14635:     return (NULL);
14636: }
14637: 
14638: /**
14639:  * xmlSchemaGetParticleTotalRangeMin:
14640:  * @particle: the particle
14641:  *
14642:  * Schema Component Constraint: Effective Total Range
14643:  * (all and sequence) + (choice)
14644:  *
14645:  * Returns the minimun Effective Total Range.
14646:  */
14647: static int
14648: xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14649: {
14650:     if ((particle->children == NULL) ||
14651: 	(particle->minOccurs == 0))
14652: 	return (0);
14653:     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14654: 	int min = -1, cur;
14655: 	xmlSchemaParticlePtr part =
14656: 	    (xmlSchemaParticlePtr) particle->children->children;
14657: 
14658: 	if (part == NULL)
14659: 	    return (0);
14660: 	while (part != NULL) {
14661: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14662: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14663: 		cur = part->minOccurs;
14664: 	    else
14665: 		cur = xmlSchemaGetParticleTotalRangeMin(part);
14666: 	    if (cur == 0)
14667: 		return (0);
14668: 	    if ((min > cur) || (min == -1))
14669: 		min = cur;
14670: 	    part = (xmlSchemaParticlePtr) part->next;
14671: 	}
14672: 	return (particle->minOccurs * min);
14673:     } else {
14674: 	/* <all> and <sequence> */
14675: 	int sum = 0;
14676: 	xmlSchemaParticlePtr part =
14677: 	    (xmlSchemaParticlePtr) particle->children->children;
14678: 
14679: 	if (part == NULL)
14680: 	    return (0);
14681: 	do {
14682: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14683: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14684: 		sum += part->minOccurs;
14685: 	    else
14686: 		sum += xmlSchemaGetParticleTotalRangeMin(part);
14687: 	    part = (xmlSchemaParticlePtr) part->next;
14688: 	} while (part != NULL);
14689: 	return (particle->minOccurs * sum);
14690:     }
14691: }
14692: 
14693: #if 0
14694: /**
14695:  * xmlSchemaGetParticleTotalRangeMax:
14696:  * @particle: the particle
14697:  *
14698:  * Schema Component Constraint: Effective Total Range
14699:  * (all and sequence) + (choice)
14700:  *
14701:  * Returns the maximum Effective Total Range.
14702:  */
14703: static int
14704: xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14705: {
14706:     if ((particle->children == NULL) ||
14707: 	(particle->children->children == NULL))
14708: 	return (0);
14709:     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14710: 	int max = -1, cur;
14711: 	xmlSchemaParticlePtr part =
14712: 	    (xmlSchemaParticlePtr) particle->children->children;
14713: 
14714: 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14715: 	    if (part->children == NULL)
14716: 		continue;
14717: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14718: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14719: 		cur = part->maxOccurs;
14720: 	    else
14721: 		cur = xmlSchemaGetParticleTotalRangeMax(part);
14722: 	    if (cur == UNBOUNDED)
14723: 		return (UNBOUNDED);
14724: 	    if ((max < cur) || (max == -1))
14725: 		max = cur;
14726: 	}
14727: 	/* TODO: Handle overflows? */
14728: 	return (particle->maxOccurs * max);
14729:     } else {
14730: 	/* <all> and <sequence> */
14731: 	int sum = 0, cur;
14732: 	xmlSchemaParticlePtr part =
14733: 	    (xmlSchemaParticlePtr) particle->children->children;
14734: 
14735: 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14736: 	    if (part->children == NULL)
14737: 		continue;
14738: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14739: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14740: 		cur = part->maxOccurs;
14741: 	    else
14742: 		cur = xmlSchemaGetParticleTotalRangeMax(part);
14743: 	    if (cur == UNBOUNDED)
14744: 		return (UNBOUNDED);
14745: 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14746: 		return (UNBOUNDED);
14747: 	    sum += cur;
14748: 	}
14749: 	/* TODO: Handle overflows? */
14750: 	return (particle->maxOccurs * sum);
14751:     }
14752: }
14753: #endif
14754: 
14755: /**
14756:  * xmlSchemaIsParticleEmptiable:
14757:  * @particle: the particle
14758:  *
14759:  * Schema Component Constraint: Particle Emptiable
14760:  * Checks whether the given particle is emptiable.
14761:  *
14762:  * Returns 1 if emptiable, 0 otherwise.
14763:  */
14764: static int
14765: xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14766: {
14767:     /*
14768:     * SPEC (1) "Its {min occurs} is 0."
14769:     */
14770:     if ((particle == NULL) || (particle->minOccurs == 0) ||
14771: 	(particle->children == NULL))
14772: 	return (1);
14773:     /*
14774:     * SPEC (2) "Its {term} is a group and the minimum part of the
14775:     * effective total range of that group, [...] is 0."
14776:     */
14777:     if (WXS_IS_MODEL_GROUP(particle->children)) {
14778: 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
14779: 	    return (1);
14780:     }
14781:     return (0);
14782: }
14783: 
14784: /**
14785:  * xmlSchemaCheckCOSSTDerivedOK:
14786:  * @actxt: a context
14787:  * @type:  the derived simple type definition
14788:  * @baseType:  the base type definition
14789:  * @subset: the subset of ('restriction', ect.)
14790:  *
14791:  * Schema Component Constraint:
14792:  * Type Derivation OK (Simple) (cos-st-derived-OK)
14793:  *
14794:  * Checks wheter @type can be validly
14795:  * derived from @baseType.
14796:  *
14797:  * Returns 0 on success, an positive error code otherwise.
14798:  */
14799: static int
14800: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14801: 			     xmlSchemaTypePtr type,
14802: 			     xmlSchemaTypePtr baseType,
14803: 			     int subset)
14804: {
14805:     /*
14806:     * 1 They are the same type definition.
14807:     * TODO: The identy check might have to be more complex than this.
14808:     */
14809:     if (type == baseType)
14810: 	return (0);
14811:     /*
14812:     * 2.1 restriction is not in the subset, or in the {final}
14813:     * of its own {base type definition};
14814:     *
14815:     * NOTE that this will be used also via "xsi:type".
14816:     *
14817:     * TODO: Revise this, it looks strange. How can the "type"
14818:     * not be fixed or *in* fixing?
14819:     */
14820:     if (WXS_IS_TYPE_NOT_FIXED(type))
14821: 	if (xmlSchemaTypeFixup(type, actxt) == -1)
14822: 	    return(-1);
14823:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
14824: 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14825: 	    return(-1);
14826:     if ((subset & SUBSET_RESTRICTION) ||
14827: 	(xmlSchemaTypeFinalContains(type->baseType,
14828: 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14829: 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14830:     }
14831:     /* 2.2 */
14832:     if (type->baseType == baseType) {
14833: 	/*
14834: 	* 2.2.1 D's �base type definition� is B.
14835: 	*/
14836: 	return (0);
14837:     }
14838:     /*
14839:     * 2.2.2 D's �base type definition� is not the �ur-type definition�
14840:     * and is validly derived from B given the subset, as defined by this
14841:     * constraint.
14842:     */
14843:     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14844: 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14845: 	    baseType, subset) == 0)) {
14846: 	return (0);
14847:     }
14848:     /*
14849:     * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
14850:     * definition�.
14851:     */
14852:     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14853: 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14854: 	return (0);
14855:     }
14856:     /*
14857:     * 2.2.4 B's {variety} is union and D is validly derived from a type
14858:     * definition in B's {member type definitions} given the subset, as
14859:     * defined by this constraint.
14860:     *
14861:     * NOTE: This seems not to involve built-in types, since there is no
14862:     * built-in Union Simple Type.
14863:     */
14864:     if (WXS_IS_UNION(baseType)) {
14865: 	xmlSchemaTypeLinkPtr cur;
14866: 
14867: 	cur = baseType->memberTypes;
14868: 	while (cur != NULL) {
14869: 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14870: 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14871: 		    return(-1);
14872: 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14873: 		    type, cur->type, subset) == 0)
14874: 	    {
14875: 		/*
14876: 		* It just has to be validly derived from at least one
14877: 		* member-type.
14878: 		*/
14879: 		return (0);
14880: 	    }
14881: 	    cur = cur->next;
14882: 	}
14883:     }
14884:     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14885: }
14886: 
14887: /**
14888:  * xmlSchemaCheckTypeDefCircularInternal:
14889:  * @pctxt:  the schema parser context
14890:  * @ctxtType:  the type definition
14891:  * @ancestor: an ancestor of @ctxtType
14892:  *
14893:  * Checks st-props-correct (2) + ct-props-correct (3).
14894:  * Circular type definitions are not allowed.
14895:  *
14896:  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14897:  * circular, 0 otherwise.
14898:  */
14899: static int
14900: xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14901: 			   xmlSchemaTypePtr ctxtType,
14902: 			   xmlSchemaTypePtr ancestor)
14903: {
14904:     int ret;
14905: 
14906:     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14907: 	return (0);
14908: 
14909:     if (ctxtType == ancestor) {
14910: 	xmlSchemaPCustomErr(pctxt,
14911: 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
14912: 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14913: 	    "The definition is circular", NULL);
14914: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14915:     }
14916:     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14917: 	/*
14918: 	* Avoid inifinite recursion on circular types not yet checked.
14919: 	*/
14920: 	return (0);
14921:     }
14922:     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14923:     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14924: 	ancestor->baseType);
14925:     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14926:     return (ret);
14927: }
14928: 
14929: /**
14930:  * xmlSchemaCheckTypeDefCircular:
14931:  * @item:  the complex/simple type definition
14932:  * @ctxt:  the parser context
14933:  * @name:  the name
14934:  *
14935:  * Checks for circular type definitions.
14936:  */
14937: static void
14938: xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14939: 			      xmlSchemaParserCtxtPtr ctxt)
14940: {
14941:     if ((item == NULL) ||
14942: 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
14943: 	(item->baseType == NULL))
14944: 	return;
14945:     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14946: 	item->baseType);
14947: }
14948: 
14949: /*
14950: * Simple Type Definition Representation OK (src-simple-type) 4
14951: *
14952: * "4 Circular union type definition is disallowed. That is, if the
14953: * <union> alternative is chosen, there must not be any entries in the
14954: * memberTypes [attribute] at any depth which resolve to the component
14955: * corresponding to the <simpleType>."
14956: *
14957: * Note that this should work on the *representation* of a component,
14958: * thus assumes any union types in the member types not being yet
14959: * substituted. At this stage we need the variety of the types
14960: * to be already computed.
14961: */
14962: static int
14963: xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14964: 					xmlSchemaTypePtr ctxType,
14965: 					xmlSchemaTypeLinkPtr members)
14966: {
14967:     xmlSchemaTypeLinkPtr member;
14968:     xmlSchemaTypePtr memberType;
14969: 
14970:     member = members;
14971:     while (member != NULL) {
14972: 	memberType = member->type;
14973: 	while ((memberType != NULL) &&
14974: 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14975: 	    if (memberType == ctxType) {
14976: 		xmlSchemaPCustomErr(pctxt,
14977: 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14978: 		    WXS_BASIC_CAST ctxType, NULL,
14979: 		    "The union type definition is circular", NULL);
14980: 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14981: 	    }
14982: 	    if ((WXS_IS_UNION(memberType)) &&
14983: 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14984: 	    {
14985: 		int res;
14986: 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14987: 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14988: 		    ctxType,
14989: 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14990: 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14991: 		if (res != 0)
14992: 		    return(res);
14993: 	    }
14994: 	    memberType = memberType->baseType;
14995: 	}
14996: 	member = member->next;
14997:     }
14998:     return(0);
14999: }
15000: 
15001: static int
15002: xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
15003: 				   xmlSchemaTypePtr type)
15004: {
15005:     if (! WXS_IS_UNION(type))
15006: 	return(0);
15007:     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
15008: 	type->memberTypes));
15009: }
15010: 
15011: /**
15012:  * xmlSchemaResolveTypeReferences:
15013:  * @item:  the complex/simple type definition
15014:  * @ctxt:  the parser context
15015:  * @name:  the name
15016:  *
15017:  * Resolvese type definition references
15018:  */
15019: static void
15020: xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
15021: 			 xmlSchemaParserCtxtPtr ctxt)
15022: {
15023:     if (typeDef == NULL)
15024: 	return;
15025: 
15026:     /*
15027:     * Resolve the base type.
15028:     */
15029:     if (typeDef->baseType == NULL) {
15030: 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15031: 	    typeDef->base, typeDef->baseNs);
15032: 	if (typeDef->baseType == NULL) {
15033: 	    xmlSchemaPResCompAttrErr(ctxt,
15034: 		XML_SCHEMAP_SRC_RESOLVE,
15035: 		WXS_BASIC_CAST typeDef, typeDef->node,
15036: 		"base", typeDef->base, typeDef->baseNs,
15037: 		XML_SCHEMA_TYPE_SIMPLE, NULL);
15038: 	    return;
15039: 	}
15040:     }
15041:     if (WXS_IS_SIMPLE(typeDef)) {
15042: 	if (WXS_IS_UNION(typeDef)) {
15043: 	    /*
15044: 	    * Resolve the memberTypes.
15045: 	    */
15046: 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15047: 	    return;
15048: 	} else if (WXS_IS_LIST(typeDef)) {
15049: 	    /*
15050: 	    * Resolve the itemType.
15051: 	    */
15052: 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15053: 
15054: 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15055: 		    typeDef->base, typeDef->baseNs);
15056: 
15057: 		if ((typeDef->subtypes == NULL) ||
15058: 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
15059: 		{
15060: 		    typeDef->subtypes = NULL;
15061: 		    xmlSchemaPResCompAttrErr(ctxt,
15062: 			XML_SCHEMAP_SRC_RESOLVE,
15063: 			WXS_BASIC_CAST typeDef, typeDef->node,
15064: 			"itemType", typeDef->base, typeDef->baseNs,
15065: 			XML_SCHEMA_TYPE_SIMPLE, NULL);
15066: 		}
15067: 	    }
15068: 	    return;
15069: 	}
15070:     }
15071:     /*
15072:     * The ball of letters below means, that if we have a particle
15073:     * which has a QName-helper component as its {term}, we want
15074:     * to resolve it...
15075:     */
15076:     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15077: 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15078: 	    XML_SCHEMA_TYPE_PARTICLE) &&
15079: 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15080: 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15081: 	    XML_SCHEMA_EXTRA_QNAMEREF))
15082:     {
15083: 	xmlSchemaQNameRefPtr ref =
15084: 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15085: 	xmlSchemaModelGroupDefPtr groupDef;
15086: 
15087: 	/*
15088: 	* URGENT TODO: Test this.
15089: 	*/
15090: 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15091: 	/*
15092: 	* Resolve the MG definition reference.
15093: 	*/
15094: 	groupDef =
15095: 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15096: 		ref->itemType, ref->name, ref->targetNamespace);
15097: 	if (groupDef == NULL) {
15098: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15099: 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15100: 		"ref", ref->name, ref->targetNamespace, ref->itemType,
15101: 		NULL);
15102: 	    /* Remove the particle. */
15103: 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15104: 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15105: 	    /* Remove the particle. */
15106: 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15107: 	else {
15108: 	    /*
15109: 	    * Assign the MG definition's {model group} to the
15110: 	    * particle's {term}.
15111: 	    */
15112: 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15113: 
15114: 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15115: 		/*
15116: 		* SPEC cos-all-limited (1.2)
15117: 		* "1.2 the {term} property of a particle with
15118: 		* {max occurs}=1 which is part of a pair which constitutes
15119: 		* the {content type} of a complex type definition."
15120: 		*/
15121: 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15122: 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
15123: 			/* TODO: error code */
15124: 			XML_SCHEMAP_COS_ALL_LIMITED,
15125: 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15126: 			"The particle's {max occurs} must be 1, since the "
15127: 			"reference resolves to an 'all' model group",
15128: 			NULL, NULL);
15129: 		}
15130: 	    }
15131: 	}
15132:     }
15133: }
15134: 
15135: 
15136: 
15137: /**
15138:  * xmlSchemaCheckSTPropsCorrect:
15139:  * @ctxt:  the schema parser context
15140:  * @type:  the simple type definition
15141:  *
15142:  * Checks st-props-correct.
15143:  *
15144:  * Returns 0 if the properties are correct,
15145:  * if not, a positive error code and -1 on internal
15146:  * errors.
15147:  */
15148: static int
15149: xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15150: 			     xmlSchemaTypePtr type)
15151: {
15152:     xmlSchemaTypePtr baseType = type->baseType;
15153:     xmlChar *str = NULL;
15154: 
15155:     /* STATE: error funcs converted. */
15156:     /*
15157:     * Schema Component Constraint: Simple Type Definition Properties Correct
15158:     *
15159:     * NOTE: This is somehow redundant, since we actually built a simple type
15160:     * to have all the needed information; this acts as an self test.
15161:     */
15162:     /* Base type: If the datatype has been �derived� by �restriction�
15163:     * then the Simple Type Definition component from which it is �derived�,
15164:     * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
15165:     */
15166:     if (baseType == NULL) {
15167: 	/*
15168: 	* TODO: Think about: "modulo the impact of Missing
15169: 	* Sub-components (�5.3)."
15170: 	*/
15171: 	xmlSchemaPCustomErr(ctxt,
15172: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15173: 	    WXS_BASIC_CAST type, NULL,
15174: 	    "No base type existent", NULL);
15175: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15176: 
15177:     }
15178:     if (! WXS_IS_SIMPLE(baseType)) {
15179: 	xmlSchemaPCustomErr(ctxt,
15180: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15181: 	    WXS_BASIC_CAST type, NULL,
15182: 	    "The base type '%s' is not a simple type",
15183: 	    xmlSchemaGetComponentQName(&str, baseType));
15184: 	FREE_AND_NULL(str)
15185: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15186:     }
15187:     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15188: 	(WXS_IS_RESTRICTION(type) == 0) &&
15189: 	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15190:          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15191: 	xmlSchemaPCustomErr(ctxt,
15192: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15193: 	    WXS_BASIC_CAST type, NULL,
15194: 	    "A type, derived by list or union, must have "
15195: 	    "the simple ur-type definition as base type, not '%s'",
15196: 	    xmlSchemaGetComponentQName(&str, baseType));
15197: 	FREE_AND_NULL(str)
15198: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15199:     }
15200:     /*
15201:     * Variety: One of {atomic, list, union}.
15202:     */
15203:     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15204: 	(! WXS_IS_LIST(type))) {
15205: 	xmlSchemaPCustomErr(ctxt,
15206: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15207: 	    WXS_BASIC_CAST type, NULL,
15208: 	    "The variety is absent", NULL);
15209: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15210:     }
15211:     /* TODO: Finish this. Hmm, is this finished? */
15212: 
15213:     /*
15214:     * 3 The {final} of the {base type definition} must not contain restriction.
15215:     */
15216:     if (xmlSchemaTypeFinalContains(baseType,
15217: 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15218: 	xmlSchemaPCustomErr(ctxt,
15219: 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
15220: 	    WXS_BASIC_CAST type, NULL,
15221: 	    "The 'final' of its base type '%s' must not contain "
15222: 	    "'restriction'",
15223: 	    xmlSchemaGetComponentQName(&str, baseType));
15224: 	FREE_AND_NULL(str)
15225: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15226:     }
15227: 
15228:     /*
15229:     * 2 All simple type definitions must be derived ultimately from the �simple
15230:     * ur-type definition (so� circular definitions are disallowed). That is, it
15231:     * must be possible to reach a built-in primitive datatype or the �simple
15232:     * ur-type definition� by repeatedly following the {base type definition}.
15233:     *
15234:     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15235:     */
15236:     return (0);
15237: }
15238: 
15239: /**
15240:  * xmlSchemaCheckCOSSTRestricts:
15241:  * @ctxt:  the schema parser context
15242:  * @type:  the simple type definition
15243:  *
15244:  * Schema Component Constraint:
15245:  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15246: 
15247:  * Checks if the given @type (simpleType) is derived validly by restriction.
15248:  * STATUS:
15249:  *
15250:  * Returns -1 on internal errors, 0 if the type is validly derived,
15251:  * a positive error code otherwise.
15252:  */
15253: static int
15254: xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15255: 			     xmlSchemaTypePtr type)
15256: {
15257:     xmlChar *str = NULL;
15258: 
15259:     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15260: 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15261: 	    "given type is not a user-derived simpleType");
15262: 	return (-1);
15263:     }
15264: 
15265:     if (WXS_IS_ATOMIC(type)) {
15266: 	xmlSchemaTypePtr primitive;
15267: 	/*
15268: 	* 1.1 The {base type definition} must be an atomic simple
15269: 	* type definition or a built-in primitive datatype.
15270: 	*/
15271: 	if (! WXS_IS_ATOMIC(type->baseType)) {
15272: 	    xmlSchemaPCustomErr(pctxt,
15273: 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15274: 		WXS_BASIC_CAST type, NULL,
15275: 		"The base type '%s' is not an atomic simple type",
15276: 		xmlSchemaGetComponentQName(&str, type->baseType));
15277: 	    FREE_AND_NULL(str)
15278: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15279: 	}
15280: 	/* 1.2 The {final} of the {base type definition} must not contain
15281: 	* restriction.
15282: 	*/
15283: 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15284: 	if (xmlSchemaTypeFinalContains(type->baseType,
15285: 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15286: 	    xmlSchemaPCustomErr(pctxt,
15287: 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15288: 		WXS_BASIC_CAST type, NULL,
15289: 		"The final of its base type '%s' must not contain 'restriction'",
15290: 		xmlSchemaGetComponentQName(&str, type->baseType));
15291: 	    FREE_AND_NULL(str)
15292: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15293: 	}
15294: 
15295: 	/*
15296: 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
15297: 	* type definition}, as specified in the appropriate subsection of 3.2
15298: 	* Primitive datatypes.
15299: 	*/
15300: 	if (type->facets != NULL) {
15301: 	    xmlSchemaFacetPtr facet;
15302: 	    int ok = 1;
15303: 
15304: 	    primitive = xmlSchemaGetPrimitiveType(type);
15305: 	    if (primitive == NULL) {
15306: 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15307: 		    "failed to get primitive type");
15308: 		return (-1);
15309: 	    }
15310: 	    facet = type->facets;
15311: 	    do {
15312: 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15313: 		    ok = 0;
15314: 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
15315: 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15316: 			type, primitive, facet);
15317: 		}
15318: 		facet = facet->next;
15319: 	    } while (facet != NULL);
15320: 	    if (ok == 0)
15321: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15322: 	}
15323: 	/*
15324: 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15325: 	* of the {base type definition} (call this BF),then the DF's {value}
15326: 	* must be a valid restriction of BF's {value} as defined in
15327: 	* [XML Schemas: Datatypes]."
15328: 	*
15329: 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
15330: 	* xmlSchemaDeriveAndValidateFacets()
15331: 	*/
15332:     } else if (WXS_IS_LIST(type)) {
15333: 	xmlSchemaTypePtr itemType = NULL;
15334: 
15335: 	itemType = type->subtypes;
15336: 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15337: 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15338: 		"failed to evaluate the item type");
15339: 	    return (-1);
15340: 	}
15341: 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
15342: 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15343: 	/*
15344: 	* 2.1 The {item type definition} must have a {variety} of atomic or
15345: 	* union (in which case all the {member type definitions}
15346: 	* must be atomic).
15347: 	*/
15348: 	if ((! WXS_IS_ATOMIC(itemType)) &&
15349: 	    (! WXS_IS_UNION(itemType))) {
15350: 	    xmlSchemaPCustomErr(pctxt,
15351: 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15352: 		WXS_BASIC_CAST type, NULL,
15353: 		"The item type '%s' does not have a variety of atomic or union",
15354: 		xmlSchemaGetComponentQName(&str, itemType));
15355: 	    FREE_AND_NULL(str)
15356: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15357: 	} else if (WXS_IS_UNION(itemType)) {
15358: 	    xmlSchemaTypeLinkPtr member;
15359: 
15360: 	    member = itemType->memberTypes;
15361: 	    while (member != NULL) {
15362: 		if (! WXS_IS_ATOMIC(member->type)) {
15363: 		    xmlSchemaPCustomErr(pctxt,
15364: 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15365: 			WXS_BASIC_CAST type, NULL,
15366: 			"The item type is a union type, but the "
15367: 			"member type '%s' of this item type is not atomic",
15368: 			xmlSchemaGetComponentQName(&str, member->type));
15369: 		    FREE_AND_NULL(str)
15370: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15371: 		}
15372: 		member = member->next;
15373: 	    }
15374: 	}
15375: 
15376: 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15377: 	    xmlSchemaFacetPtr facet;
15378: 	    /*
15379: 	    * This is the case if we have: <simpleType><list ..
15380: 	    */
15381: 	    /*
15382: 	    * 2.3.1
15383: 	    * 2.3.1.1 The {final} of the {item type definition} must not
15384: 	    * contain list.
15385: 	    */
15386: 	    if (xmlSchemaTypeFinalContains(itemType,
15387: 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
15388: 		xmlSchemaPCustomErr(pctxt,
15389: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15390: 		    WXS_BASIC_CAST type, NULL,
15391: 		    "The final of its item type '%s' must not contain 'list'",
15392: 		    xmlSchemaGetComponentQName(&str, itemType));
15393: 		FREE_AND_NULL(str)
15394: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15395: 	    }
15396: 	    /*
15397: 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
15398: 	    * facet component.
15399: 	    * OPTIMIZE TODO: the S4S already disallows any facet
15400: 	    * to be specified.
15401: 	    */
15402: 	    if (type->facets != NULL) {
15403: 		facet = type->facets;
15404: 		do {
15405: 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15406: 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
15407: 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15408: 			    type, facet);
15409: 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15410: 		    }
15411: 		    facet = facet->next;
15412: 		} while (facet != NULL);
15413: 	    }
15414: 	    /*
15415: 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
15416: 	    * A �list� datatype can be �derived� from an �atomic� datatype
15417: 	    * whose �lexical space� allows space (such as string or anyURI)or
15418: 	    * a �union� datatype any of whose {member type definitions}'s
15419: 	    * �lexical space� allows space.
15420: 	    */
15421: 	} else {
15422: 	    /*
15423: 	    * This is the case if we have: <simpleType><restriction ...
15424: 	    * I.e. the variety of "list" is inherited.
15425: 	    */
15426: 	    /*
15427: 	    * 2.3.2
15428: 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
15429: 	    */
15430: 	    if (! WXS_IS_LIST(type->baseType)) {
15431: 		xmlSchemaPCustomErr(pctxt,
15432: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15433: 		    WXS_BASIC_CAST type, NULL,
15434: 		    "The base type '%s' must be a list type",
15435: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15436: 		FREE_AND_NULL(str)
15437: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15438: 	    }
15439: 	    /*
15440: 	    * 2.3.2.2 The {final} of the {base type definition} must not
15441: 	    * contain restriction.
15442: 	    */
15443: 	    if (xmlSchemaTypeFinalContains(type->baseType,
15444: 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15445: 		xmlSchemaPCustomErr(pctxt,
15446: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15447: 		    WXS_BASIC_CAST type, NULL,
15448: 		    "The 'final' of the base type '%s' must not contain 'restriction'",
15449: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15450: 		FREE_AND_NULL(str)
15451: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15452: 	    }
15453: 	    /*
15454: 	    * 2.3.2.3 The {item type definition} must be validly derived
15455: 	    * from the {base type definition}'s {item type definition} given
15456: 	    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
15457: 	    */
15458: 	    {
15459: 		xmlSchemaTypePtr baseItemType;
15460: 
15461: 		baseItemType = type->baseType->subtypes;
15462: 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15463: 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15464: 			"failed to eval the item type of a base type");
15465: 		    return (-1);
15466: 		}
15467: 		if ((itemType != baseItemType) &&
15468: 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15469: 			baseItemType, 0) != 0)) {
15470: 		    xmlChar *strBIT = NULL, *strBT = NULL;
15471: 		    xmlSchemaPCustomErrExt(pctxt,
15472: 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15473: 			WXS_BASIC_CAST type, NULL,
15474: 			"The item type '%s' is not validly derived from "
15475: 			"the item type '%s' of the base type '%s'",
15476: 			xmlSchemaGetComponentQName(&str, itemType),
15477: 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
15478: 			xmlSchemaGetComponentQName(&strBT, type->baseType));
15479: 
15480: 		    FREE_AND_NULL(str)
15481: 		    FREE_AND_NULL(strBIT)
15482: 		    FREE_AND_NULL(strBT)
15483: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15484: 		}
15485: 	    }
15486: 
15487: 	    if (type->facets != NULL) {
15488: 		xmlSchemaFacetPtr facet;
15489: 		int ok = 1;
15490: 		/*
15491: 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15492: 		* and enumeration facet components are allowed among the {facets}.
15493: 		*/
15494: 		facet = type->facets;
15495: 		do {
15496: 		    switch (facet->type) {
15497: 			case XML_SCHEMA_FACET_LENGTH:
15498: 			case XML_SCHEMA_FACET_MINLENGTH:
15499: 			case XML_SCHEMA_FACET_MAXLENGTH:
15500: 			case XML_SCHEMA_FACET_WHITESPACE:
15501: 			    /*
15502: 			    * TODO: 2.5.1.2 List datatypes
15503: 			    * The value of �whiteSpace� is fixed to the value collapse.
15504: 			    */
15505: 			case XML_SCHEMA_FACET_PATTERN:
15506: 			case XML_SCHEMA_FACET_ENUMERATION:
15507: 			    break;
15508: 			default: {
15509: 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
15510: 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15511: 				type, facet);
15512: 			    /*
15513: 			    * We could return, but it's nicer to report all
15514: 			    * invalid facets.
15515: 			    */
15516: 			    ok = 0;
15517: 			}
15518: 		    }
15519: 		    facet = facet->next;
15520: 		} while (facet != NULL);
15521: 		if (ok == 0)
15522: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15523: 		/*
15524: 		* SPEC (2.3.2.5) (same as 1.3.2)
15525: 		*
15526: 		* NOTE (2.3.2.5) This is currently done in
15527: 		* xmlSchemaDeriveAndValidateFacets()
15528: 		*/
15529: 	    }
15530: 	}
15531:     } else if (WXS_IS_UNION(type)) {
15532: 	/*
15533: 	* 3.1 The {member type definitions} must all have {variety} of
15534: 	* atomic or list.
15535: 	*/
15536: 	xmlSchemaTypeLinkPtr member;
15537: 
15538: 	member = type->memberTypes;
15539: 	while (member != NULL) {
15540: 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
15541: 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15542: 
15543: 	    if ((! WXS_IS_ATOMIC(member->type)) &&
15544: 		(! WXS_IS_LIST(member->type))) {
15545: 		xmlSchemaPCustomErr(pctxt,
15546: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15547: 		    WXS_BASIC_CAST type, NULL,
15548: 		    "The member type '%s' is neither an atomic, nor a list type",
15549: 		    xmlSchemaGetComponentQName(&str, member->type));
15550: 		FREE_AND_NULL(str)
15551: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15552: 	    }
15553: 	    member = member->next;
15554: 	}
15555: 	/*
15556: 	* 3.3.1 If the {base type definition} is the �simple ur-type
15557: 	* definition�
15558: 	*/
15559: 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15560: 	    /*
15561: 	    * 3.3.1.1 All of the {member type definitions} must have a
15562: 	    * {final} which does not contain union.
15563: 	    */
15564: 	    member = type->memberTypes;
15565: 	    while (member != NULL) {
15566: 		if (xmlSchemaTypeFinalContains(member->type,
15567: 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
15568: 		    xmlSchemaPCustomErr(pctxt,
15569: 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15570: 			WXS_BASIC_CAST type, NULL,
15571: 			"The 'final' of member type '%s' contains 'union'",
15572: 			xmlSchemaGetComponentQName(&str, member->type));
15573: 		    FREE_AND_NULL(str)
15574: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15575: 		}
15576: 		member = member->next;
15577: 	    }
15578: 	    /*
15579: 	    * 3.3.1.2 The {facets} must be empty.
15580: 	    */
15581: 	    if (type->facetSet != NULL) {
15582: 		xmlSchemaPCustomErr(pctxt,
15583: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15584: 		    WXS_BASIC_CAST type, NULL,
15585: 		    "No facets allowed", NULL);
15586: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15587: 	    }
15588: 	} else {
15589: 	    /*
15590: 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
15591: 	    * I.e. the variety of "list" is inherited.
15592: 	    */
15593: 	    if (! WXS_IS_UNION(type->baseType)) {
15594: 		xmlSchemaPCustomErr(pctxt,
15595: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15596: 		    WXS_BASIC_CAST type, NULL,
15597: 		    "The base type '%s' is not a union type",
15598: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15599: 		FREE_AND_NULL(str)
15600: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15601: 	    }
15602: 	    /*
15603: 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15604: 	    */
15605: 	    if (xmlSchemaTypeFinalContains(type->baseType,
15606: 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15607: 		xmlSchemaPCustomErr(pctxt,
15608: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15609: 		    WXS_BASIC_CAST type, NULL,
15610: 		    "The 'final' of its base type '%s' must not contain 'restriction'",
15611: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15612: 		FREE_AND_NULL(str)
15613: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15614: 	    }
15615: 	    /*
15616: 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
15617: 	    * derived from the corresponding type definitions in the {base
15618: 	    * type definition}'s {member type definitions} given the empty set,
15619: 	    * as defined in Type Derivation OK (Simple) (�3.14.6).
15620: 	    */
15621: 	    {
15622: 		xmlSchemaTypeLinkPtr baseMember;
15623: 
15624: 		/*
15625: 		* OPTIMIZE: if the type is restricting, it has no local defined
15626: 		* member types and inherits the member types of the base type;
15627: 		* thus a check for equality can be skipped.
15628: 		*/
15629: 		/*
15630: 		* Even worse: I cannot see a scenario where a restricting
15631: 		* union simple type can have other member types as the member
15632: 		* types of it's base type. This check seems not necessary with
15633: 		* respect to the derivation process in libxml2.
15634: 		* But necessary if constructing types with an API.
15635: 		*/
15636: 		if (type->memberTypes != NULL) {
15637: 		    member = type->memberTypes;
15638: 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15639: 		    if ((member == NULL) && (baseMember != NULL)) {
15640: 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15641: 			    "different number of member types in base");
15642: 		    }
15643: 		    while (member != NULL) {
15644: 			if (baseMember == NULL) {
15645: 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15646: 			    "different number of member types in base");
15647: 			} else if ((member->type != baseMember->type) &&
15648: 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15649: 				member->type, baseMember->type, 0) != 0)) {
15650: 			    xmlChar *strBMT = NULL, *strBT = NULL;
15651: 
15652: 			    xmlSchemaPCustomErrExt(pctxt,
15653: 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15654: 				WXS_BASIC_CAST type, NULL,
15655: 				"The member type %s is not validly "
15656: 				"derived from its corresponding member "
15657: 				"type %s of the base type %s",
15658: 				xmlSchemaGetComponentQName(&str, member->type),
15659: 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15660: 				xmlSchemaGetComponentQName(&strBT, type->baseType));
15661: 			    FREE_AND_NULL(str)
15662: 			    FREE_AND_NULL(strBMT)
15663: 			    FREE_AND_NULL(strBT)
15664: 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15665: 			}
15666: 			member = member->next;
15667:                         if (baseMember != NULL)
15668:                             baseMember = baseMember->next;
15669: 		    }
15670: 		}
15671: 	    }
15672: 	    /*
15673: 	    * 3.3.2.4 Only pattern and enumeration facet components are
15674: 	    * allowed among the {facets}.
15675: 	    */
15676: 	    if (type->facets != NULL) {
15677: 		xmlSchemaFacetPtr facet;
15678: 		int ok = 1;
15679: 
15680: 		facet = type->facets;
15681: 		do {
15682: 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15683: 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15684: 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
15685: 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15686: 				type, facet);
15687: 			ok = 0;
15688: 		    }
15689: 		    facet = facet->next;
15690: 		} while (facet != NULL);
15691: 		if (ok == 0)
15692: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15693: 
15694: 	    }
15695: 	    /*
15696: 	    * SPEC (3.3.2.5) (same as 1.3.2)
15697: 	    *
15698: 	    * NOTE (3.3.2.5) This is currently done in
15699: 	    * xmlSchemaDeriveAndValidateFacets()
15700: 	    */
15701: 	}
15702:     }
15703: 
15704:     return (0);
15705: }
15706: 
15707: /**
15708:  * xmlSchemaCheckSRCSimpleType:
15709:  * @ctxt:  the schema parser context
15710:  * @type:  the simple type definition
15711:  *
15712:  * Checks crc-simple-type constraints.
15713:  *
15714:  * Returns 0 if the constraints are satisfied,
15715:  * if not a positive error code and -1 on internal
15716:  * errors.
15717:  */
15718: #if 0
15719: static int
15720: xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15721: 			    xmlSchemaTypePtr type)
15722: {
15723:     /*
15724:     * src-simple-type.1 The corresponding simple type definition, if any,
15725:     * must satisfy the conditions set out in Constraints on Simple Type
15726:     * Definition Schema Components (�3.14.6).
15727:     */
15728:     if (WXS_IS_RESTRICTION(type)) {
15729: 	/*
15730: 	* src-simple-type.2 "If the <restriction> alternative is chosen,
15731: 	* either it must have a base [attribute] or a <simpleType> among its
15732: 	* [children], but not both."
15733: 	* NOTE: This is checked in the parse function of <restriction>.
15734: 	*/
15735: 	/*
15736: 	*
15737: 	*/
15738:     } else if (WXS_IS_LIST(type)) {
15739: 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15740: 	* an itemType [attribute] or a <simpleType> among its [children],
15741: 	* but not both."
15742: 	*
15743: 	* NOTE: This is checked in the parse function of <list>.
15744: 	*/
15745:     } else if (WXS_IS_UNION(type)) {
15746: 	/*
15747: 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15748: 	*/
15749:     }
15750:     return (0);
15751: }
15752: #endif
15753: 
15754: static int
15755: xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15756: {
15757:    if (ctxt->vctxt == NULL) {
15758: 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15759: 	if (ctxt->vctxt == NULL) {
15760: 	    xmlSchemaPErr(ctxt, NULL,
15761: 		XML_SCHEMAP_INTERNAL,
15762: 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15763: 		"failed to create a temp. validation context.\n",
15764: 		NULL, NULL);
15765: 	    return (-1);
15766: 	}
15767: 	/* TODO: Pass user data. */
15768: 	xmlSchemaSetValidErrors(ctxt->vctxt,
15769: 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
15770: 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15771: 	    ctxt->serror, ctxt->errCtxt);
15772:     }
15773:     return (0);
15774: }
15775: 
15776: static int
15777: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15778: 			     xmlNodePtr node,
15779: 			     xmlSchemaTypePtr type,
15780: 			     const xmlChar *value,
15781: 			     xmlSchemaValPtr *retVal,
15782: 			     int fireErrors,
15783: 			     int normalize,
15784: 			     int isNormalized);
15785: 
15786: /**
15787:  * xmlSchemaParseCheckCOSValidDefault:
15788:  * @pctxt:  the schema parser context
15789:  * @type:  the simple type definition
15790:  * @value: the default value
15791:  * @node: an optional node (the holder of the value)
15792:  *
15793:  * Schema Component Constraint: Element Default Valid (Immediate)
15794:  * (cos-valid-default)
15795:  * This will be used by the parser only. For the validator there's
15796:  * an other version.
15797:  *
15798:  * Returns 0 if the constraints are satisfied,
15799:  * if not, a positive error code and -1 on internal
15800:  * errors.
15801:  */
15802: static int
15803: xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15804: 				   xmlNodePtr node,
15805: 				   xmlSchemaTypePtr type,
15806: 				   const xmlChar *value,
15807: 				   xmlSchemaValPtr *val)
15808: {
15809:     int ret = 0;
15810: 
15811:     /*
15812:     * cos-valid-default:
15813:     * Schema Component Constraint: Element Default Valid (Immediate)
15814:     * For a string to be a valid default with respect to a type
15815:     * definition the appropriate case among the following must be true:
15816:     */
15817:     if WXS_IS_COMPLEX(type) {
15818: 	/*
15819: 	* Complex type.
15820: 	*
15821: 	* SPEC (2.1) "its {content type} must be a simple type definition
15822: 	* or mixed."
15823: 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
15824: 	* type}'s particle must be �emptiable� as defined by
15825: 	* Particle Emptiable (�3.9.6)."
15826: 	*/
15827: 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15828: 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15829: 	    /* NOTE that this covers (2.2.2) as well. */
15830: 	    xmlSchemaPCustomErr(pctxt,
15831: 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15832: 		WXS_BASIC_CAST type, type->node,
15833: 		"For a string to be a valid default, the type definition "
15834: 		"must be a simple type or a complex type with mixed content "
15835: 		"and a particle emptiable", NULL);
15836: 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15837: 	}
15838:     }
15839:     /*
15840:     * 1 If the type definition is a simple type definition, then the string
15841:     * must be �valid� with respect to that definition as defined by String
15842:     * Valid (�3.14.4).
15843:     *
15844:     * AND
15845:     *
15846:     * 2.2.1 If the {content type} is a simple type definition, then the
15847:     * string must be �valid� with respect to that simple type definition
15848:     * as defined by String Valid (�3.14.4).
15849:     */
15850:     if (WXS_IS_SIMPLE(type))
15851: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15852: 	    type, value, val, 1, 1, 0);
15853:     else if (WXS_HAS_SIMPLE_CONTENT(type))
15854: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15855: 	    type->contentTypeDef, value, val, 1, 1, 0);
15856:     else
15857: 	return (ret);
15858: 
15859:     if (ret < 0) {
15860: 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15861: 	    "calling xmlSchemaVCheckCVCSimpleType()");
15862:     }
15863: 
15864:     return (ret);
15865: }
15866: 
15867: /**
15868:  * xmlSchemaCheckCTPropsCorrect:
15869:  * @ctxt:  the schema parser context
15870:  * @type:  the complex type definition
15871:  *
15872:  *.(4.6) Constraints on Complex Type Definition Schema Components
15873:  * Schema Component Constraint:
15874:  * Complex Type Definition Properties Correct (ct-props-correct)
15875:  * STATUS: (seems) complete
15876:  *
15877:  * Returns 0 if the constraints are satisfied, a positive
15878:  * error code if not and -1 if an internal error occured.
15879:  */
15880: static int
15881: xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15882: 			     xmlSchemaTypePtr type)
15883: {
15884:     /*
15885:     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15886:     *
15887:     * SPEC (1) "The values of the properties of a complex type definition must
15888:     * be as described in the property tableau in The Complex Type Definition
15889:     * Schema Component (�3.4.1), modulo the impact of Missing
15890:     * Sub-components (�5.3)."
15891:     */
15892:     if ((type->baseType != NULL) &&
15893: 	(WXS_IS_SIMPLE(type->baseType)) &&
15894: 	(WXS_IS_EXTENSION(type) == 0)) {
15895: 	/*
15896: 	* SPEC (2) "If the {base type definition} is a simple type definition,
15897: 	* the {derivation method} must be extension."
15898: 	*/
15899: 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
15900: 	    XML_SCHEMAP_SRC_CT_1,
15901: 	    NULL, WXS_BASIC_CAST type,
15902: 	    "If the base type is a simple type, the derivation method must be "
15903: 	    "'extension'", NULL, NULL);
15904: 	return (XML_SCHEMAP_SRC_CT_1);
15905:     }
15906:     /*
15907:     * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
15908:     * definition�. That is, it must be possible to reach the �ur-type
15909:     * definition by repeatedly following the {base type definition}."
15910:     *
15911:     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15912:     */
15913:     /*
15914:     * NOTE that (4) and (5) need the following:
15915:     *   - attribute uses need to be already inherited (apply attr. prohibitions)
15916:     *   - attribute group references need to be expanded already
15917:     *   - simple types need to be typefixed already
15918:     */
15919:     if (type->attrUses &&
15920: 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15921:     {
15922: 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15923: 	xmlSchemaAttributeUsePtr use, tmp;
15924: 	int i, j, hasId = 0;
15925: 
15926: 	for (i = uses->nbItems -1; i >= 0; i--) {
15927: 	    use = uses->items[i];
15928: 
15929: 	    /*
15930: 	    * SPEC ct-props-correct
15931: 	    * (4) "Two distinct attribute declarations in the
15932: 	    * {attribute uses} must not have identical {name}s and
15933: 	    * {target namespace}s."
15934: 	    */
15935: 	    if (i > 0) {
15936: 		for (j = i -1; j >= 0; j--) {
15937: 		    tmp = uses->items[j];
15938: 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
15939: 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
15940: 			(WXS_ATTRUSE_DECL_TNS(use) ==
15941: 			WXS_ATTRUSE_DECL_TNS(tmp)))
15942: 		    {
15943: 			xmlChar *str = NULL;
15944: 
15945: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
15946: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
15947: 			    NULL, WXS_BASIC_CAST type,
15948: 			    "Duplicate %s",
15949: 			    xmlSchemaGetComponentDesignation(&str, use),
15950: 			    NULL);
15951: 			FREE_AND_NULL(str);
15952: 			/*
15953: 			* Remove the duplicate.
15954: 			*/
15955: 			if (xmlSchemaItemListRemove(uses, i) == -1)
15956: 			    goto exit_failure;
15957: 			goto next_use;
15958: 		    }
15959: 		}
15960: 	    }
15961: 	    /*
15962: 	    * SPEC ct-props-correct
15963: 	    * (5) "Two distinct attribute declarations in the
15964: 	    * {attribute uses} must not have {type definition}s which
15965: 	    * are or are derived from ID."
15966: 	    */
15967: 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15968: 		if (xmlSchemaIsDerivedFromBuiltInType(
15969: 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15970: 		{
15971: 		    if (hasId) {
15972: 			xmlChar *str = NULL;
15973: 
15974: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
15975: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
15976: 			    NULL, WXS_BASIC_CAST type,
15977: 			    "There must not exist more than one attribute "
15978: 			    "declaration of type 'xs:ID' "
15979: 			    "(or derived from 'xs:ID'). The %s violates this "
15980: 			    "constraint",
15981: 			    xmlSchemaGetComponentDesignation(&str, use),
15982: 			    NULL);
15983: 			FREE_AND_NULL(str);
15984: 			if (xmlSchemaItemListRemove(uses, i) == -1)
15985: 			    goto exit_failure;
15986: 		    }
15987: 
15988: 		    hasId = 1;
15989: 		}
15990: 	    }
15991: next_use: {}
15992: 	}
15993:     }
15994:     return (0);
15995: exit_failure:
15996:     return(-1);
15997: }
15998: 
15999: static int
16000: xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
16001: 		       xmlSchemaTypePtr typeB)
16002: {
16003:     /*
16004:     * TODO: This should implement component-identity
16005:     * in the future.
16006:     */
16007:     if ((typeA == NULL) || (typeB == NULL))
16008: 	return (0);
16009:     return (typeA == typeB);
16010: }
16011: 
16012: /**
16013:  * xmlSchemaCheckCOSCTDerivedOK:
16014:  * @ctxt:  the schema parser context
16015:  * @type:  the to-be derived complex type definition
16016:  * @baseType:  the base complex type definition
16017:  * @set: the given set
16018:  *
16019:  * Schema Component Constraint:
16020:  * Type Derivation OK (Complex) (cos-ct-derived-ok)
16021:  *
16022:  * STATUS: completed
16023:  *
16024:  * Returns 0 if the constraints are satisfied, or 1
16025:  * if not.
16026:  */
16027: static int
16028: xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16029: 			     xmlSchemaTypePtr type,
16030: 			     xmlSchemaTypePtr baseType,
16031: 			     int set)
16032: {
16033:     int equal = xmlSchemaAreEqualTypes(type, baseType);
16034:     /* TODO: Error codes. */
16035:     /*
16036:     * SPEC "For a complex type definition (call it D, for derived)
16037:     * to be validly derived from a type definition (call this
16038:     * B, for base) given a subset of {extension, restriction}
16039:     * all of the following must be true:"
16040:     */
16041:     if (! equal) {
16042: 	/*
16043: 	* SPEC (1) "If B and D are not the same type definition, then the
16044: 	* {derivation method} of D must not be in the subset."
16045: 	*/
16046: 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16047: 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16048: 	    return (1);
16049:     } else {
16050: 	/*
16051: 	* SPEC (2.1) "B and D must be the same type definition."
16052: 	*/
16053: 	return (0);
16054:     }
16055:     /*
16056:     * SPEC (2.2) "B must be D's {base type definition}."
16057:     */
16058:     if (type->baseType == baseType)
16059: 	return (0);
16060:     /*
16061:     * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
16062:     * definition�."
16063:     */
16064:     if (WXS_IS_ANYTYPE(type->baseType))
16065: 	return (1);
16066: 
16067:     if (WXS_IS_COMPLEX(type->baseType)) {
16068: 	/*
16069: 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16070: 	* must be validly derived from B given the subset as defined by this
16071: 	* constraint."
16072: 	*/
16073: 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16074: 	    baseType, set));
16075:     } else {
16076: 	/*
16077: 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16078: 	* must be validly derived from B given the subset as defined in Type
16079: 	* Derivation OK (Simple) (�3.14.6).
16080: 	*/
16081: 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16082: 	    baseType, set));
16083:     }
16084: }
16085: 
16086: /**
16087:  * xmlSchemaCheckCOSDerivedOK:
16088:  * @type:  the derived simple type definition
16089:  * @baseType:  the base type definition
16090:  *
16091:  * Calls:
16092:  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16093:  *
16094:  * Checks wheter @type can be validly derived from @baseType.
16095:  *
16096:  * Returns 0 on success, an positive error code otherwise.
16097:  */
16098: static int
16099: xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16100: 			   xmlSchemaTypePtr type,
16101: 			   xmlSchemaTypePtr baseType,
16102: 			   int set)
16103: {
16104:     if (WXS_IS_SIMPLE(type))
16105: 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16106:     else
16107: 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16108: }
16109: 
16110: /**
16111:  * xmlSchemaCheckCOSCTExtends:
16112:  * @ctxt:  the schema parser context
16113:  * @type:  the complex type definition
16114:  *
16115:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16116:  * Schema Component Constraint:
16117:  * Derivation Valid (Extension) (cos-ct-extends)
16118:  *
16119:  * STATUS:
16120:  *   missing:
16121:  *     (1.5)
16122:  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16123:  *
16124:  * Returns 0 if the constraints are satisfied, a positive
16125:  * error code if not and -1 if an internal error occured.
16126:  */
16127: static int
16128: xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16129: 			   xmlSchemaTypePtr type)
16130: {
16131:     xmlSchemaTypePtr base = type->baseType;
16132:     /*
16133:     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16134:     * temporarily only.
16135:     */
16136:     /*
16137:     * SPEC (1) "If the {base type definition} is a complex type definition,
16138:     * then all of the following must be true:"
16139:     */
16140:     if (WXS_IS_COMPLEX(base)) {
16141: 	/*
16142: 	* SPEC (1.1) "The {final} of the {base type definition} must not
16143: 	* contain extension."
16144: 	*/
16145: 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16146: 	    xmlSchemaPCustomErr(ctxt,
16147: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16148: 		WXS_BASIC_CAST type, NULL,
16149: 		"The 'final' of the base type definition "
16150: 		"contains 'extension'", NULL);
16151: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16152: 	}
16153: 
16154: 	/*
16155: 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
16156: 	* since they are automatically satisfied through the
16157: 	* inheriting mechanism.
16158: 	* Note that even if redefining components, the inheriting mechanism
16159: 	* is used.
16160: 	*/
16161: #if 0
16162: 	/*
16163: 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16164: 	* uses}
16165: 	* of the complex type definition itself, that is, for every attribute
16166: 	* use in the {attribute uses} of the {base type definition}, there
16167: 	* must be an attribute use in the {attribute uses} of the complex
16168: 	* type definition itself whose {attribute declaration} has the same
16169: 	* {name}, {target namespace} and {type definition} as its attribute
16170: 	* declaration"
16171: 	*/
16172: 	if (base->attrUses != NULL) {
16173: 	    int i, j, found;
16174: 	    xmlSchemaAttributeUsePtr use, buse;
16175: 
16176: 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16177: 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
16178: 		found = 0;
16179: 		if (type->attrUses != NULL) {
16180: 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
16181: 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16182: 		    {
16183: 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
16184: 				WXS_ATTRUSE_DECL_NAME(buse)) &&
16185: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
16186: 				WXS_ATTRUSE_DECL_TNS(buse)) &&
16187: 			    (WXS_ATTRUSE_TYPEDEF(use) ==
16188: 				WXS_ATTRUSE_TYPEDEF(buse))
16189: 			{
16190: 			    found = 1;
16191: 			    break;
16192: 			}
16193: 		    }
16194: 		}
16195: 		if (! found) {
16196: 		    xmlChar *str = NULL;
16197: 
16198: 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16199: 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16200: 			NULL, WXS_BASIC_CAST type,
16201: 			/*
16202: 			* TODO: The report does not indicate that also the
16203: 			* type needs to be the same.
16204: 			*/
16205: 			"This type is missing a matching correspondent "
16206: 			"for its {base type}'s %s in its {attribute uses}",
16207: 			xmlSchemaGetComponentDesignation(&str,
16208: 			    buse->children),
16209: 			NULL);
16210: 		    FREE_AND_NULL(str)
16211: 		}
16212: 	    }
16213: 	}
16214: 	/*
16215: 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16216: 	* definition must also have one, and the base type definition's
16217: 	* {attribute  wildcard}'s {namespace constraint} must be a subset
16218: 	* of the complex  type definition's {attribute wildcard}'s {namespace
16219: 	* constraint}, as defined by Wildcard Subset (�3.10.6)."
16220: 	*/
16221: 
16222: 	/*
16223: 	* MAYBE TODO: Enable if ever needed. But this will be needed only
16224: 	* if created the type via a schema construction API.
16225: 	*/
16226: 	if (base->attributeWildcard != NULL) {
16227: 	    if (type->attributeWilcard == NULL) {
16228: 		xmlChar *str = NULL;
16229: 
16230: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
16231: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16232: 		    NULL, type,
16233: 		    "The base %s has an attribute wildcard, "
16234: 		    "but this type is missing an attribute wildcard",
16235: 		    xmlSchemaGetComponentDesignation(&str, base));
16236: 		FREE_AND_NULL(str)
16237: 
16238: 	    } else if (xmlSchemaCheckCOSNSSubset(
16239: 		base->attributeWildcard, type->attributeWildcard))
16240: 	    {
16241: 		xmlChar *str = NULL;
16242: 
16243: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
16244: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16245: 		    NULL, type,
16246: 		    "The attribute wildcard is not a valid "
16247: 		    "superset of the one in the base %s",
16248: 		    xmlSchemaGetComponentDesignation(&str, base));
16249: 		FREE_AND_NULL(str)
16250: 	    }
16251: 	}
16252: #endif
16253: 	/*
16254: 	* SPEC (1.4) "One of the following must be true:"
16255: 	*/
16256: 	if ((type->contentTypeDef != NULL) &&
16257: 	    (type->contentTypeDef == base->contentTypeDef)) {
16258: 	    /*
16259: 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
16260: 	    * and the {content type} of the complex type definition itself
16261: 	    * must be the same simple type definition"
16262: 	    * PASS
16263: 	    */
16264: 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16265: 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16266: 	    /*
16267: 	    * SPEC (1.4.2) "The {content type} of both the {base type
16268: 	    * definition} and the complex type definition itself must
16269: 	    * be empty."
16270: 	    * PASS
16271: 	    */
16272: 	} else {
16273: 	    /*
16274: 	    * SPEC (1.4.3) "All of the following must be true:"
16275: 	    */
16276: 	    if (type->subtypes == NULL) {
16277: 		/*
16278: 		* SPEC 1.4.3.1 The {content type} of the complex type
16279: 		* definition itself must specify a particle.
16280: 		*/
16281: 		xmlSchemaPCustomErr(ctxt,
16282: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16283: 		    WXS_BASIC_CAST type, NULL,
16284: 		    "The content type must specify a particle", NULL);
16285: 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16286: 	    }
16287: 	    /*
16288: 	    * SPEC (1.4.3.2) "One of the following must be true:"
16289: 	    */
16290: 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16291: 		/*
16292: 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
16293: 		* definition} must be empty.
16294: 		* PASS
16295: 		*/
16296: 	    } else {
16297: 		/*
16298: 		* SPEC (1.4.3.2.2) "All of the following must be true:"
16299: 		*/
16300: 		if ((type->contentType != base->contentType) ||
16301: 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16302: 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16303: 		    /*
16304: 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16305: 		    * or both must be element-only."
16306: 		    */
16307: 		    xmlSchemaPCustomErr(ctxt,
16308: 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16309: 			WXS_BASIC_CAST type, NULL,
16310: 			"The content type of both, the type and its base "
16311: 			"type, must either 'mixed' or 'element-only'", NULL);
16312: 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16313: 		}
16314: 		/*
16315: 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16316: 		* complex type definition must be a �valid extension�
16317: 		* of the {base type definition}'s particle, as defined
16318: 		* in Particle Valid (Extension) (�3.9.6)."
16319: 		*
16320: 		* NOTE that we won't check "Particle Valid (Extension)",
16321: 		* since it is ensured by the derivation process in
16322: 		* xmlSchemaTypeFixup(). We need to implement this when heading
16323: 		* for a construction API
16324: 		* TODO: !! This is needed to be checked if redefining a type !!
16325: 		*/
16326: 	    }
16327: 	    /*
16328: 	    * URGENT TODO (1.5)
16329: 	    */
16330: 	}
16331:     } else {
16332: 	/*
16333: 	* SPEC (2) "If the {base type definition} is a simple type definition,
16334: 	* then all of the following must be true:"
16335: 	*/
16336: 	if (type->contentTypeDef != base) {
16337: 	    /*
16338: 	    * SPEC (2.1) "The {content type} must be the same simple type
16339: 	    * definition."
16340: 	    */
16341: 	    xmlSchemaPCustomErr(ctxt,
16342: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16343: 		WXS_BASIC_CAST type, NULL,
16344: 		"The content type must be the simple base type", NULL);
16345: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16346: 	}
16347: 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16348: 	    /*
16349: 	    * SPEC (2.2) "The {final} of the {base type definition} must not
16350: 	    * contain extension"
16351: 	    * NOTE that this is the same as (1.1).
16352: 	    */
16353: 	    xmlSchemaPCustomErr(ctxt,
16354: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16355: 		WXS_BASIC_CAST type, NULL,
16356: 		"The 'final' of the base type definition "
16357: 		"contains 'extension'", NULL);
16358: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16359: 	}
16360:     }
16361:     return (0);
16362: }
16363: 
16364: /**
16365:  * xmlSchemaCheckDerivationOKRestriction:
16366:  * @ctxt:  the schema parser context
16367:  * @type:  the complex type definition
16368:  *
16369:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16370:  * Schema Component Constraint:
16371:  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16372:  *
16373:  * STATUS:
16374:  *   missing:
16375:  *     (5.4.2) ???
16376:  *
16377:  * ATTENTION:
16378:  * In XML Schema 1.1 this will be:
16379:  * Validation Rule: Checking complex type subsumption
16380:  *
16381:  * Returns 0 if the constraints are satisfied, a positive
16382:  * error code if not and -1 if an internal error occured.
16383:  */
16384: static int
16385: xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16386: 				      xmlSchemaTypePtr type)
16387: {
16388:     xmlSchemaTypePtr base;
16389: 
16390:     /*
16391:     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16392:     * temporarily only.
16393:     */
16394:     base = type->baseType;
16395:     if (! WXS_IS_COMPLEX(base)) {
16396: 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
16397: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16398: 	    type->node, WXS_BASIC_CAST type,
16399: 	    "The base type must be a complex type", NULL, NULL);
16400: 	return(ctxt->err);
16401:     }
16402:     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16403: 	/*
16404: 	* SPEC (1) "The {base type definition} must be a complex type
16405: 	* definition whose {final} does not contain restriction."
16406: 	*/
16407: 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
16408: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16409: 	    type->node, WXS_BASIC_CAST type,
16410: 	    "The 'final' of the base type definition "
16411: 	    "contains 'restriction'", NULL, NULL);
16412: 	return (ctxt->err);
16413:     }
16414:     /*
16415:     * SPEC (2), (3) and (4)
16416:     * Those are handled in a separate function, since the
16417:     * same constraints are needed for redefinition of
16418:     * attribute groups as well.
16419:     */
16420:     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16421: 	XML_SCHEMA_ACTION_DERIVE,
16422: 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16423: 	type->attrUses, base->attrUses,
16424: 	type->attributeWildcard,
16425: 	base->attributeWildcard) == -1)
16426:     {
16427: 	return(-1);
16428:     }
16429:     /*
16430:     * SPEC (5) "One of the following must be true:"
16431:     */
16432:     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16433: 	/*
16434: 	* SPEC (5.1) "The {base type definition} must be the
16435: 	* �ur-type definition�."
16436: 	* PASS
16437: 	*/
16438:     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16439: 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16440: 	/*
16441: 	* SPEC (5.2.1) "The {content type} of the complex type definition
16442: 	* must be a simple type definition"
16443: 	*
16444: 	* SPEC (5.2.2) "One of the following must be true:"
16445: 	*/
16446: 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16447: 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16448: 	{
16449: 	    int err;
16450: 	    /*
16451: 	    * SPEC (5.2.2.1) "The {content type} of the {base type
16452: 	    * definition} must be a simple type definition from which
16453: 	    * the {content type} is validly derived given the empty
16454: 	    * set as defined in Type Derivation OK (Simple) (�3.14.6)."
16455: 	    *
16456: 	    * ATTENTION TODO: This seems not needed if the type implicitely
16457: 	    * derived from the base type.
16458: 	    *
16459: 	    */
16460: 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16461: 		type->contentTypeDef, base->contentTypeDef, 0);
16462: 	    if (err != 0) {
16463: 		xmlChar *strA = NULL, *strB = NULL;
16464: 
16465: 		if (err == -1)
16466: 		    return(-1);
16467: 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
16468: 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16469: 		    NULL, WXS_BASIC_CAST type,
16470: 		    "The {content type} %s is not validly derived from the "
16471: 		    "base type's {content type} %s",
16472: 		    xmlSchemaGetComponentDesignation(&strA,
16473: 			type->contentTypeDef),
16474: 		    xmlSchemaGetComponentDesignation(&strB,
16475: 			base->contentTypeDef));
16476: 		FREE_AND_NULL(strA);
16477: 		FREE_AND_NULL(strB);
16478: 		return(ctxt->err);
16479: 	    }
16480: 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16481: 	    (xmlSchemaIsParticleEmptiable(
16482: 		(xmlSchemaParticlePtr) base->subtypes))) {
16483: 	    /*
16484: 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
16485: 	    * and have a particle which is �emptiable� as defined in
16486: 	    * 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: 		"a simple type or 'mixed' and an emptiable particle", NULL);
16495: 	    return (ctxt->err);
16496: 	}
16497:     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16498: 	/*
16499: 	* SPEC (5.3.1) "The {content type} of the complex type itself must
16500: 	* be empty"
16501: 	*/
16502: 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16503: 	    /*
16504: 	    * SPEC (5.3.2.1) "The {content type} of the {base type
16505: 	    * definition} must also be empty."
16506: 	    * PASS
16507: 	    */
16508: 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16509: 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16510: 	    xmlSchemaIsParticleEmptiable(
16511: 		(xmlSchemaParticlePtr) base->subtypes)) {
16512: 	    /*
16513: 	    * SPEC (5.3.2.2) "The {content type} of the {base type
16514: 	    * definition} must be elementOnly or mixed and have a particle
16515: 	    * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
16516: 	    * PASS
16517: 	    */
16518: 	} else {
16519: 	    xmlSchemaPCustomErr(ctxt,
16520: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16521: 		WXS_BASIC_CAST type, NULL,
16522: 		"The content type of the base type must be either "
16523: 		"empty or 'mixed' (or 'elements-only') and an emptiable "
16524: 		"particle", NULL);
16525: 	    return (ctxt->err);
16526: 	}
16527:     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16528: 	WXS_HAS_MIXED_CONTENT(type)) {
16529: 	/*
16530: 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
16531: 	* itself must be element-only"
16532: 	*/
16533: 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16534: 	    /*
16535: 	    * SPEC (5.4.1.2) "The {content type} of the complex type
16536: 	    * definition itself and of the {base type definition} must be
16537: 	    * mixed"
16538: 	    */
16539: 	    xmlSchemaPCustomErr(ctxt,
16540: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16541: 		WXS_BASIC_CAST type, NULL,
16542: 		"If the content type is 'mixed', then the content type of the "
16543: 		"base type must also be 'mixed'", NULL);
16544: 	    return (ctxt->err);
16545: 	}
16546: 	/*
16547: 	* SPEC (5.4.2) "The particle of the complex type definition itself
16548: 	* must be a �valid restriction� of the particle of the {content
16549: 	* type} of the {base type definition} as defined in Particle Valid
16550: 	* (Restriction) (�3.9.6).
16551: 	*
16552: 	* URGENT TODO: (5.4.2)
16553: 	*/
16554:     } else {
16555: 	xmlSchemaPCustomErr(ctxt,
16556: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16557: 	    WXS_BASIC_CAST type, NULL,
16558: 	    "The type is not a valid restriction of its base type", NULL);
16559: 	return (ctxt->err);
16560:     }
16561:     return (0);
16562: }
16563: 
16564: /**
16565:  * xmlSchemaCheckCTComponent:
16566:  * @ctxt:  the schema parser context
16567:  * @type:  the complex type definition
16568:  *
16569:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16570:  *
16571:  * Returns 0 if the constraints are satisfied, a positive
16572:  * error code if not and -1 if an internal error occured.
16573:  */
16574: static int
16575: xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16576: 			  xmlSchemaTypePtr type)
16577: {
16578:     int ret;
16579:     /*
16580:     * Complex Type Definition Properties Correct
16581:     */
16582:     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16583:     if (ret != 0)
16584: 	return (ret);
16585:     if (WXS_IS_EXTENSION(type))
16586: 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16587:     else
16588: 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16589:     return (ret);
16590: }
16591: 
16592: /**
16593:  * xmlSchemaCheckSRCCT:
16594:  * @ctxt:  the schema parser context
16595:  * @type:  the complex type definition
16596:  *
16597:  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16598:  * Schema Representation Constraint:
16599:  * Complex Type Definition Representation OK (src-ct)
16600:  *
16601:  * Returns 0 if the constraints are satisfied, a positive
16602:  * error code if not and -1 if an internal error occured.
16603:  */
16604: static int
16605: xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16606: 		    xmlSchemaTypePtr type)
16607: {
16608:     xmlSchemaTypePtr base;
16609:     int ret = 0;
16610: 
16611:     /*
16612:     * TODO: Adjust the error codes here, as I used
16613:     * XML_SCHEMAP_SRC_CT_1 only yet.
16614:     */
16615:     base = type->baseType;
16616:     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16617: 	/*
16618: 	* 1 If the <complexContent> alternative is chosen, the type definition
16619: 	* �resolved� to by the �actual value� of the base [attribute]
16620: 	* must be a complex type definition;
16621: 	*/
16622: 	if (! WXS_IS_COMPLEX(base)) {
16623: 	    xmlChar *str = NULL;
16624: 	    xmlSchemaPCustomErr(ctxt,
16625: 		XML_SCHEMAP_SRC_CT_1,
16626: 		WXS_BASIC_CAST type, type->node,
16627: 		"If using <complexContent>, the base type is expected to be "
16628: 		"a complex type. The base type '%s' is a simple type",
16629: 		xmlSchemaFormatQName(&str, base->targetNamespace,
16630: 		base->name));
16631: 	    FREE_AND_NULL(str)
16632: 	    return (XML_SCHEMAP_SRC_CT_1);
16633: 	}
16634:     } else {
16635: 	/*
16636: 	* SPEC
16637: 	* 2 If the <simpleContent> alternative is chosen, all of the
16638: 	* following must be true:
16639: 	* 2.1 The type definition �resolved� to by the �actual value� of the
16640: 	* base [attribute] must be one of the following:
16641: 	*/
16642: 	if (WXS_IS_SIMPLE(base)) {
16643: 	    if (WXS_IS_EXTENSION(type) == 0) {
16644: 		xmlChar *str = NULL;
16645: 		/*
16646: 		* 2.1.3 only if the <extension> alternative is also
16647: 		* chosen, a simple type definition.
16648: 		*/
16649: 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
16650: 		xmlSchemaPCustomErr(ctxt,
16651: 		    XML_SCHEMAP_SRC_CT_1,
16652: 		    WXS_BASIC_CAST type, NULL,
16653: 		    "If using <simpleContent> and <restriction>, the base "
16654: 		    "type must be a complex type. The base type '%s' is "
16655: 		    "a simple type",
16656: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16657: 			base->name));
16658: 		FREE_AND_NULL(str)
16659: 		return (XML_SCHEMAP_SRC_CT_1);
16660: 	    }
16661: 	} else {
16662: 	    /* Base type is a complex type. */
16663: 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16664: 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16665: 		/*
16666: 		* 2.1.1 a complex type definition whose {content type} is a
16667: 		* simple type definition;
16668: 		* PASS
16669: 		*/
16670: 		if (base->contentTypeDef == NULL) {
16671: 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16672: 			WXS_BASIC_CAST type, NULL,
16673: 			"Internal error: xmlSchemaCheckSRCCT, "
16674: 			"'%s', base type has no content type",
16675: 			type->name);
16676: 		    return (-1);
16677: 		}
16678: 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16679: 		(WXS_IS_RESTRICTION(type))) {
16680: 
16681: 		/*
16682: 		* 2.1.2 only if the <restriction> alternative is also
16683: 		* chosen, a complex type definition whose {content type}
16684: 		* is mixed and a particle emptiable.
16685: 		*/
16686: 		if (! xmlSchemaIsParticleEmptiable(
16687: 		    (xmlSchemaParticlePtr) base->subtypes)) {
16688: 		    ret = XML_SCHEMAP_SRC_CT_1;
16689: 		} else
16690: 		    /*
16691: 		    * Attention: at this point the <simpleType> child is in
16692: 		    * ->contentTypeDef (put there during parsing).
16693: 		    */
16694: 		    if (type->contentTypeDef == NULL) {
16695: 		    xmlChar *str = NULL;
16696: 		    /*
16697: 		    * 2.2 If clause 2.1.2 above is satisfied, then there
16698: 		    * must be a <simpleType> among the [children] of
16699: 		    * <restriction>.
16700: 		    */
16701: 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
16702: 		    xmlSchemaPCustomErr(ctxt,
16703: 			XML_SCHEMAP_SRC_CT_1,
16704: 			WXS_BASIC_CAST type, NULL,
16705: 			"A <simpleType> is expected among the children "
16706: 			"of <restriction>, if <simpleContent> is used and "
16707: 			"the base type '%s' is a complex type",
16708: 			xmlSchemaFormatQName(&str, base->targetNamespace,
16709: 			base->name));
16710: 		    FREE_AND_NULL(str)
16711: 		    return (XML_SCHEMAP_SRC_CT_1);
16712: 		}
16713: 	    } else {
16714: 		ret = XML_SCHEMAP_SRC_CT_1;
16715: 	    }
16716: 	}
16717: 	if (ret > 0) {
16718: 	    xmlChar *str = NULL;
16719: 	    if (WXS_IS_RESTRICTION(type)) {
16720: 		xmlSchemaPCustomErr(ctxt,
16721: 		    XML_SCHEMAP_SRC_CT_1,
16722: 		    WXS_BASIC_CAST type, NULL,
16723: 		    "If <simpleContent> and <restriction> is used, the "
16724: 		    "base type must be a simple type or a complex type with "
16725: 		    "mixed content and particle emptiable. The base type "
16726: 		    "'%s' is none of those",
16727: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16728: 		    base->name));
16729: 	    } else {
16730: 		xmlSchemaPCustomErr(ctxt,
16731: 		    XML_SCHEMAP_SRC_CT_1,
16732: 		    WXS_BASIC_CAST type, NULL,
16733: 		    "If <simpleContent> and <extension> is used, the "
16734: 		    "base type must be a simple type. The base type '%s' "
16735: 		    "is a complex type",
16736: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16737: 		    base->name));
16738: 	    }
16739: 	    FREE_AND_NULL(str)
16740: 	}
16741:     }
16742:     /*
16743:     * SPEC (3) "The corresponding complex type definition component must
16744:     * satisfy the conditions set out in Constraints on Complex Type
16745:     * Definition Schema Components (�3.4.6);"
16746:     * NOTE (3) will be done in xmlSchemaTypeFixup().
16747:     */
16748:     /*
16749:     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16750:     * above for {attribute wildcard} is satisfied, the intensional
16751:     * intersection must be expressible, as defined in Attribute Wildcard
16752:     * Intersection (�3.10.6).
16753:     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16754:     */
16755:     return (ret);
16756: }
16757: 
16758: #ifdef ENABLE_PARTICLE_RESTRICTION
16759: /**
16760:  * xmlSchemaCheckParticleRangeOK:
16761:  * @ctxt:  the schema parser context
16762:  * @type:  the complex type definition
16763:  *
16764:  * (3.9.6) Constraints on Particle Schema Components
16765:  * Schema Component Constraint:
16766:  * Occurrence Range OK (range-ok)
16767:  *
16768:  * STATUS: complete
16769:  *
16770:  * Returns 0 if the constraints are satisfied, a positive
16771:  * error code if not and -1 if an internal error occured.
16772:  */
16773: static int
16774: xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16775: 			      int bmin, int bmax)
16776: {
16777:     if (rmin < bmin)
16778: 	return (1);
16779:     if ((bmax != UNBOUNDED) &&
16780: 	(rmax > bmax))
16781: 	return (1);
16782:     return (0);
16783: }
16784: 
16785: /**
16786:  * xmlSchemaCheckRCaseNameAndTypeOK:
16787:  * @ctxt:  the schema parser context
16788:  * @r: the restricting element declaration particle
16789:  * @b: the base element declaration particle
16790:  *
16791:  * (3.9.6) Constraints on Particle Schema Components
16792:  * Schema Component Constraint:
16793:  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16794:  * (rcase-NameAndTypeOK)
16795:  *
16796:  * STATUS:
16797:  *   MISSING (3.2.3)
16798:  *   CLARIFY: (3.2.2)
16799:  *
16800:  * Returns 0 if the constraints are satisfied, a positive
16801:  * error code if not and -1 if an internal error occured.
16802:  */
16803: static int
16804: xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16805: 				 xmlSchemaParticlePtr r,
16806: 				 xmlSchemaParticlePtr b)
16807: {
16808:     xmlSchemaElementPtr elemR, elemB;
16809: 
16810:     /* TODO: Error codes (rcase-NameAndTypeOK). */
16811:     elemR = (xmlSchemaElementPtr) r->children;
16812:     elemB = (xmlSchemaElementPtr) b->children;
16813:     /*
16814:     * SPEC (1) "The declarations' {name}s and {target namespace}s are
16815:     * the same."
16816:     */
16817:     if ((elemR != elemB) &&
16818: 	((! xmlStrEqual(elemR->name, elemB->name)) ||
16819: 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16820: 	return (1);
16821:     /*
16822:     * SPEC (2) "R's occurrence range is a valid restriction of B's
16823:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16824:     */
16825:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16826: 	    b->minOccurs, b->maxOccurs) != 0)
16827: 	return (1);
16828:     /*
16829:     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16830:     * {scope} are global."
16831:     */
16832:     if (elemR == elemB)
16833: 	return (0);
16834:     /*
16835:     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16836:     */
16837:     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16838: 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16839: 	 return (1);
16840:     /*
16841:     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16842:     * or is not fixed, or R's declaration's {value constraint} is fixed
16843:     * with the same value."
16844:     */
16845:     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16846: 	((elemR->value == NULL) ||
16847: 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16848: 	 /* TODO: Equality of the initial value or normalized or canonical? */
16849: 	 (! xmlStrEqual(elemR->value, elemB->value))))
16850: 	 return (1);
16851:     /*
16852:     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16853:     * definitions} is a subset of B's declaration's {identity-constraint
16854:     * definitions}, if any."
16855:     */
16856:     if (elemB->idcs != NULL) {
16857: 	/* TODO */
16858:     }
16859:     /*
16860:     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16861:     * superset of B's declaration's {disallowed substitutions}."
16862:     */
16863:     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16864: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16865: 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16866: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16867: 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16868: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16869: 	 return (1);
16870:     /*
16871:     * SPEC (3.2.5) "R's {type definition} is validly derived given
16872:     * {extension, list, union} from B's {type definition}"
16873:     *
16874:     * BADSPEC TODO: What's the point of adding "list" and "union" to the
16875:     * set, if the corresponding constraints handle "restriction" and
16876:     * "extension" only?
16877:     *
16878:     */
16879:     {
16880: 	int set = 0;
16881: 
16882: 	set |= SUBSET_EXTENSION;
16883: 	set |= SUBSET_LIST;
16884: 	set |= SUBSET_UNION;
16885: 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16886: 	    elemB->subtypes, set) != 0)
16887: 	    return (1);
16888:     }
16889:     return (0);
16890: }
16891: 
16892: /**
16893:  * xmlSchemaCheckRCaseNSCompat:
16894:  * @ctxt:  the schema parser context
16895:  * @r: the restricting element declaration particle
16896:  * @b: the base wildcard particle
16897:  *
16898:  * (3.9.6) Constraints on Particle Schema Components
16899:  * Schema Component Constraint:
16900:  * Particle Derivation OK (Elt:Any -- NSCompat)
16901:  * (rcase-NSCompat)
16902:  *
16903:  * STATUS: complete
16904:  *
16905:  * Returns 0 if the constraints are satisfied, a positive
16906:  * error code if not and -1 if an internal error occured.
16907:  */
16908: static int
16909: xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16910: 			    xmlSchemaParticlePtr r,
16911: 			    xmlSchemaParticlePtr b)
16912: {
16913:     /* TODO:Error codes (rcase-NSCompat). */
16914:     /*
16915:     * SPEC "For an element declaration particle to be a �valid restriction�
16916:     * of a wildcard particle all of the following must be true:"
16917:     *
16918:     * SPEC (1) "The element declaration's {target namespace} is �valid�
16919:     * with respect to the wildcard's {namespace constraint} as defined by
16920:     * Wildcard allows Namespace Name (�3.10.4)."
16921:     */
16922:     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16923: 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16924: 	return (1);
16925:     /*
16926:     * SPEC (2) "R's occurrence range is a valid restriction of B's
16927:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16928:     */
16929:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16930: 	    b->minOccurs, b->maxOccurs) != 0)
16931: 	return (1);
16932: 
16933:     return (0);
16934: }
16935: 
16936: /**
16937:  * xmlSchemaCheckRCaseRecurseAsIfGroup:
16938:  * @ctxt:  the schema parser context
16939:  * @r: the restricting element declaration particle
16940:  * @b: the base model group particle
16941:  *
16942:  * (3.9.6) Constraints on Particle Schema Components
16943:  * Schema Component Constraint:
16944:  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16945:  * (rcase-RecurseAsIfGroup)
16946:  *
16947:  * STATUS: TODO
16948:  *
16949:  * Returns 0 if the constraints are satisfied, a positive
16950:  * error code if not and -1 if an internal error occured.
16951:  */
16952: static int
16953: xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16954: 				    xmlSchemaParticlePtr r,
16955: 				    xmlSchemaParticlePtr b)
16956: {
16957:     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16958:     TODO
16959:     return (0);
16960: }
16961: 
16962: /**
16963:  * xmlSchemaCheckRCaseNSSubset:
16964:  * @ctxt:  the schema parser context
16965:  * @r: the restricting wildcard particle
16966:  * @b: the base wildcard particle
16967:  *
16968:  * (3.9.6) Constraints on Particle Schema Components
16969:  * Schema Component Constraint:
16970:  * Particle Derivation OK (Any:Any -- NSSubset)
16971:  * (rcase-NSSubset)
16972:  *
16973:  * STATUS: complete
16974:  *
16975:  * Returns 0 if the constraints are satisfied, a positive
16976:  * error code if not and -1 if an internal error occured.
16977:  */
16978: static int
16979: xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16980: 				    xmlSchemaParticlePtr r,
16981: 				    xmlSchemaParticlePtr b,
16982: 				    int isAnyTypeBase)
16983: {
16984:     /* TODO: Error codes (rcase-NSSubset). */
16985:     /*
16986:     * SPEC (1) "R's occurrence range is a valid restriction of B's
16987:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16988:     */
16989:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16990: 	    b->minOccurs, b->maxOccurs))
16991: 	return (1);
16992:     /*
16993:     * SPEC (2) "R's {namespace constraint} must be an intensional subset
16994:     * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
16995:     */
16996:     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16997: 	(xmlSchemaWildcardPtr) b->children))
16998: 	return (1);
16999:     /*
17000:     * SPEC (3) "Unless B is the content model wildcard of the �ur-type
17001:     * definition�, R's {process contents} must be identical to or stronger
17002:     * than B's {process contents}, where strict is stronger than lax is
17003:     * stronger than skip."
17004:     */
17005:     if (! isAnyTypeBase) {
17006: 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
17007: 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
17008: 	    return (1);
17009:     }
17010: 
17011:     return (0);
17012: }
17013: 
17014: /**
17015:  * xmlSchemaCheckCOSParticleRestrict:
17016:  * @ctxt:  the schema parser context
17017:  * @type:  the complex type definition
17018:  *
17019:  * (3.9.6) Constraints on Particle Schema Components
17020:  * Schema Component Constraint:
17021:  * Particle Valid (Restriction) (cos-particle-restrict)
17022:  *
17023:  * STATUS: TODO
17024:  *
17025:  * Returns 0 if the constraints are satisfied, a positive
17026:  * error code if not and -1 if an internal error occured.
17027:  */
17028: static int
17029: xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17030: 				  xmlSchemaParticlePtr r,
17031: 				  xmlSchemaParticlePtr b)
17032: {
17033:     int ret = 0;
17034: 
17035:     /*part = WXS_TYPE_PARTICLE(type);
17036:     basePart = WXS_TYPE_PARTICLE(base);
17037:     */
17038: 
17039:     TODO
17040: 
17041:     /*
17042:     * SPEC (1) "They are the same particle."
17043:     */
17044:     if (r == b)
17045: 	return (0);
17046: 
17047: 
17048:     return (0);
17049: }
17050: 
17051: #if 0
17052: /**
17053:  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17054:  * @ctxt:  the schema parser context
17055:  * @r: the model group particle
17056:  * @b: the base wildcard particle
17057:  *
17058:  * (3.9.6) Constraints on Particle Schema Components
17059:  * Schema Component Constraint:
17060:  * Particle Derivation OK (All/Choice/Sequence:Any --
17061:  *                         NSRecurseCheckCardinality)
17062:  * (rcase-NSRecurseCheckCardinality)
17063:  *
17064:  * STATUS: TODO: subst-groups
17065:  *
17066:  * Returns 0 if the constraints are satisfied, a positive
17067:  * error code if not and -1 if an internal error occured.
17068:  */
17069: static int
17070: xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17071: 					     xmlSchemaParticlePtr r,
17072: 					     xmlSchemaParticlePtr b)
17073: {
17074:     xmlSchemaParticlePtr part;
17075:     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17076:     if ((r->children == NULL) || (r->children->children == NULL))
17077: 	return (-1);
17078:     /*
17079:     * SPEC "For a group particle to be a �valid restriction� of a
17080:     * wildcard particle..."
17081:     *
17082:     * SPEC (1) "Every member of the {particles} of the group is a �valid
17083:     * restriction� of the wildcard as defined by
17084:     * Particle Valid (Restriction) (�3.9.6)."
17085:     */
17086:     part = (xmlSchemaParticlePtr) r->children->children;
17087:     do {
17088: 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17089: 	    return (1);
17090: 	part = (xmlSchemaParticlePtr) part->next;
17091:     } while (part != NULL);
17092:     /*
17093:     * SPEC (2) "The effective total range of the group [...] is a
17094:     * valid restriction of B's occurrence range as defined by
17095:     * Occurrence Range OK (�3.9.6)."
17096:     */
17097:     if (xmlSchemaCheckParticleRangeOK(
17098: 	    xmlSchemaGetParticleTotalRangeMin(r),
17099: 	    xmlSchemaGetParticleTotalRangeMax(r),
17100: 	    b->minOccurs, b->maxOccurs) != 0)
17101: 	return (1);
17102:     return (0);
17103: }
17104: #endif
17105: 
17106: /**
17107:  * xmlSchemaCheckRCaseRecurse:
17108:  * @ctxt:  the schema parser context
17109:  * @r: the <all> or <sequence> model group particle
17110:  * @b: the base <all> or <sequence> model group particle
17111:  *
17112:  * (3.9.6) Constraints on Particle Schema Components
17113:  * Schema Component Constraint:
17114:  * Particle Derivation OK (All:All,Sequence:Sequence --
17115:                            Recurse)
17116:  * (rcase-Recurse)
17117:  *
17118:  * STATUS:  ?
17119:  * TODO: subst-groups
17120:  *
17121:  * Returns 0 if the constraints are satisfied, a positive
17122:  * error code if not and -1 if an internal error occured.
17123:  */
17124: static int
17125: xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17126: 			   xmlSchemaParticlePtr r,
17127: 			   xmlSchemaParticlePtr b)
17128: {
17129:     /* xmlSchemaParticlePtr part; */
17130:     /* TODO: Error codes (rcase-Recurse). */
17131:     if ((r->children == NULL) || (b->children == NULL) ||
17132: 	(r->children->type != b->children->type))
17133: 	return (-1);
17134:     /*
17135:     * SPEC "For an all or sequence group particle to be a �valid
17136:     * restriction� of another group particle with the same {compositor}..."
17137:     *
17138:     * SPEC (1) "R's occurrence range is a valid restriction of B's
17139:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
17140:     */
17141:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17142: 	    b->minOccurs, b->maxOccurs))
17143: 	return (1);
17144: 
17145: 
17146:     return (0);
17147: }
17148: 
17149: #endif
17150: 
17151: #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17152:     xmlSchemaPCustomErrExt(pctxt,      \
17153: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17154: 	WXS_BASIC_CAST fac1, fac1->node, \
17155: 	"It is an error for both '%s' and '%s' to be specified on the "\
17156: 	"same type definition", \
17157: 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17158: 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17159: 
17160: #define FACET_RESTR_ERR(fac1, msg) \
17161:     xmlSchemaPCustomErr(pctxt,      \
17162: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17163: 	WXS_BASIC_CAST fac1, fac1->node, \
17164: 	msg, NULL);
17165: 
17166: #define FACET_RESTR_FIXED_ERR(fac) \
17167:     xmlSchemaPCustomErr(pctxt, \
17168: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17169: 	WXS_BASIC_CAST fac, fac->node, \
17170: 	"The base type's facet is 'fixed', thus the value must not " \
17171: 	"differ", NULL);
17172: 
17173: static void
17174: xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17175: 			xmlSchemaFacetPtr facet1,
17176: 			xmlSchemaFacetPtr facet2,
17177: 			int lessGreater,
17178: 			int orEqual,
17179: 			int ofBase)
17180: {
17181:     xmlChar *msg = NULL;
17182: 
17183:     msg = xmlStrdup(BAD_CAST "'");
17184:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17185:     msg = xmlStrcat(msg, BAD_CAST "' has to be");
17186:     if (lessGreater == 0)
17187: 	msg = xmlStrcat(msg, BAD_CAST " equal to");
17188:     if (lessGreater == 1)
17189: 	msg = xmlStrcat(msg, BAD_CAST " greater than");
17190:     else
17191: 	msg = xmlStrcat(msg, BAD_CAST " less than");
17192: 
17193:     if (orEqual)
17194: 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
17195:     msg = xmlStrcat(msg, BAD_CAST " '");
17196:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17197:     if (ofBase)
17198: 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17199:     else
17200: 	msg = xmlStrcat(msg, BAD_CAST "'");
17201: 
17202:     xmlSchemaPCustomErr(pctxt,
17203: 	XML_SCHEMAP_INVALID_FACET_VALUE,
17204: 	WXS_BASIC_CAST facet1, NULL,
17205: 	(const char *) msg, NULL);
17206: 
17207:     if (msg != NULL)
17208: 	xmlFree(msg);
17209: }
17210: 
17211: /*
17212: * xmlSchemaDeriveAndValidateFacets:
17213: *
17214: * Schema Component Constraint: Simple Type Restriction (Facets)
17215: * (st-restrict-facets)
17216: */
17217: static int
17218: xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17219: 				 xmlSchemaTypePtr type)
17220: {
17221:     xmlSchemaTypePtr base = type->baseType;
17222:     xmlSchemaFacetLinkPtr link, cur, last = NULL;
17223:     xmlSchemaFacetPtr facet, bfacet,
17224: 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
17225: 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17226: 	fmininc = NULL, fmaxinc = NULL,
17227: 	fminexc = NULL, fmaxexc = NULL,
17228: 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17229: 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17230: 	bfmininc = NULL, bfmaxinc = NULL,
17231: 	bfminexc = NULL, bfmaxexc = NULL;
17232:     int res; /* err = 0, fixedErr; */
17233: 
17234:     /*
17235:     * SPEC st-restrict-facets 1:
17236:     * "The {variety} of R is the same as that of B."
17237:     */
17238:     /*
17239:     * SPEC st-restrict-facets 2:
17240:     * "If {variety} is atomic, the {primitive type definition}
17241:     * of R is the same as that of B."
17242:     *
17243:     * NOTE: we leave 1 & 2 out for now, since this will be
17244:     * satisfied by the derivation process.
17245:     * CONSTRUCTION TODO: Maybe needed if using a construction API.
17246:     */
17247:     /*
17248:     * SPEC st-restrict-facets 3:
17249:     * "The {facets} of R are the union of S and the {facets}
17250:     * of B, eliminating duplicates. To eliminate duplicates,
17251:     * when a facet of the same kind occurs in both S and the
17252:     * {facets} of B, the one in the {facets} of B is not
17253:     * included, with the exception of enumeration and pattern
17254:     * facets, for which multiple occurrences with distinct values
17255:     * are allowed."
17256:     */
17257: 
17258:     if ((type->facetSet == NULL) && (base->facetSet == NULL))
17259: 	return (0);
17260: 
17261:     last = type->facetSet;
17262:     if (last != NULL)
17263: 	while (last->next != NULL)
17264: 	    last = last->next;
17265: 
17266:     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17267: 	facet = cur->facet;
17268: 	switch (facet->type) {
17269: 	    case XML_SCHEMA_FACET_LENGTH:
17270: 		flength = facet; break;
17271: 	    case XML_SCHEMA_FACET_MINLENGTH:
17272: 		fminlen = facet; break;
17273: 	    case XML_SCHEMA_FACET_MININCLUSIVE:
17274: 		fmininc = facet; break;
17275: 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
17276: 		fminexc = facet; break;
17277: 	    case XML_SCHEMA_FACET_MAXLENGTH:
17278: 		fmaxlen = facet; break;
17279: 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
17280: 		fmaxinc = facet; break;
17281: 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17282: 		fmaxexc = facet; break;
17283: 	    case XML_SCHEMA_FACET_TOTALDIGITS:
17284: 		ftotdig = facet; break;
17285: 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
17286: 		ffracdig = facet; break;
17287: 	    default:
17288: 		break;
17289: 	}
17290:     }
17291:     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17292: 	facet = cur->facet;
17293: 	switch (facet->type) {
17294: 	    case XML_SCHEMA_FACET_LENGTH:
17295: 		bflength = facet; break;
17296: 	    case XML_SCHEMA_FACET_MINLENGTH:
17297: 		bfminlen = facet; break;
17298: 	    case XML_SCHEMA_FACET_MININCLUSIVE:
17299: 		bfmininc = facet; break;
17300: 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
17301: 		bfminexc = facet; break;
17302: 	    case XML_SCHEMA_FACET_MAXLENGTH:
17303: 		bfmaxlen = facet; break;
17304: 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
17305: 		bfmaxinc = facet; break;
17306: 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17307: 		bfmaxexc = facet; break;
17308: 	    case XML_SCHEMA_FACET_TOTALDIGITS:
17309: 		bftotdig = facet; break;
17310: 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
17311: 		bffracdig = facet; break;
17312: 	    default:
17313: 		break;
17314: 	}
17315:     }
17316:     /*
17317:     * length and minLength or maxLength (2.2) + (3.2)
17318:     */
17319:     if (flength && (fminlen || fmaxlen)) {
17320: 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17321: 	    "either of 'minLength' or 'maxLength' to be specified on "
17322: 	    "the same type definition")
17323:     }
17324:     /*
17325:     * Mutual exclusions in the same derivation step.
17326:     */
17327:     if ((fmaxinc) && (fmaxexc)) {
17328: 	/*
17329: 	* SCC "maxInclusive and maxExclusive"
17330: 	*/
17331: 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17332:     }
17333:     if ((fmininc) && (fminexc)) {
17334: 	/*
17335: 	* SCC "minInclusive and minExclusive"
17336: 	*/
17337: 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17338:     }
17339: 
17340:     if (flength && bflength) {
17341: 	/*
17342: 	* SCC "length valid restriction"
17343: 	* The values have to be equal.
17344: 	*/
17345: 	res = xmlSchemaCompareValues(flength->val, bflength->val);
17346: 	if (res == -2)
17347: 	    goto internal_error;
17348: 	if (res != 0)
17349: 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17350: 	if ((res != 0) && (bflength->fixed)) {
17351: 	    FACET_RESTR_FIXED_ERR(flength)
17352: 	}
17353: 
17354:     }
17355:     if (fminlen && bfminlen) {
17356: 	/*
17357: 	* SCC "minLength valid restriction"
17358: 	* minLength >= BASE minLength
17359: 	*/
17360: 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17361: 	if (res == -2)
17362: 	    goto internal_error;
17363: 	if (res == -1)
17364: 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17365: 	if ((res != 0) && (bfminlen->fixed)) {
17366: 	    FACET_RESTR_FIXED_ERR(fminlen)
17367: 	}
17368:     }
17369:     if (fmaxlen && bfmaxlen) {
17370: 	/*
17371: 	* SCC "maxLength valid restriction"
17372: 	* maxLength <= BASE minLength
17373: 	*/
17374: 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17375: 	if (res == -2)
17376: 	    goto internal_error;
17377: 	if (res == 1)
17378: 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17379: 	if ((res != 0) && (bfmaxlen->fixed)) {
17380: 	    FACET_RESTR_FIXED_ERR(fmaxlen)
17381: 	}
17382:     }
17383:     /*
17384:     * SCC "length and minLength or maxLength"
17385:     */
17386:     if (! flength)
17387: 	flength = bflength;
17388:     if (flength) {
17389: 	if (! fminlen)
17390: 	    fminlen = bfminlen;
17391: 	if (fminlen) {
17392: 	    /* (1.1) length >= minLength */
17393: 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
17394: 	    if (res == -2)
17395: 		goto internal_error;
17396: 	    if (res == -1)
17397: 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17398: 	}
17399: 	if (! fmaxlen)
17400: 	    fmaxlen = bfmaxlen;
17401: 	if (fmaxlen) {
17402: 	    /* (2.1) length <= maxLength */
17403: 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17404: 	    if (res == -2)
17405: 		goto internal_error;
17406: 	    if (res == 1)
17407: 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17408: 	}
17409:     }
17410:     if (fmaxinc) {
17411: 	/*
17412: 	* "maxInclusive"
17413: 	*/
17414: 	if (fmininc) {
17415: 	    /* SCC "maxInclusive >= minInclusive" */
17416: 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17417: 	    if (res == -2)
17418: 		goto internal_error;
17419: 	    if (res == -1) {
17420: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17421: 	    }
17422: 	}
17423: 	/*
17424: 	* SCC "maxInclusive valid restriction"
17425: 	*/
17426: 	if (bfmaxinc) {
17427: 	    /* maxInclusive <= BASE maxInclusive */
17428: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17429: 	    if (res == -2)
17430: 		goto internal_error;
17431: 	    if (res == 1)
17432: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17433: 	    if ((res != 0) && (bfmaxinc->fixed)) {
17434: 		FACET_RESTR_FIXED_ERR(fmaxinc)
17435: 	    }
17436: 	}
17437: 	if (bfmaxexc) {
17438: 	    /* maxInclusive < BASE maxExclusive */
17439: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17440: 	    if (res == -2)
17441: 		goto internal_error;
17442: 	    if (res != -1) {
17443: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17444: 	    }
17445: 	}
17446: 	if (bfmininc) {
17447: 	    /* maxInclusive >= BASE minInclusive */
17448: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17449: 	    if (res == -2)
17450: 		goto internal_error;
17451: 	    if (res == -1) {
17452: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17453: 	    }
17454: 	}
17455: 	if (bfminexc) {
17456: 	    /* maxInclusive > BASE minExclusive */
17457: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17458: 	    if (res == -2)
17459: 		goto internal_error;
17460: 	    if (res != 1) {
17461: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17462: 	    }
17463: 	}
17464:     }
17465:     if (fmaxexc) {
17466: 	/*
17467: 	* "maxExclusive >= minExclusive"
17468: 	*/
17469: 	if (fminexc) {
17470: 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17471: 	    if (res == -2)
17472: 		goto internal_error;
17473: 	    if (res == -1) {
17474: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17475: 	    }
17476: 	}
17477: 	/*
17478: 	* "maxExclusive valid restriction"
17479: 	*/
17480: 	if (bfmaxexc) {
17481: 	    /* maxExclusive <= BASE maxExclusive */
17482: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17483: 	    if (res == -2)
17484: 		goto internal_error;
17485: 	    if (res == 1) {
17486: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17487: 	    }
17488: 	    if ((res != 0) && (bfmaxexc->fixed)) {
17489: 		FACET_RESTR_FIXED_ERR(fmaxexc)
17490: 	    }
17491: 	}
17492: 	if (bfmaxinc) {
17493: 	    /* maxExclusive <= BASE maxInclusive */
17494: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17495: 	    if (res == -2)
17496: 		goto internal_error;
17497: 	    if (res == 1) {
17498: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17499: 	    }
17500: 	}
17501: 	if (bfmininc) {
17502: 	    /* maxExclusive > BASE minInclusive */
17503: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17504: 	    if (res == -2)
17505: 		goto internal_error;
17506: 	    if (res != 1) {
17507: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17508: 	    }
17509: 	}
17510: 	if (bfminexc) {
17511: 	    /* maxExclusive > BASE minExclusive */
17512: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17513: 	    if (res == -2)
17514: 		goto internal_error;
17515: 	    if (res != 1) {
17516: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17517: 	    }
17518: 	}
17519:     }
17520:     if (fminexc) {
17521: 	/*
17522: 	* "minExclusive < maxInclusive"
17523: 	*/
17524: 	if (fmaxinc) {
17525: 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17526: 	    if (res == -2)
17527: 		goto internal_error;
17528: 	    if (res != -1) {
17529: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17530: 	    }
17531: 	}
17532: 	/*
17533: 	* "minExclusive valid restriction"
17534: 	*/
17535: 	if (bfminexc) {
17536: 	    /* minExclusive >= BASE minExclusive */
17537: 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17538: 	    if (res == -2)
17539: 		goto internal_error;
17540: 	    if (res == -1) {
17541: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17542: 	    }
17543: 	    if ((res != 0) && (bfminexc->fixed)) {
17544: 		FACET_RESTR_FIXED_ERR(fminexc)
17545: 	    }
17546: 	}
17547: 	if (bfmaxinc) {
17548: 	    /* minExclusive <= BASE maxInclusive */
17549: 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17550: 	    if (res == -2)
17551: 		goto internal_error;
17552: 	    if (res == 1) {
17553: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17554: 	    }
17555: 	}
17556: 	if (bfmininc) {
17557: 	    /* minExclusive >= BASE minInclusive */
17558: 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17559: 	    if (res == -2)
17560: 		goto internal_error;
17561: 	    if (res == -1) {
17562: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17563: 	    }
17564: 	}
17565: 	if (bfmaxexc) {
17566: 	    /* minExclusive < BASE maxExclusive */
17567: 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17568: 	    if (res == -2)
17569: 		goto internal_error;
17570: 	    if (res != -1) {
17571: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17572: 	    }
17573: 	}
17574:     }
17575:     if (fmininc) {
17576: 	/*
17577: 	* "minInclusive < maxExclusive"
17578: 	*/
17579: 	if (fmaxexc) {
17580: 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17581: 	    if (res == -2)
17582: 		goto internal_error;
17583: 	    if (res != -1) {
17584: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17585: 	    }
17586: 	}
17587: 	/*
17588: 	* "minExclusive valid restriction"
17589: 	*/
17590: 	if (bfmininc) {
17591: 	    /* minInclusive >= BASE minInclusive */
17592: 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17593: 	    if (res == -2)
17594: 		goto internal_error;
17595: 	    if (res == -1) {
17596: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17597: 	    }
17598: 	    if ((res != 0) && (bfmininc->fixed)) {
17599: 		FACET_RESTR_FIXED_ERR(fmininc)
17600: 	    }
17601: 	}
17602: 	if (bfmaxinc) {
17603: 	    /* minInclusive <= BASE maxInclusive */
17604: 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17605: 	    if (res == -2)
17606: 		goto internal_error;
17607: 	    if (res == 1) {
17608: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17609: 	    }
17610: 	}
17611: 	if (bfminexc) {
17612: 	    /* minInclusive > BASE minExclusive */
17613: 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17614: 	    if (res == -2)
17615: 		goto internal_error;
17616: 	    if (res != 1)
17617: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17618: 	}
17619: 	if (bfmaxexc) {
17620: 	    /* minInclusive < BASE maxExclusive */
17621: 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17622: 	    if (res == -2)
17623: 		goto internal_error;
17624: 	    if (res != -1)
17625: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17626: 	}
17627:     }
17628:     if (ftotdig && bftotdig) {
17629: 	/*
17630: 	* SCC " totalDigits valid restriction"
17631: 	* totalDigits <= BASE totalDigits
17632: 	*/
17633: 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17634: 	if (res == -2)
17635: 	    goto internal_error;
17636: 	if (res == 1)
17637: 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17638: 	    -1, 1, 1);
17639: 	if ((res != 0) && (bftotdig->fixed)) {
17640: 	    FACET_RESTR_FIXED_ERR(ftotdig)
17641: 	}
17642:     }
17643:     if (ffracdig && bffracdig) {
17644: 	/*
17645: 	* SCC  "fractionDigits valid restriction"
17646: 	* fractionDigits <= BASE fractionDigits
17647: 	*/
17648: 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17649: 	if (res == -2)
17650: 	    goto internal_error;
17651: 	if (res == 1)
17652: 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17653: 	    -1, 1, 1);
17654: 	if ((res != 0) && (bffracdig->fixed)) {
17655: 	    FACET_RESTR_FIXED_ERR(ffracdig)
17656: 	}
17657:     }
17658:     /*
17659:     * SCC "fractionDigits less than or equal to totalDigits"
17660:     */
17661:     if (! ftotdig)
17662: 	ftotdig = bftotdig;
17663:     if (! ffracdig)
17664: 	ffracdig = bffracdig;
17665:     if (ftotdig && ffracdig) {
17666: 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17667: 	if (res == -2)
17668: 	    goto internal_error;
17669: 	if (res == 1)
17670: 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17671: 		-1, 1, 0);
17672:     }
17673:     /*
17674:     * *Enumerations* won' be added here, since only the first set
17675:     * of enumerations in the ancestor-or-self axis is used
17676:     * for validation, plus we need to use the base type of those
17677:     * enumerations for whitespace.
17678:     *
17679:     * *Patterns*: won't be add here, since they are ORed at
17680:     * type level and ANDed at ancestor level. This will
17681:     * happed during validation by walking the base axis
17682:     * of the type.
17683:     */
17684:     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17685: 	bfacet = cur->facet;
17686: 	/*
17687: 	* Special handling of enumerations and patterns.
17688: 	* TODO: hmm, they should not appear in the set, so remove this.
17689: 	*/
17690: 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17691: 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17692: 	    continue;
17693: 	/*
17694: 	* Search for a duplicate facet in the current type.
17695: 	*/
17696: 	link = type->facetSet;
17697: 	/* err = 0; */
17698: 	/* fixedErr = 0; */
17699: 	while (link != NULL) {
17700: 	    facet = link->facet;
17701: 	    if (facet->type == bfacet->type) {
17702: 		switch (facet->type) {
17703: 		    case XML_SCHEMA_FACET_WHITESPACE:
17704: 			/*
17705: 			* The whitespace must be stronger.
17706: 			*/
17707: 			if (facet->whitespace < bfacet->whitespace) {
17708: 			    FACET_RESTR_ERR(facet,
17709: 				"The 'whitespace' value has to be equal to "
17710: 				"or stronger than the 'whitespace' value of "
17711: 				"the base type")
17712: 			}
17713: 			if ((bfacet->fixed) &&
17714: 			    (facet->whitespace != bfacet->whitespace)) {
17715: 			    FACET_RESTR_FIXED_ERR(facet)
17716: 			}
17717: 			break;
17718: 		    default:
17719: 			break;
17720: 		}
17721: 		/* Duplicate found. */
17722: 		break;
17723: 	    }
17724: 	    link = link->next;
17725: 	}
17726: 	/*
17727: 	* If no duplicate was found: add the base types's facet
17728: 	* to the set.
17729: 	*/
17730: 	if (link == NULL) {
17731: 	    link = (xmlSchemaFacetLinkPtr)
17732: 		xmlMalloc(sizeof(xmlSchemaFacetLink));
17733: 	    if (link == NULL) {
17734: 		xmlSchemaPErrMemory(pctxt,
17735: 		    "deriving facets, creating a facet link", NULL);
17736: 		return (-1);
17737: 	    }
17738: 	    link->facet = cur->facet;
17739: 	    link->next = NULL;
17740: 	    if (last == NULL)
17741: 		type->facetSet = link;
17742: 	    else
17743: 		last->next = link;
17744: 	    last = link;
17745: 	}
17746: 
17747:     }
17748: 
17749:     return (0);
17750: internal_error:
17751:     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17752: 	"an error occured");
17753:     return (-1);
17754: }
17755: 
17756: static int
17757: xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17758: 					     xmlSchemaTypePtr type)
17759: {
17760:     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17761:     /*
17762:     * The actual value is then formed by replacing any union type
17763:     * definition in the �explicit members� with the members of their
17764:     * {member type definitions}, in order.
17765:     *
17766:     * TODO: There's a bug entry at
17767:     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17768:     * which indicates that we'll keep the union types the future.
17769:     */
17770:     link = type->memberTypes;
17771:     while (link != NULL) {
17772: 
17773: 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
17774: 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17775: 
17776: 	if (WXS_IS_UNION(link->type)) {
17777: 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17778: 	    if (subLink != NULL) {
17779: 		link->type = subLink->type;
17780: 		if (subLink->next != NULL) {
17781: 		    lastLink = link->next;
17782: 		    subLink = subLink->next;
17783: 		    prevLink = link;
17784: 		    while (subLink != NULL) {
17785: 			newLink = (xmlSchemaTypeLinkPtr)
17786: 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
17787: 			if (newLink == NULL) {
17788: 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
17789: 				NULL);
17790: 			    return (-1);
17791: 			}
17792: 			newLink->type = subLink->type;
17793: 			prevLink->next = newLink;
17794: 			prevLink = newLink;
17795: 			newLink->next = lastLink;
17796: 
17797: 			subLink = subLink->next;
17798: 		    }
17799: 		}
17800: 	    }
17801: 	}
17802: 	link = link->next;
17803:     }
17804:     return (0);
17805: }
17806: 
17807: static void
17808: xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17809: {
17810:     int has = 0, needVal = 0, normVal = 0;
17811: 
17812:     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17813:     if (has) {
17814: 	needVal = (type->baseType->flags &
17815: 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17816: 	normVal = (type->baseType->flags &
17817: 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17818:     }
17819:     if (type->facets != NULL) {
17820: 	xmlSchemaFacetPtr fac;
17821: 
17822: 	for (fac = type->facets; fac != NULL; fac = fac->next) {
17823: 	    switch (fac->type) {
17824: 		case XML_SCHEMA_FACET_WHITESPACE:
17825: 		    break;
17826: 		case XML_SCHEMA_FACET_PATTERN:
17827: 		    normVal = 1;
17828: 		    has = 1;
17829: 		    break;
17830: 		case XML_SCHEMA_FACET_ENUMERATION:
17831: 		    needVal = 1;
17832: 		    normVal = 1;
17833: 		    has = 1;
17834: 		    break;
17835: 		default:
17836: 		    has = 1;
17837: 		    break;
17838: 	    }
17839: 	}
17840:     }
17841:     if (normVal)
17842: 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17843:     if (needVal)
17844: 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17845:     if (has)
17846: 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17847: 
17848:     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17849: 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17850: 	/*
17851: 	* OPTIMIZE VAL TODO: Some facets need a computed value.
17852: 	*/
17853: 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17854: 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
17855: 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17856: 	}
17857:     }
17858: }
17859: 
17860: static int
17861: xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17862: {
17863: 
17864: 
17865:     /*
17866:     * Evaluate the whitespace-facet value.
17867:     */
17868:     if (WXS_IS_LIST(type)) {
17869: 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17870: 	return (0);
17871:     } else if (WXS_IS_UNION(type))
17872: 	return (0);
17873: 
17874:     if (type->facetSet != NULL) {
17875: 	xmlSchemaFacetLinkPtr lin;
17876: 
17877: 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17878: 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17879: 		switch (lin->facet->whitespace) {
17880: 		case XML_SCHEMAS_FACET_PRESERVE:
17881: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17882: 		    break;
17883: 		case XML_SCHEMAS_FACET_REPLACE:
17884: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17885: 		    break;
17886: 		case XML_SCHEMAS_FACET_COLLAPSE:
17887: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17888: 		    break;
17889: 		default:
17890: 		    return (-1);
17891: 		}
17892: 		return (0);
17893: 	    }
17894: 	}
17895:     }
17896:     /*
17897:     * For all �atomic� datatypes other than string (and types �derived�
17898:     * by �restriction� from it) the value of whiteSpace is fixed to
17899:     * collapse
17900:     */
17901:     {
17902: 	xmlSchemaTypePtr anc;
17903: 
17904: 	for (anc = type->baseType; anc != NULL &&
17905: 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
17906: 		anc = anc->baseType) {
17907: 
17908: 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17909: 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17910: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17911: 
17912: 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17913: 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17914: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17915: 
17916: 		} else
17917: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17918: 		break;
17919: 	    }
17920: 	}
17921:     }
17922:     return (0);
17923: }
17924: 
17925: static int
17926: xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17927: 			  xmlSchemaTypePtr type)
17928: {
17929:     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17930: 	return(0);
17931:     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17932: 	return(0);
17933:     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17934: 
17935:     if (WXS_IS_LIST(type)) {
17936: 	/*
17937: 	* Corresponds to <simpleType><list>...
17938: 	*/
17939: 	if (type->subtypes == NULL) {
17940: 	    /*
17941: 	    * This one is really needed, so get out.
17942: 	    */
17943: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17944: 		"list type has no item-type assigned");
17945: 	    return(-1);
17946: 	}
17947:     } else if (WXS_IS_UNION(type)) {
17948: 	/*
17949: 	* Corresponds to <simpleType><union>...
17950: 	*/
17951: 	if (type->memberTypes == NULL) {
17952: 	    /*
17953: 	    * This one is really needed, so get out.
17954: 	    */
17955: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17956: 		"union type has no member-types assigned");
17957: 	    return(-1);
17958: 	}
17959:     } else {
17960: 	/*
17961: 	* Corresponds to <simpleType><restriction>...
17962: 	*/
17963: 	if (type->baseType == NULL) {
17964: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17965: 		"type has no base-type assigned");
17966: 	    return(-1);
17967: 	}
17968: 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17969: 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17970: 		return(-1);
17971: 	/*
17972: 	* Variety
17973: 	* If the <restriction> alternative is chosen, then the
17974: 	* {variety} of the {base type definition}.
17975: 	*/
17976: 	if (WXS_IS_ATOMIC(type->baseType))
17977: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17978: 	else if (WXS_IS_LIST(type->baseType)) {
17979: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17980: 	    /*
17981: 	    * Inherit the itemType.
17982: 	    */
17983: 	    type->subtypes = type->baseType->subtypes;
17984: 	} else if (WXS_IS_UNION(type->baseType)) {
17985: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17986: 	    /*
17987: 	    * NOTE that we won't assign the memberTypes of the base,
17988: 	    * since this will make trouble when freeing them; we will
17989: 	    * use a lookup function to access them instead.
17990: 	    */
17991: 	}
17992:     }
17993:     return(0);
17994: }
17995: 
17996: #ifdef DEBUG_TYPE
17997: static void
17998: xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
17999: 		       xmlSchemaTypePtr type)
18000: {
18001:     if (type->node != NULL) {
18002:         xmlGenericError(xmlGenericErrorContext,
18003:                         "Type of %s : %s:%d :", name,
18004:                         type->node->doc->URL,
18005:                         xmlGetLineNo(type->node));
18006:     } else {
18007:         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
18008:     }
18009:     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
18010: 	switch (type->contentType) {
18011: 	    case XML_SCHEMA_CONTENT_SIMPLE:
18012: 		xmlGenericError(xmlGenericErrorContext, "simple\n");
18013: 		break;
18014: 	    case XML_SCHEMA_CONTENT_ELEMENTS:
18015: 		xmlGenericError(xmlGenericErrorContext, "elements\n");
18016: 		break;
18017: 	    case XML_SCHEMA_CONTENT_UNKNOWN:
18018: 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
18019: 		break;
18020: 	    case XML_SCHEMA_CONTENT_EMPTY:
18021: 		xmlGenericError(xmlGenericErrorContext, "empty\n");
18022: 		break;
18023: 	    case XML_SCHEMA_CONTENT_MIXED:
18024: 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
18025: 		    type->subtypes))
18026: 		    xmlGenericError(xmlGenericErrorContext,
18027: 			"mixed as emptiable particle\n");
18028: 		else
18029: 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
18030: 		break;
18031: 		/* Removed, since not used. */
18032: 		/*
18033: 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18034: 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18035: 		break;
18036: 		*/
18037: 	    case XML_SCHEMA_CONTENT_BASIC:
18038: 		xmlGenericError(xmlGenericErrorContext, "basic\n");
18039: 		break;
18040: 	    default:
18041: 		xmlGenericError(xmlGenericErrorContext,
18042: 		    "not registered !!!\n");
18043: 		break;
18044: 	}
18045:     }
18046: }
18047: #endif
18048: 
18049: /*
18050: * 3.14.6 Constraints on Simple Type Definition Schema Components
18051: */
18052: static int
18053: xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18054: 				 xmlSchemaTypePtr type)
18055: {
18056:     int res, olderrs = pctxt->nberrors;
18057: 
18058:     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18059: 	return(-1);
18060: 
18061:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18062: 	return(0);
18063: 
18064:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18065:     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18066: 
18067:     if (type->baseType == NULL) {
18068: 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18069: 	    "missing baseType");
18070: 	goto exit_failure;
18071:     }
18072:     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18073: 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18074:     /*
18075:     * If a member type of a union is a union itself, we need to substitute
18076:     * that member type for its member types.
18077:     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18078:     * types in WXS 1.1.
18079:     */
18080:     if ((type->memberTypes != NULL) &&
18081: 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18082: 	return(-1);
18083:     /*
18084:     * SPEC src-simple-type 1
18085:     * "The corresponding simple type definition, if any, must satisfy
18086:     * the conditions set out in Constraints on Simple Type Definition
18087:     * Schema Components (�3.14.6)."
18088:     */
18089:     /*
18090:     * Schema Component Constraint: Simple Type Definition Properties Correct
18091:     * (st-props-correct)
18092:     */
18093:     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18094:     HFAILURE HERROR
18095:     /*
18096:     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18097:     * (cos-st-restricts)
18098:     */
18099:     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18100:     HFAILURE HERROR
18101:     /*
18102:     * TODO: Removed the error report, since it got annoying to get an
18103:     * extra error report, if anything failed until now.
18104:     * Enable this if needed.
18105:     *
18106:     * xmlSchemaPErr(ctxt, type->node,
18107:     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18108:     *    "Simple type '%s' does not satisfy the constraints "
18109:     *    "on simple type definitions.\n",
18110:     *    type->name, NULL);
18111:     */
18112:     /*
18113:     * Schema Component Constraint: Simple Type Restriction (Facets)
18114:     * (st-restrict-facets)
18115:     */
18116:     res = xmlSchemaCheckFacetValues(type, pctxt);
18117:     HFAILURE HERROR
18118:     if ((type->facetSet != NULL) ||
18119: 	(type->baseType->facetSet != NULL)) {
18120: 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18121: 	HFAILURE HERROR
18122:     }
18123:     /*
18124:     * Whitespace value.
18125:     */
18126:     res = xmlSchemaTypeFixupWhitespace(type);
18127:     HFAILURE HERROR
18128:     xmlSchemaTypeFixupOptimFacets(type);
18129: 
18130: exit_error:
18131: #ifdef DEBUG_TYPE
18132:     xmlSchemaDebugFixedType(pctxt, type);
18133: #endif
18134:     if (olderrs != pctxt->nberrors)
18135: 	return(pctxt->err);
18136:     return(0);
18137: 
18138: exit_failure:
18139: #ifdef DEBUG_TYPE
18140:     xmlSchemaDebugFixedType(pctxt, type);
18141: #endif
18142:     return(-1);
18143: }
18144: 
18145: static int
18146: xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18147: 			  xmlSchemaTypePtr type)
18148: {
18149:     int res = 0, olderrs = pctxt->nberrors;
18150:     xmlSchemaTypePtr baseType = type->baseType;
18151: 
18152:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18153: 	return(0);
18154:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18155:     if (baseType == NULL) {
18156: 	PERROR_INT("xmlSchemaFixupComplexType",
18157: 	    "missing baseType");
18158: 	goto exit_failure;
18159:     }
18160:     /*
18161:     * Fixup the base type.
18162:     */
18163:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
18164: 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18165:     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18166: 	/*
18167: 	* Skip fixup if the base type is invalid.
18168: 	* TODO: Generate a warning!
18169: 	*/
18170: 	return(0);
18171:     }
18172:     /*
18173:     * This basically checks if the base type can be derived.
18174:     */
18175:     res = xmlSchemaCheckSRCCT(pctxt, type);
18176:     HFAILURE HERROR
18177:     /*
18178:     * Fixup the content type.
18179:     */
18180:     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18181: 	/*
18182: 	* Corresponds to <complexType><simpleContent>...
18183: 	*/
18184: 	if ((WXS_IS_COMPLEX(baseType)) &&
18185: 	    (baseType->contentTypeDef != NULL) &&
18186: 	    (WXS_IS_RESTRICTION(type))) {
18187: 	    xmlSchemaTypePtr contentBase, content;
18188: #ifdef ENABLE_NAMED_LOCALS
18189: 	    char buf[30];
18190: 	    const xmlChar *tmpname;
18191: #endif
18192: 	    /*
18193: 	    * SPEC (1) If <restriction> + base type is <complexType>,
18194: 	    * "whose own {content type} is a simple type..."
18195: 	    */
18196: 	    if (type->contentTypeDef != NULL) {
18197: 		/*
18198: 		* SPEC (1.1) "the simple type definition corresponding to the
18199: 		* <simpleType> among the [children] of <restriction> if there
18200: 		* is one;"
18201: 		* Note that this "<simpleType> among the [children]" was put
18202: 		* into ->contentTypeDef during parsing.
18203: 		*/
18204: 		contentBase = type->contentTypeDef;
18205: 		type->contentTypeDef = NULL;
18206: 	    } else {
18207: 		/*
18208: 		* (1.2) "...otherwise (<restriction> has no <simpleType>
18209: 		* among its [children]), the simple type definition which
18210: 		* is the {content type} of the ... base type."
18211: 		*/
18212: 		contentBase = baseType->contentTypeDef;
18213: 	    }
18214: 	    /*
18215: 	    * SPEC
18216: 	    * "... a simple type definition which restricts the simple
18217: 	    * type definition identified in clause 1.1 or clause 1.2
18218: 	    * with a set of facet components"
18219: 	    *
18220: 	    * Create the anonymous simple type, which will be the content
18221: 	    * type of the complex type.
18222: 	    */
18223: #ifdef ENABLE_NAMED_LOCALS
18224: 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18225: 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18226: 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
18227: 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18228: 		type->node, 0);
18229: #else
18230: 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
18231: 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18232: 		type->node, 0);
18233: #endif
18234: 	    if (content == NULL)
18235: 		goto exit_failure;
18236: 	    /*
18237: 	    * We will use the same node as for the <complexType>
18238: 	    * to have it somehow anchored in the schema doc.
18239: 	    */
18240: 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
18241: 	    content->baseType = contentBase;
18242: 	    /*
18243: 	    * Move the facets, previously anchored on the
18244: 	    * complexType during parsing.
18245: 	    */
18246: 	    content->facets = type->facets;
18247: 	    type->facets = NULL;
18248: 	    content->facetSet = type->facetSet;
18249: 	    type->facetSet = NULL;
18250: 
18251: 	    type->contentTypeDef = content;
18252: 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18253: 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18254: 	    /*
18255: 	    * Fixup the newly created type. We don't need to check
18256: 	    * for circularity here.
18257: 	    */
18258: 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18259: 	    HFAILURE HERROR
18260: 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18261: 	    HFAILURE HERROR
18262: 
18263: 	} else if ((WXS_IS_COMPLEX(baseType)) &&
18264: 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18265: 	    (WXS_IS_RESTRICTION(type))) {
18266: 	    /*
18267: 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
18268: 	    * an emptiable particle, then a simple type definition which
18269: 	    * restricts the <restriction>'s <simpleType> child.
18270: 	    */
18271: 	    if ((type->contentTypeDef == NULL) ||
18272: 		(type->contentTypeDef->baseType == NULL)) {
18273: 		/*
18274: 		* TODO: Check if this ever happens.
18275: 		*/
18276: 		xmlSchemaPCustomErr(pctxt,
18277: 		    XML_SCHEMAP_INTERNAL,
18278: 		    WXS_BASIC_CAST type, NULL,
18279: 		    "Internal error: xmlSchemaTypeFixup, "
18280: 		    "complex type '%s': the <simpleContent><restriction> "
18281: 		    "is missing a <simpleType> child, but was not catched "
18282: 		    "by xmlSchemaCheckSRCCT()", type->name);
18283: 		goto exit_failure;
18284: 	    }
18285: 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18286: 	    /*
18287: 	    * SPEC (3) If <extension> + base is <complexType> with
18288: 	    * <simpleType> content, "...then the {content type} of that
18289: 	    * complex type definition"
18290: 	    */
18291: 	    if (baseType->contentTypeDef == NULL) {
18292: 		/*
18293: 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18294: 		* should have catched this already.
18295: 		*/
18296: 		xmlSchemaPCustomErr(pctxt,
18297: 		    XML_SCHEMAP_INTERNAL,
18298: 		    WXS_BASIC_CAST type, NULL,
18299: 		    "Internal error: xmlSchemaTypeFixup, "
18300: 		    "complex type '%s': the <extension>ed base type is "
18301: 		    "a complex type with no simple content type",
18302: 		    type->name);
18303: 		goto exit_failure;
18304: 	    }
18305: 	    type->contentTypeDef = baseType->contentTypeDef;
18306: 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18307: 	    /*
18308: 	    * SPEC (4) <extension> + base is <simpleType>
18309: 	    * "... then that simple type definition"
18310: 	    */
18311: 	    type->contentTypeDef = baseType;
18312: 	} else {
18313: 	    /*
18314: 	    * TODO: Check if this ever happens.
18315: 	    */
18316: 	    xmlSchemaPCustomErr(pctxt,
18317: 		XML_SCHEMAP_INTERNAL,
18318: 		WXS_BASIC_CAST type, NULL,
18319: 		"Internal error: xmlSchemaTypeFixup, "
18320: 		"complex type '%s' with <simpleContent>: unhandled "
18321: 		"derivation case", type->name);
18322: 	    goto exit_failure;
18323: 	}
18324:     } else {
18325: 	int dummySequence = 0;
18326: 	xmlSchemaParticlePtr particle =
18327: 	    (xmlSchemaParticlePtr) type->subtypes;
18328: 	/*
18329: 	* Corresponds to <complexType><complexContent>...
18330: 	*
18331: 	* NOTE that the effective mixed was already set during parsing of
18332: 	* <complexType> and <complexContent>; its flag value is
18333: 	* XML_SCHEMAS_TYPE_MIXED.
18334: 	*
18335: 	* Compute the "effective content":
18336: 	* (2.1.1) + (2.1.2) + (2.1.3)
18337: 	*/
18338: 	if ((particle == NULL) ||
18339: 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18340: 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18341: 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18342: 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18343: 	    (particle->minOccurs == 0))) &&
18344: 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18345: 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18346: 		/*
18347: 		* SPEC (2.1.4) "If the �effective mixed� is true, then
18348: 		* a particle whose properties are as follows:..."
18349: 		*
18350: 		* Empty sequence model group with
18351: 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18352: 		* NOTE that we sill assign it the <complexType> node to
18353: 		* somehow anchor it in the doc.
18354: 		*/
18355: 		if ((particle == NULL) ||
18356: 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18357: 		    /*
18358: 		    * Create the particle.
18359: 		    */
18360: 		    particle = xmlSchemaAddParticle(pctxt,
18361: 			type->node, 1, 1);
18362: 		    if (particle == NULL)
18363: 			goto exit_failure;
18364: 		    /*
18365: 		    * Create the model group.
18366: 		    */ /* URGENT TODO: avoid adding to pending items. */
18367: 		    particle->children = (xmlSchemaTreeItemPtr)
18368: 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18369: 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
18370: 		    if (particle->children == NULL)
18371: 			goto exit_failure;
18372: 
18373: 		    type->subtypes = (xmlSchemaTypePtr) particle;
18374: 		}
18375: 		dummySequence = 1;
18376: 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18377: 	    } else {
18378: 		/*
18379: 		* SPEC (2.1.5) "otherwise empty"
18380: 		*/
18381: 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18382: 	    }
18383: 	} else {
18384: 	    /*
18385: 	    * SPEC (2.2) "otherwise the particle corresponding to the
18386: 	    * <all>, <choice>, <group> or <sequence> among the
18387: 	    * [children]."
18388: 	    */
18389: 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18390: 	}
18391: 	/*
18392: 	* Compute the "content type".
18393: 	*/
18394: 	if (WXS_IS_RESTRICTION(type)) {
18395: 	    /*
18396: 	    * SPEC (3.1) "If <restriction>..."
18397: 	    * (3.1.1) + (3.1.2) */
18398: 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18399: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18400: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18401: 	    }
18402: 	} else {
18403: 	    /*
18404: 	    * SPEC (3.2) "If <extension>..."
18405: 	    */
18406: 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18407: 		/*
18408: 		* SPEC (3.2.1)
18409: 		* "If the �effective content� is empty, then the
18410: 		*  {content type} of the [...] base ..."
18411: 		*/
18412: 		type->contentType = baseType->contentType;
18413: 		type->subtypes = baseType->subtypes;
18414: 		/*
18415: 		* Fixes bug #347316:
18416: 		* This is the case when the base type has a simple
18417: 		* type definition as content.
18418: 		*/
18419: 		type->contentTypeDef = baseType->contentTypeDef;
18420: 		/*
18421: 		* NOTE that the effective mixed is ignored here.
18422: 		*/
18423: 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18424: 		/*
18425: 		* SPEC (3.2.2)
18426: 		*/
18427: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18428: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18429: 	    } else {
18430: 		/*
18431: 		* SPEC (3.2.3)
18432: 		*/
18433: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18434: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18435: 		    /*
18436: 		    * "A model group whose {compositor} is sequence and whose
18437: 		    * {particles} are..."
18438: 		    */
18439: 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18440: 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18441: 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18442: 			XML_SCHEMA_TYPE_ALL))
18443: 		{
18444: 		    /*
18445: 		    * SPEC cos-all-limited (1)
18446: 		    */
18447: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18448: 			/* TODO: error code */
18449: 			XML_SCHEMAP_COS_ALL_LIMITED,
18450: 			WXS_ITEM_NODE(type), NULL,
18451: 			"The type has an 'all' model group in its "
18452: 			"{content type} and thus cannot be derived from "
18453: 			"a non-empty type, since this would produce a "
18454: 			"'sequence' model group containing the 'all' "
18455: 			"model group; 'all' model groups are not "
18456: 			"allowed to appear inside other model groups",
18457: 			NULL, NULL);
18458: 
18459: 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18460: 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18461: 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18462: 			XML_SCHEMA_TYPE_ALL))
18463: 		{
18464: 		    /*
18465: 		    * SPEC cos-all-limited (1)
18466: 		    */
18467: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18468: 			/* TODO: error code */
18469: 			XML_SCHEMAP_COS_ALL_LIMITED,
18470: 			WXS_ITEM_NODE(type), NULL,
18471: 			"A type cannot be derived by extension from a type "
18472: 			"which has an 'all' model group in its "
18473: 			"{content type}, since this would produce a "
18474: 			"'sequence' model group containing the 'all' "
18475: 			"model group; 'all' model groups are not "
18476: 			"allowed to appear inside other model groups",
18477: 			NULL, NULL);
18478: 
18479: 		} else if (! dummySequence) {
18480: 		    xmlSchemaTreeItemPtr effectiveContent =
18481: 			(xmlSchemaTreeItemPtr) type->subtypes;
18482: 		    /*
18483: 		    * Create the particle.
18484: 		    */
18485: 		    particle = xmlSchemaAddParticle(pctxt,
18486: 			type->node, 1, 1);
18487: 		    if (particle == NULL)
18488: 			goto exit_failure;
18489: 		    /*
18490: 		    * Create the "sequence" model group.
18491: 		    */
18492: 		    particle->children = (xmlSchemaTreeItemPtr)
18493: 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18494: 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
18495: 		    if (particle->children == NULL)
18496: 			goto exit_failure;
18497: 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18498: 		    /*
18499: 		    * SPEC "the particle of the {content type} of
18500: 		    * the ... base ..."
18501: 		    * Create a duplicate of the base type's particle
18502: 		    * and assign its "term" to it.
18503: 		    */
18504: 		    particle->children->children =
18505: 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18506: 			type->node,
18507: 			((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18508: 			((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18509: 		    if (particle->children->children == NULL)
18510: 			goto exit_failure;
18511: 		    particle = (xmlSchemaParticlePtr)
18512: 			particle->children->children;
18513: 		    particle->children =
18514: 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
18515: 		    /*
18516: 		    * SPEC "followed by the �effective content�."
18517: 		    */
18518: 		    particle->next = effectiveContent;
18519: 		    /*
18520: 		    * This all will result in:
18521: 		    * new-particle
18522: 		    *   --> new-sequence(
18523: 		    *         new-particle
18524: 		    *           --> base-model,
18525: 		    *         this-particle
18526: 		    *	        --> this-model
18527: 		    *	    )
18528: 		    */
18529: 		} else {
18530: 		    /*
18531: 		    * This is the case when there is already an empty
18532: 		    * <sequence> with minOccurs==maxOccurs==1.
18533: 		    * Just add the base types's content type.
18534: 		    * NOTE that, although we miss to add an intermediate
18535: 		    * <sequence>, this should produce no difference to
18536: 		    * neither the regex compilation of the content model,
18537: 		    * nor to the complex type contraints.
18538: 		    */
18539: 		    particle->children->children =
18540: 			(xmlSchemaTreeItemPtr) baseType->subtypes;
18541: 		}
18542: 	    }
18543: 	}
18544:     }
18545:     /*
18546:     * Now fixup attribute uses:
18547:     *   - expand attr. group references
18548:     *     - intersect attribute wildcards
18549:     *   - inherit attribute uses of the base type
18550:     *   - inherit or union attr. wildcards if extending
18551:     *   - apply attr. use prohibitions if restricting
18552:     */
18553:     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18554:     HFAILURE HERROR
18555:     /*
18556:     * Apply the complex type component constraints; this will not
18557:     * check attributes, since this is done in
18558:     * xmlSchemaFixupTypeAttributeUses().
18559:     */
18560:     res = xmlSchemaCheckCTComponent(pctxt, type);
18561:     HFAILURE HERROR
18562: 
18563: #ifdef DEBUG_TYPE
18564:     xmlSchemaDebugFixedType(pctxt, type);
18565: #endif
18566:     if (olderrs != pctxt->nberrors)
18567: 	return(pctxt->err);
18568:     else
18569: 	return(0);
18570: 
18571: exit_error:
18572:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18573: #ifdef DEBUG_TYPE
18574:     xmlSchemaDebugFixedType(pctxt, type);
18575: #endif
18576:     return(pctxt->err);
18577: 
18578: exit_failure:
18579:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18580: #ifdef DEBUG_TYPE
18581:     xmlSchemaDebugFixedType(pctxt, type);
18582: #endif
18583:     return(-1);
18584: }
18585: 
18586: 
18587: /**
18588:  * xmlSchemaTypeFixup:
18589:  * @typeDecl:  the schema type definition
18590:  * @ctxt:  the schema parser context
18591:  *
18592:  * Fixes the content model of the type.
18593:  * URGENT TODO: We need an int result!
18594:  */
18595: static int
18596: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18597:                    xmlSchemaAbstractCtxtPtr actxt)
18598: {
18599:     if (type == NULL)
18600:         return(0);
18601:     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18602: 	AERROR_INT("xmlSchemaTypeFixup",
18603: 	    "this function needs a parser context");
18604: 	return(-1);
18605:     }
18606:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18607: 	return(0);
18608:     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18609: 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18610:     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18611: 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18612:     return(0);
18613: }
18614: 
18615: /**
18616:  * xmlSchemaCheckFacet:
18617:  * @facet:  the facet
18618:  * @typeDecl:  the schema type definition
18619:  * @pctxt:  the schema parser context or NULL
18620:  * @name: the optional name of the type
18621:  *
18622:  * Checks and computes the values of facets.
18623:  *
18624:  * Returns 0 if valid, a positive error code if not valid and
18625:  *         -1 in case of an internal or API error.
18626:  */
18627: int
18628: xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18629:                     xmlSchemaTypePtr typeDecl,
18630:                     xmlSchemaParserCtxtPtr pctxt,
18631: 		    const xmlChar * name ATTRIBUTE_UNUSED)
18632: {
18633:     int ret = 0, ctxtGiven;
18634: 
18635:     if ((facet == NULL) || (typeDecl == NULL))
18636:         return(-1);
18637:     /*
18638:     * TODO: will the parser context be given if used from
18639:     * the relaxNG module?
18640:     */
18641:     if (pctxt == NULL)
18642: 	ctxtGiven = 0;
18643:     else
18644: 	ctxtGiven = 1;
18645: 
18646:     switch (facet->type) {
18647:         case XML_SCHEMA_FACET_MININCLUSIVE:
18648:         case XML_SCHEMA_FACET_MINEXCLUSIVE:
18649:         case XML_SCHEMA_FACET_MAXINCLUSIVE:
18650:         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18651: 	case XML_SCHEMA_FACET_ENUMERATION: {
18652:                 /*
18653:                  * Okay we need to validate the value
18654:                  * at that point.
18655:                  */
18656: 		xmlSchemaTypePtr base;
18657: 
18658: 		/* 4.3.5.5 Constraints on enumeration Schema Components
18659: 		* Schema Component Constraint: enumeration valid restriction
18660: 		* It is an �error� if any member of {value} is not in the
18661: 		* �value space� of {base type definition}.
18662: 		*
18663: 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
18664: 		* The value �must� be in the
18665: 		* �value space� of the �base type�.
18666: 		*/
18667: 		/*
18668: 		* This function is intended to deliver a compiled value
18669: 		* on the facet. In this implementation of XML Schemata the
18670: 		* type holding a facet, won't be a built-in type.
18671: 		* Thus to ensure that other API
18672: 		* calls (relaxng) do work, if the given type is a built-in
18673: 		* type, we will assume that the given built-in type *is
18674: 		* already* the base type.
18675: 		*/
18676: 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18677: 		    base = typeDecl->baseType;
18678: 		    if (base == NULL) {
18679: 			PERROR_INT("xmlSchemaCheckFacet",
18680: 			    "a type user derived type has no base type");
18681: 			return (-1);
18682: 		    }
18683: 		} else
18684: 		    base = typeDecl;
18685: 
18686: 		if (! ctxtGiven) {
18687: 		    /*
18688: 		    * A context is needed if called from RelaxNG.
18689: 		    */
18690: 		    pctxt = xmlSchemaNewParserCtxt("*");
18691: 		    if (pctxt == NULL)
18692: 			return (-1);
18693: 		}
18694: 		/*
18695: 		* NOTE: This call does not check the content nodes,
18696: 		* since they are not available:
18697: 		* facet->node is just the node holding the facet
18698: 		* definition, *not* the attribute holding the *value*
18699: 		* of the facet.
18700: 		*/
18701: 		ret = xmlSchemaVCheckCVCSimpleType(
18702: 		    ACTXT_CAST pctxt, facet->node, base,
18703: 		    facet->value, &(facet->val), 1, 1, 0);
18704:                 if (ret != 0) {
18705: 		    if (ret < 0) {
18706: 			/* No error message for RelaxNG. */
18707: 			if (ctxtGiven) {
18708: 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18709: 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
18710: 				"Internal error: xmlSchemaCheckFacet, "
18711: 				"failed to validate the value '%s' of the "
18712: 				"facet '%s' against the base type",
18713: 				facet->value, xmlSchemaFacetTypeToString(facet->type));
18714: 			}
18715: 			goto internal_error;
18716: 		    }
18717: 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18718: 		    /* No error message for RelaxNG. */
18719: 		    if (ctxtGiven) {
18720: 			xmlChar *str = NULL;
18721: 
18722: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
18723: 			    ret, facet->node, WXS_BASIC_CAST facet,
18724: 			    "The value '%s' of the facet does not validate "
18725: 			    "against the base type '%s'",
18726: 			    facet->value,
18727: 			    xmlSchemaFormatQName(&str,
18728: 				base->targetNamespace, base->name));
18729: 			FREE_AND_NULL(str);
18730: 		    }
18731: 		    goto exit;
18732:                 } else if (facet->val == NULL) {
18733: 		    if (ctxtGiven) {
18734: 			PERROR_INT("xmlSchemaCheckFacet",
18735: 			    "value was not computed");
18736: 		    }
18737: 		    TODO
18738: 		}
18739:                 break;
18740:             }
18741:         case XML_SCHEMA_FACET_PATTERN:
18742:             facet->regexp = xmlRegexpCompile(facet->value);
18743:             if (facet->regexp == NULL) {
18744: 		ret = XML_SCHEMAP_REGEXP_INVALID;
18745: 		/* No error message for RelaxNG. */
18746: 		if (ctxtGiven) {
18747: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18748: 			ret, facet->node, WXS_BASIC_CAST typeDecl,
18749: 			"The value '%s' of the facet 'pattern' is not a "
18750: 			"valid regular expression",
18751: 			facet->value, NULL);
18752: 		}
18753:             }
18754:             break;
18755:         case XML_SCHEMA_FACET_TOTALDIGITS:
18756:         case XML_SCHEMA_FACET_FRACTIONDIGITS:
18757:         case XML_SCHEMA_FACET_LENGTH:
18758:         case XML_SCHEMA_FACET_MAXLENGTH:
18759:         case XML_SCHEMA_FACET_MINLENGTH:
18760: 
18761: 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18762: 		ret = xmlSchemaValidatePredefinedType(
18763: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18764: 		    facet->value, &(facet->val));
18765: 	    } else {
18766: 		ret = xmlSchemaValidatePredefinedType(
18767: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18768: 		    facet->value, &(facet->val));
18769: 	    }
18770: 	    if (ret != 0) {
18771: 		if (ret < 0) {
18772: 		    /* No error message for RelaxNG. */
18773: 		    if (ctxtGiven) {
18774: 			PERROR_INT("xmlSchemaCheckFacet",
18775: 			    "validating facet value");
18776: 		    }
18777: 		    goto internal_error;
18778: 		}
18779: 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18780: 		/* No error message for RelaxNG. */
18781: 		if (ctxtGiven) {
18782: 		    /* error code */
18783: 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18784: 			ret, facet->node, WXS_BASIC_CAST typeDecl,
18785: 			"The value '%s' of the facet '%s' is not a valid '%s'",
18786: 			facet->value,
18787: 			xmlSchemaFacetTypeToString(facet->type),
18788: 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18789: 			    BAD_CAST "nonNegativeInteger" :
18790: 			    BAD_CAST "positiveInteger",
18791: 			NULL);
18792: 		}
18793: 	    }
18794: 	    break;
18795: 
18796:         case XML_SCHEMA_FACET_WHITESPACE:{
18797:                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18798:                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18799:                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18800:                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18801:                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18802:                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18803:                 } else {
18804: 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18805:                     /* No error message for RelaxNG. */
18806: 		    if (ctxtGiven) {
18807: 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18808: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
18809: 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
18810: 			    "The value '%s' of the facet 'whitespace' is not "
18811: 			    "valid", facet->value, NULL);
18812:                     }
18813:                 }
18814:             }
18815:         default:
18816:             break;
18817:     }
18818: exit:
18819:     if ((! ctxtGiven) && (pctxt != NULL))
18820: 	xmlSchemaFreeParserCtxt(pctxt);
18821:     return (ret);
18822: internal_error:
18823:     if ((! ctxtGiven) && (pctxt != NULL))
18824: 	xmlSchemaFreeParserCtxt(pctxt);
18825:     return (-1);
18826: }
18827: 
18828: /**
18829:  * xmlSchemaCheckFacetValues:
18830:  * @typeDecl:  the schema type definition
18831:  * @ctxt:  the schema parser context
18832:  *
18833:  * Checks the default values types, especially for facets
18834:  */
18835: static int
18836: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18837: 			  xmlSchemaParserCtxtPtr pctxt)
18838: {
18839:     int res, olderrs = pctxt->nberrors;
18840:     const xmlChar *name = typeDecl->name;
18841:     /*
18842:     * NOTE: It is intended to use the facets list, instead
18843:     * of facetSet.
18844:     */
18845:     if (typeDecl->facets != NULL) {
18846: 	xmlSchemaFacetPtr facet = typeDecl->facets;
18847: 
18848: 	/*
18849: 	* Temporarily assign the "schema" to the validation context
18850: 	* of the parser context. This is needed for NOTATION validation.
18851: 	*/
18852: 	if (pctxt->vctxt == NULL) {
18853: 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18854: 		return(-1);
18855: 	}
18856: 	pctxt->vctxt->schema = pctxt->schema;
18857: 	while (facet != NULL) {
18858: 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18859: 	    HFAILURE
18860: 	    facet = facet->next;
18861: 	}
18862: 	pctxt->vctxt->schema = NULL;
18863:     }
18864:     if (olderrs != pctxt->nberrors)
18865: 	return(pctxt->err);
18866:     return(0);
18867: exit_failure:
18868:     return(-1);
18869: }
18870: 
18871: /**
18872:  * xmlSchemaGetCircModelGrDefRef:
18873:  * @ctxtMGroup: the searched model group
18874:  * @selfMGroup: the second searched model group
18875:  * @particle: the first particle
18876:  *
18877:  * This one is intended to be used by
18878:  * xmlSchemaCheckGroupDefCircular only.
18879:  *
18880:  * Returns the particle with the circular model group definition reference,
18881:  * otherwise NULL.
18882:  */
18883: static xmlSchemaTreeItemPtr
18884: xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18885: 			      xmlSchemaTreeItemPtr particle)
18886: {
18887:     xmlSchemaTreeItemPtr circ = NULL;
18888:     xmlSchemaTreeItemPtr term;
18889:     xmlSchemaModelGroupDefPtr gdef;
18890: 
18891:     for (; particle != NULL; particle = particle->next) {
18892: 	term = particle->children;
18893: 	if (term == NULL)
18894: 	    continue;
18895: 	switch (term->type) {
18896: 	    case XML_SCHEMA_TYPE_GROUP:
18897: 		gdef = (xmlSchemaModelGroupDefPtr) term;
18898: 		if (gdef == groupDef)
18899: 		    return (particle);
18900: 		/*
18901: 		* Mark this model group definition to avoid infinite
18902: 		* recursion on circular references not yet examined.
18903: 		*/
18904: 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18905: 		    continue;
18906: 		if (gdef->children != NULL) {
18907: 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18908: 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18909: 			gdef->children->children);
18910: 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18911: 		    if (circ != NULL)
18912: 			return (circ);
18913: 		}
18914: 		break;
18915: 	    case XML_SCHEMA_TYPE_SEQUENCE:
18916: 	    case XML_SCHEMA_TYPE_CHOICE:
18917: 	    case XML_SCHEMA_TYPE_ALL:
18918: 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18919: 		if (circ != NULL)
18920: 		    return (circ);
18921: 		break;
18922: 	    default:
18923: 		break;
18924: 	}
18925:     }
18926:     return (NULL);
18927: }
18928: 
18929: /**
18930:  * xmlSchemaCheckGroupDefCircular:
18931:  * @item:  the model group definition
18932:  * @ctxt:  the parser context
18933:  * @name:  the name
18934:  *
18935:  * Checks for circular references to model group definitions.
18936:  */
18937: static void
18938: xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18939: 			       xmlSchemaParserCtxtPtr ctxt)
18940: {
18941:     /*
18942:     * Schema Component Constraint: Model Group Correct
18943:     * 2 Circular groups are disallowed. That is, within the {particles}
18944:     * of a group there must not be at any depth a particle whose {term}
18945:     * is the group itself.
18946:     */
18947:     if ((item == NULL) ||
18948: 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
18949: 	(item->children == NULL))
18950: 	return;
18951:     {
18952: 	xmlSchemaTreeItemPtr circ;
18953: 
18954: 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18955: 	if (circ != NULL) {
18956: 	    xmlChar *str = NULL;
18957: 	    /*
18958: 	    * TODO: The error report is not adequate: this constraint
18959: 	    * is defined for model groups but not definitions, but since
18960: 	    * there cannot be any circular model groups without a model group
18961: 	    * definition (if not using a construction API), we check those
18962: 	    * defintions only.
18963: 	    */
18964: 	    xmlSchemaPCustomErr(ctxt,
18965: 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
18966: 		NULL, WXS_ITEM_NODE(circ),
18967: 		"Circular reference to the model group definition '%s' "
18968: 		"defined", xmlSchemaFormatQName(&str,
18969: 		    item->targetNamespace, item->name));
18970: 	    FREE_AND_NULL(str)
18971: 	    /*
18972: 	    * NOTE: We will cut the reference to avoid further
18973: 	    * confusion of the processor. This is a fatal error.
18974: 	    */
18975: 	    circ->children = NULL;
18976: 	}
18977:     }
18978: }
18979: 
18980: /**
18981:  * xmlSchemaModelGroupToModelGroupDefFixup:
18982:  * @ctxt:  the parser context
18983:  * @mg:  the model group
18984:  *
18985:  * Assigns the model group of model group definitions to the "term"
18986:  * of the referencing particle.
18987:  * In xmlSchemaResolveModelGroupParticleReferences the model group
18988:  * definitions were assigned to the "term", since needed for the
18989:  * circularity check.
18990:  *
18991:  * Schema Component Constraint:
18992:  *     All Group Limited (cos-all-limited) (1.2)
18993:  */
18994: static void
18995: xmlSchemaModelGroupToModelGroupDefFixup(
18996:     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18997:     xmlSchemaModelGroupPtr mg)
18998: {
18999:     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19000: 
19001:     while (particle != NULL) {
19002: 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
19003: 	    ((WXS_PARTICLE_TERM(particle))->type !=
19004: 		XML_SCHEMA_TYPE_GROUP))
19005: 	{
19006: 	    particle = WXS_PTC_CAST particle->next;
19007: 	    continue;
19008: 	}
19009: 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
19010: 	    /*
19011: 	    * TODO: Remove the particle.
19012: 	    */
19013: 	    WXS_PARTICLE_TERM(particle) = NULL;
19014: 	    particle = WXS_PTC_CAST particle->next;
19015: 	    continue;
19016: 	}
19017: 	/*
19018: 	* Assign the model group to the {term} of the particle.
19019: 	*/
19020: 	WXS_PARTICLE_TERM(particle) =
19021: 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
19022: 
19023: 	particle = WXS_PTC_CAST particle->next;
19024:     }
19025: }
19026: 
19027: /**
19028:  * xmlSchemaCheckAttrGroupCircularRecur:
19029:  * @ctxtGr: the searched attribute group
19030:  * @attr: the current attribute list to be processed
19031:  *
19032:  * This one is intended to be used by
19033:  * xmlSchemaCheckAttrGroupCircular only.
19034:  *
19035:  * Returns the circular attribute grou reference, otherwise NULL.
19036:  */
19037: static xmlSchemaQNameRefPtr
19038: xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19039: 				     xmlSchemaItemListPtr list)
19040: {
19041:     xmlSchemaAttributeGroupPtr gr;
19042:     xmlSchemaQNameRefPtr ref, circ;
19043:     int i;
19044:     /*
19045:     * We will search for an attribute group reference which
19046:     * references the context attribute group.
19047:     */
19048:     for (i = 0; i < list->nbItems; i++) {
19049: 	ref = list->items[i];
19050: 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19051: 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19052: 	    (ref->item != NULL))
19053: 	{
19054: 	    gr = WXS_ATTR_GROUP_CAST ref->item;
19055: 	    if (gr == ctxtGr)
19056: 		return(ref);
19057: 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19058: 		continue;
19059: 	    /*
19060: 	    * Mark as visited to avoid infinite recursion on
19061: 	    * circular references not yet examined.
19062: 	    */
19063: 	    if ((gr->attrUses) &&
19064: 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19065: 	    {
19066: 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19067: 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19068: 		    (xmlSchemaItemListPtr) gr->attrUses);
19069: 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19070: 		if (circ != NULL)
19071: 		    return (circ);
19072: 	    }
19073: 
19074: 	}
19075:     }
19076:     return (NULL);
19077: }
19078: 
19079: /**
19080:  * xmlSchemaCheckAttrGroupCircular:
19081:  * attrGr:  the attribute group definition
19082:  * @ctxt:  the parser context
19083:  * @name:  the name
19084:  *
19085:  * Checks for circular references of attribute groups.
19086:  */
19087: static int
19088: xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19089: 				xmlSchemaParserCtxtPtr ctxt)
19090: {
19091:     /*
19092:     * Schema Representation Constraint:
19093:     * Attribute Group Definition Representation OK
19094:     * 3 Circular group reference is disallowed outside <redefine>.
19095:     * That is, unless this element information item's parent is
19096:     * <redefine>, then among the [children], if any, there must
19097:     * not be an <attributeGroup> with ref [attribute] which resolves
19098:     * to the component corresponding to this <attributeGroup>. Indirect
19099:     * circularity is also ruled out. That is, when QName resolution
19100:     * (Schema Document) (�3.15.3) is applied to a �QName� arising from
19101:     * any <attributeGroup>s with a ref [attribute] among the [children],
19102:     * it must not be the case that a �QName� is encountered at any depth
19103:     * which resolves to the component corresponding to this <attributeGroup>.
19104:     */
19105:     if (attrGr->attrUses == NULL)
19106: 	return(0);
19107:     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19108: 	return(0);
19109:     else {
19110: 	xmlSchemaQNameRefPtr circ;
19111: 
19112: 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19113: 	    (xmlSchemaItemListPtr) attrGr->attrUses);
19114: 	if (circ != NULL) {
19115: 	    xmlChar *str = NULL;
19116: 	    /*
19117: 	    * TODO: Report the referenced attr group as QName.
19118: 	    */
19119: 	    xmlSchemaPCustomErr(ctxt,
19120: 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19121: 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19122: 		"Circular reference to the attribute group '%s' "
19123: 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
19124: 	    FREE_AND_NULL(str);
19125: 	    /*
19126: 	    * NOTE: We will cut the reference to avoid further
19127: 	    * confusion of the processor.
19128: 	    * BADSPEC TODO: The spec should define how to process in this case.
19129: 	    */
19130: 	    circ->item = NULL;
19131: 	    return(ctxt->err);
19132: 	}
19133:     }
19134:     return(0);
19135: }
19136: 
19137: static int
19138: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19139: 				  xmlSchemaAttributeGroupPtr attrGr);
19140: 
19141: /**
19142:  * xmlSchemaExpandAttributeGroupRefs:
19143:  * @pctxt: the parser context
19144:  * @node: the node of the component holding the attribute uses
19145:  * @completeWild: the intersected wildcard to be returned
19146:  * @list: the attribute uses
19147:  *
19148:  * Substitutes contained attribute group references
19149:  * for their attribute uses. Wilcards are intersected.
19150:  * Attribute use prohibitions are removed from the list
19151:  * and returned via the @prohibs list.
19152:  * Pointlessness of attr. prohibs, if a matching attr. decl
19153:  * is existent a well, are checked.
19154:  */
19155: static int
19156: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19157: 				  xmlSchemaBasicItemPtr item,
19158: 				  xmlSchemaWildcardPtr *completeWild,
19159: 				  xmlSchemaItemListPtr list,
19160: 				  xmlSchemaItemListPtr prohibs)
19161: {
19162:     xmlSchemaAttributeGroupPtr gr;
19163:     xmlSchemaAttributeUsePtr use;
19164:     xmlSchemaItemListPtr sublist;
19165:     int i, j;
19166:     int created = (*completeWild == NULL) ? 0 : 1;
19167: 
19168:     if (prohibs)
19169: 	prohibs->nbItems = 0;
19170: 
19171:     for (i = 0; i < list->nbItems; i++) {
19172: 	use = list->items[i];
19173: 
19174: 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19175: 	    if (prohibs == NULL) {
19176: 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19177: 		    "unexpected attr prohibition found");
19178: 		return(-1);
19179: 	    }
19180: 	    /*
19181: 	    * Remove from attribute uses.
19182: 	    */
19183: 	    if (xmlSchemaItemListRemove(list, i) == -1)
19184: 		return(-1);
19185: 	    i--;
19186: 	    /*
19187: 	    * Note that duplicate prohibitions were already
19188: 	    * handled at parsing time.
19189: 	    */
19190: 	    /*
19191: 	    * Add to list of prohibitions.
19192: 	    */
19193: 	    xmlSchemaItemListAddSize(prohibs, 2, use);
19194: 	    continue;
19195: 	}
19196: 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19197: 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19198: 	{
19199: 	    if ((WXS_QNAME_CAST use)->item == NULL)
19200: 		return(-1);
19201: 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19202: 	    /*
19203: 	    * Expand the referenced attr. group.
19204: 	    * TODO: remove this, this is done in a previous step, so
19205: 	    * already done here.
19206: 	    */
19207: 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19208: 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19209: 		    return(-1);
19210: 	    }
19211: 	    /*
19212: 	    * Build the 'complete' wildcard; i.e. intersect multiple
19213: 	    * wildcards.
19214: 	    */
19215: 	    if (gr->attributeWildcard != NULL) {
19216: 		if (*completeWild == NULL) {
19217: 		    *completeWild = gr->attributeWildcard;
19218: 		} else {
19219: 		    if (! created) {
19220: 			xmlSchemaWildcardPtr tmpWild;
19221: 
19222: 			 /*
19223: 			* Copy the first encountered wildcard as context,
19224: 			* except for the annotation.
19225: 			*
19226: 			* Although the complete wildcard might not correspond
19227: 			* to any node in the schema, we will anchor it on
19228: 			* the node of the owner component.
19229: 			*/
19230: 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19231: 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19232: 			    WXS_ITEM_NODE(item));
19233: 			if (tmpWild == NULL)
19234: 			    return(-1);
19235: 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19236: 			    tmpWild, *completeWild) == -1)
19237: 			    return (-1);
19238: 			tmpWild->processContents = (*completeWild)->processContents;
19239: 			*completeWild = tmpWild;
19240: 			created = 1;
19241: 		    }
19242: 
19243: 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19244: 			gr->attributeWildcard) == -1)
19245: 			return(-1);
19246: 		}
19247: 	    }
19248: 	    /*
19249: 	    * Just remove the reference if the referenced group does not
19250: 	    * contain any attribute uses.
19251: 	    */
19252: 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19253: 	    if ((sublist == NULL) || sublist->nbItems == 0) {
19254: 		if (xmlSchemaItemListRemove(list, i) == -1)
19255: 		    return(-1);
19256: 		i--;
19257: 		continue;
19258: 	    }
19259: 	    /*
19260: 	    * Add the attribute uses.
19261: 	    */
19262: 	    list->items[i] = sublist->items[0];
19263: 	    if (sublist->nbItems != 1) {
19264: 		for (j = 1; j < sublist->nbItems; j++) {
19265: 		    i++;
19266: 		    if (xmlSchemaItemListInsert(list,
19267: 			    sublist->items[j], i) == -1)
19268: 			return(-1);
19269: 		}
19270: 	    }
19271: 	}
19272: 
19273:     }
19274:     /*
19275:     * Handle pointless prohibitions of declared attributes.
19276:     */
19277:     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19278: 	xmlSchemaAttributeUseProhibPtr prohib;
19279: 
19280: 	for (i = prohibs->nbItems -1; i >= 0; i--) {
19281: 	    prohib = prohibs->items[i];
19282: 	    for (j = 0; j < list->nbItems; j++) {
19283: 		use = list->items[j];
19284: 
19285: 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19286: 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19287: 		{
19288: 		    xmlChar *str = NULL;
19289: 
19290: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19291: 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19292: 			prohib->node, NULL,
19293: 			"Skipping pointless attribute use prohibition "
19294: 			"'%s', since a corresponding attribute use "
19295: 			"exists already in the type definition",
19296: 			xmlSchemaFormatQName(&str,
19297: 			    prohib->targetNamespace, prohib->name),
19298: 			NULL, NULL);
19299: 		    FREE_AND_NULL(str);
19300: 		    /*
19301: 		    * Remove the prohibition.
19302: 		    */
19303: 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
19304: 			return(-1);
19305: 		    break;
19306: 		}
19307: 	    }
19308: 	}
19309:     }
19310:     return(0);
19311: }
19312: 
19313: /**
19314:  * xmlSchemaAttributeGroupExpandRefs:
19315:  * @pctxt:  the parser context
19316:  * @attrGr:  the attribute group definition
19317:  *
19318:  * Computation of:
19319:  * {attribute uses} property
19320:  * {attribute wildcard} property
19321:  *
19322:  * Substitutes contained attribute group references
19323:  * for their attribute uses. Wilcards are intersected.
19324:  */
19325: static int
19326: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19327: 				  xmlSchemaAttributeGroupPtr attrGr)
19328: {
19329:     if ((attrGr->attrUses == NULL) ||
19330: 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19331: 	return(0);
19332: 
19333:     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19334:     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19335: 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19336: 	return(-1);
19337:     return(0);
19338: }
19339: 
19340: /**
19341:  * xmlSchemaAttributeGroupExpandRefs:
19342:  * @pctxt:  the parser context
19343:  * @attrGr:  the attribute group definition
19344:  *
19345:  * Substitutes contained attribute group references
19346:  * for their attribute uses. Wilcards are intersected.
19347:  *
19348:  * Schema Component Constraint:
19349:  *    Attribute Group Definition Properties Correct (ag-props-correct)
19350:  */
19351: static int
19352: xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19353: 				  xmlSchemaAttributeGroupPtr attrGr)
19354: {
19355:     /*
19356:     * SPEC ag-props-correct
19357:     * (1) "The values of the properties of an attribute group definition
19358:     * must be as described in the property tableau in The Attribute
19359:     * Group Definition Schema Component (�3.6.1), modulo the impact of
19360:     * Missing Sub-components (�5.3);"
19361:     */
19362: 
19363:     if ((attrGr->attrUses != NULL) &&
19364: 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19365:     {
19366: 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19367: 	xmlSchemaAttributeUsePtr use, tmp;
19368: 	int i, j, hasId = 0;
19369: 
19370: 	for (i = uses->nbItems -1; i >= 0; i--) {
19371: 	    use = uses->items[i];
19372: 	    /*
19373: 	    * SPEC ag-props-correct
19374: 	    * (2) "Two distinct members of the {attribute uses} must not have
19375: 	    * {attribute declaration}s both of whose {name}s match and whose
19376: 	    * {target namespace}s are identical."
19377: 	    */
19378: 	    if (i > 0) {
19379: 		for (j = i -1; j >= 0; j--) {
19380: 		    tmp = uses->items[j];
19381: 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
19382: 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
19383: 			(WXS_ATTRUSE_DECL_TNS(use) ==
19384: 			WXS_ATTRUSE_DECL_TNS(tmp)))
19385: 		    {
19386: 			xmlChar *str = NULL;
19387: 
19388: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19389: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
19390: 			    attrGr->node, WXS_BASIC_CAST attrGr,
19391: 			    "Duplicate %s",
19392: 			    xmlSchemaGetComponentDesignation(&str, use),
19393: 			    NULL);
19394: 			FREE_AND_NULL(str);
19395: 			/*
19396: 			* Remove the duplicate.
19397: 			*/
19398: 			if (xmlSchemaItemListRemove(uses, i) == -1)
19399: 			    return(-1);
19400: 			goto next_use;
19401: 		    }
19402: 		}
19403: 	    }
19404: 	    /*
19405: 	    * SPEC ag-props-correct
19406: 	    * (3) "Two distinct members of the {attribute uses} must not have
19407: 	    * {attribute declaration}s both of whose {type definition}s are or
19408: 	    * are derived from ID."
19409: 	    * TODO: Does 'derived' include member-types of unions?
19410: 	    */
19411: 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19412: 		if (xmlSchemaIsDerivedFromBuiltInType(
19413: 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19414: 		{
19415: 		    if (hasId) {
19416: 			xmlChar *str = NULL;
19417: 
19418: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19419: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
19420: 			    attrGr->node, WXS_BASIC_CAST attrGr,
19421: 			    "There must not exist more than one attribute "
19422: 			    "declaration of type 'xs:ID' "
19423: 			    "(or derived from 'xs:ID'). The %s violates this "
19424: 			    "constraint",
19425: 			    xmlSchemaGetComponentDesignation(&str, use),
19426: 			    NULL);
19427: 			FREE_AND_NULL(str);
19428: 			if (xmlSchemaItemListRemove(uses, i) == -1)
19429: 			    return(-1);
19430: 		    }
19431: 		    hasId = 1;
19432: 		}
19433: 	    }
19434: next_use: {}
19435: 	}
19436:     }
19437:     return(0);
19438: }
19439: 
19440: /**
19441:  * xmlSchemaResolveAttrGroupReferences:
19442:  * @attrgrpDecl:  the schema attribute definition
19443:  * @ctxt:  the schema parser context
19444:  * @name:  the attribute name
19445:  *
19446:  * Resolves references to attribute group definitions.
19447:  */
19448: static int
19449: xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19450: 				    xmlSchemaParserCtxtPtr ctxt)
19451: {
19452:     xmlSchemaAttributeGroupPtr group;
19453: 
19454:     if (ref->item != NULL)
19455:         return(0);
19456:     group = xmlSchemaGetAttributeGroup(ctxt->schema,
19457: 	ref->name,
19458: 	ref->targetNamespace);
19459:     if (group == NULL) {
19460: 	xmlSchemaPResCompAttrErr(ctxt,
19461: 	    XML_SCHEMAP_SRC_RESOLVE,
19462: 	    NULL, ref->node,
19463: 	    "ref", ref->name, ref->targetNamespace,
19464: 	    ref->itemType, NULL);
19465: 	return(ctxt->err);
19466:     }
19467:     ref->item = WXS_BASIC_CAST group;
19468:     return(0);
19469: }
19470: 
19471: /**
19472:  * xmlSchemaCheckAttrPropsCorrect:
19473:  * @item:  an schema attribute declaration/use
19474:  * @ctxt:  a schema parser context
19475:  * @name:  the name of the attribute
19476:  *
19477:  *
19478:  * Schema Component Constraint:
19479:  *    Attribute Declaration Properties Correct (a-props-correct)
19480:  *
19481:  * Validates the value constraints of an attribute declaration/use.
19482:  * NOTE that this needs the simle type definitions to be already
19483:  *   builded and checked.
19484:  */
19485: static int
19486: xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19487: 			       xmlSchemaAttributePtr attr)
19488: {
19489: 
19490:     /*
19491:     * SPEC a-props-correct (1)
19492:     * "The values of the properties of an attribute declaration must
19493:     * be as described in the property tableau in The Attribute
19494:     * Declaration Schema Component (�3.2.1), modulo the impact of
19495:     * Missing Sub-components (�5.3)."
19496:     */
19497: 
19498:     if (WXS_ATTR_TYPEDEF(attr) == NULL)
19499: 	return(0);
19500: 
19501:     if (attr->defValue != NULL) {
19502: 	int ret;
19503: 
19504: 	/*
19505: 	* SPEC a-props-correct (3)
19506: 	* "If the {type definition} is or is derived from ID then there
19507: 	* must not be a {value constraint}."
19508: 	*/
19509: 	if (xmlSchemaIsDerivedFromBuiltInType(
19510: 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19511: 	{
19512: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19513: 		XML_SCHEMAP_A_PROPS_CORRECT_3,
19514: 		NULL, WXS_BASIC_CAST attr,
19515: 		"Value constraints are not allowed if the type definition "
19516: 		"is or is derived from xs:ID",
19517: 		NULL, NULL);
19518: 	    return(pctxt->err);
19519: 	}
19520: 	/*
19521: 	* SPEC a-props-correct (2)
19522: 	* "if there is a {value constraint}, the canonical lexical
19523: 	* representation of its value must be �valid� with respect
19524: 	* to the {type definition} as defined in String Valid (�3.14.4)."
19525: 	* TODO: Don't care about the *cononical* stuff here, this requirement
19526: 	* will be removed in WXS 1.1 anyway.
19527: 	*/
19528: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19529: 	    attr->node, WXS_ATTR_TYPEDEF(attr),
19530: 	    attr->defValue, &(attr->defVal),
19531: 	    1, 1, 0);
19532: 	if (ret != 0) {
19533: 	    if (ret < 0) {
19534: 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19535: 		    "calling xmlSchemaVCheckCVCSimpleType()");
19536: 		return(-1);
19537: 	    }
19538: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19539: 		XML_SCHEMAP_A_PROPS_CORRECT_2,
19540: 		NULL, WXS_BASIC_CAST attr,
19541: 		"The value of the value constraint is not valid",
19542: 		NULL, NULL);
19543: 	    return(pctxt->err);
19544: 	}
19545:     }
19546: 
19547:     return(0);
19548: }
19549: 
19550: static xmlSchemaElementPtr
19551: xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19552: 				 xmlSchemaElementPtr ancestor)
19553: {
19554:     xmlSchemaElementPtr ret;
19555: 
19556:     if (WXS_SUBST_HEAD(ancestor) == NULL)
19557: 	return (NULL);
19558:     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19559: 	return (ancestor);
19560: 
19561:     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19562: 	return (NULL);
19563:     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19564:     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19565: 	WXS_SUBST_HEAD(ancestor));
19566:     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19567: 
19568:     return (ret);
19569: }
19570: 
19571: /**
19572:  * xmlSchemaCheckElemPropsCorrect:
19573:  * @ctxt:  a schema parser context
19574:  * @decl: the element declaration
19575:  * @name:  the name of the attribute
19576:  *
19577:  * Schema Component Constraint:
19578:  * Element Declaration Properties Correct (e-props-correct)
19579:  *
19580:  * STATUS:
19581:  *   missing: (6)
19582:  */
19583: static int
19584: xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19585: 			       xmlSchemaElementPtr elemDecl)
19586: {
19587:     int ret = 0;
19588:     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19589:     /*
19590:     * SPEC (1) "The values of the properties of an element declaration
19591:     * must be as described in the property tableau in The Element
19592:     * Declaration Schema Component (�3.3.1), modulo the impact of Missing
19593:     * Sub-components (�5.3)."
19594:     */
19595:     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19596: 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19597: 
19598: 	xmlSchemaCheckElementDeclComponent(head, pctxt);
19599: 	/*
19600: 	* SPEC (3) "If there is a non-�absent� {substitution group
19601: 	* affiliation}, then {scope} must be global."
19602: 	*/
19603: 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19604: 	    xmlSchemaPCustomErr(pctxt,
19605: 		XML_SCHEMAP_E_PROPS_CORRECT_3,
19606: 		WXS_BASIC_CAST elemDecl, NULL,
19607: 		"Only global element declarations can have a "
19608: 		"substitution group affiliation", NULL);
19609: 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19610: 	}
19611: 	/*
19612: 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
19613: 	* That is, it must not be possible to return to an element declaration
19614: 	* by repeatedly following the {substitution group affiliation}
19615: 	* property."
19616: 	*/
19617: 	if (head == elemDecl)
19618: 	    circ = head;
19619: 	else if (WXS_SUBST_HEAD(head) != NULL)
19620: 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
19621: 	else
19622: 	    circ = NULL;
19623: 	if (circ != NULL) {
19624: 	    xmlChar *strA = NULL, *strB = NULL;
19625: 
19626: 	    xmlSchemaPCustomErrExt(pctxt,
19627: 		XML_SCHEMAP_E_PROPS_CORRECT_6,
19628: 		WXS_BASIC_CAST circ, NULL,
19629: 		"The element declaration '%s' defines a circular "
19630: 		"substitution group to element declaration '%s'",
19631: 		xmlSchemaGetComponentQName(&strA, circ),
19632: 		xmlSchemaGetComponentQName(&strB, head),
19633: 		NULL);
19634: 	    FREE_AND_NULL(strA)
19635: 	    FREE_AND_NULL(strB)
19636: 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19637: 	}
19638: 	/*
19639: 	* SPEC (4) "If there is a {substitution group affiliation},
19640: 	* the {type definition}
19641: 	* of the element declaration must be validly derived from the {type
19642: 	* definition} of the {substitution group affiliation}, given the value
19643: 	* of the {substitution group exclusions} of the {substitution group
19644: 	* affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
19645: 	* (if the {type definition} is complex) or as defined in
19646: 	* Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
19647: 	* simple)."
19648: 	*
19649: 	* NOTE: {substitution group exclusions} means the values of the
19650: 	* attribute "final".
19651: 	*/
19652: 
19653: 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19654: 	    int set = 0;
19655: 
19656: 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19657: 		set |= SUBSET_EXTENSION;
19658: 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19659: 		set |= SUBSET_RESTRICTION;
19660: 
19661: 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19662: 		WXS_ELEM_TYPEDEF(head), set) != 0) {
19663: 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19664: 
19665: 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19666: 		xmlSchemaPCustomErrExt(pctxt,
19667: 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
19668: 		    WXS_BASIC_CAST elemDecl, NULL,
19669: 		    "The type definition '%s' was "
19670: 		    "either rejected by the substitution group "
19671: 		    "affiliation '%s', or not validly derived from its type "
19672: 		    "definition '%s'",
19673: 		    xmlSchemaGetComponentQName(&strA, typeDef),
19674: 		    xmlSchemaGetComponentQName(&strB, head),
19675: 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19676: 		FREE_AND_NULL(strA)
19677: 		FREE_AND_NULL(strB)
19678: 		FREE_AND_NULL(strC)
19679: 	    }
19680: 	}
19681:     }
19682:     /*
19683:     * SPEC (5) "If the {type definition} or {type definition}'s
19684:     * {content type}
19685:     * is or is derived from ID then there must not be a {value constraint}.
19686:     * Note: The use of ID as a type definition for elements goes beyond
19687:     * XML 1.0, and should be avoided if backwards compatibility is desired"
19688:     */
19689:     if ((elemDecl->value != NULL) &&
19690: 	((WXS_IS_SIMPLE(typeDef) &&
19691: 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19692: 	 (WXS_IS_COMPLEX(typeDef) &&
19693: 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19694: 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19695: 	    XML_SCHEMAS_ID)))) {
19696: 
19697: 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19698: 	xmlSchemaPCustomErr(pctxt,
19699: 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
19700: 	    WXS_BASIC_CAST elemDecl, NULL,
19701: 	    "The type definition (or type definition's content type) is or "
19702: 	    "is derived from ID; value constraints are not allowed in "
19703: 	    "conjunction with such a type definition", NULL);
19704:     } else if (elemDecl->value != NULL) {
19705: 	int vcret;
19706: 	xmlNodePtr node = NULL;
19707: 
19708: 	/*
19709: 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
19710: 	* representation of its value must be �valid� with respect to the
19711: 	* {type definition} as defined in Element Default Valid (Immediate)
19712: 	* (�3.3.6)."
19713: 	*/
19714: 	if (typeDef == NULL) {
19715: 	    xmlSchemaPErr(pctxt, elemDecl->node,
19716: 		XML_SCHEMAP_INTERNAL,
19717: 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
19718: 		"type is missing... skipping validation of "
19719: 		"the value constraint", NULL, NULL);
19720: 	    return (-1);
19721: 	}
19722: 	if (elemDecl->node != NULL) {
19723: 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19724: 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19725: 		    BAD_CAST "fixed");
19726: 	    else
19727: 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19728: 		    BAD_CAST "default");
19729: 	}
19730: 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19731: 	    typeDef, elemDecl->value, &(elemDecl->defVal));
19732: 	if (vcret != 0) {
19733: 	    if (vcret < 0) {
19734: 		PERROR_INT("xmlSchemaElemCheckValConstr",
19735: 		    "failed to validate the value constraint of an "
19736: 		    "element declaration");
19737: 		return (-1);
19738: 	    }
19739: 	    return (vcret);
19740: 	}
19741:     }
19742: 
19743:     return (ret);
19744: }
19745: 
19746: /**
19747:  * xmlSchemaCheckElemSubstGroup:
19748:  * @ctxt:  a schema parser context
19749:  * @decl: the element declaration
19750:  * @name:  the name of the attribute
19751:  *
19752:  * Schema Component Constraint:
19753:  * Substitution Group (cos-equiv-class)
19754:  *
19755:  * In Libxml2 the subst. groups will be precomputed, in terms of that
19756:  * a list will be built for each subst. group head, holding all direct
19757:  * referents to this head.
19758:  * NOTE that this function needs:
19759:  *   1. circular subst. groups to be checked beforehand
19760:  *   2. the declaration's type to be derived from the head's type
19761:  *
19762:  * STATUS:
19763:  *
19764:  */
19765: static void
19766: xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19767: 			     xmlSchemaElementPtr elemDecl)
19768: {
19769:     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19770: 	/* SPEC (1) "Its {abstract} is false." */
19771: 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19772: 	return;
19773:     {
19774: 	xmlSchemaElementPtr head;
19775: 	xmlSchemaTypePtr headType, type;
19776: 	int set, methSet;
19777: 	/*
19778: 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19779: 	* {disallowed substitutions} as the blocking constraint, as defined in
19780: 	* Substitution Group OK (Transitive) (�3.3.6)."
19781: 	*/
19782: 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19783: 	    head = WXS_SUBST_HEAD(head)) {
19784: 	    set = 0;
19785: 	    methSet = 0;
19786: 	    /*
19787: 	    * The blocking constraints.
19788: 	    */
19789: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19790: 		continue;
19791: 	    headType = head->subtypes;
19792: 	    type = elemDecl->subtypes;
19793: 	    if (headType == type)
19794: 		goto add_member;
19795: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19796: 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19797: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19798: 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19799: 	    /*
19800: 	    * SPEC: Substitution Group OK (Transitive) (2.3)
19801: 	    * "The set of all {derivation method}s involved in the
19802: 	    * derivation of D's {type definition} from C's {type definition}
19803: 	    * does not intersect with the union of the blocking constraint,
19804: 	    * C's {prohibited substitutions} (if C is complex, otherwise the
19805: 	    * empty set) and the {prohibited substitutions} (respectively the
19806: 	    * empty set) of any intermediate {type definition}s in the
19807: 	    * derivation of D's {type definition} from C's {type definition}."
19808: 	    */
19809: 	    /*
19810: 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19811: 	    * subst.head axis, the methSet does not need to be computed for
19812: 	    * the full depth over and over.
19813: 	    */
19814: 	    /*
19815: 	    * The set of all {derivation method}s involved in the derivation
19816: 	    */
19817: 	    while ((type != NULL) && (type != headType)) {
19818: 		if ((WXS_IS_EXTENSION(type)) &&
19819: 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19820: 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19821: 
19822: 		if (WXS_IS_RESTRICTION(type) &&
19823: 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19824: 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19825: 
19826: 		type = type->baseType;
19827: 	    }
19828: 	    /*
19829: 	    * The {prohibited substitutions} of all intermediate types +
19830: 	    * the head's type.
19831: 	    */
19832: 	    type = elemDecl->subtypes->baseType;
19833: 	    while (type != NULL) {
19834: 		if (WXS_IS_COMPLEX(type)) {
19835: 		    if ((type->flags &
19836: 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19837: 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19838: 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19839: 		    if ((type->flags &
19840: 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19841: 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19842: 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19843: 		} else
19844: 		    break;
19845: 		if (type == headType)
19846: 		    break;
19847: 		type = type->baseType;
19848: 	    }
19849: 	    if ((set != 0) &&
19850: 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19851: 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19852: 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19853: 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19854: 		continue;
19855: 	    }
19856: add_member:
19857: 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19858: 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19859: 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19860: 	}
19861:     }
19862: }
19863: 
19864: #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19865: /**
19866:  * xmlSchemaCheckElementDeclComponent
19867:  * @pctxt: the schema parser context
19868:  * @ctxtComponent: the context component (an element declaration)
19869:  * @ctxtParticle: the first particle of the context component
19870:  * @searchParticle: the element declaration particle to be analysed
19871:  *
19872:  * Schema Component Constraint: Element Declarations Consistent
19873:  */
19874: static int
19875: xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19876: 				    xmlSchemaBasicItemPtr ctxtComponent,
19877: 				    xmlSchemaParticlePtr ctxtParticle,
19878: 				    xmlSchemaParticlePtr searchParticle,
19879: 				    xmlSchemaParticlePtr curParticle,
19880: 				    int search)
19881: {
19882:     return(0);
19883: 
19884:     int ret = 0;
19885:     xmlSchemaParticlePtr cur = curParticle;
19886:     if (curParticle == NULL) {
19887: 	return(0);
19888:     }
19889:     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19890: 	/*
19891: 	* Just return in this case. A missing "term" of the particle
19892: 	* might arise due to an invalid "term" component.
19893: 	*/
19894: 	return(0);
19895:     }
19896:     while (cur != NULL) {
19897: 	switch (WXS_PARTICLE_TERM(cur)->type) {
19898: 	    case XML_SCHEMA_TYPE_ANY:
19899: 		break;
19900: 	    case XML_SCHEMA_TYPE_ELEMENT:
19901: 		if (search == 0) {
19902: 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19903: 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19904: 		    if (ret != 0)
19905: 			return(ret);
19906: 		} else {
19907: 		    xmlSchemaElementPtr elem =
19908: 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19909: 		    /*
19910: 		    * SPEC Element Declarations Consistent:
19911: 		    * "If the {particles} contains, either directly,
19912: 		    * indirectly (that is, within the {particles} of a
19913: 		    * contained model group, recursively) or �implicitly�
19914: 		    * two or more element declaration particles with
19915: 		    * the same {name} and {target namespace}, then
19916: 		    * all their type definitions must be the same
19917: 		    * top-level definition [...]"
19918: 		    */
19919: 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19920: 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19921: 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19922: 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19923: 		    {
19924: 			xmlChar *strA = NULL, *strB = NULL;
19925: 
19926: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19927: 			    /* TODO: error code */
19928: 			    XML_SCHEMAP_COS_NONAMBIG,
19929: 			    WXS_ITEM_NODE(cur), NULL,
19930: 			    "In the content model of %s, there are multiple "
19931: 			    "element declarations for '%s' with different "
19932: 			    "type definitions",
19933: 			    xmlSchemaGetComponentDesignation(&strA,
19934: 				ctxtComponent),
19935: 			    xmlSchemaFormatQName(&strB,
19936: 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19937: 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19938: 			FREE_AND_NULL(strA);
19939: 			FREE_AND_NULL(strB);
19940: 			return(XML_SCHEMAP_COS_NONAMBIG);
19941: 		    }
19942: 		}
19943: 		break;
19944: 	    case XML_SCHEMA_TYPE_SEQUENCE: {
19945: 		break;
19946: 		}
19947: 	    case XML_SCHEMA_TYPE_CHOICE:{
19948: 		/*
19949: 		xmlSchemaTreeItemPtr sub;
19950: 
19951: 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19952: 		while (sub != NULL) {
19953: 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19954: 			ctxtParticle, ctxtElem);
19955: 		    if (ret != 0)
19956: 			return(ret);
19957: 		    sub = sub->next;
19958: 		}
19959: 		*/
19960: 		break;
19961: 		}
19962: 	    case XML_SCHEMA_TYPE_ALL:
19963: 		break;
19964: 	    case XML_SCHEMA_TYPE_GROUP:
19965: 		break;
19966: 	    default:
19967: 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19968: 		    "xmlSchemaCheckElementDeclConsistent",
19969: 		    "found unexpected term of type '%s' in content model",
19970: 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19971: 		return(-1);
19972: 	}
19973: 	cur = (xmlSchemaParticlePtr) cur->next;
19974:     }
19975: 
19976: exit:
19977:     return(ret);
19978: }
19979: #endif
19980: 
19981: /**
19982:  * xmlSchemaCheckElementDeclComponent
19983:  * @item:  an schema element declaration/particle
19984:  * @ctxt:  a schema parser context
19985:  * @name:  the name of the attribute
19986:  *
19987:  * Validates the value constraints of an element declaration.
19988:  * Adds substitution group members.
19989:  */
19990: static void
19991: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19992: 				   xmlSchemaParserCtxtPtr ctxt)
19993: {
19994:     if (elemDecl == NULL)
19995: 	return;
19996:     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19997: 	return;
19998:     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19999:     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
20000: 	/*
20001: 	* Adds substitution group members.
20002: 	*/
20003: 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
20004:     }
20005: }
20006: 
20007: /**
20008:  * xmlSchemaResolveModelGroupParticleReferences:
20009:  * @particle:  a particle component
20010:  * @ctxt:  a parser context
20011:  *
20012:  * Resolves references of a model group's {particles} to
20013:  * model group definitions and to element declarations.
20014:  */
20015: static void
20016: xmlSchemaResolveModelGroupParticleReferences(
20017:     xmlSchemaParserCtxtPtr ctxt,
20018:     xmlSchemaModelGroupPtr mg)
20019: {
20020:     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
20021:     xmlSchemaQNameRefPtr ref;
20022:     xmlSchemaBasicItemPtr refItem;
20023: 
20024:     /*
20025:     * URGENT TODO: Test this.
20026:     */
20027:     while (particle != NULL) {
20028: 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20029: 	    ((WXS_PARTICLE_TERM(particle))->type !=
20030: 		XML_SCHEMA_EXTRA_QNAMEREF))
20031: 	{
20032: 	    goto next_particle;
20033: 	}
20034: 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20035: 	/*
20036: 	* Resolve the reference.
20037: 	* NULL the {term} by default.
20038: 	*/
20039: 	particle->children = NULL;
20040: 
20041: 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20042: 	    ref->itemType, ref->name, ref->targetNamespace);
20043: 	if (refItem == NULL) {
20044: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20045: 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20046: 		ref->targetNamespace, ref->itemType, NULL);
20047: 	    /* TODO: remove the particle. */
20048: 	    goto next_particle;
20049: 	}
20050: 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20051: 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20052: 		/* TODO: remove the particle. */
20053: 		goto next_particle;
20054: 	    /*
20055: 	    * NOTE that we will assign the model group definition
20056: 	    * itself to the "term" of the particle. This will ease
20057: 	    * the check for circular model group definitions. After
20058: 	    * that the "term" will be assigned the model group of the
20059: 	    * model group definition.
20060: 	    */
20061: 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20062: 		    XML_SCHEMA_TYPE_ALL) {
20063: 		/*
20064: 		* SPEC cos-all-limited (1)
20065: 		* SPEC cos-all-limited (1.2)
20066: 		* "It appears only as the value of one or both of the
20067: 		* following properties:"
20068: 		* (1.1) "the {model group} property of a model group
20069: 		*        definition."
20070: 		* (1.2) "the {term} property of a particle [... of] the "
20071: 		* {content type} of a complex type definition."
20072: 		*/
20073: 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
20074: 		    /* TODO: error code */
20075: 		    XML_SCHEMAP_COS_ALL_LIMITED,
20076: 		    WXS_ITEM_NODE(particle), NULL,
20077: 		    "A model group definition is referenced, but "
20078: 		    "it contains an 'all' model group, which "
20079: 		    "cannot be contained by model groups",
20080: 		    NULL, NULL);
20081: 		/* TODO: remove the particle. */
20082: 		goto next_particle;
20083: 	    }
20084: 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
20085: 	} else {
20086: 	    /*
20087: 	    * TODO: Are referenced element declarations the only
20088: 	    * other components we expect here?
20089: 	    */
20090: 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
20091: 	}
20092: next_particle:
20093: 	particle = WXS_PTC_CAST particle->next;
20094:     }
20095: }
20096: 
20097: static int
20098: xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20099: 		       xmlSchemaValPtr y)
20100: {
20101:     xmlSchemaTypePtr tx, ty, ptx, pty;
20102:     int ret;
20103: 
20104:     while (x != NULL) {
20105: 	/* Same types. */
20106: 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20107: 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20108: 	ptx = xmlSchemaGetPrimitiveType(tx);
20109: 	pty = xmlSchemaGetPrimitiveType(ty);
20110: 	/*
20111: 	* (1) if a datatype T' is �derived� by �restriction� from an
20112: 	* atomic datatype T then the �value space� of T' is a subset of
20113: 	* the �value space� of T. */
20114: 	/*
20115: 	* (2) if datatypes T' and T'' are �derived� by �restriction�
20116: 	* from a common atomic ancestor T then the �value space�s of T'
20117: 	* and T'' may overlap.
20118: 	*/
20119: 	if (ptx != pty)
20120: 	    return(0);
20121: 	/*
20122: 	* We assume computed values to be normalized, so do a fast
20123: 	* string comparison for string based types.
20124: 	*/
20125: 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20126: 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20127: 	    if (! xmlStrEqual(
20128: 		xmlSchemaValueGetAsString(x),
20129: 		xmlSchemaValueGetAsString(y)))
20130: 		return (0);
20131: 	} else {
20132: 	    ret = xmlSchemaCompareValuesWhtsp(
20133: 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
20134: 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
20135: 	    if (ret == -2)
20136: 		return(-1);
20137: 	    if (ret != 0)
20138: 		return(0);
20139: 	}
20140: 	/*
20141: 	* Lists.
20142: 	*/
20143: 	x = xmlSchemaValueGetNext(x);
20144: 	if (x != NULL) {
20145: 	    y = xmlSchemaValueGetNext(y);
20146: 	    if (y == NULL)
20147: 		return (0);
20148: 	} else if (xmlSchemaValueGetNext(y) != NULL)
20149: 	    return (0);
20150: 	else
20151: 	    return (1);
20152:     }
20153:     return (0);
20154: }
20155: 
20156: /**
20157:  * xmlSchemaResolveAttrUseReferences:
20158:  * @item:  an attribute use
20159:  * @ctxt:  a parser context
20160:  *
20161:  * Resolves the referenced attribute declaration.
20162:  */
20163: static int
20164: xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20165: 				  xmlSchemaParserCtxtPtr ctxt)
20166: {
20167:     if ((ctxt == NULL) || (ause == NULL))
20168: 	return(-1);
20169:     if ((ause->attrDecl == NULL) ||
20170: 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20171: 	return(0);
20172: 
20173:     {
20174: 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20175: 
20176: 	/*
20177: 	* TODO: Evaluate, what errors could occur if the declaration is not
20178: 	* found.
20179: 	*/
20180: 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20181: 	    ref->name, ref->targetNamespace);
20182:         if (ause->attrDecl == NULL) {
20183: 	    xmlSchemaPResCompAttrErr(ctxt,
20184: 		XML_SCHEMAP_SRC_RESOLVE,
20185: 		WXS_BASIC_CAST ause, ause->node,
20186: 		"ref", ref->name, ref->targetNamespace,
20187: 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20188:             return(ctxt->err);;
20189:         }
20190:     }
20191:     return(0);
20192: }
20193: 
20194: /**
20195:  * xmlSchemaCheckAttrUsePropsCorrect:
20196:  * @ctxt:  a parser context
20197:  * @use:  an attribute use
20198:  *
20199:  * Schema Component Constraint:
20200:  * Attribute Use Correct (au-props-correct)
20201:  *
20202:  */
20203: static int
20204: xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20205: 			     xmlSchemaAttributeUsePtr use)
20206: {
20207:     if ((ctxt == NULL) || (use == NULL))
20208: 	return(-1);
20209:     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20210: 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20211: 	return(0);
20212: 
20213:     /*
20214:     * SPEC au-props-correct (1)
20215:     * "The values of the properties of an attribute use must be as
20216:     * described in the property tableau in The Attribute Use Schema
20217:     * Component (�3.5.1), modulo the impact of Missing
20218:     * Sub-components (�5.3)."
20219:     */
20220: 
20221:     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20222: 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20223:         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20224:     {
20225: 	xmlSchemaPCustomErr(ctxt,
20226: 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20227: 	    WXS_BASIC_CAST use, NULL,
20228: 	    "The attribute declaration has a 'fixed' value constraint "
20229: 	    ", thus the attribute use must also have a 'fixed' value "
20230: 	    "constraint",
20231: 	    NULL);
20232: 	return(ctxt->err);
20233:     }
20234:     /*
20235:     * Compute and check the value constraint's value.
20236:     */
20237:     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20238: 	int ret;
20239: 	/*
20240: 	* TODO: The spec seems to be missing a check of the
20241: 	* value constraint of the attribute use. We will do it here.
20242: 	*/
20243: 	/*
20244: 	* SPEC a-props-correct (3)
20245: 	*/
20246: 	if (xmlSchemaIsDerivedFromBuiltInType(
20247: 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20248: 	{
20249: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20250: 		XML_SCHEMAP_AU_PROPS_CORRECT,
20251: 		NULL, WXS_BASIC_CAST use,
20252: 		"Value constraints are not allowed if the type definition "
20253: 		"is or is derived from xs:ID",
20254: 		NULL, NULL);
20255: 	    return(ctxt->err);
20256: 	}
20257: 
20258: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20259: 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
20260: 	    use->defValue, &(use->defVal),
20261: 	    1, 1, 0);
20262: 	if (ret != 0) {
20263: 	    if (ret < 0) {
20264: 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20265: 		    "calling xmlSchemaVCheckCVCSimpleType()");
20266: 		return(-1);
20267: 	    }
20268: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20269: 		XML_SCHEMAP_AU_PROPS_CORRECT,
20270: 		NULL, WXS_BASIC_CAST use,
20271: 		"The value of the value constraint is not valid",
20272: 		NULL, NULL);
20273: 	    return(ctxt->err);
20274: 	}
20275:     }
20276:     /*
20277:     * SPEC au-props-correct (2)
20278:     * "If the {attribute declaration} has a fixed
20279:     * {value constraint}, then if the attribute use itself has a
20280:     * {value constraint}, it must also be fixed and its value must match
20281:     * that of the {attribute declaration}'s {value constraint}."
20282:     */
20283:     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20284: 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20285:     {
20286: 	if (! xmlSchemaAreValuesEqual(use->defVal,
20287: 		(WXS_ATTRUSE_DECL(use))->defVal))
20288: 	{
20289: 	    xmlSchemaPCustomErr(ctxt,
20290: 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
20291: 		WXS_BASIC_CAST use, NULL,
20292: 		"The 'fixed' value constraint of the attribute use "
20293: 		"must match the attribute declaration's value "
20294: 		"constraint '%s'",
20295: 		(WXS_ATTRUSE_DECL(use))->defValue);
20296: 	}
20297: 	return(ctxt->err);
20298:     }
20299:     return(0);
20300: }
20301: 
20302: 
20303: 
20304: 
20305: /**
20306:  * xmlSchemaResolveAttrTypeReferences:
20307:  * @item:  an attribute declaration
20308:  * @ctxt:  a parser context
20309:  *
20310:  * Resolves the referenced type definition component.
20311:  */
20312: static int
20313: xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20314: 				   xmlSchemaParserCtxtPtr ctxt)
20315: {
20316:     /*
20317:     * The simple type definition corresponding to the <simpleType> element
20318:     * information item in the [children], if present, otherwise the simple
20319:     * type definition �resolved� to by the �actual value� of the type
20320:     * [attribute], if present, otherwise the �simple ur-type definition�.
20321:     */
20322:     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20323: 	return(0);
20324:     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20325:     if (item->subtypes != NULL)
20326:         return(0);
20327:     if (item->typeName != NULL) {
20328:         xmlSchemaTypePtr type;
20329: 
20330: 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
20331: 	    item->typeNs);
20332: 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20333: 	    xmlSchemaPResCompAttrErr(ctxt,
20334: 		XML_SCHEMAP_SRC_RESOLVE,
20335: 		WXS_BASIC_CAST item, item->node,
20336: 		"type", item->typeName, item->typeNs,
20337: 		XML_SCHEMA_TYPE_SIMPLE, NULL);
20338: 	    return(ctxt->err);
20339: 	} else
20340: 	    item->subtypes = type;
20341: 
20342:     } else {
20343: 	/*
20344: 	* The type defaults to the xs:anySimpleType.
20345: 	*/
20346: 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20347:     }
20348:     return(0);
20349: }
20350: 
20351: /**
20352:  * xmlSchemaResolveIDCKeyReferences:
20353:  * @idc:  the identity-constraint definition
20354:  * @ctxt:  the schema parser context
20355:  * @name:  the attribute name
20356:  *
20357:  * Resolve keyRef references to key/unique IDCs.
20358:  * Schema Component Constraint:
20359:  *   Identity-constraint Definition Properties Correct (c-props-correct)
20360:  */
20361: static int
20362: xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20363: 			  xmlSchemaParserCtxtPtr pctxt)
20364: {
20365:     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20366:         return(0);
20367:     if (idc->ref->name != NULL) {
20368: 	idc->ref->item = (xmlSchemaBasicItemPtr)
20369: 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20370: 		idc->ref->targetNamespace);
20371:         if (idc->ref->item == NULL) {
20372: 	    /*
20373: 	    * TODO: It is actually not an error to fail to resolve
20374: 	    * at this stage. BUT we need to be that strict!
20375: 	    */
20376: 	    xmlSchemaPResCompAttrErr(pctxt,
20377: 		XML_SCHEMAP_SRC_RESOLVE,
20378: 		WXS_BASIC_CAST idc, idc->node,
20379: 		"refer", idc->ref->name,
20380: 		idc->ref->targetNamespace,
20381: 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
20382:             return(pctxt->err);
20383: 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20384: 	    /*
20385: 	    * SPEC c-props-correct (1)
20386: 	    */
20387: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20388: 		XML_SCHEMAP_C_PROPS_CORRECT,
20389: 		NULL, WXS_BASIC_CAST idc,
20390: 		"The keyref references a keyref",
20391: 		NULL, NULL);
20392: 	    idc->ref->item = NULL;
20393: 	    return(pctxt->err);
20394: 	} else {
20395: 	    if (idc->nbFields !=
20396: 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20397: 		xmlChar *str = NULL;
20398: 		xmlSchemaIDCPtr refer;
20399: 
20400: 		refer = (xmlSchemaIDCPtr) idc->ref->item;
20401: 		/*
20402: 		* SPEC c-props-correct(2)
20403: 		* "If the {identity-constraint category} is keyref,
20404: 		* the cardinality of the {fields} must equal that of
20405: 		* the {fields} of the {referenced key}.
20406: 		*/
20407: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
20408: 		    XML_SCHEMAP_C_PROPS_CORRECT,
20409: 		    NULL, WXS_BASIC_CAST idc,
20410: 		    "The cardinality of the keyref differs from the "
20411: 		    "cardinality of the referenced key/unique '%s'",
20412: 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
20413: 			refer->name),
20414: 		    NULL);
20415: 		FREE_AND_NULL(str)
20416: 		return(pctxt->err);
20417: 	    }
20418: 	}
20419:     }
20420:     return(0);
20421: }
20422: 
20423: static int
20424: xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20425: 				       xmlSchemaParserCtxtPtr pctxt)
20426: {
20427:     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20428: 	prohib->targetNamespace) == NULL) {
20429: 
20430: 	xmlSchemaPResCompAttrErr(pctxt,
20431: 	    XML_SCHEMAP_SRC_RESOLVE,
20432: 	    NULL, prohib->node,
20433: 	    "ref", prohib->name, prohib->targetNamespace,
20434: 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20435: 	return(XML_SCHEMAP_SRC_RESOLVE);
20436:     }
20437:     return(0);
20438: }
20439: 
20440: #define WXS_REDEFINED_TYPE(c) \
20441: (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20442: 
20443: #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20444: (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20445: 
20446: #define WXS_REDEFINED_ATTR_GROUP(c) \
20447: (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20448: 
20449: static int
20450: xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20451: {
20452:     int err = 0;
20453:     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20454:     xmlSchemaBasicItemPtr prev, item;
20455:     int wasRedefined;
20456: 
20457:     if (redef == NULL)
20458: 	return(0);
20459: 
20460:     do {
20461: 	item = redef->item;
20462: 	/*
20463: 	* First try to locate the redefined component in the
20464: 	* schema graph starting with the redefined schema.
20465: 	* NOTE: According to this schema bug entry:
20466: 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20467: 	*   it's not clear if the referenced component needs to originate
20468: 	*   from the <redefine>d schema _document_ or the schema; the latter
20469: 	*   would include all imported and included sub-schemas of the
20470: 	*   <redefine>d schema. Currenlty we latter approach is used.
20471: 	*   SUPPLEMENT: It seems that the WG moves towards the latter
20472: 	*   approach, so we are doing it right.
20473: 	*
20474: 	*/
20475: 	prev = xmlSchemaFindRedefCompInGraph(
20476: 	    redef->targetBucket, item->type,
20477: 	    redef->refName, redef->refTargetNs);
20478: 	if (prev == NULL) {
20479: 	    xmlChar *str = NULL;
20480: 	    xmlNodePtr node;
20481: 
20482: 	    /*
20483: 	    * SPEC src-redefine:
20484: 	    * (6.2.1) "The �actual value� of its own name attribute plus
20485: 	    * target namespace must successfully �resolve� to a model
20486: 	    * group definition in I."
20487: 	    * (7.2.1) "The �actual value� of its own name attribute plus
20488: 	    * target namespace must successfully �resolve� to an attribute
20489: 	    * group definition in I."
20490: 
20491: 	    *
20492: 	    * Note that, if we are redefining with the use of references
20493: 	    * to components, the spec assumes the src-resolve to be used;
20494: 	    * but this won't assure that we search only *inside* the
20495: 	    * redefined schema.
20496: 	    */
20497: 	    if (redef->reference)
20498: 		node = WXS_ITEM_NODE(redef->reference);
20499: 	    else
20500: 		node = WXS_ITEM_NODE(item);
20501: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20502: 		/*
20503: 		* TODO: error code.
20504: 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20505: 		* reference kind.
20506: 		*/
20507: 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20508: 		"The %s '%s' to be redefined could not be found in "
20509: 		"the redefined schema",
20510: 		WXS_ITEM_TYPE_NAME(item),
20511: 		xmlSchemaFormatQName(&str, redef->refTargetNs,
20512: 		    redef->refName));
20513: 	    FREE_AND_NULL(str);
20514: 	    err = pctxt->err;
20515: 	    redef = redef->next;
20516: 	    continue;
20517: 	}
20518: 	/*
20519: 	* TODO: Obtaining and setting the redefinition state is really
20520: 	* clumsy.
20521: 	*/
20522: 	wasRedefined = 0;
20523: 	switch (item->type) {
20524: 	    case XML_SCHEMA_TYPE_COMPLEX:
20525: 	    case XML_SCHEMA_TYPE_SIMPLE:
20526: 		if ((WXS_TYPE_CAST prev)->flags &
20527: 		    XML_SCHEMAS_TYPE_REDEFINED)
20528: 		{
20529: 		    wasRedefined = 1;
20530: 		    break;
20531: 		}
20532: 		/* Mark it as redefined. */
20533: 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20534: 		/*
20535: 		* Assign the redefined type to the
20536: 		* base type of the redefining type.
20537: 		* TODO: How
20538: 		*/
20539: 		((xmlSchemaTypePtr) item)->baseType =
20540: 		    (xmlSchemaTypePtr) prev;
20541: 		break;
20542: 	    case XML_SCHEMA_TYPE_GROUP:
20543: 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20544: 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20545: 		{
20546: 		    wasRedefined = 1;
20547: 		    break;
20548: 		}
20549: 		/* Mark it as redefined. */
20550: 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20551: 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20552: 		if (redef->reference != NULL) {
20553: 		    /*
20554: 		    * Overwrite the QName-reference with the
20555: 		    * referenced model group def.
20556: 		    */
20557: 		    (WXS_PTC_CAST redef->reference)->children =
20558: 			WXS_TREE_CAST prev;
20559: 		}
20560: 		redef->target = prev;
20561: 		break;
20562: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20563: 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
20564: 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
20565: 		{
20566: 		    wasRedefined = 1;
20567: 		    break;
20568: 		}
20569: 		(WXS_ATTR_GROUP_CAST prev)->flags |=
20570: 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
20571: 		if (redef->reference != NULL) {
20572: 		    /*
20573: 		    * Assign the redefined attribute group to the
20574: 		    * QName-reference component.
20575: 		    * This is the easy case, since we will just
20576: 		    * expand the redefined group.
20577: 		    */
20578: 		    (WXS_QNAME_CAST redef->reference)->item = prev;
20579: 		    redef->target = NULL;
20580: 		} else {
20581: 		    /*
20582: 		    * This is the complicated case: we need
20583: 		    * to apply src-redefine (7.2.2) at a later
20584: 		    * stage, i.e. when attribute group references
20585: 		    * have beed expanded and simple types have
20586: 		    * beed fixed.
20587: 		    */
20588: 		    redef->target = prev;
20589: 		}
20590: 		break;
20591: 	    default:
20592: 		PERROR_INT("xmlSchemaResolveRedefReferences",
20593: 		    "Unexpected redefined component type");
20594: 		return(-1);
20595: 	}
20596: 	if (wasRedefined) {
20597: 	    xmlChar *str = NULL;
20598: 	    xmlNodePtr node;
20599: 
20600: 	    if (redef->reference)
20601: 		node = WXS_ITEM_NODE(redef->reference);
20602: 	    else
20603: 		node = WXS_ITEM_NODE(redef->item);
20604: 
20605: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20606: 		/* TODO: error code. */
20607: 		XML_SCHEMAP_SRC_REDEFINE,
20608: 		node, NULL,
20609: 		"The referenced %s was already redefined. Multiple "
20610: 		"redefinition of the same component is not supported",
20611: 		xmlSchemaGetComponentDesignation(&str, prev),
20612: 		NULL);
20613: 	    FREE_AND_NULL(str)
20614: 	    err = pctxt->err;
20615: 	    redef = redef->next;
20616: 	    continue;
20617: 	}
20618: 	redef = redef->next;
20619:     } while (redef != NULL);
20620: 
20621:     return(err);
20622: }
20623: 
20624: static int
20625: xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20626: {
20627:     int err = 0;
20628:     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20629:     xmlSchemaBasicItemPtr item;
20630: 
20631:     if (redef == NULL)
20632: 	return(0);
20633: 
20634:     do {
20635: 	if (redef->target == NULL) {
20636: 	    redef = redef->next;
20637: 	    continue;
20638: 	}
20639: 	item = redef->item;
20640: 
20641: 	switch (item->type) {
20642: 	    case XML_SCHEMA_TYPE_SIMPLE:
20643: 	    case XML_SCHEMA_TYPE_COMPLEX:
20644: 		/*
20645: 		* Since the spec wants the {name} of the redefined
20646: 		* type to be 'absent', we'll NULL it.
20647: 		*/
20648: 		(WXS_TYPE_CAST redef->target)->name = NULL;
20649: 
20650: 		/*
20651: 		* TODO: Seems like there's nothing more to do. The normal
20652: 		* inheritance mechanism is used. But not 100% sure.
20653: 		*/
20654: 		break;
20655: 	    case XML_SCHEMA_TYPE_GROUP:
20656: 		/*
20657: 		* URGENT TODO:
20658: 		* SPEC src-redefine:
20659: 		* (6.2.2) "The {model group} of the model group definition
20660: 		* which corresponds to it per XML Representation of Model
20661: 		* Group Definition Schema Components (�3.7.2) must be a
20662: 		* �valid restriction� of the {model group} of that model
20663: 		* group definition in I, as defined in Particle Valid
20664: 		* (Restriction) (�3.9.6)."
20665: 		*/
20666: 		break;
20667: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20668: 		/*
20669: 		* SPEC src-redefine:
20670: 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
20671: 		* the attribute group definition which corresponds to it
20672: 		* per XML Representation of Attribute Group Definition Schema
20673: 		* Components (�3.6.2) must be �valid restrictions� of the
20674: 		* {attribute uses} and {attribute wildcard} of that attribute
20675: 		* group definition in I, as defined in clause 2, clause 3 and
20676: 		* clause 4 of Derivation Valid (Restriction, Complex)
20677: 		* (�3.4.6) (where references to the base type definition are
20678: 		* understood as references to the attribute group definition
20679: 		* in I)."
20680: 		*/
20681: 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20682: 		    XML_SCHEMA_ACTION_REDEFINE,
20683: 		    item, redef->target,
20684: 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
20685: 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20686: 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20687: 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20688: 		if (err == -1)
20689: 		    return(-1);
20690: 		break;
20691: 	    default:
20692: 		break;
20693: 	}
20694: 	redef = redef->next;
20695:     } while (redef != NULL);
20696:     return(0);
20697: }
20698: 
20699: 
20700: static int
20701: xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20702: 		       xmlSchemaBucketPtr bucket)
20703: {
20704:     xmlSchemaBasicItemPtr item;
20705:     int err;
20706:     xmlHashTablePtr *table;
20707:     const xmlChar *name;
20708:     int i;
20709: 
20710: #define WXS_GET_GLOBAL_HASH(c, slot) { \
20711:     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20712: 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
20713:     else \
20714: 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20715: 
20716:     /*
20717:     * Add global components to the schema's hash tables.
20718:     * This is the place where duplicate components will be
20719:     * detected.
20720:     * TODO: I think normally we should support imports of the
20721:     *   same namespace from multiple locations. We don't do currently,
20722:     *   but if we do then according to:
20723:     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20724:     *   we would need, if imported directly, to import redefined
20725:     *   components as well to be able to catch clashing components.
20726:     *   (I hope I'll still know what this means after some months :-()
20727:     */
20728:     if (bucket == NULL)
20729: 	return(-1);
20730:     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20731: 	return(0);
20732:     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20733: 
20734:     for (i = 0; i < bucket->globals->nbItems; i++) {
20735: 	item = bucket->globals->items[i];
20736: 	table = NULL;
20737: 	switch (item->type) {
20738: 	    case XML_SCHEMA_TYPE_COMPLEX:
20739: 	    case XML_SCHEMA_TYPE_SIMPLE:
20740: 		if (WXS_REDEFINED_TYPE(item))
20741: 		    continue;
20742: 		name = (WXS_TYPE_CAST item)->name;
20743: 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20744: 		break;
20745: 	    case XML_SCHEMA_TYPE_ELEMENT:
20746: 		name = (WXS_ELEM_CAST item)->name;
20747: 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20748: 		break;
20749: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
20750: 		name = (WXS_ATTR_CAST item)->name;
20751: 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20752: 		break;
20753: 	    case XML_SCHEMA_TYPE_GROUP:
20754: 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20755: 		    continue;
20756: 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20757: 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20758: 		break;
20759: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20760: 		if (WXS_REDEFINED_ATTR_GROUP(item))
20761: 		    continue;
20762: 		name = (WXS_ATTR_GROUP_CAST item)->name;
20763: 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20764: 		break;
20765: 	    case XML_SCHEMA_TYPE_IDC_KEY:
20766: 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
20767: 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
20768: 		name = (WXS_IDC_CAST item)->name;
20769: 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
20770: 		break;
20771: 	    case XML_SCHEMA_TYPE_NOTATION:
20772: 		name = ((xmlSchemaNotationPtr) item)->name;
20773: 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20774: 		break;
20775: 	    default:
20776: 		PERROR_INT("xmlSchemaAddComponents",
20777: 		    "Unexpected global component type");
20778: 		continue;
20779: 	}
20780: 	if (*table == NULL) {
20781: 	    *table = xmlHashCreateDict(10, pctxt->dict);
20782: 	    if (*table == NULL) {
20783: 		PERROR_INT("xmlSchemaAddComponents",
20784: 		    "failed to create a component hash table");
20785: 		return(-1);
20786: 	    }
20787: 	}
20788: 	err = xmlHashAddEntry(*table, name, item);
20789: 	if (err != 0) {
20790: 	    xmlChar *str = NULL;
20791: 
20792: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20793: 		XML_SCHEMAP_REDEFINED_TYPE,
20794: 		WXS_ITEM_NODE(item),
20795: 		WXS_BASIC_CAST item,
20796: 		"A global %s '%s' does already exist",
20797: 		WXS_ITEM_TYPE_NAME(item),
20798: 		xmlSchemaGetComponentQName(&str, item));
20799: 	    FREE_AND_NULL(str);
20800: 	}
20801:     }
20802:     /*
20803:     * Process imported/included schemas.
20804:     */
20805:     if (bucket->relations != NULL) {
20806: 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
20807: 	do {
20808: 	    if ((rel->bucket != NULL) &&
20809: 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20810: 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20811: 		    return(-1);
20812: 	    }
20813: 	    rel = rel->next;
20814: 	} while (rel != NULL);
20815:     }
20816:     return(0);
20817: }
20818: 
20819: static int
20820: xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20821: 			 xmlSchemaBucketPtr rootBucket)
20822: {
20823:     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20824:     xmlSchemaTreeItemPtr item, *items;
20825:     int nbItems, i, ret = 0;
20826:     xmlSchemaBucketPtr oldbucket = con->bucket;
20827:     xmlSchemaElementPtr elemDecl;
20828: 
20829: #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20830: 
20831:     if ((con->pending == NULL) ||
20832: 	(con->pending->nbItems == 0))
20833: 	return(0);
20834: 
20835:     /*
20836:     * Since xmlSchemaFixupComplexType() will create new particles
20837:     * (local components), and those particle components need a bucket
20838:     * on the constructor, we'll assure here that the constructor has
20839:     * a bucket.
20840:     * TODO: Think about storing locals _only_ on the main bucket.
20841:     */
20842:     if (con->bucket == NULL)
20843: 	con->bucket = rootBucket;
20844: 
20845:     /* TODO:
20846:     * SPEC (src-redefine):
20847:     * (6.2) "If it has no such self-reference, then all of the
20848:     * following must be true:"
20849: 
20850:     * (6.2.2) The {model group} of the model group definition which
20851:     * corresponds to it per XML Representation of Model Group
20852:     * Definition Schema Components (�3.7.2) must be a �valid
20853:     * restriction� of the {model group} of that model group definition
20854:     * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
20855:     */
20856:     xmlSchemaCheckSRCRedefineFirst(pctxt);
20857: 
20858:     /*
20859:     * Add global components to the schemata's hash tables.
20860:     */
20861:     xmlSchemaAddComponents(pctxt, rootBucket);
20862: 
20863:     pctxt->ctxtType = NULL;
20864:     items = (xmlSchemaTreeItemPtr *) con->pending->items;
20865:     nbItems = con->pending->nbItems;
20866:     /*
20867:     * Now that we have parsed *all* the schema document(s) and converted
20868:     * them to schema components, we can resolve references, apply component
20869:     * constraints, create the FSA from the content model, etc.
20870:     */
20871:     /*
20872:     * Resolve references of..
20873:     *
20874:     * 1. element declarations:
20875:     *   - the type definition
20876:     *   - the substitution group affiliation
20877:     * 2. simple/complex types:
20878:     *   - the base type definition
20879:     *   - the memberTypes of union types
20880:     *   - the itemType of list types
20881:     * 3. attributes declarations and attribute uses:
20882:     *   - the type definition
20883:     *   - if an attribute use, then the attribute declaration
20884:     * 4. attribute group references:
20885:     *   - the attribute group definition
20886:     * 5. particles:
20887:     *   - the term of the particle (e.g. a model group)
20888:     * 6. IDC key-references:
20889:     *   - the referenced IDC 'key' or 'unique' definition
20890:     * 7. Attribute prohibitions which had a "ref" attribute.
20891:     */
20892:     for (i = 0; i < nbItems; i++) {
20893: 	item = items[i];
20894: 	switch (item->type) {
20895: 	    case XML_SCHEMA_TYPE_ELEMENT:
20896: 		xmlSchemaResolveElementReferences(
20897: 		    (xmlSchemaElementPtr) item, pctxt);
20898: 		FIXHFAILURE;
20899: 		break;
20900: 	    case XML_SCHEMA_TYPE_COMPLEX:
20901: 	    case XML_SCHEMA_TYPE_SIMPLE:
20902: 		xmlSchemaResolveTypeReferences(
20903: 		    (xmlSchemaTypePtr) item, pctxt);
20904: 		FIXHFAILURE;
20905: 		break;
20906: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
20907: 		xmlSchemaResolveAttrTypeReferences(
20908: 		    (xmlSchemaAttributePtr) item, pctxt);
20909: 		FIXHFAILURE;
20910: 		break;
20911: 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20912: 		xmlSchemaResolveAttrUseReferences(
20913: 		    (xmlSchemaAttributeUsePtr) item, pctxt);
20914: 		FIXHFAILURE;
20915: 		break;
20916: 	    case XML_SCHEMA_EXTRA_QNAMEREF:
20917: 		if ((WXS_QNAME_CAST item)->itemType ==
20918: 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20919: 		{
20920: 		    xmlSchemaResolveAttrGroupReferences(
20921: 			WXS_QNAME_CAST item, pctxt);
20922: 		}
20923: 		FIXHFAILURE;
20924: 		break;
20925: 	    case XML_SCHEMA_TYPE_SEQUENCE:
20926: 	    case XML_SCHEMA_TYPE_CHOICE:
20927: 	    case XML_SCHEMA_TYPE_ALL:
20928: 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
20929: 		    WXS_MODEL_GROUP_CAST item);
20930: 		FIXHFAILURE;
20931: 		break;
20932: 	    case XML_SCHEMA_TYPE_IDC_KEY:
20933: 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
20934: 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
20935: 		xmlSchemaResolveIDCKeyReferences(
20936: 		    (xmlSchemaIDCPtr) item, pctxt);
20937: 		FIXHFAILURE;
20938: 		break;
20939: 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20940: 		/*
20941: 		* Handle attribue prohibition which had a
20942: 		* "ref" attribute.
20943: 		*/
20944: 		xmlSchemaResolveAttrUseProhibReferences(
20945: 		    WXS_ATTR_PROHIB_CAST item, pctxt);
20946: 		FIXHFAILURE;
20947: 		break;
20948: 	    default:
20949: 		break;
20950: 	}
20951:     }
20952:     if (pctxt->nberrors != 0)
20953: 	goto exit_error;
20954: 
20955:     /*
20956:     * Now that all references are resolved we
20957:     * can check for circularity of...
20958:     * 1. the base axis of type definitions
20959:     * 2. nested model group definitions
20960:     * 3. nested attribute group definitions
20961:     * TODO: check for circual substitution groups.
20962:     */
20963:     for (i = 0; i < nbItems; i++) {
20964: 	item = items[i];
20965: 	/*
20966: 	* Let's better stop on the first error here.
20967: 	*/
20968: 	switch (item->type) {
20969: 	    case XML_SCHEMA_TYPE_COMPLEX:
20970: 	    case XML_SCHEMA_TYPE_SIMPLE:
20971: 		xmlSchemaCheckTypeDefCircular(
20972: 		    (xmlSchemaTypePtr) item, pctxt);
20973: 		FIXHFAILURE;
20974: 		if (pctxt->nberrors != 0)
20975: 		    goto exit_error;
20976: 		break;
20977: 	    case XML_SCHEMA_TYPE_GROUP:
20978: 		xmlSchemaCheckGroupDefCircular(
20979: 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
20980: 		FIXHFAILURE;
20981: 		if (pctxt->nberrors != 0)
20982: 		    goto exit_error;
20983: 		break;
20984: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20985: 		xmlSchemaCheckAttrGroupCircular(
20986: 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
20987: 		FIXHFAILURE;
20988: 		if (pctxt->nberrors != 0)
20989: 		    goto exit_error;
20990: 		break;
20991: 	    default:
20992: 		break;
20993: 	}
20994:     }
20995:     if (pctxt->nberrors != 0)
20996: 	goto exit_error;
20997:     /*
20998:     * Model group definition references:
20999:     * Such a reference is reflected by a particle at the component
21000:     * level. Until now the 'term' of such particles pointed
21001:     * to the model group definition; this was done, in order to
21002:     * ease circularity checks. Now we need to set the 'term' of
21003:     * such particles to the model group of the model group definition.
21004:     */
21005:     for (i = 0; i < nbItems; i++) {
21006: 	item = items[i];
21007: 	switch (item->type) {
21008: 	    case XML_SCHEMA_TYPE_SEQUENCE:
21009: 	    case XML_SCHEMA_TYPE_CHOICE:
21010: 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
21011: 		    WXS_MODEL_GROUP_CAST item);
21012: 		break;
21013: 	    default:
21014: 		break;
21015: 	}
21016:     }
21017:     if (pctxt->nberrors != 0)
21018: 	goto exit_error;
21019:     /*
21020:     * Expand attribute group references of attribute group definitions.
21021:     */
21022:     for (i = 0; i < nbItems; i++) {
21023: 	item = items[i];
21024: 	switch (item->type) {
21025:             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21026: 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
21027: 		    WXS_ATTR_GROUP_HAS_REFS(item))
21028: 		{
21029: 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
21030: 			WXS_ATTR_GROUP_CAST item);
21031: 		    FIXHFAILURE;
21032: 		}
21033: 		break;
21034: 	    default:
21035: 		break;
21036: 	}
21037:     }
21038:     if (pctxt->nberrors != 0)
21039: 	goto exit_error;
21040:     /*
21041:     * First compute the variety of simple types. This is needed as
21042:     * a seperate step, since otherwise we won't be able to detect
21043:     * circular union types in all cases.
21044:     */
21045:     for (i = 0; i < nbItems; i++) {
21046: 	item = items[i];
21047: 	switch (item->type) {
21048:             case XML_SCHEMA_TYPE_SIMPLE:
21049: 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21050: 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
21051: 			(xmlSchemaTypePtr) item);
21052: 		    FIXHFAILURE;
21053: 		}
21054: 		break;
21055: 	    default:
21056: 		break;
21057: 	}
21058:     }
21059:     if (pctxt->nberrors != 0)
21060: 	goto exit_error;
21061:     /*
21062:     * Detect circular union types. Note that this needs the variety to
21063:     * be already computed.
21064:     */
21065:     for (i = 0; i < nbItems; i++) {
21066: 	item = items[i];
21067: 	switch (item->type) {
21068:             case XML_SCHEMA_TYPE_SIMPLE:
21069: 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21070: 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
21071: 			(xmlSchemaTypePtr) item);
21072: 		    FIXHFAILURE;
21073: 		}
21074: 		break;
21075: 	    default:
21076: 		break;
21077: 	}
21078:     }
21079:     if (pctxt->nberrors != 0)
21080: 	goto exit_error;
21081: 
21082:     /*
21083:     * Do the complete type fixup for simple types.
21084:     */
21085:     for (i = 0; i < nbItems; i++) {
21086: 	item = items[i];
21087: 	switch (item->type) {
21088:             case XML_SCHEMA_TYPE_SIMPLE:
21089: 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21090: 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21091: 		    FIXHFAILURE;
21092: 		}
21093: 		break;
21094: 	    default:
21095: 		break;
21096: 	}
21097:     }
21098:     if (pctxt->nberrors != 0)
21099: 	goto exit_error;
21100:     /*
21101:     * At this point we need build and check all simple types.
21102:     */
21103:     /*
21104:     * Apply contraints for attribute declarations.
21105:     */
21106:     for (i = 0; i < nbItems; i++) {
21107: 	item = items[i];
21108: 	switch (item->type) {
21109: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
21110: 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21111: 		FIXHFAILURE;
21112: 		break;
21113: 	    default:
21114: 		break;
21115: 	}
21116:     }
21117:     if (pctxt->nberrors != 0)
21118: 	goto exit_error;
21119:     /*
21120:     * Apply constraints for attribute uses.
21121:     */
21122:     for (i = 0; i < nbItems; i++) {
21123: 	item = items[i];
21124: 	switch (item->type) {
21125: 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21126: 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21127: 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21128: 			WXS_ATTR_USE_CAST item);
21129: 		    FIXHFAILURE;
21130: 		}
21131: 		break;
21132: 	    default:
21133: 		break;
21134: 	}
21135:     }
21136:     if (pctxt->nberrors != 0)
21137: 	goto exit_error;
21138: 
21139:     /*
21140:     * Apply constraints for attribute group definitions.
21141:     */
21142:     for (i = 0; i < nbItems; i++) {
21143: 	item = items[i];
21144: 	switch (item->type) {
21145: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21146: 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21147: 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21148: 	    {
21149: 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21150: 		FIXHFAILURE;
21151: 	    }
21152: 	    break;
21153: 	default:
21154: 	    break;
21155: 	}
21156:     }
21157:     if (pctxt->nberrors != 0)
21158: 	goto exit_error;
21159: 
21160:     /*
21161:     * Apply constraints for redefinitions.
21162:     */
21163:     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21164: 	xmlSchemaCheckSRCRedefineSecond(pctxt);
21165:     if (pctxt->nberrors != 0)
21166: 	goto exit_error;
21167: 
21168:     /*
21169:     * Complex types are builded and checked.
21170:     */
21171:     for (i = 0; i < nbItems; i++) {
21172: 	item = con->pending->items[i];
21173: 	switch (item->type) {
21174: 	    case XML_SCHEMA_TYPE_COMPLEX:
21175: 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21176: 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21177: 		    FIXHFAILURE;
21178: 		}
21179: 		break;
21180: 	    default:
21181: 		break;
21182: 	}
21183:     }
21184:     if (pctxt->nberrors != 0)
21185: 	goto exit_error;
21186: 
21187:     /*
21188:     * The list could have changed, since xmlSchemaFixupComplexType()
21189:     * will create particles and model groups in some cases.
21190:     */
21191:     items = (xmlSchemaTreeItemPtr *) con->pending->items;
21192:     nbItems = con->pending->nbItems;
21193: 
21194:     /*
21195:     * Apply some constraints for element declarations.
21196:     */
21197:     for (i = 0; i < nbItems; i++) {
21198: 	item = items[i];
21199: 	switch (item->type) {
21200: 	    case XML_SCHEMA_TYPE_ELEMENT:
21201: 		elemDecl = (xmlSchemaElementPtr) item;
21202: 
21203: 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21204: 		{
21205: 		    xmlSchemaCheckElementDeclComponent(
21206: 			(xmlSchemaElementPtr) elemDecl, pctxt);
21207: 		    FIXHFAILURE;
21208: 		}
21209: 
21210: #ifdef WXS_ELEM_DECL_CONS_ENABLED
21211: 		/*
21212: 		* Schema Component Constraint: Element Declarations Consistent
21213: 		* Apply this constraint to local types of element declarations.
21214: 		*/
21215: 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21216: 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21217: 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21218: 		{
21219: 		    xmlSchemaCheckElementDeclConsistent(pctxt,
21220: 			WXS_BASIC_CAST elemDecl,
21221: 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21222: 			NULL, NULL, 0);
21223: 		}
21224: #endif
21225: 		break;
21226: 	    default:
21227: 		break;
21228: 	}
21229:     }
21230:     if (pctxt->nberrors != 0)
21231: 	goto exit_error;
21232: 
21233:     /*
21234:     * Finally we can build the automaton from the content model of
21235:     * complex types.
21236:     */
21237: 
21238:     for (i = 0; i < nbItems; i++) {
21239: 	item = items[i];
21240: 	switch (item->type) {
21241: 	    case XML_SCHEMA_TYPE_COMPLEX:
21242: 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21243: 		/* FIXHFAILURE; */
21244: 		break;
21245: 	    default:
21246: 		break;
21247: 	}
21248:     }
21249:     if (pctxt->nberrors != 0)
21250: 	goto exit_error;
21251:     /*
21252:     * URGENT TODO: cos-element-consistent
21253:     */
21254:     goto exit;
21255: 
21256: exit_error:
21257:     ret = pctxt->err;
21258:     goto exit;
21259: 
21260: exit_failure:
21261:     ret = -1;
21262: 
21263: exit:
21264:     /*
21265:     * Reset the constructor. This is needed for XSI acquisition, since
21266:     * those items will be processed over and over again for every XSI
21267:     * if not cleared here.
21268:     */
21269:     con->bucket = oldbucket;
21270:     con->pending->nbItems = 0;
21271:     if (con->substGroups != NULL) {
21272: 	xmlHashFree(con->substGroups,
21273: 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
21274: 	con->substGroups = NULL;
21275:     }
21276:     if (con->redefs != NULL) {
21277: 	xmlSchemaRedefListFree(con->redefs);
21278: 	con->redefs = NULL;
21279:     }
21280:     return(ret);
21281: }
21282: /**
21283:  * xmlSchemaParse:
21284:  * @ctxt:  a schema validation context
21285:  *
21286:  * parse a schema definition resource and build an internal
21287:  * XML Shema struture which can be used to validate instances.
21288:  *
21289:  * Returns the internal XML Schema structure built from the resource or
21290:  *         NULL in case of error
21291:  */
21292: xmlSchemaPtr
21293: xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21294: {
21295:     xmlSchemaPtr mainSchema = NULL;
21296:     xmlSchemaBucketPtr bucket = NULL;
21297:     int res;
21298: 
21299:     /*
21300:     * This one is used if the schema to be parsed was specified via
21301:     * the API; i.e. not automatically by the validated instance document.
21302:     */
21303: 
21304:     xmlSchemaInitTypes();
21305: 
21306:     if (ctxt == NULL)
21307:         return (NULL);
21308: 
21309:     /* TODO: Init the context. Is this all we need?*/
21310:     ctxt->nberrors = 0;
21311:     ctxt->err = 0;
21312:     ctxt->counter = 0;
21313: 
21314:     /* Create the *main* schema. */
21315:     mainSchema = xmlSchemaNewSchema(ctxt);
21316:     if (mainSchema == NULL)
21317: 	goto exit_failure;
21318:     /*
21319:     * Create the schema constructor.
21320:     */
21321:     if (ctxt->constructor == NULL) {
21322: 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21323: 	if (ctxt->constructor == NULL)
21324: 	    return(NULL);
21325: 	/* Take ownership of the constructor to be able to free it. */
21326: 	ctxt->ownsConstructor = 1;
21327:     }
21328:     ctxt->constructor->mainSchema = mainSchema;
21329:     /*
21330:     * Locate and add the schema document.
21331:     */
21332:     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21333: 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21334: 	NULL, NULL, &bucket);
21335:     if (res == -1)
21336: 	goto exit_failure;
21337:     if (res != 0)
21338: 	goto exit;
21339: 
21340:     if (bucket == NULL) {
21341: 	/* TODO: Error code, actually we failed to *locate* the schema. */
21342: 	if (ctxt->URL)
21343: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21344: 		NULL, NULL,
21345: 		"Failed to locate the main schema resource at '%s'",
21346: 		ctxt->URL, NULL);
21347: 	else
21348: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21349: 		NULL, NULL,
21350: 		"Failed to locate the main schema resource",
21351: 		    NULL, NULL);
21352: 	goto exit;
21353:     }
21354:     /* Then do the parsing for good. */
21355:     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21356: 	goto exit_failure;
21357:     if (ctxt->nberrors != 0)
21358: 	goto exit;
21359: 
21360:     mainSchema->doc = bucket->doc;
21361:     mainSchema->preserve = ctxt->preserve;
21362: 
21363:     ctxt->schema = mainSchema;
21364: 
21365:     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21366: 	goto exit_failure;
21367: 
21368:     /*
21369:     * TODO: This is not nice, since we cannot distinguish from the
21370:     * result if there was an internal error or not.
21371:     */
21372: exit:
21373:     if (ctxt->nberrors != 0) {
21374: 	if (mainSchema) {
21375: 	    xmlSchemaFree(mainSchema);
21376: 	    mainSchema = NULL;
21377: 	}
21378: 	if (ctxt->constructor) {
21379: 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
21380: 	    ctxt->constructor = NULL;
21381: 	    ctxt->ownsConstructor = 0;
21382: 	}
21383:     }
21384:     ctxt->schema = NULL;
21385:     return(mainSchema);
21386: exit_failure:
21387:     /*
21388:     * Quite verbose, but should catch internal errors, which were
21389:     * not communitated.
21390:     */
21391:     if (mainSchema) {
21392:         xmlSchemaFree(mainSchema);
21393: 	mainSchema = NULL;
21394:     }
21395:     if (ctxt->constructor) {
21396: 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
21397: 	ctxt->constructor = NULL;
21398: 	ctxt->ownsConstructor = 0;
21399:     }
21400:     PERROR_INT2("xmlSchemaParse",
21401: 	"An internal error occured");
21402:     ctxt->schema = NULL;
21403:     return(NULL);
21404: }
21405: 
21406: /**
21407:  * xmlSchemaSetParserErrors:
21408:  * @ctxt:  a schema validation context
21409:  * @err:  the error callback
21410:  * @warn:  the warning callback
21411:  * @ctx:  contextual data for the callbacks
21412:  *
21413:  * Set the callback functions used to handle errors for a validation context
21414:  */
21415: void
21416: xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21417:                          xmlSchemaValidityErrorFunc err,
21418:                          xmlSchemaValidityWarningFunc warn, void *ctx)
21419: {
21420:     if (ctxt == NULL)
21421:         return;
21422:     ctxt->error = err;
21423:     ctxt->warning = warn;
21424:     ctxt->errCtxt = ctx;
21425:     if (ctxt->vctxt != NULL)
21426: 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21427: }
21428: 
21429: /**
21430:  * xmlSchemaSetParserStructuredErrors:
21431:  * @ctxt:  a schema parser context
21432:  * @serror:  the structured error function
21433:  * @ctx: the functions context
21434:  *
21435:  * Set the structured error callback
21436:  */
21437: void
21438: xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21439: 				   xmlStructuredErrorFunc serror,
21440: 				   void *ctx)
21441: {
21442:     if (ctxt == NULL)
21443: 	return;
21444:     ctxt->serror = serror;
21445:     ctxt->errCtxt = ctx;
21446:     if (ctxt->vctxt != NULL)
21447: 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21448: }
21449: 
21450: /**
21451:  * xmlSchemaGetParserErrors:
21452:  * @ctxt:  a XMl-Schema parser context
21453:  * @err: the error callback result
21454:  * @warn: the warning callback result
21455:  * @ctx: contextual data for the callbacks result
21456:  *
21457:  * Get the callback information used to handle errors for a parser context
21458:  *
21459:  * Returns -1 in case of failure, 0 otherwise
21460:  */
21461: int
21462: xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21463: 			 xmlSchemaValidityErrorFunc * err,
21464: 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
21465: {
21466: 	if (ctxt == NULL)
21467: 		return(-1);
21468: 	if (err != NULL)
21469: 		*err = ctxt->error;
21470: 	if (warn != NULL)
21471: 		*warn = ctxt->warning;
21472: 	if (ctx != NULL)
21473: 		*ctx = ctxt->errCtxt;
21474: 	return(0);
21475: }
21476: 
21477: /**
21478:  * xmlSchemaFacetTypeToString:
21479:  * @type:  the facet type
21480:  *
21481:  * Convert the xmlSchemaTypeType to a char string.
21482:  *
21483:  * Returns the char string representation of the facet type if the
21484:  *     type is a facet and an "Internal Error" string otherwise.
21485:  */
21486: static const xmlChar *
21487: xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21488: {
21489:     switch (type) {
21490:         case XML_SCHEMA_FACET_PATTERN:
21491:             return (BAD_CAST "pattern");
21492:         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21493:             return (BAD_CAST "maxExclusive");
21494:         case XML_SCHEMA_FACET_MAXINCLUSIVE:
21495:             return (BAD_CAST "maxInclusive");
21496:         case XML_SCHEMA_FACET_MINEXCLUSIVE:
21497:             return (BAD_CAST "minExclusive");
21498:         case XML_SCHEMA_FACET_MININCLUSIVE:
21499:             return (BAD_CAST "minInclusive");
21500:         case XML_SCHEMA_FACET_WHITESPACE:
21501:             return (BAD_CAST "whiteSpace");
21502:         case XML_SCHEMA_FACET_ENUMERATION:
21503:             return (BAD_CAST "enumeration");
21504:         case XML_SCHEMA_FACET_LENGTH:
21505:             return (BAD_CAST "length");
21506:         case XML_SCHEMA_FACET_MAXLENGTH:
21507:             return (BAD_CAST "maxLength");
21508:         case XML_SCHEMA_FACET_MINLENGTH:
21509:             return (BAD_CAST "minLength");
21510:         case XML_SCHEMA_FACET_TOTALDIGITS:
21511:             return (BAD_CAST "totalDigits");
21512:         case XML_SCHEMA_FACET_FRACTIONDIGITS:
21513:             return (BAD_CAST "fractionDigits");
21514:         default:
21515:             break;
21516:     }
21517:     return (BAD_CAST "Internal Error");
21518: }
21519: 
21520: static xmlSchemaWhitespaceValueType
21521: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21522: {
21523:     /*
21524:     * The normalization type can be changed only for types which are derived
21525:     * from xsd:string.
21526:     */
21527:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
21528: 	/*
21529: 	* Note that we assume a whitespace of preserve for anySimpleType.
21530: 	*/
21531: 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
21532: 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21533: 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
21534: 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21535: 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
21536: 	else {
21537: 	    /*
21538: 	    * For all �atomic� datatypes other than string (and types �derived�
21539: 	    * by �restriction� from it) the value of whiteSpace is fixed to
21540: 	    * collapse
21541: 	    * Note that this includes built-in list datatypes.
21542: 	    */
21543: 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21544: 	}
21545:     } else if (WXS_IS_LIST(type)) {
21546: 	/*
21547: 	* For list types the facet "whiteSpace" is fixed to "collapse".
21548: 	*/
21549: 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21550:     } else if (WXS_IS_UNION(type)) {
21551: 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21552:     } else if (WXS_IS_ATOMIC(type)) {
21553: 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21554: 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
21555: 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21556: 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
21557: 	else
21558: 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21559:     }
21560:     return (-1);
21561: }
21562: 
21563: /************************************************************************
21564:  *									*
21565:  *			Simple type validation				*
21566:  *									*
21567:  ************************************************************************/
21568: 
21569: 
21570: /************************************************************************
21571:  *									*
21572:  *			DOM Validation code				*
21573:  *									*
21574:  ************************************************************************/
21575: 
21576: /**
21577:  * xmlSchemaAssembleByLocation:
21578:  * @pctxt:  a schema parser context
21579:  * @vctxt:  a schema validation context
21580:  * @schema: the existing schema
21581:  * @node: the node that fired the assembling
21582:  * @nsName: the namespace name of the new schema
21583:  * @location: the location of the schema
21584:  *
21585:  * Expands an existing schema by an additional schema.
21586:  *
21587:  * Returns 0 if the new schema is correct, a positive error code
21588:  * number otherwise and -1 in case of an internal or API error.
21589:  */
21590: static int
21591: xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21592: 			    xmlSchemaPtr schema,
21593: 			    xmlNodePtr node,
21594: 			    const xmlChar *nsName,
21595: 			    const xmlChar *location)
21596: {
21597:     int ret = 0;
21598:     xmlSchemaParserCtxtPtr pctxt;
21599:     xmlSchemaBucketPtr bucket = NULL;
21600: 
21601:     if ((vctxt == NULL) || (schema == NULL))
21602: 	return (-1);
21603: 
21604:     if (vctxt->pctxt == NULL) {
21605: 	VERROR_INT("xmlSchemaAssembleByLocation",
21606: 	    "no parser context available");
21607: 	return(-1);
21608:     }
21609:     pctxt = vctxt->pctxt;
21610:     if (pctxt->constructor == NULL) {
21611: 	PERROR_INT("xmlSchemaAssembleByLocation",
21612: 	    "no constructor");
21613: 	return(-1);
21614:     }
21615:     /*
21616:     * Acquire the schema document.
21617:     */
21618:     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21619: 	location, node);
21620:     /*
21621:     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21622:     * the process will automatically change this to
21623:     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21624:     */
21625:     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21626: 	location, NULL, NULL, 0, node, NULL, nsName,
21627: 	&bucket);
21628:     if (ret != 0)
21629: 	return(ret);
21630:     if (bucket == NULL) {
21631: 	/*
21632: 	* Generate a warning that the document could not be located.
21633: 	*/
21634: 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21635: 	    node, NULL,
21636: 	    "The document at location '%s' could not be acquired",
21637: 	    location, NULL, NULL);
21638: 	return(ret);
21639:     }
21640:     /*
21641:     * The first located schema will be handled as if all other
21642:     * schemas imported by XSI were imported by this first schema.
21643:     */
21644:     if ((bucket != NULL) &&
21645: 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21646: 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21647:     /*
21648:     * TODO: Is this handled like an import? I.e. is it not an error
21649:     * if the schema cannot be located?
21650:     */
21651:     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21652: 	return(0);
21653:     /*
21654:     * We will reuse the parser context for every schema imported
21655:     * directly via XSI. So reset the context.
21656:     */
21657:     pctxt->nberrors = 0;
21658:     pctxt->err = 0;
21659:     pctxt->doc = bucket->doc;
21660: 
21661:     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21662:     if (ret == -1) {
21663: 	pctxt->doc = NULL;
21664: 	goto exit_failure;
21665:     }
21666:     /* Paranoid error channelling. */
21667:     if ((ret == 0) && (pctxt->nberrors != 0))
21668: 	ret = pctxt->err;
21669:     if (pctxt->nberrors == 0) {
21670: 	/*
21671: 	* Only bother to fixup pending components, if there was
21672: 	* no error yet.
21673: 	* For every XSI acquired schema (and its sub-schemata) we will
21674: 	* fixup the components.
21675: 	*/
21676: 	xmlSchemaFixupComponents(pctxt, bucket);
21677: 	ret = pctxt->err;
21678: 	/*
21679: 	* Not nice, but we need somehow to channel the schema parser
21680: 	* error to the validation context.
21681: 	*/
21682: 	if ((ret != 0) && (vctxt->err == 0))
21683: 	    vctxt->err = ret;
21684: 	vctxt->nberrors += pctxt->nberrors;
21685:     } else {
21686: 	/* Add to validation error sum. */
21687: 	vctxt->nberrors += pctxt->nberrors;
21688:     }
21689:     pctxt->doc = NULL;
21690:     return(ret);
21691: exit_failure:
21692:     pctxt->doc = NULL;
21693:     return (-1);
21694: }
21695: 
21696: static xmlSchemaAttrInfoPtr
21697: xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21698: 			 int metaType)
21699: {
21700:     if (vctxt->nbAttrInfos == 0)
21701: 	return (NULL);
21702:     {
21703: 	int i;
21704: 	xmlSchemaAttrInfoPtr iattr;
21705: 
21706: 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
21707: 	    iattr = vctxt->attrInfos[i];
21708: 	    if (iattr->metaType == metaType)
21709: 		return (iattr);
21710: 	}
21711: 
21712:     }
21713:     return (NULL);
21714: }
21715: 
21716: /**
21717:  * xmlSchemaAssembleByXSI:
21718:  * @vctxt:  a schema validation context
21719:  *
21720:  * Expands an existing schema by an additional schema using
21721:  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21722:  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21723:  * must be set to 1.
21724:  *
21725:  * Returns 0 if the new schema is correct, a positive error code
21726:  * number otherwise and -1 in case of an internal or API error.
21727:  */
21728: static int
21729: xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21730: {
21731:     const xmlChar *cur, *end;
21732:     const xmlChar *nsname = NULL, *location;
21733:     int count = 0;
21734:     int ret = 0;
21735:     xmlSchemaAttrInfoPtr iattr;
21736: 
21737:     /*
21738:     * Parse the value; we will assume an even number of values
21739:     * to be given (this is how Xerces and XSV work).
21740:     *
21741:     * URGENT TODO: !! This needs to work for both
21742:     * @noNamespaceSchemaLocation AND @schemaLocation on the same
21743:     * element !!
21744:     */
21745:     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21746: 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21747:     if (iattr == NULL)
21748: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21749: 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21750:     if (iattr == NULL)
21751: 	return (0);
21752:     cur = iattr->value;
21753:     do {
21754: 	/*
21755: 	* TODO: Move the string parsing mechanism away from here.
21756: 	*/
21757: 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21758: 	    /*
21759: 	    * Get the namespace name.
21760: 	    */
21761: 	    while (IS_BLANK_CH(*cur))
21762: 		cur++;
21763: 	    end = cur;
21764: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21765: 		end++;
21766: 	    if (end == cur)
21767: 		break;
21768: 	    count++; /* TODO: Don't use the schema's dict. */
21769: 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21770: 	    cur = end;
21771: 	}
21772: 	/*
21773: 	* Get the URI.
21774: 	*/
21775: 	while (IS_BLANK_CH(*cur))
21776: 	    cur++;
21777: 	end = cur;
21778: 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21779: 	    end++;
21780: 	if (end == cur) {
21781: 	    if (iattr->metaType ==
21782: 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21783: 	    {
21784: 		/*
21785: 		* If using @schemaLocation then tuples are expected.
21786: 		* I.e. the namespace name *and* the document's URI.
21787: 		*/
21788: 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21789: 		    iattr->node, NULL,
21790: 		    "The value must consist of tuples: the target namespace "
21791: 		    "name and the document's URI", NULL, NULL, NULL);
21792: 	    }
21793: 	    break;
21794: 	}
21795: 	count++; /* TODO: Don't use the schema's dict. */
21796: 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21797: 	cur = end;
21798: 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21799: 	    iattr->node, nsname, location);
21800: 	if (ret == -1) {
21801: 	    VERROR_INT("xmlSchemaAssembleByXSI",
21802: 		"assembling schemata");
21803: 	    return (-1);
21804: 	}
21805:     } while (*cur != 0);
21806:     return (ret);
21807: }
21808: 
21809: static const xmlChar *
21810: xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21811: 			 const xmlChar *prefix)
21812: {
21813:     if (vctxt->sax != NULL) {
21814: 	int i, j;
21815: 	xmlSchemaNodeInfoPtr inode;
21816: 
21817: 	for (i = vctxt->depth; i >= 0; i--) {
21818: 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21819: 		inode = vctxt->elemInfos[i];
21820: 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21821: 		    if (((prefix == NULL) &&
21822: 			    (inode->nsBindings[j] == NULL)) ||
21823: 			((prefix != NULL) && xmlStrEqual(prefix,
21824: 			    inode->nsBindings[j]))) {
21825: 
21826: 			/*
21827: 			* Note that the namespace bindings are already
21828: 			* in a string dict.
21829: 			*/
21830: 			return (inode->nsBindings[j+1]);
21831: 		    }
21832: 		}
21833: 	    }
21834: 	}
21835: 	return (NULL);
21836: #ifdef LIBXML_READER_ENABLED
21837:     } else if (vctxt->reader != NULL) {
21838: 	xmlChar *nsName;
21839: 
21840: 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21841: 	if (nsName != NULL) {
21842: 	    const xmlChar *ret;
21843: 
21844: 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
21845: 	    xmlFree(nsName);
21846: 	    return (ret);
21847: 	} else
21848: 	    return (NULL);
21849: #endif
21850:     } else {
21851: 	xmlNsPtr ns;
21852: 
21853: 	if ((vctxt->inode->node == NULL) ||
21854: 	    (vctxt->inode->node->doc == NULL)) {
21855: 	    VERROR_INT("xmlSchemaLookupNamespace",
21856: 		"no node or node's doc avaliable");
21857: 	    return (NULL);
21858: 	}
21859: 	ns = xmlSearchNs(vctxt->inode->node->doc,
21860: 	    vctxt->inode->node, prefix);
21861: 	if (ns != NULL)
21862: 	    return (ns->href);
21863: 	return (NULL);
21864:     }
21865: }
21866: 
21867: /*
21868: * This one works on the schema of the validation context.
21869: */
21870: static int
21871: xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21872: 			  xmlSchemaPtr schema,
21873: 			  xmlNodePtr node,
21874: 			  const xmlChar *value,
21875: 			  xmlSchemaValPtr *val,
21876: 			  int valNeeded)
21877: {
21878:     int ret;
21879: 
21880:     if (vctxt && (vctxt->schema == NULL)) {
21881: 	VERROR_INT("xmlSchemaValidateNotation",
21882: 	    "a schema is needed on the validation context");
21883: 	return (-1);
21884:     }
21885:     ret = xmlValidateQName(value, 1);
21886:     if (ret != 0)
21887: 	return (ret);
21888:     {
21889: 	xmlChar *localName = NULL;
21890: 	xmlChar *prefix = NULL;
21891: 
21892: 	localName = xmlSplitQName2(value, &prefix);
21893: 	if (prefix != NULL) {
21894: 	    const xmlChar *nsName = NULL;
21895: 
21896: 	    if (vctxt != NULL)
21897: 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21898: 	    else if (node != NULL) {
21899: 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21900: 		if (ns != NULL)
21901: 		    nsName = ns->href;
21902: 	    } else {
21903: 		xmlFree(prefix);
21904: 		xmlFree(localName);
21905: 		return (1);
21906: 	    }
21907: 	    if (nsName == NULL) {
21908: 		xmlFree(prefix);
21909: 		xmlFree(localName);
21910: 		return (1);
21911: 	    }
21912: 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21913: 		if ((valNeeded) && (val != NULL)) {
21914: 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21915: 						       xmlStrdup(nsName));
21916: 		    if (*val == NULL)
21917: 			ret = -1;
21918: 		}
21919: 	    } else
21920: 		ret = 1;
21921: 	    xmlFree(prefix);
21922: 	    xmlFree(localName);
21923: 	} else {
21924: 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21925: 		if (valNeeded && (val != NULL)) {
21926: 		    (*val) = xmlSchemaNewNOTATIONValue(
21927: 			BAD_CAST xmlStrdup(value), NULL);
21928: 		    if (*val == NULL)
21929: 			ret = -1;
21930: 		}
21931: 	    } else
21932: 		return (1);
21933: 	}
21934:     }
21935:     return (ret);
21936: }
21937: 
21938: static int
21939: xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21940: 		       const xmlChar* lname,
21941: 		       const xmlChar* nsname)
21942: {
21943:     int i;
21944: 
21945:     lname = xmlDictLookup(vctxt->dict, lname, -1);
21946:     if (lname == NULL)
21947: 	return(-1);
21948:     if (nsname != NULL) {
21949: 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21950: 	if (nsname == NULL)
21951: 	    return(-1);
21952:     }
21953:     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21954: 	if ((vctxt->nodeQNames->items [i] == lname) &&
21955: 	    (vctxt->nodeQNames->items[i +1] == nsname))
21956: 	    /* Already there */
21957: 	    return(i);
21958:     }
21959:     /* Add new entry. */
21960:     i = vctxt->nodeQNames->nbItems;
21961:     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21962:     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21963:     return(i);
21964: }
21965: 
21966: /************************************************************************
21967:  *									*
21968:  *  Validation of identity-constraints (IDC)                            *
21969:  *									*
21970:  ************************************************************************/
21971: 
21972: /**
21973:  * xmlSchemaAugmentIDC:
21974:  * @idcDef: the IDC definition
21975:  *
21976:  * Creates an augmented IDC definition item.
21977:  *
21978:  * Returns the item, or NULL on internal errors.
21979:  */
21980: static void
21981: xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
21982: 		    xmlSchemaValidCtxtPtr vctxt)
21983: {
21984:     xmlSchemaIDCAugPtr aidc;
21985: 
21986:     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21987:     if (aidc == NULL) {
21988: 	xmlSchemaVErrMemory(vctxt,
21989: 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
21990: 	    NULL);
21991: 	return;
21992:     }
21993:     aidc->keyrefDepth = -1;
21994:     aidc->def = idcDef;
21995:     aidc->next = NULL;
21996:     if (vctxt->aidcs == NULL)
21997: 	vctxt->aidcs = aidc;
21998:     else {
21999: 	aidc->next = vctxt->aidcs;
22000: 	vctxt->aidcs = aidc;
22001:     }
22002:     /*
22003:     * Save if we have keyrefs at all.
22004:     */
22005:     if ((vctxt->hasKeyrefs == 0) &&
22006: 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
22007: 	vctxt->hasKeyrefs = 1;
22008: }
22009: 
22010: /**
22011:  * xmlSchemaAugmentImportedIDC:
22012:  * @imported: the imported schema
22013:  *
22014:  * Creates an augmented IDC definition for the imported schema.
22015:  */
22016: static void
22017: xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
22018:     if (imported->schema->idcDef != NULL) {
22019: 	    xmlHashScan(imported->schema->idcDef ,
22020: 	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
22021:     }
22022: }
22023: 
22024: /**
22025:  * xmlSchemaIDCNewBinding:
22026:  * @idcDef: the IDC definition of this binding
22027:  *
22028:  * Creates a new IDC binding.
22029:  *
22030:  * Returns the new IDC binding, NULL on internal errors.
22031:  */
22032: static xmlSchemaPSVIIDCBindingPtr
22033: xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22034: {
22035:     xmlSchemaPSVIIDCBindingPtr ret;
22036: 
22037:     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22038: 	    sizeof(xmlSchemaPSVIIDCBinding));
22039:     if (ret == NULL) {
22040: 	xmlSchemaVErrMemory(NULL,
22041: 	    "allocating a PSVI IDC binding item", NULL);
22042: 	return (NULL);
22043:     }
22044:     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22045:     ret->definition = idcDef;
22046:     return (ret);
22047: }
22048: 
22049: /**
22050:  * xmlSchemaIDCStoreNodeTableItem:
22051:  * @vctxt: the WXS validation context
22052:  * @item: the IDC node table item
22053:  *
22054:  * The validation context is used to store IDC node table items.
22055:  * They are stored to avoid copying them if IDC node-tables are merged
22056:  * with corresponding parent IDC node-tables (bubbling).
22057:  *
22058:  * Returns 0 if succeeded, -1 on internal errors.
22059:  */
22060: static int
22061: xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22062: 			       xmlSchemaPSVIIDCNodePtr item)
22063: {
22064:     /*
22065:     * Add to gobal list.
22066:     */
22067:     if (vctxt->idcNodes == NULL) {
22068: 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22069: 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22070: 	if (vctxt->idcNodes == NULL) {
22071: 	    xmlSchemaVErrMemory(vctxt,
22072: 		"allocating the IDC node table item list", NULL);
22073: 	    return (-1);
22074: 	}
22075: 	vctxt->sizeIdcNodes = 20;
22076:     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22077: 	vctxt->sizeIdcNodes *= 2;
22078: 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22079: 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22080: 	    sizeof(xmlSchemaPSVIIDCNodePtr));
22081: 	if (vctxt->idcNodes == NULL) {
22082: 	    xmlSchemaVErrMemory(vctxt,
22083: 		"re-allocating the IDC node table item list", NULL);
22084: 	    return (-1);
22085: 	}
22086:     }
22087:     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22088: 
22089:     return (0);
22090: }
22091: 
22092: /**
22093:  * xmlSchemaIDCStoreKey:
22094:  * @vctxt: the WXS validation context
22095:  * @item: the IDC key
22096:  *
22097:  * The validation context is used to store an IDC key.
22098:  *
22099:  * Returns 0 if succeeded, -1 on internal errors.
22100:  */
22101: static int
22102: xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22103: 		     xmlSchemaPSVIIDCKeyPtr key)
22104: {
22105:     /*
22106:     * Add to gobal list.
22107:     */
22108:     if (vctxt->idcKeys == NULL) {
22109: 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22110: 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22111: 	if (vctxt->idcKeys == NULL) {
22112: 	    xmlSchemaVErrMemory(vctxt,
22113: 		"allocating the IDC key storage list", NULL);
22114: 	    return (-1);
22115: 	}
22116: 	vctxt->sizeIdcKeys = 40;
22117:     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22118: 	vctxt->sizeIdcKeys *= 2;
22119: 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22120: 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22121: 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
22122: 	if (vctxt->idcKeys == NULL) {
22123: 	    xmlSchemaVErrMemory(vctxt,
22124: 		"re-allocating the IDC key storage list", NULL);
22125: 	    return (-1);
22126: 	}
22127:     }
22128:     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22129: 
22130:     return (0);
22131: }
22132: 
22133: /**
22134:  * xmlSchemaIDCAppendNodeTableItem:
22135:  * @bind: the IDC binding
22136:  * @ntItem: the node-table item
22137:  *
22138:  * Appends the IDC node-table item to the binding.
22139:  *
22140:  * Returns 0 on success and -1 on internal errors.
22141:  */
22142: static int
22143: xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22144: 				xmlSchemaPSVIIDCNodePtr ntItem)
22145: {
22146:     if (bind->nodeTable == NULL) {
22147: 	bind->sizeNodes = 10;
22148: 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22149: 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22150: 	if (bind->nodeTable == NULL) {
22151: 	    xmlSchemaVErrMemory(NULL,
22152: 		"allocating an array of IDC node-table items", NULL);
22153: 	    return(-1);
22154: 	}
22155:     } else if (bind->sizeNodes <= bind->nbNodes) {
22156: 	bind->sizeNodes *= 2;
22157: 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22158: 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
22159: 		sizeof(xmlSchemaPSVIIDCNodePtr));
22160: 	if (bind->nodeTable == NULL) {
22161: 	    xmlSchemaVErrMemory(NULL,
22162: 		"re-allocating an array of IDC node-table items", NULL);
22163: 	    return(-1);
22164: 	}
22165:     }
22166:     bind->nodeTable[bind->nbNodes++] = ntItem;
22167:     return(0);
22168: }
22169: 
22170: /**
22171:  * xmlSchemaIDCAcquireBinding:
22172:  * @vctxt: the WXS validation context
22173:  * @matcher: the IDC matcher
22174:  *
22175:  * Looks up an PSVI IDC binding, for the IDC definition and
22176:  * of the given matcher. If none found, a new one is created
22177:  * and added to the IDC table.
22178:  *
22179:  * Returns an IDC binding or NULL on internal errors.
22180:  */
22181: static xmlSchemaPSVIIDCBindingPtr
22182: xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22183: 			  xmlSchemaIDCMatcherPtr matcher)
22184: {
22185:     xmlSchemaNodeInfoPtr ielem;
22186: 
22187:     ielem = vctxt->elemInfos[matcher->depth];
22188: 
22189:     if (ielem->idcTable == NULL) {
22190: 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22191: 	if (ielem->idcTable == NULL)
22192: 	    return (NULL);
22193: 	return(ielem->idcTable);
22194:     } else {
22195: 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
22196: 
22197: 	bind = ielem->idcTable;
22198: 	do {
22199: 	    if (bind->definition == matcher->aidc->def)
22200: 		return(bind);
22201: 	    if (bind->next == NULL) {
22202: 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22203: 		if (bind->next == NULL)
22204: 		    return (NULL);
22205: 		return(bind->next);
22206: 	    }
22207: 	    bind = bind->next;
22208: 	} while (bind != NULL);
22209:     }
22210:     return (NULL);
22211: }
22212: 
22213: static xmlSchemaItemListPtr
22214: xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22215: 			     xmlSchemaIDCMatcherPtr matcher)
22216: {
22217:     if (matcher->targets == NULL)
22218: 	matcher->targets = xmlSchemaItemListCreate();
22219:     return(matcher->targets);
22220: }
22221: 
22222: /**
22223:  * xmlSchemaIDCFreeKey:
22224:  * @key: the IDC key
22225:  *
22226:  * Frees an IDC key together with its compiled value.
22227:  */
22228: static void
22229: xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22230: {
22231:     if (key->val != NULL)
22232: 	xmlSchemaFreeValue(key->val);
22233:     xmlFree(key);
22234: }
22235: 
22236: /**
22237:  * xmlSchemaIDCFreeBinding:
22238:  *
22239:  * Frees an IDC binding. Note that the node table-items
22240:  * are not freed.
22241:  */
22242: static void
22243: xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22244: {
22245:     if (bind->nodeTable != NULL)
22246: 	xmlFree(bind->nodeTable);
22247:     if (bind->dupls != NULL)
22248: 	xmlSchemaItemListFree(bind->dupls);
22249:     xmlFree(bind);
22250: }
22251: 
22252: /**
22253:  * xmlSchemaIDCFreeIDCTable:
22254:  * @bind: the first IDC binding in the list
22255:  *
22256:  * Frees an IDC table, i.e. all the IDC bindings in the list.
22257:  */
22258: static void
22259: xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22260: {
22261:     xmlSchemaPSVIIDCBindingPtr prev;
22262: 
22263:     while (bind != NULL) {
22264: 	prev = bind;
22265: 	bind = bind->next;
22266: 	xmlSchemaIDCFreeBinding(prev);
22267:     }
22268: }
22269: 
22270: /**
22271:  * xmlSchemaIDCFreeMatcherList:
22272:  * @matcher: the first IDC matcher in the list
22273:  *
22274:  * Frees a list of IDC matchers.
22275:  */
22276: static void
22277: xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22278: {
22279:     xmlSchemaIDCMatcherPtr next;
22280: 
22281:     while (matcher != NULL) {
22282: 	next = matcher->next;
22283: 	if (matcher->keySeqs != NULL) {
22284: 	    int i;
22285: 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
22286: 		if (matcher->keySeqs[i] != NULL)
22287: 		    xmlFree(matcher->keySeqs[i]);
22288: 	    xmlFree(matcher->keySeqs);
22289: 	}
22290: 	if (matcher->targets != NULL) {
22291: 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22292: 		int i;
22293: 		xmlSchemaPSVIIDCNodePtr idcNode;
22294: 		/*
22295: 		* Node-table items for keyrefs are not stored globally
22296: 		* to the validation context, since they are not bubbled.
22297: 		* We need to free them here.
22298: 		*/
22299: 		for (i = 0; i < matcher->targets->nbItems; i++) {
22300: 		    idcNode =
22301: 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22302: 		    xmlFree(idcNode->keys);
22303: 		    xmlFree(idcNode);
22304: 		}
22305: 	    }
22306: 	    xmlSchemaItemListFree(matcher->targets);
22307: 	}
22308: 	xmlFree(matcher);
22309: 	matcher = next;
22310:     }
22311: }
22312: 
22313: /**
22314:  * xmlSchemaIDCReleaseMatcherList:
22315:  * @vctxt: the WXS validation context
22316:  * @matcher: the first IDC matcher in the list
22317:  *
22318:  * Caches a list of IDC matchers for reuse.
22319:  */
22320: static void
22321: xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22322: 			       xmlSchemaIDCMatcherPtr matcher)
22323: {
22324:     xmlSchemaIDCMatcherPtr next;
22325: 
22326:     while (matcher != NULL) {
22327: 	next = matcher->next;
22328: 	if (matcher->keySeqs != NULL) {
22329: 	    int i;
22330: 	    /*
22331: 	    * Don't free the array, but only the content.
22332: 	    */
22333: 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
22334: 		if (matcher->keySeqs[i] != NULL) {
22335: 		    xmlFree(matcher->keySeqs[i]);
22336: 		    matcher->keySeqs[i] = NULL;
22337: 		}
22338: 	}
22339: 	if (matcher->targets) {
22340: 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22341: 		int i;
22342: 		xmlSchemaPSVIIDCNodePtr idcNode;
22343: 		/*
22344: 		* Node-table items for keyrefs are not stored globally
22345: 		* to the validation context, since they are not bubbled.
22346: 		* We need to free them here.
22347: 		*/
22348: 		for (i = 0; i < matcher->targets->nbItems; i++) {
22349: 		    idcNode =
22350: 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22351: 		    xmlFree(idcNode->keys);
22352: 		    xmlFree(idcNode);
22353: 		}
22354: 	    }
22355: 	    xmlSchemaItemListFree(matcher->targets);
22356: 	    matcher->targets = NULL;
22357: 	}
22358: 	matcher->next = NULL;
22359: 	/*
22360: 	* Cache the matcher.
22361: 	*/
22362: 	if (vctxt->idcMatcherCache != NULL)
22363: 	    matcher->nextCached = vctxt->idcMatcherCache;
22364: 	vctxt->idcMatcherCache = matcher;
22365: 
22366: 	matcher = next;
22367:     }
22368: }
22369: 
22370: /**
22371:  * xmlSchemaIDCAddStateObject:
22372:  * @vctxt: the WXS validation context
22373:  * @matcher: the IDC matcher
22374:  * @sel: the XPath information
22375:  * @parent: the parent "selector" state object if any
22376:  * @type: "selector" or "field"
22377:  *
22378:  * Creates/reuses and activates state objects for the given
22379:  * XPath information; if the XPath expression consists of unions,
22380:  * multiple state objects are created for every unioned expression.
22381:  *
22382:  * Returns 0 on success and -1 on internal errors.
22383:  */
22384: static int
22385: xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22386: 			xmlSchemaIDCMatcherPtr matcher,
22387: 			xmlSchemaIDCSelectPtr sel,
22388: 			int type)
22389: {
22390:     xmlSchemaIDCStateObjPtr sto;
22391: 
22392:     /*
22393:     * Reuse the state objects from the pool.
22394:     */
22395:     if (vctxt->xpathStatePool != NULL) {
22396: 	sto = vctxt->xpathStatePool;
22397: 	vctxt->xpathStatePool = sto->next;
22398: 	sto->next = NULL;
22399:     } else {
22400: 	/*
22401: 	* Create a new state object.
22402: 	*/
22403: 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22404: 	if (sto == NULL) {
22405: 	    xmlSchemaVErrMemory(NULL,
22406: 		"allocating an IDC state object", NULL);
22407: 	    return (-1);
22408: 	}
22409: 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22410:     }
22411:     /*
22412:     * Add to global list.
22413:     */
22414:     if (vctxt->xpathStates != NULL)
22415: 	sto->next = vctxt->xpathStates;
22416:     vctxt->xpathStates = sto;
22417: 
22418:     /*
22419:     * Free the old xpath validation context.
22420:     */
22421:     if (sto->xpathCtxt != NULL)
22422: 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22423: 
22424:     /*
22425:     * Create a new XPath (pattern) validation context.
22426:     */
22427:     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22428: 	(xmlPatternPtr) sel->xpathComp);
22429:     if (sto->xpathCtxt == NULL) {
22430: 	VERROR_INT("xmlSchemaIDCAddStateObject",
22431: 	    "failed to create an XPath validation context");
22432: 	return (-1);
22433:     }
22434:     sto->type = type;
22435:     sto->depth = vctxt->depth;
22436:     sto->matcher = matcher;
22437:     sto->sel = sel;
22438:     sto->nbHistory = 0;
22439: 
22440: #ifdef DEBUG_IDC
22441:     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
22442: 	sto->sel->xpath);
22443: #endif
22444:     return (0);
22445: }
22446: 
22447: /**
22448:  * xmlSchemaXPathEvaluate:
22449:  * @vctxt: the WXS validation context
22450:  * @nodeType: the nodeType of the current node
22451:  *
22452:  * Evaluates all active XPath state objects.
22453:  *
22454:  * Returns the number of IC "field" state objects which resolved to
22455:  * this node, 0 if none resolved and -1 on internal errors.
22456:  */
22457: static int
22458: xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22459: 		       xmlElementType nodeType)
22460: {
22461:     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22462:     int res, resolved = 0, depth = vctxt->depth;
22463: 
22464:     if (vctxt->xpathStates == NULL)
22465: 	return (0);
22466: 
22467:     if (nodeType == XML_ATTRIBUTE_NODE)
22468: 	depth++;
22469: #ifdef DEBUG_IDC
22470:     {
22471: 	xmlChar *str = NULL;
22472: 	xmlGenericError(xmlGenericErrorContext,
22473: 	    "IDC: EVAL on %s, depth %d, type %d\n",
22474: 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22475: 		vctxt->inode->localName), depth, nodeType);
22476: 	FREE_AND_NULL(str)
22477:     }
22478: #endif
22479:     /*
22480:     * Process all active XPath state objects.
22481:     */
22482:     first = vctxt->xpathStates;
22483:     sto = first;
22484:     while (sto != head) {
22485: #ifdef DEBUG_IDC
22486: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22487: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
22488: 		sto->matcher->aidc->def->name, sto->sel->xpath);
22489: 	else
22490: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
22491: 		sto->matcher->aidc->def->name, sto->sel->xpath);
22492: #endif
22493: 	if (nodeType == XML_ELEMENT_NODE)
22494: 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22495: 		vctxt->inode->localName, vctxt->inode->nsName);
22496: 	else
22497: 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22498: 		vctxt->inode->localName, vctxt->inode->nsName);
22499: 
22500: 	if (res == -1) {
22501: 	    VERROR_INT("xmlSchemaXPathEvaluate",
22502: 		"calling xmlStreamPush()");
22503: 	    return (-1);
22504: 	}
22505: 	if (res == 0)
22506: 	    goto next_sto;
22507: 	/*
22508: 	* Full match.
22509: 	*/
22510: #ifdef DEBUG_IDC
22511: 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
22512: 	    "MATCH\n");
22513: #endif
22514: 	/*
22515: 	* Register a match in the state object history.
22516: 	*/
22517: 	if (sto->history == NULL) {
22518: 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
22519: 	    if (sto->history == NULL) {
22520: 		xmlSchemaVErrMemory(NULL,
22521: 		    "allocating the state object history", NULL);
22522: 		return(-1);
22523: 	    }
22524: 	    sto->sizeHistory = 5;
22525: 	} else if (sto->sizeHistory <= sto->nbHistory) {
22526: 	    sto->sizeHistory *= 2;
22527: 	    sto->history = (int *) xmlRealloc(sto->history,
22528: 		sto->sizeHistory * sizeof(int));
22529: 	    if (sto->history == NULL) {
22530: 		xmlSchemaVErrMemory(NULL,
22531: 		    "re-allocating the state object history", NULL);
22532: 		return(-1);
22533: 	    }
22534: 	}
22535: 	sto->history[sto->nbHistory++] = depth;
22536: 
22537: #ifdef DEBUG_IDC
22538: 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
22539: 	    vctxt->depth);
22540: #endif
22541: 
22542: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22543: 	    xmlSchemaIDCSelectPtr sel;
22544: 	    /*
22545: 	    * Activate state objects for the IDC fields of
22546: 	    * the IDC selector.
22547: 	    */
22548: #ifdef DEBUG_IDC
22549: 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
22550: 		"activating field states\n");
22551: #endif
22552: 	    sel = sto->matcher->aidc->def->fields;
22553: 	    while (sel != NULL) {
22554: 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22555: 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22556: 		    return (-1);
22557: 		sel = sel->next;
22558: 	    }
22559: 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22560: 	    /*
22561: 	    * An IDC key node was found by the IDC field.
22562: 	    */
22563: #ifdef DEBUG_IDC
22564: 	    xmlGenericError(xmlGenericErrorContext,
22565: 		"IDC:     key found\n");
22566: #endif
22567: 	    /*
22568: 	    * Notify that the character value of this node is
22569: 	    * needed.
22570: 	    */
22571: 	    if (resolved == 0) {
22572: 		if ((vctxt->inode->flags &
22573: 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22574: 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22575: 	    }
22576: 	    resolved++;
22577: 	}
22578: next_sto:
22579: 	if (sto->next == NULL) {
22580: 	    /*
22581: 	    * Evaluate field state objects created on this node as well.
22582: 	    */
22583: 	    head = first;
22584: 	    sto = vctxt->xpathStates;
22585: 	} else
22586: 	    sto = sto->next;
22587:     }
22588:     return (resolved);
22589: }
22590: 
22591: static const xmlChar *
22592: xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22593: 			      xmlChar **buf,
22594: 			      xmlSchemaPSVIIDCKeyPtr *seq,
22595: 			      int count)
22596: {
22597:     int i, res;
22598:     xmlChar *value = NULL;
22599: 
22600:     *buf = xmlStrdup(BAD_CAST "[");
22601:     for (i = 0; i < count; i++) {
22602: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
22603: 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22604: 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22605: 	    &value);
22606: 	if (res == 0)
22607: 	    *buf = xmlStrcat(*buf, BAD_CAST value);
22608: 	else {
22609: 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
22610: 		"failed to compute a canonical value");
22611: 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
22612: 	}
22613: 	if (i < count -1)
22614: 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
22615: 	else
22616: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
22617: 	if (value != NULL) {
22618: 	    xmlFree(value);
22619: 	    value = NULL;
22620: 	}
22621:     }
22622:     *buf = xmlStrcat(*buf, BAD_CAST "]");
22623: 
22624:     return (BAD_CAST *buf);
22625: }
22626: 
22627: /**
22628:  * xmlSchemaXPathPop:
22629:  * @vctxt: the WXS validation context
22630:  *
22631:  * Pops all XPath states.
22632:  *
22633:  * Returns 0 on success and -1 on internal errors.
22634:  */
22635: static int
22636: xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22637: {
22638:     xmlSchemaIDCStateObjPtr sto;
22639:     int res;
22640: 
22641:     if (vctxt->xpathStates == NULL)
22642: 	return(0);
22643:     sto = vctxt->xpathStates;
22644:     do {
22645: 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22646: 	if (res == -1)
22647: 	    return (-1);
22648: 	sto = sto->next;
22649:     } while (sto != NULL);
22650:     return(0);
22651: }
22652: 
22653: /**
22654:  * xmlSchemaXPathProcessHistory:
22655:  * @vctxt: the WXS validation context
22656:  * @type: the simple/complex type of the current node if any at all
22657:  * @val: the precompiled value
22658:  *
22659:  * Processes and pops the history items of the IDC state objects.
22660:  * IDC key-sequences are validated/created on IDC bindings.
22661:  *
22662:  * Returns 0 on success and -1 on internal errors.
22663:  */
22664: static int
22665: xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22666: 			     int depth)
22667: {
22668:     xmlSchemaIDCStateObjPtr sto, nextsto;
22669:     int res, matchDepth;
22670:     xmlSchemaPSVIIDCKeyPtr key = NULL;
22671:     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22672: 
22673:     if (vctxt->xpathStates == NULL)
22674: 	return (0);
22675:     sto = vctxt->xpathStates;
22676: 
22677: #ifdef DEBUG_IDC
22678:     {
22679: 	xmlChar *str = NULL;
22680: 	xmlGenericError(xmlGenericErrorContext,
22681: 	    "IDC: BACK on %s, depth %d\n",
22682: 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22683: 		vctxt->inode->localName), vctxt->depth);
22684: 	FREE_AND_NULL(str)
22685:     }
22686: #endif
22687:     /*
22688:     * Evaluate the state objects.
22689:     */
22690:     while (sto != NULL) {
22691: 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22692: 	if (res == -1) {
22693: 	    VERROR_INT("xmlSchemaXPathProcessHistory",
22694: 		"calling xmlStreamPop()");
22695: 	    return (-1);
22696: 	}
22697: #ifdef DEBUG_IDC
22698: 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
22699: 	    sto->sel->xpath);
22700: #endif
22701: 	if (sto->nbHistory == 0)
22702: 	    goto deregister_check;
22703: 
22704: 	matchDepth = sto->history[sto->nbHistory -1];
22705: 
22706: 	/*
22707: 	* Only matches at the current depth are of interest.
22708: 	*/
22709: 	if (matchDepth != depth) {
22710: 	    sto = sto->next;
22711: 	    continue;
22712: 	}
22713: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22714: 	    /*
22715: 	    * NOTE: According to
22716: 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22717: 	    *   ... the simple-content of complex types is also allowed.
22718: 	    */
22719: 
22720: 	    if (WXS_IS_COMPLEX(type)) {
22721: 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
22722: 		    /*
22723: 		    * Sanity check for complex types with simple content.
22724: 		    */
22725: 		    simpleType = type->contentTypeDef;
22726: 		    if (simpleType == NULL) {
22727: 			VERROR_INT("xmlSchemaXPathProcessHistory",
22728: 			    "field resolves to a CT with simple content "
22729: 			    "but the CT is missing the ST definition");
22730: 			return (-1);
22731: 		    }
22732: 		} else
22733: 		    simpleType = NULL;
22734: 	    } else
22735: 		simpleType = type;
22736: 	    if (simpleType == NULL) {
22737: 		xmlChar *str = NULL;
22738: 
22739: 		/*
22740: 		* Not qualified if the field resolves to a node of non
22741: 		* simple type.
22742: 		*/
22743: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
22744: 		    XML_SCHEMAV_CVC_IDC, NULL,
22745: 		    WXS_BASIC_CAST sto->matcher->aidc->def,
22746: 		    "The XPath '%s' of a field of %s does evaluate to a node of "
22747: 		    "non-simple type",
22748: 		    sto->sel->xpath,
22749: 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22750: 		FREE_AND_NULL(str);
22751: 		sto->nbHistory--;
22752: 		goto deregister_check;
22753: 	    }
22754: 
22755: 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
22756: 		/*
22757: 		* Failed to provide the normalized value; maybe
22758: 		* the value was invalid.
22759: 		*/
22760: 		VERROR(XML_SCHEMAV_CVC_IDC,
22761: 		    WXS_BASIC_CAST sto->matcher->aidc->def,
22762: 		    "Warning: No precomputed value available, the value "
22763: 		    "was either invalid or something strange happend");
22764: 		sto->nbHistory--;
22765: 		goto deregister_check;
22766: 	    } else {
22767: 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22768: 		xmlSchemaPSVIIDCKeyPtr *keySeq;
22769: 		int pos, idx;
22770: 
22771: 		/*
22772: 		* The key will be anchored on the matcher's list of
22773: 		* key-sequences. The position in this list is determined
22774: 		* by the target node's depth relative to the matcher's
22775: 		* depth of creation (i.e. the depth of the scope element).
22776: 		*
22777: 		* Element        Depth    Pos   List-entries
22778: 		* <scope>          0              NULL
22779: 		*   <bar>          1              NULL
22780: 		*     <target/>    2       2      target
22781: 		*   <bar>
22782:                 * </scope>
22783: 		*
22784: 		* The size of the list is only dependant on the depth of
22785: 		* the tree.
22786: 		* An entry will be NULLed in selector_leave, i.e. when
22787: 		* we hit the target's
22788: 		*/
22789: 		pos = sto->depth - matcher->depth;
22790: 		idx = sto->sel->index;
22791: 
22792: 		/*
22793: 		* Create/grow the array of key-sequences.
22794: 		*/
22795: 		if (matcher->keySeqs == NULL) {
22796: 		    if (pos > 9)
22797: 			matcher->sizeKeySeqs = pos * 2;
22798: 		    else
22799: 			matcher->sizeKeySeqs = 10;
22800: 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22801: 			xmlMalloc(matcher->sizeKeySeqs *
22802: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22803: 		    if (matcher->keySeqs == NULL) {
22804: 			xmlSchemaVErrMemory(NULL,
22805: 			    "allocating an array of key-sequences",
22806: 			    NULL);
22807: 			return(-1);
22808: 		    }
22809: 		    memset(matcher->keySeqs, 0,
22810: 			matcher->sizeKeySeqs *
22811: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22812: 		} else if (pos >= matcher->sizeKeySeqs) {
22813: 		    int i = matcher->sizeKeySeqs;
22814: 
22815: 		    matcher->sizeKeySeqs *= 2;
22816: 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22817: 			xmlRealloc(matcher->keySeqs,
22818: 			matcher->sizeKeySeqs *
22819: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22820: 		    if (matcher->keySeqs == NULL) {
22821: 			xmlSchemaVErrMemory(NULL,
22822: 			    "reallocating an array of key-sequences",
22823: 			    NULL);
22824: 			return (-1);
22825: 		    }
22826: 		    /*
22827: 		    * The array needs to be NULLed.
22828: 		    * TODO: Use memset?
22829: 		    */
22830: 		    for (; i < matcher->sizeKeySeqs; i++)
22831: 			matcher->keySeqs[i] = NULL;
22832: 		}
22833: 
22834: 		/*
22835: 		* Get/create the key-sequence.
22836: 		*/
22837: 		keySeq = matcher->keySeqs[pos];
22838: 		if (keySeq == NULL) {
22839: 		    goto create_sequence;
22840: 		} else if (keySeq[idx] != NULL) {
22841: 		    xmlChar *str = NULL;
22842: 		    /*
22843: 		    * cvc-identity-constraint:
22844: 		    * 3 For each node in the �target node set� all
22845: 		    * of the {fields}, with that node as the context
22846: 		    * node, evaluate to either an empty node-set or
22847: 		    * a node-set with exactly one member, which must
22848: 		    * have a simple type.
22849: 		    *
22850: 		    * The key was already set; report an error.
22851: 		    */
22852: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22853: 			XML_SCHEMAV_CVC_IDC, NULL,
22854: 			WXS_BASIC_CAST matcher->aidc->def,
22855: 			"The XPath '%s' of a field of %s evaluates to a "
22856: 			"node-set with more than one member",
22857: 			sto->sel->xpath,
22858: 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22859: 		    FREE_AND_NULL(str);
22860: 		    sto->nbHistory--;
22861: 		    goto deregister_check;
22862: 		} else
22863: 		    goto create_key;
22864: 
22865: create_sequence:
22866: 		/*
22867: 		* Create a key-sequence.
22868: 		*/
22869: 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22870: 		    matcher->aidc->def->nbFields *
22871: 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
22872: 		if (keySeq == NULL) {
22873: 		    xmlSchemaVErrMemory(NULL,
22874: 			"allocating an IDC key-sequence", NULL);
22875: 		    return(-1);
22876: 		}
22877: 		memset(keySeq, 0, matcher->aidc->def->nbFields *
22878: 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
22879: 		matcher->keySeqs[pos] = keySeq;
22880: create_key:
22881: 		/*
22882: 		* Create a key once per node only.
22883: 		*/
22884: 		if (key == NULL) {
22885: 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22886: 			sizeof(xmlSchemaPSVIIDCKey));
22887: 		    if (key == NULL) {
22888: 			xmlSchemaVErrMemory(NULL,
22889: 			    "allocating a IDC key", NULL);
22890: 			xmlFree(keySeq);
22891: 			matcher->keySeqs[pos] = NULL;
22892: 			return(-1);
22893: 		    }
22894: 		    /*
22895: 		    * Consume the compiled value.
22896: 		    */
22897: 		    key->type = simpleType;
22898: 		    key->val = vctxt->inode->val;
22899: 		    vctxt->inode->val = NULL;
22900: 		    /*
22901: 		    * Store the key in a global list.
22902: 		    */
22903: 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22904: 			xmlSchemaIDCFreeKey(key);
22905: 			return (-1);
22906: 		    }
22907: 		}
22908: 		keySeq[idx] = key;
22909: 	    }
22910: 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22911: 
22912: 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22913: 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
22914: 	    xmlSchemaPSVIIDCNodePtr ntItem;
22915: 	    xmlSchemaIDCMatcherPtr matcher;
22916: 	    xmlSchemaIDCPtr idc;
22917: 	    xmlSchemaItemListPtr targets;
22918: 	    int pos, i, j, nbKeys;
22919: 	    /*
22920: 	    * Here we have the following scenario:
22921: 	    * An IDC 'selector' state object resolved to a target node,
22922: 	    * during the time this target node was in the
22923: 	    * ancestor-or-self axis, the 'field' state object(s) looked
22924: 	    * out for matching nodes to create a key-sequence for this
22925: 	    * target node. Now we are back to this target node and need
22926: 	    * to put the key-sequence, together with the target node
22927: 	    * itself, into the node-table of the corresponding IDC
22928: 	    * binding.
22929: 	    */
22930: 	    matcher = sto->matcher;
22931: 	    idc = matcher->aidc->def;
22932: 	    nbKeys = idc->nbFields;
22933: 	    pos = depth - matcher->depth;
22934: 	    /*
22935: 	    * Check if the matcher has any key-sequences at all, plus
22936: 	    * if it has a key-sequence for the current target node.
22937: 	    */
22938: 	    if ((matcher->keySeqs == NULL) ||
22939: 		(matcher->sizeKeySeqs <= pos)) {
22940: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22941: 		    goto selector_key_error;
22942: 		else
22943: 		    goto selector_leave;
22944: 	    }
22945: 
22946: 	    keySeq = &(matcher->keySeqs[pos]);
22947: 	    if (*keySeq == NULL) {
22948: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22949: 		    goto selector_key_error;
22950: 		else
22951: 		    goto selector_leave;
22952: 	    }
22953: 
22954: 	    for (i = 0; i < nbKeys; i++) {
22955: 		if ((*keySeq)[i] == NULL) {
22956: 		    /*
22957: 		    * Not qualified, if not all fields did resolve.
22958: 		    */
22959: 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22960: 			/*
22961: 			* All fields of a "key" IDC must resolve.
22962: 			*/
22963: 			goto selector_key_error;
22964: 		    }
22965: 		    goto selector_leave;
22966: 		}
22967: 	    }
22968: 	    /*
22969: 	    * All fields did resolve.
22970: 	    */
22971: 
22972: 	    /*
22973: 	    * 4.1 If the {identity-constraint category} is unique(/key),
22974: 	    * then no two members of the �qualified node set� have
22975: 	    * �key-sequences� whose members are pairwise equal, as
22976: 	    * defined by Equal in [XML Schemas: Datatypes].
22977: 	    *
22978: 	    * Get the IDC binding from the matcher and check for
22979: 	    * duplicate key-sequences.
22980: 	    */
22981: #if 0
22982: 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22983: #endif
22984: 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22985: 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22986: 		(targets->nbItems != 0)) {
22987: 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22988: 
22989: 		i = 0;
22990: 		res = 0;
22991: 		/*
22992: 		* Compare the key-sequences, key by key.
22993: 		*/
22994: 		do {
22995: 		    bkeySeq =
22996: 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
22997: 		    for (j = 0; j < nbKeys; j++) {
22998: 			ckey = (*keySeq)[j];
22999: 			bkey = bkeySeq[j];
23000: 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
23001: 			if (res == -1) {
23002: 			    return (-1);
23003: 			} else if (res == 0) {
23004: 			    /*
23005: 			    * One of the keys differs, so the key-sequence
23006: 			    * won't be equal; get out.
23007: 			    */
23008: 			    break;
23009: 			}
23010: 		    }
23011: 		    if (res == 1) {
23012: 			/*
23013: 			* Duplicate key-sequence found.
23014: 			*/
23015: 			break;
23016: 		    }
23017: 		    i++;
23018: 		} while (i < targets->nbItems);
23019: 		if (i != targets->nbItems) {
23020: 		    xmlChar *str = NULL, *strB = NULL;
23021: 		    /*
23022: 		    * TODO: Try to report the key-sequence.
23023: 		    */
23024: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
23025: 			XML_SCHEMAV_CVC_IDC, NULL,
23026: 			WXS_BASIC_CAST idc,
23027: 			"Duplicate key-sequence %s in %s",
23028: 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
23029: 			    (*keySeq), nbKeys),
23030: 			xmlSchemaGetIDCDesignation(&strB, idc));
23031: 		    FREE_AND_NULL(str);
23032: 		    FREE_AND_NULL(strB);
23033: 		    goto selector_leave;
23034: 		}
23035: 	    }
23036: 	    /*
23037: 	    * Add a node-table item to the IDC binding.
23038: 	    */
23039: 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23040: 		sizeof(xmlSchemaPSVIIDCNode));
23041: 	    if (ntItem == NULL) {
23042: 		xmlSchemaVErrMemory(NULL,
23043: 		    "allocating an IDC node-table item", NULL);
23044: 		xmlFree(*keySeq);
23045: 		*keySeq = NULL;
23046: 		return(-1);
23047: 	    }
23048: 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23049: 
23050: 	    /*
23051: 	    * Store the node-table item in a global list.
23052: 	    */
23053: 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23054: 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23055: 		    xmlFree(ntItem);
23056: 		    xmlFree(*keySeq);
23057: 		    *keySeq = NULL;
23058: 		    return (-1);
23059: 		}
23060: 		ntItem->nodeQNameID = -1;
23061: 	    } else {
23062: 		/*
23063: 		* Save a cached QName for this node on the IDC node, to be
23064: 		* able to report it, even if the node is not saved.
23065: 		*/
23066: 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23067: 		    vctxt->inode->localName, vctxt->inode->nsName);
23068: 		if (ntItem->nodeQNameID == -1) {
23069: 		    xmlFree(ntItem);
23070: 		    xmlFree(*keySeq);
23071: 		    *keySeq = NULL;
23072: 		    return (-1);
23073: 		}
23074: 	    }
23075: 	    /*
23076: 	    * Init the node-table item: Save the node, position and
23077: 	    * consume the key-sequence.
23078: 	    */
23079: 	    ntItem->node = vctxt->node;
23080: 	    ntItem->nodeLine = vctxt->inode->nodeLine;
23081: 	    ntItem->keys = *keySeq;
23082: 	    *keySeq = NULL;
23083: #if 0
23084: 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23085: #endif
23086: 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23087: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23088: 		    /*
23089: 		    * Free the item, since keyref items won't be
23090: 		    * put on a global list.
23091: 		    */
23092: 		    xmlFree(ntItem->keys);
23093: 		    xmlFree(ntItem);
23094: 		}
23095: 		return (-1);
23096: 	    }
23097: 
23098: 	    goto selector_leave;
23099: selector_key_error:
23100: 	    {
23101: 		xmlChar *str = NULL;
23102: 		/*
23103: 		* 4.2.1 (KEY) The �target node set� and the
23104: 		* �qualified node set� are equal, that is, every
23105: 		* member of the �target node set� is also a member
23106: 		* of the �qualified node set� and vice versa.
23107: 		*/
23108: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
23109: 		    XML_SCHEMAV_CVC_IDC, NULL,
23110: 		    WXS_BASIC_CAST idc,
23111: 		    "Not all fields of %s evaluate to a node",
23112: 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
23113: 		FREE_AND_NULL(str);
23114: 	    }
23115: selector_leave:
23116: 	    /*
23117: 	    * Free the key-sequence if not added to the IDC table.
23118: 	    */
23119: 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
23120: 		xmlFree(*keySeq);
23121: 		*keySeq = NULL;
23122: 	    }
23123: 	} /* if selector */
23124: 
23125: 	sto->nbHistory--;
23126: 
23127: deregister_check:
23128: 	/*
23129: 	* Deregister state objects if they reach the depth of creation.
23130: 	*/
23131: 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23132: #ifdef DEBUG_IDC
23133: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
23134: 		sto->sel->xpath);
23135: #endif
23136: 	    if (vctxt->xpathStates != sto) {
23137: 		VERROR_INT("xmlSchemaXPathProcessHistory",
23138: 		    "The state object to be removed is not the first "
23139: 		    "in the list");
23140: 	    }
23141: 	    nextsto = sto->next;
23142: 	    /*
23143: 	    * Unlink from the list of active XPath state objects.
23144: 	    */
23145: 	    vctxt->xpathStates = sto->next;
23146: 	    sto->next = vctxt->xpathStatePool;
23147: 	    /*
23148: 	    * Link it to the pool of reusable state objects.
23149: 	    */
23150: 	    vctxt->xpathStatePool = sto;
23151: 	    sto = nextsto;
23152: 	} else
23153: 	    sto = sto->next;
23154:     } /* while (sto != NULL) */
23155:     return (0);
23156: }
23157: 
23158: /**
23159:  * xmlSchemaIDCRegisterMatchers:
23160:  * @vctxt: the WXS validation context
23161:  * @elemDecl: the element declaration
23162:  *
23163:  * Creates helper objects to evaluate IDC selectors/fields
23164:  * successively.
23165:  *
23166:  * Returns 0 if OK and -1 on internal errors.
23167:  */
23168: static int
23169: xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23170: 			     xmlSchemaElementPtr elemDecl)
23171: {
23172:     xmlSchemaIDCMatcherPtr matcher, last = NULL;
23173:     xmlSchemaIDCPtr idc, refIdc;
23174:     xmlSchemaIDCAugPtr aidc;
23175: 
23176:     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23177:     if (idc == NULL)
23178: 	return (0);
23179: 
23180: #ifdef DEBUG_IDC
23181:     {
23182: 	xmlChar *str = NULL;
23183: 	xmlGenericError(xmlGenericErrorContext,
23184: 	    "IDC: REGISTER on %s, depth %d\n",
23185: 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23186: 		vctxt->inode->localName), vctxt->depth);
23187: 	FREE_AND_NULL(str)
23188:     }
23189: #endif
23190:     if (vctxt->inode->idcMatchers != NULL) {
23191: 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
23192: 	    "The chain of IDC matchers is expected to be empty");
23193: 	return (-1);
23194:     }
23195:     do {
23196: 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23197: 	    /*
23198: 	    * Since IDCs bubbles are expensive we need to know the
23199: 	    * depth at which the bubbles should stop; this will be
23200: 	    * the depth of the top-most keyref IDC. If no keyref
23201: 	    * references a key/unique IDC, the keyrefDepth will
23202: 	    * be -1, indicating that no bubbles are needed.
23203: 	    */
23204: 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23205: 	    if (refIdc != NULL) {
23206: 		/*
23207: 		* Remember that we have keyrefs on this node.
23208: 		*/
23209: 		vctxt->inode->hasKeyrefs = 1;
23210: 		/*
23211: 		* Lookup the referenced augmented IDC info.
23212: 		*/
23213: 		aidc = vctxt->aidcs;
23214: 		while (aidc != NULL) {
23215: 		    if (aidc->def == refIdc)
23216: 			break;
23217: 		    aidc = aidc->next;
23218: 		}
23219: 		if (aidc == NULL) {
23220: 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
23221: 			"Could not find an augmented IDC item for an IDC "
23222: 			"definition");
23223: 		    return (-1);
23224: 		}
23225: 		if ((aidc->keyrefDepth == -1) ||
23226: 		    (vctxt->depth < aidc->keyrefDepth))
23227: 		    aidc->keyrefDepth = vctxt->depth;
23228: 	    }
23229: 	}
23230: 	/*
23231: 	* Lookup the augmented IDC item for the IDC definition.
23232: 	*/
23233: 	aidc = vctxt->aidcs;
23234: 	while (aidc != NULL) {
23235: 	    if (aidc->def == idc)
23236: 		break;
23237: 	    aidc = aidc->next;
23238: 	}
23239: 	if (aidc == NULL) {
23240: 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
23241: 		"Could not find an augmented IDC item for an IDC definition");
23242: 	    return (-1);
23243: 	}
23244: 	/*
23245: 	* Create an IDC matcher for every IDC definition.
23246: 	*/
23247: 	if (vctxt->idcMatcherCache != NULL) {
23248: 	    /*
23249: 	    * Reuse a cached matcher.
23250: 	    */
23251: 	    matcher = vctxt->idcMatcherCache;
23252: 	    vctxt->idcMatcherCache = matcher->nextCached;
23253: 	    matcher->nextCached = NULL;
23254: 	} else {
23255: 	    matcher = (xmlSchemaIDCMatcherPtr)
23256: 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23257: 	    if (matcher == NULL) {
23258: 		xmlSchemaVErrMemory(vctxt,
23259: 		    "allocating an IDC matcher", NULL);
23260: 		return (-1);
23261: 	    }
23262: 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23263: 	}
23264: 	if (last == NULL)
23265: 	    vctxt->inode->idcMatchers = matcher;
23266: 	else
23267: 	    last->next = matcher;
23268: 	last = matcher;
23269: 
23270: 	matcher->type = IDC_MATCHER;
23271: 	matcher->depth = vctxt->depth;
23272: 	matcher->aidc = aidc;
23273: 	matcher->idcType = aidc->def->type;
23274: #ifdef DEBUG_IDC
23275: 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
23276: #endif
23277: 	/*
23278: 	* Init the automaton state object.
23279: 	*/
23280: 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23281: 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23282: 	    return (-1);
23283: 
23284: 	idc = idc->next;
23285:     } while (idc != NULL);
23286:     return (0);
23287: }
23288: 
23289: static int
23290: xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23291: 			   xmlSchemaNodeInfoPtr ielem)
23292: {
23293:     xmlSchemaPSVIIDCBindingPtr bind;
23294:     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23295:     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23296:     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23297: 
23298:     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23299:     /* vctxt->createIDCNodeTables */
23300:     while (matcher != NULL) {
23301: 	/*
23302: 	* Skip keyref IDCs and empty IDC target-lists.
23303: 	*/
23304: 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23305: 	    WXS_ILIST_IS_EMPTY(matcher->targets))
23306: 	{
23307: 	    matcher = matcher->next;
23308: 	    continue;
23309: 	}
23310: 	/*
23311: 	* If we _want_ the IDC node-table to be created in any case
23312: 	* then do so. Otherwise create them only if keyrefs need them.
23313: 	*/
23314: 	if ((! vctxt->createIDCNodeTables) &&
23315: 	    ((matcher->aidc->keyrefDepth == -1) ||
23316: 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
23317: 	{
23318: 	    matcher = matcher->next;
23319: 	    continue;
23320: 	}
23321: 	/*
23322: 	* Get/create the IDC binding on this element for the IDC definition.
23323: 	*/
23324: 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23325: 
23326: 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23327: 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23328: 	    nbDupls = bind->dupls->nbItems;
23329: 	} else {
23330: 	    dupls = NULL;
23331: 	    nbDupls = 0;
23332: 	}
23333: 	if (bind->nodeTable != NULL) {
23334: 	    nbNodeTable = bind->nbNodes;
23335: 	} else {
23336: 	    nbNodeTable = 0;
23337: 	}
23338: 
23339: 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
23340: 	    /*
23341: 	    * Transfer all IDC target-nodes to the IDC node-table.
23342: 	    */
23343: 	    bind->nodeTable =
23344: 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23345: 	    bind->sizeNodes = matcher->targets->sizeItems;
23346: 	    bind->nbNodes = matcher->targets->nbItems;
23347: 
23348: 	    matcher->targets->items = NULL;
23349: 	    matcher->targets->sizeItems = 0;
23350: 	    matcher->targets->nbItems = 0;
23351: 	} else {
23352: 	    /*
23353: 	    * Compare the key-sequences and add to the IDC node-table.
23354: 	    */
23355: 	    nbTargets = matcher->targets->nbItems;
23356: 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23357: 	    nbFields = matcher->aidc->def->nbFields;
23358: 	    i = 0;
23359: 	    do {
23360: 		keys = targets[i]->keys;
23361: 		if (nbDupls) {
23362: 		    /*
23363: 		    * Search in already found duplicates first.
23364: 		    */
23365: 		    j = 0;
23366: 		    do {
23367: 			if (nbFields == 1) {
23368: 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
23369: 				dupls[j]->keys[0]->val);
23370: 			    if (res == -1)
23371: 				goto internal_error;
23372: 			    if (res == 1) {
23373: 				/*
23374: 				* Equal key-sequence.
23375: 				*/
23376: 				goto next_target;
23377: 			    }
23378: 			} else {
23379: 			    res = 0;
23380: 			    ntkeys = dupls[j]->keys;
23381: 			    for (k = 0; k < nbFields; k++) {
23382: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23383: 				    ntkeys[k]->val);
23384: 				if (res == -1)
23385: 				    goto internal_error;
23386: 				if (res == 0) {
23387: 				    /*
23388: 				    * One of the keys differs.
23389: 				    */
23390: 				    break;
23391: 				}
23392: 			    }
23393: 			    if (res == 1) {
23394: 				/*
23395: 				* Equal key-sequence found.
23396: 				*/
23397: 				goto next_target;
23398: 			    }
23399: 			}
23400: 			j++;
23401: 		    } while (j < nbDupls);
23402: 		}
23403: 		if (nbNodeTable) {
23404: 		    j = 0;
23405: 		    do {
23406: 			if (nbFields == 1) {
23407: 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
23408: 				bind->nodeTable[j]->keys[0]->val);
23409: 			    if (res == -1)
23410: 				goto internal_error;
23411: 			    if (res == 0) {
23412: 				/*
23413: 				* The key-sequence differs.
23414: 				*/
23415: 				goto next_node_table_entry;
23416: 			    }
23417: 			} else {
23418: 			    res = 0;
23419: 			    ntkeys = bind->nodeTable[j]->keys;
23420: 			    for (k = 0; k < nbFields; k++) {
23421: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23422: 				    ntkeys[k]->val);
23423: 				if (res == -1)
23424: 				    goto internal_error;
23425: 				if (res == 0) {
23426: 				    /*
23427: 				    * One of the keys differs.
23428: 				    */
23429: 				    goto next_node_table_entry;
23430: 				}
23431: 			    }
23432: 			}
23433: 			/*
23434: 			* Add the duplicate to the list of duplicates.
23435: 			*/
23436: 			if (bind->dupls == NULL) {
23437: 			    bind->dupls = xmlSchemaItemListCreate();
23438: 			    if (bind->dupls == NULL)
23439: 				goto internal_error;
23440: 			}
23441: 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23442: 			    goto internal_error;
23443: 			/*
23444: 			* Remove the duplicate entry from the IDC node-table.
23445: 			*/
23446: 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23447: 			bind->nbNodes--;
23448: 
23449: 			goto next_target;
23450: 
23451: next_node_table_entry:
23452: 			j++;
23453: 		    } while (j < nbNodeTable);
23454: 		}
23455: 		/*
23456: 		* If everything is fine, then add the IDC target-node to
23457: 		* the IDC node-table.
23458: 		*/
23459: 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23460: 		    goto internal_error;
23461: 
23462: next_target:
23463: 		i++;
23464: 	    } while (i < nbTargets);
23465: 	}
23466: 	matcher = matcher->next;
23467:     }
23468:     return(0);
23469: 
23470: internal_error:
23471:     return(-1);
23472: }
23473: 
23474: /**
23475:  * xmlSchemaBubbleIDCNodeTables:
23476:  * @depth: the current tree depth
23477:  *
23478:  * Merges IDC bindings of an element at @depth into the corresponding IDC
23479:  * bindings of its parent element. If a duplicate note-table entry is found,
23480:  * both, the parent node-table entry and child entry are discarded from the
23481:  * node-table of the parent.
23482:  *
23483:  * Returns 0 if OK and -1 on internal errors.
23484:  */
23485: static int
23486: xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23487: {
23488:     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23489:     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23490:     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23491:     xmlSchemaIDCAugPtr aidc;
23492:     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23493: 
23494:     bind = vctxt->inode->idcTable;
23495:     if (bind == NULL) {
23496: 	/* Fine, no table, no bubbles. */
23497: 	return (0);
23498:     }
23499: 
23500:     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23501:     /*
23502:     * Walk all bindings; create new or add to existing bindings.
23503:     * Remove duplicate key-sequences.
23504:     */
23505:     while (bind != NULL) {
23506: 
23507: 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23508: 	    goto next_binding;
23509: 	/*
23510: 	* Check if the key/unique IDC table needs to be bubbled.
23511: 	*/
23512: 	if (! vctxt->createIDCNodeTables) {
23513: 	    aidc = vctxt->aidcs;
23514: 	    do {
23515: 		if (aidc->def == bind->definition) {
23516: 		    if ((aidc->keyrefDepth == -1) ||
23517: 			(aidc->keyrefDepth >= vctxt->depth)) {
23518: 			goto next_binding;
23519: 		    }
23520: 		    break;
23521: 		}
23522: 		aidc = aidc->next;
23523: 	    } while (aidc != NULL);
23524: 	}
23525: 
23526: 	if (parTable != NULL)
23527: 	    parBind = *parTable;
23528: 	/*
23529: 	* Search a matching parent binding for the
23530: 	* IDC definition.
23531: 	*/
23532: 	while (parBind != NULL) {
23533: 	    if (parBind->definition == bind->definition)
23534: 		break;
23535: 	    parBind = parBind->next;
23536: 	}
23537: 
23538: 	if (parBind != NULL) {
23539: 	    /*
23540: 	    * Compare every node-table entry of the child node,
23541: 	    * i.e. the key-sequence within, ...
23542: 	    */
23543: 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
23544: 
23545: 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23546: 		oldDupls = parBind->dupls->nbItems;
23547: 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23548: 	    } else {
23549: 		dupls = NULL;
23550: 		oldDupls = 0;
23551: 	    }
23552: 
23553: 	    parNodes = parBind->nodeTable;
23554: 	    nbFields = bind->definition->nbFields;
23555: 
23556: 	    for (i = 0; i < bind->nbNodes; i++) {
23557: 		node = bind->nodeTable[i];
23558: 		if (node == NULL)
23559: 		    continue;
23560: 		/*
23561: 		* ...with every key-sequence of the parent node, already
23562: 		* evaluated to be a duplicate key-sequence.
23563: 		*/
23564: 		if (oldDupls) {
23565: 		    j = 0;
23566: 		    while (j < oldDupls) {
23567: 			if (nbFields == 1) {
23568: 			    ret = xmlSchemaAreValuesEqual(
23569: 				node->keys[0]->val,
23570: 				dupls[j]->keys[0]->val);
23571: 			    if (ret == -1)
23572: 				goto internal_error;
23573: 			    if (ret == 0) {
23574: 				j++;
23575: 				continue;
23576: 			    }
23577: 			} else {
23578: 			    parNode = dupls[j];
23579: 			    for (k = 0; k < nbFields; k++) {
23580: 				ret = xmlSchemaAreValuesEqual(
23581: 				    node->keys[k]->val,
23582: 				    parNode->keys[k]->val);
23583: 				if (ret == -1)
23584: 				    goto internal_error;
23585: 				if (ret == 0)
23586: 				    break;
23587: 			    }
23588: 			}
23589: 			if (ret == 1)
23590: 			    /* Duplicate found. */
23591: 			    break;
23592: 			j++;
23593: 		    }
23594: 		    if (j != oldDupls) {
23595: 			/* Duplicate found. Skip this entry. */
23596: 			continue;
23597: 		    }
23598: 		}
23599: 		/*
23600: 		* ... and with every key-sequence of the parent node.
23601: 		*/
23602: 		if (oldNum) {
23603: 		    j = 0;
23604: 		    while (j < oldNum) {
23605: 			parNode = parNodes[j];
23606: 			if (nbFields == 1) {
23607: 			    ret = xmlSchemaAreValuesEqual(
23608: 				node->keys[0]->val,
23609: 				parNode->keys[0]->val);
23610: 			    if (ret == -1)
23611: 				goto internal_error;
23612: 			    if (ret == 0) {
23613: 				j++;
23614: 				continue;
23615: 			    }
23616: 			} else {
23617: 			    for (k = 0; k < nbFields; k++) {
23618: 				ret = xmlSchemaAreValuesEqual(
23619: 				    node->keys[k]->val,
23620: 				    parNode->keys[k]->val);
23621: 				if (ret == -1)
23622: 				    goto internal_error;
23623: 				if (ret == 0)
23624: 				    break;
23625: 			    }
23626: 			}
23627: 			if (ret == 1)
23628: 			    /* Duplicate found. */
23629: 			    break;
23630: 			j++;
23631: 		    }
23632: 		    if (j != oldNum) {
23633: 			/*
23634: 			* Handle duplicates. Move the duplicate in
23635: 			* the parent's node-table to the list of
23636: 			* duplicates.
23637: 			*/
23638: 			oldNum--;
23639: 			parBind->nbNodes--;
23640: 			/*
23641: 			* Move last old item to pos of duplicate.
23642: 			*/
23643: 			parNodes[j] = parNodes[oldNum];
23644: 
23645: 			if (parBind->nbNodes != oldNum) {
23646: 			    /*
23647: 			    * If new items exist, move last new item to
23648: 			    * last of old items.
23649: 			    */
23650: 			    parNodes[oldNum] =
23651: 				parNodes[parBind->nbNodes];
23652: 			}
23653: 			if (parBind->dupls == NULL) {
23654: 			    parBind->dupls = xmlSchemaItemListCreate();
23655: 			    if (parBind->dupls == NULL)
23656: 				goto internal_error;
23657: 			}
23658: 			xmlSchemaItemListAdd(parBind->dupls, parNode);
23659: 		    } else {
23660: 			/*
23661: 			* Add the node-table entry (node and key-sequence) of
23662: 			* the child node to the node table of the parent node.
23663: 			*/
23664: 			if (parBind->nodeTable == NULL) {
23665: 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23666: 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23667: 			    if (parBind->nodeTable == NULL) {
23668: 				xmlSchemaVErrMemory(NULL,
23669: 				    "allocating IDC list of node-table items", NULL);
23670: 				goto internal_error;
23671: 			    }
23672: 			    parBind->sizeNodes = 1;
23673: 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
23674: 			    parBind->sizeNodes *= 2;
23675: 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23676: 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23677: 				sizeof(xmlSchemaPSVIIDCNodePtr));
23678: 			    if (parBind->nodeTable == NULL) {
23679: 				xmlSchemaVErrMemory(NULL,
23680: 				    "re-allocating IDC list of node-table items", NULL);
23681: 				goto internal_error;
23682: 			    }
23683: 			}
23684: 			parNodes = parBind->nodeTable;
23685: 			/*
23686: 			* Append the new node-table entry to the 'new node-table
23687: 			* entries' section.
23688: 			*/
23689: 			parNodes[parBind->nbNodes++] = node;
23690: 		    }
23691: 
23692: 		}
23693: 
23694: 	    }
23695: 	} else {
23696: 	    /*
23697: 	    * No binding for the IDC was found: create a new one and
23698: 	    * copy all node-tables.
23699: 	    */
23700: 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
23701: 	    if (parBind == NULL)
23702: 		goto internal_error;
23703: 
23704: 	    /*
23705: 	    * TODO: Hmm, how to optimize the initial number of
23706: 	    * allocated entries?
23707: 	    */
23708: 	    if (bind->nbNodes != 0) {
23709: 		/*
23710: 		* Add all IDC node-table entries.
23711: 		*/
23712: 		if (! vctxt->psviExposeIDCNodeTables) {
23713: 		    /*
23714: 		    * Just move the entries.
23715: 		    * NOTE: this is quite save here, since
23716: 		    * all the keyref lookups have already been
23717: 		    * performed.
23718: 		    */
23719: 		    parBind->nodeTable = bind->nodeTable;
23720: 		    bind->nodeTable = NULL;
23721: 		    parBind->sizeNodes = bind->sizeNodes;
23722: 		    bind->sizeNodes = 0;
23723: 		    parBind->nbNodes = bind->nbNodes;
23724: 		    bind->nbNodes = 0;
23725: 		} else {
23726: 		    /*
23727: 		    * Copy the entries.
23728: 		    */
23729: 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23730: 			xmlMalloc(bind->nbNodes *
23731: 			sizeof(xmlSchemaPSVIIDCNodePtr));
23732: 		    if (parBind->nodeTable == NULL) {
23733: 			xmlSchemaVErrMemory(NULL,
23734: 			    "allocating an array of IDC node-table "
23735: 			    "items", NULL);
23736: 			xmlSchemaIDCFreeBinding(parBind);
23737: 			goto internal_error;
23738: 		    }
23739: 		    parBind->sizeNodes = bind->nbNodes;
23740: 		    parBind->nbNodes = bind->nbNodes;
23741: 		    memcpy(parBind->nodeTable, bind->nodeTable,
23742: 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23743: 		}
23744: 	    }
23745: 	    if (bind->dupls) {
23746: 		/*
23747: 		* Move the duplicates.
23748: 		*/
23749: 		if (parBind->dupls != NULL)
23750: 		    xmlSchemaItemListFree(parBind->dupls);
23751: 		parBind->dupls = bind->dupls;
23752: 		bind->dupls = NULL;
23753: 	    }
23754:             if (parTable != NULL) {
23755:                 if (*parTable == NULL)
23756:                     *parTable = parBind;
23757:                 else {
23758:                     parBind->next = *parTable;
23759:                     *parTable = parBind;
23760:                 }
23761:             }
23762: 	}
23763: 
23764: next_binding:
23765: 	bind = bind->next;
23766:     }
23767:     return (0);
23768: 
23769: internal_error:
23770:     return(-1);
23771: }
23772: 
23773: /**
23774:  * xmlSchemaCheckCVCIDCKeyRef:
23775:  * @vctxt: the WXS validation context
23776:  * @elemDecl: the element declaration
23777:  *
23778:  * Check the cvc-idc-keyref constraints.
23779:  */
23780: static int
23781: xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23782: {
23783:     xmlSchemaIDCMatcherPtr matcher;
23784:     xmlSchemaPSVIIDCBindingPtr bind;
23785: 
23786:     matcher = vctxt->inode->idcMatchers;
23787:     /*
23788:     * Find a keyref.
23789:     */
23790:     while (matcher != NULL) {
23791: 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23792: 	    matcher->targets &&
23793: 	    matcher->targets->nbItems)
23794: 	{
23795: 	    int i, j, k, res, nbFields, hasDupls;
23796: 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23797: 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
23798: 
23799: 	    nbFields = matcher->aidc->def->nbFields;
23800: 
23801: 	    /*
23802: 	    * Find the IDC node-table for the referenced IDC key/unique.
23803: 	    */
23804: 	    bind = vctxt->inode->idcTable;
23805: 	    while (bind != NULL) {
23806: 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23807: 		    bind->definition)
23808: 		    break;
23809: 		bind = bind->next;
23810: 	    }
23811: 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23812: 	    /*
23813: 	    * Search for a matching key-sequences.
23814: 	    */
23815: 	    for (i = 0; i < matcher->targets->nbItems; i++) {
23816: 		res = 0;
23817: 		refNode = matcher->targets->items[i];
23818: 		if (bind != NULL) {
23819: 		    refKeys = refNode->keys;
23820: 		    for (j = 0; j < bind->nbNodes; j++) {
23821: 			keys = bind->nodeTable[j]->keys;
23822: 			for (k = 0; k < nbFields; k++) {
23823: 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
23824: 				refKeys[k]->val);
23825: 			    if (res == 0)
23826: 				break;
23827: 			    else if (res == -1) {
23828: 				return (-1);
23829: 			    }
23830: 			}
23831: 			if (res == 1) {
23832: 			    /*
23833: 			    * Match found.
23834: 			    */
23835: 			    break;
23836: 			}
23837: 		    }
23838: 		    if ((res == 0) && hasDupls) {
23839: 			/*
23840: 			* Search in duplicates
23841: 			*/
23842: 			for (j = 0; j < bind->dupls->nbItems; j++) {
23843: 			    keys = ((xmlSchemaPSVIIDCNodePtr)
23844: 				bind->dupls->items[j])->keys;
23845: 			    for (k = 0; k < nbFields; k++) {
23846: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23847: 				    refKeys[k]->val);
23848: 				if (res == 0)
23849: 				    break;
23850: 				else if (res == -1) {
23851: 				    return (-1);
23852: 				}
23853: 			    }
23854: 			    if (res == 1) {
23855: 				/*
23856: 				* Match in duplicates found.
23857: 				*/
23858: 				xmlChar *str = NULL, *strB = NULL;
23859: 				xmlSchemaKeyrefErr(vctxt,
23860: 				    XML_SCHEMAV_CVC_IDC, refNode,
23861: 				    (xmlSchemaTypePtr) matcher->aidc->def,
23862: 				    "More than one match found for "
23863: 				    "key-sequence %s of keyref '%s'",
23864: 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
23865: 					refNode->keys, nbFields),
23866: 				    xmlSchemaGetComponentQName(&strB,
23867: 					matcher->aidc->def));
23868: 				FREE_AND_NULL(str);
23869: 				FREE_AND_NULL(strB);
23870: 				break;
23871: 			    }
23872: 			}
23873: 		    }
23874: 		}
23875: 
23876: 		if (res == 0) {
23877: 		    xmlChar *str = NULL, *strB = NULL;
23878: 		    xmlSchemaKeyrefErr(vctxt,
23879: 			XML_SCHEMAV_CVC_IDC, refNode,
23880: 			(xmlSchemaTypePtr) matcher->aidc->def,
23881: 			"No match found for key-sequence %s of keyref '%s'",
23882: 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
23883: 			    refNode->keys, nbFields),
23884: 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23885: 		    FREE_AND_NULL(str);
23886: 		    FREE_AND_NULL(strB);
23887: 		}
23888: 	    }
23889: 	}
23890: 	matcher = matcher->next;
23891:     }
23892:     /* TODO: Return an error if any error encountered. */
23893:     return (0);
23894: }
23895: 
23896: /************************************************************************
23897:  *									*
23898:  *			XML Reader validation code                      *
23899:  *									*
23900:  ************************************************************************/
23901: 
23902: static xmlSchemaAttrInfoPtr
23903: xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23904: {
23905:     xmlSchemaAttrInfoPtr iattr;
23906:     /*
23907:     * Grow/create list of attribute infos.
23908:     */
23909:     if (vctxt->attrInfos == NULL) {
23910: 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23911: 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23912: 	vctxt->sizeAttrInfos = 1;
23913: 	if (vctxt->attrInfos == NULL) {
23914: 	    xmlSchemaVErrMemory(vctxt,
23915: 		"allocating attribute info list", NULL);
23916: 	    return (NULL);
23917: 	}
23918:     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23919: 	vctxt->sizeAttrInfos++;
23920: 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23921: 	    xmlRealloc(vctxt->attrInfos,
23922: 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23923: 	if (vctxt->attrInfos == NULL) {
23924: 	    xmlSchemaVErrMemory(vctxt,
23925: 		"re-allocating attribute info list", NULL);
23926: 	    return (NULL);
23927: 	}
23928:     } else {
23929: 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23930: 	if (iattr->localName != NULL) {
23931: 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
23932: 		"attr info not cleared");
23933: 	    return (NULL);
23934: 	}
23935: 	iattr->nodeType = XML_ATTRIBUTE_NODE;
23936: 	return (iattr);
23937:     }
23938:     /*
23939:     * Create an attribute info.
23940:     */
23941:     iattr = (xmlSchemaAttrInfoPtr)
23942: 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
23943:     if (iattr == NULL) {
23944: 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
23945: 	return (NULL);
23946:     }
23947:     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23948:     iattr->nodeType = XML_ATTRIBUTE_NODE;
23949:     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23950: 
23951:     return (iattr);
23952: }
23953: 
23954: static int
23955: xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23956: 			xmlNodePtr attrNode,
23957: 			int nodeLine,
23958: 			const xmlChar *localName,
23959: 			const xmlChar *nsName,
23960: 			int ownedNames,
23961: 			xmlChar *value,
23962: 			int ownedValue)
23963: {
23964:     xmlSchemaAttrInfoPtr attr;
23965: 
23966:     attr = xmlSchemaGetFreshAttrInfo(vctxt);
23967:     if (attr == NULL) {
23968: 	VERROR_INT("xmlSchemaPushAttribute",
23969: 	    "calling xmlSchemaGetFreshAttrInfo()");
23970: 	return (-1);
23971:     }
23972:     attr->node = attrNode;
23973:     attr->nodeLine = nodeLine;
23974:     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23975:     attr->localName = localName;
23976:     attr->nsName = nsName;
23977:     if (ownedNames)
23978: 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23979:     /*
23980:     * Evaluate if it's an XSI attribute.
23981:     */
23982:     if (nsName != NULL) {
23983: 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
23984: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23985: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23986: 	    }
23987: 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
23988: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23989: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23990: 	    }
23991: 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23992: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23993: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23994: 	    }
23995: 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23996: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23997: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23998: 	    }
23999: 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
24000: 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
24001: 	}
24002:     }
24003:     attr->value = value;
24004:     if (ownedValue)
24005: 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
24006:     if (attr->metaType != 0)
24007: 	attr->state = XML_SCHEMAS_ATTR_META;
24008:     return (0);
24009: }
24010: 
24011: /**
24012:  * xmlSchemaClearElemInfo:
24013:  * @vctxt: the WXS validation context
24014:  * @ielem: the element information item
24015:  */
24016: static void
24017: xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
24018: 		       xmlSchemaNodeInfoPtr ielem)
24019: {
24020:     ielem->hasKeyrefs = 0;
24021:     ielem->appliedXPath = 0;
24022:     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
24023: 	FREE_AND_NULL(ielem->localName);
24024: 	FREE_AND_NULL(ielem->nsName);
24025:     } else {
24026: 	ielem->localName = NULL;
24027: 	ielem->nsName = NULL;
24028:     }
24029:     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24030: 	FREE_AND_NULL(ielem->value);
24031:     } else {
24032: 	ielem->value = NULL;
24033:     }
24034:     if (ielem->val != NULL) {
24035: 	/*
24036: 	* PSVI TODO: Be careful not to free it when the value is
24037: 	* exposed via PSVI.
24038: 	*/
24039: 	xmlSchemaFreeValue(ielem->val);
24040: 	ielem->val = NULL;
24041:     }
24042:     if (ielem->idcMatchers != NULL) {
24043: 	/*
24044: 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24045: 	*   Does it work?
24046: 	*/
24047: 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24048: #if 0
24049: 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24050: #endif
24051: 	ielem->idcMatchers = NULL;
24052:     }
24053:     if (ielem->idcTable != NULL) {
24054: 	/*
24055: 	* OPTIMIZE TODO: Use a pool of IDC tables??.
24056: 	*/
24057: 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24058: 	ielem->idcTable = NULL;
24059:     }
24060:     if (ielem->regexCtxt != NULL) {
24061: 	xmlRegFreeExecCtxt(ielem->regexCtxt);
24062: 	ielem->regexCtxt = NULL;
24063:     }
24064:     if (ielem->nsBindings != NULL) {
24065: 	xmlFree((xmlChar **)ielem->nsBindings);
24066: 	ielem->nsBindings = NULL;
24067: 	ielem->nbNsBindings = 0;
24068: 	ielem->sizeNsBindings = 0;
24069:     }
24070: }
24071: 
24072: /**
24073:  * xmlSchemaGetFreshElemInfo:
24074:  * @vctxt: the schema validation context
24075:  *
24076:  * Creates/reuses and initializes the element info item for
24077:  * the currect tree depth.
24078:  *
24079:  * Returns the element info item or NULL on API or internal errors.
24080:  */
24081: static xmlSchemaNodeInfoPtr
24082: xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24083: {
24084:     xmlSchemaNodeInfoPtr info = NULL;
24085: 
24086:     if (vctxt->depth > vctxt->sizeElemInfos) {
24087: 	VERROR_INT("xmlSchemaGetFreshElemInfo",
24088: 	    "inconsistent depth encountered");
24089: 	return (NULL);
24090:     }
24091:     if (vctxt->elemInfos == NULL) {
24092: 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24093: 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24094: 	if (vctxt->elemInfos == NULL) {
24095: 	    xmlSchemaVErrMemory(vctxt,
24096: 		"allocating the element info array", NULL);
24097: 	    return (NULL);
24098: 	}
24099: 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24100: 	vctxt->sizeElemInfos = 10;
24101:     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24102: 	int i = vctxt->sizeElemInfos;
24103: 
24104: 	vctxt->sizeElemInfos *= 2;
24105: 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24106: 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24107: 	    sizeof(xmlSchemaNodeInfoPtr));
24108: 	if (vctxt->elemInfos == NULL) {
24109: 	    xmlSchemaVErrMemory(vctxt,
24110: 		"re-allocating the element info array", NULL);
24111: 	    return (NULL);
24112: 	}
24113: 	/*
24114: 	* We need the new memory to be NULLed.
24115: 	* TODO: Use memset instead?
24116: 	*/
24117: 	for (; i < vctxt->sizeElemInfos; i++)
24118: 	    vctxt->elemInfos[i] = NULL;
24119:     } else
24120: 	info = vctxt->elemInfos[vctxt->depth];
24121: 
24122:     if (info == NULL) {
24123: 	info = (xmlSchemaNodeInfoPtr)
24124: 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
24125: 	if (info == NULL) {
24126: 	    xmlSchemaVErrMemory(vctxt,
24127: 		"allocating an element info", NULL);
24128: 	    return (NULL);
24129: 	}
24130: 	vctxt->elemInfos[vctxt->depth] = info;
24131:     } else {
24132: 	if (info->localName != NULL) {
24133: 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
24134: 		"elem info has not been cleared");
24135: 	    return (NULL);
24136: 	}
24137:     }
24138:     memset(info, 0, sizeof(xmlSchemaNodeInfo));
24139:     info->nodeType = XML_ELEMENT_NODE;
24140:     info->depth = vctxt->depth;
24141: 
24142:     return (info);
24143: }
24144: 
24145: #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24146: #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24147: #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24148: 
24149: static int
24150: xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24151: 			xmlNodePtr node,
24152: 			xmlSchemaTypePtr type,
24153: 			xmlSchemaValType valType,
24154: 			const xmlChar * value,
24155: 			xmlSchemaValPtr val,
24156: 			unsigned long length,
24157: 			int fireErrors)
24158: {
24159:     int ret, error = 0;
24160: 
24161:     xmlSchemaTypePtr tmpType;
24162:     xmlSchemaFacetLinkPtr facetLink;
24163:     xmlSchemaFacetPtr facet;
24164:     unsigned long len = 0;
24165:     xmlSchemaWhitespaceValueType ws;
24166: 
24167:     /*
24168:     * In Libxml2, derived built-in types have currently no explicit facets.
24169:     */
24170:     if (type->type == XML_SCHEMA_TYPE_BASIC)
24171: 	return (0);
24172: 
24173:     /*
24174:     * NOTE: Do not jump away, if the facetSet of the given type is
24175:     * empty: until now, "pattern" and "enumeration" facets of the
24176:     * *base types* need to be checked as well.
24177:     */
24178:     if (type->facetSet == NULL)
24179: 	goto pattern_and_enum;
24180: 
24181:     if (! WXS_IS_ATOMIC(type)) {
24182: 	if (WXS_IS_LIST(type))
24183: 	    goto WXS_IS_LIST;
24184: 	else
24185: 	    goto pattern_and_enum;
24186:     }
24187:     /*
24188:     * Whitespace handling is only of importance for string-based
24189:     * types.
24190:     */
24191:     tmpType = xmlSchemaGetPrimitiveType(type);
24192:     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24193: 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24194: 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24195:     } else
24196: 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24197:     /*
24198:     * If the value was not computed (for string or
24199:     * anySimpleType based types), then use the provided
24200:     * type.
24201:     */
24202:     if (val == NULL)
24203: 	valType = valType;
24204:     else
24205: 	valType = xmlSchemaGetValType(val);
24206: 
24207:     ret = 0;
24208:     for (facetLink = type->facetSet; facetLink != NULL;
24209: 	facetLink = facetLink->next) {
24210: 	/*
24211: 	* Skip the pattern "whiteSpace": it is used to
24212: 	* format the character content beforehand.
24213: 	*/
24214: 	switch (facetLink->facet->type) {
24215: 	    case XML_SCHEMA_FACET_WHITESPACE:
24216: 	    case XML_SCHEMA_FACET_PATTERN:
24217: 	    case XML_SCHEMA_FACET_ENUMERATION:
24218: 		continue;
24219: 	    case XML_SCHEMA_FACET_LENGTH:
24220: 	    case XML_SCHEMA_FACET_MINLENGTH:
24221: 	    case XML_SCHEMA_FACET_MAXLENGTH:
24222: 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24223: 		    valType, value, val, &len, ws);
24224: 		break;
24225: 	    default:
24226: 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24227: 		    valType, value, val, ws);
24228: 		break;
24229: 	}
24230: 	if (ret < 0) {
24231: 	    AERROR_INT("xmlSchemaValidateFacets",
24232: 		"validating against a atomic type facet");
24233: 	    return (-1);
24234: 	} else if (ret > 0) {
24235: 	    if (fireErrors)
24236: 		xmlSchemaFacetErr(actxt, ret, node,
24237: 		value, len, type, facetLink->facet, NULL, NULL, NULL);
24238: 	    else
24239: 		return (ret);
24240: 	    if (error == 0)
24241: 		error = ret;
24242: 	}
24243: 	ret = 0;
24244:     }
24245: 
24246: WXS_IS_LIST:
24247:     if (! WXS_IS_LIST(type))
24248: 	goto pattern_and_enum;
24249:     /*
24250:     * "length", "minLength" and "maxLength" of list types.
24251:     */
24252:     ret = 0;
24253:     for (facetLink = type->facetSet; facetLink != NULL;
24254: 	facetLink = facetLink->next) {
24255: 
24256: 	switch (facetLink->facet->type) {
24257: 	    case XML_SCHEMA_FACET_LENGTH:
24258: 	    case XML_SCHEMA_FACET_MINLENGTH:
24259: 	    case XML_SCHEMA_FACET_MAXLENGTH:
24260: 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24261: 		    value, length, NULL);
24262: 		break;
24263: 	    default:
24264: 		continue;
24265: 	}
24266: 	if (ret < 0) {
24267: 	    AERROR_INT("xmlSchemaValidateFacets",
24268: 		"validating against a list type facet");
24269: 	    return (-1);
24270: 	} else if (ret > 0) {
24271: 	    if (fireErrors)
24272: 		xmlSchemaFacetErr(actxt, ret, node,
24273: 		value, length, type, facetLink->facet, NULL, NULL, NULL);
24274: 	    else
24275: 		return (ret);
24276: 	    if (error == 0)
24277: 		error = ret;
24278: 	}
24279: 	ret = 0;
24280:     }
24281: 
24282: pattern_and_enum:
24283:     if (error >= 0) {
24284: 	int found = 0;
24285: 	/*
24286: 	* Process enumerations. Facet values are in the value space
24287: 	* of the defining type's base type. This seems to be a bug in the
24288: 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
24289: 	* Only the first set of enumerations in the ancestor-or-self axis
24290: 	* is used for validation.
24291: 	*/
24292: 	ret = 0;
24293: 	tmpType = type;
24294: 	do {
24295: 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24296: 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24297: 		    continue;
24298: 		found = 1;
24299: 		ret = xmlSchemaAreValuesEqual(facet->val, val);
24300: 		if (ret == 1)
24301: 		    break;
24302: 		else if (ret < 0) {
24303: 		    AERROR_INT("xmlSchemaValidateFacets",
24304: 			"validating against an enumeration facet");
24305: 		    return (-1);
24306: 		}
24307: 	    }
24308: 	    if (ret != 0)
24309: 		break;
24310: 	    /*
24311: 	    * Break on the first set of enumerations. Any additional
24312: 	    *  enumerations which might be existent on the ancestors
24313: 	    *  of the current type are restricted by this set; thus
24314: 	    *  *must* *not* be taken into account.
24315: 	    */
24316: 	    if (found)
24317: 		break;
24318: 	    tmpType = tmpType->baseType;
24319: 	} while ((tmpType != NULL) &&
24320: 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24321: 	if (found && (ret == 0)) {
24322: 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24323: 	    if (fireErrors) {
24324: 		xmlSchemaFacetErr(actxt, ret, node,
24325: 		    value, 0, type, NULL, NULL, NULL, NULL);
24326: 	    } else
24327: 		return (ret);
24328: 	    if (error == 0)
24329: 		error = ret;
24330: 	}
24331:     }
24332: 
24333:     if (error >= 0) {
24334: 	int found;
24335: 	/*
24336: 	* Process patters. Pattern facets are ORed at type level
24337: 	* and ANDed if derived. Walk the base type axis.
24338: 	*/
24339: 	tmpType = type;
24340: 	facet = NULL;
24341: 	do {
24342: 	    found = 0;
24343: 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
24344: 		facetLink = facetLink->next) {
24345: 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24346: 		    continue;
24347: 		found = 1;
24348: 		/*
24349: 		* NOTE that for patterns, @value needs to be the
24350: 		* normalized vaule.
24351: 		*/
24352: 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
24353: 		if (ret == 1)
24354: 		    break;
24355: 		else if (ret < 0) {
24356: 		    AERROR_INT("xmlSchemaValidateFacets",
24357: 			"validating against a pattern facet");
24358: 		    return (-1);
24359: 		} else {
24360: 		    /*
24361: 		    * Save the last non-validating facet.
24362: 		    */
24363: 		    facet = facetLink->facet;
24364: 		}
24365: 	    }
24366: 	    if (found && (ret != 1)) {
24367: 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24368: 		if (fireErrors) {
24369: 		    xmlSchemaFacetErr(actxt, ret, node,
24370: 			value, 0, type, facet, NULL, NULL, NULL);
24371: 		} else
24372: 		    return (ret);
24373: 		if (error == 0)
24374: 		    error = ret;
24375: 		break;
24376: 	    }
24377: 	    tmpType = tmpType->baseType;
24378: 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24379:     }
24380: 
24381:     return (error);
24382: }
24383: 
24384: static xmlChar *
24385: xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24386: 			const xmlChar *value)
24387: {
24388:     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24389: 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
24390: 	    return (xmlSchemaCollapseString(value));
24391: 	case XML_SCHEMA_WHITESPACE_REPLACE:
24392: 	    return (xmlSchemaWhiteSpaceReplace(value));
24393: 	default:
24394: 	    return (NULL);
24395:     }
24396: }
24397: 
24398: static int
24399: xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24400: 		       const xmlChar *value,
24401: 		       xmlSchemaValPtr *val,
24402: 		       int valNeeded)
24403: {
24404:     int ret;
24405:     const xmlChar *nsName;
24406:     xmlChar *local, *prefix = NULL;
24407: 
24408:     ret = xmlValidateQName(value, 1);
24409:     if (ret != 0) {
24410: 	if (ret == -1) {
24411: 	    VERROR_INT("xmlSchemaValidateQName",
24412: 		"calling xmlValidateQName()");
24413: 	    return (-1);
24414: 	}
24415: 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24416:     }
24417:     /*
24418:     * NOTE: xmlSplitQName2 will always return a duplicated
24419:     * strings.
24420:     */
24421:     local = xmlSplitQName2(value, &prefix);
24422:     if (local == NULL)
24423: 	local = xmlStrdup(value);
24424:     /*
24425:     * OPTIMIZE TODO: Use flags for:
24426:     *  - is there any namespace binding?
24427:     *  - is there a default namespace?
24428:     */
24429:     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24430: 
24431:     if (prefix != NULL) {
24432: 	xmlFree(prefix);
24433: 	/*
24434: 	* A namespace must be found if the prefix is
24435: 	* NOT NULL.
24436: 	*/
24437: 	if (nsName == NULL) {
24438: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24439: 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24440: 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24441: 		"The QName value '%s' has no "
24442: 		"corresponding namespace declaration in "
24443: 		"scope", value, NULL);
24444: 	    if (local != NULL)
24445: 		xmlFree(local);
24446: 	    return (ret);
24447: 	}
24448:     }
24449:     if (valNeeded && val) {
24450: 	if (nsName != NULL)
24451: 	    *val = xmlSchemaNewQNameValue(
24452: 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24453: 	else
24454: 	    *val = xmlSchemaNewQNameValue(NULL,
24455: 		BAD_CAST local);
24456:     } else
24457: 	xmlFree(local);
24458:     return (0);
24459: }
24460: 
24461: /*
24462: * cvc-simple-type
24463: */
24464: static int
24465: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24466: 			     xmlNodePtr node,
24467: 			     xmlSchemaTypePtr type,
24468: 			     const xmlChar *value,
24469: 			     xmlSchemaValPtr *retVal,
24470: 			     int fireErrors,
24471: 			     int normalize,
24472: 			     int isNormalized)
24473: {
24474:     int ret = 0, valNeeded = (retVal) ? 1 : 0;
24475:     xmlSchemaValPtr val = NULL;
24476:     /* xmlSchemaWhitespaceValueType ws; */
24477:     xmlChar *normValue = NULL;
24478: 
24479: #define NORMALIZE(atype) \
24480:     if ((! isNormalized) && \
24481:     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24482: 	normValue = xmlSchemaNormalizeValue(atype, value); \
24483: 	if (normValue != NULL) \
24484: 	    value = normValue; \
24485: 	isNormalized = 1; \
24486:     }
24487: 
24488:     if ((retVal != NULL) && (*retVal != NULL)) {
24489: 	xmlSchemaFreeValue(*retVal);
24490: 	*retVal = NULL;
24491:     }
24492:     /*
24493:     * 3.14.4 Simple Type Definition Validation Rules
24494:     * Validation Rule: String Valid
24495:     */
24496:     /*
24497:     * 1 It is schema-valid with respect to that definition as defined
24498:     * by Datatype Valid in [XML Schemas: Datatypes].
24499:     */
24500:     /*
24501:     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24502:     * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
24503:     * the string must be a �declared entity name�.
24504:     */
24505:     /*
24506:     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24507:     * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
24508:     * then every whitespace-delimited substring of the string must be a �declared
24509:     * entity name�.
24510:     */
24511:     /*
24512:     * 2.3 otherwise no further condition applies.
24513:     */
24514:     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24515: 	valNeeded = 1;
24516:     if (value == NULL)
24517: 	value = BAD_CAST "";
24518:     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24519: 	xmlSchemaTypePtr biType; /* The built-in type. */
24520: 	/*
24521: 	* SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
24522: 	* a literal in the �lexical space� of {base type definition}"
24523: 	*/
24524: 	/*
24525: 	* Whitespace-normalize.
24526: 	*/
24527: 	NORMALIZE(type);
24528: 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
24529: 	    /*
24530: 	    * Get the built-in type.
24531: 	    */
24532: 	    biType = type->baseType;
24533: 	    while ((biType != NULL) &&
24534: 		(biType->type != XML_SCHEMA_TYPE_BASIC))
24535: 		biType = biType->baseType;
24536: 
24537: 	    if (biType == NULL) {
24538: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24539: 		    "could not get the built-in type");
24540: 		goto internal_error;
24541: 	    }
24542: 	} else
24543: 	    biType = type;
24544: 	/*
24545: 	* NOTATIONs need to be processed here, since they need
24546: 	* to lookup in the hashtable of NOTATION declarations of the schema.
24547: 	*/
24548: 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24549: 	    switch (biType->builtInType) {
24550: 		case XML_SCHEMAS_NOTATION:
24551: 		    ret = xmlSchemaValidateNotation(
24552: 			(xmlSchemaValidCtxtPtr) actxt,
24553: 			((xmlSchemaValidCtxtPtr) actxt)->schema,
24554: 			NULL, value, &val, valNeeded);
24555: 		    break;
24556: 		case XML_SCHEMAS_QNAME:
24557: 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24558: 			value, &val, valNeeded);
24559: 		    break;
24560: 		default:
24561: 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24562: 		    if (valNeeded)
24563: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24564: 			    value, &val, node);
24565: 		    else
24566: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24567: 			    value, NULL, node);
24568: 		    break;
24569: 	    }
24570: 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24571: 	    switch (biType->builtInType) {
24572: 		case XML_SCHEMAS_NOTATION:
24573: 		    ret = xmlSchemaValidateNotation(NULL,
24574: 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24575: 			value, &val, valNeeded);
24576: 		    break;
24577: 		default:
24578: 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24579: 		    if (valNeeded)
24580: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24581: 			    value, &val, node);
24582: 		    else
24583: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24584: 			    value, NULL, node);
24585: 		    break;
24586: 	    }
24587: 	} else {
24588: 	    /*
24589: 	    * Validation via a public API is not implemented yet.
24590: 	    */
24591: 	    TODO
24592: 	    goto internal_error;
24593: 	}
24594: 	if (ret != 0) {
24595: 	    if (ret < 0) {
24596: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24597: 		    "validating against a built-in type");
24598: 		goto internal_error;
24599: 	    }
24600: 	    if (WXS_IS_LIST(type))
24601: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24602: 	    else
24603: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24604: 	}
24605: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24606: 	    /*
24607: 	    * Check facets.
24608: 	    */
24609: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24610: 		(xmlSchemaValType) biType->builtInType, value, val,
24611: 		0, fireErrors);
24612: 	    if (ret != 0) {
24613: 		if (ret < 0) {
24614: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24615: 			"validating facets of atomic simple type");
24616: 		    goto internal_error;
24617: 		}
24618: 		if (WXS_IS_LIST(type))
24619: 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24620: 		else
24621: 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24622: 	    }
24623: 	}
24624: 	if (fireErrors && (ret > 0))
24625: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24626:     } else if (WXS_IS_LIST(type)) {
24627: 
24628: 	xmlSchemaTypePtr itemType;
24629: 	const xmlChar *cur, *end;
24630: 	xmlChar *tmpValue = NULL;
24631: 	unsigned long len = 0;
24632: 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24633: 	/* 1.2.2 if {variety} is �list� then the string must be a sequence
24634: 	* of white space separated tokens, each of which �match�es a literal
24635: 	* in the �lexical space� of {item type definition}
24636: 	*/
24637: 	/*
24638: 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24639: 	* the list type has an enum or pattern facet.
24640: 	*/
24641: 	NORMALIZE(type);
24642: 	/*
24643: 	* VAL TODO: Optimize validation of empty values.
24644: 	* VAL TODO: We do not have computed values for lists.
24645: 	*/
24646: 	itemType = WXS_LIST_ITEMTYPE(type);
24647: 	cur = value;
24648: 	do {
24649: 	    while (IS_BLANK_CH(*cur))
24650: 		cur++;
24651: 	    end = cur;
24652: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24653: 		end++;
24654: 	    if (end == cur)
24655: 		break;
24656: 	    tmpValue = xmlStrndup(cur, end - cur);
24657: 	    len++;
24658: 
24659: 	    if (valNeeded)
24660: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24661: 		    tmpValue, &curVal, fireErrors, 0, 1);
24662: 	    else
24663: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24664: 		    tmpValue, NULL, fireErrors, 0, 1);
24665: 	    FREE_AND_NULL(tmpValue);
24666: 	    if (curVal != NULL) {
24667: 		/*
24668: 		* Add to list of computed values.
24669: 		*/
24670: 		if (val == NULL)
24671: 		    val = curVal;
24672: 		else
24673: 		    xmlSchemaValueAppend(prevVal, curVal);
24674: 		prevVal = curVal;
24675: 		curVal = NULL;
24676: 	    }
24677: 	    if (ret != 0) {
24678: 		if (ret < 0) {
24679: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24680: 			"validating an item of list simple type");
24681: 		    goto internal_error;
24682: 		}
24683: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24684: 		break;
24685: 	    }
24686: 	    cur = end;
24687: 	} while (*cur != 0);
24688: 	FREE_AND_NULL(tmpValue);
24689: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24690: 	    /*
24691: 	    * Apply facets (pattern, enumeration).
24692: 	    */
24693: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24694: 		XML_SCHEMAS_UNKNOWN, value, val,
24695: 		len, fireErrors);
24696: 	    if (ret != 0) {
24697: 		if (ret < 0) {
24698: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24699: 			"validating facets of list simple type");
24700: 		    goto internal_error;
24701: 		}
24702: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24703: 	    }
24704: 	}
24705: 	if (fireErrors && (ret > 0)) {
24706: 	    /*
24707: 	    * Report the normalized value.
24708: 	    */
24709: 	    normalize = 1;
24710: 	    NORMALIZE(type);
24711: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24712: 	}
24713:     } else if (WXS_IS_UNION(type)) {
24714: 	xmlSchemaTypeLinkPtr memberLink;
24715: 	/*
24716: 	* TODO: For all datatypes �derived� by �union�  whiteSpace does
24717: 	* not apply directly; however, the normalization behavior of �union�
24718: 	* types is controlled by the value of whiteSpace on that one of the
24719: 	* �memberTypes� against which the �union� is successfully validated.
24720: 	*
24721: 	* This means that the value is normalized by the first validating
24722: 	* member type, then the facets of the union type are applied. This
24723: 	* needs changing of the value!
24724: 	*/
24725: 
24726: 	/*
24727: 	* 1.2.3 if {variety} is �union� then the string must �match� a
24728: 	* literal in the �lexical space� of at least one member of
24729: 	* {member type definitions}
24730: 	*/
24731: 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24732: 	if (memberLink == NULL) {
24733: 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24734: 		"union simple type has no member types");
24735: 	    goto internal_error;
24736: 	}
24737: 	/*
24738: 	* Always normalize union type values, since we currently
24739: 	* cannot store the whitespace information with the value
24740: 	* itself; otherwise a later value-comparison would be
24741: 	* not possible.
24742: 	*/
24743: 	while (memberLink != NULL) {
24744: 	    if (valNeeded)
24745: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24746: 		    memberLink->type, value, &val, 0, 1, 0);
24747: 	    else
24748: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24749: 		    memberLink->type, value, NULL, 0, 1, 0);
24750: 	    if (ret <= 0)
24751: 		break;
24752: 	    memberLink = memberLink->next;
24753: 	}
24754: 	if (ret != 0) {
24755: 	    if (ret < 0) {
24756: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24757: 		    "validating members of union simple type");
24758: 		goto internal_error;
24759: 	    }
24760: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24761: 	}
24762: 	/*
24763: 	* Apply facets (pattern, enumeration).
24764: 	*/
24765: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24766: 	    /*
24767: 	    * The normalization behavior of �union� types is controlled by
24768: 	    * the value of whiteSpace on that one of the �memberTypes�
24769: 	    * against which the �union� is successfully validated.
24770: 	    */
24771: 	    NORMALIZE(memberLink->type);
24772: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24773: 		XML_SCHEMAS_UNKNOWN, value, val,
24774: 		0, fireErrors);
24775: 	    if (ret != 0) {
24776: 		if (ret < 0) {
24777: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24778: 			"validating facets of union simple type");
24779: 		    goto internal_error;
24780: 		}
24781: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24782: 	    }
24783: 	}
24784: 	if (fireErrors && (ret > 0))
24785: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24786:     }
24787: 
24788:     if (normValue != NULL)
24789: 	xmlFree(normValue);
24790:     if (ret == 0) {
24791: 	if (retVal != NULL)
24792: 	    *retVal = val;
24793: 	else if (val != NULL)
24794: 	    xmlSchemaFreeValue(val);
24795:     } else if (val != NULL)
24796: 	xmlSchemaFreeValue(val);
24797:     return (ret);
24798: internal_error:
24799:     if (normValue != NULL)
24800: 	xmlFree(normValue);
24801:     if (val != NULL)
24802: 	xmlSchemaFreeValue(val);
24803:     return (-1);
24804: }
24805: 
24806: static int
24807: xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24808: 			   const xmlChar *value,
24809: 			   const xmlChar **nsName,
24810: 			   const xmlChar **localName)
24811: {
24812:     int ret = 0;
24813: 
24814:     if ((nsName == NULL) || (localName == NULL))
24815: 	return (-1);
24816:     *nsName = NULL;
24817:     *localName = NULL;
24818: 
24819:     ret = xmlValidateQName(value, 1);
24820:     if (ret == -1)
24821: 	return (-1);
24822:     if (ret > 0) {
24823: 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24824: 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24825: 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24826: 	return (1);
24827:     }
24828:     {
24829: 	xmlChar *local = NULL;
24830: 	xmlChar *prefix;
24831: 
24832: 	/*
24833: 	* NOTE: xmlSplitQName2 will return a duplicated
24834: 	* string.
24835: 	*/
24836: 	local = xmlSplitQName2(value, &prefix);
24837: 	if (local == NULL)
24838: 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
24839: 	else {
24840: 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
24841: 	    xmlFree(local);
24842: 	}
24843: 
24844: 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24845: 
24846: 	if (prefix != NULL) {
24847: 	    xmlFree(prefix);
24848: 	    /*
24849: 	    * A namespace must be found if the prefix is NOT NULL.
24850: 	    */
24851: 	    if (*nsName == NULL) {
24852: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
24853: 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24854: 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24855: 		    "The QName value '%s' has no "
24856: 		    "corresponding namespace declaration in scope",
24857: 		    value, NULL);
24858: 		return (2);
24859: 	    }
24860: 	}
24861:     }
24862:     return (0);
24863: }
24864: 
24865: static int
24866: xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24867: 			xmlSchemaAttrInfoPtr iattr,
24868: 			xmlSchemaTypePtr *localType,
24869: 			xmlSchemaElementPtr elemDecl)
24870: {
24871:     int ret = 0;
24872:     /*
24873:     * cvc-elt (3.3.4) : (4)
24874:     * AND
24875:     * Schema-Validity Assessment (Element) (cvc-assess-elt)
24876:     *   (1.2.1.2.1) - (1.2.1.2.4)
24877:     * Handle 'xsi:type'.
24878:     */
24879:     if (localType == NULL)
24880: 	return (-1);
24881:     *localType = NULL;
24882:     if (iattr == NULL)
24883: 	return (0);
24884:     else {
24885: 	const xmlChar *nsName = NULL, *local = NULL;
24886: 	/*
24887: 	* TODO: We should report a *warning* that the type was overriden
24888: 	* by the instance.
24889: 	*/
24890: 	ACTIVATE_ATTRIBUTE(iattr);
24891: 	/*
24892: 	* (cvc-elt) (3.3.4) : (4.1)
24893: 	* (cvc-assess-elt) (1.2.1.2.2)
24894: 	*/
24895: 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24896: 	    &nsName, &local);
24897: 	if (ret != 0) {
24898: 	    if (ret < 0) {
24899: 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
24900: 		    "calling xmlSchemaQNameExpand() to validate the "
24901: 		    "attribute 'xsi:type'");
24902: 		goto internal_error;
24903: 	    }
24904: 	    goto exit;
24905: 	}
24906: 	/*
24907: 	* (cvc-elt) (3.3.4) : (4.2)
24908: 	* (cvc-assess-elt) (1.2.1.2.3)
24909: 	*/
24910: 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24911: 	if (*localType == NULL) {
24912: 	    xmlChar *str = NULL;
24913: 
24914: 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24915: 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
24916: 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24917: 		"The QName value '%s' of the xsi:type attribute does not "
24918: 		"resolve to a type definition",
24919: 		xmlSchemaFormatQName(&str, nsName, local), NULL);
24920: 	    FREE_AND_NULL(str);
24921: 	    ret = vctxt->err;
24922: 	    goto exit;
24923: 	}
24924: 	if (elemDecl != NULL) {
24925: 	    int set = 0;
24926: 
24927: 	    /*
24928: 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24929: 	    * "The �local type definition� must be validly
24930: 	    * derived from the {type definition} given the union of
24931: 	    * the {disallowed substitutions} and the {type definition}'s
24932: 	    * {prohibited substitutions}, as defined in
24933: 	    * Type Derivation OK (Complex) (�3.4.6)
24934: 	    * (if it is a complex type definition),
24935: 	    * or given {disallowed substitutions} as defined in Type
24936: 	    * Derivation OK (Simple) (�3.14.6) (if it is a simple type
24937: 	    * definition)."
24938: 	    *
24939: 	    * {disallowed substitutions}: the "block" on the element decl.
24940: 	    * {prohibited substitutions}: the "block" on the type def.
24941: 	    */
24942: 	    /*
24943: 	    * OPTIMIZE TODO: We could map types already evaluated
24944: 	    * to be validly derived from other types to avoid checking
24945: 	    * this over and over for the same types.
24946: 	    */
24947: 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24948: 		(elemDecl->subtypes->flags &
24949: 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24950: 		set |= SUBSET_EXTENSION;
24951: 
24952: 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24953: 		(elemDecl->subtypes->flags &
24954: 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24955: 		set |= SUBSET_RESTRICTION;
24956: 
24957: 	    /*
24958: 	    * REMOVED and CHANGED since this produced a parser context
24959: 	    * which adds to the string dict of the schema. So this would
24960: 	    * change the schema and we don't want this. We don't need
24961: 	    * the parser context anymore.
24962: 	    *
24963: 	    * if ((vctxt->pctxt == NULL) &&
24964: 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24965: 	    *	    return (-1);
24966: 	    */
24967: 
24968: 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24969: 		elemDecl->subtypes, set) != 0) {
24970: 		xmlChar *str = NULL;
24971: 
24972: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
24973: 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24974: 		    "The type definition '%s', specified by xsi:type, is "
24975: 		    "blocked or not validly derived from the type definition "
24976: 		    "of the element declaration",
24977: 		    xmlSchemaFormatQName(&str,
24978: 			(*localType)->targetNamespace,
24979: 			(*localType)->name),
24980: 		    NULL);
24981: 		FREE_AND_NULL(str);
24982: 		ret = vctxt->err;
24983: 		*localType = NULL;
24984: 	    }
24985: 	}
24986:     }
24987: exit:
24988:     ACTIVATE_ELEM;
24989:     return (ret);
24990: internal_error:
24991:     ACTIVATE_ELEM;
24992:     return (-1);
24993: }
24994: 
24995: static int
24996: xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24997: {
24998:     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24999:     xmlSchemaTypePtr actualType;
25000: 
25001:     /*
25002:     * cvc-elt (3.3.4) : 1
25003:     */
25004:     if (elemDecl == NULL) {
25005: 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
25006: 	    "No matching declaration available");
25007:         return (vctxt->err);
25008:     }
25009:     actualType = WXS_ELEM_TYPEDEF(elemDecl);
25010:     /*
25011:     * cvc-elt (3.3.4) : 2
25012:     */
25013:     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
25014: 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
25015: 	    "The element declaration is abstract");
25016:         return (vctxt->err);
25017:     }
25018:     if (actualType == NULL) {
25019: 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25020: 	    "The type definition is absent");
25021: 	return (XML_SCHEMAV_CVC_TYPE_1);
25022:     }
25023:     if (vctxt->nbAttrInfos != 0) {
25024: 	int ret;
25025: 	xmlSchemaAttrInfoPtr iattr;
25026: 	/*
25027: 	* cvc-elt (3.3.4) : 3
25028: 	* Handle 'xsi:nil'.
25029: 	*/
25030: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25031: 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25032: 	if (iattr) {
25033: 	    ACTIVATE_ATTRIBUTE(iattr);
25034: 	    /*
25035: 	    * Validate the value.
25036: 	    */
25037: 	    ret = xmlSchemaVCheckCVCSimpleType(
25038: 		ACTXT_CAST vctxt, NULL,
25039: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25040: 		iattr->value, &(iattr->val), 1, 0, 0);
25041: 	    ACTIVATE_ELEM;
25042: 	    if (ret < 0) {
25043: 		VERROR_INT("xmlSchemaValidateElemDecl",
25044: 		    "calling xmlSchemaVCheckCVCSimpleType() to "
25045: 		    "validate the attribute 'xsi:nil'");
25046: 		return (-1);
25047: 	    }
25048: 	    if (ret == 0) {
25049: 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25050: 		    /*
25051: 		    * cvc-elt (3.3.4) : 3.1
25052: 		    */
25053: 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25054: 			"The element is not 'nillable'");
25055: 		    /* Does not return an error on purpose. */
25056: 		} else {
25057: 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25058: 			/*
25059: 			* cvc-elt (3.3.4) : 3.2.2
25060: 			*/
25061: 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25062: 			    (elemDecl->value != NULL)) {
25063: 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25064: 				"The element cannot be 'nilled' because "
25065: 				"there is a fixed value constraint defined "
25066: 				"for it");
25067: 			     /* Does not return an error on purpose. */
25068: 			} else
25069: 			    vctxt->inode->flags |=
25070: 				XML_SCHEMA_ELEM_INFO_NILLED;
25071: 		    }
25072: 		}
25073: 	    }
25074: 	}
25075: 	/*
25076: 	* cvc-elt (3.3.4) : 4
25077: 	* Handle 'xsi:type'.
25078: 	*/
25079: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25080: 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25081: 	if (iattr) {
25082: 	    xmlSchemaTypePtr localType = NULL;
25083: 
25084: 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25085: 		elemDecl);
25086: 	    if (ret != 0) {
25087: 		if (ret == -1) {
25088: 		    VERROR_INT("xmlSchemaValidateElemDecl",
25089: 			"calling xmlSchemaProcessXSIType() to "
25090: 			"process the attribute 'xsi:type'");
25091: 		    return (-1);
25092: 		}
25093: 		/* Does not return an error on purpose. */
25094: 	    }
25095: 	    if (localType != NULL) {
25096: 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25097: 		actualType = localType;
25098: 	    }
25099: 	}
25100:     }
25101:     /*
25102:     * IDC: Register identity-constraint XPath matchers.
25103:     */
25104:     if ((elemDecl->idcs != NULL) &&
25105: 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25106: 	    return (-1);
25107:     /*
25108:     * No actual type definition.
25109:     */
25110:     if (actualType == NULL) {
25111: 	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25112: 	    "The type definition is absent");
25113: 	return (XML_SCHEMAV_CVC_TYPE_1);
25114:     }
25115:     /*
25116:     * Remember the actual type definition.
25117:     */
25118:     vctxt->inode->typeDef = actualType;
25119: 
25120:     return (0);
25121: }
25122: 
25123: static int
25124: xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25125: {
25126:     xmlSchemaAttrInfoPtr iattr;
25127:     int ret = 0, i;
25128: 
25129:     /*
25130:     * SPEC cvc-type (3.1.1)
25131:     * "The attributes of must be empty, excepting those whose namespace
25132:     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25133:     * whose local name is one of type, nil, schemaLocation or
25134:     * noNamespaceSchemaLocation."
25135:     */
25136:     if (vctxt->nbAttrInfos == 0)
25137: 	return (0);
25138:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25139: 	iattr = vctxt->attrInfos[i];
25140: 	if (! iattr->metaType) {
25141: 	    ACTIVATE_ATTRIBUTE(iattr)
25142: 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25143: 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25144: 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25145:         }
25146:     }
25147:     ACTIVATE_ELEM
25148:     return (ret);
25149: }
25150: 
25151: /*
25152: * Cleanup currently used attribute infos.
25153: */
25154: static void
25155: xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25156: {
25157:     int i;
25158:     xmlSchemaAttrInfoPtr attr;
25159: 
25160:     if (vctxt->nbAttrInfos == 0)
25161: 	return;
25162:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25163: 	attr = vctxt->attrInfos[i];
25164: 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25165: 	    if (attr->localName != NULL)
25166: 		xmlFree((xmlChar *) attr->localName);
25167: 	    if (attr->nsName != NULL)
25168: 		xmlFree((xmlChar *) attr->nsName);
25169: 	}
25170: 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25171: 	    if (attr->value != NULL)
25172: 		xmlFree((xmlChar *) attr->value);
25173: 	}
25174: 	if (attr->val != NULL) {
25175: 	    xmlSchemaFreeValue(attr->val);
25176: 	    attr->val = NULL;
25177: 	}
25178: 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25179:     }
25180:     vctxt->nbAttrInfos = 0;
25181: }
25182: 
25183: /*
25184: * 3.4.4 Complex Type Definition Validation Rules
25185: *   Element Locally Valid (Complex Type) (cvc-complex-type)
25186: * 3.2.4 Attribute Declaration Validation Rules
25187: *   Validation Rule: Attribute Locally Valid (cvc-attribute)
25188: *   Attribute Locally Valid (Use) (cvc-au)
25189: *
25190: * Only "assessed" attribute information items will be visible to
25191: * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25192: */
25193: static int
25194: xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25195: {
25196:     xmlSchemaTypePtr type = vctxt->inode->typeDef;
25197:     xmlSchemaItemListPtr attrUseList;
25198:     xmlSchemaAttributeUsePtr attrUse = NULL;
25199:     xmlSchemaAttributePtr attrDecl = NULL;
25200:     xmlSchemaAttrInfoPtr iattr, tmpiattr;
25201:     int i, j, found, nbAttrs, nbUses;
25202:     int xpathRes = 0, res, wildIDs = 0, fixed;
25203:     xmlNodePtr defAttrOwnerElem = NULL;
25204: 
25205:     /*
25206:     * SPEC (cvc-attribute)
25207:     * (1) "The declaration must not be �absent� (see Missing
25208:     * Sub-components (�5.3) for how this can fail to be
25209:     * the case)."
25210:     * (2) "Its {type definition} must not be absent."
25211:     *
25212:     * NOTE (1) + (2): This is not handled here, since we currently do not
25213:     * allow validation against schemas which have missing sub-components.
25214:     *
25215:     * SPEC (cvc-complex-type)
25216:     * (3) "For each attribute information item in the element information
25217:     * item's [attributes] excepting those whose [namespace name] is
25218:     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25219:     * [local name] is one of type, nil, schemaLocation or
25220:     * noNamespaceSchemaLocation, the appropriate case among the following
25221:     * must be true:
25222:     *
25223:     */
25224:     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25225:     /*
25226:     * @nbAttrs is the number of attributes present in the instance.
25227:     */
25228:     nbAttrs = vctxt->nbAttrInfos;
25229:     if (attrUseList != NULL)
25230: 	nbUses = attrUseList->nbItems;
25231:     else
25232: 	nbUses = 0;
25233:     for (i = 0; i < nbUses; i++) {
25234:         found = 0;
25235: 	attrUse = attrUseList->items[i];
25236: 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
25237:         for (j = 0; j < nbAttrs; j++) {
25238: 	    iattr = vctxt->attrInfos[j];
25239: 	    /*
25240: 	    * SPEC (cvc-complex-type) (3)
25241: 	    * Skip meta attributes.
25242: 	    */
25243: 	    if (iattr->metaType)
25244: 		continue;
25245: 	    if (iattr->localName[0] != attrDecl->name[0])
25246: 		continue;
25247: 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
25248: 		continue;
25249: 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25250: 		continue;
25251: 	    found = 1;
25252: 	    /*
25253: 	    * SPEC (cvc-complex-type)
25254: 	    * (3.1) "If there is among the {attribute uses} an attribute
25255: 	    * use with an {attribute declaration} whose {name} matches
25256: 	    * the attribute information item's [local name] and whose
25257: 	    * {target namespace} is identical to the attribute information
25258: 	    * item's [namespace name] (where an �absent� {target namespace}
25259: 	    * is taken to be identical to a [namespace name] with no value),
25260: 	    * then the attribute information must be �valid� with respect
25261: 	    * to that attribute use as per Attribute Locally Valid (Use)
25262: 	    * (�3.5.4). In this case the {attribute declaration} of that
25263: 	    * attribute use is the �context-determined declaration� for the
25264: 	    * attribute information item with respect to Schema-Validity
25265: 	    * Assessment (Attribute) (�3.2.4) and
25266: 	    * Assessment Outcome (Attribute) (�3.2.5).
25267: 	    */
25268: 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25269: 	    iattr->use = attrUse;
25270: 	    /*
25271: 	    * Context-determined declaration.
25272: 	    */
25273: 	    iattr->decl = attrDecl;
25274: 	    iattr->typeDef = attrDecl->subtypes;
25275: 	    break;
25276: 	}
25277: 
25278: 	if (found)
25279: 	    continue;
25280: 
25281: 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25282: 	    /*
25283: 	    * Handle non-existent, required attributes.
25284: 	    *
25285: 	    * SPEC (cvc-complex-type)
25286: 	    * (4) "The {attribute declaration} of each attribute use in
25287: 	    * the {attribute uses} whose {required} is true matches one
25288: 	    * of the attribute information items in the element information
25289: 	    * item's [attributes] as per clause 3.1 above."
25290: 	    */
25291: 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25292: 	    if (tmpiattr == NULL) {
25293: 		VERROR_INT(
25294: 		    "xmlSchemaVAttributesComplex",
25295: 		    "calling xmlSchemaGetFreshAttrInfo()");
25296: 		return (-1);
25297: 	    }
25298: 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25299: 	    tmpiattr->use = attrUse;
25300: 	    tmpiattr->decl = attrDecl;
25301: 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25302: 	    ((attrUse->defValue != NULL) ||
25303: 	     (attrDecl->defValue != NULL))) {
25304: 	    /*
25305: 	    * Handle non-existent, optional, default/fixed attributes.
25306: 	    */
25307: 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25308: 	    if (tmpiattr == NULL) {
25309: 		VERROR_INT(
25310: 		    "xmlSchemaVAttributesComplex",
25311: 		    "calling xmlSchemaGetFreshAttrInfo()");
25312: 		return (-1);
25313: 	    }
25314: 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25315: 	    tmpiattr->use = attrUse;
25316: 	    tmpiattr->decl = attrDecl;
25317: 	    tmpiattr->typeDef = attrDecl->subtypes;
25318: 	    tmpiattr->localName = attrDecl->name;
25319: 	    tmpiattr->nsName = attrDecl->targetNamespace;
25320: 	}
25321:     }
25322: 
25323:     if (vctxt->nbAttrInfos == 0)
25324: 	return (0);
25325:     /*
25326:     * Validate against the wildcard.
25327:     */
25328:     if (type->attributeWildcard != NULL) {
25329: 	/*
25330: 	* SPEC (cvc-complex-type)
25331: 	* (3.2.1) "There must be an {attribute wildcard}."
25332: 	*/
25333: 	for (i = 0; i < nbAttrs; i++) {
25334: 	    iattr = vctxt->attrInfos[i];
25335: 	    /*
25336: 	    * SPEC (cvc-complex-type) (3)
25337: 	    * Skip meta attributes.
25338: 	    */
25339: 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25340: 		continue;
25341: 	    /*
25342: 	    * SPEC (cvc-complex-type)
25343: 	    * (3.2.2) "The attribute information item must be �valid� with
25344: 	    * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
25345: 	    *
25346: 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
25347: 	    * "... its [namespace name] must be �valid� with respect to
25348: 	    * the wildcard constraint, as defined in Wildcard allows
25349: 	    * Namespace Name (�3.10.4)."
25350: 	    */
25351: 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25352: 		    iattr->nsName) == 0) {
25353: 		/*
25354: 		* Handle processContents.
25355: 		*
25356: 		* SPEC (cvc-wildcard):
25357: 		* processContents | context-determined declaration:
25358: 		* "strict"          "mustFind"
25359: 		* "lax"             "none"
25360: 		* "skip"            "skip"
25361: 		*/
25362: 		if (type->attributeWildcard->processContents ==
25363: 		    XML_SCHEMAS_ANY_SKIP) {
25364: 		     /*
25365: 		    * context-determined declaration = "skip"
25366: 		    *
25367: 		    * SPEC PSVI Assessment Outcome (Attribute)
25368: 		    * [validity] = "notKnown"
25369: 		    * [validation attempted] = "none"
25370: 		    */
25371: 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25372: 		    continue;
25373: 		}
25374: 		/*
25375: 		* Find an attribute declaration.
25376: 		*/
25377: 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25378: 		    iattr->localName, iattr->nsName);
25379: 		if (iattr->decl != NULL) {
25380: 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25381: 		    /*
25382: 		    * SPEC (cvc-complex-type)
25383: 		    * (5) "Let [Definition:]  the wild IDs be the set of
25384: 		    * all attribute information item to which clause 3.2
25385: 		    * applied and whose �validation� resulted in a
25386: 		    * �context-determined declaration� of mustFind or no
25387: 		    * �context-determined declaration� at all, and whose
25388: 		    * [local name] and [namespace name] resolve (as
25389: 		    * defined by QName resolution (Instance) (�3.15.4)) to
25390: 		    * an attribute declaration whose {type definition} is
25391: 		    * or is derived from ID. Then all of the following
25392: 		    * must be true:"
25393: 		    */
25394: 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25395: 		    if (xmlSchemaIsDerivedFromBuiltInType(
25396: 			iattr->typeDef, XML_SCHEMAS_ID)) {
25397: 			/*
25398: 			* SPEC (5.1) "There must be no more than one
25399: 			* item in �wild IDs�."
25400: 			*/
25401: 			if (wildIDs != 0) {
25402: 			    /* VAL TODO */
25403: 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25404: 			    TODO
25405: 			    continue;
25406: 			}
25407: 			wildIDs++;
25408: 			/*
25409: 			* SPEC (cvc-complex-type)
25410: 			* (5.2) "If �wild IDs� is non-empty, there must not
25411: 			* be any attribute uses among the {attribute uses}
25412: 			* whose {attribute declaration}'s {type definition}
25413: 			* is or is derived from ID."
25414: 			*/
25415:                         if (attrUseList != NULL) {
25416:                             for (j = 0; j < attrUseList->nbItems; j++) {
25417:                                 if (xmlSchemaIsDerivedFromBuiltInType(
25418:                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25419:                                     XML_SCHEMAS_ID)) {
25420:                                     /* URGENT VAL TODO: implement */
25421:                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25422:                                     TODO
25423:                                     break;
25424:                                 }
25425:                             }
25426:                         }
25427: 		    }
25428: 		} else if (type->attributeWildcard->processContents ==
25429: 		    XML_SCHEMAS_ANY_LAX) {
25430: 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25431: 		    /*
25432: 		    * SPEC PSVI Assessment Outcome (Attribute)
25433: 		    * [validity] = "notKnown"
25434: 		    * [validation attempted] = "none"
25435: 		    */
25436: 		} else {
25437: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25438: 		}
25439: 	    }
25440: 	}
25441:     }
25442: 
25443:     if (vctxt->nbAttrInfos == 0)
25444: 	return (0);
25445: 
25446:     /*
25447:     * Get the owner element; needed for creation of default attributes.
25448:     * This fixes bug #341337, reported by David Grohmann.
25449:     */
25450:     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25451: 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25452: 	if (ielem && ielem->node && ielem->node->doc)
25453: 	    defAttrOwnerElem = ielem->node;
25454:     }
25455:     /*
25456:     * Validate values, create default attributes, evaluate IDCs.
25457:     */
25458:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25459: 	iattr = vctxt->attrInfos[i];
25460: 	/*
25461: 	* VAL TODO: Note that we won't try to resolve IDCs to
25462: 	* "lax" and "skip" validated attributes. Check what to
25463: 	* do in this case.
25464: 	*/
25465: 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25466: 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25467: 	    continue;
25468: 	/*
25469: 	* VAL TODO: What to do if the type definition is missing?
25470: 	*/
25471: 	if (iattr->typeDef == NULL) {
25472: 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25473: 	    continue;
25474: 	}
25475: 
25476: 	ACTIVATE_ATTRIBUTE(iattr);
25477: 	fixed = 0;
25478: 	xpathRes = 0;
25479: 
25480: 	if (vctxt->xpathStates != NULL) {
25481: 	    /*
25482: 	    * Evaluate IDCs.
25483: 	    */
25484: 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
25485: 		XML_ATTRIBUTE_NODE);
25486: 	    if (xpathRes == -1) {
25487: 		VERROR_INT("xmlSchemaVAttributesComplex",
25488: 		    "calling xmlSchemaXPathEvaluate()");
25489: 		goto internal_error;
25490: 	    }
25491: 	}
25492: 
25493: 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25494: 	    /*
25495: 	    * Default/fixed attributes.
25496: 	    * We need the value only if we need to resolve IDCs or
25497: 	    * will create default attributes.
25498: 	    */
25499: 	    if ((xpathRes) || (defAttrOwnerElem)) {
25500: 		if (iattr->use->defValue != NULL) {
25501: 		    iattr->value = (xmlChar *) iattr->use->defValue;
25502: 		    iattr->val = iattr->use->defVal;
25503: 		} else {
25504: 		    iattr->value = (xmlChar *) iattr->decl->defValue;
25505: 		    iattr->val = iattr->decl->defVal;
25506: 		}
25507: 		/*
25508: 		* IDCs will consume the precomputed default value,
25509: 		* so we need to clone it.
25510: 		*/
25511: 		if (iattr->val == NULL) {
25512: 		    VERROR_INT("xmlSchemaVAttributesComplex",
25513: 			"default/fixed value on an attribute use was "
25514: 			"not precomputed");
25515: 		    goto internal_error;
25516: 		}
25517: 		iattr->val = xmlSchemaCopyValue(iattr->val);
25518: 		if (iattr->val == NULL) {
25519: 		    VERROR_INT("xmlSchemaVAttributesComplex",
25520: 			"calling xmlSchemaCopyValue()");
25521: 		    goto internal_error;
25522: 		}
25523: 	    }
25524: 	    /*
25525: 	    * PSVI: Add the default attribute to the current element.
25526: 	    * VAL TODO: Should we use the *normalized* value? This currently
25527: 	    *   uses the *initial* value.
25528: 	    */
25529: 
25530: 	    if (defAttrOwnerElem) {
25531: 		xmlChar *normValue;
25532: 		const xmlChar *value;
25533: 
25534: 		value = iattr->value;
25535: 		/*
25536: 		* Normalize the value.
25537: 		*/
25538: 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25539: 		    iattr->value);
25540: 		if (normValue != NULL)
25541: 		    value = BAD_CAST normValue;
25542: 
25543: 		if (iattr->nsName == NULL) {
25544: 		    if (xmlNewProp(defAttrOwnerElem,
25545: 			iattr->localName, value) == NULL) {
25546: 			VERROR_INT("xmlSchemaVAttributesComplex",
25547: 			    "callling xmlNewProp()");
25548: 			if (normValue != NULL)
25549: 			    xmlFree(normValue);
25550: 			goto internal_error;
25551: 		    }
25552: 		} else {
25553: 		    xmlNsPtr ns;
25554: 
25555: 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25556: 			defAttrOwnerElem, iattr->nsName);
25557: 		    if (ns == NULL) {
25558: 			xmlChar prefix[12];
25559: 			int counter = 0;
25560: 
25561: 			/*
25562: 			* Create a namespace declaration on the validation
25563: 			* root node if no namespace declaration is in scope.
25564: 			*/
25565: 			do {
25566: 			    snprintf((char *) prefix, 12, "p%d", counter++);
25567: 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
25568: 				defAttrOwnerElem, BAD_CAST prefix);
25569: 			    if (counter > 1000) {
25570: 				VERROR_INT(
25571: 				    "xmlSchemaVAttributesComplex",
25572: 				    "could not compute a ns prefix for a "
25573: 				    "default/fixed attribute");
25574: 				if (normValue != NULL)
25575: 				    xmlFree(normValue);
25576: 				goto internal_error;
25577: 			    }
25578: 			} while (ns != NULL);
25579: 			ns = xmlNewNs(vctxt->validationRoot,
25580: 			    iattr->nsName, BAD_CAST prefix);
25581: 		    }
25582: 		    /*
25583: 		    * TODO:
25584: 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25585: 		    * If we have QNames: do we need to ensure there's a
25586: 		    * prefix defined for the QName?
25587: 		    */
25588: 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25589: 		}
25590: 		if (normValue != NULL)
25591: 		    xmlFree(normValue);
25592: 	    }
25593: 	    /*
25594: 	    * Go directly to IDC evaluation.
25595: 	    */
25596: 	    goto eval_idcs;
25597: 	}
25598: 	/*
25599: 	* Validate the value.
25600: 	*/
25601: 	if (vctxt->value != NULL) {
25602: 	    /*
25603: 	    * Free last computed value; just for safety reasons.
25604: 	    */
25605: 	    xmlSchemaFreeValue(vctxt->value);
25606: 	    vctxt->value = NULL;
25607: 	}
25608: 	/*
25609: 	* Note that the attribute *use* can be unavailable, if
25610: 	* the attribute was a wild attribute.
25611: 	*/
25612: 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25613: 	    ((iattr->use != NULL) &&
25614: 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25615: 	    fixed = 1;
25616: 	else
25617: 	    fixed = 0;
25618: 	/*
25619: 	* SPEC (cvc-attribute)
25620: 	* (3) "The item's �normalized value� must be locally �valid�
25621: 	* with respect to that {type definition} as per
25622: 	* String Valid (�3.14.4)."
25623: 	*
25624: 	* VAL TODO: Do we already have the
25625: 	* "normalized attribute value" here?
25626: 	*/
25627: 	if (xpathRes || fixed) {
25628: 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25629: 	    /*
25630: 	    * Request a computed value.
25631: 	    */
25632: 	    res = xmlSchemaVCheckCVCSimpleType(
25633: 		ACTXT_CAST vctxt,
25634: 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25635: 		1, 1, 0);
25636: 	} else {
25637: 	    res = xmlSchemaVCheckCVCSimpleType(
25638: 		ACTXT_CAST vctxt,
25639: 		iattr->node, iattr->typeDef, iattr->value, NULL,
25640: 		1, 0, 0);
25641: 	}
25642: 
25643: 	if (res != 0) {
25644: 	    if (res == -1) {
25645: 		VERROR_INT("xmlSchemaVAttributesComplex",
25646: 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
25647: 		goto internal_error;
25648: 	    }
25649: 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25650: 	    /*
25651: 	    * SPEC PSVI Assessment Outcome (Attribute)
25652: 	    * [validity] = "invalid"
25653: 	    */
25654: 	    goto eval_idcs;
25655: 	}
25656: 
25657: 	if (fixed) {
25658: 	    /*
25659: 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
25660: 	    * "For an attribute information item to be�valid�
25661: 	    * with respect to an attribute use its *normalized*
25662: 	    * value� must match the *canonical* lexical
25663: 	    * representation of the attribute use's {value
25664: 	    * constraint}value, if it is present and fixed."
25665: 	    *
25666: 	    * VAL TODO: The requirement for the *canonical* value
25667: 	    * will be removed in XML Schema 1.1.
25668: 	    */
25669: 	    /*
25670: 	    * SPEC Attribute Locally Valid (cvc-attribute)
25671: 	    * (4) "The item's *actual* value� must match the *value* of
25672: 	    * the {value constraint}, if it is present and fixed."
25673: 	    */
25674: 	    if (iattr->val == NULL) {
25675: 		/* VAL TODO: A value was not precomputed. */
25676: 		TODO
25677: 		goto eval_idcs;
25678: 	    }
25679: 	    if ((iattr->use != NULL) &&
25680: 		(iattr->use->defValue != NULL)) {
25681: 		if (iattr->use->defVal == NULL) {
25682: 		    /* VAL TODO: A default value was not precomputed. */
25683: 		    TODO
25684: 		    goto eval_idcs;
25685: 		}
25686: 		iattr->vcValue = iattr->use->defValue;
25687: 		/*
25688: 		if (xmlSchemaCompareValuesWhtsp(attr->val,
25689: 		    (xmlSchemaWhitespaceValueType) ws,
25690: 		    attr->use->defVal,
25691: 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
25692: 		*/
25693: 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25694: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25695: 	    } else {
25696: 		if (iattr->decl->defVal == NULL) {
25697: 		    /* VAL TODO: A default value was not precomputed. */
25698: 		    TODO
25699: 		    goto eval_idcs;
25700: 		}
25701: 		iattr->vcValue = iattr->decl->defValue;
25702: 		/*
25703: 		if (xmlSchemaCompareValuesWhtsp(attr->val,
25704: 		    (xmlSchemaWhitespaceValueType) ws,
25705: 		    attrDecl->defVal,
25706: 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
25707: 		*/
25708: 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25709: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25710: 	    }
25711: 	    /*
25712: 	    * [validity] = "valid"
25713: 	    */
25714: 	}
25715: eval_idcs:
25716: 	/*
25717: 	* Evaluate IDCs.
25718: 	*/
25719: 	if (xpathRes) {
25720: 	    if (xmlSchemaXPathProcessHistory(vctxt,
25721: 		vctxt->depth +1) == -1) {
25722: 		VERROR_INT("xmlSchemaVAttributesComplex",
25723: 		    "calling xmlSchemaXPathEvaluate()");
25724: 		goto internal_error;
25725: 	    }
25726: 	} else if (vctxt->xpathStates != NULL)
25727: 	    xmlSchemaXPathPop(vctxt);
25728:     }
25729: 
25730:     /*
25731:     * Report errors.
25732:     */
25733:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25734: 	iattr = vctxt->attrInfos[i];
25735: 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25736: 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25737: 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25738: 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25739: 	    continue;
25740: 	ACTIVATE_ATTRIBUTE(iattr);
25741: 	switch (iattr->state) {
25742: 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
25743: 		    xmlChar *str = NULL;
25744: 		    ACTIVATE_ELEM;
25745: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25746: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25747: 			"The attribute '%s' is required but missing",
25748: 			xmlSchemaFormatQName(&str,
25749: 			    iattr->decl->targetNamespace,
25750: 			    iattr->decl->name),
25751: 			NULL);
25752: 		    FREE_AND_NULL(str)
25753: 		    break;
25754: 		}
25755: 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25756: 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25757: 		    "The type definition is absent");
25758: 		break;
25759: 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25760: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
25761: 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
25762: 		    "The value '%s' does not match the fixed "
25763: 		    "value constraint '%s'",
25764: 		    iattr->value, iattr->vcValue);
25765: 		break;
25766: 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25767: 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25768: 		    "No matching global attribute declaration available, but "
25769: 		    "demanded by the strict wildcard");
25770: 		break;
25771: 	    case XML_SCHEMAS_ATTR_UNKNOWN:
25772: 		if (iattr->metaType)
25773: 		    break;
25774: 		/*
25775: 		* MAYBE VAL TODO: One might report different error messages
25776: 		* for the following errors.
25777: 		*/
25778: 		if (type->attributeWildcard == NULL) {
25779: 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25780: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25781: 		} else {
25782: 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25783: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25784: 		}
25785: 		break;
25786: 	    default:
25787: 		break;
25788: 	}
25789:     }
25790: 
25791:     ACTIVATE_ELEM;
25792:     return (0);
25793: internal_error:
25794:     ACTIVATE_ELEM;
25795:     return (-1);
25796: }
25797: 
25798: static int
25799: xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25800: 			      int *skip)
25801: {
25802:     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25803:     /*
25804:     * The namespace of the element was already identified to be
25805:     * matching the wildcard.
25806:     */
25807:     if ((skip == NULL) || (wild == NULL) ||
25808: 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
25809: 	VERROR_INT("xmlSchemaValidateElemWildcard",
25810: 	    "bad arguments");
25811: 	return (-1);
25812:     }
25813:     *skip = 0;
25814:     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25815: 	/*
25816: 	* URGENT VAL TODO: Either we need to position the stream to the
25817: 	* next sibling, or walk the whole subtree.
25818: 	*/
25819: 	*skip = 1;
25820: 	return (0);
25821:     }
25822:     {
25823: 	xmlSchemaElementPtr decl = NULL;
25824: 
25825: 	decl = xmlSchemaGetElem(vctxt->schema,
25826: 	    vctxt->inode->localName, vctxt->inode->nsName);
25827: 	if (decl != NULL) {
25828: 	    vctxt->inode->decl = decl;
25829: 	    return (0);
25830: 	}
25831:     }
25832:     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25833: 	/* VAL TODO: Change to proper error code. */
25834: 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25835: 	    "No matching global element declaration available, but "
25836: 	    "demanded by the strict wildcard");
25837: 	return (vctxt->err);
25838:     }
25839:     if (vctxt->nbAttrInfos != 0) {
25840: 	xmlSchemaAttrInfoPtr iattr;
25841: 	/*
25842: 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
25843: 	* (1.2.1.2.1) - (1.2.1.2.3 )
25844: 	*
25845: 	* Use the xsi:type attribute for the type definition.
25846: 	*/
25847: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25848: 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25849: 	if (iattr != NULL) {
25850: 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
25851: 		&(vctxt->inode->typeDef), NULL) == -1) {
25852: 		VERROR_INT("xmlSchemaValidateElemWildcard",
25853: 		    "calling xmlSchemaProcessXSIType() to "
25854: 		    "process the attribute 'xsi:nil'");
25855: 		return (-1);
25856: 	    }
25857: 	    /*
25858: 	    * Don't return an error on purpose.
25859: 	    */
25860: 	    return (0);
25861: 	}
25862:     }
25863:     /*
25864:     * SPEC Validation Rule: Schema-Validity Assessment (Element)
25865:     *
25866:     * Fallback to "anyType".
25867:     */
25868:     vctxt->inode->typeDef =
25869: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25870:     return (0);
25871: }
25872: 
25873: /*
25874: * xmlSchemaCheckCOSValidDefault:
25875: *
25876: * This will be called if: not nilled, no content and a default/fixed
25877: * value is provided.
25878: */
25879: 
25880: static int
25881: xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25882: 			      const xmlChar *value,
25883: 			      xmlSchemaValPtr *val)
25884: {
25885:     int ret = 0;
25886:     xmlSchemaNodeInfoPtr inode = vctxt->inode;
25887: 
25888:     /*
25889:     * cos-valid-default:
25890:     * Schema Component Constraint: Element Default Valid (Immediate)
25891:     * For a string to be a valid default with respect to a type
25892:     * definition the appropriate case among the following must be true:
25893:     */
25894:     if WXS_IS_COMPLEX(inode->typeDef) {
25895: 	/*
25896: 	* Complex type.
25897: 	*
25898: 	* SPEC (2.1) "its {content type} must be a simple type definition
25899: 	* or mixed."
25900: 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
25901: 	* type}'s particle must be �emptiable� as defined by
25902: 	* Particle Emptiable (�3.9.6)."
25903: 	*/
25904: 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25905: 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25906: 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
25907: 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25908: 	    /* NOTE that this covers (2.2.2) as well. */
25909: 	    VERROR(ret, NULL,
25910: 		"For a string to be a valid default, the type definition "
25911: 		"must be a simple type or a complex type with simple content "
25912: 		"or mixed content and a particle emptiable");
25913: 	    return(ret);
25914: 	}
25915:     }
25916:     /*
25917:     * 1 If the type definition is a simple type definition, then the string
25918:     * must be �valid� with respect to that definition as defined by String
25919:     * Valid (�3.14.4).
25920:     *
25921:     * AND
25922:     *
25923:     * 2.2.1 If the {content type} is a simple type definition, then the
25924:     * string must be �valid� with respect to that simple type definition
25925:     * as defined by String Valid (�3.14.4).
25926:     */
25927:     if (WXS_IS_SIMPLE(inode->typeDef)) {
25928: 
25929: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25930: 	    NULL, inode->typeDef, value, val, 1, 1, 0);
25931: 
25932:     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25933: 
25934: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25935: 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25936:     }
25937:     if (ret < 0) {
25938: 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
25939: 	    "calling xmlSchemaVCheckCVCSimpleType()");
25940:     }
25941:     return (ret);
25942: }
25943: 
25944: static void
25945: xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
25946: 			       const xmlChar * name ATTRIBUTE_UNUSED,
25947: 			       xmlSchemaElementPtr item,
25948: 			       xmlSchemaNodeInfoPtr inode)
25949: {
25950:     inode->decl = item;
25951: #ifdef DEBUG_CONTENT
25952:     {
25953: 	xmlChar *str = NULL;
25954: 
25955: 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
25956: 	    xmlGenericError(xmlGenericErrorContext,
25957: 		"AUTOMATON callback for '%s' [declaration]\n",
25958: 		xmlSchemaFormatQName(&str,
25959: 		inode->localName, inode->nsName));
25960: 	} else {
25961: 	    xmlGenericError(xmlGenericErrorContext,
25962: 		    "AUTOMATON callback for '%s' [wildcard]\n",
25963: 		    xmlSchemaFormatQName(&str,
25964: 		    inode->localName, inode->nsName));
25965: 
25966: 	}
25967: 	FREE_AND_NULL(str)
25968:     }
25969: #endif
25970: }
25971: 
25972: static int
25973: xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25974: {
25975:     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25976:     if (vctxt->inode == NULL) {
25977: 	VERROR_INT("xmlSchemaValidatorPushElem",
25978: 	    "calling xmlSchemaGetFreshElemInfo()");
25979: 	return (-1);
25980:     }
25981:     vctxt->nbAttrInfos = 0;
25982:     return (0);
25983: }
25984: 
25985: static int
25986: xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25987: 			     xmlSchemaNodeInfoPtr inode,
25988: 			     xmlSchemaTypePtr type,
25989: 			     const xmlChar *value)
25990: {
25991:     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25992: 	return (xmlSchemaVCheckCVCSimpleType(
25993: 	    ACTXT_CAST vctxt, NULL,
25994: 	    type, value, &(inode->val), 1, 1, 0));
25995:     else
25996: 	return (xmlSchemaVCheckCVCSimpleType(
25997: 	    ACTXT_CAST vctxt, NULL,
25998: 	    type, value, NULL, 1, 0, 0));
25999: }
26000: 
26001: 
26002: 
26003: /*
26004: * Process END of element.
26005: */
26006: static int
26007: xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
26008: {
26009:     int ret = 0;
26010:     xmlSchemaNodeInfoPtr inode = vctxt->inode;
26011: 
26012:     if (vctxt->nbAttrInfos != 0)
26013: 	xmlSchemaClearAttrInfos(vctxt);
26014:     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
26015: 	/*
26016: 	* This element was not expected;
26017: 	* we will not validate child elements of broken parents.
26018: 	* Skip validation of all content of the parent.
26019: 	*/
26020: 	vctxt->skipDepth = vctxt->depth -1;
26021: 	goto end_elem;
26022:     }
26023:     if ((inode->typeDef == NULL) ||
26024: 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
26025: 	/*
26026: 	* 1. the type definition might be missing if the element was
26027: 	*    error prone
26028: 	* 2. it might be abstract.
26029: 	*/
26030: 	goto end_elem;
26031:     }
26032:     /*
26033:     * Check the content model.
26034:     */
26035:     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26036: 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26037: 
26038: 	/*
26039: 	* Workaround for "anyType".
26040: 	*/
26041: 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26042: 	    goto character_content;
26043: 
26044: 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26045: 	    xmlChar *values[10];
26046: 	    int terminal, nbval = 10, nbneg;
26047: 
26048: 	    if (inode->regexCtxt == NULL) {
26049: 		/*
26050: 		* Create the regex context.
26051: 		*/
26052: 		inode->regexCtxt =
26053: 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
26054: 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26055: 		    vctxt);
26056: 		if (inode->regexCtxt == NULL) {
26057: 		    VERROR_INT("xmlSchemaValidatorPopElem",
26058: 			"failed to create a regex context");
26059: 		    goto internal_error;
26060: 		}
26061: #ifdef DEBUG_AUTOMATA
26062: 		xmlGenericError(xmlGenericErrorContext,
26063: 		    "AUTOMATON create on '%s'\n", inode->localName);
26064: #endif
26065: 	    }
26066: 
26067: 	    /*
26068: 	     * Do not check further content if the node has been nilled
26069: 	     */
26070: 	    if (INODE_NILLED(inode)) {
26071: 		ret = 0;
26072: #ifdef DEBUG_AUTOMATA
26073: 		xmlGenericError(xmlGenericErrorContext,
26074: 		    "AUTOMATON succeeded on nilled '%s'\n",
26075: 		    inode->localName);
26076: #endif
26077:                 goto skip_nilled;
26078: 	    }
26079: 
26080: 	    /*
26081: 	    * Get hold of the still expected content, since a further
26082: 	    * call to xmlRegExecPushString() will loose this information.
26083: 	    */
26084: 	    xmlRegExecNextValues(inode->regexCtxt,
26085: 		&nbval, &nbneg, &values[0], &terminal);
26086: 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26087: 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26088: 		/*
26089: 		* Still missing something.
26090: 		*/
26091: 		ret = 1;
26092: 		inode->flags |=
26093: 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26094: 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26095: 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26096: 		    "Missing child element(s)",
26097: 		    nbval, nbneg, values);
26098: #ifdef DEBUG_AUTOMATA
26099: 		xmlGenericError(xmlGenericErrorContext,
26100: 		    "AUTOMATON missing ERROR on '%s'\n",
26101: 		    inode->localName);
26102: #endif
26103: 	    } else {
26104: 		/*
26105: 		* Content model is satisfied.
26106: 		*/
26107: 		ret = 0;
26108: #ifdef DEBUG_AUTOMATA
26109: 		xmlGenericError(xmlGenericErrorContext,
26110: 		    "AUTOMATON succeeded on '%s'\n",
26111: 		    inode->localName);
26112: #endif
26113: 	    }
26114: 
26115: 	}
26116:     }
26117: 
26118: skip_nilled:
26119: 
26120:     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26121: 	goto end_elem;
26122: 
26123: character_content:
26124: 
26125:     if (vctxt->value != NULL) {
26126: 	xmlSchemaFreeValue(vctxt->value);
26127: 	vctxt->value = NULL;
26128:     }
26129:     /*
26130:     * Check character content.
26131:     */
26132:     if (inode->decl == NULL) {
26133: 	/*
26134: 	* Speedup if no declaration exists.
26135: 	*/
26136: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26137: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26138: 		inode, inode->typeDef, inode->value);
26139: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26140: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26141: 		inode, inode->typeDef->contentTypeDef,
26142: 		inode->value);
26143: 	}
26144: 	if (ret < 0) {
26145: 	    VERROR_INT("xmlSchemaValidatorPopElem",
26146: 		"calling xmlSchemaVCheckCVCSimpleType()");
26147: 	    goto internal_error;
26148: 	}
26149: 	goto end_elem;
26150:     }
26151:     /*
26152:     * cvc-elt (3.3.4) : 5
26153:     * The appropriate case among the following must be true:
26154:     */
26155:     /*
26156:     * cvc-elt (3.3.4) : 5.1
26157:     * If the declaration has a {value constraint},
26158:     * the item has neither element nor character [children] and
26159:     * clause 3.2 has not applied, then all of the following must be true:
26160:     */
26161:     if ((inode->decl->value != NULL) &&
26162: 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26163: 	(! INODE_NILLED(inode))) {
26164: 	/*
26165: 	* cvc-elt (3.3.4) : 5.1.1
26166: 	* If the �actual type definition� is a �local type definition�
26167: 	* then the canonical lexical representation of the {value constraint}
26168: 	* value must be a valid default for the �actual type definition� as
26169: 	* defined in Element Default Valid (Immediate) (�3.3.6).
26170: 	*/
26171: 	/*
26172: 	* NOTE: 'local' above means types acquired by xsi:type.
26173: 	* NOTE: Although the *canonical* value is stated, it is not
26174: 	* relevant if canonical or not. Additionally XML Schema 1.1
26175: 	* will removed this requirement as well.
26176: 	*/
26177: 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26178: 
26179: 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
26180: 		inode->decl->value, &(inode->val));
26181: 	    if (ret != 0) {
26182: 		if (ret < 0) {
26183: 		    VERROR_INT("xmlSchemaValidatorPopElem",
26184: 			"calling xmlSchemaCheckCOSValidDefault()");
26185: 		    goto internal_error;
26186: 		}
26187: 		goto end_elem;
26188: 	    }
26189: 	    /*
26190: 	    * Stop here, to avoid redundant validation of the value
26191: 	    * (see following).
26192: 	    */
26193: 	    goto default_psvi;
26194: 	}
26195: 	/*
26196: 	* cvc-elt (3.3.4) : 5.1.2
26197: 	* The element information item with the canonical lexical
26198: 	* representation of the {value constraint} value used as its
26199: 	* �normalized value� must be �valid� with respect to the
26200: 	* �actual type definition� as defined by Element Locally Valid (Type)
26201: 	* (�3.3.4).
26202: 	*/
26203: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26204: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26205: 		inode, inode->typeDef, inode->decl->value);
26206: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26207: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26208: 		inode, inode->typeDef->contentTypeDef,
26209: 		inode->decl->value);
26210: 	}
26211: 	if (ret != 0) {
26212: 	    if (ret < 0) {
26213: 		VERROR_INT("xmlSchemaValidatorPopElem",
26214: 		    "calling xmlSchemaVCheckCVCSimpleType()");
26215: 		goto internal_error;
26216: 	    }
26217: 	    goto end_elem;
26218: 	}
26219: 
26220: default_psvi:
26221: 	/*
26222: 	* PSVI: Create a text node on the instance element.
26223: 	*/
26224: 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26225: 	    (inode->node != NULL)) {
26226: 	    xmlNodePtr textChild;
26227: 	    xmlChar *normValue;
26228: 	    /*
26229: 	    * VAL TODO: Normalize the value.
26230: 	    */
26231: 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
26232: 		inode->decl->value);
26233: 	    if (normValue != NULL) {
26234: 		textChild = xmlNewText(BAD_CAST normValue);
26235: 		xmlFree(normValue);
26236: 	    } else
26237: 		textChild = xmlNewText(inode->decl->value);
26238: 	    if (textChild == NULL) {
26239: 		VERROR_INT("xmlSchemaValidatorPopElem",
26240: 		    "calling xmlNewText()");
26241: 		goto internal_error;
26242: 	    } else
26243: 		xmlAddChild(inode->node, textChild);
26244: 	}
26245: 
26246:     } else if (! INODE_NILLED(inode)) {
26247: 	/*
26248: 	* 5.2.1 The element information item must be �valid� with respect
26249: 	* to the �actual type definition� as defined by Element Locally
26250: 	* Valid (Type) (�3.3.4).
26251: 	*/
26252: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26253: 	     /*
26254: 	    * SPEC (cvc-type) (3.1)
26255: 	    * "If the type definition is a simple type definition, ..."
26256: 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
26257: 	    * (Element) (�3.3.4) did not apply, then the �normalized value�
26258: 	    * must be �valid� with respect to the type definition as defined
26259: 	    * by String Valid (�3.14.4).
26260: 	    */
26261: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26262: 		    inode, inode->typeDef, inode->value);
26263: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26264: 	    /*
26265: 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26266: 	    * definition, then the element information item must be
26267: 	    * �valid� with respect to the type definition as per
26268: 	    * Element Locally Valid (Complex Type) (�3.4.4);"
26269: 	    *
26270: 	    * SPEC (cvc-complex-type) (2.2)
26271: 	    * "If the {content type} is a simple type definition, ...
26272: 	    * the �normalized value� of the element information item is
26273: 	    * �valid� with respect to that simple type definition as
26274: 	    * defined by String Valid (�3.14.4)."
26275: 	    */
26276: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26277: 		inode, inode->typeDef->contentTypeDef, inode->value);
26278: 	}
26279: 	if (ret != 0) {
26280: 	    if (ret < 0) {
26281: 		VERROR_INT("xmlSchemaValidatorPopElem",
26282: 		    "calling xmlSchemaVCheckCVCSimpleType()");
26283: 		goto internal_error;
26284: 	    }
26285: 	    goto end_elem;
26286: 	}
26287: 	/*
26288: 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26289: 	* not applied, all of the following must be true:
26290: 	*/
26291: 	if ((inode->decl->value != NULL) &&
26292: 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26293: 
26294: 	    /*
26295: 	    * TODO: We will need a computed value, when comparison is
26296: 	    * done on computed values.
26297: 	    */
26298: 	    /*
26299: 	    * 5.2.2.1 The element information item must have no element
26300: 	    * information item [children].
26301: 	    */
26302: 	    if (inode->flags &
26303: 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26304: 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26305: 		VERROR(ret, NULL,
26306: 		    "The content must not containt element nodes since "
26307: 		    "there is a fixed value constraint");
26308: 		goto end_elem;
26309: 	    } else {
26310: 		/*
26311: 		* 5.2.2.2 The appropriate case among the following must
26312: 		* be true:
26313: 		*/
26314: 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26315: 		    /*
26316: 		    * 5.2.2.2.1 If the {content type} of the �actual type
26317: 		    * definition� is mixed, then the *initial value* of the
26318: 		    * item must match the canonical lexical representation
26319: 		    * of the {value constraint} value.
26320: 		    *
26321: 		    * ... the *initial value* of an element information
26322: 		    * item is the string composed of, in order, the
26323: 		    * [character code] of each character information item in
26324: 		    * the [children] of that element information item.
26325: 		    */
26326: 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
26327: 			/*
26328: 			* VAL TODO: Report invalid & expected values as well.
26329: 			* VAL TODO: Implement the canonical stuff.
26330: 			*/
26331: 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26332: 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
26333: 			    ret, NULL, NULL,
26334: 			    "The initial value '%s' does not match the fixed "
26335: 			    "value constraint '%s'",
26336: 			    inode->value, inode->decl->value);
26337: 			goto end_elem;
26338: 		    }
26339: 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26340: 		    /*
26341: 		    * 5.2.2.2.2 If the {content type} of the �actual type
26342: 		    * definition� is a simple type definition, then the
26343: 		    * *actual value* of the item must match the canonical
26344: 		    * lexical representation of the {value constraint} value.
26345: 		    */
26346: 		    /*
26347: 		    * VAL TODO: *actual value* is the normalized value, impl.
26348: 		    *           this.
26349: 		    * VAL TODO: Report invalid & expected values as well.
26350: 		    * VAL TODO: Implement a comparison with the computed values.
26351: 		    */
26352: 		    if (! xmlStrEqual(inode->value,
26353: 			    inode->decl->value)) {
26354: 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26355: 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
26356: 			    ret, NULL, NULL,
26357: 			    "The actual value '%s' does not match the fixed "
26358: 			    "value constraint '%s'",
26359: 			    inode->value,
26360: 			    inode->decl->value);
26361: 			goto end_elem;
26362: 		    }
26363: 		}
26364: 	    }
26365: 	}
26366:     }
26367: 
26368: end_elem:
26369:     if (vctxt->depth < 0) {
26370: 	/* TODO: raise error? */
26371: 	return (0);
26372:     }
26373:     if (vctxt->depth == vctxt->skipDepth)
26374: 	vctxt->skipDepth = -1;
26375:     /*
26376:     * Evaluate the history of XPath state objects.
26377:     */
26378:     if (inode->appliedXPath &&
26379: 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26380: 	goto internal_error;
26381:     /*
26382:     * MAYBE TODO:
26383:     * SPEC (6) "The element information item must be �valid� with
26384:     * respect to each of the {identity-constraint definitions} as per
26385:     * Identity-constraint Satisfied (�3.11.4)."
26386:     */
26387:     /*
26388:     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26389:     *   need to be built in any case.
26390:     *   We will currently build IDC node-tables and bubble them only if
26391:     *   keyrefs do exist.
26392:     */
26393: 
26394:     /*
26395:     * Add the current IDC target-nodes to the IDC node-tables.
26396:     */
26397:     if ((inode->idcMatchers != NULL) &&
26398: 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26399:     {
26400: 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26401: 	    goto internal_error;
26402:     }
26403:     /*
26404:     * Validate IDC keyrefs.
26405:     */
26406:     if (vctxt->inode->hasKeyrefs)
26407: 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26408: 	    goto internal_error;
26409:     /*
26410:     * Merge/free the IDC table.
26411:     */
26412:     if (inode->idcTable != NULL) {
26413: #ifdef DEBUG_IDC_NODE_TABLE
26414: 	xmlSchemaDebugDumpIDCTable(stdout,
26415: 	    inode->nsName,
26416: 	    inode->localName,
26417: 	    inode->idcTable);
26418: #endif
26419: 	if ((vctxt->depth > 0) &&
26420: 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26421: 	{
26422: 	    /*
26423: 	    * Merge the IDC node table with the table of the parent node.
26424: 	    */
26425: 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26426: 		goto internal_error;
26427: 	}
26428:     }
26429:     /*
26430:     * Clear the current ielem.
26431:     * VAL TODO: Don't free the PSVI IDC tables if they are
26432:     * requested for the PSVI.
26433:     */
26434:     xmlSchemaClearElemInfo(vctxt, inode);
26435:     /*
26436:     * Skip further processing if we are on the validation root.
26437:     */
26438:     if (vctxt->depth == 0) {
26439: 	vctxt->depth--;
26440: 	vctxt->inode = NULL;
26441: 	return (0);
26442:     }
26443:     /*
26444:     * Reset the keyrefDepth if needed.
26445:     */
26446:     if (vctxt->aidcs != NULL) {
26447: 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26448: 	do {
26449: 	    if (aidc->keyrefDepth == vctxt->depth) {
26450: 		/*
26451: 		* A 'keyrefDepth' of a key/unique IDC matches the current
26452: 		* depth, this means that we are leaving the scope of the
26453: 		* top-most keyref IDC which refers to this IDC.
26454: 		*/
26455: 		aidc->keyrefDepth = -1;
26456: 	    }
26457: 	    aidc = aidc->next;
26458: 	} while (aidc != NULL);
26459:     }
26460:     vctxt->depth--;
26461:     vctxt->inode = vctxt->elemInfos[vctxt->depth];
26462:     /*
26463:     * VAL TODO: 7 If the element information item is the �validation root�, it must be
26464:     * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
26465:     */
26466:     return (ret);
26467: 
26468: internal_error:
26469:     vctxt->err = -1;
26470:     return (-1);
26471: }
26472: 
26473: /*
26474: * 3.4.4 Complex Type Definition Validation Rules
26475: * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26476: */
26477: static int
26478: xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26479: {
26480:     xmlSchemaNodeInfoPtr pielem;
26481:     xmlSchemaTypePtr ptype;
26482:     int ret = 0;
26483: 
26484:     if (vctxt->depth <= 0) {
26485: 	VERROR_INT("xmlSchemaValidateChildElem",
26486: 	    "not intended for the validation root");
26487: 	return (-1);
26488:     }
26489:     pielem = vctxt->elemInfos[vctxt->depth -1];
26490:     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26491: 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26492:     /*
26493:     * Handle 'nilled' elements.
26494:     */
26495:     if (INODE_NILLED(pielem)) {
26496: 	/*
26497: 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
26498: 	*/
26499: 	ACTIVATE_PARENT_ELEM;
26500: 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26501: 	VERROR(ret, NULL,
26502: 	    "Neither character nor element content is allowed, "
26503: 	    "because the element was 'nilled'");
26504: 	ACTIVATE_ELEM;
26505: 	goto unexpected_elem;
26506:     }
26507: 
26508:     ptype = pielem->typeDef;
26509: 
26510:     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26511: 	/*
26512: 	* Workaround for "anyType": we have currently no content model
26513: 	* assigned for "anyType", so handle it explicitely.
26514: 	* "anyType" has an unbounded, lax "any" wildcard.
26515: 	*/
26516: 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26517: 	    vctxt->inode->localName,
26518: 	    vctxt->inode->nsName);
26519: 
26520: 	if (vctxt->inode->decl == NULL) {
26521: 	    xmlSchemaAttrInfoPtr iattr;
26522: 	    /*
26523: 	    * Process "xsi:type".
26524: 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26525: 	    */
26526: 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26527: 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26528: 	    if (iattr != NULL) {
26529: 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
26530: 		    &(vctxt->inode->typeDef), NULL);
26531: 		if (ret != 0) {
26532: 		    if (ret == -1) {
26533: 			VERROR_INT("xmlSchemaValidateChildElem",
26534: 			    "calling xmlSchemaProcessXSIType() to "
26535: 			    "process the attribute 'xsi:nil'");
26536: 			return (-1);
26537: 		    }
26538: 		    return (ret);
26539: 		}
26540: 	    } else {
26541: 		 /*
26542: 		 * Fallback to "anyType".
26543: 		 *
26544: 		 * SPEC (cvc-assess-elt)
26545: 		 * "If the item cannot be �strictly assessed�, [...]
26546: 		 * an element information item's schema validity may be laxly
26547: 		 * assessed if its �context-determined declaration� is not
26548: 		 * skip by �validating� with respect to the �ur-type
26549: 		 * definition� as per Element Locally Valid (Type) (�3.3.4)."
26550: 		*/
26551: 		vctxt->inode->typeDef =
26552: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26553: 	    }
26554: 	}
26555: 	return (0);
26556:     }
26557: 
26558:     switch (ptype->contentType) {
26559: 	case XML_SCHEMA_CONTENT_EMPTY:
26560: 	    /*
26561: 	    * SPEC (2.1) "If the {content type} is empty, then the
26562: 	    * element information item has no character or element
26563: 	    * information item [children]."
26564: 	    */
26565: 	    ACTIVATE_PARENT_ELEM
26566: 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26567: 	    VERROR(ret, NULL,
26568: 		"Element content is not allowed, "
26569: 		"because the content type is empty");
26570: 	    ACTIVATE_ELEM
26571: 	    goto unexpected_elem;
26572: 	    break;
26573: 
26574: 	case XML_SCHEMA_CONTENT_MIXED:
26575:         case XML_SCHEMA_CONTENT_ELEMENTS: {
26576: 	    xmlRegExecCtxtPtr regexCtxt;
26577: 	    xmlChar *values[10];
26578: 	    int terminal, nbval = 10, nbneg;
26579: 
26580: 	    /* VAL TODO: Optimized "anyType" validation.*/
26581: 
26582: 	    if (ptype->contModel == NULL) {
26583: 		VERROR_INT("xmlSchemaValidateChildElem",
26584: 		    "type has elem content but no content model");
26585: 		return (-1);
26586: 	    }
26587: 	    /*
26588: 	    * Safety belf for evaluation if the cont. model was already
26589: 	    * examined to be invalid.
26590: 	    */
26591: 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26592: 		VERROR_INT("xmlSchemaValidateChildElem",
26593: 		    "validating elem, but elem content is already invalid");
26594: 		return (-1);
26595: 	    }
26596: 
26597: 	    regexCtxt = pielem->regexCtxt;
26598: 	    if (regexCtxt == NULL) {
26599: 		/*
26600: 		* Create the regex context.
26601: 		*/
26602: 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26603: 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26604: 		    vctxt);
26605: 		if (regexCtxt == NULL) {
26606: 		    VERROR_INT("xmlSchemaValidateChildElem",
26607: 			"failed to create a regex context");
26608: 		    return (-1);
26609: 		}
26610: 		pielem->regexCtxt = regexCtxt;
26611: #ifdef DEBUG_AUTOMATA
26612: 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26613: 		    pielem->localName);
26614: #endif
26615: 	    }
26616: 
26617: 	    /*
26618: 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
26619: 	    * then the sequence of the element information item's
26620: 	    * element information item [children], if any, taken in
26621: 	    * order, is �valid� with respect to the {content type}'s
26622: 	    * particle, as defined in Element Sequence Locally Valid
26623: 	    * (Particle) (�3.9.4)."
26624: 	    */
26625: 	    ret = xmlRegExecPushString2(regexCtxt,
26626: 		vctxt->inode->localName,
26627: 		vctxt->inode->nsName,
26628: 		vctxt->inode);
26629: #ifdef DEBUG_AUTOMATA
26630: 	    if (ret < 0)
26631: 		xmlGenericError(xmlGenericErrorContext,
26632: 		"AUTOMATON push ERROR for '%s' on '%s'\n",
26633: 		vctxt->inode->localName, pielem->localName);
26634: 	    else
26635: 		xmlGenericError(xmlGenericErrorContext,
26636: 		"AUTOMATON push OK for '%s' on '%s'\n",
26637: 		vctxt->inode->localName, pielem->localName);
26638: #endif
26639: 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26640: 		VERROR_INT("xmlSchemaValidateChildElem",
26641: 		    "calling xmlRegExecPushString2()");
26642: 		return (-1);
26643: 	    }
26644: 	    if (ret < 0) {
26645: 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26646: 		    &values[0], &terminal);
26647: 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26648: 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26649: 		    "This element is not expected",
26650: 		    nbval, nbneg, values);
26651: 		ret = vctxt->err;
26652: 		goto unexpected_elem;
26653: 	    } else
26654: 		ret = 0;
26655: 	}
26656: 	    break;
26657: 	case XML_SCHEMA_CONTENT_SIMPLE:
26658: 	case XML_SCHEMA_CONTENT_BASIC:
26659: 	    ACTIVATE_PARENT_ELEM
26660: 	    if (WXS_IS_COMPLEX(ptype)) {
26661: 		/*
26662: 		* SPEC (cvc-complex-type) (2.2)
26663: 		* "If the {content type} is a simple type definition, then
26664: 		* the element information item has no element information
26665: 		* item [children], ..."
26666: 		*/
26667: 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26668: 		VERROR(ret, NULL, "Element content is not allowed, "
26669: 		    "because the content type is a simple type definition");
26670: 	    } else {
26671: 		/*
26672: 		* SPEC (cvc-type) (3.1.2) "The element information item must
26673: 		* have no element information item [children]."
26674: 		*/
26675: 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26676: 		VERROR(ret, NULL, "Element content is not allowed, "
26677: 		    "because the type definition is simple");
26678: 	    }
26679: 	    ACTIVATE_ELEM
26680: 	    ret = vctxt->err;
26681: 	    goto unexpected_elem;
26682: 	    break;
26683: 
26684: 	default:
26685: 	    break;
26686:     }
26687:     return (ret);
26688: unexpected_elem:
26689:     /*
26690:     * Pop this element and set the skipDepth to skip
26691:     * all further content of the parent element.
26692:     */
26693:     vctxt->skipDepth = vctxt->depth;
26694:     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26695:     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26696:     return (ret);
26697: }
26698: 
26699: #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26700: #define XML_SCHEMA_PUSH_TEXT_CREATED 2
26701: #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26702: 
26703: static int
26704: xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26705: 		  int nodeType, const xmlChar *value, int len,
26706: 		  int mode, int *consumed)
26707: {
26708:     /*
26709:     * Unfortunately we have to duplicate the text sometimes.
26710:     * OPTIMIZE: Maybe we could skip it, if:
26711:     *   1. content type is simple
26712:     *   2. whitespace is "collapse"
26713:     *   3. it consists of whitespace only
26714:     *
26715:     * Process character content.
26716:     */
26717:     if (consumed != NULL)
26718: 	*consumed = 0;
26719:     if (INODE_NILLED(vctxt->inode)) {
26720: 	/*
26721: 	* SPEC cvc-elt (3.3.4 - 3.2.1)
26722: 	* "The element information item must have no character or
26723: 	* element information item [children]."
26724: 	*/
26725: 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26726: 	    "Neither character nor element content is allowed "
26727: 	    "because the element is 'nilled'");
26728: 	return (vctxt->err);
26729:     }
26730:     /*
26731:     * SPEC (2.1) "If the {content type} is empty, then the
26732:     * element information item has no character or element
26733:     * information item [children]."
26734:     */
26735:     if (vctxt->inode->typeDef->contentType ==
26736: 	    XML_SCHEMA_CONTENT_EMPTY) {
26737: 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26738: 	    "Character content is not allowed, "
26739: 	    "because the content type is empty");
26740: 	return (vctxt->err);
26741:     }
26742: 
26743:     if (vctxt->inode->typeDef->contentType ==
26744: 	    XML_SCHEMA_CONTENT_ELEMENTS) {
26745: 	if ((nodeType != XML_TEXT_NODE) ||
26746: 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26747: 	    /*
26748: 	    * SPEC cvc-complex-type (2.3)
26749: 	    * "If the {content type} is element-only, then the
26750: 	    * element information item has no character information
26751: 	    * item [children] other than those whose [character
26752: 	    * code] is defined as a white space in [XML 1.0 (Second
26753: 	    * Edition)]."
26754: 	    */
26755: 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26756: 		"Character content other than whitespace is not allowed "
26757: 		"because the content type is 'element-only'");
26758: 	    return (vctxt->err);
26759: 	}
26760: 	return (0);
26761:     }
26762: 
26763:     if ((value == NULL) || (value[0] == 0))
26764: 	return (0);
26765:     /*
26766:     * Save the value.
26767:     * NOTE that even if the content type is *mixed*, we need the
26768:     * *initial value* for default/fixed value constraints.
26769:     */
26770:     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26771: 	((vctxt->inode->decl == NULL) ||
26772: 	(vctxt->inode->decl->value == NULL)))
26773: 	return (0);
26774: 
26775:     if (vctxt->inode->value == NULL) {
26776: 	/*
26777: 	* Set the value.
26778: 	*/
26779: 	switch (mode) {
26780: 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
26781: 		/*
26782: 		* When working on a tree.
26783: 		*/
26784: 		vctxt->inode->value = value;
26785: 		break;
26786: 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
26787: 		/*
26788: 		* When working with the reader.
26789: 		* The value will be freed by the element info.
26790: 		*/
26791: 		vctxt->inode->value = value;
26792: 		if (consumed != NULL)
26793: 		    *consumed = 1;
26794: 		vctxt->inode->flags |=
26795: 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26796: 		break;
26797: 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26798: 		/*
26799: 		* When working with SAX.
26800: 		* The value will be freed by the element info.
26801: 		*/
26802: 		if (len != -1)
26803: 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26804: 		else
26805: 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
26806: 		vctxt->inode->flags |=
26807: 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26808: 		break;
26809: 	    default:
26810: 		break;
26811: 	}
26812:     } else {
26813: 	if (len < 0)
26814: 	    len = xmlStrlen(value);
26815: 	/*
26816: 	* Concat the value.
26817: 	*/
26818: 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26819: 	    vctxt->inode->value = BAD_CAST xmlStrncat(
26820: 		(xmlChar *) vctxt->inode->value, value, len);
26821: 	} else {
26822: 	    vctxt->inode->value =
26823: 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26824: 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26825: 	}
26826:     }
26827: 
26828:     return (0);
26829: }
26830: 
26831: static int
26832: xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26833: {
26834:     int ret = 0;
26835: 
26836:     if ((vctxt->skipDepth != -1) &&
26837: 	(vctxt->depth >= vctxt->skipDepth)) {
26838: 	VERROR_INT("xmlSchemaValidateElem",
26839: 	    "in skip-state");
26840: 	goto internal_error;
26841:     }
26842:     if (vctxt->xsiAssemble) {
26843: 	/*
26844: 	* We will stop validation if there was an error during
26845: 	* dynamic schema construction.
26846: 	* Note that we simply set @skipDepth to 0, this could
26847: 	* mean that a streaming document via SAX would be
26848: 	* still read to the end but it won't be validated any more.
26849: 	* TODO: If we are sure how to stop the validation at once
26850: 	*   for all input scenarios, then this should be changed to
26851: 	*   instantly stop the validation.
26852: 	*/
26853: 	ret = xmlSchemaAssembleByXSI(vctxt);
26854: 	if (ret != 0) {
26855: 	    if (ret == -1)
26856: 		goto internal_error;
26857: 	    vctxt->skipDepth = 0;
26858: 	    return(ret);
26859: 	}
26860:         /*
26861:          * Augment the IDC definitions for the main schema and all imported ones
26862:          * NOTE: main schema is the first in the imported list
26863:          */
26864:         xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
26865:     }
26866:     if (vctxt->depth > 0) {
26867: 	/*
26868: 	* Validate this element against the content model
26869: 	* of the parent.
26870: 	*/
26871: 	ret = xmlSchemaValidateChildElem(vctxt);
26872: 	if (ret != 0) {
26873: 	    if (ret < 0) {
26874: 		VERROR_INT("xmlSchemaValidateElem",
26875: 		    "calling xmlSchemaStreamValidateChildElement()");
26876: 		goto internal_error;
26877: 	    }
26878: 	    goto exit;
26879: 	}
26880: 	if (vctxt->depth == vctxt->skipDepth)
26881: 	    goto exit;
26882: 	if ((vctxt->inode->decl == NULL) &&
26883: 	    (vctxt->inode->typeDef == NULL)) {
26884: 	    VERROR_INT("xmlSchemaValidateElem",
26885: 		"the child element was valid but neither the "
26886: 		"declaration nor the type was set");
26887: 	    goto internal_error;
26888: 	}
26889:     } else {
26890: 	/*
26891: 	* Get the declaration of the validation root.
26892: 	*/
26893: 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26894: 	    vctxt->inode->localName,
26895: 	    vctxt->inode->nsName);
26896: 	if (vctxt->inode->decl == NULL) {
26897: 	    ret = XML_SCHEMAV_CVC_ELT_1;
26898: 	    VERROR(ret, NULL,
26899: 		"No matching global declaration available "
26900: 		"for the validation root");
26901: 	    goto exit;
26902: 	}
26903:     }
26904: 
26905:     if (vctxt->inode->decl == NULL)
26906: 	goto type_validation;
26907: 
26908:     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26909: 	int skip;
26910: 	/*
26911: 	* Wildcards.
26912: 	*/
26913: 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26914: 	if (ret != 0) {
26915: 	    if (ret < 0) {
26916: 		VERROR_INT("xmlSchemaValidateElem",
26917: 		    "calling xmlSchemaValidateElemWildcard()");
26918: 		goto internal_error;
26919: 	    }
26920: 	    goto exit;
26921: 	}
26922: 	if (skip) {
26923: 	    vctxt->skipDepth = vctxt->depth;
26924: 	    goto exit;
26925: 	}
26926: 	/*
26927: 	* The declaration might be set by the wildcard validation,
26928: 	* when the processContents is "lax" or "strict".
26929: 	*/
26930: 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26931: 	    /*
26932: 	    * Clear the "decl" field to not confuse further processing.
26933: 	    */
26934: 	    vctxt->inode->decl = NULL;
26935: 	    goto type_validation;
26936: 	}
26937:     }
26938:     /*
26939:     * Validate against the declaration.
26940:     */
26941:     ret = xmlSchemaValidateElemDecl(vctxt);
26942:     if (ret != 0) {
26943: 	if (ret < 0) {
26944: 	    VERROR_INT("xmlSchemaValidateElem",
26945: 		"calling xmlSchemaValidateElemDecl()");
26946: 	    goto internal_error;
26947: 	}
26948: 	goto exit;
26949:     }
26950:     /*
26951:     * Validate against the type definition.
26952:     */
26953: type_validation:
26954: 
26955:     if (vctxt->inode->typeDef == NULL) {
26956: 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26957: 	ret = XML_SCHEMAV_CVC_TYPE_1;
26958: 	VERROR(ret, NULL,
26959: 	    "The type definition is absent");
26960: 	goto exit;
26961:     }
26962:     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26963: 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26964: 	ret = XML_SCHEMAV_CVC_TYPE_2;
26965: 	    VERROR(ret, NULL,
26966: 	    "The type definition is abstract");
26967: 	goto exit;
26968:     }
26969:     /*
26970:     * Evaluate IDCs. Do it here, since new IDC matchers are registered
26971:     * during validation against the declaration. This must be done
26972:     * _before_ attribute validation.
26973:     */
26974:     if (vctxt->xpathStates != NULL) {
26975: 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26976: 	vctxt->inode->appliedXPath = 1;
26977: 	if (ret == -1) {
26978: 	    VERROR_INT("xmlSchemaValidateElem",
26979: 		"calling xmlSchemaXPathEvaluate()");
26980: 	    goto internal_error;
26981: 	}
26982:     }
26983:     /*
26984:     * Validate attributes.
26985:     */
26986:     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26987: 	if ((vctxt->nbAttrInfos != 0) ||
26988: 	    (vctxt->inode->typeDef->attrUses != NULL)) {
26989: 
26990: 	    ret = xmlSchemaVAttributesComplex(vctxt);
26991: 	}
26992:     } else if (vctxt->nbAttrInfos != 0) {
26993: 
26994: 	ret = xmlSchemaVAttributesSimple(vctxt);
26995:     }
26996:     /*
26997:     * Clear registered attributes.
26998:     */
26999:     if (vctxt->nbAttrInfos != 0)
27000: 	xmlSchemaClearAttrInfos(vctxt);
27001:     if (ret == -1) {
27002: 	VERROR_INT("xmlSchemaValidateElem",
27003: 	    "calling attributes validation");
27004: 	goto internal_error;
27005:     }
27006:     /*
27007:     * Don't return an error if attributes are invalid on purpose.
27008:     */
27009:     ret = 0;
27010: 
27011: exit:
27012:     if (ret != 0)
27013: 	vctxt->skipDepth = vctxt->depth;
27014:     return (ret);
27015: internal_error:
27016:     return (-1);
27017: }
27018: 
27019: #ifdef XML_SCHEMA_READER_ENABLED
27020: static int
27021: xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
27022: {
27023:     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
27024:     int depth, nodeType, ret = 0, consumed;
27025:     xmlSchemaNodeInfoPtr ielem;
27026: 
27027:     vctxt->depth = -1;
27028:     ret = xmlTextReaderRead(vctxt->reader);
27029:     /*
27030:     * Move to the document element.
27031:     */
27032:     while (ret == 1) {
27033: 	nodeType = xmlTextReaderNodeType(vctxt->reader);
27034: 	if (nodeType == XML_ELEMENT_NODE)
27035: 	    goto root_found;
27036: 	ret = xmlTextReaderRead(vctxt->reader);
27037:     }
27038:     goto exit;
27039: 
27040: root_found:
27041: 
27042:     do {
27043: 	depth = xmlTextReaderDepth(vctxt->reader);
27044: 	nodeType = xmlTextReaderNodeType(vctxt->reader);
27045: 
27046: 	if (nodeType == XML_ELEMENT_NODE) {
27047: 
27048: 	    vctxt->depth++;
27049: 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27050: 		VERROR_INT("xmlSchemaVReaderWalk",
27051: 		    "calling xmlSchemaValidatorPushElem()");
27052: 		goto internal_error;
27053: 	    }
27054: 	    ielem = vctxt->inode;
27055: 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27056: 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27057: 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27058: 	    /*
27059: 	    * Is the element empty?
27060: 	    */
27061: 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27062: 	    if (ret == -1) {
27063: 		VERROR_INT("xmlSchemaVReaderWalk",
27064: 		    "calling xmlTextReaderIsEmptyElement()");
27065: 		goto internal_error;
27066: 	    }
27067: 	    if (ret) {
27068: 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27069: 	    }
27070: 	    /*
27071: 	    * Register attributes.
27072: 	    */
27073: 	    vctxt->nbAttrInfos = 0;
27074: 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27075: 	    if (ret == -1) {
27076: 		VERROR_INT("xmlSchemaVReaderWalk",
27077: 		    "calling xmlTextReaderMoveToFirstAttribute()");
27078: 		goto internal_error;
27079: 	    }
27080: 	    if (ret == 1) {
27081: 		do {
27082: 		    /*
27083: 		    * VAL TODO: How do we know that the reader works on a
27084: 		    * node tree, to be able to pass a node here?
27085: 		    */
27086: 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27087: 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27088: 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
27089: 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
27090: 
27091: 			VERROR_INT("xmlSchemaVReaderWalk",
27092: 			    "calling xmlSchemaValidatorPushAttribute()");
27093: 			goto internal_error;
27094: 		    }
27095: 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27096: 		    if (ret == -1) {
27097: 			VERROR_INT("xmlSchemaVReaderWalk",
27098: 			    "calling xmlTextReaderMoveToFirstAttribute()");
27099: 			goto internal_error;
27100: 		    }
27101: 		} while (ret == 1);
27102: 		/*
27103: 		* Back to element position.
27104: 		*/
27105: 		ret = xmlTextReaderMoveToElement(vctxt->reader);
27106: 		if (ret == -1) {
27107: 		    VERROR_INT("xmlSchemaVReaderWalk",
27108: 			"calling xmlTextReaderMoveToElement()");
27109: 		    goto internal_error;
27110: 		}
27111: 	    }
27112: 	    /*
27113: 	    * Validate the element.
27114: 	    */
27115: 	    ret= xmlSchemaValidateElem(vctxt);
27116: 	    if (ret != 0) {
27117: 		if (ret == -1) {
27118: 		    VERROR_INT("xmlSchemaVReaderWalk",
27119: 			"calling xmlSchemaValidateElem()");
27120: 		    goto internal_error;
27121: 		}
27122: 		goto exit;
27123: 	    }
27124: 	    if (vctxt->depth == vctxt->skipDepth) {
27125: 		int curDepth;
27126: 		/*
27127: 		* Skip all content.
27128: 		*/
27129: 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27130: 		    ret = xmlTextReaderRead(vctxt->reader);
27131: 		    curDepth = xmlTextReaderDepth(vctxt->reader);
27132: 		    while ((ret == 1) && (curDepth != depth)) {
27133: 			ret = xmlTextReaderRead(vctxt->reader);
27134: 			curDepth = xmlTextReaderDepth(vctxt->reader);
27135: 		    }
27136: 		    if (ret < 0) {
27137: 			/*
27138: 			* VAL TODO: A reader error occured; what to do here?
27139: 			*/
27140: 			ret = 1;
27141: 			goto exit;
27142: 		    }
27143: 		}
27144: 		goto leave_elem;
27145: 	    }
27146: 	    /*
27147: 	    * READER VAL TODO: Is an END_ELEM really never called
27148: 	    * if the elem is empty?
27149: 	    */
27150: 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27151: 		goto leave_elem;
27152: 	} else if (nodeType == END_ELEM) {
27153: 	    /*
27154: 	    * Process END of element.
27155: 	    */
27156: leave_elem:
27157: 	    ret = xmlSchemaValidatorPopElem(vctxt);
27158: 	    if (ret != 0) {
27159: 		if (ret < 0) {
27160: 		    VERROR_INT("xmlSchemaVReaderWalk",
27161: 			"calling xmlSchemaValidatorPopElem()");
27162: 		    goto internal_error;
27163: 		}
27164: 		goto exit;
27165: 	    }
27166: 	    if (vctxt->depth >= 0)
27167: 		ielem = vctxt->inode;
27168: 	    else
27169: 		ielem = NULL;
27170: 	} else if ((nodeType == XML_TEXT_NODE) ||
27171: 	    (nodeType == XML_CDATA_SECTION_NODE) ||
27172: 	    (nodeType == WHTSP) ||
27173: 	    (nodeType == SIGN_WHTSP)) {
27174: 	    /*
27175: 	    * Process character content.
27176: 	    */
27177: 	    xmlChar *value;
27178: 
27179: 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27180: 		nodeType = XML_TEXT_NODE;
27181: 
27182: 	    value = xmlTextReaderValue(vctxt->reader);
27183: 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27184: 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27185: 	    if (! consumed)
27186: 		xmlFree(value);
27187: 	    if (ret == -1) {
27188: 		VERROR_INT("xmlSchemaVReaderWalk",
27189: 		    "calling xmlSchemaVPushText()");
27190: 		goto internal_error;
27191: 	    }
27192: 	} else if ((nodeType == XML_ENTITY_NODE) ||
27193: 	    (nodeType == XML_ENTITY_REF_NODE)) {
27194: 	    /*
27195: 	    * VAL TODO: What to do with entities?
27196: 	    */
27197: 	    TODO
27198: 	}
27199: 	/*
27200: 	* Read next node.
27201: 	*/
27202: 	ret = xmlTextReaderRead(vctxt->reader);
27203:     } while (ret == 1);
27204: 
27205: exit:
27206:     return (ret);
27207: internal_error:
27208:     return (-1);
27209: }
27210: #endif
27211: 
27212: /************************************************************************
27213:  *									*
27214:  *			SAX validation handlers				*
27215:  *									*
27216:  ************************************************************************/
27217: 
27218: /*
27219: * Process text content.
27220: */
27221: static void
27222: xmlSchemaSAXHandleText(void *ctx,
27223: 		       const xmlChar * ch,
27224: 		       int len)
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:     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27233: 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27234:     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27235: 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27236: 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
27237: 	    "calling xmlSchemaVPushText()");
27238: 	vctxt->err = -1;
27239: 	xmlStopParser(vctxt->parserCtxt);
27240:     }
27241: }
27242: 
27243: /*
27244: * Process CDATA content.
27245: */
27246: static void
27247: xmlSchemaSAXHandleCDataSection(void *ctx,
27248: 			     const xmlChar * ch,
27249: 			     int len)
27250: {
27251:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27252: 
27253:     if (vctxt->depth < 0)
27254: 	return;
27255:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27256: 	return;
27257:     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27258: 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27259:     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27260: 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27261: 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
27262: 	    "calling xmlSchemaVPushText()");
27263: 	vctxt->err = -1;
27264: 	xmlStopParser(vctxt->parserCtxt);
27265:     }
27266: }
27267: 
27268: static void
27269: xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27270: 			    const xmlChar * name ATTRIBUTE_UNUSED)
27271: {
27272:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27273: 
27274:     if (vctxt->depth < 0)
27275: 	return;
27276:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27277: 	return;
27278:     /* SAX VAL TODO: What to do here? */
27279:     TODO
27280: }
27281: 
27282: static void
27283: xmlSchemaSAXHandleStartElementNs(void *ctx,
27284: 				 const xmlChar * localname,
27285: 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
27286: 				 const xmlChar * URI,
27287: 				 int nb_namespaces,
27288: 				 const xmlChar ** namespaces,
27289: 				 int nb_attributes,
27290: 				 int nb_defaulted ATTRIBUTE_UNUSED,
27291: 				 const xmlChar ** attributes)
27292: {
27293:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27294:     int ret;
27295:     xmlSchemaNodeInfoPtr ielem;
27296:     int i, j;
27297: 
27298:     /*
27299:     * SAX VAL TODO: What to do with nb_defaulted?
27300:     */
27301:     /*
27302:     * Skip elements if inside a "skip" wildcard or invalid.
27303:     */
27304:     vctxt->depth++;
27305:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27306: 	return;
27307:     /*
27308:     * Push the element.
27309:     */
27310:     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27311: 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27312: 	    "calling xmlSchemaValidatorPushElem()");
27313: 	goto internal_error;
27314:     }
27315:     ielem = vctxt->inode;
27316:     /*
27317:     * TODO: Is this OK?
27318:     */
27319:     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27320:     ielem->localName = localname;
27321:     ielem->nsName = URI;
27322:     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27323:     /*
27324:     * Register namespaces on the elem info.
27325:     */
27326:     if (nb_namespaces != 0) {
27327: 	/*
27328: 	* Although the parser builds its own namespace list,
27329: 	* we have no access to it, so we'll use an own one.
27330: 	*/
27331:         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27332: 	    /*
27333: 	    * Store prefix and namespace name.
27334: 	    */
27335: 	    if (ielem->nsBindings == NULL) {
27336: 		ielem->nsBindings =
27337: 		    (const xmlChar **) xmlMalloc(10 *
27338: 			sizeof(const xmlChar *));
27339: 		if (ielem->nsBindings == NULL) {
27340: 		    xmlSchemaVErrMemory(vctxt,
27341: 			"allocating namespace bindings for SAX validation",
27342: 			NULL);
27343: 		    goto internal_error;
27344: 		}
27345: 		ielem->nbNsBindings = 0;
27346: 		ielem->sizeNsBindings = 5;
27347: 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27348: 		ielem->sizeNsBindings *= 2;
27349: 		ielem->nsBindings =
27350: 		    (const xmlChar **) xmlRealloc(
27351: 			(void *) ielem->nsBindings,
27352: 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27353: 		if (ielem->nsBindings == NULL) {
27354: 		    xmlSchemaVErrMemory(vctxt,
27355: 			"re-allocating namespace bindings for SAX validation",
27356: 			NULL);
27357: 		    goto internal_error;
27358: 		}
27359: 	    }
27360: 
27361: 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27362: 	    if (namespaces[j+1][0] == 0) {
27363: 		/*
27364: 		* Handle xmlns="".
27365: 		*/
27366: 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27367: 	    } else
27368: 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27369: 		    namespaces[j+1];
27370: 	    ielem->nbNsBindings++;
27371: 	}
27372:     }
27373:     /*
27374:     * Register attributes.
27375:     * SAX VAL TODO: We are not adding namespace declaration
27376:     * attributes yet.
27377:     */
27378:     if (nb_attributes != 0) {
27379: 	xmlChar *value;
27380: 
27381:         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27382: 	    /*
27383: 	    * Duplicate the value.
27384: 	    */
27385: 	    value = xmlStrndup(attributes[j+3],
27386: 		attributes[j+4] - attributes[j+3]);
27387: 	    /*
27388: 	    * TODO: Set the node line.
27389: 	    */
27390: 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
27391: 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27392: 		value, 1);
27393: 	    if (ret == -1) {
27394: 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27395: 		    "calling xmlSchemaValidatorPushAttribute()");
27396: 		goto internal_error;
27397: 	    }
27398: 	}
27399:     }
27400:     /*
27401:     * Validate the element.
27402:     */
27403:     ret = xmlSchemaValidateElem(vctxt);
27404:     if (ret != 0) {
27405: 	if (ret == -1) {
27406: 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27407: 		"calling xmlSchemaValidateElem()");
27408: 	    goto internal_error;
27409: 	}
27410: 	goto exit;
27411:     }
27412: 
27413: exit:
27414:     return;
27415: internal_error:
27416:     vctxt->err = -1;
27417:     xmlStopParser(vctxt->parserCtxt);
27418:     return;
27419: }
27420: 
27421: static void
27422: xmlSchemaSAXHandleEndElementNs(void *ctx,
27423: 			       const xmlChar * localname ATTRIBUTE_UNUSED,
27424: 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
27425: 			       const xmlChar * URI ATTRIBUTE_UNUSED)
27426: {
27427:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27428:     int res;
27429: 
27430:     /*
27431:     * Skip elements if inside a "skip" wildcard or if invalid.
27432:     */
27433:     if (vctxt->skipDepth != -1) {
27434: 	if (vctxt->depth > vctxt->skipDepth) {
27435: 	    vctxt->depth--;
27436: 	    return;
27437: 	} else
27438: 	    vctxt->skipDepth = -1;
27439:     }
27440:     /*
27441:     * SAX VAL TODO: Just a temporary check.
27442:     */
27443:     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27444: 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
27445: 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27446: 	    "elem pop mismatch");
27447:     }
27448:     res = xmlSchemaValidatorPopElem(vctxt);
27449:     if (res != 0) {
27450: 	if (res < 0) {
27451: 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27452: 		"calling xmlSchemaValidatorPopElem()");
27453: 	    goto internal_error;
27454: 	}
27455: 	goto exit;
27456:     }
27457: exit:
27458:     return;
27459: internal_error:
27460:     vctxt->err = -1;
27461:     xmlStopParser(vctxt->parserCtxt);
27462:     return;
27463: }
27464: 
27465: /************************************************************************
27466:  *									*
27467:  *			Validation interfaces				*
27468:  *									*
27469:  ************************************************************************/
27470: 
27471: /**
27472:  * xmlSchemaNewValidCtxt:
27473:  * @schema:  a precompiled XML Schemas
27474:  *
27475:  * Create an XML Schemas validation context based on the given schema.
27476:  *
27477:  * Returns the validation context or NULL in case of error
27478:  */
27479: xmlSchemaValidCtxtPtr
27480: xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27481: {
27482:     xmlSchemaValidCtxtPtr ret;
27483: 
27484:     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27485:     if (ret == NULL) {
27486:         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27487:         return (NULL);
27488:     }
27489:     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27490:     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27491:     ret->dict = xmlDictCreate();
27492:     ret->nodeQNames = xmlSchemaItemListCreate();
27493:     ret->schema = schema;
27494:     return (ret);
27495: }
27496: 
27497: /**
27498:  * xmlSchemaValidateSetFilename:
27499:  * @vctxt: the schema validation context
27500:  * @filename: the file name
27501:  *
27502:  * Workaround to provide file error reporting information when this is
27503:  * not provided by current APIs
27504:  */
27505: void
27506: xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
27507:     if (vctxt == NULL)
27508:         return;
27509:     if (vctxt->filename != NULL)
27510:         xmlFree(vctxt->filename);
27511:     if (filename != NULL)
27512:         vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
27513:     else
27514:         vctxt->filename = NULL;
27515: }
27516: 
27517: /**
27518:  * xmlSchemaClearValidCtxt:
27519:  * @vctxt: the schema validation context
27520:  *
27521:  * Free the resources associated to the schema validation context;
27522:  * leaves some fields alive intended for reuse of the context.
27523:  */
27524: static void
27525: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27526: {
27527:     if (vctxt == NULL)
27528:         return;
27529: 
27530:     /*
27531:     * TODO: Should we clear the flags?
27532:     *   Might be problematic if one reuses the context
27533:     *   and assumes that the options remain the same.
27534:     */
27535:     vctxt->flags = 0;
27536:     vctxt->validationRoot = NULL;
27537:     vctxt->doc = NULL;
27538: #ifdef LIBXML_READER_ENABLED
27539:     vctxt->reader = NULL;
27540: #endif
27541:     vctxt->hasKeyrefs = 0;
27542: 
27543:     if (vctxt->value != NULL) {
27544:         xmlSchemaFreeValue(vctxt->value);
27545: 	vctxt->value = NULL;
27546:     }
27547:     /*
27548:     * Augmented IDC information.
27549:     */
27550:     if (vctxt->aidcs != NULL) {
27551: 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27552: 	do {
27553: 	    next = cur->next;
27554: 	    xmlFree(cur);
27555: 	    cur = next;
27556: 	} while (cur != NULL);
27557: 	vctxt->aidcs = NULL;
27558:     }
27559:     if (vctxt->idcMatcherCache != NULL) {
27560: 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27561: 
27562: 	while (matcher) {
27563: 	    tmp = matcher;
27564: 	    matcher = matcher->nextCached;
27565: 	    xmlSchemaIDCFreeMatcherList(tmp);
27566: 	}
27567: 	vctxt->idcMatcherCache = NULL;
27568:     }
27569: 
27570: 
27571:     if (vctxt->idcNodes != NULL) {
27572: 	int i;
27573: 	xmlSchemaPSVIIDCNodePtr item;
27574: 
27575: 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
27576: 	    item = vctxt->idcNodes[i];
27577: 	    xmlFree(item->keys);
27578: 	    xmlFree(item);
27579: 	}
27580: 	xmlFree(vctxt->idcNodes);
27581: 	vctxt->idcNodes = NULL;
27582: 	vctxt->nbIdcNodes = 0;
27583: 	vctxt->sizeIdcNodes = 0;
27584:     }
27585:     /*
27586:     * Note that we won't delete the XPath state pool here.
27587:     */
27588:     if (vctxt->xpathStates != NULL) {
27589: 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27590: 	vctxt->xpathStates = NULL;
27591:     }
27592:     /*
27593:     * Attribute info.
27594:     */
27595:     if (vctxt->nbAttrInfos != 0) {
27596: 	xmlSchemaClearAttrInfos(vctxt);
27597:     }
27598:     /*
27599:     * Element info.
27600:     */
27601:     if (vctxt->elemInfos != NULL) {
27602: 	int i;
27603: 	xmlSchemaNodeInfoPtr ei;
27604: 
27605: 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
27606: 	    ei = vctxt->elemInfos[i];
27607: 	    if (ei == NULL)
27608: 		break;
27609: 	    xmlSchemaClearElemInfo(vctxt, ei);
27610: 	}
27611:     }
27612:     xmlSchemaItemListClear(vctxt->nodeQNames);
27613:     /* Recreate the dict. */
27614:     xmlDictFree(vctxt->dict);
27615:     /*
27616:     * TODO: Is is save to recreate it? Do we have a scenario
27617:     * where the user provides the dict?
27618:     */
27619:     vctxt->dict = xmlDictCreate();
27620: 
27621:     if (vctxt->filename != NULL) {
27622:         xmlFree(vctxt->filename);
27623: 	vctxt->filename = NULL;
27624:     }
27625: }
27626: 
27627: /**
27628:  * xmlSchemaFreeValidCtxt:
27629:  * @ctxt:  the schema validation context
27630:  *
27631:  * Free the resources associated to the schema validation context
27632:  */
27633: void
27634: xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27635: {
27636:     if (ctxt == NULL)
27637:         return;
27638:     if (ctxt->value != NULL)
27639:         xmlSchemaFreeValue(ctxt->value);
27640:     if (ctxt->pctxt != NULL)
27641: 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
27642:     if (ctxt->idcNodes != NULL) {
27643: 	int i;
27644: 	xmlSchemaPSVIIDCNodePtr item;
27645: 
27646: 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
27647: 	    item = ctxt->idcNodes[i];
27648: 	    xmlFree(item->keys);
27649: 	    xmlFree(item);
27650: 	}
27651: 	xmlFree(ctxt->idcNodes);
27652:     }
27653:     if (ctxt->idcKeys != NULL) {
27654: 	int i;
27655: 	for (i = 0; i < ctxt->nbIdcKeys; i++)
27656: 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27657: 	xmlFree(ctxt->idcKeys);
27658:     }
27659: 
27660:     if (ctxt->xpathStates != NULL) {
27661: 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27662: 	ctxt->xpathStates = NULL;
27663:     }
27664:     if (ctxt->xpathStatePool != NULL) {
27665: 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27666: 	ctxt->xpathStatePool = NULL;
27667:     }
27668: 
27669:     /*
27670:     * Augmented IDC information.
27671:     */
27672:     if (ctxt->aidcs != NULL) {
27673: 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27674: 	do {
27675: 	    next = cur->next;
27676: 	    xmlFree(cur);
27677: 	    cur = next;
27678: 	} while (cur != NULL);
27679:     }
27680:     if (ctxt->attrInfos != NULL) {
27681: 	int i;
27682: 	xmlSchemaAttrInfoPtr attr;
27683: 
27684: 	/* Just a paranoid call to the cleanup. */
27685: 	if (ctxt->nbAttrInfos != 0)
27686: 	    xmlSchemaClearAttrInfos(ctxt);
27687: 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27688: 	    attr = ctxt->attrInfos[i];
27689: 	    xmlFree(attr);
27690: 	}
27691: 	xmlFree(ctxt->attrInfos);
27692:     }
27693:     if (ctxt->elemInfos != NULL) {
27694: 	int i;
27695: 	xmlSchemaNodeInfoPtr ei;
27696: 
27697: 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
27698: 	    ei = ctxt->elemInfos[i];
27699: 	    if (ei == NULL)
27700: 		break;
27701: 	    xmlSchemaClearElemInfo(ctxt, ei);
27702: 	    xmlFree(ei);
27703: 	}
27704: 	xmlFree(ctxt->elemInfos);
27705:     }
27706:     if (ctxt->nodeQNames != NULL)
27707: 	xmlSchemaItemListFree(ctxt->nodeQNames);
27708:     if (ctxt->dict != NULL)
27709: 	xmlDictFree(ctxt->dict);
27710:     if (ctxt->filename != NULL)
27711: 	xmlFree(ctxt->filename);
27712:     xmlFree(ctxt);
27713: }
27714: 
27715: /**
27716:  * xmlSchemaIsValid:
27717:  * @ctxt: the schema validation context
27718:  *
27719:  * Check if any error was detected during validation.
27720:  *
27721:  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27722:  *         of internal error.
27723:  */
27724: int
27725: xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27726: {
27727:     if (ctxt == NULL)
27728:         return(-1);
27729:     return(ctxt->err == 0);
27730: }
27731: 
27732: /**
27733:  * xmlSchemaSetValidErrors:
27734:  * @ctxt:  a schema validation context
27735:  * @err:  the error function
27736:  * @warn: the warning function
27737:  * @ctx: the functions context
27738:  *
27739:  * Set the error and warning callback informations
27740:  */
27741: void
27742: xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27743:                         xmlSchemaValidityErrorFunc err,
27744:                         xmlSchemaValidityWarningFunc warn, void *ctx)
27745: {
27746:     if (ctxt == NULL)
27747:         return;
27748:     ctxt->error = err;
27749:     ctxt->warning = warn;
27750:     ctxt->errCtxt = ctx;
27751:     if (ctxt->pctxt != NULL)
27752: 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27753: }
27754: 
27755: /**
27756:  * xmlSchemaSetValidStructuredErrors:
27757:  * @ctxt:  a schema validation context
27758:  * @serror:  the structured error function
27759:  * @ctx: the functions context
27760:  *
27761:  * Set the structured error callback
27762:  */
27763: void
27764: xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27765: 				  xmlStructuredErrorFunc serror, void *ctx)
27766: {
27767:     if (ctxt == NULL)
27768:         return;
27769: 	ctxt->serror = serror;
27770:     ctxt->error = NULL;
27771:     ctxt->warning = NULL;
27772:     ctxt->errCtxt = ctx;
27773:     if (ctxt->pctxt != NULL)
27774: 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27775: }
27776: 
27777: /**
27778:  * xmlSchemaGetValidErrors:
27779:  * @ctxt: a XML-Schema validation context
27780:  * @err: the error function result
27781:  * @warn: the warning function result
27782:  * @ctx: the functions context result
27783:  *
27784:  * Get the error and warning callback informations
27785:  *
27786:  * Returns -1 in case of error and 0 otherwise
27787:  */
27788: int
27789: xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27790: 			xmlSchemaValidityErrorFunc * err,
27791: 			xmlSchemaValidityWarningFunc * warn, void **ctx)
27792: {
27793: 	if (ctxt == NULL)
27794: 		return (-1);
27795: 	if (err != NULL)
27796: 		*err = ctxt->error;
27797: 	if (warn != NULL)
27798: 		*warn = ctxt->warning;
27799: 	if (ctx != NULL)
27800: 		*ctx = ctxt->errCtxt;
27801: 	return (0);
27802: }
27803: 
27804: 
27805: /**
27806:  * xmlSchemaSetValidOptions:
27807:  * @ctxt:	a schema validation context
27808:  * @options: a combination of xmlSchemaValidOption
27809:  *
27810:  * Sets the options to be used during the validation.
27811:  *
27812:  * Returns 0 in case of success, -1 in case of an
27813:  * API error.
27814:  */
27815: int
27816: xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27817: 			 int options)
27818: 
27819: {
27820:     int i;
27821: 
27822:     if (ctxt == NULL)
27823: 	return (-1);
27824:     /*
27825:     * WARNING: Change the start value if adding to the
27826:     * xmlSchemaValidOption.
27827:     * TODO: Is there an other, more easy to maintain,
27828:     * way?
27829:     */
27830:     for (i = 1; i < (int) sizeof(int) * 8; i++) {
27831:         if (options & 1<<i)
27832: 	    return (-1);
27833:     }
27834:     ctxt->options = options;
27835:     return (0);
27836: }
27837: 
27838: /**
27839:  * xmlSchemaValidCtxtGetOptions:
27840:  * @ctxt: a schema validation context
27841:  *
27842:  * Get the validation context options.
27843:  *
27844:  * Returns the option combination or -1 on error.
27845:  */
27846: int
27847: xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27848: 
27849: {
27850:     if (ctxt == NULL)
27851: 	return (-1);
27852:     else
27853: 	return (ctxt->options);
27854: }
27855: 
27856: static int
27857: xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27858: {
27859:     xmlAttrPtr attr;
27860:     int ret = 0;
27861:     xmlSchemaNodeInfoPtr ielem = NULL;
27862:     xmlNodePtr node, valRoot;
27863:     const xmlChar *nsName;
27864: 
27865:     /* DOC VAL TODO: Move this to the start function. */
27866:     if (vctxt->validationRoot != NULL)
27867:         valRoot = vctxt->validationRoot;
27868:     else
27869: 	valRoot = xmlDocGetRootElement(vctxt->doc);
27870:     if (valRoot == NULL) {
27871: 	/* VAL TODO: Error code? */
27872: 	VERROR(1, NULL, "The document has no document element");
27873: 	return (1);
27874:     }
27875:     vctxt->depth = -1;
27876:     vctxt->validationRoot = valRoot;
27877:     node = valRoot;
27878:     while (node != NULL) {
27879: 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27880: 	    goto next_sibling;
27881: 	if (node->type == XML_ELEMENT_NODE) {
27882: 
27883: 	    /*
27884: 	    * Init the node-info.
27885: 	    */
27886: 	    vctxt->depth++;
27887: 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
27888: 		goto internal_error;
27889: 	    ielem = vctxt->inode;
27890: 	    ielem->node = node;
27891: 	    ielem->nodeLine = node->line;
27892: 	    ielem->localName = node->name;
27893: 	    if (node->ns != NULL)
27894: 		ielem->nsName = node->ns->href;
27895: 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27896: 	    /*
27897: 	    * Register attributes.
27898: 	    * DOC VAL TODO: We do not register namespace declaration
27899: 	    * attributes yet.
27900: 	    */
27901: 	    vctxt->nbAttrInfos = 0;
27902: 	    if (node->properties != NULL) {
27903: 		attr = node->properties;
27904: 		do {
27905: 		    if (attr->ns != NULL)
27906: 			nsName = attr->ns->href;
27907: 		    else
27908: 			nsName = NULL;
27909: 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
27910: 			(xmlNodePtr) attr,
27911: 			/*
27912: 			* Note that we give it the line number of the
27913: 			* parent element.
27914: 			*/
27915: 			ielem->nodeLine,
27916: 			attr->name, nsName, 0,
27917: 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27918: 		    if (ret == -1) {
27919: 			VERROR_INT("xmlSchemaDocWalk",
27920: 			    "calling xmlSchemaValidatorPushAttribute()");
27921: 			goto internal_error;
27922: 		    }
27923: 		    attr = attr->next;
27924: 		} while (attr);
27925: 	    }
27926: 	    /*
27927: 	    * Validate the element.
27928: 	    */
27929: 	    ret = xmlSchemaValidateElem(vctxt);
27930: 	    if (ret != 0) {
27931: 		if (ret == -1) {
27932: 		    VERROR_INT("xmlSchemaDocWalk",
27933: 			"calling xmlSchemaValidateElem()");
27934: 		    goto internal_error;
27935: 		}
27936: 		/*
27937: 		* Don't stop validation; just skip the content
27938: 		* of this element.
27939: 		*/
27940: 		goto leave_node;
27941: 	    }
27942: 	    if ((vctxt->skipDepth != -1) &&
27943: 		(vctxt->depth >= vctxt->skipDepth))
27944: 		goto leave_node;
27945: 	} else if ((node->type == XML_TEXT_NODE) ||
27946: 	    (node->type == XML_CDATA_SECTION_NODE)) {
27947: 	    /*
27948: 	    * Process character content.
27949: 	    */
27950: 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27951: 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27952: 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27953: 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27954: 	    if (ret < 0) {
27955: 		VERROR_INT("xmlSchemaVDocWalk",
27956: 		    "calling xmlSchemaVPushText()");
27957: 		goto internal_error;
27958: 	    }
27959: 	    /*
27960: 	    * DOC VAL TODO: Should we skip further validation of the
27961: 	    * element content here?
27962: 	    */
27963: 	} else if ((node->type == XML_ENTITY_NODE) ||
27964: 	    (node->type == XML_ENTITY_REF_NODE)) {
27965: 	    /*
27966: 	    * DOC VAL TODO: What to do with entities?
27967: 	    */
27968: 	    VERROR_INT("xmlSchemaVDocWalk",
27969: 		"there is at least one entity reference in the node-tree "
27970: 		"currently being validated. Processing of entities with "
27971: 		"this XML Schema processor is not supported (yet). Please "
27972: 		"substitute entities before validation.");
27973: 	    goto internal_error;
27974: 	} else {
27975: 	    goto leave_node;
27976: 	    /*
27977: 	    * DOC VAL TODO: XInclude nodes, etc.
27978: 	    */
27979: 	}
27980: 	/*
27981: 	* Walk the doc.
27982: 	*/
27983: 	if (node->children != NULL) {
27984: 	    node = node->children;
27985: 	    continue;
27986: 	}
27987: leave_node:
27988: 	if (node->type == XML_ELEMENT_NODE) {
27989: 	    /*
27990: 	    * Leaving the scope of an element.
27991: 	    */
27992: 	    if (node != vctxt->inode->node) {
27993: 		VERROR_INT("xmlSchemaVDocWalk",
27994: 		    "element position mismatch");
27995: 		goto internal_error;
27996: 	    }
27997: 	    ret = xmlSchemaValidatorPopElem(vctxt);
27998: 	    if (ret != 0) {
27999: 		if (ret < 0) {
28000: 		    VERROR_INT("xmlSchemaVDocWalk",
28001: 			"calling xmlSchemaValidatorPopElem()");
28002: 		    goto internal_error;
28003: 		}
28004: 	    }
28005: 	    if (node == valRoot)
28006: 		goto exit;
28007: 	}
28008: next_sibling:
28009: 	if (node->next != NULL)
28010: 	    node = node->next;
28011: 	else {
28012: 	    node = node->parent;
28013: 	    goto leave_node;
28014: 	}
28015:     }
28016: 
28017: exit:
28018:     return (ret);
28019: internal_error:
28020:     return (-1);
28021: }
28022: 
28023: static int
28024: xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
28025:     /*
28026:     * Some initialization.
28027:     */
28028:     vctxt->err = 0;
28029:     vctxt->nberrors = 0;
28030:     vctxt->depth = -1;
28031:     vctxt->skipDepth = -1;
28032:     vctxt->xsiAssemble = 0;
28033:     vctxt->hasKeyrefs = 0;
28034: #ifdef ENABLE_IDC_NODE_TABLES_TEST
28035:     vctxt->createIDCNodeTables = 1;
28036: #else
28037:     vctxt->createIDCNodeTables = 0;
28038: #endif
28039:     /*
28040:     * Create a schema + parser if necessary.
28041:     */
28042:     if (vctxt->schema == NULL) {
28043: 	xmlSchemaParserCtxtPtr pctxt;
28044: 
28045: 	vctxt->xsiAssemble = 1;
28046: 	/*
28047: 	* If not schema was given then we will create a schema
28048: 	* dynamically using XSI schema locations.
28049: 	*
28050: 	* Create the schema parser context.
28051: 	*/
28052: 	if ((vctxt->pctxt == NULL) &&
28053: 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
28054: 	   return (-1);
28055: 	pctxt = vctxt->pctxt;
28056: 	pctxt->xsiAssemble = 1;
28057: 	/*
28058: 	* Create the schema.
28059: 	*/
28060: 	vctxt->schema = xmlSchemaNewSchema(pctxt);
28061: 	if (vctxt->schema == NULL)
28062: 	    return (-1);
28063: 	/*
28064: 	* Create the schema construction context.
28065: 	*/
28066: 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
28067: 	if (pctxt->constructor == NULL)
28068: 	    return(-1);
28069: 	pctxt->constructor->mainSchema = vctxt->schema;
28070: 	/*
28071: 	* Take ownership of the constructor to be able to free it.
28072: 	*/
28073: 	pctxt->ownsConstructor = 1;
28074:     }
28075:     /*
28076:     * Augment the IDC definitions for the main schema and all imported ones
28077:     * NOTE: main schema if the first in the imported list
28078:     */
28079:     xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
28080: 
28081:     return(0);
28082: }
28083: 
28084: static void
28085: xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28086:     if (vctxt->xsiAssemble) {
28087: 	if (vctxt->schema != NULL) {
28088: 	    xmlSchemaFree(vctxt->schema);
28089: 	    vctxt->schema = NULL;
28090: 	}
28091:     }
28092:     xmlSchemaClearValidCtxt(vctxt);
28093: }
28094: 
28095: static int
28096: xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28097: {
28098:     int ret = 0;
28099: 
28100:     if (xmlSchemaPreRun(vctxt) < 0)
28101:         return(-1);
28102: 
28103:     if (vctxt->doc != NULL) {
28104: 	/*
28105: 	 * Tree validation.
28106: 	 */
28107: 	ret = xmlSchemaVDocWalk(vctxt);
28108: #ifdef LIBXML_READER_ENABLED
28109:     } else if (vctxt->reader != NULL) {
28110: 	/*
28111: 	 * XML Reader validation.
28112: 	 */
28113: #ifdef XML_SCHEMA_READER_ENABLED
28114: 	ret = xmlSchemaVReaderWalk(vctxt);
28115: #endif
28116: #endif
28117:     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28118: 	/*
28119: 	 * SAX validation.
28120: 	 */
28121: 	ret = xmlParseDocument(vctxt->parserCtxt);
28122:     } else {
28123: 	VERROR_INT("xmlSchemaVStart",
28124: 	    "no instance to validate");
28125: 	ret = -1;
28126:     }
28127: 
28128:     xmlSchemaPostRun(vctxt);
28129:     if (ret == 0)
28130: 	ret = vctxt->err;
28131:     return (ret);
28132: }
28133: 
28134: /**
28135:  * xmlSchemaValidateOneElement:
28136:  * @ctxt:  a schema validation context
28137:  * @elem:  an element node
28138:  *
28139:  * Validate a branch of a tree, starting with the given @elem.
28140:  *
28141:  * Returns 0 if the element and its subtree is valid, a positive error
28142:  * code number otherwise and -1 in case of an internal or API error.
28143:  */
28144: int
28145: xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28146: {
28147:     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28148: 	return (-1);
28149: 
28150:     if (ctxt->schema == NULL)
28151: 	return (-1);
28152: 
28153:     ctxt->doc = elem->doc;
28154:     ctxt->node = elem;
28155:     ctxt->validationRoot = elem;
28156:     return(xmlSchemaVStart(ctxt));
28157: }
28158: 
28159: /**
28160:  * xmlSchemaValidateDoc:
28161:  * @ctxt:  a schema validation context
28162:  * @doc:  a parsed document tree
28163:  *
28164:  * Validate a document tree in memory.
28165:  *
28166:  * Returns 0 if the document is schemas valid, a positive error code
28167:  *     number otherwise and -1 in case of internal or API error.
28168:  */
28169: int
28170: xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28171: {
28172:     if ((ctxt == NULL) || (doc == NULL))
28173:         return (-1);
28174: 
28175:     ctxt->doc = doc;
28176:     ctxt->node = xmlDocGetRootElement(doc);
28177:     if (ctxt->node == NULL) {
28178:         xmlSchemaCustomErr(ACTXT_CAST ctxt,
28179: 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28180: 	    (xmlNodePtr) doc, NULL,
28181: 	    "The document has no document element", NULL, NULL);
28182:         return (ctxt->err);
28183:     }
28184:     ctxt->validationRoot = ctxt->node;
28185:     return (xmlSchemaVStart(ctxt));
28186: }
28187: 
28188: 
28189: /************************************************************************
28190:  *									*
28191:  *		Function and data for SAX streaming API			*
28192:  *									*
28193:  ************************************************************************/
28194: typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28195: typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28196: 
28197: struct _xmlSchemaSplitSAXData {
28198:     xmlSAXHandlerPtr      user_sax;
28199:     void                 *user_data;
28200:     xmlSchemaValidCtxtPtr ctxt;
28201:     xmlSAXHandlerPtr      schemas_sax;
28202: };
28203: 
28204: #define XML_SAX_PLUG_MAGIC 0xdc43ba21
28205: 
28206: struct _xmlSchemaSAXPlug {
28207:     unsigned int magic;
28208: 
28209:     /* the original callbacks informations */
28210:     xmlSAXHandlerPtr     *user_sax_ptr;
28211:     xmlSAXHandlerPtr      user_sax;
28212:     void                **user_data_ptr;
28213:     void                 *user_data;
28214: 
28215:     /* the block plugged back and validation informations */
28216:     xmlSAXHandler         schemas_sax;
28217:     xmlSchemaValidCtxtPtr ctxt;
28218: };
28219: 
28220: /* All those functions just bounces to the user provided SAX handlers */
28221: static void
28222: internalSubsetSplit(void *ctx, const xmlChar *name,
28223: 	       const xmlChar *ExternalID, const xmlChar *SystemID)
28224: {
28225:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28226:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28227:         (ctxt->user_sax->internalSubset != NULL))
28228: 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28229: 	                               SystemID);
28230: }
28231: 
28232: static int
28233: isStandaloneSplit(void *ctx)
28234: {
28235:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28236:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28237:         (ctxt->user_sax->isStandalone != NULL))
28238: 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
28239:     return(0);
28240: }
28241: 
28242: static int
28243: hasInternalSubsetSplit(void *ctx)
28244: {
28245:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28246:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28247:         (ctxt->user_sax->hasInternalSubset != NULL))
28248: 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28249:     return(0);
28250: }
28251: 
28252: static int
28253: hasExternalSubsetSplit(void *ctx)
28254: {
28255:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28256:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28257:         (ctxt->user_sax->hasExternalSubset != NULL))
28258: 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28259:     return(0);
28260: }
28261: 
28262: static void
28263: externalSubsetSplit(void *ctx, const xmlChar *name,
28264: 	       const xmlChar *ExternalID, const xmlChar *SystemID)
28265: {
28266:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28267:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28268:         (ctxt->user_sax->externalSubset != NULL))
28269: 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28270: 	                               SystemID);
28271: }
28272: 
28273: static xmlParserInputPtr
28274: resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28275: {
28276:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28277:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28278:         (ctxt->user_sax->resolveEntity != NULL))
28279: 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28280: 	                                     systemId));
28281:     return(NULL);
28282: }
28283: 
28284: static xmlEntityPtr
28285: getEntitySplit(void *ctx, const xmlChar *name)
28286: {
28287:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28288:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28289:         (ctxt->user_sax->getEntity != NULL))
28290: 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28291:     return(NULL);
28292: }
28293: 
28294: static xmlEntityPtr
28295: getParameterEntitySplit(void *ctx, const xmlChar *name)
28296: {
28297:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28298:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28299:         (ctxt->user_sax->getParameterEntity != NULL))
28300: 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28301:     return(NULL);
28302: }
28303: 
28304: 
28305: static void
28306: entityDeclSplit(void *ctx, const xmlChar *name, int type,
28307:           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28308: {
28309:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28310:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28311:         (ctxt->user_sax->entityDecl != NULL))
28312: 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28313: 	                           systemId, content);
28314: }
28315: 
28316: static void
28317: attributeDeclSplit(void *ctx, const xmlChar * elem,
28318:                    const xmlChar * name, int type, int def,
28319:                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
28320: {
28321:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28322:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28323:         (ctxt->user_sax->attributeDecl != NULL)) {
28324: 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28325: 	                              def, defaultValue, tree);
28326:     } else {
28327: 	xmlFreeEnumeration(tree);
28328:     }
28329: }
28330: 
28331: static void
28332: elementDeclSplit(void *ctx, const xmlChar *name, int type,
28333: 	    xmlElementContentPtr content)
28334: {
28335:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28336:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28337:         (ctxt->user_sax->elementDecl != NULL))
28338: 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28339: }
28340: 
28341: static void
28342: notationDeclSplit(void *ctx, const xmlChar *name,
28343: 	     const xmlChar *publicId, const xmlChar *systemId)
28344: {
28345:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28346:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28347:         (ctxt->user_sax->notationDecl != NULL))
28348: 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28349: 	                             systemId);
28350: }
28351: 
28352: static void
28353: unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28354: 		   const xmlChar *publicId, const xmlChar *systemId,
28355: 		   const xmlChar *notationName)
28356: {
28357:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28358:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28359:         (ctxt->user_sax->unparsedEntityDecl != NULL))
28360: 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28361: 	                                   systemId, notationName);
28362: }
28363: 
28364: static void
28365: setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28366: {
28367:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28368:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28369:         (ctxt->user_sax->setDocumentLocator != NULL))
28370: 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28371: }
28372: 
28373: static void
28374: startDocumentSplit(void *ctx)
28375: {
28376:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28377:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28378:         (ctxt->user_sax->startDocument != NULL))
28379: 	ctxt->user_sax->startDocument(ctxt->user_data);
28380: }
28381: 
28382: static void
28383: endDocumentSplit(void *ctx)
28384: {
28385:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28386:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28387:         (ctxt->user_sax->endDocument != NULL))
28388: 	ctxt->user_sax->endDocument(ctxt->user_data);
28389: }
28390: 
28391: static void
28392: processingInstructionSplit(void *ctx, const xmlChar *target,
28393:                       const xmlChar *data)
28394: {
28395:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28396:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28397:         (ctxt->user_sax->processingInstruction != NULL))
28398: 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28399: }
28400: 
28401: static void
28402: commentSplit(void *ctx, const xmlChar *value)
28403: {
28404:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28405:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28406:         (ctxt->user_sax->comment != NULL))
28407: 	ctxt->user_sax->comment(ctxt->user_data, value);
28408: }
28409: 
28410: /*
28411:  * Varargs error callbacks to the user application, harder ...
28412:  */
28413: 
28414: static void XMLCDECL
28415: warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28416:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28417:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28418:         (ctxt->user_sax->warning != NULL)) {
28419: 	TODO
28420:     }
28421: }
28422: static void XMLCDECL
28423: errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28424:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28425:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28426:         (ctxt->user_sax->error != NULL)) {
28427: 	TODO
28428:     }
28429: }
28430: static void XMLCDECL
28431: fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28432:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28433:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28434:         (ctxt->user_sax->fatalError != NULL)) {
28435: 	TODO
28436:     }
28437: }
28438: 
28439: /*
28440:  * Those are function where both the user handler and the schemas handler
28441:  * need to be called.
28442:  */
28443: static void
28444: charactersSplit(void *ctx, const xmlChar *ch, int len)
28445: {
28446:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28447:     if (ctxt == NULL)
28448:         return;
28449:     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28450: 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
28451:     if (ctxt->ctxt != NULL)
28452: 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28453: }
28454: 
28455: static void
28456: ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28457: {
28458:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28459:     if (ctxt == NULL)
28460:         return;
28461:     if ((ctxt->user_sax != NULL) &&
28462:         (ctxt->user_sax->ignorableWhitespace != NULL))
28463: 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28464:     if (ctxt->ctxt != NULL)
28465: 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28466: }
28467: 
28468: static void
28469: cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28470: {
28471:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28472:     if (ctxt == NULL)
28473:         return;
28474:     if ((ctxt->user_sax != NULL) &&
28475:         (ctxt->user_sax->cdataBlock != NULL))
28476: 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28477:     if (ctxt->ctxt != NULL)
28478: 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28479: }
28480: 
28481: static void
28482: referenceSplit(void *ctx, const xmlChar *name)
28483: {
28484:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28485:     if (ctxt == NULL)
28486:         return;
28487:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28488:         (ctxt->user_sax->reference != NULL))
28489: 	ctxt->user_sax->reference(ctxt->user_data, name);
28490:     if (ctxt->ctxt != NULL)
28491:         xmlSchemaSAXHandleReference(ctxt->user_data, name);
28492: }
28493: 
28494: static void
28495: startElementNsSplit(void *ctx, const xmlChar * localname,
28496: 		    const xmlChar * prefix, const xmlChar * URI,
28497: 		    int nb_namespaces, const xmlChar ** namespaces,
28498: 		    int nb_attributes, int nb_defaulted,
28499: 		    const xmlChar ** attributes) {
28500:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28501:     if (ctxt == NULL)
28502:         return;
28503:     if ((ctxt->user_sax != NULL) &&
28504:         (ctxt->user_sax->startElementNs != NULL))
28505: 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28506: 	                               URI, nb_namespaces, namespaces,
28507: 				       nb_attributes, nb_defaulted,
28508: 				       attributes);
28509:     if (ctxt->ctxt != NULL)
28510: 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28511: 	                                 URI, nb_namespaces, namespaces,
28512: 					 nb_attributes, nb_defaulted,
28513: 					 attributes);
28514: }
28515: 
28516: static void
28517: endElementNsSplit(void *ctx, const xmlChar * localname,
28518: 		    const xmlChar * prefix, const xmlChar * URI) {
28519:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28520:     if (ctxt == NULL)
28521:         return;
28522:     if ((ctxt->user_sax != NULL) &&
28523:         (ctxt->user_sax->endElementNs != NULL))
28524: 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28525:     if (ctxt->ctxt != NULL)
28526: 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28527: }
28528: 
28529: /**
28530:  * xmlSchemaSAXPlug:
28531:  * @ctxt:  a schema validation context
28532:  * @sax:  a pointer to the original xmlSAXHandlerPtr
28533:  * @user_data:  a pointer to the original SAX user data pointer
28534:  *
28535:  * Plug a SAX based validation layer in a SAX parsing event flow.
28536:  * The original @saxptr and @dataptr data are replaced by new pointers
28537:  * but the calls to the original will be maintained.
28538:  *
28539:  * Returns a pointer to a data structure needed to unplug the validation layer
28540:  *         or NULL in case of errors.
28541:  */
28542: xmlSchemaSAXPlugPtr
28543: xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28544: 		 xmlSAXHandlerPtr *sax, void **user_data)
28545: {
28546:     xmlSchemaSAXPlugPtr ret;
28547:     xmlSAXHandlerPtr old_sax;
28548: 
28549:     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28550:         return(NULL);
28551: 
28552:     /*
28553:      * We only allow to plug into SAX2 event streams
28554:      */
28555:     old_sax = *sax;
28556:     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28557:         return(NULL);
28558:     if ((old_sax != NULL) &&
28559:         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28560:         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28561:         return(NULL);
28562: 
28563:     /*
28564:      * everything seems right allocate the local data needed for that layer
28565:      */
28566:     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28567:     if (ret == NULL) {
28568:         return(NULL);
28569:     }
28570:     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28571:     ret->magic = XML_SAX_PLUG_MAGIC;
28572:     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28573:     ret->ctxt = ctxt;
28574:     ret->user_sax_ptr = sax;
28575:     ret->user_sax = old_sax;
28576:     if (old_sax == NULL) {
28577:         /*
28578: 	 * go direct, no need for the split block and functions.
28579: 	 */
28580: 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28581: 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28582: 	/*
28583: 	 * Note that we use the same text-function for both, to prevent
28584: 	 * the parser from testing for ignorable whitespace.
28585: 	 */
28586: 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28587: 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28588: 
28589: 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28590: 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28591: 
28592: 	ret->user_data = ctxt;
28593: 	*user_data = ctxt;
28594:     } else {
28595:        /*
28596:         * for each callback unused by Schemas initialize it to the Split
28597: 	* routine only if non NULL in the user block, this can speed up
28598: 	* things at the SAX level.
28599: 	*/
28600:         if (old_sax->internalSubset != NULL)
28601:             ret->schemas_sax.internalSubset = internalSubsetSplit;
28602:         if (old_sax->isStandalone != NULL)
28603:             ret->schemas_sax.isStandalone = isStandaloneSplit;
28604:         if (old_sax->hasInternalSubset != NULL)
28605:             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28606:         if (old_sax->hasExternalSubset != NULL)
28607:             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28608:         if (old_sax->resolveEntity != NULL)
28609:             ret->schemas_sax.resolveEntity = resolveEntitySplit;
28610:         if (old_sax->getEntity != NULL)
28611:             ret->schemas_sax.getEntity = getEntitySplit;
28612:         if (old_sax->entityDecl != NULL)
28613:             ret->schemas_sax.entityDecl = entityDeclSplit;
28614:         if (old_sax->notationDecl != NULL)
28615:             ret->schemas_sax.notationDecl = notationDeclSplit;
28616:         if (old_sax->attributeDecl != NULL)
28617:             ret->schemas_sax.attributeDecl = attributeDeclSplit;
28618:         if (old_sax->elementDecl != NULL)
28619:             ret->schemas_sax.elementDecl = elementDeclSplit;
28620:         if (old_sax->unparsedEntityDecl != NULL)
28621:             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28622:         if (old_sax->setDocumentLocator != NULL)
28623:             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28624:         if (old_sax->startDocument != NULL)
28625:             ret->schemas_sax.startDocument = startDocumentSplit;
28626:         if (old_sax->endDocument != NULL)
28627:             ret->schemas_sax.endDocument = endDocumentSplit;
28628:         if (old_sax->processingInstruction != NULL)
28629:             ret->schemas_sax.processingInstruction = processingInstructionSplit;
28630:         if (old_sax->comment != NULL)
28631:             ret->schemas_sax.comment = commentSplit;
28632:         if (old_sax->warning != NULL)
28633:             ret->schemas_sax.warning = warningSplit;
28634:         if (old_sax->error != NULL)
28635:             ret->schemas_sax.error = errorSplit;
28636:         if (old_sax->fatalError != NULL)
28637:             ret->schemas_sax.fatalError = fatalErrorSplit;
28638:         if (old_sax->getParameterEntity != NULL)
28639:             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28640:         if (old_sax->externalSubset != NULL)
28641:             ret->schemas_sax.externalSubset = externalSubsetSplit;
28642: 
28643: 	/*
28644: 	 * the 6 schemas callback have to go to the splitter functions
28645: 	 * Note that we use the same text-function for ignorableWhitespace
28646: 	 * if possible, to prevent the parser from testing for ignorable
28647: 	 * whitespace.
28648: 	 */
28649:         ret->schemas_sax.characters = charactersSplit;
28650: 	if ((old_sax->ignorableWhitespace != NULL) &&
28651: 	    (old_sax->ignorableWhitespace != old_sax->characters))
28652: 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28653: 	else
28654: 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
28655:         ret->schemas_sax.cdataBlock = cdataBlockSplit;
28656:         ret->schemas_sax.reference = referenceSplit;
28657:         ret->schemas_sax.startElementNs = startElementNsSplit;
28658:         ret->schemas_sax.endElementNs = endElementNsSplit;
28659: 
28660: 	ret->user_data_ptr = user_data;
28661: 	ret->user_data = *user_data;
28662: 	*user_data = ret;
28663:     }
28664: 
28665:     /*
28666:      * plug the pointers back.
28667:      */
28668:     *sax = &(ret->schemas_sax);
28669:     ctxt->sax = *sax;
28670:     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28671:     xmlSchemaPreRun(ctxt);
28672:     return(ret);
28673: }
28674: 
28675: /**
28676:  * xmlSchemaSAXUnplug:
28677:  * @plug:  a data structure returned by xmlSchemaSAXPlug
28678:  *
28679:  * Unplug a SAX based validation layer in a SAX parsing event flow.
28680:  * The original pointers used in the call are restored.
28681:  *
28682:  * Returns 0 in case of success and -1 in case of failure.
28683:  */
28684: int
28685: xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28686: {
28687:     xmlSAXHandlerPtr *sax;
28688:     void **user_data;
28689: 
28690:     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28691:         return(-1);
28692:     plug->magic = 0;
28693: 
28694:     xmlSchemaPostRun(plug->ctxt);
28695:     /* restore the data */
28696:     sax = plug->user_sax_ptr;
28697:     *sax = plug->user_sax;
28698:     if (plug->user_sax != NULL) {
28699: 	user_data = plug->user_data_ptr;
28700: 	*user_data = plug->user_data;
28701:     }
28702: 
28703:     /* free and return */
28704:     xmlFree(plug);
28705:     return(0);
28706: }
28707: 
28708: /**
28709:  * xmlSchemaValidateSetLocator:
28710:  * @vctxt: a schema validation context
28711:  * @f: the locator function pointer
28712:  * @ctxt: the locator context
28713:  *
28714:  * Allows to set a locator function to the validation context,
28715:  * which will be used to provide file and line information since
28716:  * those are not provided as part of the SAX validation flow
28717:  * Setting @f to NULL disable the locator.
28718:  */
28719: 
28720: void
28721: xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
28722:                             xmlSchemaValidityLocatorFunc f,
28723: 			    void *ctxt)
28724: {
28725:     if (vctxt == NULL) return;
28726:     vctxt->locFunc = f;
28727:     vctxt->locCtxt = ctxt;
28728: }
28729: 
28730: /**
28731:  * xmlSchemaValidateStreamLocator:
28732:  * @ctx: the xmlTextReaderPtr used
28733:  * @file: returned file information
28734:  * @line: returned line information
28735:  *
28736:  * Internal locator function for the readers
28737:  *
28738:  * Returns 0 in case the Schema validation could be (des)activated and
28739:  *         -1 in case of error.
28740:  */
28741: static int
28742: xmlSchemaValidateStreamLocator(void *ctx, const char **file,
28743:                                unsigned long *line) {
28744:     xmlParserCtxtPtr ctxt;
28745: 
28746:     if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
28747:         return(-1);
28748: 
28749:     if (file != NULL)
28750:         *file = NULL;
28751:     if (line != NULL)
28752:         *line = 0;
28753: 
28754:     ctxt = (xmlParserCtxtPtr) ctx;
28755:     if (ctxt->input != NULL) {
28756:        if (file != NULL)
28757:            *file = ctxt->input->filename;
28758:        if (line != NULL)
28759:            *line = ctxt->input->line;
28760:        return(0);
28761:     }
28762:     return(-1);
28763: }
28764: 
28765: /**
28766:  * xmlSchemaValidateStream:
28767:  * @ctxt:  a schema validation context
28768:  * @input:  the input to use for reading the data
28769:  * @enc:  an optional encoding information
28770:  * @sax:  a SAX handler for the resulting events
28771:  * @user_data:  the context to provide to the SAX handler.
28772:  *
28773:  * Validate an input based on a flow of SAX event from the parser
28774:  * and forward the events to the @sax handler with the provided @user_data
28775:  * the user provided @sax handler must be a SAX2 one.
28776:  *
28777:  * Returns 0 if the document is schemas valid, a positive error code
28778:  *     number otherwise and -1 in case of internal or API error.
28779:  */
28780: int
28781: xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28782:                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
28783:                         xmlSAXHandlerPtr sax, void *user_data)
28784: {
28785:     xmlSchemaSAXPlugPtr plug = NULL;
28786:     xmlSAXHandlerPtr old_sax = NULL;
28787:     xmlParserCtxtPtr pctxt = NULL;
28788:     xmlParserInputPtr inputStream = NULL;
28789:     int ret;
28790: 
28791:     if ((ctxt == NULL) || (input == NULL))
28792:         return (-1);
28793: 
28794:     /*
28795:      * prepare the parser
28796:      */
28797:     pctxt = xmlNewParserCtxt();
28798:     if (pctxt == NULL)
28799:         return (-1);
28800:     old_sax = pctxt->sax;
28801:     pctxt->sax = sax;
28802:     pctxt->userData = user_data;
28803: #if 0
28804:     if (options)
28805:         xmlCtxtUseOptions(pctxt, options);
28806: #endif
28807:     pctxt->linenumbers = 1;
28808:     xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
28809: 
28810:     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28811:     if (inputStream == NULL) {
28812:         ret = -1;
28813: 	goto done;
28814:     }
28815:     inputPush(pctxt, inputStream);
28816:     ctxt->parserCtxt = pctxt;
28817:     ctxt->input = input;
28818: 
28819:     /*
28820:      * Plug the validation and launch the parsing
28821:      */
28822:     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28823:     if (plug == NULL) {
28824:         ret = -1;
28825: 	goto done;
28826:     }
28827:     ctxt->input = input;
28828:     ctxt->enc = enc;
28829:     ctxt->sax = pctxt->sax;
28830:     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28831:     ret = xmlSchemaVStart(ctxt);
28832: 
28833:     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28834: 	ret = ctxt->parserCtxt->errNo;
28835: 	if (ret == 0)
28836: 	    ret = 1;
28837:     }
28838: 
28839: done:
28840:     ctxt->parserCtxt = NULL;
28841:     ctxt->sax = NULL;
28842:     ctxt->input = NULL;
28843:     if (plug != NULL) {
28844:         xmlSchemaSAXUnplug(plug);
28845:     }
28846:     /* cleanup */
28847:     if (pctxt != NULL) {
28848: 	pctxt->sax = old_sax;
28849: 	xmlFreeParserCtxt(pctxt);
28850:     }
28851:     return (ret);
28852: }
28853: 
28854: /**
28855:  * xmlSchemaValidateFile:
28856:  * @ctxt: a schema validation context
28857:  * @filename: the URI of the instance
28858:  * @options: a future set of options, currently unused
28859:  *
28860:  * Do a schemas validation of the given resource, it will use the
28861:  * SAX streamable validation internally.
28862:  *
28863:  * Returns 0 if the document is valid, a positive error code
28864:  *     number otherwise and -1 in case of an internal or API error.
28865:  */
28866: int
28867: xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28868:                       const char * filename,
28869: 		      int options ATTRIBUTE_UNUSED)
28870: {
28871:     int ret;
28872:     xmlParserInputBufferPtr input;
28873: 
28874:     if ((ctxt == NULL) || (filename == NULL))
28875:         return (-1);
28876: 
28877:     input = xmlParserInputBufferCreateFilename(filename,
28878: 	XML_CHAR_ENCODING_NONE);
28879:     if (input == NULL)
28880: 	return (-1);
28881:     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
28882: 	NULL, NULL);
28883:     return (ret);
28884: }
28885: 
28886: /**
28887:  * xmlSchemaValidCtxtGetParserCtxt:
28888:  * @ctxt: a schema validation context
28889:  *
28890:  * allow access to the parser context of the schema validation context
28891:  *
28892:  * Returns the parser context of the schema validation context or NULL
28893:  *         in case of error.
28894:  */
28895: xmlParserCtxtPtr
28896: xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28897: {
28898:     if (ctxt == NULL)
28899:         return(NULL);
28900:     return (ctxt->parserCtxt);
28901: }
28902: 
28903: #define bottom_xmlschemas
28904: #include "elfgcchack.h"
28905: #endif /* LIBXML_SCHEMAS_ENABLED */

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