From 10bd64a3883a25e80a60d27202fbef15bfaddfd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 16 Sep 2015 15:02:41 +0200 Subject: [PATCH 01/50] Add a lua interpreter to augtool This commit adds a -l/--lua flag to augtool which allows to execute Lua code instead of the native augsrun interpreter. Each API call is mapped into a correponding aug_* Lua command, as well as short * commands. --- .travis.yml | 1 + configure.ac | 2 + src/Makefile.am | 8 +- src/augtool.c | 499 ++++++++++++++++++++++++++++++++++++++++-- tests/Makefile.am | 3 +- tests/root/etc/passwd | 2 +- tests/test-lua.sh | 13 ++ tests/test.auglua | 93 ++++++++ 8 files changed, 594 insertions(+), 27 deletions(-) create mode 100755 tests/test-lua.sh create mode 100644 tests/test.auglua diff --git a/.travis.yml b/.travis.yml index 3df96934f..791488f40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ addons: packages: - libxml2-dev - libreadline-dev + - liblua5.2-dev - valgrind install: - ./autogen.sh diff --git a/configure.ac b/configure.ac index 5654723c9..b3a3a40c7 100644 --- a/configure.ac +++ b/configure.ac @@ -110,6 +110,8 @@ gl_INIT PKG_PROG_PKG_CONFIG PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) +PKG_CHECK_MODULES([LIBLUA], [lua5.2]) + AC_CHECK_FUNCS([strerror_r fsync]) AC_OUTPUT(Makefile \ diff --git a/src/Makefile.am b/src/Makefile.am index 5616796ea..1738ef164 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ GNULIB= ../gnulib/lib/libgnu.la GNULIB_CFLAGS= -I $(top_builddir)/gnulib/lib -I $(top_srcdir)/gnulib/lib -AM_CFLAGS = @AUGEAS_CFLAGS@ @WARN_CFLAGS@ $(GNULIB_CFLAGS) $(LIBXML_CFLAGS) +AM_CFLAGS = @AUGEAS_CFLAGS@ @WARN_CFLAGS@ $(GNULIB_CFLAGS) $(LIBXML_CFLAGS) $(LIBLUA_CFLAGS) AM_YFLAGS=-d -p spec_ @@ -35,13 +35,13 @@ endif libaugeas_la_LDFLAGS = $(AUGEAS_VERSION_SCRIPT) \ -version-info $(LIBAUGEAS_VERSION_INFO) -libaugeas_la_LIBADD = liblexer.la libfa.la $(LIB_SELINUX) $(LIBXML_LIBS) $(GNULIB) +libaugeas_la_LIBADD = liblexer.la libfa.la $(LIB_SELINUX) $(LIBXML_LIBS) $(LIBLUA_LIBS) $(GNULIB) augtool_SOURCES = augtool.c -augtool_LDADD = libaugeas.la $(READLINE_LIBS) $(LIBXML_LIBS) $(GNULIB) +augtool_LDADD = libaugeas.la $(READLINE_LIBS) $(LIBXML_LIBS) $(LIBLUA_LIBS) $(GNULIB) augparse_SOURCES = augparse.c -augparse_LDADD = libaugeas.la $(LIBXML_LIBS) $(GNULIB) +augparse_LDADD = libaugeas.la $(LIBXML_LIBS) $(LIBLUA_LIBS) $(GNULIB) libfa_la_SOURCES = fa.c fa.h hash.c hash.h memory.c memory.h ref.h ref.c libfa_la_LIBADD = $(LIB_SELINUX) $(GNULIB) diff --git a/src/augtool.c b/src/augtool.c index 0603c6de1..6a4024474 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -39,6 +39,10 @@ #include #include +#include +#include +#include + /* Global variables */ static augeas *aug = NULL; @@ -50,6 +54,8 @@ char *transforms = NULL; size_t transformslen = 0; const char *inputfile = NULL; int echo_commands = 0; /* Gets also changed in main_loop */ +bool use_lua = false; +static lua_State *LS = NULL; bool print_version = false; bool auto_save = false; bool interactive = false; @@ -58,6 +64,7 @@ bool timing = false; char *history_file = NULL; #define AUGTOOL_PROMPT "augtool> " +#define AUGTOOL_LUA_PROMPT "augtool|lua> " /* * General utilities @@ -302,6 +309,7 @@ static void help(void) { " syntax, e.g. -t 'Fstab incl /etc/fstab.bak'\n"); fprintf(stderr, " -e, --echo echo commands when reading from a file\n"); fprintf(stderr, " -f, --file FILE read commands from FILE\n"); + fprintf(stderr, " -l, --lua use Lua interpreter instead of native Augeas\n"); fprintf(stderr, " -s, --autosave automatically save at the end of instructions\n"); fprintf(stderr, " -i, --interactive run an interactive shell after evaluating\n" " the commands in STDIN and FILE\n"); @@ -334,6 +342,7 @@ static void parse_opts(int argc, char **argv) { { "transform", 1, 0, 't' }, { "echo", 0, 0, 'e' }, { "file", 1, 0, 'f' }, + { "lua", 0, 0, 'l' }, { "autosave", 0, 0, 's' }, { "interactive", 0, 0, 'i' }, { "nostdinc", 0, 0, 'S' }, @@ -346,7 +355,7 @@ static void parse_opts(int argc, char **argv) { }; int idx; - while ((opt = getopt_long(argc, argv, "hnbcr:I:t:ef:siSLA", options, &idx)) != -1) { + while ((opt = getopt_long(argc, argv, "hnbcr:I:t:ef:lsiSLA", options, &idx)) != -1) { switch(opt) { case 'c': flags |= AUG_TYPE_CHECK; @@ -375,6 +384,9 @@ static void parse_opts(int argc, char **argv) { case 'f': inputfile = optarg; break; + case 'l': + use_lua = true; + break; case 's': auto_save = true; break; @@ -489,6 +501,420 @@ static void install_signal_handlers(void) { sigaction(SIGINT, &sigint_action, NULL); } +static void lua_checkargs(lua_State *L, const char *name, int arity) { + int n = lua_gettop(L); + char *msg = NULL; + if (n != arity) { + strcat(msg, "Wrong number of arguments for '"); + strcat(msg, name); + strcat(msg, "'"); + lua_pushstring(L, msg); + lua_error(L); + } +} + +static int lua_pusherror(lua_State *L) { + lua_pushstring(L, aug_error_message(aug)); + lua_error(L); + return 1; +} + +static int lua_aug_get(lua_State *L) { + int r; + const char *path, *value; + + /* get number of arguments */ + lua_checkargs(L, "aug_get", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + r = aug_get(aug, path, &value); + if (r < 0) + return lua_pusherror(L); + lua_pushstring(L, value); + + /* return the number of results */ + return 1; +} + +static int lua_aug_label(lua_State *L) { + int r; + const char *path, *value; + + lua_checkargs(L, "aug_label", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + r = aug_label(aug, path, &value); + if (r < 0) + return lua_pusherror(L); + lua_pushstring(L, value); + + /* return the number of results */ + return 1; +} + +static int lua_aug_set(lua_State *L) { + int r; + const char *path, *value; + + lua_checkargs(L, "aug_set", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + value = luaL_checkstring(L, 2); + + r = aug_set(aug, path, value); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_setm(lua_State *L) { + int r; + const char *base, *sub, *value; + + lua_checkargs(L, "aug_setm", 3); + + base = luaL_checkstring(L, 1); + // TODO: check string really + sub = luaL_checkstring(L, 2); + value = luaL_checkstring(L, 3); + + r = aug_setm(aug, base, sub, value); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_insert(lua_State *L) { + int r; + const char *path, *label; + int before; + + lua_checkargs(L, "aug_insert", 3); + + path = luaL_checkstring(L, 1); + // TODO: check string really + label = luaL_checkstring(L, 2); + before = lua_toboolean(L, 3); + + r = aug_insert(aug, path, label, before); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_rm(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_rm", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + r = aug_rm(aug, path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_mv(lua_State *L) { + int r; + const char *path, *new_path; + + lua_checkargs(L, "aug_mv", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + new_path = luaL_checkstring(L, 2); + + r = aug_mv(aug, path, new_path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_cp(lua_State *L) { + int r; + const char *path, *new_path; + + lua_checkargs(L, "aug_cp", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + new_path = luaL_checkstring(L, 2); + + r = aug_cp(aug, path, new_path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_rename(lua_State *L) { + int r; + const char *path, *label; + + lua_checkargs(L, "aug_rename", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + label = luaL_checkstring(L, 2); + + r = aug_rename(aug, path, label); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_matches(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_matches", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + // TODO: a second arg is possible (value) + + r = aug_match(aug, path, NULL); + if (r < 0) + return lua_pusherror(L); + + lua_pushinteger(L, r); + /* return the number of results */ + return 1; +} + +static int lua_aug_match(lua_State *L) { + int r, i; + const char *path; + char **match = NULL; + + lua_checkargs(L, "aug_match", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + // TODO: a second arg is possible (value) + + r = aug_match(aug, path, &match); + if (r < 0) + return lua_pusherror(L); + + lua_newtable(L); + for (i = 0; i < r; i++) { + lua_pushnumber(L, i+1); + lua_pushstring(L, match[i]); + lua_settable(L, -3); + free(match[i]); + } + free(match); + lua_pushinteger(L, r); + + /* return the number of results */ + return 2; +} + +static int lua_aug_defvar(lua_State *L) { + int r; + const char *name, *expr; + + lua_checkargs(L, "aug_defvar", 2); + + name = luaL_checkstring(L, 1); + // TODO: check string really + expr = luaL_checkstring(L, 2); + + r = aug_defvar(aug, name, expr); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_defnode(lua_State *L) { + int r; + const char *name, *expr, *value; + + lua_checkargs(L, "aug_defnode", 3); + + name = luaL_checkstring(L, 1); + // TODO: check string really + expr = luaL_checkstring(L, 2); + value = luaL_checkstring(L, 3); + + r = aug_defnode(aug, name, expr, value, NULL); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_save(lua_State *L) { + int r; + + lua_checkargs(L, "aug_save", 0); + + r = aug_save(aug); + if (r == -1) { + lua_pushstring(L, "saving failed (run 'errors' for details)"); + lua_error(L); + } else { + r = aug_match(aug, "/augeas/events/saved", NULL); + if (r > 0) + printf("Saved %d file(s)\n", r); + } + + /* return the number of results */ + return 0; +} + +static int lua_aug_load(lua_State *L) { + int r; + + lua_checkargs(L, "aug_load", 0); + + r = aug_load(aug); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_text_store(lua_State *L) { + int r; + const char *lens, *node, *path; + + lua_checkargs(L, "aug_text_store", 3); + + lens = luaL_checkstring(L, 1); + node = luaL_checkstring(L, 2); + path = luaL_checkstring(L, 3); + + r = aug_text_store(aug, lens, node, path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_text_retrieve(lua_State *L) { + int r; + const char *lens, *node_in, *path, *node_out; + + lua_checkargs(L, "aug_text_retrieve", 4); + + lens = luaL_checkstring(L, 1); + node_in = luaL_checkstring(L, 2); + path = luaL_checkstring(L, 3); + node_out = luaL_checkstring(L, 4); + + r = aug_text_retrieve(aug, lens, node_in, path, node_out); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_transform(lua_State *L) { + int r; + const char *lens, *file; + bool excl; + + lua_checkargs(L, "aug_transform", 3); + + lens = luaL_checkstring(L, 1); + file = luaL_checkstring(L, 2); + excl = lua_toboolean(L, 3); + + r = aug_transform(aug, lens, file, excl); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static void setup_lua(void) { + LS = luaL_newstate(); + luaL_openlibs(LS); + lua_register(LS, "aug_get", lua_aug_get); + lua_register(LS, "aug_label", lua_aug_label); + lua_register(LS, "aug_set", lua_aug_set); + lua_register(LS, "aug_setm", lua_aug_setm); + // lua_register(LS, "aug_span", lua_aug_span); + lua_register(LS, "aug_insert", lua_aug_insert); + lua_register(LS, "aug_rm", lua_aug_rm); + lua_register(LS, "aug_mv", lua_aug_mv); + lua_register(LS, "aug_cp", lua_aug_cp); + lua_register(LS, "aug_rename", lua_aug_rename); + lua_register(LS, "aug_matches", lua_aug_matches); + lua_register(LS, "aug_match", lua_aug_match); + lua_register(LS, "aug_defvar", lua_aug_defvar); + lua_register(LS, "aug_defnode", lua_aug_defnode); + lua_register(LS, "aug_save", lua_aug_save); + lua_register(LS, "aug_load", lua_aug_load); + lua_register(LS, "aug_text_store", lua_aug_text_store); + lua_register(LS, "aug_text_retrieve", lua_aug_text_retrieve); + // lua_register(LS, "aug_escape_name", lua_aug_escape_name); + lua_register(LS, "aug_transform", lua_aug_transform); + // lua_register(LS, "aug_print", lua_aug_print); + // lua_register(LS, "aug_to_xml", lua_aug_to_xml); + // lua_register(LS, "aug_srun", lua_aug_srun); + // lua_register(LS, "aug_errors", lua_aug_errors); + + // short names + lua_register(LS, "get", lua_aug_get); + lua_register(LS, "label", lua_aug_label); + lua_register(LS, "set", lua_aug_set); + lua_register(LS, "setm", lua_aug_setm); + // lua_register(LS, "span", lua_aug_span); + lua_register(LS, "insert", lua_aug_insert); + lua_register(LS, "ins", lua_aug_insert); // alias + lua_register(LS, "rm", lua_aug_rm); + lua_register(LS, "mv", lua_aug_mv); + lua_register(LS, "move", lua_aug_mv); // alias + lua_register(LS, "cp", lua_aug_cp); + lua_register(LS, "copy", lua_aug_cp); // alias + lua_register(LS, "rename", lua_aug_rename); + lua_register(LS, "matches", lua_aug_matches); + lua_register(LS, "match", lua_aug_match); + lua_register(LS, "defvar", lua_aug_defvar); + lua_register(LS, "defnode", lua_aug_defnode); + lua_register(LS, "save", lua_aug_save); + lua_register(LS, "load", lua_aug_load); + lua_register(LS, "text_store", lua_aug_text_store); + lua_register(LS, "text_retrieve", lua_aug_text_retrieve); + // lua_register(LS, "escape_name", lua_aug_escape_name); + lua_register(LS, "transform", lua_aug_transform); + // lua_register(LS, "print", lua_aug_print); + // lua_register(LS, "to_xml", lua_aug_to_xml); + // lua_register(LS, "srun", lua_aug_srun); + // lua_register(LS, "errors", lua_aug_errors); +} + static int main_loop(void) { char *line = NULL; int ret = 0; @@ -498,14 +924,27 @@ static int main_loop(void) { bool get_line = true; bool in_interactive = false; + if (use_lua) + setup_lua(); + if (inputfile) { - if (freopen(inputfile, "r", stdin) == NULL) { - char *msg = NULL; - if (asprintf(&msg, "Failed to open %s", inputfile) < 0) - perror("Failed to open input file"); - else - perror(msg); - return -1; + if (use_lua) { + if (luaL_dofile(LS, inputfile)) { + printf("%s\n", lua_tostring(LS, -1)); + lua_close(LS); + return -1; + } + lua_close(LS); + return 0; + } else { + if (freopen(inputfile, "r", stdin) == NULL) { + char *msg = NULL; + if (asprintf(&msg, "Failed to open %s", inputfile) < 0) + perror("Failed to open input file"); + else + perror(msg); + return -1; + } } } @@ -520,7 +959,10 @@ static int main_loop(void) { while(1) { if (get_line) { - line = readline(AUGTOOL_PROMPT); + if (use_lua) + line = readline(AUGTOOL_LUA_PROMPT); + else + line = readline(AUGTOOL_PROMPT); } else { line = NULL; } @@ -568,25 +1010,40 @@ static int main_loop(void) { } if (end_reached) { + if (use_lua) + lua_close(LS); if (echo_commands) printf("\n"); return ret; } - if (*line == '\0' || *line == '#') { - free(line); - continue; - } + if (use_lua) { + // FIXME: newlines don't work! + code = luaL_loadbuffer(LS, line, strlen(line), "line") || lua_pcall(LS, 0, 0, 0); + if (isatty(fileno(stdin))) + add_history(line); - code = run_command(line, timing); - if (code == -2) { - free(line); - return ret; - } + if (code) { + fprintf(stderr, "%s\n", lua_tostring(LS, -1)); + lua_pop(LS, 1); /* pop error message from the stack */ + ret = -1; + } + } else { + if (*line == '\0' || *line == '#') { + free(line); + continue; + } - if (code < 0) { - ret = -1; - print_aug_error(); + code = run_command(line); + if (code == -2) { + free(line); + return ret; + } + + if (code < 0) { + ret = -1; + print_aug_error(); + } } if (line != inputline) diff --git a/tests/Makefile.am b/tests/Makefile.am index e0353cacd..04ca94274 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -257,7 +257,8 @@ check_SCRIPTS = \ test-put-mount.sh test-put-mount-augnew.sh test-put-mount-augsave.sh \ test-save-empty.sh test-bug-1.sh test-idempotent.sh test-preserve.sh \ test-events-saved.sh test-save-mode.sh test-unlink-error.sh \ - test-augtool-empty-line.sh test-augtool-modify-root.sh + test-augtool-empty-line.sh test-augtool-modify-root.sh \ + test-lua.sh EXTRA_DIST = \ test-augtool root lens-test-1 \ diff --git a/tests/root/etc/passwd b/tests/root/etc/passwd index 9cefbfe48..6e662777b 100644 --- a/tests/root/etc/passwd +++ b/tests/root/etc/passwd @@ -1,4 +1,4 @@ -root:x:0:0:root:/root:/bin/bash +root:x:0:0:root:/root:/bin/zsh bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin diff --git a/tests/test-lua.sh b/tests/test-lua.sh new file mode 100755 index 000000000..996addb6e --- /dev/null +++ b/tests/test-lua.sh @@ -0,0 +1,13 @@ +#! /bin/bash + +# Test the lua interpreter in augtool + +ROOT=$abs_top_srcdir/tests/root +LENSES=$abs_top_srcdir/lenses + +OUT=$(augtool --lua --nostdinc -I $LENSES -r $ROOT -f $abs_top_srcdir/tests/test.auglua 2>&1) + +echo "$OUT" + +[[ -z $OUT ]] || exit 1 + diff --git a/tests/test.auglua b/tests/test.auglua new file mode 100644 index 000000000..2c2f3f503 --- /dev/null +++ b/tests/test.auglua @@ -0,0 +1,93 @@ +--- test aug_get() +assert(aug_get("etc/passwd/root/uid") == "0") + +--- test aug_label() +assert(aug_label("etc/passwd/sync") == "sync") + +--- test aug_set() +aug_set("/foo", "bar") +assert(aug_get("/foo") == "bar") + +--- test aug_setm() +aug_setm("etc/passwd/*", "shell", "zsh") +assert(aug_get("etc/passwd/sync/shell") == "zsh") + +--- test aug_span() +--- TODO + +--- test aug_insert() +aug_insert("etc/passwd/*[1]", "foo", true) +assert(aug_label("etc/passwd/*[1]") == "foo") + +--- test aug_rm() +aug_rm("etc/passwd/sync") +assert(aug_label("etc/passwd/sync") == nil) + +--- test aug_mv() +aug_mv("etc/passwd/root", "etc/passwd/qux") +assert(aug_label("etc/passwd/*[last()]") == "qux") +assert(aug_label("etc/passwd/root") == nil) + +--- test aug_cp() +aug_cp("etc/passwd/qux", "etc/passwd/root") +assert(aug_get("etc/passwd/root/uid") == aug_get("etc/passwd/qux/uid")) + +--- test aug_rename() +aug_rename("etc/passwd/qux", "bar") +assert(aug_get("etc/passwd/root/uid") == aug_get("etc/passwd/bar/uid")) + +--- test aug_matches() +m = aug_matches("etc/passwd/*") +assert(m == 20) + +--- test aug_match() +m = aug_match("etc/passwd/*") +c = 0 +for k, v in pairs(m) do c= c+1 end +assert(c > 0) +assert(m[1] == "/files/etc/passwd/foo") + +--- test aug_defvar() +aug_defvar("root", "etc/passwd/root") +assert(aug_label("$root") == "root") + +--- test aug_defnode() +aug_defnode("raphink", "etc/passwd/raphink/uid", "314") +assert(aug_get("$raphink") == "314") +--- TODO: support 3 arguments +--- aug_defnode("gid", "etc/passwd/raphink/gid") +--- assert(aug_get("$gid") == nil) + +--- test aug_save() +--- reload tree to be clean +aug_load() +aug_set("etc/passwd/root/shell", "/bin/zsh") +aug_save() + +--- test aug_load() +aug_load() + +--- test aug_text_store() +aug_set("/input", "key=value\n") +aug_text_store("Shellvars.lns", "/input", "/parsed") +assert(aug_get("/parsed/key") == "value") + +--- test aug_text_retrieve() +aug_set("/parsed/key", "newval") +aug_text_retrieve("Shellvars.lns", "/input", "/parsed", "/output") +assert(aug_get("/output") == "key=newval\n") + +--- test aug_escape_name() +--- test that? + +--- test aug_transform() +aug_transform("Json.lns", "/tmp/foo.json", false) +assert(aug_get("/augeas/load/Json/incl[1]") == "/tmp/foo.json") + +--- test aug_print() + +--- test aug_to_xml() + +--- test aug_srun() + +--- test aug_errors() From 0bf4760eae0c56d4dda2c27677f8f415f62a87ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 16 Sep 2015 23:57:46 +0200 Subject: [PATCH 02/50] Use snprintf in lua_checkargs --- src/augtool.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 6a4024474..eea8af9cc 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -503,11 +503,9 @@ static void install_signal_handlers(void) { static void lua_checkargs(lua_State *L, const char *name, int arity) { int n = lua_gettop(L); - char *msg = NULL; + char msg[1024]; if (n != arity) { - strcat(msg, "Wrong number of arguments for '"); - strcat(msg, name); - strcat(msg, "'"); + snprintf(msg, sizeof(msg), "Wrong number of arguments for '%s'", name); lua_pushstring(L, msg); lua_error(L); } From fac868bf1109c58b967c5f84830b628615ac061c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 00:11:31 +0200 Subject: [PATCH 03/50] Allow nil as third value in defnode --- src/augtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index eea8af9cc..06b415a52 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -750,14 +750,14 @@ static int lua_aug_defvar(lua_State *L) { static int lua_aug_defnode(lua_State *L) { int r; - const char *name, *expr, *value; + const char *name, *expr, *value = NULL; lua_checkargs(L, "aug_defnode", 3); name = luaL_checkstring(L, 1); // TODO: check string really expr = luaL_checkstring(L, 2); - value = luaL_checkstring(L, 3); + value = lua_tostring(L, 3); r = aug_defnode(aug, name, expr, value, NULL); if (r < 0) From 22d60f5a60c12d0b47596aa406d8c834f7c32bb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 00:18:29 +0200 Subject: [PATCH 04/50] Make auto_save work with lua --- src/augtool.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/augtool.c b/src/augtool.c index 06b415a52..a750fcccb 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -932,6 +932,17 @@ static int main_loop(void) { lua_close(LS); return -1; } + if (auto_save) { + strncpy(inputline, "save()", sizeof(inputline)); + line = inputline; + code = luaL_loadbuffer(LS, line, strlen(line), "line") || lua_pcall(LS, 0, 0, 0); + + if (code) { + fprintf(stderr, "%s\n", lua_tostring(LS, -1)); + lua_pop(LS, 1); /* pop error message from the stack */ + ret = -1; + } + } lua_close(LS); return 0; } else { From 4e7ea58e92c06359e426a65368e9111cdb6c1690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 07:18:47 +0200 Subject: [PATCH 05/50] Add lua_aug_clear, lua_aug_clearm and lua_aug_touch --- src/augtool.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ tests/test.auglua | 16 +++++++++++++- 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/augtool.c b/src/augtool.c index a750fcccb..31d72d857 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -682,6 +682,58 @@ static int lua_aug_rename(lua_State *L) { return 0; } +static int lua_aug_clear(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_clear", 1); + + path = luaL_checkstring(L, 1); + + r = aug_set(aug, path, NULL); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_clearm(lua_State *L) { + int r; + const char *base, *sub; + + lua_checkargs(L, "aug_clearm", 2); + + base = luaL_checkstring(L, 1); + sub = luaL_checkstring(L, 2); + + r = aug_setm(aug, base, sub, NULL); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_touch(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_touch", 1); + + path = luaL_checkstring(L, 1); + + r = aug_match(aug, path, NULL); + if (r == 0) { + r = aug_set(aug, path, NULL); + if (r < 0) + return lua_pusherror(L); + } + + /* return the number of results */ + return 0; +} + static int lua_aug_matches(lua_State *L) { int r; const char *path; @@ -868,6 +920,9 @@ static void setup_lua(void) { lua_register(LS, "aug_mv", lua_aug_mv); lua_register(LS, "aug_cp", lua_aug_cp); lua_register(LS, "aug_rename", lua_aug_rename); + lua_register(LS, "aug_clear", lua_aug_clear); + lua_register(LS, "aug_clearm", lua_aug_clearm); + lua_register(LS, "aug_touch", lua_aug_touch); lua_register(LS, "aug_matches", lua_aug_matches); lua_register(LS, "aug_match", lua_aug_match); lua_register(LS, "aug_defvar", lua_aug_defvar); diff --git a/tests/test.auglua b/tests/test.auglua index 2c2f3f503..576e6ec70 100644 --- a/tests/test.auglua +++ b/tests/test.auglua @@ -36,9 +36,23 @@ assert(aug_get("etc/passwd/root/uid") == aug_get("etc/passwd/qux/uid")) aug_rename("etc/passwd/qux", "bar") assert(aug_get("etc/passwd/root/uid") == aug_get("etc/passwd/bar/uid")) +--- test aug_clear() +aug_clear("etc/passwd/qux/uid") +assert(aug_get("etc/passwd/qux/uid") == nil) + +--- test aug_clearm() +aug_clearm("etc/passwd/*", "uid") +assert(aug_get("etc/passwd/root/uid") == nil) + +--- test aug_touch() +aug_touch("etc/passwd/flex/uid") +assert(aug_get("etc/passwd/flex/uid") == nil) +aug_touch("etc/passwd/root/gid") +assert(aug_get("etc/passwd/root/gid") == "0") + --- test aug_matches() m = aug_matches("etc/passwd/*") -assert(m == 20) +assert(m == 22) --- test aug_match() m = aug_match("etc/passwd/*") From 9127af57570742f9486f69329fa88acdb6d981f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 07:22:16 +0200 Subject: [PATCH 06/50] Remove comment --- src/augtool.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 31d72d857..39e7b891b 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -742,7 +742,6 @@ static int lua_aug_matches(lua_State *L) { path = luaL_checkstring(L, 1); // TODO: check string really - // TODO: a second arg is possible (value) r = aug_match(aug, path, NULL); if (r < 0) @@ -762,7 +761,6 @@ static int lua_aug_match(lua_State *L) { path = luaL_checkstring(L, 1); // TODO: check string really - // TODO: a second arg is possible (value) r = aug_match(aug, path, &match); if (r < 0) From 18ef0fc9d619149532e60ab90ae8495a114f5f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 07:39:45 +0200 Subject: [PATCH 07/50] Continue on empty lines in lua --- src/augtool.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 39e7b891b..4e7e0a21d 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -1079,6 +1079,11 @@ static int main_loop(void) { return ret; } + if (*line == '\0' || *line == '#') { + free(line); + continue; + } + if (use_lua) { // FIXME: newlines don't work! code = luaL_loadbuffer(LS, line, strlen(line), "line") || lua_pcall(LS, 0, 0, 0); @@ -1091,11 +1096,6 @@ static int main_loop(void) { ret = -1; } } else { - if (*line == '\0' || *line == '#') { - free(line); - continue; - } - code = run_command(line); if (code == -2) { free(line); From 3f4ead554556a039bb010049555bfd6dbf2bb3d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 08:31:36 +0200 Subject: [PATCH 08/50] Make multiline work in lua REPL, irb style --- src/augtool.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 4e7e0a21d..30a7f3b42 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -65,6 +65,7 @@ char *history_file = NULL; #define AUGTOOL_PROMPT "augtool> " #define AUGTOOL_LUA_PROMPT "augtool|lua> " +#define AUGTOOL_LUA_CONT_PROMPT "augtool|lua?> " /* * General utilities @@ -966,8 +967,18 @@ static void setup_lua(void) { // lua_register(LS, "errors", lua_aug_errors); } +static int ends_with(const char *str, const char *suffix) { + if (!str || !suffix) + return 0; + size_t lenstr = strlen(str); + size_t lensuffix = strlen(suffix); + if (lensuffix > lenstr) + return 0; + return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; +} + static int main_loop(void) { - char *line = NULL; + char *line = NULL, *cur_line = NULL; int ret = 0; char inputline [128]; int code; @@ -1021,10 +1032,14 @@ static int main_loop(void) { while(1) { if (get_line) { - if (use_lua) - line = readline(AUGTOOL_LUA_PROMPT); - else + if (use_lua) { + if (cur_line == NULL) + line = readline(AUGTOOL_LUA_PROMPT); + else + line = readline(AUGTOOL_LUA_CONT_PROMPT); + } else { line = readline(AUGTOOL_PROMPT); + } } else { line = NULL; } @@ -1086,14 +1101,29 @@ static int main_loop(void) { if (use_lua) { // FIXME: newlines don't work! - code = luaL_loadbuffer(LS, line, strlen(line), "line") || lua_pcall(LS, 0, 0, 0); + char *buf; + if (cur_line == NULL) { + buf = malloc(sizeof(char) * strlen(line)); + strcpy(buf, line); + } else { + sprintf(buf, "%s\n%s", cur_line, line); + } + code = luaL_loadbuffer(LS, buf, strlen(buf), "line") || lua_pcall(LS, 0, 0, 0); if (isatty(fileno(stdin))) add_history(line); if (code) { - fprintf(stderr, "%s\n", lua_tostring(LS, -1)); - lua_pop(LS, 1); /* pop error message from the stack */ - ret = -1; + const char *err = lua_tostring(LS, -1); + if (ends_with(err, " near ")) { + cur_line = malloc(sizeof(char) * strlen(buf)); + strcpy(cur_line, buf); + } else { + fprintf(stderr, "%s\n", err); + lua_pop(LS, 1); /* pop error message from the stack */ + ret = -1; + } + } else { + cur_line = NULL; } } else { code = run_command(line); From b3519995dbae719c81780544fab2e6ebb804d8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 16:14:27 +0200 Subject: [PATCH 09/50] Make command as arg work with lua --- src/augtool.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 30a7f3b42..aaa6beade 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -986,9 +986,6 @@ static int main_loop(void) { bool get_line = true; bool in_interactive = false; - if (use_lua) - setup_lua(); - if (inputfile) { if (use_lua) { if (luaL_dofile(LS, inputfile)) { @@ -1156,9 +1153,16 @@ static int run_args(int argc, char **argv) { strcat(line, argv[i]); strcat(line, " "); } - if (echo_commands) - printf("%s%s\n", AUGTOOL_PROMPT, line); - code = run_command(line, timing); + if (echo_commands) { + if (use_lua) + printf("%s%s\n", AUGTOOL_LUA_PROMPT, line); + else + printf("%s%s\n", AUGTOOL_PROMPT, line); + } + if (use_lua) + code = luaL_loadbuffer(LS, line, strlen(line), "line") || lua_pcall(LS, 0, 0, 0); + else + code = run_command(line, timing); free(line); if (code >= 0 && auto_save) if (echo_commands) @@ -1212,6 +1216,9 @@ int main(int argc, char **argv) { } gettimeofday(&start, NULL); + if (use_lua) + setup_lua(); + aug = aug_init(root, loadpath, flags|AUG_NO_ERR_CLOSE); gettimeofday(&stop, NULL); From f8eeb2222ff28c15085c989868dcb77c6b1c71dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 17 Sep 2015 16:15:35 +0200 Subject: [PATCH 10/50] Lua aliases for store/retrieve --- src/augtool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/augtool.c b/src/augtool.c index aaa6beade..38b6d2771 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -958,7 +958,9 @@ static void setup_lua(void) { lua_register(LS, "save", lua_aug_save); lua_register(LS, "load", lua_aug_load); lua_register(LS, "text_store", lua_aug_text_store); + lua_register(LS, "store", lua_aug_text_store); // alias lua_register(LS, "text_retrieve", lua_aug_text_retrieve); + lua_register(LS, "retrieve", lua_aug_text_retrieve); // alias // lua_register(LS, "escape_name", lua_aug_escape_name); lua_register(LS, "transform", lua_aug_transform); // lua_register(LS, "print", lua_aug_print); From 70e68d19586d90461f85ec1eca0bf0da51734ff4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 23 Sep 2015 11:05:47 +0200 Subject: [PATCH 11/50] Pass arguments to lua script --- src/augtool.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 38b6d2771..3e96e2554 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -979,7 +979,7 @@ static int ends_with(const char *str, const char *suffix) { return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; } -static int main_loop(void) { +static int main_loop(int argc, char **argv) { char *line = NULL, *cur_line = NULL; int ret = 0; char inputline [128]; @@ -990,8 +990,15 @@ static int main_loop(void) { if (inputfile) { if (use_lua) { - if (luaL_dofile(LS, inputfile)) { - printf("%s\n", lua_tostring(LS, -1)); + if (luaL_loadfile(LS, inputfile)) { + printf("luaL_loadfile() failed: %s\n", lua_tostring(LS, -1)); + lua_close(LS); + return -1; + } + for (int i=0; i < argc; i++) + lua_pushstring(LS, argv[i]); + if (lua_pcall(LS, argc, 0, 0)) { + printf("lua_pcall() failed: %s\n", lua_tostring(LS, -1)); lua_close(LS); return -1; } @@ -1241,11 +1248,11 @@ int main(int argc, char **argv) { return EXIT_SUCCESS; } readline_init(); - if (optind < argc) { + if (optind < argc && !use_lua) { // Accept one command from the command line r = run_args(argc - optind, argv+optind); } else { - r = main_loop(); + r = main_loop(argc - optind, argv+optind); } if (history_file != NULL) write_history(history_file); From 0f5851f0fb6e5e24aa87fe4dd18a39dcff76db75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 23 Sep 2015 16:25:37 +0200 Subject: [PATCH 12/50] Use an aug table to assign lua methods --- src/augtool.c | 96 ++++++++++++------------------- tests/test.auglua | 144 +++++++++++++++++++++++----------------------- 2 files changed, 110 insertions(+), 130 deletions(-) diff --git a/src/augtool.c b/src/augtool.c index 3e96e2554..5797d5d45 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -909,64 +909,44 @@ static int lua_aug_transform(lua_State *L) { static void setup_lua(void) { LS = luaL_newstate(); luaL_openlibs(LS); - lua_register(LS, "aug_get", lua_aug_get); - lua_register(LS, "aug_label", lua_aug_label); - lua_register(LS, "aug_set", lua_aug_set); - lua_register(LS, "aug_setm", lua_aug_setm); - // lua_register(LS, "aug_span", lua_aug_span); - lua_register(LS, "aug_insert", lua_aug_insert); - lua_register(LS, "aug_rm", lua_aug_rm); - lua_register(LS, "aug_mv", lua_aug_mv); - lua_register(LS, "aug_cp", lua_aug_cp); - lua_register(LS, "aug_rename", lua_aug_rename); - lua_register(LS, "aug_clear", lua_aug_clear); - lua_register(LS, "aug_clearm", lua_aug_clearm); - lua_register(LS, "aug_touch", lua_aug_touch); - lua_register(LS, "aug_matches", lua_aug_matches); - lua_register(LS, "aug_match", lua_aug_match); - lua_register(LS, "aug_defvar", lua_aug_defvar); - lua_register(LS, "aug_defnode", lua_aug_defnode); - lua_register(LS, "aug_save", lua_aug_save); - lua_register(LS, "aug_load", lua_aug_load); - lua_register(LS, "aug_text_store", lua_aug_text_store); - lua_register(LS, "aug_text_retrieve", lua_aug_text_retrieve); - // lua_register(LS, "aug_escape_name", lua_aug_escape_name); - lua_register(LS, "aug_transform", lua_aug_transform); - // lua_register(LS, "aug_print", lua_aug_print); - // lua_register(LS, "aug_to_xml", lua_aug_to_xml); - // lua_register(LS, "aug_srun", lua_aug_srun); - // lua_register(LS, "aug_errors", lua_aug_errors); - - // short names - lua_register(LS, "get", lua_aug_get); - lua_register(LS, "label", lua_aug_label); - lua_register(LS, "set", lua_aug_set); - lua_register(LS, "setm", lua_aug_setm); - // lua_register(LS, "span", lua_aug_span); - lua_register(LS, "insert", lua_aug_insert); - lua_register(LS, "ins", lua_aug_insert); // alias - lua_register(LS, "rm", lua_aug_rm); - lua_register(LS, "mv", lua_aug_mv); - lua_register(LS, "move", lua_aug_mv); // alias - lua_register(LS, "cp", lua_aug_cp); - lua_register(LS, "copy", lua_aug_cp); // alias - lua_register(LS, "rename", lua_aug_rename); - lua_register(LS, "matches", lua_aug_matches); - lua_register(LS, "match", lua_aug_match); - lua_register(LS, "defvar", lua_aug_defvar); - lua_register(LS, "defnode", lua_aug_defnode); - lua_register(LS, "save", lua_aug_save); - lua_register(LS, "load", lua_aug_load); - lua_register(LS, "text_store", lua_aug_text_store); - lua_register(LS, "store", lua_aug_text_store); // alias - lua_register(LS, "text_retrieve", lua_aug_text_retrieve); - lua_register(LS, "retrieve", lua_aug_text_retrieve); // alias - // lua_register(LS, "escape_name", lua_aug_escape_name); - lua_register(LS, "transform", lua_aug_transform); - // lua_register(LS, "print", lua_aug_print); - // lua_register(LS, "to_xml", lua_aug_to_xml); - // lua_register(LS, "srun", lua_aug_srun); - // lua_register(LS, "errors", lua_aug_errors); + + static const luaL_Reg aug[] = { + { "get", lua_aug_get }, + { "label", lua_aug_label }, + { "set", lua_aug_set }, + { "setm", lua_aug_setm }, + //{ "span", lua_aug_span }, + { "insert", lua_aug_insert }, + { "ins", lua_aug_insert }, // alias + { "rm", lua_aug_rm }, + { "mv", lua_aug_mv }, + { "move", lua_aug_mv }, // alias + { "cp", lua_aug_cp }, + { "copy", lua_aug_cp }, // alias + { "rename", lua_aug_rename }, + { "clear", lua_aug_clear }, + { "clearm", lua_aug_clearm }, + { "touch", lua_aug_touch }, + { "matches", lua_aug_matches }, + { "match", lua_aug_match }, + { "defvar", lua_aug_defvar }, + { "defnode", lua_aug_defnode }, + { "save", lua_aug_save }, + { "load", lua_aug_load }, + { "text_store", lua_aug_text_store }, + { "store", lua_aug_text_store }, // alias + { "text_retrieve", lua_aug_text_retrieve }, + { "retrieve", lua_aug_text_retrieve }, // alias + //{ "escape_name", lua_aug_escape_name }, + { "transform", lua_aug_transform }, + //{ "print", lua_aug_print }, + //{ "to_xml", lua_aug_to_xml }, + //{ "errors", lua_aug_errors }, + { NULL, NULL } + }; + + luaL_newlib(LS, aug); + lua_setglobal(LS, "aug"); } static int ends_with(const char *str, const char *suffix) { diff --git a/tests/test.auglua b/tests/test.auglua index 576e6ec70..57ff31a28 100644 --- a/tests/test.auglua +++ b/tests/test.auglua @@ -1,107 +1,107 @@ ---- test aug_get() -assert(aug_get("etc/passwd/root/uid") == "0") +--- test aug.get() +assert(aug.get("etc/passwd/root/uid") == "0") ---- test aug_label() -assert(aug_label("etc/passwd/sync") == "sync") +--- test aug.label() +assert(aug.label("etc/passwd/sync") == "sync") ---- test aug_set() -aug_set("/foo", "bar") -assert(aug_get("/foo") == "bar") +--- test aug.set() +aug.set("/foo", "bar") +assert(aug.get("/foo") == "bar") ---- test aug_setm() -aug_setm("etc/passwd/*", "shell", "zsh") -assert(aug_get("etc/passwd/sync/shell") == "zsh") +--- test aug.setm() +aug.setm("etc/passwd/*", "shell", "zsh") +assert(aug.get("etc/passwd/sync/shell") == "zsh") ---- test aug_span() +--- test aug.span() --- TODO ---- test aug_insert() -aug_insert("etc/passwd/*[1]", "foo", true) -assert(aug_label("etc/passwd/*[1]") == "foo") +--- test aug.insert() +aug.insert("etc/passwd/*[1]", "foo", true) +assert(aug.label("etc/passwd/*[1]") == "foo") ---- test aug_rm() -aug_rm("etc/passwd/sync") -assert(aug_label("etc/passwd/sync") == nil) +--- test aug.rm() +aug.rm("etc/passwd/sync") +assert(aug.label("etc/passwd/sync") == nil) ---- test aug_mv() -aug_mv("etc/passwd/root", "etc/passwd/qux") -assert(aug_label("etc/passwd/*[last()]") == "qux") -assert(aug_label("etc/passwd/root") == nil) +--- test aug.mv() +aug.mv("etc/passwd/root", "etc/passwd/qux") +assert(aug.label("etc/passwd/*[last()]") == "qux") +assert(aug.label("etc/passwd/root") == nil) ---- test aug_cp() -aug_cp("etc/passwd/qux", "etc/passwd/root") -assert(aug_get("etc/passwd/root/uid") == aug_get("etc/passwd/qux/uid")) +--- test aug.cp() +aug.cp("etc/passwd/qux", "etc/passwd/root") +assert(aug.get("etc/passwd/root/uid") == aug.get("etc/passwd/qux/uid")) ---- test aug_rename() -aug_rename("etc/passwd/qux", "bar") -assert(aug_get("etc/passwd/root/uid") == aug_get("etc/passwd/bar/uid")) +--- test aug.rename() +aug.rename("etc/passwd/qux", "bar") +assert(aug.get("etc/passwd/root/uid") == aug.get("etc/passwd/bar/uid")) ---- test aug_clear() -aug_clear("etc/passwd/qux/uid") -assert(aug_get("etc/passwd/qux/uid") == nil) +--- test aug.clear() +aug.clear("etc/passwd/qux/uid") +assert(aug.get("etc/passwd/qux/uid") == nil) ---- test aug_clearm() -aug_clearm("etc/passwd/*", "uid") -assert(aug_get("etc/passwd/root/uid") == nil) +--- test aug.clearm() +aug.clearm("etc/passwd/*", "uid") +assert(aug.get("etc/passwd/root/uid") == nil) ---- test aug_touch() -aug_touch("etc/passwd/flex/uid") -assert(aug_get("etc/passwd/flex/uid") == nil) -aug_touch("etc/passwd/root/gid") -assert(aug_get("etc/passwd/root/gid") == "0") +--- test aug.touch() +aug.touch("etc/passwd/flex/uid") +assert(aug.get("etc/passwd/flex/uid") == nil) +aug.touch("etc/passwd/root/gid") +assert(aug.get("etc/passwd/root/gid") == "0") ---- test aug_matches() -m = aug_matches("etc/passwd/*") +--- test aug.matches() +m = aug.matches("etc/passwd/*") assert(m == 22) ---- test aug_match() -m = aug_match("etc/passwd/*") +--- test aug.match() +m = aug.match("etc/passwd/*") c = 0 for k, v in pairs(m) do c= c+1 end assert(c > 0) assert(m[1] == "/files/etc/passwd/foo") ---- test aug_defvar() -aug_defvar("root", "etc/passwd/root") -assert(aug_label("$root") == "root") +--- test aug.defvar() +aug.defvar("root", "etc/passwd/root") +assert(aug.label("$root") == "root") ---- test aug_defnode() -aug_defnode("raphink", "etc/passwd/raphink/uid", "314") -assert(aug_get("$raphink") == "314") +--- test aug.defnode() +aug.defnode("raphink", "etc/passwd/raphink/uid", "314") +assert(aug.get("$raphink") == "314") --- TODO: support 3 arguments ---- aug_defnode("gid", "etc/passwd/raphink/gid") ---- assert(aug_get("$gid") == nil) +--- aug.defnode("gid", "etc/passwd/raphink/gid") +--- assert(aug.get("$gid") == nil) ---- test aug_save() +--- test aug.save() --- reload tree to be clean -aug_load() -aug_set("etc/passwd/root/shell", "/bin/zsh") -aug_save() +aug.load() +aug.set("etc/passwd/root/shell", "/bin/zsh") +aug.save() ---- test aug_load() -aug_load() +--- test aug.load() +aug.load() ---- test aug_text_store() -aug_set("/input", "key=value\n") -aug_text_store("Shellvars.lns", "/input", "/parsed") -assert(aug_get("/parsed/key") == "value") +--- test aug.text_store() +aug.set("/input", "key=value\n") +aug.text_store("Shellvars.lns", "/input", "/parsed") +assert(aug.get("/parsed/key") == "value") ---- test aug_text_retrieve() -aug_set("/parsed/key", "newval") -aug_text_retrieve("Shellvars.lns", "/input", "/parsed", "/output") -assert(aug_get("/output") == "key=newval\n") +--- test aug.text_retrieve() +aug.set("/parsed/key", "newval") +aug.text_retrieve("Shellvars.lns", "/input", "/parsed", "/output") +assert(aug.get("/output") == "key=newval\n") ---- test aug_escape_name() +--- test aug.escape_name() --- test that? ---- test aug_transform() -aug_transform("Json.lns", "/tmp/foo.json", false) -assert(aug_get("/augeas/load/Json/incl[1]") == "/tmp/foo.json") +--- test aug.transform() +aug.transform("Json.lns", "/tmp/foo.json", false) +assert(aug.get("/augeas/load/Json/incl[1]") == "/tmp/foo.json") ---- test aug_print() +--- test aug.print() ---- test aug_to_xml() +--- test aug.to_xml() ---- test aug_srun() +--- test aug.srun() ---- test aug_errors() +--- test aug.errors() From ef23c22462df0a55cc91fc92f38013ee51001f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 15:13:07 +0200 Subject: [PATCH 13/50] Put lua code in src/auglua.c --- src/Makefile.am | 2 +- src/augeas_sym.version | 1 + src/auglua.c | 527 +++++++++++++++++++++++++++++++++++++++++ src/auglua.h | 46 ++++ src/augtool.c | 454 +---------------------------------- 5 files changed, 580 insertions(+), 450 deletions(-) create mode 100644 src/auglua.c create mode 100644 src/auglua.h diff --git a/src/Makefile.am b/src/Makefile.am index 1738ef164..90c0afc16 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ bin_PROGRAMS = augtool augparse include_HEADERS = augeas.h fa.h -libaugeas_la_SOURCES = augeas.h augeas.c augrun.c pathx.c \ +libaugeas_la_SOURCES = augeas.h augeas.c augrun.c auglua.h auglua.c pathx.c \ internal.h internal.c \ memory.h memory.c ref.h ref.c \ syntax.c syntax.h parser.y builtin.c lens.c lens.h regexp.c regexp.h \ diff --git a/src/augeas_sym.version b/src/augeas_sym.version index 0c4d7c43b..4e3ad99b6 100644 --- a/src/augeas_sym.version +++ b/src/augeas_sym.version @@ -69,4 +69,5 @@ AUGEAS_0.18.0 { AUGEAS_0.20.0 { global: aug_escape_name; + setup_lua; } AUGEAS_0.18.0; diff --git a/src/auglua.c b/src/auglua.c new file mode 100644 index 000000000..e15b67fc2 --- /dev/null +++ b/src/auglua.c @@ -0,0 +1,527 @@ +/* + * auglua.c: lua integration for augtool + * + * Copyright (C) 2015 Raphaël Pinson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Raphaël Pinson + */ + +#include "internal.h" +#include "augeas.h" +#include "auglua.h" +#include +#include +#include +#include + +typedef struct LuaAug { + augeas *aug; +} LuaAug; + +static const char Key = 'k'; + +static augeas *checkaug(lua_State *L) { + lua_pushlightuserdata(L, (void *)&Key); + lua_gettable(L, LUA_REGISTRYINDEX); + augeas *b = (augeas *)lua_touserdata(L, -1); // Convert value + return b; +} + +static void lua_checkargs(lua_State *L, const char *name, int arity) { + int n = lua_gettop(L); + char msg[1024]; + if (n != arity) { + snprintf(msg, sizeof(msg), "Wrong number of arguments for '%s'", name); + lua_pushstring(L, msg); + lua_error(L); + } +} + +static int lua_pusherror(lua_State *L) { + augeas *aug = checkaug(L); + lua_pushstring(L, aug_error_message(aug)); + lua_error(L); + return 1; +} + +static int lua_aug_get(lua_State *L) { + int r; + const char *path, *value; + + /* get number of arguments */ + lua_checkargs(L, "aug_get", 1); + + path = luaL_checkstring(L, 1); + + augeas *aug = checkaug(L); + r = aug_get(aug, path, &value); + if (r < 0) + return lua_pusherror(L); + lua_pushstring(L, value); + + /* return the number of results */ + return 1; +} + +static int lua_aug_label(lua_State *L) { + int r; + const char *path, *value; + + lua_checkargs(L, "aug_label", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + augeas *aug = checkaug(L); + r = aug_label(aug, path, &value); + if (r < 0) + return lua_pusherror(L); + lua_pushstring(L, value); + + /* return the number of results */ + return 1; +} + +static int lua_aug_set(lua_State *L) { + int r; + const char *path, *value; + + lua_checkargs(L, "aug_set", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + value = luaL_checkstring(L, 2); + + augeas *aug = checkaug(L); + r = aug_set(aug, path, value); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_setm(lua_State *L) { + int r; + const char *base, *sub, *value; + + lua_checkargs(L, "aug_setm", 3); + + base = luaL_checkstring(L, 1); + // TODO: check string really + sub = luaL_checkstring(L, 2); + value = luaL_checkstring(L, 3); + + augeas *aug = checkaug(L); + r = aug_setm(aug, base, sub, value); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_insert(lua_State *L) { + int r; + const char *path, *label; + int before; + + lua_checkargs(L, "aug_insert", 3); + + path = luaL_checkstring(L, 1); + // TODO: check string really + label = luaL_checkstring(L, 2); + before = lua_toboolean(L, 3); + + augeas *aug = checkaug(L); + r = aug_insert(aug, path, label, before); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_rm(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_rm", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + augeas *aug = checkaug(L); + r = aug_rm(aug, path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_mv(lua_State *L) { + int r; + const char *path, *new_path; + + lua_checkargs(L, "aug_mv", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + new_path = luaL_checkstring(L, 2); + + augeas *aug = checkaug(L); + r = aug_mv(aug, path, new_path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_cp(lua_State *L) { + int r; + const char *path, *new_path; + + lua_checkargs(L, "aug_cp", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + new_path = luaL_checkstring(L, 2); + + augeas *aug = checkaug(L); + r = aug_cp(aug, path, new_path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_rename(lua_State *L) { + int r; + const char *path, *label; + + lua_checkargs(L, "aug_rename", 2); + + path = luaL_checkstring(L, 1); + // TODO: check string really + label = luaL_checkstring(L, 2); + + augeas *aug = checkaug(L); + r = aug_rename(aug, path, label); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_clear(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_clear", 1); + + path = luaL_checkstring(L, 1); + + augeas *aug = checkaug(L); + r = aug_set(aug, path, NULL); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_clearm(lua_State *L) { + int r; + const char *base, *sub; + + lua_checkargs(L, "aug_clearm", 2); + + base = luaL_checkstring(L, 1); + sub = luaL_checkstring(L, 2); + + augeas *aug = checkaug(L); + r = aug_setm(aug, base, sub, NULL); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_touch(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_touch", 1); + + path = luaL_checkstring(L, 1); + + augeas *aug = checkaug(L); + r = aug_match(aug, path, NULL); + if (r == 0) { + r = aug_set(aug, path, NULL); + if (r < 0) + return lua_pusherror(L); + } + + /* return the number of results */ + return 0; +} + +static int lua_aug_matches(lua_State *L) { + int r; + const char *path; + + lua_checkargs(L, "aug_matches", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + augeas *aug = checkaug(L); + r = aug_match(aug, path, NULL); + if (r < 0) + return lua_pusherror(L); + + lua_pushinteger(L, r); + /* return the number of results */ + return 1; +} + +static int lua_aug_match(lua_State *L) { + int r, i; + const char *path; + char **match = NULL; + + lua_checkargs(L, "aug_match", 1); + + path = luaL_checkstring(L, 1); + // TODO: check string really + + augeas *aug = checkaug(L); + r = aug_match(aug, path, &match); + if (r < 0) + return lua_pusherror(L); + + lua_newtable(L); + for (i = 0; i < r; i++) { + lua_pushnumber(L, i+1); + lua_pushstring(L, match[i]); + lua_settable(L, -3); + free(match[i]); + } + free(match); + lua_pushinteger(L, r); + + /* return the number of results */ + return 2; +} + +static int lua_aug_defvar(lua_State *L) { + int r; + const char *name, *expr; + + lua_checkargs(L, "aug_defvar", 2); + + name = luaL_checkstring(L, 1); + // TODO: check string really + expr = luaL_checkstring(L, 2); + + augeas *aug = checkaug(L); + r = aug_defvar(aug, name, expr); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_defnode(lua_State *L) { + int r; + const char *name, *expr, *value = NULL; + + lua_checkargs(L, "aug_defnode", 3); + + name = luaL_checkstring(L, 1); + // TODO: check string really + expr = luaL_checkstring(L, 2); + value = lua_tostring(L, 3); + + augeas *aug = checkaug(L); + r = aug_defnode(aug, name, expr, value, NULL); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_save(lua_State *L) { + int r; + + lua_checkargs(L, "aug_save", 0); + + augeas *aug = checkaug(L); + r = aug_save(aug); + if (r == -1) { + lua_pushstring(L, "saving failed (run 'errors' for details)"); + lua_error(L); + } else { + r = aug_match(aug, "/augeas/events/saved", NULL); + if (r > 0) + printf("Saved %d file(s)\n", r); + } + + /* return the number of results */ + return 0; +} + +static int lua_aug_load(lua_State *L) { + int r; + + lua_checkargs(L, "aug_load", 0); + + augeas *aug = checkaug(L); + r = aug_load(aug); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_text_store(lua_State *L) { + int r; + const char *lens, *node, *path; + + lua_checkargs(L, "aug_text_store", 3); + + lens = luaL_checkstring(L, 1); + node = luaL_checkstring(L, 2); + path = luaL_checkstring(L, 3); + + augeas *aug = checkaug(L); + r = aug_text_store(aug, lens, node, path); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_text_retrieve(lua_State *L) { + int r; + const char *lens, *node_in, *path, *node_out; + + lua_checkargs(L, "aug_text_retrieve", 4); + + lens = luaL_checkstring(L, 1); + node_in = luaL_checkstring(L, 2); + path = luaL_checkstring(L, 3); + node_out = luaL_checkstring(L, 4); + + augeas *aug = checkaug(L); + r = aug_text_retrieve(aug, lens, node_in, path, node_out); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +static int lua_aug_transform(lua_State *L) { + int r; + const char *lens, *file; + bool excl; + + lua_checkargs(L, "aug_transform", 3); + + lens = luaL_checkstring(L, 1); + file = luaL_checkstring(L, 2); + excl = lua_toboolean(L, 3); + + augeas *aug = checkaug(L); + r = aug_transform(aug, lens, file, excl); + if (r < 0) + return lua_pusherror(L); + + /* return the number of results */ + return 0; +} + +struct lua_State *setup_lua(augeas *a) { + lua_State *L = luaL_newstate(); + luaL_openlibs(L); + + lua_pushlightuserdata(L, (void *)&Key); + lua_pushlightuserdata(L, (void *)a); // Push pointer + lua_settable(L, LUA_REGISTRYINDEX); + + static const luaL_Reg augfuncs[] = { + { "get", lua_aug_get }, + { "label", lua_aug_label }, + { "set", lua_aug_set }, + { "setm", lua_aug_setm }, + //{ "span", lua_aug_span }, + { "insert", lua_aug_insert }, + { "ins", lua_aug_insert }, // alias + { "rm", lua_aug_rm }, + { "mv", lua_aug_mv }, + { "move", lua_aug_mv }, // alias + { "cp", lua_aug_cp }, + { "copy", lua_aug_cp }, // alias + { "rename", lua_aug_rename }, + { "clear", lua_aug_clear }, + { "clearm", lua_aug_clearm }, + { "touch", lua_aug_touch }, + { "matches", lua_aug_matches }, + { "match", lua_aug_match }, + { "defvar", lua_aug_defvar }, + { "defnode", lua_aug_defnode }, + { "save", lua_aug_save }, + { "load", lua_aug_load }, + { "text_store", lua_aug_text_store }, + { "store", lua_aug_text_store }, // alias + { "text_retrieve", lua_aug_text_retrieve }, + { "retrieve", lua_aug_text_retrieve }, // alias + //{ "escape_name", lua_aug_escape_name }, + { "transform", lua_aug_transform }, + //{ "print", lua_aug_print }, + //{ "to_xml", lua_aug_to_xml }, + //{ "errors", lua_aug_errors }, + { NULL, NULL } + }; + + luaL_newlib(L, augfuncs); + lua_setglobal(L, "aug"); + + return L; +} + + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ + diff --git a/src/auglua.h b/src/auglua.h new file mode 100644 index 000000000..ed672fc7e --- /dev/null +++ b/src/auglua.h @@ -0,0 +1,46 @@ +/* + * auglua.h: Lua helper lib for Augeas + * + * Copyright (C) 2015 Raphaël Pinson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Raphaël Pinson + */ +#include + +#ifndef AUGLUA_H_ +#define AUGLUA_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct lua_State *setup_lua(augeas *a); + +#ifdef __cplusplus +} +#endif + +#endif + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff --git a/src/augtool.c b/src/augtool.c index 5797d5d45..8e8de7f4d 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -22,6 +22,7 @@ #include #include "augeas.h" +#include "auglua.h" #include "internal.h" #include "safe-alloc.h" @@ -502,452 +503,6 @@ static void install_signal_handlers(void) { sigaction(SIGINT, &sigint_action, NULL); } -static void lua_checkargs(lua_State *L, const char *name, int arity) { - int n = lua_gettop(L); - char msg[1024]; - if (n != arity) { - snprintf(msg, sizeof(msg), "Wrong number of arguments for '%s'", name); - lua_pushstring(L, msg); - lua_error(L); - } -} - -static int lua_pusherror(lua_State *L) { - lua_pushstring(L, aug_error_message(aug)); - lua_error(L); - return 1; -} - -static int lua_aug_get(lua_State *L) { - int r; - const char *path, *value; - - /* get number of arguments */ - lua_checkargs(L, "aug_get", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - r = aug_get(aug, path, &value); - if (r < 0) - return lua_pusherror(L); - lua_pushstring(L, value); - - /* return the number of results */ - return 1; -} - -static int lua_aug_label(lua_State *L) { - int r; - const char *path, *value; - - lua_checkargs(L, "aug_label", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - r = aug_label(aug, path, &value); - if (r < 0) - return lua_pusherror(L); - lua_pushstring(L, value); - - /* return the number of results */ - return 1; -} - -static int lua_aug_set(lua_State *L) { - int r; - const char *path, *value; - - lua_checkargs(L, "aug_set", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - value = luaL_checkstring(L, 2); - - r = aug_set(aug, path, value); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_setm(lua_State *L) { - int r; - const char *base, *sub, *value; - - lua_checkargs(L, "aug_setm", 3); - - base = luaL_checkstring(L, 1); - // TODO: check string really - sub = luaL_checkstring(L, 2); - value = luaL_checkstring(L, 3); - - r = aug_setm(aug, base, sub, value); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_insert(lua_State *L) { - int r; - const char *path, *label; - int before; - - lua_checkargs(L, "aug_insert", 3); - - path = luaL_checkstring(L, 1); - // TODO: check string really - label = luaL_checkstring(L, 2); - before = lua_toboolean(L, 3); - - r = aug_insert(aug, path, label, before); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_rm(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_rm", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - r = aug_rm(aug, path); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_mv(lua_State *L) { - int r; - const char *path, *new_path; - - lua_checkargs(L, "aug_mv", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - new_path = luaL_checkstring(L, 2); - - r = aug_mv(aug, path, new_path); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_cp(lua_State *L) { - int r; - const char *path, *new_path; - - lua_checkargs(L, "aug_cp", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - new_path = luaL_checkstring(L, 2); - - r = aug_cp(aug, path, new_path); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_rename(lua_State *L) { - int r; - const char *path, *label; - - lua_checkargs(L, "aug_rename", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - label = luaL_checkstring(L, 2); - - r = aug_rename(aug, path, label); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_clear(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_clear", 1); - - path = luaL_checkstring(L, 1); - - r = aug_set(aug, path, NULL); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_clearm(lua_State *L) { - int r; - const char *base, *sub; - - lua_checkargs(L, "aug_clearm", 2); - - base = luaL_checkstring(L, 1); - sub = luaL_checkstring(L, 2); - - r = aug_setm(aug, base, sub, NULL); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_touch(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_touch", 1); - - path = luaL_checkstring(L, 1); - - r = aug_match(aug, path, NULL); - if (r == 0) { - r = aug_set(aug, path, NULL); - if (r < 0) - return lua_pusherror(L); - } - - /* return the number of results */ - return 0; -} - -static int lua_aug_matches(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_matches", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - r = aug_match(aug, path, NULL); - if (r < 0) - return lua_pusherror(L); - - lua_pushinteger(L, r); - /* return the number of results */ - return 1; -} - -static int lua_aug_match(lua_State *L) { - int r, i; - const char *path; - char **match = NULL; - - lua_checkargs(L, "aug_match", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - r = aug_match(aug, path, &match); - if (r < 0) - return lua_pusherror(L); - - lua_newtable(L); - for (i = 0; i < r; i++) { - lua_pushnumber(L, i+1); - lua_pushstring(L, match[i]); - lua_settable(L, -3); - free(match[i]); - } - free(match); - lua_pushinteger(L, r); - - /* return the number of results */ - return 2; -} - -static int lua_aug_defvar(lua_State *L) { - int r; - const char *name, *expr; - - lua_checkargs(L, "aug_defvar", 2); - - name = luaL_checkstring(L, 1); - // TODO: check string really - expr = luaL_checkstring(L, 2); - - r = aug_defvar(aug, name, expr); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_defnode(lua_State *L) { - int r; - const char *name, *expr, *value = NULL; - - lua_checkargs(L, "aug_defnode", 3); - - name = luaL_checkstring(L, 1); - // TODO: check string really - expr = luaL_checkstring(L, 2); - value = lua_tostring(L, 3); - - r = aug_defnode(aug, name, expr, value, NULL); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_save(lua_State *L) { - int r; - - lua_checkargs(L, "aug_save", 0); - - r = aug_save(aug); - if (r == -1) { - lua_pushstring(L, "saving failed (run 'errors' for details)"); - lua_error(L); - } else { - r = aug_match(aug, "/augeas/events/saved", NULL); - if (r > 0) - printf("Saved %d file(s)\n", r); - } - - /* return the number of results */ - return 0; -} - -static int lua_aug_load(lua_State *L) { - int r; - - lua_checkargs(L, "aug_load", 0); - - r = aug_load(aug); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_text_store(lua_State *L) { - int r; - const char *lens, *node, *path; - - lua_checkargs(L, "aug_text_store", 3); - - lens = luaL_checkstring(L, 1); - node = luaL_checkstring(L, 2); - path = luaL_checkstring(L, 3); - - r = aug_text_store(aug, lens, node, path); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_text_retrieve(lua_State *L) { - int r; - const char *lens, *node_in, *path, *node_out; - - lua_checkargs(L, "aug_text_retrieve", 4); - - lens = luaL_checkstring(L, 1); - node_in = luaL_checkstring(L, 2); - path = luaL_checkstring(L, 3); - node_out = luaL_checkstring(L, 4); - - r = aug_text_retrieve(aug, lens, node_in, path, node_out); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static int lua_aug_transform(lua_State *L) { - int r; - const char *lens, *file; - bool excl; - - lua_checkargs(L, "aug_transform", 3); - - lens = luaL_checkstring(L, 1); - file = luaL_checkstring(L, 2); - excl = lua_toboolean(L, 3); - - r = aug_transform(aug, lens, file, excl); - if (r < 0) - return lua_pusherror(L); - - /* return the number of results */ - return 0; -} - -static void setup_lua(void) { - LS = luaL_newstate(); - luaL_openlibs(LS); - - static const luaL_Reg aug[] = { - { "get", lua_aug_get }, - { "label", lua_aug_label }, - { "set", lua_aug_set }, - { "setm", lua_aug_setm }, - //{ "span", lua_aug_span }, - { "insert", lua_aug_insert }, - { "ins", lua_aug_insert }, // alias - { "rm", lua_aug_rm }, - { "mv", lua_aug_mv }, - { "move", lua_aug_mv }, // alias - { "cp", lua_aug_cp }, - { "copy", lua_aug_cp }, // alias - { "rename", lua_aug_rename }, - { "clear", lua_aug_clear }, - { "clearm", lua_aug_clearm }, - { "touch", lua_aug_touch }, - { "matches", lua_aug_matches }, - { "match", lua_aug_match }, - { "defvar", lua_aug_defvar }, - { "defnode", lua_aug_defnode }, - { "save", lua_aug_save }, - { "load", lua_aug_load }, - { "text_store", lua_aug_text_store }, - { "store", lua_aug_text_store }, // alias - { "text_retrieve", lua_aug_text_retrieve }, - { "retrieve", lua_aug_text_retrieve }, // alias - //{ "escape_name", lua_aug_escape_name }, - { "transform", lua_aug_transform }, - //{ "print", lua_aug_print }, - //{ "to_xml", lua_aug_to_xml }, - //{ "errors", lua_aug_errors }, - { NULL, NULL } - }; - - luaL_newlib(LS, aug); - lua_setglobal(LS, "aug"); -} static int ends_with(const char *str, const char *suffix) { if (!str || !suffix) @@ -1205,9 +760,6 @@ int main(int argc, char **argv) { } gettimeofday(&start, NULL); - if (use_lua) - setup_lua(); - aug = aug_init(root, loadpath, flags|AUG_NO_ERR_CLOSE); gettimeofday(&stop, NULL); @@ -1222,6 +774,10 @@ int main(int argc, char **argv) { print_aug_error(); exit(EXIT_FAILURE); } + + if (use_lua) + LS = setup_lua(aug); + add_transforms(transforms, transformslen); if (print_version) { print_version_info(); From 89abf8063e473a15af15d6d4992cdc0915738416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:10:20 +0200 Subject: [PATCH 14/50] Cleanup code --- src/auglua.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index e15b67fc2..81c1cde4c 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -28,17 +28,14 @@ #include #include -typedef struct LuaAug { - augeas *aug; -} LuaAug; static const char Key = 'k'; static augeas *checkaug(lua_State *L) { lua_pushlightuserdata(L, (void *)&Key); lua_gettable(L, LUA_REGISTRYINDEX); - augeas *b = (augeas *)lua_touserdata(L, -1); // Convert value - return b; + augeas *aug = (augeas *)lua_touserdata(L, -1); // Convert value + return aug; } static void lua_checkargs(lua_State *L, const char *name, int arity) { @@ -470,6 +467,8 @@ struct lua_State *setup_lua(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); + // lightuserdata is shared between libs + // do we really want to use that? lua_pushlightuserdata(L, (void *)&Key); lua_pushlightuserdata(L, (void *)a); // Push pointer lua_settable(L, LUA_REGISTRYINDEX); From 74227f2dec352c90ced3f9f757a5ff025e824741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:10:59 +0200 Subject: [PATCH 15/50] Rename setup_lua to luaopen_augeas --- doc/naturaldocs/conf/lenses/Menu.txt | 35 +++++++++++++++++----------- src/augeas_sym.version | 2 +- src/auglua.c | 2 +- src/auglua.h | 2 +- src/augtool.c | 2 +- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/doc/naturaldocs/conf/lenses/Menu.txt b/doc/naturaldocs/conf/lenses/Menu.txt index 41e42b1c1..cc585da5a 100644 --- a/doc/naturaldocs/conf/lenses/Menu.txt +++ b/doc/naturaldocs/conf/lenses/Menu.txt @@ -24,6 +24,11 @@ SubTitle: Modules # yyyy - Four digit year. 2006 is "2006" # year - Four digit year. 2006 is "2006" +# These are indexes you deleted, so Natural Docs will not add them again +# unless you remove them from this line. + +Don't Index: Properties + # -------------------------------------------------------------------------- # @@ -134,7 +139,7 @@ Group: Specific Modules { File: OpenShift_Config (openshift_config.aug) File: OpenShift_Http (openshift_http.aug) File: OpenShift_Quickstarts (openshift_quickstarts.aug) - File: Pagekite (pagekite.aug) + File: Pagekite (pagekite.aug) File: Pam (pam.aug) File: PamConf (pamconf.aug) File: Passwd (passwd.aug) @@ -183,9 +188,15 @@ Group: Specific Modules { File: VWware_Config (vmware_config.aug) File: Vfstab (vfstab.aug) File: Xinetd (xinetd.aug) - File: Xymon (xymon.aug) - File: XymonAlerting (xymonalerting.aug) File: Xorg (xorg.aug) + File: ClamAV (clamav.aug) + File: Dns_Zone (dns_zone.aug) + File: Mailscanner (mailscanner.aug) + File: Mailscanner_rules (mailscanner_rules.aug) + File: MasterPasswd (masterpasswd.aug) + File: Pgbouncer (pgbouncer.aug) + File: PylonsPaste (pylonspaste.aug) + File: Xymon_Alerting (xymon_alerting.aug) } # Group: Specific Modules Group: Generic Modules { @@ -215,10 +226,9 @@ Group: Tests and Examples { File: Test_Carbon (tests/test_carbon.aug) File: Test_Channels (tests/test_channels.aug) File: Test_Chrony (tests/test_chrony.aug) - File: Test_ClamAV (tests/test_clamav.aug) File: Test_Collectd (tests/test_collectd.aug) File: Test_CPanel (tests/test_cpanel.aug) - File: Test_CSV (tests/test_csv.aug) + File: test_csv.aug (tests/test_csv.aug) File: Test_Cups (tests/test_cups.aug) File: Test_Dovecot (tests/test_dovecot.aug) File: Test_Erlang (tests/test_erlang.aug) @@ -240,8 +250,6 @@ Group: Tests and Examples { File: Test_Ldso (tests/test_ldso.aug) File: Test_Lightdm (tests/test_lightdm.aug) File: Test_LVM (tests/test_lvm.aug) - File: Test_Mailscanner (tests/test_mailscanner.aug) - File: Test_Mailscanner_Rules (tests/test_mailscanner_rules.aug) File: Test_MCollective (tests/test_mcollective.aug) File: Test_Memcached (tests/test_memcached.aug) File: Test_MongoDBServer (tests/test_mongodbserver.aug) @@ -252,21 +260,18 @@ Group: Tests and Examples { File: Test_OpenShift_Config (tests/test_openshift_config.aug) File: Test_OpenShift_Http (tests/test_openshift_http.aug) File: Test_OpenShift_Quickstarts (tests/test_openshift_quickstarts.aug) - File: Test_Pgbouncer (tests/test_pgbouncer.aug) File: Test_Postfix_Transport (tests/test_postfix_transport.aug) File: Test_Postfix_Virtual (tests/test_postfix_virtual.aug) File: Test_Postgresql (tests/test_postgresql.aug) File: Test_Protocols (tests/test_protocols.aug) File: Test_Puppet_Auth (tests/test_puppet_auth.aug) File: Test_Puppetfile (tests/test_puppetfile.aug) - File: Test_Pylonspaste (tests/test_pylonspaste.aug) File: Test_Qpid (tests/test_qpid.aug) File: Test_Quote (tests/test_quote.aug) File: Test_Rabbitmq (tests/test_rabbitmq.aug) File: Test_Redis (tests/test_redis.aug) File: Test_Reprepro_Uploaders (tests/test_reprepro_uploaders.aug) File: Test_Rhsm (tests/test_rhsm.aug) - File: Test_Rmt (tests/test_rmt.aug) File: Test_Rsyslog (tests/test_rsyslog.aug) File: Test_Simplelines (tests/test_simplelines.aug) File: Test_Simplevars (tests/test_simplevars.aug) @@ -277,19 +282,23 @@ Group: Tests and Examples { File: Test_Systemd (tests/test_systemd.aug) File: Test_Thttpd (tests/test_thttpd.aug) File: Test_Tmpfiles (tests/test_tmpfiles.aug) - File: Test_Tuned (tests/test_tuned.aug) File: Test_Up2date (tests/test_up2date.aug) File: Test_UpdateDB (tests/test_updatedb.aug) File: Test_VMware_Config (tests/test_vmware_config.aug) File: Test_Xml (tests/test_xml.aug) - File: Test_Xymon (tests/test_xymon.aug) - File: Test_XymonAlerting (tests/test_xymonalerting.aug) File: Test_Yum (tests/test_yum.aug) File: Test_login_defs (tests/test_login_defs.aug) File: Test_sssd (tests/test_sssd.aug) File: Test_sudoers (no auto-title, tests/test_sudoers.aug) File: Test_ssh (tests/test_ssh.aug) File: Test_sshd (tests/test_sshd.aug) + File: AptPreferences.pin (tests/test_aptpreferences.aug) + File: Desktop.lns (tests/test_desktop.aug) + File: test_httpd.aug (tests/test_httpd.aug) + File: test_shellvars.aug (tests/test_shellvars.aug) + File: test_shellvars_list.aug (tests/test_shellvars_list.aug) + File: test_slapd.aug (tests/test_slapd.aug) + File: Test_Xymon_Alerting (tests/test_xymon_alerting.aug) } # Group: Tests and Examples Group: Index { diff --git a/src/augeas_sym.version b/src/augeas_sym.version index 4e3ad99b6..c286ff7bd 100644 --- a/src/augeas_sym.version +++ b/src/augeas_sym.version @@ -69,5 +69,5 @@ AUGEAS_0.18.0 { AUGEAS_0.20.0 { global: aug_escape_name; - setup_lua; + luaopen_augeas; } AUGEAS_0.18.0; diff --git a/src/auglua.c b/src/auglua.c index 81c1cde4c..93515abcb 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -463,7 +463,7 @@ static int lua_aug_transform(lua_State *L) { return 0; } -struct lua_State *setup_lua(augeas *a) { +struct lua_State *luaopen_augeas(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); diff --git a/src/auglua.h b/src/auglua.h index ed672fc7e..9001c8720 100644 --- a/src/auglua.h +++ b/src/auglua.h @@ -28,7 +28,7 @@ extern "C" { #endif -struct lua_State *setup_lua(augeas *a); +struct lua_State *luaopen_augeas(augeas *a); #ifdef __cplusplus } diff --git a/src/augtool.c b/src/augtool.c index 8e8de7f4d..c55630ab3 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -776,7 +776,7 @@ int main(int argc, char **argv) { } if (use_lua) - LS = setup_lua(aug); + LS = luaopen_augeas(aug); add_transforms(transforms, transformslen); if (print_version) { From ea2daf2866c3e12e86e9c4edb4d4c44310c16cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:16:22 +0200 Subject: [PATCH 16/50] Reset Menu.txt --- doc/naturaldocs/conf/lenses/Menu.txt | 35 +++++++++++----------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/doc/naturaldocs/conf/lenses/Menu.txt b/doc/naturaldocs/conf/lenses/Menu.txt index cc585da5a..41e42b1c1 100644 --- a/doc/naturaldocs/conf/lenses/Menu.txt +++ b/doc/naturaldocs/conf/lenses/Menu.txt @@ -24,11 +24,6 @@ SubTitle: Modules # yyyy - Four digit year. 2006 is "2006" # year - Four digit year. 2006 is "2006" -# These are indexes you deleted, so Natural Docs will not add them again -# unless you remove them from this line. - -Don't Index: Properties - # -------------------------------------------------------------------------- # @@ -139,7 +134,7 @@ Group: Specific Modules { File: OpenShift_Config (openshift_config.aug) File: OpenShift_Http (openshift_http.aug) File: OpenShift_Quickstarts (openshift_quickstarts.aug) - File: Pagekite (pagekite.aug) + File: Pagekite (pagekite.aug) File: Pam (pam.aug) File: PamConf (pamconf.aug) File: Passwd (passwd.aug) @@ -188,15 +183,9 @@ Group: Specific Modules { File: VWware_Config (vmware_config.aug) File: Vfstab (vfstab.aug) File: Xinetd (xinetd.aug) + File: Xymon (xymon.aug) + File: XymonAlerting (xymonalerting.aug) File: Xorg (xorg.aug) - File: ClamAV (clamav.aug) - File: Dns_Zone (dns_zone.aug) - File: Mailscanner (mailscanner.aug) - File: Mailscanner_rules (mailscanner_rules.aug) - File: MasterPasswd (masterpasswd.aug) - File: Pgbouncer (pgbouncer.aug) - File: PylonsPaste (pylonspaste.aug) - File: Xymon_Alerting (xymon_alerting.aug) } # Group: Specific Modules Group: Generic Modules { @@ -226,9 +215,10 @@ Group: Tests and Examples { File: Test_Carbon (tests/test_carbon.aug) File: Test_Channels (tests/test_channels.aug) File: Test_Chrony (tests/test_chrony.aug) + File: Test_ClamAV (tests/test_clamav.aug) File: Test_Collectd (tests/test_collectd.aug) File: Test_CPanel (tests/test_cpanel.aug) - File: test_csv.aug (tests/test_csv.aug) + File: Test_CSV (tests/test_csv.aug) File: Test_Cups (tests/test_cups.aug) File: Test_Dovecot (tests/test_dovecot.aug) File: Test_Erlang (tests/test_erlang.aug) @@ -250,6 +240,8 @@ Group: Tests and Examples { File: Test_Ldso (tests/test_ldso.aug) File: Test_Lightdm (tests/test_lightdm.aug) File: Test_LVM (tests/test_lvm.aug) + File: Test_Mailscanner (tests/test_mailscanner.aug) + File: Test_Mailscanner_Rules (tests/test_mailscanner_rules.aug) File: Test_MCollective (tests/test_mcollective.aug) File: Test_Memcached (tests/test_memcached.aug) File: Test_MongoDBServer (tests/test_mongodbserver.aug) @@ -260,18 +252,21 @@ Group: Tests and Examples { File: Test_OpenShift_Config (tests/test_openshift_config.aug) File: Test_OpenShift_Http (tests/test_openshift_http.aug) File: Test_OpenShift_Quickstarts (tests/test_openshift_quickstarts.aug) + File: Test_Pgbouncer (tests/test_pgbouncer.aug) File: Test_Postfix_Transport (tests/test_postfix_transport.aug) File: Test_Postfix_Virtual (tests/test_postfix_virtual.aug) File: Test_Postgresql (tests/test_postgresql.aug) File: Test_Protocols (tests/test_protocols.aug) File: Test_Puppet_Auth (tests/test_puppet_auth.aug) File: Test_Puppetfile (tests/test_puppetfile.aug) + File: Test_Pylonspaste (tests/test_pylonspaste.aug) File: Test_Qpid (tests/test_qpid.aug) File: Test_Quote (tests/test_quote.aug) File: Test_Rabbitmq (tests/test_rabbitmq.aug) File: Test_Redis (tests/test_redis.aug) File: Test_Reprepro_Uploaders (tests/test_reprepro_uploaders.aug) File: Test_Rhsm (tests/test_rhsm.aug) + File: Test_Rmt (tests/test_rmt.aug) File: Test_Rsyslog (tests/test_rsyslog.aug) File: Test_Simplelines (tests/test_simplelines.aug) File: Test_Simplevars (tests/test_simplevars.aug) @@ -282,23 +277,19 @@ Group: Tests and Examples { File: Test_Systemd (tests/test_systemd.aug) File: Test_Thttpd (tests/test_thttpd.aug) File: Test_Tmpfiles (tests/test_tmpfiles.aug) + File: Test_Tuned (tests/test_tuned.aug) File: Test_Up2date (tests/test_up2date.aug) File: Test_UpdateDB (tests/test_updatedb.aug) File: Test_VMware_Config (tests/test_vmware_config.aug) File: Test_Xml (tests/test_xml.aug) + File: Test_Xymon (tests/test_xymon.aug) + File: Test_XymonAlerting (tests/test_xymonalerting.aug) File: Test_Yum (tests/test_yum.aug) File: Test_login_defs (tests/test_login_defs.aug) File: Test_sssd (tests/test_sssd.aug) File: Test_sudoers (no auto-title, tests/test_sudoers.aug) File: Test_ssh (tests/test_ssh.aug) File: Test_sshd (tests/test_sshd.aug) - File: AptPreferences.pin (tests/test_aptpreferences.aug) - File: Desktop.lns (tests/test_desktop.aug) - File: test_httpd.aug (tests/test_httpd.aug) - File: test_shellvars.aug (tests/test_shellvars.aug) - File: test_shellvars_list.aug (tests/test_shellvars_list.aug) - File: test_slapd.aug (tests/test_slapd.aug) - File: Test_Xymon_Alerting (tests/test_xymon_alerting.aug) } # Group: Tests and Examples Group: Index { From 1ebed134d29125deea06bdd0986d487ffc57bf53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:18:06 +0200 Subject: [PATCH 17/50] Newlines DO work --- src/augtool.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/augtool.c b/src/augtool.c index c55630ab3..d1d536d0e 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -641,7 +641,6 @@ static int main_loop(int argc, char **argv) { } if (use_lua) { - // FIXME: newlines don't work! char *buf; if (cur_line == NULL) { buf = malloc(sizeof(char) * strlen(line)); From 029b60d1113777a6f3beae8efaf8e3d4acd7f844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:25:31 +0200 Subject: [PATCH 18/50] Add aug_lua --- src/augeas_sym.version | 1 + src/auglua.c | 5 +++++ src/auglua.h | 2 ++ src/augtool.c | 3 ++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/augeas_sym.version b/src/augeas_sym.version index c286ff7bd..c4fd71da7 100644 --- a/src/augeas_sym.version +++ b/src/augeas_sym.version @@ -70,4 +70,5 @@ AUGEAS_0.20.0 { global: aug_escape_name; luaopen_augeas; + aug_lua; } AUGEAS_0.18.0; diff --git a/src/auglua.c b/src/auglua.c index 93515abcb..c58de8fde 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -514,6 +514,11 @@ struct lua_State *luaopen_augeas(augeas *a) { return L; } +int aug_lua(lua_State *L, const char *text) { + int code = luaL_loadbuffer(L, text, strlen(text), "line") || lua_pcall(L, 0, 0, 0); + return code; +} + /* * Local variables: diff --git a/src/auglua.h b/src/auglua.h index 9001c8720..8fa19b713 100644 --- a/src/auglua.h +++ b/src/auglua.h @@ -30,6 +30,8 @@ extern "C" { struct lua_State *luaopen_augeas(augeas *a); +int aug_lua(lua_State *L, const char *text); + #ifdef __cplusplus } #endif diff --git a/src/augtool.c b/src/augtool.c index d1d536d0e..d493b961a 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -648,7 +648,8 @@ static int main_loop(int argc, char **argv) { } else { sprintf(buf, "%s\n%s", cur_line, line); } - code = luaL_loadbuffer(LS, buf, strlen(buf), "line") || lua_pcall(LS, 0, 0, 0); + + code = aug_lua(LS, buf); if (isatty(fileno(stdin))) add_history(line); From 9b30c76da7dace2b03e08e8ee58b3df0102f31b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:45:55 +0200 Subject: [PATCH 19/50] Use a better registry key --- src/auglua.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auglua.c b/src/auglua.c index c58de8fde..df8bd0dc9 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -29,7 +29,7 @@ #include -static const char Key = 'k'; +static const char *Key = "augeas_registry_key"; static augeas *checkaug(lua_State *L) { lua_pushlightuserdata(L, (void *)&Key); From 731466ec1b47237df5f238f6dfe46b019f66c8b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:47:04 +0200 Subject: [PATCH 20/50] better var name --- src/auglua.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index df8bd0dc9..e664e0186 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -29,10 +29,10 @@ #include -static const char *Key = "augeas_registry_key"; +static const char *registry_key = "augeas_registry_key"; static augeas *checkaug(lua_State *L) { - lua_pushlightuserdata(L, (void *)&Key); + lua_pushlightuserdata(L, (void *)®istry_key); lua_gettable(L, LUA_REGISTRYINDEX); augeas *aug = (augeas *)lua_touserdata(L, -1); // Convert value return aug; @@ -469,7 +469,7 @@ struct lua_State *luaopen_augeas(augeas *a) { // lightuserdata is shared between libs // do we really want to use that? - lua_pushlightuserdata(L, (void *)&Key); + lua_pushlightuserdata(L, (void *)®istry_key); lua_pushlightuserdata(L, (void *)a); // Push pointer lua_settable(L, LUA_REGISTRYINDEX); From 94a577f0393e5f964447afdc900370ba44fb3466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 16:53:30 +0200 Subject: [PATCH 21/50] Reset etc/passwd in root --- tests/root/etc/passwd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/root/etc/passwd b/tests/root/etc/passwd index 6e662777b..9cefbfe48 100644 --- a/tests/root/etc/passwd +++ b/tests/root/etc/passwd @@ -1,4 +1,4 @@ -root:x:0:0:root:/root:/bin/zsh +root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin From 8c4d38d5de3187f4e62eaf9cc1c8dcb86c7c5c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Thu, 24 Sep 2015 17:07:11 +0200 Subject: [PATCH 22/50] Revert "Reset etc/passwd in root" This reverts commit c23b796b3436dbccb0a7b356de9d2875898295a6. --- tests/root/etc/passwd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/root/etc/passwd b/tests/root/etc/passwd index 9cefbfe48..6e662777b 100644 --- a/tests/root/etc/passwd +++ b/tests/root/etc/passwd @@ -1,4 +1,4 @@ -root:x:0:0:root:/root:/bin/bash +root:x:0:0:root:/root:/bin/zsh bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin From 3c110692de07b2805fcbd6dbe062e66440505acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 2 Dec 2015 10:14:53 +0100 Subject: [PATCH 23/50] AUGEAS_0.21.0 --- src/augeas_sym.version | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/augeas_sym.version b/src/augeas_sym.version index c4fd71da7..671636e32 100644 --- a/src/augeas_sym.version +++ b/src/augeas_sym.version @@ -69,6 +69,10 @@ AUGEAS_0.18.0 { AUGEAS_0.20.0 { global: aug_escape_name; +} AUGEAS_0.18.0; + +AUGEAS_0.21.0 { + global: luaopen_augeas; aug_lua; -} AUGEAS_0.18.0; +} AUGEAS_0.20.0; From 03b95f394facbc6a1596395eda7476e545250420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 2 Dec 2015 10:16:18 +0100 Subject: [PATCH 24/50] Remove unnecessary comments --- src/auglua.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index e664e0186..214bb337c 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -70,7 +70,6 @@ static int lua_aug_get(lua_State *L) { return lua_pusherror(L); lua_pushstring(L, value); - /* return the number of results */ return 1; } @@ -89,7 +88,6 @@ static int lua_aug_label(lua_State *L) { return lua_pusherror(L); lua_pushstring(L, value); - /* return the number of results */ return 1; } @@ -108,7 +106,6 @@ static int lua_aug_set(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -128,7 +125,6 @@ static int lua_aug_setm(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -149,7 +145,6 @@ static int lua_aug_insert(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -167,7 +162,6 @@ static int lua_aug_rm(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -186,7 +180,6 @@ static int lua_aug_mv(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -205,7 +198,6 @@ static int lua_aug_cp(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -224,7 +216,6 @@ static int lua_aug_rename(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -241,7 +232,6 @@ static int lua_aug_clear(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -259,7 +249,6 @@ static int lua_aug_clearm(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -279,7 +268,6 @@ static int lua_aug_touch(lua_State *L) { return lua_pusherror(L); } - /* return the number of results */ return 0; } @@ -298,7 +286,6 @@ static int lua_aug_matches(lua_State *L) { return lua_pusherror(L); lua_pushinteger(L, r); - /* return the number of results */ return 1; } @@ -327,7 +314,6 @@ static int lua_aug_match(lua_State *L) { free(match); lua_pushinteger(L, r); - /* return the number of results */ return 2; } @@ -346,7 +332,6 @@ static int lua_aug_defvar(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -366,7 +351,6 @@ static int lua_aug_defnode(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -386,7 +370,6 @@ static int lua_aug_save(lua_State *L) { printf("Saved %d file(s)\n", r); } - /* return the number of results */ return 0; } @@ -400,7 +383,6 @@ static int lua_aug_load(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -419,7 +401,6 @@ static int lua_aug_text_store(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -439,7 +420,6 @@ static int lua_aug_text_retrieve(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } @@ -459,7 +439,6 @@ static int lua_aug_transform(lua_State *L) { if (r < 0) return lua_pusherror(L); - /* return the number of results */ return 0; } From 382e55f7534a864b2103f209ff1cb99349591a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 2 Dec 2015 10:18:48 +0100 Subject: [PATCH 25/50] Use lua_pushfstring --- src/auglua.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 214bb337c..aadaba52b 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -42,8 +42,7 @@ static void lua_checkargs(lua_State *L, const char *name, int arity) { int n = lua_gettop(L); char msg[1024]; if (n != arity) { - snprintf(msg, sizeof(msg), "Wrong number of arguments for '%s'", name); - lua_pushstring(L, msg); + lua_pushfstring(L, msg, sizeof(msg), "Wrong number of arguments for '%s'", name); lua_error(L); } } From bd23da0e3ed2ebf8c7aeee986c6902a7a77b9009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Pinson?= Date: Wed, 2 Dec 2015 10:36:25 +0100 Subject: [PATCH 26/50] Fix call of run_command() --- src/augtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/augtool.c b/src/augtool.c index d493b961a..4daabaff0 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -667,7 +667,7 @@ static int main_loop(int argc, char **argv) { cur_line = NULL; } } else { - code = run_command(line); + code = run_command(line, timing); if (code == -2) { free(line); return ret; From b40abf41acb1c64672967bc13e845c79c5be0aca Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 15 Nov 2016 13:57:53 +0200 Subject: [PATCH 27/50] configure: scan for Lua versions --- configure.ac | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b3a3a40c7..c8f9700d9 100644 --- a/configure.ac +++ b/configure.ac @@ -110,7 +110,19 @@ gl_INIT PKG_PROG_PKG_CONFIG PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) -PKG_CHECK_MODULES([LIBLUA], [lua5.2]) +m4_foreach_w([LUAPKG], [lua5.1 lua5.2 lua5.3 lua], [ + AC_MSG_CHECKING([for LUAPKG]) + PKG_CHECK_EXISTS(LUAPKG, [ + AC_MSG_RESULT([yes]) + LIBLUA_CFLAGS=$($PKG_CONFIG --cflags LUAPKG) + LIBLUA_LIBS=$($PKG_CONFIG --libs LUAPKG) + ], [AC_MSG_RESULT([no])]) +]) +if test -z "$LIBLUA_LIBS"; then + AC_MSG_ERROR([no Lua libraries found]) +fi +AC_SUBST([LIBLUA_CFLAGS]) +AC_SUBST([LIBLUA_LIBS]) AC_CHECK_FUNCS([strerror_r fsync]) From 219dff88fc567828fd0cef60330c7dfab61e8d1f Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 13:04:42 +0200 Subject: [PATCH 28/50] move Lua extensions to libauglua --- configure.ac | 1 + src/Makefile.am | 15 +++++++++++---- src/augeas_sym.version | 6 ------ src/auglua_sym.version | 6 ++++++ 4 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 src/auglua_sym.version diff --git a/configure.ac b/configure.ac index c8f9700d9..d2665647a 100644 --- a/configure.ac +++ b/configure.ac @@ -65,6 +65,7 @@ if test x"$enable_debug" = x"yes"; then fi dnl Version info in libtool's notation +AC_SUBST([LIBAUGLUA_VERSION_INFO], [0:0:0]) AC_SUBST([LIBAUGEAS_VERSION_INFO], [20:0:20]) AC_SUBST([LIBFA_VERSION_INFO], [5:1:4]) diff --git a/src/Makefile.am b/src/Makefile.am index 90c0afc16..8ee88a079 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,14 +11,14 @@ BUILT_SOURCES = datadir.h DISTCLEANFILES = datadir.h -lib_LTLIBRARIES = libfa.la libaugeas.la +lib_LTLIBRARIES = libfa.la libaugeas.la libauglua.la noinst_LTLIBRARIES = liblexer.la bin_PROGRAMS = augtool augparse include_HEADERS = augeas.h fa.h -libaugeas_la_SOURCES = augeas.h augeas.c augrun.c auglua.h auglua.c pathx.c \ +libaugeas_la_SOURCES = augeas.h augeas.c augrun.c pathx.c \ internal.h internal.c \ memory.h memory.c ref.h ref.c \ syntax.c syntax.h parser.y builtin.c lens.c lens.h regexp.c regexp.h \ @@ -26,19 +26,26 @@ libaugeas_la_SOURCES = augeas.h augeas.c augrun.c auglua.h auglua.c pathx.c \ info.c info.h errcode.c errcode.h jmt.h jmt.c if USE_VERSION_SCRIPT + AUGLUA_VERSION_SCRIPT = $(VERSION_SCRIPT_FLAGS)$(srcdir)/auglua_sym.version AUGEAS_VERSION_SCRIPT = $(VERSION_SCRIPT_FLAGS)$(srcdir)/augeas_sym.version FA_VERSION_SCRIPT = $(VERSION_SCRIPT_FLAGS)$(srcdir)/fa_sym.version else + AUGLUA_VERSION_SCRIPT = AUGEAS_VERSION_SCRIPT = FA_VERSION_SCRIPT = endif libaugeas_la_LDFLAGS = $(AUGEAS_VERSION_SCRIPT) \ -version-info $(LIBAUGEAS_VERSION_INFO) -libaugeas_la_LIBADD = liblexer.la libfa.la $(LIB_SELINUX) $(LIBXML_LIBS) $(LIBLUA_LIBS) $(GNULIB) +libaugeas_la_LIBADD = liblexer.la libfa.la $(LIB_SELINUX) $(LIBXML_LIBS) $(GNULIB) + +libauglua_la_LDFLAGS = $(AUGLUA_VERSION_SCRIPT) \ + -version-info $(LIBAUGLUA_VERSION_INFO) +libauglua_la_SOURCES = augeas.h auglua.c auglua.h internal.h +libauglua_la_LIBADD = libaugeas.la $(LIBLUA_LIBS) augtool_SOURCES = augtool.c -augtool_LDADD = libaugeas.la $(READLINE_LIBS) $(LIBXML_LIBS) $(LIBLUA_LIBS) $(GNULIB) +augtool_LDADD = libaugeas.la libauglua.la $(READLINE_LIBS) $(GNULIB) augparse_SOURCES = augparse.c augparse_LDADD = libaugeas.la $(LIBXML_LIBS) $(LIBLUA_LIBS) $(GNULIB) diff --git a/src/augeas_sym.version b/src/augeas_sym.version index 671636e32..0c4d7c43b 100644 --- a/src/augeas_sym.version +++ b/src/augeas_sym.version @@ -70,9 +70,3 @@ AUGEAS_0.20.0 { global: aug_escape_name; } AUGEAS_0.18.0; - -AUGEAS_0.21.0 { - global: - luaopen_augeas; - aug_lua; -} AUGEAS_0.20.0; diff --git a/src/auglua_sym.version b/src/auglua_sym.version new file mode 100644 index 000000000..23481d43d --- /dev/null +++ b/src/auglua_sym.version @@ -0,0 +1,6 @@ +AUGLUA_0.0.0 { + global: + luaopen_augeas; + aug_lua; + local: *; +}; From acbde1e33aa73594531fb4903249cc4cddb9233d Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Wed, 16 Nov 2016 15:15:43 +0200 Subject: [PATCH 29/50] import laugeas.c from lua-augeas as luamod --- src/luamod.c | 412 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 src/luamod.c diff --git a/src/luamod.c b/src/luamod.c new file mode 100644 index 000000000..11a8736e0 --- /dev/null +++ b/src/luamod.c @@ -0,0 +1,412 @@ +/* +--- Lua wrapper for Augeas library. +-- +-- In general, the functions map straight to the C library. See the +-- descriptions below for details. + */ +#include +#include + +#include +#include +#include + +#include + +#define LIBNAME "augeas" +#define PAUG_META "augeas" + +#ifndef VERSION +#define VERSION "unknown" +#endif + +#define LUA_FILEHANDLE "FILE*" + +#if LUA_VERSION_NUM < 502 +# define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) +# define luaL_setfuncs(L,l,n) (assert(n==0), luaL_register(L,NULL,l)) +#else +static int luaL_typerror (lua_State *L, int narg, const char *tname) +{ + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); +} +#endif + +struct aug_flagmap { + const char *name; + int value; +}; + +struct aug_flagmap Taug_flagmap[] = { + { "none", AUG_NONE }, + { "save_backup", AUG_SAVE_BACKUP }, + { "save_newfile", AUG_SAVE_NEWFILE }, + { "typecheck", AUG_TYPE_CHECK }, + { "no_stdinc", AUG_NO_STDINC }, + { "save_noop", AUG_SAVE_NOOP }, + { "no_load", AUG_NO_LOAD }, + { "no_modl_autoload", AUG_NO_MODL_AUTOLOAD }, + { NULL, 0 } +}; + +static const char *get_opt_string_field(lua_State *L, int index, + const char *key, const char *def) +{ + const char *value; + lua_getfield(L, index, key); + value = luaL_optstring(L, -1, def); + lua_pop(L, 1); + return value; +} + +static int get_boolean_field(lua_State *L, int index, const char *key) +{ + int value; + lua_getfield(L, index, key); + value = lua_toboolean(L, -1); + lua_pop(L, 1); + return value; +} + +static int pusherror(lua_State *L, augeas *aug, const char *info) +{ + lua_pushnil(L); + if (info==NULL) + lua_pushstring(L, aug_error_message(aug)); + else + lua_pushfstring(L, "%s: %s", info, aug_error_message(aug)); + lua_pushinteger(L, aug_error(aug)); + return 3; +} + +static int pushresult(lua_State *L, int i, augeas *aug, const char *info) +{ + if (i < 0) + return pusherror(L, aug, info); + lua_pushinteger(L, i); + return 1; +} + +static augeas *Paug_checkarg(lua_State *L, int index) +{ + augeas **a; + luaL_checktype(L, index, LUA_TUSERDATA); + a = (augeas **) luaL_checkudata(L, index, PAUG_META); + if (a == NULL) + luaL_typerror(L, index, PAUG_META); + return *a; +} + +static int Paug_init(lua_State *L) +{ + augeas **a; + struct aug_flagmap *f; + const char *root = NULL, *loadpath = NULL; + int flags = 0; + + if (lua_istable(L, 1)) { + root = get_opt_string_field(L, 1, "root", NULL); + loadpath = get_opt_string_field(L, 1, "loadpath", NULL); + for (f = Taug_flagmap; f->name != NULL; f++) + if (get_boolean_field(L, 1, f->name)) + flags |= f->value; + } else { + root = luaL_optstring(L, 1, NULL); + loadpath = luaL_optstring(L, 2, NULL); + flags = luaL_optinteger(L, 3, AUG_NONE); + } + + a = (augeas **) lua_newuserdata(L, sizeof(augeas *)); + luaL_getmetatable(L, PAUG_META); + lua_setmetatable(L, -2); + + *a = aug_init(root, loadpath, flags); + if (*a == NULL) + luaL_error(L, "aug_init failed"); + return 1; +} + +static int Paug_defvar(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *name = luaL_checkstring(L, 2); + const char *expr = luaL_checkstring(L, 3); + return pushresult(L, aug_defvar(a, name, expr), a, NULL); +} + +static int Paug_defnode(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *name = luaL_checkstring(L, 2); + const char *expr = luaL_checkstring(L, 3); + const char *value = luaL_checkstring(L, 4); + return pushresult(L, aug_defnode(a, name, expr, value, NULL), a, NULL); +} + +static int Paug_close(lua_State *L) +{ + augeas **a; + luaL_checktype(L, 1, LUA_TUSERDATA); + a = (augeas **) luaL_checkudata(L, 1, PAUG_META); + + if (a && *a) { + aug_close(*a); + *a = NULL; + } + return 0; +} + +static int Paug_get(lua_State *L) +{ + augeas *a; + const char *path; + const char *value = NULL; + int r; + + a = Paug_checkarg(L, 1); + path = luaL_checkstring(L, 2); + r = aug_get(a, path, &value); + if (r < 0) + return pusherror(L, a, path); + lua_pushstring(L, value); + return 1; +} + +static int Paug_set(lua_State *L) +{ + augeas *a; + const char *path, *value; + + a = Paug_checkarg(L, 1); + path = luaL_checkstring(L, 2); + value = lua_isnil(L, 3) ? NULL : luaL_checkstring(L, 3); + return pushresult(L, aug_set(a, path, value), a, path); +} + +static int Paug_setm(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *base = luaL_checkstring(L, 2); + const char *sub= luaL_checkstring(L, 3); + const char *value = lua_isnil(L, 4) ? NULL : luaL_checkstring(L, 4); + return pushresult(L, aug_setm(a, base, sub, value), a, NULL); +} + +static int Paug_insert(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + const char *label = luaL_checkstring(L, 3); + int before = lua_toboolean(L, 4); + return pushresult(L, aug_insert(a, path, label, before), a, path); +} + +static int Paug_rm(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + return pushresult(L, aug_rm(a, path), a, NULL); +} + +static int Paug_mv(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *src = luaL_checkstring(L, 2); + const char *dst = luaL_checkstring(L, 3); + return pushresult(L, aug_mv(a, src, dst), a, NULL); +} + +static int Paug_matches(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + return pushresult(L, aug_match(a, path, NULL), a, path); +} + +static int Paug_match(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + char **match = NULL; + int i, n; + n = aug_match(a, path, &match); + if (n < 0) + return pusherror(L, a, path); + + lua_newtable(L); + for (i = 0; i < n; i++) { + lua_pushnumber(L, i+1); + lua_pushstring(L, match[i]); + lua_settable(L, -3); + free(match[i]); + } + free(match); + lua_pushinteger(L, n); + return 2; +} + +static int Paug_save(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + return pushresult(L, aug_save(a), a, NULL); +} + +static int Paug_load(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + return pushresult(L, aug_load(a), a, NULL); +} + +static int Paug_print(lua_State *L) +{ + augeas *a; + const char *path; + FILE *f = stdout; + a = Paug_checkarg(L, 1); + path = luaL_checkstring(L, 2); + if (lua_isuserdata(L, 3)) + f = *(FILE**) luaL_checkudata(L, 3, LUA_FILEHANDLE); + return pushresult(L, aug_print(a, f, path), a, path); +} + +static int Paug_error(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + lua_pushinteger(L, aug_error(a)); + return 1; +} + +static int Paug_error_message(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + lua_pushstring(L, aug_error_message(a)); + return 1; +} + +static int Paug_error_minor_message(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + lua_pushstring(L, aug_error_minor_message(a)); + return 1; +} + +static int Paug_error_details(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + lua_pushstring(L, aug_error_details(a)); + return 1; +} + +static const luaL_Reg Paug_methods[] = { +/* +--- Initializes the library. +-- +-- * `params` Table of initialization parameters; all optional. `root` path to +-- Augeas, `loadpath` to Augeas lenses, and string/boolean pairs for the +-- flags in the Taug_flagmap array. +-- * `[return]` augeas object, used as first parameter in subsequent function +-- calls +function init(params) + */ + {"init", Paug_init}, + {"defvar", Paug_defvar}, + {"defnode", Paug_defnode}, +/* +--- Closes the library. Optional; automatically called by garbage collector. +-- +-- * `augobj` Augeas object from init() +function close(augobj) + */ + {"close", Paug_close}, +/* +--- Gets the value for an Augeas path. +-- +-- * `augobj` Augeas object from init() +-- * `path` Augeas path +-- * `[return]` Value for path +function get(augobj, path) + */ + {"get", Paug_get}, +/* +--- Sets the value for an Augeas path. +-- +-- * `augobj` Augeas object from init() +-- * `path` Augeas path +-- * `value` Value for path +function set(augobj, path, value) + */ + {"set", Paug_set}, + {"setm", Paug_setm}, + {"insert", Paug_insert}, + {"rm", Paug_rm}, + {"mv", Paug_mv}, + {"matches", Paug_matches}, +/* +--- Collects paths in the Augeas tree. +-- +-- * `augobj` Augeas object from init() +-- * `path` Source path to be matched +-- * `[return]` Array of matching paths +function match(augobj, path) + */ + {"match", Paug_match}, + {"save", Paug_save}, +/* +--- Loads the values for the Augeas tree. +-- +-- * `augobj` Augeas object from init() +function load(augobj) + */ + {"load", Paug_load}, +/* +--- Prints the value(s) for an Augeas path. +-- +-- * `augobj` Augeas object from init() +-- * `path` Augeas path +-- * `file_handle` *optional* open file for output; otherwise uses stdout +function print(augobj, path, file_handle) + */ + {"print", Paug_print}, + {"error", Paug_error}, + {"error_message", Paug_error_message}, + {"error_minor_message", Paug_error_minor_message}, + {"error_details", Paug_error_details}, + {NULL, NULL} +}; + +static const luaL_Reg Laug_meta_methods[] = { + {"__gc", Paug_close}, + {NULL, NULL} +}; + + +LUALIB_API int luaopen_augeas(lua_State *L) +{ + struct aug_flagmap *f = Taug_flagmap; + luaL_newlib(L, Paug_methods); + lua_pushliteral(L, "version"); + lua_pushliteral(L, VERSION); + lua_settable(L, -3); + + while (f->name != NULL) { + lua_pushstring(L, f->name); + lua_pushinteger(L, f->value); + lua_settable(L, -3); + f++; + } + + luaL_newmetatable(L, PAUG_META); + luaL_setfuncs(L, Laug_meta_methods, 0); + lua_pushliteral(L, "__index"); + lua_pushvalue(L, -3); + lua_rawset(L, -3); + lua_pushliteral(L, "__metatable"); + lua_pushvalue(L, -3); + lua_rawset(L, -3); + lua_pop(L, 1); + + return 1; +} + From c2e3a3b01650d838e0ad5f9df08f4766a9d82cc2 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Wed, 16 Nov 2016 15:18:16 +0200 Subject: [PATCH 30/50] luamod: add copyright notice --- src/luamod.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/luamod.c b/src/luamod.c index 11a8736e0..344562eb6 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -4,6 +4,12 @@ -- In general, the functions map straight to the C library. See the -- descriptions below for details. */ + +/* + * Copyright (C) 2010-2013 Natanael Copa + * Copyright (C) 2013 Kaarle Ritvanen + */ + #include #include From 8ce7857eb88bb3aaf6b13421d02d936e4711f687 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 10:08:00 +0200 Subject: [PATCH 31/50] compile luamod --- configure.ac | 2 ++ src/Makefile.am | 7 +++++++ src/luamod.c | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index d2665647a..326929383 100644 --- a/configure.ac +++ b/configure.ac @@ -117,6 +117,7 @@ m4_foreach_w([LUAPKG], [lua5.1 lua5.2 lua5.3 lua], [ AC_MSG_RESULT([yes]) LIBLUA_CFLAGS=$($PKG_CONFIG --cflags LUAPKG) LIBLUA_LIBS=$($PKG_CONFIG --libs LUAPKG) + LUA_VERSION=$($PKG_CONFIG --variable=V LUAPKG) ], [AC_MSG_RESULT([no])]) ]) if test -z "$LIBLUA_LIBS"; then @@ -124,6 +125,7 @@ if test -z "$LIBLUA_LIBS"; then fi AC_SUBST([LIBLUA_CFLAGS]) AC_SUBST([LIBLUA_LIBS]) +AC_SUBST([LUA_VERSION]) AC_CHECK_FUNCS([strerror_r fsync]) diff --git a/src/Makefile.am b/src/Makefile.am index 8ee88a079..b17e984d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,6 +14,9 @@ DISTCLEANFILES = datadir.h lib_LTLIBRARIES = libfa.la libaugeas.la libauglua.la noinst_LTLIBRARIES = liblexer.la +luadir = $(libdir)/lua/$(LUA_VERSION) +lua_LTLIBRARIES = augeas.la + bin_PROGRAMS = augtool augparse include_HEADERS = augeas.h fa.h @@ -57,6 +60,10 @@ libfa_la_LDFLAGS = $(FA_VERSION_SCRIPT) -version-info $(LIBFA_VERSION_INFO) liblexer_la_SOURCES = lexer.l liblexer_la_CFLAGS = $(AM_CFLAGS) -Wno-error +augeas_la_SOURCES = augeas.h luamod.c +augeas_la_LIBADD = libaugeas.la +augeas_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -module -shared + FAILMALLOC_START ?= 1 FAILMALLOC_REP ?= 20 FAILMALLOC_PROG ?= ./augtool diff --git a/src/luamod.c b/src/luamod.c index 344562eb6..c767ee702 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -7,7 +7,7 @@ /* * Copyright (C) 2010-2013 Natanael Copa - * Copyright (C) 2013 Kaarle Ritvanen + * Copyright (C) 2013-2016 Kaarle Ritvanen */ #include @@ -17,7 +17,7 @@ #include #include -#include +#include "augeas.h" #define LIBNAME "augeas" #define PAUG_META "augeas" From 4afe954051842ac457345c295ac42cef711bae0a Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 12:06:05 +0200 Subject: [PATCH 32/50] rename luaopen_augeas back to setup_lua --- src/auglua.c | 3 ++- src/auglua.h | 2 +- src/auglua_sym.version | 2 +- src/augtool.c | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index aadaba52b..f5d41a5c2 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -2,6 +2,7 @@ * auglua.c: lua integration for augtool * * Copyright (C) 2015 Raphaël Pinson + * Copyright (C) 2016 Kaarle Ritvanen * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -441,7 +442,7 @@ static int lua_aug_transform(lua_State *L) { return 0; } -struct lua_State *luaopen_augeas(augeas *a) { +struct lua_State *setup_lua(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); diff --git a/src/auglua.h b/src/auglua.h index 8fa19b713..0d0261069 100644 --- a/src/auglua.h +++ b/src/auglua.h @@ -28,7 +28,7 @@ extern "C" { #endif -struct lua_State *luaopen_augeas(augeas *a); +struct lua_State *setup_lua(augeas *a); int aug_lua(lua_State *L, const char *text); diff --git a/src/auglua_sym.version b/src/auglua_sym.version index 23481d43d..df97f89f5 100644 --- a/src/auglua_sym.version +++ b/src/auglua_sym.version @@ -1,6 +1,6 @@ AUGLUA_0.0.0 { global: - luaopen_augeas; + setup_lua; aug_lua; local: *; }; diff --git a/src/augtool.c b/src/augtool.c index 4daabaff0..b33dd0f29 100644 --- a/src/augtool.c +++ b/src/augtool.c @@ -776,7 +776,7 @@ int main(int argc, char **argv) { } if (use_lua) - LS = luaopen_augeas(aug); + LS = setup_lua(aug); add_transforms(transforms, transformslen); if (print_version) { From 6c17a37a28c08b95fb4362460c3ad4a915d22beb Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 13:27:05 +0200 Subject: [PATCH 33/50] luamod: define public interface --- src/Makefile.am | 2 +- src/luamod.c | 1 + src/luamod.h | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 src/luamod.h diff --git a/src/Makefile.am b/src/Makefile.am index b17e984d0..b7665b27e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,7 +60,7 @@ libfa_la_LDFLAGS = $(FA_VERSION_SCRIPT) -version-info $(LIBFA_VERSION_INFO) liblexer_la_SOURCES = lexer.l liblexer_la_CFLAGS = $(AM_CFLAGS) -Wno-error -augeas_la_SOURCES = augeas.h luamod.c +augeas_la_SOURCES = augeas.h luamod.c luamod.h augeas_la_LIBADD = libaugeas.la augeas_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -module -shared diff --git a/src/luamod.c b/src/luamod.c index c767ee702..bdcd4b3da 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -18,6 +18,7 @@ #include #include "augeas.h" +#include "luamod.h" #define LIBNAME "augeas" #define PAUG_META "augeas" diff --git a/src/luamod.h b/src/luamod.h new file mode 100644 index 000000000..3a4e869bc --- /dev/null +++ b/src/luamod.h @@ -0,0 +1,6 @@ +/* Copyright (C) 2016 Kaarle Ritvanen */ + +#include +#include + +LUALIB_API int luaopen_augeas(lua_State *L); From 433ee8635291dbb10b3279f66b982995e4e2f4c9 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 22:14:29 +0200 Subject: [PATCH 34/50] luamod: userdata structure --- src/luamod.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/luamod.c b/src/luamod.c index bdcd4b3da..9248b5ba2 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -41,6 +41,10 @@ static int luaL_typerror (lua_State *L, int narg, const char *tname) } #endif +struct aug_userdata { + augeas *aug; +}; + struct aug_flagmap { const char *name; int value; @@ -98,17 +102,17 @@ static int pushresult(lua_State *L, int i, augeas *aug, const char *info) static augeas *Paug_checkarg(lua_State *L, int index) { - augeas **a; + struct aug_userdata *ud; luaL_checktype(L, index, LUA_TUSERDATA); - a = (augeas **) luaL_checkudata(L, index, PAUG_META); - if (a == NULL) + ud = (struct aug_userdata *) luaL_checkudata(L, index, PAUG_META); + if (ud == NULL) luaL_typerror(L, index, PAUG_META); - return *a; + return ud->aug; } static int Paug_init(lua_State *L) { - augeas **a; + struct aug_userdata *ud; struct aug_flagmap *f; const char *root = NULL, *loadpath = NULL; int flags = 0; @@ -125,12 +129,12 @@ static int Paug_init(lua_State *L) flags = luaL_optinteger(L, 3, AUG_NONE); } - a = (augeas **) lua_newuserdata(L, sizeof(augeas *)); + ud = (struct aug_userdata *) lua_newuserdata(L, sizeof(struct aug_userdata)); luaL_getmetatable(L, PAUG_META); lua_setmetatable(L, -2); - *a = aug_init(root, loadpath, flags); - if (*a == NULL) + ud->aug = aug_init(root, loadpath, flags); + if (ud->aug == NULL) luaL_error(L, "aug_init failed"); return 1; } @@ -154,13 +158,13 @@ static int Paug_defnode(lua_State *L) static int Paug_close(lua_State *L) { - augeas **a; + struct aug_userdata *ud; luaL_checktype(L, 1, LUA_TUSERDATA); - a = (augeas **) luaL_checkudata(L, 1, PAUG_META); + ud = (struct aug_userdata *) luaL_checkudata(L, 1, PAUG_META); - if (a && *a) { - aug_close(*a); - *a = NULL; + if (ud && ud->aug) { + aug_close(ud->aug); + ud->aug = NULL; } return 0; } From f69a357577a7c855e66024cba5e883f4e639d43f Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 14:31:53 +0200 Subject: [PATCH 35/50] auglua: use lua_pushliteral with registry key --- src/auglua.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index f5d41a5c2..b101bc03a 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -30,10 +30,10 @@ #include -static const char *registry_key = "augeas_registry_key"; +#define REG_KEY_INSTANCE "augeas-instance" static augeas *checkaug(lua_State *L) { - lua_pushlightuserdata(L, (void *)®istry_key); + lua_pushliteral(L, REG_KEY_INSTANCE); lua_gettable(L, LUA_REGISTRYINDEX); augeas *aug = (augeas *)lua_touserdata(L, -1); // Convert value return aug; @@ -448,7 +448,7 @@ struct lua_State *setup_lua(augeas *a) { // lightuserdata is shared between libs // do we really want to use that? - lua_pushlightuserdata(L, (void *)®istry_key); + lua_pushliteral(L, REG_KEY_INSTANCE); lua_pushlightuserdata(L, (void *)a); // Push pointer lua_settable(L, LUA_REGISTRYINDEX); From 5886de442c681e54395d3cfa59c7754b418d97e9 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 11:39:26 +0200 Subject: [PATCH 36/50] auglua: use luamod to push instance to stack --- src/Makefile.am | 2 +- src/auglua.c | 9 ++++----- src/luamod.c | 25 +++++++++++++++++-------- src/luamod.h | 3 +++ 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index b7665b27e..61efc6e65 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -44,7 +44,7 @@ libaugeas_la_LIBADD = liblexer.la libfa.la $(LIB_SELINUX) $(LIBXML_LIBS) $(GNULI libauglua_la_LDFLAGS = $(AUGLUA_VERSION_SCRIPT) \ -version-info $(LIBAUGLUA_VERSION_INFO) -libauglua_la_SOURCES = augeas.h auglua.c auglua.h internal.h +libauglua_la_SOURCES = augeas.h auglua.c auglua.h internal.h luamod.c luamod.h libauglua_la_LIBADD = libaugeas.la $(LIBLUA_LIBS) augtool_SOURCES = augtool.c diff --git a/src/auglua.c b/src/auglua.c index b101bc03a..da0844170 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -23,6 +23,7 @@ #include "internal.h" #include "augeas.h" +#include "luamod.h" #include "auglua.h" #include #include @@ -35,8 +36,8 @@ static augeas *checkaug(lua_State *L) { lua_pushliteral(L, REG_KEY_INSTANCE); lua_gettable(L, LUA_REGISTRYINDEX); - augeas *aug = (augeas *)lua_touserdata(L, -1); // Convert value - return aug; + augeas **aug = (augeas **)lua_touserdata(L, -1); // Convert value + return *aug; } static void lua_checkargs(lua_State *L, const char *name, int arity) { @@ -446,10 +447,8 @@ struct lua_State *setup_lua(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); - // lightuserdata is shared between libs - // do we really want to use that? lua_pushliteral(L, REG_KEY_INSTANCE); - lua_pushlightuserdata(L, (void *)a); // Push pointer + luamod_push_augeas(L, a); lua_settable(L, LUA_REGISTRYINDEX); static const luaL_Reg augfuncs[] = { diff --git a/src/luamod.c b/src/luamod.c index 9248b5ba2..b8e94df15 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -43,6 +43,7 @@ static int luaL_typerror (lua_State *L, int narg, const char *tname) struct aug_userdata { augeas *aug; + int gc; }; struct aug_flagmap { @@ -110,9 +111,17 @@ static augeas *Paug_checkarg(lua_State *L, int index) return ud->aug; } +void luamod_push_augeas(lua_State *L, augeas *a) { + struct aug_userdata *ud = (struct aug_userdata *) lua_newuserdata(L, sizeof(struct aug_userdata)); + luaL_getmetatable(L, PAUG_META); + lua_setmetatable(L, -2); + ud->aug = a; + ud->gc = 0; +} + static int Paug_init(lua_State *L) { - struct aug_userdata *ud; + augeas *a; struct aug_flagmap *f; const char *root = NULL, *loadpath = NULL; int flags = 0; @@ -129,13 +138,13 @@ static int Paug_init(lua_State *L) flags = luaL_optinteger(L, 3, AUG_NONE); } - ud = (struct aug_userdata *) lua_newuserdata(L, sizeof(struct aug_userdata)); - luaL_getmetatable(L, PAUG_META); - lua_setmetatable(L, -2); - - ud->aug = aug_init(root, loadpath, flags); - if (ud->aug == NULL) + a = aug_init(root, loadpath, flags); + if (a == NULL) luaL_error(L, "aug_init failed"); + + luamod_push_augeas(L, a); + ((struct aug_userdata *) lua_touserdata(L, -1))->gc = 1; + return 1; } @@ -162,7 +171,7 @@ static int Paug_close(lua_State *L) luaL_checktype(L, 1, LUA_TUSERDATA); ud = (struct aug_userdata *) luaL_checkudata(L, 1, PAUG_META); - if (ud && ud->aug) { + if (ud && ud->gc && ud->aug) { aug_close(ud->aug); ud->aug = NULL; } diff --git a/src/luamod.h b/src/luamod.h index 3a4e869bc..1f2b6a8e0 100644 --- a/src/luamod.h +++ b/src/luamod.h @@ -3,4 +3,7 @@ #include #include +#include "augeas.h" + LUALIB_API int luaopen_augeas(lua_State *L); +void luamod_push_augeas(lua_State *L, augeas *a); From 682cd107b5af19efcd5d5a0f4afd55ea19a8b610 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 18 Nov 2016 19:59:34 +0200 Subject: [PATCH 37/50] auglua: use luamod for missing functions --- src/auglua.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/auglua.c b/src/auglua.c index da0844170..aaaf408aa 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -31,8 +31,14 @@ #include +#define REG_KEY_MODULE "augeas-module" #define REG_KEY_INSTANCE "augeas-instance" +static void push_reg_value(lua_State *L, const char *key) { + lua_pushstring(L, key); + lua_gettable(L, LUA_REGISTRYINDEX); +} + static augeas *checkaug(lua_State *L) { lua_pushliteral(L, REG_KEY_INSTANCE); lua_gettable(L, LUA_REGISTRYINDEX); @@ -443,10 +449,39 @@ static int lua_aug_transform(lua_State *L) { return 0; } +static int call_function(lua_State *L) { + lua_pushvalue(L, lua_upvalueindex(1)); + lua_insert(L, 1); + + push_reg_value(L, REG_KEY_INSTANCE); + lua_insert(L, 2); + + lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + + if (lua_isnil(L, 1) && lua_isstring(L, 2)) { + lua_pushvalue(L, 2); + lua_error(L); + } + return lua_gettop(L); +} + +static int bind_function(lua_State *L) { + push_reg_value(L, REG_KEY_MODULE); + lua_insert(L, 2); + lua_gettable(L, 2); + + lua_pushcclosure(L, call_function, 1); + return 1; +} + struct lua_State *setup_lua(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); + lua_pushliteral(L, REG_KEY_MODULE); + luaopen_augeas(L); + lua_settable(L, LUA_REGISTRYINDEX); + lua_pushliteral(L, REG_KEY_INSTANCE); luamod_push_augeas(L, a); lua_settable(L, LUA_REGISTRYINDEX); @@ -487,6 +522,11 @@ struct lua_State *setup_lua(augeas *a) { }; luaL_newlib(L, augfuncs); + + static const luaL_Reg meta[] = {{"__index", bind_function}, {NULL, NULL}}; + luaL_newlib(L, meta); + lua_setmetatable(L, -2); + lua_setglobal(L, "aug"); return L; From fc0c81251f095cb1448d73c122deeb5eaa91f3c6 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:00:53 +0200 Subject: [PATCH 38/50] auglua: remove redundant functions --- src/auglua.c | 220 --------------------------------------------------- src/luamod.c | 2 + 2 files changed, 2 insertions(+), 220 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index aaaf408aa..6ea7f56a7 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,24 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_get(lua_State *L) { - int r; - const char *path, *value; - - /* get number of arguments */ - lua_checkargs(L, "aug_get", 1); - - path = luaL_checkstring(L, 1); - - augeas *aug = checkaug(L); - r = aug_get(aug, path, &value); - if (r < 0) - return lua_pusherror(L); - lua_pushstring(L, value); - - return 1; -} - static int lua_aug_label(lua_State *L) { int r; const char *path, *value; @@ -98,98 +80,6 @@ static int lua_aug_label(lua_State *L) { return 1; } -static int lua_aug_set(lua_State *L) { - int r; - const char *path, *value; - - lua_checkargs(L, "aug_set", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - value = luaL_checkstring(L, 2); - - augeas *aug = checkaug(L); - r = aug_set(aug, path, value); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - -static int lua_aug_setm(lua_State *L) { - int r; - const char *base, *sub, *value; - - lua_checkargs(L, "aug_setm", 3); - - base = luaL_checkstring(L, 1); - // TODO: check string really - sub = luaL_checkstring(L, 2); - value = luaL_checkstring(L, 3); - - augeas *aug = checkaug(L); - r = aug_setm(aug, base, sub, value); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - -static int lua_aug_insert(lua_State *L) { - int r; - const char *path, *label; - int before; - - lua_checkargs(L, "aug_insert", 3); - - path = luaL_checkstring(L, 1); - // TODO: check string really - label = luaL_checkstring(L, 2); - before = lua_toboolean(L, 3); - - augeas *aug = checkaug(L); - r = aug_insert(aug, path, label, before); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - -static int lua_aug_rm(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_rm", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - augeas *aug = checkaug(L); - r = aug_rm(aug, path); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - -static int lua_aug_mv(lua_State *L) { - int r; - const char *path, *new_path; - - lua_checkargs(L, "aug_mv", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - new_path = luaL_checkstring(L, 2); - - augeas *aug = checkaug(L); - r = aug_mv(aug, path, new_path); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_cp(lua_State *L) { int r; const char *path, *new_path; @@ -278,89 +168,6 @@ static int lua_aug_touch(lua_State *L) { return 0; } -static int lua_aug_matches(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_matches", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - augeas *aug = checkaug(L); - r = aug_match(aug, path, NULL); - if (r < 0) - return lua_pusherror(L); - - lua_pushinteger(L, r); - return 1; -} - -static int lua_aug_match(lua_State *L) { - int r, i; - const char *path; - char **match = NULL; - - lua_checkargs(L, "aug_match", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - augeas *aug = checkaug(L); - r = aug_match(aug, path, &match); - if (r < 0) - return lua_pusherror(L); - - lua_newtable(L); - for (i = 0; i < r; i++) { - lua_pushnumber(L, i+1); - lua_pushstring(L, match[i]); - lua_settable(L, -3); - free(match[i]); - } - free(match); - lua_pushinteger(L, r); - - return 2; -} - -static int lua_aug_defvar(lua_State *L) { - int r; - const char *name, *expr; - - lua_checkargs(L, "aug_defvar", 2); - - name = luaL_checkstring(L, 1); - // TODO: check string really - expr = luaL_checkstring(L, 2); - - augeas *aug = checkaug(L); - r = aug_defvar(aug, name, expr); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - -static int lua_aug_defnode(lua_State *L) { - int r; - const char *name, *expr, *value = NULL; - - lua_checkargs(L, "aug_defnode", 3); - - name = luaL_checkstring(L, 1); - // TODO: check string really - expr = luaL_checkstring(L, 2); - value = lua_tostring(L, 3); - - augeas *aug = checkaug(L); - r = aug_defnode(aug, name, expr, value, NULL); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_save(lua_State *L) { int r; @@ -380,19 +187,6 @@ static int lua_aug_save(lua_State *L) { return 0; } -static int lua_aug_load(lua_State *L) { - int r; - - lua_checkargs(L, "aug_load", 0); - - augeas *aug = checkaug(L); - r = aug_load(aug); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_text_store(lua_State *L) { int r; const char *lens, *node, *path; @@ -487,35 +281,21 @@ struct lua_State *setup_lua(augeas *a) { lua_settable(L, LUA_REGISTRYINDEX); static const luaL_Reg augfuncs[] = { - { "get", lua_aug_get }, { "label", lua_aug_label }, - { "set", lua_aug_set }, - { "setm", lua_aug_setm }, //{ "span", lua_aug_span }, - { "insert", lua_aug_insert }, - { "ins", lua_aug_insert }, // alias - { "rm", lua_aug_rm }, - { "mv", lua_aug_mv }, - { "move", lua_aug_mv }, // alias { "cp", lua_aug_cp }, { "copy", lua_aug_cp }, // alias { "rename", lua_aug_rename }, { "clear", lua_aug_clear }, { "clearm", lua_aug_clearm }, { "touch", lua_aug_touch }, - { "matches", lua_aug_matches }, - { "match", lua_aug_match }, - { "defvar", lua_aug_defvar }, - { "defnode", lua_aug_defnode }, { "save", lua_aug_save }, - { "load", lua_aug_load }, { "text_store", lua_aug_text_store }, { "store", lua_aug_text_store }, // alias { "text_retrieve", lua_aug_text_retrieve }, { "retrieve", lua_aug_text_retrieve }, // alias //{ "escape_name", lua_aug_escape_name }, { "transform", lua_aug_transform }, - //{ "print", lua_aug_print }, //{ "to_xml", lua_aug_to_xml }, //{ "errors", lua_aug_errors }, { NULL, NULL } diff --git a/src/luamod.c b/src/luamod.c index b8e94df15..e5945ed8a 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -360,8 +360,10 @@ function set(augobj, path, value) {"set", Paug_set}, {"setm", Paug_setm}, {"insert", Paug_insert}, + {"ins", Paug_insert}, {"rm", Paug_rm}, {"mv", Paug_mv}, + {"move", Paug_mv}, {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. From 02624efd145af372bc7b9a031e6ef702e4f37d1c Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:12:54 +0200 Subject: [PATCH 39/50] auglua: move label to luamod --- src/auglua.c | 19 ------------------- src/luamod.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 6ea7f56a7..7cb945159 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,24 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_label(lua_State *L) { - int r; - const char *path, *value; - - lua_checkargs(L, "aug_label", 1); - - path = luaL_checkstring(L, 1); - // TODO: check string really - - augeas *aug = checkaug(L); - r = aug_label(aug, path, &value); - if (r < 0) - return lua_pusherror(L); - lua_pushstring(L, value); - - return 1; -} - static int lua_aug_cp(lua_State *L) { int r; const char *path, *new_path; @@ -281,7 +263,6 @@ struct lua_State *setup_lua(augeas *a) { lua_settable(L, LUA_REGISTRYINDEX); static const luaL_Reg augfuncs[] = { - { "label", lua_aug_label }, //{ "span", lua_aug_span }, { "cp", lua_aug_cp }, { "copy", lua_aug_cp }, // alias diff --git a/src/luamod.c b/src/luamod.c index e5945ed8a..bcb59ef86 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -8,6 +8,7 @@ /* * Copyright (C) 2010-2013 Natanael Copa * Copyright (C) 2013-2016 Kaarle Ritvanen + * Copyright (C) 2015 Raphaël Pinson */ #include @@ -194,6 +195,18 @@ static int Paug_get(lua_State *L) return 1; } +static int Paug_label(lua_State *L) +{ + const char *value; + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + int r = aug_label(a, path, &value); + if (r < 0) + return pusherror(L, a, path); + lua_pushstring(L, value); + return 1; +} + static int Paug_set(lua_State *L) { augeas *a; @@ -357,6 +370,7 @@ function get(augobj, path) -- * `value` Value for path function set(augobj, path, value) */ + {"label", Paug_label}, {"set", Paug_set}, {"setm", Paug_setm}, {"insert", Paug_insert}, From 2b3d9e95c540c51d4c81ba3aae4cf46980df45f4 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:15:04 +0200 Subject: [PATCH 40/50] auglua: move cp to luamod --- src/auglua.c | 20 -------------------- src/luamod.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 7cb945159..fdc9f974c 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,24 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_cp(lua_State *L) { - int r; - const char *path, *new_path; - - lua_checkargs(L, "aug_cp", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - new_path = luaL_checkstring(L, 2); - - augeas *aug = checkaug(L); - r = aug_cp(aug, path, new_path); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_rename(lua_State *L) { int r; const char *path, *label; @@ -264,8 +246,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, - { "cp", lua_aug_cp }, - { "copy", lua_aug_cp }, // alias { "rename", lua_aug_rename }, { "clear", lua_aug_clear }, { "clearm", lua_aug_clearm }, diff --git a/src/luamod.c b/src/luamod.c index bcb59ef86..067f61328 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -251,6 +251,14 @@ static int Paug_mv(lua_State *L) return pushresult(L, aug_mv(a, src, dst), a, NULL); } +static int Paug_cp(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *src = luaL_checkstring(L, 2); + const char *dst = luaL_checkstring(L, 3); + return pushresult(L, aug_cp(a, src, dst), a, NULL); +} + static int Paug_matches(lua_State *L) { augeas *a = Paug_checkarg(L, 1); @@ -378,6 +386,8 @@ function set(augobj, path, value) {"rm", Paug_rm}, {"mv", Paug_mv}, {"move", Paug_mv}, + {"cp", Paug_cp}, + {"copy", Paug_cp}, {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. From 60f28b2ea7d8a389c571def3e258b2a079044d65 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:17:52 +0200 Subject: [PATCH 41/50] auglua: move rename to luamod --- src/auglua.c | 19 ------------------- src/luamod.c | 9 +++++++++ 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index fdc9f974c..f33ba777e 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,24 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_rename(lua_State *L) { - int r; - const char *path, *label; - - lua_checkargs(L, "aug_rename", 2); - - path = luaL_checkstring(L, 1); - // TODO: check string really - label = luaL_checkstring(L, 2); - - augeas *aug = checkaug(L); - r = aug_rename(aug, path, label); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_clear(lua_State *L) { int r; const char *path; @@ -246,7 +228,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, - { "rename", lua_aug_rename }, { "clear", lua_aug_clear }, { "clearm", lua_aug_clearm }, { "touch", lua_aug_touch }, diff --git a/src/luamod.c b/src/luamod.c index 067f61328..fd4600e68 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -259,6 +259,14 @@ static int Paug_cp(lua_State *L) return pushresult(L, aug_cp(a, src, dst), a, NULL); } +static int Paug_rename(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + const char *label = luaL_checkstring(L, 3); + return pushresult(L, aug_rename(a, path, label), a, path); +} + static int Paug_matches(lua_State *L) { augeas *a = Paug_checkarg(L, 1); @@ -388,6 +396,7 @@ function set(augobj, path, value) {"move", Paug_mv}, {"cp", Paug_cp}, {"copy", Paug_cp}, + {"rename", Paug_rename}, {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. From f6350cbaa3c471a25197315d596f6985924e9b6b Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:26:15 +0200 Subject: [PATCH 42/50] auglua: move clear to luamod --- src/auglua.c | 17 ----------------- src/luamod.c | 8 ++++++++ 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index f33ba777e..f61f569b9 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,22 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_clear(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_clear", 1); - - path = luaL_checkstring(L, 1); - - augeas *aug = checkaug(L); - r = aug_set(aug, path, NULL); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_clearm(lua_State *L) { int r; const char *base, *sub; @@ -228,7 +212,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, - { "clear", lua_aug_clear }, { "clearm", lua_aug_clearm }, { "touch", lua_aug_touch }, { "save", lua_aug_save }, diff --git a/src/luamod.c b/src/luamod.c index fd4600e68..4634f2301 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -267,6 +267,13 @@ static int Paug_rename(lua_State *L) return pushresult(L, aug_rename(a, path, label), a, path); } +static int Paug_clear(lua_State *L) +{ + lua_settop(L, 2); + lua_pushnil(L); + return Paug_set(L); +} + static int Paug_matches(lua_State *L) { augeas *a = Paug_checkarg(L, 1); @@ -397,6 +404,7 @@ function set(augobj, path, value) {"cp", Paug_cp}, {"copy", Paug_cp}, {"rename", Paug_rename}, + {"clear", Paug_clear}, {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. From 7d291e17be5f6f3161c270f0d6aac1a5afe41272 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:27:01 +0200 Subject: [PATCH 43/50] auglua: move clearm to luamod --- src/auglua.c | 18 ------------------ src/luamod.c | 8 ++++++++ 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index f61f569b9..412281fdd 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,23 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_clearm(lua_State *L) { - int r; - const char *base, *sub; - - lua_checkargs(L, "aug_clearm", 2); - - base = luaL_checkstring(L, 1); - sub = luaL_checkstring(L, 2); - - augeas *aug = checkaug(L); - r = aug_setm(aug, base, sub, NULL); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_touch(lua_State *L) { int r; const char *path; @@ -212,7 +195,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, - { "clearm", lua_aug_clearm }, { "touch", lua_aug_touch }, { "save", lua_aug_save }, { "text_store", lua_aug_text_store }, diff --git a/src/luamod.c b/src/luamod.c index 4634f2301..2caf570ea 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -274,6 +274,13 @@ static int Paug_clear(lua_State *L) return Paug_set(L); } +static int Paug_clearm(lua_State *L) +{ + lua_settop(L, 3); + lua_pushnil(L); + return Paug_setm(L); +} + static int Paug_matches(lua_State *L) { augeas *a = Paug_checkarg(L, 1); @@ -405,6 +412,7 @@ function set(augobj, path, value) {"copy", Paug_cp}, {"rename", Paug_rename}, {"clear", Paug_clear}, + {"clearm", Paug_clearm}, {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. From 3de1ad55c534dc164484dbdb4717c9d64d1aeb55 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Tue, 22 Nov 2016 23:32:55 +0200 Subject: [PATCH 44/50] auglua: move touch to luamod --- src/auglua.c | 20 -------------------- src/luamod.c | 8 ++++++++ 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 412281fdd..3abc88a07 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -62,25 +62,6 @@ static int lua_pusherror(lua_State *L) { return 1; } -static int lua_aug_touch(lua_State *L) { - int r; - const char *path; - - lua_checkargs(L, "aug_touch", 1); - - path = luaL_checkstring(L, 1); - - augeas *aug = checkaug(L); - r = aug_match(aug, path, NULL); - if (r == 0) { - r = aug_set(aug, path, NULL); - if (r < 0) - return lua_pusherror(L); - } - - return 0; -} - static int lua_aug_save(lua_State *L) { int r; @@ -195,7 +176,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, - { "touch", lua_aug_touch }, { "save", lua_aug_save }, { "text_store", lua_aug_text_store }, { "store", lua_aug_text_store }, // alias diff --git a/src/luamod.c b/src/luamod.c index 2caf570ea..a7b25cfc9 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -281,6 +281,13 @@ static int Paug_clearm(lua_State *L) return Paug_setm(L); } +static int Paug_touch(lua_State *L) +{ + augeas *a = Paug_checkarg(L, 1); + const char *path = luaL_checkstring(L, 2); + return aug_match(a, path, NULL) ? 0 : Paug_clear(L); +} + static int Paug_matches(lua_State *L) { augeas *a = Paug_checkarg(L, 1); @@ -413,6 +420,7 @@ function set(augobj, path, value) {"rename", Paug_rename}, {"clear", Paug_clear}, {"clearm", Paug_clearm}, + {"touch", Paug_touch}, {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. From 01778a80b35bc9ee64a8de1313ae1dfe5d28e362 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 25 Nov 2016 11:07:38 +0200 Subject: [PATCH 45/50] auglua: move text_store to luamod --- src/auglua.c | 20 -------------------- src/luamod.c | 10 ++++++++++ 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 3abc88a07..4ae63aaa6 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -81,24 +81,6 @@ static int lua_aug_save(lua_State *L) { return 0; } -static int lua_aug_text_store(lua_State *L) { - int r; - const char *lens, *node, *path; - - lua_checkargs(L, "aug_text_store", 3); - - lens = luaL_checkstring(L, 1); - node = luaL_checkstring(L, 2); - path = luaL_checkstring(L, 3); - - augeas *aug = checkaug(L); - r = aug_text_store(aug, lens, node, path); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_text_retrieve(lua_State *L) { int r; const char *lens, *node_in, *path, *node_out; @@ -177,8 +159,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, { "save", lua_aug_save }, - { "text_store", lua_aug_text_store }, - { "store", lua_aug_text_store }, // alias { "text_retrieve", lua_aug_text_retrieve }, { "retrieve", lua_aug_text_retrieve }, // alias //{ "escape_name", lua_aug_escape_name }, diff --git a/src/luamod.c b/src/luamod.c index a7b25cfc9..319850f14 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -329,6 +329,14 @@ static int Paug_load(lua_State *L) return pushresult(L, aug_load(a), a, NULL); } +static int Paug_text_store(lua_State *L) { + augeas *a = Paug_checkarg(L, 1); + const char *lens = luaL_checkstring(L, 2); + const char *node = luaL_checkstring(L, 3); + const char *path = luaL_checkstring(L, 4); + return pushresult(L, aug_text_store(a, lens, node, path), a, NULL); +} + static int Paug_print(lua_State *L) { augeas *a; @@ -439,6 +447,8 @@ function match(augobj, path) function load(augobj) */ {"load", Paug_load}, + {"text_store", Paug_text_store}, + {"store", Paug_text_store}, /* --- Prints the value(s) for an Augeas path. -- From a3948eff81ec13428189d1e86e3aea5ed922d43a Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 25 Nov 2016 11:11:28 +0200 Subject: [PATCH 46/50] auglua: move text_retrieve to luamod --- src/auglua.c | 21 ----------------- src/luamod.c | 65 ++++++++++++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 48 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 4ae63aaa6..918b44e63 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -81,25 +81,6 @@ static int lua_aug_save(lua_State *L) { return 0; } -static int lua_aug_text_retrieve(lua_State *L) { - int r; - const char *lens, *node_in, *path, *node_out; - - lua_checkargs(L, "aug_text_retrieve", 4); - - lens = luaL_checkstring(L, 1); - node_in = luaL_checkstring(L, 2); - path = luaL_checkstring(L, 3); - node_out = luaL_checkstring(L, 4); - - augeas *aug = checkaug(L); - r = aug_text_retrieve(aug, lens, node_in, path, node_out); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int lua_aug_transform(lua_State *L) { int r; const char *lens, *file; @@ -159,8 +140,6 @@ struct lua_State *setup_lua(augeas *a) { static const luaL_Reg augfuncs[] = { //{ "span", lua_aug_span }, { "save", lua_aug_save }, - { "text_retrieve", lua_aug_text_retrieve }, - { "retrieve", lua_aug_text_retrieve }, // alias //{ "escape_name", lua_aug_escape_name }, { "transform", lua_aug_transform }, //{ "to_xml", lua_aug_to_xml }, diff --git a/src/luamod.c b/src/luamod.c index 319850f14..1ba45514a 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -337,6 +337,15 @@ static int Paug_text_store(lua_State *L) { return pushresult(L, aug_text_store(a, lens, node, path), a, NULL); } +static int Paug_text_retrieve(lua_State *L) { + augeas *a = Paug_checkarg(L, 1); + const char *lens = luaL_checkstring(L, 2); + const char *node_in = luaL_checkstring(L, 3); + const char *path = luaL_checkstring(L, 4); + const char *node_out = luaL_checkstring(L, 5); + return pushresult(L, aug_text_retrieve(a, lens, node_in, path, node_out), a, NULL); +} + static int Paug_print(lua_State *L) { augeas *a; @@ -388,16 +397,16 @@ static const luaL_Reg Paug_methods[] = { -- calls function init(params) */ - {"init", Paug_init}, - {"defvar", Paug_defvar}, - {"defnode", Paug_defnode}, + {"init", Paug_init}, + {"defvar", Paug_defvar}, + {"defnode", Paug_defnode}, /* --- Closes the library. Optional; automatically called by garbage collector. -- -- * `augobj` Augeas object from init() function close(augobj) */ - {"close", Paug_close}, + {"close", Paug_close}, /* --- Gets the value for an Augeas path. -- @@ -406,7 +415,7 @@ function close(augobj) -- * `[return]` Value for path function get(augobj, path) */ - {"get", Paug_get}, + {"get", Paug_get}, /* --- Sets the value for an Augeas path. -- @@ -415,21 +424,21 @@ function get(augobj, path) -- * `value` Value for path function set(augobj, path, value) */ - {"label", Paug_label}, - {"set", Paug_set}, - {"setm", Paug_setm}, - {"insert", Paug_insert}, - {"ins", Paug_insert}, - {"rm", Paug_rm}, - {"mv", Paug_mv}, - {"move", Paug_mv}, - {"cp", Paug_cp}, - {"copy", Paug_cp}, - {"rename", Paug_rename}, - {"clear", Paug_clear}, - {"clearm", Paug_clearm}, - {"touch", Paug_touch}, - {"matches", Paug_matches}, + {"label", Paug_label}, + {"set", Paug_set}, + {"setm", Paug_setm}, + {"insert", Paug_insert}, + {"ins", Paug_insert}, + {"rm", Paug_rm}, + {"mv", Paug_mv}, + {"move", Paug_mv}, + {"cp", Paug_cp}, + {"copy", Paug_cp}, + {"rename", Paug_rename}, + {"clear", Paug_clear}, + {"clearm", Paug_clearm}, + {"touch", Paug_touch}, + {"matches", Paug_matches}, /* --- Collects paths in the Augeas tree. -- @@ -438,17 +447,19 @@ function set(augobj, path, value) -- * `[return]` Array of matching paths function match(augobj, path) */ - {"match", Paug_match}, - {"save", Paug_save}, + {"match", Paug_match}, + {"save", Paug_save}, /* --- Loads the values for the Augeas tree. -- -- * `augobj` Augeas object from init() function load(augobj) */ - {"load", Paug_load}, - {"text_store", Paug_text_store}, - {"store", Paug_text_store}, + {"load", Paug_load}, + {"text_store", Paug_text_store}, + {"store", Paug_text_store}, + {"text_retrieve", Paug_text_retrieve}, + {"retrieve", Paug_text_retrieve}, /* --- Prints the value(s) for an Augeas path. -- @@ -457,8 +468,8 @@ function load(augobj) -- * `file_handle` *optional* open file for output; otherwise uses stdout function print(augobj, path, file_handle) */ - {"print", Paug_print}, - {"error", Paug_error}, + {"print", Paug_print}, + {"error", Paug_error}, {"error_message", Paug_error_message}, {"error_minor_message", Paug_error_minor_message}, {"error_details", Paug_error_details}, From 5ed0705e2e5925c479d5e14be6af980aaf834dee Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 25 Nov 2016 11:17:07 +0200 Subject: [PATCH 47/50] auglua: move transform to luamod --- src/auglua.c | 27 --------------------------- src/luamod.c | 9 +++++++++ 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index 918b44e63..fcc77d882 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -55,13 +55,6 @@ static void lua_checkargs(lua_State *L, const char *name, int arity) { } } -static int lua_pusherror(lua_State *L) { - augeas *aug = checkaug(L); - lua_pushstring(L, aug_error_message(aug)); - lua_error(L); - return 1; -} - static int lua_aug_save(lua_State *L) { int r; @@ -81,25 +74,6 @@ static int lua_aug_save(lua_State *L) { return 0; } -static int lua_aug_transform(lua_State *L) { - int r; - const char *lens, *file; - bool excl; - - lua_checkargs(L, "aug_transform", 3); - - lens = luaL_checkstring(L, 1); - file = luaL_checkstring(L, 2); - excl = lua_toboolean(L, 3); - - augeas *aug = checkaug(L); - r = aug_transform(aug, lens, file, excl); - if (r < 0) - return lua_pusherror(L); - - return 0; -} - static int call_function(lua_State *L) { lua_pushvalue(L, lua_upvalueindex(1)); lua_insert(L, 1); @@ -141,7 +115,6 @@ struct lua_State *setup_lua(augeas *a) { //{ "span", lua_aug_span }, { "save", lua_aug_save }, //{ "escape_name", lua_aug_escape_name }, - { "transform", lua_aug_transform }, //{ "to_xml", lua_aug_to_xml }, //{ "errors", lua_aug_errors }, { NULL, NULL } diff --git a/src/luamod.c b/src/luamod.c index 1ba45514a..a01b19e41 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -346,6 +346,14 @@ static int Paug_text_retrieve(lua_State *L) { return pushresult(L, aug_text_retrieve(a, lens, node_in, path, node_out), a, NULL); } +static int Paug_transform(lua_State *L) { + augeas *a = Paug_checkarg(L, 1); + const char *lens = luaL_checkstring(L, 2); + const char *file = luaL_checkstring(L, 3); + int excl = lua_toboolean(L, 4); + return pushresult(L, aug_transform(a, lens, file, excl), a, NULL); +} + static int Paug_print(lua_State *L) { augeas *a; @@ -460,6 +468,7 @@ function load(augobj) {"store", Paug_text_store}, {"text_retrieve", Paug_text_retrieve}, {"retrieve", Paug_text_retrieve}, + {"transform", Paug_transform}, /* --- Prints the value(s) for an Augeas path. -- From 5967264b8a93c53b5ad4d23c2d707f5ae80723ad Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Fri, 25 Nov 2016 12:03:07 +0200 Subject: [PATCH 48/50] auglua: save: use luamod functions --- src/auglua.c | 76 +++++++++++++++++++++++----------------------------- 1 file changed, 33 insertions(+), 43 deletions(-) diff --git a/src/auglua.c b/src/auglua.c index fcc77d882..131496f26 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -39,66 +39,56 @@ static void push_reg_value(lua_State *L, const char *key) { lua_gettable(L, LUA_REGISTRYINDEX); } -static augeas *checkaug(lua_State *L) { - lua_pushliteral(L, REG_KEY_INSTANCE); - lua_gettable(L, LUA_REGISTRYINDEX); - augeas **aug = (augeas **)lua_touserdata(L, -1); // Convert value - return *aug; -} - -static void lua_checkargs(lua_State *L, const char *name, int arity) { - int n = lua_gettop(L); - char msg[1024]; - if (n != arity) { - lua_pushfstring(L, msg, sizeof(msg), "Wrong number of arguments for '%s'", name); - lua_error(L); - } -} - -static int lua_aug_save(lua_State *L) { - int r; - - lua_checkargs(L, "aug_save", 0); - - augeas *aug = checkaug(L); - r = aug_save(aug); - if (r == -1) { - lua_pushstring(L, "saving failed (run 'errors' for details)"); - lua_error(L); - } else { - r = aug_match(aug, "/augeas/events/saved", NULL); - if (r > 0) - printf("Saved %d file(s)\n", r); - } - - return 0; -} - -static int call_function(lua_State *L) { - lua_pushvalue(L, lua_upvalueindex(1)); +static int call_function(lua_State *L, const char *name) { + push_reg_value(L, REG_KEY_MODULE); + lua_pushstring(L, name); + lua_gettable(L, -2); lua_insert(L, 1); push_reg_value(L, REG_KEY_INSTANCE); lua_insert(L, 2); lua_call(L, lua_gettop(L) - 1, LUA_MULTRET); + return lua_gettop(L); +} +static int call_bound_function(lua_State *L) { + int vals = call_function(L, lua_tostring(L, lua_upvalueindex(1))); if (lua_isnil(L, 1) && lua_isstring(L, 2)) { lua_pushvalue(L, 2); lua_error(L); } - return lua_gettop(L); + return vals; } static int bind_function(lua_State *L) { - push_reg_value(L, REG_KEY_MODULE); - lua_insert(L, 2); - lua_gettable(L, 2); - - lua_pushcclosure(L, call_function, 1); + lua_pushcclosure(L, call_bound_function, 1); return 1; } +static int lua_aug_save(lua_State *L) { + int n; + + call_function(L, "save"); + + if (lua_isnil(L, 1)) { + lua_pushstring(L, "saving failed (run 'errors' for details)"); + lua_error(L); + } else { + lua_settop(L, 0); + lua_pushliteral(L, "/augeas/events/saved"); + call_function(L, "match"); + + if (!lua_isnil(L, 1)) { + n = (int) lua_tointeger(L, 2); + if (n > 0) + printf("Saved %d file(s)\n", n); + } + } + + return 0; +} + struct lua_State *setup_lua(augeas *a) { lua_State *L = luaL_newstate(); luaL_openlibs(L); From 7a402e3b407ea4606c5c8066c266a1e4e395621d Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Wed, 23 Nov 2016 13:23:22 +0200 Subject: [PATCH 49/50] make Lua module for all available versions --- configure.ac | 15 +++++++++++++-- src/Makefile.am | 9 ++------- src/Makefile.luamod | 13 +++++++++++++ 3 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 src/Makefile.luamod diff --git a/configure.ac b/configure.ac index 326929383..f37484300 100644 --- a/configure.ac +++ b/configure.ac @@ -111,13 +111,23 @@ gl_INIT PKG_PROG_PKG_CONFIG PKG_CHECK_MODULES([LIBXML], [libxml-2.0]) +LUA_SUBDIRS= +LUA_MAKEFILES= m4_foreach_w([LUAPKG], [lua5.1 lua5.2 lua5.3 lua], [ AC_MSG_CHECKING([for LUAPKG]) PKG_CHECK_EXISTS(LUAPKG, [ AC_MSG_RESULT([yes]) LIBLUA_CFLAGS=$($PKG_CONFIG --cflags LUAPKG) LIBLUA_LIBS=$($PKG_CONFIG --libs LUAPKG) - LUA_VERSION=$($PKG_CONFIG --variable=V LUAPKG) + LUA_SUBDIRS="$LUA_SUBDIRS LUAPKG" + + LUA_SUBDIR=src/LUAPKG + AS_MKDIR_P([$LUA_SUBDIR]) + + LUA_MAKEFILE=$LUA_SUBDIR/Makefile + ln -fs ../Makefile.luamod $LUA_MAKEFILE.am + eval $AUTOMAKE $LUA_MAKEFILE + LUA_MAKEFILES="$LUA_MAKEFILES $LUA_MAKEFILE" ], [AC_MSG_RESULT([no])]) ]) if test -z "$LIBLUA_LIBS"; then @@ -125,7 +135,7 @@ if test -z "$LIBLUA_LIBS"; then fi AC_SUBST([LIBLUA_CFLAGS]) AC_SUBST([LIBLUA_LIBS]) -AC_SUBST([LUA_VERSION]) +AC_SUBST([LUA_SUBDIRS]) AC_CHECK_FUNCS([strerror_r fsync]) @@ -133,6 +143,7 @@ AC_OUTPUT(Makefile \ gnulib/lib/Makefile \ gnulib/tests/Makefile \ src/Makefile \ + $LUA_MAKEFILES \ man/Makefile \ tests/Makefile \ examples/Makefile \ diff --git a/src/Makefile.am b/src/Makefile.am index 61efc6e65..87751d389 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS = . $(LUA_SUBDIRS) + GNULIB= ../gnulib/lib/libgnu.la GNULIB_CFLAGS= -I $(top_builddir)/gnulib/lib -I $(top_srcdir)/gnulib/lib @@ -14,9 +16,6 @@ DISTCLEANFILES = datadir.h lib_LTLIBRARIES = libfa.la libaugeas.la libauglua.la noinst_LTLIBRARIES = liblexer.la -luadir = $(libdir)/lua/$(LUA_VERSION) -lua_LTLIBRARIES = augeas.la - bin_PROGRAMS = augtool augparse include_HEADERS = augeas.h fa.h @@ -60,10 +59,6 @@ libfa_la_LDFLAGS = $(FA_VERSION_SCRIPT) -version-info $(LIBFA_VERSION_INFO) liblexer_la_SOURCES = lexer.l liblexer_la_CFLAGS = $(AM_CFLAGS) -Wno-error -augeas_la_SOURCES = augeas.h luamod.c luamod.h -augeas_la_LIBADD = libaugeas.la -augeas_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -module -shared - FAILMALLOC_START ?= 1 FAILMALLOC_REP ?= 20 FAILMALLOC_PROG ?= ./augtool diff --git a/src/Makefile.luamod b/src/Makefile.luamod new file mode 100644 index 000000000..d26b7aa4d --- /dev/null +++ b/src/Makefile.luamod @@ -0,0 +1,13 @@ +# Copyright (C) 2016 Kaarle Ritvanen + +AUTOMAKE_OPTIONS = subdir-objects + +LUA_PACKAGE = $(notdir $(CURDIR)) + +luadir = $(libdir)/lua/$(shell $(PKG_CONFIG) --variable=V $(LUA_PACKAGE)) +lua_LTLIBRARIES = augeas.la + +augeas_la_SOURCES = ../augeas.h ../luamod.c ../luamod.h +augeas_la_CFLAGS = $(AM_CFLAGS) $(LIBXML_CFLAGS) $(shell $(PKG_CONFIG) --cflags $(LUA_PACKAGE)) +augeas_la_LIBADD = ../libaugeas.la +augeas_la_LDFLAGS = $(AM_LDFLAGS) -avoid-version -module -shared From c04faa6dc28949a60fa285c32f2be117fd035a89 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 28 Nov 2016 16:17:56 +0200 Subject: [PATCH 50/50] include config.h in auglua.c and luamod.c fix compilation on musl libc --- src/auglua.c | 1 + src/luamod.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/auglua.c b/src/auglua.c index 131496f26..9118a615b 100644 --- a/src/auglua.c +++ b/src/auglua.c @@ -21,6 +21,7 @@ * Author: Raphaël Pinson */ +#include #include "internal.h" #include "augeas.h" #include "luamod.h" diff --git a/src/luamod.c b/src/luamod.c index a01b19e41..d4ce082d7 100644 --- a/src/luamod.c +++ b/src/luamod.c @@ -11,6 +11,8 @@ * Copyright (C) 2015 Raphaël Pinson */ +#include + #include #include