mirror of
https://github.com/lunarmodules/luasocket.git
synced 2025-07-16 22:09:48 +02:00
Finished implementation of LuaSocket 2.0 alpha on Linux.
Some testing still needed.
This commit is contained in:
191
src/auxiliar.c
191
src/auxiliar.c
@ -1,142 +1,167 @@
|
||||
/*=========================================================================*\
|
||||
* Auxiliar routines for class hierarchy manipulation
|
||||
* LuaSocket toolkit
|
||||
*
|
||||
* RCS ID: $Id$
|
||||
\*=========================================================================*/
|
||||
#include <string.h>
|
||||
|
||||
#include "luasocket.h"
|
||||
#include "auxiliar.h"
|
||||
|
||||
/*=========================================================================*\
|
||||
* Exported functions
|
||||
\*=========================================================================*/
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Creates a new class. A class has methods given by the func array and the
|
||||
* field 'class' tells the object class. The table 'group' list the class
|
||||
* groups the object belongs to.
|
||||
* Initializes the module
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void aux_newclass(lua_State *L, const char *name, luaL_reg *func)
|
||||
void aux_open(lua_State *L)
|
||||
{
|
||||
lua_pushstring(L, name);
|
||||
/* create namespace table */
|
||||
lua_pushstring(L, LUASOCKET_LIBNAME);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "__index");
|
||||
lua_newtable(L);
|
||||
luaL_openlib(L, NULL, func, 0);
|
||||
lua_pushstring(L, "class");
|
||||
lua_pushstring(L, name);
|
||||
lua_rawset(L, -3);
|
||||
lua_pushstring(L, "group");
|
||||
lua_newtable(L);
|
||||
lua_rawset(L, -3);
|
||||
lua_rawset(L, -3);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Add group to object list of groups.
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void aux_add2group(lua_State *L, const char *name, const char *group)
|
||||
{
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_pushstring(L, "__index");
|
||||
lua_rawget(L, -2);
|
||||
lua_pushstring(L, "group");
|
||||
lua_rawget(L, -2);
|
||||
lua_pushstring(L, group);
|
||||
#ifdef LUASOCKET_DEBUG
|
||||
lua_pushstring(L, "debug");
|
||||
lua_pushnumber(L, 1);
|
||||
lua_rawset(L, -3);
|
||||
lua_pop(L, 3);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Get a userdata making sure the object belongs to a given class.
|
||||
* Creates a new class with given methods
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *aux_checkclass(lua_State *L, const char *name, int objidx)
|
||||
void aux_newclass(lua_State *L, const char *classname, luaL_reg *func)
|
||||
{
|
||||
void *data = aux_getclassudata(L, name, objidx);
|
||||
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", name);
|
||||
sprintf(msg, "%.35s expected", classname);
|
||||
luaL_argerror(L, objidx, msg);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Get a userdata making sure the object belongs to a given group.
|
||||
* Return userdata pointer if object belongs to a given group, abort with
|
||||
* error otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *aux_checkgroup(lua_State *L, const char *group, int objidx)
|
||||
void *aux_checkgroup(lua_State *L, const char *groupname, int objidx)
|
||||
{
|
||||
void *data = aux_getgroupudata(L, group, objidx);
|
||||
void *data = aux_getgroupudata(L, groupname, objidx);
|
||||
if (!data) {
|
||||
char msg[45];
|
||||
sprintf(msg, "%.35s expected", group);
|
||||
sprintf(msg, "%.35s expected", groupname);
|
||||
luaL_argerror(L, objidx, msg);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Set object class.
|
||||
* Set object class
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void aux_setclass(lua_State *L, const char *name, int objidx)
|
||||
void aux_setclass(lua_State *L, const char *classname, int objidx)
|
||||
{
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
luaL_getmetatable(L, classname);
|
||||
if (objidx < 0) objidx--;
|
||||
lua_setmetatable(L, objidx);
|
||||
}
|
||||
|
||||
/*=========================================================================*\
|
||||
* Internal functions
|
||||
\*=========================================================================*/
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Get a userdata if object belongs to a given group.
|
||||
* Get a userdata pointer if object belongs to a given group. Return NULL
|
||||
* otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *aux_getgroupudata(lua_State *L, const char *group, int objidx)
|
||||
void *aux_getgroupudata(lua_State *L, const char *groupname, int objidx)
|
||||
{
|
||||
if (!lua_getmetatable(L, objidx))
|
||||
if (!lua_getmetatable(L, objidx))
|
||||
return NULL;
|
||||
lua_pushstring(L, "__index");
|
||||
lua_rawget(L, -2);
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
return NULL;
|
||||
}
|
||||
lua_pushstring(L, "group");
|
||||
lua_rawget(L, -2);
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 3);
|
||||
return NULL;
|
||||
}
|
||||
lua_pushstring(L, group);
|
||||
lua_pushstring(L, groupname);
|
||||
lua_rawget(L, -2);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 4);
|
||||
lua_pop(L, 2);
|
||||
return NULL;
|
||||
} else {
|
||||
lua_pop(L, 2);
|
||||
return lua_touserdata(L, objidx);
|
||||
}
|
||||
lua_pop(L, 4);
|
||||
return lua_touserdata(L, objidx);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
* Get a userdata if object belongs to a given class.
|
||||
* Get a userdata pointer if object belongs to a given class. Return NULL
|
||||
* otherwise
|
||||
\*-------------------------------------------------------------------------*/
|
||||
void *aux_getclassudata(lua_State *L, const char *group, int objidx)
|
||||
void *aux_getclassudata(lua_State *L, const char *classname, int objidx)
|
||||
{
|
||||
if (!lua_getmetatable(L, objidx))
|
||||
return NULL;
|
||||
lua_pushstring(L, "__index");
|
||||
lua_rawget(L, -2);
|
||||
if (!lua_istable(L, -1)) {
|
||||
lua_pop(L, 2);
|
||||
return NULL;
|
||||
}
|
||||
lua_pushstring(L, "class");
|
||||
lua_rawget(L, -2);
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 3);
|
||||
return NULL;
|
||||
}
|
||||
lua_pop(L, 3);
|
||||
return lua_touserdata(L, objidx);
|
||||
return luaL_checkudata(L, objidx, classname);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user