patched a bug in parsing production 1 and 2 of xmlschemas regexp that

* xmlregexp.c: patched a bug in parsing production 1 and 2 of
  xmlschemas regexp that William pointed out while working on
  #134120
* test/regexp/branch result/regexp/branch: added a specific
  regression test
Daniel
This commit is contained in:
Daniel Veillard 2004-03-31 15:50:43 +00:00
parent f580674366
commit 2cbf596c7f
4 changed files with 73 additions and 34 deletions

View File

@ -1,3 +1,11 @@
Wed Mar 31 17:47:28 CEST 2004 Daniel Veillard <daniel@veillard.com>
* xmlregexp.c: patched a bug in parsing production 1 and 2 of
xmlschemas regexp that William pointed out while working on
#134120
* test/regexp/branch result/regexp/branch: added a specific
regression test
Wed Mar 31 09:50:32 HKT 2004 William Brack <wbrack@mmm.com.hk>
* Makefile.am: added PYTHONPATH to python tests for Schemas

14
result/regexp/branch Normal file
View File

@ -0,0 +1,14 @@
Regexp: a|b(d|e(g|h|i)|f)|c
a: Ok
c: Ok
bd: Ok
bf: Ok
beg: Ok
beh: Ok
bei: Ok
b: Fail
be: Fail
bi: Fail
f: Fail
ab: Fail
ac: Fail

14
test/regexp/branch Normal file
View File

@ -0,0 +1,14 @@
=>a|b(d|e(g|h|i)|f)|c
a
c
bd
bf
beg
beh
bei
b
be
bi
f
ab
ac

View File

@ -1214,14 +1214,15 @@ xmlRegStateAddTrans(xmlRegParserCtxtPtr ctxt, xmlRegStatePtr state,
#ifdef DEBUG_REGEXP_GRAPH
printf("Add trans from %d to %d ", state->no, target->no);
if (count == REGEXP_ALL_COUNTER)
printf("all transition");
printf("all transition\n");
else if (count >= 0)
printf("count based %d", count);
printf("count based %d\n", count);
else if (counter >= 0)
printf("counted %d", counter);
printf("counted %d\n", counter);
else if (atom == NULL)
printf("epsilon transition");
printf("\n");
printf("epsilon transition\n");
else if (atom != NULL)
xmlRegPrintAtom(stdout, atom);
#endif
state->trans[state->nbTrans].atom = atom;
@ -3862,50 +3863,33 @@ xmlFAParsePiece(xmlRegParserCtxtPtr ctxt) {
/**
* xmlFAParseBranch:
* @ctxt: a regexp parser context
* @first: is taht the first
*
* [2] branch ::= piece*
8
*/
static int
xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, int first) {
xmlFAParseBranch(xmlRegParserCtxtPtr ctxt) {
xmlRegStatePtr previous;
xmlRegAtomPtr prevatom = NULL;
int ret;
previous = ctxt->state;
ret = xmlFAParsePiece(ctxt);
if (ret != 0) {
if (first) {
if (xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom) < 0)
return(-1);
previous = ctxt->state;
} else {
prevatom = ctxt->atom;
}
if (xmlFAGenerateTransitions(ctxt, previous, NULL, ctxt->atom) < 0)
return(-1);
previous = ctxt->state;
ctxt->atom = NULL;
}
while ((ret != 0) && (ctxt->error == 0)) {
ret = xmlFAParsePiece(ctxt);
if (ret != 0) {
if (first) {
if (xmlFAGenerateTransitions(ctxt, previous, NULL,
ctxt->atom) < 0)
if (xmlFAGenerateTransitions(ctxt, previous, NULL,
ctxt->atom) < 0)
return(-1);
} else {
if (xmlFAGenerateTransitions(ctxt, previous, NULL,
prevatom) < 0)
return(-1);
prevatom = ctxt->atom;
}
previous = ctxt->state;
ctxt->atom = NULL;
}
}
if (!first) {
if (xmlFAGenerateTransitions(ctxt, previous, ctxt->end, prevatom) < 0)
return(-1);
}
return(0);
}
@ -3918,12 +3902,21 @@ xmlFAParseBranch(xmlRegParserCtxtPtr ctxt, int first) {
*/
static void
xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
xmlRegStatePtr start, end, oldend;
xmlRegStatePtr start, end, oldend, oldstart;
oldend = ctxt->end;
oldstart = ctxt->state;
/* if not top start should have been generated by an epsilon trans */
start = ctxt->state;
xmlFAParseBranch(ctxt, (ctxt->end == NULL));
ctxt->end = NULL;
xmlFAParseBranch(ctxt);
if (top) {
#ifdef DEBUG_REGEXP_GRAPH
printf("State %d is final\n", ctxt->state->no);
#endif
ctxt->state->type = XML_REGEXP_FINAL_STATE;
}
if (CUR != '|') {
ctxt->end = ctxt->state;
return;
@ -3932,11 +3925,21 @@ xmlFAParseRegExp(xmlRegParserCtxtPtr ctxt, int top) {
while ((CUR == '|') && (ctxt->error == 0)) {
NEXT;
ctxt->state = start;
ctxt->end = end;
xmlFAParseBranch(ctxt, 0);
ctxt->end = NULL;
xmlFAParseBranch(ctxt);
if (top) {
ctxt->state->type = XML_REGEXP_FINAL_STATE;
#ifdef DEBUG_REGEXP_GRAPH
printf("State %d is final\n", ctxt->state->no);
#endif
} else {
xmlFAGenerateEpsilonTransition(ctxt, ctxt->state, end);
}
}
if (!top) {
ctxt->state = end;
ctxt->end = end;
}
if (!top)
ctxt->end = oldend;
}
/************************************************************************