From 093d031ec45b74bb5c880c3ce3ca7f181c600e9f Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 17 May 2018 14:26:09 +0300 Subject: Pass ignore_dangling flag to dir_iterator() ctor --- build2/file.cxx | 154 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 74 deletions(-) (limited to 'build2/file.cxx') 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 (de.path ())); + dir_path sd (d / path_cast (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 -- cgit v1.1