[augeas-devel] [PATCH 2 of 2] Report errors more clearly in the tree

David Lutterkort dlutter at redhat.com
Wed May 14 00:13:01 UTC 2008


1 file changed, 129 insertions(+), 31 deletions(-)
src/transform.c |  160 ++++++++++++++++++++++++++++++++++++++++++++-----------


# HG changeset patch
# User David Lutterkort <dlutter at redhat.com>
# Date 1210723941 25200
# Node ID 0511b3cd79be99aed8cc1647254c711fcb3c66ca
# Parent  8a217bbcecadbe3488818e0d28b840e7eb2533b2
Report errors more clearly in the tree

When an error happens during get/put, store additional info in the tree:
for get errors, store the position in the file where the error occured, for
put errors, the path of the node. In both cases, also store the
human-readable message.

For a file F, all this information is stored underneath /augeas/F/error,
with the value associated with /augeas/F/error giving some indication about
the kind of error encountered.

diff -r 8a217bbcecad -r 0511b3cd79be src/transform.c
--- a/src/transform.c	Tue May 13 17:12:21 2008 -0700
+++ b/src/transform.c	Tue May 13 17:12:21 2008 -0700
@@ -44,11 +44,19 @@ static const int glob_flags = GLOB_NOSOR
  *   lens/id   : unique hexadecimal id of the lens
  *   error     : indication of errors during processing FNAME, or NULL
  *               if processing succeeded
+ *   error/pos : position in file where error occured (for get errors)
+ *   error/path: path to tree node where error occurred (for put errors)
+ *   error/message : human-readable error message
  */
 static const char *const path_node = "/path";
 static const char *const info_node = "/lens/info";
 static const char *const id_node = "/lens/id";
+
 static const char *const err_node = "/error";
