FS: use optional<string> to represent non-existent paths (#9107)

This commit is contained in:
Charles Dang 2024-07-18 09:58:55 -04:00 committed by GitHub
parent 4f40c9deb5
commit e45b46107e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 141 additions and 145 deletions

View file

@ -75,7 +75,7 @@ config get_addon_pbl_info(const std::string& addon_name, bool do_validate)
filesystem::scoped_istream stream = filesystem::istream_file(pbl_path);
std::unique_ptr<schema_validation::schema_validator> validator;
if(do_validate) {
validator = std::make_unique<schema_validation::schema_validator>(filesystem::get_wml_location("schema/pbl.cfg"));
validator = std::make_unique<schema_validation::schema_validator>(filesystem::get_wml_location("schema/pbl.cfg").value());
validator->set_create_exceptions(true);
}
read(cfg, *stream, validator.get());

View file

@ -182,7 +182,7 @@ const config& configuration::get_ai_config_for(const std::string &id)
bool configuration::get_side_config_from_file(const std::string& file, config& cfg ){
try {
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location(file));
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location(file).value());
read(cfg, *stream);
LOG_AI_CONFIGURATION << "Reading AI configuration from file '" << file << "'";
} catch(const config::error &) {

View file

@ -421,13 +421,13 @@ DEFINE_FAI_FUNCTION(run_file, 1, 1)
const std::string filename = var0.string_cast();
//NOTE: get_wml_location also filters file path to ensure it doesn't contain things like "../../top/secret"
std::string path = filesystem::get_wml_location(filename);
if(path.empty()) {
auto path = filesystem::get_wml_location(filename);
if(!path) {
ERR_AI << "run_file : not found [" << filename <<"]";
return variant(); //no suitable file
}
std::string formula_string = filesystem::read_file(path);
std::string formula_string = filesystem::read_file(path.value());
//need to get function_table from somewhere or delegate to someone who has access to it
formula_ptr parsed_formula = ai_.create_optional_formula(formula_string);
if(parsed_formula == formula_ptr()) {

View file

@ -938,10 +938,12 @@ void context_manager::load_map(const std::string& filename, bool new_context)
if(editor_controller::current_addon_id_.empty()) {
// if no addon id has been set and the file being loaded is from an addon
// then use the file path to determine the addon rather than showing a dialog
editor_controller::current_addon_id_ = filesystem::get_addon_id_from_path(filename);
if(editor_controller::current_addon_id_.empty()) {
if(auto addon_at_path = filesystem::get_addon_id_from_path(filename)) {
editor_controller::current_addon_id_ = addon_at_path.value();
} else {
editor_controller::current_addon_id_ = editor::initialize_addon();
}
set_addon_id(editor_controller::current_addon_id_);
}

View file

@ -239,17 +239,17 @@ map_context::map_context(const game_config_view& game_config, const std::string&
const std::string& macro_argument = map_data_loc.substr(2, map_data_loc.size()-4);
LOG_ED << "Map looks like a scenario, trying {" << macro_argument << "}";
std::string new_filename = filesystem::get_wml_location(macro_argument, filesystem::directory_name(filesystem::get_short_wml_path(filename_)));
auto new_filename = filesystem::get_wml_location(macro_argument, filesystem::directory_name(filesystem::get_short_wml_path(filename_)));
if(new_filename.empty()) {
if(!new_filename) {
std::string message = _("The map file looks like a scenario, but the map_data value does not point to an existing file")
+ std::string("\n") + macro_argument;
throw editor_map_load_exception(filename, message);
}
LOG_ED << "New filename is: " << new_filename;
LOG_ED << "New filename is: " << new_filename.value();
filename_ = new_filename;
filename_ = new_filename.value();
file_string = filesystem::read_file(filename_);
map_ = editor_map::from_string(file_string);
pure_map_ = true;

View file

@ -52,7 +52,7 @@ void editor_palette<Item>::expand_palette_groups_menu(std::vector<config>& items
std::string img = item_groups[mci].icon + "_30";
if (mci == active_group_index()) {
std::string pressed_img = img + "-pressed.png";
if(!filesystem::get_binary_file_location("images", pressed_img).empty()) {
if(filesystem::get_binary_file_location("images", pressed_img).has_value()) {
img = pressed_img;
} else {
img += ".png~CS(70,70,0)";

View file

@ -1551,7 +1551,7 @@ const std::vector<std::string>& get_binary_paths(const std::string& type)
return res;
}
std::string get_binary_file_location(const std::string& type, const std::string& filename)
std::optional<std::string> get_binary_file_location(const std::string& type, const std::string& filename)
{
// We define ".." as "remove everything before" this is needed because
// on the one hand allowing ".." would be a security risk but
@ -1567,7 +1567,7 @@ std::string get_binary_file_location(const std::string& type, const std::string&
}
if(!is_legal_file(filename)) {
return std::string();
return std::nullopt;
}
std::string result;
@ -1592,14 +1592,18 @@ std::string get_binary_file_location(const std::string& type, const std::string&
}
}
DBG_FS << " not found";
return result;
if(result.empty()) {
DBG_FS << " not found";
return std::nullopt;
} else {
return result;
}
}
std::string get_binary_dir_location(const std::string& type, const std::string& filename)
std::optional<std::string> get_binary_dir_location(const std::string& type, const std::string& filename)
{
if(!is_legal_file(filename)) {
return std::string();
return std::nullopt;
}
for(const std::string& bp : get_binary_paths(type)) {
@ -1613,13 +1617,13 @@ std::string get_binary_dir_location(const std::string& type, const std::string&
}
DBG_FS << " not found";
return std::string();
return std::nullopt;
}
std::string get_wml_location(const std::string& filename, const std::string& current_dir)
std::optional<std::string> get_wml_location(const std::string& filename, const std::string& current_dir)
{
if(!is_legal_file(filename)) {
return std::string();
return std::nullopt;
}
assert(game_config::path.empty() == false);
@ -1644,12 +1648,11 @@ std::string get_wml_location(const std::string& filename, const std::string& cur
if(result.empty() || !file_exists(result)) {
DBG_FS << " not found";
result.clear();
return std::nullopt;
} else {
DBG_FS << " found: '" << result.string() << "'";
return result.string();
}
return result.string();
}
static bfs::path subtract_path(const bfs::path& full, const bfs::path& prefix)
@ -1688,14 +1691,14 @@ std::string get_short_wml_path(const std::string& filename)
return filename;
}
std::string get_independent_binary_file_path(const std::string& type, const std::string& filename)
std::optional<std::string> get_independent_binary_file_path(const std::string& type, const std::string& filename)
{
bfs::path full_path(get_binary_file_location(type, filename));
if(full_path.empty()) {
return full_path.generic_string();
auto bp = get_binary_file_location(type, filename);
if(!bp) {
return std::nullopt;
}
bfs::path full_path{bp.value()};
bfs::path partial = subtract_path(full_path, get_user_data_path());
if(!partial.empty()) {
return partial.generic_string();
@ -1736,7 +1739,7 @@ std::string sanitize_path(const std::string& path)
// Return path to localized counterpart of the given file, if any, or empty string.
// Localized counterpart may also be requested to have a suffix to base name.
std::string get_localized_path(const std::string& file, const std::string& suff)
std::optional<std::string> get_localized_path(const std::string& file, const std::string& suff)
{
std::string dir = filesystem::directory_name(file);
std::string base = filesystem::base_name(file);
@ -1773,10 +1776,10 @@ std::string get_localized_path(const std::string& file, const std::string& suff)
}
}
return "";
return std::nullopt;
}
std::string get_addon_id_from_path(const std::string& location)
std::optional<std::string> get_addon_id_from_path(const std::string& location)
{
std::string full_path = normalize_path(location, true);
std::string addons_path = normalize_path(get_addons_dir(), true);
@ -1788,7 +1791,7 @@ std::string get_addon_id_from_path(const std::string& location)
}
}
return "";
return std::nullopt;
}
} // namespace filesystem

View file

@ -24,6 +24,7 @@
#include <fstream>
#include <iosfwd>
#include <memory>
#include <optional>
#include <string>
#include <vector>
@ -454,22 +455,19 @@ void clear_binary_paths_cache();
NOT_DANGLING const std::vector<std::string>& get_binary_paths(const std::string& type);
/**
* Returns a complete path to the actual file of a given @a type
* or an empty string if the file isn't present.
* Returns a complete path to the actual file of a given @a type, if it exists.
*/
std::string get_binary_file_location(const std::string& type, const std::string& filename);
std::optional<std::string> get_binary_file_location(const std::string& type, const std::string& filename);
/**
* Returns a complete path to the actual directory of a given @a type
* or an empty string if the directory isn't present.
* Returns a complete path to the actual directory of a given @a type, if it exists.
*/
std::string get_binary_dir_location(const std::string &type, const std::string &filename);
std::optional<std::string> get_binary_dir_location(const std::string &type, const std::string &filename);
/**
* Returns a complete path to the actual WML file or directory
* or an empty string if the file isn't present.
* Returns a complete path to the actual WML file or directory, if either exists.
*/
std::string get_wml_location(const std::string &filename,
std::optional<std::string> get_wml_location(const std::string &filename,
const std::string &current_dir = std::string());
/**
@ -484,7 +482,7 @@ std::string get_short_wml_path(const std::string &filename);
* images, units/konrad-fighter.png ->
* data/campaigns/Heir_To_The_Throne/images/units/konrad-fighter.png
*/
std::string get_independent_binary_file_path(const std::string& type, const std::string &filename);
std::optional<std::string> get_independent_binary_file_path(const std::string& type, const std::string &filename);
/**
* Returns the appropriate invocation for a Wesnoth-related binary, assuming
@ -498,12 +496,12 @@ std::string get_program_invocation(const std::string &program_name);
/**
* Returns the localized version of the given filename, if it exists.
*/
std::string get_localized_path(const std::string& file, const std::string& suff = "");
std::optional<std::string> get_localized_path(const std::string& file, const std::string& suff = "");
/**
* Returns the add-on ID from a path.
* aka the directory directly following the "add-ons" folder, or an empty string if none is found.
*/
std::string get_addon_id_from_path(const std::string& location);
std::optional<std::string> get_addon_id_from_path(const std::string& location);
}

View file

@ -268,13 +268,13 @@ bool ends_with(const std::string& str, const std::string& suffix)
std::string read_map(const std::string& name)
{
std::string res;
std::string map_location = get_wml_location(name);
if(map_location.empty()) {
auto map_location = get_wml_location(name);
if(!map_location) {
// Consult [binary_path] for maps as well.
map_location = get_binary_file_location("maps", name);
}
if(!map_location.empty()) {
res = read_file(map_location);
if(map_location) {
res = read_file(map_location.value());
}
if(res.empty()) {
@ -287,13 +287,13 @@ std::string read_map(const std::string& name)
std::string read_scenario(const std::string& name)
{
std::string res;
std::string file_location = get_wml_location(name);
if(file_location.empty()) {
auto file_location = get_wml_location(name);
if(!file_location) {
// Consult [binary_path] for scenarios as well.
file_location = get_binary_file_location("scenarios", name);
}
if(!file_location.empty()) {
res = read_file(file_location);
if(file_location) {
res = read_file(file_location.value());
}
if(res.empty()) {

View file

@ -80,13 +80,13 @@ bool load_font_config()
{
config cfg;
try {
const std::string& cfg_path = filesystem::get_wml_location("hardwired/fonts.cfg");
if(cfg_path.empty()) {
const auto cfg_path = filesystem::get_wml_location("hardwired/fonts.cfg");
if(!cfg_path) {
ERR_FT << "could not resolve path to fonts.cfg, file not found";
return false;
}
filesystem::scoped_istream stream = preprocess_file(cfg_path);
filesystem::scoped_istream stream = preprocess_file(cfg_path.value());
read(cfg, *stream);
} catch(const config::error &e) {
ERR_FT << "could not read fonts.cfg:\n" << e.message;

View file

@ -259,7 +259,7 @@ void game_config_manager::load_game_config(bool reload_everything, const game_cl
}
const std::string& path = core["path"];
if(!filesystem::file_exists(filesystem::get_wml_location(path))) {
if(!filesystem::get_wml_location(path)) {
events::call_in_main_thread([&]() {
gui2::dialogs::wml_error::display(
_("Error validating data core."),
@ -307,11 +307,11 @@ void game_config_manager::load_game_config(bool reload_everything, const game_cl
// Load the selected core
std::unique_ptr<schema_validation::schema_validator> validator;
if(cmdline_opts_.validate_core) {
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg").value()));
validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
}
cache_.get_config(filesystem::get_wml_location(wml_tree_root), game_config_, validator.get());
cache_.get_config(filesystem::get_wml_location(wml_tree_root).value(), game_config_, validator.get());
game_config_.append(valid_cores);
main_transaction.lock();
@ -548,7 +548,7 @@ void game_config_manager::load_addons_cfg()
try {
std::unique_ptr<schema_validation::schema_validator> validator;
if(cmdline_opts_.validate_addon && *cmdline_opts_.validate_addon == addon_id) {
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg").value()));
validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
}

View file

@ -826,7 +826,7 @@ void game_launcher::start_wesnothd()
std::string config = filesystem::get_user_data_dir() + "/lan_server.cfg";
if (!filesystem::file_exists(config)) {
// copy file if it isn't created yet
filesystem::write_file(config, filesystem::read_file(filesystem::get_wml_location("lan_server.cfg")));
filesystem::write_file(config, filesystem::read_file(filesystem::get_wml_location("lan_server.cfg").value()));
}
LOG_GENERAL << "Starting wesnothd";

View file

@ -363,7 +363,7 @@ void editor_edit_pbl::delete_translation()
void editor_edit_pbl::validate()
{
std::unique_ptr<schema_validation::schema_validator> validator;
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/pbl.cfg")));
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/pbl.cfg").value()));
validator->set_create_exceptions(false);
config temp;

View file

@ -201,12 +201,12 @@ void game_load::display_savegame_internal(const savegame::save_info& game)
// work, we fallback on unknown-unit.png.
std::string leader_image = leader["leader_image"].str();
if(!::image::exists(leader_image)) {
leader_image = filesystem::get_independent_binary_file_path("images", leader_image);
auto indep_path = filesystem::get_independent_binary_file_path("images", leader_image);
// The leader TC modifier isn't appending if the independent image path can't
// be resolved during save_index entry creation, so we need to add it here.
if(!leader_image.empty()) {
leader_image += leader["leader_image_tc_modifier"].str();
if(indep_path) {
leader_image = indep_path.value() + leader["leader_image_tc_modifier"].str();
}
}

View file

@ -49,10 +49,10 @@ void init()
//
config cfg;
try {
schema_validation::schema_validator validator(filesystem::get_wml_location("schema/gui.cfg"));
schema_validation::schema_validator validator(filesystem::get_wml_location("schema/gui.cfg").value());
preproc_map preproc(game_config::config_cache::instance().get_preproc_map());
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location("gui/_main.cfg"), &preproc);
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location("gui/_main.cfg").value(), &preproc);
read(cfg, *stream, &validator);
} catch(const config::error& e) {

View file

@ -104,7 +104,7 @@ bool load_language_list()
{
config cfg;
try {
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location("hardwired/language.cfg"));
filesystem::scoped_istream stream = preprocess_file(filesystem::get_wml_location("hardwired/language.cfg").value());
read(cfg, *stream);
} catch(const config::error &) {
return false;
@ -377,16 +377,11 @@ void init_textdomains(const game_config_view& cfg)
if(path.empty()) {
t_string::add_textdomain(name, filesystem::get_intl_dir());
} else if(auto location = filesystem::get_binary_dir_location("", path)) {
t_string::add_textdomain(name, location.value());
} else {
std::string location = filesystem::get_binary_dir_location("", path);
if (location.empty()) {
//if location is empty, this causes a crash on Windows, so we
//disallow adding empty domains
WRN_G << "no location found for '" << path << "', skipping textdomain";
} else {
t_string::add_textdomain(name, location);
}
// If location is empty, this causes a crash on Windows, so we disallow adding empty domains
WRN_G << "no location found for '" << path << "', skipping textdomain";
}
}
}

View file

@ -348,37 +348,37 @@ static surface load_image_file(const image::locator& loc)
surface res;
const std::string& name = loc.get_filename();
std::string location = filesystem::get_binary_file_location("images", name);
auto location = filesystem::get_binary_file_location("images", name);
// Many images have been converted from PNG to WEBP format,
// but the old filename may still be saved in savegame files etc.
// If the file does not exist in ".png" format, also try ".webp".
// Similarly for ".jpg", which conveniently has the same number of letters as ".png".
if(location.empty() && (filesystem::ends_with(name, ".png") || filesystem::ends_with(name, ".jpg"))) {
if(!location && (filesystem::ends_with(name, ".png") || filesystem::ends_with(name, ".jpg"))) {
std::string webp_name = name.substr(0, name.size() - 4) + ".webp";
location = filesystem::get_binary_file_location("images", webp_name);
if(!location.empty()) {
if(location) {
WRN_IMG << "Replaced missing '" << name << "' with found '"
<< webp_name << "'.";
}
}
{
if(!location.empty()) {
if(location) {
// Check if there is a localized image.
const std::string loc_location = filesystem::get_localized_path(location);
if(!loc_location.empty()) {
location = loc_location;
const auto loc_location = filesystem::get_localized_path(location.value());
if(loc_location) {
location = loc_location.value();
}
filesystem::rwops_ptr rwops = filesystem::make_read_RWops(location);
filesystem::rwops_ptr rwops = filesystem::make_read_RWops(location.value());
res = IMG_Load_RW(rwops.release(), true); // SDL takes ownership of rwops
// If there was no standalone localized image, check if there is an overlay.
if(res && loc_location.empty()) {
const std::string ovr_location = filesystem::get_localized_path(location, "--overlay");
if(!ovr_location.empty()) {
add_localized_overlay(ovr_location, res);
if(res && !loc_location) {
const auto ovr_location = filesystem::get_localized_path(location.value(), "--overlay");
if(ovr_location) {
add_localized_overlay(ovr_location.value(), res);
}
}
}
@ -565,7 +565,7 @@ bool locator::file_exists() const
{
return val_.is_data_uri
? parsed_data_URI{val_.filename}.good
: !filesystem::get_binary_file_location("images", val_.filename).empty();
: filesystem::get_binary_file_location("images", val_.filename).has_value();
}
static surface load_from_disk(const locator& loc)
@ -868,7 +868,7 @@ bool exists(const image::locator& i_locator)
if(i_locator.is_data_uri()) {
cache = parsed_data_URI{i_locator.get_filename()}.good;
} else {
cache = !filesystem::get_binary_file_location("images", i_locator.get_filename()).empty();
cache = filesystem::get_binary_file_location("images", i_locator.get_filename()).has_value();
}
}

View file

@ -487,16 +487,14 @@ void extract_summary_from_config(config& cfg_save, config& cfg_summary)
// We need a binary path-independent path to the leader image here so it can be displayed
// for campaign-specific units even when the campaign isn't loaded yet.
std::string leader_image_path = filesystem::get_independent_binary_file_path("images", leader_image);
auto leader_image_path = filesystem::get_independent_binary_file_path("images", leader_image);
// If the image path was found, we append the leader TC modifier. If it's not (such as in
// the case where the binary path hasn't been loaded yet, perhaps due to save_index being
// deleted), the unaltered image path is used and will be parsed by get_independent_binary_file_path
// at runtime.
if(!leader_image_path.empty()) {
leader_image_path += leader_image_tc_modifier;
leader_image = leader_image_path;
if(leader_image_path) {
leader_image = leader_image_path.value() + leader_image_tc_modifier;
}
leader_config["leader"] = leader;

View file

@ -57,7 +57,7 @@ static int intf_get_image_size(lua_State *L)
static int intf_have_asset(lua_State* L)
{
std::string type = luaL_checkstring(L, 1), name = luaL_checkstring(L, 2);
lua_pushboolean(L, !filesystem::get_binary_file_location(type, name).empty());
lua_pushboolean(L, filesystem::get_binary_file_location(type, name).has_value());
return 1;
}
@ -70,7 +70,7 @@ static int intf_have_asset(lua_State* L)
static int intf_resolve_asset(lua_State* L)
{
std::string type = luaL_checkstring(L, 1), name = luaL_checkstring(L, 2);
lua_push(L, filesystem::get_independent_binary_file_path(type, name));
lua_push(L, filesystem::get_independent_binary_file_path(type, name).value_or(""));
return 1;
}
@ -155,14 +155,14 @@ static bool resolve_filename(std::string& filename, const std::string& currentdi
if(!canonical_path(filename, currentdir)) {
return false;
}
std::string p = filesystem::get_wml_location(filename);
if(p.empty()) {
auto p = filesystem::get_wml_location(filename);
if(!p) {
return false;
}
if(rel) {
*rel = filename;
}
filename = p;
filename = p.value();
return true;
}

View file

@ -76,10 +76,10 @@ static int intf_load_wml(lua_State* L)
std::string schema_path = luaL_optstring(L, 3, "");
std::shared_ptr<schema_validation::schema_validator> validator;
if(!schema_path.empty()) {
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location(schema_path)));
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location(schema_path).value()));
validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
}
std::string wml_file = filesystem::get_wml_location(file);
std::string wml_file = filesystem::get_wml_location(file).value();
filesystem::scoped_istream stream;
config result;
if(preprocess) {
@ -103,7 +103,7 @@ static int intf_parse_wml(lua_State* L)
std::string schema_path = luaL_optstring(L, 2, "");
std::shared_ptr<schema_validation::schema_validator> validator;
if(!schema_path.empty()) {
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location(schema_path)));
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location(schema_path).value()));
validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
}
config result;

View file

@ -1336,7 +1336,7 @@ bool preprocessor_data::get_chunk()
if(symbol.empty()) {
parent_.error("No path argument found after #ifhave/#ifnhave directive", linenum_);
}
bool found = !filesystem::get_wml_location(symbol, directory_).empty();
bool found = filesystem::get_wml_location(symbol, directory_).has_value();
DBG_PREPROC << "testing for file or directory " << symbol << ": " << (found ? "found" : "not found");
conditional_skip(negate ? found : !found);
} else if(command == "ifver" || command == "ifnver") {
@ -1643,19 +1643,18 @@ bool preprocessor_data::get_chunk()
LOG_PREPROC << "Macro definition not found for " << symbol << ", attempting to open as file.";
pop_token();
std::string nfname = filesystem::get_wml_location(symbol, directory_);
if(!nfname.empty()) {
if(auto nfname = filesystem::get_wml_location(symbol, directory_)) {
if(!slowpath_)
// nfname.size() - symbol.size() gives you an index into nfname
// This does not necessarily match the symbol though, as it can start with ~ or ./
parent_.add_preprocessor<preprocessor_file>(nfname, nfname.size() - symbol.size());
parent_.add_preprocessor<preprocessor_file>(nfname.value(), nfname->size() - symbol.size());
else {
std::unique_ptr<preprocessor_streambuf> buf(new preprocessor_streambuf(parent_));
std::ostringstream res;
{
std::istream in(buf.get());
buf->add_preprocessor<preprocessor_file>(nfname, nfname.size() - symbol.size());
buf->add_preprocessor<preprocessor_file>(nfname.value(), nfname->size() - symbol.size());
res << in.rdbuf();
}

View file

@ -693,7 +693,7 @@ void schema_validator::print(message_info& el)
}
schema_self_validator::schema_self_validator()
: schema_validator(filesystem::get_wml_location("schema/schema.cfg"), false)
: schema_validator(filesystem::get_wml_location("schema/schema.cfg").value(), false)
, type_nesting_()
, condition_nesting_()
{

View file

@ -645,8 +645,10 @@ static void play_new_music()
return;
}
const std::string localized = filesystem::get_localized_path(current_track->file_path());
const std::string& filename = localized.empty() ? current_track->file_path() : localized;
std::string filename = current_track->file_path();
if(auto localized = filesystem::get_localized_path(filename)) {
filename = localized.value();
}
auto itor = music_cache.find(filename);
if(itor == music_cache.end()) {
@ -938,11 +940,11 @@ static Mix_Chunk* load_chunk(const std::string& file, channel_group group)
}
temp_chunk.group = group;
const std::string& filename = filesystem::get_binary_file_location("sounds", file);
const std::string localized = filesystem::get_localized_path(filename);
const auto filename = filesystem::get_binary_file_location("sounds", file);
const auto localized = filesystem::get_localized_path(filename.value_or(""));
if(!filename.empty()) {
filesystem::rwops_ptr rwops = filesystem::make_read_RWops(localized.empty() ? filename : localized);
if(filename) {
filesystem::rwops_ptr rwops = filesystem::make_read_RWops(localized.value_or(filename.value()));
temp_chunk.set_data(Mix_LoadWAV_RW(rwops.release(), true)); // SDL takes ownership of rwops
} else {
ERR_AUDIO << "Could not load sound file '" << file << "'.";
@ -950,7 +952,7 @@ static Mix_Chunk* load_chunk(const std::string& file, channel_group group)
}
if(temp_chunk.get_data() == nullptr) {
ERR_AUDIO << "Could not load sound file '" << filename << "': " << Mix_GetError();
ERR_AUDIO << "Could not load sound file '" << filename.value() << "': " << Mix_GetError();
throw chunk_load_exception();
}

View file

@ -74,9 +74,9 @@ void music_track::resolve()
return;
}
file_path_ = filesystem::get_binary_file_location("music", id_);
if (file_path_.empty()) {
if(auto path = filesystem::get_binary_file_location("music", id_)) {
file_path_ = path.value();
} else {
LOG_AUDIO << "could not find track '" << id_ << "' for track identification";
return;
}

View file

@ -42,7 +42,7 @@ BOOST_AUTO_TEST_CASE( test_fs_game_path_reverse_engineering )
{
const std::string maincfg = "_main.cfg";
std::string gamedata_rev = get_wml_location("_main.cfg");
std::string gamedata_rev = get_wml_location("_main.cfg").value();
const std::size_t strip_len = (maincfg + "/data/").length();
BOOST_REQUIRE(gamedata_rev.length() > strip_len);
@ -158,44 +158,44 @@ BOOST_AUTO_TEST_CASE( test_fs_binary_path )
//load_language_list();
game_config::load_config(main_config.mandatory_child("game_config"));
BOOST_CHECK_EQUAL( get_binary_dir_location("images", "."), gamedata + "/images/." );
BOOST_CHECK_EQUAL( get_binary_dir_location("images", ".").value(), gamedata + "/images/." );
BOOST_CHECK_EQUAL( get_binary_file_location("images", "wesnoth-icon.png"),
BOOST_CHECK_EQUAL( get_binary_file_location("images", "wesnoth-icon.png").value(),
gamedata + "/data/core/images/wesnoth-icon.png" );
BOOST_CHECK_EQUAL( get_binary_file_location("music", "silence.ogg"),
BOOST_CHECK_EQUAL( get_binary_file_location("music", "silence.ogg").value(),
gamedata + "/data/core/music/silence.ogg" );
BOOST_CHECK_EQUAL( get_binary_file_location("sounds", "explosion.ogg"),
BOOST_CHECK_EQUAL( get_binary_file_location("sounds", "explosion.ogg").value(),
gamedata + "/data/core/sounds/explosion.ogg" );
BOOST_CHECK_EQUAL( get_independent_binary_file_path("images", "wesnoth-icon.png"),
BOOST_CHECK_EQUAL( get_independent_binary_file_path("images", "wesnoth-icon.png").value(),
"data/core/images/wesnoth-icon.png" );
// Inexistent paths are resolved empty.
BOOST_CHECK( get_binary_dir_location("images", "").empty() );
BOOST_CHECK( get_binary_dir_location("inexistent_resource_type", "").empty() );
BOOST_CHECK( get_binary_file_location("image", "wesnoth-icon.png").empty() );
BOOST_CHECK( get_binary_file_location("images", "bunnies_and_ponies_and_rainbows_oh_em_gee.psd").empty() );
BOOST_CHECK( get_binary_file_location("music", "this_track_does_not_exist.aiff").empty() );
BOOST_CHECK( get_binary_file_location("sounds", "rude_noises.aiff").empty() );
BOOST_CHECK( get_independent_binary_file_path("images", "dopefish.txt").empty() );
BOOST_CHECK( !get_binary_dir_location("images", "").has_value() );
BOOST_CHECK( !get_binary_dir_location("inexistent_resource_type", "").has_value() );
BOOST_CHECK( !get_binary_file_location("image", "wesnoth-icon.png").has_value() );
BOOST_CHECK( !get_binary_file_location("images", "bunnies_and_ponies_and_rainbows_oh_em_gee.psd").has_value() );
BOOST_CHECK( !get_binary_file_location("music", "this_track_does_not_exist.aiff").has_value() );
BOOST_CHECK( !get_binary_file_location("sounds", "rude_noises.aiff").has_value() );
BOOST_CHECK( !get_independent_binary_file_path("images", "dopefish.txt").has_value() );
}
BOOST_AUTO_TEST_CASE( test_fs_wml_path )
{
const std::string& userdata = get_user_data_dir();
BOOST_CHECK_EQUAL( get_wml_location(""), "" );
BOOST_CHECK_EQUAL( get_wml_location("").value_or(""), "" );
BOOST_CHECK_EQUAL( get_wml_location("_main.cfg"), gamedata + "/data/_main.cfg" );
BOOST_CHECK_EQUAL( get_wml_location("core/_main.cfg"), gamedata + "/data/core/_main.cfg" );
BOOST_CHECK_EQUAL( get_wml_location("."), gamedata + "/data/." );
BOOST_CHECK_EQUAL( get_wml_location("_main.cfg").value(), gamedata + "/data/_main.cfg" );
BOOST_CHECK_EQUAL( get_wml_location("core/_main.cfg").value(), gamedata + "/data/core/_main.cfg" );
BOOST_CHECK_EQUAL( get_wml_location(".").value(), gamedata + "/data/." );
BOOST_CHECK_EQUAL( get_wml_location("~/"), userdata + "/data/" );
BOOST_CHECK_EQUAL( get_wml_location("~/").value(), userdata + "/data/" );
// Inexistent paths are resolved empty.
BOOST_CHECK( get_wml_location("why_would_anyone_ever_name_a_file_like_this").empty() );
BOOST_CHECK( !get_wml_location("why_would_anyone_ever_name_a_file_like_this").has_value() );
}
BOOST_AUTO_TEST_CASE( test_fs_search )

View file

@ -172,7 +172,7 @@ std::string unit_race::get_icon_path_stem() const
std::string path = "icons/unit-groups/race_" + id_;
// FIXME: hardcoded '30' is bad...
if(!filesystem::file_exists(filesystem::get_binary_file_location("images", path + "_30.png"))) {
if(!filesystem::get_binary_file_location("images", path + "_30.png")) {
path = "icons/unit-groups/race_custom";
}

View file

@ -447,17 +447,16 @@ static int process_command_args(const commandline_options& cmdline_opts)
if(cmdline_opts.validate_with) {
schema_path = *cmdline_opts.validate_with;
if(!filesystem::file_exists(schema_path)) {
auto check = filesystem::get_wml_location(schema_path);
if(!filesystem::file_exists(check)) {
PLAIN_LOG << "Could not find schema file: " << schema_path;
if(auto check = filesystem::get_wml_location(schema_path)) {
schema_path = check.value();
} else {
schema_path = check;
PLAIN_LOG << "Could not find schema file: " << schema_path;
}
} else {
schema_path = filesystem::normalize_path(schema_path);
}
} else {
schema_path = filesystem::get_wml_location("schema/game_config.cfg");
schema_path = filesystem::get_wml_location("schema/game_config.cfg").value();
}
schema_validation::schema_validator validator(schema_path);
validator.set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway