Add support for nested Lua macro expansion (RhBug:490740)
authorPanu Matilainen <pmatilai@redhat.com>
Tue, 24 May 2011 17:28:16 +0000 (20:28 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Tue, 24 May 2011 17:41:38 +0000 (20:41 +0300)
- 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.

rpmio/macro.c
rpmio/rpmlua.c
rpmio/rpmlua.h

index 8de886c..6e085e9 100644 (file)
@@ -1228,17 +1228,17 @@ expandMacro(MacroBuf mb, const char *src, size_t slen)
                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) {
                    mbAppendStr(mb, printbuf);
+                   free(printbuf);
                }
-               rpmluaSetPrintBuffer(lua, 0);
                free(scriptbuf);
                s = se;
                continue;
index 1f9254a..fa8eed3 100644 (file)
                        \
            )
 
+struct rpmluapb_s {
+    size_t alloced;
+    size_t used;
+    char *buf;
+    rpmluapb next;
+};
+
 static rpmlua globalLuaState = NULL;
 
 static int luaopen_rpm(lua_State *L);
@@ -124,20 +131,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)
@@ -773,16 +791,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);
@@ -790,14 +809,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;
 }
index c8a310e..7298ed5 100644 (file)
@@ -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 {
@@ -60,8 +59,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);