lua-users home
lua-l archive

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


I've received a bug report that the lua4nt plugin doesn't support
redirection. That's not strictly true. The plugin fully supports output
redirection if the io.stdout/io.stderr handles are used.

However, the print() function is another story altogether. This function
is hardcoded to use the output handle that was in place when the
interpreter was started (print() has for obvious reasons no notion of
module io). OTOH, the environment in which the lua4nt plugin runs pretty
much guarantees that there's a valid io.stdout around.

So, here are two workarounds for that problem: either patch the Lua
sources (function luaB_print() in lbaselib.c) and recompile or implement
a Lua function print() that calls io.stdout:write().

--[[ // Patch print() such that it'll use io.stdout
static int luaB_print (lua_State *L) {
  int n = lua_gettop(L);  /* number of arguments */
  int i;
+ FILE **pf;  // TL!!!
+ lua_getglobal(L,"io");
+ lua_pushstring(L,"stdout");
+ lua_gettable(L,-2);
+ pf=(FILE **)lua_touserdata(L,-1);
  lua_getglobal(L, "tostring");
  for (i=1; i<=n; i++) {
    const char *s;
    lua_pushvalue(L, -1);  /* function to be called */
    lua_pushvalue(L, i);   /* value to print */
    lua_call(L, 1, 1);
    s = lua_tostring(L, -1);  /* get result */
    if (s == NULL)
      return luaL_error(L, LUA_QL("tostring") " must return a string to
"
                           LUA_QL("print"));
    if (i>1) fputs("\t", *pf);
    fputs(s, *pf);
    lua_pop(L, 1);  /* pop result */
  }
  fputs("\n", *pf);
+ lua_pop(L,3);  // TL!!!
  return 0;
}
--]]

-- Or use this as a replacement for print()
function apairs(...)
	local function _apairs(a,i)
		if i<a.n then return i+1,a[i+1] end
	end
	return _apairs,{n=select('#',...),...},0
end

function print(...)
	local t={}
	-- the much simpler local t={...} doesn't cut it if there's
	-- a terminating nil in ... so this does it bit by bit
	for i,v in apairs(...) do t[i]=tostring(v) end
	io.stdout:write(table.concat(t,'\t'),'\n')
end

print(1,2,3,"four",nil)
print(1,2,3,"four",nil,true)

The next version of lua4nt will include these changes.

-- 
cheers  thomasl

web: http://thomaslauer.com/start