[augeas-devel] augeas: master - Properly handle lenses that use L_REC lenses

David Lutterkort lutter at fedoraproject.org
Tue Jan 26 02:22:16 UTC 2010


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=ef83517f7fbce7d7bfe4fef800524c6af8459659
Commit:        ef83517f7fbce7d7bfe4fef800524c6af8459659
Parent:        f6efcbe9b36e30a58d558a88f868d3f97596b05a
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Mon Jan 25 17:04:15 2010 -0800
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Mon Jan 25 18:17:22 2010 -0800

Properly handle lenses that use L_REC lenses

In constructs involving a recursive lens, we need to take the body of the
recursive lens into consideration. We avoid infinite recursion by stopping
when we see an L_REC that is marked as rec_internal, since that's the
struct lens that points back to the top of the lens from within it.

jmt_build now expects to be handed a properly set up recursive lens, which
means that for an L_REC both the internal and external instances have to
exist and be connected

  * src/lens.c (lns_check_rec): defer building the jmt until the end
  * src/jmt.c: when building the jmt, consider L_REC as long as it's not
    internal
---
 src/jmt.c  |   12 +++---------
 src/lens.c |    8 ++++----
 2 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/jmt.c b/src/jmt.c
index 33119f4..a089748 100644
--- a/src/jmt.c
+++ b/src/jmt.c
@@ -1183,7 +1183,8 @@ static void index_lenses(struct jmt *jmt, struct lens *lens) {
         index_lenses(jmt, lens->child);
         break;
     case L_REC:
-        /* Nothing to do */
+        if (! lens->rec_internal)
+            index_lenses(jmt, lens->body);
         break;
     default:
         BUG_ON(true, jmt, "Unexpected lens tag %d", lens->tag);
@@ -1751,9 +1752,6 @@ static void determinize(struct jmt *jmt) {
 struct jmt *jmt_build(struct lens *lens) {
     struct jmt *jmt = NULL;
     int r;
-    ind_t l;
-
-    ensure(lens->tag == L_REC && lens->rec_internal, lens->info);
 
     r = ALLOC(jmt);
     ERR_NOMEM(r < 0, lens->info);
@@ -1761,11 +1759,7 @@ struct jmt *jmt_build(struct lens *lens) {
     jmt->error = lens->info->error;
     array_init(&jmt->lenses, sizeof(struct jmt_lens));
 
-    l = add_lens(jmt, lens);
-    ERR_BAIL(jmt);
-    ensure(l == 0, lens->info);
-
-    index_lenses(jmt, lens->body);
+    index_lenses(jmt, lens);
 
     if (debugging("cf.jmt"))
         print_grammar_top(jmt, lens);
diff --git a/src/lens.c b/src/lens.c
index be980c9..6ea21a4 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -2001,9 +2001,6 @@ struct value *lns_check_rec(struct info *info,
     if (result != NULL)
         goto error;
 
-    struct jmt *jmt = jmt_build(rec);
-    ERR_BAIL(info);
-
     result = lns_make_rec(ref(rec->info));
     struct lens *top = result->lens;
     for (int t=0; t < ntypes; t++)
@@ -2017,10 +2014,13 @@ struct value *lns_check_rec(struct info *info,
     top->rec_internal = 0;
     rec->alias = top;
 
-    top->jmt = jmt;
+    top->jmt = jmt_build(top);
+    ERR_BAIL(info);
 
     return result;
  error:
+    if (result != NULL && result->tag != V_EXN)
+        unref(result, value);
     if (result == NULL)
         result = exn_error();
     return result;




More information about the augeas-devel mailing list