2

I learned how to redefine the Lua's print() in C++ from this post. (https://stackoverflow.com/a/4514193/5224286)

Here's the redefined print function that prints variables to my host program's console. (through the functions named post..)

int l_my_print(lua_State *L)
{
    int nargs = lua_gettop(L);
    for (int i = 1; i <= nargs; ++i)
    {
        if (lua_isnil(L, i))
            poststring("nil");
        else if (lua_isboolean(L, i))
            lua_toboolean(L, i) ? poststring("true") : poststring("false");
        else if (lua_isnumber(L, i))
            postfloat(static_cast<t_float>(lua_tonumber(L, i)));
        else if (lua_isstring(L, i))
            poststring(lua_tostring(L, i));
        else if (lua_istable(L, i))
            poststring("table: "); //how to print like Lua's built-in print()?
    }
    endpost();
    return 0;
}

This code works fine except when I print tables. (it just prints table: now)

I wonder how to print tables just like how Lua's print() works.

For example, when I run the following code in Lua: (before the redefine)

print({1,2,3});

I get this result: (which seems to change constantly)

table: 0x23b8660

Is this a hex representation of pointer to the Lua-table?

What should I do with my l_my_print() function so it can work just like Lua's print()?

4
  • 2
    Call lua_tostring on the table too. Commented Sep 1, 2018 at 10:52
  • 1
    See lua_topointer: lua.org/manual/5.3/manual.html#lua_topointer Commented Sep 1, 2018 at 11:13
  • 1
    "Is this a hex representation of a pointer to the Lua-table?" Not by definition. It's not even guaranteed to be unique. (People do find it somewhat useful when debugging when it is, though.) Why do you need it? Commented Sep 3, 2018 at 19:15
  • @TomBlodget I don't need it specifically for anything. I just wanted to make my custom print to work just like the original one. Commented Sep 4, 2018 at 15:22

2 Answers 2

1

Just use luaL_tolstring to get the string representation of anything. This also respects the __tostring metamethod. The example below uses std::string_view from C++17 for zero-copy read-only string arguments.

#include <iostream>
#include <string_view>

#include <lua.hpp>

void poststring(std::string_view sv) { std::cout << sv << '\n'; }

void endpost() { std::cout << "---\n"; }

int l_my_print(lua_State *L) {
    int nargs = lua_gettop(L);
    for (int i = 1; i <= nargs; ++i) {
        poststring(luaL_tolstring(L, i, nullptr));
        lua_pop(L, 1); // remove the string
    }
    endpost();
    return 0;
}

int main() {
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);

    lua_pushcfunction(L, l_my_print);
    lua_setglobal(L, "my_print");

    int i = 0;
    lua_pushlightuserdata(L, &i);
    lua_setglobal(L, "udata");

    luaL_dostring(L, "my_print(1, 3.14, \"Hello World\")\n"
                     "my_print(false, udata, {})\n");

    lua_close(L);
}

Example invocation:

$ clang++ -Wall -Wextra -Wpedantic -std=c++17 -I/usr/include/lua5.3 test.cpp -llua5.3
$ ./a.out 
1
3.14
Hello World
---
false
userdata: 0x7fff4685993c
table: 0x883300
---
Sign up to request clarification or add additional context in comments.

Comments

0

Or you could do the conversion in Lua:

    --Produces a compact, uncluttered representation of a table. Mutual recursion is employed
    --source: http://lua-users.org/wiki/TableUtils
    function table.tostring( tbl )
      local result, done = {}, {}
      for k, v in ipairs( tbl ) do
        table.insert( result, table.val_to_str( v ) )
        done[ k ] = true
      end
      for k, v in pairs( tbl ) do
        if not done[ k ] then
          table.insert( result,
            table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
        end
      end
      return "{" .. table.concat( result, "," ) .. "}"
    end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.