summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorniemeyer <devnull@localhost>2004-03-19 20:08:20 +0000
committerniemeyer <devnull@localhost>2004-03-19 20:08:20 +0000
commit635edd95230e17e8ada5793719d7e385e729df30 (patch)
tree09290ba08b74c4ad43a9d67b6f0f8eaa18413006
parenta1a283837a6b70c9ee4731f9172cfc614a1a7c6b (diff)
downloadlibrpm-tizen-635edd95230e17e8ada5793719d7e385e729df30.tar.gz
librpm-tizen-635edd95230e17e8ada5793719d7e385e729df30.tar.bz2
librpm-tizen-635edd95230e17e8ada5793719d7e385e729df30.zip
- New internal Lua support scheme, laying under rpmio.
- New API abstracting access to Lua state (rpmlua is abstract to everyone but rpmlua.c). - New %{lua: ... } macro. Modified Files: lib/Makefile.am lib/psm.c lib/rpmts.c lua/local/linit.lch lua/local/linit.lua rpmio/Makefile.am rpmio/macro.c Added Files: rpmio/rpmlua.c rpmio/rpmlua.h Removed Files: lib/rpmlua.c lib/rpmlua.h CVS patchset: 7178 CVS date: 2004/03/19 20:08:20
-rw-r--r--lib/Makefile.am7
-rw-r--r--lib/psm.c77
-rw-r--r--lib/rpmlua.c253
-rw-r--r--lib/rpmlua.h31
-rw-r--r--lib/rpmts.c2
-rw-r--r--lua/local/linit.lch67
-rw-r--r--lua/local/linit.lua10
-rw-r--r--rpmio/Makefile.am8
-rw-r--r--rpmio/macro.c27
-rw-r--r--rpmio/rpmlua.c588
-rw-r--r--rpmio/rpmlua.h84
11 files changed, 823 insertions, 331 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 37c503a4a..317659eba 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -11,8 +11,6 @@ INCLUDES = -I. \
-I$(top_srcdir)/rpmio \
@WITH_BEECRYPT_INCLUDE@ \
-I$(top_srcdir)/popt \
- -I$(top_builddir)/lua/include \
- -I$(top_builddir)/lua/local \
@INCPATH@
EXTRA_DIST = getdate.y
@@ -22,7 +20,7 @@ pkginc_HEADERS = \
misc.h rpmcli.h rpmlib.h \
rpmal.h rpmds.h rpmfi.h rpmps.h rpmsx.h rpmte.h rpmts.h stringbuf.h
noinst_HEADERS = \
- cpio.h fsm.h manifest.h psm.h rpmlead.h signature.h rpmlock.h rpmlua.h
+ cpio.h fsm.h manifest.h psm.h rpmlead.h signature.h rpmlock.h
mylibs = librpm.la
LIBS =
@@ -38,12 +36,11 @@ librpm_la_SOURCES = \
rpmal.c rpmchecksig.c rpmds.c rpmfi.c rpminstall.c \
rpmlead.c rpmlibprov.c rpmps.c rpmrc.c rpmsx.c rpmte.c rpmts.c \
rpmvercmp.c signature.c stringbuf.c transaction.c \
- verify.c rpmlock.c rpmlua.c
+ verify.c rpmlock.c
librpm_la_LDFLAGS = -release 4.3 $(LDFLAGS) \
$(top_builddir)/rpmdb/librpmdb.la \
$(top_builddir)/rpmio/librpmio.la \
$(top_builddir)/popt/libpopt.la \
- $(top_builddir)/lua/liblua.la \
@WITH_SELINUX_LIB@
getdate.c: getdate.y
diff --git a/lib/psm.c b/lib/psm.c
index a01b8e4cb..c64ef4299 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -9,6 +9,7 @@
#include <rpmlib.h>
#include <rpmmacro.h>
#include <rpmurl.h>
+#include <rpmlua.h>
#include "cpio.h"
#include "fsm.h" /* XXX CPIO_FOO/FSM_FOO constants */
@@ -560,6 +561,78 @@ exit:
}
/**
+ * Run internal Lua script.
+ */
+rpmRC runLuaScript(rpmlua lua, Header h, const char *sln,
+ int progArgc, const char **progArgv,
+ const char *script, int arg1, int arg2)
+{
+ int rootFd = -1;
+ const char *n, *v, *r;
+ rpmRC rc = RPMRC_OK;
+ int i;
+ int xx;
+ rpmts ts;
+ rpmluav var;
+
+ xx = headerNVR(h, &n, &v, &r);
+
+ ts = rpmluaGetData(lua, "ts");
+ if (ts && !rpmtsChrootDone(ts)) {
+ const char *rootDir = rpmtsRootDir(ts);
+ if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')) {
+ chdir("/");
+ rootFd = open(".", O_RDONLY, 0);
+ if (rootFd >= 0) {
+ chroot(rootDir);
+ rpmtsSetChrootDone(ts, 1);
+ }
+ }
+ }
+
+ /* Create arg variable */
+ rpmluaPushTable(lua, "arg");
+ var = rpmluavNew();
+ rpmluavSetListMode(var, 1);
+ if (progArgv) {
+ for (i = 0; i < progArgc && progArgv[i]; i++) {
+ rpmluavSetValue(var, RPMLUAV_STRING, progArgv[i]);
+ rpmluaSetVar(lua, var);
+ }
+ }
+ if (arg1 >= 0) {
+ rpmluavSetValueNum(var, arg1);
+ rpmluaSetVar(lua, var);
+ }
+ if (arg2 >= 0) {
+ rpmluavSetValueNum(var, arg2);
+ rpmluaSetVar(lua, var);
+ }
+ var = rpmluavFree(var);
+ rpmluaPop(lua);
+
+ {
+ char buf[BUFSIZ];
+ snprintf(buf, BUFSIZ, "%s(%s-%s-%s)", sln, n, v, r);
+ if (rpmluaRunScript(lua, script, buf) == -1)
+ rc = RPMRC_FAIL;
+ }
+
+ rpmluaDelVar(lua, "arg");
+
+ if (rootFd >= 0) {
+ fchdir(rootFd);
+ close(rootFd);
+ chroot(".");
+ rpmtsSetChrootDone(ts, 0);
+ }
+
+exit:
+ return rc;
+}
+
+
+/**
*/
/*@unchecked@*/
static int ldconfig_done = 0;
@@ -619,8 +692,8 @@ static rpmRC runScript(rpmpsm psm, Header h, const char * sln,
return rc;
if (progArgv && strcmp(progArgv[0], "<lua>") == 0) {
- return rpmluaRunScript(ts->lua, h, sln, progArgc, progArgv,
- script, arg1, arg2);
+ return runLuaScript(ts->lua, h, sln, progArgc, progArgv,
+ script, arg1, arg2);
}
psm->sq.reaper = 1;
diff --git a/lib/rpmlua.c b/lib/rpmlua.c
deleted file mode 100644
index 48f8ca6eb..000000000
--- a/lib/rpmlua.c
+++ /dev/null
@@ -1,253 +0,0 @@
-#include "system.h"
-#include "rpmlib.h"
-#include <rpmmacro.h>
-#include <rpmurl.h>
-
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-#include <lposix.h>
-#include <lrexlib.h>
-
-#include <unistd.h>
-
-#define _RPMLUA_INTERNAL
-#include "rpmlua.h"
-
-static int luaopen_rpm(lua_State *L);
-
-rpmlua rpmluaNew()
-{
- rpmlua lua = (rpmlua) xcalloc(1, sizeof(struct rpmlua_s));
- lua_State *L = lua_open();
- const luaL_reg lualibs[] = {
- {"base", luaopen_base},
- {"table", luaopen_table},
- {"io", luaopen_io},
- {"string", luaopen_string},
- {"debug", luaopen_debug},
- {"loadlib", luaopen_loadlib},
- {"posix", luaopen_posix},
- {"rex", luaopen_rex},
- {"rpm", luaopen_rpm},
- {NULL, NULL},
- };
- const luaL_reg *lib = lualibs;
- for (; lib->name; lib++) {
- lib->func(L);
- lua_settop(L, 0);
- }
- lua_pushliteral(L, "LUA_PATH");
- lua_pushstring(L, RPMCONFIGDIR "/lua/?.lua");
- lua_rawset(L, LUA_GLOBALSINDEX);
- lua->L = L;
- return lua;
-}
-
-void *rpmluaFree(rpmlua lua)
-{
- if (lua) {
- if (lua->L) lua_close(lua->L);
- free(lua);
- }
- return NULL;
-}
-
-void rpmluaSetTS(rpmlua lua, rpmts ts)
-{
- lua->ts = ts;
-}
-
-rpmRC rpmluaCheckScript(rpmlua lua, const char *script, const char *name)
-{
- lua_State *L = lua->L;
- rpmRC rc = RPMRC_OK;
- if (!name)
- name = "<lua>";
- if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
- rpmError(RPMERR_SCRIPT,
- _("invalid syntax in lua scriptlet: %s\n"),
- lua_tostring(L, -1));
- rc = RPMRC_FAIL;
- }
- lua_pop(L, 1); /* Error or chunk. */
- return rc;
-}
-
-rpmRC rpmluaRunScript(rpmlua lua, Header h, const char *sln,
- int progArgc, const char **progArgv,
- const char *script, int arg1, int arg2)
-{
- lua_State *L = lua->L;
- int rootFd = -1;
- const char *n, *v, *r;
- rpmRC rc = RPMRC_OK;
- int i;
- int xx;
- if (!L) {
- rpmError(RPMERR_SCRIPT,
- _("internal lua interpreter not available\n"));
- rc = RPMRC_FAIL;
- goto exit;
- }
- xx = headerNVR(h, &n, &v, &r);
- if (luaL_loadbuffer(L, script, strlen(script), "<lua>") != 0) {
- rpmError(RPMERR_SCRIPT,
- _("%s(%s-%s-%s) lua scriptlet failed loading: %s\n"),
- sln, n, v, r, lua_tostring(L, -1));
- lua_pop(L, 1);
- rc = RPMRC_FAIL;
- goto exit;
- }
-
- if (lua->ts && !rpmtsChrootDone(lua->ts)) {
- const char *rootDir = rpmtsRootDir(lua->ts);
- if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')) {
- chdir("/");
- rootFd = open(".", O_RDONLY, 0);
- if (rootFd >= 0) {
- chroot(rootDir);
- rpmtsSetChrootDone(lua->ts, 1);
- }
- }
- }
-
- /* Create arg variable */
- lua_pushliteral(L, "arg");
- lua_newtable(L);
- i = 0;
- if (progArgv) {
- while (i < progArgc && progArgv[i]) {
- lua_pushstring(L, progArgv[i]);
- lua_rawseti(L, -2, ++i);
- }
- }
- if (arg1 >= 0) {
- lua_pushnumber(L, arg1);
- lua_rawseti(L, -2, ++i);
- }
- if (arg2 >= 0) {
- lua_pushnumber(L, arg2);
- lua_rawseti(L, -2, ++i);
- }
- lua_rawset(L, LUA_GLOBALSINDEX);
-
- if (lua_pcall(L, 0, 0, 0) != 0) {
- rpmError(RPMERR_SCRIPT, _("%s(%s-%s-%s) lua scriptlet failed: %s\n"),
- sln, n, v, r, lua_tostring(L, -1));
- lua_pop(L, 1);
- rc = RPMRC_FAIL;
- }
-
- /* Remove 'arg' global. */
- lua_pushliteral(L, "arg");
- lua_pushnil(L);
- lua_rawset(L, LUA_GLOBALSINDEX);
-
- if (rootFd >= 0) {
- fchdir(rootFd);
- close(rootFd);
- chroot(".");
- rpmtsSetChrootDone(lua->ts, 0);
- }
-
-exit:
- return rc;
-}
-
-/* From lua.c */
-static int rpmluaReadline(lua_State *l, const char *prompt) {
- static char buffer[1024];
- if (prompt) {
- fputs(prompt, stdout);
- fflush(stdout);
- }
- if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
- return 0; /* read fails */
- } else {
- lua_pushstring(l, buffer);
- return 1;
- }
-}
-
-/* Based on lua.c */
-static void _rpmluaInteractive(lua_State *L)
-{
- fputs("\n", stdout);
- printf("RPM Interactive %s Interpreter\n", LUA_VERSION);
- for (;;) {
- if (rpmluaReadline(L, "> ") == 0)
- break;
- if (lua_tostring(L, -1)[0] == '=') {
- lua_pushfstring(L, "print(%s)", lua_tostring(L, -1)+1);
- lua_remove(L, -2);
- }
- int rc = 0;
- for (;;) {
- rc = luaL_loadbuffer(L, lua_tostring(L, -1),
- lua_strlen(L, -1), "<lua>");
- if (rc == LUA_ERRSYNTAX &&
- strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
- if (rpmluaReadline(L, ">> ") == 0)
- break;
- lua_remove(L, -2); // Remove error
- lua_concat(L, 2);
- continue;
- }
- break;
- }
- if (rc == 0)
- rc = lua_pcall(L, 0, 0, 0);
- if (rc != 0) {
- fprintf(stderr, "%s\n", lua_tostring(L, -1));
- lua_pop(L, 1);
- }
- lua_pop(L, 1); // Remove line
- }
- fputs("\n", stdout);
-}
-
-void rpmluaInteractive(rpmlua lua)
-{
- _rpmluaInteractive(lua->L);
-}
-
-/* ------------------------------------------------------------------ */
-/* Lua API */
-
-static int rpm_expand(lua_State *L)
-{
- const char *str = luaL_checkstring(L, 1);
- lua_pushstring(L, rpmExpand(str, NULL));
- return 1;
-}
-
-static int rpm_define(lua_State *L)
-{
- const char *str = luaL_checkstring(L, 1);
- rpmDefineMacro(NULL, str, 0);
- return 0;
-}
-
-static int rpm_interactive(lua_State *L)
-{
- _rpmluaInteractive(L);
- return 0;
-}
-
-static const luaL_reg rpmlib[] = {
- {"expand", rpm_expand},
- {"define", rpm_define},
- {"interactive", rpm_interactive},
- {NULL, NULL}
-};
-
-static int luaopen_rpm(lua_State *L)
-{
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- luaL_openlib(L, "rpm", rpmlib, 0);
- return 0;
-}
-
-/* vim:sts=4:sw=4
-*/
diff --git a/lib/rpmlua.h b/lib/rpmlua.h
deleted file mode 100644
index 724ce039a..000000000
--- a/lib/rpmlua.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef RPMLUA_H
-#define RPMLUA_H
-
-#if defined(_RPMLUA_INTERNAL)
-
-#include "rpmts.h"
-
-#include <lua.h>
-
-struct rpmlua_s {
- lua_State *L;
- rpmts ts;
-};
-
-#endif /* _RPMLUA_INTERNAL */
-
-typedef struct rpmlua_s * rpmlua;
-
-rpmlua rpmluaNew(void);
-void *rpmluaFree(rpmlua lua);
-void rpmluaSetTS(rpmlua lua, rpmts ts);
-rpmRC rpmluaCheckScript(rpmlua lua, const char *script, const char *name);
-rpmRC rpmluaRunScript(rpmlua lua, Header h, const char *sln,
- int progArgc, const char **progArgv,
- const char *script, int arg1, int arg2);
-void rpmluaInteractive(rpmlua lua);
-
-#endif /* RPMLUA_H */
-
-/* vim:sts=4:sw=4
-*/
diff --git a/lib/rpmts.c b/lib/rpmts.c
index 1a6e3fbd0..2d0819818 100644
--- a/lib/rpmts.c
+++ b/lib/rpmts.c
@@ -1512,7 +1512,7 @@ rpmts rpmtsCreate(void)
ts->score = NULL;
ts->lua = rpmluaNew();
- rpmluaSetTS(ts->lua, ts);
+ rpmluaSetData(ts->lua, "ts", ts);
ts->nrefs = 0;
diff --git a/lua/local/linit.lch b/lua/local/linit.lch
index 862d04efd..56ced87cf 100644
--- a/lua/local/linit.lch
+++ b/lua/local/linit.lch
@@ -6,39 +6,40 @@
/* local/linit.lua */
static const unsigned char B1[]={
10,114,101,120, 46,110,101,119, 32, 61, 32,114,101,120, 46,110,101,119, 80, 79,
- 83, 73, 88, 10, 10,102,117,110, 99,116,105,111,110, 32,114,101,120, 46,103,114,
-101,112, 40,102,105,108,101,110, 97,109,101, 44, 32,101,120,112,114, 41, 10, 9,
-105,102, 32,110,111,116, 32,112,111,115,105,120, 46,115,116, 97,116, 40,102,105,
-108,101,110, 97,109,101, 44, 32, 34,109,111,100,101, 34, 41, 32,116,104,101,110,
- 10, 9, 9,114,101,116,117,114,110, 32,110,105,108, 10, 9,101,110,100, 10, 9,
-108,111, 99, 97,108, 32,108,105,110,101,115, 32, 61, 32,123,125, 10, 9,108,111,
- 99, 97,108, 32,112, 97,116, 32, 61, 32,114,101,120, 46,110,101,119, 40,101,120,
-112,114, 41, 10, 9,108,111, 99, 97,108, 32,112,111,115, 32, 61, 32, 49, 10, 9,
-102,111,114, 32,108,105,110,101, 32,105,110, 32,105,111, 46,108,105,110,101,115,
- 40,102,105,108,101,110, 97,109,101, 41, 32,100,111, 10, 9, 9,105,102, 32,112,
- 97,116, 58,109, 97,116, 99,104, 40,108,105,110,101, 41, 32,116,104,101,110, 10,
- 9, 9, 9,116, 97, 98,108,101, 46,105,110,115,101,114,116, 40,108,105,110,101,
-115, 44, 32,112,111,115, 44, 32,108,105,110,101, 41, 10, 9, 9,101,110,100, 10,
- 9, 9,112,111,115, 32, 61, 32,112,111,115, 32, 43, 32, 49, 10, 9,101,110,100,
- 10, 9,105,102, 32,116, 97, 98,108,101, 46,103,101,116,110, 40,108,105,110,101,
-115, 41, 32, 61, 61, 32, 48, 32,116,104,101,110, 10, 9, 9,114,101,116,117,114,
-110, 32,110,105,108, 10, 9,101,110,100, 10, 9,114,101,116,117,114,110, 32,108,
-105,110,101,115, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,114,
-101,120, 46,105,103,114,101,112, 40,102,105,108,101,110, 97,109,101, 44, 32,101,
-120,112,114, 41, 10, 9,114,101,116,117,114,110, 32,105,112, 97,105,114,115, 40,
-114,101,120, 46,103,114,101,112, 40,102,105,108,101,110, 97,109,101, 44, 32,101,
-120,112,114, 41, 41, 10,101,110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,
-114,101,120, 46, 98,103,114,101,112, 40,102,105,108,101,110, 97,109,101, 44, 32,
-101,120,112,114, 41, 10, 9,105,102, 32,110,111,116, 32,112,111,115,105,120, 46,
-115,116, 97,116, 40,102,105,108,101,110, 97,109,101, 44, 32, 34,109,111,100,101,
- 34, 41, 32,116,104,101,110, 10, 9, 9,114,101,116,117,114,110, 32,110,105,108,
- 10, 9,101,110,100, 10, 9,108,111, 99, 97,108, 32,112, 97,116, 32, 61, 32,114,
-101,120, 46,110,101,119, 40,101,120,112,114, 41, 10, 9,102,111,114, 32,108,105,
-110,101, 32,105,110, 32,105,111, 46,108,105,110,101,115, 40,102,105,108,101,110,
- 97,109,101, 41, 32,100,111, 10, 9, 9,105,102, 32,112, 97,116, 58,109, 97,116,
- 99,104, 40,108,105,110,101, 41, 32,116,104,101,110, 10, 9, 9, 9,114,101,116,
-117,114,110, 32,116,114,117,101, 10, 9, 9,101,110,100, 10, 9,101,110,100, 10,
- 9,114,101,116,117,114,110, 32,102, 97,108,115,101, 10,101,110,100, 10, 10,
+ 83, 73, 88, 10, 10,117,116,105,108, 32, 61, 32,123,125, 10, 10,102,117,110, 99,
+116,105,111,110, 32,117,116,105,108, 46,103,114,101,112, 40,101,120,112,114, 44,
+ 32,102,105,108,101,110, 97,109,101, 41, 10, 9,105,102, 32,110,111,116, 32,112,
+111,115,105,120, 46,115,116, 97,116, 40,102,105,108,101,110, 97,109,101, 44, 32,
+ 34,109,111,100,101, 34, 41, 32,116,104,101,110, 10, 9, 9,114,101,116,117,114,
+110, 32,110,105,108, 10, 9,101,110,100, 10, 9,108,111, 99, 97,108, 32,108,105,
+110,101,115, 32, 61, 32,123,125, 10, 9,108,111, 99, 97,108, 32,112, 97,116, 32,
+ 61, 32,114,101,120, 46,110,101,119, 40,101,120,112,114, 41, 10, 9,108,111, 99,
+ 97,108, 32,112,111,115, 32, 61, 32, 49, 10, 9,102,111,114, 32,108,105,110,101,
+ 32,105,110, 32,105,111, 46,108,105,110,101,115, 40,102,105,108,101,110, 97,109,
+101, 41, 32,100,111, 10, 9, 9,105,102, 32,112, 97,116, 58,109, 97,116, 99,104,
+ 40,108,105,110,101, 41, 32,116,104,101,110, 10, 9, 9, 9,116, 97, 98,108,101,
+ 46,105,110,115,101,114,116, 40,108,105,110,101,115, 44, 32,112,111,115, 44, 32,
+108,105,110,101, 41, 10, 9, 9,101,110,100, 10, 9, 9,112,111,115, 32, 61, 32,
+112,111,115, 32, 43, 32, 49, 10, 9,101,110,100, 10, 9,105,102, 32,116, 97, 98,
+108,101, 46,103,101,116,110, 40,108,105,110,101,115, 41, 32, 61, 61, 32, 48, 32,
+116,104,101,110, 10, 9, 9,114,101,116,117,114,110, 32,110,105,108, 10, 9,101,
+110,100, 10, 9,114,101,116,117,114,110, 32,108,105,110,101,115, 10,101,110,100,
+ 10, 10,102,117,110, 99,116,105,111,110, 32,117,116,105,108, 46,105,103,114,101,
+112, 40,101,120,112,114, 44, 32,102,105,108,101,110, 97,109,101, 41, 10, 9,114,
+101,116,117,114,110, 32,105,112, 97,105,114,115, 40,114,101,120, 46,103,114,101,
+112, 40,101,120,112,114, 44, 32,102,105,108,101,110, 97,109,101, 41, 41, 10,101,
+110,100, 10, 10,102,117,110, 99,116,105,111,110, 32,117,116,105,108, 46, 98,103,
+114,101,112, 40,101,120,112,114, 44, 32,102,105,108,101,110, 97,109,101, 41, 10,
+ 9,105,102, 32,110,111,116, 32,112,111,115,105,120, 46,115,116, 97,116, 40,102,
+105,108,101,110, 97,109,101, 44, 32, 34,109,111,100,101, 34, 41, 32,116,104,101,
+110, 10, 9, 9,114,101,116,117,114,110, 32,110,105,108, 10, 9,101,110,100, 10,
+ 9,108,111, 99, 97,108, 32,112, 97,116, 32, 61, 32,114,101,120, 46,110,101,119,
+ 40,101,120,112,114, 41, 10, 9,102,111,114, 32,108,105,110,101, 32,105,110, 32,
+105,111, 46,108,105,110,101,115, 40,102,105,108,101,110, 97,109,101, 41, 32,100,
+111, 10, 9, 9,105,102, 32,112, 97,116, 58,109, 97,116, 99,104, 40,108,105,110,
+101, 41, 32,116,104,101,110, 10, 9, 9, 9,114,101,116,117,114,110, 32,116,114,
+117,101, 10, 9, 9,101,110,100, 10, 9,101,110,100, 10, 9,114,101,116,117,114,
+110, 32,102, 97,108,115,101, 10,101,110,100, 10, 10,
};
lua_dobuffer(L,(const char*)B1,sizeof(B1),"local/linit.lua");
diff --git a/lua/local/linit.lua b/lua/local/linit.lua
index a63316cd7..7b134ba75 100644
--- a/lua/local/linit.lua
+++ b/lua/local/linit.lua
@@ -1,7 +1,9 @@
rex.new = rex.newPOSIX
-function rex.grep(filename, expr)
+util = {}
+
+function util.grep(expr, filename)
if not posix.stat(filename, "mode") then
return nil
end
@@ -20,11 +22,11 @@ function rex.grep(filename, expr)
return lines
end
-function rex.igrep(filename, expr)
- return ipairs(rex.grep(filename, expr))
+function util.igrep(expr, filename)
+ return ipairs(rex.grep(expr, filename))
end
-function rex.bgrep(filename, expr)
+function util.bgrep(expr, filename)
if not posix.stat(filename, "mode") then
return nil
end
diff --git a/rpmio/Makefile.am b/rpmio/Makefile.am
index b1ddd5bec..c3f72a3ee 100644
--- a/rpmio/Makefile.am
+++ b/rpmio/Makefile.am
@@ -12,13 +12,15 @@ INCLUDES = -I. \
-I$(top_srcdir) \
@WITH_BEECRYPT_INCLUDE@ \
-I$(top_srcdir)/popt \
+ -I$(top_srcdir)/lua/include \
+ -I$(top_srcdir)/lua/local \
@INCPATH@
pkgincdir = $(pkgincludedir)
pkginc_HEADERS = \
argv.h fts.h \
rpmio.h rpmurl.h rpmmacro.h rpmlog.h rpmmessages.h rpmerr.h rpmpgp.h \
- rpmsq.h rpmsw.h ugid.h
+ rpmsq.h rpmsw.h ugid.h rpmlua.h
noinst_HEADERS = rpmio_internal.h
BEECRYPTLOBJS = $(shell test X"@WITH_BEECRYPT_SUBDIR@" != X && cat $(top_builddir)/@WITH_BEECTYPT_SUBDIR@/listobjs)
@@ -30,10 +32,12 @@ usrlib_LTLIBRARIES = librpmio.la
librpmio_la_SOURCES = \
argv.c digest.c fts.c macro.c \
rpmio.c rpmlog.c rpmmalloc.c \
- rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c stubs.c url.c ugid.c
+ rpmpgp.c rpmrpc.c rpmsq.c rpmsw.c strcasecmp.c stubs.c url.c ugid.c \
+ rpmlua.c
librpmio_la_LDFLAGS = -release 4.3 $(LDFLAGS) \
@WITH_BEECRYPT_LIB@ \
$(top_builddir)/file/src/libfmagic.la \
+ $(top_builddir)/lua/liblua.la \
@WITH_ZLIB_LIB@ \
-lrt -lpthread
librpmio_la_LIBADD = # $(BEECRYPTLOBJS)
diff --git a/rpmio/macro.c b/rpmio/macro.c
index 1d11a46c6..d8e4859e9 100644
--- a/rpmio/macro.c
+++ b/rpmio/macro.c
@@ -43,6 +43,7 @@ typedef FILE * FD_t;
#include <rpmio_internal.h>
#include <rpmmessages.h>
#include <rpmerr.h>
+#include <rpmlua.h>
#endif
@@ -1363,6 +1364,32 @@ expandMacro(MacroBuf mb)
continue;
}
+ if (STREQ("lua", f, fn)) {
+ rpmlua lua = rpmluaNew();
+ const char *ls = s+sizeof("{lua:")-1;
+ const char *lse = se-sizeof("}")+1;
+ char *scriptbuf = (char *)xmalloc((lse-ls)+1);
+ const char *printbuf;
+ memcpy(scriptbuf, ls, lse-ls);
+ scriptbuf[lse-ls] = '\0';
+ rpmluaSetPrintBuffer(lua, 1);
+ if (rpmluaRunScript(lua, scriptbuf, NULL) == -1)
+ rc = 1;
+ printbuf = rpmluaGetPrintBuffer(lua);
+ if (printbuf) {
+ int len = strlen(printbuf);
+ if (len > mb->nb)
+ len = mb->nb;
+ memcpy(mb->t, printbuf, len);
+ mb->t += len;
+ mb->nb -= len;
+ }
+ free(scriptbuf);
+ lua = rpmluaFree(lua);
+ s = se;
+ continue;
+ }
+
/* XXX necessary but clunky */
if (STREQ("basename", f, fn) ||
STREQ("suffix", f, fn) ||
diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c
new file mode 100644
index 000000000..6b545b4a1
--- /dev/null
+++ b/rpmio/rpmlua.c
@@ -0,0 +1,588 @@
+#include "system.h"
+#include <rpmio.h>
+#include <rpmmacro.h>
+#include <rpmerr.h>
+#include <rpmurl.h>
+
+#include <lua.h>
+#include <lualib.h>
+#include <lauxlib.h>
+#include <lposix.h>
+#include <lrexlib.h>
+
+#include <unistd.h>
+#include <assert.h>
+
+#define _RPMLUA_INTERNAL
+#include "rpmlua.h"
+
+#if !defined(HAVE_VSNPRINTF)
+static inline int vsnprintf(char * buf, /*@unused@*/ int nb,
+ const char * fmt, va_list ap)
+{
+ return vsprintf(buf, fmt, ap);
+}
+#endif
+
+static int luaopen_rpm(lua_State *L);
+static int rpm_print(lua_State *L);
+
+rpmlua rpmluaNew()
+{
+ rpmlua lua = (rpmlua) xcalloc(1, sizeof(struct rpmlua_s));
+ lua_State *L = lua_open();
+ lua->L = L;
+ const luaL_reg lualibs[] = {
+ {"base", luaopen_base},
+ {"table", luaopen_table},
+ {"io", luaopen_io},
+ {"string", luaopen_string},
+ {"debug", luaopen_debug},
+ {"loadlib", luaopen_loadlib},
+ {"posix", luaopen_posix},
+ {"rex", luaopen_rex},
+ {"rpm", luaopen_rpm},
+ {NULL, NULL},
+ };
+ const luaL_reg *lib = lualibs;
+ for (; lib->name; lib++) {
+ lib->func(L);
+ lua_settop(L, 0);
+ }
+ lua_pushliteral(L, "LUA_PATH");
+ lua_pushstring(L, RPMCONFIGDIR "/lua/?.lua");
+ lua_rawset(L, LUA_GLOBALSINDEX);
+ lua_pushliteral(L, "print");
+ lua_pushcfunction(L, rpm_print);
+ lua_rawset(L, LUA_GLOBALSINDEX);
+ rpmluaSetData(lua, "lua", lua);
+ return lua;
+}
+
+void *rpmluaFree(rpmlua lua)
+{
+ if (lua) {
+ if (lua->L) lua_close(lua->L);
+ free(lua->printbuf);
+ free(lua);
+ }
+ return NULL;
+}
+
+void rpmluaSetData(rpmlua lua, const char *key, const void *data)
+{
+ lua_State *L = lua->L;
+ lua_pushliteral(L, "rpm_");
+ lua_pushstring(L, key);
+ lua_concat(L, 2);
+ if (data == NULL)
+ lua_pushnil(L);
+ else
+ lua_pushlightuserdata(L, (void *)data);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+}
+
+static void *getdata(lua_State *L, const char *key)
+{
+ void *ret = NULL;
+ lua_pushliteral(L, "rpm_");
+ lua_pushstring(L, key);
+ lua_concat(L, 2);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (lua_islightuserdata(L, -1))
+ ret = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+ return ret;
+}
+
+void *rpmluaGetData(rpmlua lua, const char *key)
+{
+ return getdata(lua->L, key);
+}
+
+void rpmluaSetPrintBuffer(rpmlua lua, int flag)
+{
+ lua->storeprint = flag;
+ free(lua->printbuf);
+ lua->printbuf = NULL;
+ lua->printbufsize = 0;
+}
+
+const char *rpmluaGetPrintBuffer(rpmlua lua)
+{
+ return lua->printbuf;
+}
+
+static int pushvar(lua_State *L, rpmluavType type, void *value)
+{
+ int ret = 0;
+ switch (type) {
+ case RPMLUAV_NIL:
+ lua_pushnil(L);
+ break;
+ case RPMLUAV_STRING:
+ lua_pushstring(L, *((char **)value));
+ break;
+ case RPMLUAV_NUMBER:
+ lua_pushnumber(L, *((double *)value));
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ return ret;
+}
+
+void rpmluaSetVar(rpmlua lua, rpmluav var)
+{
+ lua_State *L = lua->L;
+ if (var->listmode && lua->pushsize > 0) {
+ if (var->keyType != RPMLUAV_NUMBER || var->key.num == 0) {
+ var->keyType = RPMLUAV_NUMBER;
+ var->key.num = luaL_getn(L, -1);
+ }
+ var->key.num++;
+ }
+ if (!var->listmode || lua->pushsize > 0) {
+ if (lua->pushsize == 0)
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ if (pushvar(L, var->keyType, &var->key) != -1) {
+ if (pushvar(L, var->valueType, &var->value) != -1)
+ lua_rawset(L, -3);
+ else
+ lua_pop(L, 1);
+ }
+ if (lua->pushsize == 0)
+ lua_pop(L, 1);
+ }
+}
+
+static void popvar(lua_State *L, rpmluavType *type, void *value)
+{
+ switch (lua_type(L, -1)) {
+ case LUA_TSTRING:
+ *type = RPMLUAV_STRING;
+ *((const char **)value) = lua_tostring(L, -1);
+ break;
+ case LUA_TNUMBER:
+ *type = RPMLUAV_NUMBER;
+ *((double *)value) = lua_tonumber(L, -1);
+ break;
+ default:
+ *type = RPMLUAV_NIL;
+ *((void **)value) = NULL;
+ break;
+ }
+ lua_pop(L, 1);
+}
+
+void rpmluaGetVar(rpmlua lua, rpmluav var)
+{
+ lua_State *L = lua->L;
+ if (!var->listmode) {
+ if (lua->pushsize == 0)
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ if (pushvar(L, var->keyType, &var->key) != -1) {
+ lua_rawget(L, -2);
+ popvar(L, &var->valueType, &var->value);
+ }
+ if (lua->pushsize == 0)
+ lua_pop(L, 1);
+ } else if (lua->pushsize > 0) {
+ pushvar(L, var->keyType, &var->key);
+ if (lua_next(L, -2) != 0)
+ popvar(L, &var->valueType, &var->value);
+ }
+}
+
+#define FINDKEY_RETURN 0
+#define FINDKEY_CREATE 1
+#define FINDKEY_REMOVE 2
+static int findkey(lua_State *L, int oper, const char *key, va_list va)
+{
+ char buf[BUFSIZ];
+ const char *s, *e;
+ int ret = 0;
+ vsnprintf(buf, BUFSIZ, key, va);
+ s = e = buf;
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ for (;;) {
+ if (*e == '\0' || *e == '.') {
+ if (e != s) {
+ lua_pushlstring(L, s, e-s);
+ switch (oper) {
+ case FINDKEY_REMOVE:
+ if (*e == '\0') {
+ lua_pushnil(L);
+ lua_rawset(L, -3);
+ lua_pop(L, 1);
+ break;
+ }
+ /* @fallthrough@ */
+ case FINDKEY_RETURN:
+ lua_rawget(L, -2);
+ lua_remove(L, -2);
+ break;
+ case FINDKEY_CREATE:
+ lua_rawget(L, -2);
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ lua_pushlstring(L, s, e-s);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, -4);
+ }
+ lua_remove(L, -2);
+ break;
+ }
+ }
+ if (*e == '\0')
+ break;
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ ret = -1;
+ break;
+ }
+ s = e+1;
+ }
+ e++;
+ }
+
+ return ret;
+}
+
+void rpmluaDelVar(rpmlua lua, const char *key, ...)
+{
+ va_list va;
+ va_start(va, key);
+ findkey(lua->L, FINDKEY_REMOVE, key, va);
+ va_end(va);
+}
+
+int rpmluaVarExists(rpmlua lua, const char *key, ...)
+{
+ int ret = 0;
+ va_list va;
+ va_start(va, key);
+ if (findkey(lua->L, FINDKEY_RETURN, key, va) == 0) {
+ if (!lua_isnil(lua->L, -1))
+ ret = 1;
+ lua_pop(lua->L, 1);
+ }
+ va_end(va);
+ return ret;
+}
+
+void rpmluaPushTable(rpmlua lua, const char *key, ...)
+{
+ va_list va;
+ va_start(va, key);
+ findkey(lua->L, FINDKEY_CREATE, key, va);
+ lua->pushsize++;
+ va_end(va);
+}
+
+void rpmluaPop(rpmlua lua)
+{
+ assert(lua->pushsize > 0);
+ lua->pushsize--;
+ lua_pop(lua->L, 1);
+}
+
+rpmluav rpmluavNew(void)
+{
+ rpmluav var = (rpmluav) xcalloc(1, sizeof(struct rpmluav_s));
+ return var;
+}
+
+void *rpmluavFree(rpmluav var)
+{
+ free(var);
+ return NULL;
+}
+
+void rpmluavSetListMode(rpmluav var, int flag)
+{
+ var->listmode = flag;
+ var->keyType = RPMLUAV_NIL;
+}
+
+void rpmluavSetKey(rpmluav var, rpmluavType type, const void *value)
+{
+ var->keyType = type;
+ switch (type) {
+ case RPMLUAV_NUMBER:
+ var->key.num = *((double *)value);
+ break;
+ case RPMLUAV_STRING:
+ var->key.str = (char *)value;
+ break;
+ default:
+ break;
+ }
+}
+
+void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value)
+{
+ var->valueType = type;
+ switch (type) {
+ case RPMLUAV_NUMBER:
+ var->value.num = *((const double *)value);
+ break;
+ case RPMLUAV_STRING:
+ var->value.str = (const char *)value;
+ break;
+ default:
+ break;
+ }
+}
+
+void rpmluavGetKey(rpmluav var, rpmluavType *type, void **value)
+{
+ *type = var->keyType;
+ switch (var->keyType) {
+ case RPMLUAV_NUMBER:
+ *((double **)value) = &var->key.num;
+ break;
+ case RPMLUAV_STRING:
+ *((const char **)value) = var->key.str;
+ break;
+ default:
+ break;
+ }
+}
+
+void rpmluavGetValue(rpmluav var, rpmluavType *type, void **value)
+{
+ *type = var->valueType;
+ switch (var->valueType) {
+ case RPMLUAV_NUMBER:
+ *((double **)value) = &var->value.num;
+ break;
+ case RPMLUAV_STRING:
+ *((const char **)value) = var->value.str;
+ break;
+ default:
+ break;
+ }
+}
+
+void rpmluavSetKeyNum(rpmluav var, double value)
+{
+ rpmluavSetKey(var, RPMLUAV_NUMBER, &value);
+}
+
+void rpmluavSetValueNum(rpmluav var, double value)
+{
+ rpmluavSetValue(var, RPMLUAV_NUMBER, &value);
+}
+
+double rpmluavGetKeyNum(rpmluav var)
+{
+ rpmluavType type;
+ void *value;
+ rpmluavGetKey(var, &type, &value);
+ if (type == RPMLUAV_NUMBER)
+ return *((double *)value);
+ return 0;
+}
+
+double rpmluavGetValueNum(rpmluav var)
+{
+ rpmluavType type;
+ void *value;
+ rpmluavGetValue(var, &type, &value);
+ if (type == RPMLUAV_NUMBER)
+ return *((double *)value);
+ return 0;
+}
+
+int rpmluavKeyIsNum(rpmluav var)
+{
+ return (var->keyType == RPMLUAV_NUMBER) ? 1 : 0;
+}
+
+int rpmluavValueIsNum(rpmluav var)
+{
+ return (var->valueType == RPMLUAV_NUMBER) ? 1 : 0;
+}
+
+int rpmluaCheckScript(rpmlua lua, const char *script, const char *name)
+{
+ lua_State *L = lua->L;
+ int ret = 0;
+ if (!name)
+ name = "<lua>";
+ if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
+ rpmError(RPMERR_SCRIPT,
+ _("invalid syntax in lua scriptlet: %s\n"),
+ lua_tostring(L, -1));
+ ret = -1;
+ }
+ lua_pop(L, 1); /* Error or chunk. */
+ return ret;
+}
+
+int rpmluaRunScript(rpmlua lua, const char *script, const char *name)
+{
+ lua_State *L = lua->L;
+ int ret = 0;
+ if (!name)
+ name = "<lua>";
+ if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
+ rpmError(RPMERR_SCRIPT, _("invalid syntax in lua script: %s\n"),
+ lua_tostring(L, -1));
+ lua_pop(L, 1);
+ ret = -1;
+ } else if (lua_pcall(L, 0, 0, 0) != 0) {
+ rpmError(RPMERR_SCRIPT, _("lua script failed: %s\n"),
+ lua_tostring(L, -1));
+ lua_pop(L, 1);
+ ret = -1;
+ }
+ return ret;
+}
+
+/* From lua.c */
+static int rpmluaReadline(lua_State *l, const char *prompt) {
+ static char buffer[1024];
+ if (prompt) {
+ fputs(prompt, stdout);
+ fflush(stdout);
+ }
+ if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
+ return 0; /* read fails */
+ } else {
+ lua_pushstring(l, buffer);
+ return 1;
+ }
+}
+
+/* Based on lua.c */
+static void _rpmluaInteractive(lua_State *L)
+{
+ fputs("\n", stdout);
+ printf("RPM Interactive %s Interpreter\n", LUA_VERSION);
+ for (;;) {
+ if (rpmluaReadline(L, "> ") == 0)
+ break;
+ if (lua_tostring(L, -1)[0] == '=') {
+ lua_pushfstring(L, "print(%s)", lua_tostring(L, -1)+1);
+ lua_remove(L, -2);
+ }
+ int rc = 0;
+ for (;;) {
+ rc = luaL_loadbuffer(L, lua_tostring(L, -1),
+ lua_strlen(L, -1), "<lua>");
+ if (rc == LUA_ERRSYNTAX &&
+ strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
+ if (rpmluaReadline(L, ">> ") == 0)
+ break;
+ lua_remove(L, -2); // Remove error
+ lua_concat(L, 2);
+ continue;
+ }
+ break;
+ }
+ if (rc == 0)
+ rc = lua_pcall(L, 0, 0, 0);
+ if (rc != 0) {
+ fprintf(stderr, "%s\n", lua_tostring(L, -1));
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1); // Remove line
+ }
+ fputs("\n", stdout);
+}
+
+void rpmluaInteractive(rpmlua lua)
+{
+ _rpmluaInteractive(lua->L);
+}
+
+/* ------------------------------------------------------------------ */
+/* Lua API */
+
+static int rpm_expand(lua_State *L)
+{
+ const char *str = luaL_checkstring(L, 1);
+ lua_pushstring(L, rpmExpand(str, NULL));
+ return 1;
+}
+
+static int rpm_define(lua_State *L)
+{
+ const char *str = luaL_checkstring(L, 1);
+ rpmDefineMacro(NULL, str, 0);
+ return 0;
+}
+
+static int rpm_interactive(lua_State *L)
+{
+ _rpmluaInteractive(L);
+ return 0;
+}
+
+/* Based on luaB_print. */
+static int rpm_print (lua_State *L)
+{
+ rpmlua lua = (rpmlua)getdata(L, "lua");;
+ int n = lua_gettop(L); /* number of arguments */
+ int i;
+ if (!lua) return 0;
+ lua_getglobal(L, "tostring");
+ for (i = 1; i <= n; i++) {
+ const char *s;
+ lua_pushvalue(L, -1); /* function to be called */
+ lua_pushvalue(L, i); /* value to print */
+ lua_call(L, 1, 1);
+ s = lua_tostring(L, -1); /* get result */
+ if (s == NULL)
+ return luaL_error(L, "`tostring' must return a string to `print'");
+ if (lua->storeprint) {
+ int sl = lua_strlen(L, -1);
+ if (lua->printbufused+sl+1 > lua->printbufsize) {
+ lua->printbufsize += sl+512;
+ lua->printbuf = xrealloc(lua->printbuf, lua->printbufsize);
+ }
+ if (i > 1)
+ lua->printbuf[lua->printbufused++] = '\t';
+ memcpy(lua->printbuf+lua->printbufused, s, sl+1);
+ lua->printbufused += sl;
+ } else {
+ if (i > 1)
+ fputs("\t", stdout);
+ fputs(s, stdout);
+ }
+ lua_pop(L, 1); /* pop result */
+ }
+ lua_pop(L, 1);
+ if (!lua->storeprint) {
+ fputs("\n", stdout);
+ } else {
+ if (lua->printbufused+1 >= lua->printbufsize) {
+ lua->printbufsize += 512;
+ lua->printbuf = xrealloc(lua->printbuf, lua->printbufsize);
+ }
+ lua->printbuf[lua->printbufused++] = '\n';
+ lua->printbuf[lua->printbufused] = '\0';
+ }
+ return 0;
+}
+
+static const luaL_reg rpmlib[] = {
+ {"expand", rpm_expand},
+ {"define", rpm_define},
+ {"interactive", rpm_interactive},
+ {NULL, NULL}
+};
+
+static int luaopen_rpm(lua_State *L)
+{
+ lua_pushvalue(L, LUA_GLOBALSINDEX);
+ luaL_openlib(L, "rpm", rpmlib, 0);
+ return 0;
+}
+
+/* vim:sts=4:sw=4
+*/
diff --git a/rpmio/rpmlua.h b/rpmio/rpmlua.h
new file mode 100644
index 000000000..fad02efc6
--- /dev/null
+++ b/rpmio/rpmlua.h
@@ -0,0 +1,84 @@
+#ifndef RPMLUA_H
+#define RPMLUA_H
+
+typedef enum rpmluavType_e {
+ RPMLUAV_NIL = 0,
+ RPMLUAV_STRING = 1,
+ RPMLUAV_NUMBER = 2
+} rpmluavType;
+
+#if defined(_RPMLUA_INTERNAL)
+
+#include <stdarg.h>
+#include <lua.h>
+
+struct rpmlua_s {
+ lua_State *L;
+ int pushsize;
+ int storeprint;
+ int printbufsize;
+ int printbufused;
+ char *printbuf;
+};
+
+struct rpmluav_s {
+ rpmluavType keyType;
+ rpmluavType valueType;
+ union {
+ const char *str;
+ const void *ptr;
+ double num;
+ } key;
+ union {
+ const char *str;
+ const void *ptr;
+ double num;
+ } value;
+ int listmode;
+};
+
+#endif /* _RPMLUA_INTERNAL */
+
+typedef struct rpmlua_s * rpmlua;
+typedef struct rpmluav_s * rpmluav;
+
+rpmlua rpmluaNew(void);
+void *rpmluaFree(rpmlua lua);
+
+int rpmluaCheckScript(rpmlua lua, const char *script, const char *name);
+int rpmluaRunScript(rpmlua lua, const char *script, const char *name);
+void rpmluaInteractive(rpmlua lua);
+
+void rpmluaSetData(rpmlua lua, const char *key, const void *data);
+void *rpmluaGetData(rpmlua lua, const char *key);
+
+void rpmluaSetPrintBuffer(rpmlua lua, int flag);
+const char *rpmluaGetPrintBuffer(rpmlua lua);
+
+void rpmluaSetVar(rpmlua lua, rpmluav var);
+void rpmluaGetVar(rpmlua lua, rpmluav var);
+void rpmluaDelVar(rpmlua lua, const char *key, ...);
+int rpmluaVarExists(rpmlua lua, const char *key, ...);
+void rpmluaPushTable(rpmlua lua, const char *key, ...);
+void rpmluaPop(rpmlua lua);
+
+rpmluav rpmluavNew(void);
+void *rpmluavFree(rpmluav var);
+void rpmluavSetListMode(rpmluav var, int flag);
+void rpmluavSetKey(rpmluav var, rpmluavType type, const void *value);
+void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value);
+void rpmluavGetKey(rpmluav var, rpmluavType *type, void **value);
+void rpmluavGetValue(rpmluav var, rpmluavType *type, void **value);
+
+/* Optional helpers for numbers. */
+void rpmluavSetKeyNum(rpmluav var, double value);
+void rpmluavSetValueNum(rpmluav var, double value);
+double rpmluavGetKeyNum(rpmluav var);
+double rpmluavGetValueNum(rpmluav var);
+int rpmluavKeyIsNum(rpmluav var);
+int rpmluavValueIsNum(rpmluav var);
+
+#endif /* RPMLUA_H */
+
+/* vim:sts=4:sw=4
+*/