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