1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-10-21 14:53:44 +03:00

first implementation for | support Daniel

* pattern.c: first implementation for | support
Daniel
This commit is contained in:
Daniel Veillard
2005-02-05 16:35:04 +00:00
parent 0996a162c9
commit f1f08cf8dc
2 changed files with 203 additions and 130 deletions

View File

@@ -1,3 +1,7 @@
Sat Feb 5 18:36:56 CET 2005 Daniel Veillard <daniel@veillard.com>
* pattern.c: first implementation for | support
Sat Feb 5 14:58:46 CET 2005 Daniel Veillard <daniel@veillard.com> Sat Feb 5 14:58:46 CET 2005 Daniel Veillard <daniel@veillard.com>
* pattern.c: fixed the namespaces support * pattern.c: fixed the namespaces support

329
pattern.c
View File

@@ -66,6 +66,7 @@ struct _xmlStreamComp {
}; };
struct _xmlStreamCtxt { struct _xmlStreamCtxt {
struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
xmlStreamCompPtr comp; /* the compiled stream */ xmlStreamCompPtr comp; /* the compiled stream */
int nbState; /* number of state in the automata */ int nbState; /* number of state in the automata */
int maxState; /* allocated number of state */ int maxState; /* allocated number of state */
@@ -118,7 +119,7 @@ struct _xmlStepOp {
struct _xmlPattern { struct _xmlPattern {
void *data; /* the associated template */ void *data; /* the associated template */
xmlDictPtr dict; /* the optional dictionnary */ xmlDictPtr dict; /* the optional dictionnary */
struct _xmlPattern *next; /* siblings */ struct _xmlPattern *next; /* next pattern if | is used */
const xmlChar *pattern; /* the pattern */ const xmlChar *pattern; /* the pattern */
int nbStep; int nbStep;
@@ -188,6 +189,8 @@ xmlFreePattern(xmlPatternPtr comp) {
if (comp == NULL) if (comp == NULL)
return; return;
if (comp->next != NULL)
xmlFreePattern(comp->next);
if (comp->stream != NULL) if (comp->stream != NULL)
xmlFreeStreamComp(comp->stream); xmlFreeStreamComp(comp->stream);
if (comp->pattern != NULL) if (comp->pattern != NULL)
@@ -1362,132 +1365,132 @@ xmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
int int
xmlStreamPush(xmlStreamCtxtPtr stream, xmlStreamPush(xmlStreamCtxtPtr stream,
const xmlChar *name, const xmlChar *ns) { const xmlChar *name, const xmlChar *ns) {
int ret = 0, tmp, i, m, match, step, desc, final; int ret = 0, err = 0, tmp, i, m, match, step, desc, final;
xmlStreamCompPtr comp; xmlStreamCompPtr comp;
if ((stream == NULL) || (stream->nbState < 0)) if ((stream == NULL) || (stream->nbState < 0))
return(-1); return(-1);
comp = stream->comp;
if ((name == NULL) && (ns == NULL)) {
stream->nbState = 0;
stream->level = 0;
if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
tmp = xmlStreamCtxtAddState(stream, 0, 0);
if (tmp < 0)
return(-1);
if (comp->steps[tmp].flags & XML_STREAM_STEP_FINAL)
return(1);
}
return(0);
}
/*
* Check evolution of existing states
*/
m = stream->nbState;
for (i = 0;i < m;i++) {
match = 0;
step = stream->states[2 * i];
/* dead states */
if (step < 0) continue;
/* skip new states just added */
if (stream->states[(2 * i) + 1] > stream->level) continue;
/* skip continuations */
desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
if ((stream->states[(2 * i) + 1] < stream->level) && (!desc))continue;
/* discard old states */ while (stream != NULL) {
/* something needed about old level discarded */ comp = stream->comp;
if ((name == NULL) && (ns == NULL)) {
if (comp->dict) { stream->nbState = 0;
if (comp->steps[step].name == NULL) { stream->level = 0;
if (comp->steps[step].ns == NULL) if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
match = 1; tmp = xmlStreamCtxtAddState(stream, 0, 0);
else if (tmp < 0)
match = (comp->steps[step].ns == ns); err++;
} else { if (comp->steps[tmp].flags & XML_STREAM_STEP_FINAL)
match = ((comp->steps[step].name == name) &&
(comp->steps[step].ns == ns));
}
} else {
if (comp->steps[step].name == NULL) {
if (comp->steps[step].ns == NULL)
match = 1;
else
match = xmlStrEqual(comp->steps[step].ns, ns);
} else {
match = ((xmlStrEqual(comp->steps[step].name, name)) &&
(xmlStrEqual(comp->steps[step].ns, ns)));
}
}
if (match) {
final = comp->steps[step].flags & XML_STREAM_STEP_FINAL;
if (desc) {
if (final) {
ret = 1; ret = 1;
continue; /* while */
}
continue; /* while */
}
/*
* Check evolution of existing states
*/
m = stream->nbState;
for (i = 0;i < m;i++) {
match = 0;
step = stream->states[2 * i];
/* dead states */
if (step < 0) continue;
/* skip new states just added */
if (stream->states[(2 * i) + 1] > stream->level)
continue;
/* skip continuations */
desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
if ((stream->states[(2 * i) + 1] < stream->level) && (!desc))
continue;
/* discard old states */
/* something needed about old level discarded */
if (comp->dict) {
if (comp->steps[step].name == NULL) {
if (comp->steps[step].ns == NULL)
match = 1;
else
match = (comp->steps[step].ns == ns);
} else { } else {
/* descending match create a new state */ match = ((comp->steps[step].name == name) &&
xmlStreamCtxtAddState(stream, step + 1, stream->level + 1); (comp->steps[step].ns == ns));
} }
} else { } else {
if (final) { if (comp->steps[step].name == NULL) {
ret = 1; if (comp->steps[step].ns == NULL)
#if 0 match = 1;
stream->states[2 * i] = -1; else
#endif match = xmlStrEqual(comp->steps[step].ns, ns);
} else { } else {
#if 0 match = ((xmlStrEqual(comp->steps[step].name, name)) &&
stream->states[2 * i] = step + 1; (xmlStrEqual(comp->steps[step].ns, ns)));
stream->states[2 * i + 1] = stream->level + 1; }
#endif }
xmlStreamCtxtAddState(stream, step + 1, stream->level + 1); if (match) {
final = comp->steps[step].flags & XML_STREAM_STEP_FINAL;
if (desc) {
if (final) {
ret = 1;
} else {
/* descending match create a new state */
xmlStreamCtxtAddState(stream, step + 1,
stream->level + 1);
}
} else {
if (final) {
ret = 1;
} else {
xmlStreamCtxtAddState(stream, step + 1,
stream->level + 1);
}
} }
} }
#if 0
} else if (!desc) {
/* didn't match, discard */
stream->states[2 * i] = -1;
#endif
} }
}
/* /*
* Check creating a new state. * Check creating a new state.
*/ */
stream->level++; stream->level++;
if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) { if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) {
match = 0; match = 0;
if (comp->dict) { if (comp->dict) {
if (comp->steps[0].name == NULL) { if (comp->steps[0].name == NULL) {
if (comp->steps[0].ns == NULL) if (comp->steps[0].ns == NULL)
match = 1; match = 1;
else else
match = (comp->steps[0].ns == ns); match = (comp->steps[0].ns == ns);
} else {
match = ((comp->steps[0].name == name) &&
(comp->steps[0].ns == ns));
}
} else { } else {
match = ((comp->steps[0].name == name) && if (comp->steps[0].name == NULL) {
(comp->steps[0].ns == ns)); if (comp->steps[0].ns == NULL)
match = 1;
else
match = xmlStrEqual(comp->steps[0].ns, ns);
} else {
match = ((xmlStrEqual(comp->steps[0].name, name)) &&
(xmlStrEqual(comp->steps[0].ns, ns)));
}
} }
} else { if (match) {
if (comp->steps[0].name == NULL) { if (comp->steps[0].flags & XML_STREAM_STEP_FINAL)
if (comp->steps[0].ns == NULL) ret = 1;
match = 1;
else else
match = xmlStrEqual(comp->steps[0].ns, ns); xmlStreamCtxtAddState(stream, 1, stream->level);
} else {
match = ((xmlStrEqual(comp->steps[0].name, name)) &&
(xmlStrEqual(comp->steps[0].ns, ns)));
} }
} }
if (match) {
if (comp->steps[0].flags & XML_STREAM_STEP_FINAL) stream = stream->next;
ret = 1; } /* while stream != NULL */
else
xmlStreamCtxtAddState(stream, 1, stream->level);
}
}
#ifdef DEBUG_STREAMING #ifdef DEBUG_STREAMING
xmlDebugStreamCtxt(stream, ret); xmlDebugStreamCtxt(stream, ret);
#endif #endif
if (err > 0)
ret = -1;
return(ret); return(ret);
} }
@@ -1502,22 +1505,27 @@ xmlStreamPush(xmlStreamCtxtPtr stream,
int int
xmlStreamPop(xmlStreamCtxtPtr stream) { xmlStreamPop(xmlStreamCtxtPtr stream) {
int i, m; int i, m;
int ret;
if (stream == NULL) if (stream == NULL)
return(-1); return(-1);
stream->level--; ret = 0;
if (stream->level < 0) while (stream != NULL) {
return(-1); stream->level--;
if (stream->level < 0)
/* ret = -1;
* Check evolution of existing states
*/ /*
m = stream->nbState; * Check evolution of existing states
for (i = 0;i < m;i++) { */
if (stream->states[(2 * i)] < 0) break; m = stream->nbState;
/* discard obsoleted states */ for (i = 0;i < m;i++) {
if (stream->states[(2 * i) + 1] > stream->level) if (stream->states[(2 * i)] < 0) break;
stream->states[(2 * i)] = -1; /* discard obsoleted states */
if (stream->states[(2 * i) + 1] > stream->level)
stream->states[(2 * i)] = -1;
}
stream = stream->next;
} }
return(0); return(0);
} }
@@ -1543,25 +1551,57 @@ xmlPatternPtr
xmlPatterncompile(const xmlChar *pattern, xmlDict *dict, xmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
int flags ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED,
const xmlChar **namespaces) { const xmlChar **namespaces) {
xmlPatternPtr ret = NULL; xmlPatternPtr ret = NULL, cur;
xmlPatParserContextPtr ctxt = NULL; xmlPatParserContextPtr ctxt = NULL;
const xmlChar *or, *start;
xmlChar *tmp = NULL;
ctxt = xmlNewPatParserContext(pattern, dict, namespaces); if (pattern == NULL)
if (ctxt == NULL) goto error; return(NULL);
ret = xmlNewPattern();
if (ret == NULL) goto error;
ctxt->comp = ret;
xmlCompilePathPattern(ctxt); start = pattern;
xmlFreePatParserContext(ctxt); while (*or != 0) {
or = start;
tmp = NULL;
while ((*or != 0) && (*or != '|')) or++;
if (*or == 0)
ctxt = xmlNewPatParserContext(start, dict, namespaces);
else {
tmp = xmlStrndup(start, or - start);
if (tmp != NULL) {
ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
}
or++;
}
if (ctxt == NULL) goto error;
cur = xmlNewPattern();
if (cur == NULL) goto error;
if (ret == NULL)
ret = cur;
else {
cur->next = ret->next;
ret->next = cur;
}
ctxt->comp = cur;
xmlStreamCompile(ret); xmlCompilePathPattern(ctxt);
if (xmlReversePattern(ret) < 0) xmlFreePatParserContext(ctxt);
goto error;
xmlStreamCompile(cur);
if (xmlReversePattern(cur) < 0)
goto error;
start = or;
if (tmp != NULL) {
xmlFree(tmp);
tmp = NULL;
}
}
return(ret); return(ret);
error: error:
if (ctxt != NULL) xmlFreePatParserContext(ctxt); if (ctxt != NULL) xmlFreePatParserContext(ctxt);
if (ret != NULL) xmlFreePattern(ret); if (ret != NULL) xmlFreePattern(ret);
if (tmp != NULL) xmlFree(tmp);
return(NULL); return(NULL);
} }
@@ -1577,9 +1617,18 @@ error:
int int
xmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node) xmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
{ {
int ret = 0;
if ((comp == NULL) || (node == NULL)) if ((comp == NULL) || (node == NULL))
return(-1); return(-1);
return(xmlPatMatch(comp, node));
while (comp != NULL) {
ret = xmlPatMatch(comp, node);
if (ret != 0)
return(ret);
comp = comp->next;
}
return(ret);
} }
/** /**
@@ -1594,9 +1643,29 @@ xmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
xmlStreamCtxtPtr xmlStreamCtxtPtr
xmlPatternGetStreamCtxt(xmlPatternPtr comp) xmlPatternGetStreamCtxt(xmlPatternPtr comp)
{ {
xmlStreamCtxtPtr ret = NULL, cur;
if ((comp == NULL) || (comp->stream == NULL)) if ((comp == NULL) || (comp->stream == NULL))
return(NULL); return(NULL);
return(xmlNewStreamCtxt(comp->stream));
while (comp != NULL) {
if (comp->stream == NULL)
goto failed;
cur = xmlNewStreamCtxt(comp->stream);
if (cur == NULL)
goto failed;
if (ret == NULL)
ret = cur;
else {
cur->next = ret->next;
ret->next = cur;
}
comp = comp->next;
}
return(ret);
failed:
xmlFreeStreamCtxt(ret);
return(NULL);
} }
#endif /* LIBXML_PATTERN_ENABLED */ #endif /* LIBXML_PATTERN_ENABLED */