Reduce usage of MAX_PATH strings in factory.c

This commit is contained in:
Thomas Bernard 2019-01-15 13:22:09 +01:00
parent f5cc3a0aba
commit b3baa57a36
No known key found for this signature in database
GPG Key ID: 0FF11B67A5C0863C
3 changed files with 178 additions and 132 deletions

View File

@ -1998,28 +1998,25 @@ int L_Run(lua_State* L)
{ {
const char * script_arg; const char * script_arg;
const char * message; const char * message;
char saved_directory[MAX_PATH_CHARACTERS]; char * saved_directory;
// these are only needed before running script char * full_path;
// (which may call L_Run() again recursively) const char * path;
// so it's safe to make them static to spare a few hundred bytes. char * file_name;
static char full_path[MAX_PATH_CHARACTERS];
static char path_element[MAX_PATH_CHARACTERS];
static int nested_calls = 0; static int nested_calls = 0;
int nb_args=lua_gettop(L); int nb_args = lua_gettop(L);
LUA_ARG_LIMIT (1, "run"); LUA_ARG_LIMIT (1, "run");
LUA_ARG_STRING(1, "run", script_arg); 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++; nested_calls++;
if (nested_calls > 100) if (nested_calls > 100)
return luaL_error(L, "run: too many nested calls (100)"); return luaL_error(L, "run: too many nested calls (100)");
// store the current directory (on the stack) // store the current directory (on the stack)
Get_current_directory(saved_directory, NULL, MAX_PATH_CHARACTERS); saved_directory = Get_current_directory(NULL, NULL, 0);
full_path = strdup(script_arg);
#if defined (__AROS__) #if defined (__AROS__)
// Convert path written on Linux/Windows norms to AROS norms : // Convert path written on Linux/Windows norms to AROS norms :
// Each element like ../ and ..\ is replaced by / // Each element like ../ and ..\ is replaced by /
@ -2053,45 +2050,65 @@ int L_Run(lua_State* L)
// On Linux/Unix, this ensures that scripts written and tested on Windows // On Linux/Unix, this ensures that scripts written and tested on Windows
// work similarly. // work similarly.
char *pos; char *pos;
strcpy(full_path, script_arg); for (pos = strchr(full_path, '\\'); pos != NULL; pos = strchr(pos, '\\'))
pos=strchr(full_path, '\\'); *pos = '/';
while (pos!=NULL)
{
*pos='/';
pos=strchr(full_path, '\\');
}
} }
#endif #endif
Extract_path(path_element, full_path); file_name = Find_last_separator(full_path);
if (path_element[0]!='\0') if (file_name != NULL)
{ {
if (!Directory_exists(path_element)) path = full_path;
*file_name = '\0';
file_name++;
if (path[0] == '\0') // the file was in ROOT directory
path = PATH_SEPARATOR;
if (!Directory_exists(path))
{
free(saved_directory);
free(full_path);
return luaL_error(L, "run: directory of script doesn't exist"); return luaL_error(L, "run: directory of script doesn't exist");
Change_directory(path_element); }
Change_directory(path);
} }
Extract_filename(path_element, full_path); else
if (luaL_loadfile(L,path_element) != 0)
{ {
nb_args= lua_gettop(L); path = NULL; // only file name
file_name = full_path;
}
if (luaL_loadfile(L, file_name) != 0)
{
int r;
nb_args = lua_gettop(L);
if (nb_args>0 && (message = lua_tostring(L, nb_args))!=NULL) if (nb_args>0 && (message = lua_tostring(L, nb_args))!=NULL)
return luaL_error(L, message); r = luaL_error(L, message);
else else
return luaL_error(L, "run: Unknown error loading script %s", path_element); r = luaL_error(L, "run: Unknown error loading script %s", file_name);
Change_directory(saved_directory);
free(saved_directory);
free(full_path);
return r;
} }
else if (lua_pcall(L, 0, 0, 0) != 0) free(full_path);
if (lua_pcall(L, 0, 0, 0) != 0)
{ {
nb_args= lua_gettop(L); int r;
nb_args = lua_gettop(L);
// We COULD build the call stack, but I think this would be more // We COULD build the call stack, but I think this would be more
// confusing than helpful. // confusing than helpful.
if (nb_args>0 && (message = lua_tostring(L, nb_args))!=NULL) if (nb_args>0 && (message = lua_tostring(L, nb_args))!=NULL)
return luaL_error(L, message); r = luaL_error(L, message);
else else
return luaL_error(L, "run: Unknown error running script!"); r = luaL_error(L, "run: Unknown error running script!");
Change_directory(saved_directory);
free(saved_directory);
return r;
} }
nested_calls--; nested_calls--;
// restore directory // restore directory
Change_directory(saved_directory); Change_directory(saved_directory);
free(saved_directory);
return 0; return 0;
} }
@ -2177,6 +2194,7 @@ void Draw_script_name(word x, word y, word index, byte highlighted)
void Draw_script_information(T_Fileselector_item * script_item, const char *full_directory) void Draw_script_information(T_Fileselector_item * script_item, const char *full_directory)
{ {
FILE *script_file; FILE *script_file;
char * full_name;
char text_block[3][DESC_WIDTH+1]; char text_block[3][DESC_WIDTH+1];
int x, y; int x, y;
int i; int i;
@ -2184,79 +2202,77 @@ void Draw_script_information(T_Fileselector_item * script_item, const char *full
// Blank the target area // Blank the target area
Window_rectangle(7, FILESEL_Y + 89, DESC_WIDTH*6+2, 4*8, MC_Black); Window_rectangle(7, FILESEL_Y + 89, DESC_WIDTH*6+2, 4*8, MC_Black);
if (script_item && script_item->Full_name && script_item->Full_name[0]!='\0') if (script_item && script_item->Full_name && script_item->Full_name[0] != '\0')
{ {
char full_name[MAX_PATH_CHARACTERS]; full_name = Filepath_append_to_dir(full_directory, script_item->Full_name);
strcpy(full_name, full_directory);
Append_path(full_name, script_item->Full_name, NULL);
x=0; x = 0;
y=0; y = 0;
text_block[0][0] = text_block[1][0] = text_block[2][0] = '\0'; text_block[0][0] = text_block[1][0] = text_block[2][0] = '\0';
if (script_item->Type == 0) if (script_item->Type == FSOBJECT_FILE)
{ {
// Start reading // Start reading
script_file = fopen(full_name, "r"); script_file = fopen(full_name, "r");
if (script_file != NULL) if (script_file != NULL)
{ {
int c; int c;
c = fgetc(script_file); c = fgetc(script_file);
while (c != EOF && y<3) while (c != EOF && y<3)
{ {
if (c == '\n') if (c == '\n')
{ {
if (x<2) if (x<2)
break; // Carriage return without comment: Stopping break; // Carriage return without comment: Stopping
y++; y++;
x=0; x=0;
} }
else if (x==0 || x==1) else if (x==0 || x==1)
{ {
if (c != '-') if (c != '-')
break; // Non-comment line was encountered. Stopping. break; // Non-comment line was encountered. Stopping.
x++; x++;
} }
else else
{ {
if (x < DESC_WIDTH+2) if (x < DESC_WIDTH+2)
{ {
// Adding character // Adding character
text_block[y][x-2] = (c<32 || c>255) ? ' ' : c; text_block[y][x-2] = (c<32 || c>255) ? ' ' : c;
text_block[y][x-1] = '\0'; text_block[y][x-1] = '\0';
} }
x++; x++;
} }
// Read next // Read next
c = fgetc(script_file); c = fgetc(script_file);
} }
fclose(script_file); fclose(script_file);
} }
Print_help(8, FILESEL_Y + 89 , text_block[0], 'N', 0, 0); Print_help(8, FILESEL_Y + 89 , text_block[0], 'N', 0, 0);
Print_help(8, FILESEL_Y + 89+ 8, text_block[1], 'N', 0, 0); Print_help(8, FILESEL_Y + 89+ 8, text_block[1], 'N', 0, 0);
Print_help(8, FILESEL_Y + 89+16, text_block[2], 'N', 0, 0); Print_help(8, FILESEL_Y + 89+16, text_block[2], 'N', 0, 0);
// Display a line with the keyboard shortcut // Display a line with the keyboard shortcut
Print_help(8, FILESEL_Y + 89+24, "Key:", 'N', 0, 0); Print_help(8, FILESEL_Y + 89+24, "Key:", 'N', 0, 0);
for (i=0; i<10; i++) for (i=0; i<10; i++)
if (Bound_script[i]!=NULL && !strcmp(Bound_script[i], full_name)) if (Bound_script[i]!=NULL && !strcmp(Bound_script[i], full_name))
break; break;
if (i<10) if (i<10)
{ {
const char *shortcut; const char *shortcut;
shortcut=Keyboard_shortcut_value(SPECIAL_RUN_SCRIPT_1+i); shortcut = Keyboard_shortcut_value(SPECIAL_RUN_SCRIPT_1+i);
Print_help(8+4*6, FILESEL_Y + 89+24, shortcut, 'K', 0, strlen(shortcut)); Print_help(8+4*6, FILESEL_Y + 89+24, shortcut, 'K', 0, strlen(shortcut));
} }
else else
{ {
Print_help(8+4*6, FILESEL_Y + 89+24, "None", 'K', 0, 4); Print_help(8+4*6, FILESEL_Y + 89+24, "None", 'K', 0, 4);
} }
} }
free(full_name);
} }
Update_window_area(8, FILESEL_Y + 89, DESC_WIDTH*6+2, 4*8); Update_window_area(8, FILESEL_Y + 89, DESC_WIDTH*6+2, 4*8);
} }
// Add a script to the list // Add a script to the list
@ -2314,7 +2330,7 @@ void Highlight_script(T_Fileselector *selector, T_List_button *list, const char
Locate_list_item(list, index); Locate_list_item(list, index);
} }
static char Last_run_script[MAX_PATH_CHARACTERS]=""; static char * Last_run_script = NULL;
// Before: Cursor hidden // Before: Cursor hidden
// After: Cursor shown // After: Cursor shown
@ -2322,41 +2338,56 @@ void Run_script(const char *script_subdirectory, const char *script_filename)
{ {
lua_State* L; lua_State* L;
const char* message; const char* message;
byte old_cursor_shape=Cursor_shape; byte old_cursor_shape = Cursor_shape;
char buf[MAX_PATH_CHARACTERS]; char buf[MAX_PATH_CHARACTERS];
int original_image_width=Main.image_width; int original_image_width = Main.image_width;
int original_image_height=Main.image_height; int original_image_height = Main.image_height;
int original_current_layer = Main.current_layer; int original_current_layer = Main.current_layer;
// Some scripts are slow // Some scripts are slow
Cursor_shape=CURSOR_SHAPE_HOURGLASS; Cursor_shape = CURSOR_SHAPE_HOURGLASS;
Display_cursor(); Display_cursor();
Flush_update(); Flush_update();
Cursor_is_visible=1; Cursor_is_visible=1;
free(Last_run_script);
if (script_subdirectory && script_subdirectory[0]!='\0') if (script_subdirectory && script_subdirectory[0]!='\0')
{ Last_run_script = Filepath_append_to_dir(script_subdirectory, script_filename);
strcpy(Last_run_script, script_subdirectory);
Append_path(Last_run_script, script_filename, NULL);
}
else else
{ Last_run_script = strdup(script_filename);
strcpy(Last_run_script, script_filename);
}
// This chdir is for the script's sake. Grafx2 itself will (try to) // This chdir is for the script's sake. Grafx2 itself will (try to)
// not rely on what is the system's current directory. // not rely on what is the system's current directory.
Extract_path(buf,Last_run_script); Extract_path(buf, Last_run_script);
Change_directory(buf); Change_directory(buf);
L = luaL_newstate(); // used to be lua_open() on Lua 5.1, deprecated on 5.2 L = luaL_newstate(); // used to be lua_open() on Lua 5.1, deprecated on 5.2
strcpy(buf, "LUA_PATH="); /// @todo as the value doesn't vary, this should be
strcat(buf, Data_directory); /// done once at the start of the program
Append_path(buf+9, SCRIPTS_SUBDIRECTORY, NULL); strcpy(buf, Data_directory);
Append_path(buf+9, LUALIB_SUBDIRECTORY, NULL); Append_path(buf, SCRIPTS_SUBDIRECTORY, NULL);
Append_path(buf+9, "?.lua", NULL); Append_path(buf, LUALIB_SUBDIRECTORY, NULL);
putenv(buf); Append_path(buf, "?.lua", NULL);
// SetEnvironmentVariableA() won't work because lua uses getenv()
#if defined(_MSC_VER)
if (_putenv_s("LUA_PATH", buf) < 0)
GFX2_Log(GFX2_ERROR, "_putenv_s(\"LUA_PATH\", \"%s\") failed\n", buf);
#elif defined(WIN32)
// Mingw has neither setenv() nor _putenv_s()
memmove(buf + 9, buf, strlen(buf) + 1);
memcpy(buf, "LUA_PATH=", 9);
if (putenv(buf) < 0)
GFX2_Log(GFX2_ERROR, "putenv(\"%s\") failed\n", buf);
#else
/* From linux man :
* This function makes
* copies of the strings pointed to by name and value (by contrast with
* putenv(3)).
*/
if (setenv("LUA_PATH", buf, 1) < 0)
GFX2_Log(GFX2_ERROR, "setenv(\"LUA_PATH\", \"%s\", 1) failed\n", buf);
#endif
// Drawing // Drawing
lua_register(L,"putbrushpixel",L_PutBrushPixel); lua_register(L,"putbrushpixel",L_PutBrushPixel);
@ -2473,7 +2504,7 @@ void Run_script(const char *script_subdirectory, const char *script_filename)
{ {
memcpy(Brush_backup, Brush, ((long)Brush_height)*Brush_width); memcpy(Brush_backup, Brush, ((long)Brush_height)*Brush_width);
if (luaL_loadfile(L,Last_run_script) != 0) if (luaL_loadfile(L, Last_run_script) != 0)
{ {
int stack_size; int stack_size;
stack_size= lua_gettop(L); stack_size= lua_gettop(L);
@ -2581,20 +2612,20 @@ void Repeat_script(void)
void Set_script_shortcut(T_Fileselector_item * script_item, const char *full_directory) void Set_script_shortcut(T_Fileselector_item * script_item, const char *full_directory)
{ {
int i; int i;
char full_name[MAX_PATH_CHARACTERS]; char * full_name;
if (script_item && script_item->Full_name && script_item->Full_name[0]!='\0') if (script_item && script_item->Full_name && script_item->Full_name[0] != '\0')
{ {
strcpy(full_name, full_directory); full_name = Filepath_append_to_dir(full_directory, script_item->Full_name);
Append_path(full_name, script_item->Full_name, NULL);
// Find if it already has a shortcut // Find if it already has a shortcut
for (i=0; i<10; i++) for (i=0; i<10; i++)
if (Bound_script[i]!=NULL && !strcmp(Bound_script[i], full_name)) if (Bound_script[i] != NULL && !strcmp(Bound_script[i], full_name))
break; break;
if (i<10) if (i<10)
{ {
// Existing shortcut // Existing shortcut
free(full_name);
} }
else else
{ {
@ -2602,16 +2633,17 @@ void Set_script_shortcut(T_Fileselector_item * script_item, const char *full_dir
for (i=0; i<10; i++) for (i=0; i<10; i++)
if (Bound_script[i]==NULL if (Bound_script[i]==NULL
|| !Has_shortcut(SPECIAL_RUN_SCRIPT_1+i) || !Has_shortcut(SPECIAL_RUN_SCRIPT_1+i)
|| !File_exists(full_name)) || !File_exists(Bound_script[i]))
break; break;
if (i<10) if (i<10)
{ {
free(Bound_script[i]); free(Bound_script[i]);
Bound_script[i]=strdup(full_name); Bound_script[i] = full_name;
} }
else else
{ {
Warning_message("Already 10 scripts have shortcuts."); Warning_message("Already 10 scripts have shortcuts.");
free(full_name);
return; return;
} }
} }
@ -2633,7 +2665,7 @@ void Reload_scripts_list(void)
{ {
// Reinitialize the list // Reinitialize the list
Free_fileselector_list(&Scripts_selector); Free_fileselector_list(&Scripts_selector);
if (Config.Scripts_directory[0]=='\0') if (Config.Scripts_directory == NULL || Config.Scripts_directory[0]=='\0')
{ {
Read_list_of_drives(&Scripts_selector,NAME_WIDTH+1); Read_list_of_drives(&Scripts_selector,NAME_WIDTH+1);
} }
@ -2725,7 +2757,7 @@ void Button_Brush_Factory(void)
do do
{ {
clicked_button = Window_clicked_button(); clicked_button = Window_clicked_button();
if (Key==KEY_BACKSPACE && Config.Scripts_directory[0]!='\0') if (Key==KEY_BACKSPACE && Config.Scripts_directory != NULL && Config.Scripts_directory[0]!='\0')
{ {
// Make it select first entry (parent directory) // Make it select first entry (parent directory)
scriptlist->List_start=0; scriptlist->List_start=0;
@ -2782,23 +2814,34 @@ void Button_Brush_Factory(void)
item = Get_item_by_index(&Scripts_selector, item = Get_item_by_index(&Scripts_selector,
scriptlist->List_start + scriptlist->Cursor_position); scriptlist->List_start + scriptlist->Cursor_position);
if (item->Type==0) // File if (item->Type == FSOBJECT_FILE)
{ {
strcpy(selected_file, item->Full_name); strcpy(selected_file, item->Full_name);
break; break;
} }
else if (item->Type==1 || item->Type==2) // Directory else if (item->Type == FSOBJECT_DIR || item->Type == FSOBJECT_DRIVE)
{ {
if (item->Type==2) if (item->Type == FSOBJECT_DRIVE)
{ {
// Selecting one drive root // Selecting one drive root
strcpy(selected_file, PARENT_DIR); strcpy(selected_file, PARENT_DIR);
strcat(Config.Scripts_directory, item->Full_name); free(Config.Scripts_directory);
Config.Scripts_directory = strdup(item->Full_name);
} }
else else
{ {
// Going down one or up by one directory // Going down one or up by one directory
Append_path(Config.Scripts_directory, item->Full_name, selected_file); if (strcmp(item->Full_name, PARENT_DIR) == 0)
Append_path(Config.Scripts_directory, item->Full_name, selected_file);
else
{
char * new_dir = Filepath_append_to_dir(Config.Scripts_directory, item->Full_name);
if (new_dir != NULL)
{
free(Config.Scripts_directory);
Config.Scripts_directory = new_dir;
}
}
} }
// No break: going back up to beginning of loop // No break: going back up to beginning of loop

View File

@ -870,9 +870,11 @@ void Release_lock_file(const char *file_directory)
remove(lock_filename); remove(lock_filename);
} }
const char * Get_current_directory(char * buf, word * buf_unicode, size_t size) char * Get_current_directory(char * buf, word * buf_unicode, size_t size)
{ {
#if defined(__MINT__) #if defined(__MINT__)
if (buf == NULL)
buf = malloc(MAX_PATH_CHARACTERS);
buf[0] = 'A'+Dgetdrv(); buf[0] = 'A'+Dgetdrv();
buf[1] = ':'; buf[1] = ':';
buf[2] = '\\'; buf[2] = '\\';
@ -884,6 +886,7 @@ const char * Get_current_directory(char * buf, word * buf_unicode, size_t size)
return buf; return buf;
#elif defined(WIN32) #elif defined(WIN32)
/// @TODO allocate buf if needed
if (GetCurrentDirectoryA(size, buf) == 0) if (GetCurrentDirectoryA(size, buf) == 0)
return NULL; return NULL;
if (buf_unicode != NULL) if (buf_unicode != NULL)

View File

@ -183,7 +183,7 @@ void Release_lock_file(const char *file_directory);
/// ///
/// Return the current directory, equivalent to getcwd() /// Return the current directory, equivalent to getcwd()
const char * Get_current_directory(char * buf, word * buf_unicode, size_t size); char * Get_current_directory(char * buf, word * buf_unicode, size_t size);
/// ///
/// Change current directory. return 0 for success, -1 in case of error /// Change current directory. return 0 for success, -1 in case of error