more work on Relax-NG augmented/updated the regression tests Daniel
* relaxng.c: more work on Relax-NG
* test/relaxng/* result/relaxng/*: augmented/updated the
regression tests
Daniel
diff --git a/ChangeLog b/ChangeLog
index d53f386..bbe98d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sun Jan 26 01:49:58 CET 2003 Daniel Veillard <daniel@veillard.com>
+
+ * relaxng.c: more work on Relax-NG
+ * test/relaxng/* result/relaxng/*: augmented/updated the
+ regression tests
+
Sat Jan 25 18:59:54 CET 2003 Daniel Veillard <daniel@veillard.com>
* README: updated the policy on private mail answers
diff --git a/relaxng.c b/relaxng.c
index 61af8c0..2391f72 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -98,6 +98,7 @@
xmlNodePtr node; /* the node in the source */
xmlChar *name; /* the element local name if present */
xmlChar *ns; /* the namespace local name if present */
+ xmlChar *value; /* value when available */
void *data; /* data lib or specific pointer */
xmlRelaxNGDefinePtr content;/* the expected content */
xmlRelaxNGDefinePtr next; /* list within grouping sequences */
@@ -438,6 +439,8 @@
xmlFree(define->name);
if (define->ns != NULL)
xmlFree(define->ns);
+ if (define->value != NULL)
+ xmlFree(define->value);
if (define->attrs != NULL)
xmlRelaxNGFreeDefineList(define->attrs);
if ((define->content != NULL) &&
@@ -968,6 +971,88 @@
}
/**
+ * xmlRelaxNGParseValue:
+ * @ctxt: a Relax-NG parser context
+ * @node: the data node.
+ *
+ * parse the content of a RelaxNG value node.
+ *
+ * Returns the definition pointer or NULL in case of error
+ */
+static xmlRelaxNGDefinePtr
+xmlRelaxNGParseValue(xmlRelaxNGParserCtxtPtr ctxt, xmlNodePtr node) {
+ xmlRelaxNGDefinePtr def = NULL;
+ xmlRelaxNGTypeLibraryPtr lib;
+ xmlChar *type;
+ xmlChar *library;
+ int tmp;
+
+ def = xmlRelaxNGNewDefine(ctxt, node);
+ if (def == NULL)
+ return(NULL);
+ def->type = XML_RELAXNG_VALUE;
+
+ type = xmlGetProp(node, BAD_CAST "type");
+ if (type != NULL) {
+ library = xmlRelaxNGGetDataTypeLibrary(ctxt, node);
+ if (library == NULL)
+ library = xmlStrdup(BAD_CAST "http://relaxng.org/ns/structure/1.0");
+
+ def->name = type;
+ def->ns = library;
+
+ lib = (xmlRelaxNGTypeLibraryPtr)
+ xmlHashLookup(xmlRelaxNGRegisteredTypes, library);
+ if (lib == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Use of unregistered type library '%s'\n",
+ library);
+ ctxt->nbErrors++;
+ def->data = NULL;
+ } else {
+ def->data = lib;
+ if (lib->have == NULL) {
+ ctxt->error(ctxt->userData,
+ "Internal error with type library '%s': no 'have'\n",
+ library);
+ ctxt->nbErrors++;
+ } else {
+ tmp = lib->have(lib->data, def->name);
+ if (tmp != 1) {
+ ctxt->error(ctxt->userData,
+ "Error type '%s' is not exported by type library '%s'\n",
+ def->name, library);
+ ctxt->nbErrors++;
+ }
+ }
+ }
+ }
+ if (node->children == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Element <value> has no content\n");
+ ctxt->nbErrors++;
+ } else if ((node->children->type != XML_TEXT_NODE) ||
+ (node->children->next != NULL)) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Expecting a single text value for <value>content\n");
+ ctxt->nbErrors++;
+ } else {
+ def->value = xmlNodeGetContent(node);
+ if (def->value == NULL) {
+ if (ctxt->error != NULL)
+ ctxt->error(ctxt->userData,
+ "Element <value> has no content\n");
+ ctxt->nbErrors++;
+ }
+ }
+ /* TODO check ahead of time that the value is okay per the type */
+ return(def);
+}
+
+/**
* xmlRelaxNGParseData:
* @ctxt: a Relax-NG parser context
* @node: the data node.
@@ -1234,6 +1319,8 @@
} else if (IS_RELAXNG(node, "define")) {
xmlRelaxNGParseDefine(ctxt, node);
def = NULL;
+ } else if (IS_RELAXNG(node, "value")) {
+ def = xmlRelaxNGParseValue(ctxt, node);
} else {
TODO
}
@@ -2546,6 +2633,49 @@
}
/**
+ * xmlRelaxNGNormalize:
+ * @ctxt: a schema validation context
+ * @str: the string to normalize
+ *
+ * Implements the normalizeWhiteSpace( s ) function from
+ * section 6.2.9 of the spec
+ *
+ * Returns the new string or NULL in case of error.
+ */
+static xmlChar *
+xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt, const xmlChar *str) {
+ xmlChar *ret, *p;
+ const xmlChar *tmp;
+ int len;
+
+ if (str == NULL)
+ return(NULL);
+ tmp = str;
+ while (*tmp != 0) tmp++;
+ len = tmp - str;
+
+ ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
+ if (ret == NULL) {
+ VALID_CTXT();
+ VALID_ERROR("xmlRelaxNGNormalize: out of memory\n");
+ return(NULL);
+ }
+ p = ret;
+ while (IS_BLANK(*str)) str++;
+ while (*str != 0) {
+ if (IS_BLANK(*str)) {
+ while (IS_BLANK(*str)) str++;
+ if (*str == 0)
+ break;
+ *p++ = ' ';
+ } else
+ *p++ = *str++;
+ }
+ *p = 0;
+ return(ret);
+}
+
+/**
* xmlRelaxNGValidateDatatype:
* @ctxt: a Relax-NG validation context
* @value: the string value
@@ -2596,7 +2726,7 @@
static int
xmlRelaxNGValidateValue(xmlRelaxNGValidCtxtPtr ctxt,
xmlRelaxNGDefinePtr define) {
- int ret = 0;
+ int ret = 0, oldflags;
xmlChar *value;
value = ctxt->state->value;
@@ -2607,6 +2737,46 @@
break;
case XML_RELAXNG_TEXT:
break;
+ case XML_RELAXNG_CHOICE: {
+ xmlRelaxNGDefinePtr list = define->content;
+
+ oldflags = ctxt->flags;
+ ctxt->flags |= FLAGS_IGNORABLE;
+
+ while (list != NULL) {
+ ret = xmlRelaxNGValidateValue(ctxt, list);
+ if (ret == 0) {
+ break;
+ }
+ list = list->next;
+ }
+ ctxt->flags = oldflags;
+ break;
+ }
+ case XML_RELAXNG_VALUE: {
+ if (!xmlStrEqual(value, define->value)) {
+ if (define->name != NULL) {
+ TODO /* value validation w.r.t. the type */
+ } else {
+ xmlChar *nval, *nvalue;
+
+ /*
+ * TODO: trivial optimizations are possible by
+ * computing at compile-time
+ */
+ nval = xmlRelaxNGNormalize(ctxt, define->value);
+ nvalue = xmlRelaxNGNormalize(ctxt, value);
+
+ if (!xmlStrEqual(nval, nvalue))
+ ret = -1;
+ if (nval != NULL)
+ xmlFree(nval);
+ if (nvalue != NULL)
+ xmlFree(nvalue);
+ }
+ }
+ break;
+ }
default:
TODO
ret = -1;
diff --git a/result/relaxng/tutor3_2_1.err b/result/relaxng/tutor3_2_1.err
index 8e23334..48ac0c4 100644
--- a/result/relaxng/tutor3_2_1.err
+++ b/result/relaxng/tutor3_2_1.err
@@ -1,3 +1,3 @@
-error detected at relaxng.c:2812
-error detected at relaxng.c:2860
+error detected at relaxng.c:2982
+error detected at relaxng.c:3030
xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/result/relaxng/tutor3_5_2.err b/result/relaxng/tutor3_5_2.err
index 909ad8b..9c72d17 100644
--- a/result/relaxng/tutor3_5_2.err
+++ b/result/relaxng/tutor3_5_2.err
@@ -1,5 +1,5 @@
xmlRelaxNGValidateAttribute(name): -1
xmlRelaxNGValidateDefinition(): validated email : 0
xmlRelaxNGValidateDefinition(): validated card : -1
-error detected at relaxng.c:2860
+error detected at relaxng.c:3030
xmlRelaxNGValidateDefinition(): validated addressBook : -1
diff --git a/result/relaxng/tutor5_1_1.err b/result/relaxng/tutor5_1_1.err
index d987a68..e9fa2d9 100644
--- a/result/relaxng/tutor5_1_1.err
+++ b/result/relaxng/tutor5_1_1.err
@@ -1,3 +1,3 @@
-Unimplemented block at relaxng.c:667
-Unimplemented block at relaxng.c:686
+Unimplemented block at relaxng.c:670
+Unimplemented block at relaxng.c:689
xmlRelaxNGValidateDefinition(): validated number : 0
diff --git a/result/relaxng/tutor5_2_1.err b/result/relaxng/tutor5_2_1.err
index 24865cc..ac9beb0 100644
--- a/result/relaxng/tutor5_2_1.err
+++ b/result/relaxng/tutor5_2_1.err
@@ -1,7 +1,7 @@
-Unimplemented block at relaxng.c:667
-Unimplemented block at relaxng.c:667
-Unimplemented block at relaxng.c:686
+Unimplemented block at relaxng.c:670
+Unimplemented block at relaxng.c:670
+Unimplemented block at relaxng.c:689
xmlRelaxNGValidateDefinition(): validated x : 0
-Unimplemented block at relaxng.c:686
+Unimplemented block at relaxng.c:689
xmlRelaxNGValidateDefinition(): validated y : 0
xmlRelaxNGValidateDefinition(): validated point : 0
diff --git a/result/relaxng/tutor5_3_1.err b/result/relaxng/tutor5_3_1.err
index 0ea4f9a..5f30338 100644
--- a/result/relaxng/tutor5_3_1.err
+++ b/result/relaxng/tutor5_3_1.err
@@ -1,3 +1,3 @@
-error detected at relaxng.c:2993
+error detected at relaxng.c:3163
xmlRelaxNGValidateDefinition(): validated note : 0
xmlRelaxNGValidateDefinition(): validated bad : -1
diff --git a/result/relaxng/tutor6_1_1 b/result/relaxng/tutor6_1_1
new file mode 100644
index 0000000..3c44662
--- /dev/null
+++ b/result/relaxng/tutor6_1_1
@@ -0,0 +1 @@
+./test/relaxng/tutor6_1_1.xml validates
diff --git a/result/relaxng/tutor6_1_1.err b/result/relaxng/tutor6_1_1.err
new file mode 100644
index 0000000..6e45621
--- /dev/null
+++ b/result/relaxng/tutor6_1_1.err
@@ -0,0 +1,4 @@
+xmlRelaxNGValidateAttribute(preferredFormat): 0
+xmlRelaxNGValidateAttribute(email): 0
+xmlRelaxNGValidateAttribute(name): 0
+xmlRelaxNGValidateDefinition(): validated card : 0
diff --git a/result/relaxng/tutor6_1_2 b/result/relaxng/tutor6_1_2
new file mode 100644
index 0000000..6c70fed
--- /dev/null
+++ b/result/relaxng/tutor6_1_2
@@ -0,0 +1 @@
+./test/relaxng/tutor6_1_2.xml validates
diff --git a/result/relaxng/tutor6_1_2.err b/result/relaxng/tutor6_1_2.err
new file mode 100644
index 0000000..6e45621
--- /dev/null
+++ b/result/relaxng/tutor6_1_2.err
@@ -0,0 +1,4 @@
+xmlRelaxNGValidateAttribute(preferredFormat): 0
+xmlRelaxNGValidateAttribute(email): 0
+xmlRelaxNGValidateAttribute(name): 0
+xmlRelaxNGValidateDefinition(): validated card : 0
diff --git a/result/relaxng/tutor6_1_3 b/result/relaxng/tutor6_1_3
new file mode 100644
index 0000000..2dea674
--- /dev/null
+++ b/result/relaxng/tutor6_1_3
@@ -0,0 +1,2 @@
+Extra attribute preferredFormat for element card
+./test/relaxng/tutor6_1_3.xml validation generated an internal error
diff --git a/result/relaxng/tutor6_1_3.err b/result/relaxng/tutor6_1_3.err
new file mode 100644
index 0000000..68f183f
--- /dev/null
+++ b/result/relaxng/tutor6_1_3.err
@@ -0,0 +1,5 @@
+xmlRelaxNGValidateAttribute(preferredFormat): -1
+xmlRelaxNGValidateAttribute(email): 0
+xmlRelaxNGValidateAttribute(name): 0
+error detected at relaxng.c:3038
+xmlRelaxNGValidateDefinition(): validated card : -1
diff --git a/test/relaxng/tutor6_1_1.xml b/test/relaxng/tutor6_1_1.xml
new file mode 100644
index 0000000..30460ae
--- /dev/null
+++ b/test/relaxng/tutor6_1_1.xml
@@ -0,0 +1 @@
+<card name="foo" email="bar" preferredFormat="text"/>
diff --git a/test/relaxng/tutor6_1_2.xml b/test/relaxng/tutor6_1_2.xml
new file mode 100644
index 0000000..bf3dfc2
--- /dev/null
+++ b/test/relaxng/tutor6_1_2.xml
@@ -0,0 +1 @@
+<card name="foo" email="bar" preferredFormat="html"/>
diff --git a/test/relaxng/tutor6_1_3.xml b/test/relaxng/tutor6_1_3.xml
new file mode 100644
index 0000000..6038d79
--- /dev/null
+++ b/test/relaxng/tutor6_1_3.xml
@@ -0,0 +1 @@
+<card name="foo" email="bar" preferredFormat="error"/>