diff options
Diffstat (limited to 'src/tools.c')
-rw-r--r-- | src/tools.c | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/src/tools.c b/src/tools.c index 13a3ebd..f72663f 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -33,6 +33,7 @@ THE SOFTWARE. | |||
33 | 33 | ||
34 | #include "tools.h" | 34 | #include "tools.h" |
35 | #include "keeper.h" | 35 | #include "keeper.h" |
36 | #include "lanes.h" | ||
36 | 37 | ||
37 | #include "lualib.h" | 38 | #include "lualib.h" |
38 | #include "lauxlib.h" | 39 | #include "lauxlib.h" |
@@ -42,6 +43,43 @@ THE SOFTWARE. | |||
42 | #include <ctype.h> | 43 | #include <ctype.h> |
43 | #include <stdlib.h> | 44 | #include <stdlib.h> |
44 | 45 | ||
46 | /* | ||
47 | ** Copied from Lua 5.2 loadlib.c | ||
48 | */ | ||
49 | #if LUA_VERSION_NUM == 501 | ||
50 | static int luaL_getsubtable (lua_State *L, int idx, const char *fname) | ||
51 | { | ||
52 | lua_getfield(L, idx, fname); | ||
53 | if (lua_istable(L, -1)) | ||
54 | return 1; /* table already there */ | ||
55 | else | ||
56 | { | ||
57 | lua_pop(L, 1); /* remove previous result */ | ||
58 | idx = lua_absindex(L, idx); | ||
59 | lua_newtable(L); | ||
60 | lua_pushvalue(L, -1); /* copy to be left at top */ | ||
61 | lua_setfield(L, idx, fname); /* assign new table to field */ | ||
62 | return 0; /* false, because did not find table there */ | ||
63 | } | ||
64 | } | ||
65 | |||
66 | void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) | ||
67 | { | ||
68 | lua_pushcfunction(L, openf); | ||
69 | lua_pushstring(L, modname); /* argument to open function */ | ||
70 | lua_call(L, 1, 1); /* open module */ | ||
71 | luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
72 | lua_pushvalue(L, -2); /* make copy of module (call result) */ | ||
73 | lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ | ||
74 | lua_pop(L, 1); /* remove _LOADED table */ | ||
75 | if (glb) | ||
76 | { | ||
77 | lua_pushvalue(L, -1); /* copy of 'mod' */ | ||
78 | lua_setglobal(L, modname); /* _G[modname] = module */ | ||
79 | } | ||
80 | } | ||
81 | #endif // LUA_VERSION_NUM | ||
82 | |||
45 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); | 83 | DEBUGSPEW_CODE( char const* debugspew_indent = "----+----!----+----!----+----!----+----!----+----!----+----!----+----!----+"); |
46 | DEBUGSPEW_CODE( int debugspew_indent_depth = 0); | 84 | DEBUGSPEW_CODE( int debugspew_indent_depth = 0); |
47 | 85 | ||
@@ -98,14 +136,24 @@ void luaG_dump( lua_State* L ) { | |||
98 | 136 | ||
99 | /*---=== luaG_newstate ===---*/ | 137 | /*---=== luaG_newstate ===---*/ |
100 | 138 | ||
139 | static int require_lanes_core( lua_State* L) | ||
140 | { | ||
141 | // leaves a copy of 'lanes.core' module table on the stack | ||
142 | luaL_requiref( L, "lanes.core", luaopen_lanes_core, 0); | ||
143 | return 1; | ||
144 | } | ||
145 | |||
146 | |||
101 | static const luaL_Reg libs[] = | 147 | static const luaL_Reg libs[] = |
102 | { | 148 | { |
103 | { LUA_LOADLIBNAME, luaopen_package}, | 149 | { LUA_LOADLIBNAME, luaopen_package}, |
104 | { LUA_TABLIBNAME, luaopen_table}, | 150 | { LUA_TABLIBNAME, luaopen_table}, |
105 | { LUA_STRLIBNAME, luaopen_string}, | 151 | { LUA_STRLIBNAME, luaopen_string}, |
106 | { LUA_MATHLIBNAME, luaopen_math}, | 152 | { LUA_MATHLIBNAME, luaopen_math}, |
153 | #ifndef PLATFORM_XBOX // no os/io libs on xbox | ||
107 | { LUA_OSLIBNAME, luaopen_os}, | 154 | { LUA_OSLIBNAME, luaopen_os}, |
108 | { LUA_IOLIBNAME, luaopen_io}, | 155 | { LUA_IOLIBNAME, luaopen_io}, |
156 | #endif // PLATFORM_XBOX | ||
109 | #if LUA_VERSION_NUM >= 502 | 157 | #if LUA_VERSION_NUM >= 502 |
110 | { LUA_BITLIBNAME, luaopen_bit32}, | 158 | { LUA_BITLIBNAME, luaopen_bit32}, |
111 | { LUA_COLIBNAME, luaopen_coroutine}, // Lua 5.2: coroutine is no longer a part of base! | 159 | { LUA_COLIBNAME, luaopen_coroutine}, // Lua 5.2: coroutine is no longer a part of base! |
@@ -113,6 +161,7 @@ static const luaL_Reg libs[] = | |||
113 | { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package | 161 | { LUA_COLIBNAME, NULL}, // Lua 5.1: part of base package |
114 | #endif // LUA_VERSION_NUM | 162 | #endif // LUA_VERSION_NUM |
115 | { LUA_DBLIBNAME, luaopen_debug}, | 163 | { LUA_DBLIBNAME, luaopen_debug}, |
164 | { "lanes.core", require_lanes_core}, // So that we can open it like any base library (possible since we have access to the init function) | ||
116 | // | 165 | // |
117 | { "base", NULL}, // ignore "base" (already acquired it) | 166 | { "base", NULL}, // ignore "base" (already acquired it) |
118 | { NULL, NULL } | 167 | { NULL, NULL } |
@@ -135,9 +184,11 @@ static void open1lib( lua_State* L, char const* name, size_t len) | |||
135 | lua_pop( L, 1); | 184 | lua_pop( L, 1); |
136 | #else // LUA_VERSION_NUM | 185 | #else // LUA_VERSION_NUM |
137 | STACK_GROW( L, 1); | 186 | STACK_GROW( L, 1); |
187 | // push function and 1 argument on the stack | ||
138 | lua_pushcfunction( L, libs[i].func); | 188 | lua_pushcfunction( L, libs[i].func); |
139 | // pushes the module table on the stack | 189 | lua_pushstring( L, libs[i].name); |
140 | lua_call( L, 0, 0); | 190 | // call function, pushes the module table on the stack |
191 | lua_call( L, 1, 0); | ||
141 | #endif // LUA_VERSION_NUM | 192 | #endif // LUA_VERSION_NUM |
142 | STACK_END( L, 0); | 193 | STACK_END( L, 0); |
143 | } | 194 | } |
@@ -443,6 +494,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* _name) | |||
443 | * Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. | 494 | * Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. |
444 | * | 495 | * |
445 | */ | 496 | */ |
497 | extern void register_core_libfuncs_for_keeper( lua_State* L); | ||
446 | 498 | ||
447 | lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs) | 499 | lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs) |
448 | { | 500 | { |
@@ -475,10 +527,24 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con | |||
475 | // | 527 | // |
476 | if( libs) | 528 | if( libs) |
477 | { | 529 | { |
478 | if( libs[0] == '*' && libs[1] == 0) // special "*" case (mainly to help with LuaJIT compatibility) | 530 | // special "*" case (mainly to help with LuaJIT compatibility) |
531 | // "K" is used when opening keeper states: almost the same as "*", but for the fact we don't open lanes.core | ||
532 | // as we are called from luaopen_lanes_core() already, and that would deadlock | ||
533 | if( (libs[0] == '*' || libs[0] == 'K') && libs[1] == 0) | ||
479 | { | 534 | { |
480 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); | 535 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "opening ALL standard libraries\n" INDENT_END)); |
481 | luaL_openlibs( L); | 536 | luaL_openlibs( L); |
537 | if( libs[0] == '*') | ||
538 | { | ||
539 | // don't forget lanes.core for regular lane states | ||
540 | open1lib( L, "lanes.core", 10); | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | // In keeper states however, we only want to register the lanes.core functions to be able to transfer them through lindas | ||
545 | // (we don't care about a full lanes.core init in the keeper states as we won't call anything in there) | ||
546 | register_core_libfuncs_for_keeper( L); | ||
547 | } | ||
482 | libs = NULL; // done with libs | 548 | libs = NULL; // done with libs |
483 | } | 549 | } |
484 | else | 550 | else |
@@ -504,12 +570,12 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con | |||
504 | unsigned int len = 0; | 570 | unsigned int len = 0; |
505 | for( p = libs; *p; p += len) | 571 | for( p = libs; *p; p += len) |
506 | { | 572 | { |
507 | len = 0; | 573 | // skip delimiters ('.' can be part of name for "lanes.core") |
508 | // skip delimiters | 574 | while( *p && !isalnum( *p) && *p != '.') |
509 | while( *p && !isalnum( *p)) | ||
510 | ++ p; | 575 | ++ p; |
511 | // skip name | 576 | // skip name |
512 | while( isalnum( p[len])) | 577 | len = 0; |
578 | while( isalnum( p[len]) || p[len] == '.') | ||
513 | ++ len; | 579 | ++ len; |
514 | // open library | 580 | // open library |
515 | open1lib( L, p, len); | 581 | open1lib( L, p, len); |