From 285ebabb07c93921a60e4ab2dbefcbc0c49fb334 Mon Sep 17 00:00:00 2001 From: "Kasimier T. Buchcik" Date: Fri, 4 Mar 2005 18:04:59 +0000 Subject: [PATCH] Enabled IDC parsing and validation. Added xmlSchemaCopyValue to the API; * xmlschemas.c: Enabled IDC parsing and validation. * xmlschemastypes.c include/libxml/xmlschemastypes.h: Added xmlSchemaCopyValue to the API; this was done due to validation of default attributes against IDCs: since IDC keys consume the precomputed value, one needs a copy. * pattern.c: Enabled IDC support; this is currently done via calling xmlPatterncompile with a flag arg of 1. --- ChangeLog | 10 +++++ include/libxml/xmlschemastypes.h | 4 +- pattern.c | 71 ++++++++++++++++++++------------ xmlschemas.c | 20 +++++---- xmlschemastypes.c | 67 ++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 02c45c61..28faa520 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Fri Mar 4 18:57:44 CET 2005 Kasimier Buchcik + + * xmlschemas.c: Enabled IDC parsing and validation. + * xmlschemastypes.c include/libxml/xmlschemastypes.h: + Added xmlSchemaCopyValue to the API; this was done due to + validation of default attributes against IDCs: since IDC keys + consume the precomputed value, one needs a copy. + * pattern.c: Enabled IDC support; this is currently done + via calling xmlPatterncompile with a flag arg of 1. + Wed Mar 2 11:45:18 CET 2005 Daniel Veillard * Makefile.am doc/examples/Makefile.am python/tests/Makefile.am diff --git a/include/libxml/xmlschemastypes.h b/include/libxml/xmlschemastypes.h index 6a26716c..004386f6 100644 --- a/include/libxml/xmlschemastypes.h +++ b/include/libxml/xmlschemastypes.h @@ -108,7 +108,9 @@ XMLPUBFUN int XMLCALL xmlSchemaCompareValuesWhtsp (xmlSchemaValPtr x, xmlSchemaWhitespaceValueType xws, xmlSchemaValPtr y, - xmlSchemaWhitespaceValueType yws); + xmlSchemaWhitespaceValueType yws); +XMLPUBFUN xmlSchemaValPtr XMLCALL + xmlSchemaCopyValue (xmlSchemaValPtr val); #ifdef __cplusplus } diff --git a/pattern.c b/pattern.c index 22d5c31d..041039ef 100644 --- a/pattern.c +++ b/pattern.c @@ -38,7 +38,7 @@ #ifdef LIBXML_PATTERN_ENABLED /* #define DEBUG_STREAMING */ -/* #define SUPPORT_IDC */ +#define SUPPORT_IDC #define ERROR(a, b, c, d) #define ERROR5(a, b, c, d, e) @@ -48,6 +48,8 @@ #define XML_STREAM_STEP_ROOT 4 #define XML_STREAM_STEP_ATTR 8 +#define XML_PATTERN_NOTPATTERN 1 + typedef struct _xmlStreamStep xmlStreamStep; typedef xmlStreamStep *xmlStreamStepPtr; struct _xmlStreamStep { @@ -72,6 +74,7 @@ struct _xmlStreamCtxt { int maxState; /* allocated number of state */ int level; /* how deep are we ? */ int *states; /* the array of step indexes */ + int flags; /* validation options */ }; static void xmlFreeStreamComp(xmlStreamCompPtr comp); @@ -1660,23 +1663,34 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream, /* * Check the start only if this is a "desc" evaluation - * of if we are at the first level of evaluation. + * or if we are at the first level of evaluation. */ -#ifdef SUPPORT_IDC desc = comp->steps[0].flags & XML_STREAM_STEP_DESC; + if ( ((comp->steps[0].flags & XML_STREAM_STEP_ROOT) == 0) && + ( ((stream->flags & XML_PATTERN_NOTPATTERN) == 0) || + ( (desc || (stream->level == 1)) ) + ) + ) { + +/* +#ifdef SUPPORT_IDC + + if ((desc || (stream->level == 1)) && (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT))) { - /* + * * Workaround for missing "self::node()" on "@foo". - */ + * if (comp->steps[0].flags & XML_STREAM_STEP_ATTR) { xmlStreamCtxtAddState(stream, 0, stream->level); goto stream_next; } #else + if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) { #endif + */ match = 0; if (comp->dict) { if (comp->steps[0].name == NULL) { @@ -1685,21 +1699,21 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream, else match = (comp->steps[0].ns == ns); } else { -#ifdef SUPPORT_IDC - /* - * Workaround for missing "self::node() on "foo". - */ - if (!desc) { - xmlStreamCtxtAddState(stream, 0, stream->level); - goto stream_next; + if (stream->flags & XML_PATTERN_NOTPATTERN) { + /* + * Workaround for missing "self::node() on "foo". + */ + if (!desc) { + xmlStreamCtxtAddState(stream, 0, stream->level); + goto stream_next; + } else { + match = ((comp->steps[0].name == name) && + (comp->steps[0].ns == ns)); + } } else { match = ((comp->steps[0].name == name) && (comp->steps[0].ns == ns)); } -#else - match = ((comp->steps[0].name == name) && - (comp->steps[0].ns == ns)); -#endif } } else { if (comp->steps[0].name == NULL) { @@ -1708,21 +1722,21 @@ xmlStreamPushInternal(xmlStreamCtxtPtr stream, else match = xmlStrEqual(comp->steps[0].ns, ns); } else { -#ifdef SUPPORT_IDC - /* - * Workaround for missing "self::node() on "foo". - */ - if (!desc) { - xmlStreamCtxtAddState(stream, 0, stream->level); - goto stream_next; + if (stream->flags & XML_PATTERN_NOTPATTERN) { + /* + * Workaround for missing "self::node() on "foo". + */ + if (!desc) { + xmlStreamCtxtAddState(stream, 0, stream->level); + goto stream_next; + } else { + match = ((xmlStrEqual(comp->steps[0].name, name)) && + (xmlStrEqual(comp->steps[0].ns, ns))); + } } else { match = ((xmlStrEqual(comp->steps[0].name, name)) && (xmlStrEqual(comp->steps[0].ns, ns))); } -#else - match = ((xmlStrEqual(comp->steps[0].name, name)) && - (xmlStrEqual(comp->steps[0].ns, ns))); -#endif } } if (match) { @@ -1876,6 +1890,7 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, cur->next = ret->next; ret->next = cur; } + cur->flags = flags; ctxt->comp = cur; xmlCompilePathPattern(ctxt); @@ -1915,6 +1930,7 @@ xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, cur = cur->next; } } + return(ret); error: if (ctxt != NULL) xmlFreePatParserContext(ctxt); @@ -1978,6 +1994,7 @@ xmlPatternGetStreamCtxt(xmlPatternPtr comp) cur->next = ret->next; ret->next = cur; } + cur->flags = comp->flags; comp = comp->next; } return(ret); diff --git a/xmlschemas.c b/xmlschemas.c index cd49a1ee..83140532 100644 --- a/xmlschemas.c +++ b/xmlschemas.c @@ -54,11 +54,11 @@ #define ELEM_INFO_ENABLED 1 -/* #define IDC_ENABLED 1 */ +#define IDC_ENABLED 1 -/* #define IDC_VALUE_SUPPORT 1 */ +#define IDC_VALUE_SUPPORT 1 -/* #define IDC_XPATH_SUPPORT 1 */ +#define IDC_XPATH_SUPPORT 1 /* #define DEBUG_IDC 1 */ @@ -5984,10 +5984,10 @@ xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt, } if (isField) selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, - NULL, 0, nsArray); + NULL, 1, nsArray); else selector->xpathComp = (void *) xmlPatterncompile(selector->xpath, - NULL, 0, nsArray); + NULL, 1, nsArray); if (nsArray != NULL) xmlFree((xmlChar **) nsArray); @@ -19876,6 +19876,7 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche } /* * Init the attribute info. + * TODO: Hmm, maby a bit oversized this all. */ ctxt->attrInfo->flags = 0; ctxt->attrInfo->decl = (xmlSchemaTypePtr) attrDecl; @@ -19895,13 +19896,14 @@ xmlSchemaValidateAttributes(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem, xmlSche ctxt->attrInfo->value = NULL; } if (ret > 0) { + /* + * IDCs will consume the precomputed default value, + * so we need to clone it somehow. + */ ctxt->attrInfo->value = xmlSchemaCopyValue(attrDecl->defVal); /* TODO: error on NULL return. */ } - /* - * TODO URGENT: This will consume the precomputed default value, - * so we need to clone it somehow. - */ + if (xmlSchemaXPathProcessHistory(ctxt, ctxt->depth +1) == -1) goto fatal_exit; } diff --git a/xmlschemastypes.c b/xmlschemastypes.c index d9cc7c69..6ee6a1ea 100644 --- a/xmlschemastypes.c +++ b/xmlschemastypes.c @@ -3050,6 +3050,73 @@ xmlSchemaDupVal (xmlSchemaValPtr v) return ret; } +/** + * xmlSchemaCopyValue: + * @val: the precomputed value to be copied + * + * Copies the precomputed value. This duplicates any string within. + * + * Returns the copy or NULL if a copy for a data-type is not implemented. + */ +xmlSchemaValPtr +xmlSchemaCopyValue(xmlSchemaValPtr val) +{ + xmlSchemaValPtr ret; + + if (val == NULL) + return (NULL); + /* + * Copy the string values. + */ + switch (val->type) { + case XML_SCHEMAS_IDREFS: + case XML_SCHEMAS_ENTITIES: + case XML_SCHEMAS_NMTOKENS: + case XML_SCHEMAS_ANYTYPE: + case XML_SCHEMAS_ANYSIMPLETYPE: + return (NULL); + case XML_SCHEMAS_STRING: + case XML_SCHEMAS_NORMSTRING: + case XML_SCHEMAS_TOKEN: + case XML_SCHEMAS_LANGUAGE: + case XML_SCHEMAS_NAME: + case XML_SCHEMAS_NCNAME: + case XML_SCHEMAS_ID: + case XML_SCHEMAS_IDREF: + case XML_SCHEMAS_ENTITY: + case XML_SCHEMAS_NMTOKEN: + ret = xmlSchemaDupVal(val); + if (val->value.str != NULL) + ret->value.str = xmlStrdup(BAD_CAST val->value.str); + return (ret); + case XML_SCHEMAS_QNAME: + case XML_SCHEMAS_ANYURI: + case XML_SCHEMAS_NOTATION: + ret = xmlSchemaDupVal(val); + if (val->value.qname.name != NULL) + ret->value.qname.name = + xmlStrdup(BAD_CAST val->value.qname.name); + if (val->value.qname.uri != NULL) + ret->value.qname.uri = + xmlStrdup(BAD_CAST val->value.qname.uri); + return (ret); + case XML_SCHEMAS_HEXBINARY: + ret = xmlSchemaDupVal(val); + if (val->value.hex.str != NULL) + ret->value.hex.str = xmlStrdup(BAD_CAST val->value.hex.str); + return (ret); + case XML_SCHEMAS_BASE64BINARY: + ret = xmlSchemaDupVal(val); + if (val->value.base64.str != NULL) + ret->value.base64.str = + xmlStrdup(BAD_CAST val->value.base64.str); + return (ret); + default: + return (xmlSchemaDupVal(val)); + } + return (NULL); +} + /** * _xmlSchemaDateAdd: * @dt: an #xmlSchemaValPtr