[augeas-devel] augeas: master - Pretty-print lens atypes and use that for errors during put

David Lutterkort lutter at fedoraproject.org
Tue Sep 1 18:09:24 UTC 2009


Gitweb:        http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=78ec63424d1819e253004339f2e32603083ac29a
Commit:        78ec63424d1819e253004339f2e32603083ac29a
Parent:        f218d05899362615124cfab574cef888b3cefff2
Author:        David Lutterkort <lutter at redhat.com>
AuthorDate:    Tue Aug 25 16:08:29 2009 -0700
Committer:     David Lutterkort <lutter at redhat.com>
CommitterDate: Mon Aug 31 14:39:56 2009 -0700

Pretty-print lens atypes and use that for errors during put

* src/lens.c (lns_format_atype): new function
* src/lens.h (lns_format_atype): new prototype
* src/put.c (regexp_match_error): use lns_format_atype for errors
---
 src/lens.c |  182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lens.h |    4 +
 src/put.c  |   26 +++++----
 3 files changed, 201 insertions(+), 11 deletions(-)

diff --git a/src/lens.c b/src/lens.c
index 7342a48..b6c8769 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -716,6 +716,188 @@ char *enc_format(const char *e, size_t len) {
     return result;
 }
 
+static int lns_format_subtree_atype(struct lens *l, char **buf) {
+    char *k = NULL, *v = NULL;
+    const struct regexp *ktype = l->child->ktype;
+    const struct regexp *vtype = l->child->vtype;
+    int r, result = -1;
+
+    if (ktype != NULL) {
+        k = regexp_escape(ktype);
+        if (k == NULL)
+            goto done;
+    }
+    if (vtype != NULL) {
+        v = regexp_escape(vtype);
+        if (v == NULL)
+            goto done;
+        if (k == NULL)
+            r = xasprintf(buf, "{ = /%s/ }", k, v);
+        else
+            r = xasprintf(buf, "{ /%s/ = /%s/ }", k, v);
+    } else {
+        if (k == NULL)
+            r = xasprintf(buf, "{ }", k);
+        else
+            r = xasprintf(buf, "{ /%s/ }", k);
+    }
+    if (r < 0)
+        goto done;
+
+    result = 0;
+ done:
+    FREE(v);
+    FREE(k);
+    return result;
+}
+
+static int lns_format_rep_atype(struct lens *l, char **buf, char quant) {
+    char *a = NULL;
+    int r, result = -1;
+
+    r = lns_format_atype(l->child, &a);
+    if (r < 0)
+        goto done;
+    if (strlen(a) == 0) {
+        *buf = a;
+        a = NULL;
+        result = 0;
+        goto done;
+    }
+
+    if (l->child->tag == L_CONCAT || l->child->tag == L_UNION)
+        r = xasprintf(buf, "(%s)%c", a, quant);
+    else
+        r = xasprintf(buf, "%s%c", a, quant);
+
+    if (r < 0)
+        goto done;
+
+    result = 0;
+ done:
+    FREE(a);
+    return result;
+}
+
+static int lns_format_concat_atype(struct lens *l, char **buf) {
+    char **c = NULL, *s = NULL, *p;
+    int r, result = -1;
+    size_t len = 0, nconc = 0;
+
+    if (ALLOC_N(c, l->nchildren) < 0)
+        goto done;
+
+    for (int i=0; i < l->nchildren; i++) {
+        r = lns_format_atype(l->children[i], c+i);
+        if (r < 0)
+            goto done;
+        len += strlen(c[i]) + 2;
+        if (strlen(c[i]) > 0)
+            nconc += 1;
+        if (l->children[i]->tag == L_UNION)
+            len += 2;
+    }
+
+    if (ALLOC_N(s, len+1) < 0)
+        goto done;
+    p = s;
+    for (int i=0; i < l->nchildren; i++) {
+        bool needs_parens = nconc > 1 && l->children[i]->tag == L_UNION;
+        if (strlen(c[i]) == 0)
+            continue;
+        if (needs_parens)
+            *p++ = '(';
+        p = stpcpy(p, c[i]);
+        if (needs_parens)
+            *p++ = ')';
+    }
+
+    *buf = s;
+    s = NULL;
+    result = 0;
+ done:
+    if (c != NULL)
+        for (int i=0; i < l->nchildren; i++)
+            FREE(c[i]);
+    FREE(c);
+    FREE(s);
+    return result;
+}
+
+static int lns_format_union_atype(struct lens *l, char **buf) {
+    char **c = NULL, *s = NULL, *p;
+    int r, result = -1;
+    size_t len = 0;
+
+    if (ALLOC_N(c, l->nchildren) < 0)
+        goto done;
+
+    for (int i=0; i < l->nchildren; i++) {
+        r = lns_format_atype(l->children[i], c+i);
+        if (r < 0)
+            goto done;
+        len += strlen(c[i]) + 2;
+    }
+    len += l->nchildren - 1;
+
+    if (ALLOC_N(s, len+1) < 0)
+        goto done;
+
+    p = s;
+    for (int i=0; i < l->nchildren; i++) {
+        if (i > 0)
+            p = stpcpy(p, " | ");
+        if (strlen(c[i]) == 0)
+            p = stpcpy(p, "()");
+        else
+            p = stpcpy(p, c[i]);
+    }
+    *buf = s;
+    s = NULL;
+    result = 0;
+ done:
+    if (c != NULL)
+        for (int i=0; i < l->nchildren; i++)
+            FREE(c[i]);
+    FREE(c);
+    FREE(s);
+    return result;
+}
+
+int lns_format_atype(struct lens *l, char **buf) {
+    *buf = NULL;
+
+    switch(l->tag) {
+    case L_DEL:
+    case L_STORE:
+    case L_KEY:
+    case L_LABEL:
+    case L_SEQ:
+    case L_COUNTER:
+        *buf = strdup("");
+        return (*buf == NULL) ? -1 : 0;
+        break;
+    case L_SUBTREE:
+        return lns_format_subtree_atype(l, buf);
+        break;
+    case L_STAR:
+        return lns_format_rep_atype(l, buf, '*');
+        break;
+    case L_MAYBE:
+        return lns_format_rep_atype(l, buf, '?');
+        break;
+    case L_CONCAT:
+        return lns_format_concat_atype(l, buf);
+        break;
+    case L_UNION:
+        return lns_format_union_atype(l, buf);
+        break;
+    default:
+        assert(0);
+        break;
+    };
+}
+
 /*
  * Local variables:
  *  indent-tabs-mode: nil
diff --git a/src/lens.h b/src/lens.h
index 32af92d..7f9e30d 100644
--- a/src/lens.h
+++ b/src/lens.h
@@ -96,6 +96,10 @@ struct value *lns_make_plus(struct info *, struct lens *,
 struct value *lns_make_maybe(struct info *, struct lens *,
                              int check);
 
+/* Pretty-print the atype of a lens. Allocates BUF, which must be freed by
+ * the caller */
+int lns_format_atype(struct lens *, char **buf);
+
 /* Auxiliary data structures used during get/put/create */
 struct skel {
     struct skel *next;
diff --git a/src/put.c b/src/put.c
index 7d725e5..fe3df39 100644
--- a/src/put.c
+++ b/src/put.c
@@ -107,22 +107,26 @@ static char *encpcpy(char *e, const char *key, const char *value) {
 }
 
 static void regexp_match_error(struct state *state, struct lens *lens,
-                               int count, struct split *split,
-                               struct regexp *r) {
+                               int count, struct split *split) {
     // FIXME: Split the regexp and encoding back
     // into something resembling a tree level
-    char *text = strndup(split->enc + split->start,
-                         split->end - split->start);
-    char *pat = regexp_escape(r);
+    char *text = NULL;
+    char *pat = NULL;
+
+    lns_format_atype(lens, &pat);
+    text = enc_format(split->enc + split->start, split->end - split->start);
 
     if (count == -1) {
-        put_error(state, lens, "Failed to match /%s/ with %s", pat, enc_format(text, strlen(text)));
+        put_error(state, lens,
+                  "Failed to match \n    %s\n  with tree\n   %s",
+                  pat, text);
     } else if (count == -2) {
-        put_error(state, lens, "Internal error matching /%s/ with %s",
+        put_error(state, lens,
+                  "Internal error matching\n    %s\n  with tree\n   %s",
                   pat, text);
     } else if (count == -3) {
         /* Should have been caught by the typechecker */
-        put_error(state, lens, "Syntax error in regexp /%s/", pat);
+        put_error(state, lens, "Syntax error in tree schema\n    %s", pat);
     }
     free(pat);
     free(text);
@@ -219,7 +223,7 @@ static struct split *split_concat(struct state *state, struct lens *lens) {
     if (count >= 0 && count != outer->end - outer->start)
         count = -1;
     if (count < 0) {
-        regexp_match_error(state, lens, count, outer, atype);
+        regexp_match_error(state, lens, count, outer);
         return NULL;
     }
 
@@ -260,7 +264,7 @@ static struct split *split_iter(struct state *state, struct lens *lens) {
         if (count == -1) {
             break;
         } else if (count < -1) {
-            regexp_match_error(state, lens, count, outer, atype);
+            regexp_match_error(state, lens->child, count, outer);
             goto error;
         }
 
@@ -288,7 +292,7 @@ static int applies(struct lens *lens, struct state *state) {
     count = regexp_match(lens->atype, split->enc, split->end,
                          split->start, NULL);
     if (count < -1) {
-        regexp_match_error(state, lens, count, split, lens->atype);
+        regexp_match_error(state, lens, count, split);
         return 0;
     }
 




More information about the augeas-devel mailing list