LUA updated to 5.3.0 upd
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
Lua License
|
||||
-----------
|
||||
|
||||
Lua is licensed under the terms of the MIT license reproduced below.
|
||||
This means that Lua is free software and can be used for both academic
|
||||
and commercial purposes at absolutely no cost.
|
||||
|
||||
For details and rationale, see http://www.lua.org/license.html .
|
||||
|
||||
===============================================================================
|
||||
|
||||
Copyright (C) 1994-2008 Lua.org, PUC-Rio.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
===============================================================================
|
||||
|
||||
(end of COPYRIGHT)
|
||||
@@ -1,183 +0,0 @@
|
||||
HISTORY for Lua 5.1
|
||||
|
||||
* Changes from version 5.0 to 5.1
|
||||
-------------------------------
|
||||
Language:
|
||||
+ new module system.
|
||||
+ new semantics for control variables of fors.
|
||||
+ new semantics for setn/getn.
|
||||
+ new syntax/semantics for varargs.
|
||||
+ new long strings and comments.
|
||||
+ new `mod' operator (`%')
|
||||
+ new length operator #t
|
||||
+ metatables for all types
|
||||
API:
|
||||
+ new functions: lua_createtable, lua_get(set)field, lua_push(to)integer.
|
||||
+ user supplies memory allocator (lua_open becomes lua_newstate).
|
||||
+ luaopen_* functions must be called through Lua.
|
||||
Implementation:
|
||||
+ new configuration scheme via luaconf.h.
|
||||
+ incremental garbage collection.
|
||||
+ better handling of end-of-line in the lexer.
|
||||
+ fully reentrant parser (new Lua function `load')
|
||||
+ better support for 64-bit machines.
|
||||
+ native loadlib support for Mac OS X.
|
||||
+ standard distribution in only one library (lualib.a merged into lua.a)
|
||||
|
||||
* Changes from version 4.0 to 5.0
|
||||
-------------------------------
|
||||
Language:
|
||||
+ lexical scoping.
|
||||
+ Lua coroutines.
|
||||
+ standard libraries now packaged in tables.
|
||||
+ tags replaced by metatables and tag methods replaced by metamethods,
|
||||
stored in metatables.
|
||||
+ proper tail calls.
|
||||
+ each function can have its own global table, which can be shared.
|
||||
+ new __newindex metamethod, called when we insert a new key into a table.
|
||||
+ new block comments: --[[ ... ]].
|
||||
+ new generic for.
|
||||
+ new weak tables.
|
||||
+ new boolean type.
|
||||
+ new syntax "local function".
|
||||
+ (f()) returns the first value returned by f.
|
||||
+ {f()} fills a table with all values returned by f.
|
||||
+ \n ignored in [[\n .
|
||||
+ fixed and-or priorities.
|
||||
+ more general syntax for function definition (e.g. function a.x.y:f()...end).
|
||||
+ more general syntax for function calls (e.g. (print or write)(9)).
|
||||
+ new functions (time/date, tmpfile, unpack, require, load*, etc.).
|
||||
API:
|
||||
+ chunks are loaded by using lua_load; new luaL_loadfile and luaL_loadbuffer.
|
||||
+ introduced lightweight userdata, a simple "void*" without a metatable.
|
||||
+ new error handling protocol: the core no longer prints error messages;
|
||||
all errors are reported to the caller on the stack.
|
||||
+ new lua_atpanic for host cleanup.
|
||||
+ new, signal-safe, hook scheme.
|
||||
Implementation:
|
||||
+ new license: MIT.
|
||||
+ new, faster, register-based virtual machine.
|
||||
+ support for external multithreading and coroutines.
|
||||
+ new and consistent error message format.
|
||||
+ the core no longer needs "stdio.h" for anything (except for a single
|
||||
use of sprintf to convert numbers to strings).
|
||||
+ lua.c now runs the environment variable LUA_INIT, if present. It can
|
||||
be "@filename", to run a file, or the chunk itself.
|
||||
+ support for user extensions in lua.c.
|
||||
sample implementation given for command line editing.
|
||||
+ new dynamic loading library, active by default on several platforms.
|
||||
+ safe garbage-collector metamethods.
|
||||
+ precompiled bytecodes checked for integrity (secure binary dostring).
|
||||
+ strings are fully aligned.
|
||||
+ position capture in string.find.
|
||||
+ read('*l') can read lines with embedded zeros.
|
||||
|
||||
* Changes from version 3.2 to 4.0
|
||||
-------------------------------
|
||||
Language:
|
||||
+ new "break" and "for" statements (both numerical and for tables).
|
||||
+ uniform treatment of globals: globals are now stored in a Lua table.
|
||||
+ improved error messages.
|
||||
+ no more '$debug': full speed *and* full debug information.
|
||||
+ new read form: read(N) for next N bytes.
|
||||
+ general read patterns now deprecated.
|
||||
(still available with -DCOMPAT_READPATTERNS.)
|
||||
+ all return values are passed as arguments for the last function
|
||||
(old semantics still available with -DLUA_COMPAT_ARGRET)
|
||||
+ garbage collection tag methods for tables now deprecated.
|
||||
+ there is now only one tag method for order.
|
||||
API:
|
||||
+ New API: fully re-entrant, simpler, and more efficient.
|
||||
+ New debug API.
|
||||
Implementation:
|
||||
+ faster than ever: cleaner virtual machine and new hashing algorithm.
|
||||
+ non-recursive garbage-collector algorithm.
|
||||
+ reduced memory usage for programs with many strings.
|
||||
+ improved treatment for memory allocation errors.
|
||||
+ improved support for 16-bit machines (we hope).
|
||||
+ code now compiles unmodified as both ANSI C and C++.
|
||||
+ numbers in bases other than 10 are converted using strtoul.
|
||||
+ new -f option in Lua to support #! scripts.
|
||||
+ luac can now combine text and binaries.
|
||||
|
||||
* Changes from version 3.1 to 3.2
|
||||
-------------------------------
|
||||
+ redirected all output in Lua's core to _ERRORMESSAGE and _ALERT.
|
||||
+ increased limit on the number of constants and globals per function
|
||||
(from 2^16 to 2^24).
|
||||
+ debugging info (lua_debug and hooks) moved into lua_state and new API
|
||||
functions provided to get and set this info.
|
||||
+ new debug lib gives full debugging access within Lua.
|
||||
+ new table functions "foreachi", "sort", "tinsert", "tremove", "getn".
|
||||
+ new io functions "flush", "seek".
|
||||
|
||||
* Changes from version 3.0 to 3.1
|
||||
-------------------------------
|
||||
+ NEW FEATURE: anonymous functions with closures (via "upvalues").
|
||||
+ new syntax:
|
||||
- local variables in chunks.
|
||||
- better scope control with DO block END.
|
||||
- constructors can now be also written: { record-part; list-part }.
|
||||
- more general syntax for function calls and lvalues, e.g.:
|
||||
f(x).y=1
|
||||
o:f(x,y):g(z)
|
||||
f"string" is sugar for f("string")
|
||||
+ strings may now contain arbitrary binary data (e.g., embedded zeros).
|
||||
+ major code re-organization and clean-up; reduced module interdependecies.
|
||||
+ no arbitrary limits on the total number of constants and globals.
|
||||
+ support for multiple global contexts.
|
||||
+ better syntax error messages.
|
||||
+ new traversal functions "foreach" and "foreachvar".
|
||||
+ the default for numbers is now double.
|
||||
changing it to use floats or longs is easy.
|
||||
+ complete debug information stored in pre-compiled chunks.
|
||||
+ sample interpreter now prompts user when run interactively, and also
|
||||
handles control-C interruptions gracefully.
|
||||
|
||||
* Changes from version 2.5 to 3.0
|
||||
-------------------------------
|
||||
+ NEW CONCEPT: "tag methods".
|
||||
Tag methods replace fallbacks as the meta-mechanism for extending the
|
||||
semantics of Lua. Whereas fallbacks had a global nature, tag methods
|
||||
work on objects having the same tag (e.g., groups of tables).
|
||||
Existing code that uses fallbacks should work without change.
|
||||
+ new, general syntax for constructors {[exp] = exp, ... }.
|
||||
+ support for handling variable number of arguments in functions (varargs).
|
||||
+ support for conditional compilation ($if ... $else ... $end).
|
||||
+ cleaner semantics in API simplifies host code.
|
||||
+ better support for writing libraries (auxlib.h).
|
||||
+ better type checking and error messages in the standard library.
|
||||
+ luac can now also undump.
|
||||
|
||||
* Changes from version 2.4 to 2.5
|
||||
-------------------------------
|
||||
+ io and string libraries are now based on pattern matching;
|
||||
the old libraries are still available for compatibility
|
||||
+ dofile and dostring can now return values (via return statement)
|
||||
+ better support for 16- and 64-bit machines
|
||||
+ expanded documentation, with more examples
|
||||
|
||||
* Changes from version 2.2 to 2.4
|
||||
-------------------------------
|
||||
+ external compiler creates portable binary files that can be loaded faster
|
||||
+ interface for debugging and profiling
|
||||
+ new "getglobal" fallback
|
||||
+ new functions for handling references to Lua objects
|
||||
+ new functions in standard lib
|
||||
+ only one copy of each string is stored
|
||||
+ expanded documentation, with more examples
|
||||
|
||||
* Changes from version 2.1 to 2.2
|
||||
-------------------------------
|
||||
+ functions now may be declared with any "lvalue" as a name
|
||||
+ garbage collection of functions
|
||||
+ support for pipes
|
||||
|
||||
* Changes from version 1.1 to 2.1
|
||||
-------------------------------
|
||||
+ object-oriented support
|
||||
+ fallbacks
|
||||
+ simplified syntax for tables
|
||||
+ many internal improvements
|
||||
|
||||
(end of HISTORY)
|
||||
@@ -1,99 +0,0 @@
|
||||
INSTALL for Lua 5.1
|
||||
|
||||
* Building Lua
|
||||
------------
|
||||
Lua is built in the src directory, but the build process can be
|
||||
controlled from the top-level Makefile.
|
||||
|
||||
Building Lua on Unix systems should be very easy. First do "make" and
|
||||
see if your platform is listed. If so, just do "make xxx", where xxx
|
||||
is your platform name. The platforms currently supported are:
|
||||
aix ansi bsd freebsd generic linux macosx mingw posix solaris
|
||||
|
||||
If your platform is not listed, try the closest one or posix, generic,
|
||||
ansi, in this order.
|
||||
|
||||
See below for customization instructions and for instructions on how
|
||||
to build with other Windows compilers.
|
||||
|
||||
If you want to check that Lua has been built correctly, do "make test"
|
||||
after building Lua. Also, have a look at the example programs in test.
|
||||
|
||||
* Installing Lua
|
||||
--------------
|
||||
Once you have built Lua, you may want to install it in an official
|
||||
place in your system. In this case, do "make install". The official
|
||||
place and the way to install files are defined in Makefile. You must
|
||||
have the right permissions to install files.
|
||||
|
||||
If you want to build and install Lua in one step, do "make xxx install",
|
||||
where xxx is your platform name.
|
||||
|
||||
If you want to install Lua locally, then do "make local". This will
|
||||
create directories bin, include, lib, man, and install Lua there as
|
||||
follows:
|
||||
|
||||
bin: lua luac
|
||||
include: lua.h luaconf.h lualib.h lauxlib.h lua.hpp
|
||||
lib: liblua.a
|
||||
man/man1: lua.1 luac.1
|
||||
|
||||
These are the only directories you need for development.
|
||||
|
||||
There are man pages for lua and luac, in both nroff and html, and a
|
||||
reference manual in html in doc, some sample code in test, and some
|
||||
useful stuff in etc. You don't need these directories for development.
|
||||
|
||||
If you want to install Lua locally, but in some other directory, do
|
||||
"make install INSTALL_TOP=xxx", where xxx is your chosen directory.
|
||||
|
||||
See below for instructions for Windows and other systems.
|
||||
|
||||
* Customization
|
||||
-------------
|
||||
Three things can be customized by editing a file:
|
||||
- Where and how to install Lua -- edit Makefile.
|
||||
- How to build Lua -- edit src/Makefile.
|
||||
- Lua features -- edit src/luaconf.h.
|
||||
|
||||
You don't actually need to edit the Makefiles because you may set the
|
||||
relevant variables when invoking make.
|
||||
|
||||
On the other hand, if you need to select some Lua features, you'll need
|
||||
to edit src/luaconf.h. The edited file will be the one installed, and
|
||||
it will be used by any Lua clients that you build, to ensure consistency.
|
||||
|
||||
We strongly recommend that you enable dynamic loading. This is done
|
||||
automatically for all platforms listed above that have this feature
|
||||
(and also Windows). See src/luaconf.h and also src/Makefile.
|
||||
|
||||
* Building Lua on Windows and other systems
|
||||
-----------------------------------------
|
||||
If you're not using the usual Unix tools, then the instructions for
|
||||
building Lua depend on the compiler you use. You'll need to create
|
||||
projects (or whatever your compiler uses) for building the library,
|
||||
the interpreter, and the compiler, as follows:
|
||||
|
||||
library: lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c
|
||||
lmem.c lobject.c lopcodes.c lparser.c lstate.c lstring.c
|
||||
ltable.c ltm.c lundump.c lvm.c lzio.c
|
||||
lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c
|
||||
ltablib.c lstrlib.c loadlib.c linit.c
|
||||
|
||||
interpreter: library, lua.c
|
||||
|
||||
compiler: library, luac.c print.c
|
||||
|
||||
If you use Visual Studio .NET, you can use etc/luavs.bat in its
|
||||
"Command Prompt".
|
||||
|
||||
If all you want is to build the Lua interpreter, you may put all .c files
|
||||
in a single project, except for luac.c and print.c. Or just use etc/all.c.
|
||||
|
||||
To use Lua as a library in your own programs, you'll need to know how to
|
||||
create and use libraries with your compiler.
|
||||
|
||||
As mentioned above, you may edit luaconf.h to select some features before
|
||||
building Lua.
|
||||
|
||||
(end of INSTALL)
|
||||
@@ -1,186 +0,0 @@
|
||||
/* tolua
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TOLUA_H
|
||||
#define TOLUA_H
|
||||
|
||||
#ifndef TOLUA_API
|
||||
#define TOLUA_API extern
|
||||
#endif
|
||||
|
||||
#define TOLUA_VERSION "tolua++-1.0.92"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define tolua_pushcppstring(x,y) tolua_pushstring(x,y.c_str())
|
||||
#define tolua_iscppstring tolua_isstring
|
||||
|
||||
#define tolua_iscppstringarray tolua_isstringarray
|
||||
#define tolua_pushfieldcppstring(L,lo,idx,s) tolua_pushfieldstring(L, lo, idx, s.c_str())
|
||||
|
||||
#ifndef TEMPLATE_BIND
|
||||
#define TEMPLATE_BIND(p)
|
||||
#endif
|
||||
|
||||
#define TOLUA_TEMPLATE_BIND(p)
|
||||
|
||||
#define TOLUA_PROTECTED_DESTRUCTOR
|
||||
#define TOLUA_PROPERTY_TYPE(p)
|
||||
|
||||
typedef int lua_Object;
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
struct tolua_Error
|
||||
{
|
||||
int index;
|
||||
int array;
|
||||
const char* type;
|
||||
};
|
||||
typedef struct tolua_Error tolua_Error;
|
||||
|
||||
#define TOLUA_NOPEER LUA_REGISTRYINDEX /* for lua 5.1 */
|
||||
|
||||
TOLUA_API const char* tolua_typename (lua_State* L, int lo);
|
||||
TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err);
|
||||
TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err);
|
||||
TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isvaluenil (lua_State* L, int lo, tolua_Error* err);
|
||||
TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isvaluearray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isbooleanarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isnumberarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isstringarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_istablearray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isuserdataarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err);
|
||||
TOLUA_API int tolua_isusertypearray
|
||||
(lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err);
|
||||
|
||||
TOLUA_API void tolua_open (lua_State* L);
|
||||
|
||||
TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size);
|
||||
TOLUA_API int tolua_register_gc (lua_State* L, int lo);
|
||||
TOLUA_API int tolua_default_collect (lua_State* tolua_S);
|
||||
|
||||
TOLUA_API void tolua_usertype (lua_State* L, const char* type);
|
||||
TOLUA_API void tolua_beginmodule (lua_State* L, const char* name);
|
||||
TOLUA_API void tolua_endmodule (lua_State* L);
|
||||
TOLUA_API void tolua_module (lua_State* L, const char* name, int hasvar);
|
||||
TOLUA_API void tolua_class (lua_State* L, const char* name, const char* base);
|
||||
TOLUA_API void tolua_cclass (lua_State* L, const char* lname, const char* name, const char* base, lua_CFunction col);
|
||||
TOLUA_API void tolua_function (lua_State* L, const char* name, lua_CFunction func);
|
||||
TOLUA_API void tolua_constant (lua_State* L, const char* name, lua_Number value);
|
||||
TOLUA_API void tolua_variable (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set);
|
||||
TOLUA_API void tolua_array (lua_State* L,const char* name, lua_CFunction get, lua_CFunction set);
|
||||
|
||||
/* TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type); */
|
||||
/* TOLUA_API void tolua_addbase(lua_State* L, char* name, char* base); */
|
||||
|
||||
TOLUA_API void tolua_pushvalue (lua_State* L, int lo);
|
||||
TOLUA_API void tolua_pushboolean (lua_State* L, int value);
|
||||
TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value);
|
||||
TOLUA_API void tolua_pushstring (lua_State* L, const char* value);
|
||||
TOLUA_API void tolua_pushuserdata (lua_State* L, void* value);
|
||||
TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type);
|
||||
TOLUA_API void tolua_pushusertype_and_takeownership(lua_State* L, void* value, const char* type);
|
||||
TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v);
|
||||
TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v);
|
||||
TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v);
|
||||
TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v);
|
||||
TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v);
|
||||
TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type);
|
||||
TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type);
|
||||
|
||||
TOLUA_API lua_Number tolua_tonumber (lua_State* L, int narg, lua_Number def);
|
||||
TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def);
|
||||
TOLUA_API void* tolua_touserdata (lua_State* L, int narg, void* def);
|
||||
TOLUA_API void* tolua_tousertype (lua_State* L, int narg, void* def);
|
||||
TOLUA_API int tolua_tovalue (lua_State* L, int narg, int def);
|
||||
TOLUA_API int tolua_toboolean (lua_State* L, int narg, int def);
|
||||
TOLUA_API lua_Number tolua_tofieldnumber (lua_State* L, int lo, int index, lua_Number def);
|
||||
TOLUA_API const char* tolua_tofieldstring (lua_State* L, int lo, int index, const char* def);
|
||||
TOLUA_API void* tolua_tofielduserdata (lua_State* L, int lo, int index, void* def);
|
||||
TOLUA_API void* tolua_tofieldusertype (lua_State* L, int lo, int index, void* def);
|
||||
TOLUA_API int tolua_tofieldvalue (lua_State* L, int lo, int index, int def);
|
||||
TOLUA_API int tolua_getfieldboolean (lua_State* L, int lo, int index, int def);
|
||||
|
||||
TOLUA_API void tolua_dobuffer(lua_State* L, char* B, unsigned int size, const char* name);
|
||||
|
||||
TOLUA_API int class_gc_event (lua_State* L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
static inline const char* tolua_tocppstring (lua_State* L, int narg, const char* def) {
|
||||
|
||||
const char* s = tolua_tostring(L, narg, def);
|
||||
return s?s:"";
|
||||
};
|
||||
|
||||
static inline const char* tolua_tofieldcppstring (lua_State* L, int lo, int index, const char* def) {
|
||||
|
||||
const char* s = tolua_tofieldstring(L, lo, index, def);
|
||||
return s?s:"";
|
||||
};
|
||||
|
||||
#else
|
||||
#define tolua_tocppstring tolua_tostring
|
||||
#define tolua_tofieldcppstring tolua_tofieldstring
|
||||
#endif
|
||||
|
||||
TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index);
|
||||
|
||||
#ifndef Mtolua_new
|
||||
#define Mtolua_new(EXP) new EXP
|
||||
#endif
|
||||
|
||||
#ifndef Mtolua_delete
|
||||
#define Mtolua_delete(EXP) delete EXP
|
||||
#endif
|
||||
|
||||
#ifndef Mtolua_new_dim
|
||||
#define Mtolua_new_dim(EXP, len) new EXP[len]
|
||||
#endif
|
||||
|
||||
#ifndef Mtolua_delete_dim
|
||||
#define Mtolua_delete_dim(EXP) delete [] EXP
|
||||
#endif
|
||||
|
||||
#ifndef tolua_outside
|
||||
#define tolua_outside
|
||||
#endif
|
||||
|
||||
#ifndef tolua_owned
|
||||
#define tolua_owned
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,227 +0,0 @@
|
||||
/*
|
||||
** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $
|
||||
** print bytecodes
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define luac_c
|
||||
#define LUA_CORE
|
||||
|
||||
#include "ldebug.h"
|
||||
#include "lobject.h"
|
||||
#include "lopcodes.h"
|
||||
#include "lundump.h"
|
||||
|
||||
#define PrintFunction luaU_print
|
||||
|
||||
#define Sizeof(x) ((int)sizeof(x))
|
||||
#define VOID(p) ((const void*)(p))
|
||||
|
||||
static void PrintString(const TString* ts)
|
||||
{
|
||||
const char* s=getstr(ts);
|
||||
size_t i,n=ts->tsv.len;
|
||||
putchar('"');
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
int c=s[i];
|
||||
switch (c)
|
||||
{
|
||||
case '"': printf("\\\""); break;
|
||||
case '\\': printf("\\\\"); break;
|
||||
case '\a': printf("\\a"); break;
|
||||
case '\b': printf("\\b"); break;
|
||||
case '\f': printf("\\f"); break;
|
||||
case '\n': printf("\\n"); break;
|
||||
case '\r': printf("\\r"); break;
|
||||
case '\t': printf("\\t"); break;
|
||||
case '\v': printf("\\v"); break;
|
||||
default: if (isprint((unsigned char)c))
|
||||
putchar(c);
|
||||
else
|
||||
printf("\\%03u",(unsigned char)c);
|
||||
}
|
||||
}
|
||||
putchar('"');
|
||||
}
|
||||
|
||||
static void PrintConstant(const Proto* f, int i)
|
||||
{
|
||||
const TValue* o=&f->k[i];
|
||||
switch (ttype(o))
|
||||
{
|
||||
case LUA_TNIL:
|
||||
printf("nil");
|
||||
break;
|
||||
case LUA_TBOOLEAN:
|
||||
printf(bvalue(o) ? "true" : "false");
|
||||
break;
|
||||
case LUA_TNUMBER:
|
||||
printf(LUA_NUMBER_FMT,nvalue(o));
|
||||
break;
|
||||
case LUA_TSTRING:
|
||||
PrintString(rawtsvalue(o));
|
||||
break;
|
||||
default: /* cannot happen */
|
||||
printf("? type=%d",ttype(o));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintCode(const Proto* f)
|
||||
{
|
||||
const Instruction* code=f->code;
|
||||
int pc,n=f->sizecode;
|
||||
for (pc=0; pc<n; pc++)
|
||||
{
|
||||
Instruction i=code[pc];
|
||||
OpCode o=GET_OPCODE(i);
|
||||
int a=GETARG_A(i);
|
||||
int b=GETARG_B(i);
|
||||
int c=GETARG_C(i);
|
||||
int bx=GETARG_Bx(i);
|
||||
int sbx=GETARG_sBx(i);
|
||||
int line=getline(f,pc);
|
||||
printf("\t%d\t",pc+1);
|
||||
if (line>0) printf("[%d]\t",line); else printf("[-]\t");
|
||||
printf("%-9s\t",luaP_opnames[o]);
|
||||
switch (getOpMode(o))
|
||||
{
|
||||
case iABC:
|
||||
printf("%d",a);
|
||||
if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
|
||||
if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
|
||||
break;
|
||||
case iABx:
|
||||
if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
|
||||
break;
|
||||
case iAsBx:
|
||||
if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
|
||||
break;
|
||||
}
|
||||
switch (o)
|
||||
{
|
||||
case OP_LOADK:
|
||||
printf("\t; "); PrintConstant(f,bx);
|
||||
break;
|
||||
case OP_GETUPVAL:
|
||||
case OP_SETUPVAL:
|
||||
printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
|
||||
break;
|
||||
case OP_GETGLOBAL:
|
||||
case OP_SETGLOBAL:
|
||||
printf("\t; %s",svalue(&f->k[bx]));
|
||||
break;
|
||||
case OP_GETTABLE:
|
||||
case OP_SELF:
|
||||
if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
|
||||
break;
|
||||
case OP_SETTABLE:
|
||||
case OP_ADD:
|
||||
case OP_SUB:
|
||||
case OP_MUL:
|
||||
case OP_DIV:
|
||||
case OP_POW:
|
||||
case OP_EQ:
|
||||
case OP_LT:
|
||||
case OP_LE:
|
||||
if (ISK(b) || ISK(c))
|
||||
{
|
||||
printf("\t; ");
|
||||
if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
|
||||
printf(" ");
|
||||
if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
|
||||
}
|
||||
break;
|
||||
case OP_JMP:
|
||||
case OP_FORLOOP:
|
||||
case OP_FORPREP:
|
||||
printf("\t; to %d",sbx+pc+2);
|
||||
break;
|
||||
case OP_CLOSURE:
|
||||
printf("\t; %p",VOID(f->p[bx]));
|
||||
break;
|
||||
case OP_SETLIST:
|
||||
if (c==0) printf("\t; %d",(int)code[++pc]);
|
||||
else printf("\t; %d",c);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#define SS(x) (x==1)?"":"s"
|
||||
#define S(x) x,SS(x)
|
||||
|
||||
static void PrintHeader(const Proto* f)
|
||||
{
|
||||
const char* s=getstr(f->source);
|
||||
if (*s=='@' || *s=='=')
|
||||
s++;
|
||||
else if (*s==LUA_SIGNATURE[0])
|
||||
s="(bstring)";
|
||||
else
|
||||
s="(string)";
|
||||
printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
|
||||
(f->linedefined==0)?"main":"function",s,
|
||||
f->linedefined,f->lastlinedefined,
|
||||
S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
|
||||
printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
|
||||
f->numparams,f->is_vararg?"+":"",SS(f->numparams),
|
||||
S(f->maxstacksize),S(f->nups));
|
||||
printf("%d local%s, %d constant%s, %d function%s\n",
|
||||
S(f->sizelocvars),S(f->sizek),S(f->sizep));
|
||||
}
|
||||
|
||||
static void PrintConstants(const Proto* f)
|
||||
{
|
||||
int i,n=f->sizek;
|
||||
printf("constants (%d) for %p:\n",n,VOID(f));
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
printf("\t%d\t",i+1);
|
||||
PrintConstant(f,i);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintLocals(const Proto* f)
|
||||
{
|
||||
int i,n=f->sizelocvars;
|
||||
printf("locals (%d) for %p:\n",n,VOID(f));
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
printf("\t%d\t%s\t%d\t%d\n",
|
||||
i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintUpvalues(const Proto* f)
|
||||
{
|
||||
int i,n=f->sizeupvalues;
|
||||
printf("upvalues (%d) for %p:\n",n,VOID(f));
|
||||
if (f->upvalues==NULL) return;
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void PrintFunction(const Proto* f, int full)
|
||||
{
|
||||
int i,n=f->sizep;
|
||||
PrintHeader(f);
|
||||
PrintCode(f);
|
||||
if (full)
|
||||
{
|
||||
PrintConstants(f);
|
||||
PrintLocals(f);
|
||||
PrintUpvalues(f);
|
||||
}
|
||||
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
|
||||
}
|
||||
@@ -1,536 +0,0 @@
|
||||
/* tolua: event functions
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "tolua++.h"
|
||||
|
||||
/* Store at ubox
|
||||
* It stores, creating the corresponding table if needed,
|
||||
* the pair key/value in the corresponding ubox table
|
||||
*/
|
||||
static void storeatubox (lua_State* L, int lo)
|
||||
{
|
||||
#ifdef LUA_VERSION_NUM
|
||||
lua_getfenv(L, lo);
|
||||
if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfenv(L, lo); /* stack: k,v,table */
|
||||
};
|
||||
lua_insert(L, -3);
|
||||
lua_settable(L, -3); /* on lua 5.1, we trade the "tolua_peers" lookup for a settable call */
|
||||
lua_pop(L, 1);
|
||||
#else
|
||||
/* stack: key value (to be stored) */
|
||||
lua_pushstring(L,"tolua_peers");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: k v ubox */
|
||||
lua_pushvalue(L,lo);
|
||||
lua_rawget(L,-2); /* stack: k v ubox ubox[u] */
|
||||
if (!lua_istable(L,-1))
|
||||
{
|
||||
lua_pop(L,1); /* stack: k v ubox */
|
||||
lua_newtable(L); /* stack: k v ubox table */
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,-2); /* stack: k v ubox table u table */
|
||||
lua_rawset(L,-4); /* stack: k v ubox ubox[u]=table */
|
||||
}
|
||||
lua_insert(L,-4); /* put table before k */
|
||||
lua_pop(L,1); /* pop ubox */
|
||||
lua_rawset(L,-3); /* store at table */
|
||||
lua_pop(L,1); /* pop ubox[u] */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Module index function
|
||||
*/
|
||||
static int module_index_event (lua_State* L)
|
||||
{
|
||||
lua_pushstring(L,".get");
|
||||
lua_rawget(L,-3);
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,2); /* key */
|
||||
lua_rawget(L,-2);
|
||||
if (lua_iscfunction(L,-1))
|
||||
{
|
||||
lua_call(L,0,1);
|
||||
return 1;
|
||||
}
|
||||
else if (lua_istable(L,-1))
|
||||
return 1;
|
||||
}
|
||||
/* call old index meta event */
|
||||
if (lua_getmetatable(L,1))
|
||||
{
|
||||
lua_pushstring(L,"__index");
|
||||
lua_rawget(L,-2);
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_call(L,2,1);
|
||||
return 1;
|
||||
}
|
||||
else if (lua_istable(L,-1))
|
||||
{
|
||||
lua_gettable(L,-3);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Module newindex function
|
||||
*/
|
||||
static int module_newindex_event (lua_State* L)
|
||||
{
|
||||
lua_pushstring(L,".set");
|
||||
lua_rawget(L,-4);
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,2); /* key */
|
||||
lua_rawget(L,-2);
|
||||
if (lua_iscfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1); /* only to be compatible with non-static vars */
|
||||
lua_pushvalue(L,3); /* value */
|
||||
lua_call(L,2,0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* call old newindex meta event */
|
||||
if (lua_getmetatable(L,1) && lua_getmetatable(L,-1))
|
||||
{
|
||||
lua_pushstring(L,"__newindex");
|
||||
lua_rawget(L,-2);
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
lua_pushvalue(L,3);
|
||||
lua_call(L,3,0);
|
||||
}
|
||||
}
|
||||
lua_settop(L,3);
|
||||
lua_rawset(L,-3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Class index function
|
||||
* If the object is a userdata (ie, an object), it searches the field in
|
||||
* the alternative table stored in the corresponding "ubox" table.
|
||||
*/
|
||||
static int class_index_event (lua_State* L)
|
||||
{
|
||||
int t = lua_type(L,1);
|
||||
if (t == LUA_TUSERDATA)
|
||||
{
|
||||
/* Access alternative table */
|
||||
#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */
|
||||
lua_getfenv(L,1);
|
||||
if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {
|
||||
lua_pushvalue(L, 2); /* key */
|
||||
lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */
|
||||
if (!lua_isnil(L, -1))
|
||||
return 1;
|
||||
};
|
||||
#else
|
||||
lua_pushstring(L,"tolua_peers");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: obj key ubox */
|
||||
lua_pushvalue(L,1);
|
||||
lua_rawget(L,-2); /* stack: obj key ubox ubox[u] */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,2); /* key */
|
||||
lua_rawget(L,-2); /* stack: obj key ubox ubox[u] value */
|
||||
if (!lua_isnil(L,-1))
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
lua_settop(L,2); /* stack: obj key */
|
||||
/* Try metatables */
|
||||
lua_pushvalue(L,1); /* stack: obj key obj */
|
||||
while (lua_getmetatable(L,-1))
|
||||
{ /* stack: obj key obj mt */
|
||||
lua_remove(L,-2); /* stack: obj key mt */
|
||||
if (lua_isnumber(L,2)) /* check if key is a numeric value */
|
||||
{
|
||||
/* try operator[] */
|
||||
lua_pushstring(L,".geti");
|
||||
lua_rawget(L,-2); /* stack: obj key mt func */
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
lua_call(L,2,1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushvalue(L,2); /* stack: obj key mt key */
|
||||
lua_rawget(L,-2); /* stack: obj key mt value */
|
||||
if (!lua_isnil(L,-1))
|
||||
return 1;
|
||||
else
|
||||
lua_pop(L,1);
|
||||
/* try C/C++ variable */
|
||||
lua_pushstring(L,".get");
|
||||
lua_rawget(L,-2); /* stack: obj key mt tget */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,2);
|
||||
lua_rawget(L,-2); /* stack: obj key mt value */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
lua_call(L,2,1);
|
||||
return 1;
|
||||
}
|
||||
else if (lua_istable(L,-1))
|
||||
{
|
||||
/* deal with array: create table to be returned and cache it in ubox */
|
||||
void* u = *((void**)lua_touserdata(L,1));
|
||||
lua_newtable(L); /* stack: obj key mt value table */
|
||||
lua_pushstring(L,".self");
|
||||
lua_pushlightuserdata(L,u);
|
||||
lua_rawset(L,-3); /* store usertype in ".self" */
|
||||
lua_insert(L,-2); /* stack: obj key mt table value */
|
||||
lua_setmetatable(L,-2); /* set stored value as metatable */
|
||||
lua_pushvalue(L,-1); /* stack: obj key met table table */
|
||||
lua_pushvalue(L,2); /* stack: obj key mt table table key */
|
||||
lua_insert(L,-2); /* stack: obj key mt table key table */
|
||||
storeatubox(L,1); /* stack: obj key mt table */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
lua_settop(L,3);
|
||||
}
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
else if (t== LUA_TTABLE)
|
||||
{
|
||||
module_index_event(L);
|
||||
return 1;
|
||||
}
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Newindex function
|
||||
* It first searches for a C/C++ varaible to be set.
|
||||
* Then, it either stores it in the alternative ubox table (in the case it is
|
||||
* an object) or in the own table (that represents the class or module).
|
||||
*/
|
||||
static int class_newindex_event (lua_State* L)
|
||||
{
|
||||
int t = lua_type(L,1);
|
||||
if (t == LUA_TUSERDATA)
|
||||
{
|
||||
/* Try accessing a C/C++ variable to be set */
|
||||
lua_getmetatable(L,1);
|
||||
while (lua_istable(L,-1)) /* stack: t k v mt */
|
||||
{
|
||||
if (lua_isnumber(L,2)) /* check if key is a numeric value */
|
||||
{
|
||||
/* try operator[] */
|
||||
lua_pushstring(L,".seti");
|
||||
lua_rawget(L,-2); /* stack: obj key mt func */
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
lua_pushvalue(L,3);
|
||||
lua_call(L,3,0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L,".set");
|
||||
lua_rawget(L,-2); /* stack: t k v mt tset */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,2);
|
||||
lua_rawget(L,-2); /* stack: t k v mt tset func */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,3);
|
||||
lua_call(L,2,0);
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1); /* stack: t k v mt tset */
|
||||
}
|
||||
lua_pop(L,1); /* stack: t k v mt */
|
||||
if (!lua_getmetatable(L,-1)) /* stack: t k v mt mt */
|
||||
lua_pushnil(L);
|
||||
lua_remove(L,-2); /* stack: t k v mt */
|
||||
}
|
||||
}
|
||||
lua_settop(L,3); /* stack: t k v */
|
||||
|
||||
/* then, store as a new field */
|
||||
storeatubox(L,1);
|
||||
}
|
||||
else if (t== LUA_TTABLE)
|
||||
{
|
||||
module_newindex_event(L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int class_call_event(lua_State* L) {
|
||||
|
||||
if (lua_istable(L, 1)) {
|
||||
lua_pushstring(L, ".call");
|
||||
lua_rawget(L, 1);
|
||||
if (lua_isfunction(L, -1)) {
|
||||
|
||||
lua_insert(L, 1);
|
||||
lua_call(L, lua_gettop(L)-1, 1);
|
||||
|
||||
return 1;
|
||||
};
|
||||
};
|
||||
tolua_error(L,"Attempt to call a non-callable object.",NULL);
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int do_operator (lua_State* L, const char* op)
|
||||
{
|
||||
if (lua_isuserdata(L,1))
|
||||
{
|
||||
/* Try metatables */
|
||||
lua_pushvalue(L,1); /* stack: op1 op2 */
|
||||
while (lua_getmetatable(L,-1))
|
||||
{ /* stack: op1 op2 op1 mt */
|
||||
lua_remove(L,-2); /* stack: op1 op2 mt */
|
||||
lua_pushstring(L,op); /* stack: op1 op2 mt key */
|
||||
lua_rawget(L,-2); /* stack: obj key mt func */
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
lua_call(L,2,1);
|
||||
return 1;
|
||||
}
|
||||
lua_settop(L,3);
|
||||
}
|
||||
}
|
||||
tolua_error(L,"Attempt to perform operation on an invalid operand",NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int class_add_event (lua_State* L)
|
||||
{
|
||||
return do_operator(L,".add");
|
||||
}
|
||||
|
||||
static int class_sub_event (lua_State* L)
|
||||
{
|
||||
return do_operator(L,".sub");
|
||||
}
|
||||
|
||||
static int class_mul_event (lua_State* L)
|
||||
{
|
||||
return do_operator(L,".mul");
|
||||
}
|
||||
|
||||
static int class_div_event (lua_State* L)
|
||||
{
|
||||
return do_operator(L,".div");
|
||||
}
|
||||
|
||||
static int class_lt_event (lua_State* L)
|
||||
{
|
||||
return do_operator(L,".lt");
|
||||
}
|
||||
|
||||
static int class_le_event (lua_State* L)
|
||||
{
|
||||
return do_operator(L,".le");
|
||||
}
|
||||
|
||||
static int class_eq_event (lua_State* L)
|
||||
{
|
||||
/* copying code from do_operator here to return false when no operator is found */
|
||||
if (lua_isuserdata(L,1))
|
||||
{
|
||||
/* Try metatables */
|
||||
lua_pushvalue(L,1); /* stack: op1 op2 */
|
||||
while (lua_getmetatable(L,-1))
|
||||
{ /* stack: op1 op2 op1 mt */
|
||||
lua_remove(L,-2); /* stack: op1 op2 mt */
|
||||
lua_pushstring(L,".eq"); /* stack: op1 op2 mt key */
|
||||
lua_rawget(L,-2); /* stack: obj key mt func */
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_pushvalue(L,2);
|
||||
lua_call(L,2,1);
|
||||
return 1;
|
||||
}
|
||||
lua_settop(L,3);
|
||||
}
|
||||
}
|
||||
|
||||
lua_settop(L, 3);
|
||||
lua_pushboolean(L, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
static int class_gc_event (lua_State* L)
|
||||
{
|
||||
void* u = *((void**)lua_touserdata(L,1));
|
||||
fprintf(stderr, "collecting: looking at %p\n", u);
|
||||
lua_pushstring(L,"tolua_gc");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
lua_pushlightuserdata(L,u);
|
||||
lua_rawget(L,-2);
|
||||
if (lua_isfunction(L,-1))
|
||||
{
|
||||
lua_pushvalue(L,1);
|
||||
lua_call(L,1,0);
|
||||
lua_pushlightuserdata(L,u);
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L,-3);
|
||||
}
|
||||
lua_pop(L,2);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
TOLUA_API int class_gc_event (lua_State* L)
|
||||
{
|
||||
void* u = *((void**)lua_touserdata(L,1));
|
||||
int top;
|
||||
/*fprintf(stderr, "collecting: looking at %p\n", u);*/
|
||||
/*
|
||||
lua_pushstring(L,"tolua_gc");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
*/
|
||||
lua_pushvalue(L, lua_upvalueindex(1));
|
||||
lua_pushlightuserdata(L,u);
|
||||
lua_rawget(L,-2); /* stack: gc umt */
|
||||
lua_getmetatable(L,1); /* stack: gc umt mt */
|
||||
/*fprintf(stderr, "checking type\n");*/
|
||||
top = lua_gettop(L);
|
||||
if (tolua_fast_isa(L,top,top-1, lua_upvalueindex(2))) /* make sure we collect correct type */
|
||||
{
|
||||
/*fprintf(stderr, "Found type!\n");*/
|
||||
/* get gc function */
|
||||
lua_pushliteral(L,".collector");
|
||||
lua_rawget(L,-2); /* stack: gc umt mt collector */
|
||||
if (lua_isfunction(L,-1)) {
|
||||
/*fprintf(stderr, "Found .collector!\n");*/
|
||||
}
|
||||
else {
|
||||
lua_pop(L,1);
|
||||
/*fprintf(stderr, "Using default cleanup\n");*/
|
||||
lua_pushcfunction(L,tolua_default_collect);
|
||||
}
|
||||
|
||||
lua_pushvalue(L,1); /* stack: gc umt mt collector u */
|
||||
lua_call(L,1,0);
|
||||
|
||||
lua_pushlightuserdata(L,u); /* stack: gc umt mt u */
|
||||
lua_pushnil(L); /* stack: gc umt mt u nil */
|
||||
lua_rawset(L,-5); /* stack: gc umt mt */
|
||||
}
|
||||
lua_pop(L,3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Register module events
|
||||
* It expects the metatable on the top of the stack
|
||||
*/
|
||||
TOLUA_API void tolua_moduleevents (lua_State* L)
|
||||
{
|
||||
lua_pushstring(L,"__index");
|
||||
lua_pushcfunction(L,module_index_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__newindex");
|
||||
lua_pushcfunction(L,module_newindex_event);
|
||||
lua_rawset(L,-3);
|
||||
}
|
||||
|
||||
/* Check if the object on the top has a module metatable
|
||||
*/
|
||||
TOLUA_API int tolua_ismodulemetatable (lua_State* L)
|
||||
{
|
||||
int r = 0;
|
||||
if (lua_getmetatable(L,-1))
|
||||
{
|
||||
lua_pushstring(L,"__index");
|
||||
lua_rawget(L,-2);
|
||||
r = (lua_tocfunction(L,-1) == module_index_event);
|
||||
lua_pop(L,2);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Register class events
|
||||
* It expects the metatable on the top of the stack
|
||||
*/
|
||||
TOLUA_API void tolua_classevents (lua_State* L)
|
||||
{
|
||||
lua_pushstring(L,"__index");
|
||||
lua_pushcfunction(L,class_index_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__newindex");
|
||||
lua_pushcfunction(L,class_newindex_event);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
lua_pushstring(L,"__add");
|
||||
lua_pushcfunction(L,class_add_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__sub");
|
||||
lua_pushcfunction(L,class_sub_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__mul");
|
||||
lua_pushcfunction(L,class_mul_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__div");
|
||||
lua_pushcfunction(L,class_div_event);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
lua_pushstring(L,"__lt");
|
||||
lua_pushcfunction(L,class_lt_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__le");
|
||||
lua_pushcfunction(L,class_le_event);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__eq");
|
||||
lua_pushcfunction(L,class_eq_event);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
lua_pushstring(L,"__call");
|
||||
lua_pushcfunction(L,class_call_event);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
lua_pushstring(L,"__gc");
|
||||
lua_pushstring(L, "tolua_gc_event");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
/*lua_pushcfunction(L,class_gc_event);*/
|
||||
lua_rawset(L,-3);
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/* tolua: event functions
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
#ifndef TOLUA_EVENT_H
|
||||
#define TOLUA_EVENT_H
|
||||
|
||||
#include "tolua++.h"
|
||||
|
||||
TOLUA_API void tolua_moduleevents (lua_State* L);
|
||||
TOLUA_API int tolua_ismodulemetatable (lua_State* L);
|
||||
TOLUA_API void tolua_classevents (lua_State* L);
|
||||
|
||||
#endif
|
||||
@@ -1,621 +0,0 @@
|
||||
/* tolua: functions to check types.
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
#include "tolua++.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* a fast check if a is b, without parameter validation
|
||||
i.e. if b is equal to a or a superclass of a. */
|
||||
TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index)
|
||||
{
|
||||
int result;
|
||||
if (lua_rawequal(L,mt_indexa,mt_indexb))
|
||||
result = 1;
|
||||
else
|
||||
{
|
||||
if (super_index) {
|
||||
lua_pushvalue(L, super_index);
|
||||
} else {
|
||||
lua_pushliteral(L,"tolua_super");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super */
|
||||
};
|
||||
lua_pushvalue(L,mt_indexa); /* stack: super mta */
|
||||
lua_rawget(L,-2); /* stack: super super[mta] */
|
||||
lua_pushvalue(L,mt_indexb); /* stack: super super[mta] mtb */
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super super[mta] typenameB */
|
||||
lua_rawget(L,-2); /* stack: super super[mta] bool */
|
||||
result = lua_toboolean(L,-1);
|
||||
lua_pop(L,3);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Push and returns the corresponding object typename */
|
||||
TOLUA_API const char* tolua_typename (lua_State* L, int lo)
|
||||
{
|
||||
int tag = lua_type(L,lo);
|
||||
if (tag == LUA_TNONE)
|
||||
lua_pushstring(L,"[no object]");
|
||||
else if (tag != LUA_TUSERDATA && tag != LUA_TTABLE)
|
||||
lua_pushstring(L,lua_typename(L,tag));
|
||||
else if (tag == LUA_TUSERDATA)
|
||||
{
|
||||
if (!lua_getmetatable(L,lo))
|
||||
lua_pushstring(L,lua_typename(L,tag));
|
||||
else
|
||||
{
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
if (!lua_isstring(L,-1))
|
||||
{
|
||||
lua_pop(L,1);
|
||||
lua_pushstring(L,"[undefined]");
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* is table */
|
||||
{
|
||||
lua_pushvalue(L,lo);
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
if (!lua_isstring(L,-1))
|
||||
{
|
||||
lua_pop(L,1);
|
||||
lua_pushstring(L,"table");
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L,"class ");
|
||||
lua_insert(L,-2);
|
||||
lua_concat(L,2);
|
||||
}
|
||||
}
|
||||
return lua_tostring(L,-1);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err)
|
||||
{
|
||||
if (msg[0] == '#')
|
||||
{
|
||||
const char* expected = err->type;
|
||||
const char* provided = tolua_typename(L,err->index);
|
||||
if (msg[1]=='f')
|
||||
{
|
||||
int narg = err->index;
|
||||
if (err->array)
|
||||
luaL_error(L,"%s\n argument #%d is array of '%s'; array of '%s' expected.\n",
|
||||
msg+2,narg,provided,expected);
|
||||
else
|
||||
luaL_error(L,"%s\n argument #%d is '%s'; '%s' expected.\n",
|
||||
msg+2,narg,provided,expected);
|
||||
}
|
||||
else if (msg[1]=='v')
|
||||
{
|
||||
if (err->array)
|
||||
luaL_error(L,"%s\n value is array of '%s'; array of '%s' expected.\n",
|
||||
msg+2,provided,expected);
|
||||
else
|
||||
luaL_error(L,"%s\n value is '%s'; '%s' expected.\n",
|
||||
msg+2,provided,expected);
|
||||
}
|
||||
}
|
||||
else
|
||||
luaL_error(L,msg);
|
||||
}
|
||||
|
||||
/* the equivalent of lua_is* for usertable */
|
||||
static int lua_isusertable (lua_State* L, int lo, const const char* type)
|
||||
{
|
||||
int r = 0;
|
||||
if (lo < 0) lo = lua_gettop(L)+lo+1;
|
||||
lua_pushvalue(L,lo);
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* get registry[t] */
|
||||
if (lua_isstring(L,-1))
|
||||
{
|
||||
r = strcmp(lua_tostring(L,-1),type)==0;
|
||||
if (!r)
|
||||
{
|
||||
/* try const */
|
||||
lua_pushstring(L,"const ");
|
||||
lua_insert(L,-2);
|
||||
lua_concat(L,2);
|
||||
r = lua_isstring(L,-1) && strcmp(lua_tostring(L,-1),type)==0;
|
||||
}
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
int push_table_instance(lua_State* L, int lo) {
|
||||
|
||||
if (lua_istable(L, lo)) {
|
||||
|
||||
lua_pushstring(L, ".c_instance");
|
||||
lua_gettable(L, lo);
|
||||
if (lua_isuserdata(L, -1)) {
|
||||
|
||||
lua_replace(L, lo);
|
||||
return 1;
|
||||
} else {
|
||||
|
||||
lua_pop(L, 1);
|
||||
return 0;
|
||||
};
|
||||
} else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
/* the equivalent of lua_is* for usertype */
|
||||
static int lua_isusertype (lua_State* L, int lo, const char* type)
|
||||
{
|
||||
if (!lua_isuserdata(L,lo)) {
|
||||
if (!push_table_instance(L, lo)) {
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
{
|
||||
/* check if it is of the same type */
|
||||
int r;
|
||||
const char *tn;
|
||||
if (lua_getmetatable(L,lo)) /* if metatable? */
|
||||
{
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* get registry[mt] */
|
||||
tn = lua_tostring(L,-1);
|
||||
r = tn && (strcmp(tn,type) == 0);
|
||||
lua_pop(L, 1);
|
||||
if (r)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
/* check if it is a specialized class */
|
||||
lua_pushstring(L,"tolua_super");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* get super */
|
||||
lua_getmetatable(L,lo);
|
||||
lua_rawget(L,-2); /* get super[mt] */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
int b;
|
||||
lua_pushstring(L,type);
|
||||
lua_rawget(L,-2); /* get super[mt][type] */
|
||||
b = lua_toboolean(L,-1);
|
||||
lua_pop(L,3);
|
||||
if (b)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err)
|
||||
{
|
||||
if (lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "[no object]";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_isnil(L,lo) || lua_isboolean(L,lo))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "boolean";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_isnumber(L,lo))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "number";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_isnil(L,lo) || lua_isstring(L,lo))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "string";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_istable(L,lo))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "table";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_isusertable(L,lo,type))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "userdata";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isvaluenil (lua_State* L, int lo, tolua_Error* err) {
|
||||
|
||||
if (lua_gettop(L)<abs(lo))
|
||||
return 0; /* somebody else should chack this */
|
||||
if (!lua_isnil(L, lo))
|
||||
return 0;
|
||||
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "value";
|
||||
return 1;
|
||||
};
|
||||
|
||||
TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err)
|
||||
{
|
||||
if (def || abs(lo)<=lua_gettop(L)) /* any valid index */
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = "value";
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
|
||||
{
|
||||
if (def && lua_gettop(L)<abs(lo))
|
||||
return 1;
|
||||
if (lua_isnil(L,lo) || lua_isusertype(L,lo,type))
|
||||
return 1;
|
||||
err->index = lo;
|
||||
err->array = 0;
|
||||
err->type = type;
|
||||
return 0;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isvaluearray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isbooleanarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=dim; ++i)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "boolean";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isnumberarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=dim; ++i)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!lua_isnumber(L,-1) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "number";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isstringarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=dim; ++i)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "string";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_istablearray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=dim; ++i)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (! lua_istable(L,-1) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "table";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isuserdataarray
|
||||
(lua_State* L, int lo, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=dim; ++i)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "userdata";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_isusertypearray
|
||||
(lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err)
|
||||
{
|
||||
if (!tolua_istable(L,lo,def,err))
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i=1; i<=dim; ++i)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->type = type;
|
||||
err->array = 1;
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int tolua_isbooleanfield
|
||||
(lua_State* L, int lo, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "boolean";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tolua_isnumberfield
|
||||
(lua_State* L, int lo, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!lua_isnumber(L,-1) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "number";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tolua_isstringfield
|
||||
(lua_State* L, int lo, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "string";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tolua_istablefield
|
||||
(lua_State* L, int lo, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i+1);
|
||||
lua_gettable(L,lo);
|
||||
if (! lua_istable(L,-1) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "table";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
}
|
||||
|
||||
int tolua_isusertablefield
|
||||
(lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (! lua_isusertable(L,-1,type) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = type;
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tolua_isuserdatafield
|
||||
(lua_State* L, int lo, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->array = 1;
|
||||
err->type = "userdata";
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tolua_isusertypefield
|
||||
(lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
|
||||
{
|
||||
lua_pushnumber(L,i);
|
||||
lua_gettable(L,lo);
|
||||
if (!(lua_isnil(L,-1) || lua_isusertype(L,-1,type)) &&
|
||||
!(def && lua_isnil(L,-1))
|
||||
)
|
||||
{
|
||||
err->index = lo;
|
||||
err->type = type;
|
||||
err->array = 1;
|
||||
return 0;
|
||||
}
|
||||
lua_pop(L,1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,704 +0,0 @@
|
||||
/* tolua: functions to map features
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
#include "tolua++.h"
|
||||
#include "tolua_event.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
/* Create metatable
|
||||
* Create and register new metatable
|
||||
*/
|
||||
static int tolua_newmetatable (lua_State* L, char* name)
|
||||
{
|
||||
int r = luaL_newmetatable(L,name);
|
||||
|
||||
#ifdef LUA_VERSION_NUM /* only lua 5.1 */
|
||||
if (r) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_pushstring(L, name);
|
||||
lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */
|
||||
};
|
||||
#endif
|
||||
|
||||
if (r)
|
||||
tolua_classevents(L); /* set meta events */
|
||||
lua_pop(L,1);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Map super classes
|
||||
* It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name'
|
||||
*/
|
||||
static void mapsuper (lua_State* L, const char* name, const char* base)
|
||||
{
|
||||
/* push registry.super */
|
||||
lua_pushstring(L,"tolua_super");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: super */
|
||||
luaL_getmetatable(L,name); /* stack: super mt */
|
||||
lua_rawget(L,-2); /* stack: super table */
|
||||
if (lua_isnil(L,-1))
|
||||
{
|
||||
/* create table */
|
||||
lua_pop(L,1);
|
||||
lua_newtable(L); /* stack: super table */
|
||||
luaL_getmetatable(L,name); /* stack: super table mt */
|
||||
lua_pushvalue(L,-2); /* stack: super table mt table */
|
||||
lua_rawset(L,-4); /* stack: super table */
|
||||
}
|
||||
|
||||
/* set base as super class */
|
||||
lua_pushstring(L,base);
|
||||
lua_pushboolean(L,1);
|
||||
lua_rawset(L,-3); /* stack: super table */
|
||||
|
||||
/* set all super class of base as super class of name */
|
||||
luaL_getmetatable(L,base); /* stack: super table base_mt */
|
||||
lua_rawget(L,-3); /* stack: super table base_table */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
/* traverse base table */
|
||||
lua_pushnil(L); /* first key */
|
||||
while (lua_next(L,-2) != 0)
|
||||
{
|
||||
/* stack: ... base_table key value */
|
||||
lua_pushvalue(L,-2); /* stack: ... base_table key value key */
|
||||
lua_insert(L,-2); /* stack: ... base_table key key value */
|
||||
lua_rawset(L,-5); /* stack: ... base_table key */
|
||||
}
|
||||
}
|
||||
lua_pop(L,3); /* stack: <empty> */
|
||||
}
|
||||
|
||||
/* creates a 'tolua_ubox' table for base clases, and
|
||||
// expects the metatable and base metatable on the stack */
|
||||
static void set_ubox(lua_State* L) {
|
||||
|
||||
/* mt basemt */
|
||||
if (!lua_isnil(L, -1)) {
|
||||
lua_pushstring(L, "tolua_ubox");
|
||||
lua_rawget(L,-2);
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
};
|
||||
/* mt basemt base_ubox */
|
||||
if (!lua_isnil(L,-1)) {
|
||||
lua_pushstring(L, "tolua_ubox");
|
||||
lua_insert(L, -2);
|
||||
/* mt basemt key ubox */
|
||||
lua_rawset(L,-4);
|
||||
/* (mt with ubox) basemt */
|
||||
} else {
|
||||
/* mt basemt nil */
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
|
||||
/* make weak value metatable for ubox table to allow userdata to be
|
||||
garbage-collected */
|
||||
lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3); /* stack: string ubox mt */
|
||||
lua_setmetatable(L, -2); /* stack:mt basemt string ubox */
|
||||
lua_rawset(L,-4);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/* Map inheritance
|
||||
* It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name'
|
||||
*/
|
||||
static void mapinheritance (lua_State* L, const char* name, const char* base)
|
||||
{
|
||||
/* set metatable inheritance */
|
||||
luaL_getmetatable(L,name);
|
||||
|
||||
if (base && *base)
|
||||
luaL_getmetatable(L,base);
|
||||
else {
|
||||
|
||||
if (lua_getmetatable(L, -1)) { /* already has a mt, we don't overwrite it */
|
||||
lua_pop(L, 2);
|
||||
return;
|
||||
};
|
||||
luaL_getmetatable(L,"tolua_commonclass");
|
||||
};
|
||||
|
||||
set_ubox(L);
|
||||
|
||||
lua_setmetatable(L,-2);
|
||||
lua_pop(L,1);
|
||||
}
|
||||
|
||||
/* Object type
|
||||
*/
|
||||
static int tolua_bnd_type (lua_State* L)
|
||||
{
|
||||
tolua_typename(L,lua_gettop(L));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Take ownership
|
||||
*/
|
||||
static int tolua_bnd_takeownership (lua_State* L)
|
||||
{
|
||||
int success = 0;
|
||||
if (lua_isuserdata(L,1))
|
||||
{
|
||||
if (lua_getmetatable(L,1)) /* if metatable? */
|
||||
{
|
||||
lua_pop(L,1); /* clear metatable off stack */
|
||||
/* force garbage collection to avoid C to reuse a to-be-collected address */
|
||||
#ifdef LUA_VERSION_NUM
|
||||
lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
#else
|
||||
lua_setgcthreshold(L,0);
|
||||
#endif
|
||||
|
||||
success = tolua_register_gc(L,1);
|
||||
}
|
||||
}
|
||||
lua_pushboolean(L,success!=0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Release ownership
|
||||
*/
|
||||
static int tolua_bnd_releaseownership (lua_State* L)
|
||||
{
|
||||
int done = 0;
|
||||
if (lua_isuserdata(L,1))
|
||||
{
|
||||
void* u = *((void**)lua_touserdata(L,1));
|
||||
/* force garbage collection to avoid releasing a to-be-collected address */
|
||||
#ifdef LUA_VERSION_NUM
|
||||
lua_gc(L, LUA_GCCOLLECT, 0);
|
||||
#else
|
||||
lua_setgcthreshold(L,0);
|
||||
#endif
|
||||
lua_pushstring(L,"tolua_gc");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
lua_pushlightuserdata(L,u);
|
||||
lua_rawget(L,-2);
|
||||
lua_getmetatable(L,1);
|
||||
if (lua_rawequal(L,-1,-2)) /* check that we are releasing the correct type */
|
||||
{
|
||||
lua_pushlightuserdata(L,u);
|
||||
lua_pushnil(L);
|
||||
lua_rawset(L,-5);
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
lua_pushboolean(L,done!=0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Type casting
|
||||
*/
|
||||
static int tolua_bnd_cast (lua_State* L)
|
||||
{
|
||||
|
||||
/* // old code
|
||||
void* v = tolua_tousertype(L,1,NULL);
|
||||
const char* s = tolua_tostring(L,2,NULL);
|
||||
if (v && s)
|
||||
tolua_pushusertype(L,v,s);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
*/
|
||||
|
||||
void* v;
|
||||
const char* s;
|
||||
if (lua_islightuserdata(L, 1)) {
|
||||
v = tolua_touserdata(L, 1, NULL);
|
||||
} else {
|
||||
v = tolua_tousertype(L, 1, 0);
|
||||
};
|
||||
|
||||
s = tolua_tostring(L,2,NULL);
|
||||
if (v && s)
|
||||
tolua_pushusertype(L,v,s);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Inheritance
|
||||
*/
|
||||
static int tolua_bnd_inherit (lua_State* L) {
|
||||
|
||||
/* stack: lua object, c object */
|
||||
lua_pushstring(L, ".c_instance");
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, -4);
|
||||
/* l_obj[".c_instance"] = c_obj */
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
#ifdef LUA_VERSION_NUM /* lua 5.1 */
|
||||
static int tolua_bnd_setpeer(lua_State* L) {
|
||||
|
||||
/* stack: userdata, table */
|
||||
if (!lua_isuserdata(L, -2)) {
|
||||
lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected.");
|
||||
lua_error(L);
|
||||
};
|
||||
|
||||
if (lua_isnil(L, -1)) {
|
||||
|
||||
lua_pop(L, 1);
|
||||
lua_pushvalue(L, TOLUA_NOPEER);
|
||||
};
|
||||
lua_setfenv(L, -2);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static int tolua_bnd_getpeer(lua_State* L) {
|
||||
|
||||
/* stack: userdata */
|
||||
lua_getfenv(L, -1);
|
||||
if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
|
||||
lua_pop(L, 1);
|
||||
lua_pushnil(L);
|
||||
};
|
||||
return 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
/* static int class_gc_event (lua_State* L); */
|
||||
|
||||
TOLUA_API void tolua_open (lua_State* L)
|
||||
{
|
||||
int top = lua_gettop(L);
|
||||
lua_pushstring(L,"tolua_opened");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
if (!lua_isboolean(L,-1))
|
||||
{
|
||||
lua_pushstring(L,"tolua_opened"); lua_pushboolean(L,1); lua_rawset(L,LUA_REGISTRYINDEX);
|
||||
|
||||
#ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */
|
||||
/* create peer object table */
|
||||
lua_pushstring(L, "tolua_peers"); lua_newtable(L);
|
||||
/* make weak key metatable for peers indexed by userdata object */
|
||||
lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3); /* stack: string peers mt */
|
||||
lua_setmetatable(L, -2); /* stack: string peers */
|
||||
lua_rawset(L,LUA_REGISTRYINDEX);
|
||||
#endif
|
||||
|
||||
/* create object ptr -> udata mapping table */
|
||||
lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
|
||||
/* make weak value metatable for ubox table to allow userdata to be
|
||||
garbage-collected */
|
||||
lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3); /* stack: string ubox mt */
|
||||
lua_setmetatable(L, -2); /* stack: string ubox */
|
||||
lua_rawset(L,LUA_REGISTRYINDEX);
|
||||
|
||||
lua_pushstring(L,"tolua_super"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
|
||||
lua_pushstring(L,"tolua_gc"); lua_newtable(L);lua_rawset(L,LUA_REGISTRYINDEX);
|
||||
|
||||
/* create gc_event closure */
|
||||
lua_pushstring(L, "tolua_gc_event");
|
||||
lua_pushstring(L, "tolua_gc");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_pushstring(L, "tolua_super");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
lua_pushcclosure(L, class_gc_event, 2);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
|
||||
tolua_newmetatable(L,"tolua_commonclass");
|
||||
|
||||
tolua_module(L,NULL,0);
|
||||
tolua_beginmodule(L,NULL);
|
||||
tolua_module(L,"tolua",0);
|
||||
tolua_beginmodule(L,"tolua");
|
||||
tolua_function(L,"type",tolua_bnd_type);
|
||||
tolua_function(L,"takeownership",tolua_bnd_takeownership);
|
||||
tolua_function(L,"releaseownership",tolua_bnd_releaseownership);
|
||||
tolua_function(L,"cast",tolua_bnd_cast);
|
||||
tolua_function(L,"inherit", tolua_bnd_inherit);
|
||||
#ifdef LUA_VERSION_NUM /* lua 5.1 */
|
||||
tolua_function(L, "setpeer", tolua_bnd_setpeer);
|
||||
tolua_function(L, "getpeer", tolua_bnd_getpeer);
|
||||
#endif
|
||||
|
||||
tolua_endmodule(L);
|
||||
tolua_endmodule(L);
|
||||
}
|
||||
lua_settop(L,top);
|
||||
}
|
||||
|
||||
/* Copy a C object
|
||||
*/
|
||||
TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size)
|
||||
{
|
||||
void* clone = (void*)malloc(size);
|
||||
if (clone)
|
||||
memcpy(clone,value,size);
|
||||
else
|
||||
tolua_error(L,"insuficient memory",NULL);
|
||||
return clone;
|
||||
}
|
||||
|
||||
/* Default collect function
|
||||
*/
|
||||
TOLUA_API int tolua_default_collect (lua_State* tolua_S)
|
||||
{
|
||||
void* self = tolua_tousertype(tolua_S,1,0);
|
||||
free(self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do clone
|
||||
*/
|
||||
TOLUA_API int tolua_register_gc (lua_State* L, int lo)
|
||||
{
|
||||
int success = 1;
|
||||
void *value = *(void **)lua_touserdata(L,lo);
|
||||
lua_pushstring(L,"tolua_gc");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX);
|
||||
lua_pushlightuserdata(L,value);
|
||||
lua_rawget(L,-2);
|
||||
if (!lua_isnil(L,-1)) /* make sure that object is not already owned */
|
||||
success = 0;
|
||||
else
|
||||
{
|
||||
lua_pushlightuserdata(L,value);
|
||||
lua_getmetatable(L,lo);
|
||||
lua_rawset(L,-4);
|
||||
}
|
||||
lua_pop(L,2);
|
||||
return success;
|
||||
}
|
||||
|
||||
/* Register a usertype
|
||||
* It creates the correspoding metatable in the registry, for both 'type' and 'const type'.
|
||||
* It maps 'const type' as being also a 'type'
|
||||
*/
|
||||
TOLUA_API void tolua_usertype (lua_State* L, const char* type)
|
||||
{
|
||||
char ctype[128] = "const ";
|
||||
strncat(ctype,type,120);
|
||||
|
||||
/* create both metatables */
|
||||
if (tolua_newmetatable(L,ctype) && tolua_newmetatable(L,type))
|
||||
mapsuper(L,type,ctype); /* 'type' is also a 'const type' */
|
||||
}
|
||||
|
||||
|
||||
/* Begin module
|
||||
* It pushes the module (or class) table on the stack
|
||||
*/
|
||||
TOLUA_API void tolua_beginmodule (lua_State* L, const char* name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
lua_pushstring(L,name);
|
||||
lua_rawget(L,-2);
|
||||
}
|
||||
else
|
||||
lua_pushvalue(L,LUA_GLOBALSINDEX);
|
||||
}
|
||||
|
||||
/* End module
|
||||
* It pops the module (or class) from the stack
|
||||
*/
|
||||
TOLUA_API void tolua_endmodule (lua_State* L)
|
||||
{
|
||||
lua_pop(L,1);
|
||||
}
|
||||
|
||||
/* Map module
|
||||
* It creates a new module
|
||||
*/
|
||||
#if 1
|
||||
TOLUA_API void tolua_module (lua_State* L, const char* name, int hasvar)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
/* tolua module */
|
||||
lua_pushstring(L,name);
|
||||
lua_rawget(L,-2);
|
||||
if (!lua_istable(L,-1)) /* check if module already exists */
|
||||
{
|
||||
lua_pop(L,1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,name);
|
||||
lua_pushvalue(L,-2);
|
||||
lua_rawset(L,-4); /* assing module into module */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* global table */
|
||||
lua_pushvalue(L,LUA_GLOBALSINDEX);
|
||||
}
|
||||
if (hasvar)
|
||||
{
|
||||
if (!tolua_ismodulemetatable(L)) /* check if it already has a module metatable */
|
||||
{
|
||||
/* create metatable to get/set C/C++ variable */
|
||||
lua_newtable(L);
|
||||
tolua_moduleevents(L);
|
||||
if (lua_getmetatable(L,-2))
|
||||
lua_setmetatable(L,-2); /* set old metatable as metatable of metatable */
|
||||
lua_setmetatable(L,-2);
|
||||
}
|
||||
}
|
||||
lua_pop(L,1); /* pop module */
|
||||
}
|
||||
#else
|
||||
TOLUA_API void tolua_module (lua_State* L, const char* name, int hasvar)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
/* tolua module */
|
||||
lua_pushstring(L,name);
|
||||
lua_newtable(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* global table */
|
||||
lua_pushvalue(L,LUA_GLOBALSINDEX);
|
||||
}
|
||||
if (hasvar)
|
||||
{
|
||||
/* create metatable to get/set C/C++ variable */
|
||||
lua_newtable(L);
|
||||
tolua_moduleevents(L);
|
||||
if (lua_getmetatable(L,-2))
|
||||
lua_setmetatable(L,-2); /* set old metatable as metatable of metatable */
|
||||
lua_setmetatable(L,-2);
|
||||
}
|
||||
if (name)
|
||||
lua_rawset(L,-3); /* assing module into module */
|
||||
else
|
||||
lua_pop(L,1); /* pop global table */
|
||||
}
|
||||
#endif
|
||||
|
||||
static void push_collector(lua_State* L, const char* type, lua_CFunction col) {
|
||||
|
||||
/* push collector function, but only if it's not NULL, or if there's no
|
||||
collector already */
|
||||
if (!col) return;
|
||||
luaL_getmetatable(L,type);
|
||||
lua_pushstring(L,".collector");
|
||||
/*
|
||||
if (!col) {
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, -3);
|
||||
if (!lua_isnil(L, -1)) {
|
||||
lua_pop(L, 3);
|
||||
return;
|
||||
};
|
||||
lua_pop(L, 1);
|
||||
};
|
||||
// */
|
||||
lua_pushcfunction(L,col);
|
||||
|
||||
lua_rawset(L,-3);
|
||||
lua_pop(L, 1);
|
||||
};
|
||||
|
||||
/* Map C class
|
||||
* It maps a C class, setting the appropriate inheritance and super classes.
|
||||
*/
|
||||
TOLUA_API void tolua_cclass (lua_State* L, const char* lname, const char* name, const char* base, lua_CFunction col)
|
||||
{
|
||||
char cname[128] = "const ";
|
||||
char cbase[128] = "const ";
|
||||
strncat(cname,name,120);
|
||||
strncat(cbase,base,120);
|
||||
|
||||
mapinheritance(L,name,base);
|
||||
mapinheritance(L,cname,name);
|
||||
|
||||
mapsuper(L,cname,cbase);
|
||||
mapsuper(L,name,base);
|
||||
|
||||
lua_pushstring(L,lname);
|
||||
|
||||
push_collector(L, name, col);
|
||||
/*
|
||||
luaL_getmetatable(L,name);
|
||||
lua_pushstring(L,".collector");
|
||||
lua_pushcfunction(L,col);
|
||||
|
||||
lua_rawset(L,-3);
|
||||
*/
|
||||
|
||||
luaL_getmetatable(L,name);
|
||||
lua_rawset(L,-3); /* assign class metatable to module */
|
||||
|
||||
/* now we also need to store the collector table for the const
|
||||
instances of the class */
|
||||
push_collector(L, cname, col);
|
||||
/*
|
||||
luaL_getmetatable(L,cname);
|
||||
lua_pushstring(L,".collector");
|
||||
lua_pushcfunction(L,col);
|
||||
lua_rawset(L,-3);
|
||||
lua_pop(L,1);
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Add base
|
||||
* It adds additional base classes to a class (for multiple inheritance)
|
||||
* (not for now)
|
||||
TOLUA_API void tolua_addbase(lua_State* L, char* name, char* base) {
|
||||
|
||||
char cname[128] = "const ";
|
||||
char cbase[128] = "const ";
|
||||
strncat(cname,name,120);
|
||||
strncat(cbase,base,120);
|
||||
|
||||
mapsuper(L,cname,cbase);
|
||||
mapsuper(L,name,base);
|
||||
};
|
||||
*/
|
||||
|
||||
/* Map function
|
||||
* It assigns a function into the current module (or class)
|
||||
*/
|
||||
TOLUA_API void tolua_function (lua_State* L, const char* name, lua_CFunction func)
|
||||
{
|
||||
lua_pushstring(L,name);
|
||||
lua_pushcfunction(L,func);
|
||||
lua_rawset(L,-3);
|
||||
}
|
||||
|
||||
/* sets the __call event for the class (expects the class' main table on top) */
|
||||
/* never really worked :(
|
||||
TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type) {
|
||||
|
||||
lua_getmetatable(L, -1);
|
||||
//luaL_getmetatable(L, type);
|
||||
lua_pushstring(L,"__call");
|
||||
lua_pushcfunction(L,func);
|
||||
lua_rawset(L,-3);
|
||||
lua_pop(L, 1);
|
||||
};
|
||||
*/
|
||||
|
||||
/* Map constant number
|
||||
* It assigns a constant number into the current module (or class)
|
||||
*/
|
||||
TOLUA_API void tolua_constant (lua_State* L, const char* name, lua_Number value)
|
||||
{
|
||||
lua_pushstring(L,name);
|
||||
tolua_pushnumber(L,value);
|
||||
lua_rawset(L,-3);
|
||||
}
|
||||
|
||||
|
||||
/* Map variable
|
||||
* It assigns a variable into the current module (or class)
|
||||
*/
|
||||
TOLUA_API void tolua_variable (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set)
|
||||
{
|
||||
/* get func */
|
||||
lua_pushstring(L,".get");
|
||||
lua_rawget(L,-2);
|
||||
if (!lua_istable(L,-1))
|
||||
{
|
||||
/* create .get table, leaving it at the top */
|
||||
lua_pop(L,1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,".get");
|
||||
lua_pushvalue(L,-2);
|
||||
lua_rawset(L,-4);
|
||||
}
|
||||
lua_pushstring(L,name);
|
||||
lua_pushcfunction(L,get);
|
||||
lua_rawset(L,-3); /* store variable */
|
||||
lua_pop(L,1); /* pop .get table */
|
||||
|
||||
/* set func */
|
||||
if (set)
|
||||
{
|
||||
lua_pushstring(L,".set");
|
||||
lua_rawget(L,-2);
|
||||
if (!lua_istable(L,-1))
|
||||
{
|
||||
/* create .set table, leaving it at the top */
|
||||
lua_pop(L,1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,".set");
|
||||
lua_pushvalue(L,-2);
|
||||
lua_rawset(L,-4);
|
||||
}
|
||||
lua_pushstring(L,name);
|
||||
lua_pushcfunction(L,set);
|
||||
lua_rawset(L,-3); /* store variable */
|
||||
lua_pop(L,1); /* pop .set table */
|
||||
}
|
||||
}
|
||||
|
||||
/* Access const array
|
||||
* It reports an error when trying to write into a const array
|
||||
*/
|
||||
static int const_array (lua_State* L)
|
||||
{
|
||||
luaL_error(L,"value of const array cannot be changed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Map an array
|
||||
* It assigns an array into the current module (or class)
|
||||
*/
|
||||
TOLUA_API void tolua_array (lua_State* L, const char* name, lua_CFunction get, lua_CFunction set)
|
||||
{
|
||||
lua_pushstring(L,".get");
|
||||
lua_rawget(L,-2);
|
||||
if (!lua_istable(L,-1))
|
||||
{
|
||||
/* create .get table, leaving it at the top */
|
||||
lua_pop(L,1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L,".get");
|
||||
lua_pushvalue(L,-2);
|
||||
lua_rawset(L,-4);
|
||||
}
|
||||
lua_pushstring(L,name);
|
||||
|
||||
lua_newtable(L); /* create array metatable */
|
||||
lua_pushvalue(L,-1);
|
||||
lua_setmetatable(L,-2); /* set the own table as metatable (for modules) */
|
||||
lua_pushstring(L,"__index");
|
||||
lua_pushcfunction(L,get);
|
||||
lua_rawset(L,-3);
|
||||
lua_pushstring(L,"__newindex");
|
||||
lua_pushcfunction(L,set?set:const_array);
|
||||
lua_rawset(L,-3);
|
||||
|
||||
lua_rawset(L,-3); /* store variable */
|
||||
lua_pop(L,1); /* pop .get table */
|
||||
}
|
||||
|
||||
|
||||
TOLUA_API void tolua_dobuffer(lua_State* L, char* B, unsigned int size, const char* name) {
|
||||
|
||||
#ifdef LUA_VERSION_NUM /* lua 5.1 */
|
||||
luaL_loadbuffer(L, B, size, name) || lua_pcall(L, 0, 0, 0);
|
||||
#else
|
||||
lua_dobuffer(L, B, size, name);
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
/* tolua: functions to push C values.
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
#include "tolua++.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
|
||||
{
|
||||
lua_pushvalue(L,lo);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushboolean (lua_State* L, int value)
|
||||
{
|
||||
lua_pushboolean(L,value);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value)
|
||||
{
|
||||
lua_pushnumber(L,value);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushstring (lua_State* L, const char* value)
|
||||
{
|
||||
if (value == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushstring(L,value);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushuserdata (lua_State* L, void* value)
|
||||
{
|
||||
if (value == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
lua_pushlightuserdata(L,value);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
|
||||
{
|
||||
if (value == NULL)
|
||||
lua_pushnil(L);
|
||||
else
|
||||
{
|
||||
luaL_getmetatable(L, type);
|
||||
lua_pushstring(L,"tolua_ubox");
|
||||
lua_rawget(L,-2); /* stack: mt ubox */
|
||||
if (lua_isnil(L, -1)) {
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, "tolua_ubox");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
};
|
||||
lua_pushlightuserdata(L,value);
|
||||
lua_rawget(L,-2); /* stack: mt ubox ubox[u] */
|
||||
if (lua_isnil(L,-1))
|
||||
{
|
||||
lua_pop(L,1); /* stack: mt ubox */
|
||||
lua_pushlightuserdata(L,value);
|
||||
*(void**)lua_newuserdata(L,sizeof(void *)) = value; /* stack: mt ubox u newud */
|
||||
lua_pushvalue(L,-1); /* stack: mt ubox u newud newud */
|
||||
lua_insert(L,-4); /* stack: mt newud ubox u newud */
|
||||
lua_rawset(L,-3); /* stack: mt newud ubox */
|
||||
lua_pop(L,1); /* stack: mt newud */
|
||||
/*luaL_getmetatable(L,type);*/
|
||||
lua_pushvalue(L, -2); /* stack: mt newud mt */
|
||||
lua_setmetatable(L,-2); /* stack: mt newud */
|
||||
|
||||
#ifdef LUA_VERSION_NUM
|
||||
lua_pushvalue(L, TOLUA_NOPEER);
|
||||
lua_setfenv(L, -2);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* check the need of updating the metatable to a more specialized class */
|
||||
lua_insert(L,-2); /* stack: mt ubox[u] ubox */
|
||||
lua_pop(L,1); /* stack: mt ubox[u] */
|
||||
lua_pushstring(L,"tolua_super");
|
||||
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: mt ubox[u] super */
|
||||
lua_getmetatable(L,-2); /* stack: mt ubox[u] super mt */
|
||||
lua_rawget(L,-2); /* stack: mt ubox[u] super super[mt] */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
lua_pushstring(L,type); /* stack: mt ubox[u] super super[mt] type */
|
||||
lua_rawget(L,-2); /* stack: mt ubox[u] super super[mt] flag */
|
||||
if (lua_toboolean(L,-1) == 1) /* if true */
|
||||
{
|
||||
lua_pop(L,3); /* mt ubox[u]*/
|
||||
lua_remove(L, -2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* type represents a more specilized type */
|
||||
/*luaL_getmetatable(L,type); // stack: mt ubox[u] super super[mt] flag mt */
|
||||
lua_pushvalue(L, -5); /* stack: mt ubox[u] super super[mt] flag mt */
|
||||
lua_setmetatable(L,-5); /* stack: mt ubox[u] super super[mt] flag */
|
||||
lua_pop(L,3); /* stack: mt ubox[u] */
|
||||
}
|
||||
lua_remove(L, -2); /* stack: ubox[u]*/
|
||||
}
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushusertype_and_takeownership (lua_State* L, void* value, const char* type)
|
||||
{
|
||||
tolua_pushusertype(L,value,type);
|
||||
tolua_register_gc(L,lua_gettop(L));
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
lua_pushvalue(L,v);
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
lua_pushboolean(L,v);
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
|
||||
TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
tolua_pushnumber(L,v);
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
tolua_pushstring(L,v);
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
tolua_pushuserdata(L,v);
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
tolua_pushusertype(L,v,type);
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type)
|
||||
{
|
||||
lua_pushnumber(L,index);
|
||||
tolua_pushusertype(L,v,type);
|
||||
tolua_register_gc(L,lua_gettop(L));
|
||||
lua_settable(L,lo);
|
||||
}
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
/* tolua: funcitons to convert to C types
|
||||
** Support code for Lua bindings.
|
||||
** Written by Waldemar Celes
|
||||
** TeCGraf/PUC-Rio
|
||||
** Apr 2003
|
||||
** $Id: $
|
||||
*/
|
||||
|
||||
/* This code is free software; you can redistribute it and/or modify it.
|
||||
** The software provided hereunder is on an "as is" basis, and
|
||||
** the author has no obligation to provide maintenance, support, updates,
|
||||
** enhancements, or modifications.
|
||||
*/
|
||||
|
||||
#include "tolua++.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
TOLUA_API lua_Number tolua_tonumber (lua_State* L, int narg, lua_Number def)
|
||||
{
|
||||
return lua_gettop(L)<abs(narg) ? def : lua_tonumber(L,narg);
|
||||
}
|
||||
|
||||
TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def)
|
||||
{
|
||||
return lua_gettop(L)<abs(narg) ? def : lua_tostring(L,narg);
|
||||
}
|
||||
|
||||
TOLUA_API void* tolua_touserdata (lua_State* L, int narg, void* def)
|
||||
{
|
||||
|
||||
/* return lua_gettop(L)<abs(narg) ? def : lua_touserdata(L,narg); */
|
||||
|
||||
if (lua_gettop(L)<abs(narg)) {
|
||||
return def;
|
||||
};
|
||||
|
||||
if (lua_islightuserdata(L, narg)) {
|
||||
|
||||
return lua_touserdata(L,narg);
|
||||
};
|
||||
|
||||
return tolua_tousertype(L, narg, def);
|
||||
}
|
||||
|
||||
extern int push_table_instance(lua_State* L, int lo);
|
||||
|
||||
TOLUA_API void* tolua_tousertype (lua_State* L, int narg, void* def)
|
||||
{
|
||||
if (lua_gettop(L)<abs(narg))
|
||||
return def;
|
||||
else
|
||||
{
|
||||
void* u;
|
||||
if (!lua_isuserdata(L, narg)) {
|
||||
if (!push_table_instance(L, narg)) return NULL;
|
||||
};
|
||||
u = lua_touserdata(L,narg);
|
||||
return (u==NULL) ? NULL : *((void**)u); /* nil represents NULL */
|
||||
}
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_tovalue (lua_State* L, int narg, int def)
|
||||
{
|
||||
return lua_gettop(L)<abs(narg) ? def : narg;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_toboolean (lua_State* L, int narg, int def)
|
||||
{
|
||||
return lua_gettop(L)<abs(narg) ? def : lua_toboolean(L,narg);
|
||||
}
|
||||
|
||||
TOLUA_API lua_Number tolua_tofieldnumber (lua_State* L, int lo, int index, lua_Number def)
|
||||
{
|
||||
double v;
|
||||
lua_pushnumber(L,index);
|
||||
lua_gettable(L,lo);
|
||||
v = lua_isnil(L,-1) ? def : lua_tonumber(L,-1);
|
||||
lua_pop(L,1);
|
||||
return v;
|
||||
}
|
||||
|
||||
TOLUA_API const char* tolua_tofieldstring
|
||||
(lua_State* L, int lo, int index, const char* def)
|
||||
{
|
||||
const char* v;
|
||||
lua_pushnumber(L,index);
|
||||
lua_gettable(L,lo);
|
||||
v = lua_isnil(L,-1) ? def : lua_tostring(L,-1);
|
||||
lua_pop(L,1);
|
||||
return v;
|
||||
}
|
||||
|
||||
TOLUA_API void* tolua_tofielduserdata (lua_State* L, int lo, int index, void* def)
|
||||
{
|
||||
void* v;
|
||||
lua_pushnumber(L,index);
|
||||
lua_gettable(L,lo);
|
||||
v = lua_isnil(L,-1) ? def : lua_touserdata(L,-1);
|
||||
lua_pop(L,1);
|
||||
return v;
|
||||
}
|
||||
|
||||
TOLUA_API void* tolua_tofieldusertype (lua_State* L, int lo, int index, void* def)
|
||||
{
|
||||
void* v;
|
||||
lua_pushnumber(L,index);
|
||||
lua_gettable(L,lo);
|
||||
v = lua_isnil(L,-1) ? def : (*(void **)(lua_touserdata(L, -1))); /* lua_unboxpointer(L,-1); */
|
||||
lua_pop(L,1);
|
||||
return v;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_tofieldvalue (lua_State* L, int lo, int index, int def)
|
||||
{
|
||||
int v;
|
||||
lua_pushnumber(L,index);
|
||||
lua_gettable(L,lo);
|
||||
v = lua_isnil(L,-1) ? def : lo;
|
||||
lua_pop(L,1);
|
||||
return v;
|
||||
}
|
||||
|
||||
TOLUA_API int tolua_getfieldboolean (lua_State* L, int lo, int index, int def)
|
||||
{
|
||||
int v;
|
||||
lua_pushnumber(L,index);
|
||||
lua_gettable(L,lo);
|
||||
v = lua_isnil(L,-1) ? 0 : lua_toboolean(L,-1);
|
||||
lua_pop(L,1);
|
||||
return v;
|
||||
}
|
||||
Reference in New Issue
Block a user