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

[augeas-devel] aug_lens_get



Hello,

after some discussion with David off-list, we agreed that Augeas should
grow the functionality to operate not only on files but also on any
arbitrary string input - think parsing text that comes from a DB or LDAP
or even input.

The attached patch implements this via an aug_lens_get() function that
is an addition to the public API. The parsed string goes into (newly
created) /augeas/text hierarchy, the node is specified as a parameter of
aug_lens. 

For example:
augtool> lens_get /test @Hosts "192.168.122.149 ipaserver server.ipadev"
augtool> print /augeas/text/test
/augeas/text/test
/augeas/text/test/1
/augeas/text/test/1/ipaddr = "192.168.122.149"
/augeas/text/test/1/canonical = "ipaserver"
/augeas/text/test/1/alias = "server.ipadev"
augtool> 


The next step would be an inverse function aug_lens_put() that actually
lets you modify the tree and squash it back into a string.

The patch is not completely correct - I spent some time trying to get it
right but figured that it would be faster to ask here..the thing is,
that it crashes on subsequent invocations (tested from augtool) on the
lns_get() call. 

Because it's on subsequent calls, I presume I'm reusing something I
shouldn't or similar..but I couldn't figure why myself quickly since all
lns_get() are parameters from user or local variables, so I thought it
might actually be better to ask Augeas hackers on this list.

Thanks for any comments,
Jakub

>From 714dde9556a082f31344b48b52210e465d1dea30 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek redhat com>
Date: Mon, 23 Mar 2009 19:08:31 +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         |    4 ++++
 src/transform.c        |   45 +++++++++++++++++++++++++++++++++++++++++++++
 src/transform.h        |    4 ++++
 7 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/src/augeas.c b/src/augeas.c
index 60460ba..d22ae5d 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -921,6 +921,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 73deafe..44e756b 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -212,6 +212,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 e479d13..cbbe04f 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -11,6 +11,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 f7ea46e..a6e706b 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -219,6 +219,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]));
 }
@@ -389,6 +402,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> <MODULE> <TEXT>",
+      "Parse text according to MOFULE 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 407f184..2b7dbb6 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -59,6 +59,10 @@
  * 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 AUGEAS_META_TREE "/text"
+
 /* 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 2675f23..d29896d 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -943,6 +943,51 @@ 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 || tree == NULL) {
+        err_status = "parse_failed";
+        goto done;
+    }
+
+    unref(info, info);
+
+    tree_replace(aug->origin, path, tree);
+    tree = NULL;
+
+    result = 0;
+done:
+    store_error(aug, basepath, path, err_status,
+                errno, err, txt);
+    FREE(lens);
+    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]