27 std::optional<std::pair<std::string, std::string>> explicit_data;
28 if (std::smatch match; std::regex_search(path, match, std::regex(
"(?:([a-z0-9_]+):)?(.*)")))
33 if (
const auto it = data_paths.find(match[1].str()); it != data_paths.end())
36 mooseError(
"Data from '", match[1],
"' is not registered to be searched");
41 mooseError(
"Failed to parse path '", path,
"'");
43 const std::filesystem::path value_path = std::filesystem::path(path);
46 const auto if_data_name_error = [&explicit_data](
const auto & message)
51 " along with a data name to search (requested " 58 if (std::filesystem::path(path).is_absolute())
61 if_data_name_error(
"an absolute path");
72 mooseError(
"The absolute path '", path,
"' does not exist or is not readable.");
76 std::map<std::string, std::string> not_found;
82 const std::string base = options.
base ? *options.
base : std::filesystem::current_path().c_str();
100 std::optional<std::string> skip_data_reason;
102 if (path.size() > 1 && path.substr(0, 2) ==
"./")
105 if_data_name_error(
"a path that starts with './'");
108 skip_data_reason =
"begins with './'";
111 else if (
const std::string proximate = std::filesystem::proximate(path).c_str();
112 (proximate.size() > 1 && proximate.substr(0, 2) ==
".."))
115 if_data_name_error(
"a relative path");
118 skip_data_reason =
"resolves behind '.'";
123 std::map<std::string, std::string> found;
126 const auto check_data_path = [&found, ¬_found, &path](
const auto & entry)
128 const auto & [
name, data_path] = entry;
133 not_found.emplace(
name +
" data", data_path);
139 check_data_path(*explicit_data);
141 mooseError(
"The path '", path,
"' was not found in data from '", explicit_data->first,
"'");
146 for (
const auto & entry : data_paths)
147 check_data_path(entry);
152 if (found.size() == 1)
154 const auto & [
name, data_path] = *found.begin();
158 std::stringstream oss;
160 if (found.size() > 1)
162 oss <<
"Multiple files were found when searching for the data file '" << path <<
"':\n\n";
163 for (
const auto & [
name, data_path] : found)
164 oss <<
" " <<
name <<
": " << data_path <<
"\n";
165 const auto & first_name = found.begin()->first;
166 oss <<
"\nYou can resolve this ambiguity by appending a prefix with the desired data name, for " 168 << first_name <<
":" << path;
173 oss <<
"Unable to find the data file '" << path <<
"'.\n";
174 if (not_found.size())
176 oss <<
"\nPaths searched:\n";
177 for (
const auto & [
name, data_path] : not_found)
178 oss <<
" " <<
name <<
": " << data_path <<
"\n";
180 if (skip_data_reason)
181 oss <<
"\nData path(s) were not searched because search path " << *skip_data_reason <<
".\n";
189 const std::string & path,
190 const std::optional<std::string> & base)
194 return getPath(data_name +
":" + path, options);
std::string name(const ElemQuality q)
Path getPathExplicit(const std::string &data_name, const std::string &path, const std::optional< std::string > &base=std::optional< std::string >())
Get the data path for a given path, searching the registered data given an explicit data search path...
Relative to the base (typically an input file)
static Registry & getRegistry()
Get the global Registry singleton.
bool search_all_data
Whether or not to search all registered data.
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
From installed/in-tree data.
bool graceful
Whether or not to error whenever a path is not found.
Relative to the base, but not found.
Path getPath(std::string path, const GetPathOptions &options={})
Get the data path for a given path, searching the registered data.
std::string canonicalPath(const std::string &path)
Options to be passed to getPath().
Representation of a data file path.
std::optional< std::string > base
The base path by which to search for relative paths.
std::filesystem::path pathjoin(const std::filesystem::path &p)
static const std::map< std::string, std::string > & getDataFilePaths()
Returns a map of all registered data file paths (name -> path)
bool checkFileReadable(const std::string &filename, bool check_line_endings, bool throw_on_unreadable, bool check_for_git_lfs_pointer)