lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> Hi. I tried this with my build of Lua 5.1.4 which has api_check enabled 
> and it asserts in function 'doconcat' at the first lua_rawgeti. It seems 
> that it cannot grow the stack

Sorry, I messed up the stack counts and also forgot a couple of lua_pop...
Here is the corrected version.
Thanks for spotting this.
--lhf
/*
* lrope.c
* provides unrope
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
* 05 Dec 2008 15:43:32
* This code is hereby placed in the public domain.
*/

#include "lua.h"
#include "lauxlib.h"

#define MAXLEVEL 30

static int doconcat (lua_State *L, luaL_Buffer *b, int t, int needsep) {
  int i;
  if (t>MAXLEVEL+1) luaL_error(L,"table too deep for "LUA_QL("unrope"));
  for (i=1;; i++)
  {
    lua_rawgeti(L,t,i);
    switch (lua_type(L,-1))
    {
      case LUA_TNIL:
        lua_pop(L,1);
        return needsep;
      case LUA_TNUMBER:
      case LUA_TSTRING:
        if (needsep) {lua_pushvalue(L,1); luaL_addvalue(b);}
        luaL_addvalue(b);
        needsep=1;
        break;
      case LUA_TTABLE:
        lua_replace(L,t+1);
        needsep=doconcat(L,b,t+1,needsep);
        break;
      default:
        lua_pop(L,1);
    }
 }
}

static int unrope (lua_State *L) {
  luaL_Buffer b;
  luaL_checktype(L,1,LUA_TTABLE);
  if (lua_isnoneornil(L,2)) lua_pushliteral(L,"");
  lua_settop(L,2);
  lua_insert(L,1);
  luaL_checkstack(L,MAXLEVEL-1+2,"cannot grow stack");
  lua_settop(L,MAXLEVEL+1);
  luaL_buffinit(L,&b);
  doconcat(L,&b,2,0);
  luaL_pushresult(&b);
  return 1;
}

LUALIB_API int luaopen_rope (lua_State *L) {
  lua_register(L,"unrope",unrope);
  return 0;
}