File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libxml2 / xmlschemas.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:22:18 2013 UTC (10 years, 11 months ago) by misho
Branches: libxml2, MAIN
CVS tags: v2_8_0p0, v2_8_0, HEAD
2.8.0

    1: /*
    2:  * schemas.c : implementation of the XML Schema handling and
    3:  *             schema validity checking
    4:  *
    5:  * See Copyright for the status of this software.
    6:  *
    7:  * Daniel Veillard <veillard@redhat.com>
    8:  */
    9: 
   10: /*
   11:  * TODO:
   12:  *   - when types are redefined in includes, check that all
   13:  *     types in the redef list are equal
   14:  *     -> need a type equality operation.
   15:  *   - if we don't intend to use the schema for schemas, we
   16:  *     need to validate all schema attributes (ref, type, name)
   17:  *     against their types.
   18:  *   - Eliminate item creation for: ??
   19:  *
   20:  * URGENT TODO:
   21:  *   - For xsi-driven schema acquisition, augment the IDCs after every
   22:  *     acquisition episode (xmlSchemaAugmentIDC).
   23:  *
   24:  * NOTES:
   25:  *   - Elimated item creation for: <restriction>, <extension>,
   26:  *     <simpleContent>, <complexContent>, <list>, <union>
   27:  *
   28:  * PROBLEMS:
   29:  *   - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
   30:  *     IDC XPath expression and chameleon includes: the targetNamespace is changed, so
   31:  *     XPath will have trouble to resolve to this namespace, since not known.
   32:  *
   33:  *
   34:  * CONSTRAINTS:
   35:  *
   36:  * Schema Component Constraint:
   37:  *   All Group Limited (cos-all-limited)
   38:  *   Status: complete
   39:  *   (1.2)
   40:  *     In xmlSchemaGroupDefReferenceTermFixup() and
   41:  *   (2)
   42:  *     In xmlSchemaParseModelGroup()
   43:  *     TODO: Actually this should go to component-level checks,
   44:  *     but is done here due to performance. Move it to an other layer
   45:  *     is schema construction via an API is implemented.
   46:  */
   47: #define IN_LIBXML
   48: #include "libxml.h"
   49: 
   50: #ifdef LIBXML_SCHEMAS_ENABLED
   51: 
   52: #include <string.h>
   53: #include <libxml/xmlmemory.h>
   54: #include <libxml/parser.h>
   55: #include <libxml/parserInternals.h>
   56: #include <libxml/hash.h>
   57: #include <libxml/uri.h>
   58: #include <libxml/xmlschemas.h>
   59: #include <libxml/schemasInternals.h>
   60: #include <libxml/xmlschemastypes.h>
   61: #include <libxml/xmlautomata.h>
   62: #include <libxml/xmlregexp.h>
   63: #include <libxml/dict.h>
   64: #include <libxml/encoding.h>
   65: #include <libxml/xmlIO.h>
   66: #ifdef LIBXML_PATTERN_ENABLED
   67: #include <libxml/pattern.h>
   68: #endif
   69: #ifdef LIBXML_READER_ENABLED
   70: #include <libxml/xmlreader.h>
   71: #endif
   72: 
   73: /* #define DEBUG 1 */
   74: 
   75: /* #define DEBUG_CONTENT 1 */
   76: 
   77: /* #define DEBUG_TYPE 1 */
   78: 
   79: /* #define DEBUG_CONTENT_REGEXP 1 */
   80: 
   81: /* #define DEBUG_AUTOMATA 1 */
   82: 
   83: /* #define DEBUG_IDC */
   84: 
   85: /* #define DEBUG_IDC_NODE_TABLE */
   86: 
   87: /* #define WXS_ELEM_DECL_CONS_ENABLED */
   88: 
   89: #ifdef DEBUG_IDC
   90:  #ifndef DEBUG_IDC_NODE_TABLE
   91:   #define DEBUG_IDC_NODE_TABLE
   92:  #endif
   93: #endif
   94: 
   95: /* #define ENABLE_PARTICLE_RESTRICTION 1 */
   96: 
   97: #define ENABLE_REDEFINE
   98: 
   99: /* #define ENABLE_NAMED_LOCALS */
  100: 
  101: /* #define ENABLE_IDC_NODE_TABLES_TEST */
  102: 
  103: #define DUMP_CONTENT_MODEL
  104: 
  105: #ifdef LIBXML_READER_ENABLED
  106: /* #define XML_SCHEMA_READER_ENABLED */
  107: #endif
  108: 
  109: #define UNBOUNDED (1 << 30)
  110: #define TODO 								\
  111:     xmlGenericError(xmlGenericErrorContext,				\
  112: 	    "Unimplemented block at %s:%d\n",				\
  113:             __FILE__, __LINE__);
  114: 
  115: #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  116: 
  117: /*
  118:  * The XML Schemas namespaces
  119:  */
  120: static const xmlChar *xmlSchemaNs = (const xmlChar *)
  121:     "http://www.w3.org/2001/XMLSchema";
  122: 
  123: static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  124:     "http://www.w3.org/2001/XMLSchema-instance";
  125: 
  126: static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  127:     "http://www.w3.org/2000/xmlns/";
  128: 
  129: /*
  130: * Come casting macros.
  131: */
  132: #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  133: #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  134: #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  135: #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  136: #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  137: #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  138: #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  139: #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  140: #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  141: #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  142: #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  143: #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  144: #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  145: #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  146: #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  147: #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  148: #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  149: 
  150: /*
  151: * Macros to query common properties of components.
  152: */
  153: #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  154: 
  155: #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  156: /*
  157: * Macros for element declarations.
  158: */
  159: #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  160: 
  161: #define WXS_SUBST_HEAD(item) (item)->refDecl
  162: /*
  163: * Macros for attribute declarations.
  164: */
  165: #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  166: /*
  167: * Macros for attribute uses.
  168: */
  169: #define WXS_ATTRUSE_DECL(au) WXS_ATTR_CAST (WXS_ATTR_USE_CAST (au))->attrDecl
  170: 
  171: #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  172: 
  173: #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  174: 
  175: #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  176: /*
  177: * Macros for attribute groups.
  178: */
  179: #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  180: #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  181: /*
  182: * Macros for particles.
  183: */
  184: #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  185: 
  186: #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  187: 
  188: #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  189: 
  190: #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  191: /*
  192: * Macros for model groups definitions.
  193: */
  194: #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  195: /*
  196: * Macros for model groups.
  197: */
  198: #define WXS_IS_MODEL_GROUP(i) \
  199:     (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  200:      ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  201:      ((i)->type == XML_SCHEMA_TYPE_ALL))
  202: 
  203: #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  204: /*
  205: * Macros for schema buckets.
  206: */
  207: #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  208:     ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  209: 
  210: #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  211:     ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  212: 
  213: #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  214: 
  215: #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  216: /*
  217: * Macros for complex/simple types.
  218: */
  219: #define WXS_IS_ANYTYPE(i) \
  220:      (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  221:       ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  222: 
  223: #define WXS_IS_COMPLEX(i) \
  224:     (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  225:      ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  226: 
  227: #define WXS_IS_SIMPLE(item) \
  228:     ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  229:      ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  230:       (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  231: 
  232: #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  233:     (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  234:       ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  235: 
  236: #define WXS_IS_RESTRICTION(t) \
  237:     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  238: 
  239: #define WXS_IS_EXTENSION(t) \
  240:     ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  241: 
  242: #define WXS_IS_TYPE_NOT_FIXED(i) \
  243:     (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  244:      (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  245: 
  246: #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  247:     (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  248:      (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  249: 
  250: #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  251: 
  252: #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  253: /*
  254: * Macros for exclusively for complex types.
  255: */
  256: #define WXS_HAS_COMPLEX_CONTENT(item) \
  257:     ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  258:      (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  259:      (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  260: 
  261: #define WXS_HAS_SIMPLE_CONTENT(item) \
  262:     ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  263:      (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  264: 
  265: #define WXS_HAS_MIXED_CONTENT(item) \
  266:     (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  267: 
  268: #define WXS_EMPTIABLE(t) \
  269:     (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  270: 
  271: #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  272: 
  273: #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  274: 
  275: #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  276: /*
  277: * Macros for exclusively for simple types.
  278: */
  279: #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  280: 
  281: #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  282: 
  283: #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  284: 
  285: #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  286: /*
  287: * Misc parser context macros.
  288: */
  289: #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  290: 
  291: #define WXS_HAS_BUCKETS(ctx) \
  292: ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  293: (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  294: 
  295: #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  296: 
  297: #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  298: 
  299: #define WXS_SCHEMA(ctx) (ctx)->schema
  300: 
  301: #define WXS_ADD_LOCAL(ctx, item) \
  302:     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
  303: 
  304: #define WXS_ADD_GLOBAL(ctx, item) \
  305:     xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
  306: 
  307: #define WXS_ADD_PENDING(ctx, item) \
  308:     xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  309: /*
  310: * xmlSchemaItemList macros.
  311: */
  312: #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  313: /*
  314: * Misc macros.
  315: */
  316: #define IS_SCHEMA(node, type) \
  317:    ((node != NULL) && (node->ns != NULL) && \
  318:     (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  319:     (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  320: 
  321: #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  322: 
  323: /*
  324: * Since we put the default/fixed values into the dict, we can
  325: * use pointer comparison for those values.
  326: * REMOVED: (xmlStrEqual((v1), (v2)))
  327: */
  328: #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  329: 
  330: #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  331: 
  332: #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  333: 
  334: #define HFAILURE if (res == -1) goto exit_failure;
  335: 
  336: #define HERROR if (res != 0) goto exit_error;
  337: 
  338: #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  339: /*
  340: * Some flags used for various schema constraints.
  341: */
  342: #define SUBSET_RESTRICTION  1<<0
  343: #define SUBSET_EXTENSION    1<<1
  344: #define SUBSET_SUBSTITUTION 1<<2
  345: #define SUBSET_LIST         1<<3
  346: #define SUBSET_UNION        1<<4
  347: 
  348: typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  349: typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  350: 
  351: typedef struct _xmlSchemaItemList xmlSchemaItemList;
  352: typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  353: struct _xmlSchemaItemList {
  354:     void **items;  /* used for dynamic addition of schemata */
  355:     int nbItems; /* used for dynamic addition of schemata */
  356:     int sizeItems; /* used for dynamic addition of schemata */
  357: };
  358: 
  359: #define XML_SCHEMA_CTXT_PARSER 1
  360: #define XML_SCHEMA_CTXT_VALIDATOR 2
  361: 
  362: typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  363: typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  364: struct _xmlSchemaAbstractCtxt {
  365:     int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  366: };
  367: 
  368: typedef struct _xmlSchemaBucket xmlSchemaBucket;
  369: typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  370: 
  371: #define XML_SCHEMA_SCHEMA_MAIN 0
  372: #define XML_SCHEMA_SCHEMA_IMPORT 1
  373: #define XML_SCHEMA_SCHEMA_INCLUDE 2
  374: #define XML_SCHEMA_SCHEMA_REDEFINE 3
  375: 
  376: /**
  377:  * xmlSchemaSchemaRelation:
  378:  *
  379:  * Used to create a graph of schema relationships.
  380:  */
  381: typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  382: typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  383: struct _xmlSchemaSchemaRelation {
  384:     xmlSchemaSchemaRelationPtr next;
  385:     int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  386:     const xmlChar *importNamespace;
  387:     xmlSchemaBucketPtr bucket;
  388: };
  389: 
  390: #define XML_SCHEMA_BUCKET_MARKED 1<<0
  391: #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  392: 
  393: struct _xmlSchemaBucket {
  394:     int type;
  395:     int flags;
  396:     const xmlChar *schemaLocation;
  397:     const xmlChar *origTargetNamespace;
  398:     const xmlChar *targetNamespace;
  399:     xmlDocPtr doc;
  400:     xmlSchemaSchemaRelationPtr relations;
  401:     int located;
  402:     int parsed;
  403:     int imported;
  404:     int preserveDoc;
  405:     xmlSchemaItemListPtr globals; /* Global components. */
  406:     xmlSchemaItemListPtr locals; /* Local components. */
  407: };
  408: 
  409: /**
  410:  * xmlSchemaImport:
  411:  * (extends xmlSchemaBucket)
  412:  *
  413:  * Reflects a schema. Holds some information
  414:  * about the schema and its toplevel components. Duplicate
  415:  * toplevel components are not checked at this level.
  416:  */
  417: typedef struct _xmlSchemaImport xmlSchemaImport;
  418: typedef xmlSchemaImport *xmlSchemaImportPtr;
  419: struct _xmlSchemaImport {
  420:     int type; /* Main OR import OR include. */
  421:     int flags;
  422:     const xmlChar *schemaLocation; /* The URI of the schema document. */
  423:     /* For chameleon includes, @origTargetNamespace will be NULL */
  424:     const xmlChar *origTargetNamespace;
  425:     /*
  426:     * For chameleon includes, @targetNamespace will be the
  427:     * targetNamespace of the including schema.
  428:     */
  429:     const xmlChar *targetNamespace;
  430:     xmlDocPtr doc; /* The schema node-tree. */
  431:     /* @relations will hold any included/imported/redefined schemas. */
  432:     xmlSchemaSchemaRelationPtr relations;
  433:     int located;
  434:     int parsed;
  435:     int imported;
  436:     int preserveDoc;
  437:     xmlSchemaItemListPtr globals;
  438:     xmlSchemaItemListPtr locals;
  439:     /* The imported schema. */
  440:     xmlSchemaPtr schema;
  441: };
  442: 
  443: /*
  444: * (extends xmlSchemaBucket)
  445: */
  446: typedef struct _xmlSchemaInclude xmlSchemaInclude;
  447: typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  448: struct _xmlSchemaInclude {
  449:     int type;
  450:     int flags;
  451:     const xmlChar *schemaLocation;
  452:     const xmlChar *origTargetNamespace;
  453:     const xmlChar *targetNamespace;
  454:     xmlDocPtr doc;
  455:     xmlSchemaSchemaRelationPtr relations;
  456:     int located;
  457:     int parsed;
  458:     int imported;
  459:     int preserveDoc;
  460:     xmlSchemaItemListPtr globals; /* Global components. */
  461:     xmlSchemaItemListPtr locals; /* Local components. */
  462: 
  463:     /* The owning main or import schema bucket. */
  464:     xmlSchemaImportPtr ownerImport;
  465: };
  466: 
  467: /**
  468:  * xmlSchemaBasicItem:
  469:  *
  470:  * The abstract base type for schema components.
  471:  */
  472: typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  473: typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  474: struct _xmlSchemaBasicItem {
  475:     xmlSchemaTypeType type;
  476: };
  477: 
  478: /**
  479:  * xmlSchemaAnnotItem:
  480:  *
  481:  * The abstract base type for annotated schema components.
  482:  * (Extends xmlSchemaBasicItem)
  483:  */
  484: typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  485: typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  486: struct _xmlSchemaAnnotItem {
  487:     xmlSchemaTypeType type;
  488:     xmlSchemaAnnotPtr annot;
  489: };
  490: 
  491: /**
  492:  * xmlSchemaTreeItem:
  493:  *
  494:  * The abstract base type for tree-like structured schema components.
  495:  * (Extends xmlSchemaAnnotItem)
  496:  */
  497: typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  498: typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  499: struct _xmlSchemaTreeItem {
  500:     xmlSchemaTypeType type;
  501:     xmlSchemaAnnotPtr annot;
  502:     xmlSchemaTreeItemPtr next;
  503:     xmlSchemaTreeItemPtr children;
  504: };
  505: 
  506: 
  507: #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  508: /**
  509:  * xmlSchemaAttributeUsePtr:
  510:  *
  511:  * The abstract base type for tree-like structured schema components.
  512:  * (Extends xmlSchemaTreeItem)
  513:  */
  514: typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  515: typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  516: struct _xmlSchemaAttributeUse {
  517:     xmlSchemaTypeType type;
  518:     xmlSchemaAnnotPtr annot;
  519:     xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  520:     /*
  521:     * The attr. decl. OR a QName-ref. to an attr. decl. OR
  522:     * a QName-ref. to an attribute group definition.
  523:     */
  524:     xmlSchemaAttributePtr attrDecl;
  525: 
  526:     int flags;
  527:     xmlNodePtr node;
  528:     int occurs; /* required, optional */
  529:     const xmlChar * defValue;
  530:     xmlSchemaValPtr defVal;
  531: };
  532: 
  533: /**
  534:  * xmlSchemaAttributeUseProhibPtr:
  535:  *
  536:  * A helper component to reflect attribute prohibitions.
  537:  * (Extends xmlSchemaBasicItem)
  538:  */
  539: typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  540: typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  541: struct _xmlSchemaAttributeUseProhib {
  542:     xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  543:     xmlNodePtr node;
  544:     const xmlChar *name;
  545:     const xmlChar *targetNamespace;
  546:     int isRef;
  547: };
  548: 
  549: /**
  550:  * xmlSchemaRedef:
  551:  */
  552: typedef struct _xmlSchemaRedef xmlSchemaRedef;
  553: typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  554: struct _xmlSchemaRedef {
  555:     xmlSchemaRedefPtr next;
  556:     xmlSchemaBasicItemPtr item; /* The redefining component. */
  557:     xmlSchemaBasicItemPtr reference; /* The referencing component. */
  558:     xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  559:     const xmlChar *refName; /* The name of the to-be-redefined component. */
  560:     const xmlChar *refTargetNs; /* The target namespace of the
  561:                                    to-be-redefined comp. */
  562:     xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  563: };
  564: 
  565: /**
  566:  * xmlSchemaConstructionCtxt:
  567:  */
  568: typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  569: typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  570: struct _xmlSchemaConstructionCtxt {
  571:     xmlSchemaPtr mainSchema; /* The main schema. */
  572:     xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  573:     xmlDictPtr dict;
  574:     xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  575:     /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  576:     xmlSchemaBucketPtr bucket; /* The current schema bucket */
  577:     xmlSchemaItemListPtr pending; /* All Components of all schemas that
  578:                                      need to be fixed. */
  579:     xmlHashTablePtr substGroups;
  580:     xmlSchemaRedefPtr redefs;
  581:     xmlSchemaRedefPtr lastRedef;
  582: };
  583: 
  584: #define XML_SCHEMAS_PARSE_ERROR		1
  585: #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  586: 
  587: struct _xmlSchemaParserCtxt {
  588:     int type;
  589:     void *errCtxt;             /* user specific error context */
  590:     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
  591:     xmlSchemaValidityWarningFunc warning;       /* the callback in case of warning */
  592:     int err;
  593:     int nberrors;
  594:     xmlStructuredErrorFunc serror;
  595: 
  596:     xmlSchemaConstructionCtxtPtr constructor;
  597:     int ownsConstructor; /* TODO: Move this to parser *flags*. */
  598: 
  599:     /* xmlSchemaPtr topschema;	*/
  600:     /* xmlHashTablePtr namespaces;  */
  601: 
  602:     xmlSchemaPtr schema;        /* The main schema in use */
  603:     int counter;
  604: 
  605:     const xmlChar *URL;
  606:     xmlDocPtr doc;
  607:     int preserve;		/* Whether the doc should be freed  */
  608: 
  609:     const char *buffer;
  610:     int size;
  611: 
  612:     /*
  613:      * Used to build complex element content models
  614:      */
  615:     xmlAutomataPtr am;
  616:     xmlAutomataStatePtr start;
  617:     xmlAutomataStatePtr end;
  618:     xmlAutomataStatePtr state;
  619: 
  620:     xmlDictPtr dict;		/* dictionnary for interned string names */
  621:     xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  622:     int options;
  623:     xmlSchemaValidCtxtPtr vctxt;
  624:     int isS4S;
  625:     int isRedefine;
  626:     int xsiAssemble;
  627:     int stop; /* If the parser should stop; i.e. a critical error. */
  628:     const xmlChar *targetNamespace;
  629:     xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  630: 
  631:     xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  632:     int redefCounter; /* Used for redefinitions. */
  633:     xmlSchemaItemListPtr attrProhibs;
  634: };
  635: 
  636: /**
  637:  * xmlSchemaQNameRef:
  638:  *
  639:  * A component reference item (not a schema component)
  640:  * (Extends xmlSchemaBasicItem)
  641:  */
  642: typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  643: typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  644: struct _xmlSchemaQNameRef {
  645:     xmlSchemaTypeType type;
  646:     xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  647:     xmlSchemaTypeType itemType;
  648:     const xmlChar *name;
  649:     const xmlChar *targetNamespace;
  650:     xmlNodePtr node;
  651: };
  652: 
  653: /**
  654:  * xmlSchemaParticle:
  655:  *
  656:  * A particle component.
  657:  * (Extends xmlSchemaTreeItem)
  658:  */
  659: typedef struct _xmlSchemaParticle xmlSchemaParticle;
  660: typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  661: struct _xmlSchemaParticle {
  662:     xmlSchemaTypeType type;
  663:     xmlSchemaAnnotPtr annot;
  664:     xmlSchemaTreeItemPtr next; /* next particle */
  665:     xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  666: 	a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  667:         etc.) */
  668:     int minOccurs;
  669:     int maxOccurs;
  670:     xmlNodePtr node;
  671: };
  672: 
  673: /**
  674:  * xmlSchemaModelGroup:
  675:  *
  676:  * A model group component.
  677:  * (Extends xmlSchemaTreeItem)
  678:  */
  679: typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  680: typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  681: struct _xmlSchemaModelGroup {
  682:     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  683:     xmlSchemaAnnotPtr annot;
  684:     xmlSchemaTreeItemPtr next; /* not used */
  685:     xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  686:     xmlNodePtr node;
  687: };
  688: 
  689: #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  690: #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  691: /**
  692:  * xmlSchemaModelGroupDef:
  693:  *
  694:  * A model group definition component.
  695:  * (Extends xmlSchemaTreeItem)
  696:  */
  697: typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  698: typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  699: struct _xmlSchemaModelGroupDef {
  700:     xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  701:     xmlSchemaAnnotPtr annot;
  702:     xmlSchemaTreeItemPtr next; /* not used */
  703:     xmlSchemaTreeItemPtr children; /* the "model group" */
  704:     const xmlChar *name;
  705:     const xmlChar *targetNamespace;
  706:     xmlNodePtr node;
  707:     int flags;
  708: };
  709: 
  710: typedef struct _xmlSchemaIDC xmlSchemaIDC;
  711: typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  712: 
  713: /**
  714:  * xmlSchemaIDCSelect:
  715:  *
  716:  * The identity-constraint "field" and "selector" item, holding the
  717:  * XPath expression.
  718:  */
  719: typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  720: typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  721: struct _xmlSchemaIDCSelect {
  722:     xmlSchemaIDCSelectPtr next;
  723:     xmlSchemaIDCPtr idc;
  724:     int index; /* an index position if significant for IDC key-sequences */
  725:     const xmlChar *xpath; /* the XPath expression */
  726:     void *xpathComp; /* the compiled XPath expression */
  727: };
  728: 
  729: /**
  730:  * xmlSchemaIDC:
  731:  *
  732:  * The identity-constraint definition component.
  733:  * (Extends xmlSchemaAnnotItem)
  734:  */
  735: 
  736: struct _xmlSchemaIDC {
  737:     xmlSchemaTypeType type;
  738:     xmlSchemaAnnotPtr annot;
  739:     xmlSchemaIDCPtr next;
  740:     xmlNodePtr node;
  741:     const xmlChar *name;
  742:     const xmlChar *targetNamespace;
  743:     xmlSchemaIDCSelectPtr selector;
  744:     xmlSchemaIDCSelectPtr fields;
  745:     int nbFields;
  746:     xmlSchemaQNameRefPtr ref;
  747: };
  748: 
  749: /**
  750:  * xmlSchemaIDCAug:
  751:  *
  752:  * The augmented IDC information used for validation.
  753:  */
  754: typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  755: typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  756: struct _xmlSchemaIDCAug {
  757:     xmlSchemaIDCAugPtr next; /* next in a list */
  758:     xmlSchemaIDCPtr def; /* the IDC definition */
  759:     int keyrefDepth; /* the lowest tree level to which IDC
  760:                         tables need to be bubbled upwards */
  761: };
  762: 
  763: /**
  764:  * xmlSchemaPSVIIDCKeySequence:
  765:  *
  766:  * The key sequence of a node table item.
  767:  */
  768: typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  769: typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  770: struct _xmlSchemaPSVIIDCKey {
  771:     xmlSchemaTypePtr type;
  772:     xmlSchemaValPtr val;
  773: };
  774: 
  775: /**
  776:  * xmlSchemaPSVIIDCNode:
  777:  *
  778:  * The node table item of a node table.
  779:  */
  780: typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  781: typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  782: struct _xmlSchemaPSVIIDCNode {
  783:     xmlNodePtr node;
  784:     xmlSchemaPSVIIDCKeyPtr *keys;
  785:     int nodeLine;
  786:     int nodeQNameID;
  787: 
  788: };
  789: 
  790: /**
  791:  * xmlSchemaPSVIIDCBinding:
  792:  *
  793:  * The identity-constraint binding item of the [identity-constraint table].
  794:  */
  795: typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  796: typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  797: struct _xmlSchemaPSVIIDCBinding {
  798:     xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  799:     xmlSchemaIDCPtr definition; /* the IDC definition */
  800:     xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  801:     int nbNodes; /* number of entries in the node table */
  802:     int sizeNodes; /* size of the node table */
  803:     xmlSchemaItemListPtr dupls;
  804: };
  805: 
  806: 
  807: #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  808: #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  809: 
  810: #define XPATH_STATE_OBJ_MATCHES -2
  811: #define XPATH_STATE_OBJ_BLOCKED -3
  812: 
  813: typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  814: typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  815: 
  816: /**
  817:  * xmlSchemaIDCStateObj:
  818:  *
  819:  * The state object used to evaluate XPath expressions.
  820:  */
  821: typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  822: typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  823: struct _xmlSchemaIDCStateObj {
  824:     int type;
  825:     xmlSchemaIDCStateObjPtr next; /* next if in a list */
  826:     int depth; /* depth of creation */
  827:     int *history; /* list of (depth, state-id) tuples */
  828:     int nbHistory;
  829:     int sizeHistory;
  830:     xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  831:                                        matcher */
  832:     xmlSchemaIDCSelectPtr sel;
  833:     void *xpathCtxt;
  834: };
  835: 
  836: #define IDC_MATCHER 0
  837: 
  838: /**
  839:  * xmlSchemaIDCMatcher:
  840:  *
  841:  * Used to evaluate IDC selectors (and fields).
  842:  */
  843: struct _xmlSchemaIDCMatcher {
  844:     int type;
  845:     int depth; /* the tree depth at creation time */
  846:     xmlSchemaIDCMatcherPtr next; /* next in the list */
  847:     xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  848:     xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  849:     int idcType;
  850:     xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  851:                                          elements */
  852:     int sizeKeySeqs;
  853:     xmlSchemaItemListPtr targets; /* list of target-node
  854:                                      (xmlSchemaPSVIIDCNodePtr) entries */
  855: };
  856: 
  857: /*
  858: * Element info flags.
  859: */
  860: #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES  1<<0
  861: #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  862: #define XML_SCHEMA_ELEM_INFO_NILLED	       1<<2
  863: #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE	       1<<3
  864: 
  865: #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED      1<<4
  866: #define XML_SCHEMA_ELEM_INFO_EMPTY             1<<5
  867: #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT       1<<6
  868: 
  869: #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT  1<<7
  870: #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT  1<<8
  871: #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED  1<<9
  872: #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE  1<<10
  873: 
  874: /**
  875:  * xmlSchemaNodeInfo:
  876:  *
  877:  * Holds information of an element node.
  878:  */
  879: struct _xmlSchemaNodeInfo {
  880:     int nodeType;
  881:     xmlNodePtr node;
  882:     int nodeLine;
  883:     const xmlChar *localName;
  884:     const xmlChar *nsName;
  885:     const xmlChar *value;
  886:     xmlSchemaValPtr val; /* the pre-computed value if any */
  887:     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  888: 
  889:     int flags; /* combination of node info flags */
  890: 
  891:     int valNeeded;
  892:     int normVal;
  893: 
  894:     xmlSchemaElementPtr decl; /* the element/attribute declaration */
  895:     int depth;
  896:     xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  897:                                             for the scope element*/
  898:     xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  899:                                            element */
  900:     xmlRegExecCtxtPtr regexCtxt;
  901: 
  902:     const xmlChar **nsBindings; /* Namespace bindings on this element */
  903:     int nbNsBindings;
  904:     int sizeNsBindings;
  905: 
  906:     int hasKeyrefs;
  907:     int appliedXPath; /* Indicates that an XPath has been applied. */
  908: };
  909: 
  910: #define XML_SCHEMAS_ATTR_UNKNOWN 1
  911: #define XML_SCHEMAS_ATTR_ASSESSED 2
  912: #define XML_SCHEMAS_ATTR_PROHIBITED 3
  913: #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  914: #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  915: #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  916: #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  917: #define XML_SCHEMAS_ATTR_DEFAULT 8
  918: #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  919: #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  920: #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  921: #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  922: #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  923: #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  924: #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  925: #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  926: #define XML_SCHEMAS_ATTR_META 17
  927: /*
  928: * @metaType values of xmlSchemaAttrInfo.
  929: */
  930: #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  931: #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  932: #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  933: #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  934: #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  935: 
  936: typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  937: typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  938: struct _xmlSchemaAttrInfo {
  939:     int nodeType;
  940:     xmlNodePtr node;
  941:     int nodeLine;
  942:     const xmlChar *localName;
  943:     const xmlChar *nsName;
  944:     const xmlChar *value;
  945:     xmlSchemaValPtr val; /* the pre-computed value if any */
  946:     xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  947:     int flags; /* combination of node info flags */
  948: 
  949:     xmlSchemaAttributePtr decl; /* the attribute declaration */
  950:     xmlSchemaAttributeUsePtr use;  /* the attribute use */
  951:     int state;
  952:     int metaType;
  953:     const xmlChar *vcValue; /* the value constraint value */
  954:     xmlSchemaNodeInfoPtr parent;
  955: };
  956: 
  957: 
  958: #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  959: /**
  960:  * xmlSchemaValidCtxt:
  961:  *
  962:  * A Schemas validation context
  963:  */
  964: struct _xmlSchemaValidCtxt {
  965:     int type;
  966:     void *errCtxt;             /* user specific data block */
  967:     xmlSchemaValidityErrorFunc error;   /* the callback in case of errors */
  968:     xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  969:     xmlStructuredErrorFunc serror;
  970: 
  971:     xmlSchemaPtr schema;        /* The schema in use */
  972:     xmlDocPtr doc;
  973:     xmlParserInputBufferPtr input;
  974:     xmlCharEncoding enc;
  975:     xmlSAXHandlerPtr sax;
  976:     xmlParserCtxtPtr parserCtxt;
  977:     void *user_data; /* TODO: What is this for? */
  978: 
  979:     int err;
  980:     int nberrors;
  981: 
  982:     xmlNodePtr node;
  983:     xmlNodePtr cur;
  984:     /* xmlSchemaTypePtr type; */
  985: 
  986:     xmlRegExecCtxtPtr regexp;
  987:     xmlSchemaValPtr value;
  988: 
  989:     int valueWS;
  990:     int options;
  991:     xmlNodePtr validationRoot;
  992:     xmlSchemaParserCtxtPtr pctxt;
  993:     int xsiAssemble;
  994: 
  995:     int depth;
  996:     xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
  997:     int sizeElemInfos;
  998:     xmlSchemaNodeInfoPtr inode; /* the current element information */
  999: 
 1000:     xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
 1001: 
 1002:     xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
 1003:     xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
 1004:     xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
 1005: 
 1006:     xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
 1007:     int nbIdcNodes;
 1008:     int sizeIdcNodes;
 1009: 
 1010:     xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
 1011:     int nbIdcKeys;
 1012:     int sizeIdcKeys;
 1013: 
 1014:     int flags;
 1015: 
 1016:     xmlDictPtr dict;
 1017: 
 1018: #ifdef LIBXML_READER_ENABLED
 1019:     xmlTextReaderPtr reader;
 1020: #endif
 1021: 
 1022:     xmlSchemaAttrInfoPtr *attrInfos;
 1023:     int nbAttrInfos;
 1024:     int sizeAttrInfos;
 1025: 
 1026:     int skipDepth;
 1027:     xmlSchemaItemListPtr nodeQNames;
 1028:     int hasKeyrefs;
 1029:     int createIDCNodeTables;
 1030:     int psviExposeIDCNodeTables;
 1031: };
 1032: 
 1033: /**
 1034:  * xmlSchemaSubstGroup:
 1035:  *
 1036:  *
 1037:  */
 1038: typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
 1039: typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
 1040: struct _xmlSchemaSubstGroup {
 1041:     xmlSchemaElementPtr head;
 1042:     xmlSchemaItemListPtr members;
 1043: };
 1044: 
 1045: /************************************************************************
 1046:  * 									*
 1047:  * 			Some predeclarations				*
 1048:  * 									*
 1049:  ************************************************************************/
 1050: 
 1051: static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
 1052:                                  xmlSchemaPtr schema,
 1053:                                  xmlNodePtr node);
 1054: static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
 1055:                                  xmlSchemaPtr schema,
 1056:                                  xmlNodePtr node);
 1057: static int
 1058: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
 1059:                    xmlSchemaAbstractCtxtPtr ctxt);
 1060: static const xmlChar *
 1061: xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
 1062: static int
 1063: xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 1064:                      xmlNodePtr node);
 1065: static int
 1066: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
 1067:                        xmlSchemaParserCtxtPtr ctxt);
 1068: static void
 1069: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
 1070: static xmlSchemaWhitespaceValueType
 1071: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
 1072: static xmlSchemaTreeItemPtr
 1073: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 1074: 			 xmlNodePtr node, xmlSchemaTypeType type,
 1075: 			 int withParticle);
 1076: static const xmlChar *
 1077: xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
 1078: static xmlSchemaTypeLinkPtr
 1079: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
 1080: static void
 1081: xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 1082: 		     const char *funcName,
 1083: 		     const char *message);
 1084: static int
 1085: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
 1086: 			     xmlSchemaTypePtr type,
 1087: 			     xmlSchemaTypePtr baseType,
 1088: 			     int subset);
 1089: static void
 1090: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
 1091: 				   xmlSchemaParserCtxtPtr ctxt);
 1092: static void
 1093: xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
 1094: static xmlSchemaQNameRefPtr
 1095: xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 1096: 				xmlSchemaPtr schema,
 1097: 				xmlNodePtr node);
 1098: 
 1099: /************************************************************************
 1100:  *									*
 1101:  * 			Helper functions			        *
 1102:  *									*
 1103:  ************************************************************************/
 1104: 
 1105: /**
 1106:  * xmlSchemaItemTypeToStr:
 1107:  * @type: the type of the schema item
 1108:  *
 1109:  * Returns the component name of a schema item.
 1110:  */
 1111: static const xmlChar *
 1112: xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
 1113: {
 1114:     switch (type) {
 1115: 	case XML_SCHEMA_TYPE_BASIC:
 1116: 	    return(BAD_CAST "simple type definition");
 1117: 	case XML_SCHEMA_TYPE_SIMPLE:
 1118: 	    return(BAD_CAST "simple type definition");
 1119: 	case XML_SCHEMA_TYPE_COMPLEX:
 1120: 	    return(BAD_CAST "complex type definition");
 1121: 	case XML_SCHEMA_TYPE_ELEMENT:
 1122: 	    return(BAD_CAST "element declaration");
 1123: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1124: 	    return(BAD_CAST "attribute use");
 1125: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1126: 	    return(BAD_CAST "attribute declaration");
 1127: 	case XML_SCHEMA_TYPE_GROUP:
 1128: 	    return(BAD_CAST "model group definition");
 1129: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1130: 	    return(BAD_CAST "attribute group definition");
 1131: 	case XML_SCHEMA_TYPE_NOTATION:
 1132: 	    return(BAD_CAST "notation declaration");
 1133: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1134: 	    return(BAD_CAST "model group (sequence)");
 1135: 	case XML_SCHEMA_TYPE_CHOICE:
 1136: 	    return(BAD_CAST "model group (choice)");
 1137: 	case XML_SCHEMA_TYPE_ALL:
 1138: 	    return(BAD_CAST "model group (all)");
 1139: 	case XML_SCHEMA_TYPE_PARTICLE:
 1140: 	    return(BAD_CAST "particle");
 1141: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1142: 	    return(BAD_CAST "unique identity-constraint");
 1143: 	    /* return(BAD_CAST "IDC (unique)"); */
 1144: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1145: 	    return(BAD_CAST "key identity-constraint");
 1146: 	    /* return(BAD_CAST "IDC (key)"); */
 1147: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1148: 	    return(BAD_CAST "keyref identity-constraint");
 1149: 	    /* return(BAD_CAST "IDC (keyref)"); */
 1150: 	case XML_SCHEMA_TYPE_ANY:
 1151: 	    return(BAD_CAST "wildcard (any)");
 1152: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1153: 	    return(BAD_CAST "[helper component] QName reference");
 1154: 	case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 1155: 	    return(BAD_CAST "[helper component] attribute use prohibition");
 1156: 	default:
 1157: 	    return(BAD_CAST "Not a schema component");
 1158:     }
 1159: }
 1160: 
 1161: /**
 1162:  * xmlSchemaGetComponentTypeStr:
 1163:  * @type: the type of the schema item
 1164:  *
 1165:  * Returns the component name of a schema item.
 1166:  */
 1167: static const xmlChar *
 1168: xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
 1169: {
 1170:     switch (item->type) {
 1171: 	case XML_SCHEMA_TYPE_BASIC:
 1172: 	    if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
 1173: 		return(BAD_CAST "complex type definition");
 1174: 	    else
 1175: 		return(BAD_CAST "simple type definition");
 1176: 	default:
 1177: 	    return(xmlSchemaItemTypeToStr(item->type));
 1178:     }
 1179: }
 1180: 
 1181: /**
 1182:  * xmlSchemaGetComponentNode:
 1183:  * @item: a schema component
 1184:  *
 1185:  * Returns node associated with the schema component.
 1186:  * NOTE that such a node need not be available; plus, a component's
 1187:  * node need not to reflect the component directly, since there is no
 1188:  * one-to-one relationship between the XML Schema representation and
 1189:  * the component representation.
 1190:  */
 1191: static xmlNodePtr
 1192: xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
 1193: {
 1194:     switch (item->type) {
 1195: 	case XML_SCHEMA_TYPE_ELEMENT:
 1196: 	    return (((xmlSchemaElementPtr) item)->node);
 1197: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1198: 	    return (((xmlSchemaAttributePtr) item)->node);
 1199: 	case XML_SCHEMA_TYPE_COMPLEX:
 1200: 	case XML_SCHEMA_TYPE_SIMPLE:
 1201: 	    return (((xmlSchemaTypePtr) item)->node);
 1202: 	case XML_SCHEMA_TYPE_ANY:
 1203: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1204: 	    return (((xmlSchemaWildcardPtr) item)->node);
 1205: 	case XML_SCHEMA_TYPE_PARTICLE:
 1206: 	    return (((xmlSchemaParticlePtr) item)->node);
 1207: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1208: 	case XML_SCHEMA_TYPE_CHOICE:
 1209: 	case XML_SCHEMA_TYPE_ALL:
 1210: 	    return (((xmlSchemaModelGroupPtr) item)->node);
 1211: 	case XML_SCHEMA_TYPE_GROUP:
 1212: 	    return (((xmlSchemaModelGroupDefPtr) item)->node);
 1213: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1214: 	    return (((xmlSchemaAttributeGroupPtr) item)->node);
 1215: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1216: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1217: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1218: 	    return (((xmlSchemaIDCPtr) item)->node);
 1219: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1220: 	    return(((xmlSchemaQNameRefPtr) item)->node);
 1221: 	/* TODO: What to do with NOTATIONs?
 1222: 	case XML_SCHEMA_TYPE_NOTATION:
 1223: 	    return (((xmlSchemaNotationPtr) item)->node);
 1224: 	*/
 1225: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1226: 	    return (((xmlSchemaAttributeUsePtr) item)->node);
 1227: 	default:
 1228: 	    return (NULL);
 1229:     }
 1230: }
 1231: 
 1232: #if 0
 1233: /**
 1234:  * xmlSchemaGetNextComponent:
 1235:  * @item: a schema component
 1236:  *
 1237:  * Returns the next sibling of the schema component.
 1238:  */
 1239: static xmlSchemaBasicItemPtr
 1240: xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
 1241: {
 1242:     switch (item->type) {
 1243: 	case XML_SCHEMA_TYPE_ELEMENT:
 1244: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
 1245: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1246: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
 1247: 	case XML_SCHEMA_TYPE_COMPLEX:
 1248: 	case XML_SCHEMA_TYPE_SIMPLE:
 1249: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
 1250: 	case XML_SCHEMA_TYPE_ANY:
 1251: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1252: 	    return (NULL);
 1253: 	case XML_SCHEMA_TYPE_PARTICLE:
 1254: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
 1255: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1256: 	case XML_SCHEMA_TYPE_CHOICE:
 1257: 	case XML_SCHEMA_TYPE_ALL:
 1258: 	    return (NULL);
 1259: 	case XML_SCHEMA_TYPE_GROUP:
 1260: 	    return (NULL);
 1261: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1262: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
 1263: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1264: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1265: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1266: 	    return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
 1267: 	default:
 1268: 	    return (NULL);
 1269:     }
 1270: }
 1271: #endif
 1272: 
 1273: 
 1274: /**
 1275:  * xmlSchemaFormatQName:
 1276:  * @buf: the string buffer
 1277:  * @namespaceName:  the namespace name
 1278:  * @localName: the local name
 1279:  *
 1280:  * Returns the given QName in the format "{namespaceName}localName" or
 1281:  * just "localName" if @namespaceName is NULL.
 1282:  *
 1283:  * Returns the localName if @namespaceName is NULL, a formatted
 1284:  * string otherwise.
 1285:  */
 1286: static const xmlChar*
 1287: xmlSchemaFormatQName(xmlChar **buf,
 1288: 		     const xmlChar *namespaceName,
 1289: 		     const xmlChar *localName)
 1290: {
 1291:     FREE_AND_NULL(*buf)
 1292:     if (namespaceName != NULL) {
 1293: 	*buf = xmlStrdup(BAD_CAST "{");
 1294: 	*buf = xmlStrcat(*buf, namespaceName);
 1295: 	*buf = xmlStrcat(*buf, BAD_CAST "}");
 1296:     }
 1297:     if (localName != NULL) {
 1298: 	if (namespaceName == NULL)
 1299: 	    return(localName);
 1300: 	*buf = xmlStrcat(*buf, localName);
 1301:     } else {
 1302: 	*buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
 1303:     }
 1304:     return ((const xmlChar *) *buf);
 1305: }
 1306: 
 1307: static const xmlChar*
 1308: xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
 1309: {
 1310:     if (ns != NULL)
 1311: 	return (xmlSchemaFormatQName(buf, ns->href, localName));
 1312:     else
 1313: 	return (xmlSchemaFormatQName(buf, NULL, localName));
 1314: }
 1315: 
 1316: static const xmlChar *
 1317: xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
 1318: {
 1319:     switch (item->type) {
 1320: 	case XML_SCHEMA_TYPE_ELEMENT:
 1321: 	    return (((xmlSchemaElementPtr) item)->name);
 1322: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1323: 	    return (((xmlSchemaAttributePtr) item)->name);
 1324: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1325: 	    return (((xmlSchemaAttributeGroupPtr) item)->name);
 1326: 	case XML_SCHEMA_TYPE_BASIC:
 1327: 	case XML_SCHEMA_TYPE_SIMPLE:
 1328: 	case XML_SCHEMA_TYPE_COMPLEX:
 1329: 	    return (((xmlSchemaTypePtr) item)->name);
 1330: 	case XML_SCHEMA_TYPE_GROUP:
 1331: 	    return (((xmlSchemaModelGroupDefPtr) item)->name);
 1332: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1333: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1334: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1335: 	    return (((xmlSchemaIDCPtr) item)->name);
 1336: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1337: 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
 1338: 		return(xmlSchemaGetComponentName(
 1339: 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 1340: 	    } else
 1341: 		return(NULL);
 1342: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1343: 	    return (((xmlSchemaQNameRefPtr) item)->name);
 1344: 	case XML_SCHEMA_TYPE_NOTATION:
 1345: 	    return (((xmlSchemaNotationPtr) item)->name);
 1346: 	default:
 1347: 	    /*
 1348: 	    * Other components cannot have names.
 1349: 	    */
 1350: 	    break;
 1351:     }
 1352:     return (NULL);
 1353: }
 1354: 
 1355: #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
 1356: #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
 1357: /*
 1358: static const xmlChar *
 1359: xmlSchemaGetQNameRefName(void *ref)
 1360: {
 1361:     return(((xmlSchemaQNameRefPtr) ref)->name);
 1362: }
 1363: 
 1364: static const xmlChar *
 1365: xmlSchemaGetQNameRefTargetNs(void *ref)
 1366: {
 1367:     return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
 1368: }
 1369: */
 1370: 
 1371: static const xmlChar *
 1372: xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
 1373: {
 1374:     switch (item->type) {
 1375: 	case XML_SCHEMA_TYPE_ELEMENT:
 1376: 	    return (((xmlSchemaElementPtr) item)->targetNamespace);
 1377: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 1378: 	    return (((xmlSchemaAttributePtr) item)->targetNamespace);
 1379: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1380: 	    return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
 1381: 	case XML_SCHEMA_TYPE_BASIC:
 1382: 	    return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
 1383: 	case XML_SCHEMA_TYPE_SIMPLE:
 1384: 	case XML_SCHEMA_TYPE_COMPLEX:
 1385: 	    return (((xmlSchemaTypePtr) item)->targetNamespace);
 1386: 	case XML_SCHEMA_TYPE_GROUP:
 1387: 	    return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
 1388: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1389: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1390: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1391: 	    return (((xmlSchemaIDCPtr) item)->targetNamespace);
 1392: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 1393: 	    if (WXS_ATTRUSE_DECL(item) != NULL) {
 1394: 		return(xmlSchemaGetComponentTargetNs(
 1395: 		    WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
 1396: 	    }
 1397: 	    /* TODO: Will returning NULL break something? */
 1398: 	    break;
 1399: 	case XML_SCHEMA_EXTRA_QNAMEREF:
 1400: 	    return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
 1401: 	case XML_SCHEMA_TYPE_NOTATION:
 1402: 	    return (((xmlSchemaNotationPtr) item)->targetNamespace);
 1403: 	default:
 1404: 	    /*
 1405: 	    * Other components cannot have names.
 1406: 	    */
 1407: 	    break;
 1408:     }
 1409:     return (NULL);
 1410: }
 1411: 
 1412: static const xmlChar*
 1413: xmlSchemaGetComponentQName(xmlChar **buf,
 1414: 			   void *item)
 1415: {
 1416:     return (xmlSchemaFormatQName(buf,
 1417: 	xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
 1418: 	xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
 1419: }
 1420: 
 1421: static const xmlChar*
 1422: xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
 1423: {
 1424:     xmlChar *str = NULL;
 1425: 
 1426:     *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
 1427:     *buf = xmlStrcat(*buf, BAD_CAST " '");
 1428:     *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
 1429: 	(xmlSchemaBasicItemPtr) item));
 1430:     *buf = xmlStrcat(*buf, BAD_CAST "'");
 1431:     FREE_AND_NULL(str);
 1432:     return(*buf);
 1433: }
 1434: 
 1435: static const xmlChar*
 1436: xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
 1437: {
 1438:     return(xmlSchemaGetComponentDesignation(buf, idc));
 1439: }
 1440: 
 1441: /**
 1442:  * xmlSchemaWildcardPCToString:
 1443:  * @pc: the type of processContents
 1444:  *
 1445:  * Returns a string representation of the type of
 1446:  * processContents.
 1447:  */
 1448: static const xmlChar *
 1449: xmlSchemaWildcardPCToString(int pc)
 1450: {
 1451:     switch (pc) {
 1452: 	case XML_SCHEMAS_ANY_SKIP:
 1453: 	    return (BAD_CAST "skip");
 1454: 	case XML_SCHEMAS_ANY_LAX:
 1455: 	    return (BAD_CAST "lax");
 1456: 	case XML_SCHEMAS_ANY_STRICT:
 1457: 	    return (BAD_CAST "strict");
 1458: 	default:
 1459: 	    return (BAD_CAST "invalid process contents");
 1460:     }
 1461: }
 1462: 
 1463: /**
 1464:  * xmlSchemaGetCanonValueWhtspExt:
 1465:  * @val: the precomputed value
 1466:  * @retValue: the returned value
 1467:  * @ws: the whitespace type of the value
 1468:  *
 1469:  * Get a the cononical representation of the value.
 1470:  * The caller has to free the returned retValue.
 1471:  *
 1472:  * Returns 0 if the value could be built and -1 in case of
 1473:  *         API errors or if the value type is not supported yet.
 1474:  */
 1475: static int
 1476: xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
 1477: 			       xmlSchemaWhitespaceValueType ws,
 1478: 			       xmlChar **retValue)
 1479: {
 1480:     int list;
 1481:     xmlSchemaValType valType;
 1482:     const xmlChar *value, *value2 = NULL;
 1483: 
 1484: 
 1485:     if ((retValue == NULL) || (val == NULL))
 1486: 	return (-1);
 1487:     list = xmlSchemaValueGetNext(val) ? 1 : 0;
 1488:     *retValue = NULL;
 1489:     do {
 1490: 	value = NULL;
 1491: 	valType = xmlSchemaGetValType(val);
 1492: 	switch (valType) {
 1493: 	    case XML_SCHEMAS_STRING:
 1494: 	    case XML_SCHEMAS_NORMSTRING:
 1495: 	    case XML_SCHEMAS_ANYSIMPLETYPE:
 1496: 		value = xmlSchemaValueGetAsString(val);
 1497: 		if (value != NULL) {
 1498: 		    if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
 1499: 			value2 = xmlSchemaCollapseString(value);
 1500: 		    else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
 1501: 			value2 = xmlSchemaWhiteSpaceReplace(value);
 1502: 		    if (value2 != NULL)
 1503: 			value = value2;
 1504: 		}
 1505: 		break;
 1506: 	    default:
 1507: 		if (xmlSchemaGetCanonValue(val, &value2) == -1) {
 1508: 		    if (value2 != NULL)
 1509: 			xmlFree((xmlChar *) value2);
 1510: 		    goto internal_error;
 1511: 		}
 1512: 		value = value2;
 1513: 	}
 1514: 	if (*retValue == NULL)
 1515: 	    if (value == NULL) {
 1516: 		if (! list)
 1517: 		    *retValue = xmlStrdup(BAD_CAST "");
 1518: 	    } else
 1519: 		*retValue = xmlStrdup(value);
 1520: 	else if (value != NULL) {
 1521: 	    /* List. */
 1522: 	    *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
 1523: 	    *retValue = xmlStrcat((xmlChar *) *retValue, value);
 1524: 	}
 1525: 	FREE_AND_NULL(value2)
 1526: 	val = xmlSchemaValueGetNext(val);
 1527:     } while (val != NULL);
 1528: 
 1529:     return (0);
 1530: internal_error:
 1531:     if (*retValue != NULL)
 1532: 	xmlFree((xmlChar *) (*retValue));
 1533:     if (value2 != NULL)
 1534: 	xmlFree((xmlChar *) value2);
 1535:     return (-1);
 1536: }
 1537: 
 1538: /**
 1539:  * xmlSchemaFormatItemForReport:
 1540:  * @buf: the string buffer
 1541:  * @itemDes: the designation of the item
 1542:  * @itemName: the name of the item
 1543:  * @item: the item as an object
 1544:  * @itemNode: the node of the item
 1545:  * @local: the local name
 1546:  * @parsing: if the function is used during the parse
 1547:  *
 1548:  * Returns a representation of the given item used
 1549:  * for error reports.
 1550:  *
 1551:  * The following order is used to build the resulting
 1552:  * designation if the arguments are not NULL:
 1553:  * 1a. If itemDes not NULL -> itemDes
 1554:  * 1b. If (itemDes not NULL) and (itemName not NULL)
 1555:  *     -> itemDes + itemName
 1556:  * 2. If the preceding was NULL and (item not NULL) -> item
 1557:  * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
 1558:  *
 1559:  * If the itemNode is an attribute node, the name of the attribute
 1560:  * will be appended to the result.
 1561:  *
 1562:  * Returns the formatted string and sets @buf to the resulting value.
 1563:  */
 1564: static xmlChar*
 1565: xmlSchemaFormatItemForReport(xmlChar **buf,
 1566: 		     const xmlChar *itemDes,
 1567: 		     xmlSchemaBasicItemPtr item,
 1568: 		     xmlNodePtr itemNode)
 1569: {
 1570:     xmlChar *str = NULL;
 1571:     int named = 1;
 1572: 
 1573:     if (*buf != NULL) {
 1574: 	xmlFree(*buf);
 1575: 	*buf = NULL;
 1576:     }
 1577: 
 1578:     if (itemDes != NULL) {
 1579: 	*buf = xmlStrdup(itemDes);
 1580:     } else if (item != NULL) {
 1581: 	switch (item->type) {
 1582: 	case XML_SCHEMA_TYPE_BASIC: {
 1583: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1584: 
 1585: 	    if (WXS_IS_ATOMIC(type))
 1586: 		*buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
 1587: 	    else if (WXS_IS_LIST(type))
 1588: 		*buf = xmlStrdup(BAD_CAST "list type 'xs:");
 1589: 	    else if (WXS_IS_UNION(type))
 1590: 		*buf = xmlStrdup(BAD_CAST "union type 'xs:");
 1591: 	    else
 1592: 		*buf = xmlStrdup(BAD_CAST "simple type 'xs:");
 1593: 	    *buf = xmlStrcat(*buf, type->name);
 1594: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1595: 	    }
 1596: 	    break;
 1597: 	case XML_SCHEMA_TYPE_SIMPLE: {
 1598: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1599: 
 1600: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1601: 		*buf = xmlStrdup(BAD_CAST"");
 1602: 	    } else {
 1603: 		*buf = xmlStrdup(BAD_CAST "local ");
 1604: 	    }
 1605: 	    if (WXS_IS_ATOMIC(type))
 1606: 		*buf = xmlStrcat(*buf, BAD_CAST "atomic type");
 1607: 	    else if (WXS_IS_LIST(type))
 1608: 		*buf = xmlStrcat(*buf, BAD_CAST "list type");
 1609: 	    else if (WXS_IS_UNION(type))
 1610: 		*buf = xmlStrcat(*buf, BAD_CAST "union type");
 1611: 	    else
 1612: 		*buf = xmlStrcat(*buf, BAD_CAST "simple type");
 1613: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1614: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1615: 		*buf = xmlStrcat(*buf, type->name);
 1616: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1617: 	    }
 1618: 	    }
 1619: 	    break;
 1620: 	case XML_SCHEMA_TYPE_COMPLEX: {
 1621: 	    xmlSchemaTypePtr type = WXS_TYPE_CAST item;
 1622: 
 1623: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
 1624: 		*buf = xmlStrdup(BAD_CAST "");
 1625: 	    else
 1626: 		*buf = xmlStrdup(BAD_CAST "local ");
 1627: 	    *buf = xmlStrcat(*buf, BAD_CAST "complex type");
 1628: 	    if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
 1629: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1630: 		*buf = xmlStrcat(*buf, type->name);
 1631: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1632: 	    }
 1633: 	    }
 1634: 	    break;
 1635: 	case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
 1636: 		xmlSchemaAttributeUsePtr ause;
 1637: 
 1638: 		ause = WXS_ATTR_USE_CAST item;
 1639: 		*buf = xmlStrdup(BAD_CAST "attribute use ");
 1640: 		if (WXS_ATTRUSE_DECL(ause) != NULL) {
 1641: 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1642: 		    *buf = xmlStrcat(*buf,
 1643: 			xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
 1644: 		    FREE_AND_NULL(str)
 1645: 			*buf = xmlStrcat(*buf, BAD_CAST "'");
 1646: 		} else {
 1647: 		    *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
 1648: 		}
 1649: 	    }
 1650: 	    break;
 1651: 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
 1652: 		xmlSchemaAttributePtr attr;
 1653: 
 1654: 		attr = (xmlSchemaAttributePtr) item;
 1655: 		*buf = xmlStrdup(BAD_CAST "attribute decl.");
 1656: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1657: 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1658: 		    attr->targetNamespace, attr->name));
 1659: 		FREE_AND_NULL(str)
 1660: 		    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1661: 	    }
 1662: 	    break;
 1663: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 1664: 	    xmlSchemaGetComponentDesignation(buf, item);
 1665: 	    break;
 1666: 	case XML_SCHEMA_TYPE_ELEMENT: {
 1667: 		xmlSchemaElementPtr elem;
 1668: 
 1669: 		elem = (xmlSchemaElementPtr) item;
 1670: 		*buf = xmlStrdup(BAD_CAST "element decl.");
 1671: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1672: 		*buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1673: 		    elem->targetNamespace, elem->name));
 1674: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1675: 	    }
 1676: 	    break;
 1677: 	case XML_SCHEMA_TYPE_IDC_UNIQUE:
 1678: 	case XML_SCHEMA_TYPE_IDC_KEY:
 1679: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 1680: 	    if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
 1681: 		*buf = xmlStrdup(BAD_CAST "unique '");
 1682: 	    else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
 1683: 		*buf = xmlStrdup(BAD_CAST "key '");
 1684: 	    else
 1685: 		*buf = xmlStrdup(BAD_CAST "keyRef '");
 1686: 	    *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
 1687: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1688: 	    break;
 1689: 	case XML_SCHEMA_TYPE_ANY:
 1690: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 1691: 	    *buf = xmlStrdup(xmlSchemaWildcardPCToString(
 1692: 		    ((xmlSchemaWildcardPtr) item)->processContents));
 1693: 	    *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
 1694: 	    break;
 1695: 	case XML_SCHEMA_FACET_MININCLUSIVE:
 1696: 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 1697: 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 1698: 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 1699: 	case XML_SCHEMA_FACET_TOTALDIGITS:
 1700: 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
 1701: 	case XML_SCHEMA_FACET_PATTERN:
 1702: 	case XML_SCHEMA_FACET_ENUMERATION:
 1703: 	case XML_SCHEMA_FACET_WHITESPACE:
 1704: 	case XML_SCHEMA_FACET_LENGTH:
 1705: 	case XML_SCHEMA_FACET_MAXLENGTH:
 1706: 	case XML_SCHEMA_FACET_MINLENGTH:
 1707: 	    *buf = xmlStrdup(BAD_CAST "facet '");
 1708: 	    *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
 1709: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1710: 	    break;
 1711: 	case XML_SCHEMA_TYPE_GROUP: {
 1712: 		*buf = xmlStrdup(BAD_CAST "model group def.");
 1713: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1714: 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 1715: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1716: 		FREE_AND_NULL(str)
 1717: 	    }
 1718: 	    break;
 1719: 	case XML_SCHEMA_TYPE_SEQUENCE:
 1720: 	case XML_SCHEMA_TYPE_CHOICE:
 1721: 	case XML_SCHEMA_TYPE_ALL:
 1722: 	case XML_SCHEMA_TYPE_PARTICLE:
 1723: 	    *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 1724: 	    break;
 1725: 	case XML_SCHEMA_TYPE_NOTATION: {
 1726: 		*buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
 1727: 		*buf = xmlStrcat(*buf, BAD_CAST " '");
 1728: 		*buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
 1729: 		*buf = xmlStrcat(*buf, BAD_CAST "'");
 1730: 		FREE_AND_NULL(str);
 1731: 	    }
 1732: 	default:
 1733: 	    named = 0;
 1734: 	}
 1735:     } else
 1736: 	named = 0;
 1737: 
 1738:     if ((named == 0) && (itemNode != NULL)) {
 1739: 	xmlNodePtr elem;
 1740: 
 1741: 	if (itemNode->type == XML_ATTRIBUTE_NODE)
 1742: 	    elem = itemNode->parent;
 1743: 	else
 1744: 	    elem = itemNode;
 1745: 	*buf = xmlStrdup(BAD_CAST "Element '");
 1746: 	if (elem->ns != NULL) {
 1747: 	    *buf = xmlStrcat(*buf,
 1748: 		xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
 1749: 	    FREE_AND_NULL(str)
 1750: 	} else
 1751: 	    *buf = xmlStrcat(*buf, elem->name);
 1752: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
 1753: 
 1754:     }
 1755:     if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
 1756: 	*buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
 1757: 	if (itemNode->ns != NULL) {
 1758: 	    *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
 1759: 		itemNode->ns->href, itemNode->name));
 1760: 	    FREE_AND_NULL(str)
 1761: 	} else
 1762: 	    *buf = xmlStrcat(*buf, itemNode->name);
 1763: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
 1764:     }
 1765:     FREE_AND_NULL(str)
 1766: 
 1767:     return (*buf);
 1768: }
 1769: 
 1770: /**
 1771:  * xmlSchemaFormatFacetEnumSet:
 1772:  * @buf: the string buffer
 1773:  * @type: the type holding the enumeration facets
 1774:  *
 1775:  * Builds a string consisting of all enumeration elements.
 1776:  *
 1777:  * Returns a string of all enumeration elements.
 1778:  */
 1779: static const xmlChar *
 1780: xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
 1781: 			    xmlChar **buf, xmlSchemaTypePtr type)
 1782: {
 1783:     xmlSchemaFacetPtr facet;
 1784:     xmlSchemaWhitespaceValueType ws;
 1785:     xmlChar *value = NULL;
 1786:     int res, found = 0;
 1787: 
 1788:     if (*buf != NULL)
 1789: 	xmlFree(*buf);
 1790:     *buf = NULL;
 1791: 
 1792:     do {
 1793: 	/*
 1794: 	* Use the whitespace type of the base type.
 1795: 	*/
 1796: 	ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
 1797: 	for (facet = type->facets; facet != NULL; facet = facet->next) {
 1798: 	    if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
 1799: 		continue;
 1800: 	    found = 1;
 1801: 	    res = xmlSchemaGetCanonValueWhtspExt(facet->val,
 1802: 		ws, &value);
 1803: 	    if (res == -1) {
 1804: 		xmlSchemaInternalErr(actxt,
 1805: 		    "xmlSchemaFormatFacetEnumSet",
 1806: 		    "compute the canonical lexical representation");
 1807: 		if (*buf != NULL)
 1808: 		    xmlFree(*buf);
 1809: 		*buf = NULL;
 1810: 		return (NULL);
 1811: 	    }
 1812: 	    if (*buf == NULL)
 1813: 		*buf = xmlStrdup(BAD_CAST "'");
 1814: 	    else
 1815: 		*buf = xmlStrcat(*buf, BAD_CAST ", '");
 1816: 	    *buf = xmlStrcat(*buf, BAD_CAST value);
 1817: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
 1818: 	    if (value != NULL) {
 1819: 		xmlFree((xmlChar *)value);
 1820: 		value = NULL;
 1821: 	    }
 1822: 	}
 1823: 	/*
 1824: 	* The enumeration facet of a type restricts the enumeration
 1825: 	* facet of the ancestor type; i.e., such restricted enumerations
 1826: 	* do not belong to the set of the given type. Thus we break
 1827: 	* on the first found enumeration.
 1828: 	*/
 1829: 	if (found)
 1830: 	    break;
 1831: 	type = type->baseType;
 1832:     } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
 1833: 
 1834:     return ((const xmlChar *) *buf);
 1835: }
 1836: 
 1837: /************************************************************************
 1838:  *									*
 1839:  * 			Error functions				        *
 1840:  *									*
 1841:  ************************************************************************/
 1842: 
 1843: #if 0
 1844: static void
 1845: xmlSchemaErrMemory(const char *msg)
 1846: {
 1847:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 1848:                      msg);
 1849: }
 1850: #endif
 1851: 
 1852: static void
 1853: xmlSchemaPSimpleErr(const char *msg)
 1854: {
 1855:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
 1856:                      msg);
 1857: }
 1858: 
 1859: /**
 1860:  * xmlSchemaPErrMemory:
 1861:  * @node: a context node
 1862:  * @extra:  extra informations
 1863:  *
 1864:  * Handle an out of memory condition
 1865:  */
 1866: static void
 1867: xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
 1868:                     const char *extra, xmlNodePtr node)
 1869: {
 1870:     if (ctxt != NULL)
 1871:         ctxt->nberrors++;
 1872:     __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
 1873:                      extra);
 1874: }
 1875: 
 1876: /**
 1877:  * xmlSchemaPErr:
 1878:  * @ctxt: the parsing context
 1879:  * @node: the context node
 1880:  * @error: the error code
 1881:  * @msg: the error message
 1882:  * @str1: extra data
 1883:  * @str2: extra data
 1884:  *
 1885:  * Handle a parser error
 1886:  */
 1887: static void
 1888: xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 1889:               const char *msg, const xmlChar * str1, const xmlChar * str2)
 1890: {
 1891:     xmlGenericErrorFunc channel = NULL;
 1892:     xmlStructuredErrorFunc schannel = NULL;
 1893:     void *data = NULL;
 1894: 
 1895:     if (ctxt != NULL) {
 1896:         ctxt->nberrors++;
 1897: 	ctxt->err = error;
 1898:         channel = ctxt->error;
 1899:         data = ctxt->errCtxt;
 1900: 	schannel = ctxt->serror;
 1901:     }
 1902:     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 1903:                     error, XML_ERR_ERROR, NULL, 0,
 1904:                     (const char *) str1, (const char *) str2, NULL, 0, 0,
 1905:                     msg, str1, str2);
 1906: }
 1907: 
 1908: /**
 1909:  * xmlSchemaPErr2:
 1910:  * @ctxt: the parsing context
 1911:  * @node: the context node
 1912:  * @node: the current child
 1913:  * @error: the error code
 1914:  * @msg: the error message
 1915:  * @str1: extra data
 1916:  * @str2: extra data
 1917:  *
 1918:  * Handle a parser error
 1919:  */
 1920: static void
 1921: xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 1922:                xmlNodePtr child, int error,
 1923:                const char *msg, const xmlChar * str1, const xmlChar * str2)
 1924: {
 1925:     if (child != NULL)
 1926:         xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
 1927:     else
 1928:         xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
 1929: }
 1930: 
 1931: 
 1932: /**
 1933:  * xmlSchemaPErrExt:
 1934:  * @ctxt: the parsing context
 1935:  * @node: the context node
 1936:  * @error: the error code
 1937:  * @strData1: extra data
 1938:  * @strData2: extra data
 1939:  * @strData3: extra data
 1940:  * @msg: the message
 1941:  * @str1:  extra parameter for the message display
 1942:  * @str2:  extra parameter for the message display
 1943:  * @str3:  extra parameter for the message display
 1944:  * @str4:  extra parameter for the message display
 1945:  * @str5:  extra parameter for the message display
 1946:  *
 1947:  * Handle a parser error
 1948:  */
 1949: static void
 1950: xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
 1951: 		const xmlChar * strData1, const xmlChar * strData2,
 1952: 		const xmlChar * strData3, const char *msg, const xmlChar * str1,
 1953: 		const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
 1954: 		const xmlChar * str5)
 1955: {
 1956: 
 1957:     xmlGenericErrorFunc channel = NULL;
 1958:     xmlStructuredErrorFunc schannel = NULL;
 1959:     void *data = NULL;
 1960: 
 1961:     if (ctxt != NULL) {
 1962:         ctxt->nberrors++;
 1963: 	ctxt->err = error;
 1964:         channel = ctxt->error;
 1965:         data = ctxt->errCtxt;
 1966: 	schannel = ctxt->serror;
 1967:     }
 1968:     __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
 1969:                     error, XML_ERR_ERROR, NULL, 0,
 1970:                     (const char *) strData1, (const char *) strData2,
 1971: 		    (const char *) strData3, 0, 0, msg, str1, str2,
 1972: 		    str3, str4, str5);
 1973: }
 1974: 
 1975: /************************************************************************
 1976:  *									*
 1977:  * 			Allround error functions			*
 1978:  *									*
 1979:  ************************************************************************/
 1980: 
 1981: /**
 1982:  * xmlSchemaVTypeErrMemory:
 1983:  * @node: a context node
 1984:  * @extra:  extra informations
 1985:  *
 1986:  * Handle an out of memory condition
 1987:  */
 1988: static void
 1989: xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
 1990:                     const char *extra, xmlNodePtr node)
 1991: {
 1992:     if (ctxt != NULL) {
 1993:         ctxt->nberrors++;
 1994:         ctxt->err = XML_SCHEMAV_INTERNAL;
 1995:     }
 1996:     __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
 1997:                      extra);
 1998: }
 1999: 
 2000: static void
 2001: xmlSchemaPSimpleInternalErr(xmlNodePtr node,
 2002: 			    const char *msg, const xmlChar *str)
 2003: {
 2004:      __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
 2005: 	 msg, (const char *) str);
 2006: }
 2007: 
 2008: #define WXS_ERROR_TYPE_ERROR 1
 2009: #define WXS_ERROR_TYPE_WARNING 2
 2010: /**
 2011:  * xmlSchemaErr3:
 2012:  * @ctxt: the validation context
 2013:  * @node: the context node
 2014:  * @error: the error code
 2015:  * @msg: the error message
 2016:  * @str1: extra data
 2017:  * @str2: extra data
 2018:  * @str3: extra data
 2019:  *
 2020:  * Handle a validation error
 2021:  */
 2022: static void
 2023: xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
 2024: 		  xmlErrorLevel errorLevel,
 2025: 		  int error, xmlNodePtr node, int line, const char *msg,
 2026: 		  const xmlChar *str1, const xmlChar *str2,
 2027: 		  const xmlChar *str3, const xmlChar *str4)
 2028: {
 2029:     xmlStructuredErrorFunc schannel = NULL;
 2030:     xmlGenericErrorFunc channel = NULL;
 2031:     void *data = NULL;
 2032: 
 2033:     if (ctxt != NULL) {
 2034: 	if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 2035: 	    xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
 2036: 	    const char *file = NULL;
 2037: 	    if (errorLevel != XML_ERR_WARNING) {
 2038: 		vctxt->nberrors++;
 2039: 		vctxt->err = error;
 2040: 		channel = vctxt->error;
 2041: 	    } else {
 2042: 		channel = vctxt->warning;
 2043: 	    }
 2044: 	    schannel = vctxt->serror;
 2045: 	    data = vctxt->errCtxt;
 2046: 
 2047: 	    /*
 2048: 	    * Error node. If we specify a line number, then
 2049: 	    * do not channel any node to the error function.
 2050: 	    */
 2051: 	    if (line == 0) {
 2052: 		if ((node == NULL) &&
 2053: 		    (vctxt->depth >= 0) &&
 2054: 		    (vctxt->inode != NULL)) {
 2055: 		    node = vctxt->inode->node;
 2056: 		}
 2057: 		/*
 2058: 		* Get filename and line if no node-tree.
 2059: 		*/
 2060: 		if ((node == NULL) &&
 2061: 		    (vctxt->parserCtxt != NULL) &&
 2062: 		    (vctxt->parserCtxt->input != NULL)) {
 2063: 		    file = vctxt->parserCtxt->input->filename;
 2064: 		    line = vctxt->parserCtxt->input->line;
 2065: 		}
 2066: 	    } else {
 2067: 		/*
 2068: 		* Override the given node's (if any) position
 2069: 		* and channel only the given line number.
 2070: 		*/
 2071: 		node = NULL;
 2072: 		/*
 2073: 		* Get filename.
 2074: 		*/
 2075: 		if (vctxt->doc != NULL)
 2076: 		    file = (const char *) vctxt->doc->URL;
 2077: 		else if ((vctxt->parserCtxt != NULL) &&
 2078: 		    (vctxt->parserCtxt->input != NULL))
 2079: 		    file = vctxt->parserCtxt->input->filename;
 2080: 	    }
 2081: 	    __xmlRaiseError(schannel, channel, data, ctxt,
 2082: 		node, XML_FROM_SCHEMASV,
 2083: 		error, errorLevel, file, line,
 2084: 		(const char *) str1, (const char *) str2,
 2085: 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 2086: 
 2087: 	} else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
 2088: 	    xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
 2089: 	    if (errorLevel != XML_ERR_WARNING) {
 2090: 		pctxt->nberrors++;
 2091: 		pctxt->err = error;
 2092: 		channel = pctxt->error;
 2093: 	    } else {
 2094: 		channel = pctxt->warning;
 2095: 	    }
 2096: 	    schannel = pctxt->serror;
 2097: 	    data = pctxt->errCtxt;
 2098: 	    __xmlRaiseError(schannel, channel, data, ctxt,
 2099: 		node, XML_FROM_SCHEMASP, error,
 2100: 		errorLevel, NULL, 0,
 2101: 		(const char *) str1, (const char *) str2,
 2102: 		(const char *) str3, 0, 0, msg, str1, str2, str3, str4);
 2103: 	} else {
 2104: 	    TODO
 2105: 	}
 2106:     }
 2107: }
 2108: 
 2109: /**
 2110:  * xmlSchemaErr3:
 2111:  * @ctxt: the validation context
 2112:  * @node: the context node
 2113:  * @error: the error code
 2114:  * @msg: the error message
 2115:  * @str1: extra data
 2116:  * @str2: extra data
 2117:  * @str3: extra data
 2118:  *
 2119:  * Handle a validation error
 2120:  */
 2121: static void
 2122: xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
 2123: 	      int error, xmlNodePtr node, const char *msg,
 2124: 	      const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
 2125: {
 2126:     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 2127: 	msg, str1, str2, str3, NULL);
 2128: }
 2129: 
 2130: static void
 2131: xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
 2132: 	      int error, xmlNodePtr node, const char *msg,
 2133: 	      const xmlChar *str1, const xmlChar *str2,
 2134: 	      const xmlChar *str3, const xmlChar *str4)
 2135: {
 2136:     xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
 2137: 	msg, str1, str2, str3, str4);
 2138: }
 2139: 
 2140: static void
 2141: xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
 2142: 	     int error, xmlNodePtr node, const char *msg,
 2143: 	     const xmlChar *str1, const xmlChar *str2)
 2144: {
 2145:     xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
 2146: }
 2147: 
 2148: static xmlChar *
 2149: xmlSchemaFormatNodeForError(xmlChar ** msg,
 2150: 			    xmlSchemaAbstractCtxtPtr actxt,
 2151: 			    xmlNodePtr node)
 2152: {
 2153:     xmlChar *str = NULL;
 2154: 
 2155:     *msg = NULL;
 2156:     if ((node != NULL) &&
 2157: 	(node->type != XML_ELEMENT_NODE) &&
 2158: 	(node->type != XML_ATTRIBUTE_NODE))
 2159:     {
 2160: 	/*
 2161: 	* Don't try to format other nodes than element and
 2162: 	* attribute nodes.
 2163: 	* Play save and return an empty string.
 2164: 	*/
 2165: 	*msg = xmlStrdup(BAD_CAST "");
 2166: 	return(*msg);
 2167:     }
 2168:     if (node != NULL) {
 2169: 	/*
 2170: 	* Work on tree nodes.
 2171: 	*/
 2172: 	if (node->type == XML_ATTRIBUTE_NODE) {
 2173: 	    xmlNodePtr elem = node->parent;
 2174: 
 2175: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2176: 	    if (elem->ns != NULL)
 2177: 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2178: 		    elem->ns->href, elem->name));
 2179: 	    else
 2180: 		*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2181: 		    NULL, elem->name));
 2182: 	    FREE_AND_NULL(str);
 2183: 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
 2184: 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
 2185: 	} else {
 2186: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2187: 	}
 2188: 	if (node->ns != NULL)
 2189: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2190: 	    node->ns->href, node->name));
 2191: 	else
 2192: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2193: 	    NULL, node->name));
 2194: 	FREE_AND_NULL(str);
 2195: 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
 2196:     } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
 2197: 	xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
 2198: 	/*
 2199: 	* Work on node infos.
 2200: 	*/
 2201: 	if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
 2202: 	    xmlSchemaNodeInfoPtr ielem =
 2203: 		vctxt->elemInfos[vctxt->depth];
 2204: 
 2205: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2206: 	    *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2207: 		ielem->nsName, ielem->localName));
 2208: 	    FREE_AND_NULL(str);
 2209: 	    *msg = xmlStrcat(*msg, BAD_CAST "', ");
 2210: 	    *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
 2211: 	} else {
 2212: 	    *msg = xmlStrdup(BAD_CAST "Element '");
 2213: 	}
 2214: 	*msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
 2215: 	    vctxt->inode->nsName, vctxt->inode->localName));
 2216: 	FREE_AND_NULL(str);
 2217: 	*msg = xmlStrcat(*msg, BAD_CAST "': ");
 2218:     } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
 2219: 	/*
 2220: 	* Hmm, no node while parsing?
 2221: 	* Return an empty string, in case NULL will break something.
 2222: 	*/
 2223: 	*msg = xmlStrdup(BAD_CAST "");
 2224:     } else {
 2225: 	TODO
 2226: 	return (NULL);
 2227:     }
 2228:     /*
 2229:     * VAL TODO: The output of the given schema component is currently
 2230:     * disabled.
 2231:     */
 2232: #if 0
 2233:     if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
 2234: 	*msg = xmlStrcat(*msg, BAD_CAST " [");
 2235: 	*msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
 2236: 	    NULL, type, NULL, 0));
 2237: 	FREE_AND_NULL(str)
 2238: 	*msg = xmlStrcat(*msg, BAD_CAST "]");
 2239:     }
 2240: #endif
 2241:     return (*msg);
 2242: }
 2243: 
 2244: static void
 2245: xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
 2246: 		     const char *funcName,
 2247: 		     const char *message,
 2248: 		     const xmlChar *str1,
 2249: 		     const xmlChar *str2)
 2250: {
 2251:     xmlChar *msg = NULL;
 2252: 
 2253:     if (actxt == NULL)
 2254:         return;
 2255:     msg = xmlStrdup(BAD_CAST "Internal error: ");
 2256:     msg = xmlStrcat(msg, BAD_CAST funcName);
 2257:     msg = xmlStrcat(msg, BAD_CAST ", ");
 2258:     msg = xmlStrcat(msg, BAD_CAST message);
 2259:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2260: 
 2261:     if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
 2262: 	xmlSchemaErr(actxt, XML_SCHEMAV_INTERNAL, NULL,
 2263: 	    (const char *) msg, str1, str2);
 2264: 
 2265:     else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
 2266: 	xmlSchemaErr(actxt, XML_SCHEMAP_INTERNAL, NULL,
 2267: 	    (const char *) msg, str1, str2);
 2268: 
 2269:     FREE_AND_NULL(msg)
 2270: }
 2271: 
 2272: static void
 2273: xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
 2274: 		     const char *funcName,
 2275: 		     const char *message)
 2276: {
 2277:     xmlSchemaInternalErr2(actxt, funcName, message, NULL, NULL);
 2278: }
 2279: 
 2280: #if 0
 2281: static void
 2282: xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
 2283: 		     const char *funcName,
 2284: 		     const char *message,
 2285: 		     const xmlChar *str1,
 2286: 		     const xmlChar *str2)
 2287: {
 2288:     xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
 2289: 	str1, str2);
 2290: }
 2291: #endif
 2292: 
 2293: static void
 2294: xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
 2295: 		   xmlParserErrors error,
 2296: 		   xmlNodePtr node,
 2297: 		   xmlSchemaBasicItemPtr item,
 2298: 		   const char *message,
 2299: 		   const xmlChar *str1, const xmlChar *str2,
 2300: 		   const xmlChar *str3, const xmlChar *str4)
 2301: {
 2302:     xmlChar *msg = NULL;
 2303: 
 2304:     if ((node == NULL) && (item != NULL) &&
 2305: 	(actxt->type == XML_SCHEMA_CTXT_PARSER)) {
 2306: 	node = WXS_ITEM_NODE(item);
 2307: 	xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
 2308: 	msg = xmlStrcat(msg, BAD_CAST ": ");
 2309:     } else
 2310: 	xmlSchemaFormatNodeForError(&msg, actxt, node);
 2311:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2312:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2313:     xmlSchemaErr4(actxt, error, node,
 2314: 	(const char *) msg, str1, str2, str3, str4);
 2315:     FREE_AND_NULL(msg)
 2316: }
 2317: 
 2318: static void
 2319: xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
 2320: 		   xmlParserErrors error,
 2321: 		   xmlNodePtr node,
 2322: 		   xmlSchemaBasicItemPtr item,
 2323: 		   const char *message,
 2324: 		   const xmlChar *str1,
 2325: 		   const xmlChar *str2)
 2326: {
 2327:     xmlSchemaCustomErr4(actxt, error, node, item,
 2328: 	message, str1, str2, NULL, NULL);
 2329: }
 2330: 
 2331: 
 2332: 
 2333: static void
 2334: xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
 2335: 		   xmlParserErrors error,
 2336: 		   xmlNodePtr node,
 2337: 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2338: 		   const char *message,
 2339: 		   const xmlChar *str1,
 2340: 		   const xmlChar *str2,
 2341: 		   const xmlChar *str3)
 2342: {
 2343:     xmlChar *msg = NULL;
 2344: 
 2345:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2346:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2347:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2348: 
 2349:     /* URGENT TODO: Set the error code to something sane. */
 2350:     xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
 2351: 	(const char *) msg, str1, str2, str3, NULL);
 2352: 
 2353:     FREE_AND_NULL(msg)
 2354: }
 2355: 
 2356: 
 2357: 
 2358: static void
 2359: xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
 2360: 		   xmlParserErrors error,
 2361: 		   xmlSchemaPSVIIDCNodePtr idcNode,
 2362: 		   xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2363: 		   const char *message,
 2364: 		   const xmlChar *str1,
 2365: 		   const xmlChar *str2)
 2366: {
 2367:     xmlChar *msg = NULL, *qname = NULL;
 2368: 
 2369:     msg = xmlStrdup(BAD_CAST "Element '%s': ");
 2370:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2371:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2372:     xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
 2373: 	error, NULL, idcNode->nodeLine, (const char *) msg,
 2374: 	xmlSchemaFormatQName(&qname,
 2375: 	    vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
 2376: 	    vctxt->nodeQNames->items[idcNode->nodeQNameID]),
 2377: 	str1, str2, NULL);
 2378:     FREE_AND_NULL(qname);
 2379:     FREE_AND_NULL(msg);
 2380: }
 2381: 
 2382: static int
 2383: xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
 2384: 			   xmlNodePtr node)
 2385: {
 2386:     if (node != NULL)
 2387: 	return (node->type);
 2388:     if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
 2389: 	(((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
 2390: 	return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
 2391:     return (-1);
 2392: }
 2393: 
 2394: static int
 2395: xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
 2396: {
 2397:     switch (item->type) {
 2398: 	case XML_SCHEMA_TYPE_COMPLEX:
 2399: 	case XML_SCHEMA_TYPE_SIMPLE:
 2400: 	    if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
 2401: 		return(1);
 2402: 	    break;
 2403: 	case XML_SCHEMA_TYPE_GROUP:
 2404: 	    return (1);
 2405: 	case XML_SCHEMA_TYPE_ELEMENT:
 2406: 	    if ( ((xmlSchemaElementPtr) item)->flags &
 2407: 		XML_SCHEMAS_ELEM_GLOBAL)
 2408: 		return(1);
 2409: 	    break;
 2410: 	case XML_SCHEMA_TYPE_ATTRIBUTE:
 2411: 	    if ( ((xmlSchemaAttributePtr) item)->flags &
 2412: 		XML_SCHEMAS_ATTR_GLOBAL)
 2413: 		return(1);
 2414: 	    break;
 2415: 	/* Note that attribute groups are always global. */
 2416: 	default:
 2417: 	    return(1);
 2418:     }
 2419:     return (0);
 2420: }
 2421: 
 2422: static void
 2423: xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 2424: 		       xmlParserErrors error,
 2425: 		       xmlNodePtr node,
 2426: 		       const xmlChar *value,
 2427: 		       xmlSchemaTypePtr type,
 2428: 		       int displayValue)
 2429: {
 2430:     xmlChar *msg = NULL;
 2431: 
 2432:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2433: 
 2434:     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 2435: 	    XML_ATTRIBUTE_NODE))
 2436: 	msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 2437:     else
 2438: 	msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
 2439: 	    "value of ");
 2440: 
 2441:     if (! xmlSchemaIsGlobalItem(type))
 2442: 	msg = xmlStrcat(msg, BAD_CAST "the local ");
 2443:     else
 2444: 	msg = xmlStrcat(msg, BAD_CAST "the ");
 2445: 
 2446:     if (WXS_IS_ATOMIC(type))
 2447: 	msg = xmlStrcat(msg, BAD_CAST "atomic type");
 2448:     else if (WXS_IS_LIST(type))
 2449: 	msg = xmlStrcat(msg, BAD_CAST "list type");
 2450:     else if (WXS_IS_UNION(type))
 2451: 	msg = xmlStrcat(msg, BAD_CAST "union type");
 2452: 
 2453:     if (xmlSchemaIsGlobalItem(type)) {
 2454: 	xmlChar *str = NULL;
 2455: 	msg = xmlStrcat(msg, BAD_CAST " '");
 2456: 	if (type->builtInType != 0) {
 2457: 	    msg = xmlStrcat(msg, BAD_CAST "xs:");
 2458: 	    msg = xmlStrcat(msg, type->name);
 2459: 	} else
 2460: 	    msg = xmlStrcat(msg,
 2461: 		xmlSchemaFormatQName(&str,
 2462: 		    type->targetNamespace, type->name));
 2463: 	msg = xmlStrcat(msg, BAD_CAST "'");
 2464: 	FREE_AND_NULL(str);
 2465:     }
 2466:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2467:     if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
 2468: 	    XML_ATTRIBUTE_NODE))
 2469: 	xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 2470:     else
 2471: 	xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2472:     FREE_AND_NULL(msg)
 2473: }
 2474: 
 2475: static const xmlChar *
 2476: xmlSchemaFormatErrorNodeQName(xmlChar ** str,
 2477: 			      xmlSchemaNodeInfoPtr ni,
 2478: 			      xmlNodePtr node)
 2479: {
 2480:     if (node != NULL) {
 2481: 	if (node->ns != NULL)
 2482: 	    return (xmlSchemaFormatQName(str, node->ns->href, node->name));
 2483: 	else
 2484: 	    return (xmlSchemaFormatQName(str, NULL, node->name));
 2485:     } else if (ni != NULL)
 2486: 	return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
 2487:     return (NULL);
 2488: }
 2489: 
 2490: static void
 2491: xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
 2492: 			xmlParserErrors error,
 2493: 			xmlSchemaAttrInfoPtr ni,
 2494: 			xmlNodePtr node)
 2495: {
 2496:     xmlChar *msg = NULL, *str = NULL;
 2497: 
 2498:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2499:     msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
 2500:     xmlSchemaErr(actxt, error, node, (const char *) msg,
 2501: 	xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
 2502: 	NULL);
 2503:     FREE_AND_NULL(str)
 2504:     FREE_AND_NULL(msg)
 2505: }
 2506: 
 2507: static void
 2508: xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
 2509: 		        xmlParserErrors error,
 2510: 		        xmlNodePtr node,
 2511: 			xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
 2512: 			const char *message,
 2513: 			int nbval,
 2514: 			int nbneg,
 2515: 			xmlChar **values)
 2516: {
 2517:     xmlChar *str = NULL, *msg = NULL;
 2518:     xmlChar *localName, *nsName;
 2519:     const xmlChar *cur, *end;
 2520:     int i;
 2521: 
 2522:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2523:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2524:     msg = xmlStrcat(msg, BAD_CAST ".");
 2525:     /*
 2526:     * Note that is does not make sense to report that we have a
 2527:     * wildcard here, since the wildcard might be unfolded into
 2528:     * multiple transitions.
 2529:     */
 2530:     if (nbval + nbneg > 0) {
 2531: 	if (nbval + nbneg > 1) {
 2532: 	    str = xmlStrdup(BAD_CAST " Expected is one of ( ");
 2533: 	} else
 2534: 	    str = xmlStrdup(BAD_CAST " Expected is ( ");
 2535: 	nsName = NULL;
 2536: 
 2537: 	for (i = 0; i < nbval + nbneg; i++) {
 2538: 	    cur = values[i];
 2539: 	    if (cur == NULL)
 2540: 	        continue;
 2541: 	    if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
 2542: 	        (cur[3] == ' ')) {
 2543: 		cur += 4;
 2544: 		str = xmlStrcat(str, BAD_CAST "##other");
 2545: 	    }
 2546: 	    /*
 2547: 	    * Get the local name.
 2548: 	    */
 2549: 	    localName = NULL;
 2550: 
 2551: 	    end = cur;
 2552: 	    if (*end == '*') {
 2553: 		localName = xmlStrdup(BAD_CAST "*");
 2554: 		end++;
 2555: 	    } else {
 2556: 		while ((*end != 0) && (*end != '|'))
 2557: 		    end++;
 2558: 		localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
 2559: 	    }
 2560: 	    if (*end != 0) {
 2561: 		end++;
 2562: 		/*
 2563: 		* Skip "*|*" if they come with negated expressions, since
 2564: 		* they represent the same negated wildcard.
 2565: 		*/
 2566: 		if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
 2567: 		    /*
 2568: 		    * Get the namespace name.
 2569: 		    */
 2570: 		    cur = end;
 2571: 		    if (*end == '*') {
 2572: 			nsName = xmlStrdup(BAD_CAST "{*}");
 2573: 		    } else {
 2574: 			while (*end != 0)
 2575: 			    end++;
 2576: 
 2577: 			if (i >= nbval)
 2578: 			    nsName = xmlStrdup(BAD_CAST "{##other:");
 2579: 			else
 2580: 			    nsName = xmlStrdup(BAD_CAST "{");
 2581: 
 2582: 			nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
 2583: 			nsName = xmlStrcat(nsName, BAD_CAST "}");
 2584: 		    }
 2585: 		    str = xmlStrcat(str, BAD_CAST nsName);
 2586: 		    FREE_AND_NULL(nsName)
 2587: 		} else {
 2588: 		    FREE_AND_NULL(localName);
 2589: 		    continue;
 2590: 		}
 2591: 	    }
 2592: 	    str = xmlStrcat(str, BAD_CAST localName);
 2593: 	    FREE_AND_NULL(localName);
 2594: 
 2595: 	    if (i < nbval + nbneg -1)
 2596: 		str = xmlStrcat(str, BAD_CAST ", ");
 2597: 	}
 2598: 	str = xmlStrcat(str, BAD_CAST " ).\n");
 2599: 	msg = xmlStrcat(msg, BAD_CAST str);
 2600: 	FREE_AND_NULL(str)
 2601:     } else
 2602:       msg = xmlStrcat(msg, BAD_CAST "\n");
 2603:     xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2604:     xmlFree(msg);
 2605: }
 2606: 
 2607: static void
 2608: xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
 2609: 		  xmlParserErrors error,
 2610: 		  xmlNodePtr node,
 2611: 		  const xmlChar *value,
 2612: 		  unsigned long length,
 2613: 		  xmlSchemaTypePtr type,
 2614: 		  xmlSchemaFacetPtr facet,
 2615: 		  const char *message,
 2616: 		  const xmlChar *str1,
 2617: 		  const xmlChar *str2)
 2618: {
 2619:     xmlChar *str = NULL, *msg = NULL;
 2620:     xmlSchemaTypeType facetType;
 2621:     int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
 2622: 
 2623:     xmlSchemaFormatNodeForError(&msg, actxt, node);
 2624:     if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
 2625: 	facetType = XML_SCHEMA_FACET_ENUMERATION;
 2626: 	/*
 2627: 	* If enumerations are validated, one must not expect the
 2628: 	* facet to be given.
 2629: 	*/
 2630:     } else
 2631: 	facetType = facet->type;
 2632:     msg = xmlStrcat(msg, BAD_CAST "[");
 2633:     msg = xmlStrcat(msg, BAD_CAST "facet '");
 2634:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
 2635:     msg = xmlStrcat(msg, BAD_CAST "'] ");
 2636:     if (message == NULL) {
 2637: 	/*
 2638: 	* Use a default message.
 2639: 	*/
 2640: 	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
 2641: 	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
 2642: 	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
 2643: 
 2644: 	    char len[25], actLen[25];
 2645: 
 2646: 	    /* FIXME, TODO: What is the max expected string length of the
 2647: 	    * this value?
 2648: 	    */
 2649: 	    if (nodeType == XML_ATTRIBUTE_NODE)
 2650: 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
 2651: 	    else
 2652: 		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
 2653: 
 2654: 	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
 2655: 	    snprintf(actLen, 24, "%lu", length);
 2656: 
 2657: 	    if (facetType == XML_SCHEMA_FACET_LENGTH)
 2658: 		msg = xmlStrcat(msg,
 2659: 		BAD_CAST "this differs from the allowed length of '%s'.\n");
 2660: 	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
 2661: 		msg = xmlStrcat(msg,
 2662: 		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
 2663: 	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
 2664: 		msg = xmlStrcat(msg,
 2665: 		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
 2666: 
 2667: 	    if (nodeType == XML_ATTRIBUTE_NODE)
 2668: 		xmlSchemaErr3(actxt, error, node, (const char *) msg,
 2669: 		    value, (const xmlChar *) actLen, (const xmlChar *) len);
 2670: 	    else
 2671: 		xmlSchemaErr(actxt, error, node, (const char *) msg,
 2672: 		    (const xmlChar *) actLen, (const xmlChar *) len);
 2673: 
 2674: 	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
 2675: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
 2676: 		"of the set {%s}.\n");
 2677: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2678: 		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
 2679: 	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
 2680: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
 2681: 		"by the pattern '%s'.\n");
 2682: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2683: 		facet->value);
 2684: 	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
 2685: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
 2686: 		"minimum value allowed ('%s').\n");
 2687: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2688: 		facet->value);
 2689: 	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
 2690: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
 2691: 		"maximum value allowed ('%s').\n");
 2692: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2693: 		facet->value);
 2694: 	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
 2695: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
 2696: 		"'%s'.\n");
 2697: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2698: 		facet->value);
 2699: 	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
 2700: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
 2701: 		"'%s'.\n");
 2702: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
 2703: 		facet->value);
 2704: 	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
 2705: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
 2706: 		"digits than are allowed ('%s').\n");
 2707: 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 2708: 		facet->value);
 2709: 	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
 2710: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
 2711: 		"digits than are allowed ('%s').\n");
 2712: 	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
 2713: 		facet->value);
 2714: 	} else if (nodeType == XML_ATTRIBUTE_NODE) {
 2715: 	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
 2716: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
 2717: 	} else {
 2718: 	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
 2719: 	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
 2720: 	}
 2721:     } else {
 2722: 	msg = xmlStrcat(msg, (const xmlChar *) message);
 2723: 	msg = xmlStrcat(msg, BAD_CAST ".\n");
 2724: 	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
 2725:     }
 2726:     FREE_AND_NULL(str)
 2727:     xmlFree(msg);
 2728: }
 2729: 
 2730: #define VERROR(err, type, msg) \
 2731:     xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, msg, NULL, NULL);
 2732: 
 2733: #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
 2734: 
 2735: #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
 2736: #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
 2737: 
 2738: #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
 2739: 
 2740: 
 2741: /**
 2742:  * xmlSchemaPMissingAttrErr:
 2743:  * @ctxt: the schema validation context
 2744:  * @ownerDes: the designation of  the owner
 2745:  * @ownerName: the name of the owner
 2746:  * @ownerItem: the owner as a schema object
 2747:  * @ownerElem: the owner as an element node
 2748:  * @node: the parent element node of the missing attribute node
 2749:  * @type: the corresponding type of the attribute node
 2750:  *
 2751:  * Reports an illegal attribute.
 2752:  */
 2753: static void
 2754: xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2755: 			 xmlParserErrors error,
 2756: 			 xmlSchemaBasicItemPtr ownerItem,
 2757: 			 xmlNodePtr ownerElem,
 2758: 			 const char *name,
 2759: 			 const char *message)
 2760: {
 2761:     xmlChar *des = NULL;
 2762: 
 2763:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 2764: 
 2765:     if (message != NULL)
 2766: 	xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
 2767:     else
 2768: 	xmlSchemaPErr(ctxt, ownerElem, error,
 2769: 	    "%s: The attribute '%s' is required but missing.\n",
 2770: 	    BAD_CAST des, BAD_CAST name);
 2771:     FREE_AND_NULL(des);
 2772: }
 2773: 
 2774: 
 2775: /**
 2776:  * xmlSchemaPResCompAttrErr:
 2777:  * @ctxt: the schema validation context
 2778:  * @error: the error code
 2779:  * @ownerDes: the designation of  the owner
 2780:  * @ownerItem: the owner as a schema object
 2781:  * @ownerElem: the owner as an element node
 2782:  * @name: the name of the attribute holding the QName
 2783:  * @refName: the referenced local name
 2784:  * @refURI: the referenced namespace URI
 2785:  * @message: optional message
 2786:  *
 2787:  * Used to report QName attribute values that failed to resolve
 2788:  * to schema components.
 2789:  */
 2790: static void
 2791: xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2792: 			 xmlParserErrors error,
 2793: 			 xmlSchemaBasicItemPtr ownerItem,
 2794: 			 xmlNodePtr ownerElem,
 2795: 			 const char *name,
 2796: 			 const xmlChar *refName,
 2797: 			 const xmlChar *refURI,
 2798: 			 xmlSchemaTypeType refType,
 2799: 			 const char *refTypeStr)
 2800: {
 2801:     xmlChar *des = NULL, *strA = NULL;
 2802: 
 2803:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 2804:     if (refTypeStr == NULL)
 2805: 	refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
 2806: 	xmlSchemaPErrExt(ctxt, ownerElem, error,
 2807: 	    NULL, NULL, NULL,
 2808: 	    "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
 2809: 	    "%s.\n", BAD_CAST des, BAD_CAST name,
 2810: 	    xmlSchemaFormatQName(&strA, refURI, refName),
 2811: 	    BAD_CAST refTypeStr, NULL);
 2812:     FREE_AND_NULL(des)
 2813:     FREE_AND_NULL(strA)
 2814: }
 2815: 
 2816: /**
 2817:  * xmlSchemaPCustomAttrErr:
 2818:  * @ctxt: the schema parser context
 2819:  * @error: the error code
 2820:  * @ownerDes: the designation of the owner
 2821:  * @ownerItem: the owner as a schema object
 2822:  * @attr: the illegal attribute node
 2823:  *
 2824:  * Reports an illegal attribute during the parse.
 2825:  */
 2826: static void
 2827: xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2828: 			xmlParserErrors error,
 2829: 			xmlChar **ownerDes,
 2830: 			xmlSchemaBasicItemPtr ownerItem,
 2831: 			xmlAttrPtr attr,
 2832: 			const char *msg)
 2833: {
 2834:     xmlChar *des = NULL;
 2835: 
 2836:     if (ownerDes == NULL)
 2837: 	xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
 2838:     else if (*ownerDes == NULL) {
 2839: 	xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
 2840: 	des = *ownerDes;
 2841:     } else
 2842: 	des = *ownerDes;
 2843:     if (attr == NULL) {
 2844: 	xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
 2845: 	    "%s, attribute '%s': %s.\n",
 2846: 	    BAD_CAST des, (const xmlChar *) "Unknown",
 2847: 	    (const xmlChar *) msg, NULL, NULL);
 2848:     } else {
 2849: 	xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 2850: 	    "%s, attribute '%s': %s.\n",
 2851: 	    BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
 2852:     }
 2853:     if (ownerDes == NULL)
 2854: 	FREE_AND_NULL(des);
 2855: }
 2856: 
 2857: /**
 2858:  * xmlSchemaPIllegalAttrErr:
 2859:  * @ctxt: the schema parser context
 2860:  * @error: the error code
 2861:  * @ownerDes: the designation of the attribute's owner
 2862:  * @ownerItem: the attribute's owner item
 2863:  * @attr: the illegal attribute node
 2864:  *
 2865:  * Reports an illegal attribute during the parse.
 2866:  */
 2867: static void
 2868: xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
 2869: 			 xmlParserErrors error,
 2870: 			 xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
 2871: 			 xmlAttrPtr attr)
 2872: {
 2873:     xmlChar *strA = NULL, *strB = NULL;
 2874: 
 2875:     xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
 2876:     xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
 2877: 	"%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
 2878: 	xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
 2879: 	NULL, NULL);
 2880:     FREE_AND_NULL(strA);
 2881:     FREE_AND_NULL(strB);
 2882: }
 2883: 
 2884: /**
 2885:  * xmlSchemaPCustomErr:
 2886:  * @ctxt: the schema parser context
 2887:  * @error: the error code
 2888:  * @itemDes: the designation of the schema item
 2889:  * @item: the schema item
 2890:  * @itemElem: the node of the schema item
 2891:  * @message: the error message
 2892:  * @str1: an optional param for the error message
 2893:  * @str2: an optional param for the error message
 2894:  * @str3: an optional param for the error message
 2895:  *
 2896:  * Reports an error during parsing.
 2897:  */
 2898: static void
 2899: xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
 2900: 		    xmlParserErrors error,
 2901: 		    xmlSchemaBasicItemPtr item,
 2902: 		    xmlNodePtr itemElem,
 2903: 		    const char *message,
 2904: 		    const xmlChar *str1,
 2905: 		    const xmlChar *str2,
 2906: 		    const xmlChar *str3)
 2907: {
 2908:     xmlChar *des = NULL, *msg = NULL;
 2909: 
 2910:     xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
 2911:     msg = xmlStrdup(BAD_CAST "%s: ");
 2912:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2913:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2914:     if ((itemElem == NULL) && (item != NULL))
 2915: 	itemElem = WXS_ITEM_NODE(item);
 2916:     xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
 2917: 	(const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
 2918:     FREE_AND_NULL(des);
 2919:     FREE_AND_NULL(msg);
 2920: }
 2921: 
 2922: /**
 2923:  * xmlSchemaPCustomErr:
 2924:  * @ctxt: the schema parser context
 2925:  * @error: the error code
 2926:  * @itemDes: the designation of the schema item
 2927:  * @item: the schema item
 2928:  * @itemElem: the node of the schema item
 2929:  * @message: the error message
 2930:  * @str1: the optional param for the error message
 2931:  *
 2932:  * Reports an error during parsing.
 2933:  */
 2934: static void
 2935: xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
 2936: 		    xmlParserErrors error,
 2937: 		    xmlSchemaBasicItemPtr item,
 2938: 		    xmlNodePtr itemElem,
 2939: 		    const char *message,
 2940: 		    const xmlChar *str1)
 2941: {
 2942:     xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
 2943: 	str1, NULL, NULL);
 2944: }
 2945: 
 2946: /**
 2947:  * xmlSchemaPAttrUseErr:
 2948:  * @ctxt: the schema parser context
 2949:  * @error: the error code
 2950:  * @itemDes: the designation of the schema type
 2951:  * @item: the schema type
 2952:  * @itemElem: the node of the schema type
 2953:  * @attr: the invalid schema attribute
 2954:  * @message: the error message
 2955:  * @str1: the optional param for the error message
 2956:  *
 2957:  * Reports an attribute use error during parsing.
 2958:  */
 2959: static void
 2960: xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
 2961: 		    xmlParserErrors error,
 2962: 		    xmlNodePtr node,
 2963: 		    xmlSchemaBasicItemPtr ownerItem,
 2964: 		    const xmlSchemaAttributeUsePtr attruse,
 2965: 		    const char *message,
 2966: 		    const xmlChar *str1, const xmlChar *str2,
 2967: 		    const xmlChar *str3,const xmlChar *str4)
 2968: {
 2969:     xmlChar *str = NULL, *msg = NULL;
 2970: 
 2971:     xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
 2972:     msg = xmlStrcat(msg, BAD_CAST ", ");
 2973:     msg = xmlStrcat(msg,
 2974: 	BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
 2975: 	WXS_BASIC_CAST attruse, NULL));
 2976:     FREE_AND_NULL(str);
 2977:     msg = xmlStrcat(msg, BAD_CAST ": ");
 2978:     msg = xmlStrcat(msg, (const xmlChar *) message);
 2979:     msg = xmlStrcat(msg, BAD_CAST ".\n");
 2980:     xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
 2981: 	(const char *) msg, str1, str2, str3, str4);
 2982:     xmlFree(msg);
 2983: }
 2984: 
 2985: /**
 2986:  * xmlSchemaPIllegalFacetAtomicErr:
 2987:  * @ctxt: the schema parser context
 2988:  * @error: the error code
 2989:  * @type: the schema type
 2990:  * @baseType: the base type of type
 2991:  * @facet: the illegal facet
 2992:  *
 2993:  * Reports an illegal facet for atomic simple types.
 2994:  */
 2995: static void
 2996: xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
 2997: 			  xmlParserErrors error,
 2998: 			  xmlSchemaTypePtr type,
 2999: 			  xmlSchemaTypePtr baseType,
 3000: 			  xmlSchemaFacetPtr facet)
 3001: {
 3002:     xmlChar *des = NULL, *strT = NULL;
 3003: 
 3004:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
 3005:     xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
 3006: 	"%s: The facet '%s' is not allowed on types derived from the "
 3007: 	"type %s.\n",
 3008: 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
 3009: 	xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
 3010: 	NULL, NULL);
 3011:     FREE_AND_NULL(des);
 3012:     FREE_AND_NULL(strT);
 3013: }
 3014: 
 3015: /**
 3016:  * xmlSchemaPIllegalFacetListUnionErr:
 3017:  * @ctxt: the schema parser context
 3018:  * @error: the error code
 3019:  * @itemDes: the designation of the schema item involved
 3020:  * @item: the schema item involved
 3021:  * @facet: the illegal facet
 3022:  *
 3023:  * Reports an illegal facet for <list> and <union>.
 3024:  */
 3025: static void
 3026: xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
 3027: 			  xmlParserErrors error,
 3028: 			  xmlSchemaTypePtr type,
 3029: 			  xmlSchemaFacetPtr facet)
 3030: {
 3031:     xmlChar *des = NULL;
 3032: 
 3033:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
 3034: 	type->node);
 3035:     xmlSchemaPErr(ctxt, type->node, error,
 3036: 	"%s: The facet '%s' is not allowed.\n",
 3037: 	BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
 3038:     FREE_AND_NULL(des);
 3039: }
 3040: 
 3041: /**
 3042:  * xmlSchemaPMutualExclAttrErr:
 3043:  * @ctxt: the schema validation context
 3044:  * @error: the error code
 3045:  * @elemDes: the designation of the parent element node
 3046:  * @attr: the bad attribute node
 3047:  * @type: the corresponding type of the attribute node
 3048:  *
 3049:  * Reports an illegal attribute.
 3050:  */
 3051: static void
 3052: xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
 3053: 			 xmlParserErrors error,
 3054: 			 xmlSchemaBasicItemPtr ownerItem,
 3055: 			 xmlAttrPtr attr,
 3056: 			 const char *name1,
 3057: 			 const char *name2)
 3058: {
 3059:     xmlChar *des = NULL;
 3060: 
 3061:     xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
 3062:     xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
 3063: 	"%s: The attributes '%s' and '%s' are mutually exclusive.\n",
 3064: 	BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
 3065:     FREE_AND_NULL(des);
 3066: }
 3067: 
 3068: /**
 3069:  * xmlSchemaPSimpleTypeErr:
 3070:  * @ctxt:  the schema validation context
 3071:  * @error: the error code
 3072:  * @type: the type specifier
 3073:  * @ownerDes: the designation of the owner
 3074:  * @ownerItem: the schema object if existent
 3075:  * @node: the validated node
 3076:  * @value: the validated value
 3077:  *
 3078:  * Reports a simple type validation error.
 3079:  * TODO: Should this report the value of an element as well?
 3080:  */
 3081: static void
 3082: xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
 3083: 			xmlParserErrors error,
 3084: 			xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
 3085: 			xmlNodePtr node,
 3086: 			xmlSchemaTypePtr type,
 3087: 			const char *expected,
 3088: 			const xmlChar *value,
 3089: 			const char *message,
 3090: 			const xmlChar *str1,
 3091: 			const xmlChar *str2)
 3092: {
 3093:     xmlChar *msg = NULL;
 3094: 
 3095:     xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
 3096:     if (message == NULL) {
 3097: 	/*
 3098: 	* Use default messages.
 3099: 	*/
 3100: 	if (type != NULL) {
 3101: 	    if (node->type == XML_ATTRIBUTE_NODE)
 3102: 		msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
 3103: 	    else
 3104: 		msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
 3105: 		"valid value of ");
 3106: 	    if (! xmlSchemaIsGlobalItem(type))
 3107: 		msg = xmlStrcat(msg, BAD_CAST "the local ");
 3108: 	    else
 3109: 		msg = xmlStrcat(msg, BAD_CAST "the ");
 3110: 
 3111: 	    if (WXS_IS_ATOMIC(type))
 3112: 		msg = xmlStrcat(msg, BAD_CAST "atomic type");
 3113: 	    else if (WXS_IS_LIST(type))
 3114: 		msg = xmlStrcat(msg, BAD_CAST "list type");
 3115: 	    else if (WXS_IS_UNION(type))
 3116: 		msg = xmlStrcat(msg, BAD_CAST "union type");
 3117: 
 3118: 	    if (xmlSchemaIsGlobalItem(type)) {
 3119: 		xmlChar *str = NULL;
 3120: 		msg = xmlStrcat(msg, BAD_CAST " '");
 3121: 		if (type->builtInType != 0) {
 3122: 		    msg = xmlStrcat(msg, BAD_CAST "xs:");
 3123: 		    msg = xmlStrcat(msg, type->name);
 3124: 		} else
 3125: 		    msg = xmlStrcat(msg,
 3126: 			xmlSchemaFormatQName(&str,
 3127: 			    type->targetNamespace, type->name));
 3128: 		msg = xmlStrcat(msg, BAD_CAST "'.");
 3129: 		FREE_AND_NULL(str);
 3130: 	    }
 3131: 	} else {
 3132: 	    if (node->type == XML_ATTRIBUTE_NODE)
 3133: 		msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
 3134: 	    else
 3135: 		msg = xmlStrcat(msg, BAD_CAST "The character content is not "
 3136: 		"valid.");
 3137: 	}
 3138: 	if (expected) {
 3139: 	    msg = xmlStrcat(msg, BAD_CAST " Expected is '");
 3140: 	    msg = xmlStrcat(msg, BAD_CAST expected);
 3141: 	    msg = xmlStrcat(msg, BAD_CAST "'.\n");
 3142: 	} else
 3143: 	    msg = xmlStrcat(msg, BAD_CAST "\n");
 3144: 	if (node->type == XML_ATTRIBUTE_NODE)
 3145: 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
 3146: 	else
 3147: 	    xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
 3148:     } else {
 3149: 	msg = xmlStrcat(msg, BAD_CAST message);
 3150: 	msg = xmlStrcat(msg, BAD_CAST ".\n");
 3151: 	xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
 3152: 	     (const char*) msg, str1, str2, NULL, NULL, NULL);
 3153:     }
 3154:     /* Cleanup. */
 3155:     FREE_AND_NULL(msg)
 3156: }
 3157: 
 3158: /**
 3159:  * xmlSchemaPContentErr:
 3160:  * @ctxt: the schema parser context
 3161:  * @error: the error code
 3162:  * @onwerDes: the designation of the holder of the content
 3163:  * @ownerItem: the owner item of the holder of the content
 3164:  * @ownerElem: the node of the holder of the content
 3165:  * @child: the invalid child node
 3166:  * @message: the optional error message
 3167:  * @content: the optional string describing the correct content
 3168:  *
 3169:  * Reports an error concerning the content of a schema element.
 3170:  */
 3171: static void
 3172: xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
 3173: 		     xmlParserErrors error,
 3174: 		     xmlSchemaBasicItemPtr ownerItem,
 3175: 		     xmlNodePtr ownerElem,
 3176: 		     xmlNodePtr child,
 3177: 		     const char *message,
 3178: 		     const char *content)
 3179: {
 3180:     xmlChar *des = NULL;
 3181: 
 3182:     xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
 3183:     if (message != NULL)
 3184: 	xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3185: 	    "%s: %s.\n",
 3186: 	    BAD_CAST des, BAD_CAST message);
 3187:     else {
 3188: 	if (content != NULL) {
 3189: 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3190: 		"%s: The content is not valid. Expected is %s.\n",
 3191: 		BAD_CAST des, BAD_CAST content);
 3192: 	} else {
 3193: 	    xmlSchemaPErr2(ctxt, ownerElem, child, error,
 3194: 		"%s: The content is not valid.\n",
 3195: 		BAD_CAST des, NULL);
 3196: 	}
 3197:     }
 3198:     FREE_AND_NULL(des)
 3199: }
 3200: 
 3201: /************************************************************************
 3202:  * 									*
 3203:  * 			Streamable error functions                      *
 3204:  * 									*
 3205:  ************************************************************************/
 3206: 
 3207: 
 3208: 
 3209: 
 3210: /************************************************************************
 3211:  * 									*
 3212:  * 			Validation helper functions			*
 3213:  * 									*
 3214:  ************************************************************************/
 3215: 
 3216: 
 3217: /************************************************************************
 3218:  * 									*
 3219:  * 			Allocation functions				*
 3220:  * 									*
 3221:  ************************************************************************/
 3222: 
 3223: /**
 3224:  * xmlSchemaNewSchemaForParserCtxt:
 3225:  * @ctxt:  a schema validation context
 3226:  *
 3227:  * Allocate a new Schema structure.
 3228:  *
 3229:  * Returns the newly allocated structure or NULL in case or error
 3230:  */
 3231: static xmlSchemaPtr
 3232: xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
 3233: {
 3234:     xmlSchemaPtr ret;
 3235: 
 3236:     ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
 3237:     if (ret == NULL) {
 3238:         xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
 3239:         return (NULL);
 3240:     }
 3241:     memset(ret, 0, sizeof(xmlSchema));
 3242:     ret->dict = ctxt->dict;
 3243:     xmlDictReference(ret->dict);
 3244: 
 3245:     return (ret);
 3246: }
 3247: 
 3248: /**
 3249:  * xmlSchemaNewFacet:
 3250:  *
 3251:  * Allocate a new Facet structure.
 3252:  *
 3253:  * Returns the newly allocated structure or NULL in case or error
 3254:  */
 3255: xmlSchemaFacetPtr
 3256: xmlSchemaNewFacet(void)
 3257: {
 3258:     xmlSchemaFacetPtr ret;
 3259: 
 3260:     ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
 3261:     if (ret == NULL) {
 3262:         return (NULL);
 3263:     }
 3264:     memset(ret, 0, sizeof(xmlSchemaFacet));
 3265: 
 3266:     return (ret);
 3267: }
 3268: 
 3269: /**
 3270:  * xmlSchemaNewAnnot:
 3271:  * @ctxt:  a schema validation context
 3272:  * @node:  a node
 3273:  *
 3274:  * Allocate a new annotation structure.
 3275:  *
 3276:  * Returns the newly allocated structure or NULL in case or error
 3277:  */
 3278: static xmlSchemaAnnotPtr
 3279: xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 3280: {
 3281:     xmlSchemaAnnotPtr ret;
 3282: 
 3283:     ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
 3284:     if (ret == NULL) {
 3285:         xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
 3286:         return (NULL);
 3287:     }
 3288:     memset(ret, 0, sizeof(xmlSchemaAnnot));
 3289:     ret->content = node;
 3290:     return (ret);
 3291: }
 3292: 
 3293: static xmlSchemaItemListPtr
 3294: xmlSchemaItemListCreate(void)
 3295: {
 3296:     xmlSchemaItemListPtr ret;
 3297: 
 3298:     ret = xmlMalloc(sizeof(xmlSchemaItemList));
 3299:     if (ret == NULL) {
 3300: 	xmlSchemaPErrMemory(NULL,
 3301: 	    "allocating an item list structure", NULL);
 3302: 	return (NULL);
 3303:     }
 3304:     memset(ret, 0, sizeof(xmlSchemaItemList));
 3305:     return (ret);
 3306: }
 3307: 
 3308: static void
 3309: xmlSchemaItemListClear(xmlSchemaItemListPtr list)
 3310: {
 3311:     if (list->items != NULL) {
 3312: 	xmlFree(list->items);
 3313: 	list->items = NULL;
 3314:     }
 3315:     list->nbItems = 0;
 3316:     list->sizeItems = 0;
 3317: }
 3318: 
 3319: static int
 3320: xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
 3321: {
 3322:     if (list->items == NULL) {
 3323: 	list->items = (void **) xmlMalloc(
 3324: 	    20 * sizeof(void *));
 3325: 	if (list->items == NULL) {
 3326: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3327: 	    return(-1);
 3328: 	}
 3329: 	list->sizeItems = 20;
 3330:     } else if (list->sizeItems <= list->nbItems) {
 3331: 	list->sizeItems *= 2;
 3332: 	list->items = (void **) xmlRealloc(list->items,
 3333: 	    list->sizeItems * sizeof(void *));
 3334: 	if (list->items == NULL) {
 3335: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3336: 	    list->sizeItems = 0;
 3337: 	    return(-1);
 3338: 	}
 3339:     }
 3340:     list->items[list->nbItems++] = item;
 3341:     return(0);
 3342: }
 3343: 
 3344: static int
 3345: xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
 3346: 			 int initialSize,
 3347: 			 void *item)
 3348: {
 3349:     if (list->items == NULL) {
 3350: 	if (initialSize <= 0)
 3351: 	    initialSize = 1;
 3352: 	list->items = (void **) xmlMalloc(
 3353: 	    initialSize * sizeof(void *));
 3354: 	if (list->items == NULL) {
 3355: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3356: 	    return(-1);
 3357: 	}
 3358: 	list->sizeItems = initialSize;
 3359:     } else if (list->sizeItems <= list->nbItems) {
 3360: 	list->sizeItems *= 2;
 3361: 	list->items = (void **) xmlRealloc(list->items,
 3362: 	    list->sizeItems * sizeof(void *));
 3363: 	if (list->items == NULL) {
 3364: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3365: 	    list->sizeItems = 0;
 3366: 	    return(-1);
 3367: 	}
 3368:     }
 3369:     list->items[list->nbItems++] = item;
 3370:     return(0);
 3371: }
 3372: 
 3373: static int
 3374: xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
 3375: {
 3376:     if (list->items == NULL) {
 3377: 	list->items = (void **) xmlMalloc(
 3378: 	    20 * sizeof(void *));
 3379: 	if (list->items == NULL) {
 3380: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3381: 	    return(-1);
 3382: 	}
 3383: 	list->sizeItems = 20;
 3384:     } else if (list->sizeItems <= list->nbItems) {
 3385: 	list->sizeItems *= 2;
 3386: 	list->items = (void **) xmlRealloc(list->items,
 3387: 	    list->sizeItems * sizeof(void *));
 3388: 	if (list->items == NULL) {
 3389: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3390: 	    list->sizeItems = 0;
 3391: 	    return(-1);
 3392: 	}
 3393:     }
 3394:     /*
 3395:     * Just append if the index is greater/equal than the item count.
 3396:     */
 3397:     if (idx >= list->nbItems) {
 3398: 	list->items[list->nbItems++] = item;
 3399:     } else {
 3400: 	int i;
 3401: 	for (i = list->nbItems; i > idx; i--)
 3402: 	    list->items[i] = list->items[i-1];
 3403: 	list->items[idx] = item;
 3404: 	list->nbItems++;
 3405:     }
 3406:     return(0);
 3407: }
 3408: 
 3409: #if 0 /* enable if ever needed */
 3410: static int
 3411: xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
 3412: 			    int initialSize,
 3413: 			    void *item,
 3414: 			    int idx)
 3415: {
 3416:     if (list->items == NULL) {
 3417: 	if (initialSize <= 0)
 3418: 	    initialSize = 1;
 3419: 	list->items = (void **) xmlMalloc(
 3420: 	    initialSize * sizeof(void *));
 3421: 	if (list->items == NULL) {
 3422: 	    xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
 3423: 	    return(-1);
 3424: 	}
 3425: 	list->sizeItems = initialSize;
 3426:     } else if (list->sizeItems <= list->nbItems) {
 3427: 	list->sizeItems *= 2;
 3428: 	list->items = (void **) xmlRealloc(list->items,
 3429: 	    list->sizeItems * sizeof(void *));
 3430: 	if (list->items == NULL) {
 3431: 	    xmlSchemaPErrMemory(NULL, "growing item list", NULL);
 3432: 	    list->sizeItems = 0;
 3433: 	    return(-1);
 3434: 	}
 3435:     }
 3436:     /*
 3437:     * Just append if the index is greater/equal than the item count.
 3438:     */
 3439:     if (idx >= list->nbItems) {
 3440: 	list->items[list->nbItems++] = item;
 3441:     } else {
 3442: 	int i;
 3443: 	for (i = list->nbItems; i > idx; i--)
 3444: 	    list->items[i] = list->items[i-1];
 3445: 	list->items[idx] = item;
 3446: 	list->nbItems++;
 3447:     }
 3448:     return(0);
 3449: }
 3450: #endif
 3451: 
 3452: static int
 3453: xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
 3454: {
 3455:     int i;
 3456:     if ((list->items == NULL) || (idx >= list->nbItems)) {
 3457: 	xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
 3458: 	    "index error.\n");
 3459: 	return(-1);
 3460:     }
 3461: 
 3462:     if (list->nbItems == 1) {
 3463: 	/* TODO: Really free the list? */
 3464: 	xmlFree(list->items);
 3465: 	list->items = NULL;
 3466: 	list->nbItems = 0;
 3467: 	list->sizeItems = 0;
 3468:     } else if (list->nbItems -1 == idx) {
 3469: 	list->nbItems--;
 3470:     } else {
 3471: 	for (i = idx; i < list->nbItems -1; i++)
 3472: 	    list->items[i] = list->items[i+1];
 3473: 	list->nbItems--;
 3474:     }
 3475:     return(0);
 3476: }
 3477: 
 3478: /**
 3479:  * xmlSchemaItemListFree:
 3480:  * @annot:  a schema type structure
 3481:  *
 3482:  * Deallocate a annotation structure
 3483:  */
 3484: static void
 3485: xmlSchemaItemListFree(xmlSchemaItemListPtr list)
 3486: {
 3487:     if (list == NULL)
 3488: 	return;
 3489:     if (list->items != NULL)
 3490: 	xmlFree(list->items);
 3491:     xmlFree(list);
 3492: }
 3493: 
 3494: static void
 3495: xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
 3496: {
 3497:     if (bucket == NULL)
 3498: 	return;
 3499:     if (bucket->globals != NULL) {
 3500: 	xmlSchemaComponentListFree(bucket->globals);
 3501: 	xmlSchemaItemListFree(bucket->globals);
 3502:     }
 3503:     if (bucket->locals != NULL) {
 3504: 	xmlSchemaComponentListFree(bucket->locals);
 3505: 	xmlSchemaItemListFree(bucket->locals);
 3506:     }
 3507:     if (bucket->relations != NULL) {
 3508: 	xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
 3509: 	do {
 3510: 	    prev = cur;
 3511: 	    cur = cur->next;
 3512: 	    xmlFree(prev);
 3513: 	} while (cur != NULL);
 3514:     }
 3515:     if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
 3516: 	xmlFreeDoc(bucket->doc);
 3517:     }
 3518:     if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
 3519: 	if (WXS_IMPBUCKET(bucket)->schema != NULL)
 3520: 	    xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
 3521:     }
 3522:     xmlFree(bucket);
 3523: }
 3524: 
 3525: static xmlSchemaBucketPtr
 3526: xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
 3527: 			 int type, const xmlChar *targetNamespace)
 3528: {
 3529:     xmlSchemaBucketPtr ret;
 3530:     int size;
 3531:     xmlSchemaPtr mainSchema;
 3532: 
 3533:     if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
 3534: 	PERROR_INT("xmlSchemaBucketCreate",
 3535: 	    "no main schema on constructor");
 3536: 	return(NULL);
 3537:     }
 3538:     mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
 3539:     /* Create the schema bucket. */
 3540:     if (WXS_IS_BUCKET_INCREDEF(type))
 3541: 	size = sizeof(xmlSchemaInclude);
 3542:     else
 3543: 	size = sizeof(xmlSchemaImport);
 3544:     ret = (xmlSchemaBucketPtr) xmlMalloc(size);
 3545:     if (ret == NULL) {
 3546: 	xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
 3547: 	return(NULL);
 3548:     }
 3549:     memset(ret, 0, size);
 3550:     ret->targetNamespace = targetNamespace;
 3551:     ret->type = type;
 3552:     ret->globals = xmlSchemaItemListCreate();
 3553:     if (ret->globals == NULL) {
 3554: 	xmlFree(ret);
 3555: 	return(NULL);
 3556:     }
 3557:     ret->locals = xmlSchemaItemListCreate();
 3558:     if (ret->locals == NULL) {
 3559: 	xmlFree(ret);
 3560: 	return(NULL);
 3561:     }
 3562:     /*
 3563:     * The following will assure that only the first bucket is marked as
 3564:     * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
 3565:     * For each following import buckets an xmlSchema will be created.
 3566:     * An xmlSchema will be created for every distinct targetNamespace.
 3567:     * We assign the targetNamespace to the schemata here.
 3568:     */
 3569:     if (! WXS_HAS_BUCKETS(pctxt)) {
 3570: 	if (WXS_IS_BUCKET_INCREDEF(type)) {
 3571: 	    PERROR_INT("xmlSchemaBucketCreate",
 3572: 		"first bucket but it's an include or redefine");
 3573: 	    xmlSchemaBucketFree(ret);
 3574: 	    return(NULL);
 3575: 	}
 3576: 	/* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
 3577: 	ret->type = XML_SCHEMA_SCHEMA_MAIN;
 3578: 	/* Point to the *main* schema. */
 3579: 	WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
 3580: 	WXS_IMPBUCKET(ret)->schema = mainSchema;
 3581: 	/*
 3582: 	* Ensure that the main schema gets a targetNamespace.
 3583: 	*/
 3584: 	mainSchema->targetNamespace = targetNamespace;
 3585:     } else {
 3586: 	if (type == XML_SCHEMA_SCHEMA_MAIN) {
 3587: 	    PERROR_INT("xmlSchemaBucketCreate",
 3588: 		"main bucket but it's not the first one");
 3589: 	    xmlSchemaBucketFree(ret);
 3590: 	    return(NULL);
 3591: 	} else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
 3592: 	    /*
 3593: 	    * Create a schema for imports and assign the
 3594: 	    * targetNamespace.
 3595: 	    */
 3596: 	    WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
 3597: 	    if (WXS_IMPBUCKET(ret)->schema == NULL) {
 3598: 		xmlSchemaBucketFree(ret);
 3599: 		return(NULL);
 3600: 	    }
 3601: 	    WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
 3602: 	}
 3603:     }
 3604:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
 3605: 	int res;
 3606: 	/*
 3607: 	* Imports go into the "schemasImports" slot of the main *schema*.
 3608: 	* Note that we create an import entry for the main schema as well; i.e.,
 3609: 	* even if there's only one schema, we'll get an import.
 3610: 	*/
 3611: 	if (mainSchema->schemasImports == NULL) {
 3612: 	    mainSchema->schemasImports = xmlHashCreateDict(5,
 3613: 		WXS_CONSTRUCTOR(pctxt)->dict);
 3614: 	    if (mainSchema->schemasImports == NULL) {
 3615: 		xmlSchemaBucketFree(ret);
 3616: 		return(NULL);
 3617: 	    }
 3618: 	}
 3619: 	if (targetNamespace == NULL)
 3620: 	    res = xmlHashAddEntry(mainSchema->schemasImports,
 3621: 		XML_SCHEMAS_NO_NAMESPACE, ret);
 3622: 	else
 3623: 	    res = xmlHashAddEntry(mainSchema->schemasImports,
 3624: 		targetNamespace, ret);
 3625: 	if (res != 0) {
 3626: 	    PERROR_INT("xmlSchemaBucketCreate",
 3627: 		"failed to add the schema bucket to the hash");
 3628: 	    xmlSchemaBucketFree(ret);
 3629: 	    return(NULL);
 3630: 	}
 3631:     } else {
 3632: 	/* Set the @ownerImport of an include bucket. */
 3633: 	if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
 3634: 	    WXS_INCBUCKET(ret)->ownerImport =
 3635: 		WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
 3636: 	else
 3637: 	    WXS_INCBUCKET(ret)->ownerImport =
 3638: 		WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
 3639: 
 3640: 	/* Includes got into the "includes" slot of the *main* schema. */
 3641: 	if (mainSchema->includes == NULL) {
 3642: 	    mainSchema->includes = xmlSchemaItemListCreate();
 3643: 	    if (mainSchema->includes == NULL) {
 3644: 		xmlSchemaBucketFree(ret);
 3645: 		return(NULL);
 3646: 	    }
 3647: 	}
 3648: 	xmlSchemaItemListAdd(mainSchema->includes, ret);
 3649:     }
 3650:     /*
 3651:     * Add to list of all buckets; this is used for lookup
 3652:     * during schema construction time only.
 3653:     */
 3654:     if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
 3655: 	return(NULL);
 3656:     return(ret);
 3657: }
 3658: 
 3659: static int
 3660: xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
 3661: {
 3662:     if (*list == NULL) {
 3663: 	*list = xmlSchemaItemListCreate();
 3664: 	if (*list == NULL)
 3665: 	    return(-1);
 3666:     }
 3667:     xmlSchemaItemListAddSize(*list, initialSize, item);
 3668:     return(0);
 3669: }
 3670: 
 3671: /**
 3672:  * xmlSchemaFreeAnnot:
 3673:  * @annot:  a schema type structure
 3674:  *
 3675:  * Deallocate a annotation structure
 3676:  */
 3677: static void
 3678: xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
 3679: {
 3680:     if (annot == NULL)
 3681:         return;
 3682:     if (annot->next == NULL) {
 3683: 	xmlFree(annot);
 3684:     } else {
 3685: 	xmlSchemaAnnotPtr prev;
 3686: 
 3687: 	do {
 3688: 	    prev = annot;
 3689: 	    annot = annot->next;
 3690: 	    xmlFree(prev);
 3691: 	} while (annot != NULL);
 3692:     }
 3693: }
 3694: 
 3695: /**
 3696:  * xmlSchemaFreeNotation:
 3697:  * @schema:  a schema notation structure
 3698:  *
 3699:  * Deallocate a Schema Notation structure.
 3700:  */
 3701: static void
 3702: xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
 3703: {
 3704:     if (nota == NULL)
 3705:         return;
 3706:     xmlFree(nota);
 3707: }
 3708: 
 3709: /**
 3710:  * xmlSchemaFreeAttribute:
 3711:  * @attr:  an attribute declaration
 3712:  *
 3713:  * Deallocates an attribute declaration structure.
 3714:  */
 3715: static void
 3716: xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
 3717: {
 3718:     if (attr == NULL)
 3719:         return;
 3720:     if (attr->annot != NULL)
 3721: 	xmlSchemaFreeAnnot(attr->annot);
 3722:     if (attr->defVal != NULL)
 3723: 	xmlSchemaFreeValue(attr->defVal);
 3724:     xmlFree(attr);
 3725: }
 3726: 
 3727: /**
 3728:  * xmlSchemaFreeAttributeUse:
 3729:  * @use:  an attribute use
 3730:  *
 3731:  * Deallocates an attribute use structure.
 3732:  */
 3733: static void
 3734: xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
 3735: {
 3736:     if (use == NULL)
 3737:         return;
 3738:     if (use->annot != NULL)
 3739: 	xmlSchemaFreeAnnot(use->annot);
 3740:     if (use->defVal != NULL)
 3741: 	xmlSchemaFreeValue(use->defVal);
 3742:     xmlFree(use);
 3743: }
 3744: 
 3745: /**
 3746:  * xmlSchemaFreeAttributeUseProhib:
 3747:  * @prohib:  an attribute use prohibition
 3748:  *
 3749:  * Deallocates an attribute use structure.
 3750:  */
 3751: static void
 3752: xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
 3753: {
 3754:     if (prohib == NULL)
 3755:         return;
 3756:     xmlFree(prohib);
 3757: }
 3758: 
 3759: /**
 3760:  * xmlSchemaFreeWildcardNsSet:
 3761:  * set:  a schema wildcard namespace
 3762:  *
 3763:  * Deallocates a list of wildcard constraint structures.
 3764:  */
 3765: static void
 3766: xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
 3767: {
 3768:     xmlSchemaWildcardNsPtr next;
 3769: 
 3770:     while (set != NULL) {
 3771: 	next = set->next;
 3772: 	xmlFree(set);
 3773: 	set = next;
 3774:     }
 3775: }
 3776: 
 3777: /**
 3778:  * xmlSchemaFreeWildcard:
 3779:  * @wildcard:  a wildcard structure
 3780:  *
 3781:  * Deallocates a wildcard structure.
 3782:  */
 3783: void
 3784: xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
 3785: {
 3786:     if (wildcard == NULL)
 3787:         return;
 3788:     if (wildcard->annot != NULL)
 3789:         xmlSchemaFreeAnnot(wildcard->annot);
 3790:     if (wildcard->nsSet != NULL)
 3791: 	xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
 3792:     if (wildcard->negNsSet != NULL)
 3793: 	xmlFree(wildcard->negNsSet);
 3794:     xmlFree(wildcard);
 3795: }
 3796: 
 3797: /**
 3798:  * xmlSchemaFreeAttributeGroup:
 3799:  * @schema:  a schema attribute group structure
 3800:  *
 3801:  * Deallocate a Schema Attribute Group structure.
 3802:  */
 3803: static void
 3804: xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
 3805: {
 3806:     if (attrGr == NULL)
 3807:         return;
 3808:     if (attrGr->annot != NULL)
 3809:         xmlSchemaFreeAnnot(attrGr->annot);
 3810:     if (attrGr->attrUses != NULL)
 3811: 	xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
 3812:     xmlFree(attrGr);
 3813: }
 3814: 
 3815: /**
 3816:  * xmlSchemaFreeQNameRef:
 3817:  * @item: a QName reference structure
 3818:  *
 3819:  * Deallocatea a QName reference structure.
 3820:  */
 3821: static void
 3822: xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
 3823: {
 3824:     xmlFree(item);
 3825: }
 3826: 
 3827: /**
 3828:  * xmlSchemaFreeTypeLinkList:
 3829:  * @alink: a type link
 3830:  *
 3831:  * Deallocate a list of types.
 3832:  */
 3833: static void
 3834: xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
 3835: {
 3836:     xmlSchemaTypeLinkPtr next;
 3837: 
 3838:     while (link != NULL) {
 3839: 	next = link->next;
 3840: 	xmlFree(link);
 3841: 	link = next;
 3842:     }
 3843: }
 3844: 
 3845: static void
 3846: xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
 3847: {
 3848:     xmlSchemaIDCStateObjPtr next;
 3849:     while (sto != NULL) {
 3850: 	next = sto->next;
 3851: 	if (sto->history != NULL)
 3852: 	    xmlFree(sto->history);
 3853: 	if (sto->xpathCtxt != NULL)
 3854: 	    xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
 3855: 	xmlFree(sto);
 3856: 	sto = next;
 3857:     }
 3858: }
 3859: 
 3860: /**
 3861:  * xmlSchemaFreeIDC:
 3862:  * @idc: a identity-constraint definition
 3863:  *
 3864:  * Deallocates an identity-constraint definition.
 3865:  */
 3866: static void
 3867: xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
 3868: {
 3869:     xmlSchemaIDCSelectPtr cur, prev;
 3870: 
 3871:     if (idcDef == NULL)
 3872: 	return;
 3873:     if (idcDef->annot != NULL)
 3874:         xmlSchemaFreeAnnot(idcDef->annot);
 3875:     /* Selector */
 3876:     if (idcDef->selector != NULL) {
 3877: 	if (idcDef->selector->xpathComp != NULL)
 3878: 	    xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
 3879: 	xmlFree(idcDef->selector);
 3880:     }
 3881:     /* Fields */
 3882:     if (idcDef->fields != NULL) {
 3883: 	cur = idcDef->fields;
 3884: 	do {
 3885: 	    prev = cur;
 3886: 	    cur = cur->next;
 3887: 	    if (prev->xpathComp != NULL)
 3888: 		xmlFreePattern((xmlPatternPtr) prev->xpathComp);
 3889: 	    xmlFree(prev);
 3890: 	} while (cur != NULL);
 3891:     }
 3892:     xmlFree(idcDef);
 3893: }
 3894: 
 3895: /**
 3896:  * xmlSchemaFreeElement:
 3897:  * @schema:  a schema element structure
 3898:  *
 3899:  * Deallocate a Schema Element structure.
 3900:  */
 3901: static void
 3902: xmlSchemaFreeElement(xmlSchemaElementPtr elem)
 3903: {
 3904:     if (elem == NULL)
 3905:         return;
 3906:     if (elem->annot != NULL)
 3907:         xmlSchemaFreeAnnot(elem->annot);
 3908:     if (elem->contModel != NULL)
 3909:         xmlRegFreeRegexp(elem->contModel);
 3910:     if (elem->defVal != NULL)
 3911: 	xmlSchemaFreeValue(elem->defVal);
 3912:     xmlFree(elem);
 3913: }
 3914: 
 3915: /**
 3916:  * xmlSchemaFreeFacet:
 3917:  * @facet:  a schema facet structure
 3918:  *
 3919:  * Deallocate a Schema Facet structure.
 3920:  */
 3921: void
 3922: xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
 3923: {
 3924:     if (facet == NULL)
 3925:         return;
 3926:     if (facet->val != NULL)
 3927:         xmlSchemaFreeValue(facet->val);
 3928:     if (facet->regexp != NULL)
 3929:         xmlRegFreeRegexp(facet->regexp);
 3930:     if (facet->annot != NULL)
 3931:         xmlSchemaFreeAnnot(facet->annot);
 3932:     xmlFree(facet);
 3933: }
 3934: 
 3935: /**
 3936:  * xmlSchemaFreeType:
 3937:  * @type:  a schema type structure
 3938:  *
 3939:  * Deallocate a Schema Type structure.
 3940:  */
 3941: void
 3942: xmlSchemaFreeType(xmlSchemaTypePtr type)
 3943: {
 3944:     if (type == NULL)
 3945:         return;
 3946:     if (type->annot != NULL)
 3947:         xmlSchemaFreeAnnot(type->annot);
 3948:     if (type->facets != NULL) {
 3949:         xmlSchemaFacetPtr facet, next;
 3950: 
 3951:         facet = type->facets;
 3952:         while (facet != NULL) {
 3953:             next = facet->next;
 3954:             xmlSchemaFreeFacet(facet);
 3955:             facet = next;
 3956:         }
 3957:     }
 3958:     if (type->attrUses != NULL)
 3959: 	xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
 3960:     if (type->memberTypes != NULL)
 3961: 	xmlSchemaFreeTypeLinkList(type->memberTypes);
 3962:     if (type->facetSet != NULL) {
 3963: 	xmlSchemaFacetLinkPtr next, link;
 3964: 
 3965: 	link = type->facetSet;
 3966: 	do {
 3967: 	    next = link->next;
 3968: 	    xmlFree(link);
 3969: 	    link = next;
 3970: 	} while (link != NULL);
 3971:     }
 3972:     if (type->contModel != NULL)
 3973:         xmlRegFreeRegexp(type->contModel);
 3974:     xmlFree(type);
 3975: }
 3976: 
 3977: /**
 3978:  * xmlSchemaFreeModelGroupDef:
 3979:  * @item:  a schema model group definition
 3980:  *
 3981:  * Deallocates a schema model group definition.
 3982:  */
 3983: static void
 3984: xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
 3985: {
 3986:     if (item->annot != NULL)
 3987: 	xmlSchemaFreeAnnot(item->annot);
 3988:     xmlFree(item);
 3989: }
 3990: 
 3991: /**
 3992:  * xmlSchemaFreeModelGroup:
 3993:  * @item:  a schema model group
 3994:  *
 3995:  * Deallocates a schema model group structure.
 3996:  */
 3997: static void
 3998: xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
 3999: {
 4000:     if (item->annot != NULL)
 4001: 	xmlSchemaFreeAnnot(item->annot);
 4002:     xmlFree(item);
 4003: }
 4004: 
 4005: static void
 4006: xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
 4007: {
 4008:     if ((list == NULL) || (list->nbItems == 0))
 4009: 	return;
 4010:     {
 4011: 	xmlSchemaTreeItemPtr item;
 4012: 	xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
 4013: 	int i;
 4014: 
 4015: 	for (i = 0; i < list->nbItems; i++) {
 4016: 	    item = items[i];
 4017: 	    if (item == NULL)
 4018: 		continue;
 4019: 	    switch (item->type) {
 4020: 		case XML_SCHEMA_TYPE_SIMPLE:
 4021: 		case XML_SCHEMA_TYPE_COMPLEX:
 4022: 		    xmlSchemaFreeType((xmlSchemaTypePtr) item);
 4023: 		    break;
 4024: 		case XML_SCHEMA_TYPE_ATTRIBUTE:
 4025: 		    xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
 4026: 		    break;
 4027: 		case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
 4028: 		    xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
 4029: 		    break;
 4030: 		case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
 4031: 		    xmlSchemaFreeAttributeUseProhib(
 4032: 			(xmlSchemaAttributeUseProhibPtr) item);
 4033: 		    break;
 4034: 		case XML_SCHEMA_TYPE_ELEMENT:
 4035: 		    xmlSchemaFreeElement((xmlSchemaElementPtr) item);
 4036: 		    break;
 4037: 		case XML_SCHEMA_TYPE_PARTICLE:
 4038: 		    if (item->annot != NULL)
 4039: 			xmlSchemaFreeAnnot(item->annot);
 4040: 		    xmlFree(item);
 4041: 		    break;
 4042: 		case XML_SCHEMA_TYPE_SEQUENCE:
 4043: 		case XML_SCHEMA_TYPE_CHOICE:
 4044: 		case XML_SCHEMA_TYPE_ALL:
 4045: 		    xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
 4046: 		    break;
 4047: 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 4048: 		    xmlSchemaFreeAttributeGroup(
 4049: 			(xmlSchemaAttributeGroupPtr) item);
 4050: 		    break;
 4051: 		case XML_SCHEMA_TYPE_GROUP:
 4052: 		    xmlSchemaFreeModelGroupDef(
 4053: 			(xmlSchemaModelGroupDefPtr) item);
 4054: 		    break;
 4055: 		case XML_SCHEMA_TYPE_ANY:
 4056: 		case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 4057: 		    xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
 4058: 		    break;
 4059: 		case XML_SCHEMA_TYPE_IDC_KEY:
 4060: 		case XML_SCHEMA_TYPE_IDC_UNIQUE:
 4061: 		case XML_SCHEMA_TYPE_IDC_KEYREF:
 4062: 		    xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
 4063: 		    break;
 4064: 		case XML_SCHEMA_TYPE_NOTATION:
 4065: 		    xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
 4066: 		    break;
 4067: 		case XML_SCHEMA_EXTRA_QNAMEREF:
 4068: 		    xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
 4069: 		    break;
 4070: 		default: {
 4071: 		    /* TODO: This should never be hit. */
 4072: 		    xmlSchemaPSimpleInternalErr(NULL,
 4073: 			"Internal error: xmlSchemaComponentListFree, "
 4074: 			"unexpected component type '%s'\n",
 4075: 			(const xmlChar *) WXS_ITEM_TYPE_NAME(item));
 4076: 			 }
 4077: 		    break;
 4078: 	    }
 4079: 	}
 4080: 	list->nbItems = 0;
 4081:     }
 4082: }
 4083: 
 4084: /**
 4085:  * xmlSchemaFree:
 4086:  * @schema:  a schema structure
 4087:  *
 4088:  * Deallocate a Schema structure.
 4089:  */
 4090: void
 4091: xmlSchemaFree(xmlSchemaPtr schema)
 4092: {
 4093:     if (schema == NULL)
 4094:         return;
 4095:     /* @volatiles is not used anymore :-/ */
 4096:     if (schema->volatiles != NULL)
 4097: 	TODO
 4098:     /*
 4099:     * Note that those slots are not responsible for freeing
 4100:     * schema components anymore; this will now be done by
 4101:     * the schema buckets.
 4102:     */
 4103:     if (schema->notaDecl != NULL)
 4104:         xmlHashFree(schema->notaDecl, NULL);
 4105:     if (schema->attrDecl != NULL)
 4106:         xmlHashFree(schema->attrDecl, NULL);
 4107:     if (schema->attrgrpDecl != NULL)
 4108:         xmlHashFree(schema->attrgrpDecl, NULL);
 4109:     if (schema->elemDecl != NULL)
 4110:         xmlHashFree(schema->elemDecl, NULL);
 4111:     if (schema->typeDecl != NULL)
 4112:         xmlHashFree(schema->typeDecl, NULL);
 4113:     if (schema->groupDecl != NULL)
 4114:         xmlHashFree(schema->groupDecl, NULL);
 4115:     if (schema->idcDef != NULL)
 4116:         xmlHashFree(schema->idcDef, NULL);
 4117: 
 4118:     if (schema->schemasImports != NULL)
 4119: 	xmlHashFree(schema->schemasImports,
 4120: 		    (xmlHashDeallocator) xmlSchemaBucketFree);
 4121:     if (schema->includes != NULL) {
 4122: 	xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
 4123: 	int i;
 4124: 	for (i = 0; i < list->nbItems; i++) {
 4125: 	    xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
 4126: 	}
 4127: 	xmlSchemaItemListFree(list);
 4128:     }
 4129:     if (schema->annot != NULL)
 4130:         xmlSchemaFreeAnnot(schema->annot);
 4131:     /* Never free the doc here, since this will be done by the buckets. */
 4132: 
 4133:     xmlDictFree(schema->dict);
 4134:     xmlFree(schema);
 4135: }
 4136: 
 4137: /************************************************************************
 4138:  * 									*
 4139:  * 			Debug functions					*
 4140:  * 									*
 4141:  ************************************************************************/
 4142: 
 4143: #ifdef LIBXML_OUTPUT_ENABLED
 4144: 
 4145: static void
 4146: xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
 4147: 
 4148: /**
 4149:  * xmlSchemaElementDump:
 4150:  * @elem:  an element
 4151:  * @output:  the file output
 4152:  *
 4153:  * Dump the element
 4154:  */
 4155: static void
 4156: xmlSchemaElementDump(xmlSchemaElementPtr elem, FILE * output,
 4157:                      const xmlChar * name ATTRIBUTE_UNUSED,
 4158: 		     const xmlChar * namespace ATTRIBUTE_UNUSED,
 4159:                      const xmlChar * context ATTRIBUTE_UNUSED)
 4160: {
 4161:     if (elem == NULL)
 4162:         return;
 4163: 
 4164: 
 4165:     fprintf(output, "Element");
 4166:     if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
 4167: 	fprintf(output, " (global)");
 4168:     fprintf(output, ": '%s' ", elem->name);
 4169:     if (namespace != NULL)
 4170: 	fprintf(output, "ns '%s'", namespace);
 4171:     fprintf(output, "\n");
 4172: #if 0
 4173:     if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
 4174: 	fprintf(output, "  min %d ", elem->minOccurs);
 4175:         if (elem->maxOccurs >= UNBOUNDED)
 4176:             fprintf(output, "max: unbounded\n");
 4177:         else if (elem->maxOccurs != 1)
 4178:             fprintf(output, "max: %d\n", elem->maxOccurs);
 4179:         else
 4180:             fprintf(output, "\n");
 4181:     }
 4182: #endif
 4183:     /*
 4184:     * Misc other properties.
 4185:     */
 4186:     if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
 4187: 	(elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
 4188: 	(elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
 4189: 	(elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
 4190: 	fprintf(output, "  props: ");
 4191: 	if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
 4192: 	    fprintf(output, "[fixed] ");
 4193: 	if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
 4194: 	    fprintf(output, "[default] ");
 4195: 	if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
 4196: 	    fprintf(output, "[abstract] ");
 4197: 	if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
 4198: 	    fprintf(output, "[nillable] ");
 4199: 	fprintf(output, "\n");
 4200:     }
 4201:     /*
 4202:     * Default/fixed value.
 4203:     */
 4204:     if (elem->value != NULL)
 4205: 	fprintf(output, "  value: '%s'\n", elem->value);
 4206:     /*
 4207:     * Type.
 4208:     */
 4209:     if (elem->namedType != NULL) {
 4210: 	fprintf(output, "  type: '%s' ", elem->namedType);
 4211: 	if (elem->namedTypeNs != NULL)
 4212: 	    fprintf(output, "ns '%s'\n", elem->namedTypeNs);
 4213: 	else
 4214: 	    fprintf(output, "\n");
 4215:     } else if (elem->subtypes != NULL) {
 4216: 	/*
 4217: 	* Dump local types.
 4218: 	*/
 4219: 	xmlSchemaTypeDump(elem->subtypes, output);
 4220:     }
 4221:     /*
 4222:     * Substitution group.
 4223:     */
 4224:     if (elem->substGroup != NULL) {
 4225: 	fprintf(output, "  substitutionGroup: '%s' ", elem->substGroup);
 4226: 	if (elem->substGroupNs != NULL)
 4227: 	    fprintf(output, "ns '%s'\n", elem->substGroupNs);
 4228: 	else
 4229: 	    fprintf(output, "\n");
 4230:     }
 4231: }
 4232: 
 4233: /**
 4234:  * xmlSchemaAnnotDump:
 4235:  * @output:  the file output
 4236:  * @annot:  a annotation
 4237:  *
 4238:  * Dump the annotation
 4239:  */
 4240: static void
 4241: xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
 4242: {
 4243:     xmlChar *content;
 4244: 
 4245:     if (annot == NULL)
 4246:         return;
 4247: 
 4248:     content = xmlNodeGetContent(annot->content);
 4249:     if (content != NULL) {
 4250:         fprintf(output, "  Annot: %s\n", content);
 4251:         xmlFree(content);
 4252:     } else
 4253:         fprintf(output, "  Annot: empty\n");
 4254: }
 4255: 
 4256: /**
 4257:  * xmlSchemaContentModelDump:
 4258:  * @particle: the schema particle
 4259:  * @output: the file output
 4260:  * @depth: the depth used for intentation
 4261:  *
 4262:  * Dump a SchemaType structure
 4263:  */
 4264: static void
 4265: xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
 4266: {
 4267:     xmlChar *str = NULL;
 4268:     xmlSchemaTreeItemPtr term;
 4269:     char shift[100];
 4270:     int i;
 4271: 
 4272:     if (particle == NULL)
 4273: 	return;
 4274:     for (i = 0;((i < depth) && (i < 25));i++)
 4275:         shift[2 * i] = shift[2 * i + 1] = ' ';
 4276:     shift[2 * i] = shift[2 * i + 1] = 0;
 4277:     fprintf(output, "%s", shift);
 4278:     if (particle->children == NULL) {
 4279: 	fprintf(output, "MISSING particle term\n");
 4280: 	return;
 4281:     }
 4282:     term = particle->children;
 4283:     if (term == NULL) {
 4284: 	fprintf(output, "(NULL)");
 4285:     } else {
 4286: 	switch (term->type) {
 4287: 	    case XML_SCHEMA_TYPE_ELEMENT:
 4288: 		fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
 4289: 		    ((xmlSchemaElementPtr)term)->targetNamespace,
 4290: 		    ((xmlSchemaElementPtr)term)->name));
 4291: 		FREE_AND_NULL(str);
 4292: 		break;
 4293: 	    case XML_SCHEMA_TYPE_SEQUENCE:
 4294: 		fprintf(output, "SEQUENCE");
 4295: 		break;
 4296: 	    case XML_SCHEMA_TYPE_CHOICE:
 4297: 		fprintf(output, "CHOICE");
 4298: 		break;
 4299: 	    case XML_SCHEMA_TYPE_ALL:
 4300: 		fprintf(output, "ALL");
 4301: 		break;
 4302: 	    case XML_SCHEMA_TYPE_ANY:
 4303: 		fprintf(output, "ANY");
 4304: 		break;
 4305: 	    default:
 4306: 		fprintf(output, "UNKNOWN\n");
 4307: 		return;
 4308: 	}
 4309:     }
 4310:     if (particle->minOccurs != 1)
 4311: 	fprintf(output, " min: %d", particle->minOccurs);
 4312:     if (particle->maxOccurs >= UNBOUNDED)
 4313: 	fprintf(output, " max: unbounded");
 4314:     else if (particle->maxOccurs != 1)
 4315: 	fprintf(output, " max: %d", particle->maxOccurs);
 4316:     fprintf(output, "\n");
 4317:     if (term &&
 4318: 	((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
 4319: 	 (term->type == XML_SCHEMA_TYPE_CHOICE) ||
 4320: 	 (term->type == XML_SCHEMA_TYPE_ALL)) &&
 4321: 	 (term->children != NULL)) {
 4322: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
 4323: 	    output, depth +1);
 4324:     }
 4325:     if (particle->next != NULL)
 4326: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
 4327: 		output, depth);
 4328: }
 4329: 
 4330: /**
 4331:  * xmlSchemaAttrUsesDump:
 4332:  * @uses:  attribute uses list
 4333:  * @output:  the file output
 4334:  *
 4335:  * Dumps a list of attribute use components.
 4336:  */
 4337: static void
 4338: xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
 4339: {
 4340:     xmlSchemaAttributeUsePtr use;
 4341:     xmlSchemaAttributeUseProhibPtr prohib;
 4342:     xmlSchemaQNameRefPtr ref;
 4343:     const xmlChar *name, *tns;
 4344:     xmlChar *str = NULL;
 4345:     int i;
 4346: 
 4347:     if ((uses == NULL) || (uses->nbItems == 0))
 4348:         return;
 4349: 
 4350:     fprintf(output, "  attributes:\n");
 4351:     for (i = 0; i < uses->nbItems; i++) {
 4352: 	use = uses->items[i];
 4353: 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
 4354: 	    fprintf(output, "  [prohibition] ");
 4355: 	    prohib = (xmlSchemaAttributeUseProhibPtr) use;
 4356: 	    name = prohib->name;
 4357: 	    tns = prohib->targetNamespace;
 4358: 	} else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
 4359: 	    fprintf(output, "  [reference] ");
 4360: 	    ref = (xmlSchemaQNameRefPtr) use;
 4361: 	    name = ref->name;
 4362: 	    tns = ref->targetNamespace;
 4363: 	} else {
 4364: 	    fprintf(output, "  [use] ");
 4365: 	    name = WXS_ATTRUSE_DECL_NAME(use);
 4366: 	    tns = WXS_ATTRUSE_DECL_TNS(use);
 4367: 	}
 4368: 	fprintf(output, "'%s'\n",
 4369: 	    (const char *) xmlSchemaFormatQName(&str, tns, name));
 4370: 	FREE_AND_NULL(str);
 4371:     }
 4372: }
 4373: 
 4374: /**
 4375:  * xmlSchemaTypeDump:
 4376:  * @output:  the file output
 4377:  * @type:  a type structure
 4378:  *
 4379:  * Dump a SchemaType structure
 4380:  */
 4381: static void
 4382: xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
 4383: {
 4384:     if (type == NULL) {
 4385:         fprintf(output, "Type: NULL\n");
 4386:         return;
 4387:     }
 4388:     fprintf(output, "Type: ");
 4389:     if (type->name != NULL)
 4390:         fprintf(output, "'%s' ", type->name);
 4391:     else
 4392:         fprintf(output, "(no name) ");
 4393:     if (type->targetNamespace != NULL)
 4394: 	fprintf(output, "ns '%s' ", type->targetNamespace);
 4395:     switch (type->type) {
 4396:         case XML_SCHEMA_TYPE_BASIC:
 4397:             fprintf(output, "[basic] ");
 4398:             break;
 4399:         case XML_SCHEMA_TYPE_SIMPLE:
 4400:             fprintf(output, "[simple] ");
 4401:             break;
 4402:         case XML_SCHEMA_TYPE_COMPLEX:
 4403:             fprintf(output, "[complex] ");
 4404:             break;
 4405:         case XML_SCHEMA_TYPE_SEQUENCE:
 4406:             fprintf(output, "[sequence] ");
 4407:             break;
 4408:         case XML_SCHEMA_TYPE_CHOICE:
 4409:             fprintf(output, "[choice] ");
 4410:             break;
 4411:         case XML_SCHEMA_TYPE_ALL:
 4412:             fprintf(output, "[all] ");
 4413:             break;
 4414:         case XML_SCHEMA_TYPE_UR:
 4415:             fprintf(output, "[ur] ");
 4416:             break;
 4417:         case XML_SCHEMA_TYPE_RESTRICTION:
 4418:             fprintf(output, "[restriction] ");
 4419:             break;
 4420:         case XML_SCHEMA_TYPE_EXTENSION:
 4421:             fprintf(output, "[extension] ");
 4422:             break;
 4423:         default:
 4424:             fprintf(output, "[unknown type %d] ", type->type);
 4425:             break;
 4426:     }
 4427:     fprintf(output, "content: ");
 4428:     switch (type->contentType) {
 4429:         case XML_SCHEMA_CONTENT_UNKNOWN:
 4430:             fprintf(output, "[unknown] ");
 4431:             break;
 4432:         case XML_SCHEMA_CONTENT_EMPTY:
 4433:             fprintf(output, "[empty] ");
 4434:             break;
 4435:         case XML_SCHEMA_CONTENT_ELEMENTS:
 4436:             fprintf(output, "[element] ");
 4437:             break;
 4438:         case XML_SCHEMA_CONTENT_MIXED:
 4439:             fprintf(output, "[mixed] ");
 4440:             break;
 4441:         case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
 4442: 	/* not used. */
 4443:             break;
 4444:         case XML_SCHEMA_CONTENT_BASIC:
 4445:             fprintf(output, "[basic] ");
 4446:             break;
 4447:         case XML_SCHEMA_CONTENT_SIMPLE:
 4448:             fprintf(output, "[simple] ");
 4449:             break;
 4450:         case XML_SCHEMA_CONTENT_ANY:
 4451:             fprintf(output, "[any] ");
 4452:             break;
 4453:     }
 4454:     fprintf(output, "\n");
 4455:     if (type->base != NULL) {
 4456:         fprintf(output, "  base type: '%s'", type->base);
 4457: 	if (type->baseNs != NULL)
 4458: 	    fprintf(output, " ns '%s'\n", type->baseNs);
 4459: 	else
 4460: 	    fprintf(output, "\n");
 4461:     }
 4462:     if (type->attrUses != NULL)
 4463: 	xmlSchemaAttrUsesDump(type->attrUses, output);
 4464:     if (type->annot != NULL)
 4465:         xmlSchemaAnnotDump(output, type->annot);
 4466: #ifdef DUMP_CONTENT_MODEL
 4467:     if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
 4468: 	(type->subtypes != NULL)) {
 4469: 	xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
 4470: 	    output, 1);
 4471:     }
 4472: #endif
 4473: }
 4474: 
 4475: /**
 4476:  * xmlSchemaDump:
 4477:  * @output:  the file output
 4478:  * @schema:  a schema structure
 4479:  *
 4480:  * Dump a Schema structure.
 4481:  */
 4482: void
 4483: xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
 4484: {
 4485:     if (output == NULL)
 4486:         return;
 4487:     if (schema == NULL) {
 4488:         fprintf(output, "Schemas: NULL\n");
 4489:         return;
 4490:     }
 4491:     fprintf(output, "Schemas: ");
 4492:     if (schema->name != NULL)
 4493:         fprintf(output, "%s, ", schema->name);
 4494:     else
 4495:         fprintf(output, "no name, ");
 4496:     if (schema->targetNamespace != NULL)
 4497:         fprintf(output, "%s", (const char *) schema->targetNamespace);
 4498:     else
 4499:         fprintf(output, "no target namespace");
 4500:     fprintf(output, "\n");
 4501:     if (schema->annot != NULL)
 4502:         xmlSchemaAnnotDump(output, schema->annot);
 4503:     xmlHashScan(schema->typeDecl, (xmlHashScanner) xmlSchemaTypeDump,
 4504:                 output);
 4505:     xmlHashScanFull(schema->elemDecl,
 4506:                     (xmlHashScannerFull) xmlSchemaElementDump, output);
 4507: }
 4508: 
 4509: #ifdef DEBUG_IDC_NODE_TABLE
 4510: /**
 4511:  * xmlSchemaDebugDumpIDCTable:
 4512:  * @vctxt: the WXS validation context
 4513:  *
 4514:  * Displays the current IDC table for debug purposes.
 4515:  */
 4516: static void
 4517: xmlSchemaDebugDumpIDCTable(FILE * output,
 4518: 			   const xmlChar *namespaceName,
 4519: 			   const xmlChar *localName,
 4520: 			   xmlSchemaPSVIIDCBindingPtr bind)
 4521: {
 4522:     xmlChar *str = NULL;
 4523:     const xmlChar *value;
 4524:     xmlSchemaPSVIIDCNodePtr tab;
 4525:     xmlSchemaPSVIIDCKeyPtr key;
 4526:     int i, j, res;
 4527: 
 4528:     fprintf(output, "IDC: TABLES on '%s'\n",
 4529: 	xmlSchemaFormatQName(&str, namespaceName, localName));
 4530:     FREE_AND_NULL(str)
 4531: 
 4532:     if (bind == NULL)
 4533: 	return;
 4534:     do {
 4535: 	fprintf(output, "IDC:   BINDING '%s' (%d)\n",
 4536: 	    xmlSchemaGetComponentQName(&str,
 4537: 		bind->definition), bind->nbNodes);
 4538: 	FREE_AND_NULL(str)
 4539: 	for (i = 0; i < bind->nbNodes; i++) {
 4540: 	    tab = bind->nodeTable[i];
 4541: 	    fprintf(output, "         ( ");
 4542: 	    for (j = 0; j < bind->definition->nbFields; j++) {
 4543: 		key = tab->keys[j];
 4544: 		if ((key != NULL) && (key->val != NULL)) {
 4545: 		    res = xmlSchemaGetCanonValue(key->val, &value);
 4546: 		    if (res >= 0)
 4547: 			fprintf(output, "'%s' ", value);
 4548: 		    else
 4549: 			fprintf(output, "CANON-VALUE-FAILED ");
 4550: 		    if (res == 0)
 4551: 			FREE_AND_NULL(value)
 4552: 		} else if (key != NULL)
 4553: 		    fprintf(output, "(no val), ");
 4554: 		else
 4555: 		    fprintf(output, "(key missing), ");
 4556: 	    }
 4557: 	    fprintf(output, ")\n");
 4558: 	}
 4559: 	if (bind->dupls && bind->dupls->nbItems) {
 4560: 	    fprintf(output, "IDC:     dupls (%d):\n", bind->dupls->nbItems);
 4561: 	    for (i = 0; i < bind->dupls->nbItems; i++) {
 4562: 		tab = bind->dupls->items[i];
 4563: 		fprintf(output, "         ( ");
 4564: 		for (j = 0; j < bind->definition->nbFields; j++) {
 4565: 		    key = tab->keys[j];
 4566: 		    if ((key != NULL) && (key->val != NULL)) {
 4567: 			res = xmlSchemaGetCanonValue(key->val, &value);
 4568: 			if (res >= 0)
 4569: 			    fprintf(output, "'%s' ", value);
 4570: 			else
 4571: 			    fprintf(output, "CANON-VALUE-FAILED ");
 4572: 			if (res == 0)
 4573: 			    FREE_AND_NULL(value)
 4574: 		    } else if (key != NULL)
 4575: 		    fprintf(output, "(no val), ");
 4576: 			else
 4577: 			    fprintf(output, "(key missing), ");
 4578: 		}
 4579: 		fprintf(output, ")\n");
 4580: 	    }
 4581: 	}
 4582: 	bind = bind->next;
 4583:     } while (bind != NULL);
 4584: }
 4585: #endif /* DEBUG_IDC */
 4586: #endif /* LIBXML_OUTPUT_ENABLED */
 4587: 
 4588: /************************************************************************
 4589:  *									*
 4590:  * 			Utilities					*
 4591:  *									*
 4592:  ************************************************************************/
 4593: 
 4594: /**
 4595:  * xmlSchemaGetPropNode:
 4596:  * @node: the element node
 4597:  * @name: the name of the attribute
 4598:  *
 4599:  * Seeks an attribute with a name of @name in
 4600:  * no namespace.
 4601:  *
 4602:  * Returns the attribute or NULL if not present.
 4603:  */
 4604: static xmlAttrPtr
 4605: xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
 4606: {
 4607:     xmlAttrPtr prop;
 4608: 
 4609:     if ((node == NULL) || (name == NULL))
 4610: 	return(NULL);
 4611:     prop = node->properties;
 4612:     while (prop != NULL) {
 4613:         if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
 4614: 	    return(prop);
 4615: 	prop = prop->next;
 4616:     }
 4617:     return (NULL);
 4618: }
 4619: 
 4620: /**
 4621:  * xmlSchemaGetPropNodeNs:
 4622:  * @node: the element node
 4623:  * @uri: the uri
 4624:  * @name: the name of the attribute
 4625:  *
 4626:  * Seeks an attribute with a local name of @name and
 4627:  * a namespace URI of @uri.
 4628:  *
 4629:  * Returns the attribute or NULL if not present.
 4630:  */
 4631: static xmlAttrPtr
 4632: xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
 4633: {
 4634:     xmlAttrPtr prop;
 4635: 
 4636:     if ((node == NULL) || (name == NULL))
 4637: 	return(NULL);
 4638:     prop = node->properties;
 4639:     while (prop != NULL) {
 4640: 	if ((prop->ns != NULL) &&
 4641: 	    xmlStrEqual(prop->name, BAD_CAST name) &&
 4642: 	    xmlStrEqual(prop->ns->href, BAD_CAST uri))
 4643: 	    return(prop);
 4644: 	prop = prop->next;
 4645:     }
 4646:     return (NULL);
 4647: }
 4648: 
 4649: static const xmlChar *
 4650: xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
 4651: {
 4652:     xmlChar *val;
 4653:     const xmlChar *ret;
 4654: 
 4655:     val = xmlNodeGetContent(node);
 4656:     if (val == NULL)
 4657: 	val = xmlStrdup((xmlChar *)"");
 4658:     ret = xmlDictLookup(ctxt->dict, val, -1);
 4659:     xmlFree(val);
 4660:     return(ret);
 4661: }
 4662: 
 4663: static const xmlChar *
 4664: xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
 4665: {
 4666:     return((const xmlChar*) xmlNodeGetContent(node));
 4667: }
 4668: 
 4669: /**
 4670:  * xmlSchemaGetProp:
 4671:  * @ctxt: the parser context
 4672:  * @node: the node
 4673:  * @name: the property name
 4674:  *
 4675:  * Read a attribute value and internalize the string
 4676:  *
 4677:  * Returns the string or NULL if not present.
 4678:  */
 4679: static const xmlChar *
 4680: xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 4681:                  const char *name)
 4682: {
 4683:     xmlChar *val;
 4684:     const xmlChar *ret;
 4685: 
 4686:     val = xmlGetNoNsProp(node, BAD_CAST name);
 4687:     if (val == NULL)
 4688:         return(NULL);
 4689:     ret = xmlDictLookup(ctxt->dict, val, -1);
 4690:     xmlFree(val);
 4691:     return(ret);
 4692: }
 4693: 
 4694: /************************************************************************
 4695:  * 									*
 4696:  * 			Parsing functions				*
 4697:  * 									*
 4698:  ************************************************************************/
 4699: 
 4700: #define WXS_FIND_GLOBAL_ITEM(slot)			\
 4701:     if (xmlStrEqual(nsName, schema->targetNamespace)) { \
 4702: 	ret = xmlHashLookup(schema->slot, name); \
 4703: 	if (ret != NULL) goto exit; \
 4704:     } \
 4705:     if (xmlHashSize(schema->schemasImports) > 1) { \
 4706: 	xmlSchemaImportPtr import; \
 4707: 	if (nsName == NULL) \
 4708: 	    import = xmlHashLookup(schema->schemasImports, \
 4709: 		XML_SCHEMAS_NO_NAMESPACE); \
 4710: 	else \
 4711: 	    import = xmlHashLookup(schema->schemasImports, nsName); \
 4712: 	if (import == NULL) \
 4713: 	    goto exit; \
 4714: 	ret = xmlHashLookup(import->schema->slot, name); \
 4715:     }
 4716: 
 4717: /**
 4718:  * xmlSchemaGetElem:
 4719:  * @schema:  the schema context
 4720:  * @name:  the element name
 4721:  * @ns:  the element namespace
 4722:  *
 4723:  * Lookup a global element declaration in the schema.
 4724:  *
 4725:  * Returns the element declaration or NULL if not found.
 4726:  */
 4727: static xmlSchemaElementPtr
 4728: xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
 4729:                  const xmlChar * nsName)
 4730: {
 4731:     xmlSchemaElementPtr ret = NULL;
 4732: 
 4733:     if ((name == NULL) || (schema == NULL))
 4734:         return(NULL);
 4735:     if (schema != NULL) {
 4736: 	WXS_FIND_GLOBAL_ITEM(elemDecl)
 4737:     }
 4738: exit:
 4739: #ifdef DEBUG
 4740:     if (ret == NULL) {
 4741:         if (nsName == NULL)
 4742:             fprintf(stderr, "Unable to lookup element decl. %s", name);
 4743:         else
 4744:             fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
 4745:                     nsName);
 4746:     }
 4747: #endif
 4748:     return (ret);
 4749: }
 4750: 
 4751: /**
 4752:  * xmlSchemaGetType:
 4753:  * @schema:  the main schema
 4754:  * @name:  the type's name
 4755:  * nsName:  the type's namespace
 4756:  *
 4757:  * Lookup a type in the schemas or the predefined types
 4758:  *
 4759:  * Returns the group definition or NULL if not found.
 4760:  */
 4761: static xmlSchemaTypePtr
 4762: xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
 4763:                  const xmlChar * nsName)
 4764: {
 4765:     xmlSchemaTypePtr ret = NULL;
 4766: 
 4767:     if (name == NULL)
 4768:         return (NULL);
 4769:     /* First try the built-in types. */
 4770:     if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
 4771: 	ret = xmlSchemaGetPredefinedType(name, nsName);
 4772: 	if (ret != NULL)
 4773: 	    goto exit;
 4774: 	/*
 4775: 	* Note that we try the parsed schemas as well here
 4776: 	* since one might have parsed the S4S, which contain more
 4777: 	* than the built-in types.
 4778: 	* TODO: Can we optimize this?
 4779: 	*/
 4780:     }
 4781:     if (schema != NULL) {
 4782: 	WXS_FIND_GLOBAL_ITEM(typeDecl)
 4783:     }
 4784: exit:
 4785: 
 4786: #ifdef DEBUG
 4787:     if (ret == NULL) {
 4788:         if (nsName == NULL)
 4789:             fprintf(stderr, "Unable to lookup type %s", name);
 4790:         else
 4791:             fprintf(stderr, "Unable to lookup type %s:%s", name,
 4792:                     nsName);
 4793:     }
 4794: #endif
 4795:     return (ret);
 4796: }
 4797: 
 4798: /**
 4799:  * xmlSchemaGetAttributeDecl:
 4800:  * @schema:  the context of the schema
 4801:  * @name:  the name of the attribute
 4802:  * @ns:  the target namespace of the attribute
 4803:  *
 4804:  * Lookup a an attribute in the schema or imported schemas
 4805:  *
 4806:  * Returns the attribute declaration or NULL if not found.
 4807:  */
 4808: static xmlSchemaAttributePtr
 4809: xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
 4810:                  const xmlChar * nsName)
 4811: {
 4812:     xmlSchemaAttributePtr ret = NULL;
 4813: 
 4814:     if ((name == NULL) || (schema == NULL))
 4815:         return (NULL);
 4816:     if (schema != NULL) {
 4817: 	WXS_FIND_GLOBAL_ITEM(attrDecl)
 4818:     }
 4819: exit:
 4820: #ifdef DEBUG
 4821:     if (ret == NULL) {
 4822:         if (nsName == NULL)
 4823:             fprintf(stderr, "Unable to lookup attribute %s", name);
 4824:         else
 4825:             fprintf(stderr, "Unable to lookup attribute %s:%s", name,
 4826:                     nsName);
 4827:     }
 4828: #endif
 4829:     return (ret);
 4830: }
 4831: 
 4832: /**
 4833:  * xmlSchemaGetAttributeGroup:
 4834:  * @schema:  the context of the schema
 4835:  * @name:  the name of the attribute group
 4836:  * @ns:  the target namespace of the attribute group
 4837:  *
 4838:  * Lookup a an attribute group in the schema or imported schemas
 4839:  *
 4840:  * Returns the attribute group definition or NULL if not found.
 4841:  */
 4842: static xmlSchemaAttributeGroupPtr
 4843: xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
 4844:                  const xmlChar * nsName)
 4845: {
 4846:     xmlSchemaAttributeGroupPtr ret = NULL;
 4847: 
 4848:     if ((name == NULL) || (schema == NULL))
 4849:         return (NULL);
 4850:     if (schema != NULL) {
 4851: 	WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
 4852:     }
 4853: exit:
 4854:     /* TODO:
 4855:     if ((ret != NULL) && (ret->redef != NULL)) {
 4856: 	* Return the last redefinition. *
 4857: 	ret = ret->redef;
 4858:     }
 4859:     */
 4860: #ifdef DEBUG
 4861:     if (ret == NULL) {
 4862:         if (nsName == NULL)
 4863:             fprintf(stderr, "Unable to lookup attribute group %s", name);
 4864:         else
 4865:             fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
 4866:                     nsName);
 4867:     }
 4868: #endif
 4869:     return (ret);
 4870: }
 4871: 
 4872: /**
 4873:  * xmlSchemaGetGroup:
 4874:  * @schema:  the context of the schema
 4875:  * @name:  the name of the group
 4876:  * @ns:  the target namespace of the group
 4877:  *
 4878:  * Lookup a group in the schema or imported schemas
 4879:  *
 4880:  * Returns the group definition or NULL if not found.
 4881:  */
 4882: static xmlSchemaModelGroupDefPtr
 4883: xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
 4884:                  const xmlChar * nsName)
 4885: {
 4886:     xmlSchemaModelGroupDefPtr ret = NULL;
 4887: 
 4888:     if ((name == NULL) || (schema == NULL))
 4889:         return (NULL);
 4890:     if (schema != NULL) {
 4891: 	WXS_FIND_GLOBAL_ITEM(groupDecl)
 4892:     }
 4893: exit:
 4894: 
 4895: #ifdef DEBUG
 4896:     if (ret == NULL) {
 4897:         if (nsName == NULL)
 4898:             fprintf(stderr, "Unable to lookup group %s", name);
 4899:         else
 4900:             fprintf(stderr, "Unable to lookup group %s:%s", name,
 4901:                     nsName);
 4902:     }
 4903: #endif
 4904:     return (ret);
 4905: }
 4906: 
 4907: static xmlSchemaNotationPtr
 4908: xmlSchemaGetNotation(xmlSchemaPtr schema,
 4909: 		     const xmlChar *name,
 4910: 		     const xmlChar *nsName)
 4911: {
 4912:     xmlSchemaNotationPtr ret = NULL;
 4913: 
 4914:     if ((name == NULL) || (schema == NULL))
 4915:         return (NULL);
 4916:     if (schema != NULL) {
 4917: 	WXS_FIND_GLOBAL_ITEM(notaDecl)
 4918:     }
 4919: exit:
 4920:     return (ret);
 4921: }
 4922: 
 4923: static xmlSchemaIDCPtr
 4924: xmlSchemaGetIDC(xmlSchemaPtr schema,
 4925: 		const xmlChar *name,
 4926: 		const xmlChar *nsName)
 4927: {
 4928:     xmlSchemaIDCPtr ret = NULL;
 4929: 
 4930:     if ((name == NULL) || (schema == NULL))
 4931:         return (NULL);
 4932:     if (schema != NULL) {
 4933: 	WXS_FIND_GLOBAL_ITEM(idcDef)
 4934:     }
 4935: exit:
 4936:     return (ret);
 4937: }
 4938: 
 4939: /**
 4940:  * xmlSchemaGetNamedComponent:
 4941:  * @schema:  the schema
 4942:  * @name:  the name of the group
 4943:  * @ns:  the target namespace of the group
 4944:  *
 4945:  * Lookup a group in the schema or imported schemas
 4946:  *
 4947:  * Returns the group definition or NULL if not found.
 4948:  */
 4949: static xmlSchemaBasicItemPtr
 4950: xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
 4951: 			   xmlSchemaTypeType itemType,
 4952: 			   const xmlChar *name,
 4953: 			   const xmlChar *targetNs)
 4954: {
 4955:     switch (itemType) {
 4956: 	case XML_SCHEMA_TYPE_GROUP:
 4957: 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
 4958: 		name, targetNs));
 4959: 	case XML_SCHEMA_TYPE_ELEMENT:
 4960: 	    return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
 4961: 		name, targetNs));
 4962: 	default:
 4963: 	    TODO
 4964: 	    return (NULL);
 4965:     }
 4966: }
 4967: 
 4968: /************************************************************************
 4969:  * 									*
 4970:  * 			Parsing functions				*
 4971:  * 									*
 4972:  ************************************************************************/
 4973: 
 4974: #define IS_BLANK_NODE(n)						\
 4975:     (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
 4976: 
 4977: /**
 4978:  * xmlSchemaIsBlank:
 4979:  * @str:  a string
 4980:  * @len: the length of the string or -1
 4981:  *
 4982:  * Check if a string is ignorable
 4983:  *
 4984:  * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
 4985:  */
 4986: static int
 4987: xmlSchemaIsBlank(xmlChar * str, int len)
 4988: {
 4989:     if (str == NULL)
 4990:         return (1);
 4991:     if (len < 0) {
 4992: 	while (*str != 0) {
 4993: 	    if (!(IS_BLANK_CH(*str)))
 4994: 		return (0);
 4995: 	    str++;
 4996: 	}
 4997:     } else while ((*str != 0) && (len != 0)) {
 4998: 	if (!(IS_BLANK_CH(*str)))
 4999: 	    return (0);
 5000: 	str++;
 5001: 	len--;
 5002:     }
 5003: 
 5004:     return (1);
 5005: }
 5006: 
 5007: #define WXS_COMP_NAME(c, t) ((t) (c))->name
 5008: #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
 5009: /*
 5010: * xmlSchemaFindRedefCompInGraph:
 5011: * ATTENTION TODO: This uses pointer comp. for strings.
 5012: */
 5013: static xmlSchemaBasicItemPtr
 5014: xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
 5015: 			      xmlSchemaTypeType type,
 5016: 			      const xmlChar *name,
 5017: 			      const xmlChar *nsName)
 5018: {
 5019:     xmlSchemaBasicItemPtr ret;
 5020:     int i;
 5021: 
 5022:     if ((bucket == NULL) || (name == NULL))
 5023: 	return(NULL);
 5024:     if ((bucket->globals == NULL) ||
 5025: 	(bucket->globals->nbItems == 0))
 5026: 	goto subschemas;
 5027:     /*
 5028:     * Search in global components.
 5029:     */
 5030:     for (i = 0; i < bucket->globals->nbItems; i++) {
 5031: 	ret = bucket->globals->items[i];
 5032: 	if (ret->type == type) {
 5033: 	    switch (type) {
 5034: 		case XML_SCHEMA_TYPE_COMPLEX:
 5035: 		case XML_SCHEMA_TYPE_SIMPLE:
 5036: 		    if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
 5037: 			(WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
 5038: 			nsName))
 5039: 		    {
 5040: 			return(ret);
 5041: 		    }
 5042: 		    break;
 5043: 		case XML_SCHEMA_TYPE_GROUP:
 5044: 		    if ((WXS_COMP_NAME(ret,
 5045: 			    xmlSchemaModelGroupDefPtr) == name) &&
 5046: 			(WXS_COMP_TNS(ret,
 5047: 			    xmlSchemaModelGroupDefPtr) == nsName))
 5048: 		    {
 5049: 			return(ret);
 5050: 		    }
 5051: 		    break;
 5052: 		case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
 5053: 		    if ((WXS_COMP_NAME(ret,
 5054: 			    xmlSchemaAttributeGroupPtr) == name) &&
 5055: 			(WXS_COMP_TNS(ret,
 5056: 			    xmlSchemaAttributeGroupPtr) == nsName))
 5057: 		    {
 5058: 			return(ret);
 5059: 		    }
 5060: 		    break;
 5061: 		default:
 5062: 		    /* Should not be hit. */
 5063: 		    return(NULL);
 5064: 	    }
 5065: 	}
 5066:     }
 5067: subschemas:
 5068:     /*
 5069:     * Process imported/included schemas.
 5070:     */
 5071:     if (bucket->relations != NULL) {
 5072: 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
 5073: 
 5074: 	/*
 5075: 	* TODO: Marking the bucket will not avoid multiple searches
 5076: 	* in the same schema, but avoids at least circularity.
 5077: 	*/
 5078: 	bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
 5079: 	do {
 5080: 	    if ((rel->bucket != NULL) &&
 5081: 		((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
 5082: 		ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
 5083: 		    type, name, nsName);
 5084: 		if (ret != NULL)
 5085: 		    return(ret);
 5086: 	    }
 5087: 	    rel = rel->next;
 5088: 	} while (rel != NULL);
 5089: 	 bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
 5090:     }
 5091:     return(NULL);
 5092: }
 5093: 
 5094: /**
 5095:  * xmlSchemaAddNotation:
 5096:  * @ctxt:  a schema parser context
 5097:  * @schema:  the schema being built
 5098:  * @name:  the item name
 5099:  *
 5100:  * Add an XML schema annotation declaration
 5101:  * *WARNING* this interface is highly subject to change
 5102:  *
 5103:  * Returns the new struture or NULL in case of error
 5104:  */
 5105: static xmlSchemaNotationPtr
 5106: xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5107:                      const xmlChar *name, const xmlChar *nsName,
 5108: 		     xmlNodePtr node ATTRIBUTE_UNUSED)
 5109: {
 5110:     xmlSchemaNotationPtr ret = NULL;
 5111: 
 5112:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5113:         return (NULL);
 5114: 
 5115:     ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
 5116:     if (ret == NULL) {
 5117:         xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
 5118:         return (NULL);
 5119:     }
 5120:     memset(ret, 0, sizeof(xmlSchemaNotation));
 5121:     ret->type = XML_SCHEMA_TYPE_NOTATION;
 5122:     ret->name = name;
 5123:     ret->targetNamespace = nsName;
 5124:     /* TODO: do we need the node to be set?
 5125:     * ret->node = node;*/
 5126:     WXS_ADD_GLOBAL(ctxt, ret);
 5127:     return (ret);
 5128: }
 5129: 
 5130: /**
 5131:  * xmlSchemaAddAttribute:
 5132:  * @ctxt:  a schema parser context
 5133:  * @schema:  the schema being built
 5134:  * @name:  the item name
 5135:  * @namespace:  the namespace
 5136:  *
 5137:  * Add an XML schema Attrribute declaration
 5138:  * *WARNING* this interface is highly subject to change
 5139:  *
 5140:  * Returns the new struture or NULL in case of error
 5141:  */
 5142: static xmlSchemaAttributePtr
 5143: xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5144:                       const xmlChar * name, const xmlChar * nsName,
 5145: 		      xmlNodePtr node, int topLevel)
 5146: {
 5147:     xmlSchemaAttributePtr ret = NULL;
 5148: 
 5149:     if ((ctxt == NULL) || (schema == NULL))
 5150:         return (NULL);
 5151: 
 5152:     ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
 5153:     if (ret == NULL) {
 5154:         xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
 5155:         return (NULL);
 5156:     }
 5157:     memset(ret, 0, sizeof(xmlSchemaAttribute));
 5158:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
 5159:     ret->node = node;
 5160:     ret->name = name;
 5161:     ret->targetNamespace = nsName;
 5162: 
 5163:     if (topLevel)
 5164: 	WXS_ADD_GLOBAL(ctxt, ret);
 5165:     else
 5166: 	WXS_ADD_LOCAL(ctxt, ret);
 5167:     WXS_ADD_PENDING(ctxt, ret);
 5168:     return (ret);
 5169: }
 5170: 
 5171: /**
 5172:  * xmlSchemaAddAttributeUse:
 5173:  * @ctxt:  a schema parser context
 5174:  * @schema:  the schema being built
 5175:  * @name:  the item name
 5176:  * @namespace:  the namespace
 5177:  *
 5178:  * Add an XML schema Attrribute declaration
 5179:  * *WARNING* this interface is highly subject to change
 5180:  *
 5181:  * Returns the new struture or NULL in case of error
 5182:  */
 5183: static xmlSchemaAttributeUsePtr
 5184: xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
 5185: 			 xmlNodePtr node)
 5186: {
 5187:     xmlSchemaAttributeUsePtr ret = NULL;
 5188: 
 5189:     if (pctxt == NULL)
 5190:         return (NULL);
 5191: 
 5192:     ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
 5193:     if (ret == NULL) {
 5194:         xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
 5195:         return (NULL);
 5196:     }
 5197:     memset(ret, 0, sizeof(xmlSchemaAttributeUse));
 5198:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
 5199:     ret->node = node;
 5200: 
 5201:     WXS_ADD_LOCAL(pctxt, ret);
 5202:     return (ret);
 5203: }
 5204: 
 5205: /*
 5206: * xmlSchemaAddRedef:
 5207: *
 5208: * Adds a redefinition information. This is used at a later stage to:
 5209: * resolve references to the redefined components and to check constraints.
 5210: */
 5211: static xmlSchemaRedefPtr
 5212: xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
 5213: 		  xmlSchemaBucketPtr targetBucket,
 5214: 		  void *item,
 5215: 		  const xmlChar *refName,
 5216: 		  const xmlChar *refTargetNs)
 5217: {
 5218:     xmlSchemaRedefPtr ret;
 5219: 
 5220:     ret = (xmlSchemaRedefPtr)
 5221: 	xmlMalloc(sizeof(xmlSchemaRedef));
 5222:     if (ret == NULL) {
 5223: 	xmlSchemaPErrMemory(pctxt,
 5224: 	    "allocating redefinition info", NULL);
 5225: 	return (NULL);
 5226:     }
 5227:     memset(ret, 0, sizeof(xmlSchemaRedef));
 5228:     ret->item = item;
 5229:     ret->targetBucket = targetBucket;
 5230:     ret->refName = refName;
 5231:     ret->refTargetNs = refTargetNs;
 5232:     if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
 5233: 	WXS_CONSTRUCTOR(pctxt)->redefs = ret;
 5234:     else
 5235: 	WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
 5236:     WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
 5237: 
 5238:     return (ret);
 5239: }
 5240: 
 5241: /**
 5242:  * xmlSchemaAddAttributeGroupDefinition:
 5243:  * @ctxt:  a schema parser context
 5244:  * @schema:  the schema being built
 5245:  * @name:  the item name
 5246:  * @nsName:  the target namespace
 5247:  * @node: the corresponding node
 5248:  *
 5249:  * Add an XML schema Attrribute Group definition.
 5250:  *
 5251:  * Returns the new struture or NULL in case of error
 5252:  */
 5253: static xmlSchemaAttributeGroupPtr
 5254: xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 5255:                            xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 5256: 			   const xmlChar *name,
 5257: 			   const xmlChar *nsName,
 5258: 			   xmlNodePtr node)
 5259: {
 5260:     xmlSchemaAttributeGroupPtr ret = NULL;
 5261: 
 5262:     if ((pctxt == NULL) || (name == NULL))
 5263:         return (NULL);
 5264: 
 5265:     ret = (xmlSchemaAttributeGroupPtr)
 5266:         xmlMalloc(sizeof(xmlSchemaAttributeGroup));
 5267:     if (ret == NULL) {
 5268: 	xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
 5269: 	return (NULL);
 5270:     }
 5271:     memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
 5272:     ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
 5273:     ret->name = name;
 5274:     ret->targetNamespace = nsName;
 5275:     ret->node = node;
 5276: 
 5277:     /* TODO: Remove the flag. */
 5278:     ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
 5279:     if (pctxt->isRedefine) {
 5280: 	pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
 5281: 	    ret, name, nsName);
 5282: 	if (pctxt->redef == NULL) {
 5283: 	    xmlFree(ret);
 5284: 	    return(NULL);
 5285: 	}
 5286: 	pctxt->redefCounter = 0;
 5287:     }
 5288:     WXS_ADD_GLOBAL(pctxt, ret);
 5289:     WXS_ADD_PENDING(pctxt, ret);
 5290:     return (ret);
 5291: }
 5292: 
 5293: /**
 5294:  * xmlSchemaAddElement:
 5295:  * @ctxt:  a schema parser context
 5296:  * @schema:  the schema being built
 5297:  * @name:  the type name
 5298:  * @namespace:  the type namespace
 5299:  *
 5300:  * Add an XML schema Element declaration
 5301:  * *WARNING* this interface is highly subject to change
 5302:  *
 5303:  * Returns the new struture or NULL in case of error
 5304:  */
 5305: static xmlSchemaElementPtr
 5306: xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
 5307:                     const xmlChar * name, const xmlChar * nsName,
 5308: 		    xmlNodePtr node, int topLevel)
 5309: {
 5310:     xmlSchemaElementPtr ret = NULL;
 5311: 
 5312:     if ((ctxt == NULL) || (name == NULL))
 5313:         return (NULL);
 5314: 
 5315:     ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
 5316:     if (ret == NULL) {
 5317:         xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
 5318:         return (NULL);
 5319:     }
 5320:     memset(ret, 0, sizeof(xmlSchemaElement));
 5321:     ret->type = XML_SCHEMA_TYPE_ELEMENT;
 5322:     ret->name = name;
 5323:     ret->targetNamespace = nsName;
 5324:     ret->node = node;
 5325: 
 5326:     if (topLevel)
 5327: 	WXS_ADD_GLOBAL(ctxt, ret);
 5328:     else
 5329: 	WXS_ADD_LOCAL(ctxt, ret);
 5330:     WXS_ADD_PENDING(ctxt, ret);
 5331:     return (ret);
 5332: }
 5333: 
 5334: /**
 5335:  * xmlSchemaAddType:
 5336:  * @ctxt:  a schema parser context
 5337:  * @schema:  the schema being built
 5338:  * @name:  the item name
 5339:  * @namespace:  the namespace
 5340:  *
 5341:  * Add an XML schema item
 5342:  * *WARNING* this interface is highly subject to change
 5343:  *
 5344:  * Returns the new struture or NULL in case of error
 5345:  */
 5346: static xmlSchemaTypePtr
 5347: xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5348: 		 xmlSchemaTypeType type,
 5349:                  const xmlChar * name, const xmlChar * nsName,
 5350: 		 xmlNodePtr node, int topLevel)
 5351: {
 5352:     xmlSchemaTypePtr ret = NULL;
 5353: 
 5354:     if ((ctxt == NULL) || (schema == NULL))
 5355:         return (NULL);
 5356: 
 5357:     ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
 5358:     if (ret == NULL) {
 5359:         xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
 5360:         return (NULL);
 5361:     }
 5362:     memset(ret, 0, sizeof(xmlSchemaType));
 5363:     ret->type = type;
 5364:     ret->name = name;
 5365:     ret->targetNamespace = nsName;
 5366:     ret->node = node;
 5367:     if (topLevel) {
 5368: 	if (ctxt->isRedefine) {
 5369: 	    ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 5370: 		ret, name, nsName);
 5371: 	    if (ctxt->redef == NULL) {
 5372: 		xmlFree(ret);
 5373: 		return(NULL);
 5374: 	    }
 5375: 	    ctxt->redefCounter = 0;
 5376: 	}
 5377: 	WXS_ADD_GLOBAL(ctxt, ret);
 5378:     } else
 5379: 	WXS_ADD_LOCAL(ctxt, ret);
 5380:     WXS_ADD_PENDING(ctxt, ret);
 5381:     return (ret);
 5382: }
 5383: 
 5384: static xmlSchemaQNameRefPtr
 5385: xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
 5386: 		     xmlSchemaTypeType refType,
 5387: 		     const xmlChar *refName,
 5388: 		     const xmlChar *refNs)
 5389: {
 5390:     xmlSchemaQNameRefPtr ret;
 5391: 
 5392:     ret = (xmlSchemaQNameRefPtr)
 5393: 	xmlMalloc(sizeof(xmlSchemaQNameRef));
 5394:     if (ret == NULL) {
 5395: 	xmlSchemaPErrMemory(pctxt,
 5396: 	    "allocating QName reference item", NULL);
 5397: 	return (NULL);
 5398:     }
 5399:     ret->node = NULL;
 5400:     ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
 5401:     ret->name = refName;
 5402:     ret->targetNamespace = refNs;
 5403:     ret->item = NULL;
 5404:     ret->itemType = refType;
 5405:     /*
 5406:     * Store the reference item in the schema.
 5407:     */
 5408:     WXS_ADD_LOCAL(pctxt, ret);
 5409:     return (ret);
 5410: }
 5411: 
 5412: static xmlSchemaAttributeUseProhibPtr
 5413: xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
 5414: {
 5415:     xmlSchemaAttributeUseProhibPtr ret;
 5416: 
 5417:     ret = (xmlSchemaAttributeUseProhibPtr)
 5418: 	xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
 5419:     if (ret == NULL) {
 5420: 	xmlSchemaPErrMemory(pctxt,
 5421: 	    "allocating attribute use prohibition", NULL);
 5422: 	return (NULL);
 5423:     }
 5424:     memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
 5425:     ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
 5426:     WXS_ADD_LOCAL(pctxt, ret);
 5427:     return (ret);
 5428: }
 5429: 
 5430: 
 5431: /**
 5432:  * xmlSchemaAddModelGroup:
 5433:  * @ctxt:  a schema parser context
 5434:  * @schema:  the schema being built
 5435:  * @type: the "compositor" type of the model group
 5436:  * @node: the node in the schema doc
 5437:  *
 5438:  * Adds a schema model group
 5439:  * *WARNING* this interface is highly subject to change
 5440:  *
 5441:  * Returns the new struture or NULL in case of error
 5442:  */
 5443: static xmlSchemaModelGroupPtr
 5444: xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
 5445: 		       xmlSchemaPtr schema,
 5446: 		       xmlSchemaTypeType type,
 5447: 		       xmlNodePtr node)
 5448: {
 5449:     xmlSchemaModelGroupPtr ret = NULL;
 5450: 
 5451:     if ((ctxt == NULL) || (schema == NULL))
 5452:         return (NULL);
 5453: 
 5454:     ret = (xmlSchemaModelGroupPtr)
 5455: 	xmlMalloc(sizeof(xmlSchemaModelGroup));
 5456:     if (ret == NULL) {
 5457: 	xmlSchemaPErrMemory(ctxt, "allocating model group component",
 5458: 	    NULL);
 5459: 	return (NULL);
 5460:     }
 5461:     memset(ret, 0, sizeof(xmlSchemaModelGroup));
 5462:     ret->type = type;
 5463:     ret->node = node;
 5464:     WXS_ADD_LOCAL(ctxt, ret);
 5465:     if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
 5466: 	(type == XML_SCHEMA_TYPE_CHOICE))
 5467: 	WXS_ADD_PENDING(ctxt, ret);
 5468:     return (ret);
 5469: }
 5470: 
 5471: 
 5472: /**
 5473:  * xmlSchemaAddParticle:
 5474:  * @ctxt:  a schema parser context
 5475:  * @schema:  the schema being built
 5476:  * @node: the corresponding node in the schema doc
 5477:  * @min: the minOccurs
 5478:  * @max: the maxOccurs
 5479:  *
 5480:  * Adds an XML schema particle component.
 5481:  * *WARNING* this interface is highly subject to change
 5482:  *
 5483:  * Returns the new struture or NULL in case of error
 5484:  */
 5485: static xmlSchemaParticlePtr
 5486: xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
 5487: 		     xmlNodePtr node, int min, int max)
 5488: {
 5489:     xmlSchemaParticlePtr ret = NULL;
 5490:     if (ctxt == NULL)
 5491:         return (NULL);
 5492: 
 5493: #ifdef DEBUG
 5494:     fprintf(stderr, "Adding particle component\n");
 5495: #endif
 5496:     ret = (xmlSchemaParticlePtr)
 5497: 	xmlMalloc(sizeof(xmlSchemaParticle));
 5498:     if (ret == NULL) {
 5499: 	xmlSchemaPErrMemory(ctxt, "allocating particle component",
 5500: 	    NULL);
 5501: 	return (NULL);
 5502:     }
 5503:     ret->type = XML_SCHEMA_TYPE_PARTICLE;
 5504:     ret->annot = NULL;
 5505:     ret->node = node;
 5506:     ret->minOccurs = min;
 5507:     ret->maxOccurs = max;
 5508:     ret->next = NULL;
 5509:     ret->children = NULL;
 5510: 
 5511:     WXS_ADD_LOCAL(ctxt, ret);
 5512:     /*
 5513:     * Note that addition to pending components will be done locally
 5514:     * to the specific parsing function, since the most particles
 5515:     * need not to be fixed up (i.e. the reference to be resolved).
 5516:     * REMOVED: WXS_ADD_PENDING(ctxt, ret);
 5517:     */
 5518:     return (ret);
 5519: }
 5520: 
 5521: /**
 5522:  * xmlSchemaAddModelGroupDefinition:
 5523:  * @ctxt:  a schema validation context
 5524:  * @schema:  the schema being built
 5525:  * @name:  the group name
 5526:  *
 5527:  * Add an XML schema Group definition
 5528:  *
 5529:  * Returns the new struture or NULL in case of error
 5530:  */
 5531: static xmlSchemaModelGroupDefPtr
 5532: xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 5533: 				 xmlSchemaPtr schema,
 5534: 				 const xmlChar *name,
 5535: 				 const xmlChar *nsName,
 5536: 				 xmlNodePtr node)
 5537: {
 5538:     xmlSchemaModelGroupDefPtr ret = NULL;
 5539: 
 5540:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5541:         return (NULL);
 5542: 
 5543:     ret = (xmlSchemaModelGroupDefPtr)
 5544: 	xmlMalloc(sizeof(xmlSchemaModelGroupDef));
 5545:     if (ret == NULL) {
 5546:         xmlSchemaPErrMemory(ctxt, "adding group", NULL);
 5547:         return (NULL);
 5548:     }
 5549:     memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
 5550:     ret->name = name;
 5551:     ret->type = XML_SCHEMA_TYPE_GROUP;
 5552:     ret->node = node;
 5553:     ret->targetNamespace = nsName;
 5554: 
 5555:     if (ctxt->isRedefine) {
 5556: 	ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
 5557: 	    ret, name, nsName);
 5558: 	if (ctxt->redef == NULL) {
 5559: 	    xmlFree(ret);
 5560: 	    return(NULL);
 5561: 	}
 5562: 	ctxt->redefCounter = 0;
 5563:     }
 5564:     WXS_ADD_GLOBAL(ctxt, ret);
 5565:     WXS_ADD_PENDING(ctxt, ret);
 5566:     return (ret);
 5567: }
 5568: 
 5569: /**
 5570:  * xmlSchemaNewWildcardNs:
 5571:  * @ctxt:  a schema validation context
 5572:  *
 5573:  * Creates a new wildcard namespace constraint.
 5574:  *
 5575:  * Returns the new struture or NULL in case of error
 5576:  */
 5577: static xmlSchemaWildcardNsPtr
 5578: xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
 5579: {
 5580:     xmlSchemaWildcardNsPtr ret;
 5581: 
 5582:     ret = (xmlSchemaWildcardNsPtr)
 5583: 	xmlMalloc(sizeof(xmlSchemaWildcardNs));
 5584:     if (ret == NULL) {
 5585: 	xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
 5586: 	return (NULL);
 5587:     }
 5588:     ret->value = NULL;
 5589:     ret->next = NULL;
 5590:     return (ret);
 5591: }
 5592: 
 5593: static xmlSchemaIDCPtr
 5594: xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5595:                   const xmlChar *name, const xmlChar *nsName,
 5596: 		  int category, xmlNodePtr node)
 5597: {
 5598:     xmlSchemaIDCPtr ret = NULL;
 5599: 
 5600:     if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
 5601:         return (NULL);
 5602: 
 5603:     ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
 5604:     if (ret == NULL) {
 5605:         xmlSchemaPErrMemory(ctxt,
 5606: 	    "allocating an identity-constraint definition", NULL);
 5607:         return (NULL);
 5608:     }
 5609:     memset(ret, 0, sizeof(xmlSchemaIDC));
 5610:     /* The target namespace of the parent element declaration. */
 5611:     ret->targetNamespace = nsName;
 5612:     ret->name = name;
 5613:     ret->type = category;
 5614:     ret->node = node;
 5615: 
 5616:     WXS_ADD_GLOBAL(ctxt, ret);
 5617:     /*
 5618:     * Only keyrefs need to be fixup up.
 5619:     */
 5620:     if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
 5621: 	WXS_ADD_PENDING(ctxt, ret);
 5622:     return (ret);
 5623: }
 5624: 
 5625: /**
 5626:  * xmlSchemaAddWildcard:
 5627:  * @ctxt:  a schema validation context
 5628:  * @schema: a schema
 5629:  *
 5630:  * Adds a wildcard.
 5631:  * It corresponds to a xsd:anyAttribute and xsd:any.
 5632:  *
 5633:  * Returns the new struture or NULL in case of error
 5634:  */
 5635: static xmlSchemaWildcardPtr
 5636: xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 5637: 		     xmlSchemaTypeType type, xmlNodePtr node)
 5638: {
 5639:     xmlSchemaWildcardPtr ret = NULL;
 5640: 
 5641:     if ((ctxt == NULL) || (schema == NULL))
 5642:         return (NULL);
 5643: 
 5644:     ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
 5645:     if (ret == NULL) {
 5646:         xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
 5647:         return (NULL);
 5648:     }
 5649:     memset(ret, 0, sizeof(xmlSchemaWildcard));
 5650:     ret->type = type;
 5651:     ret->node = node;
 5652:     WXS_ADD_LOCAL(ctxt, ret);
 5653:     return (ret);
 5654: }
 5655: 
 5656: static void
 5657: xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
 5658: {
 5659:     if (group == NULL)
 5660: 	return;
 5661:     if (group->members != NULL)
 5662: 	xmlSchemaItemListFree(group->members);
 5663:     xmlFree(group);
 5664: }
 5665: 
 5666: static xmlSchemaSubstGroupPtr
 5667: xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
 5668: 		       xmlSchemaElementPtr head)
 5669: {
 5670:     xmlSchemaSubstGroupPtr ret;
 5671: 
 5672:     /* Init subst group hash. */
 5673:     if (WXS_SUBST_GROUPS(pctxt) == NULL) {
 5674: 	WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
 5675: 	if (WXS_SUBST_GROUPS(pctxt) == NULL)
 5676: 	    return(NULL);
 5677:     }
 5678:     /* Create a new substitution group. */
 5679:     ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
 5680:     if (ret == NULL) {
 5681: 	xmlSchemaPErrMemory(NULL,
 5682: 	    "allocating a substitution group container", NULL);
 5683: 	return(NULL);
 5684:     }
 5685:     memset(ret, 0, sizeof(xmlSchemaSubstGroup));
 5686:     ret->head = head;
 5687:     /* Create list of members. */
 5688:     ret->members = xmlSchemaItemListCreate();
 5689:     if (ret->members == NULL) {
 5690: 	xmlSchemaSubstGroupFree(ret);
 5691: 	return(NULL);
 5692:     }
 5693:     /* Add subst group to hash. */
 5694:     if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
 5695: 	head->name, head->targetNamespace, ret) != 0) {
 5696: 	PERROR_INT("xmlSchemaSubstGroupAdd",
 5697: 	    "failed to add a new substitution container");
 5698: 	xmlSchemaSubstGroupFree(ret);
 5699: 	return(NULL);
 5700:     }
 5701:     return(ret);
 5702: }
 5703: 
 5704: static xmlSchemaSubstGroupPtr
 5705: xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
 5706: 		       xmlSchemaElementPtr head)
 5707: {
 5708:     if (WXS_SUBST_GROUPS(pctxt) == NULL)
 5709: 	return(NULL);
 5710:     return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
 5711: 	head->name, head->targetNamespace));
 5712: 
 5713: }
 5714: 
 5715: /**
 5716:  * xmlSchemaAddElementSubstitutionMember:
 5717:  * @pctxt:  a schema parser context
 5718:  * @head:  the head of the substitution group
 5719:  * @member: the new member of the substitution group
 5720:  *
 5721:  * Allocate a new annotation structure.
 5722:  *
 5723:  * Returns the newly allocated structure or NULL in case or error
 5724:  */
 5725: static int
 5726: xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
 5727: 				      xmlSchemaElementPtr head,
 5728: 				      xmlSchemaElementPtr member)
 5729: {
 5730:     xmlSchemaSubstGroupPtr substGroup = NULL;
 5731: 
 5732:     if ((pctxt == NULL) || (head == NULL) || (member == NULL))
 5733: 	return (-1);
 5734: 
 5735:     substGroup = xmlSchemaSubstGroupGet(pctxt, head);
 5736:     if (substGroup == NULL)
 5737: 	substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
 5738:     if (substGroup == NULL)
 5739: 	return(-1);
 5740:     if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
 5741: 	return(-1);
 5742:     return(0);
 5743: }
 5744: 
 5745: /************************************************************************
 5746:  * 									*
 5747:  *		Utilities for parsing					*
 5748:  * 									*
 5749:  ************************************************************************/
 5750: 
 5751: /**
 5752:  * xmlSchemaPValAttrNodeQNameValue:
 5753:  * @ctxt:  a schema parser context
 5754:  * @schema: the schema context
 5755:  * @ownerDes: the designation of the parent element
 5756:  * @ownerItem: the parent as a schema object
 5757:  * @value:  the QName value
 5758:  * @local: the resulting local part if found, the attribute value otherwise
 5759:  * @uri:  the resulting namespace URI if found
 5760:  *
 5761:  * Extracts the local name and the URI of a QName value and validates it.
 5762:  * This one is intended to be used on attribute values that
 5763:  * should resolve to schema components.
 5764:  *
 5765:  * Returns 0, in case the QName is valid, a positive error code
 5766:  * if not valid and -1 if an internal error occurs.
 5767:  */
 5768: static int
 5769: xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
 5770: 				       xmlSchemaPtr schema,
 5771: 				       xmlSchemaBasicItemPtr ownerItem,
 5772: 				       xmlAttrPtr attr,
 5773: 				       const xmlChar *value,
 5774: 				       const xmlChar **uri,
 5775: 				       const xmlChar **local)
 5776: {
 5777:     const xmlChar *pref;
 5778:     xmlNsPtr ns;
 5779:     int len, ret;
 5780: 
 5781:     *uri = NULL;
 5782:     *local = NULL;
 5783:     ret = xmlValidateQName(value, 1);
 5784:     if (ret > 0) {
 5785: 	xmlSchemaPSimpleTypeErr(ctxt,
 5786: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5787: 	    ownerItem, (xmlNodePtr) attr,
 5788: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
 5789: 	    NULL, value, NULL, NULL, NULL);
 5790: 	*local = value;
 5791: 	return (ctxt->err);
 5792:     } else if (ret < 0)
 5793: 	return (-1);
 5794: 
 5795:     if (!strchr((char *) value, ':')) {
 5796: 	ns = xmlSearchNs(attr->doc, attr->parent, NULL);
 5797: 	if (ns)
 5798: 	    *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 5799: 	else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
 5800: 	    /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
 5801: 	    * parser context. */
 5802: 	    /*
 5803: 	    * This one takes care of included schemas with no
 5804: 	    * target namespace.
 5805: 	    */
 5806: 	    *uri = ctxt->targetNamespace;
 5807: 	}
 5808: 	*local = xmlDictLookup(ctxt->dict, value, -1);
 5809: 	return (0);
 5810:     }
 5811:     /*
 5812:     * At this point xmlSplitQName3 has to return a local name.
 5813:     */
 5814:     *local = xmlSplitQName3(value, &len);
 5815:     *local = xmlDictLookup(ctxt->dict, *local, -1);
 5816:     pref = xmlDictLookup(ctxt->dict, value, len);
 5817:     ns = xmlSearchNs(attr->doc, attr->parent, pref);
 5818:     if (ns == NULL) {
 5819: 	xmlSchemaPSimpleTypeErr(ctxt,
 5820: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5821: 	    ownerItem, (xmlNodePtr) attr,
 5822: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
 5823: 	    "The value '%s' of simple type 'xs:QName' has no "
 5824: 	    "corresponding namespace declaration in scope", value, NULL);
 5825: 	return (ctxt->err);
 5826:     } else {
 5827:         *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
 5828:     }
 5829:     return (0);
 5830: }
 5831: 
 5832: /**
 5833:  * xmlSchemaPValAttrNodeQName:
 5834:  * @ctxt:  a schema parser context
 5835:  * @schema: the schema context
 5836:  * @ownerDes: the designation of the owner element
 5837:  * @ownerItem: the owner as a schema object
 5838:  * @attr:  the attribute node
 5839:  * @local: the resulting local part if found, the attribute value otherwise
 5840:  * @uri:  the resulting namespace URI if found
 5841:  *
 5842:  * Extracts and validates the QName of an attribute value.
 5843:  * This one is intended to be used on attribute values that
 5844:  * should resolve to schema components.
 5845:  *
 5846:  * Returns 0, in case the QName is valid, a positive error code
 5847:  * if not valid and -1 if an internal error occurs.
 5848:  */
 5849: static int
 5850: xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
 5851: 				       xmlSchemaPtr schema,
 5852: 				       xmlSchemaBasicItemPtr ownerItem,
 5853: 				       xmlAttrPtr attr,
 5854: 				       const xmlChar **uri,
 5855: 				       const xmlChar **local)
 5856: {
 5857:     const xmlChar *value;
 5858: 
 5859:     value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 5860:     return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 5861: 	ownerItem, attr, value, uri, local));
 5862: }
 5863: 
 5864: /**
 5865:  * xmlSchemaPValAttrQName:
 5866:  * @ctxt:  a schema parser context
 5867:  * @schema: the schema context
 5868:  * @ownerDes: the designation of the parent element
 5869:  * @ownerItem: the owner as a schema object
 5870:  * @ownerElem:  the parent node of the attribute
 5871:  * @name:  the name of the attribute
 5872:  * @local: the resulting local part if found, the attribute value otherwise
 5873:  * @uri:  the resulting namespace URI if found
 5874:  *
 5875:  * Extracts and validates the QName of an attribute value.
 5876:  *
 5877:  * Returns 0, in case the QName is valid, a positive error code
 5878:  * if not valid and -1 if an internal error occurs.
 5879:  */
 5880: static int
 5881: xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
 5882: 				   xmlSchemaPtr schema,
 5883: 				   xmlSchemaBasicItemPtr ownerItem,
 5884: 				   xmlNodePtr ownerElem,
 5885: 				   const char *name,
 5886: 				   const xmlChar **uri,
 5887: 				   const xmlChar **local)
 5888: {
 5889:     xmlAttrPtr attr;
 5890: 
 5891:     attr = xmlSchemaGetPropNode(ownerElem, name);
 5892:     if (attr == NULL) {
 5893: 	*local = NULL;
 5894: 	*uri = NULL;
 5895: 	return (0);
 5896:     }
 5897:     return (xmlSchemaPValAttrNodeQName(ctxt, schema,
 5898: 	ownerItem, attr, uri, local));
 5899: }
 5900: 
 5901: /**
 5902:  * xmlSchemaPValAttrID:
 5903:  * @ctxt:  a schema parser context
 5904:  * @schema: the schema context
 5905:  * @ownerDes: the designation of the parent element
 5906:  * @ownerItem: the owner as a schema object
 5907:  * @ownerElem:  the parent node of the attribute
 5908:  * @name:  the name of the attribute
 5909:  *
 5910:  * Extracts and validates the ID of an attribute value.
 5911:  *
 5912:  * Returns 0, in case the ID is valid, a positive error code
 5913:  * if not valid and -1 if an internal error occurs.
 5914:  */
 5915: static int
 5916: xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
 5917: {
 5918:     int ret;
 5919:     const xmlChar *value;
 5920: 
 5921:     if (attr == NULL)
 5922: 	return(0);
 5923:     value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
 5924:     ret = xmlValidateNCName(value, 1);
 5925:     if (ret == 0) {
 5926: 	/*
 5927: 	* NOTE: the IDness might have already be declared in the DTD
 5928: 	*/
 5929: 	if (attr->atype != XML_ATTRIBUTE_ID) {
 5930: 	    xmlIDPtr res;
 5931: 	    xmlChar *strip;
 5932: 
 5933: 	    /*
 5934: 	    * TODO: Use xmlSchemaStrip here; it's not exported at this
 5935: 	    * moment.
 5936: 	    */
 5937: 	    strip = xmlSchemaCollapseString(value);
 5938: 	    if (strip != NULL) {
 5939: 		xmlFree((xmlChar *) value);
 5940: 		value = strip;
 5941: 	    }
 5942:     	    res = xmlAddID(NULL, attr->doc, value, attr);
 5943: 	    if (res == NULL) {
 5944: 		ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 5945: 		xmlSchemaPSimpleTypeErr(ctxt,
 5946: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5947: 		    NULL, (xmlNodePtr) attr,
 5948: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 5949: 		    NULL, NULL, "Duplicate value '%s' of simple "
 5950: 		    "type 'xs:ID'", value, NULL);
 5951: 	    } else
 5952: 		attr->atype = XML_ATTRIBUTE_ID;
 5953: 	}
 5954:     } else if (ret > 0) {
 5955: 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 5956: 	xmlSchemaPSimpleTypeErr(ctxt,
 5957: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 5958: 	    NULL, (xmlNodePtr) attr,
 5959: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
 5960: 	    NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
 5961: 	    "not a valid 'xs:NCName'",
 5962: 	    value, NULL);
 5963:     }
 5964:     if (value != NULL)
 5965: 	xmlFree((xmlChar *)value);
 5966: 
 5967:     return (ret);
 5968: }
 5969: 
 5970: static int
 5971: xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
 5972: 		    xmlNodePtr ownerElem,
 5973: 		    const xmlChar *name)
 5974: {
 5975:     xmlAttrPtr attr;
 5976: 
 5977:     attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
 5978:     if (attr == NULL)
 5979: 	return(0);
 5980:     return(xmlSchemaPValAttrNodeID(ctxt, attr));
 5981: 
 5982: }
 5983: 
 5984: /**
 5985:  * xmlGetMaxOccurs:
 5986:  * @ctxt:  a schema validation context
 5987:  * @node:  a subtree containing XML Schema informations
 5988:  *
 5989:  * Get the maxOccurs property
 5990:  *
 5991:  * Returns the default if not found, or the value
 5992:  */
 5993: static int
 5994: xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 5995: 		int min, int max, int def, const char *expected)
 5996: {
 5997:     const xmlChar *val, *cur;
 5998:     int ret = 0;
 5999:     xmlAttrPtr attr;
 6000: 
 6001:     attr = xmlSchemaGetPropNode(node, "maxOccurs");
 6002:     if (attr == NULL)
 6003: 	return (def);
 6004:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6005: 
 6006:     if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
 6007: 	if (max != UNBOUNDED) {
 6008: 	    xmlSchemaPSimpleTypeErr(ctxt,
 6009: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6010: 		/* XML_SCHEMAP_INVALID_MINOCCURS, */
 6011: 		NULL, (xmlNodePtr) attr, NULL, expected,
 6012: 		val, NULL, NULL, NULL);
 6013: 	    return (def);
 6014: 	} else
 6015: 	    return (UNBOUNDED);  /* encoding it with -1 might be another option */
 6016:     }
 6017: 
 6018:     cur = val;
 6019:     while (IS_BLANK_CH(*cur))
 6020:         cur++;
 6021:     if (*cur == 0) {
 6022:         xmlSchemaPSimpleTypeErr(ctxt,
 6023: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6024: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6025: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6026: 	    val, NULL, NULL, NULL);
 6027: 	return (def);
 6028:     }
 6029:     while ((*cur >= '0') && (*cur <= '9')) {
 6030:         ret = ret * 10 + (*cur - '0');
 6031:         cur++;
 6032:     }
 6033:     while (IS_BLANK_CH(*cur))
 6034:         cur++;
 6035:     /*
 6036:     * TODO: Restrict the maximal value to Integer.
 6037:     */
 6038:     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 6039: 	xmlSchemaPSimpleTypeErr(ctxt,
 6040: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6041: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6042: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6043: 	    val, NULL, NULL, NULL);
 6044:         return (def);
 6045:     }
 6046:     return (ret);
 6047: }
 6048: 
 6049: /**
 6050:  * xmlGetMinOccurs:
 6051:  * @ctxt:  a schema validation context
 6052:  * @node:  a subtree containing XML Schema informations
 6053:  *
 6054:  * Get the minOccurs property
 6055:  *
 6056:  * Returns the default if not found, or the value
 6057:  */
 6058: static int
 6059: xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
 6060: 		int min, int max, int def, const char *expected)
 6061: {
 6062:     const xmlChar *val, *cur;
 6063:     int ret = 0;
 6064:     xmlAttrPtr attr;
 6065: 
 6066:     attr = xmlSchemaGetPropNode(node, "minOccurs");
 6067:     if (attr == NULL)
 6068: 	return (def);
 6069:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6070:     cur = val;
 6071:     while (IS_BLANK_CH(*cur))
 6072:         cur++;
 6073:     if (*cur == 0) {
 6074:         xmlSchemaPSimpleTypeErr(ctxt,
 6075: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6076: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6077: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6078: 	    val, NULL, NULL, NULL);
 6079:         return (def);
 6080:     }
 6081:     while ((*cur >= '0') && (*cur <= '9')) {
 6082:         ret = ret * 10 + (*cur - '0');
 6083:         cur++;
 6084:     }
 6085:     while (IS_BLANK_CH(*cur))
 6086:         cur++;
 6087:     /*
 6088:     * TODO: Restrict the maximal value to Integer.
 6089:     */
 6090:     if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
 6091: 	xmlSchemaPSimpleTypeErr(ctxt,
 6092: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6093: 	    /* XML_SCHEMAP_INVALID_MINOCCURS, */
 6094: 	    NULL, (xmlNodePtr) attr, NULL, expected,
 6095: 	    val, NULL, NULL, NULL);
 6096:         return (def);
 6097:     }
 6098:     return (ret);
 6099: }
 6100: 
 6101: /**
 6102:  * xmlSchemaPGetBoolNodeValue:
 6103:  * @ctxt:  a schema validation context
 6104:  * @ownerDes:  owner designation
 6105:  * @ownerItem:  the owner as a schema item
 6106:  * @node: the node holding the value
 6107:  *
 6108:  * Converts a boolean string value into 1 or 0.
 6109:  *
 6110:  * Returns 0 or 1.
 6111:  */
 6112: static int
 6113: xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
 6114: 			   xmlSchemaBasicItemPtr ownerItem,
 6115: 			   xmlNodePtr node)
 6116: {
 6117:     xmlChar *value = NULL;
 6118:     int res = 0;
 6119: 
 6120:     value = xmlNodeGetContent(node);
 6121:     /*
 6122:     * 3.2.2.1 Lexical representation
 6123:     * An instance of a datatype that is defined as �boolean�
 6124:     * can have the following legal literals {true, false, 1, 0}.
 6125:     */
 6126:     if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
 6127:         res = 1;
 6128:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
 6129:         res = 0;
 6130:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
 6131: 	res = 1;
 6132:     else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
 6133:         res = 0;
 6134:     else {
 6135:         xmlSchemaPSimpleTypeErr(ctxt,
 6136: 	    XML_SCHEMAP_INVALID_BOOLEAN,
 6137: 	    ownerItem, node,
 6138: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 6139: 	    NULL, BAD_CAST value,
 6140: 	    NULL, NULL, NULL);
 6141:     }
 6142:     if (value != NULL)
 6143: 	xmlFree(value);
 6144:     return (res);
 6145: }
 6146: 
 6147: /**
 6148:  * xmlGetBooleanProp:
 6149:  * @ctxt:  a schema validation context
 6150:  * @node:  a subtree containing XML Schema informations
 6151:  * @name:  the attribute name
 6152:  * @def:  the default value
 6153:  *
 6154:  * Evaluate if a boolean property is set
 6155:  *
 6156:  * Returns the default if not found, 0 if found to be false,
 6157:  * 1 if found to be true
 6158:  */
 6159: static int
 6160: xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
 6161: 		  xmlNodePtr node,
 6162:                   const char *name, int def)
 6163: {
 6164:     const xmlChar *val;
 6165: 
 6166:     val = xmlSchemaGetProp(ctxt, node, name);
 6167:     if (val == NULL)
 6168:         return (def);
 6169:     /*
 6170:     * 3.2.2.1 Lexical representation
 6171:     * An instance of a datatype that is defined as �boolean�
 6172:     * can have the following legal literals {true, false, 1, 0}.
 6173:     */
 6174:     if (xmlStrEqual(val, BAD_CAST "true"))
 6175:         def = 1;
 6176:     else if (xmlStrEqual(val, BAD_CAST "false"))
 6177:         def = 0;
 6178:     else if (xmlStrEqual(val, BAD_CAST "1"))
 6179: 	def = 1;
 6180:     else if (xmlStrEqual(val, BAD_CAST "0"))
 6181:         def = 0;
 6182:     else {
 6183:         xmlSchemaPSimpleTypeErr(ctxt,
 6184: 	    XML_SCHEMAP_INVALID_BOOLEAN,
 6185: 	    NULL,
 6186: 	    (xmlNodePtr) xmlSchemaGetPropNode(node, name),
 6187: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
 6188: 	    NULL, val, NULL, NULL, NULL);
 6189:     }
 6190:     return (def);
 6191: }
 6192: 
 6193: /************************************************************************
 6194:  * 									*
 6195:  *		Shema extraction from an Infoset			*
 6196:  * 									*
 6197:  ************************************************************************/
 6198: static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
 6199:                                                  ctxt, xmlSchemaPtr schema,
 6200:                                                  xmlNodePtr node,
 6201: 						 int topLevel);
 6202: static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
 6203:                                                   ctxt,
 6204:                                                   xmlSchemaPtr schema,
 6205:                                                   xmlNodePtr node,
 6206: 						  int topLevel);
 6207: static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
 6208:                                                   ctxt,
 6209:                                                   xmlSchemaPtr schema,
 6210:                                                   xmlNodePtr node,
 6211: 						  xmlSchemaTypeType parentType);
 6212: static xmlSchemaBasicItemPtr
 6213: xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 6214: 			     xmlSchemaPtr schema,
 6215: 			     xmlNodePtr node,
 6216: 			     xmlSchemaItemListPtr uses,
 6217: 			     int parentType);
 6218: static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
 6219:                                            xmlSchemaPtr schema,
 6220:                                            xmlNodePtr node);
 6221: static xmlSchemaWildcardPtr
 6222: xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 6223:                            xmlSchemaPtr schema, xmlNodePtr node);
 6224: 
 6225: /**
 6226:  * xmlSchemaPValAttrNodeValue:
 6227:  *
 6228:  * @ctxt:  a schema parser context
 6229:  * @ownerDes: the designation of the parent element
 6230:  * @ownerItem: the schema object owner if existent
 6231:  * @attr:  the schema attribute node being validated
 6232:  * @value: the value
 6233:  * @type: the built-in type to be validated against
 6234:  *
 6235:  * Validates a value against the given built-in type.
 6236:  * This one is intended to be used internally for validation
 6237:  * of schema attribute values during parsing of the schema.
 6238:  *
 6239:  * Returns 0 if the value is valid, a positive error code
 6240:  * number otherwise and -1 in case of an internal or API error.
 6241:  */
 6242: static int
 6243: xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
 6244: 			   xmlSchemaBasicItemPtr ownerItem,
 6245: 			   xmlAttrPtr attr,
 6246: 			   const xmlChar *value,
 6247: 			   xmlSchemaTypePtr type)
 6248: {
 6249: 
 6250:     int ret = 0;
 6251: 
 6252:     /*
 6253:     * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
 6254:     * one is really meant to be used internally, so better not.
 6255:     */
 6256:     if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
 6257: 	return (-1);
 6258:     if (type->type != XML_SCHEMA_TYPE_BASIC) {
 6259: 	PERROR_INT("xmlSchemaPValAttrNodeValue",
 6260: 	    "the given type is not a built-in type");
 6261: 	return (-1);
 6262:     }
 6263:     switch (type->builtInType) {
 6264: 	case XML_SCHEMAS_NCNAME:
 6265: 	case XML_SCHEMAS_QNAME:
 6266: 	case XML_SCHEMAS_ANYURI:
 6267: 	case XML_SCHEMAS_TOKEN:
 6268: 	case XML_SCHEMAS_LANGUAGE:
 6269: 	    ret = xmlSchemaValPredefTypeNode(type, value, NULL,
 6270: 		(xmlNodePtr) attr);
 6271: 	    break;
 6272: 	default: {
 6273: 	    PERROR_INT("xmlSchemaPValAttrNodeValue",
 6274: 		"validation using the given type is not supported while "
 6275: 		"parsing a schema");
 6276: 	    return (-1);
 6277: 	}
 6278:     }
 6279:     /*
 6280:     * TODO: Should we use the S4S error codes instead?
 6281:     */
 6282:     if (ret < 0) {
 6283: 	PERROR_INT("xmlSchemaPValAttrNodeValue",
 6284: 	    "failed to validate a schema attribute value");
 6285: 	return (-1);
 6286:     } else if (ret > 0) {
 6287: 	if (WXS_IS_LIST(type))
 6288: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
 6289: 	else
 6290: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
 6291: 	xmlSchemaPSimpleTypeErr(pctxt,
 6292: 	    ret, ownerItem, (xmlNodePtr) attr,
 6293: 	    type, NULL, value, NULL, NULL, NULL);
 6294:     }
 6295:     return (ret);
 6296: }
 6297: 
 6298: /**
 6299:  * xmlSchemaPValAttrNode:
 6300:  *
 6301:  * @ctxt:  a schema parser context
 6302:  * @ownerDes: the designation of the parent element
 6303:  * @ownerItem: the schema object owner if existent
 6304:  * @attr:  the schema attribute node being validated
 6305:  * @type: the built-in type to be validated against
 6306:  * @value: the resulting value if any
 6307:  *
 6308:  * Extracts and validates a value against the given built-in type.
 6309:  * This one is intended to be used internally for validation
 6310:  * of schema attribute values during parsing of the schema.
 6311:  *
 6312:  * Returns 0 if the value is valid, a positive error code
 6313:  * number otherwise and -1 in case of an internal or API error.
 6314:  */
 6315: static int
 6316: xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
 6317: 			   xmlSchemaBasicItemPtr ownerItem,
 6318: 			   xmlAttrPtr attr,
 6319: 			   xmlSchemaTypePtr type,
 6320: 			   const xmlChar **value)
 6321: {
 6322:     const xmlChar *val;
 6323: 
 6324:     if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
 6325: 	return (-1);
 6326: 
 6327:     val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6328:     if (value != NULL)
 6329: 	*value = val;
 6330: 
 6331:     return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
 6332: 	val, type));
 6333: }
 6334: 
 6335: /**
 6336:  * xmlSchemaPValAttr:
 6337:  *
 6338:  * @ctxt:  a schema parser context
 6339:  * @node: the element node of the attribute
 6340:  * @ownerDes: the designation of the parent element
 6341:  * @ownerItem: the schema object owner if existent
 6342:  * @ownerElem: the owner element node
 6343:  * @name:  the name of the schema attribute node
 6344:  * @type: the built-in type to be validated against
 6345:  * @value: the resulting value if any
 6346:  *
 6347:  * Extracts and validates a value against the given built-in type.
 6348:  * This one is intended to be used internally for validation
 6349:  * of schema attribute values during parsing of the schema.
 6350:  *
 6351:  * Returns 0 if the value is valid, a positive error code
 6352:  * number otherwise and -1 in case of an internal or API error.
 6353:  */
 6354: static int
 6355: xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
 6356: 		       xmlSchemaBasicItemPtr ownerItem,
 6357: 		       xmlNodePtr ownerElem,
 6358: 		       const char *name,
 6359: 		       xmlSchemaTypePtr type,
 6360: 		       const xmlChar **value)
 6361: {
 6362:     xmlAttrPtr attr;
 6363: 
 6364:     if ((ctxt == NULL) || (type == NULL)) {
 6365: 	if (value != NULL)
 6366: 	    *value = NULL;
 6367: 	return (-1);
 6368:     }
 6369:     if (type->type != XML_SCHEMA_TYPE_BASIC) {
 6370: 	if (value != NULL)
 6371: 	    *value = NULL;
 6372: 	xmlSchemaPErr(ctxt, ownerElem,
 6373: 	    XML_SCHEMAP_INTERNAL,
 6374: 	    "Internal error: xmlSchemaPValAttr, the given "
 6375: 	    "type '%s' is not a built-in type.\n",
 6376: 	    type->name, NULL);
 6377: 	return (-1);
 6378:     }
 6379:     attr = xmlSchemaGetPropNode(ownerElem, name);
 6380:     if (attr == NULL) {
 6381: 	if (value != NULL)
 6382: 	    *value = NULL;
 6383: 	return (0);
 6384:     }
 6385:     return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
 6386: 	type, value));
 6387: }
 6388: 
 6389: static int
 6390: xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
 6391: 		  xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 6392: 		  xmlNodePtr node,
 6393: 		  xmlAttrPtr attr,
 6394: 		  const xmlChar *namespaceName)
 6395: {
 6396:     /* TODO: Pointer comparison instead? */
 6397:     if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
 6398: 	return (0);
 6399:     if (xmlStrEqual(xmlSchemaNs, namespaceName))
 6400: 	return (0);
 6401:     /*
 6402:     * Check if the referenced namespace was <import>ed.
 6403:     */
 6404:     if (WXS_BUCKET(pctxt)->relations != NULL) {
 6405: 	xmlSchemaSchemaRelationPtr rel;
 6406: 
 6407: 	rel = WXS_BUCKET(pctxt)->relations;
 6408: 	do {
 6409: 	    if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
 6410: 		xmlStrEqual(namespaceName, rel->importNamespace))
 6411: 		return (0);
 6412: 	    rel = rel->next;
 6413: 	} while (rel != NULL);
 6414:     }
 6415:     /*
 6416:     * No matching <import>ed namespace found.
 6417:     */
 6418:     {
 6419: 	xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
 6420: 
 6421: 	if (namespaceName == NULL)
 6422: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 6423: 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 6424: 		"References from this schema to components in no "
 6425: 		"namespace are not allowed, since not indicated by an "
 6426: 		"import statement", NULL, NULL);
 6427: 	else
 6428: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 6429: 		XML_SCHEMAP_SRC_RESOLVE, n, NULL,
 6430: 		"References from this schema to components in the "
 6431: 		"namespace '%s' are not allowed, since not indicated by an "
 6432: 		"import statement", namespaceName, NULL);
 6433:     }
 6434:     return (XML_SCHEMAP_SRC_RESOLVE);
 6435: }
 6436: 
 6437: /**
 6438:  * xmlSchemaParseLocalAttributes:
 6439:  * @ctxt:  a schema validation context
 6440:  * @schema:  the schema being built
 6441:  * @node:  a subtree containing XML Schema informations
 6442:  * @type:  the hosting type where the attributes will be anchored
 6443:  *
 6444:  * Parses attribute uses and attribute declarations and
 6445:  * attribute group references.
 6446:  */
 6447: static int
 6448: xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6449:                         xmlNodePtr *child, xmlSchemaItemListPtr *list,
 6450: 			int parentType, int *hasRefs)
 6451: {
 6452:     void *item;
 6453: 
 6454:     while ((IS_SCHEMA((*child), "attribute")) ||
 6455:            (IS_SCHEMA((*child), "attributeGroup"))) {
 6456:         if (IS_SCHEMA((*child), "attribute")) {
 6457: 	    item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
 6458: 		*list, parentType);
 6459:         } else {
 6460:             item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
 6461: 	    if ((item != NULL) && (hasRefs != NULL))
 6462: 		*hasRefs = 1;
 6463:         }
 6464: 	if (item != NULL) {
 6465: 	    if (*list == NULL) {
 6466: 		/* TODO: Customize grow factor. */
 6467: 		*list = xmlSchemaItemListCreate();
 6468: 		if (*list == NULL)
 6469: 		    return(-1);
 6470: 	    }
 6471: 	    if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
 6472: 		return(-1);
 6473: 	}
 6474:         *child = (*child)->next;
 6475:     }
 6476:     return (0);
 6477: }
 6478: 
 6479: /**
 6480:  * xmlSchemaParseAnnotation:
 6481:  * @ctxt:  a schema validation context
 6482:  * @schema:  the schema being built
 6483:  * @node:  a subtree containing XML Schema informations
 6484:  *
 6485:  * parse a XML schema Attrribute declaration
 6486:  * *WARNING* this interface is highly subject to change
 6487:  *
 6488:  * Returns -1 in case of error, 0 if the declaration is improper and
 6489:  *         1 in case of success.
 6490:  */
 6491: static xmlSchemaAnnotPtr
 6492: xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
 6493: {
 6494:     xmlSchemaAnnotPtr ret;
 6495:     xmlNodePtr child = NULL;
 6496:     xmlAttrPtr attr;
 6497:     int barked = 0;
 6498: 
 6499:     /*
 6500:     * INFO: S4S completed.
 6501:     */
 6502:     /*
 6503:     * id = ID
 6504:     * {any attributes with non-schema namespace . . .}>
 6505:     * Content: (appinfo | documentation)*
 6506:     */
 6507:     if ((ctxt == NULL) || (node == NULL))
 6508:         return (NULL);
 6509:     if (needed)
 6510: 	ret = xmlSchemaNewAnnot(ctxt, node);
 6511:     else
 6512: 	ret = NULL;
 6513:     attr = node->properties;
 6514:     while (attr != NULL) {
 6515: 	if (((attr->ns == NULL) &&
 6516: 	    (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
 6517: 	    ((attr->ns != NULL) &&
 6518: 	    xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 6519: 
 6520: 	    xmlSchemaPIllegalAttrErr(ctxt,
 6521: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6522: 	}
 6523: 	attr = attr->next;
 6524:     }
 6525:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6526:     /*
 6527:     * And now for the children...
 6528:     */
 6529:     child = node->children;
 6530:     while (child != NULL) {
 6531: 	if (IS_SCHEMA(child, "appinfo")) {
 6532: 	    /* TODO: make available the content of "appinfo". */
 6533: 	    /*
 6534: 	    * source = anyURI
 6535: 	    * {any attributes with non-schema namespace . . .}>
 6536: 	    * Content: ({any})*
 6537: 	    */
 6538: 	    attr = child->properties;
 6539: 	    while (attr != NULL) {
 6540: 		if (((attr->ns == NULL) &&
 6541: 		     (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
 6542: 		     ((attr->ns != NULL) &&
 6543: 		      xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
 6544: 
 6545: 		    xmlSchemaPIllegalAttrErr(ctxt,
 6546: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6547: 		}
 6548: 		attr = attr->next;
 6549: 	    }
 6550: 	    xmlSchemaPValAttr(ctxt, NULL, child, "source",
 6551: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 6552: 	    child = child->next;
 6553: 	} else if (IS_SCHEMA(child, "documentation")) {
 6554: 	    /* TODO: make available the content of "documentation". */
 6555: 	    /*
 6556: 	    * source = anyURI
 6557: 	    * {any attributes with non-schema namespace . . .}>
 6558: 	    * Content: ({any})*
 6559: 	    */
 6560: 	    attr = child->properties;
 6561: 	    while (attr != NULL) {
 6562: 		if (attr->ns == NULL) {
 6563: 		    if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
 6564: 			xmlSchemaPIllegalAttrErr(ctxt,
 6565: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6566: 		    }
 6567: 		} else {
 6568: 		    if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
 6569: 			(xmlStrEqual(attr->name, BAD_CAST "lang") &&
 6570: 			(!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
 6571: 
 6572: 			xmlSchemaPIllegalAttrErr(ctxt,
 6573: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6574: 		    }
 6575: 		}
 6576: 		attr = attr->next;
 6577: 	    }
 6578: 	    /*
 6579: 	    * Attribute "xml:lang".
 6580: 	    */
 6581: 	    attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
 6582: 	    if (attr != NULL)
 6583: 		xmlSchemaPValAttrNode(ctxt, NULL, attr,
 6584: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
 6585: 	    child = child->next;
 6586: 	} else {
 6587: 	    if (!barked)
 6588: 		xmlSchemaPContentErr(ctxt,
 6589: 		    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6590: 		    NULL, node, child, NULL, "(appinfo | documentation)*");
 6591: 	    barked = 1;
 6592: 	    child = child->next;
 6593: 	}
 6594:     }
 6595: 
 6596:     return (ret);
 6597: }
 6598: 
 6599: /**
 6600:  * xmlSchemaParseFacet:
 6601:  * @ctxt:  a schema validation context
 6602:  * @schema:  the schema being built
 6603:  * @node:  a subtree containing XML Schema informations
 6604:  *
 6605:  * parse a XML schema Facet declaration
 6606:  * *WARNING* this interface is highly subject to change
 6607:  *
 6608:  * Returns the new type structure or NULL in case of error
 6609:  */
 6610: static xmlSchemaFacetPtr
 6611: xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6612:                     xmlNodePtr node)
 6613: {
 6614:     xmlSchemaFacetPtr facet;
 6615:     xmlNodePtr child = NULL;
 6616:     const xmlChar *value;
 6617: 
 6618:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6619:         return (NULL);
 6620: 
 6621:     facet = xmlSchemaNewFacet();
 6622:     if (facet == NULL) {
 6623:         xmlSchemaPErrMemory(ctxt, "allocating facet", node);
 6624:         return (NULL);
 6625:     }
 6626:     facet->node = node;
 6627:     value = xmlSchemaGetProp(ctxt, node, "value");
 6628:     if (value == NULL) {
 6629:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
 6630:                        "Facet %s has no value\n", node->name, NULL);
 6631:         xmlSchemaFreeFacet(facet);
 6632:         return (NULL);
 6633:     }
 6634:     if (IS_SCHEMA(node, "minInclusive")) {
 6635:         facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
 6636:     } else if (IS_SCHEMA(node, "minExclusive")) {
 6637:         facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
 6638:     } else if (IS_SCHEMA(node, "maxInclusive")) {
 6639:         facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
 6640:     } else if (IS_SCHEMA(node, "maxExclusive")) {
 6641:         facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
 6642:     } else if (IS_SCHEMA(node, "totalDigits")) {
 6643:         facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
 6644:     } else if (IS_SCHEMA(node, "fractionDigits")) {
 6645:         facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
 6646:     } else if (IS_SCHEMA(node, "pattern")) {
 6647:         facet->type = XML_SCHEMA_FACET_PATTERN;
 6648:     } else if (IS_SCHEMA(node, "enumeration")) {
 6649:         facet->type = XML_SCHEMA_FACET_ENUMERATION;
 6650:     } else if (IS_SCHEMA(node, "whiteSpace")) {
 6651:         facet->type = XML_SCHEMA_FACET_WHITESPACE;
 6652:     } else if (IS_SCHEMA(node, "length")) {
 6653:         facet->type = XML_SCHEMA_FACET_LENGTH;
 6654:     } else if (IS_SCHEMA(node, "maxLength")) {
 6655:         facet->type = XML_SCHEMA_FACET_MAXLENGTH;
 6656:     } else if (IS_SCHEMA(node, "minLength")) {
 6657:         facet->type = XML_SCHEMA_FACET_MINLENGTH;
 6658:     } else {
 6659:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
 6660:                        "Unknown facet type %s\n", node->name, NULL);
 6661:         xmlSchemaFreeFacet(facet);
 6662:         return (NULL);
 6663:     }
 6664:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6665:     facet->value = value;
 6666:     if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
 6667: 	(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
 6668: 	const xmlChar *fixed;
 6669: 
 6670: 	fixed = xmlSchemaGetProp(ctxt, node, "fixed");
 6671: 	if (fixed != NULL) {
 6672: 	    if (xmlStrEqual(fixed, BAD_CAST "true"))
 6673: 		facet->fixed = 1;
 6674: 	}
 6675:     }
 6676:     child = node->children;
 6677: 
 6678:     if (IS_SCHEMA(child, "annotation")) {
 6679:         facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6680:         child = child->next;
 6681:     }
 6682:     if (child != NULL) {
 6683:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
 6684:                        "Facet %s has unexpected child content\n",
 6685:                        node->name, NULL);
 6686:     }
 6687:     return (facet);
 6688: }
 6689: 
 6690: /**
 6691:  * xmlSchemaParseWildcardNs:
 6692:  * @ctxt:  a schema parser context
 6693:  * @wildc:  the wildcard, already created
 6694:  * @node:  a subtree containing XML Schema informations
 6695:  *
 6696:  * Parses the attribute "processContents" and "namespace"
 6697:  * of a xsd:anyAttribute and xsd:any.
 6698:  * *WARNING* this interface is highly subject to change
 6699:  *
 6700:  * Returns 0 if everything goes fine, a positive error code
 6701:  * if something is not valid and -1 if an internal error occurs.
 6702:  */
 6703: static int
 6704: xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
 6705: 			 xmlSchemaPtr schema ATTRIBUTE_UNUSED,
 6706: 			 xmlSchemaWildcardPtr wildc,
 6707: 			 xmlNodePtr node)
 6708: {
 6709:     const xmlChar *pc, *ns, *dictnsItem;
 6710:     int ret = 0;
 6711:     xmlChar *nsItem;
 6712:     xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
 6713:     xmlAttrPtr attr;
 6714: 
 6715:     pc = xmlSchemaGetProp(ctxt, node, "processContents");
 6716:     if ((pc == NULL)
 6717:         || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
 6718:         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 6719:     } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
 6720:         wildc->processContents = XML_SCHEMAS_ANY_SKIP;
 6721:     } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
 6722:         wildc->processContents = XML_SCHEMAS_ANY_LAX;
 6723:     } else {
 6724:         xmlSchemaPSimpleTypeErr(ctxt,
 6725: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 6726: 	    NULL, node,
 6727: 	    NULL, "(strict | skip | lax)", pc,
 6728: 	    NULL, NULL, NULL);
 6729:         wildc->processContents = XML_SCHEMAS_ANY_STRICT;
 6730: 	ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 6731:     }
 6732:     /*
 6733:      * Build the namespace constraints.
 6734:      */
 6735:     attr = xmlSchemaGetPropNode(node, "namespace");
 6736:     ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 6737:     if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
 6738: 	wildc->any = 1;
 6739:     else if (xmlStrEqual(ns, BAD_CAST "##other")) {
 6740: 	wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
 6741: 	if (wildc->negNsSet == NULL) {
 6742: 	    return (-1);
 6743: 	}
 6744: 	wildc->negNsSet->value = ctxt->targetNamespace;
 6745:     } else {
 6746: 	const xmlChar *end, *cur;
 6747: 
 6748: 	cur = ns;
 6749: 	do {
 6750: 	    while (IS_BLANK_CH(*cur))
 6751: 		cur++;
 6752: 	    end = cur;
 6753: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 6754: 		end++;
 6755: 	    if (end == cur)
 6756: 		break;
 6757: 	    nsItem = xmlStrndup(cur, end - cur);
 6758: 	    if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
 6759: 		    (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
 6760: 		xmlSchemaPSimpleTypeErr(ctxt,
 6761: 		    XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
 6762: 		    NULL, (xmlNodePtr) attr,
 6763: 		    NULL,
 6764: 		    "((##any | ##other) | List of (xs:anyURI | "
 6765: 		    "(##targetNamespace | ##local)))",
 6766: 		    nsItem, NULL, NULL, NULL);
 6767: 		ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
 6768: 	    } else {
 6769: 		if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
 6770: 		    dictnsItem = ctxt->targetNamespace;
 6771: 		} else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
 6772: 		    dictnsItem = NULL;
 6773: 		} else {
 6774: 		    /*
 6775: 		    * Validate the item (anyURI).
 6776: 		    */
 6777: 		    xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
 6778: 			nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
 6779: 		    dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
 6780: 		}
 6781: 		/*
 6782: 		* Avoid dublicate namespaces.
 6783: 		*/
 6784: 		tmp = wildc->nsSet;
 6785: 		while (tmp != NULL) {
 6786: 		    if (dictnsItem == tmp->value)
 6787: 			break;
 6788: 		    tmp = tmp->next;
 6789: 		}
 6790: 		if (tmp == NULL) {
 6791: 		    tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
 6792: 		    if (tmp == NULL) {
 6793: 			xmlFree(nsItem);
 6794: 			return (-1);
 6795: 		    }
 6796: 		    tmp->value = dictnsItem;
 6797: 		    tmp->next = NULL;
 6798: 		    if (wildc->nsSet == NULL)
 6799: 			wildc->nsSet = tmp;
 6800: 		    else if (lastNs != NULL)
 6801: 			lastNs->next = tmp;
 6802: 		    lastNs = tmp;
 6803: 		}
 6804: 
 6805: 	    }
 6806: 	    xmlFree(nsItem);
 6807: 	    cur = end;
 6808: 	} while (*cur != 0);
 6809:     }
 6810:     return (ret);
 6811: }
 6812: 
 6813: static int
 6814: xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
 6815: 				 xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
 6816: 				 xmlNodePtr node,
 6817: 				 int minOccurs,
 6818: 				 int maxOccurs) {
 6819: 
 6820:     if ((maxOccurs == 0) && ( minOccurs == 0))
 6821: 	return (0);
 6822:     if (maxOccurs != UNBOUNDED) {
 6823: 	/*
 6824: 	* TODO: Maybe we should better not create the particle,
 6825: 	* if min/max is invalid, since it could confuse the build of the
 6826: 	* content model.
 6827: 	*/
 6828: 	/*
 6829: 	* 3.9.6 Schema Component Constraint: Particle Correct
 6830: 	*
 6831: 	*/
 6832: 	if (maxOccurs < 1) {
 6833: 	    /*
 6834: 	    * 2.2 {max occurs} must be greater than or equal to 1.
 6835: 	    */
 6836: 	    xmlSchemaPCustomAttrErr(ctxt,
 6837: 		XML_SCHEMAP_P_PROPS_CORRECT_2_2,
 6838: 		NULL, NULL,
 6839: 		xmlSchemaGetPropNode(node, "maxOccurs"),
 6840: 		"The value must be greater than or equal to 1");
 6841: 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
 6842: 	} else if (minOccurs > maxOccurs) {
 6843: 	    /*
 6844: 	    * 2.1 {min occurs} must not be greater than {max occurs}.
 6845: 	    */
 6846: 	    xmlSchemaPCustomAttrErr(ctxt,
 6847: 		XML_SCHEMAP_P_PROPS_CORRECT_2_1,
 6848: 		NULL, NULL,
 6849: 		xmlSchemaGetPropNode(node, "minOccurs"),
 6850: 		"The value must not be greater than the value of 'maxOccurs'");
 6851: 	    return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
 6852: 	}
 6853:     }
 6854:     return (0);
 6855: }
 6856: 
 6857: /**
 6858:  * xmlSchemaParseAny:
 6859:  * @ctxt:  a schema validation context
 6860:  * @schema:  the schema being built
 6861:  * @node:  a subtree containing XML Schema informations
 6862:  *
 6863:  * Parsea a XML schema <any> element. A particle and wildcard
 6864:  * will be created (except if minOccurs==maxOccurs==0, in this case
 6865:  * nothing will be created).
 6866:  * *WARNING* this interface is highly subject to change
 6867:  *
 6868:  * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
 6869:  */
 6870: static xmlSchemaParticlePtr
 6871: xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6872:                   xmlNodePtr node)
 6873: {
 6874:     xmlSchemaParticlePtr particle;
 6875:     xmlNodePtr child = NULL;
 6876:     xmlSchemaWildcardPtr wild;
 6877:     int min, max;
 6878:     xmlAttrPtr attr;
 6879:     xmlSchemaAnnotPtr annot = NULL;
 6880: 
 6881:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6882:         return (NULL);
 6883:     /*
 6884:     * Check for illegal attributes.
 6885:     */
 6886:     attr = node->properties;
 6887:     while (attr != NULL) {
 6888: 	if (attr->ns == NULL) {
 6889: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 6890: 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 6891: 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 6892: 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 6893: 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 6894: 		xmlSchemaPIllegalAttrErr(ctxt,
 6895: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6896: 	    }
 6897: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 6898: 	    xmlSchemaPIllegalAttrErr(ctxt,
 6899: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 6900: 	}
 6901: 	attr = attr->next;
 6902:     }
 6903:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6904:     /*
 6905:     * minOccurs/maxOccurs.
 6906:     */
 6907:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 6908: 	"(xs:nonNegativeInteger | unbounded)");
 6909:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
 6910: 	"xs:nonNegativeInteger");
 6911:     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 6912:     /*
 6913:     * Create & parse the wildcard.
 6914:     */
 6915:     wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
 6916:     if (wild == NULL)
 6917: 	return (NULL);
 6918:     xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
 6919:     /*
 6920:     * And now for the children...
 6921:     */
 6922:     child = node->children;
 6923:     if (IS_SCHEMA(child, "annotation")) {
 6924:         annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6925:         child = child->next;
 6926:     }
 6927:     if (child != NULL) {
 6928: 	xmlSchemaPContentErr(ctxt,
 6929: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6930: 	    NULL, node, child,
 6931: 	    NULL, "(annotation?)");
 6932:     }
 6933:     /*
 6934:     * No component if minOccurs==maxOccurs==0.
 6935:     */
 6936:     if ((min == 0) && (max == 0)) {
 6937: 	/* Don't free the wildcard, since it's already on the list. */
 6938: 	return (NULL);
 6939:     }
 6940:     /*
 6941:     * Create the particle.
 6942:     */
 6943:     particle = xmlSchemaAddParticle(ctxt, node, min, max);
 6944:     if (particle == NULL)
 6945:         return (NULL);
 6946:     particle->annot = annot;
 6947:     particle->children = (xmlSchemaTreeItemPtr) wild;
 6948: 
 6949:     return (particle);
 6950: }
 6951: 
 6952: /**
 6953:  * xmlSchemaParseNotation:
 6954:  * @ctxt:  a schema validation context
 6955:  * @schema:  the schema being built
 6956:  * @node:  a subtree containing XML Schema informations
 6957:  *
 6958:  * parse a XML schema Notation declaration
 6959:  *
 6960:  * Returns the new structure or NULL in case of error
 6961:  */
 6962: static xmlSchemaNotationPtr
 6963: xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 6964:                        xmlNodePtr node)
 6965: {
 6966:     const xmlChar *name;
 6967:     xmlSchemaNotationPtr ret;
 6968:     xmlNodePtr child = NULL;
 6969: 
 6970:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 6971:         return (NULL);
 6972:     name = xmlSchemaGetProp(ctxt, node, "name");
 6973:     if (name == NULL) {
 6974:         xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
 6975:                        "Notation has no name\n", NULL, NULL);
 6976:         return (NULL);
 6977:     }
 6978:     ret = xmlSchemaAddNotation(ctxt, schema, name,
 6979: 	ctxt->targetNamespace, node);
 6980:     if (ret == NULL)
 6981:         return (NULL);
 6982:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 6983: 
 6984:     child = node->children;
 6985:     if (IS_SCHEMA(child, "annotation")) {
 6986:         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 6987:         child = child->next;
 6988:     }
 6989:     if (child != NULL) {
 6990: 	xmlSchemaPContentErr(ctxt,
 6991: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 6992: 	    NULL, node, child,
 6993: 	    NULL, "(annotation?)");
 6994:     }
 6995: 
 6996:     return (ret);
 6997: }
 6998: 
 6999: /**
 7000:  * xmlSchemaParseAnyAttribute:
 7001:  * @ctxt:  a schema validation context
 7002:  * @schema:  the schema being built
 7003:  * @node:  a subtree containing XML Schema informations
 7004:  *
 7005:  * parse a XML schema AnyAttrribute declaration
 7006:  * *WARNING* this interface is highly subject to change
 7007:  *
 7008:  * Returns a wildcard or NULL.
 7009:  */
 7010: static xmlSchemaWildcardPtr
 7011: xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
 7012:                            xmlSchemaPtr schema, xmlNodePtr node)
 7013: {
 7014:     xmlSchemaWildcardPtr ret;
 7015:     xmlNodePtr child = NULL;
 7016:     xmlAttrPtr attr;
 7017: 
 7018:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 7019:         return (NULL);
 7020: 
 7021:     ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
 7022: 	node);
 7023:     if (ret == NULL) {
 7024:         return (NULL);
 7025:     }
 7026:     /*
 7027:     * Check for illegal attributes.
 7028:     */
 7029:     attr = node->properties;
 7030:     while (attr != NULL) {
 7031: 	if (attr->ns == NULL) {
 7032: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 7033: 	        (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
 7034: 		(!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
 7035: 		xmlSchemaPIllegalAttrErr(ctxt,
 7036: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7037: 	    }
 7038: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7039: 	    xmlSchemaPIllegalAttrErr(ctxt,
 7040: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7041: 	}
 7042: 	attr = attr->next;
 7043:     }
 7044:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 7045:     /*
 7046:     * Parse the namespace list.
 7047:     */
 7048:     if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
 7049: 	return (NULL);
 7050:     /*
 7051:     * And now for the children...
 7052:     */
 7053:     child = node->children;
 7054:     if (IS_SCHEMA(child, "annotation")) {
 7055:         ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 7056:         child = child->next;
 7057:     }
 7058:     if (child != NULL) {
 7059: 	xmlSchemaPContentErr(ctxt,
 7060: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7061: 	    NULL, node, child,
 7062: 	    NULL, "(annotation?)");
 7063:     }
 7064: 
 7065:     return (ret);
 7066: }
 7067: 
 7068: 
 7069: /**
 7070:  * xmlSchemaParseAttribute:
 7071:  * @ctxt:  a schema validation context
 7072:  * @schema:  the schema being built
 7073:  * @node:  a subtree containing XML Schema informations
 7074:  *
 7075:  * parse a XML schema Attrribute declaration
 7076:  * *WARNING* this interface is highly subject to change
 7077:  *
 7078:  * Returns the attribute declaration.
 7079:  */
 7080: static xmlSchemaBasicItemPtr
 7081: xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
 7082: 			     xmlSchemaPtr schema,
 7083: 			     xmlNodePtr node,
 7084: 			     xmlSchemaItemListPtr uses,
 7085: 			     int parentType)
 7086: {
 7087:     const xmlChar *attrValue, *name = NULL, *ns = NULL;
 7088:     xmlSchemaAttributeUsePtr use = NULL;
 7089:     xmlNodePtr child = NULL;
 7090:     xmlAttrPtr attr;
 7091:     const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
 7092:     int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 7093:     int	nberrors, hasForm = 0, defValueType = 0;
 7094: 
 7095: #define WXS_ATTR_DEF_VAL_DEFAULT 1
 7096: #define WXS_ATTR_DEF_VAL_FIXED 2
 7097: 
 7098:     /*
 7099:      * 3.2.3 Constraints on XML Representations of Attribute Declarations
 7100:      */
 7101: 
 7102:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7103:         return (NULL);
 7104:     attr = xmlSchemaGetPropNode(node, "ref");
 7105:     if (attr != NULL) {
 7106: 	if (xmlSchemaPValAttrNodeQName(pctxt, schema,
 7107: 	    NULL, attr, &tmpNs, &tmpName) != 0) {
 7108: 	    return (NULL);
 7109: 	}
 7110: 	if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
 7111: 	    return(NULL);
 7112: 	isRef = 1;
 7113:     }
 7114:     nberrors = pctxt->nberrors;
 7115:     /*
 7116:     * Check for illegal attributes.
 7117:     */
 7118:     attr = node->properties;
 7119:     while (attr != NULL) {
 7120: 	if (attr->ns == NULL) {
 7121: 	    if (isRef) {
 7122: 		if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 7123: 		    xmlSchemaPValAttrNodeID(pctxt, attr);
 7124: 		    goto attr_next;
 7125: 		} else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
 7126: 		    goto attr_next;
 7127: 		}
 7128: 	    } else {
 7129: 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
 7130: 		    goto attr_next;
 7131: 		} else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
 7132: 		    xmlSchemaPValAttrNodeID(pctxt, attr);
 7133: 		    goto attr_next;
 7134: 		} else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
 7135: 		    xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
 7136: 			attr, &tmpNs, &tmpName);
 7137: 		    goto attr_next;
 7138: 		} else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
 7139: 		    /*
 7140: 		    * Evaluate the target namespace
 7141: 		    */
 7142: 		    hasForm = 1;
 7143: 		    attrValue = xmlSchemaGetNodeContent(pctxt,
 7144: 			(xmlNodePtr) attr);
 7145: 		    if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 7146: 			ns = pctxt->targetNamespace;
 7147: 		    } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
 7148: 		    {
 7149: 			xmlSchemaPSimpleTypeErr(pctxt,
 7150: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 7151: 			    NULL, (xmlNodePtr) attr,
 7152: 			    NULL, "(qualified | unqualified)",
 7153: 			    attrValue, NULL, NULL, NULL);
 7154: 		    }
 7155: 		    goto attr_next;
 7156: 		}
 7157: 	    }
 7158: 	    if (xmlStrEqual(attr->name, BAD_CAST "use")) {
 7159: 
 7160: 		attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7161: 		/* TODO: Maybe we need to normalize the value beforehand. */
 7162: 		if (xmlStrEqual(attrValue, BAD_CAST "optional"))
 7163: 		    occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
 7164: 		else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
 7165: 		    occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
 7166: 		else if (xmlStrEqual(attrValue, BAD_CAST "required"))
 7167: 		    occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
 7168: 		else {
 7169: 		    xmlSchemaPSimpleTypeErr(pctxt,
 7170: 			XML_SCHEMAP_INVALID_ATTR_USE,
 7171: 			NULL, (xmlNodePtr) attr,
 7172: 			NULL, "(optional | prohibited | required)",
 7173: 			attrValue, NULL, NULL, NULL);
 7174: 		}
 7175: 		goto attr_next;
 7176: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
 7177: 		/*
 7178: 		* 3.2.3 : 1
 7179: 		* default and fixed must not both be present.
 7180: 		*/
 7181: 		if (defValue) {
 7182: 		    xmlSchemaPMutualExclAttrErr(pctxt,
 7183: 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7184: 			NULL, attr, "default", "fixed");
 7185: 		} else {
 7186: 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7187: 		    defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
 7188: 		}
 7189: 		goto attr_next;
 7190: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
 7191: 		/*
 7192: 		* 3.2.3 : 1
 7193: 		* default and fixed must not both be present.
 7194: 		*/
 7195: 		if (defValue) {
 7196: 		    xmlSchemaPMutualExclAttrErr(pctxt,
 7197: 			XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7198: 			NULL, attr, "default", "fixed");
 7199: 		} else {
 7200: 		    defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7201: 		    defValueType = WXS_ATTR_DEF_VAL_FIXED;
 7202: 		}
 7203: 		goto attr_next;
 7204: 	    }
 7205: 	} else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
 7206: 	    goto attr_next;
 7207: 
 7208: 	xmlSchemaPIllegalAttrErr(pctxt,
 7209: 	    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7210: 
 7211: attr_next:
 7212: 	attr = attr->next;
 7213:     }
 7214:     /*
 7215:     * 3.2.3 : 2
 7216:     * If default and use are both present, use must have
 7217:     * the actual value optional.
 7218:     */
 7219:     if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
 7220: 	(occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
 7221: 	xmlSchemaPSimpleTypeErr(pctxt,
 7222: 	    XML_SCHEMAP_SRC_ATTRIBUTE_2,
 7223: 	    NULL, node, NULL,
 7224: 	    "(optional | prohibited | required)", NULL,
 7225: 	    "The value of the attribute 'use' must be 'optional' "
 7226: 	    "if the attribute 'default' is present",
 7227: 	    NULL, NULL);
 7228:     }
 7229:     /*
 7230:     * We want correct attributes.
 7231:     */
 7232:     if (nberrors != pctxt->nberrors)
 7233: 	return(NULL);
 7234:     if (! isRef) {
 7235: 	xmlSchemaAttributePtr attrDecl;
 7236: 
 7237: 	/* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
 7238: 	if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
 7239: 	    ns = pctxt->targetNamespace;
 7240: 	/*
 7241: 	* 3.2.6 Schema Component Constraint: xsi: Not Allowed
 7242: 	* TODO: Move this to the component layer.
 7243: 	*/
 7244: 	if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
 7245: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7246: 		XML_SCHEMAP_NO_XSI,
 7247: 		node, NULL,
 7248: 		"The target namespace must not match '%s'",
 7249: 		xmlSchemaInstanceNs, NULL);
 7250: 	}
 7251: 	attr = xmlSchemaGetPropNode(node, "name");
 7252: 	if (attr == NULL) {
 7253: 	    xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 7254: 		NULL, node, "name", NULL);
 7255: 	    return (NULL);
 7256: 	}
 7257: 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 7258: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 7259: 	    return (NULL);
 7260: 	}
 7261: 	/*
 7262: 	* 3.2.6 Schema Component Constraint: xmlns Not Allowed
 7263: 	* TODO: Move this to the component layer.
 7264: 	*/
 7265: 	if (xmlStrEqual(name, BAD_CAST "xmlns")) {
 7266: 	    xmlSchemaPSimpleTypeErr(pctxt,
 7267: 		XML_SCHEMAP_NO_XMLNS,
 7268: 		NULL, (xmlNodePtr) attr,
 7269: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 7270: 		"The value of the attribute must not match 'xmlns'",
 7271: 		NULL, NULL);
 7272: 	    return (NULL);
 7273: 	}
 7274: 	if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
 7275: 	    goto check_children;
 7276: 	/*
 7277: 	* Create the attribute use component.
 7278: 	*/
 7279: 	use = xmlSchemaAddAttributeUse(pctxt, node);
 7280: 	if (use == NULL)
 7281: 	    return(NULL);
 7282: 	use->occurs = occurs;
 7283: 	/*
 7284: 	* Create the attribute declaration.
 7285: 	*/
 7286: 	attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
 7287: 	if (attrDecl == NULL)
 7288: 	    return (NULL);
 7289: 	if (tmpName != NULL) {
 7290: 	    attrDecl->typeName = tmpName;
 7291: 	    attrDecl->typeNs = tmpNs;
 7292: 	}
 7293: 	use->attrDecl = attrDecl;
 7294: 	/*
 7295: 	* Value constraint.
 7296: 	*/
 7297: 	if (defValue != NULL) {
 7298: 	    attrDecl->defValue = defValue;
 7299: 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 7300: 		attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
 7301: 	}
 7302:     } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 7303: 	xmlSchemaQNameRefPtr ref;
 7304: 
 7305: 	/*
 7306: 	* Create the attribute use component.
 7307: 	*/
 7308: 	use = xmlSchemaAddAttributeUse(pctxt, node);
 7309: 	if (use == NULL)
 7310: 	    return(NULL);
 7311: 	/*
 7312: 	* We need to resolve the reference at later stage.
 7313: 	*/
 7314: 	WXS_ADD_PENDING(pctxt, use);
 7315: 	use->occurs = occurs;
 7316: 	/*
 7317: 	* Create a QName reference to the attribute declaration.
 7318: 	*/
 7319: 	ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
 7320: 	    tmpName, tmpNs);
 7321: 	if (ref == NULL)
 7322: 	    return(NULL);
 7323: 	/*
 7324: 	* Assign the reference. This will be substituted for the
 7325: 	* referenced attribute declaration when the QName is resolved.
 7326: 	*/
 7327: 	use->attrDecl = WXS_ATTR_CAST ref;
 7328: 	/*
 7329: 	* Value constraint.
 7330: 	*/
 7331: 	if (defValue != NULL)
 7332: 	    use->defValue = defValue;
 7333: 	    if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
 7334: 		use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
 7335:     }
 7336: 
 7337: check_children:
 7338:     /*
 7339:     * And now for the children...
 7340:     */
 7341:     child = node->children;
 7342:     if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
 7343: 	xmlSchemaAttributeUseProhibPtr prohib;
 7344: 
 7345: 	if (IS_SCHEMA(child, "annotation")) {
 7346: 	    xmlSchemaParseAnnotation(pctxt, child, 0);
 7347: 	    child = child->next;
 7348: 	}
 7349: 	if (child != NULL) {
 7350: 	    xmlSchemaPContentErr(pctxt,
 7351: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7352: 		NULL, node, child, NULL,
 7353: 		"(annotation?)");
 7354: 	}
 7355: 	/*
 7356: 	* Check for pointlessness of attribute prohibitions.
 7357: 	*/
 7358: 	if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
 7359: 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7360: 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7361: 		node, NULL,
 7362: 		"Skipping attribute use prohibition, since it is "
 7363: 		"pointless inside an <attributeGroup>",
 7364: 		NULL, NULL, NULL);
 7365: 	    return(NULL);
 7366: 	} else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
 7367: 	    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7368: 		XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7369: 		node, NULL,
 7370: 		"Skipping attribute use prohibition, since it is "
 7371: 		"pointless when extending a type",
 7372: 		NULL, NULL, NULL);
 7373: 	    return(NULL);
 7374: 	}
 7375: 	if (! isRef) {
 7376: 	    tmpName = name;
 7377: 	    tmpNs = ns;
 7378: 	}
 7379: 	/*
 7380: 	* Check for duplicate attribute prohibitions.
 7381: 	*/
 7382: 	if (uses) {
 7383: 	    int i;
 7384: 
 7385: 	    for (i = 0; i < uses->nbItems; i++) {
 7386: 		use = uses->items[i];
 7387: 		if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
 7388: 		    (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
 7389: 		    (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
 7390: 		{
 7391: 		    xmlChar *str = NULL;
 7392: 
 7393: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
 7394: 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
 7395: 			node, NULL,
 7396: 			"Skipping duplicate attribute use prohibition '%s'",
 7397: 			xmlSchemaFormatQName(&str, tmpNs, tmpName),
 7398: 			NULL, NULL);
 7399: 		    FREE_AND_NULL(str)
 7400: 		    return(NULL);
 7401: 		}
 7402: 	    }
 7403: 	}
 7404: 	/*
 7405: 	* Create the attribute prohibition helper component.
 7406: 	*/
 7407: 	prohib = xmlSchemaAddAttributeUseProhib(pctxt);
 7408: 	if (prohib == NULL)
 7409: 	    return(NULL);
 7410: 	prohib->node = node;
 7411: 	prohib->name = tmpName;
 7412: 	prohib->targetNamespace = tmpNs;
 7413: 	if (isRef) {
 7414: 	    /*
 7415: 	    * We need at least to resolve to the attribute declaration.
 7416: 	    */
 7417: 	    WXS_ADD_PENDING(pctxt, prohib);
 7418: 	}
 7419: 	return(WXS_BASIC_CAST prohib);
 7420:     } else {
 7421: 	if (IS_SCHEMA(child, "annotation")) {
 7422: 	    /*
 7423: 	    * TODO: Should this go into the attr decl?
 7424: 	    */
 7425: 	    use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7426: 	    child = child->next;
 7427: 	}
 7428: 	if (isRef) {
 7429: 	    if (child != NULL) {
 7430: 		if (IS_SCHEMA(child, "simpleType"))
 7431: 		    /*
 7432: 		    * 3.2.3 : 3.2
 7433: 		    * If ref is present, then all of <simpleType>,
 7434: 		    * form and type must be absent.
 7435: 		    */
 7436: 		    xmlSchemaPContentErr(pctxt,
 7437: 			XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
 7438: 			NULL, node, child, NULL,
 7439: 			"(annotation?)");
 7440: 		else
 7441: 		    xmlSchemaPContentErr(pctxt,
 7442: 			XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7443: 			NULL, node, child, NULL,
 7444: 			"(annotation?)");
 7445: 	    }
 7446: 	} else {
 7447: 	    if (IS_SCHEMA(child, "simpleType")) {
 7448: 		if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
 7449: 		    /*
 7450: 		    * 3.2.3 : 4
 7451: 		    * type and <simpleType> must not both be present.
 7452: 		    */
 7453: 		    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 7454: 			NULL, node, child,
 7455: 			"The attribute 'type' and the <simpleType> child "
 7456: 			"are mutually exclusive", NULL);
 7457: 		} else
 7458: 		    WXS_ATTRUSE_TYPEDEF(use) =
 7459: 			xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 7460: 		child = child->next;
 7461: 	    }
 7462: 	    if (child != NULL)
 7463: 		xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7464: 		NULL, node, child, NULL,
 7465: 		"(annotation?, simpleType?)");
 7466: 	}
 7467:     }
 7468:     return (WXS_BASIC_CAST use);
 7469: }
 7470: 
 7471: 
 7472: static xmlSchemaAttributePtr
 7473: xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
 7474: 			      xmlSchemaPtr schema,
 7475: 			      xmlNodePtr node)
 7476: {
 7477:     const xmlChar *attrValue;
 7478:     xmlSchemaAttributePtr ret;
 7479:     xmlNodePtr child = NULL;
 7480:     xmlAttrPtr attr;
 7481: 
 7482:     /*
 7483:      * Note that the w3c spec assumes the schema to be validated with schema
 7484:      * for schemas beforehand.
 7485:      *
 7486:      * 3.2.3 Constraints on XML Representations of Attribute Declarations
 7487:      */
 7488:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7489:         return (NULL);
 7490:     /*
 7491:     * 3.2.3 : 3.1
 7492:     * One of ref or name must be present, but not both
 7493:     */
 7494:     attr = xmlSchemaGetPropNode(node, "name");
 7495:     if (attr == NULL) {
 7496: 	xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
 7497: 	    NULL, node, "name", NULL);
 7498: 	return (NULL);
 7499:     }
 7500:     if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
 7501: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
 7502: 	return (NULL);
 7503:     }
 7504:     /*
 7505:     * 3.2.6 Schema Component Constraint: xmlns Not Allowed
 7506:     * TODO: Move this to the component layer.
 7507:     */
 7508:     if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
 7509: 	xmlSchemaPSimpleTypeErr(pctxt,
 7510: 	    XML_SCHEMAP_NO_XMLNS,
 7511: 	    NULL, (xmlNodePtr) attr,
 7512: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
 7513: 	    "The value of the attribute must not match 'xmlns'",
 7514: 	    NULL, NULL);
 7515: 	return (NULL);
 7516:     }
 7517:     /*
 7518:     * 3.2.6 Schema Component Constraint: xsi: Not Allowed
 7519:     * TODO: Move this to the component layer.
 7520:     *       Or better leave it here and add it to the component layer
 7521:     *       if we have a schema construction API.
 7522:     */
 7523:     if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
 7524: 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7525: 	    XML_SCHEMAP_NO_XSI, node, NULL,
 7526: 	    "The target namespace must not match '%s'",
 7527: 	    xmlSchemaInstanceNs, NULL);
 7528:     }
 7529: 
 7530:     ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
 7531: 	pctxt->targetNamespace, node, 1);
 7532:     if (ret == NULL)
 7533: 	return (NULL);
 7534:     ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
 7535: 
 7536:     /*
 7537:     * Check for illegal attributes.
 7538:     */
 7539:     attr = node->properties;
 7540:     while (attr != NULL) {
 7541: 	if (attr->ns == NULL) {
 7542: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 7543: 		(!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 7544: 		(!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 7545: 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 7546: 		(!xmlStrEqual(attr->name, BAD_CAST "type")))
 7547: 	    {
 7548: 		xmlSchemaPIllegalAttrErr(pctxt,
 7549: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7550: 	    }
 7551: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7552: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7553: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7554: 	}
 7555: 	attr = attr->next;
 7556:     }
 7557:     xmlSchemaPValAttrQName(pctxt, schema, NULL,
 7558: 	node, "type", &ret->typeNs, &ret->typeName);
 7559: 
 7560:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7561:     /*
 7562:     * Attribute "fixed".
 7563:     */
 7564:     ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
 7565:     if (ret->defValue != NULL)
 7566: 	ret->flags |= XML_SCHEMAS_ATTR_FIXED;
 7567:     /*
 7568:     * Attribute "default".
 7569:     */
 7570:     attr = xmlSchemaGetPropNode(node, "default");
 7571:     if (attr != NULL) {
 7572: 	/*
 7573: 	* 3.2.3 : 1
 7574: 	* default and fixed must not both be present.
 7575: 	*/
 7576: 	if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
 7577: 	    xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
 7578: 		WXS_BASIC_CAST ret, attr, "default", "fixed");
 7579: 	} else
 7580: 	    ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
 7581:     }
 7582:     /*
 7583:     * And now for the children...
 7584:     */
 7585:     child = node->children;
 7586:     if (IS_SCHEMA(child, "annotation")) {
 7587:         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7588:         child = child->next;
 7589:     }
 7590:     if (IS_SCHEMA(child, "simpleType")) {
 7591: 	if (ret->typeName != NULL) {
 7592: 	    /*
 7593: 	    * 3.2.3 : 4
 7594: 	    * type and <simpleType> must not both be present.
 7595: 	    */
 7596: 	    xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
 7597: 		NULL, node, child,
 7598: 		"The attribute 'type' and the <simpleType> child "
 7599: 		"are mutually exclusive", NULL);
 7600: 	} else
 7601: 	    ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
 7602: 	child = child->next;
 7603:     }
 7604:     if (child != NULL)
 7605: 	xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7606: 	    NULL, node, child, NULL,
 7607: 	    "(annotation?, simpleType?)");
 7608: 
 7609:     return (ret);
 7610: }
 7611: 
 7612: /**
 7613:  * xmlSchemaParseAttributeGroupRef:
 7614:  * @ctxt:  a schema validation context
 7615:  * @schema:  the schema being built
 7616:  * @node:  a subtree containing XML Schema informations
 7617:  *
 7618:  * Parse an attribute group definition reference.
 7619:  * Note that a reference to an attribute group does not
 7620:  * correspond to any component at all.
 7621:  * *WARNING* this interface is highly subject to change
 7622:  *
 7623:  * Returns the attribute group or NULL in case of error.
 7624:  */
 7625: static xmlSchemaQNameRefPtr
 7626: xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
 7627: 				xmlSchemaPtr schema,
 7628: 				xmlNodePtr node)
 7629: {
 7630:     xmlSchemaQNameRefPtr ret;
 7631:     xmlNodePtr child = NULL;
 7632:     xmlAttrPtr attr;
 7633:     const xmlChar *refNs = NULL, *ref = NULL;
 7634: 
 7635:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7636:         return (NULL);
 7637: 
 7638:     attr = xmlSchemaGetPropNode(node, "ref");
 7639:     if (attr == NULL) {
 7640: 	xmlSchemaPMissingAttrErr(pctxt,
 7641: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 7642: 	    NULL, node, "ref", NULL);
 7643: 	return (NULL);
 7644:     }
 7645:     xmlSchemaPValAttrNodeQName(pctxt, schema,
 7646: 	NULL, attr, &refNs, &ref);
 7647:     if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
 7648: 	return(NULL);
 7649: 
 7650:     /*
 7651:     * Check for illegal attributes.
 7652:     */
 7653:     attr = node->properties;
 7654:     while (attr != NULL) {
 7655: 	if (attr->ns == NULL) {
 7656: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 7657: 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
 7658: 	    {
 7659: 		xmlSchemaPIllegalAttrErr(pctxt,
 7660: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7661: 	    }
 7662: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7663: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7664: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7665: 	}
 7666: 	attr = attr->next;
 7667:     }
 7668:     /* Attribute ID */
 7669:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7670: 
 7671:     /*
 7672:     * And now for the children...
 7673:     */
 7674:     child = node->children;
 7675:     if (IS_SCHEMA(child, "annotation")) {
 7676: 	/*
 7677: 	* TODO: We do not have a place to store the annotation, do we?
 7678: 	*/
 7679:         xmlSchemaParseAnnotation(pctxt, child, 0);
 7680:         child = child->next;
 7681:     }
 7682:     if (child != NULL) {
 7683: 	xmlSchemaPContentErr(pctxt,
 7684: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7685: 	    NULL, node, child, NULL,
 7686: 	    "(annotation?)");
 7687:     }
 7688: 
 7689:     /*
 7690:     * Handle attribute group redefinitions.
 7691:     */
 7692:     if (pctxt->isRedefine && pctxt->redef &&
 7693: 	(pctxt->redef->item->type ==
 7694: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
 7695: 	(ref == pctxt->redef->refName) &&
 7696: 	(refNs == pctxt->redef->refTargetNs))
 7697:     {
 7698: 	/*
 7699: 	* SPEC src-redefine:
 7700: 	* (7.1) "If it has an <attributeGroup> among its contents
 7701: 	* the �actual value� of whose ref [attribute] is the same
 7702: 	* as the �actual value� of its own name attribute plus
 7703: 	* target namespace, then it must have exactly one such group."
 7704: 	*/
 7705: 	if (pctxt->redefCounter != 0) {
 7706: 	    xmlChar *str = NULL;
 7707: 
 7708: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
 7709: 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
 7710: 		"The redefining attribute group definition "
 7711: 		"'%s' must not contain more than one "
 7712: 		"reference to the redefined definition",
 7713: 		xmlSchemaFormatQName(&str, refNs, ref), NULL);
 7714: 	    FREE_AND_NULL(str);
 7715: 	    return(NULL);
 7716: 	}
 7717: 	pctxt->redefCounter++;
 7718: 	/*
 7719: 	* URGENT TODO: How to ensure that the reference will not be
 7720: 	* handled by the normal component resolution mechanism?
 7721: 	*/
 7722: 	ret = xmlSchemaNewQNameRef(pctxt,
 7723: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 7724: 	if (ret == NULL)
 7725: 	    return(NULL);
 7726: 	ret->node = node;
 7727: 	pctxt->redef->reference = WXS_BASIC_CAST ret;
 7728:     } else {
 7729: 	/*
 7730: 	* Create a QName-reference helper component. We will substitute this
 7731: 	* component for the attribute uses of the referenced attribute group
 7732: 	* definition.
 7733: 	*/
 7734: 	ret = xmlSchemaNewQNameRef(pctxt,
 7735: 	    XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
 7736: 	if (ret == NULL)
 7737: 	    return(NULL);
 7738: 	ret->node = node;
 7739: 	/* Add to pending items, to be able to resolve the reference. */
 7740: 	WXS_ADD_PENDING(pctxt, ret);
 7741:     }
 7742:     return (ret);
 7743: }
 7744: 
 7745: /**
 7746:  * xmlSchemaParseAttributeGroupDefinition:
 7747:  * @pctxt:  a schema validation context
 7748:  * @schema:  the schema being built
 7749:  * @node:  a subtree containing XML Schema informations
 7750:  *
 7751:  * parse a XML schema Attribute Group declaration
 7752:  * *WARNING* this interface is highly subject to change
 7753:  *
 7754:  * Returns the attribute group definition or NULL in case of error.
 7755:  */
 7756: static xmlSchemaAttributeGroupPtr
 7757: xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
 7758: 				       xmlSchemaPtr schema,
 7759: 				       xmlNodePtr node)
 7760: {
 7761:     const xmlChar *name;
 7762:     xmlSchemaAttributeGroupPtr ret;
 7763:     xmlNodePtr child = NULL;
 7764:     xmlAttrPtr attr;
 7765:     int hasRefs = 0;
 7766: 
 7767:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
 7768:         return (NULL);
 7769: 
 7770:     attr = xmlSchemaGetPropNode(node, "name");
 7771:     if (attr == NULL) {
 7772: 	xmlSchemaPMissingAttrErr(pctxt,
 7773: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 7774: 	    NULL, node, "name", NULL);
 7775: 	return (NULL);
 7776:     }
 7777:     /*
 7778:     * The name is crucial, exit if invalid.
 7779:     */
 7780:     if (xmlSchemaPValAttrNode(pctxt,
 7781: 	NULL, attr,
 7782: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 7783: 	return (NULL);
 7784:     }
 7785:     ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
 7786: 	name, pctxt->targetNamespace, node);
 7787:     if (ret == NULL)
 7788: 	return (NULL);
 7789:     /*
 7790:     * Check for illegal attributes.
 7791:     */
 7792:     attr = node->properties;
 7793:     while (attr != NULL) {
 7794: 	if (attr->ns == NULL) {
 7795: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 7796: 		(!xmlStrEqual(attr->name, BAD_CAST "id")))
 7797: 	    {
 7798: 		xmlSchemaPIllegalAttrErr(pctxt,
 7799: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7800: 	    }
 7801: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 7802: 	    xmlSchemaPIllegalAttrErr(pctxt,
 7803: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 7804: 	}
 7805: 	attr = attr->next;
 7806:     }
 7807:     /* Attribute ID */
 7808:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
 7809:     /*
 7810:     * And now for the children...
 7811:     */
 7812:     child = node->children;
 7813:     if (IS_SCHEMA(child, "annotation")) {
 7814:         ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
 7815:         child = child->next;
 7816:     }
 7817:     /*
 7818:     * Parse contained attribute decls/refs.
 7819:     */
 7820:     if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
 7821: 	(xmlSchemaItemListPtr *) &(ret->attrUses),
 7822: 	XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
 7823: 	return(NULL);
 7824:     if (hasRefs)
 7825: 	ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
 7826:     /*
 7827:     * Parse the attribute wildcard.
 7828:     */
 7829:     if (IS_SCHEMA(child, "anyAttribute")) {
 7830: 	ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
 7831: 	    schema, child);
 7832: 	child = child->next;
 7833:     }
 7834:     if (child != NULL) {
 7835: 	xmlSchemaPContentErr(pctxt,
 7836: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 7837: 	    NULL, node, child, NULL,
 7838: 	    "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
 7839:     }
 7840:     return (ret);
 7841: }
 7842: 
 7843: /**
 7844:  * xmlSchemaPValAttrFormDefault:
 7845:  * @value:  the value
 7846:  * @flags: the flags to be modified
 7847:  * @flagQualified: the specific flag for "qualified"
 7848:  *
 7849:  * Returns 0 if the value is valid, 1 otherwise.
 7850:  */
 7851: static int
 7852: xmlSchemaPValAttrFormDefault(const xmlChar *value,
 7853: 			     int *flags,
 7854: 			     int flagQualified)
 7855: {
 7856:     if (xmlStrEqual(value, BAD_CAST "qualified")) {
 7857: 	if  ((*flags & flagQualified) == 0)
 7858: 	    *flags |= flagQualified;
 7859:     } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
 7860: 	return (1);
 7861: 
 7862:     return (0);
 7863: }
 7864: 
 7865: /**
 7866:  * xmlSchemaPValAttrBlockFinal:
 7867:  * @value:  the value
 7868:  * @flags: the flags to be modified
 7869:  * @flagAll: the specific flag for "#all"
 7870:  * @flagExtension: the specific flag for "extension"
 7871:  * @flagRestriction: the specific flag for "restriction"
 7872:  * @flagSubstitution: the specific flag for "substitution"
 7873:  * @flagList: the specific flag for "list"
 7874:  * @flagUnion: the specific flag for "union"
 7875:  *
 7876:  * Validates the value of the attribute "final" and "block". The value
 7877:  * is converted into the specified flag values and returned in @flags.
 7878:  *
 7879:  * Returns 0 if the value is valid, 1 otherwise.
 7880:  */
 7881: 
 7882: static int
 7883: xmlSchemaPValAttrBlockFinal(const xmlChar *value,
 7884: 			    int *flags,
 7885: 			    int flagAll,
 7886: 			    int flagExtension,
 7887: 			    int flagRestriction,
 7888: 			    int flagSubstitution,
 7889: 			    int flagList,
 7890: 			    int flagUnion)
 7891: {
 7892:     int ret = 0;
 7893: 
 7894:     /*
 7895:     * TODO: This does not check for dublicate entries.
 7896:     */
 7897:     if ((flags == NULL) || (value == NULL))
 7898: 	return (-1);
 7899:     if (value[0] == 0)
 7900: 	return (0);
 7901:     if (xmlStrEqual(value, BAD_CAST "#all")) {
 7902: 	if (flagAll != -1)
 7903: 	    *flags |= flagAll;
 7904: 	else {
 7905: 	    if (flagExtension != -1)
 7906: 		*flags |= flagExtension;
 7907: 	    if (flagRestriction != -1)
 7908: 		*flags |= flagRestriction;
 7909: 	    if (flagSubstitution != -1)
 7910: 		*flags |= flagSubstitution;
 7911: 	    if (flagList != -1)
 7912: 		*flags |= flagList;
 7913: 	    if (flagUnion != -1)
 7914: 		*flags |= flagUnion;
 7915: 	}
 7916:     } else {
 7917: 	const xmlChar *end, *cur = value;
 7918: 	xmlChar *item;
 7919: 
 7920: 	do {
 7921: 	    while (IS_BLANK_CH(*cur))
 7922: 		cur++;
 7923: 	    end = cur;
 7924: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 7925: 		end++;
 7926: 	    if (end == cur)
 7927: 		break;
 7928: 	    item = xmlStrndup(cur, end - cur);
 7929: 	    if (xmlStrEqual(item, BAD_CAST "extension")) {
 7930: 		if (flagExtension != -1) {
 7931: 		    if ((*flags & flagExtension) == 0)
 7932: 			*flags |= flagExtension;
 7933: 		} else
 7934: 		    ret = 1;
 7935: 	    } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
 7936: 		if (flagRestriction != -1) {
 7937: 		    if ((*flags & flagRestriction) == 0)
 7938: 			*flags |= flagRestriction;
 7939: 		} else
 7940: 		    ret = 1;
 7941: 	    } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
 7942: 		if (flagSubstitution != -1) {
 7943: 		    if ((*flags & flagSubstitution) == 0)
 7944: 			*flags |= flagSubstitution;
 7945: 		} else
 7946: 		    ret = 1;
 7947: 	    } else if (xmlStrEqual(item, BAD_CAST "list")) {
 7948: 		if (flagList != -1) {
 7949: 		    if ((*flags & flagList) == 0)
 7950: 			*flags |= flagList;
 7951: 		} else
 7952: 		    ret = 1;
 7953: 	    } else if (xmlStrEqual(item, BAD_CAST "union")) {
 7954: 		if (flagUnion != -1) {
 7955: 		    if ((*flags & flagUnion) == 0)
 7956: 			*flags |= flagUnion;
 7957: 		} else
 7958: 		    ret = 1;
 7959: 	    } else
 7960: 		ret = 1;
 7961: 	    if (item != NULL)
 7962: 		xmlFree(item);
 7963: 	    cur = end;
 7964: 	} while ((ret == 0) && (*cur != 0));
 7965:     }
 7966: 
 7967:     return (ret);
 7968: }
 7969: 
 7970: static int
 7971: xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
 7972: 			     xmlSchemaIDCPtr idc,
 7973: 			     xmlSchemaIDCSelectPtr selector,
 7974: 			     xmlAttrPtr attr,
 7975: 			     int isField)
 7976: {
 7977:     xmlNodePtr node;
 7978: 
 7979:     /*
 7980:     * c-selector-xpath:
 7981:     * Schema Component Constraint: Selector Value OK
 7982:     *
 7983:     * TODO: 1 The {selector} must be a valid XPath expression, as defined
 7984:     * in [XPath].
 7985:     */
 7986:     if (selector == NULL) {
 7987: 	xmlSchemaPErr(ctxt, idc->node,
 7988: 	    XML_SCHEMAP_INTERNAL,
 7989: 	    "Internal error: xmlSchemaCheckCSelectorXPath, "
 7990: 	    "the selector is not specified.\n", NULL, NULL);
 7991: 	return (-1);
 7992:     }
 7993:     if (attr == NULL)
 7994: 	node = idc->node;
 7995:     else
 7996: 	node = (xmlNodePtr) attr;
 7997:     if (selector->xpath == NULL) {
 7998: 	xmlSchemaPCustomErr(ctxt,
 7999: 	    /* TODO: Adjust error code. */
 8000: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8001: 	    NULL, node,
 8002: 	    "The XPath expression of the selector is not valid", NULL);
 8003: 	return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 8004:     } else {
 8005: 	const xmlChar **nsArray = NULL;
 8006: 	xmlNsPtr *nsList = NULL;
 8007: 	/*
 8008: 	* Compile the XPath expression.
 8009: 	*/
 8010: 	/*
 8011: 	* TODO: We need the array of in-scope namespaces for compilation.
 8012: 	* TODO: Call xmlPatterncompile with different options for selector/
 8013: 	* field.
 8014: 	*/
 8015: 	if (attr == NULL)
 8016: 	    nsList = NULL;
 8017: 	else
 8018: 	    nsList = xmlGetNsList(attr->doc, attr->parent);
 8019: 	/*
 8020: 	* Build an array of prefixes and namespaces.
 8021: 	*/
 8022: 	if (nsList != NULL) {
 8023: 	    int i, count = 0;
 8024: 
 8025: 	    for (i = 0; nsList[i] != NULL; i++)
 8026: 		count++;
 8027: 
 8028: 	    nsArray = (const xmlChar **) xmlMalloc(
 8029: 		(count * 2 + 1) * sizeof(const xmlChar *));
 8030: 	    if (nsArray == NULL) {
 8031: 		xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
 8032: 		    NULL);
 8033: 		xmlFree(nsList);
 8034: 		return (-1);
 8035: 	    }
 8036: 	    for (i = 0; i < count; i++) {
 8037: 		nsArray[2 * i] = nsList[i]->href;
 8038: 		nsArray[2 * i + 1] = nsList[i]->prefix;
 8039: 	    }
 8040: 	    nsArray[count * 2] = NULL;
 8041: 	    xmlFree(nsList);
 8042: 	}
 8043: 	/*
 8044: 	* TODO: Differentiate between "selector" and "field".
 8045: 	*/
 8046: 	if (isField)
 8047: 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 8048: 		NULL, XML_PATTERN_XSFIELD, nsArray);
 8049: 	else
 8050: 	    selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
 8051: 		NULL, XML_PATTERN_XSSEL, nsArray);
 8052: 	if (nsArray != NULL)
 8053: 	    xmlFree((xmlChar **) nsArray);
 8054: 
 8055: 	if (selector->xpathComp == NULL) {
 8056: 	    xmlSchemaPCustomErr(ctxt,
 8057: 		/* TODO: Adjust error code? */
 8058: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8059: 		NULL, node,
 8060: 		"The XPath expression '%s' could not be "
 8061: 		"compiled", selector->xpath);
 8062: 	    return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
 8063: 	}
 8064:     }
 8065:     return (0);
 8066: }
 8067: 
 8068: #define ADD_ANNOTATION(annot)   \
 8069:     xmlSchemaAnnotPtr cur = item->annot; \
 8070:     if (item->annot == NULL) {  \
 8071: 	item->annot = annot;    \
 8072: 	return (annot);         \
 8073:     }                           \
 8074:     cur = item->annot;          \
 8075:     if (cur->next != NULL) {    \
 8076: 	cur = cur->next;	\
 8077:     }                           \
 8078:     cur->next = annot;
 8079: 
 8080: /**
 8081:  * xmlSchemaAssignAnnotation:
 8082:  * @item: the schema component
 8083:  * @annot: the annotation
 8084:  *
 8085:  * Adds the annotation to the given schema component.
 8086:  *
 8087:  * Returns the given annotaion.
 8088:  */
 8089: static xmlSchemaAnnotPtr
 8090: xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
 8091: 		       xmlSchemaAnnotPtr annot)
 8092: {
 8093:     if ((annItem == NULL) || (annot == NULL))
 8094: 	return (NULL);
 8095:     switch (annItem->type) {
 8096: 	case XML_SCHEMA_TYPE_ELEMENT: {
 8097: 		xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
 8098: 		ADD_ANNOTATION(annot)
 8099: 	    }
 8100: 	    break;
 8101: 	case XML_SCHEMA_TYPE_ATTRIBUTE: {
 8102: 		xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
 8103: 		ADD_ANNOTATION(annot)
 8104: 	    }
 8105: 	    break;
 8106: 	case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
 8107: 	case XML_SCHEMA_TYPE_ANY: {
 8108: 		xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
 8109: 		ADD_ANNOTATION(annot)
 8110: 	    }
 8111: 	    break;
 8112: 	case XML_SCHEMA_TYPE_PARTICLE:
 8113: 	case XML_SCHEMA_TYPE_IDC_KEY:
 8114: 	case XML_SCHEMA_TYPE_IDC_KEYREF:
 8115: 	case XML_SCHEMA_TYPE_IDC_UNIQUE: {
 8116: 		xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
 8117: 		ADD_ANNOTATION(annot)
 8118: 	    }
 8119: 	    break;
 8120: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
 8121: 		xmlSchemaAttributeGroupPtr item =
 8122: 		    (xmlSchemaAttributeGroupPtr) annItem;
 8123: 		ADD_ANNOTATION(annot)
 8124: 	    }
 8125: 	    break;
 8126: 	case XML_SCHEMA_TYPE_NOTATION: {
 8127: 		xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
 8128: 		ADD_ANNOTATION(annot)
 8129: 	    }
 8130: 	    break;
 8131: 	case XML_SCHEMA_FACET_MININCLUSIVE:
 8132: 	case XML_SCHEMA_FACET_MINEXCLUSIVE:
 8133: 	case XML_SCHEMA_FACET_MAXINCLUSIVE:
 8134: 	case XML_SCHEMA_FACET_MAXEXCLUSIVE:
 8135: 	case XML_SCHEMA_FACET_TOTALDIGITS:
 8136: 	case XML_SCHEMA_FACET_FRACTIONDIGITS:
 8137: 	case XML_SCHEMA_FACET_PATTERN:
 8138: 	case XML_SCHEMA_FACET_ENUMERATION:
 8139: 	case XML_SCHEMA_FACET_WHITESPACE:
 8140: 	case XML_SCHEMA_FACET_LENGTH:
 8141: 	case XML_SCHEMA_FACET_MAXLENGTH:
 8142: 	case XML_SCHEMA_FACET_MINLENGTH: {
 8143: 		xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
 8144: 		ADD_ANNOTATION(annot)
 8145: 	    }
 8146: 	    break;
 8147: 	case XML_SCHEMA_TYPE_SIMPLE:
 8148: 	case XML_SCHEMA_TYPE_COMPLEX: {
 8149: 		xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
 8150: 		ADD_ANNOTATION(annot)
 8151: 	    }
 8152: 	    break;
 8153: 	case XML_SCHEMA_TYPE_GROUP: {
 8154: 		xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
 8155: 		ADD_ANNOTATION(annot)
 8156: 	    }
 8157: 	    break;
 8158: 	case XML_SCHEMA_TYPE_SEQUENCE:
 8159: 	case XML_SCHEMA_TYPE_CHOICE:
 8160: 	case XML_SCHEMA_TYPE_ALL: {
 8161: 		xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
 8162: 		ADD_ANNOTATION(annot)
 8163: 	    }
 8164: 	    break;
 8165: 	default:
 8166: 	     xmlSchemaPCustomErr(NULL,
 8167: 		XML_SCHEMAP_INTERNAL,
 8168: 		NULL, NULL,
 8169: 		"Internal error: xmlSchemaAddAnnotation, "
 8170: 		"The item is not a annotated schema component", NULL);
 8171: 	     break;
 8172:     }
 8173:     return (annot);
 8174: }
 8175: 
 8176: /**
 8177:  * xmlSchemaParseIDCSelectorAndField:
 8178:  * @ctxt:  a schema validation context
 8179:  * @schema:  the schema being built
 8180:  * @node:  a subtree containing XML Schema informations
 8181:  *
 8182:  * Parses a XML Schema identity-contraint definition's
 8183:  * <selector> and <field> elements.
 8184:  *
 8185:  * Returns the parsed identity-constraint definition.
 8186:  */
 8187: static xmlSchemaIDCSelectPtr
 8188: xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
 8189: 			  xmlSchemaIDCPtr idc,
 8190: 			  xmlNodePtr node,
 8191: 			  int isField)
 8192: {
 8193:     xmlSchemaIDCSelectPtr item;
 8194:     xmlNodePtr child = NULL;
 8195:     xmlAttrPtr attr;
 8196: 
 8197:     /*
 8198:     * Check for illegal attributes.
 8199:     */
 8200:     attr = node->properties;
 8201:     while (attr != NULL) {
 8202: 	if (attr->ns == NULL) {
 8203: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8204: 		(!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
 8205: 		xmlSchemaPIllegalAttrErr(ctxt,
 8206: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8207: 	    }
 8208: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8209: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8210: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8211: 	}
 8212: 	attr = attr->next;
 8213:     }
 8214:     /*
 8215:     * Create the item.
 8216:     */
 8217:     item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
 8218:     if (item == NULL) {
 8219:         xmlSchemaPErrMemory(ctxt,
 8220: 	    "allocating a 'selector' of an identity-constraint definition",
 8221: 	    NULL);
 8222:         return (NULL);
 8223:     }
 8224:     memset(item, 0, sizeof(xmlSchemaIDCSelect));
 8225:     /*
 8226:     * Attribute "xpath" (mandatory).
 8227:     */
 8228:     attr = xmlSchemaGetPropNode(node, "xpath");
 8229:     if (attr == NULL) {
 8230:     	xmlSchemaPMissingAttrErr(ctxt,
 8231: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 8232: 	    NULL, node,
 8233: 	    "name", NULL);
 8234:     } else {
 8235: 	item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8236: 	/*
 8237: 	* URGENT TODO: "field"s have an other syntax than "selector"s.
 8238: 	*/
 8239: 
 8240: 	if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
 8241: 	    isField) == -1) {
 8242: 	    xmlSchemaPErr(ctxt,
 8243: 		(xmlNodePtr) attr,
 8244: 		XML_SCHEMAP_INTERNAL,
 8245: 		"Internal error: xmlSchemaParseIDCSelectorAndField, "
 8246: 		"validating the XPath expression of a IDC selector.\n",
 8247: 		NULL, NULL);
 8248: 	}
 8249: 
 8250:     }
 8251:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8252:     /*
 8253:     * And now for the children...
 8254:     */
 8255:     child = node->children;
 8256:     if (IS_SCHEMA(child, "annotation")) {
 8257: 	/*
 8258: 	* Add the annotation to the parent IDC.
 8259: 	*/
 8260: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
 8261: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 8262: 	child = child->next;
 8263:     }
 8264:     if (child != NULL) {
 8265: 	xmlSchemaPContentErr(ctxt,
 8266: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8267: 	    NULL, node, child,
 8268: 	    NULL, "(annotation?)");
 8269:     }
 8270: 
 8271:     return (item);
 8272: }
 8273: 
 8274: /**
 8275:  * xmlSchemaParseIDC:
 8276:  * @ctxt:  a schema validation context
 8277:  * @schema:  the schema being built
 8278:  * @node:  a subtree containing XML Schema informations
 8279:  *
 8280:  * Parses a XML Schema identity-contraint definition.
 8281:  *
 8282:  * Returns the parsed identity-constraint definition.
 8283:  */
 8284: static xmlSchemaIDCPtr
 8285: xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
 8286: 		  xmlSchemaPtr schema,
 8287: 		  xmlNodePtr node,
 8288: 		  xmlSchemaTypeType idcCategory,
 8289: 		  const xmlChar *targetNamespace)
 8290: {
 8291:     xmlSchemaIDCPtr item = NULL;
 8292:     xmlNodePtr child = NULL;
 8293:     xmlAttrPtr attr;
 8294:     const xmlChar *name = NULL;
 8295:     xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
 8296: 
 8297:     /*
 8298:     * Check for illegal attributes.
 8299:     */
 8300:     attr = node->properties;
 8301:     while (attr != NULL) {
 8302: 	if (attr->ns == NULL) {
 8303: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8304: 		(!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 8305: 		((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
 8306: 		 (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
 8307: 		xmlSchemaPIllegalAttrErr(ctxt,
 8308: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8309: 	    }
 8310: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8311: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8312: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8313: 	}
 8314: 	attr = attr->next;
 8315:     }
 8316:     /*
 8317:     * Attribute "name" (mandatory).
 8318:     */
 8319:     attr = xmlSchemaGetPropNode(node, "name");
 8320:     if (attr == NULL) {
 8321: 	xmlSchemaPMissingAttrErr(ctxt,
 8322: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 8323: 	    NULL, node,
 8324: 	    "name", NULL);
 8325: 	return (NULL);
 8326:     } else if (xmlSchemaPValAttrNode(ctxt,
 8327: 	NULL, attr,
 8328: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 8329: 	return (NULL);
 8330:     }
 8331:     /* Create the component. */
 8332:     item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
 8333: 	idcCategory, node);
 8334:     if (item == NULL)
 8335: 	return(NULL);
 8336: 
 8337:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8338:     if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
 8339: 	/*
 8340: 	* Attribute "refer" (mandatory).
 8341: 	*/
 8342: 	attr = xmlSchemaGetPropNode(node, "refer");
 8343: 	if (attr == NULL) {
 8344: 	    xmlSchemaPMissingAttrErr(ctxt,
 8345: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 8346: 		NULL, node,
 8347: 		"refer", NULL);
 8348: 	} else {
 8349: 	    /*
 8350: 	    * Create a reference item.
 8351: 	    */
 8352: 	    item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
 8353: 		NULL, NULL);
 8354: 	    if (item->ref == NULL)
 8355: 		return (NULL);
 8356: 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
 8357: 		NULL, attr,
 8358: 		&(item->ref->targetNamespace),
 8359: 		&(item->ref->name));
 8360: 	    xmlSchemaCheckReference(ctxt, schema, node, attr,
 8361: 		item->ref->targetNamespace);
 8362: 	}
 8363:     }
 8364:     /*
 8365:     * And now for the children...
 8366:     */
 8367:     child = node->children;
 8368:     if (IS_SCHEMA(child, "annotation")) {
 8369: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 8370: 	child = child->next;
 8371:     }
 8372:     if (child == NULL) {
 8373: 	xmlSchemaPContentErr(ctxt,
 8374: 		XML_SCHEMAP_S4S_ELEM_MISSING,
 8375: 		NULL, node, child,
 8376: 		"A child element is missing",
 8377: 		"(annotation?, (selector, field+))");
 8378:     }
 8379:     /*
 8380:     * Child element <selector>.
 8381:     */
 8382:     if (IS_SCHEMA(child, "selector")) {
 8383: 	item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
 8384: 	    item, child, 0);
 8385: 	child = child->next;
 8386: 	/*
 8387: 	* Child elements <field>.
 8388: 	*/
 8389: 	if (IS_SCHEMA(child, "field")) {
 8390: 	    do {
 8391: 		field = xmlSchemaParseIDCSelectorAndField(ctxt,
 8392: 		    item, child, 1);
 8393: 		if (field != NULL) {
 8394: 		    field->index = item->nbFields;
 8395: 		    item->nbFields++;
 8396: 		    if (lastField != NULL)
 8397: 			lastField->next = field;
 8398: 		    else
 8399: 			item->fields = field;
 8400: 		    lastField = field;
 8401: 		}
 8402: 		child = child->next;
 8403: 	    } while (IS_SCHEMA(child, "field"));
 8404: 	} else {
 8405: 	    xmlSchemaPContentErr(ctxt,
 8406: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8407: 		NULL, node, child,
 8408: 		NULL, "(annotation?, (selector, field+))");
 8409: 	}
 8410:     }
 8411:     if (child != NULL) {
 8412: 	xmlSchemaPContentErr(ctxt,
 8413: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8414: 	    NULL, node, child,
 8415: 	    NULL, "(annotation?, (selector, field+))");
 8416:     }
 8417: 
 8418:     return (item);
 8419: }
 8420: 
 8421: /**
 8422:  * xmlSchemaParseElement:
 8423:  * @ctxt:  a schema validation context
 8424:  * @schema:  the schema being built
 8425:  * @node:  a subtree containing XML Schema informations
 8426:  * @topLevel: indicates if this is global declaration
 8427:  *
 8428:  * Parses a XML schema element declaration.
 8429:  * *WARNING* this interface is highly subject to change
 8430:  *
 8431:  * Returns the element declaration or a particle; NULL in case
 8432:  * of an error or if the particle has minOccurs==maxOccurs==0.
 8433:  */
 8434: static xmlSchemaBasicItemPtr
 8435: xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 8436:                       xmlNodePtr node, int *isElemRef, int topLevel)
 8437: {
 8438:     xmlSchemaElementPtr decl = NULL;
 8439:     xmlSchemaParticlePtr particle = NULL;
 8440:     xmlSchemaAnnotPtr annot = NULL;
 8441:     xmlNodePtr child = NULL;
 8442:     xmlAttrPtr attr, nameAttr;
 8443:     int min, max, isRef = 0;
 8444:     xmlChar *des = NULL;
 8445: 
 8446:     /* 3.3.3 Constraints on XML Representations of Element Declarations */
 8447:     /* TODO: Complete implementation of 3.3.6 */
 8448: 
 8449:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 8450:         return (NULL);
 8451: 
 8452:     if (isElemRef != NULL)
 8453: 	*isElemRef = 0;
 8454:     /*
 8455:     * If we get a "ref" attribute on a local <element> we will assume it's
 8456:     * a reference - even if there's a "name" attribute; this seems to be more
 8457:     * robust.
 8458:     */
 8459:     nameAttr = xmlSchemaGetPropNode(node, "name");
 8460:     attr = xmlSchemaGetPropNode(node, "ref");
 8461:     if ((topLevel) || (attr == NULL)) {
 8462: 	if (nameAttr == NULL) {
 8463: 	    xmlSchemaPMissingAttrErr(ctxt,
 8464: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 8465: 		NULL, node, "name", NULL);
 8466: 	    return (NULL);
 8467: 	}
 8468:     } else
 8469: 	isRef = 1;
 8470: 
 8471:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8472:     child = node->children;
 8473:     if (IS_SCHEMA(child, "annotation")) {
 8474: 	annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 8475: 	child = child->next;
 8476:     }
 8477:     /*
 8478:     * Skip particle part if a global declaration.
 8479:     */
 8480:     if (topLevel)
 8481: 	goto declaration_part;
 8482:     /*
 8483:     * The particle part ==================================================
 8484:     */
 8485:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 8486:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
 8487:     xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
 8488:     particle = xmlSchemaAddParticle(ctxt, node, min, max);
 8489:     if (particle == NULL)
 8490: 	goto return_null;
 8491: 
 8492:     /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
 8493: 
 8494:     if (isRef) {
 8495: 	const xmlChar *refNs = NULL, *ref = NULL;
 8496: 	xmlSchemaQNameRefPtr refer = NULL;
 8497: 	/*
 8498: 	* The reference part =============================================
 8499: 	*/
 8500: 	if (isElemRef != NULL)
 8501: 	    *isElemRef = 1;
 8502: 
 8503: 	xmlSchemaPValAttrNodeQName(ctxt, schema,
 8504: 	    NULL, attr, &refNs, &ref);
 8505: 	xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 8506: 	/*
 8507: 	* SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
 8508: 	*/
 8509: 	if (nameAttr != NULL) {
 8510: 	    xmlSchemaPMutualExclAttrErr(ctxt,
 8511: 		XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
 8512: 	}
 8513: 	/*
 8514: 	* Check for illegal attributes.
 8515: 	*/
 8516: 	attr = node->properties;
 8517: 	while (attr != NULL) {
 8518: 	    if (attr->ns == NULL) {
 8519: 		if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
 8520: 		    xmlStrEqual(attr->name, BAD_CAST "name") ||
 8521: 		    xmlStrEqual(attr->name, BAD_CAST "id") ||
 8522: 		    xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
 8523: 		    xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
 8524: 		{
 8525: 		    attr = attr->next;
 8526: 		    continue;
 8527: 		} else {
 8528: 		    /* SPEC (3.3.3 : 2.2) */
 8529: 		    xmlSchemaPCustomAttrErr(ctxt,
 8530: 			XML_SCHEMAP_SRC_ELEMENT_2_2,
 8531: 			NULL, NULL, attr,
 8532: 			"Only the attributes 'minOccurs', 'maxOccurs' and "
 8533: 			"'id' are allowed in addition to 'ref'");
 8534: 		    break;
 8535: 		}
 8536: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8537: 		xmlSchemaPIllegalAttrErr(ctxt,
 8538: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8539: 	    }
 8540: 	    attr = attr->next;
 8541: 	}
 8542: 	/*
 8543: 	* No children except <annotation> expected.
 8544: 	*/
 8545: 	if (child != NULL) {
 8546: 	    xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8547: 		NULL, node, child, NULL, "(annotation?)");
 8548: 	}
 8549: 	if ((min == 0) && (max == 0))
 8550: 	    goto return_null;
 8551: 	/*
 8552: 	* Create the reference item and attach it to the particle.
 8553: 	*/
 8554: 	refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
 8555: 	    ref, refNs);
 8556: 	if (refer == NULL)
 8557: 	    goto return_null;
 8558: 	particle->children = (xmlSchemaTreeItemPtr) refer;
 8559: 	particle->annot = annot;
 8560: 	/*
 8561: 	* Add the particle to pending components, since the reference
 8562: 	* need to be resolved.
 8563: 	*/
 8564: 	WXS_ADD_PENDING(ctxt, particle);
 8565: 	return ((xmlSchemaBasicItemPtr) particle);
 8566:     }
 8567:     /*
 8568:     * The declaration part ===============================================
 8569:     */
 8570: declaration_part:
 8571:     {
 8572: 	const xmlChar *ns = NULL, *fixed, *name, *attrValue;
 8573: 	xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
 8574: 
 8575: 	if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
 8576: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
 8577: 	    goto return_null;
 8578: 	/*
 8579: 	* Evaluate the target namespace.
 8580: 	*/
 8581: 	if (topLevel) {
 8582: 	    ns = ctxt->targetNamespace;
 8583: 	} else {
 8584: 	    attr = xmlSchemaGetPropNode(node, "form");
 8585: 	    if (attr != NULL) {
 8586: 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8587: 		if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
 8588: 		    ns = ctxt->targetNamespace;
 8589: 		} else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
 8590: 		    xmlSchemaPSimpleTypeErr(ctxt,
 8591: 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8592: 			NULL, (xmlNodePtr) attr,
 8593: 			NULL, "(qualified | unqualified)",
 8594: 			attrValue, NULL, NULL, NULL);
 8595: 		}
 8596: 	    } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 8597: 		ns = ctxt->targetNamespace;
 8598: 	}
 8599: 	decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
 8600: 	if (decl == NULL) {
 8601: 	    goto return_null;
 8602: 	}
 8603: 	/*
 8604: 	* Check for illegal attributes.
 8605: 	*/
 8606: 	attr = node->properties;
 8607: 	while (attr != NULL) {
 8608: 	    if (attr->ns == NULL) {
 8609: 		if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 8610: 		    (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
 8611: 		    (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8612: 		    (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
 8613: 		    (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
 8614: 		    (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
 8615: 		    (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
 8616: 		{
 8617: 		    if (topLevel == 0) {
 8618: 			if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
 8619: 			    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 8620: 			    (!xmlStrEqual(attr->name, BAD_CAST "form")))
 8621: 			{
 8622: 			    xmlSchemaPIllegalAttrErr(ctxt,
 8623: 				XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8624: 			}
 8625: 		    } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
 8626: 			(!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
 8627: 			(!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
 8628: 
 8629: 			xmlSchemaPIllegalAttrErr(ctxt,
 8630: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8631: 		    }
 8632: 		}
 8633: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8634: 
 8635: 		xmlSchemaPIllegalAttrErr(ctxt,
 8636: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8637: 	    }
 8638: 	    attr = attr->next;
 8639: 	}
 8640: 	/*
 8641: 	* Extract/validate attributes.
 8642: 	*/
 8643: 	if (topLevel) {
 8644: 	    /*
 8645: 	    * Process top attributes of global element declarations here.
 8646: 	    */
 8647: 	    decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
 8648: 	    decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
 8649: 	    xmlSchemaPValAttrQName(ctxt, schema,
 8650: 		NULL, node, "substitutionGroup",
 8651: 		&(decl->substGroupNs), &(decl->substGroup));
 8652: 	    if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
 8653: 		decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
 8654: 	    /*
 8655: 	    * Attribute "final".
 8656: 	    */
 8657: 	    attr = xmlSchemaGetPropNode(node, "final");
 8658: 	    if (attr == NULL) {
 8659: 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 8660: 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
 8661: 		if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 8662: 		    decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
 8663: 	    } else {
 8664: 		attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8665: 		if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 8666: 		    -1,
 8667: 		    XML_SCHEMAS_ELEM_FINAL_EXTENSION,
 8668: 		    XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
 8669: 		    xmlSchemaPSimpleTypeErr(ctxt,
 8670: 			XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8671: 			NULL, (xmlNodePtr) attr,
 8672: 			NULL, "(#all | List of (extension | restriction))",
 8673: 			attrValue, NULL, NULL, NULL);
 8674: 		}
 8675: 	    }
 8676: 	}
 8677: 	/*
 8678: 	* Attribute "block".
 8679: 	*/
 8680: 	attr = xmlSchemaGetPropNode(node, "block");
 8681: 	if (attr == NULL) {
 8682: 	    /*
 8683: 	    * Apply default "block" values.
 8684: 	    */
 8685: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 8686: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
 8687: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 8688: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
 8689: 	    if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 8690: 		decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
 8691: 	} else {
 8692: 	    attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8693: 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
 8694: 		-1,
 8695: 		XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
 8696: 		XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
 8697: 		XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
 8698: 		xmlSchemaPSimpleTypeErr(ctxt,
 8699: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 8700: 		    NULL, (xmlNodePtr) attr,
 8701: 		    NULL, "(#all | List of (extension | "
 8702: 		    "restriction | substitution))", attrValue,
 8703: 		    NULL, NULL, NULL);
 8704: 	    }
 8705: 	}
 8706: 	if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
 8707: 	    decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
 8708: 
 8709: 	attr = xmlSchemaGetPropNode(node, "type");
 8710: 	if (attr != NULL) {
 8711: 	    xmlSchemaPValAttrNodeQName(ctxt, schema,
 8712: 		NULL, attr,
 8713: 		&(decl->namedTypeNs), &(decl->namedType));
 8714: 	    xmlSchemaCheckReference(ctxt, schema, node,
 8715: 		attr, decl->namedTypeNs);
 8716: 	}
 8717: 	decl->value = xmlSchemaGetProp(ctxt, node, "default");
 8718: 	attr = xmlSchemaGetPropNode(node, "fixed");
 8719: 	if (attr != NULL) {
 8720: 	    fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8721: 	    if (decl->value != NULL) {
 8722: 		/*
 8723: 		* 3.3.3 : 1
 8724: 		* default and fixed must not both be present.
 8725: 		*/
 8726: 		xmlSchemaPMutualExclAttrErr(ctxt,
 8727: 		    XML_SCHEMAP_SRC_ELEMENT_1,
 8728: 		    NULL, attr, "default", "fixed");
 8729: 	    } else {
 8730: 		decl->flags |= XML_SCHEMAS_ELEM_FIXED;
 8731: 		decl->value = fixed;
 8732: 	    }
 8733: 	}
 8734: 	/*
 8735: 	* And now for the children...
 8736: 	*/
 8737: 	if (IS_SCHEMA(child, "complexType")) {
 8738: 	    /*
 8739: 	    * 3.3.3 : 3
 8740: 	    * "type" and either <simpleType> or <complexType> are mutually
 8741: 	    * exclusive
 8742: 	    */
 8743: 	    if (decl->namedType != NULL) {
 8744: 		xmlSchemaPContentErr(ctxt,
 8745: 		    XML_SCHEMAP_SRC_ELEMENT_3,
 8746: 		    NULL, node, child,
 8747: 		    "The attribute 'type' and the <complexType> child are "
 8748: 		    "mutually exclusive", NULL);
 8749: 	    } else
 8750: 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
 8751: 	    child = child->next;
 8752: 	} else if (IS_SCHEMA(child, "simpleType")) {
 8753: 	    /*
 8754: 	    * 3.3.3 : 3
 8755: 	    * "type" and either <simpleType> or <complexType> are
 8756: 	    * mutually exclusive
 8757: 	    */
 8758: 	    if (decl->namedType != NULL) {
 8759: 		xmlSchemaPContentErr(ctxt,
 8760: 		    XML_SCHEMAP_SRC_ELEMENT_3,
 8761: 		    NULL, node, child,
 8762: 		    "The attribute 'type' and the <simpleType> child are "
 8763: 		    "mutually exclusive", NULL);
 8764: 	    } else
 8765: 		WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 8766: 	    child = child->next;
 8767: 	}
 8768: 	while ((IS_SCHEMA(child, "unique")) ||
 8769: 	    (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
 8770: 	    if (IS_SCHEMA(child, "unique")) {
 8771: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8772: 		    XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
 8773: 	    } else if (IS_SCHEMA(child, "key")) {
 8774: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8775: 		    XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
 8776: 	    } else if (IS_SCHEMA(child, "keyref")) {
 8777: 		curIDC = xmlSchemaParseIDC(ctxt, schema, child,
 8778: 		    XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
 8779: 	    }
 8780: 	    if (lastIDC != NULL)
 8781: 		lastIDC->next = curIDC;
 8782: 	    else
 8783: 		decl->idcs = (void *) curIDC;
 8784: 	    lastIDC = curIDC;
 8785: 	    child = child->next;
 8786: 	}
 8787: 	if (child != NULL) {
 8788: 	    xmlSchemaPContentErr(ctxt,
 8789: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8790: 		NULL, node, child,
 8791: 		NULL, "(annotation?, ((simpleType | complexType)?, "
 8792: 		"(unique | key | keyref)*))");
 8793: 	}
 8794: 	decl->annot = annot;
 8795:     }
 8796:     /*
 8797:     * NOTE: Element Declaration Representation OK 4. will be checked at a
 8798:     * different layer.
 8799:     */
 8800:     FREE_AND_NULL(des)
 8801:     if (topLevel)
 8802: 	return ((xmlSchemaBasicItemPtr) decl);
 8803:     else {
 8804: 	particle->children = (xmlSchemaTreeItemPtr) decl;
 8805: 	return ((xmlSchemaBasicItemPtr) particle);
 8806:     }
 8807: 
 8808: return_null:
 8809:     FREE_AND_NULL(des);
 8810:     if (annot != NULL) {
 8811: 	if (particle != NULL)
 8812: 	    particle->annot = NULL;
 8813: 	if (decl != NULL)
 8814: 	    decl->annot = NULL;
 8815: 	xmlSchemaFreeAnnot(annot);
 8816:     }
 8817:     return (NULL);
 8818: }
 8819: 
 8820: /**
 8821:  * xmlSchemaParseUnion:
 8822:  * @ctxt:  a schema validation context
 8823:  * @schema:  the schema being built
 8824:  * @node:  a subtree containing XML Schema informations
 8825:  *
 8826:  * parse a XML schema Union definition
 8827:  * *WARNING* this interface is highly subject to change
 8828:  *
 8829:  * Returns -1 in case of internal error, 0 in case of success and a positive
 8830:  * error code otherwise.
 8831:  */
 8832: static int
 8833: xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 8834:                     xmlNodePtr node)
 8835: {
 8836:     xmlSchemaTypePtr type;
 8837:     xmlNodePtr child = NULL;
 8838:     xmlAttrPtr attr;
 8839:     const xmlChar *cur = NULL;
 8840: 
 8841:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 8842:         return (-1);
 8843:     /* Not a component, don't create it. */
 8844:     type = ctxt->ctxtType;
 8845:     /*
 8846:     * Mark the simple type as being of variety "union".
 8847:     */
 8848:     type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
 8849:     /*
 8850:     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 8851:     * then the �simple ur-type definition�."
 8852:     */
 8853:     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 8854:     /*
 8855:     * Check for illegal attributes.
 8856:     */
 8857:     attr = node->properties;
 8858:     while (attr != NULL) {
 8859: 	if (attr->ns == NULL) {
 8860: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 8861: 		(!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
 8862: 		xmlSchemaPIllegalAttrErr(ctxt,
 8863: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8864: 	    }
 8865: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 8866: 	    xmlSchemaPIllegalAttrErr(ctxt,
 8867: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 8868: 	}
 8869: 	attr = attr->next;
 8870:     }
 8871:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 8872:     /*
 8873:     * Attribute "memberTypes". This is a list of QNames.
 8874:     * TODO: Check the value to contain anything.
 8875:     */
 8876:     attr = xmlSchemaGetPropNode(node, "memberTypes");
 8877:     if (attr != NULL) {
 8878: 	const xmlChar *end;
 8879: 	xmlChar *tmp;
 8880: 	const xmlChar *localName, *nsName;
 8881: 	xmlSchemaTypeLinkPtr link, lastLink = NULL;
 8882: 	xmlSchemaQNameRefPtr ref;
 8883: 
 8884: 	cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 8885: 	type->base = cur;
 8886: 	do {
 8887: 	    while (IS_BLANK_CH(*cur))
 8888: 		cur++;
 8889: 	    end = cur;
 8890: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
 8891: 		end++;
 8892: 	    if (end == cur)
 8893: 		break;
 8894: 	    tmp = xmlStrndup(cur, end - cur);
 8895: 	    if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
 8896: 		NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
 8897: 		/*
 8898: 		* Create the member type link.
 8899: 		*/
 8900: 		link = (xmlSchemaTypeLinkPtr)
 8901: 		    xmlMalloc(sizeof(xmlSchemaTypeLink));
 8902: 		if (link == NULL) {
 8903: 		    xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
 8904: 			"allocating a type link", NULL);
 8905: 		    return (-1);
 8906: 		}
 8907: 		link->type = NULL;
 8908: 		link->next = NULL;
 8909: 		if (lastLink == NULL)
 8910: 		    type->memberTypes = link;
 8911: 		else
 8912: 		    lastLink->next = link;
 8913: 		lastLink = link;
 8914: 		/*
 8915: 		* Create a reference item.
 8916: 		*/
 8917: 		ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
 8918: 		    localName, nsName);
 8919: 		if (ref == NULL) {
 8920: 		    FREE_AND_NULL(tmp)
 8921: 		    return (-1);
 8922: 		}
 8923: 		/*
 8924: 		* Assign the reference to the link, it will be resolved
 8925: 		* later during fixup of the union simple type.
 8926: 		*/
 8927: 		link->type = (xmlSchemaTypePtr) ref;
 8928: 	    }
 8929: 	    FREE_AND_NULL(tmp)
 8930: 	    cur = end;
 8931: 	} while (*cur != 0);
 8932: 
 8933:     }
 8934:     /*
 8935:     * And now for the children...
 8936:     */
 8937:     child = node->children;
 8938:     if (IS_SCHEMA(child, "annotation")) {
 8939: 	/*
 8940: 	* Add the annotation to the simple type ancestor.
 8941: 	*/
 8942: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 8943: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 8944:         child = child->next;
 8945:     }
 8946:     if (IS_SCHEMA(child, "simpleType")) {
 8947: 	xmlSchemaTypePtr subtype, last = NULL;
 8948: 
 8949: 	/*
 8950: 	* Anchor the member types in the "subtypes" field of the
 8951: 	* simple type.
 8952: 	*/
 8953: 	while (IS_SCHEMA(child, "simpleType")) {
 8954: 	    subtype = (xmlSchemaTypePtr)
 8955: 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 8956: 	    if (subtype != NULL) {
 8957: 		if (last == NULL) {
 8958: 		    type->subtypes = subtype;
 8959: 		    last = subtype;
 8960: 		} else {
 8961: 		    last->next = subtype;
 8962: 		    last = subtype;
 8963: 		}
 8964: 		last->next = NULL;
 8965: 	    }
 8966: 	    child = child->next;
 8967: 	}
 8968:     }
 8969:     if (child != NULL) {
 8970: 	xmlSchemaPContentErr(ctxt,
 8971: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 8972: 	    NULL, node, child, NULL, "(annotation?, simpleType*)");
 8973:     }
 8974:     if ((attr == NULL) && (type->subtypes == NULL)) {
 8975: 	 /*
 8976: 	* src-union-memberTypes-or-simpleTypes
 8977: 	* Either the memberTypes [attribute] of the <union> element must
 8978: 	* be non-empty or there must be at least one simpleType [child].
 8979: 	*/
 8980: 	xmlSchemaPCustomErr(ctxt,
 8981: 	    XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
 8982: 	    NULL, node,
 8983: 	    "Either the attribute 'memberTypes' or "
 8984: 	    "at least one <simpleType> child must be present", NULL);
 8985:     }
 8986:     return (0);
 8987: }
 8988: 
 8989: /**
 8990:  * xmlSchemaParseList:
 8991:  * @ctxt:  a schema validation context
 8992:  * @schema:  the schema being built
 8993:  * @node:  a subtree containing XML Schema informations
 8994:  *
 8995:  * parse a XML schema List definition
 8996:  * *WARNING* this interface is highly subject to change
 8997:  *
 8998:  * Returns -1 in case of error, 0 if the declaration is improper and
 8999:  *         1 in case of success.
 9000:  */
 9001: static xmlSchemaTypePtr
 9002: xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 9003:                    xmlNodePtr node)
 9004: {
 9005:     xmlSchemaTypePtr type;
 9006:     xmlNodePtr child = NULL;
 9007:     xmlAttrPtr attr;
 9008: 
 9009:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9010:         return (NULL);
 9011:     /* Not a component, don't create it. */
 9012:     type = ctxt->ctxtType;
 9013:     /*
 9014:     * Mark the type as being of variety "list".
 9015:     */
 9016:     type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
 9017:     /*
 9018:     * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
 9019:     * then the �simple ur-type definition�."
 9020:     */
 9021:     type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
 9022:     /*
 9023:     * Check for illegal attributes.
 9024:     */
 9025:     attr = node->properties;
 9026:     while (attr != NULL) {
 9027: 	if (attr->ns == NULL) {
 9028: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9029: 		(!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
 9030: 		xmlSchemaPIllegalAttrErr(ctxt,
 9031: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9032: 	    }
 9033: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9034: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9035: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9036: 	}
 9037: 	attr = attr->next;
 9038:     }
 9039: 
 9040:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9041: 
 9042:     /*
 9043:     * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
 9044:     * fields for holding the reference to the itemType.
 9045:     *
 9046:     * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
 9047:     * the "ref" fields.
 9048:     */
 9049:     xmlSchemaPValAttrQName(ctxt, schema, NULL,
 9050: 	node, "itemType", &(type->baseNs), &(type->base));
 9051:     /*
 9052:     * And now for the children...
 9053:     */
 9054:     child = node->children;
 9055:     if (IS_SCHEMA(child, "annotation")) {
 9056: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
 9057: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
 9058:         child = child->next;
 9059:     }
 9060:     if (IS_SCHEMA(child, "simpleType")) {
 9061: 	/*
 9062: 	* src-list-itemType-or-simpleType
 9063: 	* Either the itemType [attribute] or the <simpleType> [child] of
 9064: 	* the <list> element must be present, but not both.
 9065: 	*/
 9066: 	if (type->base != NULL) {
 9067: 	    xmlSchemaPCustomErr(ctxt,
 9068: 		XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9069: 		NULL, node,
 9070: 		"The attribute 'itemType' and the <simpleType> child "
 9071: 		"are mutually exclusive", NULL);
 9072: 	} else {
 9073: 	    type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
 9074: 	}
 9075:         child = child->next;
 9076:     } else if (type->base == NULL) {
 9077: 	xmlSchemaPCustomErr(ctxt,
 9078: 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9079: 	    NULL, node,
 9080: 	    "Either the attribute 'itemType' or the <simpleType> child "
 9081: 	    "must be present", NULL);
 9082:     }
 9083:     if (child != NULL) {
 9084: 	xmlSchemaPContentErr(ctxt,
 9085: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9086: 	    NULL, node, child, NULL, "(annotation?, simpleType?)");
 9087:     }
 9088:     if ((type->base == NULL) &&
 9089: 	(type->subtypes == NULL) &&
 9090: 	(xmlSchemaGetPropNode(node, "itemType") == NULL)) {
 9091: 	xmlSchemaPCustomErr(ctxt,
 9092: 	    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
 9093: 	    NULL, node,
 9094: 	    "Either the attribute 'itemType' or the <simpleType> child "
 9095: 	    "must be present", NULL);
 9096:     }
 9097:     return (NULL);
 9098: }
 9099: 
 9100: /**
 9101:  * xmlSchemaParseSimpleType:
 9102:  * @ctxt:  a schema validation context
 9103:  * @schema:  the schema being built
 9104:  * @node:  a subtree containing XML Schema informations
 9105:  *
 9106:  * parse a XML schema Simple Type definition
 9107:  * *WARNING* this interface is highly subject to change
 9108:  *
 9109:  * Returns -1 in case of error, 0 if the declaration is improper and
 9110:  * 1 in case of success.
 9111:  */
 9112: static xmlSchemaTypePtr
 9113: xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
 9114:                          xmlNodePtr node, int topLevel)
 9115: {
 9116:     xmlSchemaTypePtr type, oldCtxtType;
 9117:     xmlNodePtr child = NULL;
 9118:     const xmlChar *attrValue = NULL;
 9119:     xmlAttrPtr attr;
 9120:     int hasRestriction = 0;
 9121: 
 9122:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9123:         return (NULL);
 9124: 
 9125:     if (topLevel) {
 9126: 	attr = xmlSchemaGetPropNode(node, "name");
 9127: 	if (attr == NULL) {
 9128: 	    xmlSchemaPMissingAttrErr(ctxt,
 9129: 		XML_SCHEMAP_S4S_ATTR_MISSING,
 9130: 		NULL, node,
 9131: 		"name", NULL);
 9132: 	    return (NULL);
 9133: 	} else {
 9134: 	    if (xmlSchemaPValAttrNode(ctxt,
 9135: 		NULL, attr,
 9136: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
 9137: 		return (NULL);
 9138: 	    /*
 9139: 	    * Skip built-in types.
 9140: 	    */
 9141: 	    if (ctxt->isS4S) {
 9142: 		xmlSchemaTypePtr biType;
 9143: 
 9144: 		if (ctxt->isRedefine) {
 9145: 		    /*
 9146: 		    * REDEFINE: Disallow redefinition of built-in-types.
 9147: 		    * TODO: It seems that the spec does not say anything
 9148: 		    * about this case.
 9149: 		    */
 9150: 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 9151: 			NULL, node,
 9152: 			"Redefinition of built-in simple types is not "
 9153: 			"supported", NULL);
 9154: 		    return(NULL);
 9155: 		}
 9156: 		biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
 9157: 		if (biType != NULL)
 9158: 		    return (biType);
 9159: 	    }
 9160: 	}
 9161:     }
 9162:     /*
 9163:     * TargetNamespace:
 9164:     * SPEC "The �actual value� of the targetNamespace [attribute]
 9165:     * of the <schema> ancestor element information item if present,
 9166:     * otherwise �absent�.
 9167:     */
 9168:     if (topLevel == 0) {
 9169: #ifdef ENABLE_NAMED_LOCALS
 9170:         char buf[40];
 9171: #endif
 9172: 	/*
 9173: 	* Parse as local simple type definition.
 9174: 	*/
 9175: #ifdef ENABLE_NAMED_LOCALS
 9176:         snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
 9177: 	type = xmlSchemaAddType(ctxt, schema,
 9178: 	    XML_SCHEMA_TYPE_SIMPLE,
 9179: 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
 9180: 	    ctxt->targetNamespace, node, 0);
 9181: #else
 9182: 	type = xmlSchemaAddType(ctxt, schema,
 9183: 	    XML_SCHEMA_TYPE_SIMPLE,
 9184: 	    NULL, ctxt->targetNamespace, node, 0);
 9185: #endif
 9186: 	if (type == NULL)
 9187: 	    return (NULL);
 9188: 	type->type = XML_SCHEMA_TYPE_SIMPLE;
 9189: 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 9190: 	/*
 9191: 	* Check for illegal attributes.
 9192: 	*/
 9193: 	attr = node->properties;
 9194: 	while (attr != NULL) {
 9195: 	    if (attr->ns == NULL) {
 9196: 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
 9197: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9198: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9199: 		}
 9200: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9201: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9202: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9203: 	    }
 9204: 	    attr = attr->next;
 9205: 	}
 9206:     } else {
 9207: 	/*
 9208: 	* Parse as global simple type definition.
 9209: 	*
 9210: 	* Note that attrValue is the value of the attribute "name" here.
 9211: 	*/
 9212: 	type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
 9213: 	    attrValue, ctxt->targetNamespace, node, 1);
 9214: 	if (type == NULL)
 9215: 	    return (NULL);
 9216: 	type->type = XML_SCHEMA_TYPE_SIMPLE;
 9217: 	type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
 9218: 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
 9219: 	/*
 9220: 	* Check for illegal attributes.
 9221: 	*/
 9222: 	attr = node->properties;
 9223: 	while (attr != NULL) {
 9224: 	    if (attr->ns == NULL) {
 9225: 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9226: 		    (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 9227: 		    (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
 9228: 		    xmlSchemaPIllegalAttrErr(ctxt,
 9229: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9230: 		}
 9231: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9232: 		xmlSchemaPIllegalAttrErr(ctxt,
 9233: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9234: 	    }
 9235: 	    attr = attr->next;
 9236: 	}
 9237: 	/*
 9238: 	* Attribute "final".
 9239: 	*/
 9240: 	attr = xmlSchemaGetPropNode(node, "final");
 9241: 	if (attr == NULL) {
 9242: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 9243: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
 9244: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 9245: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
 9246: 	    if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 9247: 		type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
 9248: 	} else {
 9249: 	    attrValue = xmlSchemaGetProp(ctxt, node, "final");
 9250: 	    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
 9251: 		-1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
 9252: 		XML_SCHEMAS_TYPE_FINAL_LIST,
 9253: 		XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
 9254: 
 9255: 		xmlSchemaPSimpleTypeErr(ctxt,
 9256: 		    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9257: 		    WXS_BASIC_CAST type, (xmlNodePtr) attr,
 9258: 		    NULL, "(#all | List of (list | union | restriction)",
 9259: 		    attrValue, NULL, NULL, NULL);
 9260: 	    }
 9261: 	}
 9262:     }
 9263:     type->targetNamespace = ctxt->targetNamespace;
 9264:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9265:     /*
 9266:     * And now for the children...
 9267:     */
 9268:     oldCtxtType = ctxt->ctxtType;
 9269: 
 9270:     ctxt->ctxtType = type;
 9271: 
 9272:     child = node->children;
 9273:     if (IS_SCHEMA(child, "annotation")) {
 9274:         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9275:         child = child->next;
 9276:     }
 9277:     if (child == NULL) {
 9278: 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
 9279: 	    NULL, node, child, NULL,
 9280: 	    "(annotation?, (restriction | list | union))");
 9281:     } else if (IS_SCHEMA(child, "restriction")) {
 9282:         xmlSchemaParseRestriction(ctxt, schema, child,
 9283: 	    XML_SCHEMA_TYPE_SIMPLE);
 9284: 	hasRestriction = 1;
 9285:         child = child->next;
 9286:     } else if (IS_SCHEMA(child, "list")) {
 9287:         xmlSchemaParseList(ctxt, schema, child);
 9288:         child = child->next;
 9289:     } else if (IS_SCHEMA(child, "union")) {
 9290:         xmlSchemaParseUnion(ctxt, schema, child);
 9291:         child = child->next;
 9292:     }
 9293:     if (child != NULL) {
 9294: 	xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9295: 	    NULL, node, child, NULL,
 9296: 	    "(annotation?, (restriction | list | union))");
 9297:     }
 9298:     /*
 9299:     * REDEFINE: SPEC src-redefine (5)
 9300:     * "Within the [children], each <simpleType> must have a
 9301:     * <restriction> among its [children] ... the �actual value� of whose
 9302:     * base [attribute] must be the same as the �actual value� of its own
 9303:     * name attribute plus target namespace;"
 9304:     */
 9305:     if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
 9306: 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
 9307: 	    NULL, node, "This is a redefinition, thus the "
 9308: 	    "<simpleType> must have a <restriction> child", NULL);
 9309:     }
 9310: 
 9311:     ctxt->ctxtType = oldCtxtType;
 9312:     return (type);
 9313: }
 9314: 
 9315: /**
 9316:  * xmlSchemaParseModelGroupDefRef:
 9317:  * @ctxt:  the parser context
 9318:  * @schema: the schema being built
 9319:  * @node:  the node
 9320:  *
 9321:  * Parses a reference to a model group definition.
 9322:  *
 9323:  * We will return a particle component with a qname-component or
 9324:  * NULL in case of an error.
 9325:  */
 9326: static xmlSchemaTreeItemPtr
 9327: xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
 9328: 			       xmlSchemaPtr schema,
 9329: 			       xmlNodePtr node)
 9330: {
 9331:     xmlSchemaParticlePtr item;
 9332:     xmlNodePtr child = NULL;
 9333:     xmlAttrPtr attr;
 9334:     const xmlChar *ref = NULL, *refNs = NULL;
 9335:     int min, max;
 9336: 
 9337:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9338:         return (NULL);
 9339: 
 9340:     attr = xmlSchemaGetPropNode(node, "ref");
 9341:     if (attr == NULL) {
 9342: 	xmlSchemaPMissingAttrErr(ctxt,
 9343: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 9344: 	    NULL, node, "ref", NULL);
 9345: 	return (NULL);
 9346:     } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
 9347: 	attr, &refNs, &ref) != 0) {
 9348: 	return (NULL);
 9349:     }
 9350:     xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
 9351:     min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
 9352:     max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
 9353: 	"(xs:nonNegativeInteger | unbounded)");
 9354:     /*
 9355:     * Check for illegal attributes.
 9356:     */
 9357:     attr = node->properties;
 9358:     while (attr != NULL) {
 9359: 	if (attr->ns == NULL) {
 9360: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
 9361: 		(!xmlStrEqual(attr->name, BAD_CAST "id")) &&
 9362: 		(!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
 9363: 		(!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
 9364: 		xmlSchemaPIllegalAttrErr(ctxt,
 9365: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9366: 	    }
 9367: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9368: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9369: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9370: 	}
 9371: 	attr = attr->next;
 9372:     }
 9373:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9374:     item = xmlSchemaAddParticle(ctxt, node, min, max);
 9375:     if (item == NULL)
 9376: 	return (NULL);
 9377:     /*
 9378:     * Create a qname-reference and set as the term; it will be substituted
 9379:     * for the model group after the reference has been resolved.
 9380:     */
 9381:     item->children = (xmlSchemaTreeItemPtr)
 9382: 	xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
 9383:     xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
 9384:     /*
 9385:     * And now for the children...
 9386:     */
 9387:     child = node->children;
 9388:     /* TODO: Is annotation even allowed for a model group reference? */
 9389:     if (IS_SCHEMA(child, "annotation")) {
 9390: 	/*
 9391: 	* TODO: What to do exactly with the annotation?
 9392: 	*/
 9393: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9394: 	child = child->next;
 9395:     }
 9396:     if (child != NULL) {
 9397: 	xmlSchemaPContentErr(ctxt,
 9398: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9399: 	    NULL, node, child, NULL,
 9400: 	    "(annotation?)");
 9401:     }
 9402:     /*
 9403:     * Corresponds to no component at all if minOccurs==maxOccurs==0.
 9404:     */
 9405:     if ((min == 0) && (max == 0))
 9406: 	return (NULL);
 9407: 
 9408:     return ((xmlSchemaTreeItemPtr) item);
 9409: }
 9410: 
 9411: /**
 9412:  * xmlSchemaParseModelGroupDefinition:
 9413:  * @ctxt:  a schema validation context
 9414:  * @schema:  the schema being built
 9415:  * @node:  a subtree containing XML Schema informations
 9416:  *
 9417:  * Parses a XML schema model group definition.
 9418:  *
 9419:  * Note that the contraint src-redefine (6.2) can't be applied until
 9420:  * references have been resolved. So we will do this at the
 9421:  * component fixup level.
 9422:  *
 9423:  * *WARNING* this interface is highly subject to change
 9424:  *
 9425:  * Returns -1 in case of error, 0 if the declaration is improper and
 9426:  *         1 in case of success.
 9427:  */
 9428: static xmlSchemaModelGroupDefPtr
 9429: xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
 9430: 				   xmlSchemaPtr schema,
 9431: 				   xmlNodePtr node)
 9432: {
 9433:     xmlSchemaModelGroupDefPtr item;
 9434:     xmlNodePtr child = NULL;
 9435:     xmlAttrPtr attr;
 9436:     const xmlChar *name;
 9437: 
 9438:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
 9439:         return (NULL);
 9440: 
 9441:     attr = xmlSchemaGetPropNode(node, "name");
 9442:     if (attr == NULL) {
 9443: 	xmlSchemaPMissingAttrErr(ctxt,
 9444: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
 9445: 	    NULL, node,
 9446: 	    "name", NULL);
 9447: 	return (NULL);
 9448:     } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
 9449: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
 9450: 	return (NULL);
 9451:     }
 9452:     item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
 9453: 	ctxt->targetNamespace, node);
 9454:     if (item == NULL)
 9455: 	return (NULL);
 9456:     /*
 9457:     * Check for illegal attributes.
 9458:     */
 9459:     attr = node->properties;
 9460:     while (attr != NULL) {
 9461: 	if (attr->ns == NULL) {
 9462: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
 9463: 		(!xmlStrEqual(attr->name, BAD_CAST "id"))) {
 9464: 		xmlSchemaPIllegalAttrErr(ctxt,
 9465: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9466: 	    }
 9467: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
 9468: 	    xmlSchemaPIllegalAttrErr(ctxt,
 9469: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
 9470: 	}
 9471: 	attr = attr->next;
 9472:     }
 9473:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9474:     /*
 9475:     * And now for the children...
 9476:     */
 9477:     child = node->children;
 9478:     if (IS_SCHEMA(child, "annotation")) {
 9479: 	item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9480: 	child = child->next;
 9481:     }
 9482:     if (IS_SCHEMA(child, "all")) {
 9483: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9484: 	    XML_SCHEMA_TYPE_ALL, 0);
 9485: 	child = child->next;
 9486:     } else if (IS_SCHEMA(child, "choice")) {
 9487: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9488: 	    XML_SCHEMA_TYPE_CHOICE, 0);
 9489: 	child = child->next;
 9490:     } else if (IS_SCHEMA(child, "sequence")) {
 9491: 	item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
 9492: 	    XML_SCHEMA_TYPE_SEQUENCE, 0);
 9493: 	child = child->next;
 9494:     }
 9495: 
 9496: 
 9497: 
 9498:     if (child != NULL) {
 9499: 	xmlSchemaPContentErr(ctxt,
 9500: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9501: 	    NULL, node, child, NULL,
 9502: 	    "(annotation?, (all | choice | sequence)?)");
 9503:     }
 9504:     return (item);
 9505: }
 9506: 
 9507: /**
 9508:  * xmlSchemaCleanupDoc:
 9509:  * @ctxt:  a schema validation context
 9510:  * @node:  the root of the document.
 9511:  *
 9512:  * removes unwanted nodes in a schemas document tree
 9513:  */
 9514: static void
 9515: xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
 9516: {
 9517:     xmlNodePtr delete, cur;
 9518: 
 9519:     if ((ctxt == NULL) || (root == NULL)) return;
 9520: 
 9521:     /*
 9522:      * Remove all the blank text nodes
 9523:      */
 9524:     delete = NULL;
 9525:     cur = root;
 9526:     while (cur != NULL) {
 9527:         if (delete != NULL) {
 9528:             xmlUnlinkNode(delete);
 9529:             xmlFreeNode(delete);
 9530:             delete = NULL;
 9531:         }
 9532:         if (cur->type == XML_TEXT_NODE) {
 9533:             if (IS_BLANK_NODE(cur)) {
 9534:                 if (xmlNodeGetSpacePreserve(cur) != 1) {
 9535:                     delete = cur;
 9536:                 }
 9537:             }
 9538:         } else if ((cur->type != XML_ELEMENT_NODE) &&
 9539:                    (cur->type != XML_CDATA_SECTION_NODE)) {
 9540:             delete = cur;
 9541:             goto skip_children;
 9542:         }
 9543: 
 9544:         /*
 9545:          * Skip to next node
 9546:          */
 9547:         if (cur->children != NULL) {
 9548:             if ((cur->children->type != XML_ENTITY_DECL) &&
 9549:                 (cur->children->type != XML_ENTITY_REF_NODE) &&
 9550:                 (cur->children->type != XML_ENTITY_NODE)) {
 9551:                 cur = cur->children;
 9552:                 continue;
 9553:             }
 9554:         }
 9555:       skip_children:
 9556:         if (cur->next != NULL) {
 9557:             cur = cur->next;
 9558:             continue;
 9559:         }
 9560: 
 9561:         do {
 9562:             cur = cur->parent;
 9563:             if (cur == NULL)
 9564:                 break;
 9565:             if (cur == root) {
 9566:                 cur = NULL;
 9567:                 break;
 9568:             }
 9569:             if (cur->next != NULL) {
 9570:                 cur = cur->next;
 9571:                 break;
 9572:             }
 9573:         } while (cur != NULL);
 9574:     }
 9575:     if (delete != NULL) {
 9576:         xmlUnlinkNode(delete);
 9577:         xmlFreeNode(delete);
 9578:         delete = NULL;
 9579:     }
 9580: }
 9581: 
 9582: 
 9583: static void
 9584: xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
 9585: {
 9586:     if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
 9587: 	schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
 9588: 
 9589:     if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
 9590: 	schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
 9591: 
 9592:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
 9593: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
 9594:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
 9595: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
 9596:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
 9597: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
 9598:     if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
 9599: 	schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
 9600: 
 9601:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
 9602: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
 9603:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
 9604: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
 9605:     if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
 9606: 	schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
 9607: }
 9608: 
 9609: static int
 9610: xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
 9611: 			     xmlSchemaPtr schema,
 9612: 			     xmlNodePtr node)
 9613: {
 9614:     xmlAttrPtr attr;
 9615:     const xmlChar *val;
 9616:     int res = 0, oldErrs = ctxt->nberrors;
 9617: 
 9618:     /*
 9619:     * Those flags should be moved to the parser context flags,
 9620:     * since they are not visible at the component level. I.e.
 9621:     * they are used if processing schema *documents* only.
 9622:     */
 9623:     res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
 9624:     HFAILURE;
 9625: 
 9626:     /*
 9627:     * Since the version is of type xs:token, we won't bother to
 9628:     * check it.
 9629:     */
 9630:     /* REMOVED:
 9631:     attr = xmlSchemaGetPropNode(node, "version");
 9632:     if (attr != NULL) {
 9633: 	res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
 9634: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
 9635: 	HFAILURE;
 9636:     }
 9637:     */
 9638:     attr = xmlSchemaGetPropNode(node, "targetNamespace");
 9639:     if (attr != NULL) {
 9640: 	res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
 9641: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
 9642: 	HFAILURE;
 9643: 	if (res != 0) {
 9644: 	    ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
 9645: 	    goto exit;
 9646: 	}
 9647:     }
 9648:     attr = xmlSchemaGetPropNode(node, "elementFormDefault");
 9649:     if (attr != NULL) {
 9650: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9651: 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 9652: 	    XML_SCHEMAS_QUALIF_ELEM);
 9653: 	HFAILURE;
 9654: 	if (res != 0) {
 9655: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9656: 		XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
 9657: 		NULL, (xmlNodePtr) attr, NULL,
 9658: 		"(qualified | unqualified)", val, NULL, NULL, NULL);
 9659: 	}
 9660:     }
 9661:     attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
 9662:     if (attr != NULL) {
 9663: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9664: 	res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
 9665: 	    XML_SCHEMAS_QUALIF_ATTR);
 9666: 	HFAILURE;
 9667: 	if (res != 0) {
 9668: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9669: 		XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
 9670: 		NULL, (xmlNodePtr) attr, NULL,
 9671: 		"(qualified | unqualified)", val, NULL, NULL, NULL);
 9672: 	}
 9673:     }
 9674:     attr = xmlSchemaGetPropNode(node, "finalDefault");
 9675:     if (attr != NULL) {
 9676: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9677: 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 9678: 	    XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
 9679: 	    XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
 9680: 	    -1,
 9681: 	    XML_SCHEMAS_FINAL_DEFAULT_LIST,
 9682: 	    XML_SCHEMAS_FINAL_DEFAULT_UNION);
 9683: 	HFAILURE;
 9684: 	if (res != 0) {
 9685: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9686: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9687: 		NULL, (xmlNodePtr) attr, NULL,
 9688: 		"(#all | List of (extension | restriction | list | union))",
 9689: 		val, NULL, NULL, NULL);
 9690: 	}
 9691:     }
 9692:     attr = xmlSchemaGetPropNode(node, "blockDefault");
 9693:     if (attr != NULL) {
 9694: 	val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
 9695: 	res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
 9696: 	    XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
 9697: 	    XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
 9698: 	    XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
 9699: 	HFAILURE;
 9700: 	if (res != 0) {
 9701: 	    xmlSchemaPSimpleTypeErr(ctxt,
 9702: 		XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
 9703: 		NULL, (xmlNodePtr) attr, NULL,
 9704: 		"(#all | List of (extension | restriction | substitution))",
 9705: 		val, NULL, NULL, NULL);
 9706: 	}
 9707:     }
 9708: 
 9709: exit:
 9710:     if (oldErrs != ctxt->nberrors)
 9711: 	res = ctxt->err;
 9712:     return(res);
 9713: exit_failure:
 9714:     return(-1);
 9715: }
 9716: 
 9717: /**
 9718:  * xmlSchemaParseSchemaTopLevel:
 9719:  * @ctxt:  a schema validation context
 9720:  * @schema:  the schemas
 9721:  * @nodes:  the list of top level nodes
 9722:  *
 9723:  * Returns the internal XML Schema structure built from the resource or
 9724:  *         NULL in case of error
 9725:  */
 9726: static int
 9727: xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
 9728:                              xmlSchemaPtr schema, xmlNodePtr nodes)
 9729: {
 9730:     xmlNodePtr child;
 9731:     xmlSchemaAnnotPtr annot;
 9732:     int res = 0, oldErrs, tmpOldErrs;
 9733: 
 9734:     if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
 9735:         return(-1);
 9736: 
 9737:     oldErrs = ctxt->nberrors;
 9738:     child = nodes;
 9739:     while ((IS_SCHEMA(child, "include")) ||
 9740: 	   (IS_SCHEMA(child, "import")) ||
 9741: 	   (IS_SCHEMA(child, "redefine")) ||
 9742: 	   (IS_SCHEMA(child, "annotation"))) {
 9743: 	if (IS_SCHEMA(child, "annotation")) {
 9744: 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9745: 	    if (schema->annot == NULL)
 9746: 		schema->annot = annot;
 9747: 	    else
 9748: 		xmlSchemaFreeAnnot(annot);
 9749: 	} else if (IS_SCHEMA(child, "import")) {
 9750: 	    tmpOldErrs = ctxt->nberrors;
 9751: 	    res = xmlSchemaParseImport(ctxt, schema, child);
 9752: 	    HFAILURE;
 9753: 	    HSTOP(ctxt);
 9754: 	    if (tmpOldErrs != ctxt->nberrors)
 9755: 		goto exit;
 9756: 	} else if (IS_SCHEMA(child, "include")) {
 9757: 	    tmpOldErrs = ctxt->nberrors;
 9758: 	    res = xmlSchemaParseInclude(ctxt, schema, child);
 9759: 	    HFAILURE;
 9760: 	    HSTOP(ctxt);
 9761: 	    if (tmpOldErrs != ctxt->nberrors)
 9762: 		goto exit;
 9763: 	} else if (IS_SCHEMA(child, "redefine")) {
 9764: 	    tmpOldErrs = ctxt->nberrors;
 9765: 	    res = xmlSchemaParseRedefine(ctxt, schema, child);
 9766: 	    HFAILURE;
 9767: 	    HSTOP(ctxt);
 9768: 	    if (tmpOldErrs != ctxt->nberrors)
 9769: 		goto exit;
 9770: 	}
 9771: 	child = child->next;
 9772:     }
 9773:     /*
 9774:     * URGENT TODO: Change the functions to return int results.
 9775:     * We need especially to catch internal errors.
 9776:     */
 9777:     while (child != NULL) {
 9778: 	if (IS_SCHEMA(child, "complexType")) {
 9779: 	    xmlSchemaParseComplexType(ctxt, schema, child, 1);
 9780: 	    child = child->next;
 9781: 	} else if (IS_SCHEMA(child, "simpleType")) {
 9782: 	    xmlSchemaParseSimpleType(ctxt, schema, child, 1);
 9783: 	    child = child->next;
 9784: 	} else if (IS_SCHEMA(child, "element")) {
 9785: 	    xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
 9786: 	    child = child->next;
 9787: 	} else if (IS_SCHEMA(child, "attribute")) {
 9788: 	    xmlSchemaParseGlobalAttribute(ctxt, schema, child);
 9789: 	    child = child->next;
 9790: 	} else if (IS_SCHEMA(child, "attributeGroup")) {
 9791: 	    xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
 9792: 	    child = child->next;
 9793: 	} else if (IS_SCHEMA(child, "group")) {
 9794: 	    xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
 9795: 	    child = child->next;
 9796: 	} else if (IS_SCHEMA(child, "notation")) {
 9797: 	    xmlSchemaParseNotation(ctxt, schema, child);
 9798: 	    child = child->next;
 9799: 	} else {
 9800: 	    xmlSchemaPContentErr(ctxt,
 9801: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
 9802: 		NULL, child->parent, child,
 9803: 		NULL, "((include | import | redefine | annotation)*, "
 9804: 		"(((simpleType | complexType | group | attributeGroup) "
 9805: 		"| element | attribute | notation), annotation*)*)");
 9806: 	    child = child->next;
 9807: 	}
 9808: 	while (IS_SCHEMA(child, "annotation")) {
 9809: 	    /*
 9810: 	    * TODO: We should add all annotations.
 9811: 	    */
 9812: 	    annot = xmlSchemaParseAnnotation(ctxt, child, 1);
 9813: 	    if (schema->annot == NULL)
 9814: 		schema->annot = annot;
 9815: 	    else
 9816: 		xmlSchemaFreeAnnot(annot);
 9817: 	    child = child->next;
 9818: 	}
 9819:     }
 9820: exit:
 9821:     ctxt->ctxtType = NULL;
 9822:     if (oldErrs != ctxt->nberrors)
 9823: 	res = ctxt->err;
 9824:     return(res);
 9825: exit_failure:
 9826:     return(-1);
 9827: }
 9828: 
 9829: static xmlSchemaSchemaRelationPtr
 9830: xmlSchemaSchemaRelationCreate(void)
 9831: {
 9832:     xmlSchemaSchemaRelationPtr ret;
 9833: 
 9834:     ret = (xmlSchemaSchemaRelationPtr)
 9835: 	xmlMalloc(sizeof(xmlSchemaSchemaRelation));
 9836:     if (ret == NULL) {
 9837: 	xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
 9838: 	return(NULL);
 9839:     }
 9840:     memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
 9841:     return(ret);
 9842: }
 9843: 
 9844: #if 0
 9845: static void
 9846: xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
 9847: {
 9848:     xmlFree(rel);
 9849: }
 9850: #endif
 9851: 
 9852: static void
 9853: xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
 9854: {
 9855:     xmlSchemaRedefPtr prev;
 9856: 
 9857:     while (redef != NULL) {
 9858: 	prev = redef;
 9859: 	redef = redef->next;
 9860: 	xmlFree(prev);
 9861:     }
 9862: }
 9863: 
 9864: static void
 9865: xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
 9866: {
 9867:     /*
 9868:     * After the construction context has been freed, there will be
 9869:     * no schema graph available any more. Only the schema buckets
 9870:     * will stay alive, which are put into the "schemasImports" and
 9871:     * "includes" slots of the xmlSchema.
 9872:     */
 9873:     if (con->buckets != NULL)
 9874: 	xmlSchemaItemListFree(con->buckets);
 9875:     if (con->pending != NULL)
 9876: 	xmlSchemaItemListFree(con->pending);
 9877:     if (con->substGroups != NULL)
 9878: 	xmlHashFree(con->substGroups,
 9879: 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
 9880:     if (con->redefs != NULL)
 9881: 	xmlSchemaRedefListFree(con->redefs);
 9882:     if (con->dict != NULL)
 9883: 	xmlDictFree(con->dict);
 9884:     xmlFree(con);
 9885: }
 9886: 
 9887: static xmlSchemaConstructionCtxtPtr
 9888: xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
 9889: {
 9890:     xmlSchemaConstructionCtxtPtr ret;
 9891: 
 9892:     ret = (xmlSchemaConstructionCtxtPtr)
 9893: 	xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
 9894:     if (ret == NULL) {
 9895:         xmlSchemaPErrMemory(NULL,
 9896: 	    "allocating schema construction context", NULL);
 9897:         return (NULL);
 9898:     }
 9899:     memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
 9900: 
 9901:     ret->buckets = xmlSchemaItemListCreate();
 9902:     if (ret->buckets == NULL) {
 9903: 	xmlSchemaPErrMemory(NULL,
 9904: 	    "allocating list of schema buckets", NULL);
 9905: 	xmlFree(ret);
 9906:         return (NULL);
 9907:     }
 9908:     ret->pending = xmlSchemaItemListCreate();
 9909:     if (ret->pending == NULL) {
 9910: 	xmlSchemaPErrMemory(NULL,
 9911: 	    "allocating list of pending global components", NULL);
 9912: 	xmlSchemaConstructionCtxtFree(ret);
 9913:         return (NULL);
 9914:     }
 9915:     ret->dict = dict;
 9916:     xmlDictReference(dict);
 9917:     return(ret);
 9918: }
 9919: 
 9920: static xmlSchemaParserCtxtPtr
 9921: xmlSchemaParserCtxtCreate(void)
 9922: {
 9923:     xmlSchemaParserCtxtPtr ret;
 9924: 
 9925:     ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
 9926:     if (ret == NULL) {
 9927:         xmlSchemaPErrMemory(NULL, "allocating schema parser context",
 9928:                             NULL);
 9929:         return (NULL);
 9930:     }
 9931:     memset(ret, 0, sizeof(xmlSchemaParserCtxt));
 9932:     ret->type = XML_SCHEMA_CTXT_PARSER;
 9933:     ret->attrProhibs = xmlSchemaItemListCreate();
 9934:     if (ret->attrProhibs == NULL) {
 9935: 	xmlFree(ret);
 9936: 	return(NULL);
 9937:     }
 9938:     return(ret);
 9939: }
 9940: 
 9941: /**
 9942:  * xmlSchemaNewParserCtxtUseDict:
 9943:  * @URL:  the location of the schema
 9944:  * @dict: the dictionary to be used
 9945:  *
 9946:  * Create an XML Schemas parse context for that file/resource expected
 9947:  * to contain an XML Schemas file.
 9948:  *
 9949:  * Returns the parser context or NULL in case of error
 9950:  */
 9951: static xmlSchemaParserCtxtPtr
 9952: xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
 9953: {
 9954:     xmlSchemaParserCtxtPtr ret;
 9955: 
 9956:     ret = xmlSchemaParserCtxtCreate();
 9957:     if (ret == NULL)
 9958:         return (NULL);
 9959:     ret->dict = dict;
 9960:     xmlDictReference(dict);
 9961:     if (URL != NULL)
 9962: 	ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
 9963:     return (ret);
 9964: }
 9965: 
 9966: static int
 9967: xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
 9968: {
 9969:     if (vctxt->pctxt == NULL) {
 9970:         if (vctxt->schema != NULL)
 9971: 	    vctxt->pctxt =
 9972: 		xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
 9973: 	else
 9974: 	    vctxt->pctxt = xmlSchemaNewParserCtxt("*");
 9975: 	if (vctxt->pctxt == NULL) {
 9976: 	    VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
 9977: 		"failed to create a temp. parser context");
 9978: 	    return (-1);
 9979: 	}
 9980: 	/* TODO: Pass user data. */
 9981: 	xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
 9982: 	    vctxt->warning, vctxt->errCtxt);
 9983: 	xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
 9984: 	    vctxt->errCtxt);
 9985:     }
 9986:     return (0);
 9987: }
 9988: 
 9989: /**
 9990:  * xmlSchemaGetSchemaBucket:
 9991:  * @pctxt: the schema parser context
 9992:  * @schemaLocation: the URI of the schema document
 9993:  *
 9994:  * Returns a schema bucket if it was already parsed.
 9995:  *
 9996:  * Returns a schema bucket if it was already parsed from
 9997:  *         @schemaLocation, NULL otherwise.
 9998:  */
 9999: static xmlSchemaBucketPtr
10000: xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10001: 			    const xmlChar *schemaLocation)
10002: {
10003:     xmlSchemaBucketPtr cur;
10004:     xmlSchemaItemListPtr list;
10005: 
10006:     list = pctxt->constructor->buckets;
10007:     if (list->nbItems == 0)
10008: 	return(NULL);
10009:     else {
10010: 	int i;
10011: 	for (i = 0; i < list->nbItems; i++) {
10012: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10013: 	    /* Pointer comparison! */
10014: 	    if (cur->schemaLocation == schemaLocation)
10015: 		return(cur);
10016: 	}
10017:     }
10018:     return(NULL);
10019: }
10020: 
10021: static xmlSchemaBucketPtr
10022: xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
10023: 				     const xmlChar *schemaLocation,
10024: 				     const xmlChar *targetNamespace)
10025: {
10026:     xmlSchemaBucketPtr cur;
10027:     xmlSchemaItemListPtr list;
10028: 
10029:     list = pctxt->constructor->buckets;
10030:     if (list->nbItems == 0)
10031: 	return(NULL);
10032:     else {
10033: 	int i;
10034: 	for (i = 0; i < list->nbItems; i++) {
10035: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10036: 	    /* Pointer comparison! */
10037: 	    if ((cur->origTargetNamespace == NULL) &&
10038: 		(cur->schemaLocation == schemaLocation) &&
10039: 		(cur->targetNamespace == targetNamespace))
10040: 		return(cur);
10041: 	}
10042:     }
10043:     return(NULL);
10044: }
10045: 
10046: 
10047: #define IS_BAD_SCHEMA_DOC(b) \
10048:     (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
10049: 
10050: static xmlSchemaBucketPtr
10051: xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
10052: 				 const xmlChar *targetNamespace,
10053: 				 int imported)
10054: {
10055:     xmlSchemaBucketPtr cur;
10056:     xmlSchemaItemListPtr list;
10057: 
10058:     list = pctxt->constructor->buckets;
10059:     if (list->nbItems == 0)
10060: 	return(NULL);
10061:     else {
10062: 	int i;
10063: 	for (i = 0; i < list->nbItems; i++) {
10064: 	    cur = (xmlSchemaBucketPtr) list->items[i];
10065: 	    if ((! IS_BAD_SCHEMA_DOC(cur)) &&
10066: 		(cur->origTargetNamespace == targetNamespace) &&
10067: 		((imported && cur->imported) ||
10068: 		 ((!imported) && (!cur->imported))))
10069: 		return(cur);
10070: 	}
10071:     }
10072:     return(NULL);
10073: }
10074: 
10075: static int
10076: xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
10077: 		     xmlSchemaPtr schema,
10078: 		     xmlSchemaBucketPtr bucket)
10079: {
10080:     int oldFlags;
10081:     xmlDocPtr oldDoc;
10082:     xmlNodePtr node;
10083:     int ret, oldErrs;
10084:     xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
10085: 
10086:     /*
10087:     * Save old values; reset the *main* schema.
10088:     * URGENT TODO: This is not good; move the per-document information
10089:     * to the parser. Get rid of passing the main schema to the
10090:     * parsing functions.
10091:     */
10092:     oldFlags = schema->flags;
10093:     oldDoc = schema->doc;
10094:     if (schema->flags != 0)
10095: 	xmlSchemaClearSchemaDefaults(schema);
10096:     schema->doc = bucket->doc;
10097:     pctxt->schema = schema;
10098:     /*
10099:     * Keep the current target namespace on the parser *not* on the
10100:     * main schema.
10101:     */
10102:     pctxt->targetNamespace = bucket->targetNamespace;
10103:     WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
10104: 
10105:     if ((bucket->targetNamespace != NULL) &&
10106: 	xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
10107: 	/*
10108: 	* We are parsing the schema for schemas!
10109: 	*/
10110: 	pctxt->isS4S = 1;
10111:     }
10112:     /* Mark it as parsed, even if parsing fails. */
10113:     bucket->parsed++;
10114:     /* Compile the schema doc. */
10115:     node = xmlDocGetRootElement(bucket->doc);
10116:     ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
10117:     if (ret != 0)
10118: 	goto exit;
10119:     /* An empty schema; just get out. */
10120:     if (node->children == NULL)
10121: 	goto exit;
10122:     oldErrs = pctxt->nberrors;
10123:     ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
10124:     if (ret != 0)
10125: 	goto exit;
10126:     /*
10127:     * TODO: Not nice, but I'm not 100% sure we will get always an error
10128:     * as a result of the obove functions; so better rely on pctxt->err
10129:     * as well.
10130:     */
10131:     if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
10132: 	ret = pctxt->err;
10133: 	goto exit;
10134:     }
10135: 
10136: exit:
10137:     WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
10138:     /* Restore schema values. */
10139:     schema->doc = oldDoc;
10140:     schema->flags = oldFlags;
10141:     return(ret);
10142: }
10143: 
10144: static int
10145: xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
10146: 		     xmlSchemaPtr schema,
10147: 		     xmlSchemaBucketPtr bucket)
10148: {
10149:     xmlSchemaParserCtxtPtr newpctxt;
10150:     int res = 0;
10151: 
10152:     if (bucket == NULL)
10153: 	return(0);
10154:     if (bucket->parsed) {
10155: 	PERROR_INT("xmlSchemaParseNewDoc",
10156: 	    "reparsing a schema doc");
10157: 	return(-1);
10158:     }
10159:     if (bucket->doc == NULL) {
10160: 	PERROR_INT("xmlSchemaParseNewDoc",
10161: 	    "parsing a schema doc, but there's no doc");
10162: 	return(-1);
10163:     }
10164:     if (pctxt->constructor == NULL) {
10165: 	PERROR_INT("xmlSchemaParseNewDoc",
10166: 	    "no constructor");
10167: 	return(-1);
10168:     }
10169:     /* Create and init the temporary parser context. */
10170:     newpctxt = xmlSchemaNewParserCtxtUseDict(
10171: 	(const char *) bucket->schemaLocation, pctxt->dict);
10172:     if (newpctxt == NULL)
10173: 	return(-1);
10174:     newpctxt->constructor = pctxt->constructor;
10175:     /*
10176:     * TODO: Can we avoid that the parser knows about the main schema?
10177:     * It would be better if he knows about the current schema bucket
10178:     * only.
10179:     */
10180:     newpctxt->schema = schema;
10181:     xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
10182: 	pctxt->errCtxt);
10183:     xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
10184: 	pctxt->errCtxt);
10185:     newpctxt->counter = pctxt->counter;
10186: 
10187: 
10188:     res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
10189: 
10190:     /* Channel back errors and cleanup the temporary parser context. */
10191:     if (res != 0)
10192: 	pctxt->err = res;
10193:     pctxt->nberrors += newpctxt->nberrors;
10194:     pctxt->counter = newpctxt->counter;
10195:     newpctxt->constructor = NULL;
10196:     /* Free the parser context. */
10197:     xmlSchemaFreeParserCtxt(newpctxt);
10198:     return(res);
10199: }
10200: 
10201: static void
10202: xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
10203: 				xmlSchemaSchemaRelationPtr rel)
10204: {
10205:     xmlSchemaSchemaRelationPtr cur = bucket->relations;
10206: 
10207:     if (cur == NULL) {
10208: 	bucket->relations = rel;
10209: 	return;
10210:     }
10211:     while (cur->next != NULL)
10212: 	cur = cur->next;
10213:     cur->next = rel;
10214: }
10215: 
10216: 
10217: static const xmlChar *
10218: xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
10219: 			  xmlNodePtr ctxtNode)
10220: {
10221:     /*
10222:     * Build an absolue location URI.
10223:     */
10224:     if (location != NULL) {
10225: 	if (ctxtNode == NULL)
10226: 	    return(location);
10227: 	else {
10228: 	    xmlChar *base, *URI;
10229: 	    const xmlChar *ret = NULL;
10230: 
10231: 	    base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
10232: 	    if (base == NULL) {
10233: 		URI = xmlBuildURI(location, ctxtNode->doc->URL);
10234: 	    } else {
10235: 		URI = xmlBuildURI(location, base);
10236: 		xmlFree(base);
10237: 	    }
10238: 	    if (URI != NULL) {
10239: 		ret = xmlDictLookup(dict, URI, -1);
10240: 		xmlFree(URI);
10241: 		return(ret);
10242: 	    }
10243: 	}
10244:     }
10245:     return(NULL);
10246: }
10247: 
10248: 
10249: 
10250: /**
10251:  * xmlSchemaAddSchemaDoc:
10252:  * @pctxt:  a schema validation context
10253:  * @schema:  the schema being built
10254:  * @node:  a subtree containing XML Schema informations
10255:  *
10256:  * Parse an included (and to-be-redefined) XML schema document.
10257:  *
10258:  * Returns 0 on success, a positive error code on errors and
10259:  *         -1 in case of an internal or API error.
10260:  */
10261: 
10262: static int
10263: xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
10264: 		int type, /* import or include or redefine */
10265: 		const xmlChar *schemaLocation,
10266: 		xmlDocPtr schemaDoc,
10267: 		const char *schemaBuffer,
10268: 		int schemaBufferLen,
10269: 		xmlNodePtr invokingNode,
10270: 		const xmlChar *sourceTargetNamespace,
10271: 		const xmlChar *importNamespace,
10272: 		xmlSchemaBucketPtr *bucket)
10273: {
10274:     const xmlChar *targetNamespace = NULL;
10275:     xmlSchemaSchemaRelationPtr relation = NULL;
10276:     xmlDocPtr doc = NULL;
10277:     int res = 0, err = 0, located = 0, preserveDoc = 0;
10278:     xmlSchemaBucketPtr bkt = NULL;
10279: 
10280:     if (bucket != NULL)
10281: 	*bucket = NULL;
10282: 
10283:     switch (type) {
10284: 	case XML_SCHEMA_SCHEMA_IMPORT:
10285: 	case XML_SCHEMA_SCHEMA_MAIN:
10286: 	    err = XML_SCHEMAP_SRC_IMPORT;
10287: 	    break;
10288: 	case XML_SCHEMA_SCHEMA_INCLUDE:
10289: 	    err = XML_SCHEMAP_SRC_INCLUDE;
10290: 	    break;
10291: 	case XML_SCHEMA_SCHEMA_REDEFINE:
10292: 	    err = XML_SCHEMAP_SRC_REDEFINE;
10293: 	    break;
10294:     }
10295: 
10296: 
10297:     /* Special handling for the main schema:
10298:     * skip the location and relation logic and just parse the doc.
10299:     * We need just a bucket to be returned in this case.
10300:     */
10301:     if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
10302: 	goto doc_load;
10303: 
10304:     /* Note that we expect the location to be an absulute URI. */
10305:     if (schemaLocation != NULL) {
10306: 	bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
10307: 	if ((bkt != NULL) &&
10308: 	    (pctxt->constructor->bucket == bkt)) {
10309: 	    /* Report self-imports/inclusions/redefinitions. */
10310: 
10311: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10312: 		invokingNode, NULL,
10313: 		"The schema must not import/include/redefine itself",
10314: 		NULL, NULL);
10315: 	    goto exit;
10316: 	}
10317:     }
10318:     /*
10319:     * Create a relation for the graph of schemas.
10320:     */
10321:     relation = xmlSchemaSchemaRelationCreate();
10322:     if (relation == NULL)
10323: 	return(-1);
10324:     xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
10325: 	relation);
10326:     relation->type = type;
10327: 
10328:     /*
10329:     * Save the namespace import information.
10330:     */
10331:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
10332: 	relation->importNamespace = importNamespace;
10333: 	if (schemaLocation == NULL) {
10334: 	    /*
10335: 	    * No location; this is just an import of the namespace.
10336: 	    * Note that we don't assign a bucket to the relation
10337: 	    * in this case.
10338: 	    */
10339: 	    goto exit;
10340: 	}
10341: 	targetNamespace = importNamespace;
10342:     }
10343: 
10344:     /* Did we already fetch the doc? */
10345:     if (bkt != NULL) {
10346: 	if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
10347: 	    /*
10348: 	    * We included/redefined and then try to import a schema,
10349: 	    * but the new location provided for import was different.
10350: 	    */
10351: 	    if (schemaLocation == NULL)
10352: 		schemaLocation = BAD_CAST "in_memory_buffer";
10353: 	    if (!xmlStrEqual(schemaLocation,
10354: 		bkt->schemaLocation)) {
10355: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10356: 		    invokingNode, NULL,
10357: 		    "The schema document '%s' cannot be imported, since "
10358: 		    "it was already included or redefined",
10359: 		    schemaLocation, NULL);
10360: 		goto exit;
10361: 	    }
10362: 	} else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
10363: 	    /*
10364: 	    * We imported and then try to include/redefine a schema,
10365: 	    * but the new location provided for the include/redefine
10366: 	    * was different.
10367: 	    */
10368: 	    if (schemaLocation == NULL)
10369: 		schemaLocation = BAD_CAST "in_memory_buffer";
10370: 	    if (!xmlStrEqual(schemaLocation,
10371: 		bkt->schemaLocation)) {
10372: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
10373: 		    invokingNode, NULL,
10374: 		    "The schema document '%s' cannot be included or "
10375: 		    "redefined, since it was already imported",
10376: 		    schemaLocation, NULL);
10377: 		goto exit;
10378: 	    }
10379: 	}
10380:     }
10381: 
10382:     if (WXS_IS_BUCKET_IMPMAIN(type)) {
10383: 	/*
10384: 	* Given that the schemaLocation [attribute] is only a hint, it is open
10385: 	* to applications to ignore all but the first <import> for a given
10386: 	* namespace, regardless of the �actual value� of schemaLocation, but
10387: 	* such a strategy risks missing useful information when new
10388: 	* schemaLocations are offered.
10389: 	*
10390: 	* We will use the first <import> that comes with a location.
10391: 	* Further <import>s *with* a location, will result in an error.
10392: 	* TODO: Better would be to just report a warning here, but
10393: 	* we'll try it this way until someone complains.
10394: 	*
10395: 	* Schema Document Location Strategy:
10396: 	* 3 Based on the namespace name, identify an existing schema document,
10397: 	* either as a resource which is an XML document or a <schema> element
10398: 	* information item, in some local schema repository;
10399: 	* 5 Attempt to resolve the namespace name to locate such a resource.
10400: 	*
10401: 	* NOTE: (3) and (5) are not supported.
10402: 	*/
10403: 	if (bkt != NULL) {
10404: 	    relation->bucket = bkt;
10405: 	    goto exit;
10406: 	}
10407: 	bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
10408: 	    importNamespace, 1);
10409: 
10410: 	if (bkt != NULL) {
10411: 	    relation->bucket = bkt;
10412: 	    if (bkt->schemaLocation == NULL) {
10413: 		/* First given location of the schema; load the doc. */
10414: 		bkt->schemaLocation = schemaLocation;
10415: 	    } else {
10416: 		if (!xmlStrEqual(schemaLocation,
10417: 		    bkt->schemaLocation)) {
10418: 		    /*
10419: 		    * Additional location given; just skip it.
10420: 		    * URGENT TODO: We should report a warning here.
10421: 		    * res = XML_SCHEMAP_SRC_IMPORT;
10422: 		    */
10423: 		    if (schemaLocation == NULL)
10424: 			schemaLocation = BAD_CAST "in_memory_buffer";
10425: 
10426: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10427: 			XML_SCHEMAP_WARN_SKIP_SCHEMA,
10428: 			invokingNode, NULL,
10429: 			"Skipping import of schema located at '%s' for the "
10430: 			"namespace '%s', since this namespace was already "
10431: 			"imported with the schema located at '%s'",
10432: 			schemaLocation, importNamespace, bkt->schemaLocation);
10433: 		}
10434: 		goto exit;
10435: 	    }
10436: 	}
10437: 	/*
10438: 	* No bucket + first location: load the doc and create a
10439: 	* bucket.
10440: 	*/
10441:     } else {
10442: 	/* <include> and <redefine> */
10443: 	if (bkt != NULL) {
10444: 
10445: 	    if ((bkt->origTargetNamespace == NULL) &&
10446: 		(bkt->targetNamespace != sourceTargetNamespace)) {
10447: 		xmlSchemaBucketPtr chamel;
10448: 
10449: 		/*
10450: 		* Chameleon include/redefine: skip loading only if it was
10451: 		* aleady build for the targetNamespace of the including
10452: 		* schema.
10453: 		*/
10454: 		/*
10455: 		* URGENT TODO: If the schema is a chameleon-include then copy
10456: 		* the components into the including schema and modify the
10457: 		* targetNamespace of those components, do nothing otherwise.
10458: 		* NOTE: This is currently worked-around by compiling the
10459: 		* chameleon for every destinct including targetNamespace; thus
10460: 		* not performant at the moment.
10461: 		* TODO: Check when the namespace in wildcards for chameleons
10462: 		* needs to be converted: before we built wildcard intersections
10463: 		* or after.
10464: 		*   Answer: after!
10465: 		*/
10466: 		chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
10467: 		    schemaLocation, sourceTargetNamespace);
10468: 		if (chamel != NULL) {
10469: 		    /* A fitting chameleon was already parsed; NOP. */
10470: 		    relation->bucket = chamel;
10471: 		    goto exit;
10472: 		}
10473: 		/*
10474: 		* We need to parse the chameleon again for a different
10475: 		* targetNamespace.
10476: 		* CHAMELEON TODO: Optimize this by only parsing the
10477: 		* chameleon once, and then copying the components to
10478: 		* the new targetNamespace.
10479: 		*/
10480: 		bkt = NULL;
10481: 	    } else {
10482: 		relation->bucket = bkt;
10483: 		goto exit;
10484: 	    }
10485: 	}
10486:     }
10487:     if ((bkt != NULL) && (bkt->doc != NULL)) {
10488: 	PERROR_INT("xmlSchemaAddSchemaDoc",
10489: 	    "trying to load a schema doc, but a doc is already "
10490: 	    "assigned to the schema bucket");
10491: 	goto exit_failure;
10492:     }
10493: 
10494: doc_load:
10495:     /*
10496:     * Load the document.
10497:     */
10498:     if (schemaDoc != NULL) {
10499: 	doc = schemaDoc;
10500: 	/* Don' free this one, since it was provided by the caller. */
10501: 	preserveDoc = 1;
10502: 	/* TODO: Does the context or the doc hold the location? */
10503: 	if (schemaDoc->URL != NULL)
10504: 	    schemaLocation = xmlDictLookup(pctxt->dict,
10505: 		schemaDoc->URL, -1);
10506:         else
10507: 	    schemaLocation = BAD_CAST "in_memory_buffer";
10508:     } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
10509: 	xmlParserCtxtPtr parserCtxt;
10510: 
10511: 	parserCtxt = xmlNewParserCtxt();
10512: 	if (parserCtxt == NULL) {
10513: 	    xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
10514: 		"allocating a parser context", NULL);
10515: 	    goto exit_failure;
10516: 	}
10517: 	if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
10518: 	    /*
10519: 	    * TODO: Do we have to burden the schema parser dict with all
10520: 	    * the content of the schema doc?
10521: 	    */
10522: 	    xmlDictFree(parserCtxt->dict);
10523: 	    parserCtxt->dict = pctxt->dict;
10524: 	    xmlDictReference(parserCtxt->dict);
10525: 	}
10526: 	if (schemaLocation != NULL) {
10527: 	    /* Parse from file. */
10528: 	    doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
10529: 		NULL, SCHEMAS_PARSE_OPTIONS);
10530: 	} else if (schemaBuffer != NULL) {
10531: 	    /* Parse from memory buffer. */
10532: 	    doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
10533: 		NULL, NULL, SCHEMAS_PARSE_OPTIONS);
10534: 	    schemaLocation = BAD_CAST "in_memory_buffer";
10535: 	    if (doc != NULL)
10536: 		doc->URL = xmlStrdup(schemaLocation);
10537: 	}
10538: 	/*
10539: 	* For <import>:
10540: 	* 2.1 The referent is (a fragment of) a resource which is an
10541: 	* XML document (see clause 1.1), which in turn corresponds to
10542: 	* a <schema> element information item in a well-formed information
10543: 	* set, which in turn corresponds to a valid schema.
10544: 	* TODO: (2.1) fragments of XML documents are not supported.
10545: 	*
10546: 	* 2.2 The referent is a <schema> element information item in
10547: 	* a well-formed information set, which in turn corresponds
10548: 	* to a valid schema.
10549: 	* TODO: (2.2) is not supported.
10550: 	*/
10551: 	if (doc == NULL) {
10552: 	    xmlErrorPtr lerr;
10553: 	    lerr = xmlGetLastError();
10554: 	    /*
10555: 	    * Check if this a parser error, or if the document could
10556: 	    * just not be located.
10557: 	    * TODO: Try to find specific error codes to react only on
10558: 	    * localisation failures.
10559: 	    */
10560: 	    if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
10561: 		/*
10562: 		* We assume a parser error here.
10563: 		*/
10564: 		located = 1;
10565: 		/* TODO: Error code ?? */
10566: 		res = XML_SCHEMAP_SRC_IMPORT_2_1;
10567: 		xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10568: 		    invokingNode, NULL,
10569: 		    "Failed to parse the XML resource '%s'",
10570: 		    schemaLocation, NULL);
10571: 	    }
10572: 	}
10573: 	xmlFreeParserCtxt(parserCtxt);
10574: 	if ((doc == NULL) && located)
10575: 	    goto exit_error;
10576:     } else {
10577: 	xmlSchemaPErr(pctxt, NULL,
10578: 	    XML_SCHEMAP_NOTHING_TO_PARSE,
10579: 	    "No information for parsing was provided with the "
10580: 	    "given schema parser context.\n",
10581: 	    NULL, NULL);
10582: 	goto exit_failure;
10583:     }
10584:     /*
10585:     * Preprocess the document.
10586:     */
10587:     if (doc != NULL) {
10588: 	xmlNodePtr docElem = NULL;
10589: 
10590: 	located = 1;
10591: 	docElem = xmlDocGetRootElement(doc);
10592: 	if (docElem == NULL) {
10593: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
10594: 		invokingNode, NULL,
10595: 		"The document '%s' has no document element",
10596: 		schemaLocation, NULL);
10597: 	    goto exit_error;
10598: 	}
10599: 	/*
10600: 	* Remove all the blank text nodes.
10601: 	*/
10602: 	xmlSchemaCleanupDoc(pctxt, docElem);
10603: 	/*
10604: 	* Check the schema's top level element.
10605: 	*/
10606: 	if (!IS_SCHEMA(docElem, "schema")) {
10607: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
10608: 		invokingNode, NULL,
10609: 		"The XML document '%s' is not a schema document",
10610: 		schemaLocation, NULL);
10611: 	    goto exit_error;
10612: 	}
10613: 	/*
10614: 	* Note that we don't apply a type check for the
10615: 	* targetNamespace value here.
10616: 	*/
10617: 	targetNamespace = xmlSchemaGetProp(pctxt, docElem,
10618: 	    "targetNamespace");
10619:     }
10620: 
10621: /* after_doc_loading: */
10622:     if ((bkt == NULL) && located) {
10623: 	/* Only create a bucket if the schema was located. */
10624:         bkt = xmlSchemaBucketCreate(pctxt, type,
10625: 	    targetNamespace);
10626: 	if (bkt == NULL)
10627: 	    goto exit_failure;
10628:     }
10629:     if (bkt != NULL) {
10630: 	bkt->schemaLocation = schemaLocation;
10631: 	bkt->located = located;
10632: 	if (doc != NULL) {
10633: 	    bkt->doc = doc;
10634: 	    bkt->targetNamespace = targetNamespace;
10635: 	    bkt->origTargetNamespace = targetNamespace;
10636: 	    if (preserveDoc)
10637: 		bkt->preserveDoc = 1;
10638: 	}
10639: 	if (WXS_IS_BUCKET_IMPMAIN(type))
10640: 	    bkt->imported++;
10641: 	    /*
10642: 	    * Add it to the graph of schemas.
10643: 	    */
10644: 	if (relation != NULL)
10645: 	    relation->bucket = bkt;
10646:     }
10647: 
10648: exit:
10649:     /*
10650:     * Return the bucket explicitely; this is needed for the
10651:     * main schema.
10652:     */
10653:     if (bucket != NULL)
10654: 	*bucket = bkt;
10655:     return (0);
10656: 
10657: exit_error:
10658:     if ((doc != NULL) && (! preserveDoc)) {
10659: 	xmlFreeDoc(doc);
10660: 	if (bkt != NULL)
10661: 	    bkt->doc = NULL;
10662:     }
10663:     return(pctxt->err);
10664: 
10665: exit_failure:
10666:     if ((doc != NULL) && (! preserveDoc)) {
10667: 	xmlFreeDoc(doc);
10668: 	if (bkt != NULL)
10669: 	    bkt->doc = NULL;
10670:     }
10671:     return (-1);
10672: }
10673: 
10674: /**
10675:  * xmlSchemaParseImport:
10676:  * @ctxt:  a schema validation context
10677:  * @schema:  the schema being built
10678:  * @node:  a subtree containing XML Schema informations
10679:  *
10680:  * parse a XML schema Import definition
10681:  * *WARNING* this interface is highly subject to change
10682:  *
10683:  * Returns 0 in case of success, a positive error code if
10684:  * not valid and -1 in case of an internal error.
10685:  */
10686: static int
10687: xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
10688:                      xmlNodePtr node)
10689: {
10690:     xmlNodePtr child;
10691:     const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
10692:     const xmlChar *thisTargetNamespace;
10693:     xmlAttrPtr attr;
10694:     int ret = 0;
10695:     xmlSchemaBucketPtr bucket = NULL;
10696: 
10697:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10698:         return (-1);
10699: 
10700:     /*
10701:     * Check for illegal attributes.
10702:     */
10703:     attr = node->properties;
10704:     while (attr != NULL) {
10705: 	if (attr->ns == NULL) {
10706: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10707: 		(!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
10708: 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10709: 		xmlSchemaPIllegalAttrErr(pctxt,
10710: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10711: 	    }
10712: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10713: 	    xmlSchemaPIllegalAttrErr(pctxt,
10714: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10715: 	}
10716: 	attr = attr->next;
10717:     }
10718:     /*
10719:     * Extract and validate attributes.
10720:     */
10721:     if (xmlSchemaPValAttr(pctxt, NULL, node,
10722: 	"namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10723: 	&namespaceName) != 0) {
10724: 	xmlSchemaPSimpleTypeErr(pctxt,
10725: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10726: 	    NULL, node,
10727: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10728: 	    NULL, namespaceName, NULL, NULL, NULL);
10729: 	return (pctxt->err);
10730:     }
10731: 
10732:     if (xmlSchemaPValAttr(pctxt, NULL, node,
10733: 	"schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10734: 	&schemaLocation) != 0) {
10735: 	xmlSchemaPSimpleTypeErr(pctxt,
10736: 	    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
10737: 	    NULL, node,
10738: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10739: 	    NULL, namespaceName, NULL, NULL, NULL);
10740: 	return (pctxt->err);
10741:     }
10742:     /*
10743:     * And now for the children...
10744:     */
10745:     child = node->children;
10746:     if (IS_SCHEMA(child, "annotation")) {
10747:         /*
10748:          * the annotation here is simply discarded ...
10749: 	 * TODO: really?
10750:          */
10751:         child = child->next;
10752:     }
10753:     if (child != NULL) {
10754: 	xmlSchemaPContentErr(pctxt,
10755: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
10756: 	    NULL, node, child, NULL,
10757: 	    "(annotation?)");
10758:     }
10759:     /*
10760:     * Apply additional constraints.
10761:     *
10762:     * Note that it is important to use the original @targetNamespace
10763:     * (or none at all), to rule out imports of schemas _with_ a
10764:     * @targetNamespace if the importing schema is a chameleon schema
10765:     * (with no @targetNamespace).
10766:     */
10767:     thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
10768:     if (namespaceName != NULL) {
10769: 	/*
10770: 	* 1.1 If the namespace [attribute] is present, then its �actual value�
10771: 	* must not match the �actual value� of the enclosing <schema>'s
10772: 	* targetNamespace [attribute].
10773: 	*/
10774: 	if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
10775: 	    xmlSchemaPCustomErr(pctxt,
10776: 		XML_SCHEMAP_SRC_IMPORT_1_1,
10777: 		NULL, node,
10778: 		"The value of the attribute 'namespace' must not match "
10779: 		"the target namespace '%s' of the importing schema",
10780: 		thisTargetNamespace);
10781: 	    return (pctxt->err);
10782: 	}
10783:     } else {
10784: 	/*
10785: 	* 1.2 If the namespace [attribute] is not present, then the enclosing
10786: 	* <schema> must have a targetNamespace [attribute].
10787: 	*/
10788: 	if (thisTargetNamespace == NULL) {
10789: 	    xmlSchemaPCustomErr(pctxt,
10790: 		XML_SCHEMAP_SRC_IMPORT_1_2,
10791: 		NULL, node,
10792: 		"The attribute 'namespace' must be existent if "
10793: 		"the importing schema has no target namespace",
10794: 		NULL);
10795: 	    return (pctxt->err);
10796: 	}
10797:     }
10798:     /*
10799:     * Locate and acquire the schema document.
10800:     */
10801:     if (schemaLocation != NULL)
10802: 	schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
10803: 	    schemaLocation, node);
10804:     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
10805: 	schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
10806: 	namespaceName, &bucket);
10807: 
10808:     if (ret != 0)
10809: 	return(ret);
10810: 
10811:     /*
10812:     * For <import>: "It is *not* an error for the application
10813:     * schema reference strategy to fail."
10814:     * So just don't parse if no schema document was found.
10815:     * Note that we will get no bucket if the schema could not be
10816:     * located or if there was no schemaLocation.
10817:     */
10818:     if ((bucket == NULL) && (schemaLocation != NULL)) {
10819: 	xmlSchemaCustomWarning(ACTXT_CAST pctxt,
10820: 	    XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
10821: 	    node, NULL,
10822: 	    "Failed to locate a schema at location '%s'. "
10823: 	    "Skipping the import", schemaLocation, NULL, NULL);
10824:     }
10825: 
10826:     if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
10827: 	ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
10828:     }
10829: 
10830:     return (ret);
10831: }
10832: 
10833: static int
10834: xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
10835: 				     xmlSchemaPtr schema,
10836: 				     xmlNodePtr node,
10837: 				     xmlChar **schemaLocation,
10838: 				     int type)
10839: {
10840:     xmlAttrPtr attr;
10841: 
10842:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
10843: 	(schemaLocation == NULL))
10844:         return (-1);
10845: 
10846:     *schemaLocation = NULL;
10847:     /*
10848:     * Check for illegal attributes.
10849:     * Applies for both <include> and <redefine>.
10850:     */
10851:     attr = node->properties;
10852:     while (attr != NULL) {
10853: 	if (attr->ns == NULL) {
10854: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
10855: 		(!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
10856: 		xmlSchemaPIllegalAttrErr(pctxt,
10857: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10858: 	    }
10859: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
10860: 	    xmlSchemaPIllegalAttrErr(pctxt,
10861: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
10862: 	}
10863: 	attr = attr->next;
10864:     }
10865:     xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
10866:     /*
10867:     * Preliminary step, extract the URI-Reference and make an URI
10868:     * from the base.
10869:     */
10870:     /*
10871:     * Attribute "schemaLocation" is mandatory.
10872:     */
10873:     attr = xmlSchemaGetPropNode(node, "schemaLocation");
10874:     if (attr != NULL) {
10875:         xmlChar *base = NULL;
10876:         xmlChar *uri = NULL;
10877: 
10878: 	if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
10879: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
10880: 	    (const xmlChar **) schemaLocation) != 0)
10881: 	    goto exit_error;
10882: 	base = xmlNodeGetBase(node->doc, node);
10883: 	if (base == NULL) {
10884: 	    uri = xmlBuildURI(*schemaLocation, node->doc->URL);
10885: 	} else {
10886: 	    uri = xmlBuildURI(*schemaLocation, base);
10887: 	    xmlFree(base);
10888: 	}
10889: 	if (uri == NULL) {
10890: 	    PERROR_INT("xmlSchemaParseIncludeOrRedefine",
10891: 		"could not build an URI from the schemaLocation")
10892: 	    goto exit_failure;
10893: 	}
10894: 	(*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
10895: 	xmlFree(uri);
10896:     } else {
10897: 	xmlSchemaPMissingAttrErr(pctxt,
10898: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
10899: 	    NULL, node, "schemaLocation", NULL);
10900: 	goto exit_error;
10901:     }
10902:     /*
10903:     * Report self-inclusion and self-redefinition.
10904:     */
10905:     if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
10906: 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
10907: 	    xmlSchemaPCustomErr(pctxt,
10908: 		XML_SCHEMAP_SRC_REDEFINE,
10909: 		NULL, node,
10910: 		"The schema document '%s' cannot redefine itself.",
10911: 		*schemaLocation);
10912: 	} else {
10913: 	    xmlSchemaPCustomErr(pctxt,
10914: 		XML_SCHEMAP_SRC_INCLUDE,
10915: 		NULL, node,
10916: 		"The schema document '%s' cannot include itself.",
10917: 		*schemaLocation);
10918: 	}
10919: 	goto exit_error;
10920:     }
10921: 
10922:     return(0);
10923: exit_error:
10924:     return(pctxt->err);
10925: exit_failure:
10926:     return(-1);
10927: }
10928: 
10929: static int
10930: xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
10931: 				xmlSchemaPtr schema,
10932: 				xmlNodePtr node,
10933: 				int type)
10934: {
10935:     xmlNodePtr child = NULL;
10936:     const xmlChar *schemaLocation = NULL;
10937:     int res = 0; /* hasRedefinitions = 0 */
10938:     int isChameleon = 0, wasChameleon = 0;
10939:     xmlSchemaBucketPtr bucket = NULL;
10940: 
10941:     if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
10942:         return (-1);
10943: 
10944:     /*
10945:     * Parse attributes. Note that the returned schemaLocation will
10946:     * be already converted to an absolute URI.
10947:     */
10948:     res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
10949: 	node, (xmlChar **) (&schemaLocation), type);
10950:     if (res != 0)
10951: 	return(res);
10952:     /*
10953:     * Load and add the schema document.
10954:     */
10955:     res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
10956: 	NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
10957:     if (res != 0)
10958: 	return(res);
10959:     /*
10960:     * If we get no schema bucket back, then this means that the schema
10961:     * document could not be located or was broken XML or was not
10962:     * a schema document.
10963:     */
10964:     if ((bucket == NULL) || (bucket->doc == NULL)) {
10965: 	if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
10966: 	    /*
10967: 	    * WARNING for <include>:
10968: 	    * We will raise an error if the schema cannot be located
10969: 	    * for inclusions, since the that was the feedback from the
10970: 	    * schema people. I.e. the following spec piece will *not* be
10971: 	    * satisfied:
10972: 	    * SPEC src-include: "It is not an error for the �actual value� of the
10973: 	    * schemaLocation [attribute] to fail to resolve it all, in which
10974: 	    * case no corresponding inclusion is performed.
10975: 	    * So do we need a warning report here?"
10976: 	    */
10977: 	    res = XML_SCHEMAP_SRC_INCLUDE;
10978: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10979: 		node, NULL,
10980: 		"Failed to load the document '%s' for inclusion",
10981: 		schemaLocation, NULL);
10982: 	} else {
10983: 	    /*
10984: 	    * NOTE: This was changed to raise an error even if no redefinitions
10985: 	    * are specified.
10986: 	    *
10987: 	    * SPEC src-redefine (1)
10988: 	    * "If there are any element information items among the [children]
10989: 	    * other than <annotation> then the �actual value� of the
10990: 	    * schemaLocation [attribute] must successfully resolve."
10991: 	    * TODO: Ask the WG if a the location has always to resolve
10992: 	    * here as well!
10993: 	    */
10994: 	    res = XML_SCHEMAP_SRC_REDEFINE;
10995: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
10996: 		node, NULL,
10997: 		"Failed to load the document '%s' for redefinition",
10998: 		schemaLocation, NULL);
10999: 	}
11000:     } else {
11001: 	/*
11002: 	* Check targetNamespace sanity before parsing the new schema.
11003: 	* TODO: Note that we won't check further content if the
11004: 	* targetNamespace was bad.
11005: 	*/
11006: 	if (bucket->origTargetNamespace != NULL) {
11007: 	    /*
11008: 	    * SPEC src-include (2.1)
11009: 	    * "SII has a targetNamespace [attribute], and its �actual
11010: 	    * value� is identical to the �actual value� of the targetNamespace
11011: 	    * [attribute] of SII� (which must have such an [attribute])."
11012: 	    */
11013: 	    if (pctxt->targetNamespace == NULL) {
11014: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
11015: 		    XML_SCHEMAP_SRC_INCLUDE,
11016: 		    node, NULL,
11017: 		    "The target namespace of the included/redefined schema "
11018: 		    "'%s' has to be absent, since the including/redefining "
11019: 		    "schema has no target namespace",
11020: 		    schemaLocation, NULL);
11021: 		goto exit_error;
11022: 	    } else if (!xmlStrEqual(bucket->origTargetNamespace,
11023: 		pctxt->targetNamespace)) {
11024: 		/* TODO: Change error function. */
11025: 		xmlSchemaPCustomErrExt(pctxt,
11026: 		    XML_SCHEMAP_SRC_INCLUDE,
11027: 		    NULL, node,
11028: 		    "The target namespace '%s' of the included/redefined "
11029: 		    "schema '%s' differs from '%s' of the "
11030: 		    "including/redefining schema",
11031: 		    bucket->origTargetNamespace, schemaLocation,
11032: 		    pctxt->targetNamespace);
11033: 		goto exit_error;
11034: 	    }
11035: 	} else if (pctxt->targetNamespace != NULL) {
11036: 	    /*
11037: 	    * Chameleons: the original target namespace will
11038: 	    * differ from the resulting namespace.
11039: 	    */
11040: 	    isChameleon = 1;
11041: 	    if (bucket->parsed &&
11042: 		bucket->origTargetNamespace != NULL) {
11043: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
11044: 		    XML_SCHEMAP_SRC_INCLUDE,
11045: 		    node, NULL,
11046: 		    "The target namespace of the included/redefined schema "
11047: 		    "'%s' has to be absent or the same as the "
11048: 		    "including/redefining schema's target namespace",
11049: 		    schemaLocation, NULL);
11050: 		goto exit_error;
11051: 	    }
11052: 	    bucket->targetNamespace = pctxt->targetNamespace;
11053: 	}
11054:     }
11055:     /*
11056:     * Parse the schema.
11057:     */
11058:     if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
11059: 	if (isChameleon) {
11060: 	    /* TODO: Get rid of this flag on the schema itself. */
11061: 	    if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
11062: 		schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11063: 	    } else
11064: 		wasChameleon = 1;
11065: 	}
11066: 	xmlSchemaParseNewDoc(pctxt, schema, bucket);
11067: 	/* Restore chameleon flag. */
11068: 	if (isChameleon && (!wasChameleon))
11069: 	    schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
11070:     }
11071:     /*
11072:     * And now for the children...
11073:     */
11074:     child = node->children;
11075:     if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11076: 	/*
11077: 	* Parse (simpleType | complexType | group | attributeGroup))*
11078: 	*/
11079: 	pctxt->redefined = bucket;
11080: 	/*
11081: 	* How to proceed if the redefined schema was not located?
11082: 	*/
11083: 	pctxt->isRedefine = 1;
11084: 	while (IS_SCHEMA(child, "annotation") ||
11085: 	    IS_SCHEMA(child, "simpleType") ||
11086: 	    IS_SCHEMA(child, "complexType") ||
11087: 	    IS_SCHEMA(child, "group") ||
11088: 	    IS_SCHEMA(child, "attributeGroup")) {
11089: 	    if (IS_SCHEMA(child, "annotation")) {
11090: 		/*
11091: 		* TODO: discard or not?
11092: 		*/
11093: 	    } else if (IS_SCHEMA(child, "simpleType")) {
11094: 		xmlSchemaParseSimpleType(pctxt, schema, child, 1);
11095: 	    } else if (IS_SCHEMA(child, "complexType")) {
11096: 		xmlSchemaParseComplexType(pctxt, schema, child, 1);
11097: 		/* hasRedefinitions = 1; */
11098: 	    } else if (IS_SCHEMA(child, "group")) {
11099: 		/* hasRedefinitions = 1; */
11100: 		xmlSchemaParseModelGroupDefinition(pctxt,
11101: 		    schema, child);
11102: 	    } else if (IS_SCHEMA(child, "attributeGroup")) {
11103: 		/* hasRedefinitions = 1; */
11104: 		xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
11105: 		    child);
11106: 	    }
11107: 	    child = child->next;
11108: 	}
11109: 	pctxt->redefined = NULL;
11110: 	pctxt->isRedefine = 0;
11111:     } else {
11112: 	if (IS_SCHEMA(child, "annotation")) {
11113: 	    /*
11114: 	    * TODO: discard or not?
11115: 	    */
11116: 	    child = child->next;
11117: 	}
11118:     }
11119:     if (child != NULL) {
11120: 	res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
11121: 	if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
11122: 	    xmlSchemaPContentErr(pctxt, res,
11123: 		NULL, node, child, NULL,
11124: 		"(annotation | (simpleType | complexType | group | attributeGroup))*");
11125: 	} else {
11126: 	     xmlSchemaPContentErr(pctxt, res,
11127: 		NULL, node, child, NULL,
11128: 		"(annotation?)");
11129: 	}
11130:     }
11131:     return(res);
11132: 
11133: exit_error:
11134:     return(pctxt->err);
11135: }
11136: 
11137: static int
11138: xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11139:                        xmlNodePtr node)
11140: {
11141:     int res;
11142: #ifndef ENABLE_REDEFINE
11143:     TODO
11144:     return(0);
11145: #endif
11146:     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11147: 	XML_SCHEMA_SCHEMA_REDEFINE);
11148:     if (res != 0)
11149: 	return(res);
11150:     return(0);
11151: }
11152: 
11153: static int
11154: xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
11155:                        xmlNodePtr node)
11156: {
11157:     int res;
11158: 
11159:     res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
11160: 	XML_SCHEMA_SCHEMA_INCLUDE);
11161:     if (res != 0)
11162: 	return(res);
11163:     return(0);
11164: }
11165: 
11166: /**
11167:  * xmlSchemaParseModelGroup:
11168:  * @ctxt:  a schema validation context
11169:  * @schema:  the schema being built
11170:  * @node:  a subtree containing XML Schema informations
11171:  * @type: the "compositor" type
11172:  * @particleNeeded: if a a model group with a particle
11173:  *
11174:  * parse a XML schema Sequence definition.
11175:  * Applies parts of:
11176:  *   Schema Representation Constraint:
11177:  *     Redefinition Constraints and Semantics (src-redefine)
11178:  *     (6.1), (6.1.1), (6.1.2)
11179:  *
11180:  *   Schema Component Constraint:
11181:  *     All Group Limited (cos-all-limited) (2)
11182:  *     TODO: Actually this should go to component-level checks,
11183:  *     but is done here due to performance. Move it to an other layer
11184:  *     is schema construction via an API is implemented.
11185:  *
11186:  * *WARNING* this interface is highly subject to change
11187:  *
11188:  * Returns -1 in case of error, 0 if the declaration is improper and
11189:  *         1 in case of success.
11190:  */
11191: static xmlSchemaTreeItemPtr
11192: xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11193: 			 xmlNodePtr node, xmlSchemaTypeType type,
11194: 			 int withParticle)
11195: {
11196:     xmlSchemaModelGroupPtr item;
11197:     xmlSchemaParticlePtr particle = NULL;
11198:     xmlNodePtr child = NULL;
11199:     xmlAttrPtr attr;
11200:     int min = 1, max = 1, isElemRef, hasRefs = 0;
11201: 
11202:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11203:         return (NULL);
11204:     /*
11205:     * Create a model group with the given compositor.
11206:     */
11207:     item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
11208:     if (item == NULL)
11209: 	return (NULL);
11210: 
11211:     if (withParticle) {
11212: 	if (type == XML_SCHEMA_TYPE_ALL) {
11213: 	    min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
11214: 	    max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
11215: 	} else {
11216: 	    /* choice + sequence */
11217: 	    min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
11218: 	    max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
11219: 		"(xs:nonNegativeInteger | unbounded)");
11220: 	}
11221: 	xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
11222: 	/*
11223: 	* Create a particle
11224: 	*/
11225: 	particle = xmlSchemaAddParticle(ctxt, node, min, max);
11226: 	if (particle == NULL)
11227: 	    return (NULL);
11228: 	particle->children = (xmlSchemaTreeItemPtr) item;
11229: 	/*
11230: 	* Check for illegal attributes.
11231: 	*/
11232: 	attr = node->properties;
11233: 	while (attr != NULL) {
11234: 	    if (attr->ns == NULL) {
11235: 		if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11236: 		    (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
11237: 		    (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
11238: 		    xmlSchemaPIllegalAttrErr(ctxt,
11239: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11240: 		}
11241: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11242: 		xmlSchemaPIllegalAttrErr(ctxt,
11243: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11244: 	    }
11245: 	    attr = attr->next;
11246: 	}
11247:     } else {
11248: 	/*
11249: 	* Check for illegal attributes.
11250: 	*/
11251: 	attr = node->properties;
11252: 	while (attr != NULL) {
11253: 	    if (attr->ns == NULL) {
11254: 		if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
11255: 		    xmlSchemaPIllegalAttrErr(ctxt,
11256: 			XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11257: 		}
11258: 	    } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11259: 		xmlSchemaPIllegalAttrErr(ctxt,
11260: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11261: 	    }
11262: 	    attr = attr->next;
11263: 	}
11264:     }
11265: 
11266:     /*
11267:     * Extract and validate attributes.
11268:     */
11269:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11270:     /*
11271:     * And now for the children...
11272:     */
11273:     child = node->children;
11274:     if (IS_SCHEMA(child, "annotation")) {
11275:         item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
11276:         child = child->next;
11277:     }
11278:     if (type == XML_SCHEMA_TYPE_ALL) {
11279: 	xmlSchemaParticlePtr part, last = NULL;
11280: 
11281: 	while (IS_SCHEMA(child, "element")) {
11282: 	    part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
11283: 		schema, child, &isElemRef, 0);
11284: 	    /*
11285: 	    * SPEC cos-all-limited (2)
11286: 	    * "The {max occurs} of all the particles in the {particles}
11287: 	    * of the ('all') group must be 0 or 1.
11288: 	    */
11289: 	    if (part != NULL) {
11290: 		if (isElemRef)
11291: 		    hasRefs++;
11292: 		if (part->minOccurs > 1) {
11293: 		    xmlSchemaPCustomErr(ctxt,
11294: 			XML_SCHEMAP_COS_ALL_LIMITED,
11295: 			NULL, child,
11296: 			"Invalid value for minOccurs (must be 0 or 1)",
11297: 			NULL);
11298: 		    /* Reset to 1. */
11299: 		    part->minOccurs = 1;
11300: 		}
11301: 		if (part->maxOccurs > 1) {
11302: 		    xmlSchemaPCustomErr(ctxt,
11303: 			XML_SCHEMAP_COS_ALL_LIMITED,
11304: 			NULL, child,
11305: 			"Invalid value for maxOccurs (must be 0 or 1)",
11306: 			NULL);
11307: 		    /* Reset to 1. */
11308: 		    part->maxOccurs = 1;
11309: 		}
11310: 		if (last == NULL)
11311: 		    item->children = (xmlSchemaTreeItemPtr) part;
11312: 		else
11313: 		    last->next = (xmlSchemaTreeItemPtr) part;
11314: 		last = part;
11315: 	    }
11316: 	    child = child->next;
11317: 	}
11318: 	if (child != NULL) {
11319: 	    xmlSchemaPContentErr(ctxt,
11320: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11321: 		NULL, node, child, NULL,
11322: 		"(annotation?, (annotation?, element*)");
11323: 	}
11324:     } else {
11325: 	/* choice + sequence */
11326: 	xmlSchemaTreeItemPtr part = NULL, last = NULL;
11327: 
11328: 	while ((IS_SCHEMA(child, "element")) ||
11329: 	    (IS_SCHEMA(child, "group")) ||
11330: 	    (IS_SCHEMA(child, "any")) ||
11331: 	    (IS_SCHEMA(child, "choice")) ||
11332: 	    (IS_SCHEMA(child, "sequence"))) {
11333: 
11334: 	    if (IS_SCHEMA(child, "element")) {
11335: 		part = (xmlSchemaTreeItemPtr)
11336: 		    xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
11337: 		if (part && isElemRef)
11338: 		    hasRefs++;
11339: 	    } else if (IS_SCHEMA(child, "group")) {
11340: 		part =
11341: 		    xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11342: 		if (part != NULL)
11343: 		    hasRefs++;
11344: 		/*
11345: 		* Handle redefinitions.
11346: 		*/
11347: 		if (ctxt->isRedefine && ctxt->redef &&
11348: 		    (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
11349: 		    part && part->children)
11350: 		{
11351: 		    if ((xmlSchemaGetQNameRefName(part->children) ==
11352: 			    ctxt->redef->refName) &&
11353: 			(xmlSchemaGetQNameRefTargetNs(part->children) ==
11354: 			    ctxt->redef->refTargetNs))
11355: 		    {
11356: 			/*
11357: 			* SPEC src-redefine:
11358: 			* (6.1) "If it has a <group> among its contents at
11359: 			* some level the �actual value� of whose ref
11360: 			* [attribute] is the same as the �actual value� of
11361: 			* its own name attribute plus target namespace, then
11362: 			* all of the following must be true:"
11363: 			* (6.1.1) "It must have exactly one such group."
11364: 			*/
11365: 			if (ctxt->redefCounter != 0) {
11366: 			    xmlChar *str = NULL;
11367: 
11368: 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
11369: 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11370: 				"The redefining model group definition "
11371: 				"'%s' must not contain more than one "
11372: 				"reference to the redefined definition",
11373: 				xmlSchemaFormatQName(&str,
11374: 				    ctxt->redef->refTargetNs,
11375: 				    ctxt->redef->refName),
11376: 				NULL);
11377: 			    FREE_AND_NULL(str)
11378: 			    part = NULL;
11379: 			} else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
11380: 			    ((WXS_PARTICLE(part))->maxOccurs != 1))
11381: 			{
11382: 			    xmlChar *str = NULL;
11383: 			    /*
11384: 			    * SPEC src-redefine:
11385: 			    * (6.1.2) "The �actual value� of both that
11386: 			    * group's minOccurs and maxOccurs [attribute]
11387: 			    * must be 1 (or �absent�).
11388: 			    */
11389: 			    xmlSchemaCustomErr(ACTXT_CAST ctxt,
11390: 				XML_SCHEMAP_SRC_REDEFINE, child, NULL,
11391: 				"The redefining model group definition "
11392: 				"'%s' must not contain a reference to the "
11393: 				"redefined definition with a "
11394: 				"maxOccurs/minOccurs other than 1",
11395: 				xmlSchemaFormatQName(&str,
11396: 				    ctxt->redef->refTargetNs,
11397: 				    ctxt->redef->refName),
11398: 				NULL);
11399: 			    FREE_AND_NULL(str)
11400: 			    part = NULL;
11401: 			}
11402: 			ctxt->redef->reference = WXS_BASIC_CAST part;
11403: 			ctxt->redefCounter++;
11404: 		    }
11405: 		}
11406: 	    } else if (IS_SCHEMA(child, "any")) {
11407: 		part = (xmlSchemaTreeItemPtr)
11408: 		    xmlSchemaParseAny(ctxt, schema, child);
11409: 	    } else if (IS_SCHEMA(child, "choice")) {
11410: 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
11411: 		    XML_SCHEMA_TYPE_CHOICE, 1);
11412: 	    } else if (IS_SCHEMA(child, "sequence")) {
11413: 		part = xmlSchemaParseModelGroup(ctxt, schema, child,
11414: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
11415: 	    }
11416: 	    if (part != NULL) {
11417: 		if (last == NULL)
11418: 		    item->children = part;
11419: 		else
11420: 		    last->next = part;
11421: 		last = part;
11422: 	    }
11423: 	    child = child->next;
11424: 	}
11425: 	if (child != NULL) {
11426: 	    xmlSchemaPContentErr(ctxt,
11427: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11428: 		NULL, node, child, NULL,
11429: 		"(annotation?, (element | group | choice | sequence | any)*)");
11430: 	}
11431:     }
11432:     if ((max == 0) && (min == 0))
11433: 	return (NULL);
11434:     if (hasRefs) {
11435: 	/*
11436: 	* We need to resolve references.
11437: 	*/
11438: 	WXS_ADD_PENDING(ctxt, item);
11439:     }
11440:     if (withParticle)
11441: 	return ((xmlSchemaTreeItemPtr) particle);
11442:     else
11443: 	return ((xmlSchemaTreeItemPtr) item);
11444: }
11445: 
11446: /**
11447:  * xmlSchemaParseRestriction:
11448:  * @ctxt:  a schema validation context
11449:  * @schema:  the schema being built
11450:  * @node:  a subtree containing XML Schema informations
11451:  *
11452:  * parse a XML schema Restriction definition
11453:  * *WARNING* this interface is highly subject to change
11454:  *
11455:  * Returns the type definition or NULL in case of error
11456:  */
11457: static xmlSchemaTypePtr
11458: xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11459:                           xmlNodePtr node, xmlSchemaTypeType parentType)
11460: {
11461:     xmlSchemaTypePtr type;
11462:     xmlNodePtr child = NULL;
11463:     xmlAttrPtr attr;
11464: 
11465:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11466:         return (NULL);
11467:     /* Not a component, don't create it. */
11468:     type = ctxt->ctxtType;
11469:     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
11470: 
11471:     /*
11472:     * Check for illegal attributes.
11473:     */
11474:     attr = node->properties;
11475:     while (attr != NULL) {
11476: 	if (attr->ns == NULL) {
11477: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11478: 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11479: 		xmlSchemaPIllegalAttrErr(ctxt,
11480: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11481: 	    }
11482: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11483: 	    xmlSchemaPIllegalAttrErr(ctxt,
11484: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11485: 	}
11486: 	attr = attr->next;
11487:     }
11488:     /*
11489:     * Extract and validate attributes.
11490:     */
11491:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11492:     /*
11493:     * Attribute
11494:     */
11495:     /*
11496:     * Extract the base type. The "base" attribute is mandatory if inside
11497:     * a complex type or if redefining.
11498:     *
11499:     * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
11500:     * among its [children]), the simple type definition which is
11501:     * the {content type} of the type definition �resolved� to by
11502:     * the �actual value� of the base [attribute]"
11503:     */
11504:     if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
11505: 	&(type->baseNs), &(type->base)) == 0)
11506:     {
11507: 	if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
11508: 	    xmlSchemaPMissingAttrErr(ctxt,
11509: 		XML_SCHEMAP_S4S_ATTR_MISSING,
11510: 		NULL, node, "base", NULL);
11511: 	} else if ((ctxt->isRedefine) &&
11512: 	    (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
11513: 	{
11514: 	    if (type->base == NULL) {
11515: 		xmlSchemaPMissingAttrErr(ctxt,
11516: 		    XML_SCHEMAP_S4S_ATTR_MISSING,
11517: 		    NULL, node, "base", NULL);
11518: 	    } else if ((! xmlStrEqual(type->base, type->name)) ||
11519: 		(! xmlStrEqual(type->baseNs, type->targetNamespace)))
11520: 	    {
11521: 		xmlChar *str1 = NULL, *str2 = NULL;
11522: 		/*
11523: 		* REDEFINE: SPEC src-redefine (5)
11524: 		* "Within the [children], each <simpleType> must have a
11525: 		* <restriction> among its [children] ... the �actual value� of
11526: 		* whose base [attribute] must be the same as the �actual value�
11527: 		* of its own name attribute plus target namespace;"
11528: 		*/
11529: 		xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
11530: 		    NULL, node, "This is a redefinition, but the QName "
11531: 		    "value '%s' of the 'base' attribute does not match the "
11532: 		    "type's designation '%s'",
11533: 		    xmlSchemaFormatQName(&str1, type->baseNs, type->base),
11534: 		    xmlSchemaFormatQName(&str2, type->targetNamespace,
11535: 			type->name), NULL);
11536: 		FREE_AND_NULL(str1);
11537: 		FREE_AND_NULL(str2);
11538: 		/* Avoid confusion and erase the values. */
11539: 		type->base = NULL;
11540: 		type->baseNs = NULL;
11541: 	    }
11542: 	}
11543:     }
11544:     /*
11545:     * And now for the children...
11546:     */
11547:     child = node->children;
11548:     if (IS_SCHEMA(child, "annotation")) {
11549: 	/*
11550: 	* Add the annotation to the simple type ancestor.
11551: 	*/
11552: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11553: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11554:         child = child->next;
11555:     }
11556:     if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
11557: 	/*
11558: 	* Corresponds to <simpleType><restriction><simpleType>.
11559: 	*/
11560: 	if (IS_SCHEMA(child, "simpleType")) {
11561: 	    if (type->base != NULL) {
11562: 		/*
11563: 		* src-restriction-base-or-simpleType
11564: 		* Either the base [attribute] or the simpleType [child] of the
11565: 		* <restriction> element must be present, but not both.
11566: 		*/
11567: 		xmlSchemaPContentErr(ctxt,
11568: 		    XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11569: 		    NULL, node, child,
11570: 		    "The attribute 'base' and the <simpleType> child are "
11571: 		    "mutually exclusive", NULL);
11572: 	    } else {
11573: 		type->baseType = (xmlSchemaTypePtr)
11574: 		    xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11575: 	    }
11576: 	    child = child->next;
11577: 	} else if (type->base == NULL) {
11578: 	    xmlSchemaPContentErr(ctxt,
11579: 		XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
11580: 		NULL, node, child,
11581: 		"Either the attribute 'base' or a <simpleType> child "
11582: 		"must be present", NULL);
11583: 	}
11584:     } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11585: 	/*
11586: 	* Corresponds to <complexType><complexContent><restriction>...
11587: 	* followed by:
11588: 	*
11589: 	* Model groups <all>, <choice> and <sequence>.
11590: 	*/
11591: 	if (IS_SCHEMA(child, "all")) {
11592: 	    type->subtypes = (xmlSchemaTypePtr)
11593: 		xmlSchemaParseModelGroup(ctxt, schema, child,
11594: 		    XML_SCHEMA_TYPE_ALL, 1);
11595: 	    child = child->next;
11596: 	} else if (IS_SCHEMA(child, "choice")) {
11597: 	    type->subtypes = (xmlSchemaTypePtr)
11598: 		xmlSchemaParseModelGroup(ctxt,
11599: 		    schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
11600: 	    child = child->next;
11601: 	} else if (IS_SCHEMA(child, "sequence")) {
11602: 	    type->subtypes = (xmlSchemaTypePtr)
11603: 		xmlSchemaParseModelGroup(ctxt, schema, child,
11604: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
11605: 	    child = child->next;
11606: 	/*
11607: 	* Model group reference <group>.
11608: 	*/
11609: 	} else if (IS_SCHEMA(child, "group")) {
11610: 	    type->subtypes = (xmlSchemaTypePtr)
11611: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11612: 	    /*
11613: 	    * Note that the reference will be resolved in
11614: 	    * xmlSchemaResolveTypeReferences();
11615: 	    */
11616: 	    child = child->next;
11617: 	}
11618:     } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11619: 	/*
11620: 	* Corresponds to <complexType><simpleContent><restriction>...
11621: 	*
11622: 	* "1.1 the simple type definition corresponding to the <simpleType>
11623: 	* among the [children] of <restriction> if there is one;"
11624: 	*/
11625: 	if (IS_SCHEMA(child, "simpleType")) {
11626: 	    /*
11627: 	    * We will store the to-be-restricted simple type in
11628: 	    * type->contentTypeDef *temporarily*.
11629: 	    */
11630: 	    type->contentTypeDef = (xmlSchemaTypePtr)
11631: 		xmlSchemaParseSimpleType(ctxt, schema, child, 0);
11632: 	    if ( type->contentTypeDef == NULL)
11633: 		return (NULL);
11634: 	    child = child->next;
11635: 	}
11636:     }
11637: 
11638:     if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
11639: 	(parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
11640: 	xmlSchemaFacetPtr facet, lastfacet = NULL;
11641: 	/*
11642: 	* Corresponds to <complexType><simpleContent><restriction>...
11643: 	* <simpleType><restriction>...
11644: 	*/
11645: 
11646: 	/*
11647: 	* Add the facets to the simple type ancestor.
11648: 	*/
11649: 	/*
11650: 	* TODO: Datatypes: 4.1.3 Constraints on XML Representation of
11651: 	* Simple Type Definition Schema Representation Constraint:
11652: 	* *Single Facet Value*
11653: 	*/
11654: 	while ((IS_SCHEMA(child, "minInclusive")) ||
11655: 	    (IS_SCHEMA(child, "minExclusive")) ||
11656: 	    (IS_SCHEMA(child, "maxInclusive")) ||
11657: 	    (IS_SCHEMA(child, "maxExclusive")) ||
11658: 	    (IS_SCHEMA(child, "totalDigits")) ||
11659: 	    (IS_SCHEMA(child, "fractionDigits")) ||
11660: 	    (IS_SCHEMA(child, "pattern")) ||
11661: 	    (IS_SCHEMA(child, "enumeration")) ||
11662: 	    (IS_SCHEMA(child, "whiteSpace")) ||
11663: 	    (IS_SCHEMA(child, "length")) ||
11664: 	    (IS_SCHEMA(child, "maxLength")) ||
11665: 	    (IS_SCHEMA(child, "minLength"))) {
11666: 	    facet = xmlSchemaParseFacet(ctxt, schema, child);
11667: 	    if (facet != NULL) {
11668: 		if (lastfacet == NULL)
11669: 		    type->facets = facet;
11670: 		else
11671: 		    lastfacet->next = facet;
11672: 		lastfacet = facet;
11673: 		lastfacet->next = NULL;
11674: 	    }
11675: 	    child = child->next;
11676: 	}
11677: 	/*
11678: 	* Create links for derivation and validation.
11679: 	*/
11680: 	if (type->facets != NULL) {
11681: 	    xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
11682: 
11683: 	    facet = type->facets;
11684: 	    do {
11685: 		facetLink = (xmlSchemaFacetLinkPtr)
11686: 		    xmlMalloc(sizeof(xmlSchemaFacetLink));
11687: 		if (facetLink == NULL) {
11688: 		    xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
11689: 		    xmlFree(facetLink);
11690: 		    return (NULL);
11691: 		}
11692: 		facetLink->facet = facet;
11693: 		facetLink->next = NULL;
11694: 		if (lastFacetLink == NULL)
11695: 		    type->facetSet = facetLink;
11696: 		else
11697: 		    lastFacetLink->next = facetLink;
11698: 		lastFacetLink = facetLink;
11699: 		facet = facet->next;
11700: 	    } while (facet != NULL);
11701: 	}
11702:     }
11703:     if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
11704: 	/*
11705: 	* Attribute uses/declarations.
11706: 	*/
11707: 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11708: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
11709: 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
11710: 	    return(NULL);
11711: 	/*
11712: 	* Attribute wildcard.
11713: 	*/
11714: 	if (IS_SCHEMA(child, "anyAttribute")) {
11715: 	    type->attributeWildcard =
11716: 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
11717: 	    child = child->next;
11718: 	}
11719:     }
11720:     if (child != NULL) {
11721: 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11722: 	    xmlSchemaPContentErr(ctxt,
11723: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11724: 		NULL, node, child, NULL,
11725: 		"annotation?, (group | all | choice | sequence)?, "
11726: 		"((attribute | attributeGroup)*, anyAttribute?))");
11727: 	} else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
11728: 	     xmlSchemaPContentErr(ctxt,
11729: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11730: 		NULL, node, child, NULL,
11731: 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11732: 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11733: 		"length | minLength | maxLength | enumeration | whiteSpace | "
11734: 		"pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
11735: 	} else {
11736: 	    /* Simple type */
11737: 	    xmlSchemaPContentErr(ctxt,
11738: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11739: 		NULL, node, child, NULL,
11740: 		"(annotation?, (simpleType?, (minExclusive | minInclusive | "
11741: 		"maxExclusive | maxInclusive | totalDigits | fractionDigits | "
11742: 		"length | minLength | maxLength | enumeration | whiteSpace | "
11743: 		"pattern)*))");
11744: 	}
11745:     }
11746:     return (NULL);
11747: }
11748: 
11749: /**
11750:  * xmlSchemaParseExtension:
11751:  * @ctxt:  a schema validation context
11752:  * @schema:  the schema being built
11753:  * @node:  a subtree containing XML Schema informations
11754:  *
11755:  * Parses an <extension>, which is found inside a
11756:  * <simpleContent> or <complexContent>.
11757:  * *WARNING* this interface is highly subject to change.
11758:  *
11759:  * TODO: Returns the type definition or NULL in case of error
11760:  */
11761: static xmlSchemaTypePtr
11762: xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
11763:                         xmlNodePtr node, xmlSchemaTypeType parentType)
11764: {
11765:     xmlSchemaTypePtr type;
11766:     xmlNodePtr child = NULL;
11767:     xmlAttrPtr attr;
11768: 
11769:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
11770:         return (NULL);
11771:     /* Not a component, don't create it. */
11772:     type = ctxt->ctxtType;
11773:     type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
11774: 
11775:     /*
11776:     * Check for illegal attributes.
11777:     */
11778:     attr = node->properties;
11779:     while (attr != NULL) {
11780: 	if (attr->ns == NULL) {
11781: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
11782: 		(!xmlStrEqual(attr->name, BAD_CAST "base"))) {
11783: 		xmlSchemaPIllegalAttrErr(ctxt,
11784: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11785: 	    }
11786: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11787: 	    xmlSchemaPIllegalAttrErr(ctxt,
11788: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11789: 	}
11790: 	attr = attr->next;
11791:     }
11792: 
11793:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11794: 
11795:     /*
11796:     * Attribute "base" - mandatory.
11797:     */
11798:     if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
11799: 	"base", &(type->baseNs), &(type->base)) == 0) &&
11800: 	(type->base == NULL)) {
11801: 	xmlSchemaPMissingAttrErr(ctxt,
11802: 	    XML_SCHEMAP_S4S_ATTR_MISSING,
11803: 	    NULL, node, "base", NULL);
11804:     }
11805:     /*
11806:     * And now for the children...
11807:     */
11808:     child = node->children;
11809:     if (IS_SCHEMA(child, "annotation")) {
11810: 	/*
11811: 	* Add the annotation to the type ancestor.
11812: 	*/
11813: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11814: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11815:         child = child->next;
11816:     }
11817:     if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11818: 	/*
11819: 	* Corresponds to <complexType><complexContent><extension>... and:
11820: 	*
11821: 	* Model groups <all>, <choice>, <sequence> and <group>.
11822: 	*/
11823: 	if (IS_SCHEMA(child, "all")) {
11824: 	    type->subtypes = (xmlSchemaTypePtr)
11825: 		xmlSchemaParseModelGroup(ctxt, schema,
11826: 		    child, XML_SCHEMA_TYPE_ALL, 1);
11827: 	    child = child->next;
11828: 	} else if (IS_SCHEMA(child, "choice")) {
11829: 	    type->subtypes = (xmlSchemaTypePtr)
11830: 		xmlSchemaParseModelGroup(ctxt, schema,
11831: 		    child, XML_SCHEMA_TYPE_CHOICE, 1);
11832: 	    child = child->next;
11833: 	} else if (IS_SCHEMA(child, "sequence")) {
11834: 	    type->subtypes = (xmlSchemaTypePtr)
11835: 		xmlSchemaParseModelGroup(ctxt, schema,
11836: 		child, XML_SCHEMA_TYPE_SEQUENCE, 1);
11837: 	    child = child->next;
11838: 	} else if (IS_SCHEMA(child, "group")) {
11839: 	    type->subtypes = (xmlSchemaTypePtr)
11840: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
11841: 	    /*
11842: 	    * Note that the reference will be resolved in
11843: 	    * xmlSchemaResolveTypeReferences();
11844: 	    */
11845: 	    child = child->next;
11846: 	}
11847:     }
11848:     if (child != NULL) {
11849: 	/*
11850: 	* Attribute uses/declarations.
11851: 	*/
11852: 	if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
11853: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
11854: 	    XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
11855: 	    return(NULL);
11856: 	/*
11857: 	* Attribute wildcard.
11858: 	*/
11859: 	if (IS_SCHEMA(child, "anyAttribute")) {
11860: 	    ctxt->ctxtType->attributeWildcard =
11861: 		xmlSchemaParseAnyAttribute(ctxt, schema, child);
11862: 	    child = child->next;
11863: 	}
11864:     }
11865:     if (child != NULL) {
11866: 	if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
11867: 	    /* Complex content extension. */
11868: 	    xmlSchemaPContentErr(ctxt,
11869: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11870: 		NULL, node, child, NULL,
11871: 		"(annotation?, ((group | all | choice | sequence)?, "
11872: 		"((attribute | attributeGroup)*, anyAttribute?)))");
11873: 	} else {
11874: 	    /* Simple content extension. */
11875: 	    xmlSchemaPContentErr(ctxt,
11876: 		XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11877: 		NULL, node, child, NULL,
11878: 		"(annotation?, ((attribute | attributeGroup)*, "
11879: 		"anyAttribute?))");
11880: 	}
11881:     }
11882:     return (NULL);
11883: }
11884: 
11885: /**
11886:  * xmlSchemaParseSimpleContent:
11887:  * @ctxt:  a schema validation context
11888:  * @schema:  the schema being built
11889:  * @node:  a subtree containing XML Schema informations
11890:  *
11891:  * parse a XML schema SimpleContent definition
11892:  * *WARNING* this interface is highly subject to change
11893:  *
11894:  * Returns the type definition or NULL in case of error
11895:  */
11896: static int
11897: xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
11898:                             xmlSchemaPtr schema, xmlNodePtr node,
11899: 			    int *hasRestrictionOrExtension)
11900: {
11901:     xmlSchemaTypePtr type;
11902:     xmlNodePtr child = NULL;
11903:     xmlAttrPtr attr;
11904: 
11905:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11906: 	(hasRestrictionOrExtension == NULL))
11907:         return (-1);
11908:     *hasRestrictionOrExtension = 0;
11909:     /* Not a component, don't create it. */
11910:     type = ctxt->ctxtType;
11911:     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
11912:     /*
11913:     * Check for illegal attributes.
11914:     */
11915:     attr = node->properties;
11916:     while (attr != NULL) {
11917: 	if (attr->ns == NULL) {
11918: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
11919: 		xmlSchemaPIllegalAttrErr(ctxt,
11920: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11921: 	    }
11922: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
11923: 	    xmlSchemaPIllegalAttrErr(ctxt,
11924: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
11925: 	}
11926: 	attr = attr->next;
11927:     }
11928: 
11929:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
11930: 
11931:     /*
11932:     * And now for the children...
11933:     */
11934:     child = node->children;
11935:     if (IS_SCHEMA(child, "annotation")) {
11936: 	/*
11937: 	* Add the annotation to the complex type ancestor.
11938: 	*/
11939: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
11940: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
11941:         child = child->next;
11942:     }
11943:     if (child == NULL) {
11944: 	xmlSchemaPContentErr(ctxt,
11945: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
11946: 	    NULL, node, NULL, NULL,
11947: 	    "(annotation?, (restriction | extension))");
11948:     }
11949:     if (child == NULL) {
11950: 	xmlSchemaPContentErr(ctxt,
11951: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
11952: 	    NULL, node, NULL, NULL,
11953: 	    "(annotation?, (restriction | extension))");
11954:     }
11955:     if (IS_SCHEMA(child, "restriction")) {
11956:         xmlSchemaParseRestriction(ctxt, schema, child,
11957: 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11958: 	(*hasRestrictionOrExtension) = 1;
11959:         child = child->next;
11960:     } else if (IS_SCHEMA(child, "extension")) {
11961:         xmlSchemaParseExtension(ctxt, schema, child,
11962: 	    XML_SCHEMA_TYPE_SIMPLE_CONTENT);
11963: 	(*hasRestrictionOrExtension) = 1;
11964:         child = child->next;
11965:     }
11966:     if (child != NULL) {
11967: 	xmlSchemaPContentErr(ctxt,
11968: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
11969: 	    NULL, node, child, NULL,
11970: 	    "(annotation?, (restriction | extension))");
11971:     }
11972:     return (0);
11973: }
11974: 
11975: /**
11976:  * xmlSchemaParseComplexContent:
11977:  * @ctxt:  a schema validation context
11978:  * @schema:  the schema being built
11979:  * @node:  a subtree containing XML Schema informations
11980:  *
11981:  * parse a XML schema ComplexContent definition
11982:  * *WARNING* this interface is highly subject to change
11983:  *
11984:  * Returns the type definition or NULL in case of error
11985:  */
11986: static int
11987: xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
11988:                              xmlSchemaPtr schema, xmlNodePtr node,
11989: 			     int *hasRestrictionOrExtension)
11990: {
11991:     xmlSchemaTypePtr type;
11992:     xmlNodePtr child = NULL;
11993:     xmlAttrPtr attr;
11994: 
11995:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
11996: 	(hasRestrictionOrExtension == NULL))
11997:         return (-1);
11998:     *hasRestrictionOrExtension = 0;
11999:     /* Not a component, don't create it. */
12000:     type = ctxt->ctxtType;
12001:     /*
12002:     * Check for illegal attributes.
12003:     */
12004:     attr = node->properties;
12005:     while (attr != NULL) {
12006: 	if (attr->ns == NULL) {
12007: 	    if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
12008: 		(!xmlStrEqual(attr->name, BAD_CAST "mixed")))
12009: 	    {
12010: 		xmlSchemaPIllegalAttrErr(ctxt,
12011: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12012: 	    }
12013: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12014: 	    xmlSchemaPIllegalAttrErr(ctxt,
12015: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12016: 	}
12017: 	attr = attr->next;
12018:     }
12019: 
12020:     xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12021: 
12022:     /*
12023:     * Set the 'mixed' on the complex type ancestor.
12024:     */
12025:     if (xmlGetBooleanProp(ctxt, node, "mixed", 0))  {
12026: 	if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
12027: 	    type->flags |= XML_SCHEMAS_TYPE_MIXED;
12028:     }
12029:     child = node->children;
12030:     if (IS_SCHEMA(child, "annotation")) {
12031: 	/*
12032: 	* Add the annotation to the complex type ancestor.
12033: 	*/
12034: 	xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
12035: 	    xmlSchemaParseAnnotation(ctxt, child, 1));
12036:         child = child->next;
12037:     }
12038:     if (child == NULL) {
12039: 	xmlSchemaPContentErr(ctxt,
12040: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
12041: 	    NULL, node, NULL,
12042: 	    NULL, "(annotation?, (restriction | extension))");
12043:     }
12044:     if (child == NULL) {
12045: 	xmlSchemaPContentErr(ctxt,
12046: 	    XML_SCHEMAP_S4S_ELEM_MISSING,
12047: 	    NULL, node, NULL,
12048: 	    NULL, "(annotation?, (restriction | extension))");
12049:     }
12050:     if (IS_SCHEMA(child, "restriction")) {
12051:         xmlSchemaParseRestriction(ctxt, schema, child,
12052: 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12053: 	(*hasRestrictionOrExtension) = 1;
12054:         child = child->next;
12055:     } else if (IS_SCHEMA(child, "extension")) {
12056:         xmlSchemaParseExtension(ctxt, schema, child,
12057: 	    XML_SCHEMA_TYPE_COMPLEX_CONTENT);
12058: 	(*hasRestrictionOrExtension) = 1;
12059:         child = child->next;
12060:     }
12061:     if (child != NULL) {
12062: 	xmlSchemaPContentErr(ctxt,
12063: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12064: 	    NULL, node, child,
12065: 	    NULL, "(annotation?, (restriction | extension))");
12066:     }
12067:     return (0);
12068: }
12069: 
12070: /**
12071:  * xmlSchemaParseComplexType:
12072:  * @ctxt:  a schema validation context
12073:  * @schema:  the schema being built
12074:  * @node:  a subtree containing XML Schema informations
12075:  *
12076:  * parse a XML schema Complex Type definition
12077:  * *WARNING* this interface is highly subject to change
12078:  *
12079:  * Returns the type definition or NULL in case of error
12080:  */
12081: static xmlSchemaTypePtr
12082: xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
12083:                           xmlNodePtr node, int topLevel)
12084: {
12085:     xmlSchemaTypePtr type, ctxtType;
12086:     xmlNodePtr child = NULL;
12087:     const xmlChar *name = NULL;
12088:     xmlAttrPtr attr;
12089:     const xmlChar *attrValue;
12090: #ifdef ENABLE_NAMED_LOCALS
12091:     char buf[40];
12092: #endif
12093:     int final = 0, block = 0, hasRestrictionOrExtension = 0;
12094: 
12095: 
12096:     if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
12097:         return (NULL);
12098: 
12099:     ctxtType = ctxt->ctxtType;
12100: 
12101:     if (topLevel) {
12102: 	attr = xmlSchemaGetPropNode(node, "name");
12103: 	if (attr == NULL) {
12104: 	    xmlSchemaPMissingAttrErr(ctxt,
12105: 		XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
12106: 	    return (NULL);
12107: 	} else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
12108: 	    xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
12109: 	    return (NULL);
12110: 	}
12111:     }
12112: 
12113:     if (topLevel == 0) {
12114: 	/*
12115: 	* Parse as local complex type definition.
12116: 	*/
12117: #ifdef ENABLE_NAMED_LOCALS
12118:         snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
12119: 	type = xmlSchemaAddType(ctxt, schema,
12120: 	    XML_SCHEMA_TYPE_COMPLEX,
12121: 	    xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
12122: 	    ctxt->targetNamespace, node, 0);
12123: #else
12124: 	type = xmlSchemaAddType(ctxt, schema,
12125: 	    XML_SCHEMA_TYPE_COMPLEX,
12126: 	    NULL, ctxt->targetNamespace, node, 0);
12127: #endif
12128: 	if (type == NULL)
12129: 	    return (NULL);
12130: 	name = type->name;
12131: 	type->node = node;
12132: 	type->type = XML_SCHEMA_TYPE_COMPLEX;
12133: 	/*
12134: 	* TODO: We need the target namespace.
12135: 	*/
12136:     } else {
12137: 	/*
12138: 	* Parse as global complex type definition.
12139: 	*/
12140: 	type = xmlSchemaAddType(ctxt, schema,
12141: 	    XML_SCHEMA_TYPE_COMPLEX,
12142: 	    name, ctxt->targetNamespace, node, 1);
12143: 	if (type == NULL)
12144: 	    return (NULL);
12145: 	type->node = node;
12146: 	type->type = XML_SCHEMA_TYPE_COMPLEX;
12147: 	type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
12148:     }
12149:     type->targetNamespace = ctxt->targetNamespace;
12150:     /*
12151:     * Handle attributes.
12152:     */
12153:     attr = node->properties;
12154:     while (attr != NULL) {
12155: 	if (attr->ns == NULL) {
12156: 	    if (xmlStrEqual(attr->name, BAD_CAST "id")) {
12157: 		/*
12158: 		* Attribute "id".
12159: 		*/
12160: 		xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
12161: 	    } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
12162: 		/*
12163: 		* Attribute "mixed".
12164: 		*/
12165: 		if (xmlSchemaPGetBoolNodeValue(ctxt,
12166: 			NULL, (xmlNodePtr) attr))
12167: 		    type->flags |= XML_SCHEMAS_TYPE_MIXED;
12168: 	    } else if (topLevel) {
12169: 		/*
12170: 		* Attributes of global complex type definitions.
12171: 		*/
12172: 		if (xmlStrEqual(attr->name, BAD_CAST "name")) {
12173: 		    /* Pass. */
12174: 		} else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
12175: 		    /*
12176: 		    * Attribute "abstract".
12177: 		    */
12178: 		    if (xmlSchemaPGetBoolNodeValue(ctxt,
12179: 			    NULL, (xmlNodePtr) attr))
12180: 			type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
12181: 		} else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
12182: 		    /*
12183: 		    * Attribute "final".
12184: 		    */
12185: 		    attrValue = xmlSchemaGetNodeContent(ctxt,
12186: 			(xmlNodePtr) attr);
12187: 		    if (xmlSchemaPValAttrBlockFinal(attrValue,
12188: 			&(type->flags),
12189: 			-1,
12190: 			XML_SCHEMAS_TYPE_FINAL_EXTENSION,
12191: 			XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
12192: 			-1, -1, -1) != 0)
12193: 		    {
12194: 			xmlSchemaPSimpleTypeErr(ctxt,
12195: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12196: 			    NULL, (xmlNodePtr) attr, NULL,
12197: 			    "(#all | List of (extension | restriction))",
12198: 			    attrValue, NULL, NULL, NULL);
12199: 		    } else
12200: 			final = 1;
12201: 		} else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
12202: 		    /*
12203: 		    * Attribute "block".
12204: 		    */
12205: 		    attrValue = xmlSchemaGetNodeContent(ctxt,
12206: 			(xmlNodePtr) attr);
12207: 		    if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
12208: 			-1,
12209: 			XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
12210: 			XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
12211: 			-1, -1, -1) != 0) {
12212: 			xmlSchemaPSimpleTypeErr(ctxt,
12213: 			    XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
12214: 			    NULL, (xmlNodePtr) attr, NULL,
12215: 			    "(#all | List of (extension | restriction)) ",
12216: 			    attrValue, NULL, NULL, NULL);
12217: 		    } else
12218: 			block = 1;
12219: 		} else {
12220: 			xmlSchemaPIllegalAttrErr(ctxt,
12221: 			    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12222: 		}
12223: 	    } else {
12224: 		xmlSchemaPIllegalAttrErr(ctxt,
12225: 		    XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12226: 	    }
12227: 	} else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
12228: 	    xmlSchemaPIllegalAttrErr(ctxt,
12229: 		XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
12230: 	}
12231: 	attr = attr->next;
12232:     }
12233:     if (! block) {
12234: 	/*
12235: 	* Apply default "block" values.
12236: 	*/
12237: 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
12238: 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
12239: 	if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
12240: 	    type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
12241:     }
12242:     if (! final) {
12243: 	/*
12244: 	* Apply default "block" values.
12245: 	*/
12246: 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
12247: 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
12248: 	if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
12249: 	    type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
12250:     }
12251:     /*
12252:     * And now for the children...
12253:     */
12254:     child = node->children;
12255:     if (IS_SCHEMA(child, "annotation")) {
12256:         type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
12257:         child = child->next;
12258:     }
12259:     ctxt->ctxtType = type;
12260:     if (IS_SCHEMA(child, "simpleContent")) {
12261: 	/*
12262: 	* <complexType><simpleContent>...
12263: 	* 3.4.3 : 2.2
12264: 	* Specifying mixed='true' when the <simpleContent>
12265: 	* alternative is chosen has no effect
12266: 	*/
12267: 	if (type->flags & XML_SCHEMAS_TYPE_MIXED)
12268: 	    type->flags ^= XML_SCHEMAS_TYPE_MIXED;
12269:         xmlSchemaParseSimpleContent(ctxt, schema, child,
12270: 	    &hasRestrictionOrExtension);
12271:         child = child->next;
12272:     } else if (IS_SCHEMA(child, "complexContent")) {
12273: 	/*
12274: 	* <complexType><complexContent>...
12275: 	*/
12276: 	type->contentType = XML_SCHEMA_CONTENT_EMPTY;
12277:         xmlSchemaParseComplexContent(ctxt, schema, child,
12278: 	    &hasRestrictionOrExtension);
12279:         child = child->next;
12280:     } else {
12281: 	/*
12282: 	* E.g <complexType><sequence>... or <complexType><attribute>... etc.
12283: 	*
12284: 	* SPEC
12285: 	* "...the third alternative (neither <simpleContent> nor
12286: 	* <complexContent>) is chosen. This case is understood as shorthand
12287: 	* for complex content restricting the �ur-type definition�, and the
12288: 	* details of the mappings should be modified as necessary.
12289: 	*/
12290: 	type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
12291: 	type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
12292: 	/*
12293: 	* Parse model groups.
12294: 	*/
12295:         if (IS_SCHEMA(child, "all")) {
12296:             type->subtypes = (xmlSchemaTypePtr)
12297: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12298: 		    XML_SCHEMA_TYPE_ALL, 1);
12299:             child = child->next;
12300:         } else if (IS_SCHEMA(child, "choice")) {
12301:             type->subtypes = (xmlSchemaTypePtr)
12302: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12303: 		    XML_SCHEMA_TYPE_CHOICE, 1);
12304:             child = child->next;
12305:         } else if (IS_SCHEMA(child, "sequence")) {
12306:             type->subtypes = (xmlSchemaTypePtr)
12307: 		xmlSchemaParseModelGroup(ctxt, schema, child,
12308: 		    XML_SCHEMA_TYPE_SEQUENCE, 1);
12309:             child = child->next;
12310:         } else if (IS_SCHEMA(child, "group")) {
12311:             type->subtypes = (xmlSchemaTypePtr)
12312: 		xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
12313: 	    /*
12314: 	    * Note that the reference will be resolved in
12315: 	    * xmlSchemaResolveTypeReferences();
12316: 	    */
12317:             child = child->next;
12318:         }
12319: 	/*
12320: 	* Parse attribute decls/refs.
12321: 	*/
12322:         if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
12323: 	    (xmlSchemaItemListPtr *) &(type->attrUses),
12324: 	    XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
12325: 	    return(NULL);
12326: 	/*
12327: 	* Parse attribute wildcard.
12328: 	*/
12329: 	if (IS_SCHEMA(child, "anyAttribute")) {
12330: 	    type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
12331: 	    child = child->next;
12332: 	}
12333:     }
12334:     if (child != NULL) {
12335: 	xmlSchemaPContentErr(ctxt,
12336: 	    XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
12337: 	    NULL, node, child,
12338: 	    NULL, "(annotation?, (simpleContent | complexContent | "
12339: 	    "((group | all | choice | sequence)?, ((attribute | "
12340: 	    "attributeGroup)*, anyAttribute?))))");
12341:     }
12342:     /*
12343:     * REDEFINE: SPEC src-redefine (5)
12344:     */
12345:     if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
12346: 	xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
12347: 	    NULL, node, "This is a redefinition, thus the "
12348: 	    "<complexType> must have a <restriction> or <extension> "
12349: 	    "grand-child", NULL);
12350:     }
12351:     ctxt->ctxtType = ctxtType;
12352:     return (type);
12353: }
12354: 
12355: /************************************************************************
12356:  * 									*
12357:  * 			Validating using Schemas			*
12358:  * 									*
12359:  ************************************************************************/
12360: 
12361: /************************************************************************
12362:  * 									*
12363:  * 			Reading/Writing Schemas				*
12364:  * 									*
12365:  ************************************************************************/
12366: 
12367: #if 0 /* Will be enabled if it is clear what options are needed. */
12368: /**
12369:  * xmlSchemaParserCtxtSetOptions:
12370:  * @ctxt:	a schema parser context
12371:  * @options: a combination of xmlSchemaParserOption
12372:  *
12373:  * Sets the options to be used during the parse.
12374:  *
12375:  * Returns 0 in case of success, -1 in case of an
12376:  * API error.
12377:  */
12378: static int
12379: xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
12380: 			      int options)
12381: 
12382: {
12383:     int i;
12384: 
12385:     if (ctxt == NULL)
12386: 	return (-1);
12387:     /*
12388:     * WARNING: Change the start value if adding to the
12389:     * xmlSchemaParseOption.
12390:     */
12391:     for (i = 1; i < (int) sizeof(int) * 8; i++) {
12392:         if (options & 1<<i) {
12393: 	    return (-1);
12394:         }
12395:     }
12396:     ctxt->options = options;
12397:     return (0);
12398: }
12399: 
12400: /**
12401:  * xmlSchemaValidCtxtGetOptions:
12402:  * @ctxt: a schema parser context
12403:  *
12404:  * Returns the option combination of the parser context.
12405:  */
12406: static int
12407: xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
12408: 
12409: {
12410:     if (ctxt == NULL)
12411: 	return (-1);
12412:     else
12413: 	return (ctxt->options);
12414: }
12415: #endif
12416: 
12417: /**
12418:  * xmlSchemaNewParserCtxt:
12419:  * @URL:  the location of the schema
12420:  *
12421:  * Create an XML Schemas parse context for that file/resource expected
12422:  * to contain an XML Schemas file.
12423:  *
12424:  * Returns the parser context or NULL in case of error
12425:  */
12426: xmlSchemaParserCtxtPtr
12427: xmlSchemaNewParserCtxt(const char *URL)
12428: {
12429:     xmlSchemaParserCtxtPtr ret;
12430: 
12431:     if (URL == NULL)
12432:         return (NULL);
12433: 
12434:     ret = xmlSchemaParserCtxtCreate();
12435:     if (ret == NULL)
12436: 	return(NULL);
12437:     ret->dict = xmlDictCreate();
12438:     ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
12439:     return (ret);
12440: }
12441: 
12442: /**
12443:  * xmlSchemaNewMemParserCtxt:
12444:  * @buffer:  a pointer to a char array containing the schemas
12445:  * @size:  the size of the array
12446:  *
12447:  * Create an XML Schemas parse context for that memory buffer expected
12448:  * to contain an XML Schemas file.
12449:  *
12450:  * Returns the parser context or NULL in case of error
12451:  */
12452: xmlSchemaParserCtxtPtr
12453: xmlSchemaNewMemParserCtxt(const char *buffer, int size)
12454: {
12455:     xmlSchemaParserCtxtPtr ret;
12456: 
12457:     if ((buffer == NULL) || (size <= 0))
12458:         return (NULL);
12459:     ret = xmlSchemaParserCtxtCreate();
12460:     if (ret == NULL)
12461: 	return(NULL);
12462:     ret->buffer = buffer;
12463:     ret->size = size;
12464:     ret->dict = xmlDictCreate();
12465:     return (ret);
12466: }
12467: 
12468: /**
12469:  * xmlSchemaNewDocParserCtxt:
12470:  * @doc:  a preparsed document tree
12471:  *
12472:  * Create an XML Schemas parse context for that document.
12473:  * NB. The document may be modified during the parsing process.
12474:  *
12475:  * Returns the parser context or NULL in case of error
12476:  */
12477: xmlSchemaParserCtxtPtr
12478: xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
12479: {
12480:     xmlSchemaParserCtxtPtr ret;
12481: 
12482:     if (doc == NULL)
12483:       return (NULL);
12484:     ret = xmlSchemaParserCtxtCreate();
12485:     if (ret == NULL)
12486: 	return(NULL);
12487:     ret->doc = doc;
12488:     ret->dict = xmlDictCreate();
12489:     /* The application has responsibility for the document */
12490:     ret->preserve = 1;
12491: 
12492:     return (ret);
12493: }
12494: 
12495: /**
12496:  * xmlSchemaFreeParserCtxt:
12497:  * @ctxt:  the schema parser context
12498:  *
12499:  * Free the resources associated to the schema parser context
12500:  */
12501: void
12502: xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
12503: {
12504:     if (ctxt == NULL)
12505:         return;
12506:     if (ctxt->doc != NULL && !ctxt->preserve)
12507:         xmlFreeDoc(ctxt->doc);
12508:     if (ctxt->vctxt != NULL) {
12509: 	xmlSchemaFreeValidCtxt(ctxt->vctxt);
12510:     }
12511:     if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
12512: 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
12513: 	ctxt->constructor = NULL;
12514: 	ctxt->ownsConstructor = 0;
12515:     }
12516:     if (ctxt->attrProhibs != NULL)
12517: 	xmlSchemaItemListFree(ctxt->attrProhibs);
12518:     xmlDictFree(ctxt->dict);
12519:     xmlFree(ctxt);
12520: }
12521: 
12522: /************************************************************************
12523:  *									*
12524:  *			Building the content models			*
12525:  *									*
12526:  ************************************************************************/
12527: 
12528: /**
12529:  * xmlSchemaBuildContentModelForSubstGroup:
12530:  *
12531:  * Returns 1 if nillable, 0 otherwise
12532:  */
12533: static int
12534: xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
12535: 	xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
12536: {
12537:     xmlAutomataStatePtr start, tmp;
12538:     xmlSchemaElementPtr elemDecl, member;
12539:     xmlSchemaSubstGroupPtr substGroup;
12540:     int i;
12541:     int ret = 0;
12542: 
12543:     elemDecl = (xmlSchemaElementPtr) particle->children;
12544:     /*
12545:     * Wrap the substitution group with a CHOICE.
12546:     */
12547:     start = pctxt->state;
12548:     if (end == NULL)
12549: 	end = xmlAutomataNewState(pctxt->am);
12550:     substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
12551:     if (substGroup == NULL) {
12552: 	xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
12553: 	    XML_SCHEMAP_INTERNAL,
12554: 	    "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
12555: 	    "declaration is marked having a subst. group but none "
12556: 	    "available.\n", elemDecl->name, NULL);
12557: 	return(0);
12558:     }
12559:     if (counter >= 0) {
12560: 	/*
12561: 	* NOTE that we put the declaration in, even if it's abstract.
12562: 	* However, an error will be raised during *validation* if an element
12563: 	* information item shall be validated against an abstract element
12564: 	* declaration.
12565: 	*/
12566: 	tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
12567:         xmlAutomataNewTransition2(pctxt->am, tmp, end,
12568: 	            elemDecl->name, elemDecl->targetNamespace, elemDecl);
12569: 	/*
12570: 	* Add subst. group members.
12571: 	*/
12572: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12573: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12574:             xmlAutomataNewTransition2(pctxt->am, tmp, end,
12575: 		               member->name, member->targetNamespace, member);
12576: 	}
12577:     } else if (particle->maxOccurs == 1) {
12578: 	/*
12579: 	* NOTE that we put the declaration in, even if it's abstract,
12580: 	*/
12581: 	xmlAutomataNewEpsilon(pctxt->am,
12582: 	    xmlAutomataNewTransition2(pctxt->am,
12583: 	    start, NULL,
12584: 	    elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
12585: 	/*
12586: 	* Add subst. group members.
12587: 	*/
12588: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12589: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12590: 	    /*
12591: 	    * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
12592: 	    *  was incorrectly used instead of xmlAutomataNewTransition2()
12593: 	    *  (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
12594: 	    *  section in xmlSchemaBuildAContentModel() ).
12595: 	    * TODO: Check if xmlAutomataNewOnceTrans2() was instead
12596: 	    *  intended for the above "counter" section originally. I.e.,
12597: 	    *  check xs:all with subst-groups.
12598: 	    *
12599: 	    * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
12600: 	    *	               member->name, member->targetNamespace,
12601: 	    *		       1, 1, member);
12602: 	    */
12603: 	    tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
12604: 		member->name, member->targetNamespace, member);
12605: 	    xmlAutomataNewEpsilon(pctxt->am, tmp, end);
12606: 	}
12607:     } else {
12608: 	xmlAutomataStatePtr hop;
12609: 	int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12610: 	    UNBOUNDED : particle->maxOccurs - 1;
12611: 	int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12612: 
12613: 	counter =
12614: 	    xmlAutomataNewCounter(pctxt->am, minOccurs,
12615: 	    maxOccurs);
12616: 	hop = xmlAutomataNewState(pctxt->am);
12617: 
12618: 	xmlAutomataNewEpsilon(pctxt->am,
12619: 	    xmlAutomataNewTransition2(pctxt->am,
12620: 	    start, NULL,
12621: 	    elemDecl->name, elemDecl->targetNamespace, elemDecl),
12622: 	    hop);
12623: 	/*
12624: 	 * Add subst. group members.
12625: 	 */
12626: 	for (i = 0; i < substGroup->members->nbItems; i++) {
12627: 	    member = (xmlSchemaElementPtr) substGroup->members->items[i];
12628: 	    xmlAutomataNewEpsilon(pctxt->am,
12629: 		xmlAutomataNewTransition2(pctxt->am,
12630: 		start, NULL,
12631: 		member->name, member->targetNamespace, member),
12632: 		hop);
12633: 	}
12634: 	xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12635: 	xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12636:     }
12637:     if (particle->minOccurs == 0) {
12638: 	xmlAutomataNewEpsilon(pctxt->am, start, end);
12639:         ret = 1;
12640:     }
12641:     pctxt->state = end;
12642:     return(ret);
12643: }
12644: 
12645: /**
12646:  * xmlSchemaBuildContentModelForElement:
12647:  *
12648:  * Returns 1 if nillable, 0 otherwise
12649:  */
12650: static int
12651: xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
12652: 				     xmlSchemaParticlePtr particle)
12653: {
12654:     int ret = 0;
12655: 
12656:     if (((xmlSchemaElementPtr) particle->children)->flags &
12657: 	XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
12658: 	/*
12659: 	* Substitution groups.
12660: 	*/
12661: 	ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
12662:     } else {
12663: 	xmlSchemaElementPtr elemDecl;
12664: 	xmlAutomataStatePtr start;
12665: 
12666: 	elemDecl = (xmlSchemaElementPtr) particle->children;
12667: 
12668: 	if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
12669: 	    return(0);
12670: 	if (particle->maxOccurs == 1) {
12671: 	    start = ctxt->state;
12672: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12673: 		    elemDecl->name, elemDecl->targetNamespace, elemDecl);
12674: 	} else if ((particle->maxOccurs >= UNBOUNDED) &&
12675: 	           (particle->minOccurs < 2)) {
12676: 	    /* Special case. */
12677: 	    start = ctxt->state;
12678: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12679: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12680: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
12681: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12682: 	} else {
12683: 	    int counter;
12684: 	    int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12685: 			    UNBOUNDED : particle->maxOccurs - 1;
12686: 	    int minOccurs = particle->minOccurs < 1 ?
12687: 			    0 : particle->minOccurs - 1;
12688: 
12689: 	    start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
12690: 	    counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
12691: 	    ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
12692: 		elemDecl->name, elemDecl->targetNamespace, elemDecl);
12693: 	    xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
12694: 	    ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
12695: 		NULL, counter);
12696: 	}
12697: 	if (particle->minOccurs == 0) {
12698: 	    xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
12699:             ret = 1;
12700:         }
12701:     }
12702:     return(ret);
12703: }
12704: 
12705: /**
12706:  * xmlSchemaBuildAContentModel:
12707:  * @ctxt:  the schema parser context
12708:  * @particle:  the particle component
12709:  * @name:  the complex type's name whose content is being built
12710:  *
12711:  * Create the automaton for the {content type} of a complex type.
12712:  *
12713:  * Returns 1 if the content is nillable, 0 otherwise
12714:  */
12715: static int
12716: xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
12717: 			    xmlSchemaParticlePtr particle)
12718: {
12719:     int ret = 0, tmp2;
12720: 
12721:     if (particle == NULL) {
12722: 	PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
12723: 	return(1);
12724:     }
12725:     if (particle->children == NULL) {
12726: 	/*
12727: 	* Just return in this case. A missing "term" of the particle
12728: 	* might arise due to an invalid "term" component.
12729: 	*/
12730: 	return(1);
12731:     }
12732: 
12733:     switch (particle->children->type) {
12734: 	case XML_SCHEMA_TYPE_ANY: {
12735: 	    xmlAutomataStatePtr start, end;
12736: 	    xmlSchemaWildcardPtr wild;
12737: 	    xmlSchemaWildcardNsPtr ns;
12738: 
12739: 	    wild = (xmlSchemaWildcardPtr) particle->children;
12740: 
12741: 	    start = pctxt->state;
12742: 	    end = xmlAutomataNewState(pctxt->am);
12743: 
12744: 	    if (particle->maxOccurs == 1) {
12745: 		if (wild->any == 1) {
12746: 		    /*
12747: 		    * We need to add both transitions:
12748: 		    *
12749: 		    * 1. the {"*", "*"} for elements in a namespace.
12750: 		    */
12751: 		    pctxt->state =
12752: 			xmlAutomataNewTransition2(pctxt->am,
12753: 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12754: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12755: 		    /*
12756: 		    * 2. the {"*"} for elements in no namespace.
12757: 		    */
12758: 		    pctxt->state =
12759: 			xmlAutomataNewTransition2(pctxt->am,
12760: 			start, NULL, BAD_CAST "*", NULL, wild);
12761: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12762: 
12763: 		} else if (wild->nsSet != NULL) {
12764: 		    ns = wild->nsSet;
12765: 		    do {
12766: 			pctxt->state = start;
12767: 			pctxt->state = xmlAutomataNewTransition2(pctxt->am,
12768: 			    pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
12769: 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12770: 			ns = ns->next;
12771: 		    } while (ns != NULL);
12772: 
12773: 		} else if (wild->negNsSet != NULL) {
12774: 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12775: 			start, end, BAD_CAST "*", wild->negNsSet->value,
12776: 			wild);
12777: 		}
12778: 	    } else {
12779: 		int counter;
12780: 		xmlAutomataStatePtr hop;
12781: 		int maxOccurs =
12782: 		    particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
12783:                                            particle->maxOccurs - 1;
12784: 		int minOccurs =
12785: 		    particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12786: 
12787: 		counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12788: 		hop = xmlAutomataNewState(pctxt->am);
12789: 		if (wild->any == 1) {
12790: 		    pctxt->state =
12791: 			xmlAutomataNewTransition2(pctxt->am,
12792: 			start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
12793: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12794: 		    pctxt->state =
12795: 			xmlAutomataNewTransition2(pctxt->am,
12796: 			start, NULL, BAD_CAST "*", NULL, wild);
12797: 		    xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12798: 		} else if (wild->nsSet != NULL) {
12799: 		    ns = wild->nsSet;
12800: 		    do {
12801: 			pctxt->state =
12802: 			    xmlAutomataNewTransition2(pctxt->am,
12803: 				start, NULL, BAD_CAST "*", ns->value, wild);
12804: 			xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12805: 			ns = ns->next;
12806: 		    } while (ns != NULL);
12807: 
12808: 		} else if (wild->negNsSet != NULL) {
12809: 		    pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
12810: 			start, hop, BAD_CAST "*", wild->negNsSet->value,
12811: 			wild);
12812: 		}
12813: 		xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
12814: 		xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
12815: 	    }
12816: 	    if (particle->minOccurs == 0) {
12817: 		xmlAutomataNewEpsilon(pctxt->am, start, end);
12818:                 ret = 1;
12819: 	    }
12820: 	    pctxt->state = end;
12821:             break;
12822: 	}
12823:         case XML_SCHEMA_TYPE_ELEMENT:
12824: 	    ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
12825: 	    break;
12826:         case XML_SCHEMA_TYPE_SEQUENCE:{
12827:             xmlSchemaTreeItemPtr sub;
12828: 
12829:             ret = 1;
12830:             /*
12831:              * If max and min occurances are default (1) then
12832:              * simply iterate over the particles of the <sequence>.
12833:              */
12834:             if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
12835:                 sub = particle->children->children;
12836: 
12837:                 while (sub != NULL) {
12838:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12839:                                         (xmlSchemaParticlePtr) sub);
12840:                     if (tmp2 != 1) ret = 0;
12841:                     sub = sub->next;
12842:                 }
12843:             } else {
12844:                 xmlAutomataStatePtr oldstate = pctxt->state;
12845: 
12846:                 if (particle->maxOccurs >= UNBOUNDED) {
12847:                     if (particle->minOccurs > 1) {
12848:                         xmlAutomataStatePtr tmp;
12849:                         int counter;
12850: 
12851:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12852:                             oldstate, NULL);
12853:                         oldstate = pctxt->state;
12854: 
12855:                         counter = xmlAutomataNewCounter(pctxt->am,
12856:                             particle->minOccurs - 1, UNBOUNDED);
12857: 
12858:                         sub = particle->children->children;
12859:                         while (sub != NULL) {
12860:                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
12861:                                             (xmlSchemaParticlePtr) sub);
12862:                             if (tmp2 != 1) ret = 0;
12863:                             sub = sub->next;
12864:                         }
12865:                         tmp = pctxt->state;
12866:                         xmlAutomataNewCountedTrans(pctxt->am, tmp,
12867:                                                    oldstate, counter);
12868:                         pctxt->state =
12869:                             xmlAutomataNewCounterTrans(pctxt->am, tmp,
12870:                                                        NULL, counter);
12871:                         if (ret == 1)
12872:                             xmlAutomataNewEpsilon(pctxt->am,
12873:                                                 oldstate, pctxt->state);
12874: 
12875:                     } else {
12876:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12877:                             oldstate, NULL);
12878:                         oldstate = pctxt->state;
12879: 
12880:                         sub = particle->children->children;
12881:                         while (sub != NULL) {
12882:                             tmp2 = xmlSchemaBuildAContentModel(pctxt,
12883:                                         (xmlSchemaParticlePtr) sub);
12884:                             if (tmp2 != 1) ret = 0;
12885:                             sub = sub->next;
12886:                         }
12887:                         xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
12888:                                               oldstate);
12889:                         /*
12890:                          * epsilon needed to block previous trans from
12891:                          * being allowed to enter back from another
12892:                          * construct
12893:                          */
12894:                         pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12895:                                             pctxt->state, NULL);
12896:                         if (particle->minOccurs == 0) {
12897:                             xmlAutomataNewEpsilon(pctxt->am,
12898:                                 oldstate, pctxt->state);
12899:                             ret = 1;
12900:                         }
12901:                     }
12902:                 } else if ((particle->maxOccurs > 1)
12903:                            || (particle->minOccurs > 1)) {
12904:                     xmlAutomataStatePtr tmp;
12905:                     int counter;
12906: 
12907:                     pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
12908:                         oldstate, NULL);
12909:                     oldstate = pctxt->state;
12910: 
12911:                     counter = xmlAutomataNewCounter(pctxt->am,
12912:                         particle->minOccurs - 1,
12913:                         particle->maxOccurs - 1);
12914: 
12915:                     sub = particle->children->children;
12916:                     while (sub != NULL) {
12917:                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
12918:                                         (xmlSchemaParticlePtr) sub);
12919:                         if (tmp2 != 1) ret = 0;
12920:                         sub = sub->next;
12921:                     }
12922:                     tmp = pctxt->state;
12923:                     xmlAutomataNewCountedTrans(pctxt->am,
12924:                         tmp, oldstate, counter);
12925:                     pctxt->state =
12926:                         xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
12927:                                                    counter);
12928:                     if ((particle->minOccurs == 0) || (ret == 1)) {
12929:                         xmlAutomataNewEpsilon(pctxt->am,
12930:                                             oldstate, pctxt->state);
12931:                         ret = 1;
12932:                     }
12933:                 } else {
12934:                     sub = particle->children->children;
12935:                     while (sub != NULL) {
12936:                         tmp2 = xmlSchemaBuildAContentModel(pctxt,
12937:                                         (xmlSchemaParticlePtr) sub);
12938:                         if (tmp2 != 1) ret = 0;
12939:                         sub = sub->next;
12940:                     }
12941:                     if (particle->minOccurs == 0) {
12942:                         xmlAutomataNewEpsilon(pctxt->am, oldstate,
12943:                                               pctxt->state);
12944:                         ret = 1;
12945:                     }
12946:                 }
12947:             }
12948:             break;
12949:         }
12950:         case XML_SCHEMA_TYPE_CHOICE:{
12951:             xmlSchemaTreeItemPtr sub;
12952:             xmlAutomataStatePtr start, end;
12953: 
12954:             ret = 0;
12955:             start = pctxt->state;
12956:             end = xmlAutomataNewState(pctxt->am);
12957: 
12958:             /*
12959:              * iterate over the subtypes and remerge the end with an
12960:              * epsilon transition
12961:              */
12962:             if (particle->maxOccurs == 1) {
12963:                 sub = particle->children->children;
12964:                 while (sub != NULL) {
12965:                     pctxt->state = start;
12966:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12967:                                         (xmlSchemaParticlePtr) sub);
12968:                     if (tmp2 == 1) ret = 1;
12969:                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
12970:                     sub = sub->next;
12971:                 }
12972:             } else {
12973:                 int counter;
12974:                 xmlAutomataStatePtr hop, base;
12975:                 int maxOccurs = particle->maxOccurs == UNBOUNDED ?
12976:                     UNBOUNDED : particle->maxOccurs - 1;
12977:                 int minOccurs =
12978:                     particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
12979: 
12980:                 /*
12981:                  * use a counter to keep track of the number of transtions
12982:                  * which went through the choice.
12983:                  */
12984:                 counter =
12985:                     xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
12986:                 hop = xmlAutomataNewState(pctxt->am);
12987:                 base = xmlAutomataNewState(pctxt->am);
12988: 
12989:                 sub = particle->children->children;
12990:                 while (sub != NULL) {
12991:                     pctxt->state = base;
12992:                     tmp2 = xmlSchemaBuildAContentModel(pctxt,
12993:                                         (xmlSchemaParticlePtr) sub);
12994:                     if (tmp2 == 1) ret = 1;
12995:                     xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
12996:                     sub = sub->next;
12997:                 }
12998:                 xmlAutomataNewEpsilon(pctxt->am, start, base);
12999:                 xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
13000:                 xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
13001:                 if (ret == 1)
13002:                     xmlAutomataNewEpsilon(pctxt->am, base, end);
13003:             }
13004:             if (particle->minOccurs == 0) {
13005:                 xmlAutomataNewEpsilon(pctxt->am, start, end);
13006:                 ret = 1;
13007:             }
13008:             pctxt->state = end;
13009:             break;
13010:         }
13011:         case XML_SCHEMA_TYPE_ALL:{
13012:             xmlAutomataStatePtr start, tmp;
13013:             xmlSchemaParticlePtr sub;
13014:             xmlSchemaElementPtr elemDecl;
13015: 
13016:             ret = 1;
13017: 
13018:             sub = (xmlSchemaParticlePtr) particle->children->children;
13019:             if (sub == NULL)
13020:                 break;
13021: 
13022:             ret = 0;
13023: 
13024:             start = pctxt->state;
13025:             tmp = xmlAutomataNewState(pctxt->am);
13026:             xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
13027:             pctxt->state = tmp;
13028:             while (sub != NULL) {
13029:                 pctxt->state = tmp;
13030: 
13031:                 elemDecl = (xmlSchemaElementPtr) sub->children;
13032:                 if (elemDecl == NULL) {
13033:                     PERROR_INT("xmlSchemaBuildAContentModel",
13034:                         "<element> particle has no term");
13035:                     return(ret);
13036:                 };
13037:                 /*
13038:                 * NOTE: The {max occurs} of all the particles in the
13039:                 * {particles} of the group must be 0 or 1; this is
13040:                 * already ensured during the parse of the content of
13041:                 * <all>.
13042:                 */
13043:                 if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
13044:                     int counter;
13045: 
13046:                     /*
13047:                      * This is an abstract group, we need to share
13048:                      * the same counter for all the element transitions
13049:                      * derived from the group
13050:                      */
13051:                     counter = xmlAutomataNewCounter(pctxt->am,
13052:                                        sub->minOccurs, sub->maxOccurs);
13053:                     xmlSchemaBuildContentModelForSubstGroup(pctxt,
13054:                                        sub, counter, pctxt->state);
13055:                 } else {
13056:                     if ((sub->minOccurs == 1) &&
13057:                         (sub->maxOccurs == 1)) {
13058:                         xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
13059:                                                 pctxt->state,
13060:                                                 elemDecl->name,
13061:                                                 elemDecl->targetNamespace,
13062:                                                 1, 1, elemDecl);
13063:                     } else if ((sub->minOccurs == 0) &&
13064:                         (sub->maxOccurs == 1)) {
13065: 
13066:                         xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
13067:                                                  pctxt->state,
13068:                                                  elemDecl->name,
13069:                                                  elemDecl->targetNamespace,
13070:                                                  0,
13071:                                                  1,
13072:                                                  elemDecl);
13073:                     }
13074:                 }
13075:                 sub = (xmlSchemaParticlePtr) sub->next;
13076:             }
13077:             pctxt->state =
13078:                 xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
13079:             if (particle->minOccurs == 0) {
13080:                 xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
13081:                 ret = 1;
13082:             }
13083:             break;
13084:         }
13085: 	case XML_SCHEMA_TYPE_GROUP:
13086: 	    /*
13087: 	    * If we hit a model group definition, then this means that
13088: 	    * it was empty, thus was not substituted for the containing
13089: 	    * model group. Just do nothing in this case.
13090: 	    * TODO: But the group should be substituted and not occur at
13091: 	    * all in the content model at this point. Fix this.
13092: 	    */
13093:             ret = 1;
13094: 	    break;
13095:         default:
13096: 	    xmlSchemaInternalErr2(ACTXT_CAST pctxt,
13097: 		"xmlSchemaBuildAContentModel",
13098: 		"found unexpected term of type '%s' in content model",
13099: 		WXS_ITEM_TYPE_NAME(particle->children), NULL);
13100:             return(ret);
13101:     }
13102:     return(ret);
13103: }
13104: 
13105: /**
13106:  * xmlSchemaBuildContentModel:
13107:  * @ctxt:  the schema parser context
13108:  * @type:  the complex type definition
13109:  * @name:  the element name
13110:  *
13111:  * Builds the content model of the complex type.
13112:  */
13113: static void
13114: xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
13115: 			   xmlSchemaParserCtxtPtr ctxt)
13116: {
13117:     if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
13118: 	(type->contModel != NULL) ||
13119: 	((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
13120: 	(type->contentType != XML_SCHEMA_CONTENT_MIXED)))
13121: 	return;
13122: 
13123: #ifdef DEBUG_CONTENT
13124:     xmlGenericError(xmlGenericErrorContext,
13125:                     "Building content model for %s\n", name);
13126: #endif
13127:     ctxt->am = NULL;
13128:     ctxt->am = xmlNewAutomata();
13129:     if (ctxt->am == NULL) {
13130:         xmlGenericError(xmlGenericErrorContext,
13131: 	    "Cannot create automata for complex type %s\n", type->name);
13132:         return;
13133:     }
13134:     ctxt->state = xmlAutomataGetInitState(ctxt->am);
13135:     /*
13136:     * Build the automaton.
13137:     */
13138:     xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
13139:     xmlAutomataSetFinalState(ctxt->am, ctxt->state);
13140:     type->contModel = xmlAutomataCompile(ctxt->am);
13141:     if (type->contModel == NULL) {
13142:         xmlSchemaPCustomErr(ctxt,
13143: 	    XML_SCHEMAP_INTERNAL,
13144: 	    WXS_BASIC_CAST type, type->node,
13145: 	    "Failed to compile the content model", NULL);
13146:     } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
13147:         xmlSchemaPCustomErr(ctxt,
13148: 	    XML_SCHEMAP_NOT_DETERMINISTIC,
13149: 	    /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
13150: 	    WXS_BASIC_CAST type, type->node,
13151: 	    "The content model is not determinist", NULL);
13152:     } else {
13153: #ifdef DEBUG_CONTENT_REGEXP
13154:         xmlGenericError(xmlGenericErrorContext,
13155:                         "Content model of %s:\n", type->name);
13156:         xmlRegexpPrint(stderr, type->contModel);
13157: #endif
13158:     }
13159:     ctxt->state = NULL;
13160:     xmlFreeAutomata(ctxt->am);
13161:     ctxt->am = NULL;
13162: }
13163: 
13164: /**
13165:  * xmlSchemaResolveElementReferences:
13166:  * @elem:  the schema element context
13167:  * @ctxt:  the schema parser context
13168:  *
13169:  * Resolves the references of an element declaration
13170:  * or particle, which has an element declaration as it's
13171:  * term.
13172:  */
13173: static void
13174: xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
13175: 				  xmlSchemaParserCtxtPtr ctxt)
13176: {
13177:     if ((ctxt == NULL) || (elemDecl == NULL) ||
13178: 	((elemDecl != NULL) &&
13179: 	(elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
13180:         return;
13181:     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
13182: 
13183:     if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
13184: 	xmlSchemaTypePtr type;
13185: 
13186: 	/* (type definition) ... otherwise the type definition �resolved�
13187: 	* to by the �actual value� of the type [attribute] ...
13188: 	*/
13189: 	type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
13190: 	    elemDecl->namedTypeNs);
13191: 	if (type == NULL) {
13192: 	    xmlSchemaPResCompAttrErr(ctxt,
13193: 		XML_SCHEMAP_SRC_RESOLVE,
13194: 		WXS_BASIC_CAST elemDecl, elemDecl->node,
13195: 		"type", elemDecl->namedType, elemDecl->namedTypeNs,
13196: 		XML_SCHEMA_TYPE_BASIC, "type definition");
13197: 	} else
13198: 	    elemDecl->subtypes = type;
13199:     }
13200:     if (elemDecl->substGroup != NULL) {
13201: 	xmlSchemaElementPtr substHead;
13202: 
13203: 	/*
13204: 	* FIXME TODO: Do we need a new field in _xmlSchemaElement for
13205: 	* substitutionGroup?
13206: 	*/
13207: 	substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
13208: 	    elemDecl->substGroupNs);
13209: 	if (substHead == NULL) {
13210: 	    xmlSchemaPResCompAttrErr(ctxt,
13211: 		XML_SCHEMAP_SRC_RESOLVE,
13212: 		WXS_BASIC_CAST elemDecl, NULL,
13213: 		"substitutionGroup", elemDecl->substGroup,
13214: 		elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
13215: 	} else {
13216: 	    xmlSchemaResolveElementReferences(substHead, ctxt);
13217: 	    /*
13218: 	    * Set the "substitution group affiliation".
13219: 	    * NOTE that now we use the "refDecl" field for this.
13220: 	    */
13221: 	    WXS_SUBST_HEAD(elemDecl) = substHead;
13222: 	    /*
13223: 	    * The type definitions is set to:
13224: 	    * SPEC "...the {type definition} of the element
13225: 	    * declaration �resolved� to by the �actual value�
13226: 	    * of the substitutionGroup [attribute], if present"
13227: 	    */
13228: 	    if (elemDecl->subtypes == NULL)
13229: 		elemDecl->subtypes = substHead->subtypes;
13230: 	}
13231:     }
13232:     /*
13233:     * SPEC "The definition of anyType serves as the default type definition
13234:     * for element declarations whose XML representation does not specify one."
13235:     */
13236:     if ((elemDecl->subtypes == NULL) &&
13237: 	(elemDecl->namedType == NULL) &&
13238: 	(elemDecl->substGroup == NULL))
13239: 	elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
13240: }
13241: 
13242: /**
13243:  * xmlSchemaResolveUnionMemberTypes:
13244:  * @ctxt:  the schema parser context
13245:  * @type:  the schema simple type definition
13246:  *
13247:  * Checks and builds the "member type definitions" property of the union
13248:  * simple type. This handles part (1), part (2) is done in
13249:  * xmlSchemaFinishMemberTypeDefinitionsProperty()
13250:  *
13251:  * Returns -1 in case of an internal error, 0 otherwise.
13252:  */
13253: static int
13254: xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
13255: 				 xmlSchemaTypePtr type)
13256: {
13257: 
13258:     xmlSchemaTypeLinkPtr link, lastLink, newLink;
13259:     xmlSchemaTypePtr memberType;
13260: 
13261:     /*
13262:     * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
13263:     * define the explicit members as the type definitions �resolved�
13264:     * to by the items in the �actual value� of the memberTypes [attribute],
13265:     * if any, followed by the type definitions corresponding to the
13266:     * <simpleType>s among the [children] of <union>, if any."
13267:     */
13268:     /*
13269:     * Resolve references.
13270:     */
13271:     link = type->memberTypes;
13272:     lastLink = NULL;
13273:     while (link != NULL) {
13274: 	const xmlChar *name, *nsName;
13275: 
13276: 	name = ((xmlSchemaQNameRefPtr) link->type)->name;
13277: 	nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
13278: 
13279: 	memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
13280: 	if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
13281: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
13282: 		WXS_BASIC_CAST type, type->node, "memberTypes",
13283: 		name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
13284: 	    /*
13285: 	    * Remove the member type link.
13286: 	    */
13287: 	    if (lastLink == NULL)
13288: 		type->memberTypes = link->next;
13289: 	    else
13290: 		lastLink->next = link->next;
13291: 	    newLink = link;
13292: 	    link = link->next;
13293: 	    xmlFree(newLink);
13294: 	} else {
13295: 	    link->type = memberType;
13296: 	    lastLink = link;
13297: 	    link = link->next;
13298: 	}
13299:     }
13300:     /*
13301:     * Add local simple types,
13302:     */
13303:     memberType = type->subtypes;
13304:     while (memberType != NULL) {
13305: 	link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
13306: 	if (link == NULL) {
13307: 	    xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
13308: 	    return (-1);
13309: 	}
13310: 	link->type = memberType;
13311: 	link->next = NULL;
13312: 	if (lastLink == NULL)
13313: 	    type->memberTypes = link;
13314: 	else
13315: 	    lastLink->next = link;
13316: 	lastLink = link;
13317: 	memberType = memberType->next;
13318:     }
13319:     return (0);
13320: }
13321: 
13322: /**
13323:  * xmlSchemaIsDerivedFromBuiltInType:
13324:  * @ctxt:  the schema parser context
13325:  * @type:  the type definition
13326:  * @valType: the value type
13327:  *
13328:  *
13329:  * Returns 1 if the type has the given value type, or
13330:  * is derived from such a type.
13331:  */
13332: static int
13333: xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13334: {
13335:     if (type == NULL)
13336: 	return (0);
13337:     if (WXS_IS_COMPLEX(type))
13338: 	return (0);
13339:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
13340: 	if (type->builtInType == valType)
13341: 	    return(1);
13342: 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13343: 	    (type->builtInType == XML_SCHEMAS_ANYTYPE))
13344: 	    return (0);
13345: 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13346:     }
13347:     return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13348: }
13349: 
13350: #if 0
13351: /**
13352:  * xmlSchemaIsDerivedFromBuiltInType:
13353:  * @ctxt:  the schema parser context
13354:  * @type:  the type definition
13355:  * @valType: the value type
13356:  *
13357:  *
13358:  * Returns 1 if the type has the given value type, or
13359:  * is derived from such a type.
13360:  */
13361: static int
13362: xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
13363: {
13364:     if (type == NULL)
13365: 	return (0);
13366:     if (WXS_IS_COMPLEX(type))
13367: 	return (0);
13368:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
13369: 	if (type->builtInType == valType)
13370: 	    return(1);
13371: 	return (0);
13372:     } else
13373: 	return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
13374: 
13375:     return (0);
13376: }
13377: 
13378: static xmlSchemaTypePtr
13379: xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
13380: {
13381:     if (type == NULL)
13382: 	return (NULL);
13383:     if (WXS_IS_COMPLEX(type))
13384: 	return (NULL);
13385:     if (type->type == XML_SCHEMA_TYPE_BASIC)
13386: 	return(type);
13387:     return(xmlSchemaQueryBuiltInType(type->subtypes));
13388: }
13389: #endif
13390: 
13391: /**
13392:  * xmlSchemaGetPrimitiveType:
13393:  * @type:  the simpleType definition
13394:  *
13395:  * Returns the primitive type of the given type or
13396:  * NULL in case of error.
13397:  */
13398: static xmlSchemaTypePtr
13399: xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
13400: {
13401: 
13402:     while (type != NULL) {
13403: 	/*
13404: 	* Note that anySimpleType is actually not a primitive type
13405: 	* but we need that here.
13406: 	*/
13407: 	if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
13408: 	   (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
13409: 	    return (type);
13410: 	type = type->baseType;
13411:     }
13412: 
13413:     return (NULL);
13414: }
13415: 
13416: #if 0
13417: /**
13418:  * xmlSchemaGetBuiltInTypeAncestor:
13419:  * @type:  the simpleType definition
13420:  *
13421:  * Returns the primitive type of the given type or
13422:  * NULL in case of error.
13423:  */
13424: static xmlSchemaTypePtr
13425: xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
13426: {
13427:     if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
13428: 	return (0);
13429:     while (type != NULL) {
13430: 	if (type->type == XML_SCHEMA_TYPE_BASIC)
13431: 	    return (type);
13432: 	type = type->baseType;
13433:     }
13434: 
13435:     return (NULL);
13436: }
13437: #endif
13438: 
13439: /**
13440:  * xmlSchemaCloneWildcardNsConstraints:
13441:  * @ctxt:  the schema parser context
13442:  * @dest:  the destination wildcard
13443:  * @source: the source wildcard
13444:  *
13445:  * Clones the namespace constraints of source
13446:  * and assignes them to dest.
13447:  * Returns -1 on internal error, 0 otherwise.
13448:  */
13449: static int
13450: xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
13451: 				    xmlSchemaWildcardPtr dest,
13452: 				    xmlSchemaWildcardPtr source)
13453: {
13454:     xmlSchemaWildcardNsPtr cur, tmp, last;
13455: 
13456:     if ((source == NULL) || (dest == NULL))
13457: 	return(-1);
13458:     dest->any = source->any;
13459:     cur = source->nsSet;
13460:     last = NULL;
13461:     while (cur != NULL) {
13462: 	tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13463: 	if (tmp == NULL)
13464: 	    return(-1);
13465: 	tmp->value = cur->value;
13466: 	if (last == NULL)
13467: 	    dest->nsSet = tmp;
13468: 	else
13469: 	    last->next = tmp;
13470: 	last = tmp;
13471: 	cur = cur->next;
13472:     }
13473:     if (dest->negNsSet != NULL)
13474: 	xmlSchemaFreeWildcardNsSet(dest->negNsSet);
13475:     if (source->negNsSet != NULL) {
13476: 	dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13477: 	if (dest->negNsSet == NULL)
13478: 	    return(-1);
13479: 	dest->negNsSet->value = source->negNsSet->value;
13480:     } else
13481: 	dest->negNsSet = NULL;
13482:     return(0);
13483: }
13484: 
13485: /**
13486:  * xmlSchemaUnionWildcards:
13487:  * @ctxt:  the schema parser context
13488:  * @completeWild:  the first wildcard
13489:  * @curWild: the second wildcard
13490:  *
13491:  * Unions the namespace constraints of the given wildcards.
13492:  * @completeWild will hold the resulting union.
13493:  * Returns a positive error code on failure, -1 in case of an
13494:  * internal error, 0 otherwise.
13495:  */
13496: static int
13497: xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
13498: 			    xmlSchemaWildcardPtr completeWild,
13499: 			    xmlSchemaWildcardPtr curWild)
13500: {
13501:     xmlSchemaWildcardNsPtr cur, curB, tmp;
13502: 
13503:     /*
13504:     * 1 If O1 and O2 are the same value, then that value must be the
13505:     * value.
13506:     */
13507:     if ((completeWild->any == curWild->any) &&
13508: 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13509: 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13510: 
13511: 	if ((completeWild->negNsSet == NULL) ||
13512: 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13513: 
13514: 	    if (completeWild->nsSet != NULL) {
13515: 		int found = 0;
13516: 
13517: 		/*
13518: 		* Check equality of sets.
13519: 		*/
13520: 		cur = completeWild->nsSet;
13521: 		while (cur != NULL) {
13522: 		    found = 0;
13523: 		    curB = curWild->nsSet;
13524: 		    while (curB != NULL) {
13525: 			if (cur->value == curB->value) {
13526: 			    found = 1;
13527: 			    break;
13528: 			}
13529: 			curB = curB->next;
13530: 		    }
13531: 		    if (!found)
13532: 			break;
13533: 		    cur = cur->next;
13534: 		}
13535: 		if (found)
13536: 		    return(0);
13537: 	    } else
13538: 		return(0);
13539: 	}
13540:     }
13541:     /*
13542:     * 2 If either O1 or O2 is any, then any must be the value
13543:     */
13544:     if (completeWild->any != curWild->any) {
13545: 	if (completeWild->any == 0) {
13546: 	    completeWild->any = 1;
13547: 	    if (completeWild->nsSet != NULL) {
13548: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13549: 		completeWild->nsSet = NULL;
13550: 	    }
13551: 	    if (completeWild->negNsSet != NULL) {
13552: 		xmlFree(completeWild->negNsSet);
13553: 		completeWild->negNsSet = NULL;
13554: 	    }
13555: 	}
13556: 	return (0);
13557:     }
13558:     /*
13559:     * 3 If both O1 and O2 are sets of (namespace names or �absent�),
13560:     * then the union of those sets must be the value.
13561:     */
13562:     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13563: 	int found;
13564: 	xmlSchemaWildcardNsPtr start;
13565: 
13566: 	cur = curWild->nsSet;
13567: 	start = completeWild->nsSet;
13568: 	while (cur != NULL) {
13569: 	    found = 0;
13570: 	    curB = start;
13571: 	    while (curB != NULL) {
13572: 		if (cur->value == curB->value) {
13573: 		    found = 1;
13574: 		    break;
13575: 		}
13576: 		curB = curB->next;
13577: 	    }
13578: 	    if (!found) {
13579: 		tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
13580: 		if (tmp == NULL)
13581: 		    return (-1);
13582: 		tmp->value = cur->value;
13583: 		tmp->next = completeWild->nsSet;
13584: 		completeWild->nsSet = tmp;
13585: 	    }
13586: 	    cur = cur->next;
13587: 	}
13588: 
13589: 	return(0);
13590:     }
13591:     /*
13592:     * 4 If the two are negations of different values (namespace names
13593:     * or �absent�), then a pair of not and �absent� must be the value.
13594:     */
13595:     if ((completeWild->negNsSet != NULL) &&
13596: 	(curWild->negNsSet != NULL) &&
13597: 	(completeWild->negNsSet->value != curWild->negNsSet->value)) {
13598: 	completeWild->negNsSet->value = NULL;
13599: 
13600: 	return(0);
13601:     }
13602:     /*
13603:      * 5.
13604:      */
13605:     if (((completeWild->negNsSet != NULL) &&
13606: 	(completeWild->negNsSet->value != NULL) &&
13607: 	(curWild->nsSet != NULL)) ||
13608: 	((curWild->negNsSet != NULL) &&
13609: 	(curWild->negNsSet->value != NULL) &&
13610: 	(completeWild->nsSet != NULL))) {
13611: 
13612: 	int nsFound, absentFound = 0;
13613: 
13614: 	if (completeWild->nsSet != NULL) {
13615: 	    cur = completeWild->nsSet;
13616: 	    curB = curWild->negNsSet;
13617: 	} else {
13618: 	    cur = curWild->nsSet;
13619: 	    curB = completeWild->negNsSet;
13620: 	}
13621: 	nsFound = 0;
13622: 	while (cur != NULL) {
13623: 	    if (cur->value == NULL)
13624: 		absentFound = 1;
13625: 	    else if (cur->value == curB->value)
13626: 		nsFound = 1;
13627: 	    if (nsFound && absentFound)
13628: 		break;
13629: 	    cur = cur->next;
13630: 	}
13631: 
13632: 	if (nsFound && absentFound) {
13633: 	    /*
13634: 	    * 5.1 If the set S includes both the negated namespace
13635: 	    * name and �absent�, then any must be the value.
13636: 	    */
13637: 	    completeWild->any = 1;
13638: 	    if (completeWild->nsSet != NULL) {
13639: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13640: 		completeWild->nsSet = NULL;
13641: 	    }
13642: 	    if (completeWild->negNsSet != NULL) {
13643: 		xmlFree(completeWild->negNsSet);
13644: 		completeWild->negNsSet = NULL;
13645: 	    }
13646: 	} else if (nsFound && (!absentFound)) {
13647: 	    /*
13648: 	    * 5.2 If the set S includes the negated namespace name
13649: 	    * but not �absent�, then a pair of not and �absent� must
13650: 	    * be the value.
13651: 	    */
13652: 	    if (completeWild->nsSet != NULL) {
13653: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13654: 		completeWild->nsSet = NULL;
13655: 	    }
13656: 	    if (completeWild->negNsSet == NULL) {
13657: 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13658: 		if (completeWild->negNsSet == NULL)
13659: 		    return (-1);
13660: 	    }
13661: 	    completeWild->negNsSet->value = NULL;
13662: 	} else if ((!nsFound) && absentFound) {
13663: 	    /*
13664: 	    * 5.3 If the set S includes �absent� but not the negated
13665: 	    * namespace name, then the union is not expressible.
13666: 	    */
13667: 	    xmlSchemaPErr(ctxt, completeWild->node,
13668: 		XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
13669: 		"The union of the wilcard is not expressible.\n",
13670: 		NULL, NULL);
13671: 	    return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
13672: 	} else if ((!nsFound) && (!absentFound)) {
13673: 	    /*
13674: 	    * 5.4 If the set S does not include either the negated namespace
13675: 	    * name or �absent�, then whichever of O1 or O2 is a pair of not
13676: 	    * and a namespace name must be the value.
13677: 	    */
13678: 	    if (completeWild->negNsSet == NULL) {
13679: 		if (completeWild->nsSet != NULL) {
13680: 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13681: 		    completeWild->nsSet = NULL;
13682: 		}
13683: 		completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13684: 		if (completeWild->negNsSet == NULL)
13685: 		    return (-1);
13686: 		completeWild->negNsSet->value = curWild->negNsSet->value;
13687: 	    }
13688: 	}
13689: 	return (0);
13690:     }
13691:     /*
13692:      * 6.
13693:      */
13694:     if (((completeWild->negNsSet != NULL) &&
13695: 	(completeWild->negNsSet->value == NULL) &&
13696: 	(curWild->nsSet != NULL)) ||
13697: 	((curWild->negNsSet != NULL) &&
13698: 	(curWild->negNsSet->value == NULL) &&
13699: 	(completeWild->nsSet != NULL))) {
13700: 
13701: 	if (completeWild->nsSet != NULL) {
13702: 	    cur = completeWild->nsSet;
13703: 	} else {
13704: 	    cur = curWild->nsSet;
13705: 	}
13706: 	while (cur != NULL) {
13707: 	    if (cur->value == NULL) {
13708: 		/*
13709: 		* 6.1 If the set S includes �absent�, then any must be the
13710: 		* value.
13711: 		*/
13712: 		completeWild->any = 1;
13713: 		if (completeWild->nsSet != NULL) {
13714: 		    xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13715: 		    completeWild->nsSet = NULL;
13716: 		}
13717: 		if (completeWild->negNsSet != NULL) {
13718: 		    xmlFree(completeWild->negNsSet);
13719: 		    completeWild->negNsSet = NULL;
13720: 		}
13721: 		return (0);
13722: 	    }
13723: 	    cur = cur->next;
13724: 	}
13725: 	if (completeWild->negNsSet == NULL) {
13726: 	    /*
13727: 	    * 6.2 If the set S does not include �absent�, then a pair of not
13728: 	    * and �absent� must be the value.
13729: 	    */
13730: 	    if (completeWild->nsSet != NULL) {
13731: 		xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
13732: 		completeWild->nsSet = NULL;
13733: 	    }
13734: 	    completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
13735: 	    if (completeWild->negNsSet == NULL)
13736: 		return (-1);
13737: 	    completeWild->negNsSet->value = NULL;
13738: 	}
13739: 	return (0);
13740:     }
13741:     return (0);
13742: 
13743: }
13744: 
13745: /**
13746:  * xmlSchemaIntersectWildcards:
13747:  * @ctxt:  the schema parser context
13748:  * @completeWild:  the first wildcard
13749:  * @curWild: the second wildcard
13750:  *
13751:  * Intersects the namespace constraints of the given wildcards.
13752:  * @completeWild will hold the resulting intersection.
13753:  * Returns a positive error code on failure, -1 in case of an
13754:  * internal error, 0 otherwise.
13755:  */
13756: static int
13757: xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
13758: 			    xmlSchemaWildcardPtr completeWild,
13759: 			    xmlSchemaWildcardPtr curWild)
13760: {
13761:     xmlSchemaWildcardNsPtr cur, curB, prev,  tmp;
13762: 
13763:     /*
13764:     * 1 If O1 and O2 are the same value, then that value must be the
13765:     * value.
13766:     */
13767:     if ((completeWild->any == curWild->any) &&
13768: 	((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
13769: 	((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
13770: 
13771: 	if ((completeWild->negNsSet == NULL) ||
13772: 	    (completeWild->negNsSet->value == curWild->negNsSet->value)) {
13773: 
13774: 	    if (completeWild->nsSet != NULL) {
13775: 		int found = 0;
13776: 
13777: 		/*
13778: 		* Check equality of sets.
13779: 		*/
13780: 		cur = completeWild->nsSet;
13781: 		while (cur != NULL) {
13782: 		    found = 0;
13783: 		    curB = curWild->nsSet;
13784: 		    while (curB != NULL) {
13785: 			if (cur->value == curB->value) {
13786: 			    found = 1;
13787: 			    break;
13788: 			}
13789: 			curB = curB->next;
13790: 		    }
13791: 		    if (!found)
13792: 			break;
13793: 		    cur = cur->next;
13794: 		}
13795: 		if (found)
13796: 		    return(0);
13797: 	    } else
13798: 		return(0);
13799: 	}
13800:     }
13801:     /*
13802:     * 2 If either O1 or O2 is any, then the other must be the value.
13803:     */
13804:     if ((completeWild->any != curWild->any) && (completeWild->any)) {
13805: 	if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13806: 	    return(-1);
13807: 	return(0);
13808:     }
13809:     /*
13810:     * 3 If either O1 or O2 is a pair of not and a value (a namespace
13811:     * name or �absent�) and the other is a set of (namespace names or
13812:     * �absent�), then that set, minus the negated value if it was in
13813:     * the set, minus �absent� if it was in the set, must be the value.
13814:     */
13815:     if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
13816: 	((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
13817: 	const xmlChar *neg;
13818: 
13819: 	if (completeWild->nsSet == NULL) {
13820: 	    neg = completeWild->negNsSet->value;
13821: 	    if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
13822: 		return(-1);
13823: 	} else
13824: 	    neg = curWild->negNsSet->value;
13825: 	/*
13826: 	* Remove absent and negated.
13827: 	*/
13828: 	prev = NULL;
13829: 	cur = completeWild->nsSet;
13830: 	while (cur != NULL) {
13831: 	    if (cur->value == NULL) {
13832: 		if (prev == NULL)
13833: 		    completeWild->nsSet = cur->next;
13834: 		else
13835: 		    prev->next = cur->next;
13836: 		xmlFree(cur);
13837: 		break;
13838: 	    }
13839: 	    prev = cur;
13840: 	    cur = cur->next;
13841: 	}
13842: 	if (neg != NULL) {
13843: 	    prev = NULL;
13844: 	    cur = completeWild->nsSet;
13845: 	    while (cur != NULL) {
13846: 		if (cur->value == neg) {
13847: 		    if (prev == NULL)
13848: 			completeWild->nsSet = cur->next;
13849: 		    else
13850: 			prev->next = cur->next;
13851: 		    xmlFree(cur);
13852: 		    break;
13853: 		}
13854: 		prev = cur;
13855: 		cur = cur->next;
13856: 	    }
13857: 	}
13858: 
13859: 	return(0);
13860:     }
13861:     /*
13862:     * 4 If both O1 and O2 are sets of (namespace names or �absent�),
13863:     * then the intersection of those sets must be the value.
13864:     */
13865:     if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
13866: 	int found;
13867: 
13868: 	cur = completeWild->nsSet;
13869: 	prev = NULL;
13870: 	while (cur != NULL) {
13871: 	    found = 0;
13872: 	    curB = curWild->nsSet;
13873: 	    while (curB != NULL) {
13874: 		if (cur->value == curB->value) {
13875: 		    found = 1;
13876: 		    break;
13877: 		}
13878: 		curB = curB->next;
13879: 	    }
13880: 	    if (!found) {
13881: 		if (prev == NULL)
13882: 		    completeWild->nsSet = cur->next;
13883: 		else
13884: 		    prev->next = cur->next;
13885: 		tmp = cur->next;
13886: 		xmlFree(cur);
13887: 		cur = tmp;
13888: 		continue;
13889: 	    }
13890: 	    prev = cur;
13891: 	    cur = cur->next;
13892: 	}
13893: 
13894: 	return(0);
13895:     }
13896:     /* 5 If the two are negations of different namespace names,
13897:     * then the intersection is not expressible
13898:     */
13899:     if ((completeWild->negNsSet != NULL) &&
13900: 	(curWild->negNsSet != NULL) &&
13901: 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13902: 	(completeWild->negNsSet->value != NULL) &&
13903: 	(curWild->negNsSet->value != NULL)) {
13904: 
13905: 	xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
13906: 	    "The intersection of the wilcard is not expressible.\n",
13907: 	    NULL, NULL);
13908: 	return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
13909:     }
13910:     /*
13911:     * 6 If the one is a negation of a namespace name and the other
13912:     * is a negation of �absent�, then the one which is the negation
13913:     * of a namespace name must be the value.
13914:     */
13915:     if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
13916: 	(completeWild->negNsSet->value != curWild->negNsSet->value) &&
13917: 	(completeWild->negNsSet->value == NULL)) {
13918: 	completeWild->negNsSet->value =  curWild->negNsSet->value;
13919:     }
13920:     return(0);
13921: }
13922: 
13923: /**
13924:  * xmlSchemaIsWildcardNsConstraintSubset:
13925:  * @ctxt:  the schema parser context
13926:  * @sub:  the first wildcard
13927:  * @super: the second wildcard
13928:  *
13929:  * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
13930:  *
13931:  * Returns 0 if the namespace constraint of @sub is an intensional
13932:  * subset of @super, 1 otherwise.
13933:  */
13934: static int
13935: xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
13936: 			  xmlSchemaWildcardPtr super)
13937: {
13938:     /*
13939:     * 1 super must be any.
13940:     */
13941:     if (super->any)
13942: 	return (0);
13943:     /*
13944:     * 2.1 sub must be a pair of not and a namespace name or �absent�.
13945:     * 2.2 super must be a pair of not and the same value.
13946:     */
13947:     if ((sub->negNsSet != NULL) &&
13948: 	(super->negNsSet != NULL) &&
13949: 	(sub->negNsSet->value == super->negNsSet->value))
13950: 	return (0);
13951:     /*
13952:     * 3.1 sub must be a set whose members are either namespace names or �absent�.
13953:     */
13954:     if (sub->nsSet != NULL) {
13955: 	/*
13956: 	* 3.2.1 super must be the same set or a superset thereof.
13957: 	*/
13958: 	if (super->nsSet != NULL) {
13959: 	    xmlSchemaWildcardNsPtr cur, curB;
13960: 	    int found = 0;
13961: 
13962: 	    cur = sub->nsSet;
13963: 	    while (cur != NULL) {
13964: 		found = 0;
13965: 		curB = super->nsSet;
13966: 		while (curB != NULL) {
13967: 		    if (cur->value == curB->value) {
13968: 			found = 1;
13969: 			break;
13970: 		    }
13971: 		    curB = curB->next;
13972: 		}
13973: 		if (!found)
13974: 		    return (1);
13975: 		cur = cur->next;
13976: 	    }
13977: 	    if (found)
13978: 		return (0);
13979: 	} else if (super->negNsSet != NULL) {
13980: 	    xmlSchemaWildcardNsPtr cur;
13981: 	    /*
13982: 	    * 3.2.2 super must be a pair of not and a namespace name or
13983: 	    * �absent� and that value must not be in sub's set.
13984: 	    */
13985: 	    cur = sub->nsSet;
13986: 	    while (cur != NULL) {
13987: 		if (cur->value == super->negNsSet->value)
13988: 		    return (1);
13989: 		cur = cur->next;
13990: 	    }
13991: 	    return (0);
13992: 	}
13993:     }
13994:     return (1);
13995: }
13996: 
13997: static int
13998: xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
13999: 				     int *fixed,
14000: 				     const xmlChar **value,
14001: 				     xmlSchemaValPtr *val)
14002: {
14003:     *fixed = 0;
14004:     *value = NULL;
14005:     if (val != 0)
14006: 	*val = NULL;
14007: 
14008:     if (attruse->defValue != NULL) {
14009: 	*value = attruse->defValue;
14010: 	if (val != NULL)
14011: 	    *val = attruse->defVal;
14012: 	if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
14013: 	    *fixed = 1;
14014: 	return(1);
14015:     } else if ((attruse->attrDecl != NULL) &&
14016: 	(attruse->attrDecl->defValue != NULL)) {
14017: 	*value = attruse->attrDecl->defValue;
14018: 	if (val != NULL)
14019: 	    *val = attruse->attrDecl->defVal;
14020: 	if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
14021: 	    *fixed = 1;
14022: 	return(1);
14023:     }
14024:     return(0);
14025: }
14026: /**
14027:  * xmlSchemaCheckCVCWildcardNamespace:
14028:  * @wild:  the wildcard
14029:  * @ns:  the namespace
14030:  *
14031:  * Validation Rule: Wildcard allows Namespace Name
14032:  * (cvc-wildcard-namespace)
14033:  *
14034:  * Returns 0 if the given namespace matches the wildcard,
14035:  * 1 otherwise and -1 on API errors.
14036:  */
14037: static int
14038: xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
14039: 				   const xmlChar* ns)
14040: {
14041:     if (wild == NULL)
14042: 	return(-1);
14043: 
14044:     if (wild->any)
14045: 	return(0);
14046:     else if (wild->nsSet != NULL) {
14047: 	xmlSchemaWildcardNsPtr cur;
14048: 
14049: 	cur = wild->nsSet;
14050: 	while (cur != NULL) {
14051: 	    if (xmlStrEqual(cur->value, ns))
14052: 		return(0);
14053: 	    cur = cur->next;
14054: 	}
14055:     } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
14056: 	(!xmlStrEqual(wild->negNsSet->value, ns)))
14057: 	return(0);
14058: 
14059:     return(1);
14060: }
14061: 
14062: #define XML_SCHEMA_ACTION_DERIVE 0
14063: #define XML_SCHEMA_ACTION_REDEFINE 1
14064: 
14065: #define WXS_ACTION_STR(a) \
14066: ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
14067: 
14068: /*
14069: * Schema Component Constraint:
14070: *   Derivation Valid (Restriction, Complex)
14071: *   derivation-ok-restriction (2) - (4)
14072: *
14073: * ATTENTION:
14074: * In XML Schema 1.1 this will be:
14075: * Validation Rule:
14076: *     Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
14077: *
14078: */
14079: static int
14080: xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
14081: 				       int action,
14082: 				       xmlSchemaBasicItemPtr item,
14083: 				       xmlSchemaBasicItemPtr baseItem,
14084: 				       xmlSchemaItemListPtr uses,
14085: 				       xmlSchemaItemListPtr baseUses,
14086: 				       xmlSchemaWildcardPtr wild,
14087: 				       xmlSchemaWildcardPtr baseWild)
14088: {
14089:     xmlSchemaAttributeUsePtr cur = NULL, bcur;
14090:     int i, j, found; /* err = 0; */
14091:     const xmlChar *bEffValue;
14092:     int effFixed;
14093: 
14094:     if (uses != NULL) {
14095: 	for (i = 0; i < uses->nbItems; i++) {
14096: 	    cur = uses->items[i];
14097: 	    found = 0;
14098: 	    if (baseUses == NULL)
14099: 		goto not_found;
14100: 	    for (j = 0; j < baseUses->nbItems; j++) {
14101: 		bcur = baseUses->items[j];
14102: 		if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14103: 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
14104: 		    (WXS_ATTRUSE_DECL_TNS(cur) ==
14105: 			WXS_ATTRUSE_DECL_TNS(bcur)))
14106: 		{
14107: 		    /*
14108: 		    * (2.1) "If there is an attribute use in the {attribute
14109: 		    * uses} of the {base type definition} (call this B) whose
14110: 		    * {attribute declaration} has the same {name} and {target
14111: 		    * namespace}, then  all of the following must be true:"
14112: 		    */
14113: 		    found = 1;
14114: 
14115: 		    if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
14116: 			(bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
14117: 		    {
14118: 			xmlChar *str = NULL;
14119: 			/*
14120: 			* (2.1.1) "one of the following must be true:"
14121: 			* (2.1.1.1) "B's {required} is false."
14122: 			* (2.1.1.2) "R's {required} is true."
14123: 			*/
14124: 			xmlSchemaPAttrUseErr4(pctxt,
14125: 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
14126: 			    WXS_ITEM_NODE(item), item, cur,
14127: 			    "The 'optional' attribute use is inconsistent "
14128: 			    "with the corresponding 'required' attribute use of "
14129: 			    "the %s %s",
14130: 			    WXS_ACTION_STR(action),
14131: 			    xmlSchemaGetComponentDesignation(&str, baseItem),
14132: 			    NULL, NULL);
14133: 			FREE_AND_NULL(str);
14134: 			/* err = pctxt->err; */
14135: 		    } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
14136: 			WXS_ATTRUSE_TYPEDEF(cur),
14137: 			WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
14138: 		    {
14139: 			xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
14140: 
14141: 			/*
14142: 			* SPEC (2.1.2) "R's {attribute declaration}'s
14143: 			* {type definition} must be validly derived from
14144: 			* B's {type definition} given the empty set as
14145: 			* defined in Type Derivation OK (Simple) (�3.14.6)."
14146: 			*/
14147: 			xmlSchemaPAttrUseErr4(pctxt,
14148: 			    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
14149: 			    WXS_ITEM_NODE(item), item, cur,
14150: 			    "The attribute declaration's %s "
14151: 			    "is not validly derived from "
14152: 			    "the corresponding %s of the "
14153: 			    "attribute declaration in the %s %s",
14154: 			    xmlSchemaGetComponentDesignation(&strA,
14155: 				WXS_ATTRUSE_TYPEDEF(cur)),
14156: 			    xmlSchemaGetComponentDesignation(&strB,
14157: 				WXS_ATTRUSE_TYPEDEF(bcur)),
14158: 			    WXS_ACTION_STR(action),
14159: 			    xmlSchemaGetComponentDesignation(&strC, baseItem));
14160: 			    /* xmlSchemaGetComponentDesignation(&str, baseItem), */
14161: 			FREE_AND_NULL(strA);
14162: 			FREE_AND_NULL(strB);
14163: 			FREE_AND_NULL(strC);
14164: 			/* err = pctxt->err; */
14165: 		    } else {
14166: 			/*
14167: 			* 2.1.3 [Definition:]  Let the effective value
14168: 			* constraint of an attribute use be its {value
14169: 			* constraint}, if present, otherwise its {attribute
14170: 			* declaration}'s {value constraint} .
14171: 			*/
14172: 			xmlSchemaGetEffectiveValueConstraint(bcur,
14173: 			    &effFixed, &bEffValue, NULL);
14174: 			/*
14175: 			* 2.1.3 ... one of the following must be true
14176: 			*
14177: 			* 2.1.3.1 B's �effective value constraint� is
14178: 			* �absent� or default.
14179: 			*/
14180: 			if ((bEffValue != NULL) &&
14181: 			    (effFixed == 1)) {
14182: 			    const xmlChar *rEffValue = NULL;
14183: 
14184: 			    xmlSchemaGetEffectiveValueConstraint(bcur,
14185: 				&effFixed, &rEffValue, NULL);
14186: 			    /*
14187: 			    * 2.1.3.2 R's �effective value constraint� is
14188: 			    * fixed with the same string as B's.
14189: 			    * MAYBE TODO: Compare the computed values.
14190: 			    *       Hmm, it says "same string" so
14191: 			    *       string-equality might really be sufficient.
14192: 			    */
14193: 			    if ((effFixed == 0) ||
14194: 				(! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
14195: 			    {
14196: 				xmlChar *str = NULL;
14197: 
14198: 				xmlSchemaPAttrUseErr4(pctxt,
14199: 				    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
14200: 				    WXS_ITEM_NODE(item), item, cur,
14201: 				    "The effective value constraint of the "
14202: 				    "attribute use is inconsistent with "
14203: 				    "its correspondent in the %s %s",
14204: 				    WXS_ACTION_STR(action),
14205: 				    xmlSchemaGetComponentDesignation(&str,
14206: 					baseItem),
14207: 				    NULL, NULL);
14208: 				FREE_AND_NULL(str);
14209: 				/* err = pctxt->err; */
14210: 			    }
14211: 			}
14212: 		    }
14213: 		    break;
14214: 		}
14215: 	    }
14216: not_found:
14217: 	    if (!found) {
14218: 		/*
14219: 		* (2.2) "otherwise the {base type definition} must have an
14220: 		* {attribute wildcard} and the {target namespace} of the
14221: 		* R's {attribute declaration} must be �valid� with respect
14222: 		* to that wildcard, as defined in Wildcard allows Namespace
14223: 		* Name (�3.10.4)."
14224: 		*/
14225: 		if ((baseWild == NULL) ||
14226: 		    (xmlSchemaCheckCVCWildcardNamespace(baseWild,
14227: 		    (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
14228: 		{
14229: 		    xmlChar *str = NULL;
14230: 
14231: 		    xmlSchemaPAttrUseErr4(pctxt,
14232: 			XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
14233: 			WXS_ITEM_NODE(item), item, cur,
14234: 			"Neither a matching attribute use, "
14235: 			"nor a matching wildcard exists in the %s %s",
14236: 			WXS_ACTION_STR(action),
14237: 			xmlSchemaGetComponentDesignation(&str, baseItem),
14238: 			NULL, NULL);
14239: 		    FREE_AND_NULL(str);
14240: 		    /* err = pctxt->err; */
14241: 		}
14242: 	    }
14243: 	}
14244:     }
14245:     /*
14246:     * SPEC derivation-ok-restriction (3):
14247:     * (3) "For each attribute use in the {attribute uses} of the {base type
14248:     * definition} whose {required} is true, there must be an attribute
14249:     * use with an {attribute declaration} with the same {name} and
14250:     * {target namespace} as its {attribute declaration} in the {attribute
14251:     * uses} of the complex type definition itself whose {required} is true.
14252:     */
14253:     if (baseUses != NULL) {
14254: 	for (j = 0; j < baseUses->nbItems; j++) {
14255: 	    bcur = baseUses->items[j];
14256: 	    if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
14257: 		continue;
14258: 	    found = 0;
14259: 	    if (uses != NULL) {
14260: 		for (i = 0; i < uses->nbItems; i++) {
14261: 		    cur = uses->items[i];
14262: 		    if ((WXS_ATTRUSE_DECL_NAME(cur) ==
14263: 			WXS_ATTRUSE_DECL_NAME(bcur)) &&
14264: 			(WXS_ATTRUSE_DECL_TNS(cur) ==
14265: 			WXS_ATTRUSE_DECL_TNS(bcur))) {
14266: 			found = 1;
14267: 			break;
14268: 		    }
14269: 		}
14270: 	    }
14271: 	    if (!found) {
14272: 		xmlChar *strA = NULL, *strB = NULL;
14273: 
14274: 		xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14275: 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
14276: 		    NULL, item,
14277: 		    "A matching attribute use for the "
14278: 		    "'required' %s of the %s %s is missing",
14279: 		    xmlSchemaGetComponentDesignation(&strA, bcur),
14280: 		    WXS_ACTION_STR(action),
14281: 		    xmlSchemaGetComponentDesignation(&strB, baseItem),
14282: 		    NULL);
14283: 		FREE_AND_NULL(strA);
14284: 		FREE_AND_NULL(strB);
14285: 	    }
14286: 	}
14287:     }
14288:     /*
14289:     * derivation-ok-restriction (4)
14290:     */
14291:     if (wild != NULL) {
14292: 	/*
14293: 	* (4) "If there is an {attribute wildcard}, all of the
14294: 	* following must be true:"
14295: 	*/
14296: 	if (baseWild == NULL) {
14297: 	    xmlChar *str = NULL;
14298: 
14299: 	    /*
14300: 	    * (4.1) "The {base type definition} must also have one."
14301: 	    */
14302: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14303: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
14304: 		NULL, item,
14305: 		"The %s has an attribute wildcard, "
14306: 		"but the %s %s '%s' does not have one",
14307: 		WXS_ITEM_TYPE_NAME(item),
14308: 		WXS_ACTION_STR(action),
14309: 		WXS_ITEM_TYPE_NAME(baseItem),
14310: 		xmlSchemaGetComponentQName(&str, baseItem));
14311: 	    FREE_AND_NULL(str);
14312: 	    return(pctxt->err);
14313: 	} else if ((baseWild->any == 0) &&
14314: 		xmlSchemaCheckCOSNSSubset(wild, baseWild))
14315: 	{
14316: 	    xmlChar *str = NULL;
14317: 	    /*
14318: 	    * (4.2) "The complex type definition's {attribute wildcard}'s
14319: 	    * {namespace constraint} must be a subset of the {base type
14320: 	    * definition}'s {attribute wildcard}'s {namespace constraint},
14321: 	    * as defined by Wildcard Subset (�3.10.6)."
14322: 	    */
14323: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14324: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
14325: 		NULL, item,
14326: 		"The attribute wildcard is not a valid "
14327: 		"subset of the wildcard in the %s %s '%s'",
14328: 		WXS_ACTION_STR(action),
14329: 		WXS_ITEM_TYPE_NAME(baseItem),
14330: 		xmlSchemaGetComponentQName(&str, baseItem),
14331: 		NULL);
14332: 	    FREE_AND_NULL(str);
14333: 	    return(pctxt->err);
14334: 	}
14335: 	/* 4.3 Unless the {base type definition} is the �ur-type
14336: 	* definition�, the complex type definition's {attribute
14337: 	* wildcard}'s {process contents} must be identical to or
14338: 	* stronger than the {base type definition}'s {attribute
14339: 	* wildcard}'s {process contents}, where strict is stronger
14340: 	* than lax is stronger than skip.
14341: 	*/
14342: 	if ((! WXS_IS_ANYTYPE(baseItem)) &&
14343: 	    (wild->processContents < baseWild->processContents)) {
14344: 	    xmlChar *str = NULL;
14345: 	    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
14346: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
14347: 		NULL, baseItem,
14348: 		"The {process contents} of the attribute wildcard is "
14349: 		"weaker than the one in the %s %s '%s'",
14350: 		WXS_ACTION_STR(action),
14351: 		WXS_ITEM_TYPE_NAME(baseItem),
14352: 		xmlSchemaGetComponentQName(&str, baseItem),
14353: 		NULL);
14354: 	    FREE_AND_NULL(str)
14355: 		return(pctxt->err);
14356: 	}
14357:     }
14358:     return(0);
14359: }
14360: 
14361: 
14362: static int
14363: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
14364: 				  xmlSchemaBasicItemPtr item,
14365: 				  xmlSchemaWildcardPtr *completeWild,
14366: 				  xmlSchemaItemListPtr list,
14367: 				  xmlSchemaItemListPtr prohibs);
14368: /**
14369:  * xmlSchemaFixupTypeAttributeUses:
14370:  * @ctxt:  the schema parser context
14371:  * @type:  the complex type definition
14372:  *
14373:  *
14374:  * Builds the wildcard and the attribute uses on the given complex type.
14375:  * Returns -1 if an internal error occurs, 0 otherwise.
14376:  *
14377:  * ATTENTION TODO: Experimantally this uses pointer comparisons for
14378:  * strings, so recheck this if we start to hardcode some schemata, since
14379:  * they might not be in the same dict.
14380:  * NOTE: It is allowed to "extend" the xs:anyType type.
14381:  */
14382: static int
14383: xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
14384: 				  xmlSchemaTypePtr type)
14385: {
14386:     xmlSchemaTypePtr baseType = NULL;
14387:     xmlSchemaAttributeUsePtr use;
14388:     xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
14389: 
14390:     if (type->baseType == NULL) {
14391: 	PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14392: 	    "no base type");
14393:         return (-1);
14394:     }
14395:     baseType = type->baseType;
14396:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
14397: 	if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
14398: 	    return(-1);
14399: 
14400:     uses = type->attrUses;
14401:     baseUses = baseType->attrUses;
14402:     /*
14403:     * Expand attribute group references. And build the 'complete'
14404:     * wildcard, i.e. intersect multiple wildcards.
14405:     * Move attribute prohibitions into a separate list.
14406:     */
14407:     if (uses != NULL) {
14408: 	if (WXS_IS_RESTRICTION(type)) {
14409: 	    /*
14410: 	    * This one will transfer all attr. prohibitions
14411: 	    * into pctxt->attrProhibs.
14412: 	    */
14413: 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14414: 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14415: 		pctxt->attrProhibs) == -1)
14416: 	    {
14417: 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14418: 		"failed to expand attributes");
14419: 	    }
14420: 	    if (pctxt->attrProhibs->nbItems != 0)
14421: 		prohibs = pctxt->attrProhibs;
14422: 	} else {
14423: 	    if (xmlSchemaExpandAttributeGroupRefs(pctxt,
14424: 		WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
14425: 		NULL) == -1)
14426: 	    {
14427: 		PERROR_INT("xmlSchemaFixupTypeAttributeUses",
14428: 		"failed to expand attributes");
14429: 	    }
14430: 	}
14431:     }
14432:     /*
14433:     * Inherit the attribute uses of the base type.
14434:     */
14435:     if (baseUses != NULL) {
14436: 	int i, j;
14437: 	xmlSchemaAttributeUseProhibPtr pro;
14438: 
14439: 	if (WXS_IS_RESTRICTION(type)) {
14440: 	    int usesCount;
14441: 	    xmlSchemaAttributeUsePtr tmp;
14442: 
14443: 	    if (uses != NULL)
14444: 		usesCount = uses->nbItems;
14445: 	    else
14446: 		usesCount = 0;
14447: 
14448: 	    /* Restriction. */
14449: 	    for (i = 0; i < baseUses->nbItems; i++) {
14450: 		use = baseUses->items[i];
14451: 		if (prohibs) {
14452: 		    /*
14453: 		    * Filter out prohibited uses.
14454: 		    */
14455: 		    for (j = 0; j < prohibs->nbItems; j++) {
14456: 			pro = prohibs->items[j];
14457: 			if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
14458: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
14459: 				pro->targetNamespace))
14460: 			{
14461: 			    goto inherit_next;
14462: 			}
14463: 		    }
14464: 		}
14465: 		if (usesCount) {
14466: 		    /*
14467: 		    * Filter out existing uses.
14468: 		    */
14469: 		    for (j = 0; j < usesCount; j++) {
14470: 			tmp = uses->items[j];
14471: 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
14472: 				WXS_ATTRUSE_DECL_NAME(tmp)) &&
14473: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
14474: 				WXS_ATTRUSE_DECL_TNS(tmp)))
14475: 			{
14476: 			    goto inherit_next;
14477: 			}
14478: 		    }
14479: 		}
14480: 		if (uses == NULL) {
14481: 		    type->attrUses = xmlSchemaItemListCreate();
14482: 		    if (type->attrUses == NULL)
14483: 			goto exit_failure;
14484: 		    uses = type->attrUses;
14485: 		}
14486: 		xmlSchemaItemListAddSize(uses, 2, use);
14487: inherit_next: {}
14488: 	    }
14489: 	} else {
14490: 	    /* Extension. */
14491: 	    for (i = 0; i < baseUses->nbItems; i++) {
14492: 		use = baseUses->items[i];
14493: 		if (uses == NULL) {
14494: 		    type->attrUses = xmlSchemaItemListCreate();
14495: 		    if (type->attrUses == NULL)
14496: 			goto exit_failure;
14497: 		    uses = type->attrUses;
14498: 		}
14499: 		xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
14500: 	    }
14501: 	}
14502:     }
14503:     /*
14504:     * Shrink attr. uses.
14505:     */
14506:     if (uses) {
14507: 	if (uses->nbItems == 0) {
14508: 	    xmlSchemaItemListFree(uses);
14509: 	    type->attrUses = NULL;
14510: 	}
14511: 	/*
14512: 	* TODO: We could shrink the size of the array
14513: 	* to fit the actual number of items.
14514: 	*/
14515:     }
14516:     /*
14517:     * Compute the complete wildcard.
14518:     */
14519:     if (WXS_IS_EXTENSION(type)) {
14520: 	if (baseType->attributeWildcard != NULL) {
14521: 	    /*
14522: 	    * (3.2.2.1) "If the �base wildcard� is non-�absent�, then
14523: 	    * the appropriate case among the following:"
14524: 	    */
14525: 	    if (type->attributeWildcard != NULL) {
14526: 		/*
14527: 		* Union the complete wildcard with the base wildcard.
14528: 		* SPEC {attribute wildcard}
14529: 		* (3.2.2.1.2) "otherwise a wildcard whose {process contents}
14530: 		* and {annotation} are those of the �complete wildcard�,
14531: 		* and whose {namespace constraint} is the intensional union
14532: 		* of the {namespace constraint} of the �complete wildcard�
14533: 		* and of the �base wildcard�, as defined in Attribute
14534: 		* Wildcard Union (�3.10.6)."
14535: 		*/
14536: 		if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
14537: 		    baseType->attributeWildcard) == -1)
14538: 		    goto exit_failure;
14539: 	    } else {
14540: 		/*
14541: 		* (3.2.2.1.1) "If the �complete wildcard� is �absent�,
14542: 		* then the �base wildcard�."
14543: 		*/
14544: 		type->attributeWildcard = baseType->attributeWildcard;
14545: 	    }
14546: 	} else {
14547: 	    /*
14548: 	    * (3.2.2.2) "otherwise (the �base wildcard� is �absent�) the
14549: 	    * �complete wildcard"
14550: 	    * NOOP
14551: 	    */
14552: 	}
14553:     } else {
14554: 	/*
14555: 	* SPEC {attribute wildcard}
14556: 	* (3.1) "If the <restriction> alternative is chosen, then the
14557: 	* �complete wildcard�;"
14558: 	* NOOP
14559: 	*/
14560:     }
14561: 
14562:     return (0);
14563: 
14564: exit_failure:
14565:     return(-1);
14566: }
14567: 
14568: /**
14569:  * xmlSchemaTypeFinalContains:
14570:  * @schema:  the schema
14571:  * @type:  the type definition
14572:  * @final: the final
14573:  *
14574:  * Evaluates if a type definition contains the given "final".
14575:  * This does take "finalDefault" into account as well.
14576:  *
14577:  * Returns 1 if the type does containt the given "final",
14578:  * 0 otherwise.
14579:  */
14580: static int
14581: xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
14582: {
14583:     if (type == NULL)
14584: 	return (0);
14585:     if (type->flags & final)
14586: 	return (1);
14587:     else
14588: 	return (0);
14589: }
14590: 
14591: /**
14592:  * xmlSchemaGetUnionSimpleTypeMemberTypes:
14593:  * @type:  the Union Simple Type
14594:  *
14595:  * Returns a list of member types of @type if existing,
14596:  * returns NULL otherwise.
14597:  */
14598: static xmlSchemaTypeLinkPtr
14599: xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
14600: {
14601:     while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
14602: 	if (type->memberTypes != NULL)
14603: 	    return (type->memberTypes);
14604: 	else
14605: 	    type = type->baseType;
14606:     }
14607:     return (NULL);
14608: }
14609: 
14610: /**
14611:  * xmlSchemaGetParticleTotalRangeMin:
14612:  * @particle: the particle
14613:  *
14614:  * Schema Component Constraint: Effective Total Range
14615:  * (all and sequence) + (choice)
14616:  *
14617:  * Returns the minimun Effective Total Range.
14618:  */
14619: static int
14620: xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
14621: {
14622:     if ((particle->children == NULL) ||
14623: 	(particle->minOccurs == 0))
14624: 	return (0);
14625:     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14626: 	int min = -1, cur;
14627: 	xmlSchemaParticlePtr part =
14628: 	    (xmlSchemaParticlePtr) particle->children->children;
14629: 
14630: 	if (part == NULL)
14631: 	    return (0);
14632: 	while (part != NULL) {
14633: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14634: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14635: 		cur = part->minOccurs;
14636: 	    else
14637: 		cur = xmlSchemaGetParticleTotalRangeMin(part);
14638: 	    if (cur == 0)
14639: 		return (0);
14640: 	    if ((min > cur) || (min == -1))
14641: 		min = cur;
14642: 	    part = (xmlSchemaParticlePtr) part->next;
14643: 	}
14644: 	return (particle->minOccurs * min);
14645:     } else {
14646: 	/* <all> and <sequence> */
14647: 	int sum = 0;
14648: 	xmlSchemaParticlePtr part =
14649: 	    (xmlSchemaParticlePtr) particle->children->children;
14650: 
14651: 	if (part == NULL)
14652: 	    return (0);
14653: 	do {
14654: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14655: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14656: 		sum += part->minOccurs;
14657: 	    else
14658: 		sum += xmlSchemaGetParticleTotalRangeMin(part);
14659: 	    part = (xmlSchemaParticlePtr) part->next;
14660: 	} while (part != NULL);
14661: 	return (particle->minOccurs * sum);
14662:     }
14663: }
14664: 
14665: #if 0
14666: /**
14667:  * xmlSchemaGetParticleTotalRangeMax:
14668:  * @particle: the particle
14669:  *
14670:  * Schema Component Constraint: Effective Total Range
14671:  * (all and sequence) + (choice)
14672:  *
14673:  * Returns the maximum Effective Total Range.
14674:  */
14675: static int
14676: xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
14677: {
14678:     if ((particle->children == NULL) ||
14679: 	(particle->children->children == NULL))
14680: 	return (0);
14681:     if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
14682: 	int max = -1, cur;
14683: 	xmlSchemaParticlePtr part =
14684: 	    (xmlSchemaParticlePtr) particle->children->children;
14685: 
14686: 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14687: 	    if (part->children == NULL)
14688: 		continue;
14689: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14690: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14691: 		cur = part->maxOccurs;
14692: 	    else
14693: 		cur = xmlSchemaGetParticleTotalRangeMax(part);
14694: 	    if (cur == UNBOUNDED)
14695: 		return (UNBOUNDED);
14696: 	    if ((max < cur) || (max == -1))
14697: 		max = cur;
14698: 	}
14699: 	/* TODO: Handle overflows? */
14700: 	return (particle->maxOccurs * max);
14701:     } else {
14702: 	/* <all> and <sequence> */
14703: 	int sum = 0, cur;
14704: 	xmlSchemaParticlePtr part =
14705: 	    (xmlSchemaParticlePtr) particle->children->children;
14706: 
14707: 	for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
14708: 	    if (part->children == NULL)
14709: 		continue;
14710: 	    if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
14711: 		(part->children->type == XML_SCHEMA_TYPE_ANY))
14712: 		cur = part->maxOccurs;
14713: 	    else
14714: 		cur = xmlSchemaGetParticleTotalRangeMax(part);
14715: 	    if (cur == UNBOUNDED)
14716: 		return (UNBOUNDED);
14717: 	    if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
14718: 		return (UNBOUNDED);
14719: 	    sum += cur;
14720: 	}
14721: 	/* TODO: Handle overflows? */
14722: 	return (particle->maxOccurs * sum);
14723:     }
14724: }
14725: #endif
14726: 
14727: /**
14728:  * xmlSchemaIsParticleEmptiable:
14729:  * @particle: the particle
14730:  *
14731:  * Schema Component Constraint: Particle Emptiable
14732:  * Checks whether the given particle is emptiable.
14733:  *
14734:  * Returns 1 if emptiable, 0 otherwise.
14735:  */
14736: static int
14737: xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
14738: {
14739:     /*
14740:     * SPEC (1) "Its {min occurs} is 0."
14741:     */
14742:     if ((particle == NULL) || (particle->minOccurs == 0) ||
14743: 	(particle->children == NULL))
14744: 	return (1);
14745:     /*
14746:     * SPEC (2) "Its {term} is a group and the minimum part of the
14747:     * effective total range of that group, [...] is 0."
14748:     */
14749:     if (WXS_IS_MODEL_GROUP(particle->children)) {
14750: 	if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
14751: 	    return (1);
14752:     }
14753:     return (0);
14754: }
14755: 
14756: /**
14757:  * xmlSchemaCheckCOSSTDerivedOK:
14758:  * @actxt: a context
14759:  * @type:  the derived simple type definition
14760:  * @baseType:  the base type definition
14761:  * @subset: the subset of ('restriction', ect.)
14762:  *
14763:  * Schema Component Constraint:
14764:  * Type Derivation OK (Simple) (cos-st-derived-OK)
14765:  *
14766:  * Checks wheter @type can be validly
14767:  * derived from @baseType.
14768:  *
14769:  * Returns 0 on success, an positive error code otherwise.
14770:  */
14771: static int
14772: xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
14773: 			     xmlSchemaTypePtr type,
14774: 			     xmlSchemaTypePtr baseType,
14775: 			     int subset)
14776: {
14777:     /*
14778:     * 1 They are the same type definition.
14779:     * TODO: The identy check might have to be more complex than this.
14780:     */
14781:     if (type == baseType)
14782: 	return (0);
14783:     /*
14784:     * 2.1 restriction is not in the subset, or in the {final}
14785:     * of its own {base type definition};
14786:     *
14787:     * NOTE that this will be used also via "xsi:type".
14788:     *
14789:     * TODO: Revise this, it looks strange. How can the "type"
14790:     * not be fixed or *in* fixing?
14791:     */
14792:     if (WXS_IS_TYPE_NOT_FIXED(type))
14793: 	if (xmlSchemaTypeFixup(type, actxt) == -1)
14794: 	    return(-1);
14795:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
14796: 	if (xmlSchemaTypeFixup(baseType, actxt) == -1)
14797: 	    return(-1);
14798:     if ((subset & SUBSET_RESTRICTION) ||
14799: 	(xmlSchemaTypeFinalContains(type->baseType,
14800: 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
14801: 	return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
14802:     }
14803:     /* 2.2 */
14804:     if (type->baseType == baseType) {
14805: 	/*
14806: 	* 2.2.1 D's �base type definition� is B.
14807: 	*/
14808: 	return (0);
14809:     }
14810:     /*
14811:     * 2.2.2 D's �base type definition� is not the �ur-type definition�
14812:     * and is validly derived from B given the subset, as defined by this
14813:     * constraint.
14814:     */
14815:     if ((! WXS_IS_ANYTYPE(type->baseType)) &&
14816: 	(xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
14817: 	    baseType, subset) == 0)) {
14818: 	return (0);
14819:     }
14820:     /*
14821:     * 2.2.3 D's {variety} is list or union and B is the �simple ur-type
14822:     * definition�.
14823:     */
14824:     if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
14825: 	(WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
14826: 	return (0);
14827:     }
14828:     /*
14829:     * 2.2.4 B's {variety} is union and D is validly derived from a type
14830:     * definition in B's {member type definitions} given the subset, as
14831:     * defined by this constraint.
14832:     *
14833:     * NOTE: This seems not to involve built-in types, since there is no
14834:     * built-in Union Simple Type.
14835:     */
14836:     if (WXS_IS_UNION(baseType)) {
14837: 	xmlSchemaTypeLinkPtr cur;
14838: 
14839: 	cur = baseType->memberTypes;
14840: 	while (cur != NULL) {
14841: 	    if (WXS_IS_TYPE_NOT_FIXED(cur->type))
14842: 		if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
14843: 		    return(-1);
14844: 	    if (xmlSchemaCheckCOSSTDerivedOK(actxt,
14845: 		    type, cur->type, subset) == 0)
14846: 	    {
14847: 		/*
14848: 		* It just has to be validly derived from at least one
14849: 		* member-type.
14850: 		*/
14851: 		return (0);
14852: 	    }
14853: 	    cur = cur->next;
14854: 	}
14855:     }
14856:     return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
14857: }
14858: 
14859: /**
14860:  * xmlSchemaCheckTypeDefCircularInternal:
14861:  * @pctxt:  the schema parser context
14862:  * @ctxtType:  the type definition
14863:  * @ancestor: an ancestor of @ctxtType
14864:  *
14865:  * Checks st-props-correct (2) + ct-props-correct (3).
14866:  * Circular type definitions are not allowed.
14867:  *
14868:  * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
14869:  * circular, 0 otherwise.
14870:  */
14871: static int
14872: xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
14873: 			   xmlSchemaTypePtr ctxtType,
14874: 			   xmlSchemaTypePtr ancestor)
14875: {
14876:     int ret;
14877: 
14878:     if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
14879: 	return (0);
14880: 
14881:     if (ctxtType == ancestor) {
14882: 	xmlSchemaPCustomErr(pctxt,
14883: 	    XML_SCHEMAP_ST_PROPS_CORRECT_2,
14884: 	    WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
14885: 	    "The definition is circular", NULL);
14886: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
14887:     }
14888:     if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
14889: 	/*
14890: 	* Avoid inifinite recursion on circular types not yet checked.
14891: 	*/
14892: 	return (0);
14893:     }
14894:     ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
14895:     ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
14896: 	ancestor->baseType);
14897:     ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
14898:     return (ret);
14899: }
14900: 
14901: /**
14902:  * xmlSchemaCheckTypeDefCircular:
14903:  * @item:  the complex/simple type definition
14904:  * @ctxt:  the parser context
14905:  * @name:  the name
14906:  *
14907:  * Checks for circular type definitions.
14908:  */
14909: static void
14910: xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
14911: 			      xmlSchemaParserCtxtPtr ctxt)
14912: {
14913:     if ((item == NULL) ||
14914: 	(item->type == XML_SCHEMA_TYPE_BASIC) ||
14915: 	(item->baseType == NULL))
14916: 	return;
14917:     xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
14918: 	item->baseType);
14919: }
14920: 
14921: /*
14922: * Simple Type Definition Representation OK (src-simple-type) 4
14923: *
14924: * "4 Circular union type definition is disallowed. That is, if the
14925: * <union> alternative is chosen, there must not be any entries in the
14926: * memberTypes [attribute] at any depth which resolve to the component
14927: * corresponding to the <simpleType>."
14928: *
14929: * Note that this should work on the *representation* of a component,
14930: * thus assumes any union types in the member types not being yet
14931: * substituted. At this stage we need the variety of the types
14932: * to be already computed.
14933: */
14934: static int
14935: xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
14936: 					xmlSchemaTypePtr ctxType,
14937: 					xmlSchemaTypeLinkPtr members)
14938: {
14939:     xmlSchemaTypeLinkPtr member;
14940:     xmlSchemaTypePtr memberType;
14941: 
14942:     member = members;
14943:     while (member != NULL) {
14944: 	memberType = member->type;
14945: 	while ((memberType != NULL) &&
14946: 	    (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
14947: 	    if (memberType == ctxType) {
14948: 		xmlSchemaPCustomErr(pctxt,
14949: 		    XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
14950: 		    WXS_BASIC_CAST ctxType, NULL,
14951: 		    "The union type definition is circular", NULL);
14952: 		return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
14953: 	    }
14954: 	    if ((WXS_IS_UNION(memberType)) &&
14955: 		((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
14956: 	    {
14957: 		int res;
14958: 		memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
14959: 		res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
14960: 		    ctxType,
14961: 		    xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
14962: 		memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
14963: 		if (res != 0)
14964: 		    return(res);
14965: 	    }
14966: 	    memberType = memberType->baseType;
14967: 	}
14968: 	member = member->next;
14969:     }
14970:     return(0);
14971: }
14972: 
14973: static int
14974: xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
14975: 				   xmlSchemaTypePtr type)
14976: {
14977:     if (! WXS_IS_UNION(type))
14978: 	return(0);
14979:     return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
14980: 	type->memberTypes));
14981: }
14982: 
14983: /**
14984:  * xmlSchemaResolveTypeReferences:
14985:  * @item:  the complex/simple type definition
14986:  * @ctxt:  the parser context
14987:  * @name:  the name
14988:  *
14989:  * Resolvese type definition references
14990:  */
14991: static void
14992: xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
14993: 			 xmlSchemaParserCtxtPtr ctxt)
14994: {
14995:     if (typeDef == NULL)
14996: 	return;
14997: 
14998:     /*
14999:     * Resolve the base type.
15000:     */
15001:     if (typeDef->baseType == NULL) {
15002: 	typeDef->baseType = xmlSchemaGetType(ctxt->schema,
15003: 	    typeDef->base, typeDef->baseNs);
15004: 	if (typeDef->baseType == NULL) {
15005: 	    xmlSchemaPResCompAttrErr(ctxt,
15006: 		XML_SCHEMAP_SRC_RESOLVE,
15007: 		WXS_BASIC_CAST typeDef, typeDef->node,
15008: 		"base", typeDef->base, typeDef->baseNs,
15009: 		XML_SCHEMA_TYPE_SIMPLE, NULL);
15010: 	    return;
15011: 	}
15012:     }
15013:     if (WXS_IS_SIMPLE(typeDef)) {
15014: 	if (WXS_IS_UNION(typeDef)) {
15015: 	    /*
15016: 	    * Resolve the memberTypes.
15017: 	    */
15018: 	    xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
15019: 	    return;
15020: 	} else if (WXS_IS_LIST(typeDef)) {
15021: 	    /*
15022: 	    * Resolve the itemType.
15023: 	    */
15024: 	    if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
15025: 
15026: 		typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
15027: 		    typeDef->base, typeDef->baseNs);
15028: 
15029: 		if ((typeDef->subtypes == NULL) ||
15030: 		    (! WXS_IS_SIMPLE(typeDef->subtypes)))
15031: 		{
15032: 		    typeDef->subtypes = NULL;
15033: 		    xmlSchemaPResCompAttrErr(ctxt,
15034: 			XML_SCHEMAP_SRC_RESOLVE,
15035: 			WXS_BASIC_CAST typeDef, typeDef->node,
15036: 			"itemType", typeDef->base, typeDef->baseNs,
15037: 			XML_SCHEMA_TYPE_SIMPLE, NULL);
15038: 		}
15039: 	    }
15040: 	    return;
15041: 	}
15042:     }
15043:     /*
15044:     * The ball of letters below means, that if we have a particle
15045:     * which has a QName-helper component as its {term}, we want
15046:     * to resolve it...
15047:     */
15048:     else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
15049: 	((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
15050: 	    XML_SCHEMA_TYPE_PARTICLE) &&
15051: 	(WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
15052: 	((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
15053: 	    XML_SCHEMA_EXTRA_QNAMEREF))
15054:     {
15055: 	xmlSchemaQNameRefPtr ref =
15056: 	    WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
15057: 	xmlSchemaModelGroupDefPtr groupDef;
15058: 
15059: 	/*
15060: 	* URGENT TODO: Test this.
15061: 	*/
15062: 	WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
15063: 	/*
15064: 	* Resolve the MG definition reference.
15065: 	*/
15066: 	groupDef =
15067: 	    WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
15068: 		ref->itemType, ref->name, ref->targetNamespace);
15069: 	if (groupDef == NULL) {
15070: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
15071: 		NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
15072: 		"ref", ref->name, ref->targetNamespace, ref->itemType,
15073: 		NULL);
15074: 	    /* Remove the particle. */
15075: 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15076: 	} else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
15077: 	    /* Remove the particle. */
15078: 	    WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
15079: 	else {
15080: 	    /*
15081: 	    * Assign the MG definition's {model group} to the
15082: 	    * particle's {term}.
15083: 	    */
15084: 	    WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
15085: 
15086: 	    if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
15087: 		/*
15088: 		* SPEC cos-all-limited (1.2)
15089: 		* "1.2 the {term} property of a particle with
15090: 		* {max occurs}=1 which is part of a pair which constitutes
15091: 		* the {content type} of a complex type definition."
15092: 		*/
15093: 		if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
15094: 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
15095: 			/* TODO: error code */
15096: 			XML_SCHEMAP_COS_ALL_LIMITED,
15097: 			WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
15098: 			"The particle's {max occurs} must be 1, since the "
15099: 			"reference resolves to an 'all' model group",
15100: 			NULL, NULL);
15101: 		}
15102: 	    }
15103: 	}
15104:     }
15105: }
15106: 
15107: 
15108: 
15109: /**
15110:  * xmlSchemaCheckSTPropsCorrect:
15111:  * @ctxt:  the schema parser context
15112:  * @type:  the simple type definition
15113:  *
15114:  * Checks st-props-correct.
15115:  *
15116:  * Returns 0 if the properties are correct,
15117:  * if not, a positive error code and -1 on internal
15118:  * errors.
15119:  */
15120: static int
15121: xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
15122: 			     xmlSchemaTypePtr type)
15123: {
15124:     xmlSchemaTypePtr baseType = type->baseType;
15125:     xmlChar *str = NULL;
15126: 
15127:     /* STATE: error funcs converted. */
15128:     /*
15129:     * Schema Component Constraint: Simple Type Definition Properties Correct
15130:     *
15131:     * NOTE: This is somehow redundant, since we actually built a simple type
15132:     * to have all the needed information; this acts as an self test.
15133:     */
15134:     /* Base type: If the datatype has been �derived� by �restriction�
15135:     * then the Simple Type Definition component from which it is �derived�,
15136:     * otherwise the Simple Type Definition for anySimpleType (�4.1.6).
15137:     */
15138:     if (baseType == NULL) {
15139: 	/*
15140: 	* TODO: Think about: "modulo the impact of Missing
15141: 	* Sub-components (�5.3)."
15142: 	*/
15143: 	xmlSchemaPCustomErr(ctxt,
15144: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15145: 	    WXS_BASIC_CAST type, NULL,
15146: 	    "No base type existent", NULL);
15147: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15148: 
15149:     }
15150:     if (! WXS_IS_SIMPLE(baseType)) {
15151: 	xmlSchemaPCustomErr(ctxt,
15152: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15153: 	    WXS_BASIC_CAST type, NULL,
15154: 	    "The base type '%s' is not a simple type",
15155: 	    xmlSchemaGetComponentQName(&str, baseType));
15156: 	FREE_AND_NULL(str)
15157: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15158:     }
15159:     if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
15160: 	(WXS_IS_RESTRICTION(type) == 0) &&
15161: 	((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
15162:          (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
15163: 	xmlSchemaPCustomErr(ctxt,
15164: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15165: 	    WXS_BASIC_CAST type, NULL,
15166: 	    "A type, derived by list or union, must have "
15167: 	    "the simple ur-type definition as base type, not '%s'",
15168: 	    xmlSchemaGetComponentQName(&str, baseType));
15169: 	FREE_AND_NULL(str)
15170: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15171:     }
15172:     /*
15173:     * Variety: One of {atomic, list, union}.
15174:     */
15175:     if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
15176: 	(! WXS_IS_LIST(type))) {
15177: 	xmlSchemaPCustomErr(ctxt,
15178: 	    XML_SCHEMAP_ST_PROPS_CORRECT_1,
15179: 	    WXS_BASIC_CAST type, NULL,
15180: 	    "The variety is absent", NULL);
15181: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
15182:     }
15183:     /* TODO: Finish this. Hmm, is this finished? */
15184: 
15185:     /*
15186:     * 3 The {final} of the {base type definition} must not contain restriction.
15187:     */
15188:     if (xmlSchemaTypeFinalContains(baseType,
15189: 	XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15190: 	xmlSchemaPCustomErr(ctxt,
15191: 	    XML_SCHEMAP_ST_PROPS_CORRECT_3,
15192: 	    WXS_BASIC_CAST type, NULL,
15193: 	    "The 'final' of its base type '%s' must not contain "
15194: 	    "'restriction'",
15195: 	    xmlSchemaGetComponentQName(&str, baseType));
15196: 	FREE_AND_NULL(str)
15197: 	return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
15198:     }
15199: 
15200:     /*
15201:     * 2 All simple type definitions must be derived ultimately from the �simple
15202:     * ur-type definition (so� circular definitions are disallowed). That is, it
15203:     * must be possible to reach a built-in primitive datatype or the �simple
15204:     * ur-type definition� by repeatedly following the {base type definition}.
15205:     *
15206:     * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
15207:     */
15208:     return (0);
15209: }
15210: 
15211: /**
15212:  * xmlSchemaCheckCOSSTRestricts:
15213:  * @ctxt:  the schema parser context
15214:  * @type:  the simple type definition
15215:  *
15216:  * Schema Component Constraint:
15217:  * Derivation Valid (Restriction, Simple) (cos-st-restricts)
15218: 
15219:  * Checks if the given @type (simpleType) is derived validly by restriction.
15220:  * STATUS:
15221:  *
15222:  * Returns -1 on internal errors, 0 if the type is validly derived,
15223:  * a positive error code otherwise.
15224:  */
15225: static int
15226: xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
15227: 			     xmlSchemaTypePtr type)
15228: {
15229:     xmlChar *str = NULL;
15230: 
15231:     if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
15232: 	PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15233: 	    "given type is not a user-derived simpleType");
15234: 	return (-1);
15235:     }
15236: 
15237:     if (WXS_IS_ATOMIC(type)) {
15238: 	xmlSchemaTypePtr primitive;
15239: 	/*
15240: 	* 1.1 The {base type definition} must be an atomic simple
15241: 	* type definition or a built-in primitive datatype.
15242: 	*/
15243: 	if (! WXS_IS_ATOMIC(type->baseType)) {
15244: 	    xmlSchemaPCustomErr(pctxt,
15245: 		XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
15246: 		WXS_BASIC_CAST type, NULL,
15247: 		"The base type '%s' is not an atomic simple type",
15248: 		xmlSchemaGetComponentQName(&str, type->baseType));
15249: 	    FREE_AND_NULL(str)
15250: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
15251: 	}
15252: 	/* 1.2 The {final} of the {base type definition} must not contain
15253: 	* restriction.
15254: 	*/
15255: 	/* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
15256: 	if (xmlSchemaTypeFinalContains(type->baseType,
15257: 	    XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15258: 	    xmlSchemaPCustomErr(pctxt,
15259: 		XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
15260: 		WXS_BASIC_CAST type, NULL,
15261: 		"The final of its base type '%s' must not contain 'restriction'",
15262: 		xmlSchemaGetComponentQName(&str, type->baseType));
15263: 	    FREE_AND_NULL(str)
15264: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
15265: 	}
15266: 
15267: 	/*
15268: 	* 1.3.1 DF must be an allowed constraining facet for the {primitive
15269: 	* type definition}, as specified in the appropriate subsection of 3.2
15270: 	* Primitive datatypes.
15271: 	*/
15272: 	if (type->facets != NULL) {
15273: 	    xmlSchemaFacetPtr facet;
15274: 	    int ok = 1;
15275: 
15276: 	    primitive = xmlSchemaGetPrimitiveType(type);
15277: 	    if (primitive == NULL) {
15278: 		PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15279: 		    "failed to get primitive type");
15280: 		return (-1);
15281: 	    }
15282: 	    facet = type->facets;
15283: 	    do {
15284: 		if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
15285: 		    ok = 0;
15286: 		    xmlSchemaPIllegalFacetAtomicErr(pctxt,
15287: 			XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
15288: 			type, primitive, facet);
15289: 		}
15290: 		facet = facet->next;
15291: 	    } while (facet != NULL);
15292: 	    if (ok == 0)
15293: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
15294: 	}
15295: 	/*
15296: 	* SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
15297: 	* of the {base type definition} (call this BF),then the DF's {value}
15298: 	* must be a valid restriction of BF's {value} as defined in
15299: 	* [XML Schemas: Datatypes]."
15300: 	*
15301: 	* NOTE (1.3.2) Facet derivation constraints are currently handled in
15302: 	* xmlSchemaDeriveAndValidateFacets()
15303: 	*/
15304:     } else if (WXS_IS_LIST(type)) {
15305: 	xmlSchemaTypePtr itemType = NULL;
15306: 
15307: 	itemType = type->subtypes;
15308: 	if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
15309: 	    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15310: 		"failed to evaluate the item type");
15311: 	    return (-1);
15312: 	}
15313: 	if (WXS_IS_TYPE_NOT_FIXED(itemType))
15314: 	    xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
15315: 	/*
15316: 	* 2.1 The {item type definition} must have a {variety} of atomic or
15317: 	* union (in which case all the {member type definitions}
15318: 	* must be atomic).
15319: 	*/
15320: 	if ((! WXS_IS_ATOMIC(itemType)) &&
15321: 	    (! WXS_IS_UNION(itemType))) {
15322: 	    xmlSchemaPCustomErr(pctxt,
15323: 		XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15324: 		WXS_BASIC_CAST type, NULL,
15325: 		"The item type '%s' does not have a variety of atomic or union",
15326: 		xmlSchemaGetComponentQName(&str, itemType));
15327: 	    FREE_AND_NULL(str)
15328: 	    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15329: 	} else if (WXS_IS_UNION(itemType)) {
15330: 	    xmlSchemaTypeLinkPtr member;
15331: 
15332: 	    member = itemType->memberTypes;
15333: 	    while (member != NULL) {
15334: 		if (! WXS_IS_ATOMIC(member->type)) {
15335: 		    xmlSchemaPCustomErr(pctxt,
15336: 			XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
15337: 			WXS_BASIC_CAST type, NULL,
15338: 			"The item type is a union type, but the "
15339: 			"member type '%s' of this item type is not atomic",
15340: 			xmlSchemaGetComponentQName(&str, member->type));
15341: 		    FREE_AND_NULL(str)
15342: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
15343: 		}
15344: 		member = member->next;
15345: 	    }
15346: 	}
15347: 
15348: 	if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
15349: 	    xmlSchemaFacetPtr facet;
15350: 	    /*
15351: 	    * This is the case if we have: <simpleType><list ..
15352: 	    */
15353: 	    /*
15354: 	    * 2.3.1
15355: 	    * 2.3.1.1 The {final} of the {item type definition} must not
15356: 	    * contain list.
15357: 	    */
15358: 	    if (xmlSchemaTypeFinalContains(itemType,
15359: 		XML_SCHEMAS_TYPE_FINAL_LIST)) {
15360: 		xmlSchemaPCustomErr(pctxt,
15361: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
15362: 		    WXS_BASIC_CAST type, NULL,
15363: 		    "The final of its item type '%s' must not contain 'list'",
15364: 		    xmlSchemaGetComponentQName(&str, itemType));
15365: 		FREE_AND_NULL(str)
15366: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
15367: 	    }
15368: 	    /*
15369: 	    * 2.3.1.2 The {facets} must only contain the whiteSpace
15370: 	    * facet component.
15371: 	    * OPTIMIZE TODO: the S4S already disallows any facet
15372: 	    * to be specified.
15373: 	    */
15374: 	    if (type->facets != NULL) {
15375: 		facet = type->facets;
15376: 		do {
15377: 		    if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
15378: 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
15379: 			    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
15380: 			    type, facet);
15381: 			return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
15382: 		    }
15383: 		    facet = facet->next;
15384: 		} while (facet != NULL);
15385: 	    }
15386: 	    /*
15387: 	    * MAYBE TODO: (Hmm, not really) Datatypes states:
15388: 	    * A �list� datatype can be �derived� from an �atomic� datatype
15389: 	    * whose �lexical space� allows space (such as string or anyURI)or
15390: 	    * a �union� datatype any of whose {member type definitions}'s
15391: 	    * �lexical space� allows space.
15392: 	    */
15393: 	} else {
15394: 	    /*
15395: 	    * This is the case if we have: <simpleType><restriction ...
15396: 	    * I.e. the variety of "list" is inherited.
15397: 	    */
15398: 	    /*
15399: 	    * 2.3.2
15400: 	    * 2.3.2.1 The {base type definition} must have a {variety} of list.
15401: 	    */
15402: 	    if (! WXS_IS_LIST(type->baseType)) {
15403: 		xmlSchemaPCustomErr(pctxt,
15404: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
15405: 		    WXS_BASIC_CAST type, NULL,
15406: 		    "The base type '%s' must be a list type",
15407: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15408: 		FREE_AND_NULL(str)
15409: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
15410: 	    }
15411: 	    /*
15412: 	    * 2.3.2.2 The {final} of the {base type definition} must not
15413: 	    * contain restriction.
15414: 	    */
15415: 	    if (xmlSchemaTypeFinalContains(type->baseType,
15416: 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15417: 		xmlSchemaPCustomErr(pctxt,
15418: 		    XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
15419: 		    WXS_BASIC_CAST type, NULL,
15420: 		    "The 'final' of the base type '%s' must not contain 'restriction'",
15421: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15422: 		FREE_AND_NULL(str)
15423: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
15424: 	    }
15425: 	    /*
15426: 	    * 2.3.2.3 The {item type definition} must be validly derived
15427: 	    * from the {base type definition}'s {item type definition} given
15428: 	    * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6).
15429: 	    */
15430: 	    {
15431: 		xmlSchemaTypePtr baseItemType;
15432: 
15433: 		baseItemType = type->baseType->subtypes;
15434: 		if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
15435: 		    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15436: 			"failed to eval the item type of a base type");
15437: 		    return (-1);
15438: 		}
15439: 		if ((itemType != baseItemType) &&
15440: 		    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
15441: 			baseItemType, 0) != 0)) {
15442: 		    xmlChar *strBIT = NULL, *strBT = NULL;
15443: 		    xmlSchemaPCustomErrExt(pctxt,
15444: 			XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
15445: 			WXS_BASIC_CAST type, NULL,
15446: 			"The item type '%s' is not validly derived from "
15447: 			"the item type '%s' of the base type '%s'",
15448: 			xmlSchemaGetComponentQName(&str, itemType),
15449: 			xmlSchemaGetComponentQName(&strBIT, baseItemType),
15450: 			xmlSchemaGetComponentQName(&strBT, type->baseType));
15451: 
15452: 		    FREE_AND_NULL(str)
15453: 		    FREE_AND_NULL(strBIT)
15454: 		    FREE_AND_NULL(strBT)
15455: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
15456: 		}
15457: 	    }
15458: 
15459: 	    if (type->facets != NULL) {
15460: 		xmlSchemaFacetPtr facet;
15461: 		int ok = 1;
15462: 		/*
15463: 		* 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
15464: 		* and enumeration facet components are allowed among the {facets}.
15465: 		*/
15466: 		facet = type->facets;
15467: 		do {
15468: 		    switch (facet->type) {
15469: 			case XML_SCHEMA_FACET_LENGTH:
15470: 			case XML_SCHEMA_FACET_MINLENGTH:
15471: 			case XML_SCHEMA_FACET_MAXLENGTH:
15472: 			case XML_SCHEMA_FACET_WHITESPACE:
15473: 			    /*
15474: 			    * TODO: 2.5.1.2 List datatypes
15475: 			    * The value of �whiteSpace� is fixed to the value collapse.
15476: 			    */
15477: 			case XML_SCHEMA_FACET_PATTERN:
15478: 			case XML_SCHEMA_FACET_ENUMERATION:
15479: 			    break;
15480: 			default: {
15481: 			    xmlSchemaPIllegalFacetListUnionErr(pctxt,
15482: 				XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
15483: 				type, facet);
15484: 			    /*
15485: 			    * We could return, but it's nicer to report all
15486: 			    * invalid facets.
15487: 			    */
15488: 			    ok = 0;
15489: 			}
15490: 		    }
15491: 		    facet = facet->next;
15492: 		} while (facet != NULL);
15493: 		if (ok == 0)
15494: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
15495: 		/*
15496: 		* SPEC (2.3.2.5) (same as 1.3.2)
15497: 		*
15498: 		* NOTE (2.3.2.5) This is currently done in
15499: 		* xmlSchemaDeriveAndValidateFacets()
15500: 		*/
15501: 	    }
15502: 	}
15503:     } else if (WXS_IS_UNION(type)) {
15504: 	/*
15505: 	* 3.1 The {member type definitions} must all have {variety} of
15506: 	* atomic or list.
15507: 	*/
15508: 	xmlSchemaTypeLinkPtr member;
15509: 
15510: 	member = type->memberTypes;
15511: 	while (member != NULL) {
15512: 	    if (WXS_IS_TYPE_NOT_FIXED(member->type))
15513: 		xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
15514: 
15515: 	    if ((! WXS_IS_ATOMIC(member->type)) &&
15516: 		(! WXS_IS_LIST(member->type))) {
15517: 		xmlSchemaPCustomErr(pctxt,
15518: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
15519: 		    WXS_BASIC_CAST type, NULL,
15520: 		    "The member type '%s' is neither an atomic, nor a list type",
15521: 		    xmlSchemaGetComponentQName(&str, member->type));
15522: 		FREE_AND_NULL(str)
15523: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
15524: 	    }
15525: 	    member = member->next;
15526: 	}
15527: 	/*
15528: 	* 3.3.1 If the {base type definition} is the �simple ur-type
15529: 	* definition�
15530: 	*/
15531: 	if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
15532: 	    /*
15533: 	    * 3.3.1.1 All of the {member type definitions} must have a
15534: 	    * {final} which does not contain union.
15535: 	    */
15536: 	    member = type->memberTypes;
15537: 	    while (member != NULL) {
15538: 		if (xmlSchemaTypeFinalContains(member->type,
15539: 		    XML_SCHEMAS_TYPE_FINAL_UNION)) {
15540: 		    xmlSchemaPCustomErr(pctxt,
15541: 			XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
15542: 			WXS_BASIC_CAST type, NULL,
15543: 			"The 'final' of member type '%s' contains 'union'",
15544: 			xmlSchemaGetComponentQName(&str, member->type));
15545: 		    FREE_AND_NULL(str)
15546: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
15547: 		}
15548: 		member = member->next;
15549: 	    }
15550: 	    /*
15551: 	    * 3.3.1.2 The {facets} must be empty.
15552: 	    */
15553: 	    if (type->facetSet != NULL) {
15554: 		xmlSchemaPCustomErr(pctxt,
15555: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
15556: 		    WXS_BASIC_CAST type, NULL,
15557: 		    "No facets allowed", NULL);
15558: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
15559: 	    }
15560: 	} else {
15561: 	    /*
15562: 	    * 3.3.2.1 The {base type definition} must have a {variety} of union.
15563: 	    * I.e. the variety of "list" is inherited.
15564: 	    */
15565: 	    if (! WXS_IS_UNION(type->baseType)) {
15566: 		xmlSchemaPCustomErr(pctxt,
15567: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
15568: 		    WXS_BASIC_CAST type, NULL,
15569: 		    "The base type '%s' is not a union type",
15570: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15571: 		FREE_AND_NULL(str)
15572: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
15573: 	    }
15574: 	    /*
15575: 	    * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
15576: 	    */
15577: 	    if (xmlSchemaTypeFinalContains(type->baseType,
15578: 		XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
15579: 		xmlSchemaPCustomErr(pctxt,
15580: 		    XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
15581: 		    WXS_BASIC_CAST type, NULL,
15582: 		    "The 'final' of its base type '%s' must not contain 'restriction'",
15583: 		    xmlSchemaGetComponentQName(&str, type->baseType));
15584: 		FREE_AND_NULL(str)
15585: 		return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
15586: 	    }
15587: 	    /*
15588: 	    * 3.3.2.3 The {member type definitions}, in order, must be validly
15589: 	    * derived from the corresponding type definitions in the {base
15590: 	    * type definition}'s {member type definitions} given the empty set,
15591: 	    * as defined in Type Derivation OK (Simple) (�3.14.6).
15592: 	    */
15593: 	    {
15594: 		xmlSchemaTypeLinkPtr baseMember;
15595: 
15596: 		/*
15597: 		* OPTIMIZE: if the type is restricting, it has no local defined
15598: 		* member types and inherits the member types of the base type;
15599: 		* thus a check for equality can be skipped.
15600: 		*/
15601: 		/*
15602: 		* Even worse: I cannot see a scenario where a restricting
15603: 		* union simple type can have other member types as the member
15604: 		* types of it's base type. This check seems not necessary with
15605: 		* respect to the derivation process in libxml2.
15606: 		* But necessary if constructing types with an API.
15607: 		*/
15608: 		if (type->memberTypes != NULL) {
15609: 		    member = type->memberTypes;
15610: 		    baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
15611: 		    if ((member == NULL) && (baseMember != NULL)) {
15612: 			PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15613: 			    "different number of member types in base");
15614: 		    }
15615: 		    while (member != NULL) {
15616: 			if (baseMember == NULL) {
15617: 			    PERROR_INT("xmlSchemaCheckCOSSTRestricts",
15618: 			    "different number of member types in base");
15619: 			} else if ((member->type != baseMember->type) &&
15620: 			    (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
15621: 				member->type, baseMember->type, 0) != 0)) {
15622: 			    xmlChar *strBMT = NULL, *strBT = NULL;
15623: 
15624: 			    xmlSchemaPCustomErrExt(pctxt,
15625: 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
15626: 				WXS_BASIC_CAST type, NULL,
15627: 				"The member type %s is not validly "
15628: 				"derived from its corresponding member "
15629: 				"type %s of the base type %s",
15630: 				xmlSchemaGetComponentQName(&str, member->type),
15631: 				xmlSchemaGetComponentQName(&strBMT, baseMember->type),
15632: 				xmlSchemaGetComponentQName(&strBT, type->baseType));
15633: 			    FREE_AND_NULL(str)
15634: 			    FREE_AND_NULL(strBMT)
15635: 			    FREE_AND_NULL(strBT)
15636: 			    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
15637: 			}
15638: 			member = member->next;
15639:                         if (baseMember != NULL)
15640:                             baseMember = baseMember->next;
15641: 		    }
15642: 		}
15643: 	    }
15644: 	    /*
15645: 	    * 3.3.2.4 Only pattern and enumeration facet components are
15646: 	    * allowed among the {facets}.
15647: 	    */
15648: 	    if (type->facets != NULL) {
15649: 		xmlSchemaFacetPtr facet;
15650: 		int ok = 1;
15651: 
15652: 		facet = type->facets;
15653: 		do {
15654: 		    if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
15655: 			(facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
15656: 			xmlSchemaPIllegalFacetListUnionErr(pctxt,
15657: 				XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
15658: 				type, facet);
15659: 			ok = 0;
15660: 		    }
15661: 		    facet = facet->next;
15662: 		} while (facet != NULL);
15663: 		if (ok == 0)
15664: 		    return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
15665: 
15666: 	    }
15667: 	    /*
15668: 	    * SPEC (3.3.2.5) (same as 1.3.2)
15669: 	    *
15670: 	    * NOTE (3.3.2.5) This is currently done in
15671: 	    * xmlSchemaDeriveAndValidateFacets()
15672: 	    */
15673: 	}
15674:     }
15675: 
15676:     return (0);
15677: }
15678: 
15679: /**
15680:  * xmlSchemaCheckSRCSimpleType:
15681:  * @ctxt:  the schema parser context
15682:  * @type:  the simple type definition
15683:  *
15684:  * Checks crc-simple-type constraints.
15685:  *
15686:  * Returns 0 if the constraints are satisfied,
15687:  * if not a positive error code and -1 on internal
15688:  * errors.
15689:  */
15690: #if 0
15691: static int
15692: xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
15693: 			    xmlSchemaTypePtr type)
15694: {
15695:     /*
15696:     * src-simple-type.1 The corresponding simple type definition, if any,
15697:     * must satisfy the conditions set out in Constraints on Simple Type
15698:     * Definition Schema Components (�3.14.6).
15699:     */
15700:     if (WXS_IS_RESTRICTION(type)) {
15701: 	/*
15702: 	* src-simple-type.2 "If the <restriction> alternative is chosen,
15703: 	* either it must have a base [attribute] or a <simpleType> among its
15704: 	* [children], but not both."
15705: 	* NOTE: This is checked in the parse function of <restriction>.
15706: 	*/
15707: 	/*
15708: 	*
15709: 	*/
15710:     } else if (WXS_IS_LIST(type)) {
15711: 	/* src-simple-type.3 "If the <list> alternative is chosen, either it must have
15712: 	* an itemType [attribute] or a <simpleType> among its [children],
15713: 	* but not both."
15714: 	*
15715: 	* NOTE: This is checked in the parse function of <list>.
15716: 	*/
15717:     } else if (WXS_IS_UNION(type)) {
15718: 	/*
15719: 	* src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
15720: 	*/
15721:     }
15722:     return (0);
15723: }
15724: #endif
15725: 
15726: static int
15727: xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
15728: {
15729:    if (ctxt->vctxt == NULL) {
15730: 	ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
15731: 	if (ctxt->vctxt == NULL) {
15732: 	    xmlSchemaPErr(ctxt, NULL,
15733: 		XML_SCHEMAP_INTERNAL,
15734: 		"Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
15735: 		"failed to create a temp. validation context.\n",
15736: 		NULL, NULL);
15737: 	    return (-1);
15738: 	}
15739: 	/* TODO: Pass user data. */
15740: 	xmlSchemaSetValidErrors(ctxt->vctxt,
15741: 	    ctxt->error, ctxt->warning, ctxt->errCtxt);
15742: 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
15743: 	    ctxt->serror, ctxt->errCtxt);
15744:     }
15745:     return (0);
15746: }
15747: 
15748: static int
15749: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
15750: 			     xmlNodePtr node,
15751: 			     xmlSchemaTypePtr type,
15752: 			     const xmlChar *value,
15753: 			     xmlSchemaValPtr *retVal,
15754: 			     int fireErrors,
15755: 			     int normalize,
15756: 			     int isNormalized);
15757: 
15758: /**
15759:  * xmlSchemaParseCheckCOSValidDefault:
15760:  * @pctxt:  the schema parser context
15761:  * @type:  the simple type definition
15762:  * @value: the default value
15763:  * @node: an optional node (the holder of the value)
15764:  *
15765:  * Schema Component Constraint: Element Default Valid (Immediate)
15766:  * (cos-valid-default)
15767:  * This will be used by the parser only. For the validator there's
15768:  * an other version.
15769:  *
15770:  * Returns 0 if the constraints are satisfied,
15771:  * if not, a positive error code and -1 on internal
15772:  * errors.
15773:  */
15774: static int
15775: xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
15776: 				   xmlNodePtr node,
15777: 				   xmlSchemaTypePtr type,
15778: 				   const xmlChar *value,
15779: 				   xmlSchemaValPtr *val)
15780: {
15781:     int ret = 0;
15782: 
15783:     /*
15784:     * cos-valid-default:
15785:     * Schema Component Constraint: Element Default Valid (Immediate)
15786:     * For a string to be a valid default with respect to a type
15787:     * definition the appropriate case among the following must be true:
15788:     */
15789:     if WXS_IS_COMPLEX(type) {
15790: 	/*
15791: 	* Complex type.
15792: 	*
15793: 	* SPEC (2.1) "its {content type} must be a simple type definition
15794: 	* or mixed."
15795: 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
15796: 	* type}'s particle must be �emptiable� as defined by
15797: 	* Particle Emptiable (�3.9.6)."
15798: 	*/
15799: 	if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
15800: 	    ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
15801: 	    /* NOTE that this covers (2.2.2) as well. */
15802: 	    xmlSchemaPCustomErr(pctxt,
15803: 		XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
15804: 		WXS_BASIC_CAST type, type->node,
15805: 		"For a string to be a valid default, the type definition "
15806: 		"must be a simple type or a complex type with mixed content "
15807: 		"and a particle emptiable", NULL);
15808: 	    return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
15809: 	}
15810:     }
15811:     /*
15812:     * 1 If the type definition is a simple type definition, then the string
15813:     * must be �valid� with respect to that definition as defined by String
15814:     * Valid (�3.14.4).
15815:     *
15816:     * AND
15817:     *
15818:     * 2.2.1 If the {content type} is a simple type definition, then the
15819:     * string must be �valid� with respect to that simple type definition
15820:     * as defined by String Valid (�3.14.4).
15821:     */
15822:     if (WXS_IS_SIMPLE(type))
15823: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15824: 	    type, value, val, 1, 1, 0);
15825:     else if (WXS_HAS_SIMPLE_CONTENT(type))
15826: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
15827: 	    type->contentTypeDef, value, val, 1, 1, 0);
15828:     else
15829: 	return (ret);
15830: 
15831:     if (ret < 0) {
15832: 	PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
15833: 	    "calling xmlSchemaVCheckCVCSimpleType()");
15834:     }
15835: 
15836:     return (ret);
15837: }
15838: 
15839: /**
15840:  * xmlSchemaCheckCTPropsCorrect:
15841:  * @ctxt:  the schema parser context
15842:  * @type:  the complex type definition
15843:  *
15844:  *.(4.6) Constraints on Complex Type Definition Schema Components
15845:  * Schema Component Constraint:
15846:  * Complex Type Definition Properties Correct (ct-props-correct)
15847:  * STATUS: (seems) complete
15848:  *
15849:  * Returns 0 if the constraints are satisfied, a positive
15850:  * error code if not and -1 if an internal error occured.
15851:  */
15852: static int
15853: xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
15854: 			     xmlSchemaTypePtr type)
15855: {
15856:     /*
15857:     * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
15858:     *
15859:     * SPEC (1) "The values of the properties of a complex type definition must
15860:     * be as described in the property tableau in The Complex Type Definition
15861:     * Schema Component (�3.4.1), modulo the impact of Missing
15862:     * Sub-components (�5.3)."
15863:     */
15864:     if ((type->baseType != NULL) &&
15865: 	(WXS_IS_SIMPLE(type->baseType)) &&
15866: 	(WXS_IS_EXTENSION(type) == 0)) {
15867: 	/*
15868: 	* SPEC (2) "If the {base type definition} is a simple type definition,
15869: 	* the {derivation method} must be extension."
15870: 	*/
15871: 	xmlSchemaCustomErr(ACTXT_CAST pctxt,
15872: 	    XML_SCHEMAP_SRC_CT_1,
15873: 	    NULL, WXS_BASIC_CAST type,
15874: 	    "If the base type is a simple type, the derivation method must be "
15875: 	    "'extension'", NULL, NULL);
15876: 	return (XML_SCHEMAP_SRC_CT_1);
15877:     }
15878:     /*
15879:     * SPEC (3) "Circular definitions are disallowed, except for the �ur-type
15880:     * definition�. That is, it must be possible to reach the �ur-type
15881:     * definition by repeatedly following the {base type definition}."
15882:     *
15883:     * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
15884:     */
15885:     /*
15886:     * NOTE that (4) and (5) need the following:
15887:     *   - attribute uses need to be already inherited (apply attr. prohibitions)
15888:     *   - attribute group references need to be expanded already
15889:     *   - simple types need to be typefixed already
15890:     */
15891:     if (type->attrUses &&
15892: 	(((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
15893:     {
15894: 	xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
15895: 	xmlSchemaAttributeUsePtr use, tmp;
15896: 	int i, j, hasId = 0;
15897: 
15898: 	for (i = uses->nbItems -1; i >= 0; i--) {
15899: 	    use = uses->items[i];
15900: 
15901: 	    /*
15902: 	    * SPEC ct-props-correct
15903: 	    * (4) "Two distinct attribute declarations in the
15904: 	    * {attribute uses} must not have identical {name}s and
15905: 	    * {target namespace}s."
15906: 	    */
15907: 	    if (i > 0) {
15908: 		for (j = i -1; j >= 0; j--) {
15909: 		    tmp = uses->items[j];
15910: 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
15911: 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
15912: 			(WXS_ATTRUSE_DECL_TNS(use) ==
15913: 			WXS_ATTRUSE_DECL_TNS(tmp)))
15914: 		    {
15915: 			xmlChar *str = NULL;
15916: 
15917: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
15918: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
15919: 			    NULL, WXS_BASIC_CAST type,
15920: 			    "Duplicate %s",
15921: 			    xmlSchemaGetComponentDesignation(&str, use),
15922: 			    NULL);
15923: 			FREE_AND_NULL(str);
15924: 			/*
15925: 			* Remove the duplicate.
15926: 			*/
15927: 			if (xmlSchemaItemListRemove(uses, i) == -1)
15928: 			    goto exit_failure;
15929: 			goto next_use;
15930: 		    }
15931: 		}
15932: 	    }
15933: 	    /*
15934: 	    * SPEC ct-props-correct
15935: 	    * (5) "Two distinct attribute declarations in the
15936: 	    * {attribute uses} must not have {type definition}s which
15937: 	    * are or are derived from ID."
15938: 	    */
15939: 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
15940: 		if (xmlSchemaIsDerivedFromBuiltInType(
15941: 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
15942: 		{
15943: 		    if (hasId) {
15944: 			xmlChar *str = NULL;
15945: 
15946: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
15947: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
15948: 			    NULL, WXS_BASIC_CAST type,
15949: 			    "There must not exist more than one attribute "
15950: 			    "declaration of type 'xs:ID' "
15951: 			    "(or derived from 'xs:ID'). The %s violates this "
15952: 			    "constraint",
15953: 			    xmlSchemaGetComponentDesignation(&str, use),
15954: 			    NULL);
15955: 			FREE_AND_NULL(str);
15956: 			if (xmlSchemaItemListRemove(uses, i) == -1)
15957: 			    goto exit_failure;
15958: 		    }
15959: 
15960: 		    hasId = 1;
15961: 		}
15962: 	    }
15963: next_use: {}
15964: 	}
15965:     }
15966:     return (0);
15967: exit_failure:
15968:     return(-1);
15969: }
15970: 
15971: static int
15972: xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
15973: 		       xmlSchemaTypePtr typeB)
15974: {
15975:     /*
15976:     * TODO: This should implement component-identity
15977:     * in the future.
15978:     */
15979:     if ((typeA == NULL) || (typeB == NULL))
15980: 	return (0);
15981:     return (typeA == typeB);
15982: }
15983: 
15984: /**
15985:  * xmlSchemaCheckCOSCTDerivedOK:
15986:  * @ctxt:  the schema parser context
15987:  * @type:  the to-be derived complex type definition
15988:  * @baseType:  the base complex type definition
15989:  * @set: the given set
15990:  *
15991:  * Schema Component Constraint:
15992:  * Type Derivation OK (Complex) (cos-ct-derived-ok)
15993:  *
15994:  * STATUS: completed
15995:  *
15996:  * Returns 0 if the constraints are satisfied, or 1
15997:  * if not.
15998:  */
15999: static int
16000: xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16001: 			     xmlSchemaTypePtr type,
16002: 			     xmlSchemaTypePtr baseType,
16003: 			     int set)
16004: {
16005:     int equal = xmlSchemaAreEqualTypes(type, baseType);
16006:     /* TODO: Error codes. */
16007:     /*
16008:     * SPEC "For a complex type definition (call it D, for derived)
16009:     * to be validly derived from a type definition (call this
16010:     * B, for base) given a subset of {extension, restriction}
16011:     * all of the following must be true:"
16012:     */
16013:     if (! equal) {
16014: 	/*
16015: 	* SPEC (1) "If B and D are not the same type definition, then the
16016: 	* {derivation method} of D must not be in the subset."
16017: 	*/
16018: 	if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
16019: 	    ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
16020: 	    return (1);
16021:     } else {
16022: 	/*
16023: 	* SPEC (2.1) "B and D must be the same type definition."
16024: 	*/
16025: 	return (0);
16026:     }
16027:     /*
16028:     * SPEC (2.2) "B must be D's {base type definition}."
16029:     */
16030:     if (type->baseType == baseType)
16031: 	return (0);
16032:     /*
16033:     * SPEC (2.3.1) "D's {base type definition} must not be the �ur-type
16034:     * definition�."
16035:     */
16036:     if (WXS_IS_ANYTYPE(type->baseType))
16037: 	return (1);
16038: 
16039:     if (WXS_IS_COMPLEX(type->baseType)) {
16040: 	/*
16041: 	* SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
16042: 	* must be validly derived from B given the subset as defined by this
16043: 	* constraint."
16044: 	*/
16045: 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
16046: 	    baseType, set));
16047:     } else {
16048: 	/*
16049: 	* SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
16050: 	* must be validly derived from B given the subset as defined in Type
16051: 	* Derivation OK (Simple) (�3.14.6).
16052: 	*/
16053: 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
16054: 	    baseType, set));
16055:     }
16056: }
16057: 
16058: /**
16059:  * xmlSchemaCheckCOSDerivedOK:
16060:  * @type:  the derived simple type definition
16061:  * @baseType:  the base type definition
16062:  *
16063:  * Calls:
16064:  * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
16065:  *
16066:  * Checks wheter @type can be validly derived from @baseType.
16067:  *
16068:  * Returns 0 on success, an positive error code otherwise.
16069:  */
16070: static int
16071: xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
16072: 			   xmlSchemaTypePtr type,
16073: 			   xmlSchemaTypePtr baseType,
16074: 			   int set)
16075: {
16076:     if (WXS_IS_SIMPLE(type))
16077: 	return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
16078:     else
16079: 	return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
16080: }
16081: 
16082: /**
16083:  * xmlSchemaCheckCOSCTExtends:
16084:  * @ctxt:  the schema parser context
16085:  * @type:  the complex type definition
16086:  *
16087:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16088:  * Schema Component Constraint:
16089:  * Derivation Valid (Extension) (cos-ct-extends)
16090:  *
16091:  * STATUS:
16092:  *   missing:
16093:  *     (1.5)
16094:  *     (1.4.3.2.2.2) "Particle Valid (Extension)"
16095:  *
16096:  * Returns 0 if the constraints are satisfied, a positive
16097:  * error code if not and -1 if an internal error occured.
16098:  */
16099: static int
16100: xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
16101: 			   xmlSchemaTypePtr type)
16102: {
16103:     xmlSchemaTypePtr base = type->baseType;
16104:     /*
16105:     * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
16106:     * temporarily only.
16107:     */
16108:     /*
16109:     * SPEC (1) "If the {base type definition} is a complex type definition,
16110:     * then all of the following must be true:"
16111:     */
16112:     if (WXS_IS_COMPLEX(base)) {
16113: 	/*
16114: 	* SPEC (1.1) "The {final} of the {base type definition} must not
16115: 	* contain extension."
16116: 	*/
16117: 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16118: 	    xmlSchemaPCustomErr(ctxt,
16119: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16120: 		WXS_BASIC_CAST type, NULL,
16121: 		"The 'final' of the base type definition "
16122: 		"contains 'extension'", NULL);
16123: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16124: 	}
16125: 
16126: 	/*
16127: 	* ATTENTION: The constrains (1.2) and (1.3) are not applied,
16128: 	* since they are automatically satisfied through the
16129: 	* inheriting mechanism.
16130: 	* Note that even if redefining components, the inheriting mechanism
16131: 	* is used.
16132: 	*/
16133: #if 0
16134: 	/*
16135: 	* SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
16136: 	* uses}
16137: 	* of the complex type definition itself, that is, for every attribute
16138: 	* use in the {attribute uses} of the {base type definition}, there
16139: 	* must be an attribute use in the {attribute uses} of the complex
16140: 	* type definition itself whose {attribute declaration} has the same
16141: 	* {name}, {target namespace} and {type definition} as its attribute
16142: 	* declaration"
16143: 	*/
16144: 	if (base->attrUses != NULL) {
16145: 	    int i, j, found;
16146: 	    xmlSchemaAttributeUsePtr use, buse;
16147: 
16148: 	    for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
16149: 		buse = (WXS_LIST_CAST base->attrUses)->items[i];
16150: 		found = 0;
16151: 		if (type->attrUses != NULL) {
16152: 		    use = (WXS_LIST_CAST type->attrUses)->items[j];
16153: 		    for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
16154: 		    {
16155: 			if ((WXS_ATTRUSE_DECL_NAME(use) ==
16156: 				WXS_ATTRUSE_DECL_NAME(buse)) &&
16157: 			    (WXS_ATTRUSE_DECL_TNS(use) ==
16158: 				WXS_ATTRUSE_DECL_TNS(buse)) &&
16159: 			    (WXS_ATTRUSE_TYPEDEF(use) ==
16160: 				WXS_ATTRUSE_TYPEDEF(buse))
16161: 			{
16162: 			    found = 1;
16163: 			    break;
16164: 			}
16165: 		    }
16166: 		}
16167: 		if (! found) {
16168: 		    xmlChar *str = NULL;
16169: 
16170: 		    xmlSchemaCustomErr(ACTXT_CAST ctxt,
16171: 			XML_SCHEMAP_COS_CT_EXTENDS_1_2,
16172: 			NULL, WXS_BASIC_CAST type,
16173: 			/*
16174: 			* TODO: The report does not indicate that also the
16175: 			* type needs to be the same.
16176: 			*/
16177: 			"This type is missing a matching correspondent "
16178: 			"for its {base type}'s %s in its {attribute uses}",
16179: 			xmlSchemaGetComponentDesignation(&str,
16180: 			    buse->children),
16181: 			NULL);
16182: 		    FREE_AND_NULL(str)
16183: 		}
16184: 	    }
16185: 	}
16186: 	/*
16187: 	* SPEC (1.3) "If it has an {attribute wildcard}, the complex type
16188: 	* definition must also have one, and the base type definition's
16189: 	* {attribute  wildcard}'s {namespace constraint} must be a subset
16190: 	* of the complex  type definition's {attribute wildcard}'s {namespace
16191: 	* constraint}, as defined by Wildcard Subset (�3.10.6)."
16192: 	*/
16193: 
16194: 	/*
16195: 	* MAYBE TODO: Enable if ever needed. But this will be needed only
16196: 	* if created the type via a schema construction API.
16197: 	*/
16198: 	if (base->attributeWildcard != NULL) {
16199: 	    if (type->attributeWilcard == NULL) {
16200: 		xmlChar *str = NULL;
16201: 
16202: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
16203: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16204: 		    NULL, type,
16205: 		    "The base %s has an attribute wildcard, "
16206: 		    "but this type is missing an attribute wildcard",
16207: 		    xmlSchemaGetComponentDesignation(&str, base));
16208: 		FREE_AND_NULL(str)
16209: 
16210: 	    } else if (xmlSchemaCheckCOSNSSubset(
16211: 		base->attributeWildcard, type->attributeWildcard))
16212: 	    {
16213: 		xmlChar *str = NULL;
16214: 
16215: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
16216: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_3,
16217: 		    NULL, type,
16218: 		    "The attribute wildcard is not a valid "
16219: 		    "superset of the one in the base %s",
16220: 		    xmlSchemaGetComponentDesignation(&str, base));
16221: 		FREE_AND_NULL(str)
16222: 	    }
16223: 	}
16224: #endif
16225: 	/*
16226: 	* SPEC (1.4) "One of the following must be true:"
16227: 	*/
16228: 	if ((type->contentTypeDef != NULL) &&
16229: 	    (type->contentTypeDef == base->contentTypeDef)) {
16230: 	    /*
16231: 	    * SPEC (1.4.1) "The {content type} of the {base type definition}
16232: 	    * and the {content type} of the complex type definition itself
16233: 	    * must be the same simple type definition"
16234: 	    * PASS
16235: 	    */
16236: 	} else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
16237: 	    (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
16238: 	    /*
16239: 	    * SPEC (1.4.2) "The {content type} of both the {base type
16240: 	    * definition} and the complex type definition itself must
16241: 	    * be empty."
16242: 	    * PASS
16243: 	    */
16244: 	} else {
16245: 	    /*
16246: 	    * SPEC (1.4.3) "All of the following must be true:"
16247: 	    */
16248: 	    if (type->subtypes == NULL) {
16249: 		/*
16250: 		* SPEC 1.4.3.1 The {content type} of the complex type
16251: 		* definition itself must specify a particle.
16252: 		*/
16253: 		xmlSchemaPCustomErr(ctxt,
16254: 		    XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16255: 		    WXS_BASIC_CAST type, NULL,
16256: 		    "The content type must specify a particle", NULL);
16257: 		return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16258: 	    }
16259: 	    /*
16260: 	    * SPEC (1.4.3.2) "One of the following must be true:"
16261: 	    */
16262: 	    if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16263: 		/*
16264: 		* SPEC (1.4.3.2.1) "The {content type} of the {base type
16265: 		* definition} must be empty.
16266: 		* PASS
16267: 		*/
16268: 	    } else {
16269: 		/*
16270: 		* SPEC (1.4.3.2.2) "All of the following must be true:"
16271: 		*/
16272: 		if ((type->contentType != base->contentType) ||
16273: 		    ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
16274: 		    (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
16275: 		    /*
16276: 		    * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
16277: 		    * or both must be element-only."
16278: 		    */
16279: 		    xmlSchemaPCustomErr(ctxt,
16280: 			XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16281: 			WXS_BASIC_CAST type, NULL,
16282: 			"The content type of both, the type and its base "
16283: 			"type, must either 'mixed' or 'element-only'", NULL);
16284: 		    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16285: 		}
16286: 		/*
16287: 		* URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
16288: 		* complex type definition must be a �valid extension�
16289: 		* of the {base type definition}'s particle, as defined
16290: 		* in Particle Valid (Extension) (�3.9.6)."
16291: 		*
16292: 		* NOTE that we won't check "Particle Valid (Extension)",
16293: 		* since it is ensured by the derivation process in
16294: 		* xmlSchemaTypeFixup(). We need to implement this when heading
16295: 		* for a construction API
16296: 		* TODO: !! This is needed to be checked if redefining a type !!
16297: 		*/
16298: 	    }
16299: 	    /*
16300: 	    * URGENT TODO (1.5)
16301: 	    */
16302: 	}
16303:     } else {
16304: 	/*
16305: 	* SPEC (2) "If the {base type definition} is a simple type definition,
16306: 	* then all of the following must be true:"
16307: 	*/
16308: 	if (type->contentTypeDef != base) {
16309: 	    /*
16310: 	    * SPEC (2.1) "The {content type} must be the same simple type
16311: 	    * definition."
16312: 	    */
16313: 	    xmlSchemaPCustomErr(ctxt,
16314: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16315: 		WXS_BASIC_CAST type, NULL,
16316: 		"The content type must be the simple base type", NULL);
16317: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16318: 	}
16319: 	if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
16320: 	    /*
16321: 	    * SPEC (2.2) "The {final} of the {base type definition} must not
16322: 	    * contain extension"
16323: 	    * NOTE that this is the same as (1.1).
16324: 	    */
16325: 	    xmlSchemaPCustomErr(ctxt,
16326: 		XML_SCHEMAP_COS_CT_EXTENDS_1_1,
16327: 		WXS_BASIC_CAST type, NULL,
16328: 		"The 'final' of the base type definition "
16329: 		"contains 'extension'", NULL);
16330: 	    return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
16331: 	}
16332:     }
16333:     return (0);
16334: }
16335: 
16336: /**
16337:  * xmlSchemaCheckDerivationOKRestriction:
16338:  * @ctxt:  the schema parser context
16339:  * @type:  the complex type definition
16340:  *
16341:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16342:  * Schema Component Constraint:
16343:  * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
16344:  *
16345:  * STATUS:
16346:  *   missing:
16347:  *     (5.4.2) ???
16348:  *
16349:  * ATTENTION:
16350:  * In XML Schema 1.1 this will be:
16351:  * Validation Rule: Checking complex type subsumption
16352:  *
16353:  * Returns 0 if the constraints are satisfied, a positive
16354:  * error code if not and -1 if an internal error occured.
16355:  */
16356: static int
16357: xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
16358: 				      xmlSchemaTypePtr type)
16359: {
16360:     xmlSchemaTypePtr base;
16361: 
16362:     /*
16363:     * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
16364:     * temporarily only.
16365:     */
16366:     base = type->baseType;
16367:     if (! WXS_IS_COMPLEX(base)) {
16368: 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
16369: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16370: 	    type->node, WXS_BASIC_CAST type,
16371: 	    "The base type must be a complex type", NULL, NULL);
16372: 	return(ctxt->err);
16373:     }
16374:     if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
16375: 	/*
16376: 	* SPEC (1) "The {base type definition} must be a complex type
16377: 	* definition whose {final} does not contain restriction."
16378: 	*/
16379: 	xmlSchemaCustomErr(ACTXT_CAST ctxt,
16380: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16381: 	    type->node, WXS_BASIC_CAST type,
16382: 	    "The 'final' of the base type definition "
16383: 	    "contains 'restriction'", NULL, NULL);
16384: 	return (ctxt->err);
16385:     }
16386:     /*
16387:     * SPEC (2), (3) and (4)
16388:     * Those are handled in a separate function, since the
16389:     * same constraints are needed for redefinition of
16390:     * attribute groups as well.
16391:     */
16392:     if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
16393: 	XML_SCHEMA_ACTION_DERIVE,
16394: 	WXS_BASIC_CAST type, WXS_BASIC_CAST base,
16395: 	type->attrUses, base->attrUses,
16396: 	type->attributeWildcard,
16397: 	base->attributeWildcard) == -1)
16398:     {
16399: 	return(-1);
16400:     }
16401:     /*
16402:     * SPEC (5) "One of the following must be true:"
16403:     */
16404:     if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
16405: 	/*
16406: 	* SPEC (5.1) "The {base type definition} must be the
16407: 	* �ur-type definition�."
16408: 	* PASS
16409: 	*/
16410:     } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16411: 	    (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16412: 	/*
16413: 	* SPEC (5.2.1) "The {content type} of the complex type definition
16414: 	* must be a simple type definition"
16415: 	*
16416: 	* SPEC (5.2.2) "One of the following must be true:"
16417: 	*/
16418: 	if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16419: 	    (base->contentType == XML_SCHEMA_CONTENT_BASIC))
16420: 	{
16421: 	    int err;
16422: 	    /*
16423: 	    * SPEC (5.2.2.1) "The {content type} of the {base type
16424: 	    * definition} must be a simple type definition from which
16425: 	    * the {content type} is validly derived given the empty
16426: 	    * set as defined in Type Derivation OK (Simple) (�3.14.6)."
16427: 	    *
16428: 	    * ATTENTION TODO: This seems not needed if the type implicitely
16429: 	    * derived from the base type.
16430: 	    *
16431: 	    */
16432: 	    err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
16433: 		type->contentTypeDef, base->contentTypeDef, 0);
16434: 	    if (err != 0) {
16435: 		xmlChar *strA = NULL, *strB = NULL;
16436: 
16437: 		if (err == -1)
16438: 		    return(-1);
16439: 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
16440: 		    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16441: 		    NULL, WXS_BASIC_CAST type,
16442: 		    "The {content type} %s is not validly derived from the "
16443: 		    "base type's {content type} %s",
16444: 		    xmlSchemaGetComponentDesignation(&strA,
16445: 			type->contentTypeDef),
16446: 		    xmlSchemaGetComponentDesignation(&strB,
16447: 			base->contentTypeDef));
16448: 		FREE_AND_NULL(strA);
16449: 		FREE_AND_NULL(strB);
16450: 		return(ctxt->err);
16451: 	    }
16452: 	} else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16453: 	    (xmlSchemaIsParticleEmptiable(
16454: 		(xmlSchemaParticlePtr) base->subtypes))) {
16455: 	    /*
16456: 	    * SPEC (5.2.2.2) "The {base type definition} must be mixed
16457: 	    * and have a particle which is �emptiable� as defined in
16458: 	    * Particle Emptiable (�3.9.6)."
16459: 	    * PASS
16460: 	    */
16461: 	} else {
16462: 	    xmlSchemaPCustomErr(ctxt,
16463: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16464: 		WXS_BASIC_CAST type, NULL,
16465: 		"The content type of the base type must be either "
16466: 		"a simple type or 'mixed' and an emptiable particle", NULL);
16467: 	    return (ctxt->err);
16468: 	}
16469:     } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16470: 	/*
16471: 	* SPEC (5.3.1) "The {content type} of the complex type itself must
16472: 	* be empty"
16473: 	*/
16474: 	if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
16475: 	    /*
16476: 	    * SPEC (5.3.2.1) "The {content type} of the {base type
16477: 	    * definition} must also be empty."
16478: 	    * PASS
16479: 	    */
16480: 	} else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16481: 	    (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
16482: 	    xmlSchemaIsParticleEmptiable(
16483: 		(xmlSchemaParticlePtr) base->subtypes)) {
16484: 	    /*
16485: 	    * SPEC (5.3.2.2) "The {content type} of the {base type
16486: 	    * definition} must be elementOnly or mixed and have a particle
16487: 	    * which is �emptiable� as defined in Particle Emptiable (�3.9.6)."
16488: 	    * PASS
16489: 	    */
16490: 	} else {
16491: 	    xmlSchemaPCustomErr(ctxt,
16492: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16493: 		WXS_BASIC_CAST type, NULL,
16494: 		"The content type of the base type must be either "
16495: 		"empty or 'mixed' (or 'elements-only') and an emptiable "
16496: 		"particle", NULL);
16497: 	    return (ctxt->err);
16498: 	}
16499:     } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
16500: 	WXS_HAS_MIXED_CONTENT(type)) {
16501: 	/*
16502: 	* SPEC (5.4.1.1) "The {content type} of the complex type definition
16503: 	* itself must be element-only"
16504: 	*/
16505: 	if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
16506: 	    /*
16507: 	    * SPEC (5.4.1.2) "The {content type} of the complex type
16508: 	    * definition itself and of the {base type definition} must be
16509: 	    * mixed"
16510: 	    */
16511: 	    xmlSchemaPCustomErr(ctxt,
16512: 		XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16513: 		WXS_BASIC_CAST type, NULL,
16514: 		"If the content type is 'mixed', then the content type of the "
16515: 		"base type must also be 'mixed'", NULL);
16516: 	    return (ctxt->err);
16517: 	}
16518: 	/*
16519: 	* SPEC (5.4.2) "The particle of the complex type definition itself
16520: 	* must be a �valid restriction� of the particle of the {content
16521: 	* type} of the {base type definition} as defined in Particle Valid
16522: 	* (Restriction) (�3.9.6).
16523: 	*
16524: 	* URGENT TODO: (5.4.2)
16525: 	*/
16526:     } else {
16527: 	xmlSchemaPCustomErr(ctxt,
16528: 	    XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
16529: 	    WXS_BASIC_CAST type, NULL,
16530: 	    "The type is not a valid restriction of its base type", NULL);
16531: 	return (ctxt->err);
16532:     }
16533:     return (0);
16534: }
16535: 
16536: /**
16537:  * xmlSchemaCheckCTComponent:
16538:  * @ctxt:  the schema parser context
16539:  * @type:  the complex type definition
16540:  *
16541:  * (3.4.6) Constraints on Complex Type Definition Schema Components
16542:  *
16543:  * Returns 0 if the constraints are satisfied, a positive
16544:  * error code if not and -1 if an internal error occured.
16545:  */
16546: static int
16547: xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
16548: 			  xmlSchemaTypePtr type)
16549: {
16550:     int ret;
16551:     /*
16552:     * Complex Type Definition Properties Correct
16553:     */
16554:     ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
16555:     if (ret != 0)
16556: 	return (ret);
16557:     if (WXS_IS_EXTENSION(type))
16558: 	ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
16559:     else
16560: 	ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
16561:     return (ret);
16562: }
16563: 
16564: /**
16565:  * xmlSchemaCheckSRCCT:
16566:  * @ctxt:  the schema parser context
16567:  * @type:  the complex type definition
16568:  *
16569:  * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
16570:  * Schema Representation Constraint:
16571:  * Complex Type Definition Representation OK (src-ct)
16572:  *
16573:  * Returns 0 if the constraints are satisfied, a positive
16574:  * error code if not and -1 if an internal error occured.
16575:  */
16576: static int
16577: xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
16578: 		    xmlSchemaTypePtr type)
16579: {
16580:     xmlSchemaTypePtr base;
16581:     int ret = 0;
16582: 
16583:     /*
16584:     * TODO: Adjust the error codes here, as I used
16585:     * XML_SCHEMAP_SRC_CT_1 only yet.
16586:     */
16587:     base = type->baseType;
16588:     if (! WXS_HAS_SIMPLE_CONTENT(type)) {
16589: 	/*
16590: 	* 1 If the <complexContent> alternative is chosen, the type definition
16591: 	* �resolved� to by the �actual value� of the base [attribute]
16592: 	* must be a complex type definition;
16593: 	*/
16594: 	if (! WXS_IS_COMPLEX(base)) {
16595: 	    xmlChar *str = NULL;
16596: 	    xmlSchemaPCustomErr(ctxt,
16597: 		XML_SCHEMAP_SRC_CT_1,
16598: 		WXS_BASIC_CAST type, type->node,
16599: 		"If using <complexContent>, the base type is expected to be "
16600: 		"a complex type. The base type '%s' is a simple type",
16601: 		xmlSchemaFormatQName(&str, base->targetNamespace,
16602: 		base->name));
16603: 	    FREE_AND_NULL(str)
16604: 	    return (XML_SCHEMAP_SRC_CT_1);
16605: 	}
16606:     } else {
16607: 	/*
16608: 	* SPEC
16609: 	* 2 If the <simpleContent> alternative is chosen, all of the
16610: 	* following must be true:
16611: 	* 2.1 The type definition �resolved� to by the �actual value� of the
16612: 	* base [attribute] must be one of the following:
16613: 	*/
16614: 	if (WXS_IS_SIMPLE(base)) {
16615: 	    if (WXS_IS_EXTENSION(type) == 0) {
16616: 		xmlChar *str = NULL;
16617: 		/*
16618: 		* 2.1.3 only if the <extension> alternative is also
16619: 		* chosen, a simple type definition.
16620: 		*/
16621: 		/* TODO: Change error code to ..._SRC_CT_2_1_3. */
16622: 		xmlSchemaPCustomErr(ctxt,
16623: 		    XML_SCHEMAP_SRC_CT_1,
16624: 		    WXS_BASIC_CAST type, NULL,
16625: 		    "If using <simpleContent> and <restriction>, the base "
16626: 		    "type must be a complex type. The base type '%s' is "
16627: 		    "a simple type",
16628: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16629: 			base->name));
16630: 		FREE_AND_NULL(str)
16631: 		return (XML_SCHEMAP_SRC_CT_1);
16632: 	    }
16633: 	} else {
16634: 	    /* Base type is a complex type. */
16635: 	    if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
16636: 		(base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
16637: 		/*
16638: 		* 2.1.1 a complex type definition whose {content type} is a
16639: 		* simple type definition;
16640: 		* PASS
16641: 		*/
16642: 		if (base->contentTypeDef == NULL) {
16643: 		    xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
16644: 			WXS_BASIC_CAST type, NULL,
16645: 			"Internal error: xmlSchemaCheckSRCCT, "
16646: 			"'%s', base type has no content type",
16647: 			type->name);
16648: 		    return (-1);
16649: 		}
16650: 	    } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
16651: 		(WXS_IS_RESTRICTION(type))) {
16652: 
16653: 		/*
16654: 		* 2.1.2 only if the <restriction> alternative is also
16655: 		* chosen, a complex type definition whose {content type}
16656: 		* is mixed and a particle emptiable.
16657: 		*/
16658: 		if (! xmlSchemaIsParticleEmptiable(
16659: 		    (xmlSchemaParticlePtr) base->subtypes)) {
16660: 		    ret = XML_SCHEMAP_SRC_CT_1;
16661: 		} else
16662: 		    /*
16663: 		    * Attention: at this point the <simpleType> child is in
16664: 		    * ->contentTypeDef (put there during parsing).
16665: 		    */
16666: 		    if (type->contentTypeDef == NULL) {
16667: 		    xmlChar *str = NULL;
16668: 		    /*
16669: 		    * 2.2 If clause 2.1.2 above is satisfied, then there
16670: 		    * must be a <simpleType> among the [children] of
16671: 		    * <restriction>.
16672: 		    */
16673: 		    /* TODO: Change error code to ..._SRC_CT_2_2. */
16674: 		    xmlSchemaPCustomErr(ctxt,
16675: 			XML_SCHEMAP_SRC_CT_1,
16676: 			WXS_BASIC_CAST type, NULL,
16677: 			"A <simpleType> is expected among the children "
16678: 			"of <restriction>, if <simpleContent> is used and "
16679: 			"the base type '%s' is a complex type",
16680: 			xmlSchemaFormatQName(&str, base->targetNamespace,
16681: 			base->name));
16682: 		    FREE_AND_NULL(str)
16683: 		    return (XML_SCHEMAP_SRC_CT_1);
16684: 		}
16685: 	    } else {
16686: 		ret = XML_SCHEMAP_SRC_CT_1;
16687: 	    }
16688: 	}
16689: 	if (ret > 0) {
16690: 	    xmlChar *str = NULL;
16691: 	    if (WXS_IS_RESTRICTION(type)) {
16692: 		xmlSchemaPCustomErr(ctxt,
16693: 		    XML_SCHEMAP_SRC_CT_1,
16694: 		    WXS_BASIC_CAST type, NULL,
16695: 		    "If <simpleContent> and <restriction> is used, the "
16696: 		    "base type must be a simple type or a complex type with "
16697: 		    "mixed content and particle emptiable. The base type "
16698: 		    "'%s' is none of those",
16699: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16700: 		    base->name));
16701: 	    } else {
16702: 		xmlSchemaPCustomErr(ctxt,
16703: 		    XML_SCHEMAP_SRC_CT_1,
16704: 		    WXS_BASIC_CAST type, NULL,
16705: 		    "If <simpleContent> and <extension> is used, the "
16706: 		    "base type must be a simple type. The base type '%s' "
16707: 		    "is a complex type",
16708: 		    xmlSchemaFormatQName(&str, base->targetNamespace,
16709: 		    base->name));
16710: 	    }
16711: 	    FREE_AND_NULL(str)
16712: 	}
16713:     }
16714:     /*
16715:     * SPEC (3) "The corresponding complex type definition component must
16716:     * satisfy the conditions set out in Constraints on Complex Type
16717:     * Definition Schema Components (�3.4.6);"
16718:     * NOTE (3) will be done in xmlSchemaTypeFixup().
16719:     */
16720:     /*
16721:     * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
16722:     * above for {attribute wildcard} is satisfied, the intensional
16723:     * intersection must be expressible, as defined in Attribute Wildcard
16724:     * Intersection (�3.10.6).
16725:     * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
16726:     */
16727:     return (ret);
16728: }
16729: 
16730: #ifdef ENABLE_PARTICLE_RESTRICTION
16731: /**
16732:  * xmlSchemaCheckParticleRangeOK:
16733:  * @ctxt:  the schema parser context
16734:  * @type:  the complex type definition
16735:  *
16736:  * (3.9.6) Constraints on Particle Schema Components
16737:  * Schema Component Constraint:
16738:  * Occurrence Range OK (range-ok)
16739:  *
16740:  * STATUS: complete
16741:  *
16742:  * Returns 0 if the constraints are satisfied, a positive
16743:  * error code if not and -1 if an internal error occured.
16744:  */
16745: static int
16746: xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
16747: 			      int bmin, int bmax)
16748: {
16749:     if (rmin < bmin)
16750: 	return (1);
16751:     if ((bmax != UNBOUNDED) &&
16752: 	(rmax > bmax))
16753: 	return (1);
16754:     return (0);
16755: }
16756: 
16757: /**
16758:  * xmlSchemaCheckRCaseNameAndTypeOK:
16759:  * @ctxt:  the schema parser context
16760:  * @r: the restricting element declaration particle
16761:  * @b: the base element declaration particle
16762:  *
16763:  * (3.9.6) Constraints on Particle Schema Components
16764:  * Schema Component Constraint:
16765:  * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
16766:  * (rcase-NameAndTypeOK)
16767:  *
16768:  * STATUS:
16769:  *   MISSING (3.2.3)
16770:  *   CLARIFY: (3.2.2)
16771:  *
16772:  * Returns 0 if the constraints are satisfied, a positive
16773:  * error code if not and -1 if an internal error occured.
16774:  */
16775: static int
16776: xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
16777: 				 xmlSchemaParticlePtr r,
16778: 				 xmlSchemaParticlePtr b)
16779: {
16780:     xmlSchemaElementPtr elemR, elemB;
16781: 
16782:     /* TODO: Error codes (rcase-NameAndTypeOK). */
16783:     elemR = (xmlSchemaElementPtr) r->children;
16784:     elemB = (xmlSchemaElementPtr) b->children;
16785:     /*
16786:     * SPEC (1) "The declarations' {name}s and {target namespace}s are
16787:     * the same."
16788:     */
16789:     if ((elemR != elemB) &&
16790: 	((! xmlStrEqual(elemR->name, elemB->name)) ||
16791: 	(! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
16792: 	return (1);
16793:     /*
16794:     * SPEC (2) "R's occurrence range is a valid restriction of B's
16795:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16796:     */
16797:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16798: 	    b->minOccurs, b->maxOccurs) != 0)
16799: 	return (1);
16800:     /*
16801:     * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
16802:     * {scope} are global."
16803:     */
16804:     if (elemR == elemB)
16805: 	return (0);
16806:     /*
16807:     * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
16808:     */
16809:     if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
16810: 	(elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
16811: 	 return (1);
16812:     /*
16813:     * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
16814:     * or is not fixed, or R's declaration's {value constraint} is fixed
16815:     * with the same value."
16816:     */
16817:     if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
16818: 	((elemR->value == NULL) ||
16819: 	 ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
16820: 	 /* TODO: Equality of the initial value or normalized or canonical? */
16821: 	 (! xmlStrEqual(elemR->value, elemB->value))))
16822: 	 return (1);
16823:     /*
16824:     * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
16825:     * definitions} is a subset of B's declaration's {identity-constraint
16826:     * definitions}, if any."
16827:     */
16828:     if (elemB->idcs != NULL) {
16829: 	/* TODO */
16830:     }
16831:     /*
16832:     * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
16833:     * superset of B's declaration's {disallowed substitutions}."
16834:     */
16835:     if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
16836: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
16837: 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
16838: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
16839: 	((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
16840: 	 ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
16841: 	 return (1);
16842:     /*
16843:     * SPEC (3.2.5) "R's {type definition} is validly derived given
16844:     * {extension, list, union} from B's {type definition}"
16845:     *
16846:     * BADSPEC TODO: What's the point of adding "list" and "union" to the
16847:     * set, if the corresponding constraints handle "restriction" and
16848:     * "extension" only?
16849:     *
16850:     */
16851:     {
16852: 	int set = 0;
16853: 
16854: 	set |= SUBSET_EXTENSION;
16855: 	set |= SUBSET_LIST;
16856: 	set |= SUBSET_UNION;
16857: 	if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
16858: 	    elemB->subtypes, set) != 0)
16859: 	    return (1);
16860:     }
16861:     return (0);
16862: }
16863: 
16864: /**
16865:  * xmlSchemaCheckRCaseNSCompat:
16866:  * @ctxt:  the schema parser context
16867:  * @r: the restricting element declaration particle
16868:  * @b: the base wildcard particle
16869:  *
16870:  * (3.9.6) Constraints on Particle Schema Components
16871:  * Schema Component Constraint:
16872:  * Particle Derivation OK (Elt:Any -- NSCompat)
16873:  * (rcase-NSCompat)
16874:  *
16875:  * STATUS: complete
16876:  *
16877:  * Returns 0 if the constraints are satisfied, a positive
16878:  * error code if not and -1 if an internal error occured.
16879:  */
16880: static int
16881: xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
16882: 			    xmlSchemaParticlePtr r,
16883: 			    xmlSchemaParticlePtr b)
16884: {
16885:     /* TODO:Error codes (rcase-NSCompat). */
16886:     /*
16887:     * SPEC "For an element declaration particle to be a �valid restriction�
16888:     * of a wildcard particle all of the following must be true:"
16889:     *
16890:     * SPEC (1) "The element declaration's {target namespace} is �valid�
16891:     * with respect to the wildcard's {namespace constraint} as defined by
16892:     * Wildcard allows Namespace Name (�3.10.4)."
16893:     */
16894:     if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
16895: 	((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
16896: 	return (1);
16897:     /*
16898:     * SPEC (2) "R's occurrence range is a valid restriction of B's
16899:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16900:     */
16901:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16902: 	    b->minOccurs, b->maxOccurs) != 0)
16903: 	return (1);
16904: 
16905:     return (0);
16906: }
16907: 
16908: /**
16909:  * xmlSchemaCheckRCaseRecurseAsIfGroup:
16910:  * @ctxt:  the schema parser context
16911:  * @r: the restricting element declaration particle
16912:  * @b: the base model group particle
16913:  *
16914:  * (3.9.6) Constraints on Particle Schema Components
16915:  * Schema Component Constraint:
16916:  * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
16917:  * (rcase-RecurseAsIfGroup)
16918:  *
16919:  * STATUS: TODO
16920:  *
16921:  * Returns 0 if the constraints are satisfied, a positive
16922:  * error code if not and -1 if an internal error occured.
16923:  */
16924: static int
16925: xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
16926: 				    xmlSchemaParticlePtr r,
16927: 				    xmlSchemaParticlePtr b)
16928: {
16929:     /* TODO: Error codes (rcase-RecurseAsIfGroup). */
16930:     TODO
16931:     return (0);
16932: }
16933: 
16934: /**
16935:  * xmlSchemaCheckRCaseNSSubset:
16936:  * @ctxt:  the schema parser context
16937:  * @r: the restricting wildcard particle
16938:  * @b: the base wildcard particle
16939:  *
16940:  * (3.9.6) Constraints on Particle Schema Components
16941:  * Schema Component Constraint:
16942:  * Particle Derivation OK (Any:Any -- NSSubset)
16943:  * (rcase-NSSubset)
16944:  *
16945:  * STATUS: complete
16946:  *
16947:  * Returns 0 if the constraints are satisfied, a positive
16948:  * error code if not and -1 if an internal error occured.
16949:  */
16950: static int
16951: xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
16952: 				    xmlSchemaParticlePtr r,
16953: 				    xmlSchemaParticlePtr b,
16954: 				    int isAnyTypeBase)
16955: {
16956:     /* TODO: Error codes (rcase-NSSubset). */
16957:     /*
16958:     * SPEC (1) "R's occurrence range is a valid restriction of B's
16959:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
16960:     */
16961:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
16962: 	    b->minOccurs, b->maxOccurs))
16963: 	return (1);
16964:     /*
16965:     * SPEC (2) "R's {namespace constraint} must be an intensional subset
16966:     * of B's {namespace constraint} as defined by Wildcard Subset (�3.10.6)."
16967:     */
16968:     if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
16969: 	(xmlSchemaWildcardPtr) b->children))
16970: 	return (1);
16971:     /*
16972:     * SPEC (3) "Unless B is the content model wildcard of the �ur-type
16973:     * definition�, R's {process contents} must be identical to or stronger
16974:     * than B's {process contents}, where strict is stronger than lax is
16975:     * stronger than skip."
16976:     */
16977:     if (! isAnyTypeBase) {
16978: 	if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
16979: 	    ((xmlSchemaWildcardPtr) b->children)->processContents)
16980: 	    return (1);
16981:     }
16982: 
16983:     return (0);
16984: }
16985: 
16986: /**
16987:  * xmlSchemaCheckCOSParticleRestrict:
16988:  * @ctxt:  the schema parser context
16989:  * @type:  the complex type definition
16990:  *
16991:  * (3.9.6) Constraints on Particle Schema Components
16992:  * Schema Component Constraint:
16993:  * Particle Valid (Restriction) (cos-particle-restrict)
16994:  *
16995:  * STATUS: TODO
16996:  *
16997:  * Returns 0 if the constraints are satisfied, a positive
16998:  * error code if not and -1 if an internal error occured.
16999:  */
17000: static int
17001: xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
17002: 				  xmlSchemaParticlePtr r,
17003: 				  xmlSchemaParticlePtr b)
17004: {
17005:     int ret = 0;
17006: 
17007:     /*part = WXS_TYPE_PARTICLE(type);
17008:     basePart = WXS_TYPE_PARTICLE(base);
17009:     */
17010: 
17011:     TODO
17012: 
17013:     /*
17014:     * SPEC (1) "They are the same particle."
17015:     */
17016:     if (r == b)
17017: 	return (0);
17018: 
17019: 
17020:     return (0);
17021: }
17022: 
17023: #if 0
17024: /**
17025:  * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
17026:  * @ctxt:  the schema parser context
17027:  * @r: the model group particle
17028:  * @b: the base wildcard particle
17029:  *
17030:  * (3.9.6) Constraints on Particle Schema Components
17031:  * Schema Component Constraint:
17032:  * Particle Derivation OK (All/Choice/Sequence:Any --
17033:  *                         NSRecurseCheckCardinality)
17034:  * (rcase-NSRecurseCheckCardinality)
17035:  *
17036:  * STATUS: TODO: subst-groups
17037:  *
17038:  * Returns 0 if the constraints are satisfied, a positive
17039:  * error code if not and -1 if an internal error occured.
17040:  */
17041: static int
17042: xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
17043: 					     xmlSchemaParticlePtr r,
17044: 					     xmlSchemaParticlePtr b)
17045: {
17046:     xmlSchemaParticlePtr part;
17047:     /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
17048:     if ((r->children == NULL) || (r->children->children == NULL))
17049: 	return (-1);
17050:     /*
17051:     * SPEC "For a group particle to be a �valid restriction� of a
17052:     * wildcard particle..."
17053:     *
17054:     * SPEC (1) "Every member of the {particles} of the group is a �valid
17055:     * restriction� of the wildcard as defined by
17056:     * Particle Valid (Restriction) (�3.9.6)."
17057:     */
17058:     part = (xmlSchemaParticlePtr) r->children->children;
17059:     do {
17060: 	if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
17061: 	    return (1);
17062: 	part = (xmlSchemaParticlePtr) part->next;
17063:     } while (part != NULL);
17064:     /*
17065:     * SPEC (2) "The effective total range of the group [...] is a
17066:     * valid restriction of B's occurrence range as defined by
17067:     * Occurrence Range OK (�3.9.6)."
17068:     */
17069:     if (xmlSchemaCheckParticleRangeOK(
17070: 	    xmlSchemaGetParticleTotalRangeMin(r),
17071: 	    xmlSchemaGetParticleTotalRangeMax(r),
17072: 	    b->minOccurs, b->maxOccurs) != 0)
17073: 	return (1);
17074:     return (0);
17075: }
17076: #endif
17077: 
17078: /**
17079:  * xmlSchemaCheckRCaseRecurse:
17080:  * @ctxt:  the schema parser context
17081:  * @r: the <all> or <sequence> model group particle
17082:  * @b: the base <all> or <sequence> model group particle
17083:  *
17084:  * (3.9.6) Constraints on Particle Schema Components
17085:  * Schema Component Constraint:
17086:  * Particle Derivation OK (All:All,Sequence:Sequence --
17087:                            Recurse)
17088:  * (rcase-Recurse)
17089:  *
17090:  * STATUS:  ?
17091:  * TODO: subst-groups
17092:  *
17093:  * Returns 0 if the constraints are satisfied, a positive
17094:  * error code if not and -1 if an internal error occured.
17095:  */
17096: static int
17097: xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
17098: 			   xmlSchemaParticlePtr r,
17099: 			   xmlSchemaParticlePtr b)
17100: {
17101:     /* xmlSchemaParticlePtr part; */
17102:     /* TODO: Error codes (rcase-Recurse). */
17103:     if ((r->children == NULL) || (b->children == NULL) ||
17104: 	(r->children->type != b->children->type))
17105: 	return (-1);
17106:     /*
17107:     * SPEC "For an all or sequence group particle to be a �valid
17108:     * restriction� of another group particle with the same {compositor}..."
17109:     *
17110:     * SPEC (1) "R's occurrence range is a valid restriction of B's
17111:     * occurrence range as defined by Occurrence Range OK (�3.9.6)."
17112:     */
17113:     if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
17114: 	    b->minOccurs, b->maxOccurs))
17115: 	return (1);
17116: 
17117: 
17118:     return (0);
17119: }
17120: 
17121: #endif
17122: 
17123: #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
17124:     xmlSchemaPCustomErrExt(pctxt,      \
17125: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17126: 	WXS_BASIC_CAST fac1, fac1->node, \
17127: 	"It is an error for both '%s' and '%s' to be specified on the "\
17128: 	"same type definition", \
17129: 	BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
17130: 	BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
17131: 
17132: #define FACET_RESTR_ERR(fac1, msg) \
17133:     xmlSchemaPCustomErr(pctxt,      \
17134: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17135: 	WXS_BASIC_CAST fac1, fac1->node, \
17136: 	msg, NULL);
17137: 
17138: #define FACET_RESTR_FIXED_ERR(fac) \
17139:     xmlSchemaPCustomErr(pctxt, \
17140: 	XML_SCHEMAP_INVALID_FACET_VALUE, \
17141: 	WXS_BASIC_CAST fac, fac->node, \
17142: 	"The base type's facet is 'fixed', thus the value must not " \
17143: 	"differ", NULL);
17144: 
17145: static void
17146: xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
17147: 			xmlSchemaFacetPtr facet1,
17148: 			xmlSchemaFacetPtr facet2,
17149: 			int lessGreater,
17150: 			int orEqual,
17151: 			int ofBase)
17152: {
17153:     xmlChar *msg = NULL;
17154: 
17155:     msg = xmlStrdup(BAD_CAST "'");
17156:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
17157:     msg = xmlStrcat(msg, BAD_CAST "' has to be");
17158:     if (lessGreater == 0)
17159: 	msg = xmlStrcat(msg, BAD_CAST " equal to");
17160:     if (lessGreater == 1)
17161: 	msg = xmlStrcat(msg, BAD_CAST " greater than");
17162:     else
17163: 	msg = xmlStrcat(msg, BAD_CAST " less than");
17164: 
17165:     if (orEqual)
17166: 	msg = xmlStrcat(msg, BAD_CAST " or equal to");
17167:     msg = xmlStrcat(msg, BAD_CAST " '");
17168:     msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
17169:     if (ofBase)
17170: 	msg = xmlStrcat(msg, BAD_CAST "' of the base type");
17171:     else
17172: 	msg = xmlStrcat(msg, BAD_CAST "'");
17173: 
17174:     xmlSchemaPCustomErr(pctxt,
17175: 	XML_SCHEMAP_INVALID_FACET_VALUE,
17176: 	WXS_BASIC_CAST facet1, NULL,
17177: 	(const char *) msg, NULL);
17178: 
17179:     if (msg != NULL)
17180: 	xmlFree(msg);
17181: }
17182: 
17183: /*
17184: * xmlSchemaDeriveAndValidateFacets:
17185: *
17186: * Schema Component Constraint: Simple Type Restriction (Facets)
17187: * (st-restrict-facets)
17188: */
17189: static int
17190: xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
17191: 				 xmlSchemaTypePtr type)
17192: {
17193:     xmlSchemaTypePtr base = type->baseType;
17194:     xmlSchemaFacetLinkPtr link, cur, last = NULL;
17195:     xmlSchemaFacetPtr facet, bfacet,
17196: 	flength = NULL, ftotdig = NULL, ffracdig = NULL,
17197: 	fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
17198: 	fmininc = NULL, fmaxinc = NULL,
17199: 	fminexc = NULL, fmaxexc = NULL,
17200: 	bflength = NULL, bftotdig = NULL, bffracdig = NULL,
17201: 	bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
17202: 	bfmininc = NULL, bfmaxinc = NULL,
17203: 	bfminexc = NULL, bfmaxexc = NULL;
17204:     int res; /* err = 0, fixedErr; */
17205: 
17206:     /*
17207:     * SPEC st-restrict-facets 1:
17208:     * "The {variety} of R is the same as that of B."
17209:     */
17210:     /*
17211:     * SPEC st-restrict-facets 2:
17212:     * "If {variety} is atomic, the {primitive type definition}
17213:     * of R is the same as that of B."
17214:     *
17215:     * NOTE: we leave 1 & 2 out for now, since this will be
17216:     * satisfied by the derivation process.
17217:     * CONSTRUCTION TODO: Maybe needed if using a construction API.
17218:     */
17219:     /*
17220:     * SPEC st-restrict-facets 3:
17221:     * "The {facets} of R are the union of S and the {facets}
17222:     * of B, eliminating duplicates. To eliminate duplicates,
17223:     * when a facet of the same kind occurs in both S and the
17224:     * {facets} of B, the one in the {facets} of B is not
17225:     * included, with the exception of enumeration and pattern
17226:     * facets, for which multiple occurrences with distinct values
17227:     * are allowed."
17228:     */
17229: 
17230:     if ((type->facetSet == NULL) && (base->facetSet == NULL))
17231: 	return (0);
17232: 
17233:     last = type->facetSet;
17234:     if (last != NULL)
17235: 	while (last->next != NULL)
17236: 	    last = last->next;
17237: 
17238:     for (cur = type->facetSet; cur != NULL; cur = cur->next) {
17239: 	facet = cur->facet;
17240: 	switch (facet->type) {
17241: 	    case XML_SCHEMA_FACET_LENGTH:
17242: 		flength = facet; break;
17243: 	    case XML_SCHEMA_FACET_MINLENGTH:
17244: 		fminlen = facet; break;
17245: 	    case XML_SCHEMA_FACET_MININCLUSIVE:
17246: 		fmininc = facet; break;
17247: 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
17248: 		fminexc = facet; break;
17249: 	    case XML_SCHEMA_FACET_MAXLENGTH:
17250: 		fmaxlen = facet; break;
17251: 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
17252: 		fmaxinc = facet; break;
17253: 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17254: 		fmaxexc = facet; break;
17255: 	    case XML_SCHEMA_FACET_TOTALDIGITS:
17256: 		ftotdig = facet; break;
17257: 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
17258: 		ffracdig = facet; break;
17259: 	    default:
17260: 		break;
17261: 	}
17262:     }
17263:     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17264: 	facet = cur->facet;
17265: 	switch (facet->type) {
17266: 	    case XML_SCHEMA_FACET_LENGTH:
17267: 		bflength = facet; break;
17268: 	    case XML_SCHEMA_FACET_MINLENGTH:
17269: 		bfminlen = facet; break;
17270: 	    case XML_SCHEMA_FACET_MININCLUSIVE:
17271: 		bfmininc = facet; break;
17272: 	    case XML_SCHEMA_FACET_MINEXCLUSIVE:
17273: 		bfminexc = facet; break;
17274: 	    case XML_SCHEMA_FACET_MAXLENGTH:
17275: 		bfmaxlen = facet; break;
17276: 	    case XML_SCHEMA_FACET_MAXINCLUSIVE:
17277: 		bfmaxinc = facet; break;
17278: 	    case XML_SCHEMA_FACET_MAXEXCLUSIVE:
17279: 		bfmaxexc = facet; break;
17280: 	    case XML_SCHEMA_FACET_TOTALDIGITS:
17281: 		bftotdig = facet; break;
17282: 	    case XML_SCHEMA_FACET_FRACTIONDIGITS:
17283: 		bffracdig = facet; break;
17284: 	    default:
17285: 		break;
17286: 	}
17287:     }
17288:     /*
17289:     * length and minLength or maxLength (2.2) + (3.2)
17290:     */
17291:     if (flength && (fminlen || fmaxlen)) {
17292: 	FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
17293: 	    "either of 'minLength' or 'maxLength' to be specified on "
17294: 	    "the same type definition")
17295:     }
17296:     /*
17297:     * Mutual exclusions in the same derivation step.
17298:     */
17299:     if ((fmaxinc) && (fmaxexc)) {
17300: 	/*
17301: 	* SCC "maxInclusive and maxExclusive"
17302: 	*/
17303: 	FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
17304:     }
17305:     if ((fmininc) && (fminexc)) {
17306: 	/*
17307: 	* SCC "minInclusive and minExclusive"
17308: 	*/
17309: 	FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
17310:     }
17311: 
17312:     if (flength && bflength) {
17313: 	/*
17314: 	* SCC "length valid restriction"
17315: 	* The values have to be equal.
17316: 	*/
17317: 	res = xmlSchemaCompareValues(flength->val, bflength->val);
17318: 	if (res == -2)
17319: 	    goto internal_error;
17320: 	if (res != 0)
17321: 	    xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
17322: 	if ((res != 0) && (bflength->fixed)) {
17323: 	    FACET_RESTR_FIXED_ERR(flength)
17324: 	}
17325: 
17326:     }
17327:     if (fminlen && bfminlen) {
17328: 	/*
17329: 	* SCC "minLength valid restriction"
17330: 	* minLength >= BASE minLength
17331: 	*/
17332: 	res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
17333: 	if (res == -2)
17334: 	    goto internal_error;
17335: 	if (res == -1)
17336: 	    xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
17337: 	if ((res != 0) && (bfminlen->fixed)) {
17338: 	    FACET_RESTR_FIXED_ERR(fminlen)
17339: 	}
17340:     }
17341:     if (fmaxlen && bfmaxlen) {
17342: 	/*
17343: 	* SCC "maxLength valid restriction"
17344: 	* maxLength <= BASE minLength
17345: 	*/
17346: 	res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
17347: 	if (res == -2)
17348: 	    goto internal_error;
17349: 	if (res == 1)
17350: 	    xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
17351: 	if ((res != 0) && (bfmaxlen->fixed)) {
17352: 	    FACET_RESTR_FIXED_ERR(fmaxlen)
17353: 	}
17354:     }
17355:     /*
17356:     * SCC "length and minLength or maxLength"
17357:     */
17358:     if (! flength)
17359: 	flength = bflength;
17360:     if (flength) {
17361: 	if (! fminlen)
17362: 	    fminlen = bfminlen;
17363: 	if (fminlen) {
17364: 	    /* (1.1) length >= minLength */
17365: 	    res = xmlSchemaCompareValues(flength->val, fminlen->val);
17366: 	    if (res == -2)
17367: 		goto internal_error;
17368: 	    if (res == -1)
17369: 		xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
17370: 	}
17371: 	if (! fmaxlen)
17372: 	    fmaxlen = bfmaxlen;
17373: 	if (fmaxlen) {
17374: 	    /* (2.1) length <= maxLength */
17375: 	    res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
17376: 	    if (res == -2)
17377: 		goto internal_error;
17378: 	    if (res == 1)
17379: 		xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
17380: 	}
17381:     }
17382:     if (fmaxinc) {
17383: 	/*
17384: 	* "maxInclusive"
17385: 	*/
17386: 	if (fmininc) {
17387: 	    /* SCC "maxInclusive >= minInclusive" */
17388: 	    res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
17389: 	    if (res == -2)
17390: 		goto internal_error;
17391: 	    if (res == -1) {
17392: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
17393: 	    }
17394: 	}
17395: 	/*
17396: 	* SCC "maxInclusive valid restriction"
17397: 	*/
17398: 	if (bfmaxinc) {
17399: 	    /* maxInclusive <= BASE maxInclusive */
17400: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
17401: 	    if (res == -2)
17402: 		goto internal_error;
17403: 	    if (res == 1)
17404: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
17405: 	    if ((res != 0) && (bfmaxinc->fixed)) {
17406: 		FACET_RESTR_FIXED_ERR(fmaxinc)
17407: 	    }
17408: 	}
17409: 	if (bfmaxexc) {
17410: 	    /* maxInclusive < BASE maxExclusive */
17411: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
17412: 	    if (res == -2)
17413: 		goto internal_error;
17414: 	    if (res != -1) {
17415: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
17416: 	    }
17417: 	}
17418: 	if (bfmininc) {
17419: 	    /* maxInclusive >= BASE minInclusive */
17420: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
17421: 	    if (res == -2)
17422: 		goto internal_error;
17423: 	    if (res == -1) {
17424: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
17425: 	    }
17426: 	}
17427: 	if (bfminexc) {
17428: 	    /* maxInclusive > BASE minExclusive */
17429: 	    res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
17430: 	    if (res == -2)
17431: 		goto internal_error;
17432: 	    if (res != 1) {
17433: 		xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
17434: 	    }
17435: 	}
17436:     }
17437:     if (fmaxexc) {
17438: 	/*
17439: 	* "maxExclusive >= minExclusive"
17440: 	*/
17441: 	if (fminexc) {
17442: 	    res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
17443: 	    if (res == -2)
17444: 		goto internal_error;
17445: 	    if (res == -1) {
17446: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
17447: 	    }
17448: 	}
17449: 	/*
17450: 	* "maxExclusive valid restriction"
17451: 	*/
17452: 	if (bfmaxexc) {
17453: 	    /* maxExclusive <= BASE maxExclusive */
17454: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
17455: 	    if (res == -2)
17456: 		goto internal_error;
17457: 	    if (res == 1) {
17458: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
17459: 	    }
17460: 	    if ((res != 0) && (bfmaxexc->fixed)) {
17461: 		FACET_RESTR_FIXED_ERR(fmaxexc)
17462: 	    }
17463: 	}
17464: 	if (bfmaxinc) {
17465: 	    /* maxExclusive <= BASE maxInclusive */
17466: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
17467: 	    if (res == -2)
17468: 		goto internal_error;
17469: 	    if (res == 1) {
17470: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
17471: 	    }
17472: 	}
17473: 	if (bfmininc) {
17474: 	    /* maxExclusive > BASE minInclusive */
17475: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
17476: 	    if (res == -2)
17477: 		goto internal_error;
17478: 	    if (res != 1) {
17479: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
17480: 	    }
17481: 	}
17482: 	if (bfminexc) {
17483: 	    /* maxExclusive > BASE minExclusive */
17484: 	    res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
17485: 	    if (res == -2)
17486: 		goto internal_error;
17487: 	    if (res != 1) {
17488: 		xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
17489: 	    }
17490: 	}
17491:     }
17492:     if (fminexc) {
17493: 	/*
17494: 	* "minExclusive < maxInclusive"
17495: 	*/
17496: 	if (fmaxinc) {
17497: 	    res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
17498: 	    if (res == -2)
17499: 		goto internal_error;
17500: 	    if (res != -1) {
17501: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
17502: 	    }
17503: 	}
17504: 	/*
17505: 	* "minExclusive valid restriction"
17506: 	*/
17507: 	if (bfminexc) {
17508: 	    /* minExclusive >= BASE minExclusive */
17509: 	    res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
17510: 	    if (res == -2)
17511: 		goto internal_error;
17512: 	    if (res == -1) {
17513: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
17514: 	    }
17515: 	    if ((res != 0) && (bfminexc->fixed)) {
17516: 		FACET_RESTR_FIXED_ERR(fminexc)
17517: 	    }
17518: 	}
17519: 	if (bfmaxinc) {
17520: 	    /* minExclusive <= BASE maxInclusive */
17521: 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
17522: 	    if (res == -2)
17523: 		goto internal_error;
17524: 	    if (res == 1) {
17525: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
17526: 	    }
17527: 	}
17528: 	if (bfmininc) {
17529: 	    /* minExclusive >= BASE minInclusive */
17530: 	    res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
17531: 	    if (res == -2)
17532: 		goto internal_error;
17533: 	    if (res == -1) {
17534: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
17535: 	    }
17536: 	}
17537: 	if (bfmaxexc) {
17538: 	    /* minExclusive < BASE maxExclusive */
17539: 	    res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
17540: 	    if (res == -2)
17541: 		goto internal_error;
17542: 	    if (res != -1) {
17543: 		xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
17544: 	    }
17545: 	}
17546:     }
17547:     if (fmininc) {
17548: 	/*
17549: 	* "minInclusive < maxExclusive"
17550: 	*/
17551: 	if (fmaxexc) {
17552: 	    res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
17553: 	    if (res == -2)
17554: 		goto internal_error;
17555: 	    if (res != -1) {
17556: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
17557: 	    }
17558: 	}
17559: 	/*
17560: 	* "minExclusive valid restriction"
17561: 	*/
17562: 	if (bfmininc) {
17563: 	    /* minInclusive >= BASE minInclusive */
17564: 	    res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
17565: 	    if (res == -2)
17566: 		goto internal_error;
17567: 	    if (res == -1) {
17568: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
17569: 	    }
17570: 	    if ((res != 0) && (bfmininc->fixed)) {
17571: 		FACET_RESTR_FIXED_ERR(fmininc)
17572: 	    }
17573: 	}
17574: 	if (bfmaxinc) {
17575: 	    /* minInclusive <= BASE maxInclusive */
17576: 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
17577: 	    if (res == -2)
17578: 		goto internal_error;
17579: 	    if (res == 1) {
17580: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
17581: 	    }
17582: 	}
17583: 	if (bfminexc) {
17584: 	    /* minInclusive > BASE minExclusive */
17585: 	    res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
17586: 	    if (res == -2)
17587: 		goto internal_error;
17588: 	    if (res != 1)
17589: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
17590: 	}
17591: 	if (bfmaxexc) {
17592: 	    /* minInclusive < BASE maxExclusive */
17593: 	    res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
17594: 	    if (res == -2)
17595: 		goto internal_error;
17596: 	    if (res != -1)
17597: 		xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
17598: 	}
17599:     }
17600:     if (ftotdig && bftotdig) {
17601: 	/*
17602: 	* SCC " totalDigits valid restriction"
17603: 	* totalDigits <= BASE totalDigits
17604: 	*/
17605: 	res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
17606: 	if (res == -2)
17607: 	    goto internal_error;
17608: 	if (res == 1)
17609: 	    xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
17610: 	    -1, 1, 1);
17611: 	if ((res != 0) && (bftotdig->fixed)) {
17612: 	    FACET_RESTR_FIXED_ERR(ftotdig)
17613: 	}
17614:     }
17615:     if (ffracdig && bffracdig) {
17616: 	/*
17617: 	* SCC  "fractionDigits valid restriction"
17618: 	* fractionDigits <= BASE fractionDigits
17619: 	*/
17620: 	res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
17621: 	if (res == -2)
17622: 	    goto internal_error;
17623: 	if (res == 1)
17624: 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
17625: 	    -1, 1, 1);
17626: 	if ((res != 0) && (bffracdig->fixed)) {
17627: 	    FACET_RESTR_FIXED_ERR(ffracdig)
17628: 	}
17629:     }
17630:     /*
17631:     * SCC "fractionDigits less than or equal to totalDigits"
17632:     */
17633:     if (! ftotdig)
17634: 	ftotdig = bftotdig;
17635:     if (! ffracdig)
17636: 	ffracdig = bffracdig;
17637:     if (ftotdig && ffracdig) {
17638: 	res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
17639: 	if (res == -2)
17640: 	    goto internal_error;
17641: 	if (res == 1)
17642: 	    xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
17643: 		-1, 1, 0);
17644:     }
17645:     /*
17646:     * *Enumerations* won' be added here, since only the first set
17647:     * of enumerations in the ancestor-or-self axis is used
17648:     * for validation, plus we need to use the base type of those
17649:     * enumerations for whitespace.
17650:     *
17651:     * *Patterns*: won't be add here, since they are ORed at
17652:     * type level and ANDed at ancestor level. This will
17653:     * happed during validation by walking the base axis
17654:     * of the type.
17655:     */
17656:     for (cur = base->facetSet; cur != NULL; cur = cur->next) {
17657: 	bfacet = cur->facet;
17658: 	/*
17659: 	* Special handling of enumerations and patterns.
17660: 	* TODO: hmm, they should not appear in the set, so remove this.
17661: 	*/
17662: 	if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
17663: 	    (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
17664: 	    continue;
17665: 	/*
17666: 	* Search for a duplicate facet in the current type.
17667: 	*/
17668: 	link = type->facetSet;
17669: 	/* err = 0; */
17670: 	/* fixedErr = 0; */
17671: 	while (link != NULL) {
17672: 	    facet = link->facet;
17673: 	    if (facet->type == bfacet->type) {
17674: 		switch (facet->type) {
17675: 		    case XML_SCHEMA_FACET_WHITESPACE:
17676: 			/*
17677: 			* The whitespace must be stronger.
17678: 			*/
17679: 			if (facet->whitespace < bfacet->whitespace) {
17680: 			    FACET_RESTR_ERR(facet,
17681: 				"The 'whitespace' value has to be equal to "
17682: 				"or stronger than the 'whitespace' value of "
17683: 				"the base type")
17684: 			}
17685: 			if ((bfacet->fixed) &&
17686: 			    (facet->whitespace != bfacet->whitespace)) {
17687: 			    FACET_RESTR_FIXED_ERR(facet)
17688: 			}
17689: 			break;
17690: 		    default:
17691: 			break;
17692: 		}
17693: 		/* Duplicate found. */
17694: 		break;
17695: 	    }
17696: 	    link = link->next;
17697: 	}
17698: 	/*
17699: 	* If no duplicate was found: add the base types's facet
17700: 	* to the set.
17701: 	*/
17702: 	if (link == NULL) {
17703: 	    link = (xmlSchemaFacetLinkPtr)
17704: 		xmlMalloc(sizeof(xmlSchemaFacetLink));
17705: 	    if (link == NULL) {
17706: 		xmlSchemaPErrMemory(pctxt,
17707: 		    "deriving facets, creating a facet link", NULL);
17708: 		return (-1);
17709: 	    }
17710: 	    link->facet = cur->facet;
17711: 	    link->next = NULL;
17712: 	    if (last == NULL)
17713: 		type->facetSet = link;
17714: 	    else
17715: 		last->next = link;
17716: 	    last = link;
17717: 	}
17718: 
17719:     }
17720: 
17721:     return (0);
17722: internal_error:
17723:     PERROR_INT("xmlSchemaDeriveAndValidateFacets",
17724: 	"an error occured");
17725:     return (-1);
17726: }
17727: 
17728: static int
17729: xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
17730: 					     xmlSchemaTypePtr type)
17731: {
17732:     xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
17733:     /*
17734:     * The actual value is then formed by replacing any union type
17735:     * definition in the �explicit members� with the members of their
17736:     * {member type definitions}, in order.
17737:     *
17738:     * TODO: There's a bug entry at
17739:     * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
17740:     * which indicates that we'll keep the union types the future.
17741:     */
17742:     link = type->memberTypes;
17743:     while (link != NULL) {
17744: 
17745: 	if (WXS_IS_TYPE_NOT_FIXED(link->type))
17746: 	    xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
17747: 
17748: 	if (WXS_IS_UNION(link->type)) {
17749: 	    subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
17750: 	    if (subLink != NULL) {
17751: 		link->type = subLink->type;
17752: 		if (subLink->next != NULL) {
17753: 		    lastLink = link->next;
17754: 		    subLink = subLink->next;
17755: 		    prevLink = link;
17756: 		    while (subLink != NULL) {
17757: 			newLink = (xmlSchemaTypeLinkPtr)
17758: 			    xmlMalloc(sizeof(xmlSchemaTypeLink));
17759: 			if (newLink == NULL) {
17760: 			    xmlSchemaPErrMemory(pctxt, "allocating a type link",
17761: 				NULL);
17762: 			    return (-1);
17763: 			}
17764: 			newLink->type = subLink->type;
17765: 			prevLink->next = newLink;
17766: 			prevLink = newLink;
17767: 			newLink->next = lastLink;
17768: 
17769: 			subLink = subLink->next;
17770: 		    }
17771: 		}
17772: 	    }
17773: 	}
17774: 	link = link->next;
17775:     }
17776:     return (0);
17777: }
17778: 
17779: static void
17780: xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
17781: {
17782:     int has = 0, needVal = 0, normVal = 0;
17783: 
17784:     has	= (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
17785:     if (has) {
17786: 	needVal = (type->baseType->flags &
17787: 	    XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
17788: 	normVal = (type->baseType->flags &
17789: 	    XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
17790:     }
17791:     if (type->facets != NULL) {
17792: 	xmlSchemaFacetPtr fac;
17793: 
17794: 	for (fac = type->facets; fac != NULL; fac = fac->next) {
17795: 	    switch (fac->type) {
17796: 		case XML_SCHEMA_FACET_WHITESPACE:
17797: 		    break;
17798: 		case XML_SCHEMA_FACET_PATTERN:
17799: 		    normVal = 1;
17800: 		    has = 1;
17801: 		    break;
17802: 		case XML_SCHEMA_FACET_ENUMERATION:
17803: 		    needVal = 1;
17804: 		    normVal = 1;
17805: 		    has = 1;
17806: 		    break;
17807: 		default:
17808: 		    has = 1;
17809: 		    break;
17810: 	    }
17811: 	}
17812:     }
17813:     if (normVal)
17814: 	type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
17815:     if (needVal)
17816: 	type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17817:     if (has)
17818: 	type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
17819: 
17820:     if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
17821: 	xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
17822: 	/*
17823: 	* OPTIMIZE VAL TODO: Some facets need a computed value.
17824: 	*/
17825: 	if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
17826: 	    (prim->builtInType != XML_SCHEMAS_STRING)) {
17827: 	    type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
17828: 	}
17829:     }
17830: }
17831: 
17832: static int
17833: xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
17834: {
17835: 
17836: 
17837:     /*
17838:     * Evaluate the whitespace-facet value.
17839:     */
17840:     if (WXS_IS_LIST(type)) {
17841: 	type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17842: 	return (0);
17843:     } else if (WXS_IS_UNION(type))
17844: 	return (0);
17845: 
17846:     if (type->facetSet != NULL) {
17847: 	xmlSchemaFacetLinkPtr lin;
17848: 
17849: 	for (lin = type->facetSet; lin != NULL; lin = lin->next) {
17850: 	    if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
17851: 		switch (lin->facet->whitespace) {
17852: 		case XML_SCHEMAS_FACET_PRESERVE:
17853: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17854: 		    break;
17855: 		case XML_SCHEMAS_FACET_REPLACE:
17856: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17857: 		    break;
17858: 		case XML_SCHEMAS_FACET_COLLAPSE:
17859: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17860: 		    break;
17861: 		default:
17862: 		    return (-1);
17863: 		}
17864: 		return (0);
17865: 	    }
17866: 	}
17867:     }
17868:     /*
17869:     * For all �atomic� datatypes other than string (and types �derived�
17870:     * by �restriction� from it) the value of whiteSpace is fixed to
17871:     * collapse
17872:     */
17873:     {
17874: 	xmlSchemaTypePtr anc;
17875: 
17876: 	for (anc = type->baseType; anc != NULL &&
17877: 		anc->builtInType != XML_SCHEMAS_ANYTYPE;
17878: 		anc = anc->baseType) {
17879: 
17880: 	    if (anc->type == XML_SCHEMA_TYPE_BASIC) {
17881: 		if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
17882: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
17883: 
17884: 		} else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
17885: 		    (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
17886: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
17887: 
17888: 		} else
17889: 		    type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
17890: 		break;
17891: 	    }
17892: 	}
17893:     }
17894:     return (0);
17895: }
17896: 
17897: static int
17898: xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
17899: 			  xmlSchemaTypePtr type)
17900: {
17901:     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
17902: 	return(0);
17903:     if (! WXS_IS_TYPE_NOT_FIXED_1(type))
17904: 	return(0);
17905:     type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
17906: 
17907:     if (WXS_IS_LIST(type)) {
17908: 	/*
17909: 	* Corresponds to <simpleType><list>...
17910: 	*/
17911: 	if (type->subtypes == NULL) {
17912: 	    /*
17913: 	    * This one is really needed, so get out.
17914: 	    */
17915: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17916: 		"list type has no item-type assigned");
17917: 	    return(-1);
17918: 	}
17919:     } else if (WXS_IS_UNION(type)) {
17920: 	/*
17921: 	* Corresponds to <simpleType><union>...
17922: 	*/
17923: 	if (type->memberTypes == NULL) {
17924: 	    /*
17925: 	    * This one is really needed, so get out.
17926: 	    */
17927: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17928: 		"union type has no member-types assigned");
17929: 	    return(-1);
17930: 	}
17931:     } else {
17932: 	/*
17933: 	* Corresponds to <simpleType><restriction>...
17934: 	*/
17935: 	if (type->baseType == NULL) {
17936: 	    PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
17937: 		"type has no base-type assigned");
17938: 	    return(-1);
17939: 	}
17940: 	if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
17941: 	    if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
17942: 		return(-1);
17943: 	/*
17944: 	* Variety
17945: 	* If the <restriction> alternative is chosen, then the
17946: 	* {variety} of the {base type definition}.
17947: 	*/
17948: 	if (WXS_IS_ATOMIC(type->baseType))
17949: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
17950: 	else if (WXS_IS_LIST(type->baseType)) {
17951: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
17952: 	    /*
17953: 	    * Inherit the itemType.
17954: 	    */
17955: 	    type->subtypes = type->baseType->subtypes;
17956: 	} else if (WXS_IS_UNION(type->baseType)) {
17957: 	    type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
17958: 	    /*
17959: 	    * NOTE that we won't assign the memberTypes of the base,
17960: 	    * since this will make trouble when freeing them; we will
17961: 	    * use a lookup function to access them instead.
17962: 	    */
17963: 	}
17964:     }
17965:     return(0);
17966: }
17967: 
17968: #ifdef DEBUG_TYPE
17969: static void
17970: xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
17971: 		       xmlSchemaTypePtr type)
17972: {
17973:     if (type->node != NULL) {
17974:         xmlGenericError(xmlGenericErrorContext,
17975:                         "Type of %s : %s:%d :", name,
17976:                         type->node->doc->URL,
17977:                         xmlGetLineNo(type->node));
17978:     } else {
17979:         xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
17980:     }
17981:     if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
17982: 	switch (type->contentType) {
17983: 	    case XML_SCHEMA_CONTENT_SIMPLE:
17984: 		xmlGenericError(xmlGenericErrorContext, "simple\n");
17985: 		break;
17986: 	    case XML_SCHEMA_CONTENT_ELEMENTS:
17987: 		xmlGenericError(xmlGenericErrorContext, "elements\n");
17988: 		break;
17989: 	    case XML_SCHEMA_CONTENT_UNKNOWN:
17990: 		xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
17991: 		break;
17992: 	    case XML_SCHEMA_CONTENT_EMPTY:
17993: 		xmlGenericError(xmlGenericErrorContext, "empty\n");
17994: 		break;
17995: 	    case XML_SCHEMA_CONTENT_MIXED:
17996: 		if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
17997: 		    type->subtypes))
17998: 		    xmlGenericError(xmlGenericErrorContext,
17999: 			"mixed as emptiable particle\n");
18000: 		else
18001: 		    xmlGenericError(xmlGenericErrorContext, "mixed\n");
18002: 		break;
18003: 		/* Removed, since not used. */
18004: 		/*
18005: 		case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
18006: 		xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
18007: 		break;
18008: 		*/
18009: 	    case XML_SCHEMA_CONTENT_BASIC:
18010: 		xmlGenericError(xmlGenericErrorContext, "basic\n");
18011: 		break;
18012: 	    default:
18013: 		xmlGenericError(xmlGenericErrorContext,
18014: 		    "not registered !!!\n");
18015: 		break;
18016: 	}
18017:     }
18018: }
18019: #endif
18020: 
18021: /*
18022: * 3.14.6 Constraints on Simple Type Definition Schema Components
18023: */
18024: static int
18025: xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
18026: 				 xmlSchemaTypePtr type)
18027: {
18028:     int res, olderrs = pctxt->nberrors;
18029: 
18030:     if (type->type != XML_SCHEMA_TYPE_SIMPLE)
18031: 	return(-1);
18032: 
18033:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18034: 	return(0);
18035: 
18036:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18037:     type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
18038: 
18039:     if (type->baseType == NULL) {
18040: 	PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
18041: 	    "missing baseType");
18042: 	goto exit_failure;
18043:     }
18044:     if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
18045: 	xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
18046:     /*
18047:     * If a member type of a union is a union itself, we need to substitute
18048:     * that member type for its member types.
18049:     * NOTE that this might change in WXS 1.1; i.e. we will keep the union
18050:     * types in WXS 1.1.
18051:     */
18052:     if ((type->memberTypes != NULL) &&
18053: 	(xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
18054: 	return(-1);
18055:     /*
18056:     * SPEC src-simple-type 1
18057:     * "The corresponding simple type definition, if any, must satisfy
18058:     * the conditions set out in Constraints on Simple Type Definition
18059:     * Schema Components (�3.14.6)."
18060:     */
18061:     /*
18062:     * Schema Component Constraint: Simple Type Definition Properties Correct
18063:     * (st-props-correct)
18064:     */
18065:     res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
18066:     HFAILURE HERROR
18067:     /*
18068:     * Schema Component Constraint: Derivation Valid (Restriction, Simple)
18069:     * (cos-st-restricts)
18070:     */
18071:     res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
18072:     HFAILURE HERROR
18073:     /*
18074:     * TODO: Removed the error report, since it got annoying to get an
18075:     * extra error report, if anything failed until now.
18076:     * Enable this if needed.
18077:     *
18078:     * xmlSchemaPErr(ctxt, type->node,
18079:     *    XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
18080:     *    "Simple type '%s' does not satisfy the constraints "
18081:     *    "on simple type definitions.\n",
18082:     *    type->name, NULL);
18083:     */
18084:     /*
18085:     * Schema Component Constraint: Simple Type Restriction (Facets)
18086:     * (st-restrict-facets)
18087:     */
18088:     res = xmlSchemaCheckFacetValues(type, pctxt);
18089:     HFAILURE HERROR
18090:     if ((type->facetSet != NULL) ||
18091: 	(type->baseType->facetSet != NULL)) {
18092: 	res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
18093: 	HFAILURE HERROR
18094:     }
18095:     /*
18096:     * Whitespace value.
18097:     */
18098:     res = xmlSchemaTypeFixupWhitespace(type);
18099:     HFAILURE HERROR
18100:     xmlSchemaTypeFixupOptimFacets(type);
18101: 
18102: exit_error:
18103: #ifdef DEBUG_TYPE
18104:     xmlSchemaDebugFixedType(pctxt, type);
18105: #endif
18106:     if (olderrs != pctxt->nberrors)
18107: 	return(pctxt->err);
18108:     return(0);
18109: 
18110: exit_failure:
18111: #ifdef DEBUG_TYPE
18112:     xmlSchemaDebugFixedType(pctxt, type);
18113: #endif
18114:     return(-1);
18115: }
18116: 
18117: static int
18118: xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
18119: 			  xmlSchemaTypePtr type)
18120: {
18121:     int res = 0, olderrs = pctxt->nberrors;
18122:     xmlSchemaTypePtr baseType = type->baseType;
18123: 
18124:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18125: 	return(0);
18126:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
18127:     if (baseType == NULL) {
18128: 	PERROR_INT("xmlSchemaFixupComplexType",
18129: 	    "missing baseType");
18130: 	goto exit_failure;
18131:     }
18132:     /*
18133:     * Fixup the base type.
18134:     */
18135:     if (WXS_IS_TYPE_NOT_FIXED(baseType))
18136: 	xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
18137:     if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
18138: 	/*
18139: 	* Skip fixup if the base type is invalid.
18140: 	* TODO: Generate a warning!
18141: 	*/
18142: 	return(0);
18143:     }
18144:     /*
18145:     * This basically checks if the base type can be derived.
18146:     */
18147:     res = xmlSchemaCheckSRCCT(pctxt, type);
18148:     HFAILURE HERROR
18149:     /*
18150:     * Fixup the content type.
18151:     */
18152:     if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
18153: 	/*
18154: 	* Corresponds to <complexType><simpleContent>...
18155: 	*/
18156: 	if ((WXS_IS_COMPLEX(baseType)) &&
18157: 	    (baseType->contentTypeDef != NULL) &&
18158: 	    (WXS_IS_RESTRICTION(type))) {
18159: 	    xmlSchemaTypePtr contentBase, content;
18160: #ifdef ENABLE_NAMED_LOCALS
18161: 	    char buf[30];
18162: 	    const xmlChar *tmpname;
18163: #endif
18164: 	    /*
18165: 	    * SPEC (1) If <restriction> + base type is <complexType>,
18166: 	    * "whose own {content type} is a simple type..."
18167: 	    */
18168: 	    if (type->contentTypeDef != NULL) {
18169: 		/*
18170: 		* SPEC (1.1) "the simple type definition corresponding to the
18171: 		* <simpleType> among the [children] of <restriction> if there
18172: 		* is one;"
18173: 		* Note that this "<simpleType> among the [children]" was put
18174: 		* into ->contentTypeDef during parsing.
18175: 		*/
18176: 		contentBase = type->contentTypeDef;
18177: 		type->contentTypeDef = NULL;
18178: 	    } else {
18179: 		/*
18180: 		* (1.2) "...otherwise (<restriction> has no <simpleType>
18181: 		* among its [children]), the simple type definition which
18182: 		* is the {content type} of the ... base type."
18183: 		*/
18184: 		contentBase = baseType->contentTypeDef;
18185: 	    }
18186: 	    /*
18187: 	    * SPEC
18188: 	    * "... a simple type definition which restricts the simple
18189: 	    * type definition identified in clause 1.1 or clause 1.2
18190: 	    * with a set of facet components"
18191: 	    *
18192: 	    * Create the anonymous simple type, which will be the content
18193: 	    * type of the complex type.
18194: 	    */
18195: #ifdef ENABLE_NAMED_LOCALS
18196: 	    snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
18197: 	    tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
18198: 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
18199: 		XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
18200: 		type->node, 0);
18201: #else
18202: 	    content = xmlSchemaAddType(pctxt, pctxt->schema,
18203: 		XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
18204: 		type->node, 0);
18205: #endif
18206: 	    if (content == NULL)
18207: 		goto exit_failure;
18208: 	    /*
18209: 	    * We will use the same node as for the <complexType>
18210: 	    * to have it somehow anchored in the schema doc.
18211: 	    */
18212: 	    content->type = XML_SCHEMA_TYPE_SIMPLE;
18213: 	    content->baseType = contentBase;
18214: 	    /*
18215: 	    * Move the facets, previously anchored on the
18216: 	    * complexType during parsing.
18217: 	    */
18218: 	    content->facets = type->facets;
18219: 	    type->facets = NULL;
18220: 	    content->facetSet = type->facetSet;
18221: 	    type->facetSet = NULL;
18222: 
18223: 	    type->contentTypeDef = content;
18224: 	    if (WXS_IS_TYPE_NOT_FIXED(contentBase))
18225: 		xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
18226: 	    /*
18227: 	    * Fixup the newly created type. We don't need to check
18228: 	    * for circularity here.
18229: 	    */
18230: 	    res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
18231: 	    HFAILURE HERROR
18232: 	    res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
18233: 	    HFAILURE HERROR
18234: 
18235: 	} else if ((WXS_IS_COMPLEX(baseType)) &&
18236: 	    (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
18237: 	    (WXS_IS_RESTRICTION(type))) {
18238: 	    /*
18239: 	    * SPEC (2) If <restriction> + base is a mixed <complexType> with
18240: 	    * an emptiable particle, then a simple type definition which
18241: 	    * restricts the <restriction>'s <simpleType> child.
18242: 	    */
18243: 	    if ((type->contentTypeDef == NULL) ||
18244: 		(type->contentTypeDef->baseType == NULL)) {
18245: 		/*
18246: 		* TODO: Check if this ever happens.
18247: 		*/
18248: 		xmlSchemaPCustomErr(pctxt,
18249: 		    XML_SCHEMAP_INTERNAL,
18250: 		    WXS_BASIC_CAST type, NULL,
18251: 		    "Internal error: xmlSchemaTypeFixup, "
18252: 		    "complex type '%s': the <simpleContent><restriction> "
18253: 		    "is missing a <simpleType> child, but was not catched "
18254: 		    "by xmlSchemaCheckSRCCT()", type->name);
18255: 		goto exit_failure;
18256: 	    }
18257: 	} else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
18258: 	    /*
18259: 	    * SPEC (3) If <extension> + base is <complexType> with
18260: 	    * <simpleType> content, "...then the {content type} of that
18261: 	    * complex type definition"
18262: 	    */
18263: 	    if (baseType->contentTypeDef == NULL) {
18264: 		/*
18265: 		* TODO: Check if this ever happens. xmlSchemaCheckSRCCT
18266: 		* should have catched this already.
18267: 		*/
18268: 		xmlSchemaPCustomErr(pctxt,
18269: 		    XML_SCHEMAP_INTERNAL,
18270: 		    WXS_BASIC_CAST type, NULL,
18271: 		    "Internal error: xmlSchemaTypeFixup, "
18272: 		    "complex type '%s': the <extension>ed base type is "
18273: 		    "a complex type with no simple content type",
18274: 		    type->name);
18275: 		goto exit_failure;
18276: 	    }
18277: 	    type->contentTypeDef = baseType->contentTypeDef;
18278: 	} else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
18279: 	    /*
18280: 	    * SPEC (4) <extension> + base is <simpleType>
18281: 	    * "... then that simple type definition"
18282: 	    */
18283: 	    type->contentTypeDef = baseType;
18284: 	} else {
18285: 	    /*
18286: 	    * TODO: Check if this ever happens.
18287: 	    */
18288: 	    xmlSchemaPCustomErr(pctxt,
18289: 		XML_SCHEMAP_INTERNAL,
18290: 		WXS_BASIC_CAST type, NULL,
18291: 		"Internal error: xmlSchemaTypeFixup, "
18292: 		"complex type '%s' with <simpleContent>: unhandled "
18293: 		"derivation case", type->name);
18294: 	    goto exit_failure;
18295: 	}
18296:     } else {
18297: 	int dummySequence = 0;
18298: 	xmlSchemaParticlePtr particle =
18299: 	    (xmlSchemaParticlePtr) type->subtypes;
18300: 	/*
18301: 	* Corresponds to <complexType><complexContent>...
18302: 	*
18303: 	* NOTE that the effective mixed was already set during parsing of
18304: 	* <complexType> and <complexContent>; its flag value is
18305: 	* XML_SCHEMAS_TYPE_MIXED.
18306: 	*
18307: 	* Compute the "effective content":
18308: 	* (2.1.1) + (2.1.2) + (2.1.3)
18309: 	*/
18310: 	if ((particle == NULL) ||
18311: 	    ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
18312: 	    ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
18313: 	    (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
18314: 	    ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
18315: 	    (particle->minOccurs == 0))) &&
18316: 	    ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
18317: 	    if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
18318: 		/*
18319: 		* SPEC (2.1.4) "If the �effective mixed� is true, then
18320: 		* a particle whose properties are as follows:..."
18321: 		*
18322: 		* Empty sequence model group with
18323: 		* minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
18324: 		* NOTE that we sill assign it the <complexType> node to
18325: 		* somehow anchor it in the doc.
18326: 		*/
18327: 		if ((particle == NULL) ||
18328: 		    (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
18329: 		    /*
18330: 		    * Create the particle.
18331: 		    */
18332: 		    particle = xmlSchemaAddParticle(pctxt,
18333: 			type->node, 1, 1);
18334: 		    if (particle == NULL)
18335: 			goto exit_failure;
18336: 		    /*
18337: 		    * Create the model group.
18338: 		    */ /* URGENT TODO: avoid adding to pending items. */
18339: 		    particle->children = (xmlSchemaTreeItemPtr)
18340: 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18341: 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
18342: 		    if (particle->children == NULL)
18343: 			goto exit_failure;
18344: 
18345: 		    type->subtypes = (xmlSchemaTypePtr) particle;
18346: 		}
18347: 		dummySequence = 1;
18348: 		type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18349: 	    } else {
18350: 		/*
18351: 		* SPEC (2.1.5) "otherwise empty"
18352: 		*/
18353: 		type->contentType = XML_SCHEMA_CONTENT_EMPTY;
18354: 	    }
18355: 	} else {
18356: 	    /*
18357: 	    * SPEC (2.2) "otherwise the particle corresponding to the
18358: 	    * <all>, <choice>, <group> or <sequence> among the
18359: 	    * [children]."
18360: 	    */
18361: 	    type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
18362: 	}
18363: 	/*
18364: 	* Compute the "content type".
18365: 	*/
18366: 	if (WXS_IS_RESTRICTION(type)) {
18367: 	    /*
18368: 	    * SPEC (3.1) "If <restriction>..."
18369: 	    * (3.1.1) + (3.1.2) */
18370: 	    if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
18371: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18372: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18373: 	    }
18374: 	} else {
18375: 	    /*
18376: 	    * SPEC (3.2) "If <extension>..."
18377: 	    */
18378: 	    if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18379: 		/*
18380: 		* SPEC (3.2.1)
18381: 		* "If the �effective content� is empty, then the
18382: 		*  {content type} of the [...] base ..."
18383: 		*/
18384: 		type->contentType = baseType->contentType;
18385: 		type->subtypes = baseType->subtypes;
18386: 		/*
18387: 		* Fixes bug #347316:
18388: 		* This is the case when the base type has a simple
18389: 		* type definition as content.
18390: 		*/
18391: 		type->contentTypeDef = baseType->contentTypeDef;
18392: 		/*
18393: 		* NOTE that the effective mixed is ignored here.
18394: 		*/
18395: 	    } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
18396: 		/*
18397: 		* SPEC (3.2.2)
18398: 		*/
18399: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18400: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18401: 	    } else {
18402: 		/*
18403: 		* SPEC (3.2.3)
18404: 		*/
18405: 		if (type->flags & XML_SCHEMAS_TYPE_MIXED)
18406: 		    type->contentType = XML_SCHEMA_CONTENT_MIXED;
18407: 		    /*
18408: 		    * "A model group whose {compositor} is sequence and whose
18409: 		    * {particles} are..."
18410: 		    */
18411: 		if ((WXS_TYPE_PARTICLE(type) != NULL) &&
18412: 		    (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
18413: 		    ((WXS_TYPE_PARTICLE_TERM(type))->type ==
18414: 			XML_SCHEMA_TYPE_ALL))
18415: 		{
18416: 		    /*
18417: 		    * SPEC cos-all-limited (1)
18418: 		    */
18419: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18420: 			/* TODO: error code */
18421: 			XML_SCHEMAP_COS_ALL_LIMITED,
18422: 			WXS_ITEM_NODE(type), NULL,
18423: 			"The type has an 'all' model group in its "
18424: 			"{content type} and thus cannot be derived from "
18425: 			"a non-empty type, since this would produce a "
18426: 			"'sequence' model group containing the 'all' "
18427: 			"model group; 'all' model groups are not "
18428: 			"allowed to appear inside other model groups",
18429: 			NULL, NULL);
18430: 
18431: 		} else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
18432: 		    (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
18433: 		    ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
18434: 			XML_SCHEMA_TYPE_ALL))
18435: 		{
18436: 		    /*
18437: 		    * SPEC cos-all-limited (1)
18438: 		    */
18439: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18440: 			/* TODO: error code */
18441: 			XML_SCHEMAP_COS_ALL_LIMITED,
18442: 			WXS_ITEM_NODE(type), NULL,
18443: 			"A type cannot be derived by extension from a type "
18444: 			"which has an 'all' model group in its "
18445: 			"{content type}, since this would produce a "
18446: 			"'sequence' model group containing the 'all' "
18447: 			"model group; 'all' model groups are not "
18448: 			"allowed to appear inside other model groups",
18449: 			NULL, NULL);
18450: 
18451: 		} else if (! dummySequence) {
18452: 		    xmlSchemaTreeItemPtr effectiveContent =
18453: 			(xmlSchemaTreeItemPtr) type->subtypes;
18454: 		    /*
18455: 		    * Create the particle.
18456: 		    */
18457: 		    particle = xmlSchemaAddParticle(pctxt,
18458: 			type->node, 1, 1);
18459: 		    if (particle == NULL)
18460: 			goto exit_failure;
18461: 		    /*
18462: 		    * Create the "sequence" model group.
18463: 		    */
18464: 		    particle->children = (xmlSchemaTreeItemPtr)
18465: 			xmlSchemaAddModelGroup(pctxt, pctxt->schema,
18466: 			XML_SCHEMA_TYPE_SEQUENCE, type->node);
18467: 		    if (particle->children == NULL)
18468: 			goto exit_failure;
18469: 		    WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
18470: 		    /*
18471: 		    * SPEC "the particle of the {content type} of
18472: 		    * the ... base ..."
18473: 		    * Create a duplicate of the base type's particle
18474: 		    * and assign its "term" to it.
18475: 		    */
18476: 		    particle->children->children =
18477: 			(xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
18478: 			type->node,
18479: 			((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
18480: 			((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
18481: 		    if (particle->children->children == NULL)
18482: 			goto exit_failure;
18483: 		    particle = (xmlSchemaParticlePtr)
18484: 			particle->children->children;
18485: 		    particle->children =
18486: 			((xmlSchemaParticlePtr) baseType->subtypes)->children;
18487: 		    /*
18488: 		    * SPEC "followed by the �effective content�."
18489: 		    */
18490: 		    particle->next = effectiveContent;
18491: 		    /*
18492: 		    * This all will result in:
18493: 		    * new-particle
18494: 		    *   --> new-sequence(
18495: 		    *         new-particle
18496: 		    *           --> base-model,
18497: 		    *         this-particle
18498: 		    *	        --> this-model
18499: 		    *	    )
18500: 		    */
18501: 		} else {
18502: 		    /*
18503: 		    * This is the case when there is already an empty
18504: 		    * <sequence> with minOccurs==maxOccurs==1.
18505: 		    * Just add the base types's content type.
18506: 		    * NOTE that, although we miss to add an intermediate
18507: 		    * <sequence>, this should produce no difference to
18508: 		    * neither the regex compilation of the content model,
18509: 		    * nor to the complex type contraints.
18510: 		    */
18511: 		    particle->children->children =
18512: 			(xmlSchemaTreeItemPtr) baseType->subtypes;
18513: 		}
18514: 	    }
18515: 	}
18516:     }
18517:     /*
18518:     * Now fixup attribute uses:
18519:     *   - expand attr. group references
18520:     *     - intersect attribute wildcards
18521:     *   - inherit attribute uses of the base type
18522:     *   - inherit or union attr. wildcards if extending
18523:     *   - apply attr. use prohibitions if restricting
18524:     */
18525:     res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
18526:     HFAILURE HERROR
18527:     /*
18528:     * Apply the complex type component constraints; this will not
18529:     * check attributes, since this is done in
18530:     * xmlSchemaFixupTypeAttributeUses().
18531:     */
18532:     res = xmlSchemaCheckCTComponent(pctxt, type);
18533:     HFAILURE HERROR
18534: 
18535: #ifdef DEBUG_TYPE
18536:     xmlSchemaDebugFixedType(pctxt, type);
18537: #endif
18538:     if (olderrs != pctxt->nberrors)
18539: 	return(pctxt->err);
18540:     else
18541: 	return(0);
18542: 
18543: exit_error:
18544:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18545: #ifdef DEBUG_TYPE
18546:     xmlSchemaDebugFixedType(pctxt, type);
18547: #endif
18548:     return(pctxt->err);
18549: 
18550: exit_failure:
18551:     type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
18552: #ifdef DEBUG_TYPE
18553:     xmlSchemaDebugFixedType(pctxt, type);
18554: #endif
18555:     return(-1);
18556: }
18557: 
18558: 
18559: /**
18560:  * xmlSchemaTypeFixup:
18561:  * @typeDecl:  the schema type definition
18562:  * @ctxt:  the schema parser context
18563:  *
18564:  * Fixes the content model of the type.
18565:  * URGENT TODO: We need an int result!
18566:  */
18567: static int
18568: xmlSchemaTypeFixup(xmlSchemaTypePtr type,
18569:                    xmlSchemaAbstractCtxtPtr actxt)
18570: {
18571:     if (type == NULL)
18572:         return(0);
18573:     if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
18574: 	AERROR_INT("xmlSchemaTypeFixup",
18575: 	    "this function needs a parser context");
18576: 	return(-1);
18577:     }
18578:     if (! WXS_IS_TYPE_NOT_FIXED(type))
18579: 	return(0);
18580:     if (type->type == XML_SCHEMA_TYPE_COMPLEX)
18581: 	return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
18582:     else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
18583: 	return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
18584:     return(0);
18585: }
18586: 
18587: /**
18588:  * xmlSchemaCheckFacet:
18589:  * @facet:  the facet
18590:  * @typeDecl:  the schema type definition
18591:  * @pctxt:  the schema parser context or NULL
18592:  * @name: the optional name of the type
18593:  *
18594:  * Checks and computes the values of facets.
18595:  *
18596:  * Returns 0 if valid, a positive error code if not valid and
18597:  *         -1 in case of an internal or API error.
18598:  */
18599: int
18600: xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
18601:                     xmlSchemaTypePtr typeDecl,
18602:                     xmlSchemaParserCtxtPtr pctxt,
18603: 		    const xmlChar * name ATTRIBUTE_UNUSED)
18604: {
18605:     int ret = 0, ctxtGiven;
18606: 
18607:     if ((facet == NULL) || (typeDecl == NULL))
18608:         return(-1);
18609:     /*
18610:     * TODO: will the parser context be given if used from
18611:     * the relaxNG module?
18612:     */
18613:     if (pctxt == NULL)
18614: 	ctxtGiven = 0;
18615:     else
18616: 	ctxtGiven = 1;
18617: 
18618:     switch (facet->type) {
18619:         case XML_SCHEMA_FACET_MININCLUSIVE:
18620:         case XML_SCHEMA_FACET_MINEXCLUSIVE:
18621:         case XML_SCHEMA_FACET_MAXINCLUSIVE:
18622:         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
18623: 	case XML_SCHEMA_FACET_ENUMERATION: {
18624:                 /*
18625:                  * Okay we need to validate the value
18626:                  * at that point.
18627:                  */
18628: 		xmlSchemaTypePtr base;
18629: 
18630: 		/* 4.3.5.5 Constraints on enumeration Schema Components
18631: 		* Schema Component Constraint: enumeration valid restriction
18632: 		* It is an �error� if any member of {value} is not in the
18633: 		* �value space� of {base type definition}.
18634: 		*
18635: 		* minInclusive, maxInclusive, minExclusive, maxExclusive:
18636: 		* The value �must� be in the
18637: 		* �value space� of the �base type�.
18638: 		*/
18639: 		/*
18640: 		* This function is intended to deliver a compiled value
18641: 		* on the facet. In this implementation of XML Schemata the
18642: 		* type holding a facet, won't be a built-in type.
18643: 		* Thus to ensure that other API
18644: 		* calls (relaxng) do work, if the given type is a built-in
18645: 		* type, we will assume that the given built-in type *is
18646: 		* already* the base type.
18647: 		*/
18648: 		if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
18649: 		    base = typeDecl->baseType;
18650: 		    if (base == NULL) {
18651: 			PERROR_INT("xmlSchemaCheckFacet",
18652: 			    "a type user derived type has no base type");
18653: 			return (-1);
18654: 		    }
18655: 		} else
18656: 		    base = typeDecl;
18657: 
18658: 		if (! ctxtGiven) {
18659: 		    /*
18660: 		    * A context is needed if called from RelaxNG.
18661: 		    */
18662: 		    pctxt = xmlSchemaNewParserCtxt("*");
18663: 		    if (pctxt == NULL)
18664: 			return (-1);
18665: 		}
18666: 		/*
18667: 		* NOTE: This call does not check the content nodes,
18668: 		* since they are not available:
18669: 		* facet->node is just the node holding the facet
18670: 		* definition, *not* the attribute holding the *value*
18671: 		* of the facet.
18672: 		*/
18673: 		ret = xmlSchemaVCheckCVCSimpleType(
18674: 		    ACTXT_CAST pctxt, facet->node, base,
18675: 		    facet->value, &(facet->val), 1, 1, 0);
18676:                 if (ret != 0) {
18677: 		    if (ret < 0) {
18678: 			/* No error message for RelaxNG. */
18679: 			if (ctxtGiven) {
18680: 			    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18681: 				XML_SCHEMAP_INTERNAL, facet->node, NULL,
18682: 				"Internal error: xmlSchemaCheckFacet, "
18683: 				"failed to validate the value '%s' of the "
18684: 				"facet '%s' against the base type",
18685: 				facet->value, xmlSchemaFacetTypeToString(facet->type));
18686: 			}
18687: 			goto internal_error;
18688: 		    }
18689: 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18690: 		    /* No error message for RelaxNG. */
18691: 		    if (ctxtGiven) {
18692: 			xmlChar *str = NULL;
18693: 
18694: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
18695: 			    ret, facet->node, WXS_BASIC_CAST facet,
18696: 			    "The value '%s' of the facet does not validate "
18697: 			    "against the base type '%s'",
18698: 			    facet->value,
18699: 			    xmlSchemaFormatQName(&str,
18700: 				base->targetNamespace, base->name));
18701: 			FREE_AND_NULL(str);
18702: 		    }
18703: 		    goto exit;
18704:                 } else if (facet->val == NULL) {
18705: 		    if (ctxtGiven) {
18706: 			PERROR_INT("xmlSchemaCheckFacet",
18707: 			    "value was not computed");
18708: 		    }
18709: 		    TODO
18710: 		}
18711:                 break;
18712:             }
18713:         case XML_SCHEMA_FACET_PATTERN:
18714:             facet->regexp = xmlRegexpCompile(facet->value);
18715:             if (facet->regexp == NULL) {
18716: 		ret = XML_SCHEMAP_REGEXP_INVALID;
18717: 		/* No error message for RelaxNG. */
18718: 		if (ctxtGiven) {
18719: 		    xmlSchemaCustomErr(ACTXT_CAST pctxt,
18720: 			ret, facet->node, WXS_BASIC_CAST typeDecl,
18721: 			"The value '%s' of the facet 'pattern' is not a "
18722: 			"valid regular expression",
18723: 			facet->value, NULL);
18724: 		}
18725:             }
18726:             break;
18727:         case XML_SCHEMA_FACET_TOTALDIGITS:
18728:         case XML_SCHEMA_FACET_FRACTIONDIGITS:
18729:         case XML_SCHEMA_FACET_LENGTH:
18730:         case XML_SCHEMA_FACET_MAXLENGTH:
18731:         case XML_SCHEMA_FACET_MINLENGTH:
18732: 
18733: 	    if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
18734: 		ret = xmlSchemaValidatePredefinedType(
18735: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
18736: 		    facet->value, &(facet->val));
18737: 	    } else {
18738: 		ret = xmlSchemaValidatePredefinedType(
18739: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
18740: 		    facet->value, &(facet->val));
18741: 	    }
18742: 	    if (ret != 0) {
18743: 		if (ret < 0) {
18744: 		    /* No error message for RelaxNG. */
18745: 		    if (ctxtGiven) {
18746: 			PERROR_INT("xmlSchemaCheckFacet",
18747: 			    "validating facet value");
18748: 		    }
18749: 		    goto internal_error;
18750: 		}
18751: 		ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18752: 		/* No error message for RelaxNG. */
18753: 		if (ctxtGiven) {
18754: 		    /* error code */
18755: 		    xmlSchemaCustomErr4(ACTXT_CAST pctxt,
18756: 			ret, facet->node, WXS_BASIC_CAST typeDecl,
18757: 			"The value '%s' of the facet '%s' is not a valid '%s'",
18758: 			facet->value,
18759: 			xmlSchemaFacetTypeToString(facet->type),
18760: 			(facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
18761: 			    BAD_CAST "nonNegativeInteger" :
18762: 			    BAD_CAST "positiveInteger",
18763: 			NULL);
18764: 		}
18765: 	    }
18766: 	    break;
18767: 
18768:         case XML_SCHEMA_FACET_WHITESPACE:{
18769:                 if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
18770:                     facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
18771:                 } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
18772:                     facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
18773:                 } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
18774:                     facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
18775:                 } else {
18776: 		    ret = XML_SCHEMAP_INVALID_FACET_VALUE;
18777:                     /* No error message for RelaxNG. */
18778: 		    if (ctxtGiven) {
18779: 			/* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
18780: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
18781: 			    ret, facet->node, WXS_BASIC_CAST typeDecl,
18782: 			    "The value '%s' of the facet 'whitespace' is not "
18783: 			    "valid", facet->value, NULL);
18784:                     }
18785:                 }
18786:             }
18787:         default:
18788:             break;
18789:     }
18790: exit:
18791:     if ((! ctxtGiven) && (pctxt != NULL))
18792: 	xmlSchemaFreeParserCtxt(pctxt);
18793:     return (ret);
18794: internal_error:
18795:     if ((! ctxtGiven) && (pctxt != NULL))
18796: 	xmlSchemaFreeParserCtxt(pctxt);
18797:     return (-1);
18798: }
18799: 
18800: /**
18801:  * xmlSchemaCheckFacetValues:
18802:  * @typeDecl:  the schema type definition
18803:  * @ctxt:  the schema parser context
18804:  *
18805:  * Checks the default values types, especially for facets
18806:  */
18807: static int
18808: xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
18809: 			  xmlSchemaParserCtxtPtr pctxt)
18810: {
18811:     int res, olderrs = pctxt->nberrors;
18812:     const xmlChar *name = typeDecl->name;
18813:     /*
18814:     * NOTE: It is intended to use the facets list, instead
18815:     * of facetSet.
18816:     */
18817:     if (typeDecl->facets != NULL) {
18818: 	xmlSchemaFacetPtr facet = typeDecl->facets;
18819: 
18820: 	/*
18821: 	* Temporarily assign the "schema" to the validation context
18822: 	* of the parser context. This is needed for NOTATION validation.
18823: 	*/
18824: 	if (pctxt->vctxt == NULL) {
18825: 	    if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
18826: 		return(-1);
18827: 	}
18828: 	pctxt->vctxt->schema = pctxt->schema;
18829: 	while (facet != NULL) {
18830: 	    res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
18831: 	    HFAILURE
18832: 	    facet = facet->next;
18833: 	}
18834: 	pctxt->vctxt->schema = NULL;
18835:     }
18836:     if (olderrs != pctxt->nberrors)
18837: 	return(pctxt->err);
18838:     return(0);
18839: exit_failure:
18840:     return(-1);
18841: }
18842: 
18843: /**
18844:  * xmlSchemaGetCircModelGrDefRef:
18845:  * @ctxtMGroup: the searched model group
18846:  * @selfMGroup: the second searched model group
18847:  * @particle: the first particle
18848:  *
18849:  * This one is intended to be used by
18850:  * xmlSchemaCheckGroupDefCircular only.
18851:  *
18852:  * Returns the particle with the circular model group definition reference,
18853:  * otherwise NULL.
18854:  */
18855: static xmlSchemaTreeItemPtr
18856: xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
18857: 			      xmlSchemaTreeItemPtr particle)
18858: {
18859:     xmlSchemaTreeItemPtr circ = NULL;
18860:     xmlSchemaTreeItemPtr term;
18861:     xmlSchemaModelGroupDefPtr gdef;
18862: 
18863:     for (; particle != NULL; particle = particle->next) {
18864: 	term = particle->children;
18865: 	if (term == NULL)
18866: 	    continue;
18867: 	switch (term->type) {
18868: 	    case XML_SCHEMA_TYPE_GROUP:
18869: 		gdef = (xmlSchemaModelGroupDefPtr) term;
18870: 		if (gdef == groupDef)
18871: 		    return (particle);
18872: 		/*
18873: 		* Mark this model group definition to avoid infinite
18874: 		* recursion on circular references not yet examined.
18875: 		*/
18876: 		if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
18877: 		    continue;
18878: 		if (gdef->children != NULL) {
18879: 		    gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18880: 		    circ = xmlSchemaGetCircModelGrDefRef(groupDef,
18881: 			gdef->children->children);
18882: 		    gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
18883: 		    if (circ != NULL)
18884: 			return (circ);
18885: 		}
18886: 		break;
18887: 	    case XML_SCHEMA_TYPE_SEQUENCE:
18888: 	    case XML_SCHEMA_TYPE_CHOICE:
18889: 	    case XML_SCHEMA_TYPE_ALL:
18890: 		circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
18891: 		if (circ != NULL)
18892: 		    return (circ);
18893: 		break;
18894: 	    default:
18895: 		break;
18896: 	}
18897:     }
18898:     return (NULL);
18899: }
18900: 
18901: /**
18902:  * xmlSchemaCheckGroupDefCircular:
18903:  * @item:  the model group definition
18904:  * @ctxt:  the parser context
18905:  * @name:  the name
18906:  *
18907:  * Checks for circular references to model group definitions.
18908:  */
18909: static void
18910: xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
18911: 			       xmlSchemaParserCtxtPtr ctxt)
18912: {
18913:     /*
18914:     * Schema Component Constraint: Model Group Correct
18915:     * 2 Circular groups are disallowed. That is, within the {particles}
18916:     * of a group there must not be at any depth a particle whose {term}
18917:     * is the group itself.
18918:     */
18919:     if ((item == NULL) ||
18920: 	(item->type != XML_SCHEMA_TYPE_GROUP) ||
18921: 	(item->children == NULL))
18922: 	return;
18923:     {
18924: 	xmlSchemaTreeItemPtr circ;
18925: 
18926: 	circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
18927: 	if (circ != NULL) {
18928: 	    xmlChar *str = NULL;
18929: 	    /*
18930: 	    * TODO: The error report is not adequate: this constraint
18931: 	    * is defined for model groups but not definitions, but since
18932: 	    * there cannot be any circular model groups without a model group
18933: 	    * definition (if not using a construction API), we check those
18934: 	    * defintions only.
18935: 	    */
18936: 	    xmlSchemaPCustomErr(ctxt,
18937: 		XML_SCHEMAP_MG_PROPS_CORRECT_2,
18938: 		NULL, WXS_ITEM_NODE(circ),
18939: 		"Circular reference to the model group definition '%s' "
18940: 		"defined", xmlSchemaFormatQName(&str,
18941: 		    item->targetNamespace, item->name));
18942: 	    FREE_AND_NULL(str)
18943: 	    /*
18944: 	    * NOTE: We will cut the reference to avoid further
18945: 	    * confusion of the processor. This is a fatal error.
18946: 	    */
18947: 	    circ->children = NULL;
18948: 	}
18949:     }
18950: }
18951: 
18952: /**
18953:  * xmlSchemaModelGroupToModelGroupDefFixup:
18954:  * @ctxt:  the parser context
18955:  * @mg:  the model group
18956:  *
18957:  * Assigns the model group of model group definitions to the "term"
18958:  * of the referencing particle.
18959:  * In xmlSchemaResolveModelGroupParticleReferences the model group
18960:  * definitions were assigned to the "term", since needed for the
18961:  * circularity check.
18962:  *
18963:  * Schema Component Constraint:
18964:  *     All Group Limited (cos-all-limited) (1.2)
18965:  */
18966: static void
18967: xmlSchemaModelGroupToModelGroupDefFixup(
18968:     xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
18969:     xmlSchemaModelGroupPtr mg)
18970: {
18971:     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
18972: 
18973:     while (particle != NULL) {
18974: 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
18975: 	    ((WXS_PARTICLE_TERM(particle))->type !=
18976: 		XML_SCHEMA_TYPE_GROUP))
18977: 	{
18978: 	    particle = WXS_PTC_CAST particle->next;
18979: 	    continue;
18980: 	}
18981: 	if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
18982: 	    /*
18983: 	    * TODO: Remove the particle.
18984: 	    */
18985: 	    WXS_PARTICLE_TERM(particle) = NULL;
18986: 	    particle = WXS_PTC_CAST particle->next;
18987: 	    continue;
18988: 	}
18989: 	/*
18990: 	* Assign the model group to the {term} of the particle.
18991: 	*/
18992: 	WXS_PARTICLE_TERM(particle) =
18993: 	    WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
18994: 
18995: 	particle = WXS_PTC_CAST particle->next;
18996:     }
18997: }
18998: 
18999: /**
19000:  * xmlSchemaCheckAttrGroupCircularRecur:
19001:  * @ctxtGr: the searched attribute group
19002:  * @attr: the current attribute list to be processed
19003:  *
19004:  * This one is intended to be used by
19005:  * xmlSchemaCheckAttrGroupCircular only.
19006:  *
19007:  * Returns the circular attribute grou reference, otherwise NULL.
19008:  */
19009: static xmlSchemaQNameRefPtr
19010: xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
19011: 				     xmlSchemaItemListPtr list)
19012: {
19013:     xmlSchemaAttributeGroupPtr gr;
19014:     xmlSchemaQNameRefPtr ref, circ;
19015:     int i;
19016:     /*
19017:     * We will search for an attribute group reference which
19018:     * references the context attribute group.
19019:     */
19020:     for (i = 0; i < list->nbItems; i++) {
19021: 	ref = list->items[i];
19022: 	if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19023: 	    (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
19024: 	    (ref->item != NULL))
19025: 	{
19026: 	    gr = WXS_ATTR_GROUP_CAST ref->item;
19027: 	    if (gr == ctxtGr)
19028: 		return(ref);
19029: 	    if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
19030: 		continue;
19031: 	    /*
19032: 	    * Mark as visited to avoid infinite recursion on
19033: 	    * circular references not yet examined.
19034: 	    */
19035: 	    if ((gr->attrUses) &&
19036: 		(gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
19037: 	    {
19038: 		gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
19039: 		circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
19040: 		    (xmlSchemaItemListPtr) gr->attrUses);
19041: 		gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
19042: 		if (circ != NULL)
19043: 		    return (circ);
19044: 	    }
19045: 
19046: 	}
19047:     }
19048:     return (NULL);
19049: }
19050: 
19051: /**
19052:  * xmlSchemaCheckAttrGroupCircular:
19053:  * attrGr:  the attribute group definition
19054:  * @ctxt:  the parser context
19055:  * @name:  the name
19056:  *
19057:  * Checks for circular references of attribute groups.
19058:  */
19059: static int
19060: xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
19061: 				xmlSchemaParserCtxtPtr ctxt)
19062: {
19063:     /*
19064:     * Schema Representation Constraint:
19065:     * Attribute Group Definition Representation OK
19066:     * 3 Circular group reference is disallowed outside <redefine>.
19067:     * That is, unless this element information item's parent is
19068:     * <redefine>, then among the [children], if any, there must
19069:     * not be an <attributeGroup> with ref [attribute] which resolves
19070:     * to the component corresponding to this <attributeGroup>. Indirect
19071:     * circularity is also ruled out. That is, when QName resolution
19072:     * (Schema Document) (�3.15.3) is applied to a �QName� arising from
19073:     * any <attributeGroup>s with a ref [attribute] among the [children],
19074:     * it must not be the case that a �QName� is encountered at any depth
19075:     * which resolves to the component corresponding to this <attributeGroup>.
19076:     */
19077:     if (attrGr->attrUses == NULL)
19078: 	return(0);
19079:     else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
19080: 	return(0);
19081:     else {
19082: 	xmlSchemaQNameRefPtr circ;
19083: 
19084: 	circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
19085: 	    (xmlSchemaItemListPtr) attrGr->attrUses);
19086: 	if (circ != NULL) {
19087: 	    xmlChar *str = NULL;
19088: 	    /*
19089: 	    * TODO: Report the referenced attr group as QName.
19090: 	    */
19091: 	    xmlSchemaPCustomErr(ctxt,
19092: 		XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
19093: 		NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
19094: 		"Circular reference to the attribute group '%s' "
19095: 		"defined", xmlSchemaGetComponentQName(&str, attrGr));
19096: 	    FREE_AND_NULL(str);
19097: 	    /*
19098: 	    * NOTE: We will cut the reference to avoid further
19099: 	    * confusion of the processor.
19100: 	    * BADSPEC TODO: The spec should define how to process in this case.
19101: 	    */
19102: 	    circ->item = NULL;
19103: 	    return(ctxt->err);
19104: 	}
19105:     }
19106:     return(0);
19107: }
19108: 
19109: static int
19110: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19111: 				  xmlSchemaAttributeGroupPtr attrGr);
19112: 
19113: /**
19114:  * xmlSchemaExpandAttributeGroupRefs:
19115:  * @pctxt: the parser context
19116:  * @node: the node of the component holding the attribute uses
19117:  * @completeWild: the intersected wildcard to be returned
19118:  * @list: the attribute uses
19119:  *
19120:  * Substitutes contained attribute group references
19121:  * for their attribute uses. Wilcards are intersected.
19122:  * Attribute use prohibitions are removed from the list
19123:  * and returned via the @prohibs list.
19124:  * Pointlessness of attr. prohibs, if a matching attr. decl
19125:  * is existent a well, are checked.
19126:  */
19127: static int
19128: xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
19129: 				  xmlSchemaBasicItemPtr item,
19130: 				  xmlSchemaWildcardPtr *completeWild,
19131: 				  xmlSchemaItemListPtr list,
19132: 				  xmlSchemaItemListPtr prohibs)
19133: {
19134:     xmlSchemaAttributeGroupPtr gr;
19135:     xmlSchemaAttributeUsePtr use;
19136:     xmlSchemaItemListPtr sublist;
19137:     int i, j;
19138:     int created = (*completeWild == NULL) ? 0 : 1;
19139: 
19140:     if (prohibs)
19141: 	prohibs->nbItems = 0;
19142: 
19143:     for (i = 0; i < list->nbItems; i++) {
19144: 	use = list->items[i];
19145: 
19146: 	if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
19147: 	    if (prohibs == NULL) {
19148: 		PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
19149: 		    "unexpected attr prohibition found");
19150: 		return(-1);
19151: 	    }
19152: 	    /*
19153: 	    * Remove from attribute uses.
19154: 	    */
19155: 	    if (xmlSchemaItemListRemove(list, i) == -1)
19156: 		return(-1);
19157: 	    i--;
19158: 	    /*
19159: 	    * Note that duplicate prohibitions were already
19160: 	    * handled at parsing time.
19161: 	    */
19162: 	    /*
19163: 	    * Add to list of prohibitions.
19164: 	    */
19165: 	    xmlSchemaItemListAddSize(prohibs, 2, use);
19166: 	    continue;
19167: 	}
19168: 	if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
19169: 	    ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
19170: 	{
19171: 	    if ((WXS_QNAME_CAST use)->item == NULL)
19172: 		return(-1);
19173: 	    gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
19174: 	    /*
19175: 	    * Expand the referenced attr. group.
19176: 	    * TODO: remove this, this is done in a previous step, so
19177: 	    * already done here.
19178: 	    */
19179: 	    if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
19180: 		if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
19181: 		    return(-1);
19182: 	    }
19183: 	    /*
19184: 	    * Build the 'complete' wildcard; i.e. intersect multiple
19185: 	    * wildcards.
19186: 	    */
19187: 	    if (gr->attributeWildcard != NULL) {
19188: 		if (*completeWild == NULL) {
19189: 		    *completeWild = gr->attributeWildcard;
19190: 		} else {
19191: 		    if (! created) {
19192: 			xmlSchemaWildcardPtr tmpWild;
19193: 
19194: 			 /*
19195: 			* Copy the first encountered wildcard as context,
19196: 			* except for the annotation.
19197: 			*
19198: 			* Although the complete wildcard might not correspond
19199: 			* to any node in the schema, we will anchor it on
19200: 			* the node of the owner component.
19201: 			*/
19202: 			tmpWild =  xmlSchemaAddWildcard(pctxt, pctxt->schema,
19203: 			    XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
19204: 			    WXS_ITEM_NODE(item));
19205: 			if (tmpWild == NULL)
19206: 			    return(-1);
19207: 			if (xmlSchemaCloneWildcardNsConstraints(pctxt,
19208: 			    tmpWild, *completeWild) == -1)
19209: 			    return (-1);
19210: 			tmpWild->processContents = (*completeWild)->processContents;
19211: 			*completeWild = tmpWild;
19212: 			created = 1;
19213: 		    }
19214: 
19215: 		    if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
19216: 			gr->attributeWildcard) == -1)
19217: 			return(-1);
19218: 		}
19219: 	    }
19220: 	    /*
19221: 	    * Just remove the reference if the referenced group does not
19222: 	    * contain any attribute uses.
19223: 	    */
19224: 	    sublist = ((xmlSchemaItemListPtr) gr->attrUses);
19225: 	    if ((sublist == NULL) || sublist->nbItems == 0) {
19226: 		if (xmlSchemaItemListRemove(list, i) == -1)
19227: 		    return(-1);
19228: 		i--;
19229: 		continue;
19230: 	    }
19231: 	    /*
19232: 	    * Add the attribute uses.
19233: 	    */
19234: 	    list->items[i] = sublist->items[0];
19235: 	    if (sublist->nbItems != 1) {
19236: 		for (j = 1; j < sublist->nbItems; j++) {
19237: 		    i++;
19238: 		    if (xmlSchemaItemListInsert(list,
19239: 			    sublist->items[j], i) == -1)
19240: 			return(-1);
19241: 		}
19242: 	    }
19243: 	}
19244: 
19245:     }
19246:     /*
19247:     * Handle pointless prohibitions of declared attributes.
19248:     */
19249:     if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
19250: 	xmlSchemaAttributeUseProhibPtr prohib;
19251: 
19252: 	for (i = prohibs->nbItems -1; i >= 0; i--) {
19253: 	    prohib = prohibs->items[i];
19254: 	    for (j = 0; j < list->nbItems; j++) {
19255: 		use = list->items[j];
19256: 
19257: 		if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
19258: 		    (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
19259: 		{
19260: 		    xmlChar *str = NULL;
19261: 
19262: 		    xmlSchemaCustomWarning(ACTXT_CAST pctxt,
19263: 			XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
19264: 			prohib->node, NULL,
19265: 			"Skipping pointless attribute use prohibition "
19266: 			"'%s', since a corresponding attribute use "
19267: 			"exists already in the type definition",
19268: 			xmlSchemaFormatQName(&str,
19269: 			    prohib->targetNamespace, prohib->name),
19270: 			NULL, NULL);
19271: 		    FREE_AND_NULL(str);
19272: 		    /*
19273: 		    * Remove the prohibition.
19274: 		    */
19275: 		    if (xmlSchemaItemListRemove(prohibs, i) == -1)
19276: 			return(-1);
19277: 		    break;
19278: 		}
19279: 	    }
19280: 	}
19281:     }
19282:     return(0);
19283: }
19284: 
19285: /**
19286:  * xmlSchemaAttributeGroupExpandRefs:
19287:  * @pctxt:  the parser context
19288:  * @attrGr:  the attribute group definition
19289:  *
19290:  * Computation of:
19291:  * {attribute uses} property
19292:  * {attribute wildcard} property
19293:  *
19294:  * Substitutes contained attribute group references
19295:  * for their attribute uses. Wilcards are intersected.
19296:  */
19297: static int
19298: xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
19299: 				  xmlSchemaAttributeGroupPtr attrGr)
19300: {
19301:     if ((attrGr->attrUses == NULL) ||
19302: 	(attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
19303: 	return(0);
19304: 
19305:     attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
19306:     if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
19307: 	&(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
19308: 	return(-1);
19309:     return(0);
19310: }
19311: 
19312: /**
19313:  * xmlSchemaAttributeGroupExpandRefs:
19314:  * @pctxt:  the parser context
19315:  * @attrGr:  the attribute group definition
19316:  *
19317:  * Substitutes contained attribute group references
19318:  * for their attribute uses. Wilcards are intersected.
19319:  *
19320:  * Schema Component Constraint:
19321:  *    Attribute Group Definition Properties Correct (ag-props-correct)
19322:  */
19323: static int
19324: xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19325: 				  xmlSchemaAttributeGroupPtr attrGr)
19326: {
19327:     /*
19328:     * SPEC ag-props-correct
19329:     * (1) "The values of the properties of an attribute group definition
19330:     * must be as described in the property tableau in The Attribute
19331:     * Group Definition Schema Component (�3.6.1), modulo the impact of
19332:     * Missing Sub-components (�5.3);"
19333:     */
19334: 
19335:     if ((attrGr->attrUses != NULL) &&
19336: 	(WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
19337:     {
19338: 	xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
19339: 	xmlSchemaAttributeUsePtr use, tmp;
19340: 	int i, j, hasId = 0;
19341: 
19342: 	for (i = uses->nbItems -1; i >= 0; i--) {
19343: 	    use = uses->items[i];
19344: 	    /*
19345: 	    * SPEC ag-props-correct
19346: 	    * (2) "Two distinct members of the {attribute uses} must not have
19347: 	    * {attribute declaration}s both of whose {name}s match and whose
19348: 	    * {target namespace}s are identical."
19349: 	    */
19350: 	    if (i > 0) {
19351: 		for (j = i -1; j >= 0; j--) {
19352: 		    tmp = uses->items[j];
19353: 		    if ((WXS_ATTRUSE_DECL_NAME(use) ==
19354: 			WXS_ATTRUSE_DECL_NAME(tmp)) &&
19355: 			(WXS_ATTRUSE_DECL_TNS(use) ==
19356: 			WXS_ATTRUSE_DECL_TNS(tmp)))
19357: 		    {
19358: 			xmlChar *str = NULL;
19359: 
19360: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19361: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
19362: 			    attrGr->node, WXS_BASIC_CAST attrGr,
19363: 			    "Duplicate %s",
19364: 			    xmlSchemaGetComponentDesignation(&str, use),
19365: 			    NULL);
19366: 			FREE_AND_NULL(str);
19367: 			/*
19368: 			* Remove the duplicate.
19369: 			*/
19370: 			if (xmlSchemaItemListRemove(uses, i) == -1)
19371: 			    return(-1);
19372: 			goto next_use;
19373: 		    }
19374: 		}
19375: 	    }
19376: 	    /*
19377: 	    * SPEC ag-props-correct
19378: 	    * (3) "Two distinct members of the {attribute uses} must not have
19379: 	    * {attribute declaration}s both of whose {type definition}s are or
19380: 	    * are derived from ID."
19381: 	    * TODO: Does 'derived' include member-types of unions?
19382: 	    */
19383: 	    if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
19384: 		if (xmlSchemaIsDerivedFromBuiltInType(
19385: 		    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
19386: 		{
19387: 		    if (hasId) {
19388: 			xmlChar *str = NULL;
19389: 
19390: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19391: 			    XML_SCHEMAP_AG_PROPS_CORRECT,
19392: 			    attrGr->node, WXS_BASIC_CAST attrGr,
19393: 			    "There must not exist more than one attribute "
19394: 			    "declaration of type 'xs:ID' "
19395: 			    "(or derived from 'xs:ID'). The %s violates this "
19396: 			    "constraint",
19397: 			    xmlSchemaGetComponentDesignation(&str, use),
19398: 			    NULL);
19399: 			FREE_AND_NULL(str);
19400: 			if (xmlSchemaItemListRemove(uses, i) == -1)
19401: 			    return(-1);
19402: 		    }
19403: 		    hasId = 1;
19404: 		}
19405: 	    }
19406: next_use: {}
19407: 	}
19408:     }
19409:     return(0);
19410: }
19411: 
19412: /**
19413:  * xmlSchemaResolveAttrGroupReferences:
19414:  * @attrgrpDecl:  the schema attribute definition
19415:  * @ctxt:  the schema parser context
19416:  * @name:  the attribute name
19417:  *
19418:  * Resolves references to attribute group definitions.
19419:  */
19420: static int
19421: xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
19422: 				    xmlSchemaParserCtxtPtr ctxt)
19423: {
19424:     xmlSchemaAttributeGroupPtr group;
19425: 
19426:     if (ref->item != NULL)
19427:         return(0);
19428:     group = xmlSchemaGetAttributeGroup(ctxt->schema,
19429: 	ref->name,
19430: 	ref->targetNamespace);
19431:     if (group == NULL) {
19432: 	xmlSchemaPResCompAttrErr(ctxt,
19433: 	    XML_SCHEMAP_SRC_RESOLVE,
19434: 	    NULL, ref->node,
19435: 	    "ref", ref->name, ref->targetNamespace,
19436: 	    ref->itemType, NULL);
19437: 	return(ctxt->err);
19438:     }
19439:     ref->item = WXS_BASIC_CAST group;
19440:     return(0);
19441: }
19442: 
19443: /**
19444:  * xmlSchemaCheckAttrPropsCorrect:
19445:  * @item:  an schema attribute declaration/use
19446:  * @ctxt:  a schema parser context
19447:  * @name:  the name of the attribute
19448:  *
19449:  *
19450:  * Schema Component Constraint:
19451:  *    Attribute Declaration Properties Correct (a-props-correct)
19452:  *
19453:  * Validates the value constraints of an attribute declaration/use.
19454:  * NOTE that this needs the simle type definitions to be already
19455:  *   builded and checked.
19456:  */
19457: static int
19458: xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19459: 			       xmlSchemaAttributePtr attr)
19460: {
19461: 
19462:     /*
19463:     * SPEC a-props-correct (1)
19464:     * "The values of the properties of an attribute declaration must
19465:     * be as described in the property tableau in The Attribute
19466:     * Declaration Schema Component (�3.2.1), modulo the impact of
19467:     * Missing Sub-components (�5.3)."
19468:     */
19469: 
19470:     if (WXS_ATTR_TYPEDEF(attr) == NULL)
19471: 	return(0);
19472: 
19473:     if (attr->defValue != NULL) {
19474: 	int ret;
19475: 
19476: 	/*
19477: 	* SPEC a-props-correct (3)
19478: 	* "If the {type definition} is or is derived from ID then there
19479: 	* must not be a {value constraint}."
19480: 	*/
19481: 	if (xmlSchemaIsDerivedFromBuiltInType(
19482: 	    WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
19483: 	{
19484: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19485: 		XML_SCHEMAP_A_PROPS_CORRECT_3,
19486: 		NULL, WXS_BASIC_CAST attr,
19487: 		"Value constraints are not allowed if the type definition "
19488: 		"is or is derived from xs:ID",
19489: 		NULL, NULL);
19490: 	    return(pctxt->err);
19491: 	}
19492: 	/*
19493: 	* SPEC a-props-correct (2)
19494: 	* "if there is a {value constraint}, the canonical lexical
19495: 	* representation of its value must be �valid� with respect
19496: 	* to the {type definition} as defined in String Valid (�3.14.4)."
19497: 	* TODO: Don't care about the *cononical* stuff here, this requirement
19498: 	* will be removed in WXS 1.1 anyway.
19499: 	*/
19500: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
19501: 	    attr->node, WXS_ATTR_TYPEDEF(attr),
19502: 	    attr->defValue, &(attr->defVal),
19503: 	    1, 1, 0);
19504: 	if (ret != 0) {
19505: 	    if (ret < 0) {
19506: 		PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
19507: 		    "calling xmlSchemaVCheckCVCSimpleType()");
19508: 		return(-1);
19509: 	    }
19510: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
19511: 		XML_SCHEMAP_A_PROPS_CORRECT_2,
19512: 		NULL, WXS_BASIC_CAST attr,
19513: 		"The value of the value constraint is not valid",
19514: 		NULL, NULL);
19515: 	    return(pctxt->err);
19516: 	}
19517:     }
19518: 
19519:     return(0);
19520: }
19521: 
19522: static xmlSchemaElementPtr
19523: xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
19524: 				 xmlSchemaElementPtr ancestor)
19525: {
19526:     xmlSchemaElementPtr ret;
19527: 
19528:     if (WXS_SUBST_HEAD(ancestor) == NULL)
19529: 	return (NULL);
19530:     if (WXS_SUBST_HEAD(ancestor) == elemDecl)
19531: 	return (ancestor);
19532: 
19533:     if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
19534: 	return (NULL);
19535:     WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
19536:     ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
19537: 	WXS_SUBST_HEAD(ancestor));
19538:     WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
19539: 
19540:     return (ret);
19541: }
19542: 
19543: /**
19544:  * xmlSchemaCheckElemPropsCorrect:
19545:  * @ctxt:  a schema parser context
19546:  * @decl: the element declaration
19547:  * @name:  the name of the attribute
19548:  *
19549:  * Schema Component Constraint:
19550:  * Element Declaration Properties Correct (e-props-correct)
19551:  *
19552:  * STATUS:
19553:  *   missing: (6)
19554:  */
19555: static int
19556: xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
19557: 			       xmlSchemaElementPtr elemDecl)
19558: {
19559:     int ret = 0;
19560:     xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
19561:     /*
19562:     * SPEC (1) "The values of the properties of an element declaration
19563:     * must be as described in the property tableau in The Element
19564:     * Declaration Schema Component (�3.3.1), modulo the impact of Missing
19565:     * Sub-components (�5.3)."
19566:     */
19567:     if (WXS_SUBST_HEAD(elemDecl) != NULL) {
19568: 	xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
19569: 
19570: 	xmlSchemaCheckElementDeclComponent(head, pctxt);
19571: 	/*
19572: 	* SPEC (3) "If there is a non-�absent� {substitution group
19573: 	* affiliation}, then {scope} must be global."
19574: 	*/
19575: 	if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
19576: 	    xmlSchemaPCustomErr(pctxt,
19577: 		XML_SCHEMAP_E_PROPS_CORRECT_3,
19578: 		WXS_BASIC_CAST elemDecl, NULL,
19579: 		"Only global element declarations can have a "
19580: 		"substitution group affiliation", NULL);
19581: 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
19582: 	}
19583: 	/*
19584: 	* TODO: SPEC (6) "Circular substitution groups are disallowed.
19585: 	* That is, it must not be possible to return to an element declaration
19586: 	* by repeatedly following the {substitution group affiliation}
19587: 	* property."
19588: 	*/
19589: 	if (head == elemDecl)
19590: 	    circ = head;
19591: 	else if (WXS_SUBST_HEAD(head) != NULL)
19592: 	    circ = xmlSchemaCheckSubstGroupCircular(head, head);
19593: 	else
19594: 	    circ = NULL;
19595: 	if (circ != NULL) {
19596: 	    xmlChar *strA = NULL, *strB = NULL;
19597: 
19598: 	    xmlSchemaPCustomErrExt(pctxt,
19599: 		XML_SCHEMAP_E_PROPS_CORRECT_6,
19600: 		WXS_BASIC_CAST circ, NULL,
19601: 		"The element declaration '%s' defines a circular "
19602: 		"substitution group to element declaration '%s'",
19603: 		xmlSchemaGetComponentQName(&strA, circ),
19604: 		xmlSchemaGetComponentQName(&strB, head),
19605: 		NULL);
19606: 	    FREE_AND_NULL(strA)
19607: 	    FREE_AND_NULL(strB)
19608: 	    ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
19609: 	}
19610: 	/*
19611: 	* SPEC (4) "If there is a {substitution group affiliation},
19612: 	* the {type definition}
19613: 	* of the element declaration must be validly derived from the {type
19614: 	* definition} of the {substitution group affiliation}, given the value
19615: 	* of the {substitution group exclusions} of the {substitution group
19616: 	* affiliation}, as defined in Type Derivation OK (Complex) (�3.4.6)
19617: 	* (if the {type definition} is complex) or as defined in
19618: 	* Type Derivation OK (Simple) (�3.14.6) (if the {type definition} is
19619: 	* simple)."
19620: 	*
19621: 	* NOTE: {substitution group exclusions} means the values of the
19622: 	* attribute "final".
19623: 	*/
19624: 
19625: 	if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
19626: 	    int set = 0;
19627: 
19628: 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
19629: 		set |= SUBSET_EXTENSION;
19630: 	    if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
19631: 		set |= SUBSET_RESTRICTION;
19632: 
19633: 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
19634: 		WXS_ELEM_TYPEDEF(head), set) != 0) {
19635: 		xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
19636: 
19637: 		ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
19638: 		xmlSchemaPCustomErrExt(pctxt,
19639: 		    XML_SCHEMAP_E_PROPS_CORRECT_4,
19640: 		    WXS_BASIC_CAST elemDecl, NULL,
19641: 		    "The type definition '%s' was "
19642: 		    "either rejected by the substitution group "
19643: 		    "affiliation '%s', or not validly derived from its type "
19644: 		    "definition '%s'",
19645: 		    xmlSchemaGetComponentQName(&strA, typeDef),
19646: 		    xmlSchemaGetComponentQName(&strB, head),
19647: 		    xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
19648: 		FREE_AND_NULL(strA)
19649: 		FREE_AND_NULL(strB)
19650: 		FREE_AND_NULL(strC)
19651: 	    }
19652: 	}
19653:     }
19654:     /*
19655:     * SPEC (5) "If the {type definition} or {type definition}'s
19656:     * {content type}
19657:     * is or is derived from ID then there must not be a {value constraint}.
19658:     * Note: The use of ID as a type definition for elements goes beyond
19659:     * XML 1.0, and should be avoided if backwards compatibility is desired"
19660:     */
19661:     if ((elemDecl->value != NULL) &&
19662: 	((WXS_IS_SIMPLE(typeDef) &&
19663: 	  xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
19664: 	 (WXS_IS_COMPLEX(typeDef) &&
19665: 	  WXS_HAS_SIMPLE_CONTENT(typeDef) &&
19666: 	  xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
19667: 	    XML_SCHEMAS_ID)))) {
19668: 
19669: 	ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
19670: 	xmlSchemaPCustomErr(pctxt,
19671: 	    XML_SCHEMAP_E_PROPS_CORRECT_5,
19672: 	    WXS_BASIC_CAST elemDecl, NULL,
19673: 	    "The type definition (or type definition's content type) is or "
19674: 	    "is derived from ID; value constraints are not allowed in "
19675: 	    "conjunction with such a type definition", NULL);
19676:     } else if (elemDecl->value != NULL) {
19677: 	int vcret;
19678: 	xmlNodePtr node = NULL;
19679: 
19680: 	/*
19681: 	* SPEC (2) "If there is a {value constraint}, the canonical lexical
19682: 	* representation of its value must be �valid� with respect to the
19683: 	* {type definition} as defined in Element Default Valid (Immediate)
19684: 	* (�3.3.6)."
19685: 	*/
19686: 	if (typeDef == NULL) {
19687: 	    xmlSchemaPErr(pctxt, elemDecl->node,
19688: 		XML_SCHEMAP_INTERNAL,
19689: 		"Internal error: xmlSchemaCheckElemPropsCorrect, "
19690: 		"type is missing... skipping validation of "
19691: 		"the value constraint", NULL, NULL);
19692: 	    return (-1);
19693: 	}
19694: 	if (elemDecl->node != NULL) {
19695: 	    if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
19696: 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19697: 		    BAD_CAST "fixed");
19698: 	    else
19699: 		node = (xmlNodePtr) xmlHasProp(elemDecl->node,
19700: 		    BAD_CAST "default");
19701: 	}
19702: 	vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
19703: 	    typeDef, elemDecl->value, &(elemDecl->defVal));
19704: 	if (vcret != 0) {
19705: 	    if (vcret < 0) {
19706: 		PERROR_INT("xmlSchemaElemCheckValConstr",
19707: 		    "failed to validate the value constraint of an "
19708: 		    "element declaration");
19709: 		return (-1);
19710: 	    }
19711: 	    return (vcret);
19712: 	}
19713:     }
19714: 
19715:     return (ret);
19716: }
19717: 
19718: /**
19719:  * xmlSchemaCheckElemSubstGroup:
19720:  * @ctxt:  a schema parser context
19721:  * @decl: the element declaration
19722:  * @name:  the name of the attribute
19723:  *
19724:  * Schema Component Constraint:
19725:  * Substitution Group (cos-equiv-class)
19726:  *
19727:  * In Libxml2 the subst. groups will be precomputed, in terms of that
19728:  * a list will be built for each subst. group head, holding all direct
19729:  * referents to this head.
19730:  * NOTE that this function needs:
19731:  *   1. circular subst. groups to be checked beforehand
19732:  *   2. the declaration's type to be derived from the head's type
19733:  *
19734:  * STATUS:
19735:  *
19736:  */
19737: static void
19738: xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
19739: 			     xmlSchemaElementPtr elemDecl)
19740: {
19741:     if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
19742: 	/* SPEC (1) "Its {abstract} is false." */
19743: 	(elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
19744: 	return;
19745:     {
19746: 	xmlSchemaElementPtr head;
19747: 	xmlSchemaTypePtr headType, type;
19748: 	int set, methSet;
19749: 	/*
19750: 	* SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
19751: 	* {disallowed substitutions} as the blocking constraint, as defined in
19752: 	* Substitution Group OK (Transitive) (�3.3.6)."
19753: 	*/
19754: 	for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
19755: 	    head = WXS_SUBST_HEAD(head)) {
19756: 	    set = 0;
19757: 	    methSet = 0;
19758: 	    /*
19759: 	    * The blocking constraints.
19760: 	    */
19761: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
19762: 		continue;
19763: 	    headType = head->subtypes;
19764: 	    type = elemDecl->subtypes;
19765: 	    if (headType == type)
19766: 		goto add_member;
19767: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
19768: 		set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19769: 	    if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
19770: 		set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19771: 	    /*
19772: 	    * SPEC: Substitution Group OK (Transitive) (2.3)
19773: 	    * "The set of all {derivation method}s involved in the
19774: 	    * derivation of D's {type definition} from C's {type definition}
19775: 	    * does not intersect with the union of the blocking constraint,
19776: 	    * C's {prohibited substitutions} (if C is complex, otherwise the
19777: 	    * empty set) and the {prohibited substitutions} (respectively the
19778: 	    * empty set) of any intermediate {type definition}s in the
19779: 	    * derivation of D's {type definition} from C's {type definition}."
19780: 	    */
19781: 	    /*
19782: 	    * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
19783: 	    * subst.head axis, the methSet does not need to be computed for
19784: 	    * the full depth over and over.
19785: 	    */
19786: 	    /*
19787: 	    * The set of all {derivation method}s involved in the derivation
19788: 	    */
19789: 	    while ((type != NULL) && (type != headType)) {
19790: 		if ((WXS_IS_EXTENSION(type)) &&
19791: 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19792: 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19793: 
19794: 		if (WXS_IS_RESTRICTION(type) &&
19795: 		    ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19796: 		    methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19797: 
19798: 		type = type->baseType;
19799: 	    }
19800: 	    /*
19801: 	    * The {prohibited substitutions} of all intermediate types +
19802: 	    * the head's type.
19803: 	    */
19804: 	    type = elemDecl->subtypes->baseType;
19805: 	    while (type != NULL) {
19806: 		if (WXS_IS_COMPLEX(type)) {
19807: 		    if ((type->flags &
19808: 			    XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19809: 			((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
19810: 		    set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
19811: 		    if ((type->flags &
19812: 			    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19813: 			((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
19814: 		    set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
19815: 		} else
19816: 		    break;
19817: 		if (type == headType)
19818: 		    break;
19819: 		type = type->baseType;
19820: 	    }
19821: 	    if ((set != 0) &&
19822: 		(((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
19823: 		(methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
19824: 		((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
19825: 		(methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
19826: 		continue;
19827: 	    }
19828: add_member:
19829: 	    xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
19830: 	    if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
19831: 		head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
19832: 	}
19833:     }
19834: }
19835: 
19836: #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
19837: /**
19838:  * xmlSchemaCheckElementDeclComponent
19839:  * @pctxt: the schema parser context
19840:  * @ctxtComponent: the context component (an element declaration)
19841:  * @ctxtParticle: the first particle of the context component
19842:  * @searchParticle: the element declaration particle to be analysed
19843:  *
19844:  * Schema Component Constraint: Element Declarations Consistent
19845:  */
19846: static int
19847: xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
19848: 				    xmlSchemaBasicItemPtr ctxtComponent,
19849: 				    xmlSchemaParticlePtr ctxtParticle,
19850: 				    xmlSchemaParticlePtr searchParticle,
19851: 				    xmlSchemaParticlePtr curParticle,
19852: 				    int search)
19853: {
19854:     return(0);
19855: 
19856:     int ret = 0;
19857:     xmlSchemaParticlePtr cur = curParticle;
19858:     if (curParticle == NULL) {
19859: 	return(0);
19860:     }
19861:     if (WXS_PARTICLE_TERM(curParticle) == NULL) {
19862: 	/*
19863: 	* Just return in this case. A missing "term" of the particle
19864: 	* might arise due to an invalid "term" component.
19865: 	*/
19866: 	return(0);
19867:     }
19868:     while (cur != NULL) {
19869: 	switch (WXS_PARTICLE_TERM(cur)->type) {
19870: 	    case XML_SCHEMA_TYPE_ANY:
19871: 		break;
19872: 	    case XML_SCHEMA_TYPE_ELEMENT:
19873: 		if (search == 0) {
19874: 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt,
19875: 			ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
19876: 		    if (ret != 0)
19877: 			return(ret);
19878: 		} else {
19879: 		    xmlSchemaElementPtr elem =
19880: 			WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
19881: 		    /*
19882: 		    * SPEC Element Declarations Consistent:
19883: 		    * "If the {particles} contains, either directly,
19884: 		    * indirectly (that is, within the {particles} of a
19885: 		    * contained model group, recursively) or �implicitly�
19886: 		    * two or more element declaration particles with
19887: 		    * the same {name} and {target namespace}, then
19888: 		    * all their type definitions must be the same
19889: 		    * top-level definition [...]"
19890: 		    */
19891: 		    if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
19892: 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
19893: 			xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19894: 			    WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
19895: 		    {
19896: 			xmlChar *strA = NULL, *strB = NULL;
19897: 
19898: 			xmlSchemaCustomErr(ACTXT_CAST pctxt,
19899: 			    /* TODO: error code */
19900: 			    XML_SCHEMAP_COS_NONAMBIG,
19901: 			    WXS_ITEM_NODE(cur), NULL,
19902: 			    "In the content model of %s, there are multiple "
19903: 			    "element declarations for '%s' with different "
19904: 			    "type definitions",
19905: 			    xmlSchemaGetComponentDesignation(&strA,
19906: 				ctxtComponent),
19907: 			    xmlSchemaFormatQName(&strB,
19908: 				WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
19909: 				WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
19910: 			FREE_AND_NULL(strA);
19911: 			FREE_AND_NULL(strB);
19912: 			return(XML_SCHEMAP_COS_NONAMBIG);
19913: 		    }
19914: 		}
19915: 		break;
19916: 	    case XML_SCHEMA_TYPE_SEQUENCE: {
19917: 		break;
19918: 		}
19919: 	    case XML_SCHEMA_TYPE_CHOICE:{
19920: 		/*
19921: 		xmlSchemaTreeItemPtr sub;
19922: 
19923: 		sub = WXS_PARTICLE_TERM(particle)->children;  (xmlSchemaParticlePtr)
19924: 		while (sub != NULL) {
19925: 		    ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
19926: 			ctxtParticle, ctxtElem);
19927: 		    if (ret != 0)
19928: 			return(ret);
19929: 		    sub = sub->next;
19930: 		}
19931: 		*/
19932: 		break;
19933: 		}
19934: 	    case XML_SCHEMA_TYPE_ALL:
19935: 		break;
19936: 	    case XML_SCHEMA_TYPE_GROUP:
19937: 		break;
19938: 	    default:
19939: 		xmlSchemaInternalErr2(ACTXT_CAST pctxt,
19940: 		    "xmlSchemaCheckElementDeclConsistent",
19941: 		    "found unexpected term of type '%s' in content model",
19942: 		    WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
19943: 		return(-1);
19944: 	}
19945: 	cur = (xmlSchemaParticlePtr) cur->next;
19946:     }
19947: 
19948: exit:
19949:     return(ret);
19950: }
19951: #endif
19952: 
19953: /**
19954:  * xmlSchemaCheckElementDeclComponent
19955:  * @item:  an schema element declaration/particle
19956:  * @ctxt:  a schema parser context
19957:  * @name:  the name of the attribute
19958:  *
19959:  * Validates the value constraints of an element declaration.
19960:  * Adds substitution group members.
19961:  */
19962: static void
19963: xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
19964: 				   xmlSchemaParserCtxtPtr ctxt)
19965: {
19966:     if (elemDecl == NULL)
19967: 	return;
19968:     if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
19969: 	return;
19970:     elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
19971:     if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
19972: 	/*
19973: 	* Adds substitution group members.
19974: 	*/
19975: 	xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
19976:     }
19977: }
19978: 
19979: /**
19980:  * xmlSchemaResolveModelGroupParticleReferences:
19981:  * @particle:  a particle component
19982:  * @ctxt:  a parser context
19983:  *
19984:  * Resolves references of a model group's {particles} to
19985:  * model group definitions and to element declarations.
19986:  */
19987: static void
19988: xmlSchemaResolveModelGroupParticleReferences(
19989:     xmlSchemaParserCtxtPtr ctxt,
19990:     xmlSchemaModelGroupPtr mg)
19991: {
19992:     xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
19993:     xmlSchemaQNameRefPtr ref;
19994:     xmlSchemaBasicItemPtr refItem;
19995: 
19996:     /*
19997:     * URGENT TODO: Test this.
19998:     */
19999:     while (particle != NULL) {
20000: 	if ((WXS_PARTICLE_TERM(particle) == NULL) ||
20001: 	    ((WXS_PARTICLE_TERM(particle))->type !=
20002: 		XML_SCHEMA_EXTRA_QNAMEREF))
20003: 	{
20004: 	    goto next_particle;
20005: 	}
20006: 	ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
20007: 	/*
20008: 	* Resolve the reference.
20009: 	* NULL the {term} by default.
20010: 	*/
20011: 	particle->children = NULL;
20012: 
20013: 	refItem = xmlSchemaGetNamedComponent(ctxt->schema,
20014: 	    ref->itemType, ref->name, ref->targetNamespace);
20015: 	if (refItem == NULL) {
20016: 	    xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
20017: 		NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
20018: 		ref->targetNamespace, ref->itemType, NULL);
20019: 	    /* TODO: remove the particle. */
20020: 	    goto next_particle;
20021: 	}
20022: 	if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
20023: 	    if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
20024: 		/* TODO: remove the particle. */
20025: 		goto next_particle;
20026: 	    /*
20027: 	    * NOTE that we will assign the model group definition
20028: 	    * itself to the "term" of the particle. This will ease
20029: 	    * the check for circular model group definitions. After
20030: 	    * that the "term" will be assigned the model group of the
20031: 	    * model group definition.
20032: 	    */
20033: 	    if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
20034: 		    XML_SCHEMA_TYPE_ALL) {
20035: 		/*
20036: 		* SPEC cos-all-limited (1)
20037: 		* SPEC cos-all-limited (1.2)
20038: 		* "It appears only as the value of one or both of the
20039: 		* following properties:"
20040: 		* (1.1) "the {model group} property of a model group
20041: 		*        definition."
20042: 		* (1.2) "the {term} property of a particle [... of] the "
20043: 		* {content type} of a complex type definition."
20044: 		*/
20045: 		xmlSchemaCustomErr(ACTXT_CAST ctxt,
20046: 		    /* TODO: error code */
20047: 		    XML_SCHEMAP_COS_ALL_LIMITED,
20048: 		    WXS_ITEM_NODE(particle), NULL,
20049: 		    "A model group definition is referenced, but "
20050: 		    "it contains an 'all' model group, which "
20051: 		    "cannot be contained by model groups",
20052: 		    NULL, NULL);
20053: 		/* TODO: remove the particle. */
20054: 		goto next_particle;
20055: 	    }
20056: 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
20057: 	} else {
20058: 	    /*
20059: 	    * TODO: Are referenced element declarations the only
20060: 	    * other components we expect here?
20061: 	    */
20062: 	    particle->children = (xmlSchemaTreeItemPtr) refItem;
20063: 	}
20064: next_particle:
20065: 	particle = WXS_PTC_CAST particle->next;
20066:     }
20067: }
20068: 
20069: static int
20070: xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
20071: 		       xmlSchemaValPtr y)
20072: {
20073:     xmlSchemaTypePtr tx, ty, ptx, pty;
20074:     int ret;
20075: 
20076:     while (x != NULL) {
20077: 	/* Same types. */
20078: 	tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
20079: 	ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
20080: 	ptx = xmlSchemaGetPrimitiveType(tx);
20081: 	pty = xmlSchemaGetPrimitiveType(ty);
20082: 	/*
20083: 	* (1) if a datatype T' is �derived� by �restriction� from an
20084: 	* atomic datatype T then the �value space� of T' is a subset of
20085: 	* the �value space� of T. */
20086: 	/*
20087: 	* (2) if datatypes T' and T'' are �derived� by �restriction�
20088: 	* from a common atomic ancestor T then the �value space�s of T'
20089: 	* and T'' may overlap.
20090: 	*/
20091: 	if (ptx != pty)
20092: 	    return(0);
20093: 	/*
20094: 	* We assume computed values to be normalized, so do a fast
20095: 	* string comparison for string based types.
20096: 	*/
20097: 	if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
20098: 	    WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
20099: 	    if (! xmlStrEqual(
20100: 		xmlSchemaValueGetAsString(x),
20101: 		xmlSchemaValueGetAsString(y)))
20102: 		return (0);
20103: 	} else {
20104: 	    ret = xmlSchemaCompareValuesWhtsp(
20105: 		x, XML_SCHEMA_WHITESPACE_PRESERVE,
20106: 		y, XML_SCHEMA_WHITESPACE_PRESERVE);
20107: 	    if (ret == -2)
20108: 		return(-1);
20109: 	    if (ret != 0)
20110: 		return(0);
20111: 	}
20112: 	/*
20113: 	* Lists.
20114: 	*/
20115: 	x = xmlSchemaValueGetNext(x);
20116: 	if (x != NULL) {
20117: 	    y = xmlSchemaValueGetNext(y);
20118: 	    if (y == NULL)
20119: 		return (0);
20120: 	} else if (xmlSchemaValueGetNext(y) != NULL)
20121: 	    return (0);
20122: 	else
20123: 	    return (1);
20124:     }
20125:     return (0);
20126: }
20127: 
20128: /**
20129:  * xmlSchemaResolveAttrUseReferences:
20130:  * @item:  an attribute use
20131:  * @ctxt:  a parser context
20132:  *
20133:  * Resolves the referenced attribute declaration.
20134:  */
20135: static int
20136: xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
20137: 				  xmlSchemaParserCtxtPtr ctxt)
20138: {
20139:     if ((ctxt == NULL) || (ause == NULL))
20140: 	return(-1);
20141:     if ((ause->attrDecl == NULL) ||
20142: 	(ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
20143: 	return(0);
20144: 
20145:     {
20146: 	xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
20147: 
20148: 	/*
20149: 	* TODO: Evaluate, what errors could occur if the declaration is not
20150: 	* found.
20151: 	*/
20152: 	ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
20153: 	    ref->name, ref->targetNamespace);
20154:         if (ause->attrDecl == NULL) {
20155: 	    xmlSchemaPResCompAttrErr(ctxt,
20156: 	    	XML_SCHEMAP_SRC_RESOLVE,
20157: 		WXS_BASIC_CAST ause, ause->node,
20158: 		"ref", ref->name, ref->targetNamespace,
20159: 		XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20160:             return(ctxt->err);;
20161:         }
20162:     }
20163:     return(0);
20164: }
20165: 
20166: /**
20167:  * xmlSchemaCheckAttrUsePropsCorrect:
20168:  * @ctxt:  a parser context
20169:  * @use:  an attribute use
20170:  *
20171:  * Schema Component Constraint:
20172:  * Attribute Use Correct (au-props-correct)
20173:  *
20174:  */
20175: static int
20176: xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
20177: 			     xmlSchemaAttributeUsePtr use)
20178: {
20179:     if ((ctxt == NULL) || (use == NULL))
20180: 	return(-1);
20181:     if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
20182: 	((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
20183: 	return(0);
20184: 
20185:     /*
20186:     * SPEC au-props-correct (1)
20187:     * "The values of the properties of an attribute use must be as
20188:     * described in the property tableau in The Attribute Use Schema
20189:     * Component (�3.5.1), modulo the impact of Missing
20190:     * Sub-components (�5.3)."
20191:     */
20192: 
20193:     if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
20194: 	((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
20195:         ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20196:     {
20197: 	xmlSchemaPCustomErr(ctxt,
20198: 	    XML_SCHEMAP_AU_PROPS_CORRECT_2,
20199: 	    WXS_BASIC_CAST use, NULL,
20200: 	    "The attribute declaration has a 'fixed' value constraint "
20201: 	    ", thus the attribute use must also have a 'fixed' value "
20202: 	    "constraint",
20203: 	    NULL);
20204: 	return(ctxt->err);
20205:     }
20206:     /*
20207:     * Compute and check the value constraint's value.
20208:     */
20209:     if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
20210: 	int ret;
20211: 	/*
20212: 	* TODO: The spec seems to be missing a check of the
20213: 	* value constraint of the attribute use. We will do it here.
20214: 	*/
20215: 	/*
20216: 	* SPEC a-props-correct (3)
20217: 	*/
20218: 	if (xmlSchemaIsDerivedFromBuiltInType(
20219: 	    WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
20220: 	{
20221: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20222: 		XML_SCHEMAP_AU_PROPS_CORRECT,
20223: 		NULL, WXS_BASIC_CAST use,
20224: 		"Value constraints are not allowed if the type definition "
20225: 		"is or is derived from xs:ID",
20226: 		NULL, NULL);
20227: 	    return(ctxt->err);
20228: 	}
20229: 
20230: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
20231: 	    use->node, WXS_ATTRUSE_TYPEDEF(use),
20232: 	    use->defValue, &(use->defVal),
20233: 	    1, 1, 0);
20234: 	if (ret != 0) {
20235: 	    if (ret < 0) {
20236: 		PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
20237: 		    "calling xmlSchemaVCheckCVCSimpleType()");
20238: 		return(-1);
20239: 	    }
20240: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt,
20241: 		XML_SCHEMAP_AU_PROPS_CORRECT,
20242: 		NULL, WXS_BASIC_CAST use,
20243: 		"The value of the value constraint is not valid",
20244: 		NULL, NULL);
20245: 	    return(ctxt->err);
20246: 	}
20247:     }
20248:     /*
20249:     * SPEC au-props-correct (2)
20250:     * "If the {attribute declaration} has a fixed
20251:     * {value constraint}, then if the attribute use itself has a
20252:     * {value constraint}, it must also be fixed and its value must match
20253:     * that of the {attribute declaration}'s {value constraint}."
20254:     */
20255:     if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
20256: 	(((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
20257:     {
20258: 	if (! xmlSchemaAreValuesEqual(use->defVal,
20259: 		(WXS_ATTRUSE_DECL(use))->defVal))
20260: 	{
20261: 	    xmlSchemaPCustomErr(ctxt,
20262: 		XML_SCHEMAP_AU_PROPS_CORRECT_2,
20263: 		WXS_BASIC_CAST use, NULL,
20264: 		"The 'fixed' value constraint of the attribute use "
20265: 		"must match the attribute declaration's value "
20266: 		"constraint '%s'",
20267: 		(WXS_ATTRUSE_DECL(use))->defValue);
20268: 	}
20269: 	return(ctxt->err);
20270:     }
20271:     return(0);
20272: }
20273: 
20274: 
20275: 
20276: 
20277: /**
20278:  * xmlSchemaResolveAttrTypeReferences:
20279:  * @item:  an attribute declaration
20280:  * @ctxt:  a parser context
20281:  *
20282:  * Resolves the referenced type definition component.
20283:  */
20284: static int
20285: xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
20286: 				   xmlSchemaParserCtxtPtr ctxt)
20287: {
20288:     /*
20289:     * The simple type definition corresponding to the <simpleType> element
20290:     * information item in the [children], if present, otherwise the simple
20291:     * type definition �resolved� to by the �actual value� of the type
20292:     * [attribute], if present, otherwise the �simple ur-type definition�.
20293:     */
20294:     if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
20295: 	return(0);
20296:     item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
20297:     if (item->subtypes != NULL)
20298:         return(0);
20299:     if (item->typeName != NULL) {
20300:         xmlSchemaTypePtr type;
20301: 
20302: 	type = xmlSchemaGetType(ctxt->schema, item->typeName,
20303: 	    item->typeNs);
20304: 	if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
20305: 	    xmlSchemaPResCompAttrErr(ctxt,
20306: 		XML_SCHEMAP_SRC_RESOLVE,
20307: 		WXS_BASIC_CAST item, item->node,
20308: 		"type", item->typeName, item->typeNs,
20309: 		XML_SCHEMA_TYPE_SIMPLE, NULL);
20310: 	    return(ctxt->err);
20311: 	} else
20312: 	    item->subtypes = type;
20313: 
20314:     } else {
20315: 	/*
20316: 	* The type defaults to the xs:anySimpleType.
20317: 	*/
20318: 	item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
20319:     }
20320:     return(0);
20321: }
20322: 
20323: /**
20324:  * xmlSchemaResolveIDCKeyReferences:
20325:  * @idc:  the identity-constraint definition
20326:  * @ctxt:  the schema parser context
20327:  * @name:  the attribute name
20328:  *
20329:  * Resolve keyRef references to key/unique IDCs.
20330:  * Schema Component Constraint:
20331:  *   Identity-constraint Definition Properties Correct (c-props-correct)
20332:  */
20333: static int
20334: xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
20335: 			  xmlSchemaParserCtxtPtr pctxt)
20336: {
20337:     if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
20338:         return(0);
20339:     if (idc->ref->name != NULL) {
20340: 	idc->ref->item = (xmlSchemaBasicItemPtr)
20341: 	    xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
20342: 		idc->ref->targetNamespace);
20343:         if (idc->ref->item == NULL) {
20344: 	    /*
20345: 	    * TODO: It is actually not an error to fail to resolve
20346: 	    * at this stage. BUT we need to be that strict!
20347: 	    */
20348: 	    xmlSchemaPResCompAttrErr(pctxt,
20349: 		XML_SCHEMAP_SRC_RESOLVE,
20350: 		WXS_BASIC_CAST idc, idc->node,
20351: 		"refer", idc->ref->name,
20352: 		idc->ref->targetNamespace,
20353: 		XML_SCHEMA_TYPE_IDC_KEY, NULL);
20354:             return(pctxt->err);
20355: 	} else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
20356: 	    /*
20357: 	    * SPEC c-props-correct (1)
20358: 	    */
20359: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20360: 		XML_SCHEMAP_C_PROPS_CORRECT,
20361: 		NULL, WXS_BASIC_CAST idc,
20362: 		"The keyref references a keyref",
20363: 		NULL, NULL);
20364: 	    idc->ref->item = NULL;
20365: 	    return(pctxt->err);
20366: 	} else {
20367: 	    if (idc->nbFields !=
20368: 		((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
20369: 		xmlChar *str = NULL;
20370: 		xmlSchemaIDCPtr refer;
20371: 
20372: 		refer = (xmlSchemaIDCPtr) idc->ref->item;
20373: 		/*
20374: 		* SPEC c-props-correct(2)
20375: 		* "If the {identity-constraint category} is keyref,
20376: 		* the cardinality of the {fields} must equal that of
20377: 		* the {fields} of the {referenced key}.
20378: 		*/
20379: 		xmlSchemaCustomErr(ACTXT_CAST pctxt,
20380: 		    XML_SCHEMAP_C_PROPS_CORRECT,
20381: 		    NULL, WXS_BASIC_CAST idc,
20382: 		    "The cardinality of the keyref differs from the "
20383: 		    "cardinality of the referenced key/unique '%s'",
20384: 		    xmlSchemaFormatQName(&str, refer->targetNamespace,
20385: 			refer->name),
20386: 		    NULL);
20387: 		FREE_AND_NULL(str)
20388: 		return(pctxt->err);
20389: 	    }
20390: 	}
20391:     }
20392:     return(0);
20393: }
20394: 
20395: static int
20396: xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
20397: 				       xmlSchemaParserCtxtPtr pctxt)
20398: {
20399:     if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
20400: 	prohib->targetNamespace) == NULL) {
20401: 
20402: 	xmlSchemaPResCompAttrErr(pctxt,
20403: 	    XML_SCHEMAP_SRC_RESOLVE,
20404: 	    NULL, prohib->node,
20405: 	    "ref", prohib->name, prohib->targetNamespace,
20406: 	    XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
20407: 	return(XML_SCHEMAP_SRC_RESOLVE);
20408:     }
20409:     return(0);
20410: }
20411: 
20412: #define WXS_REDEFINED_TYPE(c) \
20413: (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
20414: 
20415: #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
20416: (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20417: 
20418: #define WXS_REDEFINED_ATTR_GROUP(c) \
20419: (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
20420: 
20421: static int
20422: xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
20423: {
20424:     int err = 0;
20425:     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20426:     xmlSchemaBasicItemPtr prev, item;
20427:     int wasRedefined;
20428: 
20429:     if (redef == NULL)
20430: 	return(0);
20431: 
20432:     do {
20433: 	item = redef->item;
20434: 	/*
20435: 	* First try to locate the redefined component in the
20436: 	* schema graph starting with the redefined schema.
20437: 	* NOTE: According to this schema bug entry:
20438: 	*   http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
20439: 	*   it's not clear if the referenced component needs to originate
20440: 	*   from the <redefine>d schema _document_ or the schema; the latter
20441: 	*   would include all imported and included sub-schemas of the
20442: 	*   <redefine>d schema. Currenlty we latter approach is used.
20443: 	*   SUPPLEMENT: It seems that the WG moves towards the latter
20444: 	*   approach, so we are doing it right.
20445: 	*
20446: 	*/
20447: 	prev = xmlSchemaFindRedefCompInGraph(
20448: 	    redef->targetBucket, item->type,
20449: 	    redef->refName, redef->refTargetNs);
20450: 	if (prev == NULL) {
20451: 	    xmlChar *str = NULL;
20452: 	    xmlNodePtr node;
20453: 
20454: 	    /*
20455: 	    * SPEC src-redefine:
20456: 	    * (6.2.1) "The �actual value� of its own name attribute plus
20457: 	    * target namespace must successfully �resolve� to a model
20458: 	    * group definition in I."
20459: 	    * (7.2.1) "The �actual value� of its own name attribute plus
20460: 	    * target namespace must successfully �resolve� to an attribute
20461: 	    * group definition in I."
20462: 
20463: 	    *
20464: 	    * Note that, if we are redefining with the use of references
20465: 	    * to components, the spec assumes the src-resolve to be used;
20466: 	    * but this won't assure that we search only *inside* the
20467: 	    * redefined schema.
20468: 	    */
20469: 	    if (redef->reference)
20470: 		node = WXS_ITEM_NODE(redef->reference);
20471: 	    else
20472: 		node = WXS_ITEM_NODE(item);
20473: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20474: 		/*
20475: 		* TODO: error code.
20476: 		* Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
20477: 		* reference kind.
20478: 		*/
20479: 		XML_SCHEMAP_SRC_REDEFINE, node, NULL,
20480: 		"The %s '%s' to be redefined could not be found in "
20481: 		"the redefined schema",
20482: 		WXS_ITEM_TYPE_NAME(item),
20483: 		xmlSchemaFormatQName(&str, redef->refTargetNs,
20484: 		    redef->refName));
20485: 	    FREE_AND_NULL(str);
20486: 	    err = pctxt->err;
20487: 	    redef = redef->next;
20488: 	    continue;
20489: 	}
20490: 	/*
20491: 	* TODO: Obtaining and setting the redefinition state is really
20492: 	* clumsy.
20493: 	*/
20494: 	wasRedefined = 0;
20495: 	switch (item->type) {
20496: 	    case XML_SCHEMA_TYPE_COMPLEX:
20497: 	    case XML_SCHEMA_TYPE_SIMPLE:
20498: 		if ((WXS_TYPE_CAST prev)->flags &
20499: 		    XML_SCHEMAS_TYPE_REDEFINED)
20500: 		{
20501: 		    wasRedefined = 1;
20502: 		    break;
20503: 		}
20504: 		/* Mark it as redefined. */
20505: 		(WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
20506: 		/*
20507: 		* Assign the redefined type to the
20508: 		* base type of the redefining type.
20509: 		* TODO: How
20510: 		*/
20511: 		((xmlSchemaTypePtr) item)->baseType =
20512: 		    (xmlSchemaTypePtr) prev;
20513: 		break;
20514: 	    case XML_SCHEMA_TYPE_GROUP:
20515: 		if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
20516: 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
20517: 		{
20518: 		    wasRedefined = 1;
20519: 		    break;
20520: 		}
20521: 		/* Mark it as redefined. */
20522: 		(WXS_MODEL_GROUPDEF_CAST prev)->flags |=
20523: 		    XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
20524: 		if (redef->reference != NULL) {
20525: 		    /*
20526: 		    * Overwrite the QName-reference with the
20527: 		    * referenced model group def.
20528: 		    */
20529: 		    (WXS_PTC_CAST redef->reference)->children =
20530: 			WXS_TREE_CAST prev;
20531: 		}
20532: 		redef->target = prev;
20533: 		break;
20534: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20535: 		if ((WXS_ATTR_GROUP_CAST prev)->flags &
20536: 		    XML_SCHEMAS_ATTRGROUP_REDEFINED)
20537: 		{
20538: 		    wasRedefined = 1;
20539: 		    break;
20540: 		}
20541: 		(WXS_ATTR_GROUP_CAST prev)->flags |=
20542: 		    XML_SCHEMAS_ATTRGROUP_REDEFINED;
20543: 		if (redef->reference != NULL) {
20544: 		    /*
20545: 		    * Assign the redefined attribute group to the
20546: 		    * QName-reference component.
20547: 		    * This is the easy case, since we will just
20548: 		    * expand the redefined group.
20549: 		    */
20550: 		    (WXS_QNAME_CAST redef->reference)->item = prev;
20551: 		    redef->target = NULL;
20552: 		} else {
20553: 		    /*
20554: 		    * This is the complicated case: we need
20555: 		    * to apply src-redefine (7.2.2) at a later
20556: 		    * stage, i.e. when attribute group references
20557: 		    * have beed expanded and simple types have
20558: 		    * beed fixed.
20559: 		    */
20560: 		    redef->target = prev;
20561: 		}
20562: 		break;
20563: 	    default:
20564: 		PERROR_INT("xmlSchemaResolveRedefReferences",
20565: 		    "Unexpected redefined component type");
20566: 		return(-1);
20567: 	}
20568: 	if (wasRedefined) {
20569: 	    xmlChar *str = NULL;
20570: 	    xmlNodePtr node;
20571: 
20572: 	    if (redef->reference)
20573: 		node = WXS_ITEM_NODE(redef->reference);
20574: 	    else
20575: 		node = WXS_ITEM_NODE(redef->item);
20576: 
20577: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20578: 		/* TODO: error code. */
20579: 		XML_SCHEMAP_SRC_REDEFINE,
20580: 		node, NULL,
20581: 		"The referenced %s was already redefined. Multiple "
20582: 		"redefinition of the same component is not supported",
20583: 		xmlSchemaGetComponentDesignation(&str, prev),
20584: 		NULL);
20585: 	    FREE_AND_NULL(str)
20586: 	    err = pctxt->err;
20587: 	    redef = redef->next;
20588: 	    continue;
20589: 	}
20590: 	redef = redef->next;
20591:     } while (redef != NULL);
20592: 
20593:     return(err);
20594: }
20595: 
20596: static int
20597: xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
20598: {
20599:     int err = 0;
20600:     xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
20601:     xmlSchemaBasicItemPtr item;
20602: 
20603:     if (redef == NULL)
20604: 	return(0);
20605: 
20606:     do {
20607: 	if (redef->target == NULL) {
20608: 	    redef = redef->next;
20609: 	    continue;
20610: 	}
20611: 	item = redef->item;
20612: 
20613: 	switch (item->type) {
20614: 	    case XML_SCHEMA_TYPE_SIMPLE:
20615: 	    case XML_SCHEMA_TYPE_COMPLEX:
20616: 		/*
20617: 		* Since the spec wants the {name} of the redefined
20618: 		* type to be 'absent', we'll NULL it.
20619: 		*/
20620: 		(WXS_TYPE_CAST redef->target)->name = NULL;
20621: 
20622: 		/*
20623: 		* TODO: Seems like there's nothing more to do. The normal
20624: 		* inheritance mechanism is used. But not 100% sure.
20625: 		*/
20626: 		break;
20627: 	    case XML_SCHEMA_TYPE_GROUP:
20628: 		/*
20629: 		* URGENT TODO:
20630: 		* SPEC src-redefine:
20631: 		* (6.2.2) "The {model group} of the model group definition
20632: 		* which corresponds to it per XML Representation of Model
20633: 		* Group Definition Schema Components (�3.7.2) must be a
20634: 		* �valid restriction� of the {model group} of that model
20635: 		* group definition in I, as defined in Particle Valid
20636: 		* (Restriction) (�3.9.6)."
20637: 		*/
20638: 		break;
20639: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20640: 		/*
20641: 		* SPEC src-redefine:
20642: 		* (7.2.2) "The {attribute uses} and {attribute wildcard} of
20643: 		* the attribute group definition which corresponds to it
20644: 		* per XML Representation of Attribute Group Definition Schema
20645: 		* Components (�3.6.2) must be �valid restrictions� of the
20646: 		* {attribute uses} and {attribute wildcard} of that attribute
20647: 		* group definition in I, as defined in clause 2, clause 3 and
20648: 		* clause 4 of Derivation Valid (Restriction, Complex)
20649: 		* (�3.4.6) (where references to the base type definition are
20650: 		* understood as references to the attribute group definition
20651: 		* in I)."
20652: 		*/
20653: 		err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
20654: 		    XML_SCHEMA_ACTION_REDEFINE,
20655: 		    item, redef->target,
20656: 		    (WXS_ATTR_GROUP_CAST item)->attrUses,
20657: 		    (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
20658: 		    (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
20659: 		    (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
20660: 		if (err == -1)
20661: 		    return(-1);
20662: 		break;
20663: 	    default:
20664: 		break;
20665: 	}
20666: 	redef = redef->next;
20667:     } while (redef != NULL);
20668:     return(0);
20669: }
20670: 
20671: 
20672: static int
20673: xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
20674: 		       xmlSchemaBucketPtr bucket)
20675: {
20676:     xmlSchemaBasicItemPtr item;
20677:     int err;
20678:     xmlHashTablePtr *table;
20679:     const xmlChar *name;
20680:     int i;
20681: 
20682: #define WXS_GET_GLOBAL_HASH(c, slot) { \
20683:     if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
20684: 	table = &(WXS_IMPBUCKET((c))->schema->slot); \
20685:     else \
20686: 	table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
20687: 
20688:     /*
20689:     * Add global components to the schema's hash tables.
20690:     * This is the place where duplicate components will be
20691:     * detected.
20692:     * TODO: I think normally we should support imports of the
20693:     *   same namespace from multiple locations. We don't do currently,
20694:     *   but if we do then according to:
20695:     *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
20696:     *   we would need, if imported directly, to import redefined
20697:     *   components as well to be able to catch clashing components.
20698:     *   (I hope I'll still know what this means after some months :-()
20699:     */
20700:     if (bucket == NULL)
20701: 	return(-1);
20702:     if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
20703: 	return(0);
20704:     bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
20705: 
20706:     for (i = 0; i < bucket->globals->nbItems; i++) {
20707: 	item = bucket->globals->items[i];
20708: 	table = NULL;
20709: 	switch (item->type) {
20710: 	    case XML_SCHEMA_TYPE_COMPLEX:
20711: 	    case XML_SCHEMA_TYPE_SIMPLE:
20712: 		if (WXS_REDEFINED_TYPE(item))
20713: 		    continue;
20714: 		name = (WXS_TYPE_CAST item)->name;
20715: 		WXS_GET_GLOBAL_HASH(bucket, typeDecl)
20716: 		break;
20717: 	    case XML_SCHEMA_TYPE_ELEMENT:
20718: 		name = (WXS_ELEM_CAST item)->name;
20719: 		WXS_GET_GLOBAL_HASH(bucket, elemDecl)
20720: 		break;
20721: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
20722: 		name = (WXS_ATTR_CAST item)->name;
20723: 		WXS_GET_GLOBAL_HASH(bucket, attrDecl)
20724: 		break;
20725: 	    case XML_SCHEMA_TYPE_GROUP:
20726: 		if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
20727: 		    continue;
20728: 		name = (WXS_MODEL_GROUPDEF_CAST item)->name;
20729: 		WXS_GET_GLOBAL_HASH(bucket, groupDecl)
20730: 		break;
20731: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20732: 		if (WXS_REDEFINED_ATTR_GROUP(item))
20733: 		    continue;
20734: 		name = (WXS_ATTR_GROUP_CAST item)->name;
20735: 		WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
20736: 		break;
20737: 	    case XML_SCHEMA_TYPE_IDC_KEY:
20738: 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
20739: 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
20740: 		name = (WXS_IDC_CAST item)->name;
20741: 		WXS_GET_GLOBAL_HASH(bucket, idcDef)
20742: 		break;
20743: 	    case XML_SCHEMA_TYPE_NOTATION:
20744: 		name = ((xmlSchemaNotationPtr) item)->name;
20745: 		WXS_GET_GLOBAL_HASH(bucket, notaDecl)
20746: 		break;
20747: 	    default:
20748: 		PERROR_INT("xmlSchemaAddComponents",
20749: 		    "Unexpected global component type");
20750: 		continue;
20751: 	}
20752: 	if (*table == NULL) {
20753: 	    *table = xmlHashCreateDict(10, pctxt->dict);
20754: 	    if (*table == NULL) {
20755: 		PERROR_INT("xmlSchemaAddComponents",
20756: 		    "failed to create a component hash table");
20757: 		return(-1);
20758: 	    }
20759: 	}
20760: 	err = xmlHashAddEntry(*table, name, item);
20761: 	if (err != 0) {
20762: 	    xmlChar *str = NULL;
20763: 
20764: 	    xmlSchemaCustomErr(ACTXT_CAST pctxt,
20765: 		XML_SCHEMAP_REDEFINED_TYPE,
20766: 		WXS_ITEM_NODE(item),
20767: 		WXS_BASIC_CAST item,
20768: 		"A global %s '%s' does already exist",
20769: 		WXS_ITEM_TYPE_NAME(item),
20770: 		xmlSchemaGetComponentQName(&str, item));
20771: 	    FREE_AND_NULL(str);
20772: 	}
20773:     }
20774:     /*
20775:     * Process imported/included schemas.
20776:     */
20777:     if (bucket->relations != NULL) {
20778: 	xmlSchemaSchemaRelationPtr rel = bucket->relations;
20779: 	do {
20780: 	    if ((rel->bucket != NULL) &&
20781: 		((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
20782: 		if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
20783: 		    return(-1);
20784: 	    }
20785: 	    rel = rel->next;
20786: 	} while (rel != NULL);
20787:     }
20788:     return(0);
20789: }
20790: 
20791: static int
20792: xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
20793: 			 xmlSchemaBucketPtr rootBucket)
20794: {
20795:     xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
20796:     xmlSchemaTreeItemPtr item, *items;
20797:     int nbItems, i, ret = 0;
20798:     xmlSchemaBucketPtr oldbucket = con->bucket;
20799:     xmlSchemaElementPtr elemDecl;
20800: 
20801: #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
20802: 
20803:     if ((con->pending == NULL) ||
20804: 	(con->pending->nbItems == 0))
20805: 	return(0);
20806: 
20807:     /*
20808:     * Since xmlSchemaFixupComplexType() will create new particles
20809:     * (local components), and those particle components need a bucket
20810:     * on the constructor, we'll assure here that the constructor has
20811:     * a bucket.
20812:     * TODO: Think about storing locals _only_ on the main bucket.
20813:     */
20814:     if (con->bucket == NULL)
20815: 	con->bucket = rootBucket;
20816: 
20817:     /* TODO:
20818:     * SPEC (src-redefine):
20819:     * (6.2) "If it has no such self-reference, then all of the
20820:     * following must be true:"
20821: 
20822:     * (6.2.2) The {model group} of the model group definition which
20823:     * corresponds to it per XML Representation of Model Group
20824:     * Definition Schema Components (�3.7.2) must be a �valid
20825:     * restriction� of the {model group} of that model group definition
20826:     * in I, as defined in Particle Valid (Restriction) (�3.9.6)."
20827:     */
20828:     xmlSchemaCheckSRCRedefineFirst(pctxt);
20829: 
20830:     /*
20831:     * Add global components to the schemata's hash tables.
20832:     */
20833:     xmlSchemaAddComponents(pctxt, rootBucket);
20834: 
20835:     pctxt->ctxtType = NULL;
20836:     items = (xmlSchemaTreeItemPtr *) con->pending->items;
20837:     nbItems = con->pending->nbItems;
20838:     /*
20839:     * Now that we have parsed *all* the schema document(s) and converted
20840:     * them to schema components, we can resolve references, apply component
20841:     * constraints, create the FSA from the content model, etc.
20842:     */
20843:     /*
20844:     * Resolve references of..
20845:     *
20846:     * 1. element declarations:
20847:     *   - the type definition
20848:     *   - the substitution group affiliation
20849:     * 2. simple/complex types:
20850:     *   - the base type definition
20851:     *   - the memberTypes of union types
20852:     *   - the itemType of list types
20853:     * 3. attributes declarations and attribute uses:
20854:     *   - the type definition
20855:     *   - if an attribute use, then the attribute declaration
20856:     * 4. attribute group references:
20857:     *   - the attribute group definition
20858:     * 5. particles:
20859:     *   - the term of the particle (e.g. a model group)
20860:     * 6. IDC key-references:
20861:     *   - the referenced IDC 'key' or 'unique' definition
20862:     * 7. Attribute prohibitions which had a "ref" attribute.
20863:     */
20864:     for (i = 0; i < nbItems; i++) {
20865: 	item = items[i];
20866: 	switch (item->type) {
20867: 	    case XML_SCHEMA_TYPE_ELEMENT:
20868: 		xmlSchemaResolveElementReferences(
20869: 		    (xmlSchemaElementPtr) item, pctxt);
20870: 		FIXHFAILURE;
20871: 		break;
20872: 	    case XML_SCHEMA_TYPE_COMPLEX:
20873: 	    case XML_SCHEMA_TYPE_SIMPLE:
20874: 		xmlSchemaResolveTypeReferences(
20875: 		    (xmlSchemaTypePtr) item, pctxt);
20876: 		FIXHFAILURE;
20877: 		break;
20878: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
20879: 		xmlSchemaResolveAttrTypeReferences(
20880: 		    (xmlSchemaAttributePtr) item, pctxt);
20881: 		FIXHFAILURE;
20882: 		break;
20883: 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
20884: 		xmlSchemaResolveAttrUseReferences(
20885: 		    (xmlSchemaAttributeUsePtr) item, pctxt);
20886: 		FIXHFAILURE;
20887: 		break;
20888: 	    case XML_SCHEMA_EXTRA_QNAMEREF:
20889: 		if ((WXS_QNAME_CAST item)->itemType ==
20890: 		    XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
20891: 		{
20892: 		    xmlSchemaResolveAttrGroupReferences(
20893: 			WXS_QNAME_CAST item, pctxt);
20894: 		}
20895: 		FIXHFAILURE;
20896: 		break;
20897: 	    case XML_SCHEMA_TYPE_SEQUENCE:
20898: 	    case XML_SCHEMA_TYPE_CHOICE:
20899: 	    case XML_SCHEMA_TYPE_ALL:
20900: 		xmlSchemaResolveModelGroupParticleReferences(pctxt,
20901: 		    WXS_MODEL_GROUP_CAST item);
20902: 		FIXHFAILURE;
20903: 		break;
20904: 	    case XML_SCHEMA_TYPE_IDC_KEY:
20905: 	    case XML_SCHEMA_TYPE_IDC_UNIQUE:
20906: 	    case XML_SCHEMA_TYPE_IDC_KEYREF:
20907: 		xmlSchemaResolveIDCKeyReferences(
20908: 		    (xmlSchemaIDCPtr) item, pctxt);
20909: 		FIXHFAILURE;
20910: 		break;
20911: 	    case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
20912: 		/*
20913: 		* Handle attribue prohibition which had a
20914: 		* "ref" attribute.
20915: 		*/
20916: 		xmlSchemaResolveAttrUseProhibReferences(
20917: 		    WXS_ATTR_PROHIB_CAST item, pctxt);
20918: 		FIXHFAILURE;
20919: 		break;
20920: 	    default:
20921: 		break;
20922: 	}
20923:     }
20924:     if (pctxt->nberrors != 0)
20925: 	goto exit_error;
20926: 
20927:     /*
20928:     * Now that all references are resolved we
20929:     * can check for circularity of...
20930:     * 1. the base axis of type definitions
20931:     * 2. nested model group definitions
20932:     * 3. nested attribute group definitions
20933:     * TODO: check for circual substitution groups.
20934:     */
20935:     for (i = 0; i < nbItems; i++) {
20936: 	item = items[i];
20937: 	/*
20938: 	* Let's better stop on the first error here.
20939: 	*/
20940: 	switch (item->type) {
20941: 	    case XML_SCHEMA_TYPE_COMPLEX:
20942: 	    case XML_SCHEMA_TYPE_SIMPLE:
20943: 		xmlSchemaCheckTypeDefCircular(
20944: 		    (xmlSchemaTypePtr) item, pctxt);
20945: 		FIXHFAILURE;
20946: 		if (pctxt->nberrors != 0)
20947: 		    goto exit_error;
20948: 		break;
20949: 	    case XML_SCHEMA_TYPE_GROUP:
20950: 		xmlSchemaCheckGroupDefCircular(
20951: 		    (xmlSchemaModelGroupDefPtr) item, pctxt);
20952: 		FIXHFAILURE;
20953: 		if (pctxt->nberrors != 0)
20954: 		    goto exit_error;
20955: 		break;
20956: 	    case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20957: 		xmlSchemaCheckAttrGroupCircular(
20958: 		    (xmlSchemaAttributeGroupPtr) item, pctxt);
20959: 		FIXHFAILURE;
20960: 		if (pctxt->nberrors != 0)
20961: 		    goto exit_error;
20962: 		break;
20963: 	    default:
20964: 		break;
20965: 	}
20966:     }
20967:     if (pctxt->nberrors != 0)
20968: 	goto exit_error;
20969:     /*
20970:     * Model group definition references:
20971:     * Such a reference is reflected by a particle at the component
20972:     * level. Until now the 'term' of such particles pointed
20973:     * to the model group definition; this was done, in order to
20974:     * ease circularity checks. Now we need to set the 'term' of
20975:     * such particles to the model group of the model group definition.
20976:     */
20977:     for (i = 0; i < nbItems; i++) {
20978: 	item = items[i];
20979: 	switch (item->type) {
20980: 	    case XML_SCHEMA_TYPE_SEQUENCE:
20981: 	    case XML_SCHEMA_TYPE_CHOICE:
20982: 		xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
20983: 		    WXS_MODEL_GROUP_CAST item);
20984: 		break;
20985: 	    default:
20986: 		break;
20987: 	}
20988:     }
20989:     if (pctxt->nberrors != 0)
20990: 	goto exit_error;
20991:     /*
20992:     * Expand attribute group references of attribute group definitions.
20993:     */
20994:     for (i = 0; i < nbItems; i++) {
20995: 	item = items[i];
20996: 	switch (item->type) {
20997:             case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
20998: 		if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
20999: 		    WXS_ATTR_GROUP_HAS_REFS(item))
21000: 		{
21001: 		    xmlSchemaAttributeGroupExpandRefs(pctxt,
21002: 			WXS_ATTR_GROUP_CAST item);
21003: 		    FIXHFAILURE;
21004: 		}
21005: 		break;
21006: 	    default:
21007: 		break;
21008: 	}
21009:     }
21010:     if (pctxt->nberrors != 0)
21011: 	goto exit_error;
21012:     /*
21013:     * First compute the variety of simple types. This is needed as
21014:     * a seperate step, since otherwise we won't be able to detect
21015:     * circular union types in all cases.
21016:     */
21017:     for (i = 0; i < nbItems; i++) {
21018: 	item = items[i];
21019: 	switch (item->type) {
21020:             case XML_SCHEMA_TYPE_SIMPLE:
21021: 		if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
21022: 		    xmlSchemaFixupSimpleTypeStageOne(pctxt,
21023: 			(xmlSchemaTypePtr) item);
21024: 		    FIXHFAILURE;
21025: 		}
21026: 		break;
21027: 	    default:
21028: 		break;
21029: 	}
21030:     }
21031:     if (pctxt->nberrors != 0)
21032: 	goto exit_error;
21033:     /*
21034:     * Detect circular union types. Note that this needs the variety to
21035:     * be already computed.
21036:     */
21037:     for (i = 0; i < nbItems; i++) {
21038: 	item = items[i];
21039: 	switch (item->type) {
21040:             case XML_SCHEMA_TYPE_SIMPLE:
21041: 		if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
21042: 		    xmlSchemaCheckUnionTypeDefCircular(pctxt,
21043: 			(xmlSchemaTypePtr) item);
21044: 		    FIXHFAILURE;
21045: 		}
21046: 		break;
21047: 	    default:
21048: 		break;
21049: 	}
21050:     }
21051:     if (pctxt->nberrors != 0)
21052: 	goto exit_error;
21053: 
21054:     /*
21055:     * Do the complete type fixup for simple types.
21056:     */
21057:     for (i = 0; i < nbItems; i++) {
21058: 	item = items[i];
21059: 	switch (item->type) {
21060:             case XML_SCHEMA_TYPE_SIMPLE:
21061: 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21062: 		    xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
21063: 		    FIXHFAILURE;
21064: 		}
21065: 		break;
21066: 	    default:
21067: 		break;
21068: 	}
21069:     }
21070:     if (pctxt->nberrors != 0)
21071: 	goto exit_error;
21072:     /*
21073:     * At this point we need build and check all simple types.
21074:     */
21075:     /*
21076:     * Apply contraints for attribute declarations.
21077:     */
21078:     for (i = 0; i < nbItems; i++) {
21079: 	item = items[i];
21080: 	switch (item->type) {
21081: 	    case XML_SCHEMA_TYPE_ATTRIBUTE:
21082: 		xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
21083: 		FIXHFAILURE;
21084: 		break;
21085: 	    default:
21086: 		break;
21087: 	}
21088:     }
21089:     if (pctxt->nberrors != 0)
21090: 	goto exit_error;
21091:     /*
21092:     * Apply constraints for attribute uses.
21093:     */
21094:     for (i = 0; i < nbItems; i++) {
21095: 	item = items[i];
21096: 	switch (item->type) {
21097: 	    case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
21098: 		if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
21099: 		    xmlSchemaCheckAttrUsePropsCorrect(pctxt,
21100: 			WXS_ATTR_USE_CAST item);
21101: 		    FIXHFAILURE;
21102: 		}
21103: 		break;
21104: 	    default:
21105: 		break;
21106: 	}
21107:     }
21108:     if (pctxt->nberrors != 0)
21109: 	goto exit_error;
21110: 
21111:     /*
21112:     * Apply constraints for attribute group definitions.
21113:     */
21114:     for (i = 0; i < nbItems; i++) {
21115: 	item = items[i];
21116: 	switch (item->type) {
21117: 	case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
21118: 	    if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
21119: 		( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
21120: 	    {
21121: 		xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
21122: 		FIXHFAILURE;
21123: 	    }
21124: 	    break;
21125: 	default:
21126: 	    break;
21127: 	}
21128:     }
21129:     if (pctxt->nberrors != 0)
21130: 	goto exit_error;
21131: 
21132:     /*
21133:     * Apply constraints for redefinitions.
21134:     */
21135:     if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
21136: 	xmlSchemaCheckSRCRedefineSecond(pctxt);
21137:     if (pctxt->nberrors != 0)
21138: 	goto exit_error;
21139: 
21140:     /*
21141:     * Complex types are builded and checked.
21142:     */
21143:     for (i = 0; i < nbItems; i++) {
21144: 	item = con->pending->items[i];
21145: 	switch (item->type) {
21146: 	    case XML_SCHEMA_TYPE_COMPLEX:
21147: 		if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
21148: 		    xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
21149: 		    FIXHFAILURE;
21150: 		}
21151: 		break;
21152: 	    default:
21153: 		break;
21154: 	}
21155:     }
21156:     if (pctxt->nberrors != 0)
21157: 	goto exit_error;
21158: 
21159:     /*
21160:     * The list could have changed, since xmlSchemaFixupComplexType()
21161:     * will create particles and model groups in some cases.
21162:     */
21163:     items = (xmlSchemaTreeItemPtr *) con->pending->items;
21164:     nbItems = con->pending->nbItems;
21165: 
21166:     /*
21167:     * Apply some constraints for element declarations.
21168:     */
21169:     for (i = 0; i < nbItems; i++) {
21170: 	item = items[i];
21171: 	switch (item->type) {
21172: 	    case XML_SCHEMA_TYPE_ELEMENT:
21173: 		elemDecl = (xmlSchemaElementPtr) item;
21174: 
21175: 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
21176: 		{
21177: 		    xmlSchemaCheckElementDeclComponent(
21178: 			(xmlSchemaElementPtr) elemDecl, pctxt);
21179: 		    FIXHFAILURE;
21180: 		}
21181: 
21182: #ifdef WXS_ELEM_DECL_CONS_ENABLED
21183: 		/*
21184: 		* Schema Component Constraint: Element Declarations Consistent
21185: 		* Apply this constraint to local types of element declarations.
21186: 		*/
21187: 		if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
21188: 		    (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
21189: 		    (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
21190: 		{
21191: 		    xmlSchemaCheckElementDeclConsistent(pctxt,
21192: 			WXS_BASIC_CAST elemDecl,
21193: 			WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
21194: 			NULL, NULL, 0);
21195: 		}
21196: #endif
21197: 		break;
21198: 	    default:
21199: 		break;
21200: 	}
21201:     }
21202:     if (pctxt->nberrors != 0)
21203: 	goto exit_error;
21204: 
21205:     /*
21206:     * Finally we can build the automaton from the content model of
21207:     * complex types.
21208:     */
21209: 
21210:     for (i = 0; i < nbItems; i++) {
21211: 	item = items[i];
21212: 	switch (item->type) {
21213: 	    case XML_SCHEMA_TYPE_COMPLEX:
21214: 		xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
21215: 		/* FIXHFAILURE; */
21216: 		break;
21217: 	    default:
21218: 		break;
21219: 	}
21220:     }
21221:     if (pctxt->nberrors != 0)
21222: 	goto exit_error;
21223:     /*
21224:     * URGENT TODO: cos-element-consistent
21225:     */
21226:     goto exit;
21227: 
21228: exit_error:
21229:     ret = pctxt->err;
21230:     goto exit;
21231: 
21232: exit_failure:
21233:     ret = -1;
21234: 
21235: exit:
21236:     /*
21237:     * Reset the constructor. This is needed for XSI acquisition, since
21238:     * those items will be processed over and over again for every XSI
21239:     * if not cleared here.
21240:     */
21241:     con->bucket = oldbucket;
21242:     con->pending->nbItems = 0;
21243:     if (con->substGroups != NULL) {
21244: 	xmlHashFree(con->substGroups,
21245: 	    (xmlHashDeallocator) xmlSchemaSubstGroupFree);
21246: 	con->substGroups = NULL;
21247:     }
21248:     if (con->redefs != NULL) {
21249: 	xmlSchemaRedefListFree(con->redefs);
21250: 	con->redefs = NULL;
21251:     }
21252:     return(ret);
21253: }
21254: /**
21255:  * xmlSchemaParse:
21256:  * @ctxt:  a schema validation context
21257:  *
21258:  * parse a schema definition resource and build an internal
21259:  * XML Shema struture which can be used to validate instances.
21260:  *
21261:  * Returns the internal XML Schema structure built from the resource or
21262:  *         NULL in case of error
21263:  */
21264: xmlSchemaPtr
21265: xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
21266: {
21267:     xmlSchemaPtr mainSchema = NULL;
21268:     xmlSchemaBucketPtr bucket = NULL;
21269:     int res;
21270: 
21271:     /*
21272:     * This one is used if the schema to be parsed was specified via
21273:     * the API; i.e. not automatically by the validated instance document.
21274:     */
21275: 
21276:     xmlSchemaInitTypes();
21277: 
21278:     if (ctxt == NULL)
21279:         return (NULL);
21280: 
21281:     /* TODO: Init the context. Is this all we need?*/
21282:     ctxt->nberrors = 0;
21283:     ctxt->err = 0;
21284:     ctxt->counter = 0;
21285: 
21286:     /* Create the *main* schema. */
21287:     mainSchema = xmlSchemaNewSchema(ctxt);
21288:     if (mainSchema == NULL)
21289: 	goto exit_failure;
21290:     /*
21291:     * Create the schema constructor.
21292:     */
21293:     if (ctxt->constructor == NULL) {
21294: 	ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
21295: 	if (ctxt->constructor == NULL)
21296: 	    return(NULL);
21297: 	/* Take ownership of the constructor to be able to free it. */
21298: 	ctxt->ownsConstructor = 1;
21299:     }
21300:     ctxt->constructor->mainSchema = mainSchema;
21301:     /*
21302:     * Locate and add the schema document.
21303:     */
21304:     res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
21305: 	ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
21306: 	NULL, NULL, &bucket);
21307:     if (res == -1)
21308: 	goto exit_failure;
21309:     if (res != 0)
21310: 	goto exit;
21311: 
21312:     if (bucket == NULL) {
21313: 	/* TODO: Error code, actually we failed to *locate* the schema. */
21314: 	if (ctxt->URL)
21315: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21316: 		NULL, NULL,
21317: 		"Failed to locate the main schema resource at '%s'",
21318: 		ctxt->URL, NULL);
21319: 	else
21320: 	    xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
21321: 		NULL, NULL,
21322: 		"Failed to locate the main schema resource",
21323: 		    NULL, NULL);
21324: 	goto exit;
21325:     }
21326:     /* Then do the parsing for good. */
21327:     if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
21328: 	goto exit_failure;
21329:     if (ctxt->nberrors != 0)
21330: 	goto exit;
21331: 
21332:     mainSchema->doc = bucket->doc;
21333:     mainSchema->preserve = ctxt->preserve;
21334: 
21335:     ctxt->schema = mainSchema;
21336: 
21337:     if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
21338: 	goto exit_failure;
21339: 
21340:     /*
21341:     * TODO: This is not nice, since we cannot distinguish from the
21342:     * result if there was an internal error or not.
21343:     */
21344: exit:
21345:     if (ctxt->nberrors != 0) {
21346: 	if (mainSchema) {
21347: 	    xmlSchemaFree(mainSchema);
21348: 	    mainSchema = NULL;
21349: 	}
21350: 	if (ctxt->constructor) {
21351: 	    xmlSchemaConstructionCtxtFree(ctxt->constructor);
21352: 	    ctxt->constructor = NULL;
21353: 	    ctxt->ownsConstructor = 0;
21354: 	}
21355:     }
21356:     ctxt->schema = NULL;
21357:     return(mainSchema);
21358: exit_failure:
21359:     /*
21360:     * Quite verbose, but should catch internal errors, which were
21361:     * not communitated.
21362:     */
21363:     if (mainSchema) {
21364:         xmlSchemaFree(mainSchema);
21365: 	mainSchema = NULL;
21366:     }
21367:     if (ctxt->constructor) {
21368: 	xmlSchemaConstructionCtxtFree(ctxt->constructor);
21369: 	ctxt->constructor = NULL;
21370: 	ctxt->ownsConstructor = 0;
21371:     }
21372:     PERROR_INT2("xmlSchemaParse",
21373: 	"An internal error occured");
21374:     ctxt->schema = NULL;
21375:     return(NULL);
21376: }
21377: 
21378: /**
21379:  * xmlSchemaSetParserErrors:
21380:  * @ctxt:  a schema validation context
21381:  * @err:  the error callback
21382:  * @warn:  the warning callback
21383:  * @ctx:  contextual data for the callbacks
21384:  *
21385:  * Set the callback functions used to handle errors for a validation context
21386:  */
21387: void
21388: xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21389:                          xmlSchemaValidityErrorFunc err,
21390:                          xmlSchemaValidityWarningFunc warn, void *ctx)
21391: {
21392:     if (ctxt == NULL)
21393:         return;
21394:     ctxt->error = err;
21395:     ctxt->warning = warn;
21396:     ctxt->errCtxt = ctx;
21397:     if (ctxt->vctxt != NULL)
21398: 	xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
21399: }
21400: 
21401: /**
21402:  * xmlSchemaSetParserStructuredErrors:
21403:  * @ctxt:  a schema parser context
21404:  * @serror:  the structured error function
21405:  * @ctx: the functions context
21406:  *
21407:  * Set the structured error callback
21408:  */
21409: void
21410: xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
21411: 				   xmlStructuredErrorFunc serror,
21412: 				   void *ctx)
21413: {
21414:     if (ctxt == NULL)
21415: 	return;
21416:     ctxt->serror = serror;
21417:     ctxt->errCtxt = ctx;
21418:     if (ctxt->vctxt != NULL)
21419: 	xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
21420: }
21421: 
21422: /**
21423:  * xmlSchemaGetParserErrors:
21424:  * @ctxt:  a XMl-Schema parser context
21425:  * @err: the error callback result
21426:  * @warn: the warning callback result
21427:  * @ctx: contextual data for the callbacks result
21428:  *
21429:  * Get the callback information used to handle errors for a parser context
21430:  *
21431:  * Returns -1 in case of failure, 0 otherwise
21432:  */
21433: int
21434: xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
21435: 			 xmlSchemaValidityErrorFunc * err,
21436: 			 xmlSchemaValidityWarningFunc * warn, void **ctx)
21437: {
21438: 	if (ctxt == NULL)
21439: 		return(-1);
21440: 	if (err != NULL)
21441: 		*err = ctxt->error;
21442: 	if (warn != NULL)
21443: 		*warn = ctxt->warning;
21444: 	if (ctx != NULL)
21445: 		*ctx = ctxt->errCtxt;
21446: 	return(0);
21447: }
21448: 
21449: /**
21450:  * xmlSchemaFacetTypeToString:
21451:  * @type:  the facet type
21452:  *
21453:  * Convert the xmlSchemaTypeType to a char string.
21454:  *
21455:  * Returns the char string representation of the facet type if the
21456:  *     type is a facet and an "Internal Error" string otherwise.
21457:  */
21458: static const xmlChar *
21459: xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
21460: {
21461:     switch (type) {
21462:         case XML_SCHEMA_FACET_PATTERN:
21463:             return (BAD_CAST "pattern");
21464:         case XML_SCHEMA_FACET_MAXEXCLUSIVE:
21465:             return (BAD_CAST "maxExclusive");
21466:         case XML_SCHEMA_FACET_MAXINCLUSIVE:
21467:             return (BAD_CAST "maxInclusive");
21468:         case XML_SCHEMA_FACET_MINEXCLUSIVE:
21469:             return (BAD_CAST "minExclusive");
21470:         case XML_SCHEMA_FACET_MININCLUSIVE:
21471:             return (BAD_CAST "minInclusive");
21472:         case XML_SCHEMA_FACET_WHITESPACE:
21473:             return (BAD_CAST "whiteSpace");
21474:         case XML_SCHEMA_FACET_ENUMERATION:
21475:             return (BAD_CAST "enumeration");
21476:         case XML_SCHEMA_FACET_LENGTH:
21477:             return (BAD_CAST "length");
21478:         case XML_SCHEMA_FACET_MAXLENGTH:
21479:             return (BAD_CAST "maxLength");
21480:         case XML_SCHEMA_FACET_MINLENGTH:
21481:             return (BAD_CAST "minLength");
21482:         case XML_SCHEMA_FACET_TOTALDIGITS:
21483:             return (BAD_CAST "totalDigits");
21484:         case XML_SCHEMA_FACET_FRACTIONDIGITS:
21485:             return (BAD_CAST "fractionDigits");
21486:         default:
21487:             break;
21488:     }
21489:     return (BAD_CAST "Internal Error");
21490: }
21491: 
21492: static xmlSchemaWhitespaceValueType
21493: xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
21494: {
21495:     /*
21496:     * The normalization type can be changed only for types which are derived
21497:     * from xsd:string.
21498:     */
21499:     if (type->type == XML_SCHEMA_TYPE_BASIC) {
21500: 	/*
21501: 	* Note that we assume a whitespace of preserve for anySimpleType.
21502: 	*/
21503: 	if ((type->builtInType == XML_SCHEMAS_STRING) ||
21504: 	    (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
21505: 	    return(XML_SCHEMA_WHITESPACE_PRESERVE);
21506: 	else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
21507: 	    return(XML_SCHEMA_WHITESPACE_REPLACE);
21508: 	else {
21509: 	    /*
21510: 	    * For all �atomic� datatypes other than string (and types �derived�
21511: 	    * by �restriction� from it) the value of whiteSpace is fixed to
21512: 	    * collapse
21513: 	    * Note that this includes built-in list datatypes.
21514: 	    */
21515: 	    return(XML_SCHEMA_WHITESPACE_COLLAPSE);
21516: 	}
21517:     } else if (WXS_IS_LIST(type)) {
21518: 	/*
21519: 	* For list types the facet "whiteSpace" is fixed to "collapse".
21520: 	*/
21521: 	return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21522:     } else if (WXS_IS_UNION(type)) {
21523: 	return (XML_SCHEMA_WHITESPACE_UNKNOWN);
21524:     } else if (WXS_IS_ATOMIC(type)) {
21525: 	if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
21526: 	    return (XML_SCHEMA_WHITESPACE_PRESERVE);
21527: 	else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
21528: 	    return (XML_SCHEMA_WHITESPACE_REPLACE);
21529: 	else
21530: 	    return (XML_SCHEMA_WHITESPACE_COLLAPSE);
21531:     }
21532:     return (-1);
21533: }
21534: 
21535: /************************************************************************
21536:  * 									*
21537:  * 			Simple type validation				*
21538:  * 									*
21539:  ************************************************************************/
21540: 
21541: 
21542: /************************************************************************
21543:  * 									*
21544:  * 			DOM Validation code				*
21545:  * 									*
21546:  ************************************************************************/
21547: 
21548: /**
21549:  * xmlSchemaAssembleByLocation:
21550:  * @pctxt:  a schema parser context
21551:  * @vctxt:  a schema validation context
21552:  * @schema: the existing schema
21553:  * @node: the node that fired the assembling
21554:  * @nsName: the namespace name of the new schema
21555:  * @location: the location of the schema
21556:  *
21557:  * Expands an existing schema by an additional schema.
21558:  *
21559:  * Returns 0 if the new schema is correct, a positive error code
21560:  * number otherwise and -1 in case of an internal or API error.
21561:  */
21562: static int
21563: xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
21564: 			    xmlSchemaPtr schema,
21565: 			    xmlNodePtr node,
21566: 			    const xmlChar *nsName,
21567: 			    const xmlChar *location)
21568: {
21569:     int ret = 0;
21570:     xmlSchemaParserCtxtPtr pctxt;
21571:     xmlSchemaBucketPtr bucket = NULL;
21572: 
21573:     if ((vctxt == NULL) || (schema == NULL))
21574: 	return (-1);
21575: 
21576:     if (vctxt->pctxt == NULL) {
21577: 	VERROR_INT("xmlSchemaAssembleByLocation",
21578: 	    "no parser context available");
21579: 	return(-1);
21580:     }
21581:     pctxt = vctxt->pctxt;
21582:     if (pctxt->constructor == NULL) {
21583: 	PERROR_INT("xmlSchemaAssembleByLocation",
21584: 	    "no constructor");
21585: 	return(-1);
21586:     }
21587:     /*
21588:     * Acquire the schema document.
21589:     */
21590:     location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
21591: 	location, node);
21592:     /*
21593:     * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
21594:     * the process will automatically change this to
21595:     * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
21596:     */
21597:     ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
21598: 	location, NULL, NULL, 0, node, NULL, nsName,
21599: 	&bucket);
21600:     if (ret != 0)
21601: 	return(ret);
21602:     if (bucket == NULL) {
21603: 	/*
21604: 	* Generate a warning that the document could not be located.
21605: 	*/
21606: 	xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21607: 	    node, NULL,
21608: 	    "The document at location '%s' could not be acquired",
21609: 	    location, NULL, NULL);
21610: 	return(ret);
21611:     }
21612:     /*
21613:     * The first located schema will be handled as if all other
21614:     * schemas imported by XSI were imported by this first schema.
21615:     */
21616:     if ((bucket != NULL) &&
21617: 	(WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
21618: 	WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
21619:     /*
21620:     * TODO: Is this handled like an import? I.e. is it not an error
21621:     * if the schema cannot be located?
21622:     */
21623:     if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
21624: 	return(0);
21625:     /*
21626:     * We will reuse the parser context for every schema imported
21627:     * directly via XSI. So reset the context.
21628:     */
21629:     pctxt->nberrors = 0;
21630:     pctxt->err = 0;
21631:     pctxt->doc = bucket->doc;
21632: 
21633:     ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
21634:     if (ret == -1) {
21635: 	pctxt->doc = NULL;
21636: 	goto exit_failure;
21637:     }
21638:     /* Paranoid error channelling. */
21639:     if ((ret == 0) && (pctxt->nberrors != 0))
21640: 	ret = pctxt->err;
21641:     if (pctxt->nberrors == 0) {
21642: 	/*
21643: 	* Only bother to fixup pending components, if there was
21644: 	* no error yet.
21645: 	* For every XSI acquired schema (and its sub-schemata) we will
21646: 	* fixup the components.
21647: 	*/
21648: 	xmlSchemaFixupComponents(pctxt, bucket);
21649: 	ret = pctxt->err;
21650: 	/*
21651: 	* Not nice, but we need somehow to channel the schema parser
21652: 	* error to the validation context.
21653: 	*/
21654: 	if ((ret != 0) && (vctxt->err == 0))
21655: 	    vctxt->err = ret;
21656: 	vctxt->nberrors += pctxt->nberrors;
21657:     } else {
21658: 	/* Add to validation error sum. */
21659: 	vctxt->nberrors += pctxt->nberrors;
21660:     }
21661:     pctxt->doc = NULL;
21662:     return(ret);
21663: exit_failure:
21664:     pctxt->doc = NULL;
21665:     return (-1);
21666: }
21667: 
21668: static xmlSchemaAttrInfoPtr
21669: xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
21670: 			 int metaType)
21671: {
21672:     if (vctxt->nbAttrInfos == 0)
21673: 	return (NULL);
21674:     {
21675: 	int i;
21676: 	xmlSchemaAttrInfoPtr iattr;
21677: 
21678: 	for (i = 0; i < vctxt->nbAttrInfos; i++) {
21679: 	    iattr = vctxt->attrInfos[i];
21680: 	    if (iattr->metaType == metaType)
21681: 		return (iattr);
21682: 	}
21683: 
21684:     }
21685:     return (NULL);
21686: }
21687: 
21688: /**
21689:  * xmlSchemaAssembleByXSI:
21690:  * @vctxt:  a schema validation context
21691:  *
21692:  * Expands an existing schema by an additional schema using
21693:  * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
21694:  * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
21695:  * must be set to 1.
21696:  *
21697:  * Returns 0 if the new schema is correct, a positive error code
21698:  * number otherwise and -1 in case of an internal or API error.
21699:  */
21700: static int
21701: xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
21702: {
21703:     const xmlChar *cur, *end;
21704:     const xmlChar *nsname = NULL, *location;
21705:     int count = 0;
21706:     int ret = 0;
21707:     xmlSchemaAttrInfoPtr iattr;
21708: 
21709:     /*
21710:     * Parse the value; we will assume an even number of values
21711:     * to be given (this is how Xerces and XSV work).
21712:     *
21713:     * URGENT TODO: !! This needs to work for both
21714:     * @noNamespaceSchemaLocation AND @schemaLocation on the same
21715:     * element !!
21716:     */
21717:     iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21718: 	XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
21719:     if (iattr == NULL)
21720: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
21721: 	XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
21722:     if (iattr == NULL)
21723: 	return (0);
21724:     cur = iattr->value;
21725:     do {
21726: 	/*
21727: 	* TODO: Move the string parsing mechanism away from here.
21728: 	*/
21729: 	if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
21730: 	    /*
21731: 	    * Get the namespace name.
21732: 	    */
21733: 	    while (IS_BLANK_CH(*cur))
21734: 		cur++;
21735: 	    end = cur;
21736: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21737: 		end++;
21738: 	    if (end == cur)
21739: 		break;
21740: 	    count++; /* TODO: Don't use the schema's dict. */
21741: 	    nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21742: 	    cur = end;
21743: 	}
21744: 	/*
21745: 	* Get the URI.
21746: 	*/
21747: 	while (IS_BLANK_CH(*cur))
21748: 	    cur++;
21749: 	end = cur;
21750: 	while ((*end != 0) && (!(IS_BLANK_CH(*end))))
21751: 	    end++;
21752: 	if (end == cur) {
21753: 	    if (iattr->metaType ==
21754: 		XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
21755: 	    {
21756: 		/*
21757: 		* If using @schemaLocation then tuples are expected.
21758: 		* I.e. the namespace name *and* the document's URI.
21759: 		*/
21760: 		xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
21761: 		    iattr->node, NULL,
21762: 		    "The value must consist of tuples: the target namespace "
21763: 		    "name and the document's URI", NULL, NULL, NULL);
21764: 	    }
21765: 	    break;
21766: 	}
21767: 	count++; /* TODO: Don't use the schema's dict. */
21768: 	location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
21769: 	cur = end;
21770: 	ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
21771: 	    iattr->node, nsname, location);
21772: 	if (ret == -1) {
21773: 	    VERROR_INT("xmlSchemaAssembleByXSI",
21774: 		"assembling schemata");
21775: 	    return (-1);
21776: 	}
21777:     } while (*cur != 0);
21778:     return (ret);
21779: }
21780: 
21781: static const xmlChar *
21782: xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
21783: 			 const xmlChar *prefix)
21784: {
21785:     if (vctxt->sax != NULL) {
21786: 	int i, j;
21787: 	xmlSchemaNodeInfoPtr inode;
21788: 
21789: 	for (i = vctxt->depth; i >= 0; i--) {
21790: 	    if (vctxt->elemInfos[i]->nbNsBindings != 0) {
21791: 		inode = vctxt->elemInfos[i];
21792: 		for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
21793: 		    if (((prefix == NULL) &&
21794: 			    (inode->nsBindings[j] == NULL)) ||
21795: 			((prefix != NULL) && xmlStrEqual(prefix,
21796: 			    inode->nsBindings[j]))) {
21797: 
21798: 			/*
21799: 			* Note that the namespace bindings are already
21800: 			* in a string dict.
21801: 			*/
21802: 			return (inode->nsBindings[j+1]);
21803: 		    }
21804: 		}
21805: 	    }
21806: 	}
21807: 	return (NULL);
21808: #ifdef LIBXML_READER_ENABLED
21809:     } else if (vctxt->reader != NULL) {
21810: 	xmlChar *nsName;
21811: 
21812: 	nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
21813: 	if (nsName != NULL) {
21814: 	    const xmlChar *ret;
21815: 
21816: 	    ret = xmlDictLookup(vctxt->dict, nsName, -1);
21817: 	    xmlFree(nsName);
21818: 	    return (ret);
21819: 	} else
21820: 	    return (NULL);
21821: #endif
21822:     } else {
21823: 	xmlNsPtr ns;
21824: 
21825: 	if ((vctxt->inode->node == NULL) ||
21826: 	    (vctxt->inode->node->doc == NULL)) {
21827: 	    VERROR_INT("xmlSchemaLookupNamespace",
21828: 		"no node or node's doc avaliable");
21829: 	    return (NULL);
21830: 	}
21831: 	ns = xmlSearchNs(vctxt->inode->node->doc,
21832: 	    vctxt->inode->node, prefix);
21833: 	if (ns != NULL)
21834: 	    return (ns->href);
21835: 	return (NULL);
21836:     }
21837: }
21838: 
21839: /*
21840: * This one works on the schema of the validation context.
21841: */
21842: static int
21843: xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
21844: 			  xmlSchemaPtr schema,
21845: 			  xmlNodePtr node,
21846: 			  const xmlChar *value,
21847: 			  xmlSchemaValPtr *val,
21848: 			  int valNeeded)
21849: {
21850:     int ret;
21851: 
21852:     if (vctxt && (vctxt->schema == NULL)) {
21853: 	VERROR_INT("xmlSchemaValidateNotation",
21854: 	    "a schema is needed on the validation context");
21855: 	return (-1);
21856:     }
21857:     ret = xmlValidateQName(value, 1);
21858:     if (ret != 0)
21859: 	return (ret);
21860:     {
21861: 	xmlChar *localName = NULL;
21862: 	xmlChar *prefix = NULL;
21863: 
21864: 	localName = xmlSplitQName2(value, &prefix);
21865: 	if (prefix != NULL) {
21866: 	    const xmlChar *nsName = NULL;
21867: 
21868: 	    if (vctxt != NULL)
21869: 		nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
21870: 	    else if (node != NULL) {
21871: 		xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
21872: 		if (ns != NULL)
21873: 		    nsName = ns->href;
21874: 	    } else {
21875: 		xmlFree(prefix);
21876: 		xmlFree(localName);
21877: 		return (1);
21878: 	    }
21879: 	    if (nsName == NULL) {
21880: 		xmlFree(prefix);
21881: 		xmlFree(localName);
21882: 		return (1);
21883: 	    }
21884: 	    if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
21885: 		if ((valNeeded) && (val != NULL)) {
21886: 		    (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
21887: 						       xmlStrdup(nsName));
21888: 		    if (*val == NULL)
21889: 			ret = -1;
21890: 		}
21891: 	    } else
21892: 		ret = 1;
21893: 	    xmlFree(prefix);
21894: 	    xmlFree(localName);
21895: 	} else {
21896: 	    if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
21897: 		if (valNeeded && (val != NULL)) {
21898: 		    (*val) = xmlSchemaNewNOTATIONValue(
21899: 			BAD_CAST xmlStrdup(value), NULL);
21900: 		    if (*val == NULL)
21901: 			ret = -1;
21902: 		}
21903: 	    } else
21904: 		return (1);
21905: 	}
21906:     }
21907:     return (ret);
21908: }
21909: 
21910: static int
21911: xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
21912: 		       const xmlChar* lname,
21913: 		       const xmlChar* nsname)
21914: {
21915:     int i;
21916: 
21917:     lname = xmlDictLookup(vctxt->dict, lname, -1);
21918:     if (lname == NULL)
21919: 	return(-1);
21920:     if (nsname != NULL) {
21921: 	nsname = xmlDictLookup(vctxt->dict, nsname, -1);
21922: 	if (nsname == NULL)
21923: 	    return(-1);
21924:     }
21925:     for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
21926: 	if ((vctxt->nodeQNames->items [i] == lname) &&
21927: 	    (vctxt->nodeQNames->items[i +1] == nsname))
21928: 	    /* Already there */
21929: 	    return(i);
21930:     }
21931:     /* Add new entry. */
21932:     i = vctxt->nodeQNames->nbItems;
21933:     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
21934:     xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
21935:     return(i);
21936: }
21937: 
21938: /************************************************************************
21939:  * 									*
21940:  *  Validation of identity-constraints (IDC)                            *
21941:  * 									*
21942:  ************************************************************************/
21943: 
21944: /**
21945:  * xmlSchemaAugmentIDC:
21946:  * @idcDef: the IDC definition
21947:  *
21948:  * Creates an augmented IDC definition item.
21949:  *
21950:  * Returns the item, or NULL on internal errors.
21951:  */
21952: static void
21953: xmlSchemaAugmentIDC(xmlSchemaIDCPtr idcDef,
21954: 		    xmlSchemaValidCtxtPtr vctxt)
21955: {
21956:     xmlSchemaIDCAugPtr aidc;
21957: 
21958:     aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
21959:     if (aidc == NULL) {
21960: 	xmlSchemaVErrMemory(vctxt,
21961: 	    "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
21962: 	    NULL);
21963: 	return;
21964:     }
21965:     aidc->keyrefDepth = -1;
21966:     aidc->def = idcDef;
21967:     aidc->next = NULL;
21968:     if (vctxt->aidcs == NULL)
21969: 	vctxt->aidcs = aidc;
21970:     else {
21971: 	aidc->next = vctxt->aidcs;
21972: 	vctxt->aidcs = aidc;
21973:     }
21974:     /*
21975:     * Save if we have keyrefs at all.
21976:     */
21977:     if ((vctxt->hasKeyrefs == 0) &&
21978: 	(idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
21979: 	vctxt->hasKeyrefs = 1;
21980: }
21981: 
21982: /**
21983:  * xmlSchemaAugmentImportedIDC:
21984:  * @imported: the imported schema
21985:  *
21986:  * Creates an augmented IDC definition for the imported schema.
21987:  */
21988: static void
21989: xmlSchemaAugmentImportedIDC(xmlSchemaImportPtr imported, xmlSchemaValidCtxtPtr vctxt) {
21990:     if (imported->schema->idcDef != NULL) {
21991: 	    xmlHashScan(imported->schema->idcDef ,
21992: 	    (xmlHashScanner) xmlSchemaAugmentIDC, vctxt);
21993:     }
21994: }
21995: 
21996: /**
21997:  * xmlSchemaIDCNewBinding:
21998:  * @idcDef: the IDC definition of this binding
21999:  *
22000:  * Creates a new IDC binding.
22001:  *
22002:  * Returns the new IDC binding, NULL on internal errors.
22003:  */
22004: static xmlSchemaPSVIIDCBindingPtr
22005: xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
22006: {
22007:     xmlSchemaPSVIIDCBindingPtr ret;
22008: 
22009:     ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
22010: 	    sizeof(xmlSchemaPSVIIDCBinding));
22011:     if (ret == NULL) {
22012: 	xmlSchemaVErrMemory(NULL,
22013: 	    "allocating a PSVI IDC binding item", NULL);
22014: 	return (NULL);
22015:     }
22016:     memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
22017:     ret->definition = idcDef;
22018:     return (ret);
22019: }
22020: 
22021: /**
22022:  * xmlSchemaIDCStoreNodeTableItem:
22023:  * @vctxt: the WXS validation context
22024:  * @item: the IDC node table item
22025:  *
22026:  * The validation context is used to store IDC node table items.
22027:  * They are stored to avoid copying them if IDC node-tables are merged
22028:  * with corresponding parent IDC node-tables (bubbling).
22029:  *
22030:  * Returns 0 if succeeded, -1 on internal errors.
22031:  */
22032: static int
22033: xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
22034: 			       xmlSchemaPSVIIDCNodePtr item)
22035: {
22036:     /*
22037:     * Add to gobal list.
22038:     */
22039:     if (vctxt->idcNodes == NULL) {
22040: 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22041: 	    xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
22042: 	if (vctxt->idcNodes == NULL) {
22043: 	    xmlSchemaVErrMemory(vctxt,
22044: 		"allocating the IDC node table item list", NULL);
22045: 	    return (-1);
22046: 	}
22047: 	vctxt->sizeIdcNodes = 20;
22048:     } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
22049: 	vctxt->sizeIdcNodes *= 2;
22050: 	vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
22051: 	    xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
22052: 	    sizeof(xmlSchemaPSVIIDCNodePtr));
22053: 	if (vctxt->idcNodes == NULL) {
22054: 	    xmlSchemaVErrMemory(vctxt,
22055: 		"re-allocating the IDC node table item list", NULL);
22056: 	    return (-1);
22057: 	}
22058:     }
22059:     vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
22060: 
22061:     return (0);
22062: }
22063: 
22064: /**
22065:  * xmlSchemaIDCStoreKey:
22066:  * @vctxt: the WXS validation context
22067:  * @item: the IDC key
22068:  *
22069:  * The validation context is used to store an IDC key.
22070:  *
22071:  * Returns 0 if succeeded, -1 on internal errors.
22072:  */
22073: static int
22074: xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
22075: 		     xmlSchemaPSVIIDCKeyPtr key)
22076: {
22077:     /*
22078:     * Add to gobal list.
22079:     */
22080:     if (vctxt->idcKeys == NULL) {
22081: 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22082: 	    xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
22083: 	if (vctxt->idcKeys == NULL) {
22084: 	    xmlSchemaVErrMemory(vctxt,
22085: 		"allocating the IDC key storage list", NULL);
22086: 	    return (-1);
22087: 	}
22088: 	vctxt->sizeIdcKeys = 40;
22089:     } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
22090: 	vctxt->sizeIdcKeys *= 2;
22091: 	vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
22092: 	    xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
22093: 	    sizeof(xmlSchemaPSVIIDCKeyPtr));
22094: 	if (vctxt->idcKeys == NULL) {
22095: 	    xmlSchemaVErrMemory(vctxt,
22096: 		"re-allocating the IDC key storage list", NULL);
22097: 	    return (-1);
22098: 	}
22099:     }
22100:     vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
22101: 
22102:     return (0);
22103: }
22104: 
22105: /**
22106:  * xmlSchemaIDCAppendNodeTableItem:
22107:  * @bind: the IDC binding
22108:  * @ntItem: the node-table item
22109:  *
22110:  * Appends the IDC node-table item to the binding.
22111:  *
22112:  * Returns 0 on success and -1 on internal errors.
22113:  */
22114: static int
22115: xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
22116: 				xmlSchemaPSVIIDCNodePtr ntItem)
22117: {
22118:     if (bind->nodeTable == NULL) {
22119: 	bind->sizeNodes = 10;
22120: 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22121: 	    xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
22122: 	if (bind->nodeTable == NULL) {
22123: 	    xmlSchemaVErrMemory(NULL,
22124: 		"allocating an array of IDC node-table items", NULL);
22125: 	    return(-1);
22126: 	}
22127:     } else if (bind->sizeNodes <= bind->nbNodes) {
22128: 	bind->sizeNodes *= 2;
22129: 	bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
22130: 	    xmlRealloc(bind->nodeTable, bind->sizeNodes *
22131: 		sizeof(xmlSchemaPSVIIDCNodePtr));
22132: 	if (bind->nodeTable == NULL) {
22133: 	    xmlSchemaVErrMemory(NULL,
22134: 		"re-allocating an array of IDC node-table items", NULL);
22135: 	    return(-1);
22136: 	}
22137:     }
22138:     bind->nodeTable[bind->nbNodes++] = ntItem;
22139:     return(0);
22140: }
22141: 
22142: /**
22143:  * xmlSchemaIDCAcquireBinding:
22144:  * @vctxt: the WXS validation context
22145:  * @matcher: the IDC matcher
22146:  *
22147:  * Looks up an PSVI IDC binding, for the IDC definition and
22148:  * of the given matcher. If none found, a new one is created
22149:  * and added to the IDC table.
22150:  *
22151:  * Returns an IDC binding or NULL on internal errors.
22152:  */
22153: static xmlSchemaPSVIIDCBindingPtr
22154: xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
22155: 			  xmlSchemaIDCMatcherPtr matcher)
22156: {
22157:     xmlSchemaNodeInfoPtr ielem;
22158: 
22159:     ielem = vctxt->elemInfos[matcher->depth];
22160: 
22161:     if (ielem->idcTable == NULL) {
22162: 	ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
22163: 	if (ielem->idcTable == NULL)
22164: 	    return (NULL);
22165: 	return(ielem->idcTable);
22166:     } else {
22167: 	xmlSchemaPSVIIDCBindingPtr bind = NULL;
22168: 
22169: 	bind = ielem->idcTable;
22170: 	do {
22171: 	    if (bind->definition == matcher->aidc->def)
22172: 		return(bind);
22173: 	    if (bind->next == NULL) {
22174: 		bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
22175: 		if (bind->next == NULL)
22176: 		    return (NULL);
22177: 		return(bind->next);
22178: 	    }
22179: 	    bind = bind->next;
22180: 	} while (bind != NULL);
22181:     }
22182:     return (NULL);
22183: }
22184: 
22185: static xmlSchemaItemListPtr
22186: xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
22187: 			     xmlSchemaIDCMatcherPtr matcher)
22188: {
22189:     if (matcher->targets == NULL)
22190: 	matcher->targets = xmlSchemaItemListCreate();
22191:     return(matcher->targets);
22192: }
22193: 
22194: /**
22195:  * xmlSchemaIDCFreeKey:
22196:  * @key: the IDC key
22197:  *
22198:  * Frees an IDC key together with its compiled value.
22199:  */
22200: static void
22201: xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
22202: {
22203:     if (key->val != NULL)
22204: 	xmlSchemaFreeValue(key->val);
22205:     xmlFree(key);
22206: }
22207: 
22208: /**
22209:  * xmlSchemaIDCFreeBinding:
22210:  *
22211:  * Frees an IDC binding. Note that the node table-items
22212:  * are not freed.
22213:  */
22214: static void
22215: xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
22216: {
22217:     if (bind->nodeTable != NULL)
22218: 	xmlFree(bind->nodeTable);
22219:     if (bind->dupls != NULL)
22220: 	xmlSchemaItemListFree(bind->dupls);
22221:     xmlFree(bind);
22222: }
22223: 
22224: /**
22225:  * xmlSchemaIDCFreeIDCTable:
22226:  * @bind: the first IDC binding in the list
22227:  *
22228:  * Frees an IDC table, i.e. all the IDC bindings in the list.
22229:  */
22230: static void
22231: xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
22232: {
22233:     xmlSchemaPSVIIDCBindingPtr prev;
22234: 
22235:     while (bind != NULL) {
22236: 	prev = bind;
22237: 	bind = bind->next;
22238: 	xmlSchemaIDCFreeBinding(prev);
22239:     }
22240: }
22241: 
22242: /**
22243:  * xmlSchemaIDCFreeMatcherList:
22244:  * @matcher: the first IDC matcher in the list
22245:  *
22246:  * Frees a list of IDC matchers.
22247:  */
22248: static void
22249: xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
22250: {
22251:     xmlSchemaIDCMatcherPtr next;
22252: 
22253:     while (matcher != NULL) {
22254: 	next = matcher->next;
22255: 	if (matcher->keySeqs != NULL) {
22256: 	    int i;
22257: 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
22258: 		if (matcher->keySeqs[i] != NULL)
22259: 		    xmlFree(matcher->keySeqs[i]);
22260: 	    xmlFree(matcher->keySeqs);
22261: 	}
22262: 	if (matcher->targets != NULL) {
22263: 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22264: 		int i;
22265: 		xmlSchemaPSVIIDCNodePtr idcNode;
22266: 		/*
22267: 		* Node-table items for keyrefs are not stored globally
22268: 		* to the validation context, since they are not bubbled.
22269: 		* We need to free them here.
22270: 		*/
22271: 		for (i = 0; i < matcher->targets->nbItems; i++) {
22272: 		    idcNode =
22273: 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22274: 		    xmlFree(idcNode->keys);
22275: 		    xmlFree(idcNode);
22276: 		}
22277: 	    }
22278: 	    xmlSchemaItemListFree(matcher->targets);
22279: 	}
22280: 	xmlFree(matcher);
22281: 	matcher = next;
22282:     }
22283: }
22284: 
22285: /**
22286:  * xmlSchemaIDCReleaseMatcherList:
22287:  * @vctxt: the WXS validation context
22288:  * @matcher: the first IDC matcher in the list
22289:  *
22290:  * Caches a list of IDC matchers for reuse.
22291:  */
22292: static void
22293: xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
22294: 			       xmlSchemaIDCMatcherPtr matcher)
22295: {
22296:     xmlSchemaIDCMatcherPtr next;
22297: 
22298:     while (matcher != NULL) {
22299: 	next = matcher->next;
22300: 	if (matcher->keySeqs != NULL) {
22301: 	    int i;
22302: 	    /*
22303: 	    * Don't free the array, but only the content.
22304: 	    */
22305: 	    for (i = 0; i < matcher->sizeKeySeqs; i++)
22306: 		if (matcher->keySeqs[i] != NULL) {
22307: 		    xmlFree(matcher->keySeqs[i]);
22308: 		    matcher->keySeqs[i] = NULL;
22309: 		}
22310: 	}
22311: 	if (matcher->targets) {
22312: 	    if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
22313: 		int i;
22314: 		xmlSchemaPSVIIDCNodePtr idcNode;
22315: 		/*
22316: 		* Node-table items for keyrefs are not stored globally
22317: 		* to the validation context, since they are not bubbled.
22318: 		* We need to free them here.
22319: 		*/
22320: 		for (i = 0; i < matcher->targets->nbItems; i++) {
22321: 		    idcNode =
22322: 			(xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
22323: 		    xmlFree(idcNode->keys);
22324: 		    xmlFree(idcNode);
22325: 		}
22326: 	    }
22327: 	    xmlSchemaItemListFree(matcher->targets);
22328: 	    matcher->targets = NULL;
22329: 	}
22330: 	matcher->next = NULL;
22331: 	/*
22332: 	* Cache the matcher.
22333: 	*/
22334: 	if (vctxt->idcMatcherCache != NULL)
22335: 	    matcher->nextCached = vctxt->idcMatcherCache;
22336: 	vctxt->idcMatcherCache = matcher;
22337: 
22338: 	matcher = next;
22339:     }
22340: }
22341: 
22342: /**
22343:  * xmlSchemaIDCAddStateObject:
22344:  * @vctxt: the WXS validation context
22345:  * @matcher: the IDC matcher
22346:  * @sel: the XPath information
22347:  * @parent: the parent "selector" state object if any
22348:  * @type: "selector" or "field"
22349:  *
22350:  * Creates/reuses and activates state objects for the given
22351:  * XPath information; if the XPath expression consists of unions,
22352:  * multiple state objects are created for every unioned expression.
22353:  *
22354:  * Returns 0 on success and -1 on internal errors.
22355:  */
22356: static int
22357: xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
22358: 			xmlSchemaIDCMatcherPtr matcher,
22359: 			xmlSchemaIDCSelectPtr sel,
22360: 			int type)
22361: {
22362:     xmlSchemaIDCStateObjPtr sto;
22363: 
22364:     /*
22365:     * Reuse the state objects from the pool.
22366:     */
22367:     if (vctxt->xpathStatePool != NULL) {
22368: 	sto = vctxt->xpathStatePool;
22369: 	vctxt->xpathStatePool = sto->next;
22370: 	sto->next = NULL;
22371:     } else {
22372: 	/*
22373: 	* Create a new state object.
22374: 	*/
22375: 	sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
22376: 	if (sto == NULL) {
22377: 	    xmlSchemaVErrMemory(NULL,
22378: 		"allocating an IDC state object", NULL);
22379: 	    return (-1);
22380: 	}
22381: 	memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
22382:     }
22383:     /*
22384:     * Add to global list.
22385:     */
22386:     if (vctxt->xpathStates != NULL)
22387: 	sto->next = vctxt->xpathStates;
22388:     vctxt->xpathStates = sto;
22389: 
22390:     /*
22391:     * Free the old xpath validation context.
22392:     */
22393:     if (sto->xpathCtxt != NULL)
22394: 	xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
22395: 
22396:     /*
22397:     * Create a new XPath (pattern) validation context.
22398:     */
22399:     sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
22400: 	(xmlPatternPtr) sel->xpathComp);
22401:     if (sto->xpathCtxt == NULL) {
22402: 	VERROR_INT("xmlSchemaIDCAddStateObject",
22403: 	    "failed to create an XPath validation context");
22404: 	return (-1);
22405:     }
22406:     sto->type = type;
22407:     sto->depth = vctxt->depth;
22408:     sto->matcher = matcher;
22409:     sto->sel = sel;
22410:     sto->nbHistory = 0;
22411: 
22412: #ifdef DEBUG_IDC
22413:     xmlGenericError(xmlGenericErrorContext, "IDC:   STO push '%s'\n",
22414: 	sto->sel->xpath);
22415: #endif
22416:     return (0);
22417: }
22418: 
22419: /**
22420:  * xmlSchemaXPathEvaluate:
22421:  * @vctxt: the WXS validation context
22422:  * @nodeType: the nodeType of the current node
22423:  *
22424:  * Evaluates all active XPath state objects.
22425:  *
22426:  * Returns the number of IC "field" state objects which resolved to
22427:  * this node, 0 if none resolved and -1 on internal errors.
22428:  */
22429: static int
22430: xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
22431: 		       xmlElementType nodeType)
22432: {
22433:     xmlSchemaIDCStateObjPtr sto, head = NULL, first;
22434:     int res, resolved = 0, depth = vctxt->depth;
22435: 
22436:     if (vctxt->xpathStates == NULL)
22437: 	return (0);
22438: 
22439:     if (nodeType == XML_ATTRIBUTE_NODE)
22440: 	depth++;
22441: #ifdef DEBUG_IDC
22442:     {
22443: 	xmlChar *str = NULL;
22444: 	xmlGenericError(xmlGenericErrorContext,
22445: 	    "IDC: EVAL on %s, depth %d, type %d\n",
22446: 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22447: 		vctxt->inode->localName), depth, nodeType);
22448: 	FREE_AND_NULL(str)
22449:     }
22450: #endif
22451:     /*
22452:     * Process all active XPath state objects.
22453:     */
22454:     first = vctxt->xpathStates;
22455:     sto = first;
22456:     while (sto != head) {
22457: #ifdef DEBUG_IDC
22458: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
22459: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] selector '%s'\n",
22460: 		sto->matcher->aidc->def->name, sto->sel->xpath);
22461: 	else
22462: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   ['%s'] field '%s'\n",
22463: 		sto->matcher->aidc->def->name, sto->sel->xpath);
22464: #endif
22465: 	if (nodeType == XML_ELEMENT_NODE)
22466: 	    res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
22467: 		vctxt->inode->localName, vctxt->inode->nsName);
22468: 	else
22469: 	    res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
22470: 		vctxt->inode->localName, vctxt->inode->nsName);
22471: 
22472: 	if (res == -1) {
22473: 	    VERROR_INT("xmlSchemaXPathEvaluate",
22474: 		"calling xmlStreamPush()");
22475: 	    return (-1);
22476: 	}
22477: 	if (res == 0)
22478: 	    goto next_sto;
22479: 	/*
22480: 	* Full match.
22481: 	*/
22482: #ifdef DEBUG_IDC
22483: 	xmlGenericError(xmlGenericErrorContext, "IDC:     "
22484: 	    "MATCH\n");
22485: #endif
22486: 	/*
22487: 	* Register a match in the state object history.
22488: 	*/
22489: 	if (sto->history == NULL) {
22490: 	    sto->history = (int *) xmlMalloc(5 * sizeof(int));
22491: 	    if (sto->history == NULL) {
22492: 		xmlSchemaVErrMemory(NULL,
22493: 		    "allocating the state object history", NULL);
22494: 		return(-1);
22495: 	    }
22496: 	    sto->sizeHistory = 5;
22497: 	} else if (sto->sizeHistory <= sto->nbHistory) {
22498: 	    sto->sizeHistory *= 2;
22499: 	    sto->history = (int *) xmlRealloc(sto->history,
22500: 		sto->sizeHistory * sizeof(int));
22501: 	    if (sto->history == NULL) {
22502: 		xmlSchemaVErrMemory(NULL,
22503: 		    "re-allocating the state object history", NULL);
22504: 		return(-1);
22505: 	    }
22506: 	}
22507: 	sto->history[sto->nbHistory++] = depth;
22508: 
22509: #ifdef DEBUG_IDC
22510: 	xmlGenericError(xmlGenericErrorContext, "IDC:       push match '%d'\n",
22511: 	    vctxt->depth);
22512: #endif
22513: 
22514: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22515: 	    xmlSchemaIDCSelectPtr sel;
22516: 	    /*
22517: 	    * Activate state objects for the IDC fields of
22518: 	    * the IDC selector.
22519: 	    */
22520: #ifdef DEBUG_IDC
22521: 	    xmlGenericError(xmlGenericErrorContext, "IDC:     "
22522: 		"activating field states\n");
22523: #endif
22524: 	    sel = sto->matcher->aidc->def->fields;
22525: 	    while (sel != NULL) {
22526: 		if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
22527: 		    sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
22528: 		    return (-1);
22529: 		sel = sel->next;
22530: 	    }
22531: 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22532: 	    /*
22533: 	    * An IDC key node was found by the IDC field.
22534: 	    */
22535: #ifdef DEBUG_IDC
22536: 	    xmlGenericError(xmlGenericErrorContext,
22537: 		"IDC:     key found\n");
22538: #endif
22539: 	    /*
22540: 	    * Notify that the character value of this node is
22541: 	    * needed.
22542: 	    */
22543: 	    if (resolved == 0) {
22544: 		if ((vctxt->inode->flags &
22545: 		    XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
22546: 		vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
22547: 	    }
22548: 	    resolved++;
22549: 	}
22550: next_sto:
22551: 	if (sto->next == NULL) {
22552: 	    /*
22553: 	    * Evaluate field state objects created on this node as well.
22554: 	    */
22555: 	    head = first;
22556: 	    sto = vctxt->xpathStates;
22557: 	} else
22558: 	    sto = sto->next;
22559:     }
22560:     return (resolved);
22561: }
22562: 
22563: static const xmlChar *
22564: xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
22565: 			      xmlChar **buf,
22566: 			      xmlSchemaPSVIIDCKeyPtr *seq,
22567: 			      int count)
22568: {
22569:     int i, res;
22570:     xmlChar *value = NULL;
22571: 
22572:     *buf = xmlStrdup(BAD_CAST "[");
22573:     for (i = 0; i < count; i++) {
22574: 	*buf = xmlStrcat(*buf, BAD_CAST "'");
22575: 	res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
22576: 	    xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
22577: 	    &value);
22578: 	if (res == 0)
22579: 	    *buf = xmlStrcat(*buf, BAD_CAST value);
22580: 	else {
22581: 	    VERROR_INT("xmlSchemaFormatIDCKeySequence",
22582: 		"failed to compute a canonical value");
22583: 	    *buf = xmlStrcat(*buf, BAD_CAST "???");
22584: 	}
22585: 	if (i < count -1)
22586: 	    *buf = xmlStrcat(*buf, BAD_CAST "', ");
22587: 	else
22588: 	    *buf = xmlStrcat(*buf, BAD_CAST "'");
22589: 	if (value != NULL) {
22590: 	    xmlFree(value);
22591: 	    value = NULL;
22592: 	}
22593:     }
22594:     *buf = xmlStrcat(*buf, BAD_CAST "]");
22595: 
22596:     return (BAD_CAST *buf);
22597: }
22598: 
22599: /**
22600:  * xmlSchemaXPathPop:
22601:  * @vctxt: the WXS validation context
22602:  *
22603:  * Pops all XPath states.
22604:  *
22605:  * Returns 0 on success and -1 on internal errors.
22606:  */
22607: static int
22608: xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
22609: {
22610:     xmlSchemaIDCStateObjPtr sto;
22611:     int res;
22612: 
22613:     if (vctxt->xpathStates == NULL)
22614: 	return(0);
22615:     sto = vctxt->xpathStates;
22616:     do {
22617: 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22618: 	if (res == -1)
22619: 	    return (-1);
22620: 	sto = sto->next;
22621:     } while (sto != NULL);
22622:     return(0);
22623: }
22624: 
22625: /**
22626:  * xmlSchemaXPathProcessHistory:
22627:  * @vctxt: the WXS validation context
22628:  * @type: the simple/complex type of the current node if any at all
22629:  * @val: the precompiled value
22630:  *
22631:  * Processes and pops the history items of the IDC state objects.
22632:  * IDC key-sequences are validated/created on IDC bindings.
22633:  *
22634:  * Returns 0 on success and -1 on internal errors.
22635:  */
22636: static int
22637: xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
22638: 			     int depth)
22639: {
22640:     xmlSchemaIDCStateObjPtr sto, nextsto;
22641:     int res, matchDepth;
22642:     xmlSchemaPSVIIDCKeyPtr key = NULL;
22643:     xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
22644: 
22645:     if (vctxt->xpathStates == NULL)
22646: 	return (0);
22647:     sto = vctxt->xpathStates;
22648: 
22649: #ifdef DEBUG_IDC
22650:     {
22651: 	xmlChar *str = NULL;
22652: 	xmlGenericError(xmlGenericErrorContext,
22653: 	    "IDC: BACK on %s, depth %d\n",
22654: 	    xmlSchemaFormatQName(&str, vctxt->inode->nsName,
22655: 		vctxt->inode->localName), vctxt->depth);
22656: 	FREE_AND_NULL(str)
22657:     }
22658: #endif
22659:     /*
22660:     * Evaluate the state objects.
22661:     */
22662:     while (sto != NULL) {
22663: 	res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
22664: 	if (res == -1) {
22665: 	    VERROR_INT("xmlSchemaXPathProcessHistory",
22666: 		"calling xmlStreamPop()");
22667: 	    return (-1);
22668: 	}
22669: #ifdef DEBUG_IDC
22670: 	xmlGenericError(xmlGenericErrorContext, "IDC:   stream pop '%s'\n",
22671: 	    sto->sel->xpath);
22672: #endif
22673: 	if (sto->nbHistory == 0)
22674: 	    goto deregister_check;
22675: 
22676: 	matchDepth = sto->history[sto->nbHistory -1];
22677: 
22678: 	/*
22679: 	* Only matches at the current depth are of interest.
22680: 	*/
22681: 	if (matchDepth != depth) {
22682: 	    sto = sto->next;
22683: 	    continue;
22684: 	}
22685: 	if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
22686: 	    /*
22687: 	    * NOTE: According to
22688: 	    *   http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
22689: 	    *   ... the simple-content of complex types is also allowed.
22690: 	    */
22691: 
22692: 	    if (WXS_IS_COMPLEX(type)) {
22693: 		if (WXS_HAS_SIMPLE_CONTENT(type)) {
22694: 		    /*
22695: 		    * Sanity check for complex types with simple content.
22696: 		    */
22697: 		    simpleType = type->contentTypeDef;
22698: 		    if (simpleType == NULL) {
22699: 			VERROR_INT("xmlSchemaXPathProcessHistory",
22700: 			    "field resolves to a CT with simple content "
22701: 			    "but the CT is missing the ST definition");
22702: 			return (-1);
22703: 		    }
22704: 		} else
22705: 		    simpleType = NULL;
22706: 	    } else
22707: 		simpleType = type;
22708: 	    if (simpleType == NULL) {
22709: 		xmlChar *str = NULL;
22710: 
22711: 		/*
22712: 		* Not qualified if the field resolves to a node of non
22713: 		* simple type.
22714: 		*/
22715: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
22716: 		    XML_SCHEMAV_CVC_IDC, NULL,
22717: 		    WXS_BASIC_CAST sto->matcher->aidc->def,
22718: 		    "The XPath '%s' of a field of %s does evaluate to a node of "
22719: 		    "non-simple type",
22720: 		    sto->sel->xpath,
22721: 		    xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
22722: 		FREE_AND_NULL(str);
22723: 		sto->nbHistory--;
22724: 		goto deregister_check;
22725: 	    }
22726: 
22727: 	    if ((key == NULL) && (vctxt->inode->val == NULL)) {
22728: 		/*
22729: 		* Failed to provide the normalized value; maybe
22730: 		* the value was invalid.
22731: 		*/
22732: 		VERROR(XML_SCHEMAV_CVC_IDC,
22733: 		    WXS_BASIC_CAST sto->matcher->aidc->def,
22734: 		    "Warning: No precomputed value available, the value "
22735: 		    "was either invalid or something strange happend");
22736: 		sto->nbHistory--;
22737: 		goto deregister_check;
22738: 	    } else {
22739: 		xmlSchemaIDCMatcherPtr matcher = sto->matcher;
22740: 		xmlSchemaPSVIIDCKeyPtr *keySeq;
22741: 		int pos, idx;
22742: 
22743: 		/*
22744: 		* The key will be anchored on the matcher's list of
22745: 		* key-sequences. The position in this list is determined
22746: 		* by the target node's depth relative to the matcher's
22747: 		* depth of creation (i.e. the depth of the scope element).
22748: 		*
22749: 		* Element        Depth    Pos   List-entries
22750: 		* <scope>          0              NULL
22751: 		*   <bar>          1              NULL
22752: 		*     <target/>    2       2      target
22753: 		*   <bar>
22754:                 * </scope>
22755: 		*
22756: 		* The size of the list is only dependant on the depth of
22757: 		* the tree.
22758: 		* An entry will be NULLed in selector_leave, i.e. when
22759: 		* we hit the target's
22760: 		*/
22761: 		pos = sto->depth - matcher->depth;
22762: 		idx = sto->sel->index;
22763: 
22764: 		/*
22765: 		* Create/grow the array of key-sequences.
22766: 		*/
22767: 		if (matcher->keySeqs == NULL) {
22768: 		    if (pos > 9)
22769: 			matcher->sizeKeySeqs = pos * 2;
22770: 		    else
22771: 			matcher->sizeKeySeqs = 10;
22772: 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22773: 			xmlMalloc(matcher->sizeKeySeqs *
22774: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22775: 		    if (matcher->keySeqs == NULL) {
22776: 			xmlSchemaVErrMemory(NULL,
22777: 			    "allocating an array of key-sequences",
22778: 			    NULL);
22779: 			return(-1);
22780: 		    }
22781: 		    memset(matcher->keySeqs, 0,
22782: 			matcher->sizeKeySeqs *
22783: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22784: 		} else if (pos >= matcher->sizeKeySeqs) {
22785: 		    int i = matcher->sizeKeySeqs;
22786: 
22787: 		    matcher->sizeKeySeqs *= 2;
22788: 		    matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
22789: 			xmlRealloc(matcher->keySeqs,
22790: 			matcher->sizeKeySeqs *
22791: 			sizeof(xmlSchemaPSVIIDCKeyPtr *));
22792: 		    if (matcher->keySeqs == NULL) {
22793: 			xmlSchemaVErrMemory(NULL,
22794: 			    "reallocating an array of key-sequences",
22795: 			    NULL);
22796: 			return (-1);
22797: 		    }
22798: 		    /*
22799: 		    * The array needs to be NULLed.
22800: 		    * TODO: Use memset?
22801: 		    */
22802: 		    for (; i < matcher->sizeKeySeqs; i++)
22803: 			matcher->keySeqs[i] = NULL;
22804: 		}
22805: 
22806: 		/*
22807: 		* Get/create the key-sequence.
22808: 		*/
22809: 		keySeq = matcher->keySeqs[pos];
22810: 		if (keySeq == NULL) {
22811: 		    goto create_sequence;
22812: 		} else if (keySeq[idx] != NULL) {
22813: 		    xmlChar *str = NULL;
22814: 		    /*
22815: 		    * cvc-identity-constraint:
22816: 		    * 3 For each node in the �target node set� all
22817: 		    * of the {fields}, with that node as the context
22818: 		    * node, evaluate to either an empty node-set or
22819: 		    * a node-set with exactly one member, which must
22820: 		    * have a simple type.
22821: 		    *
22822: 		    * The key was already set; report an error.
22823: 		    */
22824: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22825: 			XML_SCHEMAV_CVC_IDC, NULL,
22826: 			WXS_BASIC_CAST matcher->aidc->def,
22827: 			"The XPath '%s' of a field of %s evaluates to a "
22828: 			"node-set with more than one member",
22829: 			sto->sel->xpath,
22830: 			xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
22831: 		    FREE_AND_NULL(str);
22832: 		    sto->nbHistory--;
22833: 		    goto deregister_check;
22834: 		} else
22835: 		    goto create_key;
22836: 
22837: create_sequence:
22838: 		/*
22839: 		* Create a key-sequence.
22840: 		*/
22841: 		keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
22842: 		    matcher->aidc->def->nbFields *
22843: 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
22844: 		if (keySeq == NULL) {
22845: 		    xmlSchemaVErrMemory(NULL,
22846: 			"allocating an IDC key-sequence", NULL);
22847: 		    return(-1);
22848: 		}
22849: 		memset(keySeq, 0, matcher->aidc->def->nbFields *
22850: 		    sizeof(xmlSchemaPSVIIDCKeyPtr));
22851: 		matcher->keySeqs[pos] = keySeq;
22852: create_key:
22853: 		/*
22854: 		* Create a key once per node only.
22855: 		*/
22856: 		if (key == NULL) {
22857: 		    key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
22858: 			sizeof(xmlSchemaPSVIIDCKey));
22859: 		    if (key == NULL) {
22860: 			xmlSchemaVErrMemory(NULL,
22861: 			    "allocating a IDC key", NULL);
22862: 			xmlFree(keySeq);
22863: 			matcher->keySeqs[pos] = NULL;
22864: 			return(-1);
22865: 		    }
22866: 		    /*
22867: 		    * Consume the compiled value.
22868: 		    */
22869: 		    key->type = simpleType;
22870: 		    key->val = vctxt->inode->val;
22871: 		    vctxt->inode->val = NULL;
22872: 		    /*
22873: 		    * Store the key in a global list.
22874: 		    */
22875: 		    if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
22876: 			xmlSchemaIDCFreeKey(key);
22877: 			return (-1);
22878: 		    }
22879: 		}
22880: 		keySeq[idx] = key;
22881: 	    }
22882: 	} else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
22883: 
22884: 	    xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
22885: 	    /* xmlSchemaPSVIIDCBindingPtr bind; */
22886: 	    xmlSchemaPSVIIDCNodePtr ntItem;
22887: 	    xmlSchemaIDCMatcherPtr matcher;
22888: 	    xmlSchemaIDCPtr idc;
22889: 	    xmlSchemaItemListPtr targets;
22890: 	    int pos, i, j, nbKeys;
22891: 	    /*
22892: 	    * Here we have the following scenario:
22893: 	    * An IDC 'selector' state object resolved to a target node,
22894: 	    * during the time this target node was in the
22895: 	    * ancestor-or-self axis, the 'field' state object(s) looked
22896: 	    * out for matching nodes to create a key-sequence for this
22897: 	    * target node. Now we are back to this target node and need
22898: 	    * to put the key-sequence, together with the target node
22899: 	    * itself, into the node-table of the corresponding IDC
22900: 	    * binding.
22901: 	    */
22902: 	    matcher = sto->matcher;
22903: 	    idc = matcher->aidc->def;
22904: 	    nbKeys = idc->nbFields;
22905: 	    pos = depth - matcher->depth;
22906: 	    /*
22907: 	    * Check if the matcher has any key-sequences at all, plus
22908: 	    * if it has a key-sequence for the current target node.
22909: 	    */
22910: 	    if ((matcher->keySeqs == NULL) ||
22911: 		(matcher->sizeKeySeqs <= pos)) {
22912: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22913: 		    goto selector_key_error;
22914: 		else
22915: 		    goto selector_leave;
22916: 	    }
22917: 
22918: 	    keySeq = &(matcher->keySeqs[pos]);
22919: 	    if (*keySeq == NULL) {
22920: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
22921: 		    goto selector_key_error;
22922: 		else
22923: 		    goto selector_leave;
22924: 	    }
22925: 
22926: 	    for (i = 0; i < nbKeys; i++) {
22927: 		if ((*keySeq)[i] == NULL) {
22928: 		    /*
22929: 		    * Not qualified, if not all fields did resolve.
22930: 		    */
22931: 		    if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
22932: 			/*
22933: 			* All fields of a "key" IDC must resolve.
22934: 			*/
22935: 			goto selector_key_error;
22936: 		    }
22937: 		    goto selector_leave;
22938: 		}
22939: 	    }
22940: 	    /*
22941: 	    * All fields did resolve.
22942: 	    */
22943: 
22944: 	    /*
22945: 	    * 4.1 If the {identity-constraint category} is unique(/key),
22946: 	    * then no two members of the �qualified node set� have
22947: 	    * �key-sequences� whose members are pairwise equal, as
22948: 	    * defined by Equal in [XML Schemas: Datatypes].
22949: 	    *
22950: 	    * Get the IDC binding from the matcher and check for
22951: 	    * duplicate key-sequences.
22952: 	    */
22953: #if 0
22954: 	    bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
22955: #endif
22956: 	    targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
22957: 	    if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
22958: 		(targets->nbItems != 0)) {
22959: 		xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
22960: 
22961: 		i = 0;
22962: 		res = 0;
22963: 		/*
22964: 		* Compare the key-sequences, key by key.
22965: 		*/
22966: 		do {
22967: 		    bkeySeq =
22968: 			((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
22969: 		    for (j = 0; j < nbKeys; j++) {
22970: 			ckey = (*keySeq)[j];
22971: 			bkey = bkeySeq[j];
22972: 			res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
22973: 			if (res == -1) {
22974: 			    return (-1);
22975: 			} else if (res == 0) {
22976: 			    /*
22977: 			    * One of the keys differs, so the key-sequence
22978: 			    * won't be equal; get out.
22979: 			    */
22980: 			    break;
22981: 			}
22982: 		    }
22983: 		    if (res == 1) {
22984: 			/*
22985: 			* Duplicate key-sequence found.
22986: 			*/
22987: 			break;
22988: 		    }
22989: 		    i++;
22990: 		} while (i < targets->nbItems);
22991: 		if (i != targets->nbItems) {
22992: 		    xmlChar *str = NULL, *strB = NULL;
22993: 		    /*
22994: 		    * TODO: Try to report the key-sequence.
22995: 		    */
22996: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
22997: 			XML_SCHEMAV_CVC_IDC, NULL,
22998: 			WXS_BASIC_CAST idc,
22999: 			"Duplicate key-sequence %s in %s",
23000: 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
23001: 			    (*keySeq), nbKeys),
23002: 			xmlSchemaGetIDCDesignation(&strB, idc));
23003: 		    FREE_AND_NULL(str);
23004: 		    FREE_AND_NULL(strB);
23005: 		    goto selector_leave;
23006: 		}
23007: 	    }
23008: 	    /*
23009: 	    * Add a node-table item to the IDC binding.
23010: 	    */
23011: 	    ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
23012: 		sizeof(xmlSchemaPSVIIDCNode));
23013: 	    if (ntItem == NULL) {
23014: 		xmlSchemaVErrMemory(NULL,
23015: 		    "allocating an IDC node-table item", NULL);
23016: 		xmlFree(*keySeq);
23017: 		*keySeq = NULL;
23018: 		return(-1);
23019: 	    }
23020: 	    memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
23021: 
23022: 	    /*
23023: 	    * Store the node-table item in a global list.
23024: 	    */
23025: 	    if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
23026: 		if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
23027: 		    xmlFree(ntItem);
23028: 		    xmlFree(*keySeq);
23029: 		    *keySeq = NULL;
23030: 		    return (-1);
23031: 		}
23032: 		ntItem->nodeQNameID = -1;
23033: 	    } else {
23034: 		/*
23035: 		* Save a cached QName for this node on the IDC node, to be
23036: 		* able to report it, even if the node is not saved.
23037: 		*/
23038: 		ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
23039: 		    vctxt->inode->localName, vctxt->inode->nsName);
23040: 		if (ntItem->nodeQNameID == -1) {
23041: 		    xmlFree(ntItem);
23042: 		    xmlFree(*keySeq);
23043: 		    *keySeq = NULL;
23044: 		    return (-1);
23045: 		}
23046: 	    }
23047: 	    /*
23048: 	    * Init the node-table item: Save the node, position and
23049: 	    * consume the key-sequence.
23050: 	    */
23051: 	    ntItem->node = vctxt->node;
23052: 	    ntItem->nodeLine = vctxt->inode->nodeLine;
23053: 	    ntItem->keys = *keySeq;
23054: 	    *keySeq = NULL;
23055: #if 0
23056: 	    if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
23057: #endif
23058: 	    if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
23059: 		if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23060: 		    /*
23061: 		    * Free the item, since keyref items won't be
23062: 		    * put on a global list.
23063: 		    */
23064: 		    xmlFree(ntItem->keys);
23065: 		    xmlFree(ntItem);
23066: 		}
23067: 		return (-1);
23068: 	    }
23069: 
23070: 	    goto selector_leave;
23071: selector_key_error:
23072: 	    {
23073: 		xmlChar *str = NULL;
23074: 		/*
23075: 		* 4.2.1 (KEY) The �target node set� and the
23076: 		* �qualified node set� are equal, that is, every
23077: 		* member of the �target node set� is also a member
23078: 		* of the �qualified node set� and vice versa.
23079: 		*/
23080: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
23081: 		    XML_SCHEMAV_CVC_IDC, NULL,
23082: 		    WXS_BASIC_CAST idc,
23083: 		    "Not all fields of %s evaluate to a node",
23084: 		    xmlSchemaGetIDCDesignation(&str, idc), NULL);
23085: 		FREE_AND_NULL(str);
23086: 	    }
23087: selector_leave:
23088: 	    /*
23089: 	    * Free the key-sequence if not added to the IDC table.
23090: 	    */
23091: 	    if ((keySeq != NULL) && (*keySeq != NULL)) {
23092: 		xmlFree(*keySeq);
23093: 		*keySeq = NULL;
23094: 	    }
23095: 	} /* if selector */
23096: 
23097: 	sto->nbHistory--;
23098: 
23099: deregister_check:
23100: 	/*
23101: 	* Deregister state objects if they reach the depth of creation.
23102: 	*/
23103: 	if ((sto->nbHistory == 0) && (sto->depth == depth)) {
23104: #ifdef DEBUG_IDC
23105: 	    xmlGenericError(xmlGenericErrorContext, "IDC:   STO pop '%s'\n",
23106: 		sto->sel->xpath);
23107: #endif
23108: 	    if (vctxt->xpathStates != sto) {
23109: 		VERROR_INT("xmlSchemaXPathProcessHistory",
23110: 		    "The state object to be removed is not the first "
23111: 		    "in the list");
23112: 	    }
23113: 	    nextsto = sto->next;
23114: 	    /*
23115: 	    * Unlink from the list of active XPath state objects.
23116: 	    */
23117: 	    vctxt->xpathStates = sto->next;
23118: 	    sto->next = vctxt->xpathStatePool;
23119: 	    /*
23120: 	    * Link it to the pool of reusable state objects.
23121: 	    */
23122: 	    vctxt->xpathStatePool = sto;
23123: 	    sto = nextsto;
23124: 	} else
23125: 	    sto = sto->next;
23126:     } /* while (sto != NULL) */
23127:     return (0);
23128: }
23129: 
23130: /**
23131:  * xmlSchemaIDCRegisterMatchers:
23132:  * @vctxt: the WXS validation context
23133:  * @elemDecl: the element declaration
23134:  *
23135:  * Creates helper objects to evaluate IDC selectors/fields
23136:  * successively.
23137:  *
23138:  * Returns 0 if OK and -1 on internal errors.
23139:  */
23140: static int
23141: xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
23142: 			     xmlSchemaElementPtr elemDecl)
23143: {
23144:     xmlSchemaIDCMatcherPtr matcher, last = NULL;
23145:     xmlSchemaIDCPtr idc, refIdc;
23146:     xmlSchemaIDCAugPtr aidc;
23147: 
23148:     idc = (xmlSchemaIDCPtr) elemDecl->idcs;
23149:     if (idc == NULL)
23150: 	return (0);
23151: 
23152: #ifdef DEBUG_IDC
23153:     {
23154: 	xmlChar *str = NULL;
23155: 	xmlGenericError(xmlGenericErrorContext,
23156: 	    "IDC: REGISTER on %s, depth %d\n",
23157: 	    (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
23158: 		vctxt->inode->localName), vctxt->depth);
23159: 	FREE_AND_NULL(str)
23160:     }
23161: #endif
23162:     if (vctxt->inode->idcMatchers != NULL) {
23163: 	VERROR_INT("xmlSchemaIDCRegisterMatchers",
23164: 	    "The chain of IDC matchers is expected to be empty");
23165: 	return (-1);
23166:     }
23167:     do {
23168: 	if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
23169: 	    /*
23170: 	    * Since IDCs bubbles are expensive we need to know the
23171: 	    * depth at which the bubbles should stop; this will be
23172: 	    * the depth of the top-most keyref IDC. If no keyref
23173: 	    * references a key/unique IDC, the keyrefDepth will
23174: 	    * be -1, indicating that no bubbles are needed.
23175: 	    */
23176: 	    refIdc = (xmlSchemaIDCPtr) idc->ref->item;
23177: 	    if (refIdc != NULL) {
23178: 		/*
23179: 		* Remember that we have keyrefs on this node.
23180: 		*/
23181: 		vctxt->inode->hasKeyrefs = 1;
23182: 		/*
23183: 		* Lookup the referenced augmented IDC info.
23184: 		*/
23185: 		aidc = vctxt->aidcs;
23186: 		while (aidc != NULL) {
23187: 		    if (aidc->def == refIdc)
23188: 			break;
23189: 		    aidc = aidc->next;
23190: 		}
23191: 		if (aidc == NULL) {
23192: 		    VERROR_INT("xmlSchemaIDCRegisterMatchers",
23193: 			"Could not find an augmented IDC item for an IDC "
23194: 			"definition");
23195: 		    return (-1);
23196: 		}
23197: 		if ((aidc->keyrefDepth == -1) ||
23198: 		    (vctxt->depth < aidc->keyrefDepth))
23199: 		    aidc->keyrefDepth = vctxt->depth;
23200: 	    }
23201: 	}
23202: 	/*
23203: 	* Lookup the augmented IDC item for the IDC definition.
23204: 	*/
23205: 	aidc = vctxt->aidcs;
23206: 	while (aidc != NULL) {
23207: 	    if (aidc->def == idc)
23208: 		break;
23209: 	    aidc = aidc->next;
23210: 	}
23211: 	if (aidc == NULL) {
23212: 	    VERROR_INT("xmlSchemaIDCRegisterMatchers",
23213: 		"Could not find an augmented IDC item for an IDC definition");
23214: 	    return (-1);
23215: 	}
23216: 	/*
23217: 	* Create an IDC matcher for every IDC definition.
23218: 	*/
23219: 	if (vctxt->idcMatcherCache != NULL) {
23220: 	    /*
23221: 	    * Reuse a cached matcher.
23222: 	    */
23223: 	    matcher = vctxt->idcMatcherCache;
23224: 	    vctxt->idcMatcherCache = matcher->nextCached;
23225: 	    matcher->nextCached = NULL;
23226: 	} else {
23227: 	    matcher = (xmlSchemaIDCMatcherPtr)
23228: 		xmlMalloc(sizeof(xmlSchemaIDCMatcher));
23229: 	    if (matcher == NULL) {
23230: 		xmlSchemaVErrMemory(vctxt,
23231: 		    "allocating an IDC matcher", NULL);
23232: 		return (-1);
23233: 	    }
23234: 	    memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
23235: 	}
23236: 	if (last == NULL)
23237: 	    vctxt->inode->idcMatchers = matcher;
23238: 	else
23239: 	    last->next = matcher;
23240: 	last = matcher;
23241: 
23242: 	matcher->type = IDC_MATCHER;
23243: 	matcher->depth = vctxt->depth;
23244: 	matcher->aidc = aidc;
23245: 	matcher->idcType = aidc->def->type;
23246: #ifdef DEBUG_IDC
23247: 	xmlGenericError(xmlGenericErrorContext, "IDC:   register matcher\n");
23248: #endif
23249: 	/*
23250: 	* Init the automaton state object.
23251: 	*/
23252: 	if (xmlSchemaIDCAddStateObject(vctxt, matcher,
23253: 	    idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
23254: 	    return (-1);
23255: 
23256: 	idc = idc->next;
23257:     } while (idc != NULL);
23258:     return (0);
23259: }
23260: 
23261: static int
23262: xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
23263: 			   xmlSchemaNodeInfoPtr ielem)
23264: {
23265:     xmlSchemaPSVIIDCBindingPtr bind;
23266:     int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
23267:     xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
23268:     xmlSchemaPSVIIDCNodePtr *targets, *dupls;
23269: 
23270:     xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
23271:     /* vctxt->createIDCNodeTables */
23272:     while (matcher != NULL) {
23273: 	/*
23274: 	* Skip keyref IDCs and empty IDC target-lists.
23275: 	*/
23276: 	if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
23277: 	    WXS_ILIST_IS_EMPTY(matcher->targets))
23278: 	{
23279: 	    matcher = matcher->next;
23280: 	    continue;
23281: 	}
23282: 	/*
23283: 	* If we _want_ the IDC node-table to be created in any case
23284: 	* then do so. Otherwise create them only if keyrefs need them.
23285: 	*/
23286: 	if ((! vctxt->createIDCNodeTables) &&
23287: 	    ((matcher->aidc->keyrefDepth == -1) ||
23288: 	     (matcher->aidc->keyrefDepth > vctxt->depth)))
23289: 	{
23290: 	    matcher = matcher->next;
23291: 	    continue;
23292: 	}
23293: 	/*
23294: 	* Get/create the IDC binding on this element for the IDC definition.
23295: 	*/
23296: 	bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
23297: 
23298: 	if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
23299: 	    dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
23300: 	    nbDupls = bind->dupls->nbItems;
23301: 	} else {
23302: 	    dupls = NULL;
23303: 	    nbDupls = 0;
23304: 	}
23305: 	if (bind->nodeTable != NULL) {
23306: 	    nbNodeTable = bind->nbNodes;
23307: 	} else {
23308: 	    nbNodeTable = 0;
23309: 	}
23310: 
23311: 	if ((nbNodeTable == 0) && (nbDupls == 0)) {
23312: 	    /*
23313: 	    * Transfer all IDC target-nodes to the IDC node-table.
23314: 	    */
23315: 	    bind->nodeTable =
23316: 		(xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23317: 	    bind->sizeNodes = matcher->targets->sizeItems;
23318: 	    bind->nbNodes = matcher->targets->nbItems;
23319: 
23320: 	    matcher->targets->items = NULL;
23321: 	    matcher->targets->sizeItems = 0;
23322: 	    matcher->targets->nbItems = 0;
23323: 	} else {
23324: 	    /*
23325: 	    * Compare the key-sequences and add to the IDC node-table.
23326: 	    */
23327: 	    nbTargets = matcher->targets->nbItems;
23328: 	    targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
23329: 	    nbFields = matcher->aidc->def->nbFields;
23330: 	    i = 0;
23331: 	    do {
23332: 		keys = targets[i]->keys;
23333: 		if (nbDupls) {
23334: 		    /*
23335: 		    * Search in already found duplicates first.
23336: 		    */
23337: 		    j = 0;
23338: 		    do {
23339: 			if (nbFields == 1) {
23340: 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
23341: 				dupls[j]->keys[0]->val);
23342: 			    if (res == -1)
23343: 				goto internal_error;
23344: 			    if (res == 1) {
23345: 				/*
23346: 				* Equal key-sequence.
23347: 				*/
23348: 				goto next_target;
23349: 			    }
23350: 			} else {
23351: 			    res = 0;
23352: 			    ntkeys = dupls[j]->keys;
23353: 			    for (k = 0; k < nbFields; k++) {
23354: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23355: 				    ntkeys[k]->val);
23356: 				if (res == -1)
23357: 				    goto internal_error;
23358: 				if (res == 0) {
23359: 				    /*
23360: 				    * One of the keys differs.
23361: 				    */
23362: 				    break;
23363: 				}
23364: 			    }
23365: 			    if (res == 1) {
23366: 				/*
23367: 				* Equal key-sequence found.
23368: 				*/
23369: 				goto next_target;
23370: 			    }
23371: 			}
23372: 			j++;
23373: 		    } while (j < nbDupls);
23374: 		}
23375: 		if (nbNodeTable) {
23376: 		    j = 0;
23377: 		    do {
23378: 			if (nbFields == 1) {
23379: 			    res = xmlSchemaAreValuesEqual(keys[0]->val,
23380: 				bind->nodeTable[j]->keys[0]->val);
23381: 			    if (res == -1)
23382: 				goto internal_error;
23383: 			    if (res == 0) {
23384: 				/*
23385: 				* The key-sequence differs.
23386: 				*/
23387: 				goto next_node_table_entry;
23388: 			    }
23389: 			} else {
23390: 			    res = 0;
23391: 			    ntkeys = bind->nodeTable[j]->keys;
23392: 			    for (k = 0; k < nbFields; k++) {
23393: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23394: 				    ntkeys[k]->val);
23395: 				if (res == -1)
23396: 				    goto internal_error;
23397: 				if (res == 0) {
23398: 				    /*
23399: 				    * One of the keys differs.
23400: 				    */
23401: 				    goto next_node_table_entry;
23402: 				}
23403: 			    }
23404: 			}
23405: 			/*
23406: 			* Add the duplicate to the list of duplicates.
23407: 			*/
23408: 			if (bind->dupls == NULL) {
23409: 			    bind->dupls = xmlSchemaItemListCreate();
23410: 			    if (bind->dupls == NULL)
23411: 				goto internal_error;
23412: 			}
23413: 			if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
23414: 			    goto internal_error;
23415: 			/*
23416: 			* Remove the duplicate entry from the IDC node-table.
23417: 			*/
23418: 			bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
23419: 			bind->nbNodes--;
23420: 
23421: 			goto next_target;
23422: 
23423: next_node_table_entry:
23424: 			j++;
23425: 		    } while (j < nbNodeTable);
23426: 		}
23427: 		/*
23428: 		* If everything is fine, then add the IDC target-node to
23429: 		* the IDC node-table.
23430: 		*/
23431: 		if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
23432: 		    goto internal_error;
23433: 
23434: next_target:
23435: 		i++;
23436: 	    } while (i < nbTargets);
23437: 	}
23438: 	matcher = matcher->next;
23439:     }
23440:     return(0);
23441: 
23442: internal_error:
23443:     return(-1);
23444: }
23445: 
23446: /**
23447:  * xmlSchemaBubbleIDCNodeTables:
23448:  * @depth: the current tree depth
23449:  *
23450:  * Merges IDC bindings of an element at @depth into the corresponding IDC
23451:  * bindings of its parent element. If a duplicate note-table entry is found,
23452:  * both, the parent node-table entry and child entry are discarded from the
23453:  * node-table of the parent.
23454:  *
23455:  * Returns 0 if OK and -1 on internal errors.
23456:  */
23457: static int
23458: xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
23459: {
23460:     xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
23461:     xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
23462:     xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
23463:     xmlSchemaIDCAugPtr aidc;
23464:     int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
23465: 
23466:     bind = vctxt->inode->idcTable;
23467:     if (bind == NULL) {
23468: 	/* Fine, no table, no bubbles. */
23469: 	return (0);
23470:     }
23471: 
23472:     parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
23473:     /*
23474:     * Walk all bindings; create new or add to existing bindings.
23475:     * Remove duplicate key-sequences.
23476:     */
23477:     while (bind != NULL) {
23478: 
23479: 	if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
23480: 	    goto next_binding;
23481: 	/*
23482: 	* Check if the key/unique IDC table needs to be bubbled.
23483: 	*/
23484: 	if (! vctxt->createIDCNodeTables) {
23485: 	    aidc = vctxt->aidcs;
23486: 	    do {
23487: 		if (aidc->def == bind->definition) {
23488: 		    if ((aidc->keyrefDepth == -1) ||
23489: 			(aidc->keyrefDepth >= vctxt->depth)) {
23490: 			goto next_binding;
23491: 		    }
23492: 		    break;
23493: 		}
23494: 		aidc = aidc->next;
23495: 	    } while (aidc != NULL);
23496: 	}
23497: 
23498: 	if (parTable != NULL)
23499: 	    parBind = *parTable;
23500: 	/*
23501: 	* Search a matching parent binding for the
23502: 	* IDC definition.
23503: 	*/
23504: 	while (parBind != NULL) {
23505: 	    if (parBind->definition == bind->definition)
23506: 		break;
23507: 	    parBind = parBind->next;
23508: 	}
23509: 
23510: 	if (parBind != NULL) {
23511: 	    /*
23512: 	    * Compare every node-table entry of the child node,
23513: 	    * i.e. the key-sequence within, ...
23514: 	    */
23515: 	    oldNum = parBind->nbNodes; /* Skip newly added items. */
23516: 
23517: 	    if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
23518: 		oldDupls = parBind->dupls->nbItems;
23519: 		dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
23520: 	    } else {
23521: 		dupls = NULL;
23522: 		oldDupls = 0;
23523: 	    }
23524: 
23525: 	    parNodes = parBind->nodeTable;
23526: 	    nbFields = bind->definition->nbFields;
23527: 
23528: 	    for (i = 0; i < bind->nbNodes; i++) {
23529: 		node = bind->nodeTable[i];
23530: 		if (node == NULL)
23531: 		    continue;
23532: 		/*
23533: 		* ...with every key-sequence of the parent node, already
23534: 		* evaluated to be a duplicate key-sequence.
23535: 		*/
23536: 		if (oldDupls) {
23537: 		    j = 0;
23538: 		    while (j < oldDupls) {
23539: 			if (nbFields == 1) {
23540: 			    ret = xmlSchemaAreValuesEqual(
23541: 				node->keys[0]->val,
23542: 				dupls[j]->keys[0]->val);
23543: 			    if (ret == -1)
23544: 				goto internal_error;
23545: 			    if (ret == 0) {
23546: 				j++;
23547: 				continue;
23548: 			    }
23549: 			} else {
23550: 			    parNode = dupls[j];
23551: 			    for (k = 0; k < nbFields; k++) {
23552: 				ret = xmlSchemaAreValuesEqual(
23553: 				    node->keys[k]->val,
23554: 				    parNode->keys[k]->val);
23555: 				if (ret == -1)
23556: 				    goto internal_error;
23557: 				if (ret == 0)
23558: 				    break;
23559: 			    }
23560: 			}
23561: 			if (ret == 1)
23562: 			    /* Duplicate found. */
23563: 			    break;
23564: 			j++;
23565: 		    }
23566: 		    if (j != oldDupls) {
23567: 			/* Duplicate found. Skip this entry. */
23568: 			continue;
23569: 		    }
23570: 		}
23571: 		/*
23572: 		* ... and with every key-sequence of the parent node.
23573: 		*/
23574: 		if (oldNum) {
23575: 		    j = 0;
23576: 		    while (j < oldNum) {
23577: 			parNode = parNodes[j];
23578: 			if (nbFields == 1) {
23579: 			    ret = xmlSchemaAreValuesEqual(
23580: 				node->keys[0]->val,
23581: 				parNode->keys[0]->val);
23582: 			    if (ret == -1)
23583: 				goto internal_error;
23584: 			    if (ret == 0) {
23585: 				j++;
23586: 				continue;
23587: 			    }
23588: 			} else {
23589: 			    for (k = 0; k < nbFields; k++) {
23590: 				ret = xmlSchemaAreValuesEqual(
23591: 				    node->keys[k]->val,
23592: 				    parNode->keys[k]->val);
23593: 				if (ret == -1)
23594: 				    goto internal_error;
23595: 				if (ret == 0)
23596: 				    break;
23597: 			    }
23598: 			}
23599: 			if (ret == 1)
23600: 			    /* Duplicate found. */
23601: 			    break;
23602: 			j++;
23603: 		    }
23604: 		    if (j != oldNum) {
23605: 			/*
23606: 			* Handle duplicates. Move the duplicate in
23607: 			* the parent's node-table to the list of
23608: 			* duplicates.
23609: 			*/
23610: 			oldNum--;
23611: 			parBind->nbNodes--;
23612: 			/*
23613: 			* Move last old item to pos of duplicate.
23614: 			*/
23615: 			parNodes[j] = parNodes[oldNum];
23616: 
23617: 			if (parBind->nbNodes != oldNum) {
23618: 			    /*
23619: 			    * If new items exist, move last new item to
23620: 			    * last of old items.
23621: 			    */
23622: 			    parNodes[oldNum] =
23623: 				parNodes[parBind->nbNodes];
23624: 			}
23625: 			if (parBind->dupls == NULL) {
23626: 			    parBind->dupls = xmlSchemaItemListCreate();
23627: 			    if (parBind->dupls == NULL)
23628: 				goto internal_error;
23629: 			}
23630: 			xmlSchemaItemListAdd(parBind->dupls, parNode);
23631: 		    } else {
23632: 			/*
23633: 			* Add the node-table entry (node and key-sequence) of
23634: 			* the child node to the node table of the parent node.
23635: 			*/
23636: 			if (parBind->nodeTable == NULL) {
23637: 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23638: 				xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
23639: 			    if (parBind->nodeTable == NULL) {
23640: 				xmlSchemaVErrMemory(NULL,
23641: 				    "allocating IDC list of node-table items", NULL);
23642: 				goto internal_error;
23643: 			    }
23644: 			    parBind->sizeNodes = 1;
23645: 			} else if (parBind->nbNodes >= parBind->sizeNodes) {
23646: 			    parBind->sizeNodes *= 2;
23647: 			    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23648: 				xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
23649: 				sizeof(xmlSchemaPSVIIDCNodePtr));
23650: 			    if (parBind->nodeTable == NULL) {
23651: 				xmlSchemaVErrMemory(NULL,
23652: 				    "re-allocating IDC list of node-table items", NULL);
23653: 				goto internal_error;
23654: 			    }
23655: 			}
23656: 			parNodes = parBind->nodeTable;
23657: 			/*
23658: 			* Append the new node-table entry to the 'new node-table
23659: 			* entries' section.
23660: 			*/
23661: 			parNodes[parBind->nbNodes++] = node;
23662: 		    }
23663: 
23664: 		}
23665: 
23666: 	    }
23667: 	} else {
23668: 	    /*
23669: 	    * No binding for the IDC was found: create a new one and
23670: 	    * copy all node-tables.
23671: 	    */
23672: 	    parBind = xmlSchemaIDCNewBinding(bind->definition);
23673: 	    if (parBind == NULL)
23674: 		goto internal_error;
23675: 
23676: 	    /*
23677: 	    * TODO: Hmm, how to optimize the initial number of
23678: 	    * allocated entries?
23679: 	    */
23680: 	    if (bind->nbNodes != 0) {
23681: 		/*
23682: 		* Add all IDC node-table entries.
23683: 		*/
23684: 		if (! vctxt->psviExposeIDCNodeTables) {
23685: 		    /*
23686: 		    * Just move the entries.
23687: 		    * NOTE: this is quite save here, since
23688: 		    * all the keyref lookups have already been
23689: 		    * performed.
23690: 		    */
23691: 		    parBind->nodeTable = bind->nodeTable;
23692: 		    bind->nodeTable = NULL;
23693: 		    parBind->sizeNodes = bind->sizeNodes;
23694: 		    bind->sizeNodes = 0;
23695: 		    parBind->nbNodes = bind->nbNodes;
23696: 		    bind->nbNodes = 0;
23697: 		} else {
23698: 		    /*
23699: 		    * Copy the entries.
23700: 		    */
23701: 		    parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
23702: 			xmlMalloc(bind->nbNodes *
23703: 			sizeof(xmlSchemaPSVIIDCNodePtr));
23704: 		    if (parBind->nodeTable == NULL) {
23705: 			xmlSchemaVErrMemory(NULL,
23706: 			    "allocating an array of IDC node-table "
23707: 			    "items", NULL);
23708: 			xmlSchemaIDCFreeBinding(parBind);
23709: 			goto internal_error;
23710: 		    }
23711: 		    parBind->sizeNodes = bind->nbNodes;
23712: 		    parBind->nbNodes = bind->nbNodes;
23713: 		    memcpy(parBind->nodeTable, bind->nodeTable,
23714: 			bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
23715: 		}
23716: 	    }
23717: 	    if (bind->dupls) {
23718: 		/*
23719: 		* Move the duplicates.
23720: 		*/
23721: 		if (parBind->dupls != NULL)
23722: 		    xmlSchemaItemListFree(parBind->dupls);
23723: 		parBind->dupls = bind->dupls;
23724: 		bind->dupls = NULL;
23725: 	    }
23726:             if (parTable != NULL) {
23727:                 if (*parTable == NULL)
23728:                     *parTable = parBind;
23729:                 else {
23730:                     parBind->next = *parTable;
23731:                     *parTable = parBind;
23732:                 }
23733:             }
23734: 	}
23735: 
23736: next_binding:
23737: 	bind = bind->next;
23738:     }
23739:     return (0);
23740: 
23741: internal_error:
23742:     return(-1);
23743: }
23744: 
23745: /**
23746:  * xmlSchemaCheckCVCIDCKeyRef:
23747:  * @vctxt: the WXS validation context
23748:  * @elemDecl: the element declaration
23749:  *
23750:  * Check the cvc-idc-keyref constraints.
23751:  */
23752: static int
23753: xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
23754: {
23755:     xmlSchemaIDCMatcherPtr matcher;
23756:     xmlSchemaPSVIIDCBindingPtr bind;
23757: 
23758:     matcher = vctxt->inode->idcMatchers;
23759:     /*
23760:     * Find a keyref.
23761:     */
23762:     while (matcher != NULL) {
23763: 	if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
23764: 	    matcher->targets &&
23765: 	    matcher->targets->nbItems)
23766: 	{
23767: 	    int i, j, k, res, nbFields, hasDupls;
23768: 	    xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
23769: 	    xmlSchemaPSVIIDCNodePtr refNode = NULL;
23770: 
23771: 	    nbFields = matcher->aidc->def->nbFields;
23772: 
23773: 	    /*
23774: 	    * Find the IDC node-table for the referenced IDC key/unique.
23775: 	    */
23776: 	    bind = vctxt->inode->idcTable;
23777: 	    while (bind != NULL) {
23778: 		if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
23779: 		    bind->definition)
23780: 		    break;
23781: 		bind = bind->next;
23782: 	    }
23783: 	    hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
23784: 	    /*
23785: 	    * Search for a matching key-sequences.
23786: 	    */
23787: 	    for (i = 0; i < matcher->targets->nbItems; i++) {
23788: 		res = 0;
23789: 		refNode = matcher->targets->items[i];
23790: 		if (bind != NULL) {
23791: 		    refKeys = refNode->keys;
23792: 		    for (j = 0; j < bind->nbNodes; j++) {
23793: 			keys = bind->nodeTable[j]->keys;
23794: 			for (k = 0; k < nbFields; k++) {
23795: 			    res = xmlSchemaAreValuesEqual(keys[k]->val,
23796: 				refKeys[k]->val);
23797: 			    if (res == 0)
23798: 				break;
23799: 			    else if (res == -1) {
23800: 				return (-1);
23801: 			    }
23802: 			}
23803: 			if (res == 1) {
23804: 			    /*
23805: 			    * Match found.
23806: 			    */
23807: 			    break;
23808: 			}
23809: 		    }
23810: 		    if ((res == 0) && hasDupls) {
23811: 			/*
23812: 			* Search in duplicates
23813: 			*/
23814: 			for (j = 0; j < bind->dupls->nbItems; j++) {
23815: 			    keys = ((xmlSchemaPSVIIDCNodePtr)
23816: 				bind->dupls->items[j])->keys;
23817: 			    for (k = 0; k < nbFields; k++) {
23818: 				res = xmlSchemaAreValuesEqual(keys[k]->val,
23819: 				    refKeys[k]->val);
23820: 				if (res == 0)
23821: 				    break;
23822: 				else if (res == -1) {
23823: 				    return (-1);
23824: 				}
23825: 			    }
23826: 			    if (res == 1) {
23827: 				/*
23828: 				* Match in duplicates found.
23829: 				*/
23830: 				xmlChar *str = NULL, *strB = NULL;
23831: 				xmlSchemaKeyrefErr(vctxt,
23832: 				    XML_SCHEMAV_CVC_IDC, refNode,
23833: 				    (xmlSchemaTypePtr) matcher->aidc->def,
23834: 				    "More than one match found for "
23835: 				    "key-sequence %s of keyref '%s'",
23836: 				    xmlSchemaFormatIDCKeySequence(vctxt, &str,
23837: 					refNode->keys, nbFields),
23838: 				    xmlSchemaGetComponentQName(&strB,
23839: 					matcher->aidc->def));
23840: 				FREE_AND_NULL(str);
23841: 				FREE_AND_NULL(strB);
23842: 				break;
23843: 			    }
23844: 			}
23845: 		    }
23846: 		}
23847: 
23848: 		if (res == 0) {
23849: 		    xmlChar *str = NULL, *strB = NULL;
23850: 		    xmlSchemaKeyrefErr(vctxt,
23851: 			XML_SCHEMAV_CVC_IDC, refNode,
23852: 			(xmlSchemaTypePtr) matcher->aidc->def,
23853: 			"No match found for key-sequence %s of keyref '%s'",
23854: 			xmlSchemaFormatIDCKeySequence(vctxt, &str,
23855: 			    refNode->keys, nbFields),
23856: 			xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
23857: 		    FREE_AND_NULL(str);
23858: 		    FREE_AND_NULL(strB);
23859: 		}
23860: 	    }
23861: 	}
23862: 	matcher = matcher->next;
23863:     }
23864:     /* TODO: Return an error if any error encountered. */
23865:     return (0);
23866: }
23867: 
23868: /************************************************************************
23869:  * 									*
23870:  * 			XML Reader validation code                      *
23871:  * 									*
23872:  ************************************************************************/
23873: 
23874: static xmlSchemaAttrInfoPtr
23875: xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
23876: {
23877:     xmlSchemaAttrInfoPtr iattr;
23878:     /*
23879:     * Grow/create list of attribute infos.
23880:     */
23881:     if (vctxt->attrInfos == NULL) {
23882: 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23883: 	    xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
23884: 	vctxt->sizeAttrInfos = 1;
23885: 	if (vctxt->attrInfos == NULL) {
23886: 	    xmlSchemaVErrMemory(vctxt,
23887: 		"allocating attribute info list", NULL);
23888: 	    return (NULL);
23889: 	}
23890:     } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
23891: 	vctxt->sizeAttrInfos++;
23892: 	vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
23893: 	    xmlRealloc(vctxt->attrInfos,
23894: 		vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
23895: 	if (vctxt->attrInfos == NULL) {
23896: 	    xmlSchemaVErrMemory(vctxt,
23897: 		"re-allocating attribute info list", NULL);
23898: 	    return (NULL);
23899: 	}
23900:     } else {
23901: 	iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
23902: 	if (iattr->localName != NULL) {
23903: 	    VERROR_INT("xmlSchemaGetFreshAttrInfo",
23904: 		"attr info not cleared");
23905: 	    return (NULL);
23906: 	}
23907: 	iattr->nodeType = XML_ATTRIBUTE_NODE;
23908: 	return (iattr);
23909:     }
23910:     /*
23911:     * Create an attribute info.
23912:     */
23913:     iattr = (xmlSchemaAttrInfoPtr)
23914: 	xmlMalloc(sizeof(xmlSchemaAttrInfo));
23915:     if (iattr == NULL) {
23916: 	xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
23917: 	return (NULL);
23918:     }
23919:     memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
23920:     iattr->nodeType = XML_ATTRIBUTE_NODE;
23921:     vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
23922: 
23923:     return (iattr);
23924: }
23925: 
23926: static int
23927: xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
23928: 			xmlNodePtr attrNode,
23929: 			int nodeLine,
23930: 			const xmlChar *localName,
23931: 			const xmlChar *nsName,
23932: 			int ownedNames,
23933: 			xmlChar *value,
23934: 			int ownedValue)
23935: {
23936:     xmlSchemaAttrInfoPtr attr;
23937: 
23938:     attr = xmlSchemaGetFreshAttrInfo(vctxt);
23939:     if (attr == NULL) {
23940: 	VERROR_INT("xmlSchemaPushAttribute",
23941: 	    "calling xmlSchemaGetFreshAttrInfo()");
23942: 	return (-1);
23943:     }
23944:     attr->node = attrNode;
23945:     attr->nodeLine = nodeLine;
23946:     attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
23947:     attr->localName = localName;
23948:     attr->nsName = nsName;
23949:     if (ownedNames)
23950: 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
23951:     /*
23952:     * Evaluate if it's an XSI attribute.
23953:     */
23954:     if (nsName != NULL) {
23955: 	if (xmlStrEqual(localName, BAD_CAST "nil")) {
23956: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23957: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
23958: 	    }
23959: 	} else if (xmlStrEqual(localName, BAD_CAST "type")) {
23960: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23961: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
23962: 	    }
23963: 	} else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
23964: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23965: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
23966: 	    }
23967: 	} else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
23968: 	    if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
23969: 		attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
23970: 	    }
23971: 	} else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
23972: 	    attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
23973: 	}
23974:     }
23975:     attr->value = value;
23976:     if (ownedValue)
23977: 	attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
23978:     if (attr->metaType != 0)
23979: 	attr->state = XML_SCHEMAS_ATTR_META;
23980:     return (0);
23981: }
23982: 
23983: /**
23984:  * xmlSchemaClearElemInfo:
23985:  * @vctxt: the WXS validation context
23986:  * @ielem: the element information item
23987:  */
23988: static void
23989: xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
23990: 		       xmlSchemaNodeInfoPtr ielem)
23991: {
23992:     ielem->hasKeyrefs = 0;
23993:     ielem->appliedXPath = 0;
23994:     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
23995: 	FREE_AND_NULL(ielem->localName);
23996: 	FREE_AND_NULL(ielem->nsName);
23997:     } else {
23998: 	ielem->localName = NULL;
23999: 	ielem->nsName = NULL;
24000:     }
24001:     if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
24002: 	FREE_AND_NULL(ielem->value);
24003:     } else {
24004: 	ielem->value = NULL;
24005:     }
24006:     if (ielem->val != NULL) {
24007: 	/*
24008: 	* PSVI TODO: Be careful not to free it when the value is
24009: 	* exposed via PSVI.
24010: 	*/
24011: 	xmlSchemaFreeValue(ielem->val);
24012: 	ielem->val = NULL;
24013:     }
24014:     if (ielem->idcMatchers != NULL) {
24015: 	/*
24016: 	* REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
24017: 	*   Does it work?
24018: 	*/
24019: 	xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
24020: #if 0
24021: 	xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
24022: #endif
24023: 	ielem->idcMatchers = NULL;
24024:     }
24025:     if (ielem->idcTable != NULL) {
24026: 	/*
24027: 	* OPTIMIZE TODO: Use a pool of IDC tables??.
24028: 	*/
24029: 	xmlSchemaIDCFreeIDCTable(ielem->idcTable);
24030: 	ielem->idcTable = NULL;
24031:     }
24032:     if (ielem->regexCtxt != NULL) {
24033: 	xmlRegFreeExecCtxt(ielem->regexCtxt);
24034: 	ielem->regexCtxt = NULL;
24035:     }
24036:     if (ielem->nsBindings != NULL) {
24037: 	xmlFree((xmlChar **)ielem->nsBindings);
24038: 	ielem->nsBindings = NULL;
24039: 	ielem->nbNsBindings = 0;
24040: 	ielem->sizeNsBindings = 0;
24041:     }
24042: }
24043: 
24044: /**
24045:  * xmlSchemaGetFreshElemInfo:
24046:  * @vctxt: the schema validation context
24047:  *
24048:  * Creates/reuses and initializes the element info item for
24049:  * the currect tree depth.
24050:  *
24051:  * Returns the element info item or NULL on API or internal errors.
24052:  */
24053: static xmlSchemaNodeInfoPtr
24054: xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
24055: {
24056:     xmlSchemaNodeInfoPtr info = NULL;
24057: 
24058:     if (vctxt->depth > vctxt->sizeElemInfos) {
24059: 	VERROR_INT("xmlSchemaGetFreshElemInfo",
24060: 	    "inconsistent depth encountered");
24061: 	return (NULL);
24062:     }
24063:     if (vctxt->elemInfos == NULL) {
24064: 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24065: 	    xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
24066: 	if (vctxt->elemInfos == NULL) {
24067: 	    xmlSchemaVErrMemory(vctxt,
24068: 		"allocating the element info array", NULL);
24069: 	    return (NULL);
24070: 	}
24071: 	memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
24072: 	vctxt->sizeElemInfos = 10;
24073:     } else if (vctxt->sizeElemInfos <= vctxt->depth) {
24074: 	int i = vctxt->sizeElemInfos;
24075: 
24076: 	vctxt->sizeElemInfos *= 2;
24077: 	vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
24078: 	    xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
24079: 	    sizeof(xmlSchemaNodeInfoPtr));
24080: 	if (vctxt->elemInfos == NULL) {
24081: 	    xmlSchemaVErrMemory(vctxt,
24082: 		"re-allocating the element info array", NULL);
24083: 	    return (NULL);
24084: 	}
24085: 	/*
24086: 	* We need the new memory to be NULLed.
24087: 	* TODO: Use memset instead?
24088: 	*/
24089: 	for (; i < vctxt->sizeElemInfos; i++)
24090: 	    vctxt->elemInfos[i] = NULL;
24091:     } else
24092: 	info = vctxt->elemInfos[vctxt->depth];
24093: 
24094:     if (info == NULL) {
24095: 	info = (xmlSchemaNodeInfoPtr)
24096: 	    xmlMalloc(sizeof(xmlSchemaNodeInfo));
24097: 	if (info == NULL) {
24098: 	    xmlSchemaVErrMemory(vctxt,
24099: 		"allocating an element info", NULL);
24100: 	    return (NULL);
24101: 	}
24102: 	vctxt->elemInfos[vctxt->depth] = info;
24103:     } else {
24104: 	if (info->localName != NULL) {
24105: 	    VERROR_INT("xmlSchemaGetFreshElemInfo",
24106: 		"elem info has not been cleared");
24107: 	    return (NULL);
24108: 	}
24109:     }
24110:     memset(info, 0, sizeof(xmlSchemaNodeInfo));
24111:     info->nodeType = XML_ELEMENT_NODE;
24112:     info->depth = vctxt->depth;
24113: 
24114:     return (info);
24115: }
24116: 
24117: #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
24118: #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
24119: #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
24120: 
24121: static int
24122: xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
24123: 			xmlNodePtr node,
24124: 			xmlSchemaTypePtr type,
24125: 			xmlSchemaValType valType,
24126: 			const xmlChar * value,
24127: 			xmlSchemaValPtr val,
24128: 			unsigned long length,
24129: 			int fireErrors)
24130: {
24131:     int ret, error = 0;
24132: 
24133:     xmlSchemaTypePtr tmpType;
24134:     xmlSchemaFacetLinkPtr facetLink;
24135:     xmlSchemaFacetPtr facet;
24136:     unsigned long len = 0;
24137:     xmlSchemaWhitespaceValueType ws;
24138: 
24139:     /*
24140:     * In Libxml2, derived built-in types have currently no explicit facets.
24141:     */
24142:     if (type->type == XML_SCHEMA_TYPE_BASIC)
24143: 	return (0);
24144: 
24145:     /*
24146:     * NOTE: Do not jump away, if the facetSet of the given type is
24147:     * empty: until now, "pattern" and "enumeration" facets of the
24148:     * *base types* need to be checked as well.
24149:     */
24150:     if (type->facetSet == NULL)
24151: 	goto pattern_and_enum;
24152: 
24153:     if (! WXS_IS_ATOMIC(type)) {
24154: 	if (WXS_IS_LIST(type))
24155: 	    goto WXS_IS_LIST;
24156: 	else
24157: 	    goto pattern_and_enum;
24158:     }
24159:     /*
24160:     * Whitespace handling is only of importance for string-based
24161:     * types.
24162:     */
24163:     tmpType = xmlSchemaGetPrimitiveType(type);
24164:     if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
24165: 	WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
24166: 	ws = xmlSchemaGetWhiteSpaceFacetValue(type);
24167:     } else
24168: 	ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
24169:     /*
24170:     * If the value was not computed (for string or
24171:     * anySimpleType based types), then use the provided
24172:     * type.
24173:     */
24174:     if (val == NULL)
24175: 	valType = valType;
24176:     else
24177: 	valType = xmlSchemaGetValType(val);
24178: 
24179:     ret = 0;
24180:     for (facetLink = type->facetSet; facetLink != NULL;
24181: 	facetLink = facetLink->next) {
24182: 	/*
24183: 	* Skip the pattern "whiteSpace": it is used to
24184: 	* format the character content beforehand.
24185: 	*/
24186: 	switch (facetLink->facet->type) {
24187: 	    case XML_SCHEMA_FACET_WHITESPACE:
24188: 	    case XML_SCHEMA_FACET_PATTERN:
24189: 	    case XML_SCHEMA_FACET_ENUMERATION:
24190: 		continue;
24191: 	    case XML_SCHEMA_FACET_LENGTH:
24192: 	    case XML_SCHEMA_FACET_MINLENGTH:
24193: 	    case XML_SCHEMA_FACET_MAXLENGTH:
24194: 		ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
24195: 		    valType, value, val, &len, ws);
24196: 		break;
24197: 	    default:
24198: 		ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
24199: 		    valType, value, val, ws);
24200: 		break;
24201: 	}
24202: 	if (ret < 0) {
24203: 	    AERROR_INT("xmlSchemaValidateFacets",
24204: 		"validating against a atomic type facet");
24205: 	    return (-1);
24206: 	} else if (ret > 0) {
24207: 	    if (fireErrors)
24208: 		xmlSchemaFacetErr(actxt, ret, node,
24209: 		value, len, type, facetLink->facet, NULL, NULL, NULL);
24210: 	    else
24211: 		return (ret);
24212: 	    if (error == 0)
24213: 		error = ret;
24214: 	}
24215: 	ret = 0;
24216:     }
24217: 
24218: WXS_IS_LIST:
24219:     if (! WXS_IS_LIST(type))
24220: 	goto pattern_and_enum;
24221:     /*
24222:     * "length", "minLength" and "maxLength" of list types.
24223:     */
24224:     ret = 0;
24225:     for (facetLink = type->facetSet; facetLink != NULL;
24226: 	facetLink = facetLink->next) {
24227: 
24228: 	switch (facetLink->facet->type) {
24229: 	    case XML_SCHEMA_FACET_LENGTH:
24230: 	    case XML_SCHEMA_FACET_MINLENGTH:
24231: 	    case XML_SCHEMA_FACET_MAXLENGTH:
24232: 		ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
24233: 		    value, length, NULL);
24234: 		break;
24235: 	    default:
24236: 		continue;
24237: 	}
24238: 	if (ret < 0) {
24239: 	    AERROR_INT("xmlSchemaValidateFacets",
24240: 		"validating against a list type facet");
24241: 	    return (-1);
24242: 	} else if (ret > 0) {
24243: 	    if (fireErrors)
24244: 		xmlSchemaFacetErr(actxt, ret, node,
24245: 		value, length, type, facetLink->facet, NULL, NULL, NULL);
24246: 	    else
24247: 		return (ret);
24248: 	    if (error == 0)
24249: 		error = ret;
24250: 	}
24251: 	ret = 0;
24252:     }
24253: 
24254: pattern_and_enum:
24255:     if (error >= 0) {
24256: 	int found = 0;
24257: 	/*
24258: 	* Process enumerations. Facet values are in the value space
24259: 	* of the defining type's base type. This seems to be a bug in the
24260: 	* XML Schema 1.0 spec. Use the whitespace type of the base type.
24261: 	* Only the first set of enumerations in the ancestor-or-self axis
24262: 	* is used for validation.
24263: 	*/
24264: 	ret = 0;
24265: 	tmpType = type;
24266: 	do {
24267: 	    for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
24268: 		if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
24269: 		    continue;
24270: 		found = 1;
24271: 		ret = xmlSchemaAreValuesEqual(facet->val, val);
24272: 		if (ret == 1)
24273: 		    break;
24274: 		else if (ret < 0) {
24275: 		    AERROR_INT("xmlSchemaValidateFacets",
24276: 			"validating against an enumeration facet");
24277: 		    return (-1);
24278: 		}
24279: 	    }
24280: 	    if (ret != 0)
24281: 		break;
24282: 	    /*
24283: 	    * Break on the first set of enumerations. Any additional
24284: 	    *  enumerations which might be existent on the ancestors
24285: 	    *  of the current type are restricted by this set; thus
24286: 	    *  *must* *not* be taken into account.
24287: 	    */
24288: 	    if (found)
24289: 		break;
24290: 	    tmpType = tmpType->baseType;
24291: 	} while ((tmpType != NULL) &&
24292: 	    (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24293: 	if (found && (ret == 0)) {
24294: 	    ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
24295: 	    if (fireErrors) {
24296: 		xmlSchemaFacetErr(actxt, ret, node,
24297: 		    value, 0, type, NULL, NULL, NULL, NULL);
24298: 	    } else
24299: 		return (ret);
24300: 	    if (error == 0)
24301: 		error = ret;
24302: 	}
24303:     }
24304: 
24305:     if (error >= 0) {
24306: 	int found;
24307: 	/*
24308: 	* Process patters. Pattern facets are ORed at type level
24309: 	* and ANDed if derived. Walk the base type axis.
24310: 	*/
24311: 	tmpType = type;
24312: 	facet = NULL;
24313: 	do {
24314: 	    found = 0;
24315: 	    for (facetLink = tmpType->facetSet; facetLink != NULL;
24316: 		facetLink = facetLink->next) {
24317: 		if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
24318: 		    continue;
24319: 		found = 1;
24320: 		/*
24321: 		* NOTE that for patterns, @value needs to be the
24322: 		* normalized vaule.
24323: 		*/
24324: 		ret = xmlRegexpExec(facetLink->facet->regexp, value);
24325: 		if (ret == 1)
24326: 		    break;
24327: 		else if (ret < 0) {
24328: 		    AERROR_INT("xmlSchemaValidateFacets",
24329: 			"validating against a pattern facet");
24330: 		    return (-1);
24331: 		} else {
24332: 		    /*
24333: 		    * Save the last non-validating facet.
24334: 		    */
24335: 		    facet = facetLink->facet;
24336: 		}
24337: 	    }
24338: 	    if (found && (ret != 1)) {
24339: 		ret = XML_SCHEMAV_CVC_PATTERN_VALID;
24340: 		if (fireErrors) {
24341: 		    xmlSchemaFacetErr(actxt, ret, node,
24342: 			value, 0, type, facet, NULL, NULL, NULL);
24343: 		} else
24344: 		    return (ret);
24345: 		if (error == 0)
24346: 		    error = ret;
24347: 		break;
24348: 	    }
24349: 	    tmpType = tmpType->baseType;
24350: 	} while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
24351:     }
24352: 
24353:     return (error);
24354: }
24355: 
24356: static xmlChar *
24357: xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
24358: 			const xmlChar *value)
24359: {
24360:     switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
24361: 	case XML_SCHEMA_WHITESPACE_COLLAPSE:
24362: 	    return (xmlSchemaCollapseString(value));
24363: 	case XML_SCHEMA_WHITESPACE_REPLACE:
24364: 	    return (xmlSchemaWhiteSpaceReplace(value));
24365: 	default:
24366: 	    return (NULL);
24367:     }
24368: }
24369: 
24370: static int
24371: xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
24372: 		       const xmlChar *value,
24373: 		       xmlSchemaValPtr *val,
24374: 		       int valNeeded)
24375: {
24376:     int ret;
24377:     const xmlChar *nsName;
24378:     xmlChar *local, *prefix = NULL;
24379: 
24380:     ret = xmlValidateQName(value, 1);
24381:     if (ret != 0) {
24382: 	if (ret == -1) {
24383: 	    VERROR_INT("xmlSchemaValidateQName",
24384: 		"calling xmlValidateQName()");
24385: 	    return (-1);
24386: 	}
24387: 	return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
24388:     }
24389:     /*
24390:     * NOTE: xmlSplitQName2 will always return a duplicated
24391:     * strings.
24392:     */
24393:     local = xmlSplitQName2(value, &prefix);
24394:     if (local == NULL)
24395: 	local = xmlStrdup(value);
24396:     /*
24397:     * OPTIMIZE TODO: Use flags for:
24398:     *  - is there any namespace binding?
24399:     *  - is there a default namespace?
24400:     */
24401:     nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24402: 
24403:     if (prefix != NULL) {
24404: 	xmlFree(prefix);
24405: 	/*
24406: 	* A namespace must be found if the prefix is
24407: 	* NOT NULL.
24408: 	*/
24409: 	if (nsName == NULL) {
24410: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24411: 	    xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
24412: 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24413: 		"The QName value '%s' has no "
24414: 		"corresponding namespace declaration in "
24415: 		"scope", value, NULL);
24416: 	    if (local != NULL)
24417: 		xmlFree(local);
24418: 	    return (ret);
24419: 	}
24420:     }
24421:     if (valNeeded && val) {
24422: 	if (nsName != NULL)
24423: 	    *val = xmlSchemaNewQNameValue(
24424: 		BAD_CAST xmlStrdup(nsName), BAD_CAST local);
24425: 	else
24426: 	    *val = xmlSchemaNewQNameValue(NULL,
24427: 		BAD_CAST local);
24428:     } else
24429: 	xmlFree(local);
24430:     return (0);
24431: }
24432: 
24433: /*
24434: * cvc-simple-type
24435: */
24436: static int
24437: xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
24438: 			     xmlNodePtr node,
24439: 			     xmlSchemaTypePtr type,
24440: 			     const xmlChar *value,
24441: 			     xmlSchemaValPtr *retVal,
24442: 			     int fireErrors,
24443: 			     int normalize,
24444: 			     int isNormalized)
24445: {
24446:     int ret = 0, valNeeded = (retVal) ? 1 : 0;
24447:     xmlSchemaValPtr val = NULL;
24448:     /* xmlSchemaWhitespaceValueType ws; */
24449:     xmlChar *normValue = NULL;
24450: 
24451: #define NORMALIZE(atype) \
24452:     if ((! isNormalized) && \
24453:     (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
24454: 	normValue = xmlSchemaNormalizeValue(atype, value); \
24455: 	if (normValue != NULL) \
24456: 	    value = normValue; \
24457: 	isNormalized = 1; \
24458:     }
24459: 
24460:     if ((retVal != NULL) && (*retVal != NULL)) {
24461: 	xmlSchemaFreeValue(*retVal);
24462: 	*retVal = NULL;
24463:     }
24464:     /*
24465:     * 3.14.4 Simple Type Definition Validation Rules
24466:     * Validation Rule: String Valid
24467:     */
24468:     /*
24469:     * 1 It is schema-valid with respect to that definition as defined
24470:     * by Datatype Valid in [XML Schemas: Datatypes].
24471:     */
24472:     /*
24473:     * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
24474:     * the empty set, as defined in Type Derivation OK (Simple) (�3.14.6), then
24475:     * the string must be a �declared entity name�.
24476:     */
24477:     /*
24478:     * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
24479:     * given the empty set, as defined in Type Derivation OK (Simple) (�3.14.6),
24480:     * then every whitespace-delimited substring of the string must be a �declared
24481:     * entity name�.
24482:     */
24483:     /*
24484:     * 2.3 otherwise no further condition applies.
24485:     */
24486:     if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
24487: 	valNeeded = 1;
24488:     if (value == NULL)
24489: 	value = BAD_CAST "";
24490:     if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
24491: 	xmlSchemaTypePtr biType; /* The built-in type. */
24492: 	/*
24493: 	* SPEC (1.2.1) "if {variety} is �atomic� then the string must �match�
24494: 	* a literal in the �lexical space� of {base type definition}"
24495: 	*/
24496: 	/*
24497: 	* Whitespace-normalize.
24498: 	*/
24499: 	NORMALIZE(type);
24500: 	if (type->type != XML_SCHEMA_TYPE_BASIC) {
24501: 	    /*
24502: 	    * Get the built-in type.
24503: 	    */
24504: 	    biType = type->baseType;
24505: 	    while ((biType != NULL) &&
24506: 		(biType->type != XML_SCHEMA_TYPE_BASIC))
24507: 		biType = biType->baseType;
24508: 
24509: 	    if (biType == NULL) {
24510: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24511: 		    "could not get the built-in type");
24512: 		goto internal_error;
24513: 	    }
24514: 	} else
24515: 	    biType = type;
24516: 	/*
24517: 	* NOTATIONs need to be processed here, since they need
24518: 	* to lookup in the hashtable of NOTATION declarations of the schema.
24519: 	*/
24520: 	if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
24521: 	    switch (biType->builtInType) {
24522: 		case XML_SCHEMAS_NOTATION:
24523: 		    ret = xmlSchemaValidateNotation(
24524: 			(xmlSchemaValidCtxtPtr) actxt,
24525: 			((xmlSchemaValidCtxtPtr) actxt)->schema,
24526: 			NULL, value, &val, valNeeded);
24527: 		    break;
24528: 		case XML_SCHEMAS_QNAME:
24529: 		    ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
24530: 			value, &val, valNeeded);
24531: 		    break;
24532: 		default:
24533: 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24534: 		    if (valNeeded)
24535: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24536: 			    value, &val, node);
24537: 		    else
24538: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24539: 			    value, NULL, node);
24540: 		    break;
24541: 	    }
24542: 	} else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
24543: 	    switch (biType->builtInType) {
24544: 		case XML_SCHEMAS_NOTATION:
24545: 		    ret = xmlSchemaValidateNotation(NULL,
24546: 			((xmlSchemaParserCtxtPtr) actxt)->schema, node,
24547: 			value, &val, valNeeded);
24548: 		    break;
24549: 		default:
24550: 		    /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
24551: 		    if (valNeeded)
24552: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24553: 			    value, &val, node);
24554: 		    else
24555: 			ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
24556: 			    value, NULL, node);
24557: 		    break;
24558: 	    }
24559: 	} else {
24560: 	    /*
24561: 	    * Validation via a public API is not implemented yet.
24562: 	    */
24563: 	    TODO
24564: 	    goto internal_error;
24565: 	}
24566: 	if (ret != 0) {
24567: 	    if (ret < 0) {
24568: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24569: 		    "validating against a built-in type");
24570: 		goto internal_error;
24571: 	    }
24572: 	    if (WXS_IS_LIST(type))
24573: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24574: 	    else
24575: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24576: 	}
24577: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24578: 	    /*
24579: 	    * Check facets.
24580: 	    */
24581: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24582: 		(xmlSchemaValType) biType->builtInType, value, val,
24583: 		0, fireErrors);
24584: 	    if (ret != 0) {
24585: 		if (ret < 0) {
24586: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24587: 			"validating facets of atomic simple type");
24588: 		    goto internal_error;
24589: 		}
24590: 		if (WXS_IS_LIST(type))
24591: 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24592: 		else
24593: 		    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
24594: 	    }
24595: 	}
24596: 	if (fireErrors && (ret > 0))
24597: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24598:     } else if (WXS_IS_LIST(type)) {
24599: 
24600: 	xmlSchemaTypePtr itemType;
24601: 	const xmlChar *cur, *end;
24602: 	xmlChar *tmpValue = NULL;
24603: 	unsigned long len = 0;
24604: 	xmlSchemaValPtr prevVal = NULL, curVal = NULL;
24605: 	/* 1.2.2 if {variety} is �list� then the string must be a sequence
24606: 	* of white space separated tokens, each of which �match�es a literal
24607: 	* in the �lexical space� of {item type definition}
24608: 	*/
24609: 	/*
24610: 	* Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
24611: 	* the list type has an enum or pattern facet.
24612: 	*/
24613: 	NORMALIZE(type);
24614: 	/*
24615: 	* VAL TODO: Optimize validation of empty values.
24616: 	* VAL TODO: We do not have computed values for lists.
24617: 	*/
24618: 	itemType = WXS_LIST_ITEMTYPE(type);
24619: 	cur = value;
24620: 	do {
24621: 	    while (IS_BLANK_CH(*cur))
24622: 		cur++;
24623: 	    end = cur;
24624: 	    while ((*end != 0) && (!(IS_BLANK_CH(*end))))
24625: 		end++;
24626: 	    if (end == cur)
24627: 		break;
24628: 	    tmpValue = xmlStrndup(cur, end - cur);
24629: 	    len++;
24630: 
24631: 	    if (valNeeded)
24632: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24633: 		    tmpValue, &curVal, fireErrors, 0, 1);
24634: 	    else
24635: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
24636: 		    tmpValue, NULL, fireErrors, 0, 1);
24637: 	    FREE_AND_NULL(tmpValue);
24638: 	    if (curVal != NULL) {
24639: 		/*
24640: 		* Add to list of computed values.
24641: 		*/
24642: 		if (val == NULL)
24643: 		    val = curVal;
24644: 		else
24645: 		    xmlSchemaValueAppend(prevVal, curVal);
24646: 		prevVal = curVal;
24647: 		curVal = NULL;
24648: 	    }
24649: 	    if (ret != 0) {
24650: 		if (ret < 0) {
24651: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24652: 			"validating an item of list simple type");
24653: 		    goto internal_error;
24654: 		}
24655: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24656: 		break;
24657: 	    }
24658: 	    cur = end;
24659: 	} while (*cur != 0);
24660: 	FREE_AND_NULL(tmpValue);
24661: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24662: 	    /*
24663: 	    * Apply facets (pattern, enumeration).
24664: 	    */
24665: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24666: 		XML_SCHEMAS_UNKNOWN, value, val,
24667: 		len, fireErrors);
24668: 	    if (ret != 0) {
24669: 		if (ret < 0) {
24670: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24671: 			"validating facets of list simple type");
24672: 		    goto internal_error;
24673: 		}
24674: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
24675: 	    }
24676: 	}
24677: 	if (fireErrors && (ret > 0)) {
24678: 	    /*
24679: 	    * Report the normalized value.
24680: 	    */
24681: 	    normalize = 1;
24682: 	    NORMALIZE(type);
24683: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24684: 	}
24685:     } else if (WXS_IS_UNION(type)) {
24686: 	xmlSchemaTypeLinkPtr memberLink;
24687: 	/*
24688: 	* TODO: For all datatypes �derived� by �union�  whiteSpace does
24689: 	* not apply directly; however, the normalization behavior of �union�
24690: 	* types is controlled by the value of whiteSpace on that one of the
24691: 	* �memberTypes� against which the �union� is successfully validated.
24692: 	*
24693: 	* This means that the value is normalized by the first validating
24694: 	* member type, then the facets of the union type are applied. This
24695: 	* needs changing of the value!
24696: 	*/
24697: 
24698: 	/*
24699: 	* 1.2.3 if {variety} is �union� then the string must �match� a
24700: 	* literal in the �lexical space� of at least one member of
24701: 	* {member type definitions}
24702: 	*/
24703: 	memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
24704: 	if (memberLink == NULL) {
24705: 	    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24706: 		"union simple type has no member types");
24707: 	    goto internal_error;
24708: 	}
24709: 	/*
24710: 	* Always normalize union type values, since we currently
24711: 	* cannot store the whitespace information with the value
24712: 	* itself; otherwise a later value-comparison would be
24713: 	* not possible.
24714: 	*/
24715: 	while (memberLink != NULL) {
24716: 	    if (valNeeded)
24717: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24718: 		    memberLink->type, value, &val, 0, 1, 0);
24719: 	    else
24720: 		ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
24721: 		    memberLink->type, value, NULL, 0, 1, 0);
24722: 	    if (ret <= 0)
24723: 		break;
24724: 	    memberLink = memberLink->next;
24725: 	}
24726: 	if (ret != 0) {
24727: 	    if (ret < 0) {
24728: 		AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24729: 		    "validating members of union simple type");
24730: 		goto internal_error;
24731: 	    }
24732: 	    ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24733: 	}
24734: 	/*
24735: 	* Apply facets (pattern, enumeration).
24736: 	*/
24737: 	if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
24738: 	    /*
24739: 	    * The normalization behavior of �union� types is controlled by
24740: 	    * the value of whiteSpace on that one of the �memberTypes�
24741: 	    * against which the �union� is successfully validated.
24742: 	    */
24743: 	    NORMALIZE(memberLink->type);
24744: 	    ret = xmlSchemaValidateFacets(actxt, node, type,
24745: 		XML_SCHEMAS_UNKNOWN, value, val,
24746: 		0, fireErrors);
24747: 	    if (ret != 0) {
24748: 		if (ret < 0) {
24749: 		    AERROR_INT("xmlSchemaVCheckCVCSimpleType",
24750: 			"validating facets of union simple type");
24751: 		    goto internal_error;
24752: 		}
24753: 		ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
24754: 	    }
24755: 	}
24756: 	if (fireErrors && (ret > 0))
24757: 	    xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
24758:     }
24759: 
24760:     if (normValue != NULL)
24761: 	xmlFree(normValue);
24762:     if (ret == 0) {
24763: 	if (retVal != NULL)
24764: 	    *retVal = val;
24765: 	else if (val != NULL)
24766: 	    xmlSchemaFreeValue(val);
24767:     } else if (val != NULL)
24768: 	xmlSchemaFreeValue(val);
24769:     return (ret);
24770: internal_error:
24771:     if (normValue != NULL)
24772: 	xmlFree(normValue);
24773:     if (val != NULL)
24774: 	xmlSchemaFreeValue(val);
24775:     return (-1);
24776: }
24777: 
24778: static int
24779: xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
24780: 			   const xmlChar *value,
24781: 			   const xmlChar **nsName,
24782: 			   const xmlChar **localName)
24783: {
24784:     int ret = 0;
24785: 
24786:     if ((nsName == NULL) || (localName == NULL))
24787: 	return (-1);
24788:     *nsName = NULL;
24789:     *localName = NULL;
24790: 
24791:     ret = xmlValidateQName(value, 1);
24792:     if (ret == -1)
24793: 	return (-1);
24794:     if (ret > 0) {
24795: 	xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
24796: 	    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24797: 	    value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
24798: 	return (1);
24799:     }
24800:     {
24801: 	xmlChar *local = NULL;
24802: 	xmlChar *prefix;
24803: 
24804: 	/*
24805: 	* NOTE: xmlSplitQName2 will return a duplicated
24806: 	* string.
24807: 	*/
24808: 	local = xmlSplitQName2(value, &prefix);
24809: 	if (local == NULL)
24810: 	    *localName = xmlDictLookup(vctxt->dict, value, -1);
24811: 	else {
24812: 	    *localName = xmlDictLookup(vctxt->dict, local, -1);
24813: 	    xmlFree(local);
24814: 	}
24815: 
24816: 	*nsName = xmlSchemaLookupNamespace(vctxt, prefix);
24817: 
24818: 	if (prefix != NULL) {
24819: 	    xmlFree(prefix);
24820: 	    /*
24821: 	    * A namespace must be found if the prefix is NOT NULL.
24822: 	    */
24823: 	    if (*nsName == NULL) {
24824: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
24825: 		    XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
24826: 		    WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24827: 		    "The QName value '%s' has no "
24828: 		    "corresponding namespace declaration in scope",
24829: 		    value, NULL);
24830: 		return (2);
24831: 	    }
24832: 	}
24833:     }
24834:     return (0);
24835: }
24836: 
24837: static int
24838: xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
24839: 			xmlSchemaAttrInfoPtr iattr,
24840: 			xmlSchemaTypePtr *localType,
24841: 			xmlSchemaElementPtr elemDecl)
24842: {
24843:     int ret = 0;
24844:     /*
24845:     * cvc-elt (3.3.4) : (4)
24846:     * AND
24847:     * Schema-Validity Assessment (Element) (cvc-assess-elt)
24848:     *   (1.2.1.2.1) - (1.2.1.2.4)
24849:     * Handle 'xsi:type'.
24850:     */
24851:     if (localType == NULL)
24852: 	return (-1);
24853:     *localType = NULL;
24854:     if (iattr == NULL)
24855: 	return (0);
24856:     else {
24857: 	const xmlChar *nsName = NULL, *local = NULL;
24858: 	/*
24859: 	* TODO: We should report a *warning* that the type was overriden
24860: 	* by the instance.
24861: 	*/
24862: 	ACTIVATE_ATTRIBUTE(iattr);
24863: 	/*
24864: 	* (cvc-elt) (3.3.4) : (4.1)
24865: 	* (cvc-assess-elt) (1.2.1.2.2)
24866: 	*/
24867: 	ret = xmlSchemaVExpandQName(vctxt, iattr->value,
24868: 	    &nsName, &local);
24869: 	if (ret != 0) {
24870: 	    if (ret < 0) {
24871: 		VERROR_INT("xmlSchemaValidateElementByDeclaration",
24872: 		    "calling xmlSchemaQNameExpand() to validate the "
24873: 		    "attribute 'xsi:type'");
24874: 		goto internal_error;
24875: 	    }
24876: 	    goto exit;
24877: 	}
24878: 	/*
24879: 	* (cvc-elt) (3.3.4) : (4.2)
24880: 	* (cvc-assess-elt) (1.2.1.2.3)
24881: 	*/
24882: 	*localType = xmlSchemaGetType(vctxt->schema, local, nsName);
24883: 	if (*localType == NULL) {
24884: 	    xmlChar *str = NULL;
24885: 
24886: 	    xmlSchemaCustomErr(ACTXT_CAST vctxt,
24887: 		XML_SCHEMAV_CVC_ELT_4_2, NULL,
24888: 		WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
24889: 		"The QName value '%s' of the xsi:type attribute does not "
24890: 		"resolve to a type definition",
24891: 		xmlSchemaFormatQName(&str, nsName, local), NULL);
24892: 	    FREE_AND_NULL(str);
24893: 	    ret = vctxt->err;
24894: 	    goto exit;
24895: 	}
24896: 	if (elemDecl != NULL) {
24897: 	    int set = 0;
24898: 
24899: 	    /*
24900: 	    * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
24901: 	    * "The �local type definition� must be validly
24902: 	    * derived from the {type definition} given the union of
24903: 	    * the {disallowed substitutions} and the {type definition}'s
24904: 	    * {prohibited substitutions}, as defined in
24905: 	    * Type Derivation OK (Complex) (�3.4.6)
24906: 	    * (if it is a complex type definition),
24907: 	    * or given {disallowed substitutions} as defined in Type
24908: 	    * Derivation OK (Simple) (�3.14.6) (if it is a simple type
24909: 	    * definition)."
24910: 	    *
24911: 	    * {disallowed substitutions}: the "block" on the element decl.
24912: 	    * {prohibited substitutions}: the "block" on the type def.
24913: 	    */
24914: 	    /*
24915: 	    * OPTIMIZE TODO: We could map types already evaluated
24916: 	    * to be validly derived from other types to avoid checking
24917: 	    * this over and over for the same types.
24918: 	    */
24919: 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
24920: 		(elemDecl->subtypes->flags &
24921: 		    XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
24922: 		set |= SUBSET_EXTENSION;
24923: 
24924: 	    if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
24925: 		(elemDecl->subtypes->flags &
24926: 		    XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
24927: 		set |= SUBSET_RESTRICTION;
24928: 
24929: 	    /*
24930: 	    * REMOVED and CHANGED since this produced a parser context
24931: 	    * which adds to the string dict of the schema. So this would
24932: 	    * change the schema and we don't want this. We don't need
24933: 	    * the parser context anymore.
24934: 	    *
24935: 	    * if ((vctxt->pctxt == NULL) &&
24936: 	    *	(xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
24937: 	    *	    return (-1);
24938: 	    */
24939: 
24940: 	    if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
24941: 		elemDecl->subtypes, set) != 0) {
24942: 		xmlChar *str = NULL;
24943: 
24944: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
24945: 		    XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
24946: 		    "The type definition '%s', specified by xsi:type, is "
24947: 		    "blocked or not validly derived from the type definition "
24948: 		    "of the element declaration",
24949: 		    xmlSchemaFormatQName(&str,
24950: 			(*localType)->targetNamespace,
24951: 			(*localType)->name),
24952: 		    NULL);
24953: 		FREE_AND_NULL(str);
24954: 		ret = vctxt->err;
24955: 		*localType = NULL;
24956: 	    }
24957: 	}
24958:     }
24959: exit:
24960:     ACTIVATE_ELEM;
24961:     return (ret);
24962: internal_error:
24963:     ACTIVATE_ELEM;
24964:     return (-1);
24965: }
24966: 
24967: static int
24968: xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
24969: {
24970:     xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
24971:     xmlSchemaTypePtr actualType;
24972: 
24973:     /*
24974:     * cvc-elt (3.3.4) : 1
24975:     */
24976:     if (elemDecl == NULL) {
24977: 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
24978: 	    "No matching declaration available");
24979:         return (vctxt->err);
24980:     }
24981:     actualType = WXS_ELEM_TYPEDEF(elemDecl);
24982:     /*
24983:     * cvc-elt (3.3.4) : 2
24984:     */
24985:     if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
24986: 	VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
24987: 	    "The element declaration is abstract");
24988:         return (vctxt->err);
24989:     }
24990:     if (actualType == NULL) {
24991:     	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
24992:     	    "The type definition is absent");
24993:     	return (XML_SCHEMAV_CVC_TYPE_1);
24994:     }
24995:     if (vctxt->nbAttrInfos != 0) {
24996: 	int ret;
24997: 	xmlSchemaAttrInfoPtr iattr;
24998: 	/*
24999: 	* cvc-elt (3.3.4) : 3
25000: 	* Handle 'xsi:nil'.
25001: 	*/
25002: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25003: 	    XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
25004: 	if (iattr) {
25005: 	    ACTIVATE_ATTRIBUTE(iattr);
25006: 	    /*
25007: 	    * Validate the value.
25008: 	    */
25009: 	    ret = xmlSchemaVCheckCVCSimpleType(
25010: 		ACTXT_CAST vctxt, NULL,
25011: 		xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
25012: 		iattr->value, &(iattr->val), 1, 0, 0);
25013: 	    ACTIVATE_ELEM;
25014: 	    if (ret < 0) {
25015: 		VERROR_INT("xmlSchemaValidateElemDecl",
25016: 		    "calling xmlSchemaVCheckCVCSimpleType() to "
25017: 		    "validate the attribute 'xsi:nil'");
25018: 		return (-1);
25019: 	    }
25020: 	    if (ret == 0) {
25021: 		if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
25022: 		    /*
25023: 		    * cvc-elt (3.3.4) : 3.1
25024: 		    */
25025: 		    VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
25026: 			"The element is not 'nillable'");
25027: 		    /* Does not return an error on purpose. */
25028: 		} else {
25029: 		    if (xmlSchemaValueGetAsBoolean(iattr->val)) {
25030: 			/*
25031: 			* cvc-elt (3.3.4) : 3.2.2
25032: 			*/
25033: 			if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
25034: 			    (elemDecl->value != NULL)) {
25035: 			    VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
25036: 				"The element cannot be 'nilled' because "
25037: 				"there is a fixed value constraint defined "
25038: 				"for it");
25039: 			     /* Does not return an error on purpose. */
25040: 			} else
25041: 			    vctxt->inode->flags |=
25042: 				XML_SCHEMA_ELEM_INFO_NILLED;
25043: 		    }
25044: 		}
25045: 	    }
25046: 	}
25047: 	/*
25048: 	* cvc-elt (3.3.4) : 4
25049: 	* Handle 'xsi:type'.
25050: 	*/
25051: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25052: 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25053: 	if (iattr) {
25054: 	    xmlSchemaTypePtr localType = NULL;
25055: 
25056: 	    ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
25057: 		elemDecl);
25058: 	    if (ret != 0) {
25059: 		if (ret == -1) {
25060: 		    VERROR_INT("xmlSchemaValidateElemDecl",
25061: 			"calling xmlSchemaProcessXSIType() to "
25062: 			"process the attribute 'xsi:type'");
25063: 		    return (-1);
25064: 		}
25065: 		/* Does not return an error on purpose. */
25066: 	    }
25067: 	    if (localType != NULL) {
25068: 		vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
25069: 		actualType = localType;
25070: 	    }
25071: 	}
25072:     }
25073:     /*
25074:     * IDC: Register identity-constraint XPath matchers.
25075:     */
25076:     if ((elemDecl->idcs != NULL) &&
25077: 	(xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
25078: 	    return (-1);
25079:     /*
25080:     * No actual type definition.
25081:     */
25082:     if (actualType == NULL) {
25083:     	VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
25084:     	    "The type definition is absent");
25085:     	return (XML_SCHEMAV_CVC_TYPE_1);
25086:     }
25087:     /*
25088:     * Remember the actual type definition.
25089:     */
25090:     vctxt->inode->typeDef = actualType;
25091: 
25092:     return (0);
25093: }
25094: 
25095: static int
25096: xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
25097: {
25098:     xmlSchemaAttrInfoPtr iattr;
25099:     int ret = 0, i;
25100: 
25101:     /*
25102:     * SPEC cvc-type (3.1.1)
25103:     * "The attributes of must be empty, excepting those whose namespace
25104:     * name is identical to http://www.w3.org/2001/XMLSchema-instance and
25105:     * whose local name is one of type, nil, schemaLocation or
25106:     * noNamespaceSchemaLocation."
25107:     */
25108:     if (vctxt->nbAttrInfos == 0)
25109: 	return (0);
25110:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25111: 	iattr = vctxt->attrInfos[i];
25112: 	if (! iattr->metaType) {
25113: 	    ACTIVATE_ATTRIBUTE(iattr)
25114: 	    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25115: 		XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
25116: 	    ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
25117:         }
25118:     }
25119:     ACTIVATE_ELEM
25120:     return (ret);
25121: }
25122: 
25123: /*
25124: * Cleanup currently used attribute infos.
25125: */
25126: static void
25127: xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
25128: {
25129:     int i;
25130:     xmlSchemaAttrInfoPtr attr;
25131: 
25132:     if (vctxt->nbAttrInfos == 0)
25133: 	return;
25134:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25135: 	attr = vctxt->attrInfos[i];
25136: 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
25137: 	    if (attr->localName != NULL)
25138: 		xmlFree((xmlChar *) attr->localName);
25139: 	    if (attr->nsName != NULL)
25140: 		xmlFree((xmlChar *) attr->nsName);
25141: 	}
25142: 	if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
25143: 	    if (attr->value != NULL)
25144: 		xmlFree((xmlChar *) attr->value);
25145: 	}
25146: 	if (attr->val != NULL) {
25147: 	    xmlSchemaFreeValue(attr->val);
25148: 	    attr->val = NULL;
25149: 	}
25150: 	memset(attr, 0, sizeof(xmlSchemaAttrInfo));
25151:     }
25152:     vctxt->nbAttrInfos = 0;
25153: }
25154: 
25155: /*
25156: * 3.4.4 Complex Type Definition Validation Rules
25157: *   Element Locally Valid (Complex Type) (cvc-complex-type)
25158: * 3.2.4 Attribute Declaration Validation Rules
25159: *   Validation Rule: Attribute Locally Valid (cvc-attribute)
25160: *   Attribute Locally Valid (Use) (cvc-au)
25161: *
25162: * Only "assessed" attribute information items will be visible to
25163: * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
25164: */
25165: static int
25166: xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
25167: {
25168:     xmlSchemaTypePtr type = vctxt->inode->typeDef;
25169:     xmlSchemaItemListPtr attrUseList;
25170:     xmlSchemaAttributeUsePtr attrUse = NULL;
25171:     xmlSchemaAttributePtr attrDecl = NULL;
25172:     xmlSchemaAttrInfoPtr iattr, tmpiattr;
25173:     int i, j, found, nbAttrs, nbUses;
25174:     int xpathRes = 0, res, wildIDs = 0, fixed;
25175:     xmlNodePtr defAttrOwnerElem = NULL;
25176: 
25177:     /*
25178:     * SPEC (cvc-attribute)
25179:     * (1) "The declaration must not be �absent� (see Missing
25180:     * Sub-components (�5.3) for how this can fail to be
25181:     * the case)."
25182:     * (2) "Its {type definition} must not be absent."
25183:     *
25184:     * NOTE (1) + (2): This is not handled here, since we currently do not
25185:     * allow validation against schemas which have missing sub-components.
25186:     *
25187:     * SPEC (cvc-complex-type)
25188:     * (3) "For each attribute information item in the element information
25189:     * item's [attributes] excepting those whose [namespace name] is
25190:     * identical to http://www.w3.org/2001/XMLSchema-instance and whose
25191:     * [local name] is one of type, nil, schemaLocation or
25192:     * noNamespaceSchemaLocation, the appropriate case among the following
25193:     * must be true:
25194:     *
25195:     */
25196:     attrUseList = (xmlSchemaItemListPtr) type->attrUses;
25197:     /*
25198:     * @nbAttrs is the number of attributes present in the instance.
25199:     */
25200:     nbAttrs = vctxt->nbAttrInfos;
25201:     if (attrUseList != NULL)
25202: 	nbUses = attrUseList->nbItems;
25203:     else
25204: 	nbUses = 0;
25205:     for (i = 0; i < nbUses; i++) {
25206:         found = 0;
25207: 	attrUse = attrUseList->items[i];
25208: 	attrDecl = WXS_ATTRUSE_DECL(attrUse);
25209:         for (j = 0; j < nbAttrs; j++) {
25210: 	    iattr = vctxt->attrInfos[j];
25211: 	    /*
25212: 	    * SPEC (cvc-complex-type) (3)
25213: 	    * Skip meta attributes.
25214: 	    */
25215: 	    if (iattr->metaType)
25216: 		continue;
25217: 	    if (iattr->localName[0] != attrDecl->name[0])
25218: 		continue;
25219: 	    if (!xmlStrEqual(iattr->localName, attrDecl->name))
25220: 		continue;
25221: 	    if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
25222: 		continue;
25223: 	    found = 1;
25224: 	    /*
25225: 	    * SPEC (cvc-complex-type)
25226: 	    * (3.1) "If there is among the {attribute uses} an attribute
25227: 	    * use with an {attribute declaration} whose {name} matches
25228: 	    * the attribute information item's [local name] and whose
25229: 	    * {target namespace} is identical to the attribute information
25230: 	    * item's [namespace name] (where an �absent� {target namespace}
25231: 	    * is taken to be identical to a [namespace name] with no value),
25232: 	    * then the attribute information must be �valid� with respect
25233: 	    * to that attribute use as per Attribute Locally Valid (Use)
25234: 	    * (�3.5.4). In this case the {attribute declaration} of that
25235: 	    * attribute use is the �context-determined declaration� for the
25236: 	    * attribute information item with respect to Schema-Validity
25237: 	    * Assessment (Attribute) (�3.2.4) and
25238: 	    * Assessment Outcome (Attribute) (�3.2.5).
25239: 	    */
25240: 	    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25241: 	    iattr->use = attrUse;
25242: 	    /*
25243: 	    * Context-determined declaration.
25244: 	    */
25245: 	    iattr->decl = attrDecl;
25246: 	    iattr->typeDef = attrDecl->subtypes;
25247: 	    break;
25248: 	}
25249: 
25250: 	if (found)
25251: 	    continue;
25252: 
25253: 	if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
25254: 	    /*
25255: 	    * Handle non-existent, required attributes.
25256: 	    *
25257: 	    * SPEC (cvc-complex-type)
25258: 	    * (4) "The {attribute declaration} of each attribute use in
25259: 	    * the {attribute uses} whose {required} is true matches one
25260: 	    * of the attribute information items in the element information
25261: 	    * item's [attributes] as per clause 3.1 above."
25262: 	    */
25263: 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25264: 	    if (tmpiattr == NULL) {
25265: 		VERROR_INT(
25266: 		    "xmlSchemaVAttributesComplex",
25267: 		    "calling xmlSchemaGetFreshAttrInfo()");
25268: 		return (-1);
25269: 	    }
25270: 	    tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
25271: 	    tmpiattr->use = attrUse;
25272: 	    tmpiattr->decl = attrDecl;
25273: 	} else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
25274: 	    ((attrUse->defValue != NULL) ||
25275: 	     (attrDecl->defValue != NULL))) {
25276: 	    /*
25277: 	    * Handle non-existent, optional, default/fixed attributes.
25278: 	    */
25279: 	    tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
25280: 	    if (tmpiattr == NULL) {
25281: 		VERROR_INT(
25282: 		    "xmlSchemaVAttributesComplex",
25283: 		    "calling xmlSchemaGetFreshAttrInfo()");
25284: 		return (-1);
25285: 	    }
25286: 	    tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
25287: 	    tmpiattr->use = attrUse;
25288: 	    tmpiattr->decl = attrDecl;
25289: 	    tmpiattr->typeDef = attrDecl->subtypes;
25290: 	    tmpiattr->localName = attrDecl->name;
25291: 	    tmpiattr->nsName = attrDecl->targetNamespace;
25292: 	}
25293:     }
25294: 
25295:     if (vctxt->nbAttrInfos == 0)
25296: 	return (0);
25297:     /*
25298:     * Validate against the wildcard.
25299:     */
25300:     if (type->attributeWildcard != NULL) {
25301: 	/*
25302: 	* SPEC (cvc-complex-type)
25303: 	* (3.2.1) "There must be an {attribute wildcard}."
25304: 	*/
25305: 	for (i = 0; i < nbAttrs; i++) {
25306: 	    iattr = vctxt->attrInfos[i];
25307: 	    /*
25308: 	    * SPEC (cvc-complex-type) (3)
25309: 	    * Skip meta attributes.
25310: 	    */
25311: 	    if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
25312: 		continue;
25313: 	    /*
25314: 	    * SPEC (cvc-complex-type)
25315: 	    * (3.2.2) "The attribute information item must be �valid� with
25316: 	    * respect to it as defined in Item Valid (Wildcard) (�3.10.4)."
25317: 	    *
25318: 	    * SPEC Item Valid (Wildcard) (cvc-wildcard)
25319: 	    * "... its [namespace name] must be �valid� with respect to
25320: 	    * the wildcard constraint, as defined in Wildcard allows
25321: 	    * Namespace Name (�3.10.4)."
25322: 	    */
25323: 	    if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
25324: 		    iattr->nsName) == 0) {
25325: 		/*
25326: 		* Handle processContents.
25327: 		*
25328: 		* SPEC (cvc-wildcard):
25329: 		* processContents | context-determined declaration:
25330: 		* "strict"          "mustFind"
25331: 		* "lax"             "none"
25332: 		* "skip"            "skip"
25333: 		*/
25334: 		if (type->attributeWildcard->processContents ==
25335: 		    XML_SCHEMAS_ANY_SKIP) {
25336: 		     /*
25337: 		    * context-determined declaration = "skip"
25338: 		    *
25339: 		    * SPEC PSVI Assessment Outcome (Attribute)
25340: 		    * [validity] = "notKnown"
25341: 		    * [validation attempted] = "none"
25342: 		    */
25343: 		    iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
25344: 		    continue;
25345: 		}
25346: 		/*
25347: 		* Find an attribute declaration.
25348: 		*/
25349: 		iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
25350: 		    iattr->localName, iattr->nsName);
25351: 		if (iattr->decl != NULL) {
25352: 		    iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
25353: 		    /*
25354: 		    * SPEC (cvc-complex-type)
25355: 		    * (5) "Let [Definition:]  the wild IDs be the set of
25356: 		    * all attribute information item to which clause 3.2
25357: 		    * applied and whose �validation� resulted in a
25358: 		    * �context-determined declaration� of mustFind or no
25359: 		    * �context-determined declaration� at all, and whose
25360: 		    * [local name] and [namespace name] resolve (as
25361: 		    * defined by QName resolution (Instance) (�3.15.4)) to
25362: 		    * an attribute declaration whose {type definition} is
25363: 		    * or is derived from ID. Then all of the following
25364: 		    * must be true:"
25365: 		    */
25366: 		    iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
25367: 		    if (xmlSchemaIsDerivedFromBuiltInType(
25368: 			iattr->typeDef, XML_SCHEMAS_ID)) {
25369: 			/*
25370: 			* SPEC (5.1) "There must be no more than one
25371: 			* item in �wild IDs�."
25372: 			*/
25373: 			if (wildIDs != 0) {
25374: 			    /* VAL TODO */
25375: 			    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
25376: 			    TODO
25377: 			    continue;
25378: 			}
25379: 			wildIDs++;
25380: 			/*
25381: 			* SPEC (cvc-complex-type)
25382: 			* (5.2) "If �wild IDs� is non-empty, there must not
25383: 			* be any attribute uses among the {attribute uses}
25384: 			* whose {attribute declaration}'s {type definition}
25385: 			* is or is derived from ID."
25386: 			*/
25387:                         if (attrUseList != NULL) {
25388:                             for (j = 0; j < attrUseList->nbItems; j++) {
25389:                                 if (xmlSchemaIsDerivedFromBuiltInType(
25390:                                     WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
25391:                                     XML_SCHEMAS_ID)) {
25392:                                     /* URGENT VAL TODO: implement */
25393:                             iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
25394:                                     TODO
25395:                                     break;
25396:                                 }
25397:                             }
25398:                         }
25399: 		    }
25400: 		} else if (type->attributeWildcard->processContents ==
25401: 		    XML_SCHEMAS_ANY_LAX) {
25402: 		    iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
25403: 		    /*
25404: 		    * SPEC PSVI Assessment Outcome (Attribute)
25405: 		    * [validity] = "notKnown"
25406: 		    * [validation attempted] = "none"
25407: 		    */
25408: 		} else {
25409: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
25410: 		}
25411: 	    }
25412: 	}
25413:     }
25414: 
25415:     if (vctxt->nbAttrInfos == 0)
25416: 	return (0);
25417: 
25418:     /*
25419:     * Get the owner element; needed for creation of default attributes.
25420:     * This fixes bug #341337, reported by David Grohmann.
25421:     */
25422:     if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
25423: 	xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
25424: 	if (ielem && ielem->node && ielem->node->doc)
25425: 	    defAttrOwnerElem = ielem->node;
25426:     }
25427:     /*
25428:     * Validate values, create default attributes, evaluate IDCs.
25429:     */
25430:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25431: 	iattr = vctxt->attrInfos[i];
25432: 	/*
25433: 	* VAL TODO: Note that we won't try to resolve IDCs to
25434: 	* "lax" and "skip" validated attributes. Check what to
25435: 	* do in this case.
25436: 	*/
25437: 	if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
25438: 	    (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
25439: 	    continue;
25440: 	/*
25441: 	* VAL TODO: What to do if the type definition is missing?
25442: 	*/
25443: 	if (iattr->typeDef == NULL) {
25444: 	    iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
25445: 	    continue;
25446: 	}
25447: 
25448: 	ACTIVATE_ATTRIBUTE(iattr);
25449: 	fixed = 0;
25450: 	xpathRes = 0;
25451: 
25452: 	if (vctxt->xpathStates != NULL) {
25453: 	    /*
25454: 	    * Evaluate IDCs.
25455: 	    */
25456: 	    xpathRes = xmlSchemaXPathEvaluate(vctxt,
25457: 		XML_ATTRIBUTE_NODE);
25458: 	    if (xpathRes == -1) {
25459: 		VERROR_INT("xmlSchemaVAttributesComplex",
25460: 		    "calling xmlSchemaXPathEvaluate()");
25461: 		goto internal_error;
25462: 	    }
25463: 	}
25464: 
25465: 	if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
25466: 	    /*
25467: 	    * Default/fixed attributes.
25468: 	    * We need the value only if we need to resolve IDCs or
25469: 	    * will create default attributes.
25470: 	    */
25471: 	    if ((xpathRes) || (defAttrOwnerElem)) {
25472: 		if (iattr->use->defValue != NULL) {
25473: 		    iattr->value = (xmlChar *) iattr->use->defValue;
25474: 		    iattr->val = iattr->use->defVal;
25475: 		} else {
25476: 		    iattr->value = (xmlChar *) iattr->decl->defValue;
25477: 		    iattr->val = iattr->decl->defVal;
25478: 		}
25479: 		/*
25480: 		* IDCs will consume the precomputed default value,
25481: 		* so we need to clone it.
25482: 		*/
25483: 		if (iattr->val == NULL) {
25484: 		    VERROR_INT("xmlSchemaVAttributesComplex",
25485: 			"default/fixed value on an attribute use was "
25486: 			"not precomputed");
25487: 		    goto internal_error;
25488: 		}
25489: 		iattr->val = xmlSchemaCopyValue(iattr->val);
25490: 		if (iattr->val == NULL) {
25491: 		    VERROR_INT("xmlSchemaVAttributesComplex",
25492: 			"calling xmlSchemaCopyValue()");
25493: 		    goto internal_error;
25494: 		}
25495: 	    }
25496: 	    /*
25497: 	    * PSVI: Add the default attribute to the current element.
25498: 	    * VAL TODO: Should we use the *normalized* value? This currently
25499: 	    *   uses the *initial* value.
25500: 	    */
25501: 
25502: 	    if (defAttrOwnerElem) {
25503: 		xmlChar *normValue;
25504: 		const xmlChar *value;
25505: 
25506: 		value = iattr->value;
25507: 		/*
25508: 		* Normalize the value.
25509: 		*/
25510: 		normValue = xmlSchemaNormalizeValue(iattr->typeDef,
25511: 		    iattr->value);
25512: 		if (normValue != NULL)
25513: 		    value = BAD_CAST normValue;
25514: 
25515: 		if (iattr->nsName == NULL) {
25516: 		    if (xmlNewProp(defAttrOwnerElem,
25517: 			iattr->localName, value) == NULL) {
25518: 			VERROR_INT("xmlSchemaVAttributesComplex",
25519: 			    "callling xmlNewProp()");
25520: 			if (normValue != NULL)
25521: 			    xmlFree(normValue);
25522: 			goto internal_error;
25523: 		    }
25524: 		} else {
25525: 		    xmlNsPtr ns;
25526: 
25527: 		    ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
25528: 			defAttrOwnerElem, iattr->nsName);
25529: 		    if (ns == NULL) {
25530: 			xmlChar prefix[12];
25531: 			int counter = 0;
25532: 
25533: 			/*
25534: 			* Create a namespace declaration on the validation
25535: 			* root node if no namespace declaration is in scope.
25536: 			*/
25537: 			do {
25538: 			    snprintf((char *) prefix, 12, "p%d", counter++);
25539: 			    ns = xmlSearchNs(defAttrOwnerElem->doc,
25540: 				defAttrOwnerElem, BAD_CAST prefix);
25541: 			    if (counter > 1000) {
25542: 				VERROR_INT(
25543: 				    "xmlSchemaVAttributesComplex",
25544: 				    "could not compute a ns prefix for a "
25545: 				    "default/fixed attribute");
25546: 				if (normValue != NULL)
25547: 				    xmlFree(normValue);
25548: 				goto internal_error;
25549: 			    }
25550: 			} while (ns != NULL);
25551: 			ns = xmlNewNs(vctxt->validationRoot,
25552: 			    iattr->nsName, BAD_CAST prefix);
25553: 		    }
25554: 		    /*
25555: 		    * TODO:
25556: 		    * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
25557: 		    * If we have QNames: do we need to ensure there's a
25558: 		    * prefix defined for the QName?
25559: 		    */
25560: 		    xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
25561: 		}
25562: 		if (normValue != NULL)
25563: 		    xmlFree(normValue);
25564: 	    }
25565: 	    /*
25566: 	    * Go directly to IDC evaluation.
25567: 	    */
25568: 	    goto eval_idcs;
25569: 	}
25570: 	/*
25571: 	* Validate the value.
25572: 	*/
25573: 	if (vctxt->value != NULL) {
25574: 	    /*
25575: 	    * Free last computed value; just for safety reasons.
25576: 	    */
25577: 	    xmlSchemaFreeValue(vctxt->value);
25578: 	    vctxt->value = NULL;
25579: 	}
25580: 	/*
25581: 	* Note that the attribute *use* can be unavailable, if
25582: 	* the attribute was a wild attribute.
25583: 	*/
25584: 	if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
25585: 	    ((iattr->use != NULL) &&
25586: 	     (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
25587: 	    fixed = 1;
25588: 	else
25589: 	    fixed = 0;
25590: 	/*
25591: 	* SPEC (cvc-attribute)
25592: 	* (3) "The item's �normalized value� must be locally �valid�
25593: 	* with respect to that {type definition} as per
25594: 	* String Valid (�3.14.4)."
25595: 	*
25596: 	* VAL TODO: Do we already have the
25597: 	* "normalized attribute value" here?
25598: 	*/
25599: 	if (xpathRes || fixed) {
25600: 	    iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
25601: 	    /*
25602: 	    * Request a computed value.
25603: 	    */
25604: 	    res = xmlSchemaVCheckCVCSimpleType(
25605: 		ACTXT_CAST vctxt,
25606: 		iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
25607: 		1, 1, 0);
25608: 	} else {
25609: 	    res = xmlSchemaVCheckCVCSimpleType(
25610: 		ACTXT_CAST vctxt,
25611: 		iattr->node, iattr->typeDef, iattr->value, NULL,
25612: 		1, 0, 0);
25613: 	}
25614: 
25615: 	if (res != 0) {
25616: 	    if (res == -1) {
25617: 		VERROR_INT("xmlSchemaVAttributesComplex",
25618: 		    "calling xmlSchemaStreamValidateSimpleTypeValue()");
25619: 		goto internal_error;
25620: 	    }
25621: 	    iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
25622: 	    /*
25623: 	    * SPEC PSVI Assessment Outcome (Attribute)
25624: 	    * [validity] = "invalid"
25625: 	    */
25626: 	    goto eval_idcs;
25627: 	}
25628: 
25629: 	if (fixed) {
25630: 	    /*
25631: 	    * SPEC Attribute Locally Valid (Use) (cvc-au)
25632: 	    * "For an attribute information item to be�valid�
25633: 	    * with respect to an attribute use its *normalized*
25634: 	    * value� must match the *canonical* lexical
25635: 	    * representation of the attribute use's {value
25636: 	    * constraint}value, if it is present and fixed."
25637: 	    *
25638: 	    * VAL TODO: The requirement for the *canonical* value
25639: 	    * will be removed in XML Schema 1.1.
25640: 	    */
25641: 	    /*
25642: 	    * SPEC Attribute Locally Valid (cvc-attribute)
25643: 	    * (4) "The item's *actual* value� must match the *value* of
25644: 	    * the {value constraint}, if it is present and fixed."
25645: 	    */
25646: 	    if (iattr->val == NULL) {
25647: 		/* VAL TODO: A value was not precomputed. */
25648: 		TODO
25649: 		goto eval_idcs;
25650: 	    }
25651: 	    if ((iattr->use != NULL) &&
25652: 		(iattr->use->defValue != NULL)) {
25653: 		if (iattr->use->defVal == NULL) {
25654: 		    /* VAL TODO: A default value was not precomputed. */
25655: 		    TODO
25656: 		    goto eval_idcs;
25657: 		}
25658: 		iattr->vcValue = iattr->use->defValue;
25659: 		/*
25660: 		if (xmlSchemaCompareValuesWhtsp(attr->val,
25661: 		    (xmlSchemaWhitespaceValueType) ws,
25662: 		    attr->use->defVal,
25663: 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
25664: 		*/
25665: 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
25666: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25667: 	    } else {
25668: 		if (iattr->decl->defVal == NULL) {
25669: 		    /* VAL TODO: A default value was not precomputed. */
25670: 		    TODO
25671: 		    goto eval_idcs;
25672: 		}
25673: 		iattr->vcValue = iattr->decl->defValue;
25674: 		/*
25675: 		if (xmlSchemaCompareValuesWhtsp(attr->val,
25676: 		    (xmlSchemaWhitespaceValueType) ws,
25677: 		    attrDecl->defVal,
25678: 		    (xmlSchemaWhitespaceValueType) ws) != 0) {
25679: 		*/
25680: 		if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
25681: 		    iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
25682: 	    }
25683: 	    /*
25684: 	    * [validity] = "valid"
25685: 	    */
25686: 	}
25687: eval_idcs:
25688: 	/*
25689: 	* Evaluate IDCs.
25690: 	*/
25691: 	if (xpathRes) {
25692: 	    if (xmlSchemaXPathProcessHistory(vctxt,
25693: 		vctxt->depth +1) == -1) {
25694: 		VERROR_INT("xmlSchemaVAttributesComplex",
25695: 		    "calling xmlSchemaXPathEvaluate()");
25696: 		goto internal_error;
25697: 	    }
25698: 	} else if (vctxt->xpathStates != NULL)
25699: 	    xmlSchemaXPathPop(vctxt);
25700:     }
25701: 
25702:     /*
25703:     * Report errors.
25704:     */
25705:     for (i = 0; i < vctxt->nbAttrInfos; i++) {
25706: 	iattr = vctxt->attrInfos[i];
25707: 	if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
25708: 	    (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
25709: 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
25710: 	    (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
25711: 	    continue;
25712: 	ACTIVATE_ATTRIBUTE(iattr);
25713: 	switch (iattr->state) {
25714: 	    case XML_SCHEMAS_ATTR_ERR_MISSING: {
25715: 		    xmlChar *str = NULL;
25716: 		    ACTIVATE_ELEM;
25717: 		    xmlSchemaCustomErr(ACTXT_CAST vctxt,
25718: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
25719: 			"The attribute '%s' is required but missing",
25720: 			xmlSchemaFormatQName(&str,
25721: 			    iattr->decl->targetNamespace,
25722: 			    iattr->decl->name),
25723: 			NULL);
25724: 		    FREE_AND_NULL(str)
25725: 		    break;
25726: 		}
25727: 	    case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
25728: 		VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
25729: 		    "The type definition is absent");
25730: 		break;
25731: 	    case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
25732: 		xmlSchemaCustomErr(ACTXT_CAST vctxt,
25733: 		    XML_SCHEMAV_CVC_AU, NULL, NULL,
25734: 		    "The value '%s' does not match the fixed "
25735: 		    "value constraint '%s'",
25736: 		    iattr->value, iattr->vcValue);
25737: 		break;
25738: 	    case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
25739: 		VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
25740: 		    "No matching global attribute declaration available, but "
25741: 		    "demanded by the strict wildcard");
25742: 		break;
25743: 	    case XML_SCHEMAS_ATTR_UNKNOWN:
25744: 		if (iattr->metaType)
25745: 		    break;
25746: 		/*
25747: 		* MAYBE VAL TODO: One might report different error messages
25748: 		* for the following errors.
25749: 		*/
25750: 		if (type->attributeWildcard == NULL) {
25751: 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25752: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
25753: 		} else {
25754: 		    xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
25755: 			XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
25756: 		}
25757: 		break;
25758: 	    default:
25759: 		break;
25760: 	}
25761:     }
25762: 
25763:     ACTIVATE_ELEM;
25764:     return (0);
25765: internal_error:
25766:     ACTIVATE_ELEM;
25767:     return (-1);
25768: }
25769: 
25770: static int
25771: xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
25772: 			      int *skip)
25773: {
25774:     xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
25775:     /*
25776:     * The namespace of the element was already identified to be
25777:     * matching the wildcard.
25778:     */
25779:     if ((skip == NULL) || (wild == NULL) ||
25780: 	(wild->type != XML_SCHEMA_TYPE_ANY)) {
25781: 	VERROR_INT("xmlSchemaValidateElemWildcard",
25782: 	    "bad arguments");
25783: 	return (-1);
25784:     }
25785:     *skip = 0;
25786:     if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
25787: 	/*
25788: 	* URGENT VAL TODO: Either we need to position the stream to the
25789: 	* next sibling, or walk the whole subtree.
25790: 	*/
25791: 	*skip = 1;
25792: 	return (0);
25793:     }
25794:     {
25795: 	xmlSchemaElementPtr decl = NULL;
25796: 
25797: 	decl = xmlSchemaGetElem(vctxt->schema,
25798: 	    vctxt->inode->localName, vctxt->inode->nsName);
25799: 	if (decl != NULL) {
25800: 	    vctxt->inode->decl = decl;
25801: 	    return (0);
25802: 	}
25803:     }
25804:     if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
25805: 	/* VAL TODO: Change to proper error code. */
25806: 	VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
25807: 	    "No matching global element declaration available, but "
25808: 	    "demanded by the strict wildcard");
25809: 	return (vctxt->err);
25810:     }
25811:     if (vctxt->nbAttrInfos != 0) {
25812: 	xmlSchemaAttrInfoPtr iattr;
25813: 	/*
25814: 	* SPEC Validation Rule: Schema-Validity Assessment (Element)
25815: 	* (1.2.1.2.1) - (1.2.1.2.3 )
25816: 	*
25817: 	* Use the xsi:type attribute for the type definition.
25818: 	*/
25819: 	iattr = xmlSchemaGetMetaAttrInfo(vctxt,
25820: 	    XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
25821: 	if (iattr != NULL) {
25822: 	    if (xmlSchemaProcessXSIType(vctxt, iattr,
25823: 		&(vctxt->inode->typeDef), NULL) == -1) {
25824: 		VERROR_INT("xmlSchemaValidateElemWildcard",
25825: 		    "calling xmlSchemaProcessXSIType() to "
25826: 		    "process the attribute 'xsi:nil'");
25827: 		return (-1);
25828: 	    }
25829: 	    /*
25830: 	    * Don't return an error on purpose.
25831: 	    */
25832: 	    return (0);
25833: 	}
25834:     }
25835:     /*
25836:     * SPEC Validation Rule: Schema-Validity Assessment (Element)
25837:     *
25838:     * Fallback to "anyType".
25839:     */
25840:     vctxt->inode->typeDef =
25841: 	xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
25842:     return (0);
25843: }
25844: 
25845: /*
25846: * xmlSchemaCheckCOSValidDefault:
25847: *
25848: * This will be called if: not nilled, no content and a default/fixed
25849: * value is provided.
25850: */
25851: 
25852: static int
25853: xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
25854: 			      const xmlChar *value,
25855: 			      xmlSchemaValPtr *val)
25856: {
25857:     int ret = 0;
25858:     xmlSchemaNodeInfoPtr inode = vctxt->inode;
25859: 
25860:     /*
25861:     * cos-valid-default:
25862:     * Schema Component Constraint: Element Default Valid (Immediate)
25863:     * For a string to be a valid default with respect to a type
25864:     * definition the appropriate case among the following must be true:
25865:     */
25866:     if WXS_IS_COMPLEX(inode->typeDef) {
25867: 	/*
25868: 	* Complex type.
25869: 	*
25870: 	* SPEC (2.1) "its {content type} must be a simple type definition
25871: 	* or mixed."
25872: 	* SPEC (2.2.2) "If the {content type} is mixed, then the {content
25873: 	* type}'s particle must be �emptiable� as defined by
25874: 	* Particle Emptiable (�3.9.6)."
25875: 	*/
25876: 	if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
25877: 	    ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
25878: 	     (! WXS_EMPTIABLE(inode->typeDef)))) {
25879: 	    ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
25880: 	    /* NOTE that this covers (2.2.2) as well. */
25881: 	    VERROR(ret, NULL,
25882: 		"For a string to be a valid default, the type definition "
25883: 		"must be a simple type or a complex type with simple content "
25884: 		"or mixed content and a particle emptiable");
25885: 	    return(ret);
25886: 	}
25887:     }
25888:     /*
25889:     * 1 If the type definition is a simple type definition, then the string
25890:     * must be �valid� with respect to that definition as defined by String
25891:     * Valid (�3.14.4).
25892:     *
25893:     * AND
25894:     *
25895:     * 2.2.1 If the {content type} is a simple type definition, then the
25896:     * string must be �valid� with respect to that simple type definition
25897:     * as defined by String Valid (�3.14.4).
25898:     */
25899:     if (WXS_IS_SIMPLE(inode->typeDef)) {
25900: 
25901: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25902: 	    NULL, inode->typeDef, value, val, 1, 1, 0);
25903: 
25904:     } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
25905: 
25906: 	ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
25907: 	    NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
25908:     }
25909:     if (ret < 0) {
25910: 	VERROR_INT("xmlSchemaCheckCOSValidDefault",
25911: 	    "calling xmlSchemaVCheckCVCSimpleType()");
25912:     }
25913:     return (ret);
25914: }
25915: 
25916: static void
25917: xmlSchemaVContentModelCallback(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
25918: 			       const xmlChar * name ATTRIBUTE_UNUSED,
25919: 			       xmlSchemaElementPtr item,
25920: 			       xmlSchemaNodeInfoPtr inode)
25921: {
25922:     inode->decl = item;
25923: #ifdef DEBUG_CONTENT
25924:     {
25925: 	xmlChar *str = NULL;
25926: 
25927: 	if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
25928: 	    xmlGenericError(xmlGenericErrorContext,
25929: 		"AUTOMATON callback for '%s' [declaration]\n",
25930: 		xmlSchemaFormatQName(&str,
25931: 		inode->localName, inode->nsName));
25932: 	} else {
25933: 	    xmlGenericError(xmlGenericErrorContext,
25934: 		    "AUTOMATON callback for '%s' [wildcard]\n",
25935: 		    xmlSchemaFormatQName(&str,
25936: 		    inode->localName, inode->nsName));
25937: 
25938: 	}
25939: 	FREE_AND_NULL(str)
25940:     }
25941: #endif
25942: }
25943: 
25944: static int
25945: xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
25946: {
25947:     vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
25948:     if (vctxt->inode == NULL) {
25949: 	VERROR_INT("xmlSchemaValidatorPushElem",
25950: 	    "calling xmlSchemaGetFreshElemInfo()");
25951: 	return (-1);
25952:     }
25953:     vctxt->nbAttrInfos = 0;
25954:     return (0);
25955: }
25956: 
25957: static int
25958: xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
25959: 			     xmlSchemaNodeInfoPtr inode,
25960: 			     xmlSchemaTypePtr type,
25961: 			     const xmlChar *value)
25962: {
25963:     if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
25964: 	return (xmlSchemaVCheckCVCSimpleType(
25965: 	    ACTXT_CAST vctxt, NULL,
25966: 	    type, value, &(inode->val), 1, 1, 0));
25967:     else
25968: 	return (xmlSchemaVCheckCVCSimpleType(
25969: 	    ACTXT_CAST vctxt, NULL,
25970: 	    type, value, NULL, 1, 0, 0));
25971: }
25972: 
25973: 
25974: 
25975: /*
25976: * Process END of element.
25977: */
25978: static int
25979: xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
25980: {
25981:     int ret = 0;
25982:     xmlSchemaNodeInfoPtr inode = vctxt->inode;
25983: 
25984:     if (vctxt->nbAttrInfos != 0)
25985: 	xmlSchemaClearAttrInfos(vctxt);
25986:     if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
25987: 	/*
25988: 	* This element was not expected;
25989: 	* we will not validate child elements of broken parents.
25990: 	* Skip validation of all content of the parent.
25991: 	*/
25992: 	vctxt->skipDepth = vctxt->depth -1;
25993: 	goto end_elem;
25994:     }
25995:     if ((inode->typeDef == NULL) ||
25996: 	(inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
25997: 	/*
25998: 	* 1. the type definition might be missing if the element was
25999: 	*    error prone
26000: 	* 2. it might be abstract.
26001: 	*/
26002: 	goto end_elem;
26003:     }
26004:     /*
26005:     * Check the content model.
26006:     */
26007:     if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
26008: 	(inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
26009: 
26010: 	/*
26011: 	* Workaround for "anyType".
26012: 	*/
26013: 	if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
26014: 	    goto character_content;
26015: 
26016: 	if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
26017: 	    xmlChar *values[10];
26018: 	    int terminal, nbval = 10, nbneg;
26019: 
26020: 	    if (inode->regexCtxt == NULL) {
26021: 		/*
26022: 		* Create the regex context.
26023: 		*/
26024: 		inode->regexCtxt =
26025: 		    xmlRegNewExecCtxt(inode->typeDef->contModel,
26026: 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26027: 		    vctxt);
26028: 		if (inode->regexCtxt == NULL) {
26029: 		    VERROR_INT("xmlSchemaValidatorPopElem",
26030: 			"failed to create a regex context");
26031: 		    goto internal_error;
26032: 		}
26033: #ifdef DEBUG_AUTOMATA
26034: 		xmlGenericError(xmlGenericErrorContext,
26035: 		    "AUTOMATON create on '%s'\n", inode->localName);
26036: #endif
26037: 	    }
26038: 	    /*
26039: 	    * Get hold of the still expected content, since a further
26040: 	    * call to xmlRegExecPushString() will loose this information.
26041: 	    */
26042: 	    xmlRegExecNextValues(inode->regexCtxt,
26043: 		&nbval, &nbneg, &values[0], &terminal);
26044: 	    ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
26045: 	    if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
26046: 		/*
26047: 		* Still missing something.
26048: 		*/
26049: 		ret = 1;
26050: 		inode->flags |=
26051: 		    XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26052: 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26053: 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
26054: 		    "Missing child element(s)",
26055: 		    nbval, nbneg, values);
26056: #ifdef DEBUG_AUTOMATA
26057: 		xmlGenericError(xmlGenericErrorContext,
26058: 		    "AUTOMATON missing ERROR on '%s'\n",
26059: 		    inode->localName);
26060: #endif
26061: 	    } else {
26062: 		/*
26063: 		* Content model is satisfied.
26064: 		*/
26065: 		ret = 0;
26066: #ifdef DEBUG_AUTOMATA
26067: 		xmlGenericError(xmlGenericErrorContext,
26068: 		    "AUTOMATON succeeded on '%s'\n",
26069: 		    inode->localName);
26070: #endif
26071: 	    }
26072: 
26073: 	}
26074:     }
26075:     if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
26076: 	goto end_elem;
26077: 
26078: character_content:
26079: 
26080:     if (vctxt->value != NULL) {
26081: 	xmlSchemaFreeValue(vctxt->value);
26082: 	vctxt->value = NULL;
26083:     }
26084:     /*
26085:     * Check character content.
26086:     */
26087:     if (inode->decl == NULL) {
26088: 	/*
26089: 	* Speedup if no declaration exists.
26090: 	*/
26091: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26092: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26093: 		inode, inode->typeDef, inode->value);
26094: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26095: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26096: 		inode, inode->typeDef->contentTypeDef,
26097: 		inode->value);
26098: 	}
26099: 	if (ret < 0) {
26100: 	    VERROR_INT("xmlSchemaValidatorPopElem",
26101: 		"calling xmlSchemaVCheckCVCSimpleType()");
26102: 	    goto internal_error;
26103: 	}
26104: 	goto end_elem;
26105:     }
26106:     /*
26107:     * cvc-elt (3.3.4) : 5
26108:     * The appropriate case among the following must be true:
26109:     */
26110:     /*
26111:     * cvc-elt (3.3.4) : 5.1
26112:     * If the declaration has a {value constraint},
26113:     * the item has neither element nor character [children] and
26114:     * clause 3.2 has not applied, then all of the following must be true:
26115:     */
26116:     if ((inode->decl->value != NULL) &&
26117: 	(inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
26118: 	(! INODE_NILLED(inode))) {
26119: 	/*
26120: 	* cvc-elt (3.3.4) : 5.1.1
26121: 	* If the �actual type definition� is a �local type definition�
26122: 	* then the canonical lexical representation of the {value constraint}
26123: 	* value must be a valid default for the �actual type definition� as
26124: 	* defined in Element Default Valid (Immediate) (�3.3.6).
26125: 	*/
26126: 	/*
26127: 	* NOTE: 'local' above means types acquired by xsi:type.
26128: 	* NOTE: Although the *canonical* value is stated, it is not
26129: 	* relevant if canonical or not. Additionally XML Schema 1.1
26130: 	* will removed this requirement as well.
26131: 	*/
26132: 	if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
26133: 
26134: 	    ret = xmlSchemaCheckCOSValidDefault(vctxt,
26135: 		inode->decl->value, &(inode->val));
26136: 	    if (ret != 0) {
26137: 		if (ret < 0) {
26138: 		    VERROR_INT("xmlSchemaValidatorPopElem",
26139: 			"calling xmlSchemaCheckCOSValidDefault()");
26140: 		    goto internal_error;
26141: 		}
26142: 		goto end_elem;
26143: 	    }
26144: 	    /*
26145: 	    * Stop here, to avoid redundant validation of the value
26146: 	    * (see following).
26147: 	    */
26148: 	    goto default_psvi;
26149: 	}
26150: 	/*
26151: 	* cvc-elt (3.3.4) : 5.1.2
26152: 	* The element information item with the canonical lexical
26153: 	* representation of the {value constraint} value used as its
26154: 	* �normalized value� must be �valid� with respect to the
26155: 	* �actual type definition� as defined by Element Locally Valid (Type)
26156: 	* (�3.3.4).
26157: 	*/
26158: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26159: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26160: 		inode, inode->typeDef, inode->decl->value);
26161: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26162: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26163: 		inode, inode->typeDef->contentTypeDef,
26164: 		inode->decl->value);
26165: 	}
26166: 	if (ret != 0) {
26167: 	    if (ret < 0) {
26168: 		VERROR_INT("xmlSchemaValidatorPopElem",
26169: 		    "calling xmlSchemaVCheckCVCSimpleType()");
26170: 		goto internal_error;
26171: 	    }
26172: 	    goto end_elem;
26173: 	}
26174: 
26175: default_psvi:
26176: 	/*
26177: 	* PSVI: Create a text node on the instance element.
26178: 	*/
26179: 	if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
26180: 	    (inode->node != NULL)) {
26181: 	    xmlNodePtr textChild;
26182: 	    xmlChar *normValue;
26183: 	    /*
26184: 	    * VAL TODO: Normalize the value.
26185: 	    */
26186: 	    normValue = xmlSchemaNormalizeValue(inode->typeDef,
26187: 		inode->decl->value);
26188: 	    if (normValue != NULL) {
26189: 		textChild = xmlNewText(BAD_CAST normValue);
26190: 		xmlFree(normValue);
26191: 	    } else
26192: 		textChild = xmlNewText(inode->decl->value);
26193: 	    if (textChild == NULL) {
26194: 		VERROR_INT("xmlSchemaValidatorPopElem",
26195: 		    "calling xmlNewText()");
26196: 		goto internal_error;
26197: 	    } else
26198: 		xmlAddChild(inode->node, textChild);
26199: 	}
26200: 
26201:     } else if (! INODE_NILLED(inode)) {
26202: 	/*
26203: 	* 5.2.1 The element information item must be �valid� with respect
26204: 	* to the �actual type definition� as defined by Element Locally
26205: 	* Valid (Type) (�3.3.4).
26206: 	*/
26207: 	if (WXS_IS_SIMPLE(inode->typeDef)) {
26208: 	     /*
26209: 	    * SPEC (cvc-type) (3.1)
26210: 	    * "If the type definition is a simple type definition, ..."
26211: 	    * (3.1.3) "If clause 3.2 of Element Locally Valid
26212: 	    * (Element) (�3.3.4) did not apply, then the �normalized value�
26213: 	    * must be �valid� with respect to the type definition as defined
26214: 	    * by String Valid (�3.14.4).
26215: 	    */
26216: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26217: 		    inode, inode->typeDef, inode->value);
26218: 	} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26219: 	    /*
26220: 	    * SPEC (cvc-type) (3.2) "If the type definition is a complex type
26221: 	    * definition, then the element information item must be
26222: 	    * �valid� with respect to the type definition as per
26223: 	    * Element Locally Valid (Complex Type) (�3.4.4);"
26224: 	    *
26225: 	    * SPEC (cvc-complex-type) (2.2)
26226: 	    * "If the {content type} is a simple type definition, ...
26227: 	    * the �normalized value� of the element information item is
26228: 	    * �valid� with respect to that simple type definition as
26229: 	    * defined by String Valid (�3.14.4)."
26230: 	    */
26231: 	    ret = xmlSchemaVCheckINodeDataType(vctxt,
26232: 		inode, inode->typeDef->contentTypeDef, inode->value);
26233: 	}
26234: 	if (ret != 0) {
26235: 	    if (ret < 0) {
26236: 		VERROR_INT("xmlSchemaValidatorPopElem",
26237: 		    "calling xmlSchemaVCheckCVCSimpleType()");
26238: 		goto internal_error;
26239: 	    }
26240: 	    goto end_elem;
26241: 	}
26242: 	/*
26243: 	* 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
26244: 	* not applied, all of the following must be true:
26245: 	*/
26246: 	if ((inode->decl->value != NULL) &&
26247: 	    (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
26248: 
26249: 	    /*
26250: 	    * TODO: We will need a computed value, when comparison is
26251: 	    * done on computed values.
26252: 	    */
26253: 	    /*
26254: 	    * 5.2.2.1 The element information item must have no element
26255: 	    * information item [children].
26256: 	    */
26257: 	    if (inode->flags &
26258: 		    XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
26259: 		ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
26260: 		VERROR(ret, NULL,
26261: 		    "The content must not containt element nodes since "
26262: 		    "there is a fixed value constraint");
26263: 		goto end_elem;
26264: 	    } else {
26265: 		/*
26266: 		* 5.2.2.2 The appropriate case among the following must
26267: 		* be true:
26268: 		*/
26269: 		if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
26270: 		    /*
26271: 		    * 5.2.2.2.1 If the {content type} of the �actual type
26272: 		    * definition� is mixed, then the *initial value* of the
26273: 		    * item must match the canonical lexical representation
26274: 		    * of the {value constraint} value.
26275: 		    *
26276: 		    * ... the *initial value* of an element information
26277: 		    * item is the string composed of, in order, the
26278: 		    * [character code] of each character information item in
26279: 		    * the [children] of that element information item.
26280: 		    */
26281: 		    if (! xmlStrEqual(inode->value, inode->decl->value)){
26282: 			/*
26283: 			* VAL TODO: Report invalid & expected values as well.
26284: 			* VAL TODO: Implement the canonical stuff.
26285: 			*/
26286: 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
26287: 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
26288: 			    ret, NULL, NULL,
26289: 			    "The initial value '%s' does not match the fixed "
26290: 			    "value constraint '%s'",
26291: 			    inode->value, inode->decl->value);
26292: 			goto end_elem;
26293: 		    }
26294: 		} else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
26295: 		    /*
26296: 		    * 5.2.2.2.2 If the {content type} of the �actual type
26297: 		    * definition� is a simple type definition, then the
26298: 		    * *actual value* of the item must match the canonical
26299: 		    * lexical representation of the {value constraint} value.
26300: 		    */
26301: 		    /*
26302: 		    * VAL TODO: *actual value* is the normalized value, impl.
26303: 		    *           this.
26304: 		    * VAL TODO: Report invalid & expected values as well.
26305: 		    * VAL TODO: Implement a comparison with the computed values.
26306: 		    */
26307: 		    if (! xmlStrEqual(inode->value,
26308: 			    inode->decl->value)) {
26309: 			ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
26310: 			xmlSchemaCustomErr(ACTXT_CAST vctxt,
26311: 			    ret, NULL, NULL,
26312: 			    "The actual value '%s' does not match the fixed "
26313: 			    "value constraint '%s'",
26314: 			    inode->value,
26315: 			    inode->decl->value);
26316: 			goto end_elem;
26317: 		    }
26318: 		}
26319: 	    }
26320: 	}
26321:     }
26322: 
26323: end_elem:
26324:     if (vctxt->depth < 0) {
26325: 	/* TODO: raise error? */
26326: 	return (0);
26327:     }
26328:     if (vctxt->depth == vctxt->skipDepth)
26329: 	vctxt->skipDepth = -1;
26330:     /*
26331:     * Evaluate the history of XPath state objects.
26332:     */
26333:     if (inode->appliedXPath &&
26334: 	(xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
26335: 	goto internal_error;
26336:     /*
26337:     * MAYBE TODO:
26338:     * SPEC (6) "The element information item must be �valid� with
26339:     * respect to each of the {identity-constraint definitions} as per
26340:     * Identity-constraint Satisfied (�3.11.4)."
26341:     */
26342:     /*
26343:     * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
26344:     *   need to be built in any case.
26345:     *   We will currently build IDC node-tables and bubble them only if
26346:     *   keyrefs do exist.
26347:     */
26348: 
26349:     /*
26350:     * Add the current IDC target-nodes to the IDC node-tables.
26351:     */
26352:     if ((inode->idcMatchers != NULL) &&
26353: 	(vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26354:     {
26355: 	if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
26356: 	    goto internal_error;
26357:     }
26358:     /*
26359:     * Validate IDC keyrefs.
26360:     */
26361:     if (vctxt->inode->hasKeyrefs)
26362: 	if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
26363: 	    goto internal_error;
26364:     /*
26365:     * Merge/free the IDC table.
26366:     */
26367:     if (inode->idcTable != NULL) {
26368: #ifdef DEBUG_IDC_NODE_TABLE
26369: 	xmlSchemaDebugDumpIDCTable(stdout,
26370: 	    inode->nsName,
26371: 	    inode->localName,
26372: 	    inode->idcTable);
26373: #endif
26374: 	if ((vctxt->depth > 0) &&
26375: 	    (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
26376: 	{
26377: 	    /*
26378: 	    * Merge the IDC node table with the table of the parent node.
26379: 	    */
26380: 	    if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
26381: 		goto internal_error;
26382: 	}
26383:     }
26384:     /*
26385:     * Clear the current ielem.
26386:     * VAL TODO: Don't free the PSVI IDC tables if they are
26387:     * requested for the PSVI.
26388:     */
26389:     xmlSchemaClearElemInfo(vctxt, inode);
26390:     /*
26391:     * Skip further processing if we are on the validation root.
26392:     */
26393:     if (vctxt->depth == 0) {
26394: 	vctxt->depth--;
26395: 	vctxt->inode = NULL;
26396: 	return (0);
26397:     }
26398:     /*
26399:     * Reset the keyrefDepth if needed.
26400:     */
26401:     if (vctxt->aidcs != NULL) {
26402: 	xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
26403: 	do {
26404: 	    if (aidc->keyrefDepth == vctxt->depth) {
26405: 		/*
26406: 		* A 'keyrefDepth' of a key/unique IDC matches the current
26407: 		* depth, this means that we are leaving the scope of the
26408: 		* top-most keyref IDC which refers to this IDC.
26409: 		*/
26410: 		aidc->keyrefDepth = -1;
26411: 	    }
26412: 	    aidc = aidc->next;
26413: 	} while (aidc != NULL);
26414:     }
26415:     vctxt->depth--;
26416:     vctxt->inode = vctxt->elemInfos[vctxt->depth];
26417:     /*
26418:     * VAL TODO: 7 If the element information item is the �validation root�, it must be
26419:     * �valid� per Validation Root Valid (ID/IDREF) (�3.3.4).
26420:     */
26421:     return (ret);
26422: 
26423: internal_error:
26424:     vctxt->err = -1;
26425:     return (-1);
26426: }
26427: 
26428: /*
26429: * 3.4.4 Complex Type Definition Validation Rules
26430: * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
26431: */
26432: static int
26433: xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
26434: {
26435:     xmlSchemaNodeInfoPtr pielem;
26436:     xmlSchemaTypePtr ptype;
26437:     int ret = 0;
26438: 
26439:     if (vctxt->depth <= 0) {
26440: 	VERROR_INT("xmlSchemaValidateChildElem",
26441: 	    "not intended for the validation root");
26442: 	return (-1);
26443:     }
26444:     pielem = vctxt->elemInfos[vctxt->depth -1];
26445:     if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
26446: 	pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
26447:     /*
26448:     * Handle 'nilled' elements.
26449:     */
26450:     if (INODE_NILLED(pielem)) {
26451: 	/*
26452: 	* SPEC (cvc-elt) (3.3.4) : (3.2.1)
26453: 	*/
26454: 	ACTIVATE_PARENT_ELEM;
26455: 	ret = XML_SCHEMAV_CVC_ELT_3_2_1;
26456: 	VERROR(ret, NULL,
26457: 	    "Neither character nor element content is allowed, "
26458: 	    "because the element was 'nilled'");
26459: 	ACTIVATE_ELEM;
26460: 	goto unexpected_elem;
26461:     }
26462: 
26463:     ptype = pielem->typeDef;
26464: 
26465:     if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
26466: 	/*
26467: 	* Workaround for "anyType": we have currently no content model
26468: 	* assigned for "anyType", so handle it explicitely.
26469: 	* "anyType" has an unbounded, lax "any" wildcard.
26470: 	*/
26471: 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26472: 	    vctxt->inode->localName,
26473: 	    vctxt->inode->nsName);
26474: 
26475: 	if (vctxt->inode->decl == NULL) {
26476: 	    xmlSchemaAttrInfoPtr iattr;
26477: 	    /*
26478: 	    * Process "xsi:type".
26479: 	    * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
26480: 	    */
26481: 	    iattr = xmlSchemaGetMetaAttrInfo(vctxt,
26482: 		XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
26483: 	    if (iattr != NULL) {
26484: 		ret = xmlSchemaProcessXSIType(vctxt, iattr,
26485: 		    &(vctxt->inode->typeDef), NULL);
26486: 		if (ret != 0) {
26487: 		    if (ret == -1) {
26488: 			VERROR_INT("xmlSchemaValidateChildElem",
26489: 			    "calling xmlSchemaProcessXSIType() to "
26490: 			    "process the attribute 'xsi:nil'");
26491: 			return (-1);
26492: 		    }
26493: 		    return (ret);
26494: 		}
26495: 	    } else {
26496: 		 /*
26497: 		 * Fallback to "anyType".
26498: 		 *
26499: 		 * SPEC (cvc-assess-elt)
26500: 		 * "If the item cannot be �strictly assessed�, [...]
26501: 		 * an element information item's schema validity may be laxly
26502: 		 * assessed if its �context-determined declaration� is not
26503: 		 * skip by �validating� with respect to the �ur-type
26504: 		 * definition� as per Element Locally Valid (Type) (�3.3.4)."
26505: 		*/
26506: 		vctxt->inode->typeDef =
26507: 		    xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
26508: 	    }
26509: 	}
26510: 	return (0);
26511:     }
26512: 
26513:     switch (ptype->contentType) {
26514: 	case XML_SCHEMA_CONTENT_EMPTY:
26515: 	    /*
26516: 	    * SPEC (2.1) "If the {content type} is empty, then the
26517: 	    * element information item has no character or element
26518: 	    * information item [children]."
26519: 	    */
26520: 	    ACTIVATE_PARENT_ELEM
26521: 	    ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
26522: 	    VERROR(ret, NULL,
26523: 		"Element content is not allowed, "
26524: 		"because the content type is empty");
26525: 	    ACTIVATE_ELEM
26526: 	    goto unexpected_elem;
26527: 	    break;
26528: 
26529: 	case XML_SCHEMA_CONTENT_MIXED:
26530:         case XML_SCHEMA_CONTENT_ELEMENTS: {
26531: 	    xmlRegExecCtxtPtr regexCtxt;
26532: 	    xmlChar *values[10];
26533: 	    int terminal, nbval = 10, nbneg;
26534: 
26535: 	    /* VAL TODO: Optimized "anyType" validation.*/
26536: 
26537: 	    if (ptype->contModel == NULL) {
26538: 		VERROR_INT("xmlSchemaValidateChildElem",
26539: 		    "type has elem content but no content model");
26540: 		return (-1);
26541: 	    }
26542: 	    /*
26543: 	    * Safety belf for evaluation if the cont. model was already
26544: 	    * examined to be invalid.
26545: 	    */
26546: 	    if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
26547: 		VERROR_INT("xmlSchemaValidateChildElem",
26548: 		    "validating elem, but elem content is already invalid");
26549: 		return (-1);
26550: 	    }
26551: 
26552: 	    regexCtxt = pielem->regexCtxt;
26553: 	    if (regexCtxt == NULL) {
26554: 		/*
26555: 		* Create the regex context.
26556: 		*/
26557: 		regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
26558: 		    (xmlRegExecCallbacks) xmlSchemaVContentModelCallback,
26559: 		    vctxt);
26560: 		if (regexCtxt == NULL) {
26561: 		    VERROR_INT("xmlSchemaValidateChildElem",
26562: 			"failed to create a regex context");
26563: 		    return (-1);
26564: 		}
26565: 		pielem->regexCtxt = regexCtxt;
26566: #ifdef DEBUG_AUTOMATA
26567: 		xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
26568: 		    pielem->localName);
26569: #endif
26570: 	    }
26571: 
26572: 	    /*
26573: 	    * SPEC (2.4) "If the {content type} is element-only or mixed,
26574: 	    * then the sequence of the element information item's
26575: 	    * element information item [children], if any, taken in
26576: 	    * order, is �valid� with respect to the {content type}'s
26577: 	    * particle, as defined in Element Sequence Locally Valid
26578: 	    * (Particle) (�3.9.4)."
26579: 	    */
26580: 	    ret = xmlRegExecPushString2(regexCtxt,
26581: 		vctxt->inode->localName,
26582: 		vctxt->inode->nsName,
26583: 		vctxt->inode);
26584: #ifdef DEBUG_AUTOMATA
26585: 	    if (ret < 0)
26586: 		xmlGenericError(xmlGenericErrorContext,
26587: 		"AUTOMATON push ERROR for '%s' on '%s'\n",
26588: 		vctxt->inode->localName, pielem->localName);
26589: 	    else
26590: 		xmlGenericError(xmlGenericErrorContext,
26591: 		"AUTOMATON push OK for '%s' on '%s'\n",
26592: 		vctxt->inode->localName, pielem->localName);
26593: #endif
26594: 	    if (vctxt->err == XML_SCHEMAV_INTERNAL) {
26595: 		VERROR_INT("xmlSchemaValidateChildElem",
26596: 		    "calling xmlRegExecPushString2()");
26597: 		return (-1);
26598: 	    }
26599: 	    if (ret < 0) {
26600: 		xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
26601: 		    &values[0], &terminal);
26602: 		xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
26603: 		    XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
26604: 		    "This element is not expected",
26605: 		    nbval, nbneg, values);
26606: 		ret = vctxt->err;
26607: 		goto unexpected_elem;
26608: 	    } else
26609: 		ret = 0;
26610: 	}
26611: 	    break;
26612: 	case XML_SCHEMA_CONTENT_SIMPLE:
26613: 	case XML_SCHEMA_CONTENT_BASIC:
26614: 	    ACTIVATE_PARENT_ELEM
26615: 	    if (WXS_IS_COMPLEX(ptype)) {
26616: 		/*
26617: 		* SPEC (cvc-complex-type) (2.2)
26618: 		* "If the {content type} is a simple type definition, then
26619: 		* the element information item has no element information
26620: 		* item [children], ..."
26621: 		*/
26622: 		ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
26623: 		VERROR(ret, NULL, "Element content is not allowed, "
26624: 		    "because the content type is a simple type definition");
26625: 	    } else {
26626: 		/*
26627: 		* SPEC (cvc-type) (3.1.2) "The element information item must
26628: 		* have no element information item [children]."
26629: 		*/
26630: 		ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
26631: 		VERROR(ret, NULL, "Element content is not allowed, "
26632: 		    "because the type definition is simple");
26633: 	    }
26634: 	    ACTIVATE_ELEM
26635: 	    ret = vctxt->err;
26636: 	    goto unexpected_elem;
26637: 	    break;
26638: 
26639: 	default:
26640: 	    break;
26641:     }
26642:     return (ret);
26643: unexpected_elem:
26644:     /*
26645:     * Pop this element and set the skipDepth to skip
26646:     * all further content of the parent element.
26647:     */
26648:     vctxt->skipDepth = vctxt->depth;
26649:     vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
26650:     pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
26651:     return (ret);
26652: }
26653: 
26654: #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
26655: #define XML_SCHEMA_PUSH_TEXT_CREATED 2
26656: #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
26657: 
26658: static int
26659: xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
26660: 		  int nodeType, const xmlChar *value, int len,
26661: 		  int mode, int *consumed)
26662: {
26663:     /*
26664:     * Unfortunately we have to duplicate the text sometimes.
26665:     * OPTIMIZE: Maybe we could skip it, if:
26666:     *   1. content type is simple
26667:     *   2. whitespace is "collapse"
26668:     *   3. it consists of whitespace only
26669:     *
26670:     * Process character content.
26671:     */
26672:     if (consumed != NULL)
26673: 	*consumed = 0;
26674:     if (INODE_NILLED(vctxt->inode)) {
26675: 	/*
26676: 	* SPEC cvc-elt (3.3.4 - 3.2.1)
26677: 	* "The element information item must have no character or
26678: 	* element information item [children]."
26679: 	*/
26680: 	VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
26681: 	    "Neither character nor element content is allowed "
26682: 	    "because the element is 'nilled'");
26683: 	return (vctxt->err);
26684:     }
26685:     /*
26686:     * SPEC (2.1) "If the {content type} is empty, then the
26687:     * element information item has no character or element
26688:     * information item [children]."
26689:     */
26690:     if (vctxt->inode->typeDef->contentType ==
26691: 	    XML_SCHEMA_CONTENT_EMPTY) {
26692: 	VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
26693: 	    "Character content is not allowed, "
26694: 	    "because the content type is empty");
26695: 	return (vctxt->err);
26696:     }
26697: 
26698:     if (vctxt->inode->typeDef->contentType ==
26699: 	    XML_SCHEMA_CONTENT_ELEMENTS) {
26700: 	if ((nodeType != XML_TEXT_NODE) ||
26701: 	    (! xmlSchemaIsBlank((xmlChar *) value, len))) {
26702: 	    /*
26703: 	    * SPEC cvc-complex-type (2.3)
26704: 	    * "If the {content type} is element-only, then the
26705: 	    * element information item has no character information
26706: 	    * item [children] other than those whose [character
26707: 	    * code] is defined as a white space in [XML 1.0 (Second
26708: 	    * Edition)]."
26709: 	    */
26710: 	    VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
26711: 		"Character content other than whitespace is not allowed "
26712: 		"because the content type is 'element-only'");
26713: 	    return (vctxt->err);
26714: 	}
26715: 	return (0);
26716:     }
26717: 
26718:     if ((value == NULL) || (value[0] == 0))
26719: 	return (0);
26720:     /*
26721:     * Save the value.
26722:     * NOTE that even if the content type is *mixed*, we need the
26723:     * *initial value* for default/fixed value constraints.
26724:     */
26725:     if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
26726: 	((vctxt->inode->decl == NULL) ||
26727: 	(vctxt->inode->decl->value == NULL)))
26728: 	return (0);
26729: 
26730:     if (vctxt->inode->value == NULL) {
26731: 	/*
26732: 	* Set the value.
26733: 	*/
26734: 	switch (mode) {
26735: 	    case XML_SCHEMA_PUSH_TEXT_PERSIST:
26736: 		/*
26737: 		* When working on a tree.
26738: 		*/
26739: 		vctxt->inode->value = value;
26740: 		break;
26741: 	    case XML_SCHEMA_PUSH_TEXT_CREATED:
26742: 		/*
26743: 		* When working with the reader.
26744: 		* The value will be freed by the element info.
26745: 		*/
26746: 		vctxt->inode->value = value;
26747: 		if (consumed != NULL)
26748: 		    *consumed = 1;
26749: 		vctxt->inode->flags |=
26750: 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26751: 		break;
26752: 	    case XML_SCHEMA_PUSH_TEXT_VOLATILE:
26753: 		/*
26754: 		* When working with SAX.
26755: 		* The value will be freed by the element info.
26756: 		*/
26757: 		if (len != -1)
26758: 		    vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
26759: 		else
26760: 		    vctxt->inode->value = BAD_CAST xmlStrdup(value);
26761: 		vctxt->inode->flags |=
26762: 		    XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26763: 		break;
26764: 	    default:
26765: 		break;
26766: 	}
26767:     } else {
26768: 	if (len < 0)
26769: 	    len = xmlStrlen(value);
26770: 	/*
26771: 	* Concat the value.
26772: 	*/
26773: 	if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
26774: 	    vctxt->inode->value = BAD_CAST xmlStrncat(
26775: 		(xmlChar *) vctxt->inode->value, value, len);
26776: 	} else {
26777: 	    vctxt->inode->value =
26778: 		BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
26779: 	    vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
26780: 	}
26781:     }
26782: 
26783:     return (0);
26784: }
26785: 
26786: static int
26787: xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
26788: {
26789:     int ret = 0;
26790: 
26791:     if ((vctxt->skipDepth != -1) &&
26792: 	(vctxt->depth >= vctxt->skipDepth)) {
26793: 	VERROR_INT("xmlSchemaValidateElem",
26794: 	    "in skip-state");
26795: 	goto internal_error;
26796:     }
26797:     if (vctxt->xsiAssemble) {
26798: 	/*
26799: 	* We will stop validation if there was an error during
26800: 	* dynamic schema construction.
26801: 	* Note that we simply set @skipDepth to 0, this could
26802: 	* mean that a streaming document via SAX would be
26803: 	* still read to the end but it won't be validated any more.
26804: 	* TODO: If we are sure how to stop the validation at once
26805: 	*   for all input scenarios, then this should be changed to
26806: 	*   instantly stop the validation.
26807: 	*/
26808: 	ret = xmlSchemaAssembleByXSI(vctxt);
26809: 	if (ret != 0) {
26810: 	    if (ret == -1)
26811: 		goto internal_error;
26812: 	    vctxt->skipDepth = 0;
26813: 	    return(ret);
26814: 	}
26815:         /*
26816:          * Augment the IDC definitions for the main schema and all imported ones
26817:          * NOTE: main schema is the first in the imported list
26818:          */
26819:         xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
26820:     }
26821:     if (vctxt->depth > 0) {
26822: 	/*
26823: 	* Validate this element against the content model
26824: 	* of the parent.
26825: 	*/
26826: 	ret = xmlSchemaValidateChildElem(vctxt);
26827: 	if (ret != 0) {
26828: 	    if (ret < 0) {
26829: 		VERROR_INT("xmlSchemaValidateElem",
26830: 		    "calling xmlSchemaStreamValidateChildElement()");
26831: 		goto internal_error;
26832: 	    }
26833: 	    goto exit;
26834: 	}
26835: 	if (vctxt->depth == vctxt->skipDepth)
26836: 	    goto exit;
26837: 	if ((vctxt->inode->decl == NULL) &&
26838: 	    (vctxt->inode->typeDef == NULL)) {
26839: 	    VERROR_INT("xmlSchemaValidateElem",
26840: 		"the child element was valid but neither the "
26841: 		"declaration nor the type was set");
26842: 	    goto internal_error;
26843: 	}
26844:     } else {
26845: 	/*
26846: 	* Get the declaration of the validation root.
26847: 	*/
26848: 	vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
26849: 	    vctxt->inode->localName,
26850: 	    vctxt->inode->nsName);
26851: 	if (vctxt->inode->decl == NULL) {
26852: 	    ret = XML_SCHEMAV_CVC_ELT_1;
26853: 	    VERROR(ret, NULL,
26854: 		"No matching global declaration available "
26855: 		"for the validation root");
26856: 	    goto exit;
26857: 	}
26858:     }
26859: 
26860:     if (vctxt->inode->decl == NULL)
26861: 	goto type_validation;
26862: 
26863:     if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
26864: 	int skip;
26865: 	/*
26866: 	* Wildcards.
26867: 	*/
26868: 	ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
26869: 	if (ret != 0) {
26870: 	    if (ret < 0) {
26871: 		VERROR_INT("xmlSchemaValidateElem",
26872: 		    "calling xmlSchemaValidateElemWildcard()");
26873: 		goto internal_error;
26874: 	    }
26875: 	    goto exit;
26876: 	}
26877: 	if (skip) {
26878: 	    vctxt->skipDepth = vctxt->depth;
26879: 	    goto exit;
26880: 	}
26881: 	/*
26882: 	* The declaration might be set by the wildcard validation,
26883: 	* when the processContents is "lax" or "strict".
26884: 	*/
26885: 	if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
26886: 	    /*
26887: 	    * Clear the "decl" field to not confuse further processing.
26888: 	    */
26889: 	    vctxt->inode->decl = NULL;
26890: 	    goto type_validation;
26891: 	}
26892:     }
26893:     /*
26894:     * Validate against the declaration.
26895:     */
26896:     ret = xmlSchemaValidateElemDecl(vctxt);
26897:     if (ret != 0) {
26898: 	if (ret < 0) {
26899: 	    VERROR_INT("xmlSchemaValidateElem",
26900: 		"calling xmlSchemaValidateElemDecl()");
26901: 	    goto internal_error;
26902: 	}
26903: 	goto exit;
26904:     }
26905:     /*
26906:     * Validate against the type definition.
26907:     */
26908: type_validation:
26909: 
26910:     if (vctxt->inode->typeDef == NULL) {
26911: 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26912: 	ret = XML_SCHEMAV_CVC_TYPE_1;
26913:     	VERROR(ret, NULL,
26914:     	    "The type definition is absent");
26915: 	goto exit;
26916:     }
26917:     if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
26918: 	vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
26919: 	ret = XML_SCHEMAV_CVC_TYPE_2;
26920:     	    VERROR(ret, NULL,
26921:     	    "The type definition is abstract");
26922: 	goto exit;
26923:     }
26924:     /*
26925:     * Evaluate IDCs. Do it here, since new IDC matchers are registered
26926:     * during validation against the declaration. This must be done
26927:     * _before_ attribute validation.
26928:     */
26929:     if (vctxt->xpathStates != NULL) {
26930: 	ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
26931: 	vctxt->inode->appliedXPath = 1;
26932: 	if (ret == -1) {
26933: 	    VERROR_INT("xmlSchemaValidateElem",
26934: 		"calling xmlSchemaXPathEvaluate()");
26935: 	    goto internal_error;
26936: 	}
26937:     }
26938:     /*
26939:     * Validate attributes.
26940:     */
26941:     if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
26942: 	if ((vctxt->nbAttrInfos != 0) ||
26943: 	    (vctxt->inode->typeDef->attrUses != NULL)) {
26944: 
26945: 	    ret = xmlSchemaVAttributesComplex(vctxt);
26946: 	}
26947:     } else if (vctxt->nbAttrInfos != 0) {
26948: 
26949: 	ret = xmlSchemaVAttributesSimple(vctxt);
26950:     }
26951:     /*
26952:     * Clear registered attributes.
26953:     */
26954:     if (vctxt->nbAttrInfos != 0)
26955: 	xmlSchemaClearAttrInfos(vctxt);
26956:     if (ret == -1) {
26957: 	VERROR_INT("xmlSchemaValidateElem",
26958: 	    "calling attributes validation");
26959: 	goto internal_error;
26960:     }
26961:     /*
26962:     * Don't return an error if attributes are invalid on purpose.
26963:     */
26964:     ret = 0;
26965: 
26966: exit:
26967:     if (ret != 0)
26968: 	vctxt->skipDepth = vctxt->depth;
26969:     return (ret);
26970: internal_error:
26971:     return (-1);
26972: }
26973: 
26974: #ifdef XML_SCHEMA_READER_ENABLED
26975: static int
26976: xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
26977: {
26978:     const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
26979:     int depth, nodeType, ret = 0, consumed;
26980:     xmlSchemaNodeInfoPtr ielem;
26981: 
26982:     vctxt->depth = -1;
26983:     ret = xmlTextReaderRead(vctxt->reader);
26984:     /*
26985:     * Move to the document element.
26986:     */
26987:     while (ret == 1) {
26988: 	nodeType = xmlTextReaderNodeType(vctxt->reader);
26989: 	if (nodeType == XML_ELEMENT_NODE)
26990: 	    goto root_found;
26991: 	ret = xmlTextReaderRead(vctxt->reader);
26992:     }
26993:     goto exit;
26994: 
26995: root_found:
26996: 
26997:     do {
26998: 	depth = xmlTextReaderDepth(vctxt->reader);
26999: 	nodeType = xmlTextReaderNodeType(vctxt->reader);
27000: 
27001: 	if (nodeType == XML_ELEMENT_NODE) {
27002: 
27003: 	    vctxt->depth++;
27004: 	    if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27005: 		VERROR_INT("xmlSchemaVReaderWalk",
27006: 		    "calling xmlSchemaValidatorPushElem()");
27007: 		goto internal_error;
27008: 	    }
27009: 	    ielem = vctxt->inode;
27010: 	    ielem->localName = xmlTextReaderLocalName(vctxt->reader);
27011: 	    ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
27012: 	    ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
27013: 	    /*
27014: 	    * Is the element empty?
27015: 	    */
27016: 	    ret = xmlTextReaderIsEmptyElement(vctxt->reader);
27017: 	    if (ret == -1) {
27018: 		VERROR_INT("xmlSchemaVReaderWalk",
27019: 		    "calling xmlTextReaderIsEmptyElement()");
27020: 		goto internal_error;
27021: 	    }
27022: 	    if (ret) {
27023: 		ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27024: 	    }
27025: 	    /*
27026: 	    * Register attributes.
27027: 	    */
27028: 	    vctxt->nbAttrInfos = 0;
27029: 	    ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
27030: 	    if (ret == -1) {
27031: 		VERROR_INT("xmlSchemaVReaderWalk",
27032: 		    "calling xmlTextReaderMoveToFirstAttribute()");
27033: 		goto internal_error;
27034: 	    }
27035: 	    if (ret == 1) {
27036: 		do {
27037: 		    /*
27038: 		    * VAL TODO: How do we know that the reader works on a
27039: 		    * node tree, to be able to pass a node here?
27040: 		    */
27041: 		    if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
27042: 			(const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
27043: 			xmlTextReaderNamespaceUri(vctxt->reader), 1,
27044: 			xmlTextReaderValue(vctxt->reader), 1) == -1) {
27045: 
27046: 			VERROR_INT("xmlSchemaVReaderWalk",
27047: 			    "calling xmlSchemaValidatorPushAttribute()");
27048: 			goto internal_error;
27049: 		    }
27050: 		    ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
27051: 		    if (ret == -1) {
27052: 			VERROR_INT("xmlSchemaVReaderWalk",
27053: 			    "calling xmlTextReaderMoveToFirstAttribute()");
27054: 			goto internal_error;
27055: 		    }
27056: 		} while (ret == 1);
27057: 		/*
27058: 		* Back to element position.
27059: 		*/
27060: 		ret = xmlTextReaderMoveToElement(vctxt->reader);
27061: 		if (ret == -1) {
27062: 		    VERROR_INT("xmlSchemaVReaderWalk",
27063: 			"calling xmlTextReaderMoveToElement()");
27064: 		    goto internal_error;
27065: 		}
27066: 	    }
27067: 	    /*
27068: 	    * Validate the element.
27069: 	    */
27070: 	    ret= xmlSchemaValidateElem(vctxt);
27071: 	    if (ret != 0) {
27072: 		if (ret == -1) {
27073: 		    VERROR_INT("xmlSchemaVReaderWalk",
27074: 			"calling xmlSchemaValidateElem()");
27075: 		    goto internal_error;
27076: 		}
27077: 		goto exit;
27078: 	    }
27079: 	    if (vctxt->depth == vctxt->skipDepth) {
27080: 		int curDepth;
27081: 		/*
27082: 		* Skip all content.
27083: 		*/
27084: 		if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
27085: 		    ret = xmlTextReaderRead(vctxt->reader);
27086: 		    curDepth = xmlTextReaderDepth(vctxt->reader);
27087: 		    while ((ret == 1) && (curDepth != depth)) {
27088: 			ret = xmlTextReaderRead(vctxt->reader);
27089: 			curDepth = xmlTextReaderDepth(vctxt->reader);
27090: 		    }
27091: 		    if (ret < 0) {
27092: 			/*
27093: 			* VAL TODO: A reader error occured; what to do here?
27094: 			*/
27095: 			ret = 1;
27096: 			goto exit;
27097: 		    }
27098: 		}
27099: 		goto leave_elem;
27100: 	    }
27101: 	    /*
27102: 	    * READER VAL TODO: Is an END_ELEM really never called
27103: 	    * if the elem is empty?
27104: 	    */
27105: 	    if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27106: 		goto leave_elem;
27107: 	} else if (nodeType == END_ELEM) {
27108: 	    /*
27109: 	    * Process END of element.
27110: 	    */
27111: leave_elem:
27112: 	    ret = xmlSchemaValidatorPopElem(vctxt);
27113: 	    if (ret != 0) {
27114: 		if (ret < 0) {
27115: 		    VERROR_INT("xmlSchemaVReaderWalk",
27116: 			"calling xmlSchemaValidatorPopElem()");
27117: 		    goto internal_error;
27118: 		}
27119: 		goto exit;
27120: 	    }
27121: 	    if (vctxt->depth >= 0)
27122: 		ielem = vctxt->inode;
27123: 	    else
27124: 		ielem = NULL;
27125: 	} else if ((nodeType == XML_TEXT_NODE) ||
27126: 	    (nodeType == XML_CDATA_SECTION_NODE) ||
27127: 	    (nodeType == WHTSP) ||
27128: 	    (nodeType == SIGN_WHTSP)) {
27129: 	    /*
27130: 	    * Process character content.
27131: 	    */
27132: 	    xmlChar *value;
27133: 
27134: 	    if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
27135: 		nodeType = XML_TEXT_NODE;
27136: 
27137: 	    value = xmlTextReaderValue(vctxt->reader);
27138: 	    ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
27139: 		-1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
27140: 	    if (! consumed)
27141: 		xmlFree(value);
27142: 	    if (ret == -1) {
27143: 		VERROR_INT("xmlSchemaVReaderWalk",
27144: 		    "calling xmlSchemaVPushText()");
27145: 		goto internal_error;
27146: 	    }
27147: 	} else if ((nodeType == XML_ENTITY_NODE) ||
27148: 	    (nodeType == XML_ENTITY_REF_NODE)) {
27149: 	    /*
27150: 	    * VAL TODO: What to do with entities?
27151: 	    */
27152: 	    TODO
27153: 	}
27154: 	/*
27155: 	* Read next node.
27156: 	*/
27157: 	ret = xmlTextReaderRead(vctxt->reader);
27158:     } while (ret == 1);
27159: 
27160: exit:
27161:     return (ret);
27162: internal_error:
27163:     return (-1);
27164: }
27165: #endif
27166: 
27167: /************************************************************************
27168:  * 									*
27169:  * 			SAX validation handlers				*
27170:  * 									*
27171:  ************************************************************************/
27172: 
27173: /*
27174: * Process text content.
27175: */
27176: static void
27177: xmlSchemaSAXHandleText(void *ctx,
27178: 		       const xmlChar * ch,
27179: 		       int len)
27180: {
27181:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27182: 
27183:     if (vctxt->depth < 0)
27184: 	return;
27185:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27186: 	return;
27187:     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27188: 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27189:     if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
27190: 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27191: 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
27192: 	    "calling xmlSchemaVPushText()");
27193: 	vctxt->err = -1;
27194: 	xmlStopParser(vctxt->parserCtxt);
27195:     }
27196: }
27197: 
27198: /*
27199: * Process CDATA content.
27200: */
27201: static void
27202: xmlSchemaSAXHandleCDataSection(void *ctx,
27203: 			     const xmlChar * ch,
27204: 			     int len)
27205: {
27206:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27207: 
27208:     if (vctxt->depth < 0)
27209: 	return;
27210:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27211: 	return;
27212:     if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
27213: 	vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27214:     if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
27215: 	XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
27216: 	VERROR_INT("xmlSchemaSAXHandleCDataSection",
27217: 	    "calling xmlSchemaVPushText()");
27218: 	vctxt->err = -1;
27219: 	xmlStopParser(vctxt->parserCtxt);
27220:     }
27221: }
27222: 
27223: static void
27224: xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
27225: 			    const xmlChar * name ATTRIBUTE_UNUSED)
27226: {
27227:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27228: 
27229:     if (vctxt->depth < 0)
27230: 	return;
27231:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27232: 	return;
27233:     /* SAX VAL TODO: What to do here? */
27234:     TODO
27235: }
27236: 
27237: static void
27238: xmlSchemaSAXHandleStartElementNs(void *ctx,
27239: 				 const xmlChar * localname,
27240: 				 const xmlChar * prefix ATTRIBUTE_UNUSED,
27241: 				 const xmlChar * URI,
27242: 				 int nb_namespaces,
27243: 				 const xmlChar ** namespaces,
27244: 				 int nb_attributes,
27245: 				 int nb_defaulted ATTRIBUTE_UNUSED,
27246: 				 const xmlChar ** attributes)
27247: {
27248:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27249:     int ret;
27250:     xmlSchemaNodeInfoPtr ielem;
27251:     int i, j;
27252: 
27253:     /*
27254:     * SAX VAL TODO: What to do with nb_defaulted?
27255:     */
27256:     /*
27257:     * Skip elements if inside a "skip" wildcard or invalid.
27258:     */
27259:     vctxt->depth++;
27260:     if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27261: 	return;
27262:     /*
27263:     * Push the element.
27264:     */
27265:     if (xmlSchemaValidatorPushElem(vctxt) == -1) {
27266: 	VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27267: 	    "calling xmlSchemaValidatorPushElem()");
27268: 	goto internal_error;
27269:     }
27270:     ielem = vctxt->inode;
27271:     /*
27272:     * TODO: Is this OK?
27273:     */
27274:     ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
27275:     ielem->localName = localname;
27276:     ielem->nsName = URI;
27277:     ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27278:     /*
27279:     * Register namespaces on the elem info.
27280:     */
27281:     if (nb_namespaces != 0) {
27282: 	/*
27283: 	* Although the parser builds its own namespace list,
27284: 	* we have no access to it, so we'll use an own one.
27285: 	*/
27286:         for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
27287: 	    /*
27288: 	    * Store prefix and namespace name.
27289: 	    */
27290: 	    if (ielem->nsBindings == NULL) {
27291: 		ielem->nsBindings =
27292: 		    (const xmlChar **) xmlMalloc(10 *
27293: 			sizeof(const xmlChar *));
27294: 		if (ielem->nsBindings == NULL) {
27295: 		    xmlSchemaVErrMemory(vctxt,
27296: 			"allocating namespace bindings for SAX validation",
27297: 			NULL);
27298: 		    goto internal_error;
27299: 		}
27300: 		ielem->nbNsBindings = 0;
27301: 		ielem->sizeNsBindings = 5;
27302: 	    } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
27303: 		ielem->sizeNsBindings *= 2;
27304: 		ielem->nsBindings =
27305: 		    (const xmlChar **) xmlRealloc(
27306: 			(void *) ielem->nsBindings,
27307: 			ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
27308: 		if (ielem->nsBindings == NULL) {
27309: 		    xmlSchemaVErrMemory(vctxt,
27310: 			"re-allocating namespace bindings for SAX validation",
27311: 			NULL);
27312: 		    goto internal_error;
27313: 		}
27314: 	    }
27315: 
27316: 	    ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
27317: 	    if (namespaces[j+1][0] == 0) {
27318: 		/*
27319: 		* Handle xmlns="".
27320: 		*/
27321: 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
27322: 	    } else
27323: 		ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
27324: 		    namespaces[j+1];
27325: 	    ielem->nbNsBindings++;
27326: 	}
27327:     }
27328:     /*
27329:     * Register attributes.
27330:     * SAX VAL TODO: We are not adding namespace declaration
27331:     * attributes yet.
27332:     */
27333:     if (nb_attributes != 0) {
27334: 	xmlChar *value;
27335: 
27336:         for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
27337: 	    /*
27338: 	    * Duplicate the value.
27339: 	    */
27340: 	    value = xmlStrndup(attributes[j+3],
27341: 		attributes[j+4] - attributes[j+3]);
27342: 	    /*
27343: 	    * TODO: Set the node line.
27344: 	    */
27345: 	    ret = xmlSchemaValidatorPushAttribute(vctxt,
27346: 		NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
27347: 		value, 1);
27348: 	    if (ret == -1) {
27349: 		VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27350: 		    "calling xmlSchemaValidatorPushAttribute()");
27351: 		goto internal_error;
27352: 	    }
27353: 	}
27354:     }
27355:     /*
27356:     * Validate the element.
27357:     */
27358:     ret = xmlSchemaValidateElem(vctxt);
27359:     if (ret != 0) {
27360: 	if (ret == -1) {
27361: 	    VERROR_INT("xmlSchemaSAXHandleStartElementNs",
27362: 		"calling xmlSchemaValidateElem()");
27363: 	    goto internal_error;
27364: 	}
27365: 	goto exit;
27366:     }
27367: 
27368: exit:
27369:     return;
27370: internal_error:
27371:     vctxt->err = -1;
27372:     xmlStopParser(vctxt->parserCtxt);
27373:     return;
27374: }
27375: 
27376: static void
27377: xmlSchemaSAXHandleEndElementNs(void *ctx,
27378: 			       const xmlChar * localname ATTRIBUTE_UNUSED,
27379: 			       const xmlChar * prefix ATTRIBUTE_UNUSED,
27380: 			       const xmlChar * URI ATTRIBUTE_UNUSED)
27381: {
27382:     xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
27383:     int res;
27384: 
27385:     /*
27386:     * Skip elements if inside a "skip" wildcard or if invalid.
27387:     */
27388:     if (vctxt->skipDepth != -1) {
27389: 	if (vctxt->depth > vctxt->skipDepth) {
27390: 	    vctxt->depth--;
27391: 	    return;
27392: 	} else
27393: 	    vctxt->skipDepth = -1;
27394:     }
27395:     /*
27396:     * SAX VAL TODO: Just a temporary check.
27397:     */
27398:     if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
27399: 	(!xmlStrEqual(vctxt->inode->nsName, URI))) {
27400: 	VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27401: 	    "elem pop mismatch");
27402:     }
27403:     res = xmlSchemaValidatorPopElem(vctxt);
27404:     if (res != 0) {
27405: 	if (res < 0) {
27406: 	    VERROR_INT("xmlSchemaSAXHandleEndElementNs",
27407: 		"calling xmlSchemaValidatorPopElem()");
27408: 	    goto internal_error;
27409: 	}
27410: 	goto exit;
27411:     }
27412: exit:
27413:     return;
27414: internal_error:
27415:     vctxt->err = -1;
27416:     xmlStopParser(vctxt->parserCtxt);
27417:     return;
27418: }
27419: 
27420: /************************************************************************
27421:  * 									*
27422:  * 			Validation interfaces				*
27423:  * 									*
27424:  ************************************************************************/
27425: 
27426: /**
27427:  * xmlSchemaNewValidCtxt:
27428:  * @schema:  a precompiled XML Schemas
27429:  *
27430:  * Create an XML Schemas validation context based on the given schema.
27431:  *
27432:  * Returns the validation context or NULL in case of error
27433:  */
27434: xmlSchemaValidCtxtPtr
27435: xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
27436: {
27437:     xmlSchemaValidCtxtPtr ret;
27438: 
27439:     ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
27440:     if (ret == NULL) {
27441:         xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
27442:         return (NULL);
27443:     }
27444:     memset(ret, 0, sizeof(xmlSchemaValidCtxt));
27445:     ret->type = XML_SCHEMA_CTXT_VALIDATOR;
27446:     ret->dict = xmlDictCreate();
27447:     ret->nodeQNames = xmlSchemaItemListCreate();
27448:     ret->schema = schema;
27449:     return (ret);
27450: }
27451: 
27452: /**
27453:  * xmlSchemaClearValidCtxt:
27454:  * @ctxt: the schema validation context
27455:  *
27456:  * Free the resources associated to the schema validation context;
27457:  * leaves some fields alive intended for reuse of the context.
27458:  */
27459: static void
27460: xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
27461: {
27462:     if (vctxt == NULL)
27463:         return;
27464: 
27465:     /*
27466:     * TODO: Should we clear the flags?
27467:     *   Might be problematic if one reuses the context
27468:     *   and assumes that the options remain the same.
27469:     */
27470:     vctxt->flags = 0;
27471:     vctxt->validationRoot = NULL;
27472:     vctxt->doc = NULL;
27473: #ifdef LIBXML_READER_ENABLED
27474:     vctxt->reader = NULL;
27475: #endif
27476:     vctxt->hasKeyrefs = 0;
27477: 
27478:     if (vctxt->value != NULL) {
27479:         xmlSchemaFreeValue(vctxt->value);
27480: 	vctxt->value = NULL;
27481:     }
27482:     /*
27483:     * Augmented IDC information.
27484:     */
27485:     if (vctxt->aidcs != NULL) {
27486: 	xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
27487: 	do {
27488: 	    next = cur->next;
27489: 	    xmlFree(cur);
27490: 	    cur = next;
27491: 	} while (cur != NULL);
27492: 	vctxt->aidcs = NULL;
27493:     }
27494:     if (vctxt->idcMatcherCache != NULL) {
27495: 	xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
27496: 
27497: 	while (matcher) {
27498: 	    tmp = matcher;
27499: 	    matcher = matcher->nextCached;
27500: 	    xmlSchemaIDCFreeMatcherList(tmp);
27501: 	}
27502: 	vctxt->idcMatcherCache = NULL;
27503:     }
27504: 
27505: 
27506:     if (vctxt->idcNodes != NULL) {
27507: 	int i;
27508: 	xmlSchemaPSVIIDCNodePtr item;
27509: 
27510: 	for (i = 0; i < vctxt->nbIdcNodes; i++) {
27511: 	    item = vctxt->idcNodes[i];
27512: 	    xmlFree(item->keys);
27513: 	    xmlFree(item);
27514: 	}
27515: 	xmlFree(vctxt->idcNodes);
27516: 	vctxt->idcNodes = NULL;
27517: 	vctxt->nbIdcNodes = 0;
27518: 	vctxt->sizeIdcNodes = 0;
27519:     }
27520:     /*
27521:     * Note that we won't delete the XPath state pool here.
27522:     */
27523:     if (vctxt->xpathStates != NULL) {
27524: 	xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
27525: 	vctxt->xpathStates = NULL;
27526:     }
27527:     /*
27528:     * Attribute info.
27529:     */
27530:     if (vctxt->nbAttrInfos != 0) {
27531: 	xmlSchemaClearAttrInfos(vctxt);
27532:     }
27533:     /*
27534:     * Element info.
27535:     */
27536:     if (vctxt->elemInfos != NULL) {
27537: 	int i;
27538: 	xmlSchemaNodeInfoPtr ei;
27539: 
27540: 	for (i = 0; i < vctxt->sizeElemInfos; i++) {
27541: 	    ei = vctxt->elemInfos[i];
27542: 	    if (ei == NULL)
27543: 		break;
27544: 	    xmlSchemaClearElemInfo(vctxt, ei);
27545: 	}
27546:     }
27547:     xmlSchemaItemListClear(vctxt->nodeQNames);
27548:     /* Recreate the dict. */
27549:     xmlDictFree(vctxt->dict);
27550:     /*
27551:     * TODO: Is is save to recreate it? Do we have a scenario
27552:     * where the user provides the dict?
27553:     */
27554:     vctxt->dict = xmlDictCreate();
27555: }
27556: 
27557: /**
27558:  * xmlSchemaFreeValidCtxt:
27559:  * @ctxt:  the schema validation context
27560:  *
27561:  * Free the resources associated to the schema validation context
27562:  */
27563: void
27564: xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
27565: {
27566:     if (ctxt == NULL)
27567:         return;
27568:     if (ctxt->value != NULL)
27569:         xmlSchemaFreeValue(ctxt->value);
27570:     if (ctxt->pctxt != NULL)
27571: 	xmlSchemaFreeParserCtxt(ctxt->pctxt);
27572:     if (ctxt->idcNodes != NULL) {
27573: 	int i;
27574: 	xmlSchemaPSVIIDCNodePtr item;
27575: 
27576: 	for (i = 0; i < ctxt->nbIdcNodes; i++) {
27577: 	    item = ctxt->idcNodes[i];
27578: 	    xmlFree(item->keys);
27579: 	    xmlFree(item);
27580: 	}
27581: 	xmlFree(ctxt->idcNodes);
27582:     }
27583:     if (ctxt->idcKeys != NULL) {
27584: 	int i;
27585: 	for (i = 0; i < ctxt->nbIdcKeys; i++)
27586: 	    xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
27587: 	xmlFree(ctxt->idcKeys);
27588:     }
27589: 
27590:     if (ctxt->xpathStates != NULL) {
27591: 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
27592: 	ctxt->xpathStates = NULL;
27593:     }
27594:     if (ctxt->xpathStatePool != NULL) {
27595: 	xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
27596: 	ctxt->xpathStatePool = NULL;
27597:     }
27598: 
27599:     /*
27600:     * Augmented IDC information.
27601:     */
27602:     if (ctxt->aidcs != NULL) {
27603: 	xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
27604: 	do {
27605: 	    next = cur->next;
27606: 	    xmlFree(cur);
27607: 	    cur = next;
27608: 	} while (cur != NULL);
27609:     }
27610:     if (ctxt->attrInfos != NULL) {
27611: 	int i;
27612: 	xmlSchemaAttrInfoPtr attr;
27613: 
27614: 	/* Just a paranoid call to the cleanup. */
27615: 	if (ctxt->nbAttrInfos != 0)
27616: 	    xmlSchemaClearAttrInfos(ctxt);
27617: 	for (i = 0; i < ctxt->sizeAttrInfos; i++) {
27618: 	    attr = ctxt->attrInfos[i];
27619: 	    xmlFree(attr);
27620: 	}
27621: 	xmlFree(ctxt->attrInfos);
27622:     }
27623:     if (ctxt->elemInfos != NULL) {
27624: 	int i;
27625: 	xmlSchemaNodeInfoPtr ei;
27626: 
27627: 	for (i = 0; i < ctxt->sizeElemInfos; i++) {
27628: 	    ei = ctxt->elemInfos[i];
27629: 	    if (ei == NULL)
27630: 		break;
27631: 	    xmlSchemaClearElemInfo(ctxt, ei);
27632: 	    xmlFree(ei);
27633: 	}
27634: 	xmlFree(ctxt->elemInfos);
27635:     }
27636:     if (ctxt->nodeQNames != NULL)
27637: 	xmlSchemaItemListFree(ctxt->nodeQNames);
27638:     if (ctxt->dict != NULL)
27639: 	xmlDictFree(ctxt->dict);
27640:     xmlFree(ctxt);
27641: }
27642: 
27643: /**
27644:  * xmlSchemaIsValid:
27645:  * @ctxt: the schema validation context
27646:  *
27647:  * Check if any error was detected during validation.
27648:  *
27649:  * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
27650:  *         of internal error.
27651:  */
27652: int
27653: xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
27654: {
27655:     if (ctxt == NULL)
27656:         return(-1);
27657:     return(ctxt->err == 0);
27658: }
27659: 
27660: /**
27661:  * xmlSchemaSetValidErrors:
27662:  * @ctxt:  a schema validation context
27663:  * @err:  the error function
27664:  * @warn: the warning function
27665:  * @ctx: the functions context
27666:  *
27667:  * Set the error and warning callback informations
27668:  */
27669: void
27670: xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27671:                         xmlSchemaValidityErrorFunc err,
27672:                         xmlSchemaValidityWarningFunc warn, void *ctx)
27673: {
27674:     if (ctxt == NULL)
27675:         return;
27676:     ctxt->error = err;
27677:     ctxt->warning = warn;
27678:     ctxt->errCtxt = ctx;
27679:     if (ctxt->pctxt != NULL)
27680: 	xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
27681: }
27682: 
27683: /**
27684:  * xmlSchemaSetValidStructuredErrors:
27685:  * @ctxt:  a schema validation context
27686:  * @serror:  the structured error function
27687:  * @ctx: the functions context
27688:  *
27689:  * Set the structured error callback
27690:  */
27691: void
27692: xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
27693: 				  xmlStructuredErrorFunc serror, void *ctx)
27694: {
27695:     if (ctxt == NULL)
27696:         return;
27697: 	ctxt->serror = serror;
27698:     ctxt->error = NULL;
27699:     ctxt->warning = NULL;
27700:     ctxt->errCtxt = ctx;
27701:     if (ctxt->pctxt != NULL)
27702: 	xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
27703: }
27704: 
27705: /**
27706:  * xmlSchemaGetValidErrors:
27707:  * @ctxt: a XML-Schema validation context
27708:  * @err: the error function result
27709:  * @warn: the warning function result
27710:  * @ctx: the functions context result
27711:  *
27712:  * Get the error and warning callback informations
27713:  *
27714:  * Returns -1 in case of error and 0 otherwise
27715:  */
27716: int
27717: xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
27718: 			xmlSchemaValidityErrorFunc * err,
27719: 			xmlSchemaValidityWarningFunc * warn, void **ctx)
27720: {
27721: 	if (ctxt == NULL)
27722: 		return (-1);
27723: 	if (err != NULL)
27724: 		*err = ctxt->error;
27725: 	if (warn != NULL)
27726: 		*warn = ctxt->warning;
27727: 	if (ctx != NULL)
27728: 		*ctx = ctxt->errCtxt;
27729: 	return (0);
27730: }
27731: 
27732: 
27733: /**
27734:  * xmlSchemaSetValidOptions:
27735:  * @ctxt:	a schema validation context
27736:  * @options: a combination of xmlSchemaValidOption
27737:  *
27738:  * Sets the options to be used during the validation.
27739:  *
27740:  * Returns 0 in case of success, -1 in case of an
27741:  * API error.
27742:  */
27743: int
27744: xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
27745: 			 int options)
27746: 
27747: {
27748:     int i;
27749: 
27750:     if (ctxt == NULL)
27751: 	return (-1);
27752:     /*
27753:     * WARNING: Change the start value if adding to the
27754:     * xmlSchemaValidOption.
27755:     * TODO: Is there an other, more easy to maintain,
27756:     * way?
27757:     */
27758:     for (i = 1; i < (int) sizeof(int) * 8; i++) {
27759:         if (options & 1<<i)
27760: 	    return (-1);
27761:     }
27762:     ctxt->options = options;
27763:     return (0);
27764: }
27765: 
27766: /**
27767:  * xmlSchemaValidCtxtGetOptions:
27768:  * @ctxt: a schema validation context
27769:  *
27770:  * Get the validation context options.
27771:  *
27772:  * Returns the option combination or -1 on error.
27773:  */
27774: int
27775: xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
27776: 
27777: {
27778:     if (ctxt == NULL)
27779: 	return (-1);
27780:     else
27781: 	return (ctxt->options);
27782: }
27783: 
27784: static int
27785: xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
27786: {
27787:     xmlAttrPtr attr;
27788:     int ret = 0;
27789:     xmlSchemaNodeInfoPtr ielem = NULL;
27790:     xmlNodePtr node, valRoot;
27791:     const xmlChar *nsName;
27792: 
27793:     /* DOC VAL TODO: Move this to the start function. */
27794:     valRoot = xmlDocGetRootElement(vctxt->doc);
27795:     if (valRoot == NULL) {
27796: 	/* VAL TODO: Error code? */
27797: 	VERROR(1, NULL, "The document has no document element");
27798: 	return (1);
27799:     }
27800:     vctxt->depth = -1;
27801:     vctxt->validationRoot = valRoot;
27802:     node = valRoot;
27803:     while (node != NULL) {
27804: 	if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
27805: 	    goto next_sibling;
27806: 	if (node->type == XML_ELEMENT_NODE) {
27807: 
27808: 	    /*
27809: 	    * Init the node-info.
27810: 	    */
27811: 	    vctxt->depth++;
27812: 	    if (xmlSchemaValidatorPushElem(vctxt) == -1)
27813: 		goto internal_error;
27814: 	    ielem = vctxt->inode;
27815: 	    ielem->node = node;
27816: 	    ielem->nodeLine = node->line;
27817: 	    ielem->localName = node->name;
27818: 	    if (node->ns != NULL)
27819: 		ielem->nsName = node->ns->href;
27820: 	    ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
27821: 	    /*
27822: 	    * Register attributes.
27823: 	    * DOC VAL TODO: We do not register namespace declaration
27824: 	    * attributes yet.
27825: 	    */
27826: 	    vctxt->nbAttrInfos = 0;
27827: 	    if (node->properties != NULL) {
27828: 		attr = node->properties;
27829: 		do {
27830: 		    if (attr->ns != NULL)
27831: 			nsName = attr->ns->href;
27832: 		    else
27833: 			nsName = NULL;
27834: 		    ret = xmlSchemaValidatorPushAttribute(vctxt,
27835: 			(xmlNodePtr) attr,
27836: 			/*
27837: 			* Note that we give it the line number of the
27838: 			* parent element.
27839: 			*/
27840: 			ielem->nodeLine,
27841: 			attr->name, nsName, 0,
27842: 			xmlNodeListGetString(attr->doc, attr->children, 1), 1);
27843: 		    if (ret == -1) {
27844: 			VERROR_INT("xmlSchemaDocWalk",
27845: 			    "calling xmlSchemaValidatorPushAttribute()");
27846: 			goto internal_error;
27847: 		    }
27848: 		    attr = attr->next;
27849: 		} while (attr);
27850: 	    }
27851: 	    /*
27852: 	    * Validate the element.
27853: 	    */
27854: 	    ret = xmlSchemaValidateElem(vctxt);
27855: 	    if (ret != 0) {
27856: 		if (ret == -1) {
27857: 		    VERROR_INT("xmlSchemaDocWalk",
27858: 			"calling xmlSchemaValidateElem()");
27859: 		    goto internal_error;
27860: 		}
27861: 		/*
27862: 		* Don't stop validation; just skip the content
27863: 		* of this element.
27864: 		*/
27865: 		goto leave_node;
27866: 	    }
27867: 	    if ((vctxt->skipDepth != -1) &&
27868: 		(vctxt->depth >= vctxt->skipDepth))
27869: 		goto leave_node;
27870: 	} else if ((node->type == XML_TEXT_NODE) ||
27871: 	    (node->type == XML_CDATA_SECTION_NODE)) {
27872: 	    /*
27873: 	    * Process character content.
27874: 	    */
27875: 	    if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
27876: 		ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
27877: 	    ret = xmlSchemaVPushText(vctxt, node->type, node->content,
27878: 		-1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
27879: 	    if (ret < 0) {
27880: 		VERROR_INT("xmlSchemaVDocWalk",
27881: 		    "calling xmlSchemaVPushText()");
27882: 		goto internal_error;
27883: 	    }
27884: 	    /*
27885: 	    * DOC VAL TODO: Should we skip further validation of the
27886: 	    * element content here?
27887: 	    */
27888: 	} else if ((node->type == XML_ENTITY_NODE) ||
27889: 	    (node->type == XML_ENTITY_REF_NODE)) {
27890: 	    /*
27891: 	    * DOC VAL TODO: What to do with entities?
27892: 	    */
27893: 	    VERROR_INT("xmlSchemaVDocWalk",
27894: 		"there is at least one entity reference in the node-tree "
27895: 		"currently being validated. Processing of entities with "
27896: 		"this XML Schema processor is not supported (yet). Please "
27897: 		"substitute entities before validation.");
27898: 	    goto internal_error;
27899: 	} else {
27900: 	    goto leave_node;
27901: 	    /*
27902: 	    * DOC VAL TODO: XInclude nodes, etc.
27903: 	    */
27904: 	}
27905: 	/*
27906: 	* Walk the doc.
27907: 	*/
27908: 	if (node->children != NULL) {
27909: 	    node = node->children;
27910: 	    continue;
27911: 	}
27912: leave_node:
27913: 	if (node->type == XML_ELEMENT_NODE) {
27914: 	    /*
27915: 	    * Leaving the scope of an element.
27916: 	    */
27917: 	    if (node != vctxt->inode->node) {
27918: 		VERROR_INT("xmlSchemaVDocWalk",
27919: 		    "element position mismatch");
27920: 		goto internal_error;
27921: 	    }
27922: 	    ret = xmlSchemaValidatorPopElem(vctxt);
27923: 	    if (ret != 0) {
27924: 		if (ret < 0) {
27925: 		    VERROR_INT("xmlSchemaVDocWalk",
27926: 			"calling xmlSchemaValidatorPopElem()");
27927: 		    goto internal_error;
27928: 		}
27929: 	    }
27930: 	    if (node == valRoot)
27931: 		goto exit;
27932: 	}
27933: next_sibling:
27934: 	if (node->next != NULL)
27935: 	    node = node->next;
27936: 	else {
27937: 	    node = node->parent;
27938: 	    goto leave_node;
27939: 	}
27940:     }
27941: 
27942: exit:
27943:     return (ret);
27944: internal_error:
27945:     return (-1);
27946: }
27947: 
27948: static int
27949: xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
27950:     /*
27951:     * Some initialization.
27952:     */
27953:     vctxt->err = 0;
27954:     vctxt->nberrors = 0;
27955:     vctxt->depth = -1;
27956:     vctxt->skipDepth = -1;
27957:     vctxt->xsiAssemble = 0;
27958:     vctxt->hasKeyrefs = 0;
27959: #ifdef ENABLE_IDC_NODE_TABLES_TEST
27960:     vctxt->createIDCNodeTables = 1;
27961: #else
27962:     vctxt->createIDCNodeTables = 0;
27963: #endif
27964:     /*
27965:     * Create a schema + parser if necessary.
27966:     */
27967:     if (vctxt->schema == NULL) {
27968: 	xmlSchemaParserCtxtPtr pctxt;
27969: 
27970: 	vctxt->xsiAssemble = 1;
27971: 	/*
27972: 	* If not schema was given then we will create a schema
27973: 	* dynamically using XSI schema locations.
27974: 	*
27975: 	* Create the schema parser context.
27976: 	*/
27977: 	if ((vctxt->pctxt == NULL) &&
27978: 	   (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
27979: 	   return (-1);
27980: 	pctxt = vctxt->pctxt;
27981: 	pctxt->xsiAssemble = 1;
27982: 	/*
27983: 	* Create the schema.
27984: 	*/
27985: 	vctxt->schema = xmlSchemaNewSchema(pctxt);
27986: 	if (vctxt->schema == NULL)
27987: 	    return (-1);
27988: 	/*
27989: 	* Create the schema construction context.
27990: 	*/
27991: 	pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
27992: 	if (pctxt->constructor == NULL)
27993: 	    return(-1);
27994: 	pctxt->constructor->mainSchema = vctxt->schema;
27995: 	/*
27996: 	* Take ownership of the constructor to be able to free it.
27997: 	*/
27998: 	pctxt->ownsConstructor = 1;
27999:     }
28000:     /*
28001:     * Augment the IDC definitions for the main schema and all imported ones
28002:     * NOTE: main schema if the first in the imported list
28003:     */
28004:     xmlHashScan(vctxt->schema->schemasImports,(xmlHashScanner)xmlSchemaAugmentImportedIDC, vctxt);
28005: 
28006:     return(0);
28007: }
28008: 
28009: static void
28010: xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
28011:     if (vctxt->xsiAssemble) {
28012: 	if (vctxt->schema != NULL) {
28013: 	    xmlSchemaFree(vctxt->schema);
28014: 	    vctxt->schema = NULL;
28015: 	}
28016:     }
28017:     xmlSchemaClearValidCtxt(vctxt);
28018: }
28019: 
28020: static int
28021: xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
28022: {
28023:     int ret = 0;
28024: 
28025:     if (xmlSchemaPreRun(vctxt) < 0)
28026:         return(-1);
28027: 
28028:     if (vctxt->doc != NULL) {
28029: 	/*
28030: 	 * Tree validation.
28031: 	 */
28032: 	ret = xmlSchemaVDocWalk(vctxt);
28033: #ifdef LIBXML_READER_ENABLED
28034:     } else if (vctxt->reader != NULL) {
28035: 	/*
28036: 	 * XML Reader validation.
28037: 	 */
28038: #ifdef XML_SCHEMA_READER_ENABLED
28039: 	ret = xmlSchemaVReaderWalk(vctxt);
28040: #endif
28041: #endif
28042:     } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
28043: 	/*
28044: 	 * SAX validation.
28045: 	 */
28046: 	ret = xmlParseDocument(vctxt->parserCtxt);
28047:     } else {
28048: 	VERROR_INT("xmlSchemaVStart",
28049: 	    "no instance to validate");
28050: 	ret = -1;
28051:     }
28052: 
28053:     xmlSchemaPostRun(vctxt);
28054:     if (ret == 0)
28055: 	ret = vctxt->err;
28056:     return (ret);
28057: }
28058: 
28059: /**
28060:  * xmlSchemaValidateOneElement:
28061:  * @ctxt:  a schema validation context
28062:  * @elem:  an element node
28063:  *
28064:  * Validate a branch of a tree, starting with the given @elem.
28065:  *
28066:  * Returns 0 if the element and its subtree is valid, a positive error
28067:  * code number otherwise and -1 in case of an internal or API error.
28068:  */
28069: int
28070: xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
28071: {
28072:     if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
28073: 	return (-1);
28074: 
28075:     if (ctxt->schema == NULL)
28076: 	return (-1);
28077: 
28078:     ctxt->doc = elem->doc;
28079:     ctxt->node = elem;
28080:     ctxt->validationRoot = elem;
28081:     return(xmlSchemaVStart(ctxt));
28082: }
28083: 
28084: /**
28085:  * xmlSchemaValidateDoc:
28086:  * @ctxt:  a schema validation context
28087:  * @doc:  a parsed document tree
28088:  *
28089:  * Validate a document tree in memory.
28090:  *
28091:  * Returns 0 if the document is schemas valid, a positive error code
28092:  *     number otherwise and -1 in case of internal or API error.
28093:  */
28094: int
28095: xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
28096: {
28097:     if ((ctxt == NULL) || (doc == NULL))
28098:         return (-1);
28099: 
28100:     ctxt->doc = doc;
28101:     ctxt->node = xmlDocGetRootElement(doc);
28102:     if (ctxt->node == NULL) {
28103:         xmlSchemaCustomErr(ACTXT_CAST ctxt,
28104: 	    XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
28105: 	    (xmlNodePtr) doc, NULL,
28106: 	    "The document has no document element", NULL, NULL);
28107:         return (ctxt->err);
28108:     }
28109:     ctxt->validationRoot = ctxt->node;
28110:     return (xmlSchemaVStart(ctxt));
28111: }
28112: 
28113: 
28114: /************************************************************************
28115:  * 									*
28116:  * 		Function and data for SAX streaming API			*
28117:  * 									*
28118:  ************************************************************************/
28119: typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
28120: typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
28121: 
28122: struct _xmlSchemaSplitSAXData {
28123:     xmlSAXHandlerPtr      user_sax;
28124:     void                 *user_data;
28125:     xmlSchemaValidCtxtPtr ctxt;
28126:     xmlSAXHandlerPtr      schemas_sax;
28127: };
28128: 
28129: #define XML_SAX_PLUG_MAGIC 0xdc43ba21
28130: 
28131: struct _xmlSchemaSAXPlug {
28132:     unsigned int magic;
28133: 
28134:     /* the original callbacks informations */
28135:     xmlSAXHandlerPtr     *user_sax_ptr;
28136:     xmlSAXHandlerPtr      user_sax;
28137:     void                **user_data_ptr;
28138:     void                 *user_data;
28139: 
28140:     /* the block plugged back and validation informations */
28141:     xmlSAXHandler         schemas_sax;
28142:     xmlSchemaValidCtxtPtr ctxt;
28143: };
28144: 
28145: /* All those functions just bounces to the user provided SAX handlers */
28146: static void
28147: internalSubsetSplit(void *ctx, const xmlChar *name,
28148: 	       const xmlChar *ExternalID, const xmlChar *SystemID)
28149: {
28150:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28151:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28152:         (ctxt->user_sax->internalSubset != NULL))
28153: 	ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
28154: 	                               SystemID);
28155: }
28156: 
28157: static int
28158: isStandaloneSplit(void *ctx)
28159: {
28160:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28161:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28162:         (ctxt->user_sax->isStandalone != NULL))
28163: 	return(ctxt->user_sax->isStandalone(ctxt->user_data));
28164:     return(0);
28165: }
28166: 
28167: static int
28168: hasInternalSubsetSplit(void *ctx)
28169: {
28170:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28171:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28172:         (ctxt->user_sax->hasInternalSubset != NULL))
28173: 	return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
28174:     return(0);
28175: }
28176: 
28177: static int
28178: hasExternalSubsetSplit(void *ctx)
28179: {
28180:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28181:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28182:         (ctxt->user_sax->hasExternalSubset != NULL))
28183: 	return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
28184:     return(0);
28185: }
28186: 
28187: static void
28188: externalSubsetSplit(void *ctx, const xmlChar *name,
28189: 	       const xmlChar *ExternalID, const xmlChar *SystemID)
28190: {
28191:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28192:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28193:         (ctxt->user_sax->externalSubset != NULL))
28194: 	ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
28195: 	                               SystemID);
28196: }
28197: 
28198: static xmlParserInputPtr
28199: resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
28200: {
28201:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28202:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28203:         (ctxt->user_sax->resolveEntity != NULL))
28204: 	return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
28205: 	                                     systemId));
28206:     return(NULL);
28207: }
28208: 
28209: static xmlEntityPtr
28210: getEntitySplit(void *ctx, const xmlChar *name)
28211: {
28212:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28213:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28214:         (ctxt->user_sax->getEntity != NULL))
28215: 	return(ctxt->user_sax->getEntity(ctxt->user_data, name));
28216:     return(NULL);
28217: }
28218: 
28219: static xmlEntityPtr
28220: getParameterEntitySplit(void *ctx, const xmlChar *name)
28221: {
28222:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28223:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28224:         (ctxt->user_sax->getParameterEntity != NULL))
28225: 	return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
28226:     return(NULL);
28227: }
28228: 
28229: 
28230: static void
28231: entityDeclSplit(void *ctx, const xmlChar *name, int type,
28232:           const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
28233: {
28234:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28235:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28236:         (ctxt->user_sax->entityDecl != NULL))
28237: 	ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
28238: 	                           systemId, content);
28239: }
28240: 
28241: static void
28242: attributeDeclSplit(void *ctx, const xmlChar * elem,
28243:                    const xmlChar * name, int type, int def,
28244:                    const xmlChar * defaultValue, xmlEnumerationPtr tree)
28245: {
28246:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28247:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28248:         (ctxt->user_sax->attributeDecl != NULL)) {
28249: 	ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
28250: 	                              def, defaultValue, tree);
28251:     } else {
28252: 	xmlFreeEnumeration(tree);
28253:     }
28254: }
28255: 
28256: static void
28257: elementDeclSplit(void *ctx, const xmlChar *name, int type,
28258: 	    xmlElementContentPtr content)
28259: {
28260:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28261:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28262:         (ctxt->user_sax->elementDecl != NULL))
28263: 	ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
28264: }
28265: 
28266: static void
28267: notationDeclSplit(void *ctx, const xmlChar *name,
28268: 	     const xmlChar *publicId, const xmlChar *systemId)
28269: {
28270:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28271:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28272:         (ctxt->user_sax->notationDecl != NULL))
28273: 	ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
28274: 	                             systemId);
28275: }
28276: 
28277: static void
28278: unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
28279: 		   const xmlChar *publicId, const xmlChar *systemId,
28280: 		   const xmlChar *notationName)
28281: {
28282:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28283:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28284:         (ctxt->user_sax->unparsedEntityDecl != NULL))
28285: 	ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
28286: 	                                   systemId, notationName);
28287: }
28288: 
28289: static void
28290: setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
28291: {
28292:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28293:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28294:         (ctxt->user_sax->setDocumentLocator != NULL))
28295: 	ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
28296: }
28297: 
28298: static void
28299: startDocumentSplit(void *ctx)
28300: {
28301:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28302:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28303:         (ctxt->user_sax->startDocument != NULL))
28304: 	ctxt->user_sax->startDocument(ctxt->user_data);
28305: }
28306: 
28307: static void
28308: endDocumentSplit(void *ctx)
28309: {
28310:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28311:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28312:         (ctxt->user_sax->endDocument != NULL))
28313: 	ctxt->user_sax->endDocument(ctxt->user_data);
28314: }
28315: 
28316: static void
28317: processingInstructionSplit(void *ctx, const xmlChar *target,
28318:                       const xmlChar *data)
28319: {
28320:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28321:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28322:         (ctxt->user_sax->processingInstruction != NULL))
28323: 	ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
28324: }
28325: 
28326: static void
28327: commentSplit(void *ctx, const xmlChar *value)
28328: {
28329:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28330:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28331:         (ctxt->user_sax->comment != NULL))
28332: 	ctxt->user_sax->comment(ctxt->user_data, value);
28333: }
28334: 
28335: /*
28336:  * Varargs error callbacks to the user application, harder ...
28337:  */
28338: 
28339: static void XMLCDECL
28340: warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28341:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28342:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28343:         (ctxt->user_sax->warning != NULL)) {
28344: 	TODO
28345:     }
28346: }
28347: static void XMLCDECL
28348: errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28349:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28350:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28351:         (ctxt->user_sax->error != NULL)) {
28352: 	TODO
28353:     }
28354: }
28355: static void XMLCDECL
28356: fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
28357:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28358:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28359:         (ctxt->user_sax->fatalError != NULL)) {
28360: 	TODO
28361:     }
28362: }
28363: 
28364: /*
28365:  * Those are function where both the user handler and the schemas handler
28366:  * need to be called.
28367:  */
28368: static void
28369: charactersSplit(void *ctx, const xmlChar *ch, int len)
28370: {
28371:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28372:     if (ctxt == NULL)
28373:         return;
28374:     if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
28375: 	ctxt->user_sax->characters(ctxt->user_data, ch, len);
28376:     if (ctxt->ctxt != NULL)
28377: 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28378: }
28379: 
28380: static void
28381: ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
28382: {
28383:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28384:     if (ctxt == NULL)
28385:         return;
28386:     if ((ctxt->user_sax != NULL) &&
28387:         (ctxt->user_sax->ignorableWhitespace != NULL))
28388: 	ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
28389:     if (ctxt->ctxt != NULL)
28390: 	xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
28391: }
28392: 
28393: static void
28394: cdataBlockSplit(void *ctx, const xmlChar *value, int len)
28395: {
28396:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28397:     if (ctxt == NULL)
28398:         return;
28399:     if ((ctxt->user_sax != NULL) &&
28400:         (ctxt->user_sax->cdataBlock != NULL))
28401: 	ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
28402:     if (ctxt->ctxt != NULL)
28403: 	xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
28404: }
28405: 
28406: static void
28407: referenceSplit(void *ctx, const xmlChar *name)
28408: {
28409:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28410:     if (ctxt == NULL)
28411:         return;
28412:     if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
28413:         (ctxt->user_sax->reference != NULL))
28414: 	ctxt->user_sax->reference(ctxt->user_data, name);
28415:     if (ctxt->ctxt != NULL)
28416:         xmlSchemaSAXHandleReference(ctxt->user_data, name);
28417: }
28418: 
28419: static void
28420: startElementNsSplit(void *ctx, const xmlChar * localname,
28421: 		    const xmlChar * prefix, const xmlChar * URI,
28422: 		    int nb_namespaces, const xmlChar ** namespaces,
28423: 		    int nb_attributes, int nb_defaulted,
28424: 		    const xmlChar ** attributes) {
28425:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28426:     if (ctxt == NULL)
28427:         return;
28428:     if ((ctxt->user_sax != NULL) &&
28429:         (ctxt->user_sax->startElementNs != NULL))
28430: 	ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
28431: 	                               URI, nb_namespaces, namespaces,
28432: 				       nb_attributes, nb_defaulted,
28433: 				       attributes);
28434:     if (ctxt->ctxt != NULL)
28435: 	xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
28436: 	                                 URI, nb_namespaces, namespaces,
28437: 					 nb_attributes, nb_defaulted,
28438: 					 attributes);
28439: }
28440: 
28441: static void
28442: endElementNsSplit(void *ctx, const xmlChar * localname,
28443: 		    const xmlChar * prefix, const xmlChar * URI) {
28444:     xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
28445:     if (ctxt == NULL)
28446:         return;
28447:     if ((ctxt->user_sax != NULL) &&
28448:         (ctxt->user_sax->endElementNs != NULL))
28449: 	ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
28450:     if (ctxt->ctxt != NULL)
28451: 	xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
28452: }
28453: 
28454: /**
28455:  * xmlSchemaSAXPlug:
28456:  * @ctxt:  a schema validation context
28457:  * @sax:  a pointer to the original xmlSAXHandlerPtr
28458:  * @user_data:  a pointer to the original SAX user data pointer
28459:  *
28460:  * Plug a SAX based validation layer in a SAX parsing event flow.
28461:  * The original @saxptr and @dataptr data are replaced by new pointers
28462:  * but the calls to the original will be maintained.
28463:  *
28464:  * Returns a pointer to a data structure needed to unplug the validation layer
28465:  *         or NULL in case of errors.
28466:  */
28467: xmlSchemaSAXPlugPtr
28468: xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
28469: 		 xmlSAXHandlerPtr *sax, void **user_data)
28470: {
28471:     xmlSchemaSAXPlugPtr ret;
28472:     xmlSAXHandlerPtr old_sax;
28473: 
28474:     if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
28475:         return(NULL);
28476: 
28477:     /*
28478:      * We only allow to plug into SAX2 event streams
28479:      */
28480:     old_sax = *sax;
28481:     if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
28482:         return(NULL);
28483:     if ((old_sax != NULL) &&
28484:         (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
28485:         ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
28486:         return(NULL);
28487: 
28488:     /*
28489:      * everything seems right allocate the local data needed for that layer
28490:      */
28491:     ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
28492:     if (ret == NULL) {
28493:         return(NULL);
28494:     }
28495:     memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
28496:     ret->magic = XML_SAX_PLUG_MAGIC;
28497:     ret->schemas_sax.initialized = XML_SAX2_MAGIC;
28498:     ret->ctxt = ctxt;
28499:     ret->user_sax_ptr = sax;
28500:     ret->user_sax = old_sax;
28501:     if (old_sax == NULL) {
28502:         /*
28503: 	 * go direct, no need for the split block and functions.
28504: 	 */
28505: 	ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
28506: 	ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
28507: 	/*
28508: 	 * Note that we use the same text-function for both, to prevent
28509: 	 * the parser from testing for ignorable whitespace.
28510: 	 */
28511: 	ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
28512: 	ret->schemas_sax.characters = xmlSchemaSAXHandleText;
28513: 
28514: 	ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
28515: 	ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
28516: 
28517: 	ret->user_data = ctxt;
28518: 	*user_data = ctxt;
28519:     } else {
28520:        /*
28521:         * for each callback unused by Schemas initialize it to the Split
28522: 	* routine only if non NULL in the user block, this can speed up
28523: 	* things at the SAX level.
28524: 	*/
28525:         if (old_sax->internalSubset != NULL)
28526:             ret->schemas_sax.internalSubset = internalSubsetSplit;
28527:         if (old_sax->isStandalone != NULL)
28528:             ret->schemas_sax.isStandalone = isStandaloneSplit;
28529:         if (old_sax->hasInternalSubset != NULL)
28530:             ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
28531:         if (old_sax->hasExternalSubset != NULL)
28532:             ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
28533:         if (old_sax->resolveEntity != NULL)
28534:             ret->schemas_sax.resolveEntity = resolveEntitySplit;
28535:         if (old_sax->getEntity != NULL)
28536:             ret->schemas_sax.getEntity = getEntitySplit;
28537:         if (old_sax->entityDecl != NULL)
28538:             ret->schemas_sax.entityDecl = entityDeclSplit;
28539:         if (old_sax->notationDecl != NULL)
28540:             ret->schemas_sax.notationDecl = notationDeclSplit;
28541:         if (old_sax->attributeDecl != NULL)
28542:             ret->schemas_sax.attributeDecl = attributeDeclSplit;
28543:         if (old_sax->elementDecl != NULL)
28544:             ret->schemas_sax.elementDecl = elementDeclSplit;
28545:         if (old_sax->unparsedEntityDecl != NULL)
28546:             ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
28547:         if (old_sax->setDocumentLocator != NULL)
28548:             ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
28549:         if (old_sax->startDocument != NULL)
28550:             ret->schemas_sax.startDocument = startDocumentSplit;
28551:         if (old_sax->endDocument != NULL)
28552:             ret->schemas_sax.endDocument = endDocumentSplit;
28553:         if (old_sax->processingInstruction != NULL)
28554:             ret->schemas_sax.processingInstruction = processingInstructionSplit;
28555:         if (old_sax->comment != NULL)
28556:             ret->schemas_sax.comment = commentSplit;
28557:         if (old_sax->warning != NULL)
28558:             ret->schemas_sax.warning = warningSplit;
28559:         if (old_sax->error != NULL)
28560:             ret->schemas_sax.error = errorSplit;
28561:         if (old_sax->fatalError != NULL)
28562:             ret->schemas_sax.fatalError = fatalErrorSplit;
28563:         if (old_sax->getParameterEntity != NULL)
28564:             ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
28565:         if (old_sax->externalSubset != NULL)
28566:             ret->schemas_sax.externalSubset = externalSubsetSplit;
28567: 
28568: 	/*
28569: 	 * the 6 schemas callback have to go to the splitter functions
28570: 	 * Note that we use the same text-function for ignorableWhitespace
28571: 	 * if possible, to prevent the parser from testing for ignorable
28572: 	 * whitespace.
28573: 	 */
28574:         ret->schemas_sax.characters = charactersSplit;
28575: 	if ((old_sax->ignorableWhitespace != NULL) &&
28576: 	    (old_sax->ignorableWhitespace != old_sax->characters))
28577: 	    ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
28578: 	else
28579: 	    ret->schemas_sax.ignorableWhitespace = charactersSplit;
28580:         ret->schemas_sax.cdataBlock = cdataBlockSplit;
28581:         ret->schemas_sax.reference = referenceSplit;
28582:         ret->schemas_sax.startElementNs = startElementNsSplit;
28583:         ret->schemas_sax.endElementNs = endElementNsSplit;
28584: 
28585: 	ret->user_data_ptr = user_data;
28586: 	ret->user_data = *user_data;
28587: 	*user_data = ret;
28588:     }
28589: 
28590:     /*
28591:      * plug the pointers back.
28592:      */
28593:     *sax = &(ret->schemas_sax);
28594:     ctxt->sax = *sax;
28595:     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28596:     xmlSchemaPreRun(ctxt);
28597:     return(ret);
28598: }
28599: 
28600: /**
28601:  * xmlSchemaSAXUnplug:
28602:  * @plug:  a data structure returned by xmlSchemaSAXPlug
28603:  *
28604:  * Unplug a SAX based validation layer in a SAX parsing event flow.
28605:  * The original pointers used in the call are restored.
28606:  *
28607:  * Returns 0 in case of success and -1 in case of failure.
28608:  */
28609: int
28610: xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
28611: {
28612:     xmlSAXHandlerPtr *sax;
28613:     void **user_data;
28614: 
28615:     if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
28616:         return(-1);
28617:     plug->magic = 0;
28618: 
28619:     xmlSchemaPostRun(plug->ctxt);
28620:     /* restore the data */
28621:     sax = plug->user_sax_ptr;
28622:     *sax = plug->user_sax;
28623:     if (plug->user_sax != NULL) {
28624: 	user_data = plug->user_data_ptr;
28625: 	*user_data = plug->user_data;
28626:     }
28627: 
28628:     /* free and return */
28629:     xmlFree(plug);
28630:     return(0);
28631: }
28632: 
28633: /**
28634:  * xmlSchemaValidateStream:
28635:  * @ctxt:  a schema validation context
28636:  * @input:  the input to use for reading the data
28637:  * @enc:  an optional encoding information
28638:  * @sax:  a SAX handler for the resulting events
28639:  * @user_data:  the context to provide to the SAX handler.
28640:  *
28641:  * Validate an input based on a flow of SAX event from the parser
28642:  * and forward the events to the @sax handler with the provided @user_data
28643:  * the user provided @sax handler must be a SAX2 one.
28644:  *
28645:  * Returns 0 if the document is schemas valid, a positive error code
28646:  *     number otherwise and -1 in case of internal or API error.
28647:  */
28648: int
28649: xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
28650:                         xmlParserInputBufferPtr input, xmlCharEncoding enc,
28651:                         xmlSAXHandlerPtr sax, void *user_data)
28652: {
28653:     xmlSchemaSAXPlugPtr plug = NULL;
28654:     xmlSAXHandlerPtr old_sax = NULL;
28655:     xmlParserCtxtPtr pctxt = NULL;
28656:     xmlParserInputPtr inputStream = NULL;
28657:     int ret;
28658: 
28659:     if ((ctxt == NULL) || (input == NULL))
28660:         return (-1);
28661: 
28662:     /*
28663:      * prepare the parser
28664:      */
28665:     pctxt = xmlNewParserCtxt();
28666:     if (pctxt == NULL)
28667:         return (-1);
28668:     old_sax = pctxt->sax;
28669:     pctxt->sax = sax;
28670:     pctxt->userData = user_data;
28671: #if 0
28672:     if (options)
28673:         xmlCtxtUseOptions(pctxt, options);
28674: #endif
28675:     pctxt->linenumbers = 1;
28676: 
28677:     inputStream = xmlNewIOInputStream(pctxt, input, enc);;
28678:     if (inputStream == NULL) {
28679:         ret = -1;
28680: 	goto done;
28681:     }
28682:     inputPush(pctxt, inputStream);
28683:     ctxt->parserCtxt = pctxt;
28684:     ctxt->input = input;
28685: 
28686:     /*
28687:      * Plug the validation and launch the parsing
28688:      */
28689:     plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
28690:     if (plug == NULL) {
28691:         ret = -1;
28692: 	goto done;
28693:     }
28694:     ctxt->input = input;
28695:     ctxt->enc = enc;
28696:     ctxt->sax = pctxt->sax;
28697:     ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
28698:     ret = xmlSchemaVStart(ctxt);
28699: 
28700:     if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
28701: 	ret = ctxt->parserCtxt->errNo;
28702: 	if (ret == 0)
28703: 	    ret = 1;
28704:     }
28705: 
28706: done:
28707:     ctxt->parserCtxt = NULL;
28708:     ctxt->sax = NULL;
28709:     ctxt->input = NULL;
28710:     if (plug != NULL) {
28711:         xmlSchemaSAXUnplug(plug);
28712:     }
28713:     /* cleanup */
28714:     if (pctxt != NULL) {
28715: 	pctxt->sax = old_sax;
28716: 	xmlFreeParserCtxt(pctxt);
28717:     }
28718:     return (ret);
28719: }
28720: 
28721: /**
28722:  * xmlSchemaValidateFile:
28723:  * @ctxt: a schema validation context
28724:  * @filename: the URI of the instance
28725:  * @options: a future set of options, currently unused
28726:  *
28727:  * Do a schemas validation of the given resource, it will use the
28728:  * SAX streamable validation internally.
28729:  *
28730:  * Returns 0 if the document is valid, a positive error code
28731:  *     number otherwise and -1 in case of an internal or API error.
28732:  */
28733: int
28734: xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
28735:                       const char * filename,
28736: 		      int options ATTRIBUTE_UNUSED)
28737: {
28738:     int ret;
28739:     xmlParserInputBufferPtr input;
28740: 
28741:     if ((ctxt == NULL) || (filename == NULL))
28742:         return (-1);
28743: 
28744:     input = xmlParserInputBufferCreateFilename(filename,
28745: 	XML_CHAR_ENCODING_NONE);
28746:     if (input == NULL)
28747: 	return (-1);
28748:     ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
28749: 	NULL, NULL);
28750:     return (ret);
28751: }
28752: 
28753: /**
28754:  * xmlSchemaValidCtxtGetParserCtxt:
28755:  * @ctxt: a schema validation context
28756:  *
28757:  * allow access to the parser context of the schema validation context
28758:  *
28759:  * Returns the parser context of the schema validation context or NULL
28760:  *         in case of error.
28761:  */
28762: xmlParserCtxtPtr
28763: xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
28764: {
28765:     if (ctxt == NULL)
28766:         return(NULL);
28767:     return (ctxt->parserCtxt);
28768: }
28769: 
28770: #define bottom_xmlschemas
28771: #include "elfgcchack.h"
28772: #endif /* LIBXML_SCHEMAS_ENABLED */

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