[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