[augeas-devel] [PATCH] Add API function aug_node_count to compute the subtree size
Francis Giraldeau
francis.giraldeau at gmail.com
Mon Jan 24 02:07:08 UTC 2011
The new function aug_node_count computes the subtree size corresponding to a
given path expression. The count includes all descendants.
* src/augeas.c : new API call implementation.
* src/augeas_sym.version : export symbol
* src/augtool.c : new command "count" to augtool
* tests/test-api.c : unittests
---
src/augeas.c | 35 +++++++++++++++++++++++++++++++++++
src/augeas.h | 10 ++++++++++
src/augeas_sym.version | 5 +++++
src/augtool.c | 24 ++++++++++++++++++++++++
src/internal.h | 2 ++
tests/test-api.c | 17 +++++++++++++++++
6 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index 25ca016..e03f02e 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -173,6 +173,14 @@ void tree_store_value(struct tree *tree, char **value) {
tree_mark_dirty(tree);
}
+int tree_size(struct tree *tree) {
+ int size = 1;
+ list_for_each(c, tree->children) {
+ size += tree_size(c);
+ }
+ return size;
+}
+
int tree_set_value(struct tree *tree, const char *value) {
char *v = NULL;
@@ -1350,6 +1358,33 @@ int aug_print(const struct augeas *aug, FILE *out, const char *pathin) {
return -1;
}
+int aug_node_count(const struct augeas *aug, const char *path) {
+ struct pathx *p;
+ struct tree *tree;
+ int r = 0;
+
+ api_entry(aug);
+
+ if (path == NULL || strlen(path) == 0) {
+ path = "/*";
+ }
+
+ p = pathx_aug_parse(aug, aug->origin, path, true);
+ ERR_BAIL(aug);
+
+ for (tree = pathx_first(p); tree != NULL; tree = pathx_next(p)) {
+ r += tree_size(tree);
+ }
+
+ free_pathx(p);
+
+ api_exit(aug);
+ return r;
+ error:
+ api_exit(aug);
+ return -1;
+}
+
void aug_close(struct augeas *aug) {
if (aug == NULL)
return;
diff --git a/src/augeas.h b/src/augeas.h
index b4848cb..aa42b5a 100644
--- a/src/augeas.h
+++ b/src/augeas.h
@@ -276,6 +276,16 @@ int aug_load(augeas *aug);
*/
int aug_print(const augeas *aug, FILE *out, const char *path);
+/* Function: aug_node_count
+ *
+ * Get the number of nodes in an augeas tree.
+ *
+ * Returns:
+ * number of nodes of the tree under PATH on success, or a negative value
+ * on failure
+ */
+int aug_node_count(const augeas *aug, const char *path);
+
/* Function: aug_close
*
* Close this Augeas instance and free any storage associated with
diff --git a/src/augeas_sym.version b/src/augeas_sym.version
index 542f5fa..6dc1a8b 100644
--- a/src/augeas_sym.version
+++ b/src/augeas_sym.version
@@ -34,3 +34,8 @@ AUGEAS_0.11.0 {
global:
aug_setm;
} AUGEAS_0.10.0;
+
+AUGEAS_0.12.0 {
+ global:
+ aug_node_count;
+} AUGEAS_0.11.0;
diff --git a/src/augtool.c b/src/augtool.c
index 7de8e9d..745e841 100644
--- a/src/augtool.c
+++ b/src/augtool.c
@@ -807,6 +807,29 @@ static const struct command_def cmd_print_def = {
.help = "Print entries in the tree. If PATH is given, printing starts there,\n otherwise the whole tree is printed"
};
+static void cmd_node_count(struct command *cmd) {
+ const char *path = arg_value(cmd, "path");
+ int size;
+
+ size = aug_node_count(aug, path);
+ err_check(cmd);
+ printf("tree size: %d\n", size);
+}
+
+static const struct command_opt_def cmd_node_count_opts[] = {
+ { .type = CMD_PATH, .name = "path", .optional = true,
+ .help = "get the number of nodes of this subtree" },
+ CMD_OPT_DEF_LAST
+};
+
+static const struct command_def cmd_size_def = {
+ .name = "count",
+ .opts = cmd_node_count_opts,
+ .handler = cmd_node_count,
+ .synopsis = "size of this subtree",
+ .help = "Print the size of this tree. If PATH is given, returns the size of the subtree there,\n otherwise, returns the size of the whole tree"
+};
+
static void cmd_save(struct command *cmd) {
int r;
r = aug_save(aug);
@@ -966,6 +989,7 @@ static const struct command_def const *commands[] = {
&cmd_match_def,
&cmd_mv_def,
&cmd_print_def,
+ &cmd_size_def,
&cmd_rm_def,
&cmd_save_def,
&cmd_set_def,
diff --git a/src/internal.h b/src/internal.h
index 71c5d42..5289336 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -407,6 +407,8 @@ struct tree *tree_find(struct augeas *aug, const char *path);
* Returns the node or NULL on error
*/
struct tree *tree_find_cr(struct augeas *aug, const char *path);
+/* Get the size of this tree */
+int tree_size(struct tree *tree);
/* Struct: memstream
* Wrappers to simulate OPEN_MEMSTREAM where that's not available. The
diff --git a/tests/test-api.c b/tests/test-api.c
index 322f4a9..4ae21ac 100644
--- a/tests/test-api.c
+++ b/tests/test-api.c
@@ -222,6 +222,22 @@ static void testDefNodeCreateMeta(CuTest *tc) {
aug_close(aug);
}
+static void testTreeSize(CuTest *tc) {
+ int s1, s2, s3;
+ struct augeas *aug;
+
+ aug = aug_init(root, loadpath, AUG_NO_STDINC|AUG_NO_LOAD);
+ CuAssertPtrNotNull(tc, aug);
+
+ s1 = aug_node_count(aug, "/augeas/version");
+ CuAssertIntEquals(tc, 8, s1);
+
+ s1 = aug_node_count(aug, "/");
+ s2 = aug_node_count(aug, "/augeas");
+ s3 = aug_node_count(aug, "/files");
+ CuAssertIntEquals(tc, s1, s2 + s3 + 1);
+}
+
int main(void) {
char *output = NULL;
CuSuite* suite = CuSuiteNew();
@@ -232,6 +248,7 @@ int main(void) {
SUITE_ADD_TEST(suite, testDefVarMeta);
SUITE_ADD_TEST(suite, testDefNodeExistingMeta);
SUITE_ADD_TEST(suite, testDefNodeCreateMeta);
+ SUITE_ADD_TEST(suite, testTreeSize);
abs_top_srcdir = getenv("abs_top_srcdir");
if (abs_top_srcdir == NULL)
--
1.7.1
More information about the augeas-devel
mailing list