|
|
2ff057 |
#include "system.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#ifdef WITH_LUA
|
|
|
2ff057 |
#include <lua.h>
|
|
|
2ff057 |
#include <lualib.h>
|
|
|
2ff057 |
#include <lauxlib.h>
|
|
|
2ff057 |
#include <lposix.h>
|
|
|
2ff057 |
#include <lrexlib.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
/* replaced in 5.1 */
|
|
|
2ff057 |
#ifndef lua_open
|
|
|
2ff057 |
#define lua_open() luaL_newstate()
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
/* defined as lua_objlen in 5.1 */
|
|
|
2ff057 |
#ifndef lua_strlen
|
|
|
2ff057 |
#define lua_strlen(L,i) lua_rawlen(L, (i))
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
/* deprecated in 5.1, defined as lua_objlen in 5.1 */
|
|
|
2ff057 |
#ifndef luaL_getn
|
|
|
2ff057 |
#define luaL_getn(L,i) ((int)lua_rawlen(L, i))
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
/* define added in 5.2 */
|
|
|
2ff057 |
#ifndef lua_pushglobaltable
|
|
|
2ff057 |
#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <unistd.h>
|
|
|
2ff057 |
#include <assert.h>
|
|
|
2ff057 |
|
|
|
2ff057 |
#include <rpm/rpmio.h>
|
|
|
2ff057 |
#include <rpm/rpmmacro.h>
|
|
|
2ff057 |
#include <rpm/rpmlog.h>
|
|
|
2ff057 |
#include <rpm/rpmurl.h>
|
|
|
2ff057 |
#include <rpm/rpmfileutil.h>
|
|
|
2ff057 |
#include <rpm/rpmbase64.h>
|
|
|
2ff057 |
#include "rpmio/rpmhook.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#define _RPMLUA_INTERNAL
|
|
|
2ff057 |
#include "rpmio/rpmlua.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#include "debug.h"
|
|
|
2ff057 |
|
|
|
2ff057 |
#define INITSTATE(_lua, lua) \
|
|
|
2ff057 |
rpmlua lua = _lua ? _lua : \
|
|
|
2ff057 |
(globalLuaState ? globalLuaState : \
|
|
|
2ff057 |
\
|
|
|
2ff057 |
(globalLuaState = rpmluaNew()) \
|
|
|
2ff057 |
\
|
|
|
2ff057 |
)
|
|
|
2ff057 |
|
|
|
2ff057 |
struct rpmluapb_s {
|
|
|
2ff057 |
size_t alloced;
|
|
|
2ff057 |
size_t used;
|
|
|
2ff057 |
char *buf;
|
|
|
2ff057 |
rpmluapb next;
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static rpmlua globalLuaState = NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
static char *(*nextFileFunc)(void *) = NULL;
|
|
|
2ff057 |
static void *nextFileFuncParam = NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
static int luaopen_rpm(lua_State *L);
|
|
|
2ff057 |
static int rpm_print(lua_State *L);
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmlua rpmluaGetGlobalState(void)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(NULL, lua);
|
|
|
2ff057 |
return lua;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmlua rpmluaNew()
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmlua lua = (rpmlua) xcalloc(1, sizeof(*lua));
|
|
|
2ff057 |
struct stat st;
|
|
|
2ff057 |
const luaL_Reg *lib;
|
|
|
2ff057 |
char *initlua = rpmGenPath(rpmConfigDir(), "init.lua", NULL);
|
|
|
2ff057 |
|
|
|
2ff057 |
static const luaL_Reg extlibs[] = {
|
|
|
2ff057 |
{"posix", luaopen_posix},
|
|
|
2ff057 |
{"rex", luaopen_rex},
|
|
|
2ff057 |
{"rpm", luaopen_rpm},
|
|
|
2ff057 |
{"os", luaopen_rpm_os},
|
|
|
2ff057 |
{NULL, NULL},
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
lua_State *L = lua_open();
|
|
|
2ff057 |
luaL_openlibs(L);
|
|
|
2ff057 |
lua->L = L;
|
|
|
2ff057 |
|
|
|
2ff057 |
for (lib = extlibs; lib->name; lib++) {
|
|
|
2ff057 |
lua_pushcfunction(L, lib->func);
|
|
|
2ff057 |
lua_pushstring(L, lib->name);
|
|
|
2ff057 |
lua_call(L, 1, 0);
|
|
|
2ff057 |
lua_settop(L, 0);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
#ifndef LUA_GLOBALSINDEX
|
|
|
2ff057 |
lua_pushglobaltable(L);
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
lua_pushliteral(L, "LUA_PATH");
|
|
|
2ff057 |
lua_pushfstring(L, "%s/%s", rpmConfigDir(), "/lua/?.lua");
|
|
|
2ff057 |
#ifdef LUA_GLOBALSINDEX
|
|
|
2ff057 |
lua_rawset(L, LUA_GLOBALSINDEX);
|
|
|
2ff057 |
#else
|
|
|
2ff057 |
lua_settable(L, -3);
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
lua_pushliteral(L, "print");
|
|
|
2ff057 |
lua_pushcfunction(L, rpm_print);
|
|
|
2ff057 |
#ifdef LUA_GLOBALSINDEX
|
|
|
2ff057 |
lua_rawset(L, LUA_GLOBALSINDEX);
|
|
|
2ff057 |
#else
|
|
|
2ff057 |
lua_settable(L, -3);
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
#ifndef LUA_GLOBALSINDEX
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
#endif
|
|
|
2ff057 |
rpmluaSetData(lua, "lua", lua);
|
|
|
2ff057 |
if (stat(initlua, &st) != -1)
|
|
|
2ff057 |
(void)rpmluaRunScriptFile(lua, initlua);
|
|
|
2ff057 |
free(initlua);
|
|
|
2ff057 |
return lua;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmlua rpmluaFree(rpmlua lua)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (lua) {
|
|
|
2ff057 |
if (lua->L) lua_close(lua->L);
|
|
|
2ff057 |
free(lua->printbuf);
|
|
|
2ff057 |
free(lua);
|
|
|
2ff057 |
if (lua == globalLuaState) globalLuaState = NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaSetData(rpmlua _lua, const char *key, const void *data)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
lua_pushliteral(L, "rpm_");
|
|
|
2ff057 |
lua_pushstring(L, key);
|
|
|
2ff057 |
lua_concat(L, 2);
|
|
|
2ff057 |
if (data == NULL)
|
|
|
2ff057 |
lua_pushnil(L);
|
|
|
2ff057 |
else
|
|
|
2ff057 |
lua_pushlightuserdata(L, (void *)data);
|
|
|
2ff057 |
lua_rawset(L, LUA_REGISTRYINDEX);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void *getdata(lua_State *L, const char *key)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
void *ret = NULL;
|
|
|
2ff057 |
lua_pushliteral(L, "rpm_");
|
|
|
2ff057 |
lua_pushstring(L, key);
|
|
|
2ff057 |
lua_concat(L, 2);
|
|
|
2ff057 |
lua_rawget(L, LUA_REGISTRYINDEX);
|
|
|
2ff057 |
if (lua_islightuserdata(L, -1))
|
|
|
2ff057 |
ret = lua_touserdata(L, -1);
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void *rpmluaGetData(rpmlua _lua, const char *key)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
return getdata(lua->L, key);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaPushPrintBuffer(rpmlua _lua)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
rpmluapb prbuf = xcalloc(1, sizeof(*prbuf));
|
|
|
2ff057 |
prbuf->buf = NULL;
|
|
|
2ff057 |
prbuf->alloced = 0;
|
|
|
2ff057 |
prbuf->used = 0;
|
|
|
2ff057 |
prbuf->next = lua->printbuf;
|
|
|
2ff057 |
|
|
|
2ff057 |
lua->printbuf = prbuf;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
char *rpmluaPopPrintBuffer(rpmlua _lua)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
rpmluapb prbuf = lua->printbuf;
|
|
|
2ff057 |
char *ret = NULL;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (prbuf) {
|
|
|
2ff057 |
ret = prbuf->buf;
|
|
|
2ff057 |
lua->printbuf = prbuf->next;
|
|
|
2ff057 |
free(prbuf);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int pushvar(lua_State *L, rpmluavType type, void *value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
switch (type) {
|
|
|
2ff057 |
case RPMLUAV_NIL:
|
|
|
2ff057 |
lua_pushnil(L);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMLUAV_STRING:
|
|
|
2ff057 |
lua_pushstring(L, *((char **)value));
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMLUAV_NUMBER:
|
|
|
2ff057 |
lua_pushnumber(L, *((double *)value));
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaSetNextFileFunc(char *(*func)(void *), void *funcParam)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
nextFileFunc = func;
|
|
|
2ff057 |
nextFileFuncParam = funcParam;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaSetVar(rpmlua _lua, rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
if (var->listmode && lua->pushsize > 0) {
|
|
|
2ff057 |
if (var->keyType != RPMLUAV_NUMBER || var->key.num == (double)0) {
|
|
|
2ff057 |
var->keyType = RPMLUAV_NUMBER;
|
|
|
2ff057 |
var->key.num = (double) luaL_getn(L, -1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
var->key.num++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (!var->listmode || lua->pushsize > 0) {
|
|
|
2ff057 |
if (lua->pushsize == 0)
|
|
|
2ff057 |
lua_pushglobaltable(L);
|
|
|
2ff057 |
if (pushvar(L, var->keyType, &var->key) != -1) {
|
|
|
2ff057 |
if (pushvar(L, var->valueType, &var->value) != -1)
|
|
|
2ff057 |
lua_rawset(L, -3);
|
|
|
2ff057 |
else
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (lua->pushsize == 0)
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static void popvar(lua_State *L, rpmluavType *type, void *value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
switch (lua_type(L, -1)) {
|
|
|
2ff057 |
case LUA_TSTRING:
|
|
|
2ff057 |
*type = RPMLUAV_STRING;
|
|
|
2ff057 |
*((const char **)value) = lua_tostring(L, -1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case LUA_TNUMBER:
|
|
|
2ff057 |
*type = RPMLUAV_NUMBER;
|
|
|
2ff057 |
*((double *)value) = lua_tonumber(L, -1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
*type = RPMLUAV_NIL;
|
|
|
2ff057 |
*((void **)value) = NULL;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaGetVar(rpmlua _lua, rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
if (!var->listmode) {
|
|
|
2ff057 |
if (lua->pushsize == 0)
|
|
|
2ff057 |
lua_pushglobaltable(L);
|
|
|
2ff057 |
if (pushvar(L, var->keyType, &var->key) != -1) {
|
|
|
2ff057 |
lua_rawget(L, -2);
|
|
|
2ff057 |
popvar(L, &var->valueType, &var->value);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (lua->pushsize == 0)
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
} else if (lua->pushsize > 0) {
|
|
|
2ff057 |
(void) pushvar(L, var->keyType, &var->key);
|
|
|
2ff057 |
if (lua_next(L, -2) != 0)
|
|
|
2ff057 |
popvar(L, &var->valueType, &var->value);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
#define FINDKEY_RETURN 0
|
|
|
2ff057 |
#define FINDKEY_CREATE 1
|
|
|
2ff057 |
#define FINDKEY_REMOVE 2
|
|
|
2ff057 |
static int findkey(lua_State *L, int oper, const char *key, va_list va)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
char *buf;
|
|
|
2ff057 |
const char *s, *e;
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
int blen;
|
|
|
2ff057 |
|
|
|
2ff057 |
blen = vsnprintf(NULL, 0, key, va);
|
|
|
2ff057 |
if (blen <= 0) {
|
|
|
2ff057 |
return -1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
buf = xmalloc(blen + 1);
|
|
|
2ff057 |
vsnprintf(buf, blen + 1, key, va);
|
|
|
2ff057 |
|
|
|
2ff057 |
s = e = buf;
|
|
|
2ff057 |
lua_pushglobaltable(L);
|
|
|
2ff057 |
for (;;) {
|
|
|
2ff057 |
if (*e == '\0' || *e == '.') {
|
|
|
2ff057 |
if (e != s) {
|
|
|
2ff057 |
lua_pushlstring(L, s, e-s);
|
|
|
2ff057 |
switch (oper) {
|
|
|
2ff057 |
case FINDKEY_REMOVE:
|
|
|
2ff057 |
if (*e == '\0') {
|
|
|
2ff057 |
lua_pushnil(L);
|
|
|
2ff057 |
lua_rawset(L, -3);
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
case FINDKEY_RETURN:
|
|
|
2ff057 |
lua_rawget(L, -2);
|
|
|
2ff057 |
lua_remove(L, -2);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case FINDKEY_CREATE:
|
|
|
2ff057 |
lua_rawget(L, -2);
|
|
|
2ff057 |
if (!lua_istable(L, -1)) {
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
lua_newtable(L);
|
|
|
2ff057 |
lua_pushlstring(L, s, e-s);
|
|
|
2ff057 |
lua_pushvalue(L, -2);
|
|
|
2ff057 |
lua_rawset(L, -4);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
lua_remove(L, -2);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (*e == '\0')
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
if (!lua_istable(L, -1)) {
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
s = e+1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
e++;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
free(buf);
|
|
|
2ff057 |
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaDelVar(rpmlua _lua, const char *key, ...)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
va_list va;
|
|
|
2ff057 |
va_start(va, key);
|
|
|
2ff057 |
(void) findkey(lua->L, FINDKEY_REMOVE, key, va);
|
|
|
2ff057 |
va_end(va);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmluaVarExists(rpmlua _lua, const char *key, ...)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
va_list va;
|
|
|
2ff057 |
va_start(va, key);
|
|
|
2ff057 |
if (findkey(L, FINDKEY_RETURN, key, va) == 0) {
|
|
|
2ff057 |
if (!lua_isnil(L, -1))
|
|
|
2ff057 |
ret = 1;
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
va_end(va);
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaPushTable(rpmlua _lua, const char *key, ...)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
va_list va;
|
|
|
2ff057 |
va_start(va, key);
|
|
|
2ff057 |
(void) findkey(lua->L, FINDKEY_CREATE, key, va);
|
|
|
2ff057 |
lua->pushsize++;
|
|
|
2ff057 |
va_end(va);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaPop(rpmlua _lua)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
assert(lua->pushsize > 0);
|
|
|
2ff057 |
lua->pushsize--;
|
|
|
2ff057 |
lua_pop(lua->L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmluav rpmluavNew(void)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmluav var = (rpmluav) xcalloc(1, sizeof(*var));
|
|
|
2ff057 |
return var;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
rpmluav rpmluavFree(rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
free(var);
|
|
|
2ff057 |
return NULL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavSetListMode(rpmluav var, int flag)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
var->listmode = flag;
|
|
|
2ff057 |
var->keyType = RPMLUAV_NIL;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavSetKey(rpmluav var, rpmluavType type, const void *value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
var->keyType = type;
|
|
|
2ff057 |
switch (type) {
|
|
|
2ff057 |
case RPMLUAV_NUMBER:
|
|
|
2ff057 |
var->key.num = *((double *)value);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMLUAV_STRING:
|
|
|
2ff057 |
var->key.str = (char *)value;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
var->valueType = type;
|
|
|
2ff057 |
switch (type) {
|
|
|
2ff057 |
case RPMLUAV_NUMBER:
|
|
|
2ff057 |
var->value.num = *((const double *)value);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMLUAV_STRING:
|
|
|
2ff057 |
var->value.str = (const char *)value;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavGetKey(rpmluav var, rpmluavType *type, void **value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
*type = var->keyType;
|
|
|
2ff057 |
switch (var->keyType) {
|
|
|
2ff057 |
case RPMLUAV_NUMBER:
|
|
|
2ff057 |
*((double **)value) = &var->key.num;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMLUAV_STRING:
|
|
|
2ff057 |
*((const char **)value) = var->key.str;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavGetValue(rpmluav var, rpmluavType *type, void **value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
*type = var->valueType;
|
|
|
2ff057 |
switch (var->valueType) {
|
|
|
2ff057 |
case RPMLUAV_NUMBER:
|
|
|
2ff057 |
*((double **)value) = &var->value.num;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case RPMLUAV_STRING:
|
|
|
2ff057 |
*((const char **)value) = var->value.str;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavSetKeyNum(rpmluav var, double value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmluavSetKey(var, RPMLUAV_NUMBER, &value);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluavSetValueNum(rpmluav var, double value)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmluavSetValue(var, RPMLUAV_NUMBER, &value);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
double rpmluavGetKeyNum(rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmluavType type;
|
|
|
2ff057 |
void *value;
|
|
|
2ff057 |
rpmluavGetKey(var, &type, &value);
|
|
|
2ff057 |
if (type == RPMLUAV_NUMBER)
|
|
|
2ff057 |
return *((double *)value);
|
|
|
2ff057 |
return (double) 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
double rpmluavGetValueNum(rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmluavType type;
|
|
|
2ff057 |
void *value;
|
|
|
2ff057 |
rpmluavGetValue(var, &type, &value);
|
|
|
2ff057 |
if (type == RPMLUAV_NUMBER)
|
|
|
2ff057 |
return *((double *)value);
|
|
|
2ff057 |
return (double) 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmluavKeyIsNum(rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (var->keyType == RPMLUAV_NUMBER) ? 1 : 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmluavValueIsNum(rpmluav var)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
return (var->valueType == RPMLUAV_NUMBER) ? 1 : 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmluaCheckScript(rpmlua _lua, const char *script, const char *name)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
if (name == NULL)
|
|
|
2ff057 |
name = "<lua>";
|
|
|
2ff057 |
if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR,
|
|
|
2ff057 |
_("invalid syntax in lua scriptlet: %s\n"),
|
|
|
2ff057 |
lua_tostring(L, -1));
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
lua_pop(L, 1); /* Error or chunk. */
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmluaRunScript(rpmlua _lua, const char *script, const char *name)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
if (name == NULL)
|
|
|
2ff057 |
name = "<lua>";
|
|
|
2ff057 |
if (script == NULL)
|
|
|
2ff057 |
script = "";
|
|
|
2ff057 |
if (luaL_loadbuffer(L, script, strlen(script), name) != 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("invalid syntax in lua script: %s\n"),
|
|
|
2ff057 |
lua_tostring(L, -1));
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
} else if (lua_pcall(L, 0, 0, 0) != 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("lua script failed: %s\n"),
|
|
|
2ff057 |
lua_tostring(L, -1));
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
int rpmluaRunScriptFile(rpmlua _lua, const char *filename)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
lua_State *L = lua->L;
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
if (luaL_loadfile(L, filename) != 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("invalid syntax in lua file: %s\n"),
|
|
|
2ff057 |
lua_tostring(L, -1));
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
} else if (lua_pcall(L, 0, 0, 0) != 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("lua script failed: %s\n"),
|
|
|
2ff057 |
lua_tostring(L, -1));
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
ret = -1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* From lua.c */
|
|
|
2ff057 |
static int rpmluaReadline(lua_State *L, const char *prompt)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
static char buffer[1024];
|
|
|
2ff057 |
if (prompt) {
|
|
|
2ff057 |
(void) fputs(prompt, stdout);
|
|
|
2ff057 |
(void) fflush(stdout);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
|
|
|
2ff057 |
return 0; /* read fails */
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
lua_pushstring(L, buffer);
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Based on lua.c */
|
|
|
2ff057 |
static void _rpmluaInteractive(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
(void) fputs("\n", stdout);
|
|
|
2ff057 |
printf("RPM Interactive %s Interpreter\n", LUA_VERSION);
|
|
|
2ff057 |
for (;;) {
|
|
|
2ff057 |
int rc = 0;
|
|
|
2ff057 |
|
|
|
2ff057 |
if (rpmluaReadline(L, "> ") == 0)
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
if (lua_tostring(L, -1)[0] == '=') {
|
|
|
2ff057 |
(void) lua_pushfstring(L, "print(%s)", lua_tostring(L, -1)+1);
|
|
|
2ff057 |
lua_remove(L, -2);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
for (;;) {
|
|
|
2ff057 |
rc = luaL_loadbuffer(L, lua_tostring(L, -1),
|
|
|
2ff057 |
lua_strlen(L, -1), "<lua>");
|
|
|
2ff057 |
if (rc == LUA_ERRSYNTAX &&
|
|
|
2ff057 |
strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) {
|
|
|
2ff057 |
if (rpmluaReadline(L, ">> ") == 0)
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
lua_remove(L, -2); /* Remove error */
|
|
|
2ff057 |
lua_concat(L, 2);
|
|
|
2ff057 |
continue;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (rc == 0)
|
|
|
2ff057 |
rc = lua_pcall(L, 0, 0, 0);
|
|
|
2ff057 |
if (rc != 0) {
|
|
|
2ff057 |
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
lua_pop(L, 1); /* Remove line */
|
|
|
2ff057 |
}
|
|
|
2ff057 |
(void) fputs("\n", stdout);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
void rpmluaInteractive(rpmlua _lua)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
INITSTATE(_lua, lua);
|
|
|
2ff057 |
_rpmluaInteractive(lua->L);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* ------------------------------------------------------------------ */
|
|
|
2ff057 |
/* Lua API */
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_b64encode(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const char *str = luaL_checkstring(L, 1);
|
|
|
2ff057 |
size_t len = lua_strlen(L, 1);
|
|
|
2ff057 |
int linelen = -1;
|
|
|
2ff057 |
if (lua_gettop(L) == 2)
|
|
|
2ff057 |
linelen = luaL_checkinteger(L, 2);
|
|
|
2ff057 |
if (str && len) {
|
|
|
2ff057 |
char *data = rpmBase64Encode(str, len, linelen);
|
|
|
2ff057 |
lua_pushstring(L, data);
|
|
|
2ff057 |
free(data);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_b64decode(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const char *str = luaL_checkstring(L, 1);
|
|
|
2ff057 |
if (str) {
|
|
|
2ff057 |
void *data = NULL;
|
|
|
2ff057 |
size_t len = 0;
|
|
|
2ff057 |
if (rpmBase64Decode(str, &data, &len) == 0) {
|
|
|
2ff057 |
lua_pushlstring(L, data, len);
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
lua_pushnil(L);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
free(data);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_expand(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const char *str = luaL_checkstring(L, 1);
|
|
|
2ff057 |
char *val = NULL;
|
|
|
2ff057 |
if (rpmExpandMacros(NULL, str, &val, 0) < 0)
|
|
|
2ff057 |
return luaL_error(L, "error expanding macro");
|
|
|
2ff057 |
lua_pushstring(L, val);
|
|
|
2ff057 |
free(val);
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_define(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const char *str = luaL_checkstring(L, 1);
|
|
|
2ff057 |
if (rpmDefineMacro(NULL, str, 0))
|
|
|
2ff057 |
return luaL_error(L, "error defining macro");
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_undefine(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const char *str = luaL_checkstring(L, 1);
|
|
|
2ff057 |
rpmPopMacro(NULL, str);
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_load(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
const char *str = luaL_checkstring(L, 1);
|
|
|
2ff057 |
int rc = rpmLoadMacroFile(NULL, str);
|
|
|
2ff057 |
lua_pushnumber(L, rc);
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_interactive(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
_rpmluaInteractive(L);
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_next_file(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (nextFileFunc)
|
|
|
2ff057 |
lua_pushstring(L, nextFileFunc(nextFileFuncParam));
|
|
|
2ff057 |
else
|
|
|
2ff057 |
lua_pushstring(L, NULL);
|
|
|
2ff057 |
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
typedef struct rpmluaHookData_s {
|
|
|
2ff057 |
lua_State *L;
|
|
|
2ff057 |
int funcRef;
|
|
|
2ff057 |
int dataRef;
|
|
|
2ff057 |
} * rpmluaHookData;
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpmluaHookWrapper(rpmhookArgs args, void *data)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmluaHookData hookdata = (rpmluaHookData)data;
|
|
|
2ff057 |
lua_State *L = hookdata->L;
|
|
|
2ff057 |
int ret = 0;
|
|
|
2ff057 |
int i;
|
|
|
2ff057 |
lua_rawgeti(L, LUA_REGISTRYINDEX, hookdata->funcRef);
|
|
|
2ff057 |
lua_newtable(L);
|
|
|
2ff057 |
for (i = 0; i != args->argc; i++) {
|
|
|
2ff057 |
switch (args->argt[i]) {
|
|
|
2ff057 |
case 's':
|
|
|
2ff057 |
lua_pushstring(L, args->argv[i].s);
|
|
|
2ff057 |
lua_rawseti(L, -2, i+1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 'i':
|
|
|
2ff057 |
lua_pushnumber(L, (lua_Number)args->argv[i].i);
|
|
|
2ff057 |
lua_rawseti(L, -2, i+1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 'f':
|
|
|
2ff057 |
lua_pushnumber(L, (lua_Number)args->argv[i].f);
|
|
|
2ff057 |
lua_rawseti(L, -2, i+1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case 'p':
|
|
|
2ff057 |
lua_pushlightuserdata(L, args->argv[i].p);
|
|
|
2ff057 |
lua_rawseti(L, -2, i+1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
(void) luaL_error(L, "unsupported type '%c' as "
|
|
|
2ff057 |
"a hook argument\n", args->argt[i]);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (lua_pcall(L, 1, 1, 0) != 0) {
|
|
|
2ff057 |
rpmlog(RPMLOG_ERR, _("lua hook failed: %s\n"),
|
|
|
2ff057 |
lua_tostring(L, -1));
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
if (lua_isnumber(L, -1))
|
|
|
2ff057 |
ret = (int)lua_tonumber(L, -1);
|
|
|
2ff057 |
lua_pop(L, 1);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return ret;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_register(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (!lua_isstring(L, 1)) {
|
|
|
2ff057 |
(void) luaL_argerror(L, 1, "hook name expected");
|
|
|
2ff057 |
} else if (!lua_isfunction(L, 2)) {
|
|
|
2ff057 |
(void) luaL_argerror(L, 2, "function expected");
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rpmluaHookData hookdata =
|
|
|
2ff057 |
lua_newuserdata(L, sizeof(struct rpmluaHookData_s));
|
|
|
2ff057 |
lua_pushvalue(L, -1);
|
|
|
2ff057 |
hookdata->dataRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
2ff057 |
lua_pushvalue(L, 2);
|
|
|
2ff057 |
hookdata->funcRef = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
2ff057 |
hookdata->L = L;
|
|
|
2ff057 |
rpmhookRegister(lua_tostring(L, 1), rpmluaHookWrapper, hookdata);
|
|
|
2ff057 |
return 1;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_unregister(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (!lua_isstring(L, 1)) {
|
|
|
2ff057 |
(void) luaL_argerror(L, 1, "hook name expected");
|
|
|
2ff057 |
} else if (!lua_isuserdata(L, 2)) {
|
|
|
2ff057 |
(void) luaL_argerror(L, 2, "hook information expected");
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rpmluaHookData hookdata = (rpmluaHookData)lua_touserdata(L, 2);
|
|
|
2ff057 |
luaL_unref(L, LUA_REGISTRYINDEX, hookdata->funcRef);
|
|
|
2ff057 |
luaL_unref(L, LUA_REGISTRYINDEX, hookdata->dataRef);
|
|
|
2ff057 |
rpmhookUnregister(lua_tostring(L, 1), rpmluaHookWrapper, hookdata);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static int rpm_call(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
if (!lua_isstring(L, 1)) {
|
|
|
2ff057 |
(void) luaL_argerror(L, 1, "hook name expected");
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rpmhookArgs args = rpmhookArgsNew(lua_gettop(L)-1);
|
|
|
2ff057 |
const char *name = lua_tostring(L, 1);
|
|
|
2ff057 |
char *argt = (char *)xmalloc(args->argc+1);
|
|
|
2ff057 |
int i;
|
|
|
2ff057 |
for (i = 0; i != args->argc; i++) {
|
|
|
2ff057 |
switch (lua_type(L, i+1)) {
|
|
|
2ff057 |
case LUA_TNIL:
|
|
|
2ff057 |
argt[i] = 'p';
|
|
|
2ff057 |
args->argv[i].p = NULL;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case LUA_TNUMBER: {
|
|
|
2ff057 |
float f = (float)lua_tonumber(L, i+1);
|
|
|
2ff057 |
if (f == (int)f) {
|
|
|
2ff057 |
argt[i] = 'i';
|
|
|
2ff057 |
args->argv[i].i = (int)f;
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
argt[i] = 'f';
|
|
|
2ff057 |
args->argv[i].f = f;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
} break;
|
|
|
2ff057 |
case LUA_TSTRING:
|
|
|
2ff057 |
argt[i] = 's';
|
|
|
2ff057 |
args->argv[i].s = lua_tostring(L, i+1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
case LUA_TUSERDATA:
|
|
|
2ff057 |
case LUA_TLIGHTUSERDATA:
|
|
|
2ff057 |
argt[i] = 'p';
|
|
|
2ff057 |
args->argv[i].p = lua_touserdata(L, i+1);
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
default:
|
|
|
2ff057 |
(void) luaL_error(L, "unsupported Lua type passed to hook");
|
|
|
2ff057 |
argt[i] = 'p';
|
|
|
2ff057 |
args->argv[i].p = NULL;
|
|
|
2ff057 |
break;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
}
|
|
|
2ff057 |
args->argt = argt;
|
|
|
2ff057 |
rpmhookCallArgs(name, args);
|
|
|
2ff057 |
free(argt);
|
|
|
2ff057 |
(void) rpmhookArgsFree(args);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
/* Based on luaB_print. */
|
|
|
2ff057 |
static int rpm_print (lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
rpmlua lua = (rpmlua)getdata(L, "lua");
|
|
|
2ff057 |
int n = lua_gettop(L); /* number of arguments */
|
|
|
2ff057 |
int i;
|
|
|
2ff057 |
if (!lua) return 0;
|
|
|
2ff057 |
lua_getglobal(L, "tostring");
|
|
|
2ff057 |
for (i = 1; i <= n; i++) {
|
|
|
2ff057 |
const char *s;
|
|
|
2ff057 |
lua_pushvalue(L, -1); /* function to be called */
|
|
|
2ff057 |
lua_pushvalue(L, i); /* value to print */
|
|
|
2ff057 |
lua_call(L, 1, 1);
|
|
|
2ff057 |
s = lua_tostring(L, -1); /* get result */
|
|
|
2ff057 |
if (s == NULL)
|
|
|
2ff057 |
return luaL_error(L, "`tostring' must return a string to `print'");
|
|
|
2ff057 |
if (lua->printbuf) {
|
|
|
2ff057 |
rpmluapb prbuf = lua->printbuf;
|
|
|
2ff057 |
int sl = lua_strlen(L, -1);
|
|
|
2ff057 |
if (prbuf->used+sl+1 > prbuf->alloced) {
|
|
|
2ff057 |
prbuf->alloced += sl+512;
|
|
|
2ff057 |
prbuf->buf = xrealloc(prbuf->buf, prbuf->alloced);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (i > 1)
|
|
|
2ff057 |
prbuf->buf[prbuf->used++] = '\t';
|
|
|
2ff057 |
memcpy(prbuf->buf+prbuf->used, s, sl+1);
|
|
|
2ff057 |
prbuf->used += sl;
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
if (i > 1)
|
|
|
2ff057 |
(void) fputs("\t", stdout);
|
|
|
2ff057 |
(void) fputs(s, stdout);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
lua_pop(L, 1); /* pop result */
|
|
|
2ff057 |
}
|
|
|
2ff057 |
if (!lua->printbuf) {
|
|
|
2ff057 |
(void) fputs("\n", stdout);
|
|
|
2ff057 |
} else {
|
|
|
2ff057 |
rpmluapb prbuf = lua->printbuf;
|
|
|
2ff057 |
if (prbuf->used+1 > prbuf->alloced) {
|
|
|
2ff057 |
prbuf->alloced += 512;
|
|
|
2ff057 |
prbuf->buf = xrealloc(prbuf->buf, prbuf->alloced);
|
|
|
2ff057 |
}
|
|
|
2ff057 |
prbuf->buf[prbuf->used] = '\0';
|
|
|
2ff057 |
}
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
|
|
|
2ff057 |
static const luaL_Reg rpmlib[] = {
|
|
|
2ff057 |
{"b64encode", rpm_b64encode},
|
|
|
2ff057 |
{"b64decode", rpm_b64decode},
|
|
|
2ff057 |
{"expand", rpm_expand},
|
|
|
2ff057 |
{"define", rpm_define},
|
|
|
2ff057 |
{"undefine", rpm_undefine},
|
|
|
2ff057 |
{"load", rpm_load},
|
|
|
2ff057 |
{"register", rpm_register},
|
|
|
2ff057 |
{"unregister", rpm_unregister},
|
|
|
2ff057 |
{"call", rpm_call},
|
|
|
2ff057 |
{"interactive", rpm_interactive},
|
|
|
2ff057 |
{"next_file", rpm_next_file},
|
|
|
2ff057 |
{NULL, NULL}
|
|
|
2ff057 |
};
|
|
|
2ff057 |
|
|
|
2ff057 |
static int luaopen_rpm(lua_State *L)
|
|
|
2ff057 |
{
|
|
|
2ff057 |
lua_pushglobaltable(L);
|
|
|
2ff057 |
luaL_openlib(L, "rpm", rpmlib, 0);
|
|
|
2ff057 |
return 0;
|
|
|
2ff057 |
}
|
|
|
2ff057 |
#endif /* WITH_LUA */
|
|
|
2ff057 |
|