more testing on the Relax-NG front, cleaning up the regression tests
* check-relaxng-test-suite.py relaxng.c: more testing on the
Relax-NG front, cleaning up the regression tests failures
current state and I forgot support for "mixed":
found 373 test schemas: 280 success 93 failures
found 529 test instances: 401 success 68 failures
* tree.c include/libxml/tree.h xmlschemastypes.c: finished and
moved the Name, NCName and QName validation routine in tree.c
* uri.c: fixed handling of URI ending up with #, i.e. having
an empty fragment ID.
* result/relaxng/*: updated the results
Daniel
diff --git a/tree.c b/tree.c
index 4937d2c..8bb0625 100644
--- a/tree.c
+++ b/tree.c
@@ -125,6 +125,246 @@
/************************************************************************
* *
+ * Check Name, NCName and QName strings *
+ * *
+ ************************************************************************/
+
+#define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
+
+/**
+ * xmlValidateNCName:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of NCName
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ * and -1 in case of internal or API error.
+ */
+int
+xmlValidateNCName(const xmlChar *value, int space) {
+ const xmlChar *cur = value;
+ int c,l;
+
+ /*
+ * First quick algorithm for ASCII range
+ */
+ if (space)
+ while (IS_BLANK(*cur)) cur++;
+ if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
+ (*cur == '_'))
+ cur++;
+ else
+ goto try_complex;
+ while (((*cur >= 'a') && (*cur <= 'z')) ||
+ ((*cur >= 'A') && (*cur <= 'Z')) ||
+ ((*cur >= '0') && (*cur <= '9')) ||
+ (*cur == '_') || (*cur == '-') || (*cur == '.'))
+ cur++;
+ if (space)
+ while (IS_BLANK(*cur)) cur++;
+ if (*cur == 0)
+ return(0);
+
+try_complex:
+ /*
+ * Second check for chars outside the ASCII range
+ */
+ cur = value;
+ c = CUR_SCHAR(cur, l);
+ if (space) {
+ while (IS_BLANK(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if ((!xmlIsLetter(c)) && (c != '_'))
+ return(1);
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') ||
+ (c == '-') || (c == '_') || xmlIsCombining(c) ||
+ xmlIsExtender(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ if (space) {
+ while (IS_BLANK(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if (c != 0)
+ return(1);
+
+ return(0);
+}
+
+/**
+ * xmlValidateQName:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of QName
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ * and -1 in case of internal or API error.
+ */
+int
+xmlValidateQName(const xmlChar *value, int space) {
+ const xmlChar *cur = value;
+ int c,l;
+
+ /*
+ * First quick algorithm for ASCII range
+ */
+ if (space)
+ while (IS_BLANK(*cur)) cur++;
+ if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
+ (*cur == '_'))
+ cur++;
+ else
+ goto try_complex;
+ while (((*cur >= 'a') && (*cur <= 'z')) ||
+ ((*cur >= 'A') && (*cur <= 'Z')) ||
+ ((*cur >= '0') && (*cur <= '9')) ||
+ (*cur == '_') || (*cur == '-') || (*cur == '.'))
+ cur++;
+ if (*cur == ':') {
+ cur++;
+ if (((*cur >= 'a') && (*cur <= 'z')) ||
+ ((*cur >= 'A') && (*cur <= 'Z')) ||
+ (*cur == '_'))
+ cur++;
+ else
+ goto try_complex;
+ while (((*cur >= 'a') && (*cur <= 'z')) ||
+ ((*cur >= 'A') && (*cur <= 'Z')) ||
+ ((*cur >= '0') && (*cur <= '9')) ||
+ (*cur == '_') || (*cur == '-') || (*cur == '.'))
+ cur++;
+ }
+ if (space)
+ while (IS_BLANK(*cur)) cur++;
+ if (*cur == 0)
+ return(0);
+
+try_complex:
+ /*
+ * Second check for chars outside the ASCII range
+ */
+ cur = value;
+ c = CUR_SCHAR(cur, l);
+ if (space) {
+ while (IS_BLANK(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if ((!xmlIsLetter(c)) && (c != '_'))
+ return(1);
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') ||
+ (c == '-') || (c == '_') || xmlIsCombining(c) ||
+ xmlIsExtender(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ if (c == ':') {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ if ((!xmlIsLetter(c)) && (c != '_'))
+ return(1);
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') ||
+ (c == '-') || (c == '_') || xmlIsCombining(c) ||
+ xmlIsExtender(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if (space) {
+ while (IS_BLANK(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if (c != 0)
+ return(1);
+ return(0);
+}
+
+/**
+ * xmlValidateName:
+ * @value: the value to check
+ * @space: allow spaces in front and end of the string
+ *
+ * Check that a value conforms to the lexical space of Name
+ *
+ * Returns 0 if this validates, a positive error code number otherwise
+ * and -1 in case of internal or API error.
+ */
+int
+xmlValidateName(const xmlChar *value, int space) {
+ const xmlChar *cur = value;
+ int c,l;
+
+ /*
+ * First quick algorithm for ASCII range
+ */
+ if (space)
+ while (IS_BLANK(*cur)) cur++;
+ if (((*cur >= 'a') && (*cur <= 'z')) || ((*cur >= 'A') && (*cur <= 'Z')) ||
+ (*cur == '_') || (*cur == ':'))
+ cur++;
+ else
+ goto try_complex;
+ while (((*cur >= 'a') && (*cur <= 'z')) ||
+ ((*cur >= 'A') && (*cur <= 'Z')) ||
+ ((*cur >= '0') && (*cur <= '9')) ||
+ (*cur == '_') || (*cur == '-') || (*cur == '.') || (*cur == ':'))
+ cur++;
+ if (space)
+ while (IS_BLANK(*cur)) cur++;
+ if (*cur == 0)
+ return(0);
+
+try_complex:
+ /*
+ * Second check for chars outside the ASCII range
+ */
+ cur = value;
+ c = CUR_SCHAR(cur, l);
+ if (space) {
+ while (IS_BLANK(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if ((!xmlIsLetter(c)) && (c != '_') && (c != ':'))
+ return(1);
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ while (xmlIsLetter(c) || xmlIsDigit(c) || (c == '.') || (c == ':') ||
+ (c == '-') || (c == '_') || xmlIsCombining(c) || xmlIsExtender(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ if (space) {
+ while (IS_BLANK(c)) {
+ cur += l;
+ c = CUR_SCHAR(cur, l);
+ }
+ }
+ if (c != 0)
+ return(1);
+ return(0);
+}
+
+/************************************************************************
+ * *
* Allocation and deallocation of basic structures *
* *
************************************************************************/