diff --git a/.gitignore b/.gitignore index a92261f..69bcda5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ -augeas-0.7.2.tar.gz augeas-0.7.3.tar.gz diff --git a/augeas-0.7.2-01-0c43ca0f.patch b/augeas-0.7.2-01-0c43ca0f.patch deleted file mode 100644 index b5bb157..0000000 --- a/augeas-0.7.2-01-0c43ca0f.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0c43ca0f0ce9008a991c2a2d99e938f4a60712a3 Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 14:12:47 -0700 -Subject: [PATCH 1/9] * src/augeas.c (aug_defvar): use constants to create /augeas/variables - ---- - src/augeas.c | 3 ++- - 1 files changed, 2 insertions(+), 1 deletions(-) - -diff --git a/src/augeas.c b/src/augeas.c -index c21afe9..7b51a77 100644 ---- a/src/augeas.c -+++ b/src/augeas.c -@@ -41,6 +41,7 @@ static const char *const s_load = "load"; - static const char *const s_pathx = "pathx"; - static const char *const s_error = "error"; - static const char *const s_pos = "pos"; -+static const char *const s_vars = "variables"; - - #define TREE_HIDDEN(tree) ((tree)->label == NULL) - -@@ -529,7 +530,7 @@ int aug_defvar(augeas *aug, const char *name, const char *expr) { - ERR_BAIL(aug); - - /* Record the definition of the variable */ -- struct tree *tree = tree_path_cr(aug->origin, 2, "augeas", "variables"); -+ struct tree *tree = tree_path_cr(aug->origin, 2, s_augeas, s_vars); - ERR_NOMEM(tree == NULL, aug); - if (expr == NULL) { - tree = tree_child(tree, name); --- -1.6.6.1 - diff --git a/augeas-0.7.2-02-6c713a08.patch b/augeas-0.7.2-02-6c713a08.patch deleted file mode 100644 index 3fda10c..0000000 --- a/augeas-0.7.2-02-6c713a08.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 6c713a0855f6f2f144ebc2240fc4ec0e3470aacc Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 14:13:13 -0700 -Subject: [PATCH 2/9] * src/augeas.c (aug_init): create /augeas/variables on startup - ---- - src/augeas.c | 5 +++-- - 1 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/augeas.c b/src/augeas.c -index 7b51a77..9ca26b6 100644 ---- a/src/augeas.c -+++ b/src/augeas.c -@@ -406,8 +406,9 @@ struct augeas *aug_init(const char *root, const char *loadpath, - } else { - aug_set(result, AUGEAS_META_SAVE_MODE, AUG_SAVE_OVERWRITE_TEXT); - } -- /* Make sure we always have /files */ -- aug_set(result, AUGEAS_FILES_TREE, NULL); -+ /* Make sure we always have /files and /augeas/variables */ -+ tree_path_cr(result->origin, 1, s_files); -+ tree_path_cr(result->origin, 2, s_augeas, s_vars); - - if (interpreter_init(result) == -1) - goto error; --- -1.6.6.1 - diff --git a/augeas-0.7.2-03-984ff1b8.patch b/augeas-0.7.2-03-984ff1b8.patch deleted file mode 100644 index 7cec6e1..0000000 --- a/augeas-0.7.2-03-984ff1b8.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 984ff1b8f37c64339ed9663d2b052dadbea82032 Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 14:21:42 -0700 -Subject: [PATCH 3/9] Redefine all variables upon load - -This is a slight change in behavior: before, we used to just discard the -contents of all variables upon load. Now, we redefine variables by -evaluating the expression with which they were defined initially again. - -The change in behavior is backwards compatible, since at worst, users will -redefine variables themselves after an aug_load ---- - src/augeas.c | 6 ++++++ - tests/test-load.c | 2 +- - 2 files changed, 7 insertions(+), 1 deletions(-) - -diff --git a/src/augeas.c b/src/augeas.c -index 9ca26b6..2e5f296 100644 ---- a/src/augeas.c -+++ b/src/augeas.c -@@ -447,6 +447,7 @@ int aug_load(struct augeas *aug) { - struct tree *meta_files = tree_child_cr(meta, s_files); - struct tree *files = tree_child_cr(aug->origin, s_files); - struct tree *load = tree_child_cr(meta, s_load); -+ struct tree *vars = tree_child_cr(meta, s_vars); - - api_entry(aug); - -@@ -461,6 +462,11 @@ int aug_load(struct augeas *aug) { - } - tree_clean(aug->origin); - -+ list_for_each(v, vars->children) { -+ aug_defvar(aug, v->label, v->value); -+ ERR_BAIL(aug); -+ } -+ - api_exit(aug); - return 0; - error: -diff --git a/tests/test-load.c b/tests/test-load.c -index 547e222..e4dd38a 100644 ---- a/tests/test-load.c -+++ b/tests/test-load.c -@@ -205,7 +205,7 @@ static void testLoadDefined(CuTest *tc) { - CuAssertRetSuccess(tc, r); - - r = aug_match(aug, "$v", NULL); -- CuAssertIntEquals(tc, 0, r); -+ CuAssertIntEquals(tc, 2, r); - - aug_close(aug); - } --- -1.6.6.1 - diff --git a/augeas-0.7.2-04-218003a8.patch b/augeas-0.7.2-04-218003a8.patch deleted file mode 100644 index 286ecfb..0000000 --- a/augeas-0.7.2-04-218003a8.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 218003a813acae99370d45157fe57589b8a8685c Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 14:50:14 -0700 -Subject: [PATCH 4/9] Move 'run' test utility to cutest.[ch] - - * tests/cutest.h (run): add prototype - * tests/cutest.c (run): add impl - * tests/test-save.c (run): remove ---- - tests/cutest.c | 24 ++++++++++++++++++++++++ - tests/cutest.h | 2 ++ - tests/test-save.c | 20 -------------------- - 3 files changed, 26 insertions(+), 20 deletions(-) - -diff --git a/tests/cutest.c b/tests/cutest.c -index 4cfe0fc..120e31c 100644 ---- a/tests/cutest.c -+++ b/tests/cutest.c -@@ -296,6 +296,30 @@ void CuSuiteDetails(CuSuite* testSuite, char **details) { - } - - /* -+ * Test utilities -+ */ -+void run(CuTest *tc, const char *format, ...) { -+ char *command; -+ va_list args; -+ int r; -+ -+ va_start(args, format); -+ r = vasprintf(&command, format, args); -+ va_end (args); -+ if (r < 0) -+ CuFail(tc, "Failed to format command (out of memory)"); -+ r = system(command); -+ if (r < 0 || (WIFEXITED(r) && WEXITSTATUS(r) != 0)) { -+ char *msg; -+ r = asprintf(&msg, "Command %s failed with status %d\n", -+ command, WEXITSTATUS(r)); -+ CuFail(tc, msg); -+ free(msg); -+ } -+ free(command); -+} -+ -+/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 -diff --git a/tests/cutest.h b/tests/cutest.h -index ae9fe0f..a667e50 100644 ---- a/tests/cutest.h -+++ b/tests/cutest.h -@@ -120,6 +120,8 @@ void CuSuiteRun(CuSuite* testSuite); - void CuSuiteSummary(CuSuite* testSuite, char **summary); - void CuSuiteDetails(CuSuite* testSuite, char **details); - -+/* Run a command */ -+void run(CuTest *tc, const char *format, ...); - #endif /* CU_TEST_H */ - - /* -diff --git a/tests/test-save.c b/tests/test-save.c -index c563ad3..daeace3 100644 ---- a/tests/test-save.c -+++ b/tests/test-save.c -@@ -40,26 +40,6 @@ struct augeas *aug = NULL; - exit(EXIT_FAILURE); \ - } while(0) - --static void run(CuTest *tc, const char *format, ...) { -- char *command; -- va_list args; -- int r; -- -- va_start(args, format); -- r = vasprintf(&command, format, args); -- va_end (args); -- if (r < 0) -- CuFail(tc, "Failed to format command (out of memory)"); -- r = system(command); -- if (r < 0 || (WIFEXITED(r) && WEXITSTATUS(r) != 0)) { -- char *msg; -- r = asprintf(&msg, "Command %s failed with status %d\n", -- command, WEXITSTATUS(r)); -- CuFail(tc, msg); -- free(msg); -- } --} -- - static void setup(CuTest *tc) { - char *lensdir; - --- -1.6.6.1 - diff --git a/augeas-0.7.2-05-21d39d66.patch b/augeas-0.7.2-05-21d39d66.patch deleted file mode 100644 index 60af029..0000000 --- a/augeas-0.7.2-05-21d39d66.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 21d39d66b9c2d827cbede4ace1fe0fc0b637992b Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 15:01:03 -0700 -Subject: [PATCH 5/9] * src/test-load.c (testLoadSave): work off a writable /etc/hosts - -This addresses a FIXME that could lead to use not detecting incorrect behavior ---- - tests/test-load.c | 53 +++++++++++++++++++++++++++++++++++++---------------- - 1 files changed, 37 insertions(+), 16 deletions(-) - -diff --git a/tests/test-load.c b/tests/test-load.c -index e4dd38a..a8107a1 100644 ---- a/tests/test-load.c -+++ b/tests/test-load.c -@@ -32,7 +32,8 @@ - #define CuAssertRetSuccess(tc, n) CuAssertTrue(tc, (n) == 0) - - static const char *abs_top_srcdir; --static char *root; -+static const char *abs_top_builddir; -+static char *root = NULL; - static char *loadpath; - - #define die(msg) \ -@@ -41,6 +42,36 @@ static char *loadpath; - exit(EXIT_FAILURE); \ - } while(0) - -+static struct augeas *setup_writable_hosts(CuTest *tc) { -+ char *etcdir, *build_root; -+ struct augeas *aug = NULL; -+ int r; -+ -+ if (asprintf(&build_root, "%s/build/test-load/%s", -+ abs_top_builddir, tc->name) < 0) { -+ CuFail(tc, "failed to set build_root"); -+ } -+ -+ if (asprintf(&etcdir, "%s/etc", build_root) < 0) -+ CuFail(tc, "asprintf etcdir failed"); -+ -+ run(tc, "test -d %s && chmod -R u+w %s || :", build_root, build_root); -+ run(tc, "rm -rf %s", build_root); -+ run(tc, "mkdir -p %s", etcdir); -+ run(tc, "cp -pr %s/etc/hosts %s", root, etcdir); -+ run(tc, "chmod -R u+w %s", build_root); -+ -+ aug = aug_init(build_root, loadpath, AUG_NO_MODL_AUTOLOAD); -+ CuAssertPtrNotNull(tc, aug); -+ -+ r = aug_set(aug, "/augeas/load/Hosts/lens", "Hosts.lns"); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_set(aug, "/augeas/load/Hosts/incl", "/etc/hosts"); -+ CuAssertRetSuccess(tc, r); -+ -+ return aug; -+} - - static void testDefault(CuTest *tc) { - augeas *aug = NULL; -@@ -162,21 +193,7 @@ static void testLoadSave(CuTest *tc) { - augeas *aug = NULL; - int r; - -- /* FIXME: This test behaves properly during distcheck, since srcdir -- * is writeprotected, making an incorrect attempt to write -- * /etc/hosts.augnew fail; during normal 'make check' the test will -- * succeed. -- * To address this, we should copy the files fro, tests/root into -- * another directory and 'chmod a-w /etc' in that root -- */ -- aug = aug_init(root, loadpath, AUG_NO_MODL_AUTOLOAD|AUG_SAVE_NOOP); -- CuAssertPtrNotNull(tc, aug); -- -- r = aug_set(aug, "/augeas/load/Hosts/lens", "Hosts.lns"); -- CuAssertRetSuccess(tc, r); -- -- r = aug_set(aug, "/augeas/load/Hosts/incl", "/etc/hosts"); -- CuAssertRetSuccess(tc, r); -+ aug = setup_writable_hosts(tc); - - r = aug_load(aug); - CuAssertRetSuccess(tc, r); -@@ -262,6 +279,10 @@ int main(void) { - if (abs_top_srcdir == NULL) - die("env var abs_top_srcdir must be set"); - -+ abs_top_builddir = getenv("abs_top_builddir"); -+ if (abs_top_builddir == NULL) -+ die("env var abs_top_builddir must be set"); -+ - if (asprintf(&root, "%s/tests/root", abs_top_srcdir) < 0) { - die("failed to set root"); - } --- -1.6.6.1 - diff --git a/augeas-0.7.2-06-11b85805.patch b/augeas-0.7.2-06-11b85805.patch deleted file mode 100644 index cf8b002..0000000 --- a/augeas-0.7.2-06-11b85805.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 11b85805955557ae87494fff57ead04be6ab90b6 Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 15:43:07 -0700 -Subject: [PATCH 6/9] Add xstrtoint64 to internal.[ch] - -The implementation is directly from libvirt - - * src/internal.h (xstrtoint64): add prototype - * src/internal.c (xstrtoint64): add impl ---- - src/internal.c | 13 +++++++++++++ - src/internal.h | 3 +++ - 2 files changed, 16 insertions(+), 0 deletions(-) - -diff --git a/src/internal.c b/src/internal.c -index befd3af..8419ca2 100644 ---- a/src/internal.c -+++ b/src/internal.c -@@ -392,6 +392,19 @@ int xasprintf(char **strp, const char *format, ...) { - return result; - } - -+/* From libvirt's src/xen/block_stats.c */ -+int xstrtoint64(char const *s, int base, int64_t *result) { -+ long long int lli; -+ char *p; -+ -+ errno = 0; -+ lli = strtoll(s, &p, base); -+ if (errno || !(*p == 0 || *p == '\n') || p == s || (int64_t) lli != lli) -+ return -1; -+ *result = lli; -+ return 0; -+} -+ - void calc_line_ofs(const char *text, size_t pos, size_t *line, size_t *ofs) { - *line = 1; - *ofs = 0; -diff --git a/src/internal.h b/src/internal.h -index b2a402f..51aa025 100644 ---- a/src/internal.h -+++ b/src/internal.h -@@ -272,6 +272,9 @@ const char *xstrerror(int errnum, char *buf, size_t len); - /* Like asprintf, but set *STRP to NULL on error */ - int xasprintf(char **strp, const char *format, ...); - -+/* Convert S to RESULT with error checking */ -+int xstrtoint64(char const *s, int base, int64_t *result); -+ - /* Calculate line and column number of character POS in TEXT */ - void calc_line_ofs(const char *text, size_t pos, size_t *line, size_t *ofs); - --- -1.6.6.1 - diff --git a/augeas-0.7.2-07-72c636de.patch b/augeas-0.7.2-07-72c636de.patch deleted file mode 100644 index 548f3c7..0000000 --- a/augeas-0.7.2-07-72c636de.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 72c636decaa8b8c1764710c60f9932892c411207 Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 15:44:35 -0700 -Subject: [PATCH 7/9] Make tree_clean available outside of augeas.c - - * src/augeas.c (tree_clean): remove 'static' - * src/internal.h (tree_clean): add prototype ---- - src/augeas.c | 3 +-- - src/internal.h | 2 ++ - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/augeas.c b/src/augeas.c -index 2e5f296..5ca1789 100644 ---- a/src/augeas.c -+++ b/src/augeas.c -@@ -74,8 +74,7 @@ static void tree_mark_dirty(struct tree *tree) { - tree->dirty = 1; - } - --/* Clear the dirty flag in the whole TREE */ --static void tree_clean(struct tree *tree) { -+void tree_clean(struct tree *tree) { - if (tree->dirty) { - list_for_each(c, tree->children) - tree_clean(c); -diff --git a/src/internal.h b/src/internal.h -index 51aa025..f1e6f3a 100644 ---- a/src/internal.h -+++ b/src/internal.h -@@ -379,6 +379,8 @@ int dump_tree(FILE *out, struct tree *tree); - int tree_equal(const struct tree *t1, const struct tree *t2); - char *path_expand(struct tree *tree, const char *ppath); - char *path_of_tree(struct tree *tree); -+/* Clear the dirty flag in the whole TREE */ -+void tree_clean(struct tree *tree); - /* Return first child with label LABEL or NULL */ - struct tree *tree_child(struct tree *tree, const char *label); - /* Return first existing child with label LABEL or create one. Return NULL --- -1.6.6.1 - diff --git a/augeas-0.7.2-08-0695bdd0.patch b/augeas-0.7.2-08-0695bdd0.patch deleted file mode 100644 index 3951a14..0000000 --- a/augeas-0.7.2-08-0695bdd0.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0695bdd057b2cbfc6146ac498179c0f162ee889f Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 15:46:53 -0700 -Subject: [PATCH 8/9] Add utility tree_store_value to avoid unnecessary strdup's - - * src/internal.h (tree_store_value): add prototype - * src/augeas.c (tree_store_value): new function; (tree_set_value): use - tree_store_value ---- - src/augeas.c | 18 ++++++++++++++---- - src/internal.h | 5 ++++- - 2 files changed, 18 insertions(+), 5 deletions(-) - -diff --git a/src/augeas.c b/src/augeas.c -index 5ca1789..744b699 100644 ---- a/src/augeas.c -+++ b/src/augeas.c -@@ -156,17 +156,27 @@ struct tree *tree_find_cr(struct augeas *aug, const char *path) { - return result; - } - --int tree_set_value(struct tree *tree, const char *value) { -+void tree_store_value(struct tree *tree, char **value) { - if (tree->value != NULL) { - free(tree->value); - tree->value = NULL; - } -+ if (*value != NULL) { -+ tree->value = *value; -+ *value = NULL; -+ } -+ tree_mark_dirty(tree); -+} -+ -+int tree_set_value(struct tree *tree, const char *value) { -+ char *v = NULL; -+ - if (value != NULL) { -- tree->value = strdup(value); -- if (tree->value == NULL) -+ v = strdup(value); -+ if (v == NULL) - return -1; - } -- tree_mark_dirty(tree); -+ tree_store_value(tree, &v); - return 0; - } - -diff --git a/src/internal.h b/src/internal.h -index f1e6f3a..7513d47 100644 ---- a/src/internal.h -+++ b/src/internal.h -@@ -389,7 +389,10 @@ struct tree *tree_child_cr(struct tree *tree, const char *label); - /* Create a path in the tree; nodes along the path are looked up with - * tree_child_cr */ - struct tree *tree_path_cr(struct tree *tree, int n, ...); --/* Set the value of TREE and update dirty flags */ -+/* Store VALUE directly as the value of TREE and set VALUE to NULL. -+ * Update dirty flags */ -+void tree_store_value(struct tree *tree, char **value); -+/* Set the value of TREE to a copy of VALUE and update dirty flags */ - int tree_set_value(struct tree *tree, const char *value); - /* Cleanly remove all children of TREE, but leave TREE itself unchanged */ - void tree_unlink_children(struct augeas *aug, struct tree *tree); --- -1.6.6.1 - diff --git a/augeas-0.7.2-09-5ee81630.patch b/augeas-0.7.2-09-5ee81630.patch deleted file mode 100644 index 09ea6d2..0000000 --- a/augeas-0.7.2-09-5ee81630.patch +++ /dev/null @@ -1,501 +0,0 @@ -From 5ee8163051be8214507c13c86171ac90ca7cb91f Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Tue, 29 Jun 2010 15:32:44 -0700 -Subject: [PATCH 9/9] Avoid unnecessary file parsing when reloading the tree - -We used to reparse every file we knew about upon aug_load. Now, we only -reparse files if the file has changed on disk. - -We test a few scenarios to make sure aug_load retains its behavior of -obliterating the tree and filling it with the latest from disk. This -includes throwing away unsaved changes or trees that have been deleted. ---- - src/augeas.c | 72 ++++++++++++++++++++++++++- - src/transform.c | 78 +++++++++++++++++++++++++++-- - tests/cutest.c | 17 ++++++ - tests/cutest.h | 4 ++ - tests/test-load.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - tests/xpath.tests | 1 + - 6 files changed, 307 insertions(+), 7 deletions(-) - -diff --git a/src/augeas.c b/src/augeas.c -index 744b699..45c2207 100644 ---- a/src/augeas.c -+++ b/src/augeas.c -@@ -451,6 +451,51 @@ void tree_unlink_children(struct augeas *aug, struct tree *tree) { - tree_unlink(tree->children); - } - -+static void tree_mark_files(struct tree *tree) { -+ if (tree_child(tree, "path") != NULL) { -+ tree_mark_dirty(tree); -+ } else { -+ list_for_each(c, tree->children) { -+ tree_mark_files(c); -+ } -+ } -+} -+ -+static void tree_rm_dirty_files(struct augeas *aug, struct tree *tree) { -+ struct tree *p; -+ -+ if (!tree->dirty) -+ return; -+ -+ if ((p = tree_child(tree, "path")) != NULL) { -+ aug_rm(aug, p->value); -+ tree_unlink(tree); -+ } else { -+ struct tree *c = tree->children; -+ while (c != NULL) { -+ struct tree *next = c->next; -+ tree_rm_dirty_files(aug, c); -+ c = next; -+ } -+ } -+} -+ -+static void tree_rm_dirty_leaves(struct augeas *aug, struct tree *tree, -+ struct tree *protect) { -+ if (! tree->dirty) -+ return; -+ -+ struct tree *c = tree->children; -+ while (c != NULL) { -+ struct tree *next = c->next; -+ tree_rm_dirty_leaves(aug, c, protect); -+ c = next; -+ } -+ -+ if (tree != protect && tree->children == NULL) -+ tree_unlink(tree); -+} -+ - int aug_load(struct augeas *aug) { - struct tree *meta = tree_child_cr(aug->origin, s_augeas); - struct tree *meta_files = tree_child_cr(meta, s_files); -@@ -462,13 +507,36 @@ int aug_load(struct augeas *aug) { - - ERR_NOMEM(load == NULL, aug); - -- tree_unlink_children(aug, meta_files); -- tree_unlink_children(aug, files); -+ /* To avoid unnecessary loads of files, we reload an existing file in -+ * several steps: -+ * (1) mark all file nodes under /augeas/files as dirty (and only those) -+ * (2) process all files matched by a lens; we check (in -+ * transform_load) if the file has been modified. If it has, we -+ * reparse it. Either way, we clear the dirty flag. We also need to -+ * reread the file if part or all of it has been modified in the -+ * tree but not been saved yet -+ * (3) remove all files from the tree that still have a dirty entry -+ * under /augeas/files. Those files are not processed by any lens -+ * anymore -+ * (4) Remove entries from /augeas/files and /files that correspond -+ * to directories without any files of interest -+ */ -+ tree_clean(meta_files); -+ tree_mark_files(meta_files); - - list_for_each(xfm, load->children) { - if (transform_validate(aug, xfm) == 0) - transform_load(aug, xfm); - } -+ -+ /* This makes it possible to spot 'directories' that are now empty -+ * because we removed their file contents */ -+ tree_clean(files); -+ -+ tree_rm_dirty_files(aug, meta_files); -+ tree_rm_dirty_leaves(aug, meta_files, meta_files); -+ tree_rm_dirty_leaves(aug, files, files); -+ - tree_clean(aug->origin); - - list_for_each(v, vars->children) { -diff --git a/src/transform.c b/src/transform.c -index 0c56034..00552da 100644 ---- a/src/transform.c -+++ b/src/transform.c -@@ -49,6 +49,7 @@ static const int glob_flags = GLOB_NOSORT; - /* Loaded files are tracked underneath METATREE. When a file with name - * FNAME is loaded, certain entries are made under METATREE / FNAME: - * path : path where tree for FNAME is put -+ * mtime : time of last modification of the file as reported by stat(2) - * lens/info : information about where the applied lens was loaded from - * lens/id : unique hexadecimal id of the lens - * error : indication of errors during processing FNAME, or NULL -@@ -60,6 +61,7 @@ static const int glob_flags = GLOB_NOSORT; - static const char *const s_path = "path"; - static const char *const s_lens = "lens"; - static const char *const s_info = "info"; -+static const char *const s_mtime = "mtime"; - - static const char *const s_error = "error"; - /* These are all put underneath "error" */ -@@ -111,6 +113,59 @@ static bool is_regular_file(const char *path) { - return S_ISREG(st.st_mode); - } - -+static char *mtime_as_string(struct augeas *aug, const char *fname) { -+ int r; -+ struct stat st; -+ char *result = NULL; -+ -+ r = stat(fname, &st); -+ if (r < 0) { -+ /* If we fail to stat, silently ignore the error -+ * and report an impossible mtime */ -+ result = strdup("0"); -+ ERR_NOMEM(result == NULL, aug); -+ } else { -+ r = xasprintf(&result, "%ld", (long) st.st_mtime); -+ ERR_NOMEM(r < 0, aug); -+ } -+ return result; -+ error: -+ FREE(result); -+ return NULL; -+} -+ -+static bool file_current(struct augeas *aug, const char *fname, -+ struct tree *finfo) { -+ struct tree *mtime = tree_child(finfo, s_mtime); -+ struct tree *file = NULL, *path = NULL; -+ int r; -+ struct stat st; -+ int64_t mtime_i; -+ -+ if (mtime == NULL || mtime->value == NULL) -+ return false; -+ -+ r = xstrtoint64(mtime->value, 10, &mtime_i); -+ if (r < 0) { -+ /* Ignore silently and err on the side of caution */ -+ return false; -+ } -+ -+ r = stat(fname, &st); -+ if (r < 0) -+ return false; -+ -+ if (mtime_i != (int64_t) st.st_mtime) -+ return false; -+ -+ path = tree_child(finfo, s_path); -+ if (path == NULL) -+ return false; -+ -+ file = tree_find(aug, path->value); -+ return (file != NULL && ! file->dirty); -+} -+ - static int filter_generate(struct tree *xfm, const char *root, - int *nmatches, char ***matches) { - glob_t globbuf; -@@ -326,7 +381,8 @@ static int store_error(struct augeas *aug, - * Returns 0 on success, -1 on error - */ - static int add_file_info(struct augeas *aug, const char *node, -- struct lens *lens, const char *lens_name) { -+ struct lens *lens, const char *lens_name, -+ const char *filename) { - struct tree *file, *tree; - char *tmp = NULL; - int r; -@@ -348,6 +404,13 @@ static int add_file_info(struct augeas *aug, const char *node, - r = tree_set_value(tree, node); - ERR_NOMEM(r < 0, aug); - -+ /* Set 'mtime' */ -+ tmp = mtime_as_string(aug, filename); -+ ERR_BAIL(aug); -+ tree = tree_child_cr(file, s_mtime); -+ ERR_NOMEM(tree == NULL, aug); -+ tree_store_value(tree, &tmp); -+ - /* Set 'lens/info' */ - tmp = format_info(lens->info); - ERR_NOMEM(tmp == NULL, aug); -@@ -362,6 +425,8 @@ static int add_file_info(struct augeas *aug, const char *node, - r = tree_set_value(tree, lens_name); - ERR_NOMEM(r < 0, aug); - -+ tree_clean(file); -+ - result = 0; - error: - free(path); -@@ -404,7 +469,7 @@ static int load_file(struct augeas *aug, struct lens *lens, - path = file_name_path(aug, filename); - ERR_NOMEM(path == NULL, aug); - -- r = add_file_info(aug, path, lens, lens_name); -+ r = add_file_info(aug, path, lens, lens_name, filename); - if (r < 0) - goto done; - -@@ -602,7 +667,8 @@ int transform_load(struct augeas *aug, struct tree *xfm) { - for (int i=0; i < nmatches; i++) { - const char *filename = matches[i] + strlen(aug->root) - 1; - struct tree *finfo = file_info(aug, filename); -- if (finfo != NULL && tree_child(finfo, s_lens) != NULL) { -+ if (finfo != NULL && !finfo->dirty && -+ tree_child(finfo, s_lens) != NULL) { - const char *s = xfm_lens_name(finfo); - char *fpath = file_name_path(aug, matches[i]); - transform_file_error(aug, "mxfm_load", filename, -@@ -610,9 +676,11 @@ int transform_load(struct augeas *aug, struct tree *xfm) { - s, lens_name); - aug_rm(aug, fpath); - free(fpath); -- } else { -+ } else if (!file_current(aug, matches[i], finfo)) { - load_file(aug, lens, lens_name, matches[i]); - } -+ if (finfo != NULL) -+ finfo->dirty = 0; - FREE(matches[i]); - } - lens_release(lens); -@@ -945,7 +1013,7 @@ int transform_save(struct augeas *aug, struct tree *xfm, - result = 1; - - done: -- r = add_file_info(aug, path, lens, lens_name); -+ r = add_file_info(aug, path, lens, lens_name, filename); - if (r < 0) { - err_status = "file_info"; - result = -1; -diff --git a/tests/cutest.c b/tests/cutest.c -index 120e31c..08dbfd7 100644 ---- a/tests/cutest.c -+++ b/tests/cutest.c -@@ -138,6 +138,23 @@ void CuAssertStrEquals_LineMsg(CuTest* tc, const char* file, int line, - CuFailInternal(tc, file, line, string); - } - -+void CuAssertStrNotEqual_LineMsg(CuTest* tc, const char* file, int line, -+ const char* message, -+ const char* expected, const char* actual) { -+ char *string = NULL; -+ -+ if (expected != NULL && actual != NULL && strcmp(expected, actual) != 0) -+ return; -+ -+ if (message != NULL) { -+ asprintf_or_die(&string, "%s: expected <%s> but was <%s>", message, -+ expected, actual); -+ } else { -+ asprintf_or_die(&string, "expected <%s> but was <%s>", expected, actual); -+ } -+ CuFailInternal(tc, file, line, string); -+} -+ - void CuAssertIntEquals_LineMsg(CuTest* tc, const char* file, int line, - const char* message, - int expected, int actual) { -diff --git a/tests/cutest.h b/tests/cutest.h -index a667e50..616fb1f 100644 ---- a/tests/cutest.h -+++ b/tests/cutest.h -@@ -61,6 +61,9 @@ void CuAssert_Line(CuTest* tc, const char* file, int line, const char* message, - void CuAssertStrEquals_LineMsg(CuTest* tc, - const char* file, int line, const char* message, - const char* expected, const char* actual); -+void CuAssertStrNotEqual_LineMsg(CuTest* tc, -+ const char* file, int line, const char* message, -+ const char* expected, const char* actual); - void CuAssertIntEquals_LineMsg(CuTest* tc, - const char* file, int line, const char* message, - int expected, int actual); -@@ -82,6 +85,7 @@ void CuAssertPtrNotEqual_LineMsg(CuTest* tc, - - #define CuAssertStrEquals(tc,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) - #define CuAssertStrEquals_Msg(tc,ms,ex,ac) CuAssertStrEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) -+#define CuAssertStrNotEqual(tc,ex,ac) CuAssertStrNotEqual_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) - #define CuAssertIntEquals(tc,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac)) - #define CuAssertIntEquals_Msg(tc,ms,ex,ac) CuAssertIntEquals_LineMsg((tc),__FILE__,__LINE__,(ms),(ex),(ac)) - #define CuAssertDblEquals(tc,ex,ac,dl) CuAssertDblEquals_LineMsg((tc),__FILE__,__LINE__,NULL,(ex),(ac),(dl)) -diff --git a/tests/test-load.c b/tests/test-load.c -index a8107a1..fe92305 100644 ---- a/tests/test-load.c -+++ b/tests/test-load.c -@@ -70,6 +70,8 @@ static struct augeas *setup_writable_hosts(CuTest *tc) { - r = aug_set(aug, "/augeas/load/Hosts/incl", "/etc/hosts"); - CuAssertRetSuccess(tc, r); - -+ free(build_root); -+ free(etcdir); - return aug; - } - -@@ -262,6 +264,142 @@ static void testDefvarExpr(CuTest *tc) { - aug_close(aug); - } - -+static void testReloadChanged(CuTest *tc) { -+ FILE *fp; -+ augeas *aug = NULL; -+ const char *build_root, *mtime2, *s; -+ char *mtime1; -+ char *hosts = NULL; -+ int r; -+ -+ aug = setup_writable_hosts(tc); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_get(aug, "/augeas/root", &build_root); -+ CuAssertIntEquals(tc, 1, r); -+ -+ r = aug_get(aug, "/augeas/files/etc/hosts/mtime", &s); -+ CuAssertIntEquals(tc, 1, r); -+ mtime1 = strdup(s); -+ CuAssertPtrNotNull(tc, mtime1); -+ -+ /* Tickle /etc/hosts behind augeas' back */ -+ r = asprintf(&hosts, "%setc/hosts", build_root); -+ CuAssertPositive(tc, r); -+ -+ fp = fopen(hosts, "a"); -+ CuAssertPtrNotNull(tc, fp); -+ -+ r = fprintf(fp, "192.168.0.1 other.example.com\n"); -+ CuAssertTrue(tc, r > 0); -+ -+ r = fclose(fp); -+ CuAssertRetSuccess(tc, r); -+ -+ /* Unsaved changes are discarded */ -+ r = aug_set(aug, "/files/etc/hosts/1/ipaddr", "127.0.0.2"); -+ CuAssertRetSuccess(tc, r); -+ -+ /* Check that we really did load the right file*/ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_get(aug, "/augeas/files/etc/hosts/mtime", &mtime2); -+ CuAssertIntEquals(tc, 1, r); -+ CuAssertStrNotEqual(tc, mtime1, mtime2); -+ -+ r = aug_match(aug, "/files/etc/hosts/*[ipaddr = '192.168.0.1']", NULL); -+ CuAssertIntEquals(tc, 1, r); -+ -+ r = aug_match(aug, "/files/etc/hosts/1[ipaddr = '127.0.0.1']", NULL); -+ CuAssertIntEquals(tc, 1, r); -+ -+ free(mtime1); -+ free(hosts); -+ aug_close(aug); -+} -+ -+static void testReloadDirty(CuTest *tc) { -+ augeas *aug = NULL; -+ int r; -+ -+ aug = setup_writable_hosts(tc); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ /* Unsaved changes are discarded */ -+ r = aug_set(aug, "/files/etc/hosts/1/ipaddr", "127.0.0.2"); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_match(aug, "/files/etc/hosts/1[ipaddr = '127.0.0.1']", NULL); -+ CuAssertIntEquals(tc, 1, r); -+ -+ aug_close(aug); -+} -+ -+static void testReloadDeleted(CuTest *tc) { -+ augeas *aug = NULL; -+ int r; -+ -+ aug = setup_writable_hosts(tc); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ /* A missing file causes a reload */ -+ r = aug_rm(aug, "/files/etc/hosts"); -+ CuAssertPositive(tc, r); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_match(aug, "/files/etc/hosts/1[ipaddr = '127.0.0.1']", NULL); -+ CuAssertIntEquals(tc, 1, r); -+ -+ /* A missing entry in a file causes a reload */ -+ r = aug_rm(aug, "/files/etc/hosts/1/ipaddr"); -+ CuAssertPositive(tc, r); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_match(aug, "/files/etc/hosts/1[ipaddr = '127.0.0.1']", NULL); -+ CuAssertIntEquals(tc, 1, r); -+ -+ aug_close(aug); -+} -+ -+static void testReloadDeletedMeta(CuTest *tc) { -+ augeas *aug = NULL; -+ int r; -+ -+ aug = setup_writable_hosts(tc); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ /* Unsaved changes are discarded */ -+ r = aug_rm(aug, "/augeas/files/etc/hosts"); -+ CuAssertPositive(tc, r); -+ -+ r = aug_set(aug, "/files/etc/hosts/1/ipaddr", "127.0.0.2"); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_load(aug); -+ CuAssertRetSuccess(tc, r); -+ -+ r = aug_match(aug, "/files/etc/hosts/1[ipaddr = '127.0.0.1']", NULL); -+ CuAssertIntEquals(tc, 1, r); -+ -+ aug_close(aug); -+} -+ - int main(void) { - char *output = NULL; - CuSuite* suite = CuSuiteNew(); -@@ -274,6 +412,10 @@ int main(void) { - SUITE_ADD_TEST(suite, testLoadSave); - SUITE_ADD_TEST(suite, testLoadDefined); - SUITE_ADD_TEST(suite, testDefvarExpr); -+ SUITE_ADD_TEST(suite, testReloadChanged); -+ SUITE_ADD_TEST(suite, testReloadDirty); -+ SUITE_ADD_TEST(suite, testReloadDeleted); -+ SUITE_ADD_TEST(suite, testReloadDeletedMeta); - - abs_top_srcdir = getenv("abs_top_srcdir"); - if (abs_top_srcdir == NULL) -diff --git a/tests/xpath.tests b/tests/xpath.tests -index f2575a3..b16792a 100644 ---- a/tests/xpath.tests -+++ b/tests/xpath.tests -@@ -148,6 +148,7 @@ test ipaddr-sibling //*[../ipaddr] - - test lircd-ancestor //*[ancestor::kudzu][label() != '#comment'] - /augeas/files/etc/sysconfig/kudzu/path = /files/etc/sysconfig/kudzu -+ /augeas/files/etc/sysconfig/kudzu/mtime = ... - /augeas/files/etc/sysconfig/kudzu/lens = @Shellvars - /augeas/files/etc/sysconfig/kudzu/lens/info = ... - /files/etc/sysconfig/kudzu/SAFE = no --- -1.6.6.1 - diff --git a/sources b/sources index 6e90823..712abef 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -0fe232b7f37a6e468e81019895fd01f4 augeas-0.7.2.tar.gz d907943fc21c2d1db5dc8d97ec02a9e5 augeas-0.7.3.tar.gz diff --git a/vim-ftdetect-syntax.patch b/vim-ftdetect-syntax.patch deleted file mode 100644 index 0fde39f..0000000 --- a/vim-ftdetect-syntax.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 81552d12ea1d6fc19ccb9a7d7e57ff09af74ce60 Mon Sep 17 00:00:00 2001 -From: David Lutterkort -Date: Mon, 14 Dec 2009 14:38:11 -0800 -Subject: [PATCH] * doc/ftdetect/augeas.vim: fix syntax - ---- - doc/ftdetect/augeas.vim | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/doc/ftdetect/augeas.vim b/doc/ftdetect/augeas.vim -index 2520eb8..7120691 100644 ---- a/doc/ftdetect/augeas.vim -+++ b/doc/ftdetect/augeas.vim -@@ -1 +1 @@ --au BufNewFile?,BufRead? *.aug set filetype=augeas -+au BufNewFile,BufRead *.aug set filetype=augeas --- -1.6.5.2 - diff --git a/xorg.aug b/xorg.aug deleted file mode 100644 index c99bc81..0000000 --- a/xorg.aug +++ /dev/null @@ -1,293 +0,0 @@ -(* -Module: Xorg - Parses /etc/X11/xorg.conf - -Authors: Raphael Pinson - Matthew Booth - -About: Reference - This lens tries to keep as close as possible to `man xorg.conf` where - possible. - -The definitions from `man xorg.conf` are put as commentaries for reference -throughout the file. More information can be found in the manual. - -About: License - This file is licensed under the GPL. - -About: Lens Usage - Sample usage of this lens in augtool - - * Get the identifier of the devices with a "Clone" option: - > match "/files/etc/X11/xorg.conf/Device[Option = 'Clone']/Identifier" - -About: Configuration files - This lens applies to /etc/X11/xorg.conf. See . -*) - -module Xorg = - autoload xfm - -(************************************************************************ - * Group: USEFUL PRIMITIVES - *************************************************************************) - -(* Group: Generic primitives *) - -(* Variable: eol *) -let eol = Util.eol - -(* Variable: to_eol - * Match everything from here to eol, cropping whitespace at both ends - *) -let to_eol = /[^ \t\n](.*[^ \t\n])?/ - -(* Variable: indent *) -let indent = Util.indent - -(* Variable: comment *) -let comment = Util.comment - -(* Variable: empty *) -let empty = Util.empty - - -(* Group: Separators *) - -(* Variable: sep_spc *) -let sep_spc = Util.del_ws_spc - -(* Variable: sep_dquote *) -let sep_dquote = Util.del_str "\"" - - -(* Group: Fields and values *) - -(* Variable: entries_re - * This is a list of all patterns which have specific handlers, and should - * therefore not be matched by the generic handler - *) -let entries_re = /([oO]ption|[sS]creen|[iI]nput[dD]evice|[dD]river|[sS]ub[sS]ection|[dD]isplay|[iI]dentifier|[vV]ideo[rR]am|[dD]efault[dD]epth|[dD]evice)/ - -(* Variable: generic_entry_re *) -let generic_entry_re = /[^# \t\n\/]+/ - entries_re - -(* Variable: quoted_string_val *) -let quoted_string_val = del "\"" "\"" . store /[^"\n]+/ . del "\"" "\"" - (* " relax, emacs *) - -(* Variable: int *) -let int = /[0-9]+/ - - -(************************************************************************ - * Group: ENTRIES AND OPTIONS - *************************************************************************) - - -(* View: entry_int - * This matches an entry which takes a single integer for an argument - *) -let entry_int (canon:string) (re:regexp) = - [ indent . del re canon . label canon . sep_spc . store int . eol ] - -(* View: entry_rgb - * This matches an entry which takes 3 integers as arguments representing red, - * green and blue components - *) -let entry_rgb (canon:string) (re:regexp) = - [ indent . del re canon . label canon - . [ label "red" . sep_spc . store int ] - . [ label "green" . sep_spc . store int ] - . [ label "blue" . sep_spc . store int ] - . eol ] - -(* View: entry_xy - * This matches an entry which takes 2 integers as arguments representing X and - * Y coordinates - *) -let entry_xy (canon:string) (re:regexp) = - [ indent . del re canon . label canon - . [ label "x" . sep_spc . store int ] - . [ label "y" . sep_spc . store int ] - . eol ] - -(* View: entry_str - * This matches an entry which takes a single quoted string - *) -let entry_str (canon:string) (re:regexp) = - [ indent . del re canon . label canon - . sep_spc . quoted_string_val . eol ] - -(* View: entry_generic - * An entry without a specific handler. Store everything after the keyword, - * cropping whitespace at both ends. - *) -let entry_generic = [ indent . key generic_entry_re - . sep_spc . store to_eol . eol ] - -(* View: option *) -let option = [ indent . del /[oO]ption/ "Option" . label "Option" . sep_spc - . quoted_string_val - . [ label "value" . sep_spc . quoted_string_val ]* - . eol ] - -(* View: screen - * The Screen entry of ServerLayout - *) -let screen = [ indent . del /[sS]creen/ "Screen" . label "Screen" . sep_spc - . [ label "num" . store int . sep_spc ]? - . quoted_string_val . sep_spc - . [ label "position" . store to_eol ] - . eol ] - -(* View: input_device *) -let input_device = [ indent . del /[iI]nput[dD]evice/ "InputDevice" - . label "InputDevice" . sep_spc . quoted_string_val - . [ label "option" . sep_spc . quoted_string_val ]* - . eol ] - -(* View: driver *) -let driver = entry_str "Driver" /[dD]river/ - -(* View: identifier *) -let identifier = entry_str "Identifier" /[iI]dentifier/ - -(* View: videoram *) -let videoram = entry_int "VideoRam" /[vV]ideo[rR]am/ - -(* View: default_depth *) -let default_depth = entry_int "DefaultDepth" /[dD]efault[dD]epth/ - -(* View: device *) -let device = entry_str "Device" /[dD]evice/ - -(************************************************************************ - * Group: DISPLAY SUBSECTION - *************************************************************************) - - -(* View: display_modes *) -let display_modes = [ indent . del /[mM]odes/ "Modes" . label "Modes" - . [ label "mode" . sep_spc . quoted_string_val ]+ - . eol ] - -(************************************************************************* - * View: display_entry - * Known values for entries in the Display subsection - * - * Definition: - * > Depth depth - * > FbBpp bpp - * > Weight red-weight green-weight blue-weight - * > Virtual xdim ydim - * > ViewPort x0 y0 - * > Modes "mode-name" ... - * > Visual "visual-name" - * > Black red green blue - * > White red green blue - * > Options - *) - -let display_entry = entry_int "Depth" /[dD]epth/ | - entry_int "FbBpp" /[fF]b[bB]pp/ | - entry_rgb "Weight" /[wW]eight/ | - entry_xy "Virtual" /[vV]irtual/ | - entry_xy "ViewPort" /[vV]iew[pP]ort/ | - display_modes | - entry_str "Visual" /[vV]isual/ | - entry_rgb "Black" /[bB]lack/ | - entry_rgb "White" /[wW]hite/ | - entry_str "Options" /[oO]ptions/ | - empty | - comment - -(* View: display *) -let display = [ indent . del "SubSection" "SubSection" . sep_spc - . sep_dquote . key "Display" . sep_dquote - . eol - . display_entry* - . indent . del "EndSubSection" "EndSubSection" . eol ] - - -(************************************************************************ - * Group: SECTIONS - *************************************************************************) - - -(************************************************************************ - * Variable: section_re - * Known values for Section names - * - * Definition: - * > The section names are: - * > - * > Files File pathnames - * > ServerFlags Server flags - * > Module Dynamic module loading - * > InputDevice Input device description - * > Device Graphics device description - * > VideoAdaptor Xv video adaptor description - * > Monitor Monitor description - * > Modes Video modes descriptions - * > Screen Screen configuration - * > ServerLayout Overall layout - * > DRI DRI-specific configuration - * > Vendor Vendor-specific configuration - *************************************************************************) -let section_re = /(Files|ServerFlags|Module|InputDevice|Device|VideoAdaptor|Monitor|Modes|Screen|ServerLayout|DRI|Vendor)/ - - -(************************************************************************ - * Variable: secton_re_obsolete - * The following obsolete section names are still recognised for - * compatibility purposes. In new config files, the InputDevice - * section should be used instead. - * - * Definition: - * > Keyboard Keyboard configuration - * > Pointer Pointer/mouse configuration - *************************************************************************) -let section_re_obsolete = /(Keyboard|Pointer)/ - -(* View: section_entry *) -let section_entry = option | - screen | - display | - input_device | - driver | - identifier | - videoram | - default_depth | - device | - entry_generic | - empty | comment - -(************************************************************************ - * View: section - * A section in xorg.conf - * - * Definition: - * > Section "SectionName" - * > SectionEntry - * > ... - * > EndSection - *************************************************************************) -let section = [ indent . del "Section" "Section" - . sep_spc . sep_dquote - . key (section_re|section_re_obsolete) . sep_dquote - . eol - . section_entry* - . indent . del "EndSection" "EndSection" . eol ] - -(* - * View: lns - * The xorg.conf lens - *) -let lns = ( empty | comment | section )* - - -(* Variable: filter *) -let filter = (incl "/etc/X11/xorg.conf") - -let xfm = transform lns filter