summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpixel <pixel>2004-11-27 21:01:20 +0000
committerpixel <pixel>2004-11-27 21:01:20 +0000
commit6ba597d46a93aaa9a17eb8a9fe8f3bcdedf686c0 (patch)
treeab0da6d8f34b38cd14d8a88ec5bc2d9721ece168
parente8fc656ff2eef558d25484b2ed633f872fb0b6d8 (diff)
Added dirent stuff to cd-tool
-rw-r--r--MSVC/dirent/_mingw.h68
-rw-r--r--MSVC/dirent/dirent.c316
-rw-r--r--MSVC/dirent/dirent.h96
-rw-r--r--include/BLua.h751
-rw-r--r--lib/BLua.cc1329
-rw-r--r--lib/lua/include/lualib.h5
-rw-r--r--lib/lua/src/LuaLib/ldirlib.c101
7 files changed, 1628 insertions, 1038 deletions
diff --git a/MSVC/dirent/_mingw.h b/MSVC/dirent/_mingw.h
new file mode 100644
index 0000000..e6fa7dd
--- /dev/null
+++ b/MSVC/dirent/_mingw.h
@@ -0,0 +1,68 @@
+/*
+ * _mingw.h
+ *
+ * Mingw specific macros included by ALL include files.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Mumit Khan <khan@xraylith.wisc.edu>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __MINGW_H
+#define __MINGW_H
+
+/* These are defined by the user (or the compiler)
+ to specify how identifiers are imported from a DLL.
+
+ __DECLSPEC_SUPPORTED Defined if dllimport attribute is supported.
+ __MINGW_IMPORT The attribute definition to specify imported
+ variables/functions.
+ __MINGW32_VERSION Runtime version.
+ __MINGW32_MAJOR_VERSION Runtime major version.
+ __MINGW32_MINOR_VERSION Runtime minor version.
+ __MINGW32_BUILD_DATE Runtime build date.
+
+ Other macros:
+
+ __int64 define to be long long. Using a typedef can
+ tweak bugs in the C++ parser.
+
+ All headers should include this first, and then use __DECLSPEC_SUPPORTED
+ to choose between the old ``__imp__name'' style or __MINGW_IMPORT
+ style declarations. */
+
+#ifndef __GNUC__
+# define __MINGW_IMPORT __declspec(dllimport)
+# define __DECLSPEC_SUPPORTED
+#else /* __GNUC__ */
+# ifdef __declspec
+ /* note the extern at the end. This is needed to work around GCC's
+ limitations in handling dllimport attribute. */
+# define __MINGW_IMPORT __attribute__((dllimport)) extern
+# define __DECLSPEC_SUPPORTED
+# else
+# undef __DECLSPEC_SUPPORTED
+# undef __MINGW_IMPORT
+# endif
+# undef __int64
+# define __int64 long long
+#endif /* __GNUC__ */
+
+#define __MINGW32_VERSION 1.2
+#define __MINGW32_MAJOR_VERSION 1
+#define __MINGW32_MINOR_VERSION 2
+
+#endif /* __MINGW_H */
+
diff --git a/MSVC/dirent/dirent.c b/MSVC/dirent/dirent.c
new file mode 100644
index 0000000..d062d63
--- /dev/null
+++ b/MSVC/dirent/dirent.c
@@ -0,0 +1,316 @@
+/*
+ * dirent.c
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Updated by Jeremy Bettis <jeremy@hksys.com>
+ * Significantly revised and rewinddir, seekdir and telldir added by Colin
+ * Peters <colin@fu.is.saga-u.ac.jp>
+ *
+ * $Revision: 1.1 $
+ * $Author: pixel $
+ * $Date: 2004-11-27 21:01:21 $
+ *
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <io.h>
+#include <direct.h>
+
+#include <dirent.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> /* for GetFileAttributes */
+
+#define SUFFIX "*"
+#define SLASH "\\"
+
+/*
+ * opendir
+ *
+ * Returns a pointer to a DIR structure appropriately filled in to begin
+ * searching a directory.
+ */
+DIR *
+opendir (const char *szPath)
+{
+ DIR *nd;
+ unsigned int rc;
+
+ errno = 0;
+
+ if (!szPath)
+ {
+ errno = EFAULT;
+ return (DIR *) 0;
+ }
+
+ if (szPath[0] == '\0')
+ {
+ errno = ENOTDIR;
+ return (DIR *) 0;
+ }
+
+ /* Attempt to determine if the given path really is a directory. */
+ rc = GetFileAttributes(szPath);
+ if (rc == -1)
+ {
+ /* call GetLastError for more error info */
+ errno = ENOENT;
+ return (DIR *) 0;
+ }
+ if (!(rc & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ /* Error, entry exists but not a directory. */
+ errno = ENOTDIR;
+ return (DIR *) 0;
+ }
+
+ /* Allocate enough space to store DIR structure and the complete
+ * directory path given. */
+ nd = (DIR *) malloc (sizeof (DIR) + strlen (szPath) + strlen (SLASH) +
+ strlen (SUFFIX));
+
+ if (!nd)
+ {
+ /* Error, out of memory. */
+ errno = ENOMEM;
+ return (DIR *) 0;
+ }
+
+ /* Create the search expression. */
+ strcpy (nd->dd_name, szPath);
+
+ /* Add on a slash if the path does not end with one. */
+ if (nd->dd_name[0] != '\0' &&
+ nd->dd_name[strlen (nd->dd_name) - 1] != '/' &&
+ nd->dd_name[strlen (nd->dd_name) - 1] != '\\')
+ {
+ strcat (nd->dd_name, SLASH);
+ }
+
+ /* Add on the search pattern */
+ strcat (nd->dd_name, SUFFIX);
+
+ /* Initialize handle to -1 so that a premature closedir doesn't try
+ * to call _findclose on it. */
+ nd->dd_handle = -1;
+
+ /* Initialize the status. */
+ nd->dd_stat = 0;
+
+ /* Initialize the dirent structure. ino and reclen are invalid under
+ * Win32, and name simply points at the appropriate part of the
+ * findfirst_t structure. */
+ nd->dd_dir.d_ino = 0;
+ nd->dd_dir.d_reclen = 0;
+ nd->dd_dir.d_namlen = 0;
+ nd->dd_dir.d_name = nd->dd_dta.name;
+
+ return nd;
+}
+
+
+/*
+ * readdir
+ *
+ * Return a pointer to a dirent structure filled with the information on the
+ * next entry in the directory.
+ */
+struct dirent *
+readdir (DIR * dirp)
+{
+ errno = 0;
+
+ /* Check for valid DIR struct. */
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return (struct dirent *) 0;
+ }
+
+ if (dirp->dd_dir.d_name != dirp->dd_dta.name)
+ {
+ /* The structure does not seem to be set up correctly. */
+ errno = EINVAL;
+ return (struct dirent *) 0;
+ }
+
+ if (dirp->dd_stat < 0)
+ {
+ /* We have already returned all files in the directory
+ * (or the structure has an invalid dd_stat). */
+ return (struct dirent *) 0;
+ }
+ else if (dirp->dd_stat == 0)
+ {
+ /* We haven't started the search yet. */
+ /* Start the search */
+ dirp->dd_handle = _findfirst (dirp->dd_name, &(dirp->dd_dta));
+
+ if (dirp->dd_handle == -1)
+ {
+ /* Whoops! Seems there are no files in that
+ * directory. */
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ dirp->dd_stat = 1;
+ }
+ }
+ else
+ {
+ /* Get the next search entry. */
+ if (_findnext (dirp->dd_handle, &(dirp->dd_dta)))
+ {
+ /* We are off the end or otherwise error. */
+ _findclose (dirp->dd_handle);
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Update the status to indicate the correct
+ * number. */
+ dirp->dd_stat++;
+ }
+ }
+
+ if (dirp->dd_stat > 0)
+ {
+ /* Successfully got an entry. Everything about the file is
+ * already appropriately filled in except the length of the
+ * file name. */
+ dirp->dd_dir.d_namlen = strlen (dirp->dd_dir.d_name);
+ return &dirp->dd_dir;
+ }
+
+ return (struct dirent *) 0;
+}
+
+
+/*
+ * closedir
+ *
+ * Frees up resources allocated by opendir.
+ */
+int
+closedir (DIR * dirp)
+{
+ int rc;
+
+ errno = 0;
+ rc = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ rc = _findclose (dirp->dd_handle);
+ }
+
+ /* Delete the dir structure. */
+ free (dirp);
+
+ return rc;
+}
+
+/*
+ * rewinddir
+ *
+ * Return to the beginning of the directory "stream". We simply call findclose
+ * and then reset things like an opendir.
+ */
+void
+rewinddir (DIR * dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+
+ dirp->dd_handle = -1;
+ dirp->dd_stat = 0;
+}
+
+/*
+ * telldir
+ *
+ * Returns the "position" in the "directory stream" which can be used with
+ * seekdir to go back to an old entry. We simply return the value in stat.
+ */
+long
+telldir (DIR * dirp)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return -1;
+ }
+ return dirp->dd_stat;
+}
+
+/*
+ * seekdir
+ *
+ * Seek to an entry previously returned by telldir. We rewind the directory
+ * and call readdir repeatedly until either dd_stat is the position number
+ * or -1 (off the end). This is not perfect, in that the directory may
+ * have changed while we weren't looking. But that is probably the case with
+ * any such system.
+ */
+void
+seekdir (DIR * dirp, long lPos)
+{
+ errno = 0;
+
+ if (!dirp)
+ {
+ errno = EFAULT;
+ return;
+ }
+
+ if (lPos < -1)
+ {
+ /* Seeking to an invalid position. */
+ errno = EINVAL;
+ return;
+ }
+ else if (lPos == -1)
+ {
+ /* Seek past end. */
+ if (dirp->dd_handle != -1)
+ {
+ _findclose (dirp->dd_handle);
+ }
+ dirp->dd_handle = -1;
+ dirp->dd_stat = -1;
+ }
+ else
+ {
+ /* Rewind and read forward to the appropriate index. */
+ rewinddir (dirp);
+
+ while ((dirp->dd_stat < lPos) && readdir (dirp))
+ ;
+ }
+}
diff --git a/MSVC/dirent/dirent.h b/MSVC/dirent/dirent.h
new file mode 100644
index 0000000..8c4a657
--- /dev/null
+++ b/MSVC/dirent/dirent.h
@@ -0,0 +1,96 @@
+/*
+ * DIRENT.H (formerly DIRLIB.H)
+ *
+ * by M. J. Weinstein Released to public domain 1-Jan-89
+ *
+ * Because I have heard that this feature (opendir, readdir, closedir)
+ * it so useful for programmers coming from UNIX or attempting to port
+ * UNIX code, and because it is reasonably light weight, I have included
+ * it in the Mingw32 package. I have also added an implementation of
+ * rewinddir, seekdir and telldir.
+ * - Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * This code is distributed in the hope that is will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includeds but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.1 $
+ * $Author: pixel $
+ * $Date: 2004-11-27 21:01:21 $
+ *
+ */
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _DIRENT_H_
+#define _DIRENT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#include <io.h>
+
+#ifndef RC_INVOKED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct dirent
+{
+ long d_ino; /* Always zero. */
+ unsigned short d_reclen; /* Always zero. */
+ unsigned short d_namlen; /* Length of name in d_name. */
+ char* d_name; /* File name. */
+ /* NOTE: The name in the dirent structure points to the name in the
+ * finddata_t structure in the DIR. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ */
+typedef struct
+{
+ /* disk transfer area for this dir */
+ struct _finddata_t dd_dta;
+
+ /* dirent struct to return from dir (NOTE: this makes this thread
+ * safe as long as only one thread uses a particular DIR struct at
+ * a time) */
+ struct dirent dd_dir;
+
+ /* _findnext handle */
+ long dd_handle;
+
+ /*
+ * Status of search:
+ * 0 = not started yet (next entry to read is first entry)
+ * -1 = off the end
+ * positive = 0 based index of next entry
+ */
+ short dd_stat;
+
+ /* given path for dir with search pattern (struct is extended) */
+ char dd_name[1];
+} DIR;
+
+
+DIR* opendir (const char*);
+struct dirent* readdir (DIR*);
+int closedir (DIR*);
+void rewinddir (DIR*);
+long telldir (DIR*);
+void seekdir (DIR*, long);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* Not _DIRENT_H_ */
+
+#endif /* Not __STRICT_ANSI__ */
+
diff --git a/include/BLua.h b/include/BLua.h
index a0daa59..52918ee 100644
--- a/include/BLua.h
+++ b/include/BLua.h
@@ -1,375 +1,376 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: BLua.h,v 1.17 2004-07-23 13:08:22 pixel Exp $ */
-
-#ifndef __BLUA_H__
-#define __BLUA_H__
-
-struct lua_State;
-
-extern "C" {
- void do_lua_lock(lua_State *);
- void do_lua_unlock(lua_State *);
-}
-
-#define lua_lock(L) do_lua_lock(L)
-#define lua_unlock(L) do_lua_unlock(L)
-
-#include <lua.h>
-#include <map>
-#include <Exceptions.h>
-#include <Handle.h>
-
-class Lua : public Base {
- public:
- Lua();
- Lua(const Lua &) throw (GeneralException);
- virtual ~Lua();
- void open_base();
- void open_table();
- void open_io();
- void open_string();
- void open_math();
- void open_debug();
- void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX);
- void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0);
- void call(int = 0, int = 0);
- void push();
- void push(lua_Number);
- void push(const String &);
- void push(bool);
- void push(char *, int size = -1);
- void push(void *);
- void push(lua_CFunction, int = 0);
- void pop(int = 1);
- void newtable();
- void * newuser(size_t);
- void settable(int = -3, bool raw = false);
- void gettable(int = -2, bool raw = false);
- void setvar();
- int gettop();
- void error(const String &);
- int type(int = -1);
- bool isnil(int = -1);
- bool isboolean(int = -1);
- bool isnumber(int = -1);
- bool isstring(int = -1);
- bool istable(int = -1);
- bool isfunction(int = -1);
- bool iscfunction(int = -1);
- bool isuserdata(int = -1);
- bool islightuserdata(int = -1);
- bool toboolean(int = -1);
- lua_Number tonumber(int = -1);
- String tostring(int = -1);
- lua_CFunction tocfunction(int = -1);
- void * touserdata(int = -1);
- Lua * tothread(int = -1);
- void load(Handle *, bool docall = true) throw (GeneralException);
- void dump(Handle *, bool strip = true);
- Lua * thread();
- int yield(int nargs = 0);
- int resume(int nresults = 0);
- static Lua * find(lua_State *) throw (GeneralException);
- void showerror();
- int getmetatable(int = -1);
- int setmetatable(int = -2);
- int sethook(lua_Hook func, int mask, int count);
-
- void do_break();
-
- virtual void lock() {}
- virtual void unlock() {}
- private:
- Lua(lua_State *);
- lua_State * L;
- static std::map<lua_State *, Lua *> lualist;
-};
-
-class LuaObject : public Base {
- public:
- LuaObject() : wantdestruct(false), pushed(false) {}
- virtual void push(Lua *) throw (GeneralException);
- static void * getme(Lua *, int = 1);
- void pushdestruct(Lua *) throw (GeneralException);
- protected:
- virtual void pushmembers(Lua *) = 0;
- void pushme(Lua *, void *, bool = true);
- static void pushit(Lua *, const String &, lua_CFunction);
- static void pushmeta(Lua *, const String &, lua_CFunction);
- bool wantdestruct, pushed;
-};
-
-class LuaException : public GeneralException {
- public:
- LuaException(String);
- protected:
- LuaException();
-};
-
-enum Lua_types_t {
- LUA_OBJECT = 0x01,
- LUA_TABLE = 0x02,
- LUA_BOOLEAN = 0x04,
- LUA_NUMBER = 0x08,
- LUA_STRING = 0x10,
- LUA_FUNCTION = 0x20,
- LUA_NIL = 0x40,
- LUA_ANY = 0x7f,
-};
-
-#define MAX_TYPE 7
-
-#define MAXARGS 32
-
-struct lua_functypes_t {
- int number;
- char * name;
- int minargs, maxargs;
- int argtypes[MAXARGS];
-};
-
-#define DECLARE_METHOD(classname, enumvar) static int method_##enumvar(lua_State * L) { \
- return LuaHelpers<classname>::method_multiplex( \
- enumvar, \
- L, \
- sLua_##classname::classname##_proceed, \
- 0, \
- classname##_methods, \
- true); \
- }
-
-#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \
- return LuaHelpers<classname>::method_multiplex( \
- enumvar, \
- L, \
- 0, \
- sLua_##classname::classname##_proceed_statics, \
- classname##_functions, \
- false); \
- }
-
-#define PUSH_METHOD(classname, enumvar) pushit( \
- L, \
- classname##_methods[enumvar].name, \
- sLua_##classname::method_##enumvar)
-
-#define PUSH_METAMETHOD(classname, enumvar) pushmeta( \
- L, \
- String("__") + classname##_methods[enumvar].name, \
- sLua_##classname::method_##enumvar)
-
-#define PUSH_FUNCTION(classname, enumvar) L->declarefunc( \
- classname##_functions[enumvar].name, \
- sLua_##classname::function_##enumvar)
-
-
-#define CHECK_METHODS(classname) { \
- int i = 0; \
- while (classname##_methods[i].number != -1) { \
- if (i != classname##_methods[i].number) { \
- throw GeneralException("Datas of " #classname "_methods inconsistants!"); \
- } \
- i++; \
- } \
-}
-
-#define CHECK_FUNCTIONS(classname) { \
- int i = 0; \
- while (classname##_functions[i].number != -1) { \
- if (i != classname##_functions[i].number) { \
- throw GeneralException("Datas of " #classname "_functions inconsistants!"); \
- } \
- i++; \
- } \
-}
-
-#include <typeinfo>
-
-template <class T>
-class LuaHelpers : public Base {
- public:
- static int method_multiplex(int caller, lua_State * _L, int (*proceed)(Lua * L, int n, T * obj, int caller), int (*proceed_static)(Lua * L, int n, int caller), lua_functypes_t * tab, bool method) {
- Lua * L = Lua::find(_L);
- int add = method ? 1 : 0;
- int n = L->gettop() - add;
- T * obj = 0;
- int i, j, mask;
- bool invalid = false, arg_valid;
-
- if (method)
- obj = (T *) LuaObject::getme(L);
-
- if ((n < tab[caller].minargs) || (n > tab[caller].maxargs)) {
- invalid = true;
- } else {
- for (i = 0; i < tab[caller].maxargs && !invalid; i++) {
- if (n >= (i + 1)) {
- arg_valid = false;
- for (j = 0; j < MAX_TYPE && !arg_valid; j++) {
- mask = 1 << j;
- if (tab[caller].argtypes[i] & mask) {
- switch(mask) {
- case LUA_OBJECT:
- if (L->istable(i + 1 + add)) {
- L->push("__obj");
- L->gettable(i + 1 + add);
- arg_valid = L->isuserdata();
- L->pop();
- } else {
- arg_valid = L->isnil(i + 1 + add);
- }
- break;
- case LUA_TABLE:
- arg_valid = L->istable(i + 1 + add);
- break;
- case LUA_BOOLEAN:
- arg_valid = L->isboolean(i + 1 + add);
- break;
- case LUA_NUMBER:
- arg_valid = L->isnumber(i + 1 + add);
- break;
- case LUA_STRING:
- arg_valid = L->isstring(i + 1 + add);
- break;
- case LUA_FUNCTION:
- arg_valid = L->isfunction(i + 1 + add);
- break;
- case LUA_NIL:
- arg_valid = L->isnil(i + 1 + add);
- break;
- }
- }
- }
- invalid = !arg_valid;
- }
- }
- }
-
- if (invalid) {
- if (method) {
- L->error(String("Invalid arguments to method `") + typeid(T).name() + "::" + tab[caller].name + "'");
- } else {
- L->error(String("Invalid arguments to function `") + typeid(T).name() + "::" + tab[caller].name + "'");
- }
- }
-
- if (method) {
- return proceed(L, n, obj, caller);
- } else {
- return proceed_static(L, n, caller);
- }
- }
-};
-
-
- /*******************************\
-|** Let's have a sample of use **|
- \*******************************/
-
-#ifdef THIS_IS_A_SAMPLE_WHICH_DOES_NOT_COMPILE
-Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
-
-enum cdfile_methods_t {
- CDFILE_XXX = 0,
- CDFILE_YYY
-};
-
-enum cdfile_functions_t {
- CDFILE_NEWCDFILE = 0,
-};
-
-struct lua_functypes_t cdutils_methods[] = {
- { CDFILE_XXX, "xxx", 1, 1, {LUA_OBJECT} },
- { CDFILE_YYY, "yyy", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
- { -1, 0, 0, 0, 0 }
-};
-
-struct lua_functypes_t cdfile_functions[] = {
- { CDFILE_NEWCDFILE, "cdfile", 1, 4, {LUA_OBJECT, LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cdfile : public Base {
- public:
- static int newcdfile(lua_State * L);
- DECLARE_METHOD(cdfile, CDFILE_XXX);
- DECLARE_METHOD(cdfile, CDFILE_YYY);
- DECLARE_FUNCTION(cdfile, CDFILE_NEWCDFILE);
- private:
- static int cdfile_proceed(Lua * L, int n, cdfile * obj, int caller);
- static int cdfile_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacdfile::pushmembers(Lua * L) {
- {
- LuaHandle::pushmembers(L);
- or
- pushme(L, SomeObject);
- }
- PUSH_METHOD(cdfile, CDFILE_XXX);
- PUSH_METHOD(cdfile, CDFILE_YYY);
-}
-
-void Luacdfile::pushstatics(Lua * L) {
- CHECK_METHODS(cdfile);
- CHECK_FUNCTIONS(cdfile);
-
- PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE);
-}
-
-int sLua_cdfile::cdfile_proceed(Lua * L, int n, cdfile * cdfile, int caller) {
- int r = 0;
- SomeObj * obj;
- int arg1 = DEFAULT1, arg2 = DEFAULT2;
-
- switch(caller) {
- case CDFILE_XXX:
- obj = (SomeObj *) LuaObject::getme(L, 2);
- cdfile->xxx(obj);
- break;
- case CDFILE_YYY:
- if (n >= 1)
- arg1 = L->tonumber(2);
- if (n >= 2)
- arg2 = L->tonumber(3);
- L->push((lua_Number) cdfile->yyy(arg1, arg2));
- r = 1;
- break;
- }
-
- return r;
-}
-
-int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
-
- switch(caller) {
- case CDFILE_NEWCDFILE:
- /****TODO****/
- break;
- }
-
- return r;
-}
-
-#endif
-
-#endif
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: BLua.h,v 1.18 2004-11-27 21:01:20 pixel Exp $ */
+
+#ifndef __BLUA_H__
+#define __BLUA_H__
+
+struct lua_State;
+
+extern "C" {
+ void do_lua_lock(lua_State *);
+ void do_lua_unlock(lua_State *);
+}
+
+#define lua_lock(L) do_lua_lock(L)
+#define lua_unlock(L) do_lua_unlock(L)
+
+#include <lua.h>
+#include <map>
+#include <Exceptions.h>
+#include <Handle.h>
+
+class Lua : public Base {
+ public:
+ Lua();
+ Lua(const Lua &) throw (GeneralException);
+ virtual ~Lua();
+ void open_base();
+ void open_table();
+ void open_io();
+ void open_string();
+ void open_math();
+ void open_debug();
+ void open_dir();
+ void declarefunc(const String &, lua_CFunction, int = LUA_GLOBALSINDEX);
+ void call(const String &, int = LUA_GLOBALSINDEX, int = 0, int = 0);
+ void call(int = 0, int = 0);
+ void push();
+ void push(lua_Number);
+ void push(const String &);
+ void push(bool);
+ void push(char *, int size = -1);
+ void push(void *);
+ void push(lua_CFunction, int = 0);
+ void pop(int = 1);
+ void newtable();
+ void * newuser(size_t);
+ void settable(int = -3, bool raw = false);
+ void gettable(int = -2, bool raw = false);
+ void setvar();
+ int gettop();
+ void error(const String &);
+ int type(int = -1);
+ bool isnil(int = -1);
+ bool isboolean(int = -1);
+ bool isnumber(int = -1);
+ bool isstring(int = -1);
+ bool istable(int = -1);
+ bool isfunction(int = -1);
+ bool iscfunction(int = -1);
+ bool isuserdata(int = -1);
+ bool islightuserdata(int = -1);
+ bool toboolean(int = -1);
+ lua_Number tonumber(int = -1);
+ String tostring(int = -1);
+ lua_CFunction tocfunction(int = -1);
+ void * touserdata(int = -1);
+ Lua * tothread(int = -1);
+ void load(Handle *, bool docall = true) throw (GeneralException);
+ void dump(Handle *, bool strip = true);
+ Lua * thread();
+ int yield(int nargs = 0);
+ int resume(int nresults = 0);
+ static Lua * find(lua_State *) throw (GeneralException);
+ void showerror();
+ int getmetatable(int = -1);
+ int setmetatable(int = -2);
+ int sethook(lua_Hook func, int mask, int count);
+
+ void do_break();
+
+ virtual void lock() {}
+ virtual void unlock() {}
+ private:
+ Lua(lua_State *);
+ lua_State * L;
+ static std::map<lua_State *, Lua *> lualist;
+};
+
+class LuaObject : public Base {
+ public:
+ LuaObject() : wantdestruct(false), pushed(false) {}
+ virtual void push(Lua *) throw (GeneralException);
+ static void * getme(Lua *, int = 1);
+ void pushdestruct(Lua *) throw (GeneralException);
+ protected:
+ virtual void pushmembers(Lua *) = 0;
+ void pushme(Lua *, void *, bool = true);
+ static void pushit(Lua *, const String &, lua_CFunction);
+ static void pushmeta(Lua *, const String &, lua_CFunction);
+ bool wantdestruct, pushed;
+};
+
+class LuaException : public GeneralException {
+ public:
+ LuaException(String);
+ protected:
+ LuaException();
+};
+
+enum Lua_types_t {
+ LUA_OBJECT = 0x01,
+ LUA_TABLE = 0x02,
+ LUA_BOOLEAN = 0x04,
+ LUA_NUMBER = 0x08,
+ LUA_STRING = 0x10,
+ LUA_FUNCTION = 0x20,
+ LUA_NIL = 0x40,
+ LUA_ANY = 0x7f,
+};
+
+#define MAX_TYPE 7
+
+#define MAXARGS 32
+
+struct lua_functypes_t {
+ int number;
+ char * name;
+ int minargs, maxargs;
+ int argtypes[MAXARGS];
+};
+
+#define DECLARE_METHOD(classname, enumvar) static int method_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ sLua_##classname::classname##_proceed, \
+ 0, \
+ classname##_methods, \
+ true); \
+ }
+
+#define DECLARE_FUNCTION(classname, enumvar) static int function_##enumvar(lua_State * L) { \
+ return LuaHelpers<classname>::method_multiplex( \
+ enumvar, \
+ L, \
+ 0, \
+ sLua_##classname::classname##_proceed_statics, \
+ classname##_functions, \
+ false); \
+ }
+
+#define PUSH_METHOD(classname, enumvar) pushit( \
+ L, \
+ classname##_methods[enumvar].name, \
+ sLua_##classname::method_##enumvar)
+
+#define PUSH_METAMETHOD(classname, enumvar) pushmeta( \
+ L, \
+ String("__") + classname##_methods[enumvar].name, \
+ sLua_##classname::method_##enumvar)
+
+#define PUSH_FUNCTION(classname, enumvar) L->declarefunc( \
+ classname##_functions[enumvar].name, \
+ sLua_##classname::function_##enumvar)
+
+
+#define CHECK_METHODS(classname) { \
+ int i = 0; \
+ while (classname##_methods[i].number != -1) { \
+ if (i != classname##_methods[i].number) { \
+ throw GeneralException("Datas of " #classname "_methods inconsistants!"); \
+ } \
+ i++; \
+ } \
+}
+
+#define CHECK_FUNCTIONS(classname) { \
+ int i = 0; \
+ while (classname##_functions[i].number != -1) { \
+ if (i != classname##_functions[i].number) { \
+ throw GeneralException("Datas of " #classname "_functions inconsistants!"); \
+ } \
+ i++; \
+ } \
+}
+
+#include <typeinfo>
+
+template <class T>
+class LuaHelpers : public Base {
+ public:
+ static int method_multiplex(int caller, lua_State * _L, int (*proceed)(Lua * L, int n, T * obj, int caller), int (*proceed_static)(Lua * L, int n, int caller), lua_functypes_t * tab, bool method) {
+ Lua * L = Lua::find(_L);
+ int add = method ? 1 : 0;
+ int n = L->gettop() - add;
+ T * obj = 0;
+ int i, j, mask;
+ bool invalid = false, arg_valid;
+
+ if (method)
+ obj = (T *) LuaObject::getme(L);
+
+ if ((n < tab[caller].minargs) || (n > tab[caller].maxargs)) {
+ invalid = true;
+ } else {
+ for (i = 0; i < tab[caller].maxargs && !invalid; i++) {
+ if (n >= (i + 1)) {
+ arg_valid = false;
+ for (j = 0; j < MAX_TYPE && !arg_valid; j++) {
+ mask = 1 << j;
+ if (tab[caller].argtypes[i] & mask) {
+ switch(mask) {
+ case LUA_OBJECT:
+ if (L->istable(i + 1 + add)) {
+ L->push("__obj");
+ L->gettable(i + 1 + add);
+ arg_valid = L->isuserdata();
+ L->pop();
+ } else {
+ arg_valid = L->isnil(i + 1 + add);
+ }
+ break;
+ case LUA_TABLE:
+ arg_valid = L->istable(i + 1 + add);
+ break;
+ case LUA_BOOLEAN:
+ arg_valid = L->isboolean(i + 1 + add);
+ break;
+ case LUA_NUMBER:
+ arg_valid = L->isnumber(i + 1 + add);
+ break;
+ case LUA_STRING:
+ arg_valid = L->isstring(i + 1 + add);
+ break;
+ case LUA_FUNCTION:
+ arg_valid = L->isfunction(i + 1 + add);
+ break;
+ case LUA_NIL:
+ arg_valid = L->isnil(i + 1 + add);
+ break;
+ }
+ }
+ }
+ invalid = !arg_valid;
+ }
+ }
+ }
+
+ if (invalid) {
+ if (method) {
+ L->error(String("Invalid arguments to method `") + typeid(T).name() + "::" + tab[caller].name + "'");
+ } else {
+ L->error(String("Invalid arguments to function `") + typeid(T).name() + "::" + tab[caller].name + "'");
+ }
+ }
+
+ if (method) {
+ return proceed(L, n, obj, caller);
+ } else {
+ return proceed_static(L, n, caller);
+ }
+ }
+};
+
+
+ /*******************************\
+|** Let's have a sample of use **|
+ \*******************************/
+
+#ifdef THIS_IS_A_SAMPLE_WHICH_DOES_NOT_COMPILE
+Luacdfile::Luacdfile(cdfile * h) : LuaHandle(h) { }
+
+enum cdfile_methods_t {
+ CDFILE_XXX = 0,
+ CDFILE_YYY
+};
+
+enum cdfile_functions_t {
+ CDFILE_NEWCDFILE = 0,
+};
+
+struct lua_functypes_t cdutils_methods[] = {
+ { CDFILE_XXX, "xxx", 1, 1, {LUA_OBJECT} },
+ { CDFILE_YYY, "yyy", 0, 2, {LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+struct lua_functypes_t cdfile_functions[] = {
+ { CDFILE_NEWCDFILE, "cdfile", 1, 4, {LUA_OBJECT, LUA_ANY, LUA_NUMBER, LUA_NUMBER} },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdfile : public Base {
+ public:
+ static int newcdfile(lua_State * L);
+ DECLARE_METHOD(cdfile, CDFILE_XXX);
+ DECLARE_METHOD(cdfile, CDFILE_YYY);
+ DECLARE_FUNCTION(cdfile, CDFILE_NEWCDFILE);
+ private:
+ static int cdfile_proceed(Lua * L, int n, cdfile * obj, int caller);
+ static int cdfile_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdfile::pushmembers(Lua * L) {
+ {
+ LuaHandle::pushmembers(L);
+ or
+ pushme(L, SomeObject);
+ }
+ PUSH_METHOD(cdfile, CDFILE_XXX);
+ PUSH_METHOD(cdfile, CDFILE_YYY);
+}
+
+void Luacdfile::pushstatics(Lua * L) {
+ CHECK_METHODS(cdfile);
+ CHECK_FUNCTIONS(cdfile);
+
+ PUSH_FUNCTION(cdfile, CDFILE_NEWCDFILE);
+}
+
+int sLua_cdfile::cdfile_proceed(Lua * L, int n, cdfile * cdfile, int caller) {
+ int r = 0;
+ SomeObj * obj;
+ int arg1 = DEFAULT1, arg2 = DEFAULT2;
+
+ switch(caller) {
+ case CDFILE_XXX:
+ obj = (SomeObj *) LuaObject::getme(L, 2);
+ cdfile->xxx(obj);
+ break;
+ case CDFILE_YYY:
+ if (n >= 1)
+ arg1 = L->tonumber(2);
+ if (n >= 2)
+ arg2 = L->tonumber(3);
+ L->push((lua_Number) cdfile->yyy(arg1, arg2));
+ r = 1;
+ break;
+ }
+
+ return r;
+}
+
+int sLua_cdfile::cdfile_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch(caller) {
+ case CDFILE_NEWCDFILE:
+ /****TODO****/
+ break;
+ }
+
+ return r;
+}
+
+#endif
+
+#endif
diff --git a/lib/BLua.cc b/lib/BLua.cc
index 1c125a2..9366dd8 100644
--- a/lib/BLua.cc
+++ b/lib/BLua.cc
@@ -1,662 +1,667 @@
-/*
- * Baltisot
- * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: BLua.cc,v 1.20 2004-07-23 13:08:23 pixel Exp $ */
-
-#include "BLua.h"
-#include <lualib.h>
-
-#ifndef BUFFERSIZE
-#define BUFFERSIZE 2048
-#endif
-
-
-
-extern "C" {
- void do_lua_lock(lua_State * _L) {
- Lua * L;
- try {
- L = Lua::find(_L);
- } catch (GeneralException e) {
- return;
- }
- L->lock();
- }
-
- void do_lua_unlock(lua_State * _L) {
- Lua * L;
- try {
- L = Lua::find(_L);
- } catch (GeneralException e) {
- return;
- }
- L->unlock();
- }
-}
-
-class LuaStatics : public Base {
- public:
- static const char * getF(lua_State *, void *, size_t *);
- static int putF(lua_State *, const void *, size_t, void *);
- static int luapanic(lua_State *);
- static int trueluapanic(lua_State *) throw(GeneralException);
- static int collector(lua_State *);
- static int destructor(lua_State *);
-
- static int andB(lua_State *);
- static int orB(lua_State *);
- static int xorB(lua_State *);
- static int notB(lua_State *);
- static int hex(lua_State *);
- static int shl(lua_State *);
- static int shr(lua_State *);
-};
-
-std::map<lua_State *, Lua *> Lua::lualist;
-
-int LuaStatics::luapanic(lua_State * L) {
- return trueluapanic(L);
-}
-
-int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) {
- Lua::find(L)->showerror();
- throw LuaException("Error running Lua code, bailing out.");
-}
-
-int LuaStatics::andB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `andB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a & b));
-
- return 1;
-}
-
-int LuaStatics::orB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `orB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a | b));
-
- return 1;
-}
-
-int LuaStatics::xorB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
- L->error("Incorrect arguments to function `xorB'");
- }
-
- a = L->tonumber(1);
- b = L->tonumber(2);
-
- L->push((lua_Number) (a ^ b));
-
- return 1;
-}
-
-int LuaStatics::notB(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 x;
-
- if ((n != 1) && !L->isnumber()) {
- L->error("Incorrect arguments to function `notB'");
- }
-
- x = L->tonumber();
-
- L->push((lua_Number) (~x));
-
- return 1;
-}
-
-int LuaStatics::shl(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to function `shl'");
- }
-
- a = L->tonumber(1);
- if (n == 2)
- b = L->tonumber(2);
- else
- b = 1;
-
- L->push((lua_Number) (a << b));
-
- return 1;
-}
-
-int LuaStatics::shr(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- Uint32 a, b;
-
- if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
- L->error("Incorrect arguments to function `shr'");
- }
-
- a = L->tonumber(1);
- if (n == 2)
- b = L->tonumber(2);
- else
- b = 1;
-
- L->push((lua_Number) (a >> b));
-
- return 1;
-}
-
-int LuaStatics::hex(lua_State * _L) {
- Lua * L = Lua::find(_L);
- int n = L->gettop();
- int x;
- String r;
-
- if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) {
- L->error("Incorrect arguments to function `hex'");
- }
-
- x = L->tonumber(1);
- String fmt = n == 2 ? L->tostring() : "%02x";
- r.set(fmt.to_charp(), x);
-
- L->push(r);
-
- return 1;
-}
-
-Lua::Lua() : L(lua_open()) {
- lua_atpanic(L, LuaStatics::luapanic);
- lualist[L] = this;
-
- declarefunc("andB", LuaStatics::andB);
- declarefunc("orB", LuaStatics::orB);
- declarefunc("xorB", LuaStatics::xorB);
- declarefunc("notB", LuaStatics::notB);
- declarefunc("shl", LuaStatics::shl);
- declarefunc("shr", LuaStatics::shr);
- declarefunc("hex", LuaStatics::hex);
-}
-
-Lua::Lua(lua_State * _L) : L(_L) {
- lua_atpanic(L, LuaStatics::luapanic);
- lualist[L] = this;
-}
-
-Lua::~Lua() {
- lua_setgcthreshold(L, 0);
- lua_close(L);
-}
-
-Lua::Lua(const Lua & l) throw (GeneralException) {
- throw GeneralException("Error: can't duplicate a Lua object.");
-}
-
-void Lua::open_base() {
- luaopen_base(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_table() {
- luaopen_table(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_io() {
- luaopen_io(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_string() {
- luaopen_string(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_math() {
- luaopen_math(L);
- lua_pop(L, 1);
-}
-
-void Lua::open_debug() {
- luaopen_debug(L);
- lua_pop(L, 1);
-}
-
-void Lua::declarefunc(const String & name, lua_CFunction f, int i) {
- lua_pushstring(L, name.to_charp());
- lua_pushcfunction(L, f);
- lua_settable(L, i);
-}
-
-void Lua::call(const String & f, int i, int nargs, int nresults) {
- lua_pushstring(L, f.to_charp());
- lua_gettable(L, i);
- lua_insert(L, -1 - nargs - nresults);
- lua_call(L, nargs, nresults);
-}
-
-void Lua::call(int nargs, int nresults) {
- lua_call(L, nargs, nresults);
-}
-
-void Lua::push() {
- lua_pushnil(L);
-}
-
-void Lua::push(lua_Number n) {
- lua_pushnumber(L, n);
-}
-
-void Lua::push(const String & s) {
- lua_pushlstring(L, s.to_charp(), s.strlen());
-}
-
-void Lua::push(bool b) {
- lua_pushboolean(L, b);
-}
-
-void Lua::push(char * s, int size) {
- if (size < 0) {
- lua_pushstring(L, s);
- } else {
- lua_pushlstring(L, s, size);
- }
-}
-
-void Lua::push(void * p) {
- lua_pushlightuserdata(L, p);
-}
-
-void Lua::push(lua_CFunction f, int n) {
- lua_pushcclosure(L, f, n);
-}
-
-void Lua::pop(int n) {
- lua_pop(L, n);
-}
-
-void Lua::newtable() {
- lua_newtable(L);
-}
-
-void * Lua::newuser(size_t s) {
- return lua_newuserdata(L, s);
-}
-
-void Lua::settable(int i, bool raw) {
- if (raw) {
- lua_rawset(L, i);
- } else {
- lua_settable(L, i);
- }
-}
-
-void Lua::gettable(int i, bool raw) {
- if (raw) {
- lua_rawget(L, i);
- } else {
- lua_gettable(L, i);
- }
-}
-
-void Lua::setvar() {
- lua_settable(L, LUA_GLOBALSINDEX);
-}
-
-int Lua::gettop() {
- return lua_gettop(L);
-}
-
-void Lua::error(const String & msg) {
- push(msg);
- lua_error(L);
-}
-
-int Lua::type(int i) {
- return lua_type(L, i);
-}
-
-bool Lua::isnil(int i) {
- return lua_isnil(L, i);
-}
-
-bool Lua::isboolean(int i) {
- return lua_isboolean(L, i);
-}
-
-bool Lua::isnumber(int i) {
- return lua_isnumber(L, i);
-}
-
-bool Lua::isstring(int i) {
- return lua_isstring(L, i);
-}
-
-bool Lua::istable(int i) {
- return lua_istable(L, i);
-}
-
-bool Lua::isfunction(int i) {
- return lua_isfunction(L, i);
-}
-
-bool Lua::iscfunction(int i) {
- return lua_iscfunction(L, i);
-}
-
-bool Lua::isuserdata(int i) {
- return lua_isuserdata(L, i);
-}
-
-bool Lua::islightuserdata(int i) {
- return lua_islightuserdata(L, i);
-}
-
-bool Lua::toboolean(int i) {
- return lua_toboolean(L, i);
-}
-
-lua_Number Lua::tonumber(int i) {
- return lua_tonumber(L, i);
-}
-
-String Lua::tostring(int i) {
- if (isnil(i))
- return String();
- return String(lua_tostring(L, i));
-}
-
-lua_CFunction Lua::tocfunction(int i) {
- return lua_tocfunction(L, i);
-}
-
-void * Lua::touserdata(int i) {
- return lua_touserdata(L, i);
-}
-
-Lua * Lua::tothread(int i) {
- return find(lua_tothread(L, i));
-}
-
-struct LoadF {
- Handle * f;
- char buff[BUFFERSIZE];
-};
-
-const char * LuaStatics::getF(lua_State * L, void * ud, size_t * size) {
- LoadF *lf = (LoadF *)ud;
- (void)L;
-
- *size = lf->f->read(lf->buff, BUFFERSIZE);
- return (*size > 0) ? lf->buff : NULL;
-}
-
-struct DumpF {
- Handle * f;
-};
-
-int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) {
- DumpF *lf = (DumpF *)ud;
- (void)L;
-
- return lf->f->write(p, size) == size;
-}
-
-void Lua::load(Handle * h, bool docall) throw (GeneralException) {
- LoadF lf;
- int status;
-
- lf.f = h;
-
- status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp());
-
- if (status) {
- showerror();
- throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'");
- }
-
- if (docall)
- call();
-}
-
-extern "C" void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void * uD);
-
-void Lua::dump(Handle * h, bool strip) {
- DumpF lf;
-
- lf.f = h;
-
- luacmain(L, strip, LuaStatics::putF, &lf);
-}
-
-Lua * Lua::thread() {
- return new Lua(lua_newthread(L));
-}
-
-int Lua::yield(int nargs) {
- return lua_yield(L, nargs);
-}
-
-int Lua::resume(int nresults) {
- return lua_resume(L, nresults);
-}
-
-Lua * Lua::find(lua_State * _L) throw (GeneralException) {
- std::map<lua_State *, Lua *>::iterator i;
-
- if ((i = lualist.find(_L)) == lualist.end()) {
- throw GeneralException("Unable to find the Lua object for this context");
- }
-
- return i->second;
-}
-
-void Lua::showerror() {
- int n = lua_gettop(L);
- int i;
- String t;
-
- printm(M_ERROR, "Lua object: Got an LUA error\n");
- printm(M_ERROR, "Inspecting LUA stack\n");
-
- if (n == 0) {
- printm(M_ERROR, "Stack empty\n");
- return;
- }
-
- for (i = 1; i <= n; i++) {
- switch(lua_type(L, i)) {
- case LUA_TNONE:
- t = "Invalid";
- break;
- case LUA_TNIL:
- t = "(Nil)";
- break;
- case LUA_TNUMBER:
- t.set("(Number) %f", lua_tonumber(L, i));
- break;
- case LUA_TBOOLEAN:
- t = String("(Bool) ") + (lua_toboolean(L, i) ? "true" : "false");
- break;
- case LUA_TSTRING:
- t = String("(String) ") + lua_tostring(L, i);
- break;
- case LUA_TTABLE:
- t = "(Table)";
- break;
- case LUA_TFUNCTION:
- t = "(Function)";
- break;
- default:
- t = "Unknown";
- }
-
- printm(M_ERROR, String(i) + ": " + t + "\n");
- }
-}
-
-int Lua::getmetatable(int i) {
- return lua_getmetatable(L, i);
-}
-
-int Lua::setmetatable(int i) {
- return lua_setmetatable(L, i);
-}
-
-int Lua::sethook(lua_Hook func, int mask, int count) {
- return lua_sethook(L, func, mask, count);
-}
-
-void Lua::do_break() {
- lua_break(L);
-}
-
-void LuaObject::push(Lua * L) throw (GeneralException) {
- if (pushed && wantdestruct) {
- throw GeneralException("Error: object is owned by the LUA script and can not be pushed.");
- }
- L->newtable();
- pushmembers(L);
- pushed = true;
-}
-
-void LuaObject::pushme(Lua * L, void * o, bool obj) {
- void ** u;
- bool * b;
- L->push("__obj");
- u = (void **) L->newuser(sizeof(o) + sizeof(bool));
- *u = o;
- b = (bool *) (u + 1);
- *b = obj;
- L->settable(-3, true);
-}
-
-void * LuaObject::getme(Lua * L, int i) {
- void ** r = 0;
-
- if (L->istable(i)) {
- L->push("__obj");
- L->gettable(i, true);
- if (!(r = (void **) L->touserdata()))
- L->error("Table is not an object.");
- if (!*r)
- L->error("Object already destroyed.");
- L->pop();
- } else if (L->isnil(i)) {
- r = 0;
- } else {
- L->error("Not an object (not even a table).");
- }
-
- return r ? *r : 0;
-}
-
-void LuaObject::pushit(Lua * L, const String & s, lua_CFunction f) {
- L->push(s);
- L->push(f);
- L->settable(-3, true);
-}
-
-void LuaObject::pushmeta(Lua * L, const String & s, lua_CFunction f) {
- if (!L->getmetatable()) {
- L->newtable();
- }
- L->push(s);
- L->push(f);
- L->settable();
- L->setmetatable();
-}
-
-int LuaStatics::collector(lua_State * _L) {
- Lua * L = Lua::find(_L);
- void ** u = (void **) L->touserdata();
- bool * obj = (bool *) (u + 1);
-// printm(M_INFO, "From LUA: collecting object\n");
- if (*obj) {
-// printm(M_INFO, "Is object at %p\n", *u);
- Base * b = (Base *) *u;
- delete b;
- } else {
-// printm(M_INFO, "Is struct at %p\n", *u);
- free(*u);
- }
- *u = 0;
- return 0;
-}
-
-int LuaStatics::destructor(lua_State * _L) {
- Lua * L = Lua::find(_L);
- Base * b = (Base *) LuaObject::getme(L);
- delete b;
- L->push("__obj");
- L->gettable(-2, true);
- void ** u = (void **) L->touserdata();
- bool * obj = (bool *) (u + 1);
- if (*obj) {
- Base * b = (Base *) *u;
- delete b;
- } else {
- free(*u);
- }
- *u = 0;
- L->pop();
- return 0;
-}
-
-void LuaObject::pushdestruct(Lua * L) throw (GeneralException) {
- if (pushed) {
- throw GeneralException("Error: can't push destructor, object already pushed");
- }
- push(L);
- L->push("__obj");
- L->gettable(-2, true);
- pushmeta(L, "__gc", LuaStatics::collector);
- L->pop();
- pushit(L, "destroy", LuaStatics::destructor);
-
- wantdestruct = true;
-}
-
-LuaException::LuaException(String fn) : GeneralException(fn) { }
-
-LuaException::LuaException() { }
+/*
+ * Baltisot
+ * Copyright (C) 1999-2003 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: BLua.cc,v 1.21 2004-11-27 21:01:20 pixel Exp $ */
+
+#include "BLua.h"
+#include <lualib.h>
+
+#ifndef BUFFERSIZE
+#define BUFFERSIZE 2048
+#endif
+
+
+
+extern "C" {
+ void do_lua_lock(lua_State * _L) {
+ Lua * L;
+ try {
+ L = Lua::find(_L);
+ } catch (GeneralException e) {
+ return;
+ }
+ L->lock();
+ }
+
+ void do_lua_unlock(lua_State * _L) {
+ Lua * L;
+ try {
+ L = Lua::find(_L);
+ } catch (GeneralException e) {
+ return;
+ }
+ L->unlock();
+ }
+}
+
+class LuaStatics : public Base {
+ public:
+ static const char * getF(lua_State *, void *, size_t *);
+ static int putF(lua_State *, const void *, size_t, void *);
+ static int luapanic(lua_State *);
+ static int trueluapanic(lua_State *) throw(GeneralException);
+ static int collector(lua_State *);
+ static int destructor(lua_State *);
+
+ static int andB(lua_State *);
+ static int orB(lua_State *);
+ static int xorB(lua_State *);
+ static int notB(lua_State *);
+ static int hex(lua_State *);
+ static int shl(lua_State *);
+ static int shr(lua_State *);
+};
+
+std::map<lua_State *, Lua *> Lua::lualist;
+
+int LuaStatics::luapanic(lua_State * L) {
+ return trueluapanic(L);
+}
+
+int LuaStatics::trueluapanic(lua_State * L) throw (GeneralException) {
+ Lua::find(L)->showerror();
+ throw LuaException("Error running Lua code, bailing out.");
+}
+
+int LuaStatics::andB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
+ L->error("Incorrect arguments to function `andB'");
+ }
+
+ a = L->tonumber(1);
+ b = L->tonumber(2);
+
+ L->push((lua_Number) (a & b));
+
+ return 1;
+}
+
+int LuaStatics::orB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
+ L->error("Incorrect arguments to function `orB'");
+ }
+
+ a = L->tonumber(1);
+ b = L->tonumber(2);
+
+ L->push((lua_Number) (a | b));
+
+ return 1;
+}
+
+int LuaStatics::xorB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n != 2) && !L->isnumber(1) && !L->isnumber(2)) {
+ L->error("Incorrect arguments to function `xorB'");
+ }
+
+ a = L->tonumber(1);
+ b = L->tonumber(2);
+
+ L->push((lua_Number) (a ^ b));
+
+ return 1;
+}
+
+int LuaStatics::notB(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 x;
+
+ if ((n != 1) && !L->isnumber()) {
+ L->error("Incorrect arguments to function `notB'");
+ }
+
+ x = L->tonumber();
+
+ L->push((lua_Number) (~x));
+
+ return 1;
+}
+
+int LuaStatics::shl(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
+ L->error("Incorrect arguments to function `shl'");
+ }
+
+ a = L->tonumber(1);
+ if (n == 2)
+ b = L->tonumber(2);
+ else
+ b = 1;
+
+ L->push((lua_Number) (a << b));
+
+ return 1;
+}
+
+int LuaStatics::shr(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ Uint32 a, b;
+
+ if ((n > 2) && !L->isnumber(1) && ((n == 2) && !L->isnumber(2))) {
+ L->error("Incorrect arguments to function `shr'");
+ }
+
+ a = L->tonumber(1);
+ if (n == 2)
+ b = L->tonumber(2);
+ else
+ b = 1;
+
+ L->push((lua_Number) (a >> b));
+
+ return 1;
+}
+
+int LuaStatics::hex(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ int n = L->gettop();
+ int x;
+ String r;
+
+ if (((n != 1) || (n != 2)) && !L->isnumber(1) && ((n == 2) && !L->isstring(2))) {
+ L->error("Incorrect arguments to function `hex'");
+ }
+
+ x = L->tonumber(1);
+ String fmt = n == 2 ? L->tostring() : "%02x";
+ r.set(fmt.to_charp(), x);
+
+ L->push(r);
+
+ return 1;
+}
+
+Lua::Lua() : L(lua_open()) {
+ lua_atpanic(L, LuaStatics::luapanic);
+ lualist[L] = this;
+
+ declarefunc("andB", LuaStatics::andB);
+ declarefunc("orB", LuaStatics::orB);
+ declarefunc("xorB", LuaStatics::xorB);
+ declarefunc("notB", LuaStatics::notB);
+ declarefunc("shl", LuaStatics::shl);
+ declarefunc("shr", LuaStatics::shr);
+ declarefunc("hex", LuaStatics::hex);
+}
+
+Lua::Lua(lua_State * _L) : L(_L) {
+ lua_atpanic(L, LuaStatics::luapanic);
+ lualist[L] = this;
+}
+
+Lua::~Lua() {
+ lua_setgcthreshold(L, 0);
+ lua_close(L);
+}
+
+Lua::Lua(const Lua & l) throw (GeneralException) {
+ throw GeneralException("Error: can't duplicate a Lua object.");
+}
+
+void Lua::open_base() {
+ luaopen_base(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_table() {
+ luaopen_table(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_io() {
+ luaopen_io(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_string() {
+ luaopen_string(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_math() {
+ luaopen_math(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_debug() {
+ luaopen_debug(L);
+ lua_pop(L, 1);
+}
+
+void Lua::open_dir() {
+ luaopen_dir(L);
+ lua_pop(L, 1);
+}
+
+void Lua::declarefunc(const String & name, lua_CFunction f, int i) {
+ lua_pushstring(L, name.to_charp());
+ lua_pushcfunction(L, f);
+ lua_settable(L, i);
+}
+
+void Lua::call(const String & f, int i, int nargs, int nresults) {
+ lua_pushstring(L, f.to_charp());
+ lua_gettable(L, i);
+ lua_insert(L, -1 - nargs - nresults);
+ lua_call(L, nargs, nresults);
+}
+
+void Lua::call(int nargs, int nresults) {
+ lua_call(L, nargs, nresults);
+}
+
+void Lua::push() {
+ lua_pushnil(L);
+}
+
+void Lua::push(lua_Number n) {
+ lua_pushnumber(L, n);
+}
+
+void Lua::push(const String & s) {
+ lua_pushlstring(L, s.to_charp(), s.strlen());
+}
+
+void Lua::push(bool b) {
+ lua_pushboolean(L, b);
+}
+
+void Lua::push(char * s, int size) {
+ if (size < 0) {
+ lua_pushstring(L, s);
+ } else {
+ lua_pushlstring(L, s, size);
+ }
+}
+
+void Lua::push(void * p) {
+ lua_pushlightuserdata(L, p);
+}
+
+void Lua::push(lua_CFunction f, int n) {
+ lua_pushcclosure(L, f, n);
+}
+
+void Lua::pop(int n) {
+ lua_pop(L, n);
+}
+
+void Lua::newtable() {
+ lua_newtable(L);
+}
+
+void * Lua::newuser(size_t s) {
+ return lua_newuserdata(L, s);
+}
+
+void Lua::settable(int i, bool raw) {
+ if (raw) {
+ lua_rawset(L, i);
+ } else {
+ lua_settable(L, i);
+ }
+}
+
+void Lua::gettable(int i, bool raw) {
+ if (raw) {
+ lua_rawget(L, i);
+ } else {
+ lua_gettable(L, i);
+ }
+}
+
+void Lua::setvar() {
+ lua_settable(L, LUA_GLOBALSINDEX);
+}
+
+int Lua::gettop() {
+ return lua_gettop(L);
+}
+
+void Lua::error(const String & msg) {
+ push(msg);
+ lua_error(L);
+}
+
+int Lua::type(int i) {
+ return lua_type(L, i);
+}
+
+bool Lua::isnil(int i) {
+ return lua_isnil(L, i);
+}
+
+bool Lua::isboolean(int i) {
+ return lua_isboolean(L, i);
+}
+
+bool Lua::isnumber(int i) {
+ return lua_isnumber(L, i);
+}
+
+bool Lua::isstring(int i) {
+ return lua_isstring(L, i);
+}
+
+bool Lua::istable(int i) {
+ return lua_istable(L, i);
+}
+
+bool Lua::isfunction(int i) {
+ return lua_isfunction(L, i);
+}
+
+bool Lua::iscfunction(int i) {
+ return lua_iscfunction(L, i);
+}
+
+bool Lua::isuserdata(int i) {
+ return lua_isuserdata(L, i);
+}
+
+bool Lua::islightuserdata(int i) {
+ return lua_islightuserdata(L, i);
+}
+
+bool Lua::toboolean(int i) {
+ return lua_toboolean(L, i);
+}
+
+lua_Number Lua::tonumber(int i) {
+ return lua_tonumber(L, i);
+}
+
+String Lua::tostring(int i) {
+ if (isnil(i))
+ return String();
+ return String(lua_tostring(L, i));
+}
+
+lua_CFunction Lua::tocfunction(int i) {
+ return lua_tocfunction(L, i);
+}
+
+void * Lua::touserdata(int i) {
+ return lua_touserdata(L, i);
+}
+
+Lua * Lua::tothread(int i) {
+ return find(lua_tothread(L, i));
+}
+
+struct LoadF {
+ Handle * f;
+ char buff[BUFFERSIZE];
+};
+
+const char * LuaStatics::getF(lua_State * L, void * ud, size_t * size) {
+ LoadF *lf = (LoadF *)ud;
+ (void)L;
+
+ *size = lf->f->read(lf->buff, BUFFERSIZE);
+ return (*size > 0) ? lf->buff : NULL;
+}
+
+struct DumpF {
+ Handle * f;
+};
+
+int LuaStatics::putF(lua_State * L, const void * p, size_t size, void * ud) {
+ DumpF *lf = (DumpF *)ud;
+ (void)L;
+
+ return lf->f->write(p, size) == size;
+}
+
+void Lua::load(Handle * h, bool docall) throw (GeneralException) {
+ LoadF lf;
+ int status;
+
+ lf.f = h;
+
+ status = lua_load(L, LuaStatics::getF, &lf, h->GetName().to_charp());
+
+ if (status) {
+ showerror();
+ throw LuaException("Error loading lua chunk from Handle `" + h->GetName() + "'");
+ }
+
+ if (docall)
+ call();
+}
+
+extern "C" void luacmain(lua_State * L, int stripping, lua_Chunkwriter w, void * uD);
+
+void Lua::dump(Handle * h, bool strip) {
+ DumpF lf;
+
+ lf.f = h;
+
+ luacmain(L, strip, LuaStatics::putF, &lf);
+}
+
+Lua * Lua::thread() {
+ return new Lua(lua_newthread(L));
+}
+
+int Lua::yield(int nargs) {
+ return lua_yield(L, nargs);
+}
+
+int Lua::resume(int nresults) {
+ return lua_resume(L, nresults);
+}
+
+Lua * Lua::find(lua_State * _L) throw (GeneralException) {
+ std::map<lua_State *, Lua *>::iterator i;
+
+ if ((i = lualist.find(_L)) == lualist.end()) {
+ throw GeneralException("Unable to find the Lua object for this context");
+ }
+
+ return i->second;
+}
+
+void Lua::showerror() {
+ int n = lua_gettop(L);
+ int i;
+ String t;
+
+ printm(M_ERROR, "Lua object: Got an LUA error\n");
+ printm(M_ERROR, "Inspecting LUA stack\n");
+
+ if (n == 0) {
+ printm(M_ERROR, "Stack empty\n");
+ return;
+ }
+
+ for (i = 1; i <= n; i++) {
+ switch(lua_type(L, i)) {
+ case LUA_TNONE:
+ t = "Invalid";
+ break;
+ case LUA_TNIL:
+ t = "(Nil)";
+ break;
+ case LUA_TNUMBER:
+ t.set("(Number) %f", lua_tonumber(L, i));
+ break;
+ case LUA_TBOOLEAN:
+ t = String("(Bool) ") + (lua_toboolean(L, i) ? "true" : "false");
+ break;
+ case LUA_TSTRING:
+ t = String("(String) ") + lua_tostring(L, i);
+ break;
+ case LUA_TTABLE:
+ t = "(Table)";
+ break;
+ case LUA_TFUNCTION:
+ t = "(Function)";
+ break;
+ default:
+ t = "Unknown";
+ }
+
+ printm(M_ERROR, String(i) + ": " + t + "\n");
+ }
+}
+
+int Lua::getmetatable(int i) {
+ return lua_getmetatable(L, i);
+}
+
+int Lua::setmetatable(int i) {
+ return lua_setmetatable(L, i);
+}
+
+int Lua::sethook(lua_Hook func, int mask, int count) {
+ return lua_sethook(L, func, mask, count);
+}
+
+void Lua::do_break() {
+ lua_break(L);
+}
+
+void LuaObject::push(Lua * L) throw (GeneralException) {
+ if (pushed && wantdestruct) {
+ throw GeneralException("Error: object is owned by the LUA script and can not be pushed.");
+ }
+ L->newtable();
+ pushmembers(L);
+ pushed = true;
+}
+
+void LuaObject::pushme(Lua * L, void * o, bool obj) {
+ void ** u;
+ bool * b;
+ L->push("__obj");
+ u = (void **) L->newuser(sizeof(o) + sizeof(bool));
+ *u = o;
+ b = (bool *) (u + 1);
+ *b = obj;
+ L->settable(-3, true);
+}
+
+void * LuaObject::getme(Lua * L, int i) {
+ void ** r = 0;
+
+ if (L->istable(i)) {
+ L->push("__obj");
+ L->gettable(i, true);
+ if (!(r = (void **) L->touserdata()))
+ L->error("Table is not an object.");
+ if (!*r)
+ L->error("Object already destroyed.");
+ L->pop();
+ } else if (L->isnil(i)) {
+ r = 0;
+ } else {
+ L->error("Not an object (not even a table).");
+ }
+
+ return r ? *r : 0;
+}
+
+void LuaObject::pushit(Lua * L, const String & s, lua_CFunction f) {
+ L->push(s);
+ L->push(f);
+ L->settable(-3, true);
+}
+
+void LuaObject::pushmeta(Lua * L, const String & s, lua_CFunction f) {
+ if (!L->getmetatable()) {
+ L->newtable();
+ }
+ L->push(s);
+ L->push(f);
+ L->settable();
+ L->setmetatable();
+}
+
+int LuaStatics::collector(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ void ** u = (void **) L->touserdata();
+ bool * obj = (bool *) (u + 1);
+// printm(M_INFO, "From LUA: collecting object\n");
+ if (*obj) {
+// printm(M_INFO, "Is object at %p\n", *u);
+ Base * b = (Base *) *u;
+ delete b;
+ } else {
+// printm(M_INFO, "Is struct at %p\n", *u);
+ free(*u);
+ }
+ *u = 0;
+ return 0;
+}
+
+int LuaStatics::destructor(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ Base * b = (Base *) LuaObject::getme(L);
+ delete b;
+ L->push("__obj");
+ L->gettable(-2, true);
+ void ** u = (void **) L->touserdata();
+ bool * obj = (bool *) (u + 1);
+ if (*obj) {
+ Base * b = (Base *) *u;
+ delete b;
+ } else {
+ free(*u);
+ }
+ *u = 0;
+ L->pop();
+ return 0;
+}
+
+void LuaObject::pushdestruct(Lua * L) throw (GeneralException) {
+ if (pushed) {
+ throw GeneralException("Error: can't push destructor, object already pushed");
+ }
+ push(L);
+ L->push("__obj");
+ L->gettable(-2, true);
+ pushmeta(L, "__gc", LuaStatics::collector);
+ L->pop();
+ pushit(L, "destroy", LuaStatics::destructor);
+
+ wantdestruct = true;
+}
+
+LuaException::LuaException(String fn) : GeneralException(fn) { }
+
+LuaException::LuaException() { }
diff --git a/lib/lua/include/lualib.h b/lib/lua/include/lualib.h
index bec0b94..081d7c3 100644
--- a/lib/lua/include/lualib.h
+++ b/lib/lua/include/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.3 2003-12-11 16:53:28 pixel Exp $
+** $Id: lualib.h,v 1.4 2004-11-27 21:01:20 pixel Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -38,6 +38,9 @@ LUALIB_API int luaopen_math (lua_State *L);
#define LUA_DBLIBNAME "debug"
LUALIB_API int luaopen_debug (lua_State *L);
+#define LUA_DIRLIBNAME "dir"
+LUALIB_API int luaopen_dir (lua_State *L);
+
LUALIB_API int luaopen_loadlib (lua_State *L);
diff --git a/lib/lua/src/LuaLib/ldirlib.c b/lib/lua/src/LuaLib/ldirlib.c
new file mode 100644
index 0000000..b6760da
--- /dev/null
+++ b/lib/lua/src/LuaLib/ldirlib.c
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef _WIN32
+#include <sys/stat.h>
+#else
+#include <sys/stat.h>
+#include <sys/type.h>
+#endif
+
+#define ldirlib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+/* forward declaration for the iterator function */
+static int dir_iter (lua_State *L);
+
+static int l_dir (lua_State *L) {
+ const char *path = luaL_checkstring(L, 1);
+
+ /* create a userdatum to store a DIR address */
+ DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *));
+
+ /* set its metatable */
+ luaL_getmetatable(L, "LuaBook.dir");
+ lua_setmetatable(L, -2);
+
+ /* try to open the given directory */
+ *d = opendir(path);
+ if (*d == NULL) /* error opening the directory? */
+ luaL_error(L, "cannot open %s: %s", path,
+ strerror(errno));
+
+ /* creates and returns the iterator function
+ (its sole upvalue, the directory userdatum,
+ is already on the stack top */
+ lua_pushcclosure(L, dir_iter, 1);
+ return 1;
+}
+
+static int dir_iter (lua_State *L) {
+ DIR *d = *(DIR **)lua_touserdata(L, lua_upvalueindex(1));
+ struct dirent *entry;
+#ifdef _WIN32
+ struct _stat file_stat;
+#else
+ struct stat file_stat;
+#endif
+ if ((entry = readdir(d)) != NULL) {
+ lua_newtable(L);
+ lua_pushstring(L, "name");
+ lua_pushstring(L, entry->d_name);
+ lua_settable(L, -3);
+#ifdef _WIN32
+ _stat(entry->d_name, &file_stat);
+#else
+ stat(entry->d_name, &file_stat);
+#endif
+ lua_pushstring(L, "type");
+ lua_pushnumber(L, (S_IFREG & file_stat.st_mode) ? 2 : ((S_IFDIR & file_stat.st_mode) ? 1 : 0));
+ lua_settable(L, -3);
+
+ return 1;
+ }
+ else return 0; /* no more values to return */
+}
+
+static int dir_gc (lua_State *L) {
+ DIR *d = *(DIR **)lua_touserdata(L, 1);
+ if (d) closedir(d);
+ return 0;
+}
+
+static const luaL_reg dirlib[] = {
+ {NULL, NULL}
+};
+
+int luaopen_dir (lua_State *L) {
+ luaL_openlib(L, LUA_DIRLIBNAME, dirlib, 0);
+ luaL_newmetatable(L, "LuaBook.dir");
+
+ /* set its __gc field */
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, dir_gc);
+ lua_settable(L, -3);
+
+ /* register the `dir' function */
+ lua_pushcfunction(L, l_dir);
+ lua_setglobal(L, "dir");
+
+ lua_pushnumber(L, 1);
+ lua_setglobal(L, "FLAG_DIR");
+
+ lua_pushnumber(L, 2);
+ lua_setglobal(L, "FLAG_FILE");
+
+ return 0;
+}