mirror of
https://github.com/mon/ifs_layeredfs.git
synced 2026-08-20 07:34:38 -05:00
Fix non-portable argc/argv
This commit is contained in:
23
meson.build
23
meson.build
@@ -1,10 +1,11 @@
|
||||
project('layeredfs', 'c', 'cpp', version: '3.9',
|
||||
project('layeredfs', 'c', 'cpp', version: '3.10',
|
||||
default_options: [
|
||||
'cpp_std=c++20',
|
||||
'buildtype=release',
|
||||
'strip=true',
|
||||
'werror=true',
|
||||
]
|
||||
],
|
||||
meson_version: '>=1.2.0',
|
||||
)
|
||||
|
||||
add_project_link_arguments('-static', language: 'cpp')
|
||||
@@ -204,3 +205,21 @@ test('unit tests', executable('tests_bin',
|
||||
),
|
||||
workdir: meson.current_source_dir(),
|
||||
)
|
||||
|
||||
test('commandline parsing test', executable('test_commandline',
|
||||
sources: 'src/test_commandline.cpp',
|
||||
link_with: [layeredfs_lib, texbin_lib, avs_standalone_lib],
|
||||
dependencies: [layeredfs_cfg_dep, gtest_main_dep, gmock_dep],
|
||||
build_by_default: false,
|
||||
),
|
||||
workdir: meson.current_source_dir(),
|
||||
args: [
|
||||
'--layered-disable',
|
||||
'--layered-verbose',
|
||||
'--layered-devmode',
|
||||
'--layered-allowlist=allowed,these folders',
|
||||
'--layered-blocklist=blocked,these folders',
|
||||
'--layered-logfile=some logfile.log',
|
||||
'--layered-data-mods-folder=./some modfolder',
|
||||
]
|
||||
)
|
||||
|
||||
@@ -67,39 +67,55 @@ void load_config(void) {
|
||||
config.logfile = NULL;
|
||||
#endif
|
||||
|
||||
int i;
|
||||
int argc;
|
||||
auto argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
if (!argv) {
|
||||
log_warning("Couldn't fetch commandline args!");
|
||||
return;
|
||||
}
|
||||
|
||||
char* arg;
|
||||
|
||||
// so close to just pulling in a third party argparsing lib...
|
||||
for (i = 0; i < __argc; i++) {
|
||||
if (strcmp(__argv[i], VERBOSE_FLAG) == 0) {
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (!wstr_narrow(argv[i], &arg))
|
||||
continue;
|
||||
|
||||
if (strcmp(arg, VERBOSE_FLAG) == 0) {
|
||||
config.verbose_logs = true;
|
||||
free(arg);
|
||||
}
|
||||
else if (strcmp(__argv[i], DEVMODE_FLAG) == 0) {
|
||||
else if (strcmp(arg, DEVMODE_FLAG) == 0) {
|
||||
config.developer_mode = true;
|
||||
free(arg);
|
||||
}
|
||||
else if (strcmp(__argv[i], DISABLE_FLAG) == 0) {
|
||||
else if (strcmp(arg, DISABLE_FLAG) == 0) {
|
||||
config.disable = true;
|
||||
free(arg);
|
||||
}
|
||||
else if (strncmp(__argv[i], ALLOWLIST_FLAG, strlen(ALLOWLIST_FLAG)) == 0) {
|
||||
allowlist = parse_list(ALLOWLIST_FLAG, __argv[i], config.allowlist);
|
||||
else if (strncmp(arg, ALLOWLIST_FLAG, strlen(ALLOWLIST_FLAG)) == 0) {
|
||||
allowlist = parse_list(ALLOWLIST_FLAG, arg, config.allowlist);
|
||||
}
|
||||
else if (strncmp(__argv[i], BLOCKLIST_FLAG, strlen(BLOCKLIST_FLAG)) == 0) {
|
||||
blocklist = parse_list(BLOCKLIST_FLAG, __argv[i], config.blocklist);
|
||||
else if (strncmp(arg, BLOCKLIST_FLAG, strlen(BLOCKLIST_FLAG)) == 0) {
|
||||
blocklist = parse_list(BLOCKLIST_FLAG, arg, config.blocklist);
|
||||
}
|
||||
else if (strncmp(__argv[i], LOGFILE_FLAG, strlen(LOGFILE_FLAG)) == 0) {
|
||||
const char *path = &__argv[i][strlen(LOGFILE_FLAG)];
|
||||
else if (strncmp(arg, LOGFILE_FLAG, strlen(LOGFILE_FLAG)) == 0) {
|
||||
const char *path = &arg[strlen(LOGFILE_FLAG)];
|
||||
// correct format: --layered-logfile=whatever.log
|
||||
if(path[0] == '=' && path[1]) {
|
||||
config.logfile = &path[1];
|
||||
}
|
||||
}
|
||||
else if (strncmp(__argv[i], MOD_FOLDER_FLAG, strlen(MOD_FOLDER_FLAG)) == 0) {
|
||||
std::string_view path = &__argv[i][strlen(MOD_FOLDER_FLAG)];
|
||||
else if (strncmp(arg, MOD_FOLDER_FLAG, strlen(MOD_FOLDER_FLAG)) == 0) {
|
||||
std::string_view path = &arg[strlen(MOD_FOLDER_FLAG)];
|
||||
// correct format: --layered-data-mods-folder=./my_mods
|
||||
if(path.starts_with("=./")) {
|
||||
config.mod_folder = path.substr(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
free(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
src/test_commandline.cpp
Normal file
20
src/test_commandline.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#include <sstream>
|
||||
#include <gtest/gtest.h>
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "avs_standalone.hpp"
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(Cmdline, ConfigParsingWorks) {
|
||||
load_config();
|
||||
|
||||
EXPECT_EQ(config.verbose_logs, 1);
|
||||
EXPECT_EQ(config.developer_mode, 1);
|
||||
EXPECT_EQ(config.disable, 1);
|
||||
EXPECT_STREQ(config.logfile, "some logfile.log");
|
||||
EXPECT_THAT(config.allowlist, ElementsAre("allowed", "these folders"));
|
||||
EXPECT_THAT(config.blocklist, ElementsAre("blocked", "these folders"));
|
||||
EXPECT_EQ(config.mod_folder, "./some modfolder");
|
||||
}
|
||||
@@ -99,6 +99,33 @@ wchar_t *str_widen(const char *src)
|
||||
return result;
|
||||
}
|
||||
|
||||
bool wstr_narrow(const wchar_t *src, char **dest)
|
||||
{
|
||||
int nbytes;
|
||||
|
||||
nbytes = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
if (nbytes <= 0) {
|
||||
goto size_fail;
|
||||
}
|
||||
|
||||
*dest = (char*)malloc(nbytes);
|
||||
|
||||
if (WideCharToMultiByte(CP_ACP, 0, src, -1, *dest, nbytes, NULL, NULL) !=
|
||||
nbytes) {
|
||||
goto conv_fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
conv_fail:
|
||||
free(*dest);
|
||||
*dest = NULL;
|
||||
|
||||
size_fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool file_exists(const char* name) {
|
||||
// file_exists is only used by the modfile machinery, so use the easy
|
||||
// method, not avs_fs_open or avs_fs_lstat
|
||||
|
||||
@@ -21,6 +21,7 @@ bool string_replace_first(std::string &str, const char* from, const char* to);
|
||||
// Like string.find(), but case insensitive
|
||||
std::size_t string_find_icase(const std::string & strHaystack, const std::string & strNeedle, std::size_t off = 0);
|
||||
wchar_t *str_widen(const char *src);
|
||||
bool wstr_narrow(const wchar_t *src, char **dest);
|
||||
void str_toupper_inline(std::string &str);
|
||||
bool file_exists(const char* name);
|
||||
bool folder_exists(const char* name);
|
||||
|
||||
BIN
xp_dlls/shell32.dll
Normal file
BIN
xp_dlls/shell32.dll
Normal file
Binary file not shown.
Reference in New Issue
Block a user