diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-06-26 18:47:49 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2003-06-26 18:47:49 +0000 |
commit | 71f6bb60bf2b7457091c7106190f92ab7e51f7c6 (patch) | |
tree | 8ad3668667bd3da3c34f7ff7ae0a9a7a4daa4679 /src/auxiliar.c | |
parent | f330540576031528f0daac231c61d4dd06e8ba1e (diff) | |
download | luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.tar.gz luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.tar.bz2 luasocket-71f6bb60bf2b7457091c7106190f92ab7e51f7c6.zip |
Finished implementation of LuaSocket 2.0 alpha on Linux.
Some testing still needed.
Diffstat (limited to 'src/auxiliar.c')
-rw-r--r-- | src/auxiliar.c | 181 |
1 files changed, 103 insertions, 78 deletions
diff --git a/src/auxiliar.c b/src/auxiliar.c index 96138f1..8b2fa37 100644 --- a/src/auxiliar.c +++ b/src/auxiliar.c | |||
@@ -1,142 +1,167 @@ | |||
1 | /*=========================================================================*\ | 1 | /*=========================================================================*\ |
2 | * Auxiliar routines for class hierarchy manipulation | 2 | * Auxiliar routines for class hierarchy manipulation |
3 | * LuaSocket toolkit | ||
3 | * | 4 | * |
4 | * RCS ID: $Id$ | 5 | * RCS ID: $Id$ |
5 | \*=========================================================================*/ | 6 | \*=========================================================================*/ |
7 | #include <string.h> | ||
8 | |||
9 | #include "luasocket.h" | ||
6 | #include "auxiliar.h" | 10 | #include "auxiliar.h" |
7 | 11 | ||
8 | /*=========================================================================*\ | 12 | /*=========================================================================*\ |
9 | * Exported functions | 13 | * Exported functions |
10 | \*=========================================================================*/ | 14 | \*=========================================================================*/ |
11 | /*-------------------------------------------------------------------------*\ | 15 | /*-------------------------------------------------------------------------*\ |
12 | * Creates a new class. A class has methods given by the func array and the | 16 | * Initializes the module |
13 | * field 'class' tells the object class. The table 'group' list the class | ||
14 | * groups the object belongs to. | ||
15 | \*-------------------------------------------------------------------------*/ | 17 | \*-------------------------------------------------------------------------*/ |
16 | void aux_newclass(lua_State *L, const char *name, luaL_reg *func) | 18 | void aux_open(lua_State *L) |
17 | { | 19 | { |
18 | lua_pushstring(L, name); | 20 | /* create namespace table */ |
19 | lua_newtable(L); | 21 | lua_pushstring(L, LUASOCKET_LIBNAME); |
20 | lua_pushstring(L, "__index"); | ||
21 | lua_newtable(L); | 22 | lua_newtable(L); |
22 | luaL_openlib(L, NULL, func, 0); | 23 | #ifdef LUASOCKET_DEBUG |
23 | lua_pushstring(L, "class"); | 24 | lua_pushstring(L, "debug"); |
24 | lua_pushstring(L, name); | 25 | lua_pushnumber(L, 1); |
25 | lua_rawset(L, -3); | ||
26 | lua_pushstring(L, "group"); | ||
27 | lua_newtable(L); | ||
28 | lua_rawset(L, -3); | ||
29 | lua_rawset(L, -3); | 26 | lua_rawset(L, -3); |
30 | lua_rawset(L, LUA_REGISTRYINDEX); | 27 | #endif |
28 | lua_settable(L, LUA_GLOBALSINDEX); | ||
29 | /* make sure modules know what is our namespace */ | ||
30 | lua_pushstring(L, "LUASOCKET_LIBNAME"); | ||
31 | lua_pushstring(L, LUASOCKET_LIBNAME); | ||
32 | lua_settable(L, LUA_GLOBALSINDEX); | ||
31 | } | 33 | } |
32 | 34 | ||
33 | /*-------------------------------------------------------------------------*\ | 35 | /*-------------------------------------------------------------------------*\ |
34 | * Add group to object list of groups. | 36 | * Creates a new class with given methods |
35 | \*-------------------------------------------------------------------------*/ | 37 | \*-------------------------------------------------------------------------*/ |
36 | void aux_add2group(lua_State *L, const char *name, const char *group) | 38 | void aux_newclass(lua_State *L, const char *classname, luaL_reg *func) |
37 | { | 39 | { |
38 | lua_pushstring(L, name); | 40 | luaL_newmetatable(L, classname); /* mt */ |
39 | lua_rawget(L, LUA_REGISTRYINDEX); | 41 | lua_pushstring(L, "__index"); /* mt,"__index" */ |
40 | lua_pushstring(L, "__index"); | 42 | lua_newtable(L); /* mt,"__index",it */ |
41 | lua_rawget(L, -2); | 43 | luaL_openlib(L, NULL, func, 0); |
42 | lua_pushstring(L, "group"); | 44 | #ifdef LUASOCKET_DEBUG |
43 | lua_rawget(L, -2); | 45 | lua_pushstring(L, "class"); /* mt,"__index",it,"class" */ |
44 | lua_pushstring(L, group); | 46 | lua_pushstring(L, classname); /* mt,"__index",it,"class",classname */ |
45 | lua_pushnumber(L, 1); | 47 | lua_rawset(L, -3); /* mt,"__index",it */ |
48 | #endif | ||
49 | /* get __gc method from class and use it for garbage collection */ | ||
50 | lua_pushstring(L, "__gc"); /* mt,"__index",it,"__gc" */ | ||
51 | lua_pushstring(L, "__gc"); /* mt,"__index",it,"__gc","__gc" */ | ||
52 | lua_rawget(L, -3); /* mt,"__index",it,"__gc",fn */ | ||
53 | lua_rawset(L, -5); /* mt,"__index",it */ | ||
54 | lua_rawset(L, -3); /* mt */ | ||
55 | lua_pop(L, 1); | ||
56 | } | ||
57 | |||
58 | /*-------------------------------------------------------------------------*\ | ||
59 | * Insert class into group | ||
60 | \*-------------------------------------------------------------------------*/ | ||
61 | void aux_add2group(lua_State *L, const char *classname, const char *groupname) | ||
62 | { | ||
63 | luaL_getmetatable(L, classname); | ||
64 | lua_pushstring(L, groupname); | ||
65 | lua_pushboolean(L, 1); | ||
46 | lua_rawset(L, -3); | 66 | lua_rawset(L, -3); |
47 | lua_pop(L, 3); | 67 | lua_pop(L, 1); |
68 | } | ||
69 | |||
70 | /*-------------------------------------------------------------------------*\ | ||
71 | * Make sure argument is a boolean | ||
72 | \*-------------------------------------------------------------------------*/ | ||
73 | int aux_checkboolean(lua_State *L, int objidx) | ||
74 | { | ||
75 | if (!lua_isboolean(L, objidx)) | ||
76 | luaL_typerror(L, objidx, lua_typename(L, LUA_TBOOLEAN)); | ||
77 | return lua_toboolean(L, objidx); | ||
48 | } | 78 | } |
49 | 79 | ||
50 | /*-------------------------------------------------------------------------*\ | 80 | /*-------------------------------------------------------------------------*\ |
51 | * Get a userdata making sure the object belongs to a given class. | 81 | * Calls appropriate option handler |
52 | \*-------------------------------------------------------------------------*/ | 82 | \*-------------------------------------------------------------------------*/ |
53 | void *aux_checkclass(lua_State *L, const char *name, int objidx) | 83 | int aux_meth_setoption(lua_State *L, luaL_reg *opt) |
54 | { | 84 | { |
55 | void *data = aux_getclassudata(L, name, objidx); | 85 | const char *name = luaL_checkstring(L, 2); /* obj, name, args */ |
86 | while (opt->name && strcmp(name, opt->name)) | ||
87 | opt++; | ||
88 | if (!opt->func) { | ||
89 | char msg[45]; | ||
90 | sprintf(msg, "unknown option `%.35s'", name); | ||
91 | luaL_argerror(L, 2, msg); | ||
92 | } | ||
93 | lua_remove(L, 2); /* obj, args */ | ||
94 | lua_pushcfunction(L, opt->func); /* obj, args, func */ | ||
95 | lua_insert(L, 1); /* func, obj, args */ | ||
96 | lua_call(L, lua_gettop(L)-1, LUA_MULTRET); | ||
97 | return lua_gettop(L); | ||
98 | } | ||
99 | |||
100 | /*-------------------------------------------------------------------------*\ | ||
101 | * Return userdata pointer if object belongs to a given class, abort with | ||
102 | * error otherwise | ||
103 | \*-------------------------------------------------------------------------*/ | ||
104 | void *aux_checkclass(lua_State *L, const char *classname, int objidx) | ||
105 | { | ||
106 | void *data = aux_getclassudata(L, classname, objidx); | ||
56 | if (!data) { | 107 | if (!data) { |
57 | char msg[45]; | 108 | char msg[45]; |
58 | sprintf(msg, "%.35s expected", name); | 109 | sprintf(msg, "%.35s expected", classname); |
59 | luaL_argerror(L, objidx, msg); | 110 | luaL_argerror(L, objidx, msg); |
60 | } | 111 | } |
61 | return data; | 112 | return data; |
62 | } | 113 | } |
63 | 114 | ||
64 | /*-------------------------------------------------------------------------*\ | 115 | /*-------------------------------------------------------------------------*\ |
65 | * Get a userdata making sure the object belongs to a given group. | 116 | * Return userdata pointer if object belongs to a given group, abort with |
117 | * error otherwise | ||
66 | \*-------------------------------------------------------------------------*/ | 118 | \*-------------------------------------------------------------------------*/ |
67 | void *aux_checkgroup(lua_State *L, const char *group, int objidx) | 119 | void *aux_checkgroup(lua_State *L, const char *groupname, int objidx) |
68 | { | 120 | { |
69 | void *data = aux_getgroupudata(L, group, objidx); | 121 | void *data = aux_getgroupudata(L, groupname, objidx); |
70 | if (!data) { | 122 | if (!data) { |
71 | char msg[45]; | 123 | char msg[45]; |
72 | sprintf(msg, "%.35s expected", group); | 124 | sprintf(msg, "%.35s expected", groupname); |
73 | luaL_argerror(L, objidx, msg); | 125 | luaL_argerror(L, objidx, msg); |
74 | } | 126 | } |
75 | return data; | 127 | return data; |
76 | } | 128 | } |
77 | 129 | ||
78 | /*-------------------------------------------------------------------------*\ | 130 | /*-------------------------------------------------------------------------*\ |
79 | * Set object class. | 131 | * Set object class |
80 | \*-------------------------------------------------------------------------*/ | 132 | \*-------------------------------------------------------------------------*/ |
81 | void aux_setclass(lua_State *L, const char *name, int objidx) | 133 | void aux_setclass(lua_State *L, const char *classname, int objidx) |
82 | { | 134 | { |
83 | lua_pushstring(L, name); | 135 | luaL_getmetatable(L, classname); |
84 | lua_rawget(L, LUA_REGISTRYINDEX); | ||
85 | if (objidx < 0) objidx--; | 136 | if (objidx < 0) objidx--; |
86 | lua_setmetatable(L, objidx); | 137 | lua_setmetatable(L, objidx); |
87 | } | 138 | } |
88 | 139 | ||
89 | /*=========================================================================*\ | ||
90 | * Internal functions | ||
91 | \*=========================================================================*/ | ||
92 | /*-------------------------------------------------------------------------*\ | 140 | /*-------------------------------------------------------------------------*\ |
93 | * Get a userdata if object belongs to a given group. | 141 | * Get a userdata pointer if object belongs to a given group. Return NULL |
142 | * otherwise | ||
94 | \*-------------------------------------------------------------------------*/ | 143 | \*-------------------------------------------------------------------------*/ |
95 | void *aux_getgroupudata(lua_State *L, const char *group, int objidx) | 144 | void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx) |
96 | { | 145 | { |
97 | if (!lua_getmetatable(L, objidx)) | 146 | if (!lua_getmetatable(L, objidx)) |
98 | return NULL; | ||
99 | lua_pushstring(L, "__index"); | ||
100 | lua_rawget(L, -2); | ||
101 | if (!lua_istable(L, -1)) { | ||
102 | lua_pop(L, 2); | ||
103 | return NULL; | ||
104 | } | ||
105 | lua_pushstring(L, "group"); | ||
106 | lua_rawget(L, -2); | ||
107 | if (!lua_istable(L, -1)) { | ||
108 | lua_pop(L, 3); | ||
109 | return NULL; | 147 | return NULL; |
110 | } | 148 | lua_pushstring(L, groupname); |
111 | lua_pushstring(L, group); | ||
112 | lua_rawget(L, -2); | 149 | lua_rawget(L, -2); |
113 | if (lua_isnil(L, -1)) { | 150 | if (lua_isnil(L, -1)) { |
114 | lua_pop(L, 4); | 151 | lua_pop(L, 2); |
115 | return NULL; | 152 | return NULL; |
153 | } else { | ||
154 | lua_pop(L, 2); | ||
155 | return lua_touserdata(L, objidx); | ||
116 | } | 156 | } |
117 | lua_pop(L, 4); | ||
118 | return lua_touserdata(L, objidx); | ||
119 | } | 157 | } |
120 | 158 | ||
121 | /*-------------------------------------------------------------------------*\ | 159 | /*-------------------------------------------------------------------------*\ |
122 | * Get a userdata if object belongs to a given class. | 160 | * Get a userdata pointer if object belongs to a given class. Return NULL |
161 | * otherwise | ||
123 | \*-------------------------------------------------------------------------*/ | 162 | \*-------------------------------------------------------------------------*/ |
124 | void *aux_getclassudata(lua_State *L, const char *group, int objidx) | 163 | void *aux_getclassudata(lua_State *L, const char *classname, int objidx) |
125 | { | 164 | { |
126 | if (!lua_getmetatable(L, objidx)) | 165 | return luaL_checkudata(L, objidx, classname); |
127 | return NULL; | ||
128 | lua_pushstring(L, "__index"); | ||
129 | lua_rawget(L, -2); | ||
130 | if (!lua_istable(L, -1)) { | ||
131 | lua_pop(L, 2); | ||
132 | return NULL; | ||
133 | } | ||
134 | lua_pushstring(L, "class"); | ||
135 | lua_rawget(L, -2); | ||
136 | if (lua_isnil(L, -1)) { | ||
137 | lua_pop(L, 3); | ||
138 | return NULL; | ||
139 | } | ||
140 | lua_pop(L, 3); | ||
141 | return lua_touserdata(L, objidx); | ||
142 | } | 166 | } |
167 | |||