From e053a7e53a041b43808c898dc0c100b6cfee15db Mon Sep 17 00:00:00 2001 From: Tim Felgentreff Date: Mon, 14 Jun 2021 23:23:40 +0200 Subject: [PATCH] use std::filesystem in more places --- gameheaders/stratagus-game-launcher.h | 78 ++++++++--------- gameheaders/stratagus-gameutils.h | 120 ++++---------------------- 2 files changed, 50 insertions(+), 148 deletions(-) diff --git a/gameheaders/stratagus-game-launcher.h b/gameheaders/stratagus-game-launcher.h index 7ea52fce1..094da652d 100644 --- a/gameheaders/stratagus-game-launcher.h +++ b/gameheaders/stratagus-game-launcher.h @@ -268,19 +268,15 @@ int check_version(char* tool_path, char* data_path) { } static void ExtractData(char* extractor_tool, char* destination, char* scripts_path, int force=0) { - struct stat st; int canJustReextract; #ifdef EXTRACTION_FILES if (force == 0) { canJustReextract = 1; char* extraction_files[] = { EXTRACTION_FILES, NULL }; char* efile = extraction_files[0]; - char efile_path[PATH_MAX] = {'\0'}; for (int i = 0; efile != NULL; i++) { - strcpy(efile_path, destination); - strcat(efile_path, SLASH); - strcat(efile_path, efile); - if (stat(efile_path, &st) != 0) { + std::filesystem::path efile_path = std::filesystem::path(destination) / efile; + if (!std::filesystem::exists(efile_path)) { // file to extract not found canJustReextract = 0; } @@ -311,17 +307,16 @@ static void ExtractData(char* extractor_tool, char* destination, char* scripts_p int patterncount = 0; while (filepatterns[patterncount++] != NULL); #endif - char srcfolder[1024] = {'\0'}; + std::filesystem::path srcfolder; if (!canJustReextract) { const char* datafile = tinyfd_openFileDialog(GAME_CD " location", "", patterncount - 1, filepatterns, NULL, 0); if (datafile == NULL) { exit(-1); } - strcpy(srcfolder, datafile); - parentdir(srcfolder); + srcfolder = std::filesystem::path(datafile).parent_path(); } else { - strcpy(srcfolder, destination); + srcfolder = std::filesystem::path(destination); } #ifdef WIN32 @@ -337,34 +332,32 @@ static void ExtractData(char* extractor_tool, char* destination, char* scripts_p #else char* sourcepath = strdup(scripts_path); #endif - mkdir_p(destination); - if (stat(sourcepath, &st) != 0) { + std::filesystem::create_directories(std::filesystem::path(destination)); + + if (!std::filesystem::exists(sourcepath)) { // deployment time path not found, try compile time path - strcpy(sourcepath, SRC_PATH()); - parentdir(sourcepath); + strcpy(sourcepath, std::filesystem::path(SRC_PATH()).parent_path().string().c_str()); } #ifndef WIN32 - if (stat(sourcepath, &st) != 0) { + if (!std::filesystem::exists(sourcepath)) { // deployment time path might be same as extractor - strcpy(sourcepath, extractor_tool); - parentdir(sourcepath); + strcpy(sourcepath, std::filesystem::path(extractor_tool).parent_path().string().c_str()); } #endif - if (stat(sourcepath, &st) != 0) { + if (!std::filesystem::exists(sourcepath)) { // scripts not found, abort! - char msg[BUFF_SIZE * 2]; - strcpy(msg, "There was an error copying the data, could not discover scripts path: "); - strcat(msg, sourcepath); - tinyfd_messageBox("Error", msg, "ok", "error", 1); + std::string msg("There was an error copying the data, could not discover scripts path: "); + msg += sourcepath; + tinyfd_messageBox("Error", msg.c_str(), "ok", "error", 1); return; } if (force != 2) { - char contrib_src_path[BUFF_SIZE]; - char contrib_dest_path[BUFF_SIZE]; + std::filesystem::path contrib_src_path; + std::filesystem::path contrib_dest_path(destination); int i = 0; int optional = 0; char* contrib_directories[] = CONTRIB_DIRECTORIES; @@ -375,27 +368,22 @@ static void ExtractData(char* extractor_tool, char* destination, char* scripts_p } else { if (contrib_directories[i][0] != '/') { // absolute Unix paths are not appended to the source path - strcpy(contrib_src_path, sourcepath); - strcat(contrib_src_path, SLASH); - strcat(contrib_src_path, contrib_directories[i]); + contrib_src_path = std::filesystem::path(sourcepath); + contrib_src_path /= contrib_directories[i]; } else { - strcpy(contrib_src_path, contrib_directories[i]); + contrib_src_path = std::filesystem::path(contrib_directories[i]); } - if (stat(contrib_src_path, &st) != 0) { + if (!std::filesystem::exists(contrib_src_path)) { // contrib dir not found, abort! if (!optional) { - char msg[BUFF_SIZE * 2]; - strcpy(msg, "There was an error copying the data, could not discover contributed directory path: "); - strcat(msg, contrib_src_path); - tinyfd_messageBox("Error", msg, "ok", "error", 1); + std::string msg("There was an error copying the data, could not discover contributed directory path: "); + msg += contrib_src_path.string(); + error("Error", msg.c_str()); return; } } else { - strcpy(contrib_dest_path, destination); - strcat(contrib_dest_path, SLASH); - strcat(contrib_dest_path, contrib_directories[i + 1]); - copy_dir(contrib_src_path, contrib_dest_path); + copy_dir(contrib_src_path, contrib_dest_path / contrib_directories[i + 1]); } i += 2; } @@ -416,7 +404,13 @@ static void ExtractData(char* extractor_tool, char* destination, char* scripts_p #endif strcat(cmdbuf, extractor_tool); strcat(cmdbuf, " " QUOTE); - strcat(cmdbuf, srcfolder); + strcat(cmdbuf, srcfolder.string().c_str()); +#ifdef WIN32 + // a trailing backslash will break the extractor because of quoting + if (cmdbuf[strlen(cmdbuf) - 1] == '\\') { + cmdbuf[strlen(cmdbuf) - 1] = '\0'; + } +#endif strcat(cmdbuf, QUOTE " " QUOTE); strcat(cmdbuf, destination); strcat(cmdbuf, QUOTE); @@ -647,10 +641,9 @@ int main(int argc, char * argv[]) { ExtractData(extractor_path, data_path, scripts_path); } if ( stat(title_path, &st) != 0 ) { - char msg[BUFF_SIZE * 2]; - strcat(msg, DATA_NOT_EXTRACTED); - strcat(msg, " (extraction was attempted, but it seems an error occurred)"); - error(TITLE, msg); + std::string msg(DATA_NOT_EXTRACTED); + msg += " (extraction was attempted, but it seems an error occurred)"; + error(TITLE, msg.c_str()); } } @@ -728,7 +721,6 @@ int main(int argc, char * argv[]) { strcpy(msg, "Execution failed for: "); strcat(msg, stratagus_bin); strcat(msg, " "); - char *subargv; for (int i = 1; stratagus_argv[i] != NULL; i++) { if (strlen(msg) + strlen(stratagus_argv[i]) > BUFF_SIZE * 8) { break; diff --git a/gameheaders/stratagus-gameutils.h b/gameheaders/stratagus-gameutils.h index c57440ee9..b9503b409 100644 --- a/gameheaders/stratagus-gameutils.h +++ b/gameheaders/stratagus-gameutils.h @@ -95,6 +95,9 @@ void copy_dir(const char* source_folder, const char* target_folder); #include #include +#include +#include + #include "stratagus-tinyfiledialogs.h" #ifdef WIN32 @@ -102,8 +105,6 @@ void copy_dir(const char* source_folder, const char* target_folder); #else #define BUFF_SIZE 4096 #endif -char dst_root[BUFF_SIZE]; -char src_root[BUFF_SIZE]; void error(const char* title, const char* text) { tinyfd_messageBox(title, text, "ok", "error", 1); @@ -111,114 +112,23 @@ void error(const char* title, const char* text) { } void mkdir_p(const char* path) { - int error = 0; - printf("mkdir %s\n", path); - if (mkdir(path, 0777)) { - error = errno; - if (error == ENOENT) { - char *sep = strrchr((char*)path, '/'); - if (sep == NULL) { - sep = strrchr((char*)path, SLASH[0]); - } - if (sep != NULL) { - *sep = '\0'; - if (strlen(path) > 0) { - // will be null if the we reach the first / - mkdir_p(path); - } - *sep = '/'; - mkdir(path, 0777); - } - } else if (error != EEXIST) { - if (mkdir(path, 0777)) { - printf("Error while trying to create '%s'\n", path); - } - } - } + std::filesystem::create_directories(path); } -#ifdef WIN32 -#include -#include -#include -void copy_dir(const char* source_folder, const char* target_folder) -{ - if (std::filesystem::equivalent(source_folder, target_folder)) { - return; +void copy_dir(std::filesystem::path source_folder, std::filesystem::path target_folder) { + if (std::filesystem::exists(target_folder)) { + if (std::filesystem::equivalent(source_folder, target_folder)) { + return; + } + // first delete the target_folder, if it exists, to ensure clean slate + std::filesystem::remove_all(target_folder); + } else { + // make the parentdir of the target folder + std::filesystem::create_directories(target_folder.parent_path()); } - // make the parentdir of the target folder - char* ptarget = _strdup(target_folder); - parentdir(ptarget); - mkdir_p(ptarget); - // convert source and target folder strings to windows wide strings - wchar_t *wsource_folder = new wchar_t[strlen(source_folder) + 1]; - size_t convertedChars = 0; - mbstowcs_s(&convertedChars, wsource_folder, strlen(source_folder) + 1, source_folder, _TRUNCATE); - wchar_t *wtarget_folder = new wchar_t[strlen(target_folder) + 1]; - mbstowcs_s(&convertedChars, wtarget_folder, strlen(target_folder) + 1, target_folder, _TRUNCATE); - WCHAR sf[MAX_PATH + 1]; - WCHAR tf[MAX_PATH + 1]; - wcscpy_s(sf, MAX_PATH, wsource_folder); - wcscpy_s(tf, MAX_PATH, wtarget_folder); - // ensure we have double-null terminated strings like Windows docs demand - sf[lstrlenW(sf) + 1] = 0; - tf[lstrlenW(tf) + 1] = 0; - // first delete the target_folder, if it exists - SHFILEOPSTRUCTW deleteS = { 0 }; - deleteS.wFunc = FO_DELETE; - deleteS.pTo = tf; - deleteS.pFrom = tf; - deleteS.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI; - SHFileOperationW(&deleteS); // now copy the new folder in its place - SHFILEOPSTRUCTW s = { 0 }; - s.wFunc = FO_COPY; - s.pTo = tf; - s.pFrom = sf; - s.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI; - SHFileOperationW(&s); + std::filesystem::copy(source_folder, target_folder, std::filesystem::copy_options::recursive | std::filesystem::copy_options::overwrite_existing); } -#else -int copy_file(const char* src_path, const struct stat* sb, int typeflag) { - char dst_path[BUFF_SIZE]; - printf("%s to %s\n", src_path, dst_root); - strcpy(dst_path, dst_root); - strcat(dst_path, src_path + strlen(src_root)); - switch(typeflag) { - case FTW_D: - mkdir_p(dst_path); - break; - case FTW_F: - mkdir_p(parentdir(strdup(dst_path))); - FILE* in = fopen(src_path, "rb"); - FILE* out = fopen(dst_path, "wb"); - char buf[4096]; - int c = 0; - if (!in) { - error("Extraction error", "Could not open source folder for reading."); - } - if (!out) { - error("Extraction error", "Could not open data folder for writing."); - } - while ((c = fread(buf, sizeof(char), 4096, in))) { - fwrite(buf, sizeof(char), c, out); - } - fclose(in); - fclose(out); - break; - } - return 0; -} - -void copy_dir(const char* src_path, const char* dst_path) { - printf("Copying %s to %s\n", src_path, dst_path); - mkdir_p(parentdir(strdup(dst_path))); - strcpy(dst_root, dst_path); - strcpy(src_root, src_path); - ftw(src_path, copy_file, 20); -} -#endif - #ifdef WIN32 char* GetExtractionLogPath(const char* game_name, char* data_path) {