182 lines
5.2 KiB
Diff
182 lines
5.2 KiB
Diff
commit 861ffb371c66fbb7a041158dab0d7b5b0f7ba8e0
|
|
Author: Panu Matilainen <pmatilai@redhat.com>
|
|
Date: Fri Mar 23 14:08:21 2018 +0200
|
|
|
|
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.
|
|
|
|
Backported from commit ecfece7ec0d0eb0485745568d10dabc428e92824
|
|
|
|
diff --git a/rpmio/macro.c b/rpmio/macro.c
|
|
index 11e23a3..c150a28 100644
|
|
--- a/rpmio/macro.c
|
|
+++ b/rpmio/macro.c
|
|
@@ -1229,13 +1229,13 @@ expandMacro(MacroBuf mb)
|
|
const char *ls = s+sizeof("{lua:")-1;
|
|
const char *lse = se-sizeof("}")+1;
|
|
char *scriptbuf = (char *)xmalloc((lse-ls)+1);
|
|
- const char *printbuf;
|
|
+ char *printbuf;
|
|
memcpy(scriptbuf, ls, lse-ls);
|
|
scriptbuf[lse-ls] = '\0';
|
|
- rpmluaSetPrintBuffer(lua, 1);
|
|
+ rpmluaPushPrintBuffer(lua);
|
|
if (rpmluaRunScript(lua, scriptbuf, NULL) == -1)
|
|
rc = 1;
|
|
- printbuf = rpmluaGetPrintBuffer(lua);
|
|
+ printbuf = rpmluaPopPrintBuffer(lua);
|
|
if (printbuf) {
|
|
size_t len = strlen(printbuf);
|
|
if (len > mb->nb)
|
|
@@ -1243,8 +1243,8 @@ expandMacro(MacroBuf mb)
|
|
memcpy(mb->t, printbuf, len);
|
|
mb->t += len;
|
|
mb->nb -= len;
|
|
+ free(printbuf);
|
|
}
|
|
- rpmluaSetPrintBuffer(lua, 0);
|
|
free(scriptbuf);
|
|
s = se;
|
|
continue;
|
|
diff --git a/rpmio/rpmlua.c b/rpmio/rpmlua.c
|
|
index bd94eff..c6e8254 100644
|
|
--- a/rpmio/rpmlua.c
|
|
+++ b/rpmio/rpmlua.c
|
|
@@ -31,6 +31,13 @@
|
|
\
|
|
)
|
|
|
|
+struct rpmluapb_s {
|
|
+ size_t alloced;
|
|
+ size_t used;
|
|
+ char *buf;
|
|
+ rpmluapb next;
|
|
+};
|
|
+
|
|
static rpmlua globalLuaState = NULL;
|
|
|
|
static int luaopen_rpm(lua_State *L);
|
|
@@ -123,20 +130,31 @@ void *rpmluaGetData(rpmlua _lua, const char *key)
|
|
return getdata(lua->L, key);
|
|
}
|
|
|
|
-void rpmluaSetPrintBuffer(rpmlua _lua, int flag)
|
|
+void rpmluaPushPrintBuffer(rpmlua _lua)
|
|
{
|
|
INITSTATE(_lua, lua);
|
|
- lua->storeprint = flag;
|
|
- free(lua->printbuf);
|
|
- lua->printbuf = NULL;
|
|
- lua->printbufsize = 0;
|
|
- lua->printbufused = 0;
|
|
+ rpmluapb prbuf = xcalloc(1, sizeof(*prbuf));
|
|
+ prbuf->buf = NULL;
|
|
+ prbuf->alloced = 0;
|
|
+ prbuf->used = 0;
|
|
+ prbuf->next = lua->printbuf;
|
|
+
|
|
+ lua->printbuf = prbuf;
|
|
}
|
|
|
|
-const char *rpmluaGetPrintBuffer(rpmlua _lua)
|
|
+char *rpmluaPopPrintBuffer(rpmlua _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)
|
|
@@ -770,16 +788,17 @@ static int rpm_print (lua_State *L)
|
|
s = lua_tostring(L, -1); /* get result */
|
|
if (s == NULL)
|
|
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);
|
|
- if (lua->printbufused+sl+1 > lua->printbufsize) {
|
|
- lua->printbufsize += sl+512;
|
|
- lua->printbuf = xrealloc(lua->printbuf, lua->printbufsize);
|
|
+ if (prbuf->used+sl+1 > prbuf->alloced) {
|
|
+ prbuf->alloced += sl+512;
|
|
+ prbuf->buf = xrealloc(prbuf->buf, prbuf->alloced);
|
|
}
|
|
if (i > 1)
|
|
- lua->printbuf[lua->printbufused++] = '\t';
|
|
- memcpy(lua->printbuf+lua->printbufused, s, sl+1);
|
|
- lua->printbufused += sl;
|
|
+ prbuf->buf[prbuf->used++] = '\t';
|
|
+ memcpy(prbuf->buf+prbuf->used, s, sl+1);
|
|
+ prbuf->used += sl;
|
|
} else {
|
|
if (i > 1)
|
|
(void) fputs("\t", stdout);
|
|
@@ -787,14 +806,15 @@ static int rpm_print (lua_State *L)
|
|
}
|
|
lua_pop(L, 1); /* pop result */
|
|
}
|
|
- if (!lua->storeprint) {
|
|
+ if (!lua->printbuf) {
|
|
(void) fputs("\n", stdout);
|
|
} else {
|
|
- if (lua->printbufused+1 > lua->printbufsize) {
|
|
- lua->printbufsize += 512;
|
|
- lua->printbuf = xrealloc(lua->printbuf, lua->printbufsize);
|
|
+ rpmluapb prbuf = lua->printbuf;
|
|
+ if (prbuf->used+1 > prbuf->alloced) {
|
|
+ prbuf->alloced += 512;
|
|
+ prbuf->buf = xrealloc(prbuf->buf, prbuf->alloced);
|
|
}
|
|
- lua->printbuf[lua->printbufused] = '\0';
|
|
+ prbuf->buf[prbuf->used] = '\0';
|
|
}
|
|
return 0;
|
|
}
|
|
diff --git a/rpmio/rpmlua.h b/rpmio/rpmlua.h
|
|
index 12b0fa1..ab6bd3c 100644
|
|
--- a/rpmio/rpmlua.h
|
|
+++ b/rpmio/rpmlua.h
|
|
@@ -12,13 +12,12 @@ typedef enum rpmluavType_e {
|
|
#include <stdarg.h>
|
|
#include <lua.h>
|
|
|
|
+typedef struct rpmluapb_s * rpmluapb;
|
|
+
|
|
struct rpmlua_s {
|
|
lua_State *L;
|
|
size_t pushsize;
|
|
- int storeprint;
|
|
- size_t printbufsize;
|
|
- size_t printbufused;
|
|
- char *printbuf;
|
|
+ rpmluapb printbuf;
|
|
};
|
|
|
|
struct rpmluav_s {
|
|
@@ -56,8 +55,8 @@ void rpmluaInteractive(rpmlua lua);
|
|
void *rpmluaGetData(rpmlua lua, const char *key);
|
|
void rpmluaSetData(rpmlua lua, const char *key, const void *data);
|
|
|
|
-const char *rpmluaGetPrintBuffer(rpmlua lua);
|
|
-void rpmluaSetPrintBuffer(rpmlua lua, int flag);
|
|
+char *rpmluaPopPrintBuffer(rpmlua lua);
|
|
+void rpmluaPushPrintBuffer(rpmlua lua);
|
|
|
|
void rpmluaGetVar(rpmlua lua, rpmluav var);
|
|
void rpmluaSetVar(rpmlua lua, rpmluav var);
|