[augeas-devel] augeas: master - * src/pathx.c: add 'and' and 'or' operators
David Lutterkort
lutter at fedoraproject.org
Thu Feb 19 20:05:53 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=568860264e88e688e85832a94b545eb4d155f3d4
Commit: 568860264e88e688e85832a94b545eb4d155f3d4
Parent: 754bce2ecc8d7255674354d494fe3d926dd31059
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Wed Feb 18 13:17:13 2009 -0800
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Wed Feb 18 14:58:45 2009 -0800
* src/pathx.c: add 'and' and 'or' operators
---
src/pathx.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++-
tests/xpath.tests | 3 ++
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/src/pathx.c b/src/pathx.c
index b9e0781..b68085d 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -69,7 +69,9 @@ enum binary_op {
OP_GE, /* '>=' */
OP_PLUS, /* '+' */
OP_MINUS, /* '-' */
- OP_STAR /* '*' */
+ OP_STAR, /* '*' */
+ OP_AND, /* 'and' */
+ OP_OR /* 'or' */
};
struct pred {
@@ -580,6 +582,16 @@ static void eval_rel(struct state *state, bool greater, bool equal) {
push_boolean_value(res, state);
}
+static void eval_and_or(struct state *state, enum binary_op op) {
+ struct value *r = pop_value(state);
+ struct value *l = pop_value(state);
+
+ if (op == OP_AND)
+ push_boolean_value(l->boolval && r->boolval, state);
+ else
+ push_boolean_value(l->boolval || r->boolval, state);
+}
+
static void eval_binary(struct expr *expr, struct state *state) {
eval_expr(expr->left, state);
eval_expr(expr->right, state);
@@ -609,6 +621,10 @@ static void eval_binary(struct expr *expr, struct state *state) {
case OP_STAR:
eval_arith(state, expr->op);
break;
+ case OP_AND:
+ case OP_OR:
+ eval_and_or(state, expr->op);
+ break;
default:
assert(0);
}
@@ -830,6 +846,8 @@ static void check_app(struct expr *expr, struct state *state) {
* T_STRING -> T_STRING -> T_BOOLEAN
* '+', '-', '*': T_NUMBER -> T_NUMBER -> T_NUMBER
*
+ * 'and', 'or': T_BOOLEAN -> T_BOOLEAN -> T_BOOLEAN
+ *
*/
static void check_binary(struct expr *expr, struct state *state) {
check_expr(expr->left, state);
@@ -863,6 +881,11 @@ static void check_binary(struct expr *expr, struct state *state) {
ok = (l == T_NUMBER && r == T_NUMBER);
res = T_NUMBER;
break;
+ case OP_AND:
+ case OP_OR:
+ ok = (l == T_BOOLEAN && r == T_BOOLEAN);
+ res = T_BOOLEAN;
+ break;
default:
assert(0);
}
@@ -1475,11 +1498,42 @@ static void parse_equality_expr(struct state *state) {
}
/*
+ * AndExpr ::= EqualityExpr ('and' EqualityExpr)*
+ */
+static void parse_and_expr(struct state *state) {
+ parse_equality_expr(state);
+ CHECK_ERROR;
+ while (*state->pos == 'a' && state->pos[1] == 'n'
+ && state->pos[2] == 'd') {
+ state->pos += 3;
+ skipws(state);
+ parse_equality_expr(state);
+ CHECK_ERROR;
+ push_new_binary_op(OP_AND, state);
+ }
+}
+
+/*
+ * OrExpr ::= AndExpr ('or' AndExpr)*
+ */
+static void parse_or_expr(struct state *state) {
+ parse_and_expr(state);
+ CHECK_ERROR;
+ while (*state->pos == 'o' && state->pos[1] == 'r') {
+ state->pos += 2;
+ skipws(state);
+ parse_and_expr(state);
+ CHECK_ERROR;
+ push_new_binary_op(OP_OR, state);
+ }
+}
+
+/*
* Expr ::= EqualityExpr
*/
static void parse_expr(struct state *state) {
skipws(state);
- parse_equality_expr(state);
+ parse_or_expr(state);
}
int pathx_parse(const struct tree *tree, const char *txt,
diff --git a/tests/xpath.tests b/tests/xpath.tests
index bded6ff..e4c6fa2 100644
--- a/tests/xpath.tests
+++ b/tests/xpath.tests
@@ -154,3 +154,6 @@ test count-one-alias /files/etc/hosts/*[count(alias) = 1]
test number-gt /files/etc/hosts/*[count(alias) > 2]
/files/etc/hosts/1
+
+test pred-or /files/etc/hosts/*[canonical = 'localhost' or alias = 'localhost']
+ /files/etc/hosts/1
More information about the augeas-devel
mailing list