[augeas-devel] augeas: master - Carry the key type explicitly in lenses
David Lutterkort
lutter at fedoraproject.org
Tue Sep 1 18:09:13 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=c2ff7ee84c402bc88b1ef74cbb381b1c30541246
Commit: c2ff7ee84c402bc88b1ef74cbb381b1c30541246
Parent: eab014ed4358eb9d45bcea2c772526afbe2fe8bb
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Sun Dec 14 23:51:34 2008 -0800
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Mon Aug 31 14:36:27 2009 -0700
Carry the key type explicitly in lenses
Instead of computing the key type recursively, store it in lens->ktype. The
key type becomes the new abstract type (atype) when a lens is used inside a
subtree combinator.
---
src/lens.c | 156 +++++++++----------------------
src/lens.h | 1 +
tests/modules/fail_multi_key_concat.aug | 3 +
tests/modules/fail_multi_key_iter.aug | 4 +
4 files changed, 52 insertions(+), 112 deletions(-)
diff --git a/src/lens.c b/src/lens.c
index 295baef..255ecc6 100644
--- a/src/lens.c
+++ b/src/lens.c
@@ -32,7 +32,6 @@ static struct value *typecheck_concat(struct info *,
static struct value *typecheck_iter(struct info *info, struct lens *l);
static struct value *typecheck_maybe(struct info *info, struct lens *l);
-static struct regexp *lns_key_regexp(struct lens *l, struct value **exn);
static struct regexp *make_key_regexp(struct info *info, const char *pat);
/* Lens names for pretty printing */
@@ -41,6 +40,11 @@ static const char *const tags[] = {
"subtree", "star", "maybe"
};
+static const struct string digits_string = {
+ .ref = REF_MAX, .str = (char *) "[0-9]+/"
+};
+static const struct string *const digits_pat = &digits_string;
+
/* Construct a finite automaton from REGEXP and return it in *FA.
*
* Return NULL if REGEXP is valid, if the regexp REGEXP has syntax errors,
@@ -149,6 +153,10 @@ static struct lens *make_lens_binop(enum lens_tag tag, struct info *info,
types[i] = lens->children[i]->atype;
lens->atype = (*combinator)(info, lens->nchildren, types);
+ for (int i=0; i < lens->nchildren; i++)
+ types[i] = lens->children[i]->ktype;
+ lens->ktype = (*combinator)(info, lens->nchildren, types);
+
FREE(types);
for (int i=0; i < lens->nchildren; i++)
@@ -207,16 +215,10 @@ struct value *lns_make_concat(struct info *info,
struct value *lns_make_subtree(struct info *info, struct lens *l) {
struct lens *lens;
- struct value *exn;
- struct regexp *atype;
-
- atype = lns_key_regexp(l, &exn);
- if (exn != NULL)
- return exn;
lens = make_lens_unop(L_SUBTREE, info, l);
lens->ctype = ref(l->ctype);
- lens->atype = atype;
+ lens->atype = ref(l->ktype);
lens->value = lens->key = 0;
if (lens->atype == NULL)
lens->atype = make_key_regexp(info, "");
@@ -242,6 +244,7 @@ struct value *lns_make_star(struct info *info, struct lens *l, int check) {
lens = make_lens_unop(L_STAR, info, l);
lens->ctype = regexp_iter(info, l->ctype, 0, -1);
lens->atype = regexp_iter(info, l->atype, 0, -1);
+ lens->ktype = regexp_iter(info, l->ktype, 0, -1);
return make_lens_value(lens);
}
@@ -269,6 +272,7 @@ struct value *lns_make_maybe(struct info *info, struct lens *l, int check) {
lens = make_lens_unop(L_MAYBE, info, l);
lens->ctype = regexp_maybe(info, l->ctype);
lens->atype = regexp_maybe(info, l->atype);
+ lens->ktype = regexp_maybe(info, l->ktype);
lens->value = l->value;
lens->key = l->key;
return make_lens_value(lens);
@@ -277,6 +281,18 @@ struct value *lns_make_maybe(struct info *info, struct lens *l, int check) {
/*
* Lens primitives
*/
+
+static struct regexp *make_regexp_from_string(struct info *info,
+ struct string *string) {
+ struct regexp *r;
+ make_ref(r);
+ if (r != NULL) {
+ r->info = ref(info);
+ r->pattern = ref(string);
+ }
+ return r;
+}
+
struct value *lns_make_prim(enum lens_tag tag, struct info *info,
struct regexp *regexp, struct string *string) {
struct lens *lens = NULL;
@@ -337,6 +353,7 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
lens->value = (tag == L_STORE);
lens->consumes_value = (tag == L_STORE);
lens->atype = regexp_make_empty(info);
+ /* Set the ctype */
if (tag == L_DEL || tag == L_STORE || tag == L_KEY) {
lens->ctype = ref(regexp);
} else if (tag == L_LABEL || tag == L_SEQ || tag == L_COUNTER) {
@@ -344,6 +361,25 @@ struct value *lns_make_prim(enum lens_tag tag, struct info *info,
} else {
assert(0);
}
+
+ /* Set the ktype */
+ if (tag == L_SEQ) {
+ lens->ktype =
+ make_regexp_from_string(info, (struct string *) digits_pat);
+ } else if (tag == L_KEY) {
+ lens->ktype = make_key_regexp(info, lens->regexp->pattern->str);
+ } else if (tag == L_LABEL) {
+ struct regexp *r = make_regexp_literal(info, lens->string->str);
+ if (r == NULL)
+ goto error;
+ if (REALLOC_N(r->pattern->str, strlen(r->pattern->str) + 2) == -1) {
+ unref(r, regexp);
+ goto error;
+ }
+ strcat(r->pattern->str, "/");
+ lens->ktype = r;
+ }
+
return make_lens_value(lens);
error:
fa_free(fa_isect);
@@ -551,110 +587,6 @@ static struct regexp *make_key_regexp(struct info *info, const char *pat) {
return regexp;
}
-static struct regexp *make_regexp_from_string(struct info *info,
- struct string *string) {
- struct regexp *r;
- make_ref(r);
- if (r != NULL) {
- r->info = ref(info);
- r->pattern = ref(string);
- }
- return r;
-}
-
-/* Calculate the regexp that matches the labels if the trees that L can
- generate.
-
- We have some headache here because of the behavior of STORE: since STORE
- creates a tree with no label (a leaf, really), its key regexp should be
- "/", but only of there is no KEY or LABEL statement that fills in the
- label of the tree that STORE created.
- */
-static struct regexp *lns_key_regexp(struct lens *l, struct value **exn) {
- static const struct string digits_string = {
- .ref = REF_MAX, .str = (char *) "[0-9]+/"
- };
- static const struct string *const digits_pat = &digits_string;
-
- *exn = NULL;
- switch(l->tag) {
- case L_STORE:
- case L_DEL:
- case L_COUNTER:
- return NULL;
- case L_SEQ:
- return make_regexp_from_string(l->info, (struct string *) digits_pat);
- case L_KEY:
- return make_key_regexp(l->info, l->regexp->pattern->str);
- case L_LABEL:
- {
- struct regexp *r = make_regexp_literal(l->info, l->string->str);
- if (r == NULL)
- return NULL;
- if (REALLOC_N(r->pattern->str, strlen(r->pattern->str) + 2) == -1) {
- unref(r, regexp);
- return NULL;
- }
- strcat(r->pattern->str, "/");
- return r;
- }
- case L_CONCAT:
- {
- struct regexp *k = NULL;
- for (int i=0; i < l->nchildren; i++) {
- struct regexp *r = lns_key_regexp(l->children[i], exn);
- if (*exn != NULL) {
- free_regexp(k);
- return NULL;
- }
- if (r != NULL) {
- if (k != NULL) {
- *exn = make_exn_value(ref(l->info),
- "More than one key");
- unref(r, regexp);
- unref(k, regexp);
- return NULL;
- } else {
- k = r;
- }
- }
- }
- return k;
- }
- break;
- case L_UNION:
- {
- struct regexp *k = NULL;
- for (int i=0; i < l->nchildren; i++) {
- struct regexp *r = lns_key_regexp(l->children[i], exn);
- if (*exn != NULL)
- return NULL;
- if (r != NULL) {
- if (k == NULL) {
- k = r;
- } else {
- struct regexp *u = regexp_union(l->info, k, r);
- unref(k, regexp);
- unref(r, regexp);
- k = u;
- }
- }
- }
- return k;
- }
- break;
- case L_SUBTREE:
- return NULL;
- break;
- case L_STAR:
- case L_MAYBE:
- return lns_key_regexp(l->child, exn);
- default:
- assert(0);
- }
- return NULL;
-}
-
void free_lens(struct lens *lens) {
if (lens == NULL)
return;
diff --git a/src/lens.h b/src/lens.h
index a8a0f9e..37fc26c 100644
--- a/src/lens.h
+++ b/src/lens.h
@@ -46,6 +46,7 @@ struct lens {
struct info *info;
struct regexp *ctype;
struct regexp *atype;
+ struct regexp *ktype;
unsigned int value : 1;
unsigned int key : 1;
unsigned int consumes_value : 1;
diff --git a/tests/modules/fail_multi_key_concat.aug b/tests/modules/fail_multi_key_concat.aug
new file mode 100644
index 0000000..7a3b147
--- /dev/null
+++ b/tests/modules/fail_multi_key_concat.aug
@@ -0,0 +1,3 @@
+module Fail_multi_key_concat =
+
+ let lns = key /a/ . key /b/
diff --git a/tests/modules/fail_multi_key_iter.aug b/tests/modules/fail_multi_key_iter.aug
new file mode 100644
index 0000000..c333626
--- /dev/null
+++ b/tests/modules/fail_multi_key_iter.aug
@@ -0,0 +1,4 @@
+module Fail_multi_key_iter =
+
+ let lns = ( key /a/ ) *
+
More information about the augeas-devel
mailing list