beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / luasocket / src / except.c
blob1d1ade0ee00e1146483a9de2f15a544c8d378860
1 /*=========================================================================*\
2 * Simple exception support
3 * LuaSocket toolkit
4 \*=========================================================================*/
5 #include <stdio.h>
7 #include "lua.h"
8 #include "lauxlib.h"
10 #include "except.h"
12 /*=========================================================================*\
13 * Internal function prototypes.
14 \*=========================================================================*/
15 static int global_protect(lua_State *L);
16 static int global_newtry(lua_State *L);
17 static int protected_(lua_State *L);
18 static int finalize(lua_State *L);
19 static int do_nothing(lua_State *L);
21 /* except functions */
22 static luaL_Reg func[] = {
23 {"newtry", global_newtry},
24 {"protect", global_protect},
25 {NULL, NULL}
28 /*-------------------------------------------------------------------------*\
29 * Try factory
30 \*-------------------------------------------------------------------------*/
31 static void wrap(lua_State *L) {
32 lua_newtable(L);
33 lua_pushnumber(L, 1);
34 lua_pushvalue(L, -3);
35 lua_settable(L, -3);
36 lua_insert(L, -2);
37 lua_pop(L, 1);
40 static int finalize(lua_State *L) {
41 if (!lua_toboolean(L, 1)) {
42 lua_pushvalue(L, lua_upvalueindex(1));
43 lua_pcall(L, 0, 0, 0);
44 lua_settop(L, 2);
45 wrap(L);
46 lua_error(L);
47 return 0;
48 } else return lua_gettop(L);
51 static int do_nothing(lua_State *L) {
52 (void) L;
53 return 0;
56 static int global_newtry(lua_State *L) {
57 lua_settop(L, 1);
58 if (lua_isnil(L, 1)) lua_pushcfunction(L, do_nothing);
59 lua_pushcclosure(L, finalize, 1);
60 return 1;
63 /*-------------------------------------------------------------------------*\
64 * Protect factory
65 \*-------------------------------------------------------------------------*/
66 static int unwrap(lua_State *L) {
67 if (lua_istable(L, -1)) {
68 lua_pushnumber(L, 1);
69 lua_gettable(L, -2);
70 lua_pushnil(L);
71 lua_insert(L, -2);
72 return 1;
73 } else return 0;
76 static int protected_(lua_State *L) {
77 lua_pushvalue(L, lua_upvalueindex(1));
78 lua_insert(L, 1);
79 if (lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0) != 0) {
80 if (unwrap(L)) return 2;
81 else lua_error(L);
82 return 0;
83 } else return lua_gettop(L);
86 static int global_protect(lua_State *L) {
87 lua_pushcclosure(L, protected_, 1);
88 return 1;
91 /*-------------------------------------------------------------------------*\
92 * Init module
93 \*-------------------------------------------------------------------------*/
94 int except_open(lua_State *L) {
95 luaL_openlib(L, NULL, func, 0);
96 return 0;