1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-03-10 08:58:16 +03:00

Fixed comparison for default/fixed attribute values, if the type was

* xmlschemas.c: Fixed comparison for default/fixed attribute
  values, if the type was 'xsd:string'. Changed the comparison
  for IDCs to use the whitespace aware comparison function.
* xmlschemastypes.c include/libxml/xmlschemastypes.h:
  Added xmlSchemaGetCanonValue, xmlSchemaNewStringValue and
  xmlSchemaCompareValuesWhtsp to the API. Added functions
  to compare strings with whitespace combinations of "preserve",
  "replace" and "collapse".
This commit is contained in:
Kasimier T. Buchcik 2005-02-17 11:10:44 +00:00
parent bd2a7d169b
commit 6e224f1272
4 changed files with 641 additions and 44 deletions

View File

@ -1,3 +1,14 @@
Thu Feb 17 12:03:46 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
* xmlschemas.c: Fixed comparison for default/fixed attribute
values, if the type was 'xsd:string'. Changed the comparison
for IDCs to use the whitespace aware comparison function.
* xmlschemastypes.c include/libxml/xmlschemastypes.h:
Added xmlSchemaGetCanonValue, xmlSchemaNewStringValue and
xmlSchemaCompareValuesWhtsp to the API. Added functions
to compare strings with whitespace combinations of "preserve",
"replace" and "collapse".
Wed Feb 16 13:24:35 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net> Wed Feb 16 13:24:35 CET 2005 Kasimier Buchcik <libxml2-cvs@cazic.net>
* xmlschemas.c: Further work on IDCs, especially evaluation for * xmlschemas.c: Further work on IDCs, especially evaluation for

View File

@ -23,6 +23,13 @@
extern "C" { extern "C" {
#endif #endif
typedef enum {
XML_SCHEMA_WHITESPACE_UNKNOWN = 0,
XML_SCHEMA_WHITESPACE_PRESERVE = 1,
XML_SCHEMA_WHITESPACE_REPLACE = 2,
XML_SCHEMA_WHITESPACE_COLLAPSE = 3
} xmlSchemaWhitespaceValueType;
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
xmlSchemaInitTypes (void); xmlSchemaInitTypes (void);
XMLPUBFUN void XMLCALL XMLPUBFUN void XMLCALL
@ -87,6 +94,17 @@ XMLPUBFUN int XMLCALL
const xmlChar *value, const xmlChar *value,
xmlSchemaValPtr *val, xmlSchemaValPtr *val,
xmlNodePtr node); xmlNodePtr node);
XMLPUBFUN int XMLCALL
xmlSchemaGetCanonValue (xmlSchemaValPtr val,
const xmlChar **retValue);
XMLPUBFUN xmlSchemaValPtr XMLCALL
xmlSchemaNewStringValue (xmlSchemaValType type,
const xmlChar *value);
XMLPUBFUN int XMLCALL
xmlSchemaCompareValuesWhtsp (xmlSchemaValPtr x,
xmlSchemaWhitespaceValueType xws,
xmlSchemaValPtr y,
xmlSchemaWhitespaceValueType yws);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -7,7 +7,7 @@
* Daniel Veillard <veillard@redhat.com> * Daniel Veillard <veillard@redhat.com>
*/ */
/* /*
* TODO: * TODO:
* - when types are redefined in includes, check that all * - when types are redefined in includes, check that all
* types in the redef list are equal * types in the redef list are equal
@ -54,7 +54,7 @@
#define ELEM_INFO_ENABLED 1 #define ELEM_INFO_ENABLED 1
/* #define IDC_ENABLED 1 */ /* #define IDC_ENABLED 1 */
/* #define IDC_VALUE_SUPPORT 1 */ /* #define IDC_VALUE_SUPPORT 1 */
@ -117,9 +117,11 @@ static const xmlChar *xmlSchemaElemDesCT = (const xmlChar *)
((item->type == XML_SCHEMA_TYPE_BASIC) && \ ((item->type == XML_SCHEMA_TYPE_BASIC) && \
(item->builtInType != XML_SCHEMAS_ANYTYPE))) (item->builtInType != XML_SCHEMAS_ANYTYPE)))
/*
#define XML_SCHEMAS_VAL_WTSP_PRESERVE 0 #define XML_SCHEMAS_VAL_WTSP_PRESERVE 0
#define XML_SCHEMAS_VAL_WTSP_REPLACE 1 #define XML_SCHEMAS_VAL_WTSP_REPLACE 1
#define XML_SCHEMAS_VAL_WTSP_COLLAPSE 2 #define XML_SCHEMAS_VAL_WTSP_COLLAPSE 2
*/
#define XML_SCHEMAS_PARSE_ERROR 1 #define XML_SCHEMAS_PARSE_ERROR 1
@ -384,9 +386,6 @@ struct _xmlSchemaIDCMatcher {
xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
elements */ elements */
int sizeKeySeqs; int sizeKeySeqs;
xmlSchemaPSVIIDCKeyPtr **refKeySeqs;
int nbRefKeySeqs;
int sizeRefKeySeqs;
int targetDepth; int targetDepth;
}; };
@ -10268,7 +10267,7 @@ xmlSchemaIsDerivedFromBuiltInType(xmlSchemaParserCtxtPtr ctxt,
} }
/** /**
* xmlSchemaIsDerivedFromBuiltInType: * xmlSchemaGetPrimitiveType:
* @type: the simpleType definition * @type: the simpleType definition
* *
* Returns the primitive type of the given type or * Returns the primitive type of the given type or
@ -10286,6 +10285,25 @@ xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
return (NULL); return (NULL);
} }
/**
* xmlSchemaGetBuiltInTypeAncestor:
* @type: the simpleType definition
*
* Returns the primitive type of the given type or
* NULL in case of error.
*/
static xmlSchemaTypePtr
xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
{
while (type != NULL) {
if (type->type == XML_SCHEMA_TYPE_BASIC)
return (type);
type = type->baseType;
}
return (NULL);
}
/** /**
* xmlSchemaBuildAttributeUsesOwned: * xmlSchemaBuildAttributeUsesOwned:
@ -14763,8 +14781,6 @@ xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
return ("Internal Error"); return ("Internal Error");
} }
static int static int
xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type) xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
{ {
@ -14776,24 +14792,24 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
*/ */
if (type->type == XML_SCHEMA_TYPE_BASIC) { if (type->type == XML_SCHEMA_TYPE_BASIC) {
if (type->builtInType == XML_SCHEMAS_STRING) if (type->builtInType == XML_SCHEMAS_STRING)
return(XML_SCHEMAS_VAL_WTSP_PRESERVE); return(XML_SCHEMAS_FACET_PRESERVE);
else if (type->builtInType == XML_SCHEMAS_NORMSTRING) else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
return(XML_SCHEMAS_VAL_WTSP_REPLACE); return(XML_SCHEMAS_FACET_REPLACE);
else { else {
/* /*
* For all ·atomic· datatypes other than string (and types ·derived· * For all ·atomic· datatypes other than string (and types ·derived·
* by ·restriction· from it) the value of whiteSpace is fixed to * by ·restriction· from it) the value of whiteSpace is fixed to
* collapse * collapse
*/ */
return(XML_SCHEMAS_VAL_WTSP_COLLAPSE); return(XML_SCHEMAS_FACET_COLLAPSE);
} }
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) { } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_LIST) {
/* /*
* For list types the facet "whiteSpace" is fixed to "collapse". * For list types the facet "whiteSpace" is fixed to "collapse".
*/ */
return (XML_SCHEMAS_VAL_WTSP_COLLAPSE); return (XML_SCHEMAS_FACET_COLLAPSE);
} else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) { } else if (type->flags & XML_SCHEMAS_TYPE_VARIETY_UNION) {
return (-1); return (XML_SCHEMAS_FACET_UNKNOWN);
} else if (type->facetSet != NULL) { } else if (type->facetSet != NULL) {
xmlSchemaTypePtr anyST; xmlSchemaTypePtr anyST;
xmlSchemaFacetLinkPtr lin; xmlSchemaFacetLinkPtr lin;
@ -14815,14 +14831,7 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
lin = type->facetSet; lin = type->facetSet;
do { do {
if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) { if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
if (lin->facet->whitespace == return(lin->facet->whitespace);
XML_SCHEMAS_FACET_COLLAPSE) {
return(XML_SCHEMAS_VAL_WTSP_COLLAPSE);
} else if (lin->facet->whitespace ==
XML_SCHEMAS_FACET_REPLACE) {
return(XML_SCHEMAS_VAL_WTSP_REPLACE);
} else
return(XML_SCHEMAS_VAL_WTSP_PRESERVE);
break; break;
} }
lin = lin->next; lin = lin->next;
@ -14831,7 +14840,7 @@ xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
} }
anc = anc->baseType; anc = anc->baseType;
} while (anc != anyST); } while (anc != anyST);
return (XML_SCHEMAS_VAL_WTSP_COLLAPSE); return (XML_SCHEMAS_FACET_COLLAPSE);
} }
return (-1); return (-1);
} }
@ -15667,11 +15676,11 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
* Normalize the value. * Normalize the value.
*/ */
if (normalize && if (normalize &&
(ctxt->valueWS != XML_SCHEMAS_VAL_WTSP_COLLAPSE)) { (ctxt->valueWS != XML_SCHEMAS_FACET_COLLAPSE)) {
int norm = xmlSchemaGetWhiteSpaceFacetValue(type); int norm = xmlSchemaGetWhiteSpaceFacetValue(type);
if ((norm != -1) && (norm > ctxt->valueWS)) { if ((norm != -1) && (norm > ctxt->valueWS)) {
if (norm == XML_SCHEMAS_VAL_WTSP_COLLAPSE) if (norm == XML_SCHEMAS_FACET_COLLAPSE)
normValue = xmlSchemaCollapseString(value); normValue = xmlSchemaCollapseString(value);
else else
normValue = xmlSchemaWhiteSpaceReplace(value); normValue = xmlSchemaWhiteSpaceReplace(value);
@ -15992,7 +16001,7 @@ xmlSchemaValidateSimpleTypeValue(xmlSchemaValidCtxtPtr ctxt,
} }
mws = xmlSchemaGetWhiteSpaceFacetValue(memberLink->type); mws = xmlSchemaGetWhiteSpaceFacetValue(memberLink->type);
if (mws > ctxt->valueWS) { if (mws > ctxt->valueWS) {
if (mws == XML_SCHEMAS_VAL_WTSP_COLLAPSE) if (mws == XML_SCHEMAS_FACET_COLLAPSE)
normValue = xmlSchemaCollapseString(value); normValue = xmlSchemaCollapseString(value);
else else
normValue = xmlSchemaWhiteSpaceReplace(value); normValue = xmlSchemaWhiteSpaceReplace(value);
@ -16636,7 +16645,14 @@ compareValue:
{ {
#ifdef IDC_VALUE_SUPPORT #ifdef IDC_VALUE_SUPPORT
int ret; int ret;
ret = xmlSchemaCompareValues(a, b); int aws, bws;
aws = xmlSchemaGetWhiteSpaceFacetValue(ta);
bws = xmlSchemaGetWhiteSpaceFacetValue(tb);
ret = xmlSchemaCompareValuesWhtsp(
a, (xmlSchemaWhitespaceValueType) aws,
b, (xmlSchemaWhitespaceValueType) bws);
if (ret == 0) if (ret == 0)
return(1); return(1);
else if (ret == -2) { else if (ret == -2) {
@ -16962,11 +16978,19 @@ xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
* Failed to provide the normalized value; maby * Failed to provide the normalized value; maby
* the value was invalid. * the value was invalid.
*/ */
xmlSchemaVErr(vctxt, NULL, xmlSchemaVCustomErr(vctxt,
XML_SCHEMAV_CVC_IDC,
vctxt->nodeInfo->node,
(xmlSchemaTypePtr) sto->matcher->aidc->def,
"Warning: No precomputed value available, the value "
"was either invalid or something strange happend", NULL);
/*
xmlSchemaVErr(vctxt, vctxt->nodeInfo->node,
XML_SCHEMAV_INTERNAL, XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaXPathProcessHistory, " "Internal error: xmlSchemaXPathProcessHistory, "
"computed value not available.\n", "computed value not available.\n",
NULL, NULL); NULL, NULL);
*/
sto->nbHistory--; sto->nbHistory--;
goto deregister_check; goto deregister_check;
} else { } else {
@ -18308,7 +18332,7 @@ xmlSchemaValidateElementByDeclaration(xmlSchemaValidCtxtPtr ctxt,
XML_SCHEMAV_INTERNAL, XML_SCHEMAV_INTERNAL,
elem, actualType, elem, actualType,
"Internal error: xmlSchemaValidateElementByDeclaration, " "Internal error: xmlSchemaValidateElementByDeclaration, "
"validating a default value", NULL); "calling validation by type", NULL);
return (-1); return (-1);
} }
/* /*
@ -19083,7 +19107,6 @@ xmlSchemaValidateElementByType(xmlSchemaValidCtxtPtr ctxt,
return (ret); return (ret);
} }
static int static int
xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt, xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
xmlSchemaAttrStatePtr state) xmlSchemaAttrStatePtr state)
@ -19126,6 +19149,10 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
if (xmlSchemaGetEffectiveValueConstraint( if (xmlSchemaGetEffectiveValueConstraint(
(xmlSchemaAttributePtr) ctxt->attrInfo->decl, (xmlSchemaAttributePtr) ctxt->attrInfo->decl,
&fixed, &defValue, &defVal) && (fixed == 1)) { &fixed, &defValue, &defVal) && (fixed == 1)) {
int ws = xmlSchemaGetWhiteSpaceFacetValue(
ctxt->attrInfo->typeDef);
/* /*
* cvc-au : Attribute Locally Valid (Use) * cvc-au : Attribute Locally Valid (Use)
* For an attribute information item to be·valid· * For an attribute information item to be·valid·
@ -19142,12 +19169,45 @@ xmlSchemaCheckAttrLocallyValid(xmlSchemaValidCtxtPtr ctxt,
* TODO: Use the *normalized* value and the *canonical* fixed * TODO: Use the *normalized* value and the *canonical* fixed
* value. * value.
*/ */
if (((ctxt->value != NULL) && if (ctxt->value != NULL) {
(xmlSchemaCompareValues(ctxt->value, defVal) != 0)) || if (defVal == NULL) {
((ctxt->value == NULL) && xmlSchemaTypePtr prim;
(! xmlStrEqual(defValue, BAD_CAST value)))) { /*
* Oops, the value was not computed.
*/
prim = xmlSchemaGetPrimitiveType(ctxt->attrInfo->typeDef);
if (prim->builtInType == XML_SCHEMAS_STRING) {
xmlSchemaTypePtr builtIn;
builtIn = xmlSchemaGetBuiltInTypeAncestor(
ctxt->attrInfo->typeDef);
defVal = xmlSchemaNewStringValue(
builtIn->builtInType, value);
((xmlSchemaAttributePtr) ctxt->attrInfo->decl)->defVal =
defVal;
value = NULL;
} else {
xmlSchemaVErr(ctxt, ctxt->attrInfo->node,
XML_SCHEMAV_INTERNAL,
"Internal error: xmlSchemaCheckAttrLocallyValid, "
"could not aquire a precomputed vale",
NULL, NULL);
}
}
if (defVal != NULL) {
if (xmlSchemaCompareValuesWhtsp(ctxt->value,
(xmlSchemaWhitespaceValueType) ws,
defVal, (xmlSchemaWhitespaceValueType) ws) != 0)
state->state =
XML_SCHEMAS_ATTR_INVALID_FIXED_VALUE;
}
} else if (! xmlStrEqual(defValue, BAD_CAST value)) {
/*
* TODO: Remove this and ensure computed values to be
* existent.
*/
state->state = state->state =
XML_SCHEMAS_ATTR_INVALID_FIXED_VALUE; XML_SCHEMAS_ATTR_INVALID_FIXED_VALUE;
} }
} }
} }

View File

@ -45,6 +45,11 @@ extern double xmlXPathNINF;
#define XML_SCHEMAS_NAMESPACE_NAME \ #define XML_SCHEMAS_NAMESPACE_NAME \
(const xmlChar *)"http://www.w3.org/2001/XMLSchema" (const xmlChar *)"http://www.w3.org/2001/XMLSchema"
#define IS_WSP_REPLACE_CH(c) ((((c) == 0x9) || ((c) == 0xa)) || \
((c) == 0xd))
#define IS_WSP_SPACE_CH(c) ((c) == 0x20)
static unsigned long powten[10] = { static unsigned long powten[10] = {
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000L, 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000L,
@ -676,6 +681,34 @@ xmlSchemaNewValue(xmlSchemaValType type) {
return(value); return(value);
} }
/**
* xmlSchemaNewStringValue:
* @type: the value type
*
* Allocate a new simple type value. The type can be
* of XML_SCHEMAS_STRING.
*
* Returns a pointer to the new value or NULL in case of error
*/
xmlSchemaValPtr
xmlSchemaNewStringValue(xmlSchemaValType type,
const xmlChar *value)
{
xmlSchemaValPtr val;
if (type != XML_SCHEMAS_STRING)
return(NULL);
val = (xmlSchemaValPtr) xmlMalloc(sizeof(xmlSchemaVal));
if (val == NULL) {
return(NULL);
}
memset(val, 0, sizeof(xmlSchemaVal));
val->type = type;
val->value.str = (xmlChar *) value;
return(val);
}
/** /**
* xmlSchemaFreeValue: * xmlSchemaFreeValue:
* @value: the value to free * @value: the value to free
@ -2210,7 +2243,11 @@ xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
case XML_SCHEMAS_IDREF: case XML_SCHEMAS_IDREF:
ret = xmlValidateNCName(value, 1); ret = xmlValidateNCName(value, 1);
if ((ret == 0) && (val != NULL)) { if ((ret == 0) && (val != NULL)) {
TODO; v = xmlSchemaNewValue(XML_SCHEMAS_IDREF);
if (v == NULL)
goto error;
v->value.str = xmlStrdup(value);
*val = v;
} }
if ((ret == 0) && (node != NULL) && if ((ret == 0) && (node != NULL) &&
(node->type == XML_ATTRIBUTE_NODE)) { (node->type == XML_ATTRIBUTE_NODE)) {
@ -3477,6 +3514,333 @@ xmlSchemaCompareDates (xmlSchemaValPtr x, xmlSchemaValPtr y)
return 0; return 0;
} }
/**
* xmlSchemaComparePreserveReplaceStrings:
* @x: a first string value
* @y: a second string value
* @invert: inverts the result if x < y or x > y.
*
* Compare 2 string for their normalized values.
* @x is a string with whitespace of "preserve", @y is
* a string with a whitespace of "replace". I.e. @x could
* be an "xsd:string" and @y an "xsd:normalizedString".
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
* case of error
*/
static int
xmlSchemaComparePreserveReplaceStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
int invert)
{
const xmlChar *utf1;
const xmlChar *utf2;
int tmp;
if ((x == NULL) || (y == NULL))
return(-2);
utf1 = x->value.str;
utf2 = y->value.str;
while ((*utf1 != 0) && (*utf2 != 0)) {
if (IS_WSP_REPLACE_CH(*utf2)) {
if (! IS_WSP_SPACE_CH(*utf1)) {
if ((*utf1 - 0x20) < 0) {
if (invert)
return(1);
else
return(-1);
} else {
if (invert)
return(-1);
else
return(1);
}
}
} else {
tmp = *utf1 - *utf2;
if (tmp < 0) {
if (invert)
return(1);
else
return(-1);
}
if (tmp > 0) {
if (invert)
return(-1);
else
return(1);
}
}
utf1++;
utf2++;
}
if (*utf1 != 0) {
if (invert)
return(-1);
else
return(1);
}
if (*utf2 != 0) {
if (invert)
return(1);
else
return(-1);
}
return(0);
}
/**
* xmlSchemaComparePreserveCollapseStrings:
* @x: a first string value
* @y: a second string value
*
* Compare 2 string for their normalized values.
* @x is a string with whitespace of "preserve", @y is
* a string with a whitespace of "collapse". I.e. @x could
* be an "xsd:string" and @y an "xsd:normalizedString".
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
* case of error
*/
static int
xmlSchemaComparePreserveCollapseStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
int invert)
{
const xmlChar *utf1;
const xmlChar *utf2;
int tmp;
if ((x == NULL) || (y == NULL))
return(-2);
utf1 = x->value.str;
utf2 = y->value.str;
/*
* Skip leading blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
utf2++;
while ((*utf1 != 0) && (*utf2 != 0)) {
if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
if (! IS_WSP_SPACE_CH(*utf1)) {
/*
* The utf2 character would have been replaced to 0x20.
*/
if ((*utf1 - 0x20) < 0) {
if (invert)
return(1);
else
return(-1);
} else {
if (invert)
return(-1);
else
return(1);
}
}
utf1++;
utf2++;
/*
* Skip contiguous blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
utf2++;
} else {
tmp = *utf1++ - *utf2++;
if (tmp < 0) {
if (invert)
return(1);
else
return(-1);
}
if (tmp > 0) {
if (invert)
return(-1);
else
return(1);
}
}
}
if (*utf1 != 0) {
if (invert)
return(-1);
else
return(1);
}
if (*utf2 != 0) {
/*
* Skip trailing blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
utf2++;
if (*utf2 != 0) {
if (invert)
return(1);
else
return(-1);
}
}
return(0);
}
/**
* xmlSchemaComparePreserveCollapseStrings:
* @x: a first string value
* @y: a second string value
*
* Compare 2 string for their normalized values.
* @x is a string with whitespace of "preserve", @y is
* a string with a whitespace of "collapse". I.e. @x could
* be an "xsd:string" and @y an "xsd:normalizedString".
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
* case of error
*/
static int
xmlSchemaCompareReplaceCollapseStrings(xmlSchemaValPtr x, xmlSchemaValPtr y,
int invert)
{
const xmlChar *utf1;
const xmlChar *utf2;
int tmp;
if ((x == NULL) || (y == NULL))
return(-2);
utf1 = x->value.str;
utf2 = y->value.str;
/*
* Skip leading blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
utf2++;
while ((*utf1 != 0) && (*utf2 != 0)) {
if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
if (! (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1))) {
/*
* The utf2 character would have been replaced to 0x20.
*/
if ((*utf1 - 0x20) < 0) {
if (invert)
return(1);
else
return(-1);
} else {
if (invert)
return(-1);
else
return(1);
}
}
utf1++;
utf2++;
/*
* Skip contiguous blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
utf2++;
} else {
if (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1)) {
/*
* The utf1 character would have been replaced to 0x20.
*/
if ((0x20 - *utf2) < 0) {
if (invert)
return(1);
else
return(-1);
} else {
if (invert)
return(-1);
else
return(1);
}
}
tmp = *utf1++ - *utf2++;
if (tmp < 0)
return(-1);
if (tmp > 0)
return(1);
}
}
if (*utf1 != 0) {
if (invert)
return(-1);
else
return(1);
}
if (*utf2 != 0) {
/*
* Skip trailing blank chars of the collapsed string.
*/
while (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2))
utf2++;
if (*utf2 != 0) {
if (invert)
return(1);
else
return(-1);
}
}
return(0);
}
/**
* xmlSchemaCompareReplacedStrings:
* @x: a first string value
* @y: a second string value
*
* Compare 2 string for their normalized values.
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, and -2 in
* case of error
*/
static int
xmlSchemaCompareReplacedStrings(xmlSchemaValPtr x, xmlSchemaValPtr y)
{
const xmlChar *utf1;
const xmlChar *utf2;
int tmp;
if ((x == NULL) || (y == NULL))
return(-2);
utf1 = x->value.str;
utf2 = y->value.str;
while ((*utf1 != 0) && (*utf2 != 0)) {
if (IS_WSP_SPACE_CH(*utf2) || IS_WSP_REPLACE_CH(*utf2)) {
if (! (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1))) {
if ((*utf1 - 0x20) < 0)
return(-1);
else
return(1);
}
} else {
if (IS_WSP_SPACE_CH(*utf1) || IS_WSP_REPLACE_CH(*utf1)) {
if ((0x20 - *utf2) < 0)
return(-1);
else
return(1);
}
tmp = *utf1 - *utf2;
if (tmp < 0)
return(-1);
if (tmp > 0)
return(1);
}
utf1++;
utf2++;
}
if (*utf1 != 0)
return(1);
if (*utf2 != 0)
return(-1);
return(0);
}
/** /**
* xmlSchemaCompareNormStrings: * xmlSchemaCompareNormStrings:
* @x: a first string value * @x: a first string value
@ -3605,15 +3969,20 @@ xmlSchemaCompareFloats(xmlSchemaValPtr x, xmlSchemaValPtr y) {
/** /**
* xmlSchemaCompareValues: * xmlSchemaCompareValues:
* @x: a first value * @x: a first value
* @xwtsp: the whitespace type
* @y: a second value * @y: a second value
* @ywtsp: the whitespace type
* *
* Compare 2 values * Compare 2 values
* *
* Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in * Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
* case of error * case of error
*/ */
int static int
xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) { xmlSchemaCompareValuesInternal(xmlSchemaValPtr x,
xmlSchemaWhitespaceValueType xws,
xmlSchemaValPtr y,
xmlSchemaWhitespaceValueType yws) {
if ((x == NULL) || (y == NULL)) if ((x == NULL) || (y == NULL))
return(-2); return(-2);
@ -3676,7 +4045,8 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
(y->type == XML_SCHEMAS_GYEARMONTH)) (y->type == XML_SCHEMAS_GYEARMONTH))
return (xmlSchemaCompareDates(x, y)); return (xmlSchemaCompareDates(x, y));
return (-2); return (-2);
case XML_SCHEMAS_NORMSTRING: case XML_SCHEMAS_STRING:
case XML_SCHEMAS_NORMSTRING:
case XML_SCHEMAS_TOKEN: case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE: case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN: case XML_SCHEMAS_NMTOKEN:
@ -3687,19 +4057,60 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
case XML_SCHEMAS_ENTITY: case XML_SCHEMAS_ENTITY:
case XML_SCHEMAS_NOTATION: case XML_SCHEMAS_NOTATION:
case XML_SCHEMAS_ANYURI: case XML_SCHEMAS_ANYURI:
if ((y->type == XML_SCHEMAS_NORMSTRING) || /*
* TODO: Compare those against QName.
*/
if (y->type == XML_SCHEMAS_QNAME) {
TODO
return (-2);
}
if ((y->type == XML_SCHEMAS_STRING) ||
(y->type == XML_SCHEMAS_NORMSTRING) ||
(y->type == XML_SCHEMAS_TOKEN) || (y->type == XML_SCHEMAS_TOKEN) ||
(y->type == XML_SCHEMAS_LANGUAGE) || (y->type == XML_SCHEMAS_LANGUAGE) ||
(y->type == XML_SCHEMAS_NMTOKEN) || (y->type == XML_SCHEMAS_NMTOKEN) ||
(y->type == XML_SCHEMAS_NAME) || (y->type == XML_SCHEMAS_NAME) ||
(y->type == XML_SCHEMAS_QNAME) ||
(y->type == XML_SCHEMAS_NCNAME) || (y->type == XML_SCHEMAS_NCNAME) ||
(y->type == XML_SCHEMAS_ID) || (y->type == XML_SCHEMAS_ID) ||
(y->type == XML_SCHEMAS_IDREF) || (y->type == XML_SCHEMAS_IDREF) ||
(y->type == XML_SCHEMAS_ENTITY) || (y->type == XML_SCHEMAS_ENTITY) ||
(y->type == XML_SCHEMAS_NOTATION) || (y->type == XML_SCHEMAS_NOTATION) ||
(y->type == XML_SCHEMAS_ANYURI)) (y->type == XML_SCHEMAS_ANYURI)) {
return (xmlSchemaCompareNormStrings(x, y));
if (xws == XML_SCHEMA_WHITESPACE_PRESERVE) {
if (yws == XML_SCHEMA_WHITESPACE_PRESERVE) {
/* TODO: What about x < y or x > y. */
if (xmlStrEqual(x->value.str, y->value.str))
return (0);
else
return (2);
} else if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
return (xmlSchemaComparePreserveReplaceStrings(x, y, 0));
else if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
return (xmlSchemaComparePreserveCollapseStrings(x, y, 0));
} else if (xws == XML_SCHEMA_WHITESPACE_REPLACE) {
if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
return (xmlSchemaComparePreserveReplaceStrings(y, x, 1));
if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
return (xmlSchemaCompareReplacedStrings(x, y));
if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
return (xmlSchemaCompareReplaceCollapseStrings(x, y, 0));
} else if (xws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
if (yws == XML_SCHEMA_WHITESPACE_PRESERVE)
return (xmlSchemaComparePreserveCollapseStrings(y, x, 1));
if (yws == XML_SCHEMA_WHITESPACE_REPLACE)
return (xmlSchemaCompareReplaceCollapseStrings(y, x, 1));
if (yws == XML_SCHEMA_WHITESPACE_COLLAPSE)
return (xmlSchemaCompareNormStrings(x, y));
} else
return (-2);
}
return (-2); return (-2);
case XML_SCHEMAS_QNAME: case XML_SCHEMAS_QNAME:
if (y->type == XML_SCHEMAS_QNAME) { if (y->type == XML_SCHEMAS_QNAME) {
@ -3754,8 +4165,7 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
else else
return(-1); return(-1);
} }
return (-2); return (-2);
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_IDREFS: case XML_SCHEMAS_IDREFS:
case XML_SCHEMAS_ENTITIES: case XML_SCHEMAS_ENTITIES:
case XML_SCHEMAS_NMTOKENS: case XML_SCHEMAS_NMTOKENS:
@ -3765,6 +4175,57 @@ xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
return -2; return -2;
} }
/**
* xmlSchemaCompareValues:
* @x: a first value
* @y: a second value
*
* Compare 2 values
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
* case of error
*/
int
xmlSchemaCompareValues(xmlSchemaValPtr x, xmlSchemaValPtr y) {
xmlSchemaWhitespaceValueType xws, yws;
if (x->type == XML_SCHEMAS_STRING)
xws = XML_SCHEMA_WHITESPACE_PRESERVE;
else if (x->type == XML_SCHEMAS_NORMSTRING)
xws = XML_SCHEMA_WHITESPACE_REPLACE;
else
xws = XML_SCHEMA_WHITESPACE_COLLAPSE;
if (y->type == XML_SCHEMAS_STRING)
yws = XML_SCHEMA_WHITESPACE_PRESERVE;
else if (x->type == XML_SCHEMAS_NORMSTRING)
yws = XML_SCHEMA_WHITESPACE_REPLACE;
else
yws = XML_SCHEMA_WHITESPACE_COLLAPSE;
return(xmlSchemaCompareValuesInternal(x, xws, y, yws));
}
/**
* xmlSchemaCompareValuesWhtsp:
* @x: a first value
* @xws: the whitespace value of x
* @y: a second value
* @yws: the whitespace value of y
*
* Compare 2 values
*
* Returns -1 if x < y, 0 if x == y, 1 if x > y, 2 if x <> y, and -2 in
* case of error
*/
int
xmlSchemaCompareValuesWhtsp(xmlSchemaValPtr x,
xmlSchemaWhitespaceValueType xws,
xmlSchemaValPtr y,
xmlSchemaWhitespaceValueType yws) {
return(xmlSchemaCompareValuesInternal(x, xws, y, yws));
}
/** /**
* xmlSchemaNormLen: * xmlSchemaNormLen:
* @value: a string * @value: a string
@ -4138,4 +4599,51 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED,
} }
/**
* xmlSchemaGetCanonValue:
* @val: the precomputed value
* @retValue: the returned value
*
* Returns a the cononical representation of the value.
* The called has to free the returned retValue.
*
* Returns 0 if the value could be built and -1 in case of
* API errors or if the value type is not supported yet.
*/
int
xmlSchemaGetCanonValue(xmlSchemaValPtr val,
const xmlChar **retValue)
{
if (retValue == NULL)
return (-1);
*retValue = NULL;
switch (val->type) {
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_NORMSTRING:
/*
case XML_SCHEMAS_TOKEN:
case XML_SCHEMAS_LANGUAGE:
case XML_SCHEMAS_NMTOKEN:
case XML_SCHEMAS_NAME:
case XML_SCHEMAS_QNAME:
case XML_SCHEMAS_NCNAME:
case XML_SCHEMAS_ID:
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_ENTITY:
case XML_SCHEMAS_NOTATION:
case XML_SCHEMAS_ANYURI:
*/
if (val->value.str == NULL)
*retValue = NULL;
else
/* TODO: This is not yet correct for non-normalized values. */
*retValue =
BAD_CAST xmlStrdup((const xmlChar *) val->value.str);
return (0);
default:
return (-1);
}
return (-1);
}
#endif /* LIBXML_SCHEMAS_ENABLED */ #endif /* LIBXML_SCHEMAS_ENABLED */