aboutsummaryrefslogtreecommitdiff
path: root/luaT
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2015-06-22 19:01:29 +0800
committerDeterminant <ted.sybil@gmail.com>2015-06-22 19:01:29 +0800
commit2497fd9e7a0fae5ee4887890d7a312e0e08a93b8 (patch)
tree382f97575bd2df9ee6abb1662b11b279fc22d72b /luaT
parent196e9b48a3541caccdffc5743001cced70667091 (diff)
major change: use luarocks to manage project
Diffstat (limited to 'luaT')
-rw-r--r--luaT/README.md239
-rw-r--r--luaT/luaT.c1079
-rw-r--r--luaT/luaT.h111
3 files changed, 0 insertions, 1429 deletions
diff --git a/luaT/README.md b/luaT/README.md
deleted file mode 100644
index 6e9cf0d..0000000
--- a/luaT/README.md
+++ /dev/null
@@ -1,239 +0,0 @@
-<a name="luat.dok"/>
-# Lua Torch C API #
-
-luaT provides an API to interface Lua and C in Torch packages. It defines a
-concept of _classes_ to Lua for Torch, and provides a mechanism to easily
-handle these Lua classes from C.
-
-It additionally provides few functions that `luaL` should have defined, and
-defines several functions similar to `luaL` ones for better type error printing when using
-`luaT` classes.
-
-<a name="luat.memory.dok"/>
-## Memory functions ##
-
-Classical memory allocation functions which generate a Lua error in case of
-problem.
-
-<a name="luaT_alloc"/>
-### void* luaT_alloc(lua_State *L, long size) ###
-
-Allocates `size` bytes, and return a pointer on the allocated
-memory. A Lua error will be generated if running out of memory.
-
-<a name="luaT_realloc"/>
-### void* luaT_realloc(lua_State *L, void *ptr, long size) ###
-
-Realloc `ptr` to `size` bytes. `ptr` must have been previously
-allocated with [luaT_alloc](#luaT_alloc) or
-[luaT_realloc](#luaT_realloc), or the C `malloc` or `realloc`
-functions. A Lua error will be generated if running out of memory.
-
-<a name="luaT_free"/>
-### void luaT_free(lua_State *L, void *ptr) ###
-
-Free memory allocated at address `ptr`. The memory must have been
-previously allocated with [luaT_alloc](#luaT_alloc) or
-[luaT_realloc](#luaT_realloc), or the C `malloc` or `realloc`
-functions.
-
-<a name="luat.classcreate"/>
-## Class creation and basic handling ##
-
-A `luaT` class is basically either a Lua _table_ or _userdata_ with
-an appropriate _metatable_. This appropriate metatable is created with
-[luaT_newmetatable](#luaT_newmetatable). Contrary to luaL userdata
-functions, luaT mechanism handles inheritance. If the class inherit from
-another class, then the metatable will itself have a metatable
-corresponding to the _parent metatable_: the metatables are cascaded
-according to the class inheritance. Multiple inheritance is not supported.
-
-<a name="luat.operatoroverloading"/>
-### Operator overloading ###
-
-The metatable of a `luaT` object contains `Lua` operators like
-`__index`, `__newindex`, `__tostring`, `__add`
-(etc...). These operators will respectively look for `__index__`,
-`__newindex__`, `__tostring__`, `__add__` (etc...) in the
-metatable. If found, the corresponding function or value will be returned,
-else a Lua error will be raised.
-
-If one wants to provide `__index__` or `__newindex__` in the
-metaclass, these operators must follow a particular scheme:
-
- * `__index__` must either return a value _and_ `true` or return `false` only. In the first case, it means `__index__` was able to handle the given argument (for e.g., the type was correct). The second case means it was not able to do anything, so `__index` in the root metatable can then try to see if the metaclass contains the required value.
-
- * `__newindex__` must either return `true` or `false`. As for `__index__`, `true` means it could handle the argument and `false` not. If not, the root metatable `__newindex` will then raise an error if the object was a userdata, or apply a rawset if the object was a Lua table.
-
-Other metaclass operators like `__tostring__`, `__add__`, etc... do not have any particular constraint.
-
-<a name="luat_newmetatable"/>
-### const char* luaT_newmetatable(lua_State *L, const char *tname, const char *parenttname, lua_CFunction constructor, lua_CFunction destructor, lua_CFunction factory) ###
-
-This function creates a new metatable, which is the Lua way to define a new
-object class. As for `luaL_newmetatable`, the metatable is registered in
-the Lua registry table, with the key `tname`. In addition, `tname` is
-also registered in the Lua registry, with the metatable as key (the
-typename of a given object can be thus easily retrieved).
-
-The class name `tname` must be of the form `modulename.classname`. The module name
-If not NULL, `parenttname` must be a valid typename corresponding to the
-parent class of the new class.
-
-If not NULL, `constructor`, a function `new` will be added to the metatable, pointing to this given function. The constructor might also
-be called through `modulename.classname()`, which is an alias setup by `luaT_metatable`.
-
-If not NULL, `destructor` will be called when garbage collecting the object.
-
-If not NULL, `factory` must be a Lua C function creating an empty object
-instance of the class. This functions are used in Torch for serialization.
-
-Note that classes can be partly defined in C and partly defined in Lua:
-once the metatable is created in C, it can be filled up with additional
-methods in Lua.
-
-The return value is the value returned by [luaT_typenameid](#luat_typenameid).
-
-<a name="luat_pushmetatable"/>
-### int luaT_pushmetatable(lua_State *L, const name *tname) ###
-
-Push the metatable with type name `tname` on the stack, it `tname` is a
-valid Torch class name (previously registered with luaT_newmetatable).
-
-On success, returns 1. If `tname` is invalid, nothing is pushed and it
-returns 0.
-
-<a name="luat_typenameid"/>
-### const char* luaT_typenameid(lua_State *L, const char *tname) ###
-
-If `tname` is a valid Torch class name, then returns a unique string (the
-contents will be the same than `tname`) pointing on the string registered
-in the Lua registry. This string is thus valid as long as Lua is
-running. The returned string shall not be freed.
-
-If `tname` is an invalid class name, returns NULL.
-
-<a name="luat_typename"/>
-### const char* luaT_typename(lua_State *L, int ud) ###
-
-Returns the typename of the object at index `ud` on the stack. If it is
-not a valid Torch object, returns NULL.
-
-<a name="luat_pushudata"/>
-### void luaT_pushudata(lua_State *L, void *udata, const char *tname) ###
-
-Given a C structure `udata`, push a userdata object on the stack with
-metatable corresponding to `tname`. Obviously, `tname` must be a valid
-Torch name registered with [luaT_newmetatable](#luat_newmetatable).
-
-<a name="luat_toudata"/>
-### void *luaT_toudata(lua_State *L, int ud, const char *tname) ###
-
-Returns a pointer to the original C structure previously pushed on the
-stack with [luaT_pushudata](#luat_pushudata), if the object at index
-`ud` is a valid Torch class name. Returns NULL otherwise.
-
-<a name="luat_isudata"/>
-### int luaT_isudata(lua_State *L, int ud, const char *tname) ###
-
-Returns 1 if the object at index `ud` on the stack is a valid Torch class name `tname`.
-Returns 0 otherwise.
-
-<a name="luat_getfield"/>
-### Checking fields of a table ###
-
-This functions check that the table at the given index `ud` on the Lua
-stack has a field named `field`, and that it is of the specified type.
-These function raises a Lua error on failure.
-
-<a name="luat_getfieldcheckudata"/>
-## void *luaT_getfieldcheckudata(lua_State *L, int ud, const char *field, const char *tname) ##
-
-Checks that the field named `field` of the table at index `ud` is a
-Torch class name `tname`. Returns the pointer of the C structure
-previously pushed on the stack with [luaT_pushudata](#luat_pushudata) on
-success. The function raises a Lua error on failure.
-
-<a name="luat_getfieldchecklightudata"/>
-## void *luaT_getfieldchecklightudata(lua_State *L, int ud, const char *field) ##
-
-Checks that the field named `field` of the table at index `ud` is a
-lightuserdata. Returns the lightuserdata pointer on success. The function
-raises a Lua error on failure.
-
-<a name="luat_getfieldcheckint"/>
-## int luaT_getfieldcheckint(lua_State *L, int ud, const char *field) ##
-
-Checks that the field named `field` of the table at index `ud` is an
-int. Returns the int value pointer on success. The function raises a Lua
-error on failure.
-
-<a name="luat_getfieldcheckstring"/>
-## const char* luaT_getfieldcheckstring(lua_State *L, int ud, const char *field) ##
-
-Checks that the field named `field` of the table at index `ud` is a
-string. Returns a pointer to the string on success. The function raises a
-Lua error on failure.
-
-<a name="luat_getfieldcheckboolean"/>
-## int luaT_getfieldcheckboolean(lua_State *L, int ud, const char *field) ##
-
-Checks that the field named `field` of the table at index `ud` is a
-boolean. On success, returns 1 if the boolean is `true`, 0 if it is
-`false`. The function raises a Lua error on failure.
-
-<a name="luat_getfieldchecktable"/>
-## void luaT_getfieldchecktable(lua_State *L, int ud, const char *field) ##
-
-Checks that the field named `field` of the table at index `ud` is a
-table. On success, push the table on the stack. The function raises a Lua
-error on failure.
-
-<a name="luat_typerror"/>
-### int luaT_typerror(lua_State *L, int ud, const char *tname) ###
-
-Raises a `luaL_argerror` (and returns its value), claiming that the
-object at index `ud` on the stack is not of type `tname`. Note that
-this function does not check the type, it only raises an error.
-
-<a name="luat_checkboolean"/>
-### int luaT_checkboolean(lua_State *L, int ud) ###
-
-Checks that the value at index `ud` is a boolean. On success, returns 1
-if the boolean is `true`, 0 if it is `false`. The function raises a Lua
-error on failure.
-
-<a name="luat_optboolean"/>
-### int luaT_optboolean(lua_State *L, int ud, int def) ###
-
-Checks that the value at index `ud` is a boolean. On success, returns 1
-if the boolean is `true`, 0 if it is `false`. If there is no value at
-index `ud`, returns `def`. In any other cases, raises an error.
-
-<a name="luat_registeratname"/>
-### void luaT_registeratname(lua_State *L, const struct luaL_Reg *methods, const char *name) ###
-
-This function assume a table is on the stack. It creates a table field
-`name` in the table (if this field does not exist yet), and fill up
-`methods` in this table field.
-
-<a name="luat_classrootname"/>
-### const char *luaT_classrootname(const char *tname) ###
-
-Assuming `tname` is of the form `modulename.classname`, returns
-`classname`. The returned value shall not be freed. It is a pointer
-inside `tname` string.
-
-<a name="luat_classmodulename"/>
-### const char *luaT_classmodulename(const char *tname) ###
-
-Assuming `tname` is of the form `modulename.classname`, returns
-`modulename`. The returned value shall not be freed. It is valid until the
-next call to `luaT_classrootname`.
-
-<a name="luat_stackdump"/>
-### void luaT_stackdump(lua_State *L) ###
-
-This function print outs the state of the Lua stack. It is useful for debug
-purposes.
-
diff --git a/luaT/luaT.c b/luaT/luaT.c
deleted file mode 100644
index 7b85ce3..0000000
--- a/luaT/luaT.c
+++ /dev/null
@@ -1,1079 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-
-#include "luaT.h"
-
-void* luaT_alloc(lua_State *L, long size)
-{
- void *ptr;
-
- if(size == 0)
- return NULL;
-
- if(size < 0)
- luaL_error(L, "$ Torch: invalid memory size -- maybe an overflow?");
-
- ptr = malloc(size);
- if(!ptr)
- luaL_error(L, "$ Torch: not enough memory: you tried to allocate %dGB. Buy new RAM!", size/1073741824);
-
- return ptr;
-}
-
-void* luaT_realloc(lua_State *L, void *ptr, long size)
-{
- if(!ptr)
- return(luaT_alloc(L, size));
-
- if(size == 0)
- {
- luaT_free(L, ptr);
- return NULL;
- }
-
- if(size < 0)
- luaL_error(L, "$ Torch: invalid memory size -- maybe an overflow?");
-
- ptr = realloc(ptr, size);
- if(!ptr)
- luaL_error(L, "$ Torch: not enough memory: you tried to reallocate %dGB. Buy new RAM!", size/1073741824);
- return ptr;
-}
-
-void luaT_free(lua_State *L, void *ptr)
-{
- free(ptr);
-}
-
-void luaT_stackdump(lua_State *L)
-{
- int i;
- const char *tname = NULL;
- int top = lua_gettop(L);
- for(i = 1; i <= top; i++)
- {
- int t = lua_type(L, i);
- printf("%3d. ", i);
- switch(t)
- {
- case LUA_TSTRING:
- printf("'%s'", lua_tostring(L,i));
- break;
- case LUA_TBOOLEAN:
- printf(lua_toboolean(L, i) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- printf("%g", lua_tonumber(L,i));
- break;
- case LUA_TUSERDATA:
- tname = luaT_typename(L, i);
- printf("userdata %lx [%s]", (long)lua_topointer(L, i), (tname ? tname : "not a Torch object"));
- break;
- case 10:
- tname = luaT_typename(L, i);
- printf("cdata %lx [%s]", (long)lua_topointer(L, i), (tname ? tname : "not a Torch object"));
- break;
- case LUA_TTABLE:
- lua_pushvalue(L, i);
- lua_rawget(L, LUA_REGISTRYINDEX);
- if(lua_isstring(L, -1))
- tname = lua_tostring(L, -1); /*luaT_typenameid(L, lua_tostring(L, -1)); */
- else
- tname = NULL;
- lua_pop(L, 1);
- if(tname)
- printf("metatable [%s]", tname);
- else
- {
- tname = luaT_typename(L, i);
- printf("table %lx [%s]", (long)lua_topointer(L, i), (tname ? tname : "not a Torch object"));
- }
- break;
- default:
- printf("Lua object type: %s", lua_typename(L,t));
- break;
- }
- printf("\n");
- }
- printf("---------------------------------------------\n");
-}
-
-/* metatable operator methods */
-static int luaT_mt__index(lua_State *L);
-static int luaT_mt__newindex(lua_State *L);
-static int luaT_mt__tostring(lua_State *L);
-static int luaT_mt__add(lua_State *L);
-static int luaT_mt__sub(lua_State *L);
-static int luaT_mt__mul(lua_State *L);
-static int luaT_mt__div(lua_State *L);
-static int luaT_mt__mod(lua_State *L);
-static int luaT_mt__pow(lua_State *L);
-static int luaT_mt__unm(lua_State *L);
-static int luaT_mt__concat(lua_State *L);
-static int luaT_mt__len(lua_State *L);
-static int luaT_mt__eq(lua_State *L);
-static int luaT_mt__lt(lua_State *L);
-static int luaT_mt__le(lua_State *L);
-static int luaT_mt__call(lua_State *L);
-
-/* Constructor-metatable methods */
-static int luaT_cmt__call(lua_State *L);
-static int luaT_cmt__newindex(lua_State *L);
-
-const char* luaT_newmetatable(lua_State *L, const char *tname, const char *parenttname,
- lua_CFunction constructor, lua_CFunction destructor, lua_CFunction factory)
-{
- lua_pushcfunction(L, luaT_lua_newmetatable);
- lua_pushstring(L, tname);
- (parenttname ? lua_pushstring(L, parenttname) : lua_pushnil(L));
- (constructor ? lua_pushcfunction(L, constructor) : lua_pushnil(L));
- (destructor ? lua_pushcfunction(L, destructor) : lua_pushnil(L));
- (factory ? lua_pushcfunction(L, factory) : lua_pushnil(L));
- lua_call(L, 5, 1);
- return luaT_typenameid(L, tname);
-}
-
-int luaT_pushmetatable(lua_State *L, const char *tname)
-{
- lua_getfield(L, LUA_REGISTRYINDEX, tname);
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1);
- return 0;
- }
- return 1;
-}
-
-const char *luaT_typenameid(lua_State *L, const char *tname)
-{
- if(luaT_pushmetatable(L, tname))
- {
- const char *tnameid = NULL;
- lua_rawget(L, LUA_REGISTRYINDEX);
- if(lua_isstring(L, -1))
- tnameid = lua_tostring(L, -1);
- lua_pop(L, 1); /* the string/nil */
- return tnameid;
- }
- return NULL;
-}
-
-static const char cdataname[] = ""
- "local _, ffi = pcall(require, 'ffi')\n"
- "if ffi then\n"
- " local id2name = {}\n"
- " return function(cdata, name)\n"
- " local id = tonumber(ffi.typeof(cdata))\n"
- " if id then\n"
- " if name then\n"
- " id2name[id] = name\n"
- " return name\n"
- " else\n"
- " return rawget(id2name, id)\n"
- " end\n"
- " end\n"
- " return nil\n"
- " end\n"
- "else\n"
- " return function() end\n"
- "end\n";
-
-static const char* luaT_cdataname(lua_State *L, int ud, const char *tname)
-{
- lua_pushstring(L, "__cdataname");
- lua_rawget(L, LUA_REGISTRYINDEX);
- if(lua_isnil(L,-1))
- {
- lua_pop(L, 1);
-
- if(luaL_dostring(L, cdataname)) /* did something go wrong? */
- luaL_error(L, "internal error (could not load cdataname): %s", lua_tostring(L, -1));
-
- lua_pushstring(L, "__cdataname");
- lua_pushvalue(L, -2);
- lua_rawset(L, LUA_REGISTRYINDEX);
- }
- if(!lua_isfunction(L, -1)) /* should not happen */
- luaL_error(L, "internal error (cdataname is not a function)");
-
- lua_pushvalue(L, ud);
- if(tname)
- lua_pushstring(L, tname);
- if(lua_pcall(L, (tname ? 2 : 1), 1, 0))
- luaL_error(L, "internal error (cdataname): %s", lua_tostring(L, -1));
-
- tname = lua_tostring(L, -1);
- lua_pop(L, 1);
-
- return tname;
-}
-
-const char* luaT_typename(lua_State *L, int ud)
-{
- if(lua_type(L, ud) == 10)
- return luaT_cdataname(L, ud, NULL);
- else if(lua_getmetatable(L, ud))
- {
- const char *tname = NULL;
- lua_rawget(L, LUA_REGISTRYINDEX);
- if(lua_isstring(L, -1))
- tname = lua_tostring(L, -1);
- lua_pop(L, 1); /* the string/nil */
- return tname;
- }
- return NULL;
-}
-
-void luaT_pushudata(lua_State *L, void *udata, const char *tname)
-{
- if(udata)
- {
- void **udata_p = lua_newuserdata(L, sizeof(void*));
- *udata_p = udata;
- if(!luaT_pushmetatable(L, tname))
- luaL_error(L, "Torch internal problem: cannot find metatable for type <%s>", tname);
- lua_setmetatable(L, -2);
- }
- else
- lua_pushnil(L);
-}
-
-void *luaT_toudata(lua_State *L, int ud, const char *tname)
-{
- void **p = lua_touserdata(L, ud);
- if(p != NULL) /* value is a userdata? */
- {
- if(!luaT_pushmetatable(L, tname))
- luaL_error(L, "Torch internal problem: cannot find metatable for type <%s>", tname);
-
- /* initialize the table we want to get the metatable on */
- /* note that we have to be careful with indices, as we just inserted stuff */
- lua_pushvalue(L, (ud < 0 ? ud - 1 : ud));
- while(lua_getmetatable(L, -1)) /* get the next metatable */
- {
- lua_remove(L, -2); /* remove the previous metatable [or object, if first time] */
- if(lua_rawequal(L, -1, -2))
- {
- lua_pop(L, 2); /* remove the two metatables */
- return *p;
- }
- }
- lua_pop(L, 2); /* remove the two metatables */
- }
- return NULL;
-}
-
-int luaT_isudata(lua_State *L, int ud, const char *tname)
-{
- if(luaT_toudata(L, ud, tname))
- return 1;
- else
- return 0;
-}
-
-void *luaT_checkudata(lua_State *L, int ud, const char *tname)
-{
- void *p = luaT_toudata(L, ud, tname);
- if(!p)
- luaT_typerror(L, ud, tname);
- return p;
-}
-
-void *luaT_getfieldcheckudata(lua_State *L, int ud, const char *field, const char *tname)
-{
- void *p;
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
- p = luaT_toudata(L, -1, tname);
- if(!p)
- luaL_error(L, "bad argument #%d (field %s is not a %s)", ud, field, tname);
- return p;
-}
-
-void *luaT_getfieldchecklightudata(lua_State *L, int ud, const char *field)
-{
- void *p;
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
-
- if(!lua_islightuserdata(L, -1))
- luaL_error(L, "bad argument #%d (field %s is not a light userdata)", ud, field);
-
- p = lua_touserdata(L, -1);
-
- return p;
-}
-
-double luaT_getfieldchecknumber(lua_State *L, int ud, const char *field)
-{
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
- if(!lua_isnumber(L, -1))
- luaL_error(L, "bad argument #%d (field %s is not a number)", ud, field);
- return lua_tonumber(L, -1);
-}
-
-int luaT_getfieldcheckint(lua_State *L, int ud, const char *field)
-{
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
- if(!lua_isnumber(L, -1))
- luaL_error(L, "bad argument #%d (field %s is not a number)", ud, field);
- return (int)lua_tonumber(L, -1);
-}
-
-const char* luaT_getfieldcheckstring(lua_State *L, int ud, const char *field)
-{
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
- if(!lua_isstring(L, -1))
- luaL_error(L, "bad argument #%d (field %s is not a string)", ud, field);
- return lua_tostring(L, -1);
-}
-
-int luaT_getfieldcheckboolean(lua_State *L, int ud, const char *field)
-{
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
- if(!lua_isboolean(L, -1))
- luaL_error(L, "bad argument #%d (field %s is not a boolean)", ud, field);
- return lua_toboolean(L, -1);
-}
-
-void luaT_getfieldchecktable(lua_State *L, int ud, const char *field)
-{
- lua_getfield(L, ud, field);
- if(lua_isnil(L, -1))
- luaL_error(L, "bad argument #%d (field %s does not exist)", ud, field);
- if(!lua_istable(L, -1))
- luaL_error(L, "bad argument #%d (field %s is not a table)", ud, field);
-}
-
-/**** type checks as in luaL ****/
-int luaT_typerror(lua_State *L, int ud, const char *tname)
-{
- const char *msg;
- const char *tnameud = luaT_typename(L, ud);
-
- if(!tnameud)
- tnameud = lua_typename(L, ud);
-
- msg = lua_pushfstring(L, "%s expected, got %s",
- tname,
- (tnameud ? tnameud : "unknown object"));
-
- return luaL_argerror(L, ud, msg);
-}
-
-int luaT_checkboolean(lua_State *L, int ud)
-{
- if(!lua_isboolean(L, ud))
- luaT_typerror(L, ud, lua_typename(L, LUA_TBOOLEAN));
- return lua_toboolean(L, ud);
-}
-
-int luaT_optboolean(lua_State *L, int ud, int def)
-{
- if(lua_isnoneornil(L,ud))
- return def;
-
- return luaT_checkboolean(L, ud);
-}
-
-void luaT_registeratname(lua_State *L, const struct luaL_Reg *methods, const char *name)
-{
- int idx = lua_gettop(L);
-
- luaL_checktype(L, idx, LUA_TTABLE);
- lua_pushstring(L, name);
- lua_rawget(L, idx);
-
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1);
- lua_pushstring(L, name);
- lua_newtable(L);
- lua_rawset(L, idx);
-
- lua_pushstring(L, name);
- lua_rawget(L, idx);
- }
-
- luaL_register(L, NULL, methods);
- lua_pop(L, 1);
-}
-
-
-/* utility functions */
-const char *luaT_classrootname(const char *tname)
-{
- int i;
- int sz = strlen(tname);
-
- for(i = 0; i < sz; i++)
- {
- if(tname[i] == '.')
- return tname+i+1;
- }
- return tname;
-}
-
-/* module_name must be a buffer at least as big as tname
- * return true if the class is part of a module */
-int luaT_classmodulename(const char *tname, char *module_name)
-{
- char chars[] = {'.', '\0'};
- size_t n;
- n = strcspn(tname, chars);
- strncpy(module_name, tname, n);
- module_name[n] = '\0';
- return tname[n] == '.';
-}
-
-/* Lua only functions */
-int luaT_lua_newmetatable(lua_State *L)
-{
- const char* tname = luaL_checkstring(L, 1);
- char module_name[256];
- int is_in_module = 0;
- is_in_module = luaT_classmodulename(tname, module_name);
-
- lua_settop(L, 5);
- luaL_argcheck(L, lua_isnoneornil(L, 2) || lua_isstring(L, 2), 2, "parent class name or nil expected");
- luaL_argcheck(L, lua_isnoneornil(L, 3) || lua_isfunction(L, 3), 3, "constructor function or nil expected");
- luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isfunction(L, 4), 4, "destructor function or nil expected");
- luaL_argcheck(L, lua_isnoneornil(L, 5) || lua_isfunction(L, 5), 5, "factory function or nil expected");
-
- if(is_in_module)
- lua_getfield(L, LUA_GLOBALSINDEX, module_name);
- else
- lua_pushvalue(L, LUA_GLOBALSINDEX);
- if(!lua_istable(L, 6))
- luaL_error(L, "while creating metatable %s: bad argument #1 (%s is an invalid module name)", tname, module_name);
-
- /* we first create the new metaclass if we have to */
- if(!luaT_pushmetatable(L, tname))
- {
- /* create the metatable */
- lua_newtable(L);
-
- /* registry[name] = metatable */
- lua_pushvalue(L, -1);
- lua_setfield(L, LUA_REGISTRYINDEX, tname);
-
- /* registry[metatable] = tname */
- lua_pushvalue(L, -1);
- lua_pushstring(L, tname);
- lua_rawset(L, LUA_REGISTRYINDEX);
-
- /* __index handling */
- lua_pushcfunction(L, luaT_mt__index);
- lua_setfield(L, -2, "__index");
-
- /* __newindex handling */
- lua_pushcfunction(L, luaT_mt__newindex);
- lua_setfield(L, -2, "__newindex");
-
- /* __typename contains the typename */
- lua_pushstring(L, tname);
- lua_setfield(L, -2, "__typename");
-
- /* __metatable is self */
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__metatable");
-
- /* by default, __version equals 1 */
- lua_pushnumber(L, 1);
- lua_setfield(L, -2, "__version");
-
- /* assign default operator functions */
- lua_pushcfunction(L, luaT_mt__tostring);
- lua_setfield(L, -2, "__tostring");
-
- lua_pushcfunction(L, luaT_mt__add);
- lua_setfield(L, -2, "__add");
-
- lua_pushcfunction(L, luaT_mt__sub);
- lua_setfield(L, -2, "__sub");
-
- lua_pushcfunction(L, luaT_mt__mul);
- lua_setfield(L, -2, "__mul");
-
- lua_pushcfunction(L, luaT_mt__div);
- lua_setfield(L, -2, "__div");
-
- lua_pushcfunction(L, luaT_mt__mod);
- lua_setfield(L, -2, "__mod");
-
- lua_pushcfunction(L, luaT_mt__pow);
- lua_setfield(L, -2, "__pow");
-
- lua_pushcfunction(L, luaT_mt__unm);
- lua_setfield(L, -2, "__unm");
-
- lua_pushcfunction(L, luaT_mt__concat);
- lua_setfield(L, -2, "__concat");
-
- lua_pushcfunction(L, luaT_mt__len);
- lua_setfield(L, -2, "__len");
-
- lua_pushcfunction(L, luaT_mt__eq);
- lua_setfield(L, -2, "__eq");
-
- lua_pushcfunction(L, luaT_mt__lt);
- lua_setfield(L, -2, "__lt");
-
- lua_pushcfunction(L, luaT_mt__le);
- lua_setfield(L, -2, "__le");
-
- lua_pushcfunction(L, luaT_mt__call);
- lua_setfield(L, -2, "__call");
- }
-
- /* we assign the parent class if necessary */
- if(!lua_isnoneornil(L, 2))
- {
- if(lua_getmetatable(L, -1))
- luaL_error(L, "class %s has been already assigned a parent class\n", tname);
- else
- {
- const char* parenttname = luaL_checkstring(L, 2);
- if(!luaT_pushmetatable(L, parenttname))
- luaL_error(L, "bad argument #2 (invalid parent class name %s)", parenttname);
- lua_setmetatable(L, -2);
- }
- }
-
- /* register the destructor function */
- if(!lua_isnoneornil(L, 4))
- {
- /* does it exists already? */
- lua_pushstring(L, "__gc");
- lua_rawget(L, -2);
-
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1); /* pop nil */
- lua_pushstring(L, "__gc");
- lua_pushvalue(L, 4);
- lua_rawset(L, -3);
- }
- else
- luaL_error(L, "%s has been already assigned a destructor", tname);
- }
-
- /* register the factory function */
- if(!lua_isnoneornil(L, 5))
- {
- /* does it exists already? */
- lua_pushstring(L, "__factory");
- lua_rawget(L, -2);
-
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1); /* pop nil */
- lua_pushstring(L, "__factory");
- lua_pushvalue(L, 5);
- lua_rawset(L, -3);
- }
- else
- luaL_error(L, "%s has been already assigned a factory", tname);
- }
-
- /******** Constructor table and metatable ********/
- lua_pushstring(L, "__constructor");
- lua_rawget(L, -2);
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1); /* pop nil */
- lua_newtable(L); /* fancy table */
- lua_newtable(L); /* fancy metatable */
-
- lua_pushvalue(L, -3); /* metatable */
- lua_setfield(L, -2, "__index"); /* so we can get the methods */
-
- lua_pushcfunction(L, luaT_cmt__newindex);
- lua_setfield(L, -2, "__newindex"); /* so we add new methods */
-
- lua_pushcfunction(L, luaT_cmt__call);
- lua_setfield(L, -2, "__call"); /* so we can create, we are here for only that */
-
- lua_pushvalue(L, -3);
- lua_setfield(L, -2, "__metatable"); /* redirect to metatable with methods */
-
- lua_setmetatable(L, -2); /* constructor metatable is ... this fancy metatable */
-
- /* set metatable[__constructor] = constructor-metatable */
- lua_pushstring(L, "__constructor");
- lua_pushvalue(L, -2);
- lua_rawset(L, -4);
- }
-
- /* register the constructor function */
- if(!lua_isnoneornil(L, 3))
- {
- /* get constructor metatable */
- lua_getmetatable(L, -1);
-
- /* does it exists already? */
- lua_pushstring(L, "__new");
- lua_rawget(L, -2);
-
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1); /* pop nil */
- lua_pushstring(L, "__new");
- lua_pushvalue(L, 3);
- lua_rawset(L, -3);
-
- /* set "new" in the metatable too */
- lua_pushstring(L, "new");
- lua_pushvalue(L, 3);
- lua_rawset(L, -5);
- }
- else
- luaL_error(L, "%s has been already assigned a constructor", tname);
-
- /* pop constructor metatable */
- lua_pop(L, 1);
- }
-
- /* module.name = constructor metatable */
- lua_setfield(L, 6, luaT_classrootname(tname));
-
- return 1; /* returns the metatable */
-}
-
-/* Lua only utility functions */
-
-/* add any custom type, provided the object has a metatable */
-int luaT_lua_metatype(lua_State *L)
-{
- if( (lua_gettop(L) != 2) && (lua_gettop(L) != 3) )
- luaL_error(L, "expecting: string table [ctype]");
-
- luaL_checkstring(L, 1);
- luaL_checktype(L, 2, LUA_TTABLE);
-
- if(lua_gettop(L) == 3)
- {
- if(!luaT_cdataname(L, 3, lua_tostring(L, 1)))
- luaL_error(L, "could not register cdata type -- missing ffi library?");
- }
-
- /* registry[name] = metatable */
- lua_pushvalue(L, 1);
- lua_pushvalue(L, 2);
- lua_rawset(L, LUA_REGISTRYINDEX);
-
- /* registry[metatable] = tname */
- lua_pushvalue(L, 2);
- lua_pushvalue(L, 1);
- lua_rawset(L, LUA_REGISTRYINDEX);
-
- return 0;
-}
-
-/* return a userdata from a C pointer */
-/* you are better to know what you are doing */
-int luaT_lua_pushudata(lua_State *L)
-{
- void *udata = NULL;
- const char *tname = luaL_checkstring(L, 2);
-
- if(lua_type(L, 1) == 10)
- udata = *((void**)lua_topointer(L, 1));
- else if(lua_isnumber(L, 1))
- udata = (void*)(long)lua_tonumber(L, 1);
- else
- luaL_argerror(L, 1, "expecting number or cdata");
-
- luaT_pushudata(L, udata, tname);
-
- return 1;
-}
-
-int luaT_lua_factory(lua_State *L)
-{
- const char* tname = luaL_checkstring(L, 1);
- if(luaT_pushmetatable(L, tname) && !lua_isnil(L, -1))
- {
- lua_pushstring(L, "__factory");
- lua_rawget(L, -2);
- }
- else
- {
- lua_pushnil(L);
- }
- return 1;
-}
-
-int luaT_lua_getconstructortable(lua_State *L)
-{
- const char* tname = luaL_checkstring(L, 1);
- if(luaT_pushmetatable(L, tname))
- {
- lua_pushstring(L, "__constructor");
- lua_rawget(L, -2);
- return 1;
- }
- return 0;
-}
-
-
-int luaT_lua_typename(lua_State *L)
-{
- const char* tname = NULL;
- luaL_checkany(L, 1);
- if((tname = luaT_typename(L, 1)))
- {
- lua_pushstring(L, tname);
- return 1;
- }
- return 0;
-}
-
-int luaT_lua_isequal(lua_State *L)
-{
- if(lua_isuserdata(L, 1) && lua_isuserdata(L, 2))
- {
- void **u1, **u2;
- luaL_argcheck(L, luaT_typename(L, 1), 1, "Torch object expected");
- luaL_argcheck(L, luaT_typename(L, 2), 2, "Torch object expected");
-
- u1 = lua_touserdata(L, 1);
- u2 = lua_touserdata(L, 2);
- if(*u1 == *u2)
- lua_pushboolean(L, 1);
- else
- lua_pushboolean(L, 0);
- }
- else if(lua_istable(L, 1) && lua_istable(L, 2))
- lua_pushboolean(L, lua_rawequal(L, 1, 2));
- else
- lua_pushboolean(L, 0);
- return 1;
-}
-
-int luaT_lua_pointer(lua_State *L)
-{
- if(lua_isuserdata(L, 1))
- {
- void **ptr;
- luaL_argcheck(L, luaT_typename(L, 1), 1, "Torch object expected");
- ptr = lua_touserdata(L, 1);
- lua_pushnumber(L, (long)(*ptr));
- return 1;
- }
- else if(lua_istable(L, 1) || lua_isthread(L, 1) || lua_isfunction(L, 1))
- {
- const void* ptr = lua_topointer(L, 1);
- lua_pushnumber(L, (long)(ptr));
- return 1;
- }
- else if(lua_type(L, 1) == 10) /* cdata */
- {
- /* we want the pointer holded by cdata */
- /* not the pointer on the cdata object */
- const void* ptr = *((void**)lua_topointer(L, 1));
- lua_pushnumber(L, (long)(ptr));
- return 1;
- }
- else if(lua_isstring(L, 1))
- {
- const char* ptr = lua_tostring(L, 1);
- lua_pushnumber(L, (long)(ptr));
- return 1;
- }
- else
- luaL_error(L, "Torch object, table, thread, cdata or function expected");
-
- return 0;
-}
-
-int luaT_lua_setenv(lua_State *L)
-{
- if(!lua_isfunction(L, 1) && !lua_isuserdata(L, 1))
- luaL_typerror(L, 1, "function or userdata");
- luaL_checktype(L, 2, LUA_TTABLE);
- lua_setfenv(L, 1);
- return 0;
-}
-
-int luaT_lua_getenv(lua_State *L)
-{
- if(!lua_isfunction(L, 1) &a