summaryrefslogtreecommitdiff
path: root/src/socket/except.c
diff options
context:
space:
mode:
authorSimon 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)
commit66e21ce0498f623ccffcee95b1fdcbc218464caa (patch)
tree83de913847ce0b1808c46a1bdedb1c4c6c66296d /src/socket/except.c
parent3799d5ed86e7b508b39544cad3b3346655c804f1 (diff)
parente7b29ab9b5e037a8896c62f0473cae8d353d5114 (diff)
downloadpowder-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.c99
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;
+}