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:
@@ -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
329
pattern.c
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user