use std::filesystem in more places
This commit is contained in:
parent
00d7531730
commit
e053a7e53a
2 changed files with 50 additions and 148 deletions
|
@ -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;
|
||||
|
|
|
@ -95,6 +95,9 @@ void copy_dir(const char* source_folder, const char* target_folder);
|
|||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
|
||||
#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 <wchar.h>
|
||||
#include <string>
|
||||
#include <filesystem>
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue