[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [augeas-devel] aug_lens_get



Thank you for the comments.

Attached is a new iteration of the patch. It fixes the issue of reusing
the lens, puts the text into /text/$name, errors
into /augeas/text/$name/errors and fixes the coding style errors.

I left the code that adds the trailing newline if it's not there for now
- from the transform_load() code I got the impression that requiring a
trailing newline is kinda bad practice in the lens file, so it's not
something the user should take care of (i.e. the caller should not be
working around the lens file)..but if it's more like a requirement of
augeas (or rather the lens language) that the input string must conform
to, it probably is something the caller of aug_lens_get() should take
care of and I will respin the patch with this code out.

Thanks,
Jakub
>From 49bebae4320bbc23e1549e7931129fe2a1c7df82 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek redhat com>
Date: Wed, 25 Mar 2009 17:04:54 +0100
Subject: [PATCH] aug_lens_get

---
 src/augeas.c           |   29 +++++++++++
 src/augeas.h           |   20 ++++++++
 src/augeas_sym.version |    1 +
 src/augtool.c          |   16 ++++++
 src/internal.h         |    8 +++
 src/transform.c        |  121 +++++++++++++++++++++++++++++++++++++----------
 src/transform.h        |    4 ++
 7 files changed, 173 insertions(+), 26 deletions(-)

diff --git a/src/augeas.c b/src/augeas.c
index 3b654f1..18300e3 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -977,6 +977,35 @@ int aug_print(const struct augeas *aug, FILE *out, const char *pathin) {
     return result;
 }
 
+int aug_lens_get(augeas *aug, const char *path, const char *lens,
+                 const char *txt, size_t txt_len) {
+    char *text = NULL;
+    int result = -1;
+
+    /* append newline to the end of the string if needed */
+    if (txt_len == 0 || txt[txt_len-1] != '\n') {
+        if (ALLOC_N(text, txt_len+2) < 0) {
+            goto fini;
+        }
+        strcpy(text, txt);
+        text[txt_len]   = '\n';
+        text[txt_len+1] = '\0';
+        txt_len += 2;
+    } else {
+        text = (char *) txt;
+    }
+
+    result = transform_string(aug, lens, path, text, txt_len);
+    if (result != 0) {
+        goto fini;
+    }
+
+    result = 0;
+fini:
+    if (text != txt) free(text);
+    return result;
+}
+
 void aug_close(struct augeas *aug) {
     if (aug == NULL)
         return;
diff --git a/src/augeas.h b/src/augeas.h
index 5a146f1..d964780 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -249,6 +249,26 @@ int aug_save(augeas *aug);
  */
 int aug_load(augeas *aug);
 
+
+/* Function: aug_lens_get
+ *
+ * Transform the string TXT into a tree using the get direction of lens
+ * LENS and put the resulting tree into the tree in AUG at PATH.
+ *
+ * The PATH must not start with '/augeas', and should not start with
+ * '/files', unless you know very well what you are doing.
+ *
+ * The LENS is the fully qualified name of a lens in the form
+ * 'Module.lens'.
+ *
+ * The string TXT is a nul-terminated string of length TXT_LEN
+ *
+ * Return -1 on error, and 0 on success
+ */
+
+int aug_lens_get(augeas *aug, const char *path, const char *lens,
+                 const char *txt, size_t txt_len);
+
 /* Function: aug_print
  *
  * Print each node matching PATH and its descendants to OUT.
diff --git a/src/augeas_sym.version b/src/augeas_sym.version
index 0fdc03d..a5a36f6 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -13,6 +13,7 @@
       aug_save;
       aug_load;
       aug_print;
+      aug_lens_get;
       # Symbols with __ are private
       __aug_load_module_file;
     local: *;
diff --git a/src/augtool.c b/src/augtool.c
index c4e90af..e671c46 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -246,6 +246,19 @@ static int cmd_get(char *args[]) {
     return 0;
 }
 
+static int cmd_lens_get(char *args[]) {
+    const char *path = cleanpath(args[0]);
+    const char *module = cleanpath(args[1]);
+    const char *txt = cleanpath(args[2]);
+    int ret;
+
+    ret = aug_lens_get(aug, path, module, txt, strlen(txt));
+    if(ret != 0)
+        printf ("Failed\n");
+
+    return ret;
+}
+
 static int cmd_print(char *args[]) {
     return aug_print(aug, stdout, cleanpath(args[0]));
 }
@@ -416,6 +429,9 @@ static const struct command const commands[] = {
       "Save all pending changes to disk. For now, files are not overwritten.\n"
       "        Instead, new files with extension .augnew are created"
     },
+    { "lens_get", 3, 3, cmd_lens_get, "lens_get <PATH> <LENS> <TEXT>",
+      "Parse text according to LENS and store result at PATH/\n"
+    },
     { "load", 0, 0, cmd_load, "load",
       "Load files accordig to the transforms in /augeas/load."
     },
diff --git a/src/internal.h b/src/internal.h
index a2698b4..13cb249 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -63,6 +63,14 @@
  * Information about files */
 #define AUGEAS_META_FILES AUGEAS_META_TREE AUGEAS_FILES_TREE
 
+/* Define: AUGEAS_TEXT_TREE
+ * A hierarchy where we keep directly parsed text */
+#define AUGEAS_TEXT_TREE "/text"
+
+/* Degine: AUGEAS_META_TEXT
+ * Information about directly parsed text */
+#define AUGEAS_META_TEXT AUGEAS_META_TREE AUGEAS_TEXT_TREE
+
 /* Define: AUGEAS_META_ROOT
  * The root directory */
 #define AUGEAS_META_ROOT AUGEAS_META_TREE "/root"
diff --git a/src/transform.c b/src/transform.c
index eda55ba..efc9637 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -200,12 +200,12 @@ void free_transform(struct transform *xform) {
     free(xform);
 }
 
-static char *err_path(const char *filename) {
+static char *err_path(const char *filename, const char *base) {
     char *result = NULL;
     if (filename == NULL)
-        pathjoin(&result, 2, AUGEAS_META_FILES, s_error);
+        pathjoin(&result, 2, base, s_error);
     else
-        pathjoin(&result, 3, AUGEAS_META_FILES, filename, s_error);
+        pathjoin(&result, 3, base, filename, s_error);
     return result;
 }
 
@@ -251,58 +251,83 @@ calc_line_ofs(const char *text, size_t pos, size_t *line, size_t *ofs)
 }
 
 /* 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
+ * ERROR_NODE. 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.
+ * clear any error associated with ERROR_NODE in the tree.
  */
 static int store_error(struct augeas *aug,
-                       const char *filename, const char *path,
+                       char **error_node, const char *path,
                        const char *status, int errnum,
                        const struct lns_error *err, const char *text) {
-    char *ep = err_path(filename);
     int r;
-    int result = -1;
-
-    if (ep == NULL)
-        return -1;
 
-    aug_rm(aug, ep);
+    aug_rm(aug, *error_node);
     if (status != NULL) {
-        r = aug_set(aug, ep, status);
+        r = aug_set(aug, *error_node, status);
         if (r < 0)
-            goto done;
+            return -1;
 
         /* Errors from err_set are ignored on purpose. We try
          * to report as much as we can */
         if (err != NULL) {
             if (err->pos >= 0) {
                 size_t line, ofs;
-                err_set(aug, &ep, s_pos, "%d", err->pos);
+                err_set(aug, error_node, s_pos, "%d", err->pos);
                 if (text != NULL) {
                     calc_line_ofs(text, err->pos, &line, &ofs);
-                    err_set(aug, &ep, s_line, "%zd", line);
-                    err_set(aug, &ep, s_char, "%zd", ofs);
+                    err_set(aug, error_node, s_line, "%zd", line);
+                    err_set(aug, error_node, s_char, "%zd", ofs);
                 }
             }
             if (err->path != NULL) {
-                err_set(aug, &ep, s_path, "%s%s", path, err->path);
+                err_set(aug, error_node, s_path, "%s%s", path, err->path);
             }
             if (err->lens != NULL) {
                 char *fi = format_info(err->lens->info);
                 if (fi != NULL) {
-                    err_set(aug, &ep, s_lens, "%s", fi);
+                    err_set(aug, error_node, s_lens, "%s", fi);
                     free(fi);
                 }
             }
-            err_set(aug, &ep, s_message, "%s", err->message);
+            err_set(aug, error_node, s_message, "%s", err->message);
         } else if (errnum != 0) {
             const char *msg = strerror(errnum);
-            err_set(aug, &ep, s_message, "%s", msg);
+            err_set(aug, error_node, s_message, "%s", msg);
         }
     }
 
-    result = 0;
- done:
+}
+
+/* Store an error associated to FILENAME under /augeas/FILENAME/error
+ */
+static int store_error_file(struct augeas *aug,
+                            const char *filename, const char *path,
+                            const char *status, int errnum,
+                            const struct lns_error *err, const char *text) {
+    char *ep = err_path(filename, AUGEAS_META_FILES);
+    int result = -1;
+
+    if (ep == NULL)
+        return -1;
+
+    result = store_error(aug, &ep, path, status, errnum, err, text);
+
+    free(ep);
+    return result;
+}
+
+static int store_error_string(struct augeas *aug,
+                              const char *string_name, const char *path,
+                              const char *status, int errnum,
+                              const struct lns_error *err, const char *text) {
+    char *ep = err_path(string_name, AUGEAS_META_TEXT);
+    int result = -1;
+
+    if (ep == NULL)
+        return -1;
+
+    result = store_error(aug, &ep, path, status, errnum, err, text);
+
     free(ep);
     return result;
 }
@@ -416,7 +441,7 @@ static int load_file(struct augeas *aug, struct lens *lens, char *filename) {
 
     result = 0;
  done:
-    store_error(aug, filename + strlen(aug->root) - 1, path, err_status,
+    store_error_file(aug, filename + strlen(aug->root) - 1, path, err_status,
                 errno, err, text);
     free_lns_error(err);
     free(path);
@@ -846,7 +871,7 @@ int transform_save(struct augeas *aug, struct tree *xfm,
     {
         const char *emsg =
             dyn_err_status == NULL ? err_status : dyn_err_status;
-        store_error(aug, filename, path, emsg, errno, err, NULL);
+        store_error_file(aug, filename, path, emsg, errno, err, NULL);
     }
     free(dyn_err_status);
     lens_release(lens);
@@ -934,7 +959,7 @@ int remove_file(struct augeas *aug, struct tree *tree) {
     {
         const char *emsg =
             dyn_err_status == NULL ? err_status : dyn_err_status;
-        store_error(aug, filename, path, emsg, errno, NULL, NULL);
+        store_error_file(aug, filename, path, emsg, errno, NULL, NULL);
     }
     free(path);
     free(augorig);
@@ -944,6 +969,50 @@ int remove_file(struct augeas *aug, struct tree *tree) {
     return -1;
 }
 
+int transform_string(struct augeas *aug, const char *lens_path, const char *basepath, 
+                     const char *txt, size_t txt_len) {
+    struct info *info = NULL;
+    struct lns_error *err = NULL;
+    struct tree *tree = NULL;
+    int result = -1;
+    const char *err_status = NULL;
+    struct lens *lens = NULL;
+    char *path = NULL;
+
+    pathjoin(&path, 2, AUGEAS_TEXT_TREE, basepath);
+
+    lens = lens_from_name(aug, lens_path);
+    if(lens == NULL) {
+        goto done;
+    }
+
+    make_ref(info);
+    info->first_line = 1;
+    info->last_line = 1;
+    info->first_column = 1;
+    info->last_column = txt_len;
+
+    tree = lns_get(info, lens, txt, &err);
+    if (err != NULL) {
+        err_status = "parse_failed";
+        goto done;
+    }
+
+    unref(info, info);
+
+    tree_replace(aug->origin, path, tree);
+    tree = NULL;
+
+    result = 0;
+done:
+    store_error_string(aug, basepath, path, err_status,
+                errno, err, txt);
+    free(path);
+    free_tree(tree);
+    free_lns_error(err);
+    return result;
+}
+
 /*
  * Local variables:
  *  indent-tabs-mode: nil
diff --git a/src/transform.h b/src/transform.h
index 1178f64..d6fb841 100644
--- a/src/transform.h
+++ b/src/transform.h
@@ -87,6 +87,10 @@ int transform_save(struct augeas *aug, struct tree *xfm,
  * Return 0 on success, -1 on failure
  */
 int remove_file(struct augeas *aug, struct tree *tree);
+
+int transform_string(struct augeas *aug, const char *lens, const char *basepath, 
+                     const char *txt, size_t txt_len);
+
 #endif
 
 
-- 
1.6.0.6


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]