Merge branch 'rr1-maint'

This commit is contained in:
Ilari Liusvaara 2013-09-27 04:43:44 +03:00
commit 22cba85a37
6 changed files with 134 additions and 22 deletions

View file

@ -14,6 +14,11 @@ extern "C"
#include <lua.h>
}
class lua_state;
std::list<std::string(*)(lua_state& state, int index)>& userdata_recogn_fns();
std::string try_recognize_userdata(lua_state& state, int index);
struct lua_function;
/**
@ -450,6 +455,8 @@ public:
int getmetatable(int index) { return lua_getmetatable(lua_handle, index); }
int rawequal(int index1, int index2) { return lua_rawequal(lua_handle, index1, index2); }
void* touserdata(int index) { return lua_touserdata(lua_handle, index); }
const void* topointer(int index) { return lua_topointer(lua_handle, index); }
int gettop() { return lua_gettop(lua_handle); }
void pushvalue(int index) { lua_pushvalue(lua_handle, index); }
void pushlightuserdata(void* p) { lua_pushlightuserdata(lua_handle, p); }
void rawset(int index) { lua_rawset(lua_handle, index); }
@ -709,6 +716,11 @@ badtype:
return ret;
}
std::string _recognize(lua_state& state, int arg)
{
return _is(state, arg) ? name : "";
}
lua_obj_pin<T> _pin(lua_state& state, int arg, const std::string& fname)
{
T* obj = get(state, arg, fname);
@ -724,6 +736,7 @@ public:
lua_class(const std::string& _name)
{
name = _name;
userdata_recogn_fns().push_back(lua_class<T>::recognize);
}
/**
@ -796,6 +809,16 @@ public:
{
return objclass<T>()._is(state, arg);
}
/**
* Identify if object is of this type.
* Parameter state: The Lua state.
* Parameter arg: Argument index.
* Returns: Name of type if object is of specified type, "" if not.
*/
static std::string recognize(lua_state& state, int arg)
{
return objclass<T>()._recognize(state, arg);
}
/**
* Get a pin of object against Lua GC.

13
lua.lyx
View file

@ -139,6 +139,19 @@ Syntax: none print(value...
\begin_layout Standard
Prints specified values to console.
Can print any Lua type at least enough to identify the type and instance.
\end_layout
\begin_layout Subsection
tostringx: Format a value to string
\end_layout
\begin_layout Itemize
Syntax: string tostringx(value val)
\end_layout
\begin_layout Standard
Formats value <val> like print would, and returns the result as a string.
\end_layout
\begin_layout Subsection

BIN
lua.pdf

Binary file not shown.

View file

@ -308,3 +308,29 @@ void lua_function_group::do_unregister(const std::string& name)
i.second(name, NULL);
}
std::list<std::string(*)(lua_state& state, int index)>& userdata_recogn_fns()
{
static std::list<std::string(*)(lua_state& state, int index)> x;
return x;
}
std::string try_recognize_userdata(lua_state& state, int index)
{
for(auto i : userdata_recogn_fns()) {
std::string x = i(state, index);
if(x != "")
return x;
}
//Hack: Lua builtin file objects.
state.pushstring("FILE*");
state.rawget(LUA_REGISTRYINDEX);
if(state.getmetatable(index)) {
if(state.rawequal(-1, -2)) {
state.pop(2);
return "FILE*";
}
state.pop(1);
}
state.pop(1);
return "unknown";
}

View file

@ -5,9 +5,76 @@
#include "core/moviedata.hpp"
#include "core/window.hpp"
#include "interface/romtype.hpp"
#include "library/string.hpp"
#include <sstream>
namespace
{
std::string luavalue_to_string(lua_state& L, int index, std::set<const void*>& printed, bool quote)
{
switch(L.type(index)) {
case LUA_TNONE:
return "none";
case LUA_TNIL:
return "nil";
case LUA_TBOOLEAN:
return L.toboolean(index) ? "true" : "false";
case LUA_TNUMBER:
return (stringfmt() << L.tonumber(index)).str();
case LUA_TSTRING: {
const char* tmp2;
size_t len;
tmp2 = L.tolstring(index, &len);
if(quote)
return "\"" + std::string(tmp2, tmp2 + len) + "\"";
else
return std::string(tmp2, tmp2 + len);
}
case LUA_TLIGHTUSERDATA:
return (stringfmt() << "Lightuserdata:" << L.touserdata(index)).str();
case LUA_TFUNCTION:
return (stringfmt() << "Function:" << L.topointer(index)).str();
case LUA_TTHREAD:
return (stringfmt() << "Thread:" << L.topointer(index)).str();
break;
case LUA_TUSERDATA:
return (stringfmt() << "Userdata<" << try_recognize_userdata(L, index) << ">:"
<< L.touserdata(index)).str();
case LUA_TTABLE: {
//Fun with recursion.
const void* ptr = L.topointer(index);
if(printed.count(ptr))
return (stringfmt() << "<table:" << ptr << ">").str();
printed.insert(ptr);
std::ostringstream s;
s << "<" << ptr << ">{";
L.pushnil();
bool first = true;
while(L.next(index)) {
if(!first)
s << ", ";
int stacktop = L.gettop();
s << "[" << luavalue_to_string(L, stacktop - 1, printed, true) << "]="
<< luavalue_to_string(L, stacktop, printed, true);
first = false;
L.pop(1);
}
s << "}";
return s.str();
}
default:
return (stringfmt() << "???:" << L.topointer(index)).str();
}
}
function_ptr_luafun lua_tostringx(lua_func_misc, "tostringx", [](lua_state& L, const std::string& fname) ->
int {
std::set<const void*> tmp2;
std::string y = luavalue_to_string(L, 1, tmp2, false);
L.pushlstring(y.c_str(), y.length());
return 1;
});
function_ptr_luafun lua_print(lua_func_misc, "print2", [](lua_state& L, const std::string& fname) -> int {
int stacksize = 0;
while(!L.isnone(stacksize + 1))
@ -15,29 +82,12 @@ namespace
std::string toprint;
bool first = true;
for(int i = 0; i < stacksize; i++) {
size_t len;
const char* tmp = NULL;
if(L.isnil(i + 1)) {
tmp = "nil";
len = 3;
} else if(L.isboolean(i + 1) && L.toboolean(i + 1)) {
tmp = "true";
len = 4;
} else if(L.isboolean(i + 1) && !L.toboolean(i + 1)) {
tmp = "false";
len = 5;
} else {
tmp = L.tolstring(i + 1, &len);
if(!tmp) {
tmp = "(unprintable)";
len = 13;
}
}
std::string localmsg(tmp, tmp + len);
std::set<const void*> tmp2;
std::string tmp = luavalue_to_string(L, i + 1, tmp2, false);
if(first)
toprint = localmsg;
toprint = tmp;
else
toprint = toprint + "\t" + localmsg;
toprint = toprint + "\t" + tmp;
first = false;
}
platform::message(toprint);

View file

@ -510,4 +510,4 @@ DECLARE_LUACLASS(lua_unsaferewind, "UNSAFEREWIND");
lua_unsaferewind::lua_unsaferewind(lua_state& L)
{
}
}