Add support for nested Lua macro expansion (RhBug:490740)

- Lift the printbuffer accounting out of rpmlua into a struct of
  its own (Funny thing, this looks a whole lot like the macro
  expansion buffer and Good Ole StringBuf Brothers ... Boys ... Mam.
  Unify them one of these days maybe)
- Replace the simplistic on/off printbuffer with a stack of buffers,
  fixup the lone caller to use the new internal push/pop API.
This commit is contained in:
Panu Matilainen 2011-05-24 20:28:16 +03:00
parent 48b5879931
commit ecfece7ec0
3 changed files with 49 additions and 30 deletions

View File

@ -1228,17 +1228,17 @@ expandMacro(MacroBuf mb, const char *src, size_t slen)
const char *ls = s+sizeof("{lua:")-1; const char *ls = s+sizeof("{lua:")-1;
const char *lse = se-sizeof("}")+1; const char *lse = se-sizeof("}")+1;
char *scriptbuf = (char *)xmalloc((lse-ls)+1); char *scriptbuf = (char *)xmalloc((lse-ls)+1);
const char *printbuf; char *printbuf;
memcpy(scriptbuf, ls, lse-ls); memcpy(scriptbuf, ls, lse-ls);
scriptbuf[lse-ls] = '\0'; scriptbuf[lse-ls] = '\0';
rpmluaSetPrintBuffer(lua, 1); rpmluaPushPrintBuffer(lua);
if (rpmluaRunScript(lua, scriptbuf, NULL) == -1) if (rpmluaRunScript(lua, scriptbuf, NULL) == -1)
rc = 1; rc = 1;
printbuf = rpmluaGetPrintBuffer(lua); printbuf = rpmluaPopPrintBuffer(lua);
if (printbuf) { if (printbuf) {
mbAppendStr(mb, printbuf); mbAppendStr(mb, printbuf);
free(printbuf);
} }
rpmluaSetPrintBuffer(lua, 0);
free(scriptbuf); free(scriptbuf);
s = se; s = se;
continue; continue;

View File

@ -31,6 +31,13 @@
\ \
) )
struct rpmluapb_s {
size_t alloced;
size_t used;
char *buf;
rpmluapb next;
};
static rpmlua globalLuaState = NULL; static rpmlua globalLuaState = NULL;
static int luaopen_rpm(lua_State *L); static int luaopen_rpm(lua_State *L);
@ -124,20 +131,31 @@ void *rpmluaGetData(rpmlua _lua, const char *key)
return getdata(lua->L, key); return getdata(lua->L, key);
} }
void rpmluaSetPrintBuffer(rpmlua _lua, int flag) void rpmluaPushPrintBuffer(rpmlua _lua)
{ {
INITSTATE(_lua, lua); INITSTATE(_lua, lua);
lua->storeprint = flag; rpmluapb prbuf = xcalloc(1, sizeof(*prbuf));
free(lua->printbuf); prbuf->buf = NULL;
lua->printbuf = NULL; prbuf->alloced = 0;
lua->printbufsize = 0; prbuf->used = 0;
lua->printbufused = 0; prbuf->next = lua->printbuf;
lua->printbuf = prbuf;
} }
const char *rpmluaGetPrintBuffer(rpmlua _lua) char *rpmluaPopPrintBuffer(rpmlua _lua)
{ {
INITSTATE(_lua, lua); INITSTATE(_lua, lua);
return lua->printbuf; rpmluapb prbuf = lua->printbuf;
char *ret = NULL;
if (prbuf) {
ret = prbuf->buf;
lua->printbuf = prbuf->next;
free(prbuf);
}
return ret;
} }
static int pushvar(lua_State *L, rpmluavType type, void *value) static int pushvar(lua_State *L, rpmluavType type, void *value)
@ -773,16 +791,17 @@ static int rpm_print (lua_State *L)
s = lua_tostring(L, -1); /* get result */ s = lua_tostring(L, -1); /* get result */
if (s == NULL) if (s == NULL)
return luaL_error(L, "`tostring' must return a string to `print'"); return luaL_error(L, "`tostring' must return a string to `print'");
if (lua->storeprint) { if (lua->printbuf) {
rpmluapb prbuf = lua->printbuf;
int sl = lua_strlen(L, -1); int sl = lua_strlen(L, -1);
if (lua->printbufused+sl+1 > lua->printbufsize) { if (prbuf->used+sl+1 > prbuf->alloced) {
lua->printbufsize += sl+512; prbuf->alloced += sl+512;
lua->printbuf = xrealloc(lua->printbuf, lua->printbufsize); prbuf->buf = xrealloc(prbuf->buf, prbuf->alloced);
} }
if (i > 1) if (i > 1)
lua->printbuf[lua->printbufused++] = '\t'; prbuf->buf[prbuf->used++] = '\t';
memcpy(lua->printbuf+lua->printbufused, s, sl+1); memcpy(prbuf->buf+prbuf->used, s, sl+1);
lua->printbufused += sl; prbuf->used += sl;
} else { } else {
if (i > 1) if (i > 1)
(void) fputs("\t", stdout); (void) fputs("\t", stdout);
@ -790,14 +809,15 @@ static int rpm_print (lua_State *L)
} }
lua_pop(L, 1); /* pop result */ lua_pop(L, 1); /* pop result */
} }
if (!lua->storeprint) { if (!lua->printbuf) {
(void) fputs("\n", stdout); (void) fputs("\n", stdout);
} else { } else {
if (lua->printbufused+1 > lua->printbufsize) { rpmluapb prbuf = lua->printbuf;
lua->printbufsize += 512; if (prbuf->used+1 > prbuf->alloced) {
lua->printbuf = xrealloc(lua->printbuf, lua->printbufsize); prbuf->alloced += 512;
prbuf->buf = xrealloc(prbuf->buf, prbuf->alloced);
} }
lua->printbuf[lua->printbufused] = '\0'; prbuf->buf[prbuf->used] = '\0';
} }
return 0; return 0;
} }

View File

@ -12,13 +12,12 @@ typedef enum rpmluavType_e {
#include <stdarg.h> #include <stdarg.h>
#include <lua.h> #include <lua.h>
typedef struct rpmluapb_s * rpmluapb;
struct rpmlua_s { struct rpmlua_s {
lua_State *L; lua_State *L;
size_t pushsize; size_t pushsize;
int storeprint; rpmluapb printbuf;
size_t printbufsize;
size_t printbufused;
char *printbuf;
}; };
struct rpmluav_s { struct rpmluav_s {
@ -60,8 +59,8 @@ void rpmluaInteractive(rpmlua lua);
void *rpmluaGetData(rpmlua lua, const char *key); void *rpmluaGetData(rpmlua lua, const char *key);
void rpmluaSetData(rpmlua lua, const char *key, const void *data); void rpmluaSetData(rpmlua lua, const char *key, const void *data);
const char *rpmluaGetPrintBuffer(rpmlua lua); char *rpmluaPopPrintBuffer(rpmlua lua);
void rpmluaSetPrintBuffer(rpmlua lua, int flag); void rpmluaPushPrintBuffer(rpmlua lua);
void rpmluaGetVar(rpmlua lua, rpmluav var); void rpmluaGetVar(rpmlua lua, rpmluav var);
void rpmluaSetVar(rpmlua lua, rpmluav var); void rpmluaSetVar(rpmlua lua, rpmluav var);