aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/algorithm.cxx5
-rw-r--r--build2/cc/link-rule.cxx5
-rw-r--r--build2/file.cxx154
-rw-r--r--build2/target.txx28
-rw-r--r--build2/test/script/builtin.cxx3
-rw-r--r--build2/test/script/runner.cxx8
6 files changed, 113 insertions, 90 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx
index ba9f5bc..bc810df 100644
--- a/build2/algorithm.cxx
+++ b/build2/algorithm.cxx
@@ -1055,7 +1055,7 @@ namespace build2
if (!(d ? dir_exists (p) : file_exists (p)))
return;
- for (;; ) // Retry/fallback loop.
+ for (;;) // Retry/fallback loop.
try
{
switch (m)
@@ -1078,7 +1078,8 @@ namespace build2
try_mkdir (to);
- for (const auto& de: dir_iterator (fr))
+ for (const auto& de: dir_iterator (fr,
+ false /* ignore_dangling */))
{
path f (fr / de.path ());
path t (to / de.path ());
diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx
index 358a835..c413d0a 100644
--- a/build2/cc/link-rule.cxx
+++ b/build2/cc/link-rule.cxx
@@ -1975,7 +1975,10 @@ namespace build2
return true;
};
- path_search (p, rm, dir_path (), false); // Don't follow symlinks.
+ path_search (p,
+ rm,
+ dir_path () /* start */,
+ false /* follow_symlinks */);
}
catch (const system_error&) {} // Ignore errors.
}
diff --git a/build2/file.cxx b/build2/file.cxx
index cadcc29..38d4a49 100644
--- a/build2/file.cxx
+++ b/build2/file.cxx
@@ -179,31 +179,41 @@ namespace build2
// our needs are pretty basic and performance is quite important, so let's
// handle this ourselves.
//
- for (const dir_entry& de: dir_iterator (d))
+ try
{
- // If this is a link, then type() will try to stat() it. And if the link
- // is dangling or points to something inaccessible, it will fail. So
- // let's first check that the name matches and only then check the type.
- //
- const path& n (de.path ());
+ for (const dir_entry& de: dir_iterator (d, false /* ignore_dangling */))
+ {
+ // If this is a link, then type() will try to stat() it. And if the
+ // link is dangling or points to something inaccessible, it will fail.
+ // So let's first check that the name matches and only then check the
+ // type.
+ //
+ const path& n (de.path ());
- if (n.string ().compare (0, pre ? 4 : 5, pre ? "pre-" : "post-") != 0 ||
- n.extension () != "build")
- continue;
+ if (n.string ().compare (0,
+ pre ? 4 : 5,
+ pre ? "pre-" : "post-") != 0 ||
+ n.extension () != "build")
+ continue;
- path f (d / n);
+ path f (d / n);
- try
- {
- if (de.type () != entry_type::regular)
- continue;
- }
- catch (const system_error& e)
- {
- fail << "unable to read buildfile " << f << ": " << e;
- }
+ try
+ {
+ if (de.type () != entry_type::regular)
+ continue;
+ }
+ catch (const system_error& e)
+ {
+ fail << "unable to read buildfile " << f << ": " << e;
+ }
- source_once (root, root, f);
+ source_once (root, root, f);
+ }
+ }
+ catch (const system_error& e)
+ {
+ fail << "unable to iterate over " << d << ": " << e;
}
}
@@ -536,75 +546,71 @@ namespace build2
{
tracer trace ("find_subprojects");
- for (const dir_entry& de: dir_iterator (d))
+ try
{
- // If this is a link, then type() will try to stat() it. And if
- // the link is dangling or points to something inaccessible, it
- // will fail.
- //
- try
+ for (const dir_entry& de: dir_iterator (d, true /* ignore_dangling */))
{
if (de.type () != entry_type::directory)
continue;
- }
- catch (const system_error&)
- {
- continue;
- }
- dir_path sd (d / path_cast<dir_path> (de.path ()));
+ dir_path sd (d / path_cast<dir_path> (de.path ()));
- bool src (false);
- if (!((out && is_out_root (sd)) || (src = is_src_root (sd))))
- {
- // We used to scan for subproject recursively but this is probably too
- // loose (think of some tests laying around). In the future we should
- // probably allow specifying something like extra/* or extra/** in
- // subprojects.
- //
- //find_subprojects (sps, sd, root, out);
- //
- continue;
- }
+ bool src (false);
+ if (!((out && is_out_root (sd)) || (src = is_src_root (sd))))
+ {
+ // We used to scan for subproject recursively but this is probably
+ // too loose (think of some tests laying around). In the future we
+ // should probably allow specifying something like extra/* or
+ // extra/** in subprojects.
+ //
+ //find_subprojects (sps, sd, root, out);
+ //
+ continue;
+ }
- // Calculate relative subdirectory for this subproject.
- //
- dir_path dir (sd.leaf (root));
- l5 ([&]{trace << "subproject " << sd << " as " << dir;});
+ // Calculate relative subdirectory for this subproject.
+ //
+ dir_path dir (sd.leaf (root));
+ l5 ([&]{trace << "subproject " << sd << " as " << dir;});
- // Load its name. Note that here we don't use fallback src_root
- // since this function is used to scan both out_root and src_root.
- //
- string name (find_project_name (sd, dir_path (), &src));
+ // Load its name. Note that here we don't use fallback src_root
+ // since this function is used to scan both out_root and src_root.
+ //
+ string name (find_project_name (sd, dir_path (), &src));
- // If the name is empty, then is is an unnamed project. While the
- // 'project' variable stays empty, here we come up with a surrogate
- // name for a key. The idea is that such a key should never conflict
- // with a real project name. We ensure this by using the project's
- // sub-directory and appending a trailing directory separator to it.
- //
- if (name.empty ())
- name = dir.posix_string () + path::traits::directory_separator;
+ // If the name is empty, then is is an unnamed project. While the
+ // 'project' variable stays empty, here we come up with a surrogate
+ // name for a key. The idea is that such a key should never conflict
+ // with a real project name. We ensure this by using the project's
+ // sub-directory and appending a trailing directory separator to it.
+ //
+ if (name.empty ())
+ name = dir.posix_string () + path::traits::directory_separator;
- // @@ Can't use move() because we may need the values in diagnostics
- // below. Looks like C++17 try_emplace() is what we need.
- //
- auto rp (sps.emplace (name, dir));
+ // @@ Can't use move() because we may need the values in diagnostics
+ // below. Looks like C++17 try_emplace() is what we need.
+ //
+ auto rp (sps.emplace (name, dir));
- // Handle duplicates.
- //
- if (!rp.second)
- {
- const dir_path& dir1 (rp.first->second);
+ // Handle duplicates.
+ //
+ if (!rp.second)
+ {
+ const dir_path& dir1 (rp.first->second);
- if (dir != dir1)
- fail << "inconsistent subproject directories for " << name <<
- info << "first alternative: " << dir1 <<
- info << "second alternative: " << dir;
+ if (dir != dir1)
+ fail << "inconsistent subproject directories for " << name <<
+ info << "first alternative: " << dir1 <<
+ info << "second alternative: " << dir;
- l6 ([&]{trace << "skipping duplicate";});
+ l6 ([&]{trace << "skipping duplicate";});
+ }
}
}
+ catch (const system_error& e)
+ {
+ fail << "unable to iterate over " << d << ": " << e;
+ }
}
bool
diff --git a/build2/target.txx b/build2/target.txx
index a5d6728..d93d300 100644
--- a/build2/target.txx
+++ b/build2/target.txx
@@ -158,17 +158,25 @@ namespace build2
//
prerequisites_type ps;
- for (const dir_entry& e: dir_iterator (base.src_path ()))
+ try
{
- if (e.type () == entry_type::directory)
- ps.push_back (
- prerequisite (nullopt,
- dir::static_type,
- dir_path (e.path ().representation ()),
- dir_path (), // In the out tree.
- string (),
- nullopt,
- base));
+ for (const dir_entry& e: dir_iterator (base.src_path (),
+ true /* ignore_dangling */))
+ {
+ if (e.type () == entry_type::directory)
+ ps.push_back (
+ prerequisite (nullopt,
+ dir::static_type,
+ dir_path (e.path ().representation ()),
+ dir_path (), // In the out tree.
+ string (),
+ nullopt,
+ base));
+ }
+ }
+ catch (const system_error& e)
+ {
+ fail << "unable to iterate over " << base.src_path () << ": " << e;
}
if (ps.empty ())
diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx
index 91d5bf2..0a238bb 100644
--- a/build2/test/script/builtin.cxx
+++ b/build2/test/script/builtin.cxx
@@ -306,7 +306,8 @@ namespace build2
if (cleanup)
sp.clean ({cleanup_type::always, to}, true);
- for (const auto& de: dir_iterator (from)) // Can throw.
+ for (const auto& de: dir_iterator (from,
+ false /* ignore_dangling */))
{
path f (from / de.path ());
path t (to / de.path ());
diff --git a/build2/test/script/runner.cxx b/build2/test/script/runner.cxx
index 889b27c..6496b0f 100644
--- a/build2/test/script/runner.cxx
+++ b/build2/test/script/runner.cxx
@@ -132,7 +132,8 @@ namespace build2
try
{
size_t n (0);
- for (const dir_entry& de: dir_iterator (p))
+ for (const dir_entry& de: dir_iterator (p,
+ false /* ignore_dangling */))
{
if (n++ < 10)
d << '\n' << (de.ltype () == entry_type::directory
@@ -822,7 +823,10 @@ namespace build2
//
try
{
- path_search (p, rm);
+ path_search (p,
+ rm,
+ dir_path () /* start */,
+ false /* follow_symlinks */);
}
catch (const system_error& e)
{