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
							 |