[augeas-devel] [PATCH 8/8] path expressions: allow concatenating strings and regexps with '+'
lutter at redhat.com
lutter at redhat.com
Sat May 7 01:12:56 UTC 2011
From: David Lutterkort <lutter at redhat.com>
---
src/pathx.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
tests/xpath.tests | 3 +++
2 files changed, 53 insertions(+), 1 deletions(-)
diff --git a/src/pathx.c b/src/pathx.c
index aadc449..e68580c 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -913,6 +913,42 @@ static void eval_union(struct state *state) {
push_value(vind, state);
}
+static void eval_concat_string(struct state *state) {
+ value_ind_t vind = make_value(T_STRING, state);
+ struct value *r = pop_value(state);
+ struct value *l = pop_value(state);
+ char *res = NULL;
+
+ CHECK_ERROR;
+
+ if (ALLOC_N(res, strlen(l->string) + strlen(r->string) + 1) < 0) {
+ STATE_ENOMEM;
+ return;
+ }
+ strcpy(res, l->string);
+ strcat(res, r->string);
+ state->value_pool[vind].string = res;
+ push_value(vind, state);
+}
+
+static void eval_concat_regexp(struct state *state) {
+ value_ind_t vind = make_value(T_REGEXP, state);
+ struct value *r = pop_value(state);
+ struct value *l = pop_value(state);
+ struct regexp *rx = NULL;
+
+ CHECK_ERROR;
+
+ rx = regexp_concat(state->error->info, l->regexp, r->regexp);
+ if (rx == NULL) {
+ STATE_ENOMEM;
+ return;
+ }
+
+ state->value_pool[vind].regexp = rx;
+ push_value(vind, state);
+}
+
static void eval_re_match(struct state *state, enum binary_op op) {
struct value *rx = pop_value(state);
struct value *v = pop_value(state);
@@ -958,8 +994,15 @@ static void eval_binary(struct expr *expr, struct state *state) {
case OP_GE:
eval_rel(state, true, true);
break;
- case OP_MINUS:
case OP_PLUS:
+ if (expr->type == T_NUMBER)
+ eval_arith(state, expr->op);
+ else if (expr->type == T_STRING)
+ eval_concat_string(state);
+ else if (expr->type == T_REGEXP)
+ eval_concat_regexp(state);
+ break;
+ case OP_MINUS:
case OP_STAR:
eval_arith(state, expr->op);
break;
@@ -1274,6 +1317,9 @@ static void check_app(struct expr *expr, struct state *state) {
* '>', '>=',
* '<', '<=' : T_NUMBER -> T_NUMBER -> T_BOOLEAN
* T_STRING -> T_STRING -> T_BOOLEAN
+ * '+' : T_NUMBER -> T_NUMBER -> T_NUMBER
+ * T_STRING -> T_STRING -> T_STRING
+ * T_REGEXP -> T_REGEXP -> T_REGEXP
* '+', '-', '*': T_NUMBER -> T_NUMBER -> T_NUMBER
*
* 'and', 'or': T_BOOLEAN -> T_BOOLEAN -> T_BOOLEAN
@@ -1311,6 +1357,9 @@ static void check_binary(struct expr *expr, struct state *state) {
res = T_BOOLEAN;
break;
case OP_PLUS:
+ ok = (l == r && (l == T_NUMBER || l == T_STRING || l == T_REGEXP));
+ res = l;
+ break;
case OP_MINUS:
case OP_STAR:
ok = (l == T_NUMBER && r == T_NUMBER);
diff --git a/tests/xpath.tests b/tests/xpath.tests
index 8071568..e2c8ee7 100644
--- a/tests/xpath.tests
+++ b/tests/xpath.tests
@@ -248,6 +248,9 @@ test glob4 /augeas/load/*[ '/etc/hosts' =~ glob(incl) ]
test glob_nomatch /files/etc/hosts/*[ipaddr][ ipaddr !~ glob(/files/etc/hosts/*/ipaddr[1]) ]
/files/etc/hosts/2
+test glob_for_lens /augeas/load/*[ '/etc/hosts/1/ipaddr' =~ glob(incl) + regexp('/.*') ]/lens
+ /augeas/load/Hosts/lens = @Hosts
+
# Union of nodesets
test union (/files/etc/yum.conf | /files/etc/yum.repos.d/*)/*/gpgcheck
/files/etc/yum.conf/main/gpgcheck = 1
--
1.7.4.4
More information about the augeas-devel
mailing list