[augeas-devel] [PATCH 08/11] Move parsing of path expressions into public API methods
David Lutterkort
lutter at redhat.com
Mon Jan 26 05:41:21 UTC 2009
For path expressions that are passed through the API, we need to report
errors. This change lays the groundwork, so that we can distinguish between
parsing user-supplied path expressions and internally generated path
expressions.
---
src/augeas.c | 115 ++++++++++++++++++++++++++++++++-----------------------
src/builtin.c | 88 ++++++++++++++++++++++++++++++++++--------
src/internal.h | 15 ++++---
src/syntax.c | 2 +-
4 files changed, 148 insertions(+), 72 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index b3ec44b..96a0a2a 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -250,19 +250,13 @@ int aug_get(const struct augeas *aug, const char *path, const char **value) {
return r;
}
-struct tree *tree_set(struct tree *origin, const char *path,
- const char *value) {
+struct tree *tree_set(struct pathx *p, const char *value) {
struct tree *tree;
- struct pathx *p;
int r;
- if (pathx_parse(origin, path, &p) != 0)
- goto error;
-
r = pathx_expand_tree(p, &tree);
if (r == -1)
- goto error;
- free_pathx(p);
+ return NULL;
if (tree->value != NULL) {
free(tree->value);
@@ -271,32 +265,30 @@ struct tree *tree_set(struct tree *origin, const char *path,
if (value != NULL) {
tree->value = strdup(value);
if (tree->value == NULL)
- goto error;
+ return NULL;
}
tree->dirty = 1;
return tree;
- error:
- free_pathx(p);
- return NULL;
}
int aug_set(struct augeas *aug, const char *path, const char *value) {
- return tree_set(aug->origin, path, value) == NULL ? -1 : 0;
-}
+ struct pathx *p;
+ int result;
-int tree_insert(struct tree *origin, const char *path, const char *label,
- int before) {
- assert(origin->parent == origin);
+ if (pathx_parse(aug->origin, path, &p) != PATHX_NOERROR)
+ return -1;
- struct pathx *p = NULL;
+ result = tree_set(p, value) == NULL ? -1 : 0;
+ free_pathx(p);
+ return result;
+}
+
+int tree_insert(struct pathx *p, const char *label, int before) {
struct tree *new = NULL, *match;
if (strchr(label, SEP) != NULL)
return -1;
- if (pathx_parse(origin, path, &p) != 0)
- goto error;
-
if (pathx_find_one(p, &match) != 1)
goto error;
@@ -310,17 +302,24 @@ int tree_insert(struct tree *origin, const char *path, const char *label,
new->next = match->next;
match->next = new;
}
- free_pathx(p);
return 0;
error:
free_tree(new);
- free_pathx(p);
return -1;
}
int aug_insert(struct augeas *aug, const char *path, const char *label,
int before) {
- return tree_insert(aug->origin, path, label, before);
+ struct pathx *p = NULL;
+ int result = -1;
+
+ if (pathx_parse(aug->origin, path, &p) != PATHX_NOERROR)
+ goto done;
+
+ result = tree_insert(p, label, before);
+ done:
+ free_pathx(p);
+ return result;
}
struct tree *make_tree(char *label, char *value, struct tree *parent,
@@ -376,26 +375,17 @@ int free_tree(struct tree *tree) {
return cnt;
}
-int tree_rm(struct tree *origin, const char *path) {
- assert(origin->parent == origin);
- assert(origin->next == NULL);
-
- struct pathx *p = NULL;
+int tree_rm(struct pathx *p) {
struct tree *tree, **del;
int cnt = 0, ndel = 0, i;
- if (pathx_parse(origin, path, &p) != 0)
- return -1;
-
for (tree = pathx_first(p); tree != NULL; tree = pathx_next(p)) {
if (! TREE_HIDDEN(tree))
ndel += 1;
}
- if (ndel == 0) {
- free_pathx(p);
+ if (ndel == 0)
return 0;
- }
if (ALLOC_N(del, ndel) < 0) {
free(del);
@@ -408,7 +398,6 @@ int tree_rm(struct tree *origin, const char *path) {
del[i] = tree;
i += 1;
}
- free_pathx(p);
for (i = 0; i < ndel; i++) {
assert (del[i]->parent != NULL);
@@ -423,18 +412,31 @@ int tree_rm(struct tree *origin, const char *path) {
}
int aug_rm(struct augeas *aug, const char *path) {
- return tree_rm(aug->origin, path);
+ struct pathx *p = NULL;
+ int result;
+
+ if (pathx_parse(aug->origin, path, &p) != PATHX_NOERROR)
+ return -1;
+
+ result = tree_rm(p);
+ free_pathx(p);
+
+ return result;
}
int tree_replace(struct tree *origin, const char *path, struct tree *sub) {
struct tree *parent;
+ struct pathx *p = NULL;
int r;
- r = tree_rm(origin, path);
+ if (pathx_parse(origin, path, &p) != PATHX_NOERROR)
+ goto error;
+
+ r = tree_rm(p);
if (r == -1)
goto error;
- parent = tree_set(aug->origin, path, NULL);
+ parent = tree_set(p, NULL);
if (parent == NULL)
goto error;
@@ -442,8 +444,10 @@ int tree_replace(struct tree *origin, const char *path, struct tree *sub) {
list_for_each(s, sub) {
s->parent = parent;
}
+ free_pathx(p);
return 0;
error:
+ free_pathx(p);
return -1;
}
@@ -716,17 +720,11 @@ static int print_rec(FILE *out, struct tree *start, const char *ppath,
return -1;
}
-int print_tree(const struct tree *start, FILE *out, const char *pathin,
- int pr_hidden) {
-
- struct pathx *p;
+static int print_tree(FILE *out, struct pathx *p, int pr_hidden) {
char *path = NULL;
struct tree *tree;
int r;
- if (pathx_parse(start, pathin, &p) != 0)
- return -1;
-
for (tree = pathx_first(p); tree != NULL; tree = pathx_next(p)) {
if (TREE_HIDDEN(tree) && ! pr_hidden)
continue;
@@ -743,18 +741,39 @@ int print_tree(const struct tree *start, FILE *out, const char *pathin,
free(path);
path = NULL;
}
- free_pathx(p);
return 0;
error:
free(path);
return -1;
}
+int dump_tree(FILE *out, struct tree *tree) {
+ struct pathx *p;
+ int result;
+
+ if (pathx_parse(tree, "/*", &p) != PATHX_NOERROR)
+ return -1;
+
+ result = print_tree(out, p, 1);
+ free_pathx(p);
+ return result;
+}
+
int aug_print(const struct augeas *aug, FILE *out, const char *pathin) {
+ struct pathx *p;
+ int result;
+
if (pathin == NULL || strlen(pathin) == 0) {
pathin = "/*";
}
- return print_tree(aug->origin, out, pathin, 0);
+
+ if (pathx_parse(aug->origin, pathin, &p) != PATHX_NOERROR)
+ return -1;
+
+ result = print_tree(out, p, 0);
+ free_pathx(p);
+
+ return result;
}
void aug_close(struct augeas *aug) {
diff --git a/src/builtin.c b/src/builtin.c
index 05aeefc..1396eb3 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -106,12 +106,32 @@ static void exn_print_tree(struct value *exn, struct tree *tree) {
struct memstream ms;
init_memstream(&ms);
- print_tree(tree, ms.stream, "/*", 1);
+ dump_tree(ms.stream, tree);
close_memstream(&ms);
exn_printf_line(exn, "%s", ms.buf);
FREE(ms.buf);
}
+static struct value *make_pathx_exn(struct info *info, struct pathx *p) {
+ struct value *v;
+ char *msg;
+ const char *txt;
+ int pos;
+
+ msg = strdup(pathx_error(p, &txt, &pos));
+ if (msg == NULL)
+ return NULL;
+
+ v = make_exn_value(ref(info), "syntax error in path expression: %s", msg);
+ if (ALLOC_N(msg, strlen(txt) + 4) >= 0) {
+ strncpy(msg, txt, pos);
+ strcat(msg, "|=|");
+ strcat(msg, txt + pos);
+ exn_add_lines(v, 1, msg);
+ }
+ return v;
+}
+
/* V_LENS -> V_STRING -> V_TREE */
static struct value *lens_get(struct info *info, struct value *l,
struct value *str) {
@@ -181,24 +201,34 @@ static struct value *tree_set_glue(struct info *info, struct value *path,
assert(tree->tag == V_TREE);
struct tree *fake = NULL;
+ struct pathx *p = NULL;
+ struct value *result = NULL;
if (tree->origin->children == NULL) {
tree->origin->children = make_tree(NULL, NULL, tree->origin, NULL);
fake = tree->origin->children;
}
- if (tree_set(tree->origin, path->string->str,
- val->string->str) == NULL) {
- return make_exn_value(ref(info),
- "Tree set of %s to '%s' failed",
- path->string->str, val->string->str);
+ if (pathx_parse(tree->origin, path->string->str, &p) != PATHX_NOERROR) {
+ result = make_pathx_exn(ref(info), p);
+ goto done;
+ }
+
+ if (tree_set(p, val->string->str) == NULL) {
+ result = make_exn_value(ref(info),
+ "Tree set of %s to '%s' failed",
+ path->string->str, val->string->str);
+ goto done;
}
if (fake != NULL) {
list_remove(fake, tree->origin->children);
free_tree(fake);
}
+ result = ref(tree);
- return ref(tree);
+ done:
+ free_pathx(p);
+ return result;
}
static struct value *tree_insert_glue(struct info *info, struct value *label,
@@ -212,15 +242,26 @@ static struct value *tree_insert_glue(struct info *info, struct value *label,
assert(tree->tag == V_TREE);
int r;
- r = tree_insert(tree->origin, path->string->str,
- label->string->str, before);
+ struct pathx *p = NULL;
+ struct value *result = NULL;
+
+ if (pathx_parse(tree->origin, path->string->str, &p) != PATHX_NOERROR) {
+ result = make_pathx_exn(ref(info), p);
+ goto done;
+ }
+
+ r = tree_insert(p, label->string->str, before);
if (r != 0) {
- return make_exn_value(ref(info),
- "Tree insert of %s at %s failed",
- label->string->str, path->string->str);
+ result = make_exn_value(ref(info),
+ "Tree insert of %s at %s failed",
+ label->string->str, path->string->str);
+ goto done;
}
- return ref(tree);
+ result = ref(tree);
+ done:
+ free_pathx(p);
+ return result;
}
/* Insert after */
@@ -246,11 +287,24 @@ static struct value *tree_rm_glue(struct info *info,
// need to copy TREE first
assert(path->tag == V_STRING);
assert(tree->tag == V_TREE);
- if (tree_rm(tree->origin, path->string->str) == -1) {
- return make_exn_value(ref(info), "Tree rm of %s failed",
- path->string->str);
+
+ struct pathx *p = NULL;
+ struct value *result = NULL;
+
+ if (pathx_parse(tree->origin, path->string->str, &p) != PATHX_NOERROR) {
+ result = make_pathx_exn(ref(info), p);
+ goto done;
+ }
+
+ if (tree_rm(p) == -1) {
+ result = make_exn_value(ref(info), "Tree rm of %s failed",
+ path->string->str);
+ goto done;
}
- return ref(tree);
+ result = ref(tree);
+ done:
+ free_pathx(p);
+ return result;
}
/* V_STRING -> V_STRING */
diff --git a/src/internal.h b/src/internal.h
index a241e8e..1107e2a 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -289,6 +289,11 @@ struct tree {
int dirty;
};
+/* The opaque structure used to represent path expressions. API's
+ * using STRUCT PATHX are declared farther below
+ */
+struct pathx;
+
#define ROOT_P(t) ((t) != NULL && (t)->parent == (t)->parent->parent)
/* Function: make_tree
@@ -306,13 +311,11 @@ struct tree *make_tree_origin(struct tree *root);
int tree_replace(struct tree *origin, const char *path, struct tree *sub);
-int tree_rm(struct tree *origin, const char *path);
-struct tree *tree_set(struct tree *origin, const char *path, const char *value);
-int tree_insert(struct tree *origin, const char *path, const char *label,
- int before);
+int tree_rm(struct pathx *p);
+struct tree *tree_set(struct pathx *p, const char *value);
+int tree_insert(struct pathx *p, const char *label, int before);
int free_tree(struct tree *tree);
-int print_tree(const struct tree *origin, FILE *out, const char *path,
- int pr_hidden);
+int dump_tree(FILE *out, struct tree *tree);
int tree_equal(const struct tree *t1, const struct tree *t2);
/* Struct: memstream
diff --git a/src/syntax.c b/src/syntax.c
index eb05a4f..7ad7480 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -625,7 +625,7 @@ static void print_value(FILE *out, struct value *v) {
fprintf(out, ">");
break;
case V_TREE:
- print_tree(v->origin, stdout, "/*" , 1);
+ dump_tree(stdout, v->origin);
break;
case V_FILTER:
fprintf(out, "<filter:");
--
1.6.0.6
More information about the augeas-devel
mailing list