Redirecting/redefining print() for embedded Lua
Asked Answered
K

5

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.

Kierkegaardian answered 22/12, 2010 at 10:15 Comment(0)
R
30

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"'

Reeva answered 22/12, 2010 at 22:12 Comment(4)
@MikeM. Is there a way so use this to have a call to luaL_dostring simply return the required output as a char*?Fourthclass
+1! exactly what I needed @ewok, luaL_dostring returns a const char * so you have exactly what you need.Squeamish
What should I return in luaopen_luamylib() function?Bastardize
Please see my other question : https://mcmap.net/q/665638/-how-to-print-lua-table-using-the-redefined-print-function/5224286Bastardize
R
11

You can simply redefine print from a Lua script.

local oldprint = print
print = function(...)
    oldprint("In ur print!");
    oldprint(...);
end
Reluctance answered 22/12, 2010 at 14:15 Comment(0)
L
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.

Lazare answered 22/12, 2010 at 10:31 Comment(3)
That seems to suggest modifying the Lua sources directly (I may be wrong) - but surely, there must be a better way?Kierkegaardian
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.Lazare
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).Boeschen
M
2

Write your own C or Lua function and redefine print.

Meyers answered 22/12, 2010 at 10:45 Comment(0)
A
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.

Arsine answered 13/10, 2016 at 15:34 Comment(1)
it's not enough in general, io.write() still writes to stdout.Kosiur

© 2022 - 2024 — McMap. All rights reserved.