-rw-r--r-- | Lua-README.txt | 18 | ||||
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | agg-plot/window-cpp.h | 18 | ||||
-rw-r--r-- | agg-plot/window.cpp | 15 | ||||
-rw-r--r-- | base.lua | 2 | ||||
-rw-r--r-- | gsl-shell.c | 15 | ||||
-rw-r--r-- | lua-gsl.c | 4 | ||||
-rw-r--r-- | lua/src/lgc.c | 2 | ||||
-rw-r--r-- | lua/src/lparser.c | 4 | ||||
-rw-r--r-- | lua/src/luaconf.h | 2 | ||||
-rw-r--r-- | makeconfig | 6 |
diff --git a/Lua-README.txt b/Lua-README.txt new file mode 100644 index 00000000..c27163de --- /dev/null +++ b/Lua-README.txt @@ -0,0 +1,18 @@ + Lua README + +Since version 1.2 GSL shell can be built to be Lua interpreter +strictly conform to Lua standard. In this case the only difference a +the Lua interpreter will be that the GSL specific functions will be +loaded in a modeule named 'gsl'. Otherwise the top level interpreter +will work just as a standard Lua but you will have the possibility to +open graphical windows. In order to have interactive windows +multithreading will be used and some locks are used to avoid race +conditions but this does not concerns the final user. + +To enable strict Lua conformity set the following line in the +makeconfig file: + +LUA_COMPATIBLE = strict + +Be aware that in this case some generice gsl functions like fxplot, +fxline etc will be not available. @@ -33,6 +33,18 @@ nono: @echo "You haven't edited 'makeconfig' yet. Set your settings there, then run 'make' again" endif +ifeq ($(strip $(LUA_COMPATIBLE)), yes) + CFGFLAGS = -DGSH_SHORT_FSYNTAX -DWINDOW_LIVE_CHECK +else + ifeq ($(strip $(LUA_COMPATIBLE)), strict) + CFGFLAGS = -DWINDOW_LIVE_CHECK -DLUA_STRICT + else + CFGFLAGS = -DGSH_SHORT_FSYNTAX -DGSH_GC_PATCH + endif +endif + +DEFS += $(CFGFLAGS) +SUBDIRS_DEFS += $(CFGFLAGS) ifeq ($(strip $(PLATFORM)), mingw) # Option for Windows Platform diff --git a/agg-plot/window-cpp.h b/agg-plot/window-cpp.h index d0239d9a..400e9b99 100644 --- a/agg-plot/window-cpp.h +++ b/agg-plot/window-cpp.h @@ -89,3 +89,21 @@ public: virtual void on_draw(); virtual void on_resize(int sx, int sy); }; + +#ifdef WINDOW_LIVE_CHECK +class window_boxed : public window { + bool m_is_alive; + +public: + window_boxed(agg::rgba& bgcol) : window(bgcol), m_is_alive(true) {}; + ~window_boxed() { m_is_alive = false; } + + bool is_alive() const { return m_is_alive; }; +}; +#else +class window_boxed : public window { +public: + window_boxed(agg::rgba& bgcol) : window(bgcol) {}; + bool is_alive() const { return true; }; +}; +#endif diff --git a/agg-plot/window.cpp b/agg-plot/window.cpp index f7cb9ed2..398efbdc 100644 --- a/agg-plot/window.cpp +++ b/agg-plot/window.cpp @@ -371,9 +371,15 @@ typedef void (window::*window_slot_method_type)(int slot_id); int window_generic_oper (lua_State *L, window_slot_method_type method) { - window *win = object_check<window>(L, 1, GS_WINDOW); + window_boxed *win = object_check<window_boxed>(L, 1, GS_WINDOW); int slot_id = luaL_checkinteger (L, 2); + // we check to be sure that the window was not garbage collected + // by Lua. In this case the destructor was called but the momory + // itself is not disposed. Since the is_alive method is non-virtual + // that shoud be always fine. + if (! win->is_alive()) return 0; + win->lock(); if (win->status == canvas_window::running) { @@ -389,9 +395,12 @@ int window_generic_oper_ext (lua_State *L, void (window::*method)(int, param_type), param_type param) { - window *win = object_check<window>(L, 1, GS_WINDOW); + window_boxed *win = object_check<window_boxed>(L, 1, GS_WINDOW); int slot_id = luaL_checkinteger (L, 2); + // see comment is the function window_generic_oper + if (! win->is_alive()) return 0; + win->lock(); if (win->status == canvas_window::running) { @@ -431,7 +440,7 @@ void window::start (lua_State *L, gslshell::ret_status& st) int window_new (lua_State *L) { - window *win = push_new_object<window>(L, GS_WINDOW, colors::white); + window_boxed *win = push_new_object<window_boxed>(L, GS_WINDOW, colors::white); const char *spec = lua_tostring (L, 1); gslshell::ret_status st; @@ -40,7 +40,7 @@ tos = function (t, maxdepth) elseif tp == 'userdata' then local ftostr = getmetatable(t).__tostring if ftostr then return ftostr(t) else - return string.format('<%s>', gsltype(t)) + return gsltype and string.format('<%s>', gsltype(t)) or '<userdata>' end else return tostring(t) diff --git a/gsl-shell.c b/gsl-shell.c index 691b340c..f716296d 100644 --- a/gsl-shell.c +++ b/gsl-shell.c @@ -85,7 +85,7 @@ static const luaL_Reg gshlibs[] = { {LUA_IOLIBNAME, luaopen_io}, {LUA_OSLIBNAME, luaopen_os}, {LUA_STRLIBNAME, luaopen_string}, -#if 0 +#ifdef LUA_STRICT {LUA_MATHLIBNAME, luaopen_math}, {LUA_DBLIBNAME, luaopen_debug}, {MLUA_GSLLIBNAME, luaopen_gsl}, @@ -135,6 +135,7 @@ gsl_shell_openlibs (lua_State *L) lua_call(L, 1, 0); } +#ifndef LUA_STRICT lua_pushvalue (L, LUA_GLOBALSINDEX); /* open math in global scope */ lua_setglobal (L, LUA_MATHLIBNAME); luaopen_math (L); @@ -148,6 +149,7 @@ gsl_shell_openlibs (lua_State *L) lua_pop (L, 1); lua_pushnil (L); /* remove gsl */ lua_setglobal (L, MLUA_GSLLIBNAME); +#endif } static void l_message (const char *pname, const char *msg) { @@ -495,9 +497,11 @@ static int pmain (lua_State *L) { lua_gc(L, LUA_GCRESTART, 0); dolibrary (L, "base"); - dolibrary (L, "igsl"); dolibrary (L, "integ"); +#ifndef LUA_STRICT + dolibrary (L, "igsl"); dolibrary (L, "draw"); +#endif s->status = handle_luainit(L); if (s->status != 0) return 0; @@ -544,13 +548,6 @@ int main (int argc, char **argv) { l_message(argv[0], "cannot create state: not enough memory"); return EXIT_FAILURE; } - /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers. - */ -#ifdef LNUM_INT32 - lua_assert( sizeof(lua_Integer) == 4 ); -#elif defined(LNUM_INT64) - lua_assert( sizeof(lua_Integer) == 8 ); -#endif s.argc = argc; s.argv = argv; status = lua_cpcall(L, &pmain, &s); @@ -56,7 +56,9 @@ #include "lua-plot.h" #endif +#ifdef LUA_STRICT static const struct luaL_Reg gsl_methods_dummy[] = {{NULL, NULL}}; +#endif int luaopen_gsl (lua_State *L) @@ -68,7 +70,7 @@ luaopen_gsl (lua_State *L) object_refs_prepare (L); #endif -#ifdef USE_SEPARATE_NAMESPACE +#ifdef LUA_STRICT luaL_register (L, MLUA_GSLLIBNAME, gsl_methods_dummy); #else lua_pushvalue (L, LUA_GLOBALSINDEX); diff --git a/lua/src/lgc.c b/lua/src/lgc.c index 4146aa2d..711f2dbf 100644 --- a/lua/src/lgc.c +++ b/lua/src/lgc.c @@ -334,7 +334,7 @@ static size_t propagateall (global_State *g) { ** other objects: if really collected, cannot keep them; for userdata ** being finalized, keep them in keys, but not in values */ -#if defined(GSL_SHELL_LUA) && defined(GSL_SHELL_GC_PATCH) +#ifdef GSH_GC_PATCH static int iscleared (const TValue *o, int iskey) { (void) iskey; if (!iscollectable(o)) return 0; diff --git a/lua/src/lparser.c b/lua/src/lparser.c index b72bc153..951f95b5 100644 --- a/lua/src/lparser.c +++ b/lua/src/lparser.c @@ -596,7 +596,7 @@ static void body (LexState *ls, expdesc *e, int needself, int line) { } -#ifdef GSL_SHELL_LUA +#ifdef GSH_SHORT_FSYNTAX static void simplebody (LexState *ls, expdesc *e, int line) { /* simplebody -> parlist `|' expr END */ FuncState new_fs; @@ -789,7 +789,7 @@ static void simpleexp (LexState *ls, expdesc *v) { body(ls, v, 0, ls->linenumber); return; } -#ifdef GSL_SHELL_LUA +#ifdef GSH_SHORT_FSYNTAX case '|': { luaX_next(ls); simplebody(ls, v, ls->linenumber); diff --git a/lua/src/luaconf.h b/lua/src/luaconf.h index 3d4d1846..6905db77 100644 --- a/lua/src/luaconf.h +++ b/lua/src/luaconf.h @@ -8,8 +8,6 @@ #ifndef lconfig_h #define lconfig_h -#define GSL_SHELL_GC_PATCH 1 - #define QUOTEME_(x) #x #define QUOTEME(x) QUOTEME_(x) diff --git a/makeconfig b/makeconfig index 0a732466..85e2ae20 100644 --- a/makeconfig +++ b/makeconfig @@ -1,6 +1,12 @@ ENABLE_AGG_PLOT = yes +# can be yes, no or strict +# Generally you should use 'no'. If you need to use other Lua modules +# you can use 'yes'. Use 'strict' only if you need a fully conformant Lua +# interpreter but be aware that this may break some things. +LUA_COMPATIBLE = no + # set this to "yes" if you want to disable gamma correction DISABLE_GAMMA_CORR = no |