+/* These are all put underneath "/error" */
+static const char *const err_pos_node = "/pos";
+static const char *const err_path_node = "/path";
+static const char *const err_msg_node = "/message";
 
 /*
  * Filters
@@ -167,59 +175,146 @@ void free_transform(struct transform *xf
     free(xform);
 }
 
-static const char *err_path(const char *filename) {
+static char *err_path(const char *filename) {
     char *result = NULL;
     pathjoin(&result, 3, AUGEAS_META_FILES, filename, err_node);
     return result;
 }
 
-static char *add_load_info(struct augeas *aug, const char *filename,
-                           const char *node, struct lens *lens) {
-    char *tmp;
+/* Record an error in the tree. The error will show up underneath
+ * /augeas/FILENAME/error. PATH is the path to the toplevel node in the
+ * tree where the lens application happened. When STATUS is NULL, just
+ * clear any error associated with FILENAME in the tree.
+ */
+static int store_error(struct augeas *aug,
+                       const char *filename, const char *path,
+                       const char *status, const struct lns_error *err) {
+    char *ep = err_path(filename);
+    size_t ep_len;
     int r;
-    char *result = NULL;
+    int result = -1;
+
+    if (ep == NULL)
+        return -1;
+    ep_len = strlen(ep);
+
+    aug_rm(aug, ep);
+    if (status != NULL) {
+        r = aug_set(aug, ep, status);
+        if (r < 0)
+            goto done;
+
+        if (err != NULL) {
+            if (err->pos > 0) {
+                char *pos;
+
+                r = pathjoin(&ep, 1, err_pos_node);
+                if (r < 0)
+                    goto done;
+                r = asprintf(&pos, "%d", err->pos);
+                if (r < 0)
+                    goto done;
+                r = aug_set(aug, ep, pos);
+                FREE(pos);
+                if (r < 0)
+                    goto done;
+            } else {
+                char *p;
+
+                r = pathjoin(&ep, 1, err_path_node);
+                if (r < 0)
+                    goto done;
+                r = asprintf(&p, "%s%s", path, err->path);
+                if (r < 0)
+                    goto done;
+                r = aug_set(aug, ep, p);
+                FREE(p);
+                if (r < 0)
+                    goto done;
+            }
+            ep[ep_len] = '\0';
+            r = pathjoin(&ep, 1, err_msg_node);
+            if (r < 0)
+                goto done;
+            r = aug_set(aug, ep, err->message);
+            if (r < 0)
+                goto done;
+        }
+    }
+
+    result = 0;
+ done:
+    free(ep);
+    return result;
+}
+
+static int add_load_info(struct augeas *aug, const char *filename,
+                         const char *node, struct lens *lens) {
+    char *tmp = NULL;
+    int r;
+    char *p = NULL;
     int end = 0;
+    int result = -1;
 
-    pathjoin(&result, 2, AUGEAS_META_FILES, filename + strlen(aug->root) - 1);
-    end = strlen(result);
+    r = pathjoin(&p, 2, AUGEAS_META_FILES, filename + strlen(aug->root) - 1);
+    if (r < 0)
+        goto done;
+    end = strlen(p);
 
-    pathjoin(&result, 1, path_node);
-    aug_set(aug, result, node);
-    result[end] = '\0';
+    r = pathjoin(&p, 1, path_node);
+    if (r < 0)
+        goto done;
 
-    pathjoin(&result, 1, info_node);
+    r = aug_set(aug, p, node);
+    if (r < 0)
+        goto done;
+    p[end] = '\0';
+
+    r = pathjoin(&p, 1, info_node);
+    if (r < 0)
+        goto done;
+
     tmp = format_info(lens->info);
-    aug_set(aug, result, tmp);
-    free(tmp);
-    result[end] = '\0';
+    if (tmp == NULL)
+        goto done;
+    r = aug_set(aug, p, tmp);
+    FREE(tmp);
+    if (r < 0)
+        goto done;
+    p[end] = '\0';
 
-    pathjoin(&result, 1, id_node);
+    r = pathjoin(&p, 1, id_node);
+    if (r < 0)
+        goto done;
+
     r = asprintf(&tmp, "%p", lens);
     if (r >= 0) {
-        aug_set(aug, result, tmp);
-        free(tmp);
+        r = aug_set(aug, p, tmp);
+        FREE(tmp);
+        if (r < 0)
+            goto done;
     }
-    result[end] = '\0';
 
-    pathjoin(&result, 1, err_node);
+    result = 0;
+ done:
+    free(p);
     return result;
 }
 
 static int load_file(struct augeas *aug, struct lens *lens,
                      const char *filename) {
     char *text = NULL;
-    char *errpath = NULL;
     const char *err_status = NULL;
     struct aug_file *file = NULL;
     struct tree *tree = NULL;
     char *path = NULL;
-    struct lns_error *err;
-    int result = -1;
+    struct lns_error *err = NULL;
+    int result = -1, r;
 
     pathjoin(&path, 2, AUGEAS_FILES_TREE, filename + strlen(aug->root) - 1);
 
-    errpath = add_load_info(aug, filename, path, lens);
-    if (errpath == NULL)
+    r = add_load_info(aug, filename, path, lens);
+    if (r < 0)
         goto done;
 
     text = read_file(filename);
@@ -249,11 +344,13 @@ static int load_file(struct augeas *aug,
 
     result = 0;
  done:
-    if (errpath != NULL)
-        aug_set(aug, errpath, err_status);
+    store_error(aug, filename + strlen(aug->root) - 1, path, err_status, err);
+    if (err != NULL) {
+        free(err->path);
+        free(err->message);
+    }
     free(path);
     free_tree(tree);
-    free(errpath);
     free(file);
     free(text);
     return result;
@@ -353,11 +450,12 @@ int transform_save(struct augeas *aug, s
     free(augnew);
     free(augorig);
     free(augsave);
-    if (err_status != NULL) {
-        const char *ep = err_path(filename);
-        aug_set(aug, ep, err_status);
-        free((char *) ep);
+    store_error(aug, filename, path, err_status, err);
+    if (err != NULL) {
+        free(err->path);
+        free(err->message);
     }
+
     if (fp != NULL)
         fclose(fp);
     return result;




More information about the augeas-devel mailing list