From 98811b636335d61da7774c4db408b766b9f4a5dc Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Thu, 14 Feb 2019 23:12:41 +0100 Subject: [PATCH] Get rid of Get_full_filename() --- src/buttons.c | 46 ++++++++++------- src/filesel.c | 6 +-- src/io.c | 95 ++++++++++++++++++---------------- src/io.h | 6 +-- src/loadsave.c | 134 +++++++++++++++++++++++++++++------------------- src/tifformat.c | 5 +- 6 files changed, 167 insertions(+), 125 deletions(-) diff --git a/src/buttons.c b/src/buttons.c index 9f08bebb..e0427d30 100644 --- a/src/buttons.c +++ b/src/buttons.c @@ -604,8 +604,9 @@ void Button_Toggle_all_toolbars(int btn) byte Button_Quit_local_function(void) { short clicked_button; - static char filename[MAX_PATH_CHARACTERS]; byte old_cursor_shape; + char * filename; + int exists; if (!Main.image_is_modified) return 1; @@ -635,8 +636,10 @@ byte Button_Quit_local_function(void) { case 1 : return 0; // Rester case 2 : // Sauver et enregistrer - Get_full_filename(filename, Main.backups->Pages->Filename, Main.backups->Pages->File_directory); - if ( (!File_exists(filename)) || Confirmation_box("Erase old file ?") ) + filename = Filepath_append_to_dir(Main.backups->Pages->File_directory, Main.backups->Pages->Filename); + exists = File_exists(filename); + free(filename); + if ( !exists || Confirmation_box("Erase old file ?") ) { T_IO_Context save_context; @@ -1276,7 +1279,7 @@ void Button_Skins(int btn) { short clicked_button; short temp; - char skinsdir[MAX_PATH_CHARACTERS]; + char * skinsdir; T_Dropdown_button * font_dropdown; T_Dropdown_button * cursor_dropdown; T_List_button * skin_list; @@ -1303,8 +1306,7 @@ void Button_Skins(int btn) Free_fileselector_list(&Skin_files_list); Free_fileselector_list(&Font_files_list); // Browse the "skins" directory - strcpy(skinsdir, Data_directory); - strcat(skinsdir, SKINS_SUBDIRECTORY); + skinsdir = Filepath_append_to_dir(Data_directory, SKINS_SUBDIRECTORY); // Add each found file to the list For_each_file(skinsdir, Add_font_or_skin); // Sort it @@ -1384,7 +1386,8 @@ void Button_Skins(int btn) Hide_cursor(); // (Re-)load GUI graphics from selected skins - strcpy(skinsdir, Get_item_by_index(&Skin_files_list, + free(skinsdir); + skinsdir = strdup(Get_item_by_index(&Skin_files_list, skin_list->List_start + skin_list->Cursor_position)->Full_name); gfx = Load_graphics(skinsdir, NULL); @@ -1546,6 +1549,7 @@ void Button_Skins(int btn) Draw_menu_button(button,state); } Display_cursor(); + free(skinsdir); } @@ -3454,12 +3458,16 @@ void Button_Reload(int btn) static void Backup_existing_file(const char * filename) { - char new_filename[MAX_PATH_CHARACTERS]; // full filename of the backup file + char * new_filename; // full filename of the backup file char * p; int i; + size_t len; - strncpy(new_filename, filename, sizeof(new_filename)); - new_filename[sizeof(new_filename) - 1] = '\0'; + if (filename == NULL) + return; + len = strlen(filename); + new_filename = malloc(len + 1 + 4); // spare bytes to concat ".BAK" + memcpy(new_filename, filename, len + 1); p = Find_last_separator(new_filename); // pointer to the filename part (after directory) if (p == NULL) p = new_filename; @@ -3467,9 +3475,9 @@ static void Backup_existing_file(const char * filename) p++; i = Position_last_dot(p); if (i >= 0) - strcpy(p + i + 1, "BAK"); + memcpy(p + i + 1, "BAK", 4); else - strcat(p, ".BAK"); + memcpy(new_filename + len, ".BAK", 5); File_error=0; @@ -3479,13 +3487,14 @@ static void Backup_existing_file(const char * filename) { // S'il y avait déjà un fichier Backup, on l'efface if ((File_exists(new_filename)) - && (remove(new_filename)!=0)) + && (Remove_path(new_filename)!=0)) File_error=1; if ((!File_error) && (rename(filename,new_filename)!=0)) File_error=1; } + free(new_filename); } @@ -3551,9 +3560,9 @@ void Save_picture(enum CONTEXT_TYPE type) confirm=Confirmation_box("Erase old file ?"); if (confirm && (Config.Backup)) { - char full_filename[MAX_PATH_CHARACTERS]; - Get_full_filename(full_filename, filename, directory); + char * full_filename = Filepath_append_to_dir(directory, filename); Backup_existing_file(full_filename); + free(full_filename); if (File_error) { confirm=0; @@ -3616,12 +3625,12 @@ void Button_Save(int btn) void Button_Autosave(int btn) { byte old_cursor_shape; - static char filename[MAX_PATH_CHARACTERS]; + char * filename; byte file_already_exists; (void)btn; - Get_full_filename(filename, Main.backups->Pages->Filename, Main.backups->Pages->File_directory); - file_already_exists=File_exists(filename); + filename = Filepath_append_to_dir(Main.backups->Pages->File_directory, Main.backups->Pages->Filename); + file_already_exists = File_exists(filename); if ( (!file_already_exists) || Confirmation_box("Erase old file ?") ) { @@ -3657,6 +3666,7 @@ void Button_Autosave(int btn) else Hide_cursor(); + free(filename); Unselect_button(BUTTON_SAVE); Display_cursor(); diff --git a/src/filesel.c b/src/filesel.c index 2e807bfd..23f47c43 100644 --- a/src/filesel.c +++ b/src/filesel.c @@ -2180,7 +2180,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context { // Bookmark char * directory_name; - const char * rel_path; + char * rel_path; load_from_clipboard = 0; switch(Window_attribute2) @@ -2243,9 +2243,7 @@ byte Button_Load_or_Save(T_Selector_settings *settings, byte load, T_IO_Context { // Erase old bookmark free(Config.Bookmark_directory[clicked_button-10]); - Config.Bookmark_directory[clicked_button-10] = NULL; - - Config.Bookmark_directory[clicked_button-10] = strdup(rel_path); + Config.Bookmark_directory[clicked_button-10] = rel_path; directory_name = Find_last_separator(Selector->Directory); if (directory_name && directory_name[1]!='\0') directory_name++; diff --git a/src/io.c b/src/io.c index e9f8b13d..ebfa7a09 100644 --- a/src/io.c +++ b/src/io.c @@ -292,6 +292,8 @@ char * Filepath_append_to_dir(const char * dir, const char * filename) { char * path; size_t len = strlen(dir); + if (len == 0) // no directory + return strdup(filename); if (dir[len-1] == PATH_SEPARATOR[0] #if defined(__WIN32__) || defined(WIN32) || dir[len-1] == '/' @@ -713,25 +715,6 @@ void For_each_directory_entry(const char * directory_name, void * pdata, T_File_ } -void Get_full_filename(char * output_name, const char * file_name, const char * directory_name) -{ - strcpy(output_name,directory_name); - if (output_name[0] != '\0') - { - // Append a separator at the end of path, if there isn't one already. - // This handles the case of directory variables which contain one, - // as well as directories like "/" on Unix. -#if defined(__AROS__) - // additional check for ':' to avoid paths like PROGDIR:/unnamed.gif - if ((output_name[strlen(output_name)-1]!=PATH_SEPARATOR[0]) && (output_name[strlen(output_name)-1]!=':')) -#else - if (output_name[strlen(output_name)-1]!=PATH_SEPARATOR[0]) -#endif - strcat(output_name,PATH_SEPARATOR); - } - strcat(output_name,file_name); -} - /** * Convert a file name to unicode characters * @@ -840,6 +823,8 @@ HANDLE Lock_file_handle = INVALID_HANDLE_VALUE; int Lock_file_handle = -1; #endif +#define GFX2_LOCK_FILENAME "gfx2.lck" + byte Create_lock_file(const char *file_directory) { #if defined (__amigaos__)||(__AROS__)||(__ANDROID__) @@ -847,14 +832,13 @@ byte Create_lock_file(const char *file_directory) #elif defined(__SWITCH__) // The switch can only run one application at a time, so we don't do anything special here #else - char lock_filename[MAX_PATH_CHARACTERS]; + char * lock_filename; #ifdef GCWZERO - strcpy(lock_filename,"/media/home/.grafx2/"); + lock_filename = Filepath_append_to_dir("/media/home/.grafx2/", GFX2_LOCK_FILENAME); #else - strcpy(lock_filename,file_directory); + lock_filename = Filepath_append_to_dir(file_directory, GFX2_LOCK_FILENAME); #endif - strcat(lock_filename,"gfx2.lck"); #ifdef WIN32 // Windowzy method for creating a lock file @@ -866,6 +850,7 @@ byte Create_lock_file(const char *file_directory) OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + free(lock_filename); if (Lock_file_handle == INVALID_HANDLE_VALUE) { return -1; @@ -873,6 +858,7 @@ byte Create_lock_file(const char *file_directory) #else // Unixy method for lock file Lock_file_handle = open(lock_filename,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR); + free(lock_filename); if (Lock_file_handle == -1) { // Usually write-protected media @@ -891,7 +877,7 @@ byte Create_lock_file(const char *file_directory) void Release_lock_file(const char *file_directory) { - char lock_filename[MAX_PATH_CHARACTERS]; + char * lock_filename; #ifdef WIN32 if (Lock_file_handle != INVALID_HANDLE_VALUE) @@ -907,9 +893,12 @@ void Release_lock_file(const char *file_directory) #endif // Actual deletion - strcpy(lock_filename,file_directory); - strcat(lock_filename,"gfx2.lck"); - remove(lock_filename); +#ifdef GCWZERO + lock_filename = Filepath_append_to_dir("/media/home/.grafx2/", GFX2_LOCK_FILENAME); +#else + lock_filename = Filepath_append_to_dir(file_directory, GFX2_LOCK_FILENAME); +#endif + Remove_path(lock_filename); } char * Get_current_directory(char * buf, word * buf_unicode, size_t size) @@ -1016,28 +1005,30 @@ int Remove_directory(const char * path) /// /// Calculate relative path -const char * Calculate_relative_path(const char * ref_path, const char * path) +char * Calculate_relative_path(const char * ref_path, const char * path) { - char real_ref_path[MAX_PATH_CHARACTERS]; - static char rel_path[MAX_PATH_CHARACTERS]; + char * real_ref_path; + char * rel_path = NULL; int last_separator = -1; int i; int separator_count = 0; + size_t len; if (ref_path == NULL || path == NULL) return NULL; - if (Realpath(ref_path, real_ref_path) == NULL) - { - strncpy(real_ref_path, ref_path, MAX_PATH_CHARACTERS); - real_ref_path[MAX_PATH_CHARACTERS-1] = '\0'; - } + real_ref_path = Realpath(ref_path, NULL); + if (real_ref_path == NULL) + real_ref_path = strdup(ref_path); #if defined(WIN32) || defined(__MINT__) if (real_ref_path[1] == ':' && path[1] == ':') { // use same case for drive letter real_ref_path[0] = (real_ref_path[0] & ~32) | (path[0] & 32); if (real_ref_path[0] != path[0]) + { + free(real_ref_path); return NULL; // path on different volumes, not possible + } } #endif // look for common path parts @@ -1054,36 +1045,54 @@ const char * Calculate_relative_path(const char * ref_path, const char * path) // real_ref_path and path. // real_ref_path[i] and path[i] are either different, or both '\0' if (real_ref_path[i] == PATH_SEPARATOR[0] && real_ref_path[i + 1] == '\0' && path[i] == '\0') - return "."; // path are identical (real_ref_path has additional trailing separator) + { + free(real_ref_path); + return strdup("."); // path are identical (real_ref_path has additional trailing separator) + } if (real_ref_path[i] == '\0') { if (path[i] == '\0') - return "."; // path are identical + { + free(real_ref_path); + return strdup("."); // path are identical + } // path is under ref_path if (path[i] == PATH_SEPARATOR[0]) { - snprintf(rel_path, MAX_PATH_CHARACTERS, ".%s", path + i); + free(real_ref_path); + len = strlen(path + i) + 1; + rel_path = malloc(len + 1); + snprintf(rel_path, len, ".%s", path + i); return rel_path; } else if (i > 0 && real_ref_path[i - 1] == PATH_SEPARATOR[0]) { - snprintf(rel_path, MAX_PATH_CHARACTERS, ".%s", path + i - 1); + free(real_ref_path); + len = strlen(path + i - 1) + 1; + rel_path = malloc(len + 1); + snprintf(rel_path, len, ".%s", path + i - 1); return rel_path; } } if (last_separator <= 0) - return path; // no common part found return absolute path + { + free(real_ref_path); + return strdup(path); // no common part found return absolute path + } // count the number of path separators in the reference path for (i = last_separator; real_ref_path[i] != '\0'; i++) { if (real_ref_path[i] == PATH_SEPARATOR[0] && real_ref_path[i + 1] != '\0') // do not count the trailing separator separator_count++; } + free(real_ref_path); i = 0; // construct the relative path + len = separator_count * (2 + strlen(PATH_SEPARATOR)) + strlen(path + last_separator + 1) + 1; + rel_path = malloc(len + 1); while(separator_count-- > 0) - i += snprintf(rel_path + i, MAX_PATH_CHARACTERS - i, "..%s", PATH_SEPARATOR); - strncpy(rel_path + i, path + last_separator + 1, MAX_PATH_CHARACTERS - i); - rel_path[MAX_PATH_CHARACTERS - 1] = '\0'; + i += snprintf(rel_path + i, len + 1 - i, "..%s", PATH_SEPARATOR); + strncpy(rel_path + i, path + last_separator + 1, len + 1 - i); + rel_path[len] = '\0'; return rel_path; } diff --git a/src/io.h b/src/io.h index c97beba0..1b635d19 100644 --- a/src/io.h +++ b/src/io.h @@ -151,10 +151,6 @@ void For_each_directory_entry(const char * directory_name, void * pdata, T_File_ /** @ingroup filename * @{ */ -/// -/// Creates a fully qualified name from a directory and filename. -/// The point is simply to insert a PATH_SEPARATOR when needed. -void Get_full_filename(char * output_name, const char * file_name, const char * directory_name); word * Get_Unicode_Filename(word * filename_unicode, const char * filename, const char * directory); @@ -203,7 +199,7 @@ int Remove_directory(const char * path); /// /// Calculate relative path -const char * Calculate_relative_path(const char * ref_path, const char * path); +char * Calculate_relative_path(const char * ref_path, const char * path); /** @}*/ #endif diff --git a/src/loadsave.c b/src/loadsave.c index cd7124a7..3f9cb5c9 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -1134,31 +1134,29 @@ void Save_image(T_IO_Context *context) #if defined(USE_SDL) || defined(USE_SDL2) void Load_SDL_Image(T_IO_Context *context) { - char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier + char * filename; // full path word x_pos,y_pos; // long file_size; dword pixel; long file_size; SDL_Surface * surface; + filename = Filepath_append_to_dir(context->File_directory, context->File_name); + file_size = File_length(filename); + File_error = 0; - Get_full_filename(filename, context->File_name, context->File_directory); - File_error=0; - surface = IMG_Load(filename); - + free(filename); + if (!surface) { File_error=1; return; } - - file_size=File_length(filename); - + if (surface->format->BytesPerPixel == 1) { // 8bpp image - Pre_load(context, surface->w, surface->h, file_size ,FORMAT_MISC, PIXEL_SIMPLE, 8); // Read palette @@ -1652,7 +1650,7 @@ static void Save_ClipBoard_Image(T_IO_Context * context) /// create an unusable image. void Emergency_backup(const char *fname, byte *source, int width, int height, T_Palette *palette) { - char filename[MAX_PATH_CHARACTERS]; // Nom complet du fichier + char * filename; // Full path name FILE *file; short x_pos,y_pos; T_IMG_Header IMG_header; @@ -1660,11 +1658,10 @@ void Emergency_backup(const char *fname, byte *source, int width, int height, T_ if (width == 0 || height == 0 || source == NULL) return; - strcpy(filename,Config_directory); - strcat(filename,fname); - - // Ouverture du fichier - file=fopen(filename,"wb"); + // Open the file + filename = Filepath_append_to_dir(Config_directory, fname); + file = fopen(filename,"wb"); + free(filename); if (!file) return; @@ -2112,7 +2109,7 @@ void Rotate_safety_backups(void) Config_directory, Main.safety_backup_prefix, (dword)(Main.safety_number + 1000000l - Rotation_safety_backup) % (dword)1000000l); - remove(deleted_file); // no matter if fail + Remove_path(deleted_file); // no matter if fail // Reset counters Main.edits_since_safety_backup=0; @@ -2181,10 +2178,10 @@ void Delete_safety_backups(void) /// For use by Save_XXX() functions FILE * Open_file_write(T_IO_Context *context) { - char filename[MAX_PATH_CHARACTERS]; // filename with full path + FILE * f; + char * filename; // filename with full path #if defined(WIN32) WCHAR filename_unicode[MAX_PATH_CHARACTERS]; - FILE * f; if (context->File_name_unicode != NULL && context->File_name_unicode[0] != 0) { @@ -2210,15 +2207,18 @@ FILE * Open_file_write(T_IO_Context *context) return f; } #endif - Get_full_filename(filename, context->File_name, context->File_directory); - return fopen(filename, "wb"); + filename = Filepath_append_to_dir(context->File_directory, context->File_name); + f = fopen(filename, "wb"); + free(filename); + return f; } FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ext) { + FILE * f; char *p; - char filename[MAX_PATH_CHARACTERS]; // filename with full path + char * filename; // filename with full path #if defined(WIN32) WCHAR filename_unicode[MAX_PATH_CHARACTERS]; WCHAR * pw; @@ -2237,33 +2237,38 @@ FILE * Open_file_write_with_alternate_ext(T_IO_Context *context, const char * ex return _wfopen(filename_unicode, L"wb"); } #endif - Get_full_filename(filename, context->File_name, context->File_directory); + filename = Filepath_append_to_dir(context->File_directory, context->File_name); +// TODO: fix ! (realloc if not enough space) p = strrchr(filename, '.'); if (p != NULL) *p = '\0'; strcat(filename, "."); strcat(filename, ext); - return fopen(filename, "wb"); + f = fopen(filename, "wb"); + free(filename); + return f; } /// For use by Load_XXX() and Test_XXX() functions FILE * Open_file_read(T_IO_Context *context) { - char filename[MAX_PATH_CHARACTERS]; // filename with full path + FILE * f; + char * filename; // filename with full path - Get_full_filename(filename, context->File_name, context->File_directory); - - return fopen(filename, "rb"); + filename = Filepath_append_to_dir(context->File_directory, context->File_name); + f = fopen(filename, "rb"); + free(filename); + return f; } struct T_Find_alternate_ext_data { const char * ext; - char basename[MAX_PATH_CHARACTERS]; - word basename_unicode[MAX_PATH_CHARACTERS]; - char foundname[MAX_PATH_CHARACTERS]; - word foundname_unicode[MAX_PATH_CHARACTERS]; + char * basename; + word * basename_unicode; + char * foundname; + word * foundname_unicode; }; static void Look_for_alternate_ext(void * pdata, const char * filename, const word * filename_unicode, byte is_file, byte is_directory, byte is_hidden) @@ -2276,8 +2281,10 @@ static void Look_for_alternate_ext(void * pdata, const char * filename, const wo if (!is_file) return; - if (filename_unicode != NULL && params->basename_unicode[0] != 0) + if (filename_unicode != NULL && params->basename_unicode != NULL) { + if (params->foundname_unicode != NULL) + return; // We already have found a file base_len = Unicode_strlen(params->basename_unicode); if (Unicode_strlen(filename_unicode) <= base_len) return; // No match. @@ -2298,11 +2305,14 @@ static void Look_for_alternate_ext(void * pdata, const char * filename, const wo if (Unicode_char_strcasecmp(filename_unicode + base_len + 1, params->ext) != 0) return; // No match. // it is a match ! - Unicode_strlcpy(params->foundname_unicode, filename_unicode, MAX_PATH_CHARACTERS); - strncpy(params->foundname, filename, MAX_PATH_CHARACTERS); + free(params->foundname); + params->foundname_unicode = Unicode_strdup(filename_unicode); + params->foundname = strdup(filename); } else { + if (params->foundname != NULL) + return; // We already have found a file base_len = strlen(params->basename); if (filename[base_len] != '.') return; // No match. @@ -2315,52 +2325,70 @@ static void Look_for_alternate_ext(void * pdata, const char * filename, const wo #endif if (strcasecmp(filename + base_len + 1, params->ext) != 0) return; // No match. - params->foundname_unicode[0] = 0; - strncpy(params->foundname, filename, MAX_PATH_CHARACTERS); + params->foundname_unicode = NULL; + params->foundname = strdup(filename); } } FILE * Open_file_read_with_alternate_ext(T_IO_Context *context, const char * ext) { + FILE * f = NULL; char * p; struct T_Find_alternate_ext_data params; memset(¶ms, 0, sizeof(params)); params.ext = ext; - strncpy(params.basename, context->File_name, MAX_PATH_CHARACTERS); + params.basename = strdup(context->File_name); + if (params.basename == NULL) + { + GFX2_Log(GFX2_ERROR, "Open_file_read_with_alternate_ext() strdup() failed\n"); + return NULL; + } p = strrchr(params.basename, '.'); if (p != NULL) *p = '\0'; if (context->File_name_unicode != NULL) { size_t i = Unicode_strlen(context->File_name_unicode); - memcpy(params.basename_unicode, context->File_name_unicode, (i + 1) * sizeof(word)); - while (i-- > 0) - if (params.basename_unicode[i] == (word)'.') - { - params.basename_unicode[i] = 0; - break; - } + params.basename_unicode = malloc(sizeof(word) * (i + 1)); + if (params.basename_unicode == NULL) + { + GFX2_Log(GFX2_ERROR, "Open_file_read_with_alternate_ext() failed to allocate %lu bytes\n", (unsigned long)(sizeof(word) * (i + 1))); + } + else + { + memcpy(params.basename_unicode, context->File_name_unicode, (i + 1) * sizeof(word)); + while (i-- > 0) + if (params.basename_unicode[i] == (word)'.') + { + params.basename_unicode[i] = 0; + break; + } + } } For_each_directory_entry(context->File_directory, ¶ms, Look_for_alternate_ext); - if (params.foundname[0] != '\0') + if (params.foundname != NULL) { - char filename[MAX_PATH_CHARACTERS]; // filename with full path + char * filename; // filename with full path - Get_full_filename(filename, params.foundname, context->File_directory); - - return fopen(filename, "rb"); + filename = Filepath_append_to_dir(context->File_directory, params.foundname); + f = fopen(filename, "rb"); + free(filename); } - return NULL; + free(params.basename); + free(params.basename_unicode); + free(params.foundname); + free(params.foundname_unicode); + return f; } /// For use by Save_XXX() functions void Remove_file(T_IO_Context *context) { - char filename[MAX_PATH_CHARACTERS]; // filename with full path - - Get_full_filename(filename, context->File_name, context->File_directory); + char * filename; // filename with full path + filename = Filepath_append_to_dir(context->File_directory, context->File_name); Remove_path(filename); + free(filename); } diff --git a/src/tifformat.c b/src/tifformat.c index e56b4110..07644e56 100644 --- a/src/tifformat.c +++ b/src/tifformat.c @@ -621,10 +621,10 @@ void Load_TIFF(T_IO_Context * context) fclose(file); } #else - char filename[MAX_PATH_CHARACTERS]; // filename with full path + char * filename; // filename with full path File_error = 1; - Get_full_filename(filename, context->File_name, context->File_directory); + filename = Filepath_append_to_dir(context->File_directory, context->File_name); TIFF_Init(); tif = TIFFOpen(filename, "r"); if (tif != NULL) @@ -632,6 +632,7 @@ void Load_TIFF(T_IO_Context * context) Load_TIFF_Sub(context, tif, File_length(filename)); TIFFClose(tif); } + free(filename); #endif }