106 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*=========================================================================*\
 | 
						|
* Simple exception support
 | 
						|
* LuaSocket toolkit
 | 
						|
\*=========================================================================*/
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
#include "lua.h"
 | 
						|
#include "lauxlib.h"
 | 
						|
 | 
						|
#include "except.h"
 | 
						|
 | 
						|
namespace NS_SLUA {
 | 
						|
 | 
						|
/*=========================================================================*\
 | 
						|
* Internal function prototypes.
 | 
						|
\*=========================================================================*/
 | 
						|
static int global_protect(lua_State *L);
 | 
						|
static int global_newtry(lua_State *L);
 | 
						|
static int protected_(lua_State *L);
 | 
						|
static int finalize(lua_State *L);
 | 
						|
static int do_nothing(lua_State *L);
 | 
						|
 | 
						|
/* except functions */
 | 
						|
static luaL_Reg except_func[] = {
 | 
						|
    {"newtry",    global_newtry},
 | 
						|
    {"protect",   global_protect},
 | 
						|
    {NULL,        NULL}
 | 
						|
};
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*\
 | 
						|
* Try factory
 | 
						|
\*-------------------------------------------------------------------------*/
 | 
						|
static void wrap(lua_State *L) {
 | 
						|
    lua_newtable(L);
 | 
						|
    lua_pushnumber(L, 1);
 | 
						|
    lua_pushvalue(L, -3);
 | 
						|
    lua_settable(L, -3);
 | 
						|
    lua_insert(L, -2);
 | 
						|
    lua_pop(L, 1);
 | 
						|
}
 | 
						|
 | 
						|
static int finalize(lua_State *L) {
 | 
						|
    if (!lua_toboolean(L, 1)) {
 | 
						|
        lua_pushvalue(L, lua_upvalueindex(1));
 | 
						|
        lua_pcall(L, 0, 0, 0);
 | 
						|
        lua_settop(L, 2);
 | 
						|
        wrap(L);
 | 
						|
        lua_error(L);
 | 
						|
        return 0;
 | 
						|
    } else return lua_gettop(L);
 | 
						|
}
 | 
						|
 | 
						|
static int do_nothing(lua_State *L) { 
 | 
						|
    (void) L;
 | 
						|
    return 0; 
 | 
						|
}
 | 
						|
 | 
						|
static int global_newtry(lua_State *L) {
 | 
						|
    lua_settop(L, 1);
 | 
						|
    if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing);
 | 
						|
    lua_pushcclosure(L, finalize, 1);
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*\
 | 
						|
* Protect factory
 | 
						|
\*-------------------------------------------------------------------------*/
 | 
						|
static int unwrap(lua_State *L) {
 | 
						|
    if (lua_istable(L, -1)) {
 | 
						|
        lua_pushnumber(L, 1);
 | 
						|
        lua_gettable(L, -2);
 | 
						|
        lua_pushnil(L);
 | 
						|
        lua_insert(L, -2);
 | 
						|
        return 1;
 | 
						|
    } else return 0;
 | 
						|
}
 | 
						|
 | 
						|
static int protected_(lua_State *L) {
 | 
						|
    lua_pushvalue(L, lua_upvalueindex(1));
 | 
						|
    lua_insert(L, 1);
 | 
						|
    if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) {
 | 
						|
        if (unwrap(L)) return 2;
 | 
						|
        else lua_error(L);
 | 
						|
        return 0;
 | 
						|
    } else return lua_gettop(L);
 | 
						|
}
 | 
						|
 | 
						|
static int global_protect(lua_State *L) {
 | 
						|
    lua_pushcclosure(L, protected_, 1);
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
/*-------------------------------------------------------------------------*\
 | 
						|
* Init module
 | 
						|
\*-------------------------------------------------------------------------*/
 | 
						|
int except_open(lua_State *L) {
 | 
						|
#if LUA_VERSION_NUM > 501 && !defined(LUA_COMPAT_MODULE)
 | 
						|
    luaL_setfuncs(L, except_func, 0);
 | 
						|
#else
 | 
						|
    luaL_openlib(L, NULL, except_func, 0);
 | 
						|
#endif
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
} // end NS_SLUA
 |