aboutsummaryrefslogtreecommitdiff
path: root/src/auxiliar.c
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2003-06-26 18:47:49 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2003-06-26 18:47:49 +0000
commit71f6bb60bf2b7457091c7106190f92ab7e51f7c6 (patch)
tree8ad3668667bd3da3c34f7ff7ae0a9a7a4daa4679 /src/auxiliar.c
parentf330540576031528f0daac231c61d4dd06e8ba1e (diff)
downloadluasocket-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.c181
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\*-------------------------------------------------------------------------*/
16void aux_newclass(lua_State *L, const char *name, luaL_reg *func) 18void 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\*-------------------------------------------------------------------------*/
36void aux_add2group(lua_State *L, const char *name, const char *group) 38void 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\*-------------------------------------------------------------------------*/
61void 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\*-------------------------------------------------------------------------*/
73int 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\*-------------------------------------------------------------------------*/
53void *aux_checkclass(lua_State *L, const char *name, int objidx) 83int 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\*-------------------------------------------------------------------------*/
104void *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\*-------------------------------------------------------------------------*/
67void *aux_checkgroup(lua_State *L, const char *group, int objidx) 119void *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\*-------------------------------------------------------------------------*/
81void aux_setclass(lua_State *L, const char *name, int objidx) 133void 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\*-------------------------------------------------------------------------*/
95void *aux_getgroupudata(lua_State *L, const char *group, int objidx) 144void *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\*-------------------------------------------------------------------------*/
124void *aux_getclassudata(lua_State *L, const char *group, int objidx) 163void *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