29 #ifndef STRATAGUS_GAMEUTILS_H
30 #define STRATAGUS_GAMEUTILS_H
32 void error(
const char *title,
const char *text);
34 void copy_dir(
const char *source_folder,
const char *target_folder);
40 #if ( defined (_MSC_VER) || defined (_WIN32) || defined (_WIN64) ) && ! defined (WIN32)
44 #ifndef _CRT_SECURE_NO_DEPRECATE
45 #define _CRT_SECURE_NO_DEPRECATE
47 #ifndef _CRT_SECURE_NO_WARNINGS
48 #define _CRT_SECURE_NO_WARNINGS
54 #define NTDDI_VERSION 0x05010200
55 #define _WIN32_WINNT 0x0501
59 #define PATH_MAX MAX_PATH
63 #pragma comment(lib, "comdlg32.lib")
64 #pragma comment(lib, "ole32.lib")
65 #pragma comment(lib, "Shlwapi.lib")
67 #define mkdir(f, m) _mkdir(f)
69 #define parentdir(x) PathRemoveFileSpec(x); if (x[strlen(x) - 1] == '\\') x[strlen(x) - 1] = '\0'
72 #define parentdir(x) strcpy(x, dirname(x))
74 #define parentdir(x) dirname(x)
96 #include <sys/types.h>
103 #if __has_include(<filesystem>)
104 #include <filesystem>
105 namespace fs = std::filesystem;
106 #elif __has_include(<experimental/filesystem>)
107 #include <experimental/filesystem>
108 namespace fs = std::experimental::filesystem;
110 error "Missing the <filesystem> header."
116 #define BUFF_SIZE MAX_PATH
118 #define BUFF_SIZE 4096
121 void error(
const char *title,
const char *text)
129 fs::create_directories(path);
133 fs::create_directories(path);
136 void copy_dir(fs::path source_folder, fs::path target_folder)
138 if (fs::exists(target_folder)) {
139 if (fs::equivalent(source_folder, target_folder)) {
143 fs::remove_all(target_folder);
146 fs::create_directories(target_folder.parent_path());
149 fs::copy(source_folder, target_folder, fs::copy_options::recursive | fs::copy_options::overwrite_existing);
155 static char *marker = (
char *)calloc(MAX_PATH,
sizeof(
char));
156 if (marker[0] !=
'\0') {
159 char logname[MAX_PATH];
160 strcpy(logname, game_name);
161 strcat(logname,
"-extraction.log");
162 if (PathCombineA(marker, data_path,
"portable-install")) {
163 if (PathFileExistsA(marker)) {
164 PathCombineA(marker, data_path, logname);
168 SHGetFolderPathA(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, marker);
169 PathAppendA(marker,
"Stratagus");
171 PathAppendA(marker, logname);
177 static wchar_t *marker = (
wchar_t *)calloc(MAX_PATH,
sizeof(
wchar_t));
178 if (marker[0] !=
'\0') {
181 wchar_t logname[MAX_PATH];
182 wcscpy(logname, game_name);
183 wcscat(logname, L
"-extraction.log");
184 if (PathCombineW(marker, data_path, L
"portable-install")) {
185 if (PathFileExistsW(marker)) {
186 PathCombineW(marker, data_path, logname);
190 SHGetFolderPathW(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL, 0, marker);
191 PathAppendW(marker, L
"Stratagus");
193 PathAppendW(marker, logname);
228 void ArgvQuote(
const std::wstring &Argument, std::wstring &CommandLine,
bool Force)
235 if (Force ==
false && Argument.empty() ==
false && Argument.find_first_of(L
" \t\n\v\"") == Argument.npos) {
236 CommandLine.append(Argument);
238 CommandLine.push_back(L
'"');
240 for (
auto It = Argument.begin(); ; ++It) {
241 unsigned NumberBackslashes = 0;
243 while (It != Argument.end() && *It == L
'\\') {
248 if (It == Argument.end()) {
254 CommandLine.append(NumberBackslashes * 2, L
'\\');
256 }
else if (*It == L
'"') {
261 CommandLine.append(NumberBackslashes * 2 + 1, L
'\\');
262 CommandLine.push_back(*It);
267 CommandLine.append(NumberBackslashes, L
'\\');
268 CommandLine.push_back(*It);
271 CommandLine.push_back(L
'"');
275 int runCommand(std::wstring &file, std::vector<std::wstring> argv,
bool echo =
false, std::wstring *outputCommandline = NULL)
277 std::wstring cmdline;
278 std::wstring executable;
282 for (
size_t i = 0; i < argv.size(); i++) {
283 std::wstring arg = argv[i];
285 if (i + 1 < argv.size()) {
286 cmdline.push_back(L
' ');
289 std::wstring cmdcmdline;
290 for (
auto c : cmdline) {
291 if (c == L
'(' || c == L
')' || c == L
'%' || c == L
'!' || c == L
'^' || c == L
'"' || c == L
'<' || c == L
'>' || c == L
'&' || c == L
'|') {
292 cmdcmdline.push_back(L
'^');
294 cmdcmdline.push_back(c);
297 if (argv.size() > 0) {
298 cmdcmdline = std::wstring(L
"@") + executable + std::wstring(L
" ") + cmdcmdline;
300 cmdcmdline = std::wstring(L
"@") + executable;
303 if (outputCommandline != NULL) {
304 outputCommandline->append(cmdcmdline);
307 std::wcout << executable << L
' ' << cmdline << L
'\n';
308 std::wcout << cmdcmdline << L
'\n';
311 int code = _wsystem(cmdcmdline.c_str());
313 std::wcout << _wcserror(errno) << L
'\n';
318 #include <sys/types.h>
320 #include <sys/wait.h>
322 int runCommand(
const char *file,
char *
const argv[],
bool echo =
false, std::string *outputCommandline = NULL)
326 if (echo || outputCommandline) {
327 std::string commandline = file;
328 for (
int i = 0; ; i++) {
329 if (argv[i] == NULL) {
333 commandline += argv[i];
336 std::cout << commandline << std::endl;
338 if (outputCommandline) {
339 outputCommandline->append(commandline);
345 exit(execvp(file, argv));
348 waitpid(pid, &status, 0);
349 if (WIFEXITED(status)) {
350 return WEXITSTATUS(status);