mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
BASE: Rework path parsing on command line
Make a macro to unify processing. Use the new Path helper to handle WIN32 and save to settings using the toConfig helper. This makes sure the path is properly encoded and will not be improperly decoded later.
This commit is contained in:
1 parent
f675e643b8
commit
c1b4dfad77
1 file changed
+35
-59
+35
-59
@@ -486,9 +486,7 @@ static Common::String createTemporaryTarget(const Common::String &engineId, cons
|
||||
* Note 2: The method will work with paths that are symbolic links to folders (isDirectory() returns true),
|
||||
* but for symbolic links to files it will not deduce a valid folder path and will just return false.
|
||||
*
|
||||
* @param settings A reference to the settings map used by parseCommandLine()
|
||||
* @param optionKeyStr The key string for updating the value for this path option on the settings map, if needed
|
||||
* @param path The path node that was created from the command line value for this path option
|
||||
* @param node The filesystem node created from the command line value and modified if needed to get a folder from a file
|
||||
* @param ensureWriteable A boolean flag that is set true if the path should be writeable, false otherwise
|
||||
* @param ensureReadable A boolean flag that is set true if the path should be readable, false otherwise
|
||||
* @param acceptFile true if the command line option allows (tolerates) a file path to deduce the folder path from
|
||||
@@ -496,22 +494,19 @@ static Common::String createTemporaryTarget(const Common::String &engineId, cons
|
||||
* was deduced from it, and the path (original or deduced respectively) meets the specified
|
||||
* readability / writeability requirements.
|
||||
*/
|
||||
bool ensureAccessibleDirectoryForPathOption(Common::StringMap &settings,
|
||||
const Common::String optionKeyStr,
|
||||
const Common::FSNode &path,
|
||||
bool ensureAccessibleDirectoryForPathOption(Common::FSNode &node,
|
||||
bool ensureWriteable,
|
||||
bool ensureReadable,
|
||||
bool acceptFile) {
|
||||
if (path.isDirectory()) {
|
||||
if ((!ensureWriteable || path.isWritable())
|
||||
&& (!ensureReadable || path.isReadable())
|
||||
if (node.isDirectory()) {
|
||||
if ((!ensureWriteable || node.isWritable())
|
||||
&& (!ensureReadable || node.isReadable())
|
||||
&& (ensureWriteable || ensureReadable)) {
|
||||
return true;
|
||||
}
|
||||
} else if (acceptFile
|
||||
&& ensureAccessibleDirectoryForPathOption(settings, optionKeyStr, path.getParent(), ensureWriteable, ensureReadable, false)) {
|
||||
settings[optionKeyStr] = path.getParent().getPath().toString(Common::Path::kNativeSeparator);
|
||||
return true;
|
||||
} else if (acceptFile) {
|
||||
node = node.getParent();
|
||||
return ensureAccessibleDirectoryForPathOption(node, ensureWriteable, ensureReadable, false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -564,6 +559,22 @@ bool ensureAccessibleDirectoryForPathOption(Common::StringMap &settings,
|
||||
const char *option = boolValue ? "true" : "false"; \
|
||||
settings[longCmd] = option;
|
||||
|
||||
#define DO_OPTION_PATH(shortCmd, longCmd) \
|
||||
DO_OPTION(shortCmd, longCmd) \
|
||||
Common::FSNode node(Common::Path::fromCommandLine(option)); \
|
||||
if (!node.exists()) { \
|
||||
usage("Non-existent path '%s' for option %s%c%s", option, \
|
||||
isLongCmd ? "--" : "-", \
|
||||
isLongCmd ? longCmd[0] : shortCmd, \
|
||||
isLongCmd ? longCmd + 1 : ""); \
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(node, false, true, true)) { \
|
||||
usage("Non-readable path '%s' for option %s%c%s", option, \
|
||||
isLongCmd ? "--" : "-", \
|
||||
isLongCmd ? longCmd[0] : shortCmd, \
|
||||
isLongCmd ? longCmd + 1 : ""); \
|
||||
} \
|
||||
settings[longCmd] = node.getPath().toConfig();
|
||||
|
||||
// Use this for options which never have a value, i.e. for 'commands', like "--help".
|
||||
#define DO_COMMAND(shortCmd, longCmd) \
|
||||
if (isLongCmd ? (!strcmp(s + 2, longCmd)) : (tolower(s[1]) == shortCmd)) { \
|
||||
@@ -579,6 +590,7 @@ bool ensureAccessibleDirectoryForPathOption(Common::StringMap &settings,
|
||||
#define DO_LONG_OPTION(longCmd) DO_OPTION(0, longCmd)
|
||||
#define DO_LONG_OPTION_INT(longCmd) DO_OPTION_INT(0, longCmd)
|
||||
#define DO_LONG_OPTION_BOOL(longCmd) DO_OPTION_BOOL(0, longCmd)
|
||||
#define DO_LONG_OPTION_PATH(longCmd) DO_OPTION_PATH(0, longCmd)
|
||||
#define DO_LONG_COMMAND(longCmd) DO_COMMAND(0, longCmd)
|
||||
|
||||
// End an option handler
|
||||
@@ -712,13 +724,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||
DO_OPTION('l', "logfile")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("screenshotpath")
|
||||
Common::FSNode path(option);
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent screenshot path '%s'", option);
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(settings, "screenshotpath", path, true, false, true)) {
|
||||
usage("Non-writable screenshot path '%s'", option);
|
||||
}
|
||||
DO_LONG_OPTION_PATH("screenshotpath")
|
||||
END_OPTION
|
||||
#endif
|
||||
|
||||
@@ -812,13 +818,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||
DO_OPTION_BOOL('n', "subtitles")
|
||||
END_OPTION
|
||||
|
||||
DO_OPTION('p', "path")
|
||||
Common::FSNode path(option);
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent game path '%s'", option);
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(settings, "path", path, false, true, true)) {
|
||||
usage("Non-readable game path '%s'", option);
|
||||
}
|
||||
DO_OPTION_PATH('p', "path")
|
||||
END_OPTION
|
||||
|
||||
DO_OPTION('q', "language")
|
||||
@@ -856,7 +856,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("soundfont")
|
||||
Common::FSNode path(option);
|
||||
Common::FSNode path(Common::Path::fromConfig(option));
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent soundfont path '%s'", option);
|
||||
} else if (!path.isReadable()) {
|
||||
@@ -908,31 +908,13 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||
DO_LONG_OPTION_BOOL("show-fps")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("savepath")
|
||||
Common::FSNode path(option);
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent saved games path '%s'", option);
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(settings, "savepath", path, true, true, true)) {
|
||||
usage("Non-writable saved games path '%s'", option);
|
||||
}
|
||||
DO_LONG_OPTION_PATH("savepath")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("extrapath")
|
||||
Common::FSNode path(option);
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent extra path '%s'", option);
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(settings, "extrapath", path, false, true, true)) {
|
||||
usage("Non-readable extra path '%s'", option);
|
||||
}
|
||||
DO_LONG_OPTION_PATH("extrapath")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("iconspath")
|
||||
Common::FSNode path(option);
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent icons path '%s'", option);
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(settings, "iconspath", path, true, true, true)) {
|
||||
usage("Non-readable icons path '%s'", option);
|
||||
}
|
||||
DO_LONG_OPTION_PATH("iconspath")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("md5-path")
|
||||
@@ -967,13 +949,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||
DO_LONG_OPTION_BOOL("exit")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_OPTION("themepath")
|
||||
Common::FSNode path(option);
|
||||
if (!path.exists()) {
|
||||
usage("Non-existent theme path '%s'", option);
|
||||
} else if (!ensureAccessibleDirectoryForPathOption(settings, "themepath", path, false, true, true)) {
|
||||
usage("Non-readable theme path '%s'", option);
|
||||
}
|
||||
DO_LONG_OPTION_PATH("themepath")
|
||||
END_OPTION
|
||||
|
||||
DO_LONG_COMMAND("list-themes")
|
||||
@@ -2011,7 +1987,7 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
|
||||
// From an UX point of view, however, it might get confusing.
|
||||
// Consider removing this if consensus says otherwise.
|
||||
} else {
|
||||
Common::Path path(settings["path"], Common::Path::kNativeSeparator);
|
||||
Common::Path path(Common::Path::fromConfig(settings["path"]));
|
||||
command = detectGames(path, gameOption.engineId, gameOption.gameId, resursive);
|
||||
if (command.empty()) {
|
||||
err = Common::kNoGameDataFoundError;
|
||||
@@ -2019,11 +1995,11 @@ bool processSettings(Common::String &command, Common::StringMap &settings, Commo
|
||||
}
|
||||
}
|
||||
} else if (command == "detect") {
|
||||
Common::Path path(settings["path"], Common::Path::kNativeSeparator);
|
||||
Common::Path path(Common::Path::fromConfig(settings["path"]));
|
||||
detectGames(path, gameOption.engineId, gameOption.gameId, settings["recursive"] == "true");
|
||||
return cmdDoExit;
|
||||
} else if (command == "add") {
|
||||
Common::Path path(settings["path"], Common::Path::kNativeSeparator);
|
||||
Common::Path path(Common::Path::fromConfig(settings["path"]));
|
||||
addGames(path, gameOption.engineId, gameOption.gameId, settings["recursive"] == "true");
|
||||
return cmdDoExit;
|
||||
} else if (command == "md5" || command == "md5mac") {
|
||||
|
||||
Reference in new issue
Block a user