From ab7dba520c8efd2cfbdd71dd91ae6b60923a12cd Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 8 Dec 2022 21:13:47 +0300 Subject: Adapt to dir_iterator API change --- libbuild2/algorithm.cxx | 3 +-- libbuild2/cc/guess.cxx | 2 +- libbuild2/cc/types.cxx | 15 ++++++++++++++- libbuild2/dist/operation.cxx | 2 +- libbuild2/file.cxx | 20 ++++++++++++++++++-- libbuild2/filesystem.cxx | 2 +- libbuild2/functions-filesystem.cxx | 30 ++++++++++++++++++++++++++---- libbuild2/parser.cxx | 15 ++++++++++++++- libbuild2/script/run.cxx | 3 +-- libbuild2/target.cxx | 24 ++++++++++++++++++++++-- 10 files changed, 99 insertions(+), 17 deletions(-) diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx index cc48a38..597ab6c 100644 --- a/libbuild2/algorithm.cxx +++ b/libbuild2/algorithm.cxx @@ -1821,8 +1821,7 @@ namespace build2 try_mkdir (to); - for (const auto& de: - dir_iterator (fr, false /* ignore_dangling */)) + for (const auto& de: dir_iterator (fr, dir_iterator::no_follow)) { path f (fr / de.path ()); path t (to / de.path ()); diff --git a/libbuild2/cc/guess.cxx b/libbuild2/cc/guess.cxx index 2a6ae67..c7aef7b 100644 --- a/libbuild2/cc/guess.cxx +++ b/libbuild2/cc/guess.cxx @@ -761,7 +761,7 @@ namespace build2 // for (const dir_entry& de: dir_iterator (r.psdk_dir / dir_path ("Include"), - false /* ignore_dangling */)) + dir_iterator::no_follow)) { if (de.type () == entry_type::directory) { diff --git a/libbuild2/cc/types.cxx b/libbuild2/cc/types.cxx index 8ee4fa9..c6cfae9 100644 --- a/libbuild2/cc/types.cxx +++ b/libbuild2/cc/types.cxx @@ -6,6 +6,7 @@ #include using namespace std; +using namespace butl; namespace build2 { @@ -123,6 +124,8 @@ namespace build2 size_t importable_headers:: insert_angle_pattern (const dir_paths& sys_hdr_dirs, const string& pat) { + tracer trace ("importable_headers::insert_angle_pattern"); + assert (pat.front () == '<' && pat.back () == '>' && path_pattern (pat)); // First see if it has already been inserted. @@ -172,7 +175,17 @@ namespace build2 try { - path_search (f, process, dir); + path_search ( + f, + process, + dir, + path_match_flags::follow_symlinks, + [&trace] (const dir_entry& de) + { + l5 ([&]{trace << "skipping inaccessible/dangling entry " + << de.base () / de.path ();}); + return true; + }); } catch (const system_error& e) { diff --git a/libbuild2/dist/operation.cxx b/libbuild2/dist/operation.cxx index af7b40b..0a75afe 100644 --- a/libbuild2/dist/operation.cxx +++ b/libbuild2/dist/operation.cxx @@ -152,7 +152,7 @@ namespace build2 try { - for (const dir_entry& e: dir_iterator (d, false /* ignore_dangling */)) + for (const dir_entry& e: dir_iterator (d, dir_iterator::no_follow)) { const path& n (e.path ()); diff --git a/libbuild2/file.cxx b/libbuild2/file.cxx index 03dea5f..bf50a25 100644 --- a/libbuild2/file.cxx +++ b/libbuild2/file.cxx @@ -358,7 +358,7 @@ namespace build2 // try { - for (const dir_entry& de: dir_iterator (d, false /* ignore_dangling */)) + for (const dir_entry& de: dir_iterator (d, dir_iterator::no_follow)) { // 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. @@ -847,10 +847,26 @@ namespace build2 try { - for (const dir_entry& de: dir_iterator (d, true /* ignore_dangling */)) + // It's probably possible that a subproject can be a symlink with the + // link target, for example, being in a git submodule. Considering that, + // it makes sense to warn about dangling symlinks. + // + for (const dir_entry& de: + dir_iterator (d, dir_iterator::detect_dangling)) { if (de.type () != entry_type::directory) + { + if (de.type () == entry_type::unknown) + { + bool sl (de.ltype () == entry_type::symlink); + + warn << "skipping " + << (sl ? "dangling symlink" : "inaccessible entry") << ' ' + << d / de.path (); + } + continue; + } dir_path sd (d / path_cast (de.path ())); diff --git a/libbuild2/filesystem.cxx b/libbuild2/filesystem.cxx index 196d9bd..f340dd7 100644 --- a/libbuild2/filesystem.cxx +++ b/libbuild2/filesystem.cxx @@ -291,7 +291,7 @@ namespace build2 { try { - for (const dir_entry& de: dir_iterator (d, false /* ignore_dangling */)) + for (const dir_entry& de: dir_iterator (d, dir_iterator::no_follow)) { // The .buildignore filesystem entry should be of the regular file // type. diff --git a/libbuild2/functions-filesystem.cxx b/libbuild2/functions-filesystem.cxx index ef7bfc5..1acb3d1 100644 --- a/libbuild2/functions-filesystem.cxx +++ b/libbuild2/functions-filesystem.cxx @@ -7,6 +7,7 @@ #include using namespace std; +using namespace butl; namespace build2 { @@ -29,12 +30,27 @@ namespace build2 return true; }; + auto dangling = [] (const dir_entry& de) + { + bool sl (de.ltype () == entry_type::symlink); + + warn << "skipping " + << (sl ? "dangling symlink" : "inaccessible entry") << ' ' + << de.base () / de.path (); + + return true; + }; + // Print paths "as is" in the diagnostics. // try { if (pattern.absolute ()) - path_search (pattern, add); + path_search (pattern, + add, + dir_path () /* start */, + path_match_flags::follow_symlinks, + dangling); else { // An absolute start directory must be specified for the relative @@ -54,7 +70,11 @@ namespace build2 << "' is relative"; } - path_search (pattern, add, *start); + path_search (pattern, + add, + *start, + path_match_flags::follow_symlinks, + dangling); } } catch (const system_error& e) @@ -83,7 +103,7 @@ namespace build2 function_family f (m, "filesystem"); - // path_search + // $path_search( [, ]) // // Return filesystem paths that match the pattern. If the pattern is an // absolute path, then the start directory is ignored (if present). @@ -91,6 +111,9 @@ namespace build2 // // Note that this function is not pure. // + // @@ In the future we may want to add a flag that controls the + // dangling/inaccessible treatment. + // { auto e (f.insert ("path_search", false)); @@ -115,6 +138,5 @@ namespace build2 convert (move (start))); }; } - } } diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index 13a3b12..dd2944d 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -6042,7 +6042,20 @@ namespace build2 try { - path_search (path (move (p)), process, *sp); + path_search (path (move (p)), + process, + *sp, + path_match_flags::follow_symlinks, + [] (const dir_entry& de) + { + bool sl (de.ltype () == entry_type::symlink); + + warn << "skipping " + << (sl ? "dangling symlink" : "inaccessible entry") + << ' ' << de.base () / de.path (); + + return true; + }); } catch (const system_error& e) { diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx index f486138..6f5934e 100644 --- a/libbuild2/script/run.cxx +++ b/libbuild2/script/run.cxx @@ -3353,8 +3353,7 @@ namespace build2 try { size_t n (0); - for (const dir_entry& de: dir_iterator (p, - false /* ignore_dangling */)) + for (const dir_entry& de: dir_iterator (p, dir_iterator::no_follow)) { if (n++ < 10) dr << '\n' << (de.ltype () == entry_type::directory diff --git a/libbuild2/target.cxx b/libbuild2/target.cxx index 76d45c7..16aec49 100644 --- a/libbuild2/target.cxx +++ b/libbuild2/target.cxx @@ -1253,7 +1253,7 @@ namespace build2 { try { - for (const dir_entry& e: dir_iterator (d, true /* ignore_dangling */)) + for (const dir_entry& e: dir_iterator (d, dir_iterator::detect_dangling)) { switch (e.type ()) { @@ -1271,6 +1271,16 @@ namespace build2 break; } + case entry_type::unknown: + { + bool sl (e.ltype () == entry_type::symlink); + + warn << "skipping " + << (sl ? "dangling symlink" : "inaccessible entry") << ' ' + << d / e.path (); + + break; + } default: break; } @@ -1292,9 +1302,10 @@ namespace build2 try { - for (const dir_entry& e: dir_iterator (d, true /* ignore_dangling */)) + for (const dir_entry& e: dir_iterator (d, dir_iterator::detect_dangling)) { if (e.type () == entry_type::directory) + { r.push_back ( prerequisite (nullopt, dir::static_type, @@ -1303,6 +1314,15 @@ namespace build2 string (), nullopt, bs)); + } + else if (e.type () == entry_type::unknown) + { + bool sl (e.ltype () == entry_type::symlink); + + warn << "skipping " + << (sl ? "dangling symlink" : "inaccessible entry") << ' ' + << d / e.path (); + } } } catch (const system_error& e) -- cgit v1.1