aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbutl/default-options.mxx8
-rw-r--r--libbutl/default-options.txx76
-rw-r--r--libbutl/git.cxx3
3 files changed, 60 insertions, 27 deletions
diff --git a/libbutl/default-options.mxx b/libbutl/default-options.mxx
index d7aa70b..62c7f92 100644
--- a/libbutl/default-options.mxx
+++ b/libbutl/default-options.mxx
@@ -7,7 +7,8 @@
#endif
#ifndef __cpp_lib_modules_ts
-#include <utility> // move(), forward()
+#include <utility> // move(), forward(), make_pair()
+#include <system_error>
#endif
// Other includes.
@@ -63,8 +64,9 @@ LIBBUTL_MODEXPORT namespace butl
//
// void (const path&, bool remote)
//
- // Throw std::system_error on the underlying OS error and pass through
- // exceptions thrown by the options scanner/parser.
+ // Throw `pair<path, system_error>` on the underlying OS error with the
+ // first half referring the filesystem entry the error relates to and pass
+ // through exceptions thrown by the options scanner/parser.
//
// Search order:
//
diff --git a/libbutl/default-options.txx b/libbutl/default-options.txx
index 2ed12e4..996ee33 100644
--- a/libbutl/default-options.txx
+++ b/libbutl/default-options.txx
@@ -4,6 +4,17 @@
LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
+ inline bool
+ options_dir_exists (const dir_path& d)
+ try
+ {
+ return dir_exists (d);
+ }
+ catch (std::system_error& e)
+ {
+ throw std::make_pair (path_cast<path> (d), std::move (e));
+ }
+
// Search for and parse the options files in the specified directory and
// its local/ subdirectory, if exists, and append the options to the
// resulting list.
@@ -33,22 +44,31 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
path p (d / f);
- if (file_exists (p)) // Follows symlinks.
+ try
{
- fn (p, remote);
-
- S s (p.string ());
-
- // @@ Note that the potentially thrown exceptions (unknown option,
- // unexpected argument, etc) will not contain any location
- // information. Intercepting exception handling to add the file
- // attribution feels too hairy for now. Maybe we should support
- // this in CLI.
- //
- O o;
- o.parse (s, U::fail, U::fail);
-
- r.push_back (default_options_entry<O> {move (p), move (o), remote});
+ if (file_exists (p)) // Follows symlinks.
+ {
+ fn (p, remote);
+
+ S s (p.string ());
+
+ // @@ Note that the potentially thrown exceptions (unknown option,
+ // unexpected argument, etc) will not contain any location
+ // information. Intercepting exception handling to add the file
+ // attribution feels too hairy for now. Maybe we should support
+ // this in CLI.
+ //
+ O o;
+ o.parse (s, U::fail, U::fail);
+
+ r.push_back (default_options_entry<O> {move (p),
+ move (o),
+ remote});
+ }
+ }
+ catch (std::system_error& e)
+ {
+ throw std::make_pair (move (p), std::move (e));
}
}
};
@@ -57,7 +77,7 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
dir_path ld (d / dir_path ("local"));
- if (dir_exists (ld))
+ if (options_dir_exists (ld))
load (ld, remote);
}
@@ -78,15 +98,23 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
return false;
bool remote (load_default_options_files<O, S, U> (start_dir.directory (),
- home_dir,
- fs,
- std::forward<F> (fn),
- r) ||
- git_repository (start_dir));
+ home_dir,
+ fs,
+ std::forward<F> (fn),
+ r));
+ if (!remote)
+ try
+ {
+ remote = git_repository (start_dir);
+ }
+ catch (std::system_error& e)
+ {
+ throw std::make_pair (start_dir / ".git", std::move (e));
+ }
dir_path d (start_dir / dir_path (".build2"));
- if (dir_exists (d))
+ if (options_dir_exists (d))
load_default_options_files<O, S, U> (d,
remote,
fs,
@@ -109,7 +137,7 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
{
assert (sys_dir->absolute () && sys_dir->normalized ());
- if (dir_exists (*sys_dir))
+ if (options_dir_exists (*sys_dir))
load_default_options_files<O, S, U> (*sys_dir,
false /* remote */,
ofs.files,
@@ -123,7 +151,7 @@ LIBBUTL_MODEXPORT namespace butl //@@ MOD Clang needs this for some reason.
dir_path d (*home_dir / dir_path (".build2"));
- if (dir_exists (d))
+ if (options_dir_exists (d))
load_default_options_files<O, S, U> (d,
false /* remote */,
ofs.files,
diff --git a/libbutl/git.cxx b/libbutl/git.cxx
index 0f58398..aa0a687 100644
--- a/libbutl/git.cxx
+++ b/libbutl/git.cxx
@@ -50,6 +50,9 @@ namespace butl
// .git can be either a directory or a file in case of a submodule or a
// separate working tree.
//
+ // NOTE: remember to update load_default_options_files() if changing
+ // anything here!
+ //
return entry_exists (d / ".git",
true /* follow_symlinks */,
true /* ignore_errors */);