diff --git a/ChangeLog b/ChangeLog index 15ba9fb2..f0b78a93 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Thu Feb 27 18:40:04 CET 2003 Daniel Veillard + + * relaxng.c xmlschemas.c xmlschemastypes.c + include/libxml/xmlschemastypes.h: added param support for relaxng + type checking, started to increment the pool of simple types + registered, still much work to be done on simple types and + facets checkings. + Wed Feb 26 16:45:39 CET 2003 Daniel Veillard * entities.c: fixes again one of the problem raised by diff --git a/include/libxml/xmlschemastypes.h b/include/libxml/xmlschemastypes.h index a758c128..992232e0 100644 --- a/include/libxml/xmlschemastypes.h +++ b/include/libxml/xmlschemastypes.h @@ -16,6 +16,7 @@ #ifdef LIBXML_SCHEMAS_ENABLED #include +#include #ifdef __cplusplus extern "C" { @@ -33,6 +34,12 @@ int xmlSchemaValidateFacet (xmlSchemaTypePtr base, const xmlChar *value, xmlSchemaValPtr val); void xmlSchemaFreeValue (xmlSchemaValPtr val); +xmlSchemaFacetPtr xmlSchemaNewFacet (void); +int xmlSchemaCheckFacet (xmlSchemaFacetPtr facet, + xmlSchemaTypePtr typeDecl, + xmlSchemaParserCtxtPtr ctxt, + const xmlChar *name); +void xmlSchemaFreeFacet (xmlSchemaFacetPtr facet); #ifdef __cplusplus } diff --git a/relaxng.c b/relaxng.c index 29db131d..ff11f3ec 100644 --- a/relaxng.c +++ b/relaxng.c @@ -332,13 +332,40 @@ typedef int (*xmlRelaxNGTypeHave) (void *data, const xmlChar *type); * @data: data needed for the library * @type: the type name * @value: the value to check + * @result: place to store the result if needed * * Function provided by a type library to check if a value match a type * * Returns 1 if yes, 0 if no and -1 in case of error. */ typedef int (*xmlRelaxNGTypeCheck) (void *data, const xmlChar *type, - const xmlChar *value); + const xmlChar *value, void **result); + +/** + * xmlRelaxNGFacetCheck: + * @data: data needed for the library + * @type: the type name + * @facet: the facet name + * @val: the facet value + * @strval: the string value + * @value: the value to check + * + * Function provided by a type library to check a value facet + * + * Returns 1 if yes, 0 if no and -1 in case of error. + */ +typedef int (*xmlRelaxNGFacetCheck) (void *data, const xmlChar *type, + const xmlChar *facet, const xmlChar *val, + const xmlChar *strval, void *value); + +/** + * xmlRelaxNGTypeFree: + * @data: data needed for the library + * @result: the value to free + * + * Function provided by a type library to free a returned result + */ +typedef void (*xmlRelaxNGTypeFree) (void *data, void *result); /** * xmlRelaxNGTypeCompare: @@ -363,6 +390,8 @@ struct _xmlRelaxNGTypeLibrary { xmlRelaxNGTypeHave have; /* the export function */ xmlRelaxNGTypeCheck check; /* the checking function */ xmlRelaxNGTypeCompare comp; /* the compare function */ + xmlRelaxNGFacetCheck facet; /* the facet check function */ + xmlRelaxNGTypeFree freef; /* the freeing function */ }; /************************************************************************ @@ -1440,7 +1469,8 @@ xmlRelaxNGSchemaTypeHave(void *data ATTRIBUTE_UNUSED, static int xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED, const xmlChar *type, - const xmlChar *value) { + const xmlChar *value, + void **result) { xmlSchemaTypePtr typ; int ret; @@ -1456,7 +1486,8 @@ xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED, BAD_CAST "http://www.w3.org/2001/XMLSchema"); if (typ == NULL) return(-1); - ret = xmlSchemaValidatePredefinedType(typ, value, NULL); + ret = xmlSchemaValidatePredefinedType(typ, value, + (xmlSchemaValPtr *) result); if (ret == 0) return(1); if (ret > 0) @@ -1464,6 +1495,79 @@ xmlRelaxNGSchemaTypeCheck(void *data ATTRIBUTE_UNUSED, return(-1); } +/** + * xmlRelaxNGSchemaFacetCheck: + * @data: data needed for the library + * @type: the type name + * @facet: the facet name + * @val: the facet value + * @strval: the string value + * @value: the value to check + * + * Function provided by a type library to check a value facet + * + * Returns 1 if yes, 0 if no and -1 in case of error. + */ +static int +xmlRelaxNGSchemaFacetCheck (void *data, const xmlChar *type, + const xmlChar *facetname, const xmlChar *val, + const xmlChar *strval, void *value) { + xmlSchemaFacetPtr facet; + xmlSchemaTypePtr typ; + int ret; + + if ((type == NULL) || (strval == NULL)) + return(-1); + typ = xmlSchemaGetPredefinedType(type, + BAD_CAST "http://www.w3.org/2001/XMLSchema"); + if (typ == NULL) + return(-1); + + facet = xmlSchemaNewFacet(); + if (facet == NULL) + return(-1); + + if (xmlStrEqual(facetname, BAD_CAST "minInclusive")) { + facet->type = XML_SCHEMA_FACET_MININCLUSIVE; + } else if (xmlStrEqual(facetname, BAD_CAST "minExclusive")) { + facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE; + } else if (xmlStrEqual(facetname, BAD_CAST "maxInclusive")) { + facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE; + } else if (xmlStrEqual(facetname, BAD_CAST "maxExclusive")) { + facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE; + } else if (xmlStrEqual(facetname, BAD_CAST "totalDigits")) { + facet->type = XML_SCHEMA_FACET_TOTALDIGITS; + } else if (xmlStrEqual(facetname, BAD_CAST "fractionDigits")) { + facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS; + } else if (xmlStrEqual(facetname, BAD_CAST "pattern")) { + facet->type = XML_SCHEMA_FACET_PATTERN; + } else if (xmlStrEqual(facetname, BAD_CAST "enumeration")) { + facet->type = XML_SCHEMA_FACET_ENUMERATION; + } else if (xmlStrEqual(facetname, BAD_CAST "whiteSpace")) { + facet->type = XML_SCHEMA_FACET_WHITESPACE; + } else if (xmlStrEqual(facetname, BAD_CAST "length")) { + facet->type = XML_SCHEMA_FACET_LENGTH; + } else if (xmlStrEqual(facetname, BAD_CAST "maxLength")) { + facet->type = XML_SCHEMA_FACET_MAXLENGTH; + } else if (xmlStrEqual(facetname, BAD_CAST "minLength")) { + facet->type = XML_SCHEMA_FACET_MINLENGTH; + } else { + xmlSchemaFreeFacet(facet); + return(-1); + } + facet->value = xmlStrdup(val); + ret = xmlSchemaCheckFacet(facet, typ, NULL, type); + if (ret != 0) { + xmlSchemaFreeFacet(facet); + return(-1); + } + ret = xmlSchemaValidateFacet(typ, facet, strval, value); + xmlSchemaFreeFacet(facet); + if (ret != 0) + return(-1); + return(0); +} + /** * xmlRelaxNGSchemaTypeCompare: * @data: data needed for the library @@ -1520,21 +1624,13 @@ xmlRelaxNGDefaultTypeHave(void *data ATTRIBUTE_UNUSED, const xmlChar *type) { static int xmlRelaxNGDefaultTypeCheck(void *data ATTRIBUTE_UNUSED, const xmlChar *type ATTRIBUTE_UNUSED, - const xmlChar *value ATTRIBUTE_UNUSED) { + const xmlChar *value ATTRIBUTE_UNUSED, + void **result ATTRIBUTE_UNUSED) { if (value == NULL) return(-1); if (xmlStrEqual(type, BAD_CAST "string")) return(1); if (xmlStrEqual(type, BAD_CAST "token")) { -#if 0 - const xmlChar *cur = value; - - while (*cur != 0) { - if (!IS_BLANK(*cur)) - return(1); - cur++; - } -#endif return(1); } @@ -1624,7 +1720,8 @@ xmlRelaxNGFreeTypeLibrary(xmlRelaxNGTypeLibraryPtr lib, static int xmlRelaxNGRegisterTypeLibrary(const xmlChar *namespace, void *data, xmlRelaxNGTypeHave have, xmlRelaxNGTypeCheck check, - xmlRelaxNGTypeCompare comp) { + xmlRelaxNGTypeCompare comp, xmlRelaxNGFacetCheck facet, + xmlRelaxNGTypeFree freef) { xmlRelaxNGTypeLibraryPtr lib; int ret; @@ -1650,6 +1747,8 @@ xmlRelaxNGRegisterTypeLibrary(const xmlChar *namespace, void *data, lib->have = have; lib->comp = comp; lib->check = check; + lib->facet = facet; + lib->freef = freef; ret = xmlHashAddEntry(xmlRelaxNGRegisteredTypes, namespace, lib); if (ret < 0) { xmlGenericError(xmlGenericErrorContext, @@ -1683,13 +1782,17 @@ xmlRelaxNGInitTypes(void) { NULL, xmlRelaxNGSchemaTypeHave, xmlRelaxNGSchemaTypeCheck, - xmlRelaxNGSchemaTypeCompare); + xmlRelaxNGSchemaTypeCompare, + xmlRelaxNGSchemaFacetCheck, + (xmlRelaxNGTypeFree) xmlSchemaFreeValue); xmlRelaxNGRegisterTypeLibrary( xmlRelaxNGNs, NULL, xmlRelaxNGDefaultTypeHave, xmlRelaxNGDefaultTypeCheck, - xmlRelaxNGDefaultTypeCompare); + xmlRelaxNGDefaultTypeCompare, + NULL, + NULL); xmlRelaxNGTypeInitialized = 1; return(0); } @@ -2009,6 +2112,8 @@ xmlRelaxNGParseData(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { lastparam->next = param; lastparam = param; } + if (lib != NULL) { + } } content = content->next; } @@ -2960,11 +3065,6 @@ xmlRelaxNGParsePattern(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) { } } else if (IS_RELAXNG(node, "data")) { def = xmlRelaxNGParseData(ctxt, node); -#if 0 - } else if (IS_RELAXNG(node, "define")) { - xmlRelaxNGParseDefine(ctxt, node); - def = NULL; -#endif } else if (IS_RELAXNG(node, "value")) { def = xmlRelaxNGParseValue(ctxt, node); } else if (IS_RELAXNG(node, "list")) { @@ -5835,29 +5935,47 @@ xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar *str) { static int xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar *value, xmlRelaxNGDefinePtr define) { - int ret; + int ret, tmp; xmlRelaxNGTypeLibraryPtr lib; + void *result = NULL; + xmlRelaxNGDefinePtr cur; if ((define == NULL) || (define->data == NULL)) { return(-1); } lib = (xmlRelaxNGTypeLibraryPtr) define->data; - if (lib->check != NULL) - ret = lib->check(lib->data, define->name, value); - else + if (lib->check != NULL) { + if ((define->attrs != NULL) && + (define->attrs->type == XML_RELAXNG_PARAM)) { + ret = lib->check(lib->data, define->name, value, &result); + } else { + ret = lib->check(lib->data, define->name, value, NULL); + } + } else ret = -1; if (ret < 0) { VALID_CTXT(); - VALID_ERROR2("Internal: failed to validate type %s\n", define->name); + VALID_ERROR2("failed to validate type %s\n", define->name); + if ((result != NULL) && (lib != NULL) && (lib->freef != NULL)) + lib->freef(lib->data, result); return(-1); } else if (ret == 1) { ret = 0; } else { VALID_CTXT(); VALID_ERROR3("Type %s doesn't allow value %s\n", define->name, value); - return(-1); ret = -1; } + cur = define->attrs; + while ((ret == 0) && (cur != NULL) && (cur->type == XML_RELAXNG_PARAM)) { + if (lib->facet != NULL) { + tmp = lib->facet(lib->data, define->name, cur->name, + cur->value, value, result); + if (tmp != 0) + ret = -1; + } + cur = cur->next; + } if ((ret == 0) && (define->content != NULL)) { const xmlChar *oldvalue, *oldendvalue; @@ -5869,6 +5987,8 @@ xmlRelaxNGValidateDatatype(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar *value, ctxt->state->value = (xmlChar *) oldvalue; ctxt->state->endvalue = (xmlChar *) oldendvalue; } + if ((result != NULL) && (lib != NULL) && (lib->freef != NULL)) + lib->freef(lib->data, result); return(ret); } @@ -6998,7 +7118,7 @@ xmlRelaxNGValidateDefinition(xmlRelaxNGValidCtxtPtr ctxt, ret = xmlRelaxNGValidateDatatype(ctxt, content, define); if (ret == -1) { VALID_CTXT(); - VALID_ERROR2("internal error validating %s\n", define->name); + VALID_ERROR2("Error validating %s\n", define->name); } else if (ret == 0) { ctxt->state->seq = NULL; } diff --git a/xmlschemas.c b/xmlschemas.c index 9bafb2dc..018b0b21 100644 --- a/xmlschemas.c +++ b/xmlschemas.c @@ -172,15 +172,13 @@ xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt) * * Returns the newly allocated structure or NULL in case or error */ -static xmlSchemaFacetPtr -xmlSchemaNewFacet(xmlSchemaParserCtxtPtr ctxt) +xmlSchemaFacetPtr +xmlSchemaNewFacet(void) { xmlSchemaFacetPtr ret; ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet)); if (ret == NULL) { - if ((ctxt != NULL) && (ctxt->error != NULL)) - ctxt->error(ctxt->userData, "Out of memory\n"); return (NULL); } memset(ret, 0, sizeof(xmlSchemaFacet)); @@ -317,7 +315,7 @@ xmlSchemaFreeElement(xmlSchemaElementPtr elem) * * Deallocate a Schema Facet structure. */ -static void +void xmlSchemaFreeFacet(xmlSchemaFacetPtr facet) { if (facet == NULL) @@ -1338,7 +1336,7 @@ xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema, if ((ctxt == NULL) || (schema == NULL) || (node == NULL)) return (NULL); - facet = xmlSchemaNewFacet(ctxt); + facet = xmlSchemaNewFacet(); if (facet == NULL) return (NULL); facet->node = node; @@ -3707,6 +3705,149 @@ xmlSchemaTypeFixup(xmlSchemaTypePtr typeDecl, #endif } +/** + * xmlSchemaCheckFacet: + * @facet: the facet + * @typeDecl: the schema type definition + * @ctxt: the schema parser context or NULL + * @name: name of the type + * + * Checks the default values types, especially for facets + * + * Returns 0 if okay or -1 in cae of error + */ +int +xmlSchemaCheckFacet(xmlSchemaFacetPtr facet, + xmlSchemaTypePtr typeDecl, + xmlSchemaParserCtxtPtr ctxt, + const xmlChar *name) +{ + static xmlSchemaTypePtr nonNegativeIntegerType = NULL; + int ret = 0; + + if (nonNegativeIntegerType == NULL) { + nonNegativeIntegerType = xmlSchemaGetPredefinedType( + BAD_CAST "nonNegativeInteger", xmlSchemaNs); + } + switch (facet->type) { + case XML_SCHEMA_FACET_MININCLUSIVE: + case XML_SCHEMA_FACET_MINEXCLUSIVE: + case XML_SCHEMA_FACET_MAXINCLUSIVE: + case XML_SCHEMA_FACET_MAXEXCLUSIVE: { + /* + * Okay we need to validate the value + * at that point. + */ + xmlSchemaValidCtxtPtr vctxt; + + vctxt = xmlSchemaNewValidCtxt(NULL); + if (vctxt == NULL) + break; + xmlSchemaValidateSimpleValue(vctxt, typeDecl, + facet->value); + facet->val = vctxt->value; + vctxt->value = NULL; + if (facet->val == NULL) { + /* error code */ + if (ctxt != NULL) { + xmlSchemaErrorContext(ctxt, NULL, + facet->node, NULL); + ctxt->error(ctxt->userData, + "Schemas: type %s facet value %s invalid\n", + name, facet->value); + } + ret = -1; + } + xmlSchemaFreeValidCtxt(vctxt); + break; + } + case XML_SCHEMA_FACET_ENUMERATION: { + /* + * Okay we need to validate the value + * at that point. + */ + xmlSchemaValidCtxtPtr vctxt; + int tmp; + + vctxt = xmlSchemaNewValidCtxt(NULL); + if (vctxt == NULL) + break; + tmp = xmlSchemaValidateSimpleValue(vctxt, typeDecl, + facet->value); + if (tmp != 0) { + if (ctxt != NULL) { + xmlSchemaErrorContext(ctxt, NULL, + facet->node, NULL); + ctxt->error(ctxt->userData, + "Schemas: type %s enumeration value %s invalid\n", + name, facet->value); + } + ret = -1; + } + xmlSchemaFreeValidCtxt(vctxt); + break; + } + case XML_SCHEMA_FACET_PATTERN: + facet->regexp = xmlRegexpCompile(facet->value); + if (facet->regexp == NULL) { + /* error code */ + if (ctxt != NULL) { + ctxt->error(ctxt->userData, + "Schemas: type %s facet regexp %s invalid\n", + name, facet->value); + } + ret = -1; + } + break; + case XML_SCHEMA_FACET_TOTALDIGITS: + case XML_SCHEMA_FACET_FRACTIONDIGITS: + case XML_SCHEMA_FACET_LENGTH: + case XML_SCHEMA_FACET_MAXLENGTH: + case XML_SCHEMA_FACET_MINLENGTH: { + int tmp; + + tmp = xmlSchemaValidatePredefinedType( + nonNegativeIntegerType, facet->value, + &facet->val); + if (tmp != 0) { + /* error code */ + if (ctxt != NULL) { + xmlSchemaErrorContext(ctxt, NULL, + facet->node, NULL); + ctxt->error(ctxt->userData, + "Schemas: type %s facet value %s invalid\n", + name, facet->value); + } + ret = -1; + } + break; + } + case XML_SCHEMA_FACET_WHITESPACE: { + if (xmlStrEqual(facet->value, BAD_CAST"preserve")) { + facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; + } else if (xmlStrEqual(facet->value, + BAD_CAST"replace")) { + facet->whitespace = XML_SCHEMAS_FACET_REPLACE; + } else if (xmlStrEqual(facet->value, + BAD_CAST"collapse")) { + facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; + } else { + if (ctxt != NULL) { + xmlSchemaErrorContext(ctxt, NULL, + facet->node, NULL); + ctxt->error(ctxt->userData, + "Schemas: type %s whiteSpace value %s invalid\n", + name, facet->value); + } + ret = -1; + } + } + default: + break; + } + return(ret); +} + /** * xmlSchemaCheckDefaults: * @typeDecl: the schema type definition @@ -3719,118 +3860,13 @@ xmlSchemaCheckDefaults(xmlSchemaTypePtr typeDecl, xmlSchemaParserCtxtPtr ctxt, const xmlChar *name) { - static xmlSchemaTypePtr nonNegativeIntegerType = NULL; if (name == NULL) name = typeDecl->name; - if (nonNegativeIntegerType == NULL) { - nonNegativeIntegerType = xmlSchemaGetPredefinedType( - BAD_CAST "nonNegativeInteger", xmlSchemaNs); - } if (typeDecl->type == XML_SCHEMA_TYPE_RESTRICTION) { if (typeDecl->facets != NULL) { xmlSchemaFacetPtr facet = typeDecl->facets; while (facet != NULL) { - switch (facet->type) { - case XML_SCHEMA_FACET_MININCLUSIVE: - case XML_SCHEMA_FACET_MINEXCLUSIVE: - case XML_SCHEMA_FACET_MAXINCLUSIVE: - case XML_SCHEMA_FACET_MAXEXCLUSIVE: { - /* - * Okay we need to validate the value - * at that point. - */ - xmlSchemaValidCtxtPtr vctxt; - - vctxt = xmlSchemaNewValidCtxt(NULL); - if (vctxt == NULL) - break; - xmlSchemaValidateSimpleValue(vctxt, typeDecl, - facet->value); - facet->val = vctxt->value; - vctxt->value = NULL; - if (facet->val == NULL) { - /* error code */ - xmlSchemaErrorContext(ctxt, NULL, - facet->node, NULL); - ctxt->error(ctxt->userData, - "Schemas: type %s facet value %s invalid\n", - name, facet->value); - } - xmlSchemaFreeValidCtxt(vctxt); - break; - } - case XML_SCHEMA_FACET_ENUMERATION: { - /* - * Okay we need to validate the value - * at that point. - */ - xmlSchemaValidCtxtPtr vctxt; - int ret; - - vctxt = xmlSchemaNewValidCtxt(NULL); - if (vctxt == NULL) - break; - ret = xmlSchemaValidateSimpleValue(vctxt, typeDecl, - facet->value); - if (ret != 0) { - xmlSchemaErrorContext(ctxt, NULL, - facet->node, NULL); - ctxt->error(ctxt->userData, - "Schemas: type %s enumeration value %s invalid\n", - name, facet->value); - } - xmlSchemaFreeValidCtxt(vctxt); - break; - } - case XML_SCHEMA_FACET_PATTERN: - facet->regexp = xmlRegexpCompile(facet->value); - if (facet->regexp == NULL) { - /* error code */ - ctxt->error(ctxt->userData, - "Schemas: type %s facet regexp %s invalid\n", - name, facet->value); - } - break; - case XML_SCHEMA_FACET_TOTALDIGITS: - case XML_SCHEMA_FACET_FRACTIONDIGITS: - case XML_SCHEMA_FACET_LENGTH: - case XML_SCHEMA_FACET_MAXLENGTH: - case XML_SCHEMA_FACET_MINLENGTH: { - int ret; - - ret = xmlSchemaValidatePredefinedType( - nonNegativeIntegerType, facet->value, - &facet->val); - if (ret != 0) { - /* error code */ - xmlSchemaErrorContext(ctxt, NULL, - facet->node, NULL); - ctxt->error(ctxt->userData, - "Schemas: type %s facet value %s invalid\n", - name, facet->value); - } - break; - } - case XML_SCHEMA_FACET_WHITESPACE: { - if (xmlStrEqual(facet->value, BAD_CAST"preserve")) { - facet->whitespace = XML_SCHEMAS_FACET_PRESERVE; - } else if (xmlStrEqual(facet->value, - BAD_CAST"replace")) { - facet->whitespace = XML_SCHEMAS_FACET_REPLACE; - } else if (xmlStrEqual(facet->value, - BAD_CAST"collapse")) { - facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE; - } else { - xmlSchemaErrorContext(ctxt, NULL, - facet->node, NULL); - ctxt->error(ctxt->userData, - "Schemas: type %s whiteSpace value %s invalid\n", - name, facet->value); - } - } - default: - break; - } + xmlSchemaCheckFacet(facet, typeDecl, ctxt, name); facet = facet->next; } } diff --git a/xmlschemastypes.c b/xmlschemastypes.c index e19391f1..051af8df 100644 --- a/xmlschemastypes.c +++ b/xmlschemastypes.c @@ -42,7 +42,7 @@ typedef enum { XML_SCHEMAS_UNKNOWN = 0, XML_SCHEMAS_STRING, - XML_SCHEMAS_NMTOKEN, + XML_SCHEMAS_NORMSTRING, XML_SCHEMAS_DECIMAL, XML_SCHEMAS_TIME, XML_SCHEMAS_GDAY, @@ -56,9 +56,33 @@ typedef enum { XML_SCHEMAS_FLOAT, XML_SCHEMAS_DOUBLE, XML_SCHEMAS_BOOLEAN, + XML_SCHEMAS_TOKEN, + XML_SCHEMAS_LANGUAGE, + XML_SCHEMAS_NMTOKEN, + XML_SCHEMAS_NMTOKENS, + XML_SCHEMAS_NAME, + XML_SCHEMAS_QNAME, + XML_SCHEMAS_NCNAME, + XML_SCHEMAS_ID, + XML_SCHEMAS_IDREF, + XML_SCHEMAS_IDREFS, + XML_SCHEMAS_ENTITY, + XML_SCHEMAS_ENTITIES, + XML_SCHEMAS_NOTATION, + XML_SCHEMAS_ANYURI, + XML_SCHEMAS_INTEGER, + XML_SCHEMAS_NPINTEGER, + XML_SCHEMAS_NINTEGER, + XML_SCHEMAS_NNINTEGER, + XML_SCHEMAS_PINTEGER, XML_SCHEMAS_INT, - XML_SCHEMAS_, - XML_SCHEMAS_XXX + XML_SCHEMAS_UINT, + XML_SCHEMAS_LONG, + XML_SCHEMAS_ULONG, + XML_SCHEMAS_SHORT, + XML_SCHEMAS_USHORT, + XML_SCHEMAS_BYTE, + XML_SCHEMAS_UBYTE } xmlSchemaValType; unsigned long powten[10] = { @@ -131,12 +155,9 @@ static xmlSchemaTypePtr xmlSchemaTypeGDayDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeGMonthDayDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeGMonthDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeDurationDef = NULL; -static xmlSchemaTypePtr xmlSchemaTypeNmtoken = NULL; static xmlSchemaTypePtr xmlSchemaTypeFloatDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL; -static xmlSchemaTypePtr xmlSchemaTypeNameDef = NULL; -static xmlSchemaTypePtr xmlSchemaTypeQNameDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL; /* @@ -155,16 +176,27 @@ static xmlSchemaTypePtr xmlSchemaTypeUnsignedLongDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeUnsignedIntDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeUnsignedShortDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeUnsignedByteDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeNormStringDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeTokenDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeLanguageDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeNameDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeQNameDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeNCNameDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeIdDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeIdrefDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeIdrefsDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeNmtokenDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL; /* * xmlSchemaInitBasicType: * @name: the type name + * @type: the value type associated * * Initialize one default type */ static xmlSchemaTypePtr -xmlSchemaInitBasicType(const char *name) { +xmlSchemaInitBasicType(const char *name, xmlSchemaValType type) { xmlSchemaTypePtr ret; ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType)); @@ -176,6 +208,7 @@ xmlSchemaInitBasicType(const char *name) { memset(ret, 0, sizeof(xmlSchemaType)); ret->name = xmlStrdup((const xmlChar *)name); ret->type = XML_SCHEMA_TYPE_BASIC; + ret->flags = type; ret->contentType = XML_SCHEMA_CONTENT_BASIC; xmlHashAddEntry2(xmlSchemaTypesBank, ret->name, XML_SCHEMAS_NAMESPACE_NAME, ret); @@ -196,45 +229,93 @@ xmlSchemaInitTypes(void) { /* * primitive datatypes */ - xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string"); - xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType"); - xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType"); - xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal"); - xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date"); - xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime"); - xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time"); - xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear"); - xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth"); - xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth"); - xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay"); - xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay"); - xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration"); - xmlSchemaTypeNmtoken = xmlSchemaInitBasicType("NMTOKEN"); - xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float"); - xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double"); - xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType("boolean"); - xmlSchemaTypeNameDef = xmlSchemaInitBasicType("Name"); - xmlSchemaTypeQNameDef = xmlSchemaInitBasicType("QName"); - xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType("anyURI"); + xmlSchemaTypeStringDef = xmlSchemaInitBasicType("string", + XML_SCHEMAS_STRING); + xmlSchemaTypeAnyTypeDef = xmlSchemaInitBasicType("anyType", + XML_SCHEMAS_UNKNOWN); + xmlSchemaTypeAnySimpleTypeDef = xmlSchemaInitBasicType("anySimpleType", + XML_SCHEMAS_UNKNOWN); + xmlSchemaTypeDecimalDef = xmlSchemaInitBasicType("decimal", + XML_SCHEMAS_DECIMAL); + xmlSchemaTypeDateDef = xmlSchemaInitBasicType("date", + XML_SCHEMAS_DATE); + xmlSchemaTypeDatetimeDef = xmlSchemaInitBasicType("dateTime", + XML_SCHEMAS_DATETIME); + xmlSchemaTypeTimeDef = xmlSchemaInitBasicType("time", + XML_SCHEMAS_TIME); + xmlSchemaTypeGYearDef = xmlSchemaInitBasicType("gYear", + XML_SCHEMAS_GYEAR); + xmlSchemaTypeGYearMonthDef = xmlSchemaInitBasicType("gYearMonth", + XML_SCHEMAS_GYEARMONTH); + xmlSchemaTypeGMonthDef = xmlSchemaInitBasicType("gMonth", + XML_SCHEMAS_GMONTH); + xmlSchemaTypeGMonthDayDef = xmlSchemaInitBasicType("gMonthDay", + XML_SCHEMAS_GMONTHDAY); + xmlSchemaTypeGDayDef = xmlSchemaInitBasicType("gDay", + XML_SCHEMAS_GDAY); + xmlSchemaTypeDurationDef = xmlSchemaInitBasicType("duration", + XML_SCHEMAS_DURATION); + xmlSchemaTypeFloatDef = xmlSchemaInitBasicType("float", + XML_SCHEMAS_FLOAT); + xmlSchemaTypeDoubleDef = xmlSchemaInitBasicType("double", + XML_SCHEMAS_DOUBLE); + xmlSchemaTypeBooleanDef = xmlSchemaInitBasicType("boolean", + XML_SCHEMAS_BOOLEAN); + xmlSchemaTypeAnyURIDef = xmlSchemaInitBasicType("anyURI", + XML_SCHEMAS_ANYURI); /* * derived datatypes */ - xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType("integer");; - xmlSchemaTypeNonPositiveIntegerDef = xmlSchemaInitBasicType("nonPositiveInteger");; - xmlSchemaTypeNegativeIntegerDef = xmlSchemaInitBasicType("negativeInteger");; - xmlSchemaTypeLongDef = xmlSchemaInitBasicType("long");; - xmlSchemaTypeIntDef = xmlSchemaInitBasicType("int");; - xmlSchemaTypeShortDef = xmlSchemaInitBasicType("short");; - xmlSchemaTypeByteDef = xmlSchemaInitBasicType("byte");; - xmlSchemaTypeNonNegativeIntegerDef = xmlSchemaInitBasicType("nonNegativeInteger"); - xmlSchemaTypeUnsignedLongDef = xmlSchemaInitBasicType("unsignedLong");; - xmlSchemaTypeUnsignedIntDef = xmlSchemaInitBasicType("unsignedInt");; - xmlSchemaTypeUnsignedShortDef = xmlSchemaInitBasicType("insignedShort");; - xmlSchemaTypeUnsignedByteDef = xmlSchemaInitBasicType("unsignedByte");; - xmlSchemaTypePositiveIntegerDef = xmlSchemaInitBasicType("positiveInteger"); - xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType("NCName"); + xmlSchemaTypeIntegerDef = xmlSchemaInitBasicType("integer", + XML_SCHEMAS_INTEGER);; + xmlSchemaTypeNonPositiveIntegerDef = xmlSchemaInitBasicType("nonPositiveInteger", + XML_SCHEMAS_NPINTEGER);; + xmlSchemaTypeNegativeIntegerDef = xmlSchemaInitBasicType("negativeInteger", + XML_SCHEMAS_NINTEGER);; + xmlSchemaTypeLongDef = xmlSchemaInitBasicType("long", + XML_SCHEMAS_LONG);; + xmlSchemaTypeIntDef = xmlSchemaInitBasicType("int", + XML_SCHEMAS_INT);; + xmlSchemaTypeShortDef = xmlSchemaInitBasicType("short", + XML_SCHEMAS_SHORT);; + xmlSchemaTypeByteDef = xmlSchemaInitBasicType("byte", + XML_SCHEMAS_BYTE);; + xmlSchemaTypeNonNegativeIntegerDef = xmlSchemaInitBasicType("nonNegativeInteger", + XML_SCHEMAS_NNINTEGER); + xmlSchemaTypeUnsignedLongDef = xmlSchemaInitBasicType("unsignedLong", + XML_SCHEMAS_ULONG);; + xmlSchemaTypeUnsignedIntDef = xmlSchemaInitBasicType("unsignedInt", + XML_SCHEMAS_UINT);; + xmlSchemaTypeUnsignedShortDef = xmlSchemaInitBasicType("insignedShort", + XML_SCHEMAS_USHORT);; + xmlSchemaTypeUnsignedByteDef = xmlSchemaInitBasicType("unsignedByte", + XML_SCHEMAS_UBYTE);; + xmlSchemaTypePositiveIntegerDef = xmlSchemaInitBasicType("positiveInteger", + XML_SCHEMAS_PINTEGER); + xmlSchemaTypeNormStringDef = xmlSchemaInitBasicType("normalizedString", + XML_SCHEMAS_NORMSTRING); + xmlSchemaTypeTokenDef = xmlSchemaInitBasicType("token", + XML_SCHEMAS_TOKEN); + xmlSchemaTypeLanguageDef = xmlSchemaInitBasicType("language", + XML_SCHEMAS_LANGUAGE); + xmlSchemaTypeIdDef = xmlSchemaInitBasicType("ID", + XML_SCHEMAS_ID); + xmlSchemaTypeIdrefDef = xmlSchemaInitBasicType("IDREF", + XML_SCHEMAS_IDREF); + xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType("IDREFS", + XML_SCHEMAS_IDREFS); + xmlSchemaTypeNameDef = xmlSchemaInitBasicType("Name", + XML_SCHEMAS_NAME); + xmlSchemaTypeQNameDef = xmlSchemaInitBasicType("QName", + XML_SCHEMAS_QNAME); + xmlSchemaTypeNCNameDef = xmlSchemaInitBasicType("NCName", + XML_SCHEMAS_NCNAME); + xmlSchemaTypeNmtokenDef = xmlSchemaInitBasicType("NMTOKEN", + XML_SCHEMAS_NMTOKEN); + xmlSchemaTypeNmtokensDef = xmlSchemaInitBasicType("NMTOKENS", + XML_SCHEMAS_NMTOKENS); xmlSchemaTypesInitialized = 1; } @@ -1006,7 +1087,7 @@ xmlSchemaValidatePredefinedType(xmlSchemaTypePtr type, const xmlChar *value, return(0); } else if (type == xmlSchemaTypeAnySimpleTypeDef) { return(0); - } else if (type == xmlSchemaTypeNmtoken) { + } else if (type == xmlSchemaTypeNmtokenDef) { if (xmlValidateNmtokenValue(value)) return(0); return(1); @@ -2036,14 +2117,14 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED, if (ret == 1) return(0); if (ret == 0) { - TODO /* error code */ + /* TODO error code */ return(1); } return(ret); case XML_SCHEMA_FACET_MAXEXCLUSIVE: ret = xmlSchemaCompareValues(val, facet->val); if (ret == -2) { - TODO /* error code */ + /* TODO error code */ return(-1); } if (ret == -1) @@ -2053,7 +2134,7 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED, case XML_SCHEMA_FACET_MAXINCLUSIVE: ret = xmlSchemaCompareValues(val, facet->val); if (ret == -2) { - TODO /* error code */ + /* TODO error code */ return(-1); } if ((ret == -1) || (ret == 0)) @@ -2063,7 +2144,7 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED, case XML_SCHEMA_FACET_MINEXCLUSIVE: ret = xmlSchemaCompareValues(val, facet->val); if (ret == -2) { - TODO /* error code */ + /* TODO error code */ return(-1); } if (ret == 1) @@ -2073,7 +2154,7 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED, case XML_SCHEMA_FACET_MININCLUSIVE: ret = xmlSchemaCompareValues(val, facet->val); if (ret == -2) { - TODO /* error code */ + /* TODO error code */ return(-1); } if ((ret == 1) || (ret == 0)) @@ -2081,28 +2162,51 @@ xmlSchemaValidateFacet(xmlSchemaTypePtr base ATTRIBUTE_UNUSED, /* error code */ return(1); case XML_SCHEMA_FACET_WHITESPACE: - TODO /* whitespaces */ + /* TODO whitespaces */ return(0); - case XML_SCHEMA_FACET_MAXLENGTH: - if ((facet->val != NULL) && - (facet->val->type == XML_SCHEMAS_DECIMAL) && - (facet->val->value.decimal.frac == 0)) { - unsigned int len; - - if (facet->val->value.decimal.sign == 1) - return(1); - len = xmlUTF8Strlen(value); - if (len > facet->val->value.decimal.base) - return(1); - return(0); - } - TODO /* error code */ - return(1); case XML_SCHEMA_FACET_ENUMERATION: if ((facet->value != NULL) && (xmlStrEqual(facet->value, value))) return(0); return(1); + case XML_SCHEMA_FACET_LENGTH: + case XML_SCHEMA_FACET_MAXLENGTH: + case XML_SCHEMA_FACET_MINLENGTH: { + unsigned int len = 0; + + if ((facet->val == NULL) || + (facet->val->type != XML_SCHEMAS_DECIMAL) || + (facet->val->value.decimal.frac != 0)) { + return(-1); + } + switch (base->flags) { + 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_NCNAME: + case XML_SCHEMAS_ID: + case XML_SCHEMAS_IDREF: { + len = xmlUTF8Strlen(value); + break; + } + default: + TODO + } + if (facet->type == XML_SCHEMA_FACET_LENGTH) { + if (len != facet->val->value.decimal.base) + return(1); + } else if (facet->type == XML_SCHEMA_FACET_MINLENGTH) { + if (len < facet->val->value.decimal.base) + return(1); + } else { + if (len > facet->val->value.decimal.base) + return(1); + } + break; + } default: TODO }