From de1c8f9a8e08e3bc0956bc8aeae58147e8fd408d Mon Sep 17 00:00:00 2001 From: Yves Rizoud Date: Sat, 11 Aug 2012 18:38:50 +0000 Subject: [PATCH] Lua: added run(), which works like dofile() but supports nested calls with subdirectories, and includes a safety against infinite recursion. See also issue 501 git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@1986 416bcca6-2ee7-4201-b75f-2eb2f807beb1 --- src/factory.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/helpfile.h | 2 +- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/factory.c b/src/factory.c index 523686f1..d6718183 100644 --- a/src/factory.c +++ b/src/factory.c @@ -1382,6 +1382,66 @@ int L_GetFileName(lua_State* L) return 2; } +/// Run a script while changing the current directory +int L_Run(lua_State* L) +{ + const char * script_arg; + const char * message; + char saved_directory[MAX_PATH_CHARACTERS]; + // these are only needed before running script + // (which may call L_Run() again recursively) + // so it's safe to make them static to spare a few hundred bytes. + static char directory[MAX_PATH_CHARACTERS]; + static char filename[MAX_PATH_CHARACTERS]; + static int nested_calls = 0; + + int nb_args=lua_gettop(L); + + LUA_ARG_LIMIT (1, "run"); + LUA_ARG_STRING(1, "run", script_arg); + if (strlen(script_arg)>=MAX_PATH_CHARACTERS) + return luaL_error(L, "run: path is too long"); + + nested_calls++; + if (nested_calls > 100) + return luaL_error(L, "run: too many nested calls (100)"); + + // store the current directory (on the stack) + getcwd(saved_directory,MAX_PATH_CHARACTERS); + + Extract_path(directory, script_arg); + if (directory[0]!='\0') + { + if (!Directory_exists(directory)) + return luaL_error(L, "run: directory of script doesn't exist"); + chdir(directory); + } + Extract_filename(filename, script_arg); + if (luaL_loadfile(L,filename) != 0) + { + nb_args= lua_gettop(L); + if (nb_args>0 && (message = lua_tostring(L, nb_args))!=NULL) + return luaL_error(L, message); + else + return luaL_error(L, "run: Unknown error loading script %s", filename); + } + else if (lua_pcall(L, 0, 0, 0) != 0) + { + nb_args= lua_gettop(L); + // We COULD build the call stack, but I think this would be more + // confusing than helpful. + + if (nb_args>0 && (message = lua_tostring(L, nb_args))!=NULL) + Verbose_message("Error running script", message); + else + Warning_message("Unknown error running script!"); + } + nested_calls--; + // restore directory + chdir(saved_directory); + return 0; +} + // Handlers for window internals T_Fileselector Scripts_selector; @@ -1665,6 +1725,8 @@ void Run_script(const char *script_subdirectory, const char *script_filename) lua_register(L,"finalizepicture",L_FinalizePicture); lua_register(L,"getfilename",L_GetFileName); lua_register(L,"selectlayer",L_SelectLayer); + lua_register(L,"run",L_Run); + // Load all standard libraries luaL_openlibs(L); diff --git a/src/helpfile.h b/src/helpfile.h index 5cd5adbb..d1de1024 100644 --- a/src/helpfile.h +++ b/src/helpfile.h @@ -430,6 +430,7 @@ static const T_Help_table helptable_credits[] = HELP_TEXT (" Yannick") HELP_TEXT (" Fernando Mastandrea (masta.uy)") HELP_TEXT (" Markus Weiss") + HELP_TEXT (" Mazze") HELP_TEXT ("") HELP_BOLD (" MORPHOS PORT") HELP_TEXT ("") @@ -448,7 +449,6 @@ static const T_Help_table helptable_credits[] = HELP_TEXT ("") HELP_TEXT (" Luc Schrijvers (Begasus)") HELP_TEXT ("") - HELP_TEXT ("") HELP_BOLD (" FREEBSD PORT") HELP_TEXT ("") HELP_TEXT (" Jean-Baptiste Berlioz (Tobé)")