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
diff --git a/ChangeLog b/ChangeLog
index dae25b8..2ffc24d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Tue Mar 18 17:50:31 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+ * 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 <daniel@veillard.com>
* relaxng.c: fixed error msg cleanup deallocation
diff --git a/check-relaxng-test-suite.py b/check-relaxng-test-suite.py
index 6f65264..2e378f4 100755
--- a/check-relaxng-test-suite.py
+++ b/check-relaxng-test-suite.py
@@ -10,6 +10,7 @@
# Memory debug specific
libxml2.debugMemory(1)
debug = 0
+verbose = 0
#
# the testsuite description
@@ -336,7 +337,7 @@
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 ffe944a..b22d1aa 100755
--- a/check-xsddata-test-suite.py
+++ b/check-xsddata-test-suite.py
@@ -10,12 +10,13 @@
# 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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_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 @@
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 d176f69..0c1b41e 100644
--- a/test/relaxng/testsuite.xml
+++ b/test/relaxng/testsuite.xml
@@ -1377,6 +1377,14 @@
</valid>
<valid>
<top>
+ <xref link=" id1 "/>
+ <ref id=" id1 "/>
+ <xref link="id1 "/>
+ <xref link=" id1"/>
+</top>
+</valid>
+<valid>
+<top>
<ref id="id1"/>
<xref link="id1"/>
</top>
@@ -1388,5 +1396,139 @@
</top>
</invalid>
</testCase>
+<testCase>
+<correct>
+<element name="top" xmlns="http://relaxng.org/ns/structure/1.0"
+ datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <zeroOrMore>
+ <choice>
+ <element name="ref">
+ <attribute name="id">
+ <data type="ID"/>
+ </attribute>
+ <text/>
+ </element>
+ <element name="xref">
+ <attribute name="link">
+ <data type="IDREFS"/>
+ </attribute>
+ <text/>
+ </element>
+ </choice>
+ </zeroOrMore>
+</element>
+</correct>
+<valid>
+<top>
+</top>
+</valid>
+<invalid>
+<top>
+ <xref link="id1"/>
+</top>
+</invalid>
+<valid>
+<top>
+ <ref id="id1"/>
+</top>
+</valid>
+<valid>
+<top>
+ <xref link="id1"/>
+ <ref id="id1"/>
+</top>
+</valid>
+<valid>
+<top>
+ <xref link="id1 id1"/>
+ <ref id="id1"/>
+</top>
+</valid>
+<valid>
+<top>
+ <ref id="id1"/>
+ <xref link="id1"/>
+</top>
+</valid>
+<valid>
+<top>
+ <ref id="id2"/>
+ <xref link="id1 id2"/>
+ <ref id="id1"/>
+</top>
+</valid>
+<valid>
+<top>
+ <ref id="id2"/>
+ <xref link=" id2 id1 id2 "/>
+ <ref id="id1"/>
+</top>
+</valid>
+<invalid>
+<top>
+ <ref id="id2"/>
+ <xref link="id1 id2"/>
+</top>
+</invalid>
+<invalid>
+<top>
+ <xref link="id1 id2"/>
+ <ref id="id1"/>
+</top>
+</invalid>
+<invalid>
+<top>
+ <ref id="id1"/>
+ <ref id="id1"/>
+</top>
+</invalid>
+</testCase>
+</testSuite>
+<testSuite>
+<documentation>Test of ENTITY/ENTITIES</documentation>
+<testCase>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="doc" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="ENTITY"/>
+</element>
+</correct>
+<invalid>
+<doc></doc>
+</invalid>
+<invalid>
+<doc>foo</doc>
+</invalid>
+<valid dtd=" <!DOCTYPE doc [ <!ENTITY foo SYSTEM 'whatever' NDATA jpeg> ]>">
+<doc>foo</doc>
+</valid>
+<valid dtd=" <!DOCTYPE doc [ <!ENTITY foo SYSTEM 'whatever' NDATA jpeg> ]>">
+<doc> foo </doc>
+</valid>
+<invalid dtd=" <!DOCTYPE doc [ <!ENTITY foo SYSTEM 'whatever' NDATA jpeg> ]>">
+<doc>foo bar</doc>
+</invalid>
+</testCase>
+<testCase>
+<correct>
+<element xmlns="http://relaxng.org/ns/structure/1.0" name="doc" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+ <data type="ENTITIES"/>
+</element>
+</correct>
+<invalid>
+<doc></doc>
+</invalid>
+<invalid>
+<doc>foo</doc>
+</invalid>
+<valid dtd=" <!DOCTYPE doc [ <!ENTITY foo SYSTEM 'whatever' NDATA jpeg> <!ENTITY bar SYSTEM 'whatever' NDATA jpeg> ]>">
+<doc> foo bar </doc>
+</valid>
+<valid dtd=" <!DOCTYPE doc [ <!ENTITY foo SYSTEM 'whatever' NDATA jpeg> <!ENTITY bar SYSTEM 'whatever' NDATA jpeg> ]>">
+<doc> foo bar foo</doc>
+</valid>
+<invalid dtd=" <!DOCTYPE doc [ <!ENTITY foo SYSTEM 'whatever' NDATA jpeg>]>">
+<doc>foo bar</doc>
+</invalid>
+</testCase>
</testSuite>
</testSuite>
diff --git a/tree.c b/tree.c
index f6b928c..2186d51 100644
--- a/tree.c
+++ b/tree.c
@@ -6994,7 +6994,7 @@
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 0508699..254e88d 100644
--- a/xmlschemastypes.c
+++ b/xmlschemastypes.c
@@ -185,6 +185,8 @@
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 @@
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 @@
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 @@
* 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 @@
/*
* 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 @@
TODO
}
xmlFree(val);
- return(0);
+ return(nb_values);
}
endval = cur;
cur = val;
@@ -1120,7 +1149,9 @@
if (ret != NULL) {
TODO
}
- return(tmp);
+ if (tmp == 0)
+ return(nb_values);
+ return(-1);
}
/**
@@ -1156,9 +1187,17 @@
} 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 @@
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 @@
(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 @@
}
}
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);