lua-users home
lua-l archive

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


On 10/28/2013 10:05 PM, Javier Guerra Giraldez wrote:
On Mon, Oct 28, 2013 at 4:03 PM, Paul Chavent <paul.chavent@fnac.net> wrote:
On 10/27/2013 08:48 PM, Tom N Harris wrote:
What's wrong with `_G.print = myprint` ?


Nothing wrong. But a lower level hook allow to specify user data (that can
be used to pass a class pointer in my case).


remember that in Lua functions are full closures, even when implemented in C.


Hi.

I've managed to redirect output by redefining _G.print (i joined my test code hereunder). Indeed, we can use closure in c. The variables that are passed to the function seems to be named upvalues. But i feel that it could also be named user-data. Am I wright or is it different ?

But I'm still convinced that this method isn't so easy because it remains two "problems" :

(1) When i get errors from lua, i use lua_printerror. This function doesn't call _G.print. So i must change my code at this place too. However, I can admit that this point is not too hard to solve...

(2) The redefined C print function must handle the arg parsing although it is already well done in the lua lib. I could copy paste the code found in the lua implementation... but i'm not too confident with this solution. I would prefer having a hook that simply take a string as argument...

Could you tell me if i'm on the good way please ?

Regards.

Paul.

8<----------------------------------------------------------------

static int l_my_print(lua_State* L)
{
  void * user_data = lua_touserdata (L, lua_upvalueindex(1));

  fprintf(stdout, "-- %d\n", *((int *)user_data));

  int nargs = lua_gettop(L);

  for(int i=1; i <= nargs; i++)
    {
      if (lua_isstring(L, i))
        {
          const char * str = lua_tostring(L, i);
          fprintf(stdout, "-- %s\n", str);
        }
      else
        {
          fprintf(stdout, "-- arg %d not a string\n", i);
        }
    }

  return 0;
}

static const struct luaL_Reg printlib [] =
{
  {"print", l_my_print},
  {NULL, NULL} /* end of array */
};

static int print_redirection(lua_State *L, void * user_data)
{
  lua_getglobal(L, "_G");
  lua_pushlightuserdata(L, user_data);
  luaL_setfuncs(L, printlib, 1);
  lua_pop(L, 1); /* the upvalues are poped from the stack after registration */
  return 0;
}

8<----------------------------------------------------------------