[augeas-devel] [PATCH] path expressions: add a function 'int'
lutter at redhat.com
lutter at redhat.com
Wed Oct 5 16:56:14 UTC 2011
From: David Lutterkort <lutter at redhat.com>
This makes it possible to do numerical comparisons of node values, for
example, 'match /files/etc/group/*[int(gid) < 3]'
---
src/pathx.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
tests/xpath.tests | 13 +++++++++++++
2 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/src/pathx.c b/src/pathx.c
index 1dd7992..6a9c377 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -279,9 +279,11 @@ static void func_count(struct state *state);
static void func_label(struct state *state);
static void func_regexp(struct state *state);
static void func_glob(struct state *state);
+static void func_int(struct state *state);
static const enum type const arg_types_nodeset[] = { T_NODESET };
static const enum type const arg_types_string[] = { T_STRING };
+static const enum type const arg_types_bool[] = { T_BOOLEAN };
static const struct func builtin_funcs[] = {
{ .name = "last", .arity = 0, .type = T_NUMBER, .arg_types = NULL,
@@ -304,7 +306,13 @@ static const struct func builtin_funcs[] = {
.impl = func_glob },
{ .name = "glob", .arity = 1, .type = T_REGEXP,
.arg_types = arg_types_nodeset,
- .impl = func_glob }
+ .impl = func_glob },
+ { .name = "int", .arity = 1, .type = T_NUMBER,
+ .arg_types = arg_types_string, .impl = func_int },
+ { .name = "int", .arity = 1, .type = T_NUMBER,
+ .arg_types = arg_types_nodeset, .impl = func_int },
+ { .name = "int", .arity = 1, .type = T_NUMBER,
+ .arg_types = arg_types_bool, .impl = func_int }
};
#define RET_ON_ERROR \
@@ -642,6 +650,39 @@ static void func_label(struct state *state) {
push_value(vind, state);
}
+static void func_int(struct state *state) {
+ value_ind_t vind = make_value(T_NUMBER, state);
+ int64_t i = -1;
+ RET_ON_ERROR;
+
+ struct value *v = pop_value(state);
+ if (v->tag == T_BOOLEAN) {
+ i = v->boolval;
+ } else {
+ const char *s = NULL;
+ if (v->tag == T_STRING) {
+ s = v->string;
+ } else {
+ /* T_NODESET */
+ if (v->nodeset->used != 1) {
+ STATE_ERROR(state, PATHX_EMMATCH);
+ return;
+ }
+ s = v->nodeset->nodes[0]->value;
+ }
+ if (s != NULL) {
+ int r;
+ r = xstrtoint64(s, 10, &i);
+ if (r < 0) {
+ STATE_ERROR(state, PATHX_ENUMBER);
+ return;
+ }
+ }
+ }
+ state->value_pool[vind].number = i;
+ push_value(vind, state);
+}
+
static struct regexp *
nodeset_as_regexp(struct info *info, struct nodeset *ns, int glob) {
struct regexp *result = NULL;
diff --git a/tests/xpath.tests b/tests/xpath.tests
index 2a74e8f..e327062 100644
--- a/tests/xpath.tests
+++ b/tests/xpath.tests
@@ -287,3 +287,16 @@ test php5 $php/mail\ function
test expr-or /files/etc/group/root/*[self::gid or self::user]
/files/etc/group/root/gid = 0
/files/etc/group/root/user = root
+
+test int-ns-eq /files/etc/group/*[int(gid) = 30]
+ /files/etc/group/gopher
+
+test int-ns-lt /files/etc/group/*[int(gid) < 3]
+ /files/etc/group/root
+ /files/etc/group/bin
+ /files/etc/group/daemon
+
+test int-bool-f /files[int(1 = 0) > 0]
+
+test int-bool-t /files[int(1 = 1) > 0]
+ /files
--
1.7.6.2
More information about the augeas-devel
mailing list