- New internal Lua support scheme, laying under rpmio.
authorniemeyer <devnull@localhost>
Fri, 19 Mar 2004 20:08:20 +0000 (20:08 +0000)
committerniemeyer <devnull@localhost>
Fri, 19 Mar 2004 20:08:20 +0000 (20:08 +0000)
- 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

lib/Makefile.am
lib/psm.c
lib/rpmlua.c [deleted file]
lib/rpmlua.h [deleted file]
lib/rpmts.c
lua/local/linit.lch
lua/local/linit.lua
rpmio/Makefile.am
rpmio/macro.c
rpmio/rpmlua.c [new file with mode: 0644]
rpmio/rpmlua.h [new file with mode: 0644]

index 37c503a4a3152e00ab84ba768d0a067db65e40a7..317659eba2119815be71b3be0013f314e93a54c0 100644 (file)
@@ -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
index a01b8e4cb642064c92a7c5309099ebb83db8b4b1..c64ef429983f80aa569b5e32ae742bde1220181d 100644 (file)
--- 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 */
@@ -559,6 +560,78 @@ exit:
     return rc;
 }
 
+/**
+ * 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@*/
@@ -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 (file)
index 48f8ca6..0000000
+++ /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 (file)
index 724ce03..0000000
+++ /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
-*/
index 1a6e3fbd0d8cdf188e7ef859f12f89c02cdcdff6..2d08198184f388e2ef701f5aa6af12f7bf75f9d2 100644 (file)
@@ -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;
 
index 862d04efd788135c62196418d6953f2c53c268be..56ced87cfcd3f60b86edcf26558a1a23a0738bce 100644 (file)
@@ -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");
index a63316cd73558f55d9a2eeff114f74539929a225..7b134ba7541a2173c2e95184b0acc8acceb1bf84 100644 (file)
@@ -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
index b1ddd5bec03030365f658053f9d90b645f48b04b..c3f72a3ee08643be5f058c1871e37be059b11a00 100644 (file)
@@ -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)
index 1d11a46c692e76573470339fdd15b0d8923b27a2..d8e4859e90f8b355e503e6b3bb8a416edcedbfbe 100644 (file)
@@ -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 (file)
index 0000000..6b545b4
--- /dev/null
@@ -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 (file)
index 0000000..fad02ef
--- /dev/null
@@ -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
+*/