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/relaxng.c b/relaxng.c
index 2391f72..a104d8e 100644
--- a/relaxng.c
+++ b/relaxng.c
@@ -653,6 +653,8 @@
* Type library hooks *
* *
************************************************************************/
+static xmlChar *xmlRelaxNGNormalize(xmlRelaxNGValidCtxtPtr ctxt,
+ const xmlChar *str);
/**
* xmlRelaxNGSchemaTypeHave:
@@ -767,8 +769,31 @@
const xmlChar *type ATTRIBUTE_UNUSED,
const xmlChar *value1 ATTRIBUTE_UNUSED,
const xmlChar *value2 ATTRIBUTE_UNUSED) {
- TODO
- return(1);
+ int ret = -1;
+
+ if (xmlStrEqual(type, BAD_CAST "string")) {
+ ret = xmlStrEqual(value1, value2);
+ } else if (xmlStrEqual(type, BAD_CAST "token")) {
+ if (!xmlStrEqual(value1, value2)) {
+ xmlChar *nval, *nvalue;
+
+ /*
+ * TODO: trivial optimizations are possible by
+ * computing at compile-time
+ */
+ nval = xmlRelaxNGNormalize(NULL, value1);
+ nvalue = xmlRelaxNGNormalize(NULL, value2);
+
+ if ((nval == NULL) || (nvalue == NULL) ||
+ (!xmlStrEqual(nval, nvalue)))
+ ret = -1;
+ if (nval != NULL)
+ xmlFree(nval);
+ if (nvalue != NULL)
+ xmlFree(nvalue);
+ }
+ }
+ return(ret);
}
static int xmlRelaxNGTypeInitialized = 0;
@@ -2656,8 +2681,13 @@
ret = (xmlChar *) xmlMalloc((len + 1) * sizeof(xmlChar));
if (ret == NULL) {
- VALID_CTXT();
- VALID_ERROR("xmlRelaxNGNormalize: out of memory\n");
+ if (ctxt != NULL) {
+ VALID_CTXT();
+ VALID_ERROR("xmlRelaxNGNormalize: out of memory\n");
+ } else {
+ xmlGenericError(xmlGenericErrorContext,
+ "xmlRelaxNGNormalize: out of memory\n");
+ }
return(NULL);
}
p = ret;
@@ -2756,7 +2786,24 @@
case XML_RELAXNG_VALUE: {
if (!xmlStrEqual(value, define->value)) {
if (define->name != NULL) {
- TODO /* value validation w.r.t. the type */
+ xmlRelaxNGTypeLibraryPtr lib;
+
+ lib = (xmlRelaxNGTypeLibraryPtr) define->data;
+ if ((lib != NULL) && (lib->comp != NULL))
+ ret = lib->comp(lib->data, define->name, value,
+ define->value);
+ else
+ ret = -1;
+ if (ret < 0) {
+ VALID_CTXT();
+ VALID_ERROR("Internal: failed to compare type %s\n",
+ define->name);
+ return(-1);
+ } else if (ret == 1) {
+ ret = 0;
+ } else {
+ ret = -1;
+ }
} else {
xmlChar *nval, *nvalue;
@@ -2767,7 +2814,8 @@
nval = xmlRelaxNGNormalize(ctxt, define->value);
nvalue = xmlRelaxNGNormalize(ctxt, value);
- if (!xmlStrEqual(nval, nvalue))
+ if ((nval == NULL) || (nvalue == NULL) ||
+ (!xmlStrEqual(nval, nvalue)))
ret = -1;
if (nval != NULL)
xmlFree(nval);
@@ -3036,7 +3084,7 @@
for (i = 0;i < state->nbAttrs;i++) {
if (state->attrs[i] != NULL) {
VALID_CTXT();
- VALID_ERROR("Extra attribute %s for element %s\n",
+ VALID_ERROR("Invalid attribute %s for element %s\n",
state->attrs[i]->name, node->name);
ret = -1;
}
@@ -3169,7 +3217,37 @@
xmlFree(content);
break;
}
- case XML_RELAXNG_VALUE:
+ case XML_RELAXNG_VALUE: {
+ xmlChar *content;
+ xmlChar *oldvalue;
+
+ content = xmlNodeGetContent(node);
+ oldvalue = ctxt->state->value;
+ ctxt->state->value = content;
+ ret = xmlRelaxNGValidateValue(ctxt, define);
+ ctxt->state->value = oldvalue;
+ if (ret == -1) {
+ VALID_CTXT();
+ VALID_ERROR("internal error validating %s\n", define->name);
+ } else if (ret == 0) {
+ ctxt->state->seq = node->next;
+ }
+ /*
+ * TODO cover the problems with
+ * <p>12<!-- comment -->34</p>
+ * TODO detect full element coverage at compilation time.
+ */
+ if ((node != NULL) && (node->next != NULL)) {
+ VALID_CTXT();
+ VALID_ERROR("The data does not cover the full element %s\n",
+ node->parent->name);
+ ret = -1;
+ }
+ if (content != NULL)
+ xmlFree(content);
+ break;
+ }
+
TODO
break;
}