Make userdata path setting code easier to read (#8833)

Partially in preparation for #8059 and also removes one use of _X11 for #8806
This commit is contained in:
Pentarctagon 2024-05-04 13:11:28 -05:00 committed by GitHub
parent f43e977263
commit d2b0df9967
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -646,9 +646,9 @@ static void setup_user_data_dir()
}
#ifdef _WIN32
// As a convenience for portable installs on Windows, relative paths with . or
// .. as the first component are considered relative to the current workdir
// instead of Documents/My Games.
// A convenience for portable installs on Windows.
// relative paths with . or .. as the first component are considered relative to the current workdir instead of Documents/My Games.
// Only provided for Windows since portable installs on other systems are not particularly relevant or supported.
static bool is_path_relative_to_cwd(const std::string& str)
{
const bfs::path p(str);
@ -659,37 +659,35 @@ static bool is_path_relative_to_cwd(const std::string& str)
return *p.begin() == "." || *p.begin() == "..";
}
#endif
void set_user_data_dir(std::string newprefdir)
bfs::path windows_userdata(const std::string& newprefdir)
{
[[maybe_unused]] bool relative_ok = false;
bfs::path dir;
std::string temp = newprefdir;
#ifdef PREFERENCES_DIR
if(newprefdir.empty()) {
newprefdir = PREFERENCES_DIR;
relative_ok = true;
}
#elif defined(__APPLE__)
if(newprefdir.empty()) {
newprefdir = "Library/Application Support/Wesnoth_"+get_version_path_suffix();
relative_ok = true;
if(temp.empty()) {
temp = PREFERENCES_DIR;
}
#endif
#ifdef _WIN32
if(newprefdir.size() > 2 && newprefdir[1] == ':') {
// if a custom userdata directory is provided as an absolute path, just use that
// else if it's relative to the current working directory, just use that
// else if no custom userdata directory was provided, default to the "My Games" folder if present or fallback to the current working directory if not
// else a relative path was provided
if(temp.size() > 2 && temp[1] == ':') {
// allow absolute path override
user_data_dir = newprefdir;
} else if(is_path_relative_to_cwd(newprefdir)) {
dir = temp;
} else if(is_path_relative_to_cwd(temp)) {
// Custom directory relative to workdir (for portable installs, etc.)
user_data_dir = get_cwd() + "/" + newprefdir;
dir = get_cwd() + "/" + temp;
} else {
if(newprefdir.empty()) {
newprefdir = "Wesnoth" + get_version_path_suffix();
if(temp.empty()) {
temp = "Wesnoth" + get_version_path_suffix();
} else {
// only warn about a relative path if it comes from the command line option, not from the PREFERENCES_DIR define
#ifdef PREFERENCES_DIR
if (newprefdir != PREFERENCES_DIR)
if (temp != PREFERENCES_DIR)
#endif
{
// TRANSLATORS: translate the part inside <...> only
@ -710,89 +708,136 @@ void set_user_data_dir(std::string newprefdir)
ERR_FS << "Could not determine path to user's Documents folder! (" << std::hex << "0x" << res << std::dec << ") "
<< "User config/data directories may be unavailable for "
<< "this session. Please report this as a bug.";
user_data_dir = bfs::path(get_cwd()) / newprefdir;
dir = bfs::path(get_cwd()) / temp;
} else {
bfs::path games_path = bfs::path(docs_path) / "My Games";
create_directory_if_missing(games_path);
user_data_dir = games_path / newprefdir;
dir = games_path / temp;
}
CoTaskMemFree(docs_path);
}
#else /*_WIN32*/
std::string backupprefdir = ".wesnoth" + get_version_path_suffix();
#ifdef WESNOTH_BOOST_OS_IOS
char *sdl_pref_path = SDL_GetPrefPath("wesnoth.org", "iWesnoth");
if(sdl_pref_path) {
backupprefdir = std::string(sdl_pref_path) + backupprefdir;
SDL_free(sdl_pref_path);
}
#endif
#ifdef _X11
return dir;
}
#elif defined(__APPLE__) || defined(WESNOTH_BOOST_OS_IOS)
bfs::path apple_userdata(const std::string& newprefdir)
{
bfs::path dir;
std::string temp = newprefdir;
const char* home_str = getenv("HOME");
if(newprefdir.empty()) {
char const* xdg_data = getenv("XDG_DATA_HOME");
if(!xdg_data || xdg_data[0] == '\0') {
if(!home_str) {
newprefdir = backupprefdir;
goto other;
}
user_data_dir = home_str;
user_data_dir /= ".local/share";
} else {
user_data_dir = xdg_data;
// if a custom userdata was not specified
// use the PREFERENCES_DIR if defined
// else if this is iOS, use the SDL pref path
// else use a default - this is currently the "unsandboxed" location from migrate_apple_config_directory_for_unsandboxed_builds() above
if(temp.empty()) {
#ifdef PREFERENCES_DIR
temp = PREFERENCES_DIR;
if(home_str && temp[0] == '~') {
temp = home_str + temp.substr(1);
}
user_data_dir /= "wesnoth";
user_data_dir /= get_version_path_suffix();
} else {
other:
bfs::path home = home_str ? home_str : ".";
if(newprefdir[0] == '/') {
user_data_dir = newprefdir;
} else {
if(!relative_ok) {
// TRANSLATORS: translate the part inside <...> only
deprecated_message(_("--userdata-dir=<relative path>"),
DEP_LEVEL::FOR_REMOVAL,
{1, 17, 0},
_("Use absolute paths. Relative paths are deprecated because they are interpreted relative to $HOME"));
}
user_data_dir = home / newprefdir;
#elif defined(WESNOTH_BOOST_OS_IOS)
char *sdl_pref_path = SDL_GetPrefPath("wesnoth.org", "iWesnoth");
if(sdl_pref_path) {
temp = std::string(sdl_pref_path) + ".wesnoth" + get_version_path_suffix();
SDL_free(sdl_pref_path);
}
}
#else
if(newprefdir.empty()) {
newprefdir = backupprefdir;
relative_ok = true;
temp = "Library/Application Support/Wesnoth_"+get_version_path_suffix();
#endif
} else if(temp[0] != '/') {
// TRANSLATORS: translate the part inside <...> only
deprecated_message(_("--userdata-dir=<relative path>"),
DEP_LEVEL::FOR_REMOVAL,
{1, 17, 0},
_("Use absolute paths. Relative paths are deprecated because they are interpreted relative to $HOME"));
}
const char* home_str = getenv("HOME");
bfs::path home = home_str ? home_str : ".";
if(newprefdir[0] == '/') {
user_data_dir = newprefdir;
// if it's an absolute path, just use that
// else make it relative to HOME if HOME is populated, otherwise make it relative to the current working directory
if(temp[0] == '/') {
dir = temp;
} else {
if(!relative_ok) {
// TRANSLATORS: translate the part inside <...> only
deprecated_message(_("--userdata-dir=<relative path>"),
DEP_LEVEL::FOR_REMOVAL,
{1, 17, 0},
_("Use absolute paths. Relative paths are deprecated because they are interpreted relative to $HOME"));
bfs::path home = home_str ? home_str : ".";
dir = home / temp;
}
return dir;
}
#else
bfs::path linux_userdata(const std::string& newprefdir)
{
bfs::path dir;
std::string temp = newprefdir;
const char* home_str = getenv("HOME");
char const* xdg_data = getenv("XDG_DATA_HOME");
#ifdef PREFERENCES_DIR
if(temp.empty()) {
temp = PREFERENCES_DIR;
if(home_str && temp[0] == '~') {
temp = home_str + temp.substr(1);
}
user_data_dir = home / newprefdir;
}
#endif
#endif /*_WIN32*/
// if a custom userdata dir is not specified
// and one of the XDG home and regular home env variables are not empty
// then use one of those
if(temp.empty() && ((xdg_data && xdg_data[0] != '\0') || home_str)) {
if(xdg_data && xdg_data[0] != '\0') {
dir = xdg_data;
} else if(home_str) {
dir = home_str;
dir /= ".local/share";
}
dir /= "wesnoth";
dir /= get_version_path_suffix();
return dir;
}
// if a custom userdata dir using an absolute path was specified, just use that
if(!temp.empty() && temp[0] == '/') {
dir = temp;
return dir;
}
// if no custom userdata folder was specified and there's also no XDG/HOME variables available, set a default folder name
if(temp.empty()) {
temp = ".wesnoth" + get_version_path_suffix();
}
// if there is a HOME variable and we've reached this point, then a custom userdata folder using a relative path was provided
// else just use the current working directory for the userdata
if(home_str) {
dir = home_str;
// TRANSLATORS: translate the part inside <...> only
deprecated_message(_("--userdata-dir=<relative path>"),
DEP_LEVEL::FOR_REMOVAL,
{1, 17, 0},
_("Use absolute paths. Relative paths are deprecated because they are interpreted relative to $HOME"));
} else {
dir = ".";
}
dir /= temp;
return dir;
}
#endif
void set_user_data_dir(std::string newprefdir)
{
#ifdef _WIN32
user_data_dir = windows_userdata(newprefdir);
#elif defined(__APPLE__) || defined(WESNOTH_BOOST_OS_IOS)
user_data_dir = apple_userdata(newprefdir);
#else
user_data_dir = linux_userdata(newprefdir);
#endif
setup_user_data_dir();
user_data_dir = normalize_path(user_data_dir.string(), true, true);
}