diff options
| author | Simon Robertshaw <simon@hardwired.org.uk> | 2013-05-04 21:26:49 (GMT) |
|---|---|---|
| committer | Simon Robertshaw <simon@hardwired.org.uk> | 2013-05-04 21:26:49 (GMT) |
| commit | 66e21ce0498f623ccffcee95b1fdcbc218464caa (patch) | |
| tree | 83de913847ce0b1808c46a1bdedb1c4c6c66296d /src/socket/except.c | |
| parent | 3799d5ed86e7b508b39544cad3b3346655c804f1 (diff) | |
| parent | e7b29ab9b5e037a8896c62f0473cae8d353d5114 (diff) | |
| download | powder-66e21ce0498f623ccffcee95b1fdcbc218464caa.zip powder-66e21ce0498f623ccffcee95b1fdcbc218464caa.tar.gz | |
Merge pull request #131 from mniip/lua
builtin luasocket
Diffstat (limited to 'src/socket/except.c')
| -rw-r--r-- | src/socket/except.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/socket/except.c b/src/socket/except.c new file mode 100644 index 0000000..5faa5be --- /dev/null +++ b/src/socket/except.c @@ -0,0 +1,99 @@ +/*=========================================================================*\ +* Simple exception support +* LuaSocket toolkit +* +* RCS ID: $Id: except.c,v 1.8 2005/09/29 06:11:41 diego Exp $ +\*=========================================================================*/ +#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; +} |
