[augeas-devel] [PATCH] New primitive lens 'value'

lutter at redhat.com lutter at redhat.com
Fri Jan 15 19:34:04 UTC 2010


From: David Lutterkort <lutter at redhat.com>

In analogy to 'label', this lens allows setting the value of a tree node to
a fixed string
---
 src/builtin.c                      |    7 +++++++
 src/get.c                          |   18 ++++++++++++++++++
 src/lens.c                         |    9 ++++++---
 src/lens.h                         |    3 ++-
 src/put.c                          |    4 ++++
 tests/modules/pass_label_value.aug |    7 +++++++
 6 files changed, 44 insertions(+), 4 deletions(-)
 create mode 100644 tests/modules/pass_label_value.aug

diff --git a/src/builtin.c b/src/builtin.c
index 1d61a7a..78593fe 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -56,6 +56,12 @@ static struct value *lns_store(struct info *info, struct value *rxp) {
     return lns_make_prim(L_STORE, ref(info), ref(rxp->regexp), NULL);
 }
 
+/* V_STRING -> V_LENS */
+static struct value *lns_value(struct info *info, struct value *str) {
+    assert(str->tag == V_STRING);
+    return lns_make_prim(L_VALUE, ref(info), NULL, ref(str->string));
+}
+
 /* V_REGEXP -> V_LENS */
 static struct value *lns_key(struct info *info, struct value *rxp) {
     assert(rxp->tag == V_REGEXP);
@@ -456,6 +462,7 @@ struct module *builtin_init(struct error *error) {
     /* Primitive lenses */
     DEFINE_NATIVE(modl, "del",     2, lns_del, T_REGEXP, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "store",   1, lns_store, T_REGEXP, T_LENS);
+    DEFINE_NATIVE(modl, "value",   1, lns_value, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "key",     1, lns_key, T_REGEXP, T_LENS);
     DEFINE_NATIVE(modl, "label",   1, lns_label, T_STRING, T_LENS);
     DEFINE_NATIVE(modl, "seq",     1, lns_seq, T_STRING, T_LENS);
diff --git a/src/get.c b/src/get.c
index cdddd7a..1d51f94 100644
--- a/src/get.c
+++ b/src/get.c
@@ -420,6 +420,18 @@ static struct skel *parse_store(struct lens *lens,
     return make_skel(lens);
 }
 
+static struct tree *get_value(struct lens *lens, struct state *state) {
+    assert(lens->tag == L_VALUE);
+    state->value = strdup(lens->string->str);
+    return NULL;
+}
+
+static struct skel *parse_value(struct lens *lens,
+                                ATTRIBUTE_UNUSED struct state *state) {
+    assert(lens->tag == L_VALUE);
+    return make_skel(lens);
+}
+
 static struct tree *get_key(struct lens *lens, struct state *state) {
     assert(lens->tag == L_KEY);
     if (! REG_MATCHED(state))
@@ -1043,6 +1055,9 @@ static struct tree *get_lens(struct lens *lens, struct state *state) {
     case L_STORE:
         tree = get_store(lens, state);
         break;
+    case L_VALUE:
+        tree = get_value(lens, state);
+        break;
     case L_KEY:
         tree = get_key(lens, state);
         break;
@@ -1169,6 +1184,9 @@ static struct skel *parse_lens(struct lens *lens, struct state *state,
     case L_STORE:
         skel = parse_store(lens, state);
         break;
+    case L_VALUE:
+        skel = parse_value(lens, state);
+        break;
     case L_KEY:
         skel = parse_key(lens, state);
         break;
diff --git a/src/lens.c b/src/lens.c
index 85d3932..40942c7 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -472,14 +472,15 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
     lens->regexp = regexp;
     lens->string = string;
     lens->key = (tag == L_KEY || tag == L_LABEL || tag == L_SEQ);
-    lens->value = (tag == L_STORE);
-    lens->consumes_value = (tag == L_STORE);
+    lens->value = (tag == L_STORE || tag == L_VALUE);
+    lens->consumes_value = (tag == L_STORE || tag == L_VALUE);
     lens->atype = regexp_make_empty(info);
     /* Set the ctype */
     if (tag == L_DEL || tag == L_STORE || tag == L_KEY) {
         lens->ctype = ref(regexp);
         lens->ctype_nullable = regexp_matches_empty(lens->ctype);
-    } else if (tag == L_LABEL || tag == L_SEQ || tag == L_COUNTER) {
+    } else if (tag == L_LABEL || tag == L_VALUE
+               || tag == L_SEQ || tag == L_COUNTER) {
         lens->ctype = regexp_make_empty(info);
         lens->ctype_nullable = 1;
     } else {
@@ -761,6 +762,7 @@ void free_lens(struct lens *lens) {
     case L_LABEL:
     case L_SEQ:
     case L_COUNTER:
+    case L_VALUE:
         unref(lens->string, string);
         break;
     case L_SUBTREE:
@@ -1027,6 +1029,7 @@ int lns_format_atype(struct lens *l, char **buf) {
     case L_STORE:
     case L_KEY:
     case L_LABEL:
+    case L_VALUE:
     case L_SEQ:
     case L_COUNTER:
         *buf = strdup("");
diff --git a/src/lens.h b/src/lens.h
index e5a59bd..9742c87 100644
--- a/src/lens.h
+++ b/src/lens.h
@@ -30,6 +30,7 @@
 enum lens_tag {
     L_DEL = 42,    /* Shift tag values so we fail fast(er) on bad pointers */
     L_STORE,
+    L_VALUE,
     L_KEY,
     L_LABEL,
     L_SEQ,
@@ -84,7 +85,7 @@ struct lens {
         /* Primitive lenses */
         struct {                   /* L_DEL uses both */
             struct regexp *regexp; /* L_STORE, L_KEY */
-            struct string *string; /* L_LABEL, L_SEQ, L_COUNTER */
+            struct string *string; /* L_VALUE, L_LABEL, L_SEQ, L_COUNTER */
         };
         /* Combinators */
         struct lens *child;         /* L_SUBTREE, L_STAR, L_MAYBE */
diff --git a/src/put.c b/src/put.c
index 16026cd..35bcd2e 100644
--- a/src/put.c
+++ b/src/put.c
@@ -370,6 +370,8 @@ static int skel_instance_of(struct lens *lens, struct skel *skel) {
         return skel->tag == L_KEY;
     case L_LABEL:
         return skel->tag == L_LABEL;
+    case L_VALUE:
+        return skel->tag == L_VALUE;
     case L_SEQ:
         return skel->tag == L_SEQ;
     case L_COUNTER:
@@ -575,6 +577,7 @@ static void put_lens(struct lens *lens, struct state *state) {
         fprintf(state->out, "%s", state->key);
         break;
     case L_LABEL:
+    case L_VALUE:
         /* Nothing to do */
         break;
     case L_SEQ:
@@ -694,6 +697,7 @@ static void create_lens(struct lens *lens, struct state *state) {
         fprintf(state->out, "%s", state->key);
         break;
     case L_LABEL:
+    case L_VALUE:
         /* Nothing to do */
         break;
     case L_SEQ:
diff --git a/tests/modules/pass_label_value.aug b/tests/modules/pass_label_value.aug
new file mode 100644
index 0000000..ffc72f0
--- /dev/null
+++ b/tests/modules/pass_label_value.aug
@@ -0,0 +1,7 @@
+module Pass_label_value =
+
+let l = [ label "label" . value "value" ]
+
+test l get "" = { "label" = "value" }
+
+test l put "" after rm "/foo" = ""
-- 
1.6.5.2




More information about the augeas-devel mailing list