[augeas-devel] [PATCH 02/11] * src/pathx.c: remove assumption that toplevel expression is a locpath
David Lutterkort
lutter at redhat.com
Mon Mar 23 06:27:27 UTC 2009
We can't assume that anymore when we have variables. That requires some
headache for pathx_expand_tree, since that needs a full trace of evaluating
a locpath against the tree.
---
src/pathx.c | 71 +++++++++++++++++++++++++++++++++++-----------------------
1 files changed, 43 insertions(+), 28 deletions(-)
diff --git a/src/pathx.c b/src/pathx.c
index d557902..d635f2d 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -123,7 +123,6 @@ static struct tree *step_next(struct step *step, struct tree *ctx,
struct pathx {
struct state *state;
- struct locpath *locpath;
struct nodeset *nodeset;
int node;
struct tree *origin;
@@ -172,6 +171,12 @@ struct expr {
};
};
+struct locpath_trace {
+ unsigned int maxns;
+ struct nodeset **ns;
+ struct locpath *lp;
+};
+
/* Internal state of the evaluator/parser */
struct state {
pathx_errcode_t errcode;
@@ -204,6 +209,10 @@ struct state {
struct expr **exprs;
size_t exprs_used;
size_t exprs_size;
+ /* Trace of a locpath evaluation, needed by pathx_expand_tree.
+ Generally NULL, unless a trace is needed.
+ */
+ struct locpath_trace *locpath_trace;
};
/* We consider NULL and the empty string to be equal */
@@ -768,8 +777,10 @@ static void ns_from_locpath(struct locpath *lp, uint *maxns,
static void eval_locpath(struct locpath *lp, struct state *state) {
struct nodeset **ns = NULL;
+ struct locpath_trace *lpt = state->locpath_trace;
uint maxns;
+ state->locpath_trace = NULL;
ns_from_locpath(lp, &maxns, &ns, state);
CHECK_ERROR;
@@ -778,9 +789,18 @@ static void eval_locpath(struct locpath *lp, struct state *state) {
state->value_pool[vind].nodeset = ns[maxns];
push_value(vind, state);
- for (int i=0; i < maxns; i++)
- free_nodeset(ns[i]);
- FREE(ns);
+ if (lpt != NULL) {
+ assert(lpt->ns == NULL);
+ assert(lpt->lp == NULL);
+ lpt->maxns = maxns;
+ lpt->ns = ns;
+ lpt->lp = lp;
+ state->locpath_trace = lpt;
+ } else {
+ for (int i=0; i < maxns; i++)
+ free_nodeset(ns[i]);
+ FREE(ns);
+ }
}
static void eval_expr(struct expr *expr, struct state *state) {
@@ -1623,14 +1643,11 @@ int pathx_parse(const struct tree *tree, const char *txt,
if (HAS_ERROR(state))
goto done;
- if (state->exprs[0]->type != T_NODESET
- || state->exprs[0]->tag != E_LOCPATH) {
+ if (state->exprs[0]->type != T_NODESET) {
STATE_ERROR(state, PATHX_ETYPE);
goto done;
}
- (*pathx)->locpath = state->exprs[0]->locpath;
-
done:
return state->errcode;
}
@@ -1763,40 +1780,30 @@ struct tree *pathx_first(struct pathx *pathx) {
* at the same depth match, TMATCH and SMATCH will be NULL. When exactly
* one node matches, TMATCH will be that node, and SMATCH will be NULL.
*/
-static int locpath_search(struct locpath *lp, struct state *state,
+static int locpath_search(struct locpath_trace *lpt,
struct tree **tmatch, struct step **smatch) {
- struct nodeset **ns = NULL;
- uint maxns;
int last;
int result = -1;
- state->ctx = *tmatch;
- *tmatch = NULL;
- *smatch = NULL;
-
- ns_from_locpath(lp, &maxns, &ns, state);
- if (HAS_ERROR(state))
- goto done;
-
- for (last=maxns; last >= 0 && ns[last]->used == 0; last--);
+ for (last=lpt->maxns; last >= 0 && lpt->ns[last]->used == 0; last--);
if (last < 0) {
- *smatch = lp->steps;
+ *smatch = lpt->lp->steps;
result = 1;
goto done;
}
- if (ns[last]->used > 1) {
+ if (lpt->ns[last]->used > 1) {
result = -1;
goto done;
}
result = 0;
- *tmatch = ns[last]->nodes[0];
- *smatch = lp->steps;
+ *tmatch = lpt->ns[last]->nodes[0];
+ *smatch = lpt->lp->steps;
for (int i=0; i < last; i++)
*smatch = (*smatch)->next;
done:
- for (int i=0; i <= maxns; i++)
- free_nodeset(ns[i]);
- FREE(ns);
+ for (int i=0; i < lpt->maxns; i++)
+ free_nodeset(lpt->ns[i]);
+ FREE(lpt->ns);
return result;
}
@@ -1809,9 +1816,17 @@ static int locpath_search(struct locpath *lp, struct state *state,
int pathx_expand_tree(struct pathx *path, struct tree **tree) {
int r;
struct step *step;
+ struct locpath_trace lpt;
+
+ MEMZERO(&lpt, 1);
+ path->state->locpath_trace = &lpt;
+ pathx_eval(path);
+ path->state->locpath_trace = NULL;
+ if (HAS_ERROR(path->state))
+ goto error;
*tree = path->origin;
- r = locpath_search(path->locpath, path->state, tree, &step);
+ r = locpath_search(&lpt, tree, &step);
if (r == -1)
return -1;
--
1.6.0.6
More information about the augeas-devel
mailing list