From a1a9d0410000cc69874e53e438b250037d3e14cd Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Tue, 18 Mar 2003 16:53:17 +0000 Subject: [PATCH] removed a warning more cleanup, added ENTITY and ENTITIES support * tree.c: removed a warning * xmlschemastypes.c: more cleanup, added ENTITY and ENTITIES support * check-relaxng-test-suite.py check-xsddata-test-suite.py: cleanup/improvements of the regression tests batch * test/relaxng/testsuite.xml: augmented libxml2 own testsuite Daniel --- ChangeLog | 9 +++ check-relaxng-test-suite.py | 3 +- check-xsddata-test-suite.py | 93 +++++++++++++++++------ test/relaxng/testsuite.xml | 142 ++++++++++++++++++++++++++++++++++++ tree.c | 2 +- xmlschemastypes.c | 116 +++++++++++++++++++++++++++-- 6 files changed, 333 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index dae25b8f..2ffc24da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Tue Mar 18 17:50:31 CET 2003 Daniel Veillard + + * tree.c: removed a warning + * xmlschemastypes.c: more cleanup, added ENTITY and ENTITIES + support + * check-relaxng-test-suite.py check-xsddata-test-suite.py: + cleanup/improvements of the regression tests batch + * test/relaxng/testsuite.xml: augmented libxml2 own testsuite + Tue Mar 18 12:36:22 CET 2003 Daniel Veillard * relaxng.c: fixed error msg cleanup deallocation diff --git a/check-relaxng-test-suite.py b/check-relaxng-test-suite.py index 6f65264a..2e378f45 100755 --- a/check-relaxng-test-suite.py +++ b/check-relaxng-test-suite.py @@ -10,6 +10,7 @@ import libxml2 # Memory debug specific libxml2.debugMemory(1) debug = 0 +verbose = 0 # # the testsuite description @@ -336,7 +337,7 @@ def handle_testSuite(node, level = 0): handle_testSuite(test, level + 1) - if level >= 1 and sections != []: + if verbose and level >= 1 and sections != []: msg = "" for section in sections: msg = msg + section.content + " " diff --git a/check-xsddata-test-suite.py b/check-xsddata-test-suite.py index ffe944aa..b22d1aa9 100755 --- a/check-xsddata-test-suite.py +++ b/check-xsddata-test-suite.py @@ -10,12 +10,13 @@ import libxml2 # Memory debug specific libxml2.debugMemory(1) debug = 0 +verbose = 1 # # the testsuite description # CONF="test/xsdtest/xsdtestsuite.xml" -LOG="check-xsdtype-test-suite.log" +LOG="check-xsddata-test-suite.log" log = open(LOG, "w") nb_schemas_tests = 0 @@ -56,13 +57,16 @@ def handle_valid(node, schema): global nb_instances_success global nb_instances_failed - instance = "" + instance = node.prop("dtd") + if instance == None: + instance = "" child = node.children while child != None: if child.type != 'text': instance = instance + child.serialize() child = child.next + mem = libxml2.debugMemory(1); try: doc = libxml2.parseDoc(instance) except: @@ -75,11 +79,21 @@ def handle_valid(node, schema): nb_instances_failed = nb_instances_failed + 1 return + if debug: + print "instance line %d" % (node.lineNo()) + try: ctxt = schema.relaxNGNewValidCtxt() ret = doc.relaxNGValidateDoc(ctxt) + del ctxt except: ret = -1 + + doc.freeDoc() + if mem != libxml2.debugMemory(1): + print "validating instance %d line %d leaks" % ( + nb_instances_tests, node.lineNo()) + if ret != 0: log.write("\nFailed to validate correct instance:\n-----\n") log.write(instance) @@ -87,7 +101,6 @@ def handle_valid(node, schema): nb_instances_failed = nb_instances_failed + 1 else: nb_instances_success = nb_instances_success + 1 - doc.freeDoc() # # handle an invalid instance @@ -97,13 +110,17 @@ def handle_invalid(node, schema): global nb_instances_success global nb_instances_failed - instance = "" + instance = node.prop("dtd") + if instance == None: + instance = "" child = node.children while child != None: if child.type != 'text': instance = instance + child.serialize() child = child.next + mem = libxml2.debugMemory(1); + try: doc = libxml2.parseDoc(instance) except: @@ -115,11 +132,22 @@ def handle_invalid(node, schema): log.write("\n-----\n") return + if debug: + print "instance line %d" % (node.lineNo()) + try: ctxt = schema.relaxNGNewValidCtxt() ret = doc.relaxNGValidateDoc(ctxt) + del ctxt + except: ret = -1 + + doc.freeDoc() + if mem != libxml2.debugMemory(1): + print "validating instance %d line %d leaks" % ( + nb_instances_tests, node.lineNo()) + if ret == 0: log.write("\nFailed to detect validation problem in instance:\n-----\n") log.write(instance) @@ -127,7 +155,6 @@ def handle_invalid(node, schema): nb_instances_failed = nb_instances_failed + 1 else: nb_instances_success = nb_instances_success + 1 - doc.freeDoc() # # handle an incorrect test @@ -293,12 +320,13 @@ def handle_testCase(node): def handle_testSuite(node, level = 0): global nb_schemas_tests, nb_schemas_success, nb_schemas_failed global nb_instances_tests, nb_instances_success, nb_instances_failed - old_schemas_tests = nb_schemas_tests - old_schemas_success = nb_schemas_success - old_schemas_failed = nb_schemas_failed - old_instances_tests = nb_instances_tests - old_instances_success = nb_instances_success - old_instances_failed = nb_instances_failed + if verbose and level >= 0: + old_schemas_tests = nb_schemas_tests + old_schemas_success = nb_schemas_success + old_schemas_failed = nb_schemas_failed + old_instances_tests = nb_instances_tests + old_instances_success = nb_instances_success + old_instances_failed = nb_instances_failed docs = node.xpathEval('documentation') authors = node.xpathEval('author') @@ -311,27 +339,48 @@ def handle_testSuite(node, level = 0): for author in authors: msg = msg + author.content + " " print msg + sections = node.xpathEval('section') + if sections != [] and level <= 0: + msg = "" + for section in sections: + msg = msg + section.content + " " + print "Tests for section %s" % (msg) for test in node.xpathEval('testCase'): handle_testCase(test) for test in node.xpathEval('testSuite'): handle_testSuite(test, level + 1) - print "Result of tests for %s" % (node.xpathEval('string(documentation)')) - if nb_schemas_tests != old_schemas_tests: - print "found %d test schemas: %d success %d failures" % ( - nb_schemas_tests - old_schemas_tests, - nb_schemas_success - old_schemas_success, - nb_schemas_failed - old_schemas_failed) - if nb_instances_tests != old_instances_tests: - print "found %d test instances: %d success %d failures" % ( - nb_instances_tests - old_instances_tests, - nb_instances_success - old_instances_success, - nb_instances_failed - old_instances_failed) + + if verbose and level >= 0 and sections != []: + msg = "" + for section in sections: + msg = msg + section.content + " " + print "Result of tests for section %s" % (msg) + if nb_schemas_tests != old_schemas_tests: + print "found %d test schemas: %d success %d failures" % ( + nb_schemas_tests - old_schemas_tests, + nb_schemas_success - old_schemas_success, + nb_schemas_failed - old_schemas_failed) + if nb_instances_tests != old_instances_tests: + print "found %d test instances: %d success %d failures" % ( + nb_instances_tests - old_instances_tests, + nb_instances_success - old_instances_success, + nb_instances_failed - old_instances_failed) # # Parse the conf file # libxml2.substituteEntitiesDefault(1); testsuite = libxml2.parseFile(CONF) + +# +# Error and warnng callbacks +# +def callback(ctx, str): + global log + log.write("%s%s" % (ctx, str)) + +libxml2.registerErrorHandler(callback, "") + libxml2.setEntityLoader(resolver) root = testsuite.getRootElement() if root.name != 'testSuite': diff --git a/test/relaxng/testsuite.xml b/test/relaxng/testsuite.xml index d176f697..0c1b41e7 100644 --- a/test/relaxng/testsuite.xml +++ b/test/relaxng/testsuite.xml @@ -1376,6 +1376,14 @@ + + + + + + + + @@ -1388,5 +1396,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Test of ENTITY/ENTITIES + + + + + + + + + + +foo + + +foo + + + foo + + +foo bar + + + + + + + + + + + + +foo + + + foo bar + + + foo bar foo + + +foo bar + + diff --git a/tree.c b/tree.c index f6b928cc..2186d514 100644 --- a/tree.c +++ b/tree.c @@ -6994,7 +6994,7 @@ xmlNodeDumpOutputInternal(xmlOutputBufferPtr buf, xmlDocPtr doc, return; } if (cur->type == XML_ATTRIBUTE_NODE) { - xmlAttrDumpOutput(buf,doc,cur,encoding); + xmlAttrDumpOutput(buf,doc, (xmlAttrPtr) cur,encoding); return; } if (cur->type == XML_NAMESPACE_DECL) { diff --git a/xmlschemastypes.c b/xmlschemastypes.c index 05086993..254e88de 100644 --- a/xmlschemastypes.c +++ b/xmlschemastypes.c @@ -185,6 +185,8 @@ static xmlSchemaTypePtr xmlSchemaTypeNCNameDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeIdDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeIdrefDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeIdrefsDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeEntityDef = NULL; +static xmlSchemaTypePtr xmlSchemaTypeEntitiesDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeNmtokenDef = NULL; static xmlSchemaTypePtr xmlSchemaTypeNmtokensDef = NULL; @@ -306,6 +308,10 @@ xmlSchemaInitTypes(void) { XML_SCHEMAS_IDREF); xmlSchemaTypeIdrefsDef = xmlSchemaInitBasicType("IDREFS", XML_SCHEMAS_IDREFS); + xmlSchemaTypeEntityDef = xmlSchemaInitBasicType("ENTITY", + XML_SCHEMAS_ENTITY); + xmlSchemaTypeEntitiesDef = xmlSchemaInitBasicType("ENTITIES", + XML_SCHEMAS_ENTITIES); xmlSchemaTypeNameDef = xmlSchemaInitBasicType("Name", XML_SCHEMAS_NAME); xmlSchemaTypeQNameDef = xmlSchemaInitBasicType("QName", @@ -1055,6 +1061,29 @@ error: return 1; } +/** + * xmlSchemaStrip: + * @value: a value + * + * Removes the leading and ending spaces of a string + * + * Returns the new string or NULL if no change was required. + */ +static xmlChar * +xmlSchemaStrip(const xmlChar *value) { + const xmlChar *start = value, *end, *f; + + if (value == NULL) return(NULL); + while ((*start != 0) && (IS_BLANK(*start))) start++; + end = start; + while (*end != 0) end++; + f = end; + end--; + while ((end > start) && (IS_BLANK(*end))) end--; + end++; + if ((start == value) && (f == end)) return(NULL); + return(xmlStrndup(start, end - start)); +} /** * xmlSchemaValAtomicListNode: @@ -1066,8 +1095,8 @@ error: * Check that a value conforms to the lexical space of the predefined * list type. if true a value is computed and returned in @ret. * - * Returns 0 if this validates, a positive error code number otherwise - * and -1 in case of internal or API error. + * Returns the number of items if this validates, a negative error code + * number otherwise */ static int xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value, @@ -1087,7 +1116,7 @@ xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value, /* * Split the list */ - while (IS_BLANK(*cur)) cur++; + while (IS_BLANK(*cur)) *cur++ = 0; while (*cur != 0) { if (IS_BLANK(*cur)) { *cur = 0; @@ -1104,7 +1133,7 @@ xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value, TODO } xmlFree(val); - return(0); + return(nb_values); } endval = cur; cur = val; @@ -1120,7 +1149,9 @@ xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value, if (ret != NULL) { TODO } - return(tmp); + if (tmp == 0) + return(nb_values); + return(-1); } /** @@ -1156,9 +1187,17 @@ xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value, } else if (type == xmlSchemaTypeAnySimpleTypeDef) { return(0); } else if (type == xmlSchemaTypeNmtokenDef) { - if (xmlValidateNmtokenValue(value)) + if (xmlValidateNMToken(value, 1) == 0) return(0); return(1); + } else if (type == xmlSchemaTypeNmtokensDef) { + ret = xmlSchemaValAtomicListNode(xmlSchemaTypeNmtokenDef, + value, val, node); + if (ret >= 0) + ret = 0; + else + ret = 1; + return(ret); } else if (type == xmlSchemaTypeDecimalDef) { const xmlChar *cur = value, *tmp; int frac = 0, len, neg = 0; @@ -1487,14 +1526,24 @@ xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value, if ((ret == 0) && (node != NULL) && (node->type == XML_ATTRIBUTE_NODE)) { xmlAttrPtr attr = (xmlAttrPtr) node; + xmlChar *strip; - xmlAddRef(NULL, node->doc, value, attr); + strip = xmlSchemaStrip(value); + if (strip != NULL) { + xmlAddRef(NULL, node->doc, strip, attr); + xmlFree(strip); + } else + xmlAddRef(NULL, node->doc, value, attr); attr->atype = XML_ATTRIBUTE_IDREF; } return(ret); } else if (type == xmlSchemaTypeIdrefsDef) { ret = xmlSchemaValAtomicListNode(xmlSchemaTypeIdrefDef, value, val, node); + if (ret < 0) + ret = 2; + else + ret = 0; if ((ret == 0) && (node != NULL) && (node->type == XML_ATTRIBUTE_NODE)) { xmlAttrPtr attr = (xmlAttrPtr) node; @@ -1511,8 +1560,14 @@ xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value, (node->type == XML_ATTRIBUTE_NODE)) { xmlAttrPtr attr = (xmlAttrPtr) node; xmlIDPtr res; + xmlChar *strip; - res = xmlAddID(NULL, node->doc, value, attr); + strip = xmlSchemaStrip(value); + if (strip != NULL) { + res = xmlAddID(NULL, node->doc, strip, attr); + xmlFree(strip); + } else + res = xmlAddID(NULL, node->doc, value, attr); if (res == NULL) { ret = 2; } else { @@ -1520,6 +1575,51 @@ xmlSchemaValPredefTypeNode(xmlSchemaTypePtr type, const xmlChar *value, } } return(ret); + } else if (type == xmlSchemaTypeEntitiesDef) { + if ((node == NULL) || (node->doc == NULL)) + return(3); + ret = xmlSchemaValAtomicListNode(xmlSchemaTypeEntityDef, + value, val, node); + if (ret <= 0) + ret = 1; + else + ret = 0; + if ((ret == 0) && (node != NULL) && + (node->type == XML_ATTRIBUTE_NODE)) { + xmlAttrPtr attr = (xmlAttrPtr) node; + + attr->atype = XML_ATTRIBUTE_ENTITIES; + } + return(ret); + } else if (type == xmlSchemaTypeEntityDef) { + xmlChar *strip; + ret = xmlValidateNCName(value, 1); + if ((node == NULL) || (node->doc == NULL)) + ret = 3; + if (ret == 0) { + xmlEntityPtr ent; + + strip = xmlSchemaStrip(value); + if (strip != NULL) { + ent = xmlGetDocEntity(node->doc, strip); + xmlFree(strip); + } else { + ent = xmlGetDocEntity(node->doc, value); + } + if ((ent == NULL) || + (ent->etype != XML_EXTERNAL_GENERAL_UNPARSED_ENTITY)) + ret = 4; + } + if ((ret == 0) && (val != NULL)) { + TODO; + } + if ((ret == 0) && (node != NULL) && + (node->type == XML_ATTRIBUTE_NODE)) { + xmlAttrPtr attr = (xmlAttrPtr) node; + + attr->atype = XML_ATTRIBUTE_ENTITY; + } + return(ret); } else { TODO return(0);