1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
// file : libbuild2/functions-filesystem.cxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#include <libbutl/filesystem.mxx>
#include <libbuild2/function.hxx>
#include <libbuild2/variable.hxx>
using namespace std;
namespace build2
{
// Return paths of filesystem entries that match the pattern. See
// path_search() overloads (below) for details.
//
static names
path_search (const path& pattern, const optional<dir_path>& start)
{
names r;
auto add = [&r] (path&& p, const std::string&, bool interm) -> bool
{
// Canonicalizing paths seems to be the right thing to do. Otherwise, we
// can end up with different separators in the same path on Windows.
//
if (!interm)
r.emplace_back (
value_traits<path>::reverse (move (p.canonicalize ())));
return true;
};
// Print paths "as is" in the diagnostics.
//
try
{
if (pattern.absolute ())
path_search (pattern, add);
else
{
// An absolute start directory must be specified for the relative
// pattern.
//
if (!start || start->relative ())
{
diag_record dr (fail);
if (!start)
dr << "start directory is not specified";
else
dr << "start directory '" << start->representation ()
<< "' is relative";
dr << info << "pattern '" << pattern.representation ()
<< "' is relative";
}
path_search (pattern, add, *start);
}
}
catch (const system_error& e)
{
diag_record d (fail);
d << "unable to scan";
// If the pattern is absolute, then the start directory is not used, and
// so printing it would be misleading.
//
if (start && pattern.relative ())
d << " '" << start->representation () << "'";
d << ": " << e
<< info << "pattern: '" << pattern.representation () << "'";
}
return r;
}
void
filesystem_functions (function_map& m)
{
// @@ Maybe we should have the ability to mark the whole family as not
// pure?
function_family f (m, "filesystem");
// path_search
//
// Return filesystem paths that match the pattern. If the pattern is an
// absolute path, then the start directory is ignored (if present).
// Otherwise, the start directory must be specified and be absolute.
//
// Note that this function is not pure.
//
{
auto e (f.insert ("path_search", false));
e += [](path pattern, optional<dir_path> start)
{
return path_search (pattern, start);
};
e += [](path pattern, names start)
{
return path_search (pattern, convert<dir_path> (move (start)));
};
e += [](names pattern, optional<dir_path> start)
{
return path_search (convert<path> (move (pattern)), start);
};
e += [](names pattern, names start)
{
return path_search (convert<path> (move (pattern)),
convert<dir_path> (move (start)));
};
}
}
}
|