Enforce backslash at the end of emulated drives paths

This commit is contained in:
Eladash 2021-04-10 08:06:40 +03:00 committed by Ivan
parent 11824b3916
commit 56d34e0e80
5 changed files with 62 additions and 33 deletions

View File

@ -396,25 +396,28 @@ void fmt::raw_append(std::string& out, const char* fmt, const fmt_type_info* sup
cfmt_append(out, fmt, cfmt_src{sup, args});
}
std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to)
std::string fmt::replace_all(std::string_view src, std::string_view from, std::string_view to, usz count)
{
auto pos = src.find(from);
std::string target;
target.reserve(src.size() + to.size());
if (pos == umax)
for (usz i = 0, replaced = 0; i < src.size();)
{
return src;
}
const usz pos = src.find(from, i);
return (pos ? src.substr(0, pos) + to : to) + std::string(src.c_str() + pos + from.length());
}
if (pos == umax || replaced++ >= count)
{
// No match or too many encountered, append the rest of the string as is
target.append(src.substr(i));
break;
}
std::string fmt::replace_all(const std::string& src, const std::string& from, const std::string& to)
{
std::string target = src;
for (auto pos = target.find(from); pos != umax; pos = target.find(from, pos + 1))
{
target = (pos ? target.substr(0, pos) + to : to) + std::string(target.c_str() + pos + from.length());
pos += to.length();
// Append source until the matched string position
target.append(src.substr(i, pos - i));
// Replace string
target.append(to);
i = pos + from.size();
}
return target;

View File

@ -24,8 +24,7 @@ inline void strcpy_trunc(D& dst, const T& src)
namespace fmt
{
std::string replace_first(const std::string& src, const std::string& from, const std::string& to);
std::string replace_all(const std::string& src, const std::string& from, const std::string& to);
std::string replace_all(std::string_view src, std::string_view from, std::string_view to, usz count = -1);
template <usz list_size>
std::string replace_all(std::string src, const std::pair<std::string, std::string> (&list)[list_size])

View File

@ -193,8 +193,8 @@ void Emulator::Init(bool add_only)
// Create directories (can be disabled if necessary)
const std::string emu_dir = GetEmuDir();
const std::string dev_hdd0 = GetHddDir();
const std::string dev_hdd1 = fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", emu_dir);
const std::string dev_usb = fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir);
const std::string dev_hdd1 = g_cfg.vfs.get(g_cfg.vfs.dev_hdd1, emu_dir);
const std::string dev_usb = g_cfg.vfs.get(g_cfg.vfs.dev_usb000, emu_dir);
const std::string dev_flsh = g_cfg.vfs.get_dev_flash();
auto make_path_verbose = [](const std::string& path)
@ -846,12 +846,12 @@ std::string Emulator::GetEmuDir()
std::string Emulator::GetHddDir()
{
return fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", GetEmuDir());
return g_cfg.vfs.get(g_cfg.vfs.dev_hdd0, GetEmuDir());
}
std::string Emulator::GetHdd1Dir()
{
return fmt::replace_all(g_cfg.vfs.dev_hdd1, "$(EmulatorDir)", GetEmuDir());
return g_cfg.vfs.get(g_cfg.vfs.dev_hdd1, GetEmuDir());
}
std::string Emulator::GetCacheDir()
@ -1158,15 +1158,14 @@ game_boot_result Emulator::Load(const std::string& title_id, bool add_only, bool
// Mount all devices
const std::string emu_dir = GetEmuDir();
const std::string home_dir = g_cfg.vfs.app_home;
std::string bdvd_dir = g_cfg.vfs.dev_bdvd;
// Mount default relative path to non-existent directory
vfs::mount("/dev_hdd0", fmt::replace_all(g_cfg.vfs.dev_hdd0, "$(EmulatorDir)", emu_dir));
vfs::mount("/dev_hdd0", g_cfg.vfs.get(g_cfg.vfs.dev_hdd0, emu_dir));
vfs::mount("/dev_flash", g_cfg.vfs.get_dev_flash());
vfs::mount("/dev_usb", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir));
vfs::mount("/dev_usb000", fmt::replace_all(g_cfg.vfs.dev_usb000, "$(EmulatorDir)", emu_dir));
vfs::mount("/app_home", home_dir.empty() ? elf_dir + '/' : fmt::replace_all(home_dir, "$(EmulatorDir)", emu_dir));
vfs::mount("/dev_usb", g_cfg.vfs.get(g_cfg.vfs.dev_usb000, emu_dir));
vfs::mount("/dev_usb000", g_cfg.vfs.get(g_cfg.vfs.dev_usb000, emu_dir));
vfs::mount("/app_home", g_cfg.vfs.app_home.to_string().empty() ? elf_dir + '/' : g_cfg.vfs.get(g_cfg.vfs.app_home, emu_dir));
if (!hdd1.empty())
{

View File

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "system_config.h"
#include "Utilities/StrUtil.h"
#include "Utilities/StrFmt.h"
#include "util/sysinfo.hpp"
@ -11,16 +12,43 @@ bool cfg_root::node_core::has_rtm() const
return utils::has_rtm();
}
std::string cfg_root::node_vfs::get(const cfg::string& _cfg, const char* _def) const
std::string cfg_root::node_vfs::get(const cfg::string& _cfg, std::string_view emu_dir) const
{
auto [spath, sshared] = _cfg.get();
std::string _emu_dir; // Storage only
if (spath.empty())
if (emu_dir.empty())
{
return fs::get_config_dir() + _def;
// Optimization if provided arg
_emu_dir = emulator_dir;
if (_emu_dir.empty())
{
_emu_dir = fs::get_config_dir() + '/';
}
// Check if path does not end with a delimiter
else if (_emu_dir.back() != fs::delim[0] && _emu_dir.back() != fs::delim[1])
{
_emu_dir += '/';
}
emu_dir = _emu_dir;
}
auto [semudir, sshared2] = emulator_dir.get();
std::string path = _cfg.to_string();
return fmt::replace_all(spath, "$(EmulatorDir)", semudir.empty() ? fs::get_config_dir() : semudir);
if (path.empty())
{
// Fallback
path = _cfg.def;
}
path = fmt::replace_all(path, "$(EmulatorDir)", emu_dir);
// Check if path does not end with a delimiter
if (path.back() != fs::delim[0] && path.back() != fs::delim[1])
{
path += '/';
}
return path;
}

View File

@ -80,7 +80,7 @@ struct cfg_root : cfg::node
{
node_vfs(cfg::node* _this) : cfg::node(_this, "VFS") {}
std::string get(const cfg::string&, const char*) const;
std::string get(const cfg::string&, std::string_view emu_dir = {}) const;
cfg::string emulator_dir{ this, "$(EmulatorDir)" }; // Default (empty): taken from fs::get_config_dir()
cfg::string dev_hdd0{ this, "/dev_hdd0/", "$(EmulatorDir)dev_hdd0/" };
@ -92,7 +92,7 @@ struct cfg_root : cfg::node
std::string get_dev_flash() const
{
return get(dev_flash, "dev_flash/");
return get(dev_flash);
}
cfg::_bool host_root{ this, "Enable /host_root/" };