[augeas-devel] augeas: master - Add preceding-sibling and following-sibling axes to path expressions
David Lutterkort
lutter at fedoraproject.org
Fri Sep 11 21:39:49 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=07568dfdf09817ca330716f3822d666433ab19bf
Commit: 07568dfdf09817ca330716f3822d666433ab19bf
Parent: 6adfee876dcbff4f043a9380a1ede09d889acb09
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Thu Sep 10 16:57:17 2009 -0700
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Fri Sep 11 14:29:05 2009 -0700
Add preceding-sibling and following-sibling axes to path expressions
---
src/pathx.c | 34 +++++++++++++++++++++++++++++++---
tests/xpath.tests | 20 ++++++++++++++++++++
2 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/src/pathx.c b/src/pathx.c
index 466951c..2df3f7d 100644
--- a/src/pathx.c
+++ b/src/pathx.c
@@ -92,7 +92,9 @@ enum axis {
DESCENDANT_OR_SELF,
PARENT,
ANCESTOR,
- ROOT
+ ROOT,
+ PRECEDING_SIBLING,
+ FOLLOWING_SIBLING
};
/* This array is indexed by enum axis */
@@ -103,7 +105,9 @@ static const char *const axis_names[] = {
"descendant-or-self",
"parent",
"ancestor",
- "root"
+ "root",
+ "preceding-sibling",
+ "following-sibling"
};
static const char *const axis_sep = "::";
@@ -427,7 +431,9 @@ static struct nodeset *make_nodeset(struct state *state) {
static void ns_add(struct nodeset *ns, struct tree *node,
struct state *state) {
- // FIXME: Need to uniquify NS
+ for (int i=0; i < ns->used; i++)
+ if (ns->nodes[i] == node)
+ return;
if (ns->used >= ns->size) {
size_t size = 2 * ns->size;
if (size < 10) size = 10;
@@ -1938,6 +1944,16 @@ static bool step_matches(struct step *step, struct tree *tree) {
return (step->name == NULL || streqx(step->name, tree->label));
}
+static struct tree *tree_prev(struct tree *pos) {
+ struct tree *node = NULL;
+ if (pos != pos->parent->children) {
+ for (node = pos->parent->children;
+ node->next != pos;
+ node = node->next);
+ }
+ return node;
+}
+
static struct tree *step_first(struct step *step, struct tree *ctx) {
struct tree *node = NULL;
switch (step->axis) {
@@ -1958,6 +1974,12 @@ static struct tree *step_first(struct step *step, struct tree *ctx) {
ctx = ctx->parent;
node = ctx;
break;
+ case PRECEDING_SIBLING:
+ node = tree_prev(ctx);
+ break;
+ case FOLLOWING_SIBLING:
+ node = ctx->next;
+ break;
default:
assert(0);
}
@@ -2001,6 +2023,12 @@ static struct tree *step_next(struct step *step, struct tree *ctx,
else
node = node->parent;
break;
+ case PRECEDING_SIBLING:
+ node = tree_prev(node);
+ break;
+ case FOLLOWING_SIBLING:
+ node = node->next;
+ break;
default:
assert(0);
}
diff --git a/tests/xpath.tests b/tests/xpath.tests
index ac93b91..d03cf79 100644
--- a/tests/xpath.tests
+++ b/tests/xpath.tests
@@ -195,3 +195,23 @@ test coerce-and-true /files['foo' and count(/files/etc/hosts/*) ]
/files
test coerce-and-false /files['' and count(/none) and /none]
+
+test preceding-sibling /files/etc/hosts/*/preceding-sibling::*[alias = 'localhost']
+ /files/etc/hosts/1
+
+test preceding-sibling-pred /files/etc/grub.conf/*[preceding-sibling::*[1] = ../default]
+ /files/etc/grub.conf/timeout = 5
+
+test preceding-sibling-pred2 /files/etc/grub.conf/*[preceding-sibling::*[1][self::default]]
+ /files/etc/grub.conf/timeout = 5
+
+test following-sibling /files/etc/hosts/1/*/following-sibling::alias
+ /files/etc/hosts/1/alias[1] = localhost
+ /files/etc/hosts/1/alias[2] = galia.watzmann.net
+ /files/etc/hosts/1/alias[3] = galia
+
+test following-sibling-pred /files/etc/hosts/1/*[following-sibling::alias]
+ /files/etc/hosts/1/ipaddr = 127.0.0.1
+ /files/etc/hosts/1/canonical = localhost.localdomain
+ /files/etc/hosts/1/alias[1] = localhost
+ /files/etc/hosts/1/alias[2] = galia.watzmann.net
More information about the augeas-devel
mailing list