19

I have embedded Lua in my C++ application. I want to redirect print statements (or maybe simply redefine the print function?), so that I can display the evaluated expression somewhere else.

What is the best way to do this: redirect or redefining the print() function?

Any snippets/pointers to snippets that show how to do this would be much appreciated.

skyeagle
  • 6,925
  • 16
  • 56
  • 71

5 Answers5

29

You can redefine the print statement in C:

static int l_my_print(lua_State* L) {
    int nargs = lua_gettop(L);

    for (int i=1; i <= nargs; i++) {
        if (lua_isstring(L, i)) {
            /* Pop the next arg using lua_tostring(L, i) and do your print */
        }
        else {
        /* Do something with non-strings if you like */
        }
    }

    return 0;
}

Then register it in the global table:

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

extern int luaopen_luamylib(lua_State *L)
{
  lua_getglobal(L, "_G");
  // luaL_register(L, NULL, printlib); // for Lua versions < 5.2
  luaL_setfuncs(L, printlib, 0);  // for Lua versions 5.2 or greater
  lua_pop(L, 1);
}

Since you are using C++ you'll need to include your file using 'extern "C"'

Jason Livesay
  • 6,317
  • 3
  • 25
  • 31
Mike M.
  • 543
  • 4
  • 13
11

You can simply redefine print from a Lua script.

local oldprint = print
print = function(...)
    oldprint("In ur print!");
    oldprint(...);
end
Puppy
  • 144,682
  • 38
  • 256
  • 465
4

See luaB_print in lbaselib.c. The comment there reads:

 /* If you need, you can define your own `print' function, following this
 model but changing `fputs' to put the strings at a proper place (a
 console window or a log file, for instance). */

You can just edit that function or define a new one. This has the advantage of being simple and portable, but it won't handle io.write (which you may or may not care about).

Redirecting IO isn't going to be platform specific (such as SetStdHandle in Windows), but will take care of print and io.write without redefining either.

Mud
  • 28,277
  • 11
  • 59
  • 92
  • That seems to suggest modifying the Lua sources directly (I may be wrong) - but surely, there must be a better way? – skyeagle Dec 22 '10 at 10:40
  • Well, I have no particular aversion to editing the Lua source, as long as I'm not changing the semantics of anything. I wrote a Lua "compiler" which bound files into the EXE as resources, then hooked Lua's file routines to read from the executable resources rather than the file system. Only had to change a few lines of source. Can't imagine what a nightmare it would have been had I tried to avoid making those changes. – Mud Dec 22 '10 at 10:53
  • The solution Mike M gives doesn't touch the Lua code. You provide a custom print function and override the default one by registering it through the Lua C function `lua_register(L,"print", my_print)`. – Max Kielland Oct 23 '14 at 15:45
2

Write your own C or Lua function and redefine print.

lhf
  • 70,581
  • 9
  • 108
  • 149
1

You can just redefine the following macros:

lua_writestring
lua_writeline
lua_writestringerror

to whatever you like. I'm not sure about the lua version where this was introduced - but it works in 5.3 for me.

Check your lauxlib.h or luaconf.h.

Martin Gerhardy
  • 1,860
  • 22
  • 13