// lua_tinker.cpp
//
// LuaTinker - Simple and light C++ wrapper for Lua.
//
// Copyright (c) 2005-2007 Kwon-il Lee (zupet@hitel.net)
//
// please check Licence.txt file for licence and legal issues.
#include <iostream>
#include "lua_tinker.h"
/*---------------------------------------------------------------------------*/
/* init */
/*---------------------------------------------------------------------------*/
void lua_tinker::init(lua_State *L)
{
init_s64(L);
init_u64(L);
}
/*---------------------------------------------------------------------------*/
/* __s64 */
/*---------------------------------------------------------------------------*/
static int tostring_s64(lua_State *L)
{
char temp[64];
sprintf(temp, "%I64d", *(long long*)lua_topointer(L, 1));
lua_pushstring(L, temp);
return 1;
}
/*---------------------------------------------------------------------------*/
static int eq_s64(lua_State *L)
{
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(long long)) == 0);
return 1;
}
/*---------------------------------------------------------------------------*/
static int lt_s64(lua_State *L)
{
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(long long)) < 0);
return 1;
}
/*---------------------------------------------------------------------------*/
static int le_s64(lua_State *L)
{
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(long long)) <= 0);
return 1;
}
/*---------------------------------------------------------------------------*/
void lua_tinker::init_s64(lua_State *L)
{
const char* name = "__s64";
// lua_pushstring(L, name);
lua_newtable(L);
lua_pushstring(L, "__name");
lua_pushstring(L, name);
lua_rawset(L, -3);
lua_pushstring(L, "__tostring");
lua_pushcclosure(L, tostring_s64, 0);
lua_rawset(L, -3);
lua_pushstring(L, "__eq");
lua_pushcclosure(L, eq_s64, 0);
lua_rawset(L, -3);
lua_pushstring(L, "__lt");
lua_pushcclosure(L, lt_s64, 0);
lua_rawset(L, -3);
lua_pushstring(L, "__le");
lua_pushcclosure(L, le_s64, 0);
lua_rawset(L, -3);
// lua_settable(L, LUA_GLOBALSINDEX);
lua_setglobal(L, name);
}
/*---------------------------------------------------------------------------*/
/* __u64 */
/*---------------------------------------------------------------------------*/
static int tostring_u64(lua_State *L)
{
char temp[64];
sprintf(temp, "%I64u", *(unsigned long long*)lua_topointer(L, 1));
lua_pushstring(L, temp);
return 1;
}
/*---------------------------------------------------------------------------*/
static int eq_u64(lua_State *L)
{
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(unsigned long long)) == 0);
return 1;
}
/*---------------------------------------------------------------------------*/
static int lt_u64(lua_State *L)
{
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(unsigned long long)) < 0);
return 1;
}
/*---------------------------------------------------------------------------*/
static int le_u64(lua_State *L)
{
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(unsigned long long)) <= 0);
return 1;
}
/*---------------------------------------------------------------------------*/
void lua_tinker::init_u64(lua_State *L)
{
const char* name = "__u64";
// lua_pushstring(L, name);
lua_newtable(L);
lua_pushstring(L, "__name");
lua_pushstring(L, name);
lua_rawset(L, -3);
lua_pushstring(L, "__tostring");
lua_pushcclosure(L, tostring_u64, 0);
lua_rawset(L, -3);
lua_pushstring(L, "__eq");
lua_pushcclosure(L, eq_u64, 0);
lua_rawset(L, -3);
lua_pushstring(L, "__lt");
lua_pushcclosure(L, lt_u64, 0);
lua_rawset(L, -3);
lua_pushstring(L, "__le");
lua_pushcclosure(L, le_u64, 0);
lua_rawset(L, -3);
// lua_settable(L, LUA_GLOBALSINDEX);
lua_setglobal(L, name);
}
/*---------------------------------------------------------------------------*/
/* excution */
/*---------------------------------------------------------------------------*/
void lua_tinker::dofile(lua_State *L, const char *filename)
{
lua_pushcclosure(L, on_error, 0);
int errfunc = lua_gettop(L);
if(luaL_loadfile(L, filename) == 0)
{
if(lua_pcall(L, 0, 0, errfunc) != 0)
{
lua_pop(L, 1);
}
}
else
{
print_error(L, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_pop(L, 1);
}
/*---------------------------------------------------------------------------*/
void lua_tinker::dostring(lua_State *L, const char* buff)
{
lua_tinker::dobuffer(L, buff, strlen(buff));
}
/*---------------------------------------------------------------------------*/
void lua_tinker::dobuffer(lua_State *L, const char* buff, size_t len)
{
lua_pushcclosure(L, on_error, 0);
int errfunc = lua_gettop(L);
if(luaL_loadbuffer(L, buff, len, "lua_tinker::dobuffer()") == 0)
{
if(lua_pcall(L, 0, 0, errfunc) != 0)
{
lua_pop(L, 1);
}
}
else
{
print_error(L, "%s", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_pop(L, 1);
}
/*---------------------------------------------------------------------------*/
/* debug helpers */
/*---------------------------------------------------------------------------*/
static void call_stack(lua_State* L, int n)
{
lua_Debug ar;
if(lua_getstack(L, n, &ar) == 1)
{
lua_getinfo(L, "nSlu", &ar);
const char* indent;
if(n == 0)
{
indent = "->\t";
lua_tinker::print_error(L, "\t<call stack>");
}
else
{
indent = "\t";
}
if(ar.name)
lua_tinker::print_error(L, "%s%s() : line %d [%s : line %d]", indent, ar.name, ar.currentline, ar.source, ar.linedefined);
else
lua_tinker::print_error(L, "%sunknown : line %d [%s : line %d]", indent, ar.currentline, ar.source, ar.linedefined);
call_stack(L, n+1);
}
}
/*---------------------------------------------------------------------------*/
int lua_tinker::on_error(lua_State *L)
{
print_error(L, "%s", lua_tostring(L, -1));
call_stack(L, 0);
return 0;
}
/*---------------------------------------------------------------------------*/
void lua_tinker::print_error(lua_State *L, const char* fmt, ...)
{
char text[4096];
va_list args;
va_start(args, fmt);
vsprintf(text, fmt, args);
va_end(args);
lua_getglobal(L, "_ALERT");
// lua_pushstring(L, "_ALERT");
// lua_gettable(L, LUA_GLOBALSINDEX);
if(lua_isfunction(L, -1))
{
lua_pushstring(L, text);
lua_call(L, 1, 0);
}
else
{
printf("!!!!! %s\n", text);
lua_pop(L, 1);
}
}
/*---------------------------------------------------------------------------*/
void lua_tinker::enum_stack(lua_State *L)
{
int top = lua_gettop(L);
print_error(L, "Type:%d", top);
for(int i=1; i<=lua_gettop(L); ++i)
{
switch(lua_type(L, i))
{
case LUA_TNIL:
print_error(L, "\t%s", lua_typename(L, lua_type(L, i)));
break;
case LUA_TBOOLEAN:
print_error(L, "\t%s %s", lua_typename(L, lua_type(L, i)), lua_toboolean(L, i)?"true":"false");
break;
case LUA_TLIGHTUSERDATA:
print_error(L, "\t%s 0x%08p", lua_typename(L, lua_type(L, i)), lua_topointer(L, i));
break;
case LUA_TNUMBER:
print_error(L, "\t%s %f", lua_typename(L, lua_type(L, i)), lua_tonumber(L, i));
break;
case LUA_TSTRING:
print_error(L, "\t%s %s", lua_typename(L, lua_type(L, i)), lua_tostring(L, i));
break;
case LUA_TTABLE:
print_error(L, "\t%s 0x%08p", lu
- 1
- 2
前往页