mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-11-16 02:08:21 +01:00
f960b3872a
Documented headers.lua Update copyright date everywhere Remove RCSID from files Move version back to 2.1 rather than 2.1.1 Fixed url package to support ipv6 hosts Changed "domain" to "family" in tcp and udp structures Implemented getfamily methods
98 lines
2.6 KiB
C
98 lines
2.6 KiB
C
/*=========================================================================*\
|
|
* Simple exception support
|
|
* LuaSocket toolkit
|
|
\*=========================================================================*/
|
|
#include <stdio.h>
|
|
|
|
#include "lua.h"
|
|
#include "lauxlib.h"
|
|
|
|
#include "except.h"
|
|
|
|
/*=========================================================================*\
|
|
* 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 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) {
|
|
luaL_openlib(L, NULL, func, 0);
|
|
return 0;
|
|
}
|