commit 861ffb371c66fbb7a041158dab0d7b5b0f7ba8e0 Author: Panu Matilainen 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 #include +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);