[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