1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-30 22:43:14 +03:00

determinism is debugged, new DTD checking code now works but

* valid.c: determinism is debugged, new DTD checking code now works
  but xmlFAComputesDeterminism takes far too much CPU and the whole
  set usues too much memory to be really usable as-is
Daniel
This commit is contained in:
Daniel Veillard
2002-09-18 16:29:02 +00:00
parent 0f04f8ed61
commit 5acfd6b58a
2 changed files with 46 additions and 20 deletions

View File

@ -1,3 +1,9 @@
Wed Sep 18 18:27:26 CEST 2002 Daniel Veillard <daniel@veillard.com>
* valid.c: determinism is debugged, new DTD checking code now works
but xmlFAComputesDeterminism takes far too much CPU and the whole
set usues too much memory to be really usable as-is
Wed Sep 18 00:54:30 CEST 2002 Daniel Veillard <daniel@veillard.com> Wed Sep 18 00:54:30 CEST 2002 Daniel Veillard <daniel@veillard.com>
* tree.c: fixed another stupid bug in xmlGetNodePath() * tree.c: fixed another stupid bug in xmlGetNodePath()

60
valid.c
View File

@ -26,6 +26,7 @@
#include <libxml/globals.h> #include <libxml/globals.h>
/* #define DEBUG_VALID_ALGO */ /* #define DEBUG_VALID_ALGO */
/* #define DEBUG_REGEXP_ALGO */
#define TODO \ #define TODO \
xmlGenericError(xmlGenericErrorContext, \ xmlGenericError(xmlGenericErrorContext, \
@ -435,7 +436,7 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
break; break;
} }
case XML_ELEMENT_CONTENT_SEQ: { case XML_ELEMENT_CONTENT_SEQ: {
xmlAutomataStatePtr oldstate; xmlAutomataStatePtr oldstate, oldend;
xmlElementContentOccur ocur; xmlElementContentOccur ocur;
/* /*
@ -449,6 +450,8 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
} while ((content->type == XML_ELEMENT_CONTENT_SEQ) && } while ((content->type == XML_ELEMENT_CONTENT_SEQ) &&
(content->ocur == XML_ELEMENT_CONTENT_ONCE)); (content->ocur == XML_ELEMENT_CONTENT_ONCE));
xmlValidBuildAContentModel(content, ctxt, name); xmlValidBuildAContentModel(content, ctxt, name);
oldend = ctxt->state;
ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
switch (ocur) { switch (ocur) {
case XML_ELEMENT_CONTENT_ONCE: case XML_ELEMENT_CONTENT_ONCE:
break; break;
@ -457,49 +460,54 @@ xmlValidBuildAContentModel(xmlElementContentPtr content,
break; break;
case XML_ELEMENT_CONTENT_MULT: case XML_ELEMENT_CONTENT_MULT:
xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state); xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate); xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
break; break;
case XML_ELEMENT_CONTENT_PLUS: case XML_ELEMENT_CONTENT_PLUS:
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldstate); xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
break; break;
} }
break; break;
} }
case XML_ELEMENT_CONTENT_OR: { case XML_ELEMENT_CONTENT_OR: {
xmlAutomataStatePtr start, end; xmlAutomataStatePtr oldstate, oldend;
xmlElementContentOccur ocur; xmlElementContentOccur ocur;
start = ctxt->state;
end = xmlAutomataNewState(ctxt->am);
ocur = content->ocur; ocur = content->ocur;
if ((ocur == XML_ELEMENT_CONTENT_PLUS) ||
(ocur == XML_ELEMENT_CONTENT_MULT)) {
ctxt->state = xmlAutomataNewEpsilon(ctxt->am,
ctxt->state, NULL);
}
oldstate = ctxt->state;
oldend = xmlAutomataNewState(ctxt->am);
/* /*
* iterate over the subtypes and remerge the end with an * iterate over the subtypes and remerge the end with an
* epsilon transition * epsilon transition
*/ */
do { do {
ctxt->state = start; ctxt->state = oldstate;
xmlValidBuildAContentModel(content->c1, ctxt, name); xmlValidBuildAContentModel(content->c1, ctxt, name);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
content = content->c2; content = content->c2;
} while ((content->type == XML_ELEMENT_CONTENT_OR) && } while ((content->type == XML_ELEMENT_CONTENT_OR) &&
(content->ocur == XML_ELEMENT_CONTENT_ONCE)); (content->ocur == XML_ELEMENT_CONTENT_ONCE));
ctxt->state = start; ctxt->state = oldstate;
xmlValidBuildAContentModel(content, ctxt, name); xmlValidBuildAContentModel(content, ctxt, name);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, end); xmlAutomataNewEpsilon(ctxt->am, ctxt->state, oldend);
ctxt->state = end; ctxt->state = xmlAutomataNewEpsilon(ctxt->am, oldend, NULL);
switch (ocur) { switch (ocur) {
case XML_ELEMENT_CONTENT_ONCE: case XML_ELEMENT_CONTENT_ONCE:
break; break;
case XML_ELEMENT_CONTENT_OPT: case XML_ELEMENT_CONTENT_OPT:
xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
break; break;
case XML_ELEMENT_CONTENT_MULT: case XML_ELEMENT_CONTENT_MULT:
xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state); xmlAutomataNewEpsilon(ctxt->am, oldstate, ctxt->state);
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, start); xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
break; break;
case XML_ELEMENT_CONTENT_PLUS: case XML_ELEMENT_CONTENT_PLUS:
xmlAutomataNewEpsilon(ctxt->am, ctxt->state, start); xmlAutomataNewEpsilon(ctxt->am, oldend, oldstate);
break; break;
} }
break; break;
@ -546,8 +554,14 @@ xmlValidBuildContentModel(xmlValidCtxtPtr ctxt, xmlElementPtr elem) {
xmlAutomataSetFinalState(ctxt->am, ctxt->state); xmlAutomataSetFinalState(ctxt->am, ctxt->state);
elem->contModel = xmlAutomataCompile(ctxt->am); elem->contModel = xmlAutomataCompile(ctxt->am);
if (!xmlAutomataIsDeterminist(ctxt->am)) { if (!xmlAutomataIsDeterminist(ctxt->am)) {
VERROR(ctxt->userData, "Content model of %s is not determinist:\n", char expr[5000];
elem->name); expr[0] = 0;
xmlSnprintfElementContent(expr, 5000, elem->content, 1);
VERROR(ctxt->userData, "Content model of %s is not determinist: %s\n",
elem->name, expr);
#ifdef DEBUG_REGEXP_ALGO
xmlRegexpPrint(stderr, elem->contModel);
#endif
ctxt->valid = 0; ctxt->valid = 0;
} }
ctxt->state = NULL; ctxt->state = NULL;
@ -873,7 +887,9 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
return; return;
} }
strcat(buf, " , "); strcat(buf, " , ");
if (content->c2->type == XML_ELEMENT_CONTENT_OR) if (((content->c2->type == XML_ELEMENT_CONTENT_OR) ||
(content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) &&
(content->c2->type != XML_ELEMENT_CONTENT_ELEMENT))
xmlSnprintfElementContent(buf, size, content->c2, 1); xmlSnprintfElementContent(buf, size, content->c2, 1);
else else
xmlSnprintfElementContent(buf, size, content->c2, 0); xmlSnprintfElementContent(buf, size, content->c2, 0);
@ -891,7 +907,9 @@ xmlSnprintfElementContent(char *buf, int size, xmlElementContentPtr content, int
return; return;
} }
strcat(buf, " | "); strcat(buf, " | ");
if (content->c2->type == XML_ELEMENT_CONTENT_SEQ) if (((content->c2->type == XML_ELEMENT_CONTENT_SEQ) ||
(content->c2->ocur != XML_ELEMENT_CONTENT_ONCE)) &&
(content->c2->type != XML_ELEMENT_CONTENT_ELEMENT))
xmlSnprintfElementContent(buf, size, content->c2, 1); xmlSnprintfElementContent(buf, size, content->c2, 1);
else else
xmlSnprintfElementContent(buf, size, content->c2, 0); xmlSnprintfElementContent(buf, size, content->c2, 0);
@ -3546,9 +3564,11 @@ xmlValidateElementDecl(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
if (elem == NULL) return(1); if (elem == NULL) return(1);
#if 0
#ifdef LIBXML_REGEXP_ENABLED #ifdef LIBXML_REGEXP_ENABLED
/* Build the regexp associated to the content model */ /* Build the regexp associated to the content model */
ret = xmlValidBuildContentModel(ctxt, elem); ret = xmlValidBuildContentModel(ctxt, elem);
#endif
#endif #endif
/* No Duplicate Types */ /* No Duplicate Types */
@ -4298,7 +4318,7 @@ xmlSnprintfElements(char *buf, int size, xmlNodePtr node, int glob) {
static int static int
xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child, xmlValidateElementContent(xmlValidCtxtPtr ctxt, xmlNodePtr child,
xmlElementPtr elemDecl, int warn, xmlNodePtr parent) { xmlElementPtr elemDecl, int warn, xmlNodePtr parent) {
int ret; int ret = 1;
xmlNodePtr repl = NULL, last = NULL, cur, tmp; xmlNodePtr repl = NULL, last = NULL, cur, tmp;
xmlElementContentPtr cont; xmlElementContentPtr cont;
const xmlChar *name; const xmlChar *name;