Index: xmlschemas.c =================================================================== RCS file: /cvs/gnome/libxml2/xmlschemas.c,v retrieving revision 1.67 diff -c -r1.67 xmlschemas.c *** xmlschemas.c 3 Jun 2004 16:00:59 -0000 1.67 --- xmlschemas.c 8 Jun 2004 14:42:46 -0000 *************** *** 5360,5365 **** --- 5360,5375 ---- return (0); } + /** + * xmlSchemaCloneWildcardNsConstraints: + * @ctxt: the schema parser context + * @dest: the destination wildcard + * @source: the source wildcard + * + * Clones the namespace constraints of source + * and assignes them to dest. + * Returns -1 on internal error, 0 otherwise. + */ static int xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt, xmlSchemaWildcardPtr *dest, *************** *** 5396,5401 **** --- 5406,5422 ---- return(0); } + /** + * xmlSchemaUnionWildcards: + * @ctxt: the schema parser context + * @completeWild: the first wildcard + * @curWild: the second wildcard + * + * Unions the namespace constraints of the given wildcards. + * @completeWild will hold the resulting union. + * Returns a positive error code on failure, -1 in case of an + * internal error, 0 otherwise. + */ static int xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt, xmlSchemaWildcardPtr completeWild, *************** *** 5444,5450 **** /* * 2 If either O1 or O2 is any, then any must be the value */ ! if ((completeWild->any != curWild->any) && (completeWild->any)) { if (completeWild->any == 0) { completeWild->any = 1; if (completeWild->nsSet != NULL) { --- 5465,5471 ---- /* * 2 If either O1 or O2 is any, then any must be the value */ ! if (completeWild->any != curWild->any) { if (completeWild->any == 0) { completeWild->any = 1; if (completeWild->nsSet != NULL) { *************** *** 5456,5461 **** --- 5477,5483 ---- completeWild->negNsSet = NULL; } } + return (0); } /* * 3 If both O1 and O2 are sets of (namespace names or ·absent·), *************** *** 5498,5503 **** --- 5520,5527 ---- (curWild->negNsSet != NULL) && (completeWild->negNsSet->value != curWild->negNsSet->value)) { completeWild->negNsSet->value = NULL; + + return(0); } /* * 5. *************** *** 5568,5574 **** XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, "The union of the wilcard is not expressible\n", NULL, NULL); ! return(0); } else if ((!nsFound) && (!absentFound)) { /* * 5.4 If the set S does not include either the negated namespace --- 5592,5598 ---- XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, "The union of the wilcard is not expressible\n", NULL, NULL); ! return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE); } else if ((!nsFound) && (!absentFound)) { /* * 5.4 If the set S does not include either the negated namespace *************** *** 5642,5647 **** --- 5666,5682 ---- } + /** + * xmlSchemaIntersectWildcards: + * @ctxt: the schema parser context + * @completeWild: the first wildcard + * @curWild: the second wildcard + * + * Intersects the namespace constraints of the given wildcards. + * @completeWild will hold the resulting intersection. + * Returns a positive error code on failure, -1 in case of an + * internal error, 0 otherwise. + */ static int xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt, xmlSchemaWildcardPtr completeWild, *************** *** 5794,5800 **** xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, "The intersection of the wilcard is not expressible\n", NULL, NULL); ! return(0); } /* * 6 If the one is a negation of a namespace name and the other --- 5829,5835 ---- xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, "The intersection of the wilcard is not expressible\n", NULL, NULL); ! return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE); } /* * 6 If the one is a negation of a namespace name and the other *************** *** 5809,5819 **** return(0); } ! static xmlSchemaWildcardPtr ! xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt, ! xmlSchemaAttributePtr attrs, ! xmlSchemaWildcardPtr completeWild) { while (attrs != NULL) { if (attrs->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { --- 5844,5938 ---- return(0); } + /** + * xmlSchemaIsWildcardNsConstraintSubset: + * @ctxt: the schema parser context + * @wildA: the first wildcard + * @wildB: the second wildcard + * + * Returns 1 if the namespace constraint of @wildA is an intensional + * subset of @wildB, 0 otherwise. + */ + static int + xmlSchemaIsWildcardNsConstraintSubset(xmlSchemaParserCtxtPtr ctxt, + xmlSchemaWildcardPtr wildA, + xmlSchemaWildcardPtr wildB) + { ! /* ! * Schema Component Constraint: Wildcard Subset ! */ ! /* ! * 1 super must be any. ! */ ! if (wildB->any) ! return (1); ! /* ! * 2.1 sub must be a pair of not and a namespace name or ·absent·. ! * 2.2 super must be a pair of not and the same value. ! */ ! if ((wildA->negNsSet != NULL) && ! (wildB->negNsSet != NULL) && ! (wildA->negNsSet->value == wildA->negNsSet->value)) ! return (1); ! /* ! * 3.1 sub must be a set whose members are either namespace names or ·absent·. ! */ ! if (wildA->nsSet != NULL) { ! /* ! * 3.2.1 super must be the same set or a superset thereof. ! */ ! if (wildB->nsSet != NULL) { ! xmlSchemaWildcardNsPtr cur, curB; ! int found = 0; ! ! cur = wildA->nsSet; ! while (cur != NULL) { ! found = 0; ! curB = wildB->nsSet; ! while (curB != NULL) { ! if (cur->value == curB->value) { ! found = 1; ! break; ! } ! curB = curB->next; ! } ! if (!found) ! return (0); ! cur = cur->next; ! } ! if (found) ! return (1); ! } else if (wildB->negNsSet != NULL) { ! xmlSchemaWildcardNsPtr cur; ! /* ! * 3.2.2 super must be a pair of not and a namespace name or ! * ·absent· and that value must not be in sub's set. ! */ ! cur = wildA->nsSet; ! while (cur != NULL) { ! if (cur->value == wildB->negNsSet->value) ! return (0); ! cur = cur->next; ! } ! return (1); ! } ! } ! return (0); ! } ! ! /** ! * xmlSchemaBuildCompleteAttributeWildcard: ! * @ctxt: the schema parser context ! * @attrs: the attribute list ! * @completeWild: the resulting complete wildcard ! * ! * Returns -1 in case of an internal error, 0 otherwise. ! */ ! static int ! xmlSchemaBuildCompleteAttributeWildcard(xmlSchemaParserCtxtPtr ctxt, ! xmlSchemaAttributePtr attrs, ! xmlSchemaWildcardPtr *completeWild) { while (attrs != NULL) { if (attrs->type == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) { *************** *** 5822,5865 **** group = (xmlSchemaAttributeGroupPtr) attrs; if ((group->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { if (group->attributes != NULL) { ! if (group->attributeWildcard != NULL) ! xmlSchemaBuildCompleteAttributeWildcard(ctxt, ! group->attributes, group->attributeWildcard); ! else ! group->attributeWildcard = ! xmlSchemaBuildCompleteAttributeWildcard(ctxt, ! group->attributes, group->attributeWildcard); } group->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; } if (group->attributeWildcard != NULL) { ! if (completeWild == NULL) { /* * Copy the first encountered wildcard as context, except for the annotation. */ ! completeWild = xmlSchemaAddWildcard(ctxt); ! completeWild->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE; ! if (!xmlSchemaCloneWildcardNsConstraints(ctxt, ! &completeWild, group->attributeWildcard)) ! return(NULL); ! completeWild->processContents = group->attributeWildcard->processContents; /* * Although the complete wildcard might not correspond to any * node in the schema, we will save this context node. */ ! completeWild->node = group->attributeWildcard->node; ! return(completeWild); ! } ! if (xmlSchemaIntersectWildcards(ctxt, completeWild, group->attributeWildcard) == -1) { ! xmlSchemaFreeWildcard(completeWild); ! return(NULL); } } } attrs = attrs->next; } ! return (completeWild); } /** --- 5941,5979 ---- group = (xmlSchemaAttributeGroupPtr) attrs; if ((group->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) { if (group->attributes != NULL) { ! if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, ! group->attributes, &group->attributeWildcard) == -1) ! return (-1); } group->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED; } if (group->attributeWildcard != NULL) { ! if (*completeWild == NULL) { /* * Copy the first encountered wildcard as context, except for the annotation. */ ! *completeWild = xmlSchemaAddWildcard(ctxt); ! (*completeWild)->type = XML_SCHEMA_TYPE_ANY_ATTRIBUTE; ! if (xmlSchemaCloneWildcardNsConstraints(ctxt, ! completeWild, group->attributeWildcard) == -1) ! return (-1); ! (*completeWild)->processContents = group->attributeWildcard->processContents; /* * Although the complete wildcard might not correspond to any * node in the schema, we will save this context node. */ ! (*completeWild)->node = group->attributeWildcard->node; ! ! } else if (xmlSchemaIntersectWildcards(ctxt, *completeWild, group->attributeWildcard) == -1) { ! xmlSchemaFreeWildcard(*completeWild); ! return (-1); } } } attrs = attrs->next; } ! return (0); } /** *************** *** 5911,5917 **** xmlSchemaAttributeLinkPtr cur, base, tmp, id = NULL, prev = NULL, uses = NULL, lastUse = NULL, lastBaseUse = NULL; xmlSchemaAttributePtr attrs; ! int baseIsAnyType = 0; /* * Complex Type Definition with complex content Schema Component. --- 6025,6031 ---- xmlSchemaAttributeLinkPtr cur, base, tmp, id = NULL, prev = NULL, uses = NULL, lastUse = NULL, lastBaseUse = NULL; xmlSchemaAttributePtr attrs; ! int baseIsAnyType = 0; /* * Complex Type Definition with complex content Schema Component. *************** *** 5927,5932 **** --- 6041,6047 ---- } if ((type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) || (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)) { + /* * Inherit the attribute uses of the base type. */ *************** *** 5966,5976 **** attrs = type->subtypes->subtypes->attributes; /* * Handle attribute wildcards. ! */ ! type->attributeWildcard = ! xmlSchemaBuildCompleteAttributeWildcard(ctxt, ! attrs, ! type->subtypes->subtypes->attributeWildcard); if ((type->attributeWildcard != NULL) && (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; --- 6081,6096 ---- attrs = type->subtypes->subtypes->attributes; /* * Handle attribute wildcards. ! */ ! type->attributeWildcard = type->subtypes->subtypes->attributeWildcard; ! ! if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, ! attrs, &type->attributeWildcard) == -1) { ! if ((type->attributeWildcard != NULL) && ! (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) ! type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; ! return (-1); ! } if ((type->attributeWildcard != NULL) && (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; *************** *** 5992,5997 **** --- 6112,6176 ---- type->attributeWildcard = baseType->attributeWildcard; } } + if (!baseIsAnyType) { + if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION) { + if (type->attributeWildcard != NULL) { + /* + * Derivation Valid (Restriction, Complex) + * 4.1 The {base type definition} must also have one. + */ + if (baseType->attributeWildcard == NULL) { + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, + "The derived type \"%s\" has an attribute wildcard, " + "but the base type \"%s\" does not have one.\n", + type->name, baseType->name); + return (1); + } else if (xmlSchemaIsWildcardNsConstraintSubset(ctxt, + type->attributeWildcard, baseType->attributeWildcard) == 0) { + /* 4.2 */ + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, + "The wildcard in the derived type \"%s\" is not a valid " + "subset of the one in the base type \"%s\".\n", + type->name, baseType->name); + return (1); + } + /* 4.3 Unless the {base type definition} is the ·ur-type + * definition·, the complex type definition's {attribute + * wildcard}'s {process contents} must be identical to or + * stronger than the {base type definition}'s {attribute + * wildcard}'s {process contents}, where strict is stronger + * than lax is stronger than skip. + */ + if (type->attributeWildcard->processContents < + baseType->attributeWildcard->processContents) { + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, + "The process contents of the wildcard in the " + "derived type \"%s\" is weaker than " + "that in the base type \"%s\".\n", + type->name, baseType->name); + return (1); + } + } + } else if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { + /* + * Derivation Valid (Extension) + * At this point the type and the base have both, either + * no wildcard or a wildcard. + */ + if ((baseType->attributeWildcard != NULL) && + (baseType->attributeWildcard != type->attributeWildcard)) { + /* 1.3 */ + if (xmlSchemaIsWildcardNsConstraintSubset(ctxt, + baseType->attributeWildcard, type->attributeWildcard) == 0) { + xmlSchemaPErr(ctxt, type->node, XML_SCHEMAP_COS_CT_EXTENDS_1_3, + "The wildcard in the derived type \"%s\" is not a valid " + "superset of the one in the base type \"%s\".\n", + type->name, baseType->name); + return (1); + } + } + } + } } else { /* * Although the complexType is implicitely derived by "restriction" *************** *** 5999,6007 **** */ baseType = NULL; attrs = type->attributes; ! if (attrs != NULL) ! type->attributeWildcard = ! xmlSchemaBuildCompleteAttributeWildcard(ctxt, attrs, type->attributeWildcard); } /* * Gather attribute uses defined by this type. --- 6178,6195 ---- */ baseType = NULL; attrs = type->attributes; ! if (attrs != NULL) { ! if (xmlSchemaBuildCompleteAttributeWildcard(ctxt, ! attrs, &type->attributeWildcard) == -1) { ! if ((type->attributeWildcard != NULL) && ! (type->attributeWildcard != type->subtypes->subtypes->attributeWildcard)) ! type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; ! return (-1); ! } ! if ((type->attributeWildcard != NULL) && ! ((type->flags & XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD) == 0)) ! type->flags |= XML_SCHEMAS_TYPE_OWNED_ATTR_WILDCARD; ! } } /* * Gather attribute uses defined by this type. *************** *** 6089,6094 **** --- 6277,6283 ---- } /* * TODO: derivation-ok-restriction 2.1.2 ({type definition} must be validly derived) + * TODO: derivation-ok-restriction 2.1.3 */ break; } *************** *** 6152,6164 **** type->attributeUses = uses; } else lastBaseUse->next = uses; ! } } else { /* ! * Derive implicitely from the ur-type. ! */ type->attributeUses = uses; ! } /* * 3.4.6 -> Complex Type Definition Properties Correct */ --- 6341,6353 ---- type->attributeUses = uses; } else lastBaseUse->next = uses; ! } } else { /* ! * Derive implicitely from the ur-type. ! */ type->attributeUses = uses; ! } /* * 3.4.6 -> Complex Type Definition Properties Correct */ *************** *** 6169,6178 **** /* * 4. Two distinct attribute declarations in the {attribute uses} must * not have identical {name}s and {target namespace}s. ! * * Note that this was already done for "restriction" and types derived from * the ur-type. ! */ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { tmp = cur->next; while (tmp != NULL) { --- 6358,6367 ---- /* * 4. Two distinct attribute declarations in the {attribute uses} must * not have identical {name}s and {target namespace}s. ! * * Note that this was already done for "restriction" and types derived from * the ur-type. ! */ if (type->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION) { tmp = cur->next; while (tmp != NULL) { *************** *** 6184,6194 **** xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_CT_PROPS_CORRECT_4, "ct-props-correct.4: Duplicate attribute use with the name \"%s\" specified\n", xmlSchemaGetOnymousAttrName(cur->attr), NULL); ! break; ! } tmp = tmp->next; ! } ! } /* * 5. Two distinct attribute declarations in the {attribute uses} must * not have {type definition}s which are or are derived from ID. --- 6373,6383 ---- xmlSchemaPErr(ctxt, cur->attr->node, XML_SCHEMAP_CT_PROPS_CORRECT_4, "ct-props-correct.4: Duplicate attribute use with the name \"%s\" specified\n", xmlSchemaGetOnymousAttrName(cur->attr), NULL); ! break; ! } tmp = tmp->next; ! } ! } /* * 5. Two distinct attribute declarations in the {attribute uses} must * not have {type definition}s which are or are derived from ID. *************** *** 6205,6211 **** "\"%s\" and \"%s\" have types which derived from ID\n", xmlSchemaGetOnymousAttrName(id->attr), xmlSchemaGetOnymousAttrName(cur->attr)); ! } id = cur; } /* --- 6394,6400 ---- "\"%s\" and \"%s\" have types which derived from ID\n", xmlSchemaGetOnymousAttrName(id->attr), xmlSchemaGetOnymousAttrName(cur->attr)); ! } id = cur; } /* *************** *** 6220,6226 **** else prev->next = cur->next; cur = cur->next; ! xmlFree(tmp); } else { prev = cur; cur = cur->next; --- 6409,6415 ---- else prev->next = cur->next; cur = cur->next; ! xmlFree(tmp); } else { prev = cur; cur = cur->next; *************** *** 8431,8437 **** printf("found\n"); #endif found = 1; ! ctxt->cur = (xmlNodePtr) attr; if (attrDecl->subtypes == NULL) { curState->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED; --- 8620,8626 ---- printf("found\n"); #endif found = 1; ! ctxt->cur = (xmlNodePtr) attr; if (attrDecl->subtypes == NULL) { curState->state = XML_SCHEMAS_ATTR_TYPE_NOT_RESOLVED;