[augeas-devel] [PATCH 4/8] Store pathx parse errors in internal error struct

David Lutterkort lutter at redhat.com
Tue Sep 22 00:49:01 UTC 2009


The pathx_parse function will now store error information in a struct
error; we pass the one from struct augeas in and save it in the pathx.
---
 src/augeas.c    |   89 ++++++++++++++++++++++++------------------------------
 src/builtin.c   |    8 ++--
 src/internal.h  |    8 ++++-
 src/pathx.c     |   53 ++++++++++++++++++++++++++++----
 src/transform.c |    3 +-
 5 files changed, 99 insertions(+), 62 deletions(-)

diff --git a/src/augeas.c b/src/augeas.c
index e8e2fc0..f6c1c3d 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -129,34 +129,32 @@ static int tree_set_value(struct tree *tree, const char *value) {
     return 0;
 }
 
-/* Parse a path expression. Report errors in /augeas/pathx/error */
-static struct pathx *parse_user_pathx(const struct augeas *aug,
-                                      bool need_nodeset,
-                                      const char *path) {
-    struct pathx *result;
-    int    pos;
-
-    if (pathx_parse(aug->origin, path, need_nodeset, aug->symtab, &result)
-        == PATHX_NOERROR)
-        return result;
+/* Report pathx errors in /augeas/pathx/error */
+static void store_pathx_error(const struct augeas *aug) {
+    if (aug->error.code != AUG_EPATHX)
+        return;
 
     struct tree *error =
         tree_path_cr(aug->origin, 3, s_augeas, s_pathx, s_error);
     if (error == NULL)
-        return NULL;
-    tree_set_value(error, pathx_error(result, NULL, &pos));
+        return;
+    tree_set_value(error, aug->error.minor_details);
 
     struct tree *tpos = tree_child_cr(error, s_pos);
     if (tpos == NULL)
-        return NULL;
+        return;
+    tree_set_value(tpos, aug->error.details);
+}
 
-    free(tpos->value);
-    if (ALLOC_N(tpos->value, strlen(path) + 4) >= 0) {
-        strncpy(tpos->value, path, pos);
-        strcat(tpos->value, "|=|");
-        strcat(tpos->value, path + pos);
-    }
-    return NULL;
+static struct pathx *parse_user_pathx(const struct augeas *aug,
+                                      bool need_nodeset,
+                                      const char *path) {
+    struct pathx *result;
+    struct error *err = err_of_aug(aug);
+
+    pathx_parse(aug->origin, err, path, need_nodeset, aug->symtab,
+                &result);
+    return result;
 }
 
 static const char *init_root(const char *root0) {
@@ -363,6 +361,9 @@ static void api_entry(const struct augeas *aug) {
 static void api_exit(const struct augeas *aug) {
     assert(aug->api_entries > 0);
     ((struct augeas *) aug)->api_entries -= 1;
+    if (aug->api_entries == 0) {
+        store_pathx_error(aug);
+    }
 }
 
 int aug_load(struct augeas *aug) {
@@ -399,8 +400,7 @@ int aug_get(const struct augeas *aug, const char *path, const char **value) {
     api_entry(aug);
 
     p = parse_user_pathx((struct augeas *) aug, true, path);
-    if (p == NULL)
-        goto error;
+    ERR_BAIL(aug);
 
     if (value != NULL)
         *value = NULL;
@@ -427,11 +427,10 @@ int aug_defvar(augeas *aug, const char *name, const char *expr) {
         result = pathx_symtab_undefine(&(aug->symtab), name);
     } else {
         p = parse_user_pathx((struct augeas *) aug, false, expr);
-        if (p == NULL)
-            goto done;
+        ERR_BAIL(aug);
         result = pathx_symtab_define(&(aug->symtab), name, p);
     }
- done:
+ error:
     free_pathx(p);
     api_exit(aug);
     return result;
@@ -452,8 +451,7 @@ int aug_defnode(augeas *aug, const char *name, const char *expr,
         created = &cr;
 
     p = parse_user_pathx((struct augeas *) aug, false, expr);
-    if (p == NULL)
-        goto done;
+    ERR_BAIL(aug);
 
     r = pathx_expand_tree(p, &tree);
     if (r < 0)
@@ -499,8 +497,7 @@ int aug_set(struct augeas *aug, const char *path, const char *value) {
     api_entry(aug);
 
     p = parse_user_pathx(aug, true, path);
-    if (p == NULL)
-        goto error;
+    ERR_BAIL(aug);
 
     result = tree_set(p, value) == NULL ? -1 : 0;
     free_pathx(p);
@@ -545,11 +542,10 @@ int aug_insert(struct augeas *aug, const char *path, const char *label,
     api_entry(aug);
 
     p = parse_user_pathx(aug, true, path);
-    if (p == NULL)
-        goto done;
+    ERR_BAIL(aug);
 
     result = tree_insert(p, label, before);
- done:
+ error:
     free_pathx(p);
     api_exit(aug);
     return result;
@@ -660,8 +656,7 @@ int aug_rm(struct augeas *aug, const char *path) {
     api_entry(aug);
 
     p = parse_user_pathx(aug, true, path);
-    if (p == NULL)
-        goto error;
+    ERR_BAIL(aug);
 
     result = tree_rm(p);
     free_pathx(p);
@@ -678,7 +673,7 @@ int tree_replace(struct tree *origin, const char *path, struct tree *sub) {
     struct pathx *p = NULL;
     int r;
 
-    if (pathx_parse(origin, path, true, NULL, &p) != PATHX_NOERROR)
+    if (pathx_parse(origin, NULL, path, true, NULL, &p) != PATHX_NOERROR)
         goto error;
 
     r = tree_rm(p);
@@ -711,26 +706,24 @@ int aug_mv(struct augeas *aug, const char *src, const char *dst) {
 
     ret = -1;
     s = parse_user_pathx(aug, true, src);
-    if (s == NULL)
-        goto done;
+    ERR_BAIL(aug);
 
     d = parse_user_pathx(aug, true, dst);
-    if (d == NULL)
-        goto done;
+    ERR_BAIL(aug);
 
     r = pathx_find_one(s, &ts);
     if (r != 1)
-        goto done;
+        goto error;
 
     r = pathx_expand_tree(d, &td);
     if (r == -1)
-        goto done;
+        goto error;
 
     /* Don't move SRC into its own descendent */
     t = td;
     do {
         if (t == ts)
-            goto done;
+            goto error;
         t = t->parent;
     } while (! ROOT_P(t));
 
@@ -750,7 +743,7 @@ int aug_mv(struct augeas *aug, const char *src, const char *dst) {
     tree_mark_dirty(td);
 
     ret = 0;
- done:
+ error:
     free_pathx(s);
     free_pathx(d);
     api_exit(aug);
@@ -772,8 +765,7 @@ int aug_match(const struct augeas *aug, const char *pathin, char ***matches) {
     }
 
     p = parse_user_pathx((struct augeas *) aug, true, pathin);
-    if (p == NULL)
-        goto error;
+    ERR_BAIL(aug);
 
     for (tree = pathx_first(p); tree != NULL; tree = pathx_next(p)) {
         if (! TREE_HIDDEN(tree))
@@ -901,7 +893,7 @@ static int unlink_removed_files(struct augeas *aug,
         if (tf == NULL) {
             /* Unlink all files in tm */
             struct pathx *px = NULL;
-            if (pathx_parse(tm, file_nodes, true, NULL, &px)
+            if (pathx_parse(tm, err_of_aug(aug), file_nodes, true, NULL, &px)
                 != PATHX_NOERROR) {
                 result = -1;
                 continue;
@@ -1042,7 +1034,7 @@ int dump_tree(FILE *out, struct tree *tree) {
     struct pathx *p;
     int result;
 
-    if (pathx_parse(tree, "/*", true, NULL, &p) != PATHX_NOERROR)
+    if (pathx_parse(tree, NULL, "/*", true, NULL, &p) != PATHX_NOERROR)
         return -1;
 
     result = print_tree(out, p, 1);
@@ -1061,8 +1053,7 @@ int aug_print(const struct augeas *aug, FILE *out, const char *pathin) {
     }
 
     p = parse_user_pathx((struct augeas *) aug, true, pathin);
-    if (p == NULL)
-        goto error;
+    ERR_BAIL(aug);
 
     result = print_tree(out, p, 0);
     free_pathx(p);
diff --git a/src/builtin.c b/src/builtin.c
index ce3fd3c..e066aba 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -212,7 +212,7 @@ static struct value *tree_set_glue(struct info *info, struct value *path,
         fake = tree->origin->children;
     }
 
-    if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+    if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
         != PATHX_NOERROR) {
         result = make_pathx_exn(ref(info), p);
         goto done;
@@ -253,7 +253,7 @@ static struct value *tree_clear_glue(struct info *info, struct value *path,
         fake = tree->origin->children;
     }
 
-    if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+    if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
         != PATHX_NOERROR) {
         result = make_pathx_exn(ref(info), p);
         goto done;
@@ -290,7 +290,7 @@ static struct value *tree_insert_glue(struct info *info, struct value *label,
     struct pathx *p = NULL;
     struct value *result = NULL;
 
-    if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+    if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
         != PATHX_NOERROR) {
         result = make_pathx_exn(ref(info), p);
         goto done;
@@ -337,7 +337,7 @@ static struct value *tree_rm_glue(struct info *info,
     struct pathx *p = NULL;
     struct value *result = NULL;
 
-    if (pathx_parse(tree->origin, path->string->str, true, NULL, &p)
+    if (pathx_parse(tree->origin, NULL, path->string->str, true, NULL, &p)
         != PATHX_NOERROR) {
         result = make_pathx_exn(ref(info), p);
         goto done;
diff --git a/src/internal.h b/src/internal.h
index 441be84..aef6c0a 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -298,6 +298,10 @@ void report_error(struct error *err, aug_errcode_t errcode,
                   const char *format, ...)
     ATTRIBUTE_FORMAT(printf, 3, 4);
 
+static inline struct error *err_of_aug(const struct augeas *aug) {
+    return &((struct augeas *) aug)->error;
+}
+
 #define ERR_BAIL(aug) if ((aug)->error.code != AUG_NOERROR) goto error;
 
 #define ERR_NOMEM(cond, aug)                             \
@@ -442,7 +446,9 @@ const char *pathx_error(struct pathx *pathx, const char **txt, int *pos);
  *
  * Returns 0 on success, and -1 on error
  */
-int pathx_parse(const struct tree *origin, const char *path,
+int pathx_parse(const struct tree *origin,
+                struct error *err,
+                const char *path,
                 bool need_nodeset,
                 struct pathx_symtab *symtab,
                 struct pathx **px);
diff --git a/src/pathx.c b/src/pathx.c
index 2a07c21..7a691d8 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -234,6 +234,9 @@ struct state {
     struct locpath_trace *locpath_trace;
     /* Symbol table for variable lookups */
     struct pathx_symtab *symtab;
+    /* Error structure, used to communicate errors to struct augeas;
+     * we never own this structure, and therefore never free it */
+    struct error        *error;
 };
 
 /* We consider NULL and the empty string to be equal */
@@ -1871,7 +1874,38 @@ static void parse_expr(struct state *state) {
     parse_or_expr(state);
 }
 
-int pathx_parse(const struct tree *tree, const char *txt,
+static void store_error(struct pathx *pathx) {
+    const char *pathx_msg = NULL;
+    const char *path = pathx->state->txt;
+    const pathx_errcode_t errcode = pathx->state->errcode;
+    struct error *err = pathx->state->error;
+
+    char *pos_str = NULL;
+    int pos;
+
+    if (err == NULL || errcode == PATHX_NOERROR || err->code != AUG_NOERROR)
+        return;
+
+    pathx_msg = pathx_error(pathx, NULL, &pos);
+
+    if (ALLOC_N(pos_str, strlen(path) + 4) >= 0) {
+        strncpy(pos_str, path, pos);
+        strcat(pos_str, "|=|");
+        strcat(pos_str, path + pos);
+    }
+
+    err->code = errcode == PATHX_ENOMEM ? AUG_ENOMEM : AUG_EPATHX;
+    err->minor = errcode;
+    err->details = pos_str;
+    pos_str = NULL;
+    err->minor_details = pathx_msg;
+
+    FREE(pos_str);
+}
+
+int pathx_parse(const struct tree *tree,
+                struct error *err,
+                const char *txt,
                 bool need_nodeset,
                 struct pathx_symtab *symtab,
                 struct pathx **pathx) {
@@ -1880,22 +1914,20 @@ int pathx_parse(const struct tree *tree, const char *txt,
     *pathx = NULL;
 
     if (ALLOC(*pathx) < 0)
-        return PATHX_ENOMEM;
+        goto oom;
 
     (*pathx)->origin = (struct tree *) tree;
 
     /* Set up state */
-    if (ALLOC((*pathx)->state) < 0) {
-        free_pathx(*pathx);
-        *pathx = NULL;
-        return PATHX_ENOMEM;
-    }
+    if (ALLOC((*pathx)->state) < 0)
+        goto oom;
     state = (*pathx)->state;
 
     state->errcode = PATHX_NOERROR;
     state->txt = txt;
     state->pos = txt;
     state->symtab = symtab;
+    state->error = err;
 
     if (ALLOC_N(state->value_pool, 8) < 0) {
         STATE_ENOMEM;
@@ -1933,7 +1965,14 @@ int pathx_parse(const struct tree *tree, const char *txt,
     }
 
  done:
+    store_error(*pathx);
     return state->errcode;
+ oom:
+    free_pathx(*pathx);
+    *pathx = NULL;
+    if (err != NULL)
+        err->code = AUG_ENOMEM;
+    return PATHX_ENOMEM;
 }
 
 /*************************************************************************
diff --git a/src/transform.c b/src/transform.c
index a9e60dc..341fc36 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -673,7 +673,8 @@ static int file_saved_event(struct augeas *aug, const char *path) {
     struct tree *dummy;
     int r;
 
-    r = pathx_parse(aug->origin, AUGEAS_EVENTS_SAVED "[last()]",
+    r = pathx_parse(aug->origin, err_of_aug(aug),
+                    AUGEAS_EVENTS_SAVED "[last()]",
                     true, NULL, &px);
     if (r != PATHX_NOERROR)
         return -1;
-- 
1.6.2.5




More information about the augeas-devel mailing list