aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2020-06-03 14:38:39 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2020-06-03 16:47:34 +0300
commitf50d0d58c8eb659e803282e19cf15398e3a8e373 (patch)
treead9d6a434661cb08a89b8871601d4dc55235a8ae
parent450c907b2a10c43748b8c15df20d92ff782269c7 (diff)
Fix $process.run() to properly handle proces_path_ex
-rw-r--r--libbuild2/build/script/parser.cxx12
-rw-r--r--libbuild2/functions-process.cxx34
-rw-r--r--libbuild2/variable.cxx15
-rw-r--r--libbuild2/variable.hxx14
4 files changed, 54 insertions, 21 deletions
diff --git a/libbuild2/build/script/parser.cxx b/libbuild2/build/script/parser.cxx
index 2a0555e..c4c4b03 100644
--- a/libbuild2/build/script/parser.cxx
+++ b/libbuild2/build/script/parser.cxx
@@ -475,18 +475,12 @@ namespace build2
{
// Find the end of the value.
//
- auto b (ns.begin ()), i (b), e (ns.end ());
- for (i += i->pair ? 2 : 1; i != e && i->pair; i += 2)
- {
- if (!i->simple () ||
- (i->value != "name" && i->value != "checksum"))
- break;
- }
+ auto b (ns.begin ());
+ auto i (value_traits<process_path_ex>::find_end (ns));
if (b->pair || i != b + 1) // First is a pair or pairs after.
{
- pp_ns.insert (pp_ns.end (),
- make_move_iterator (b), make_move_iterator (i));
+ pp_ns = names (make_move_iterator (b), make_move_iterator (i));
ns.erase (b, i);
diff --git a/libbuild2/functions-process.cxx b/libbuild2/functions-process.cxx
index e6c0582..de06f27 100644
--- a/libbuild2/functions-process.cxx
+++ b/libbuild2/functions-process.cxx
@@ -210,19 +210,39 @@ namespace build2
if (args.empty () || args[0].empty ())
fail << "executable name expected in process." << fn << "()";
- process_path pp;
+ optional<process_path> pp;
+
try
{
size_t erase;
- // This can be a process_path (pair) or just a path.
+ // This can be a process_path (pair), process_path_ex (process_path
+ // followed by the name@ and checksum@ pairs), or just a path.
+ //
+ // First, check if the arguments begin with a process_path[_ex] and, if
+ // that's the case, only use the leading name/pair to create the process
+ // path, discarding the meta-information.
//
- if (args[0].pair)
+ if (args[0].file ())
{
- pp = convert<process_path> (move (args[0]), move (args[1]));
- erase = 2;
+ // Find the end of the process_path[_ex] value.
+ //
+ auto b (args.begin ());
+ auto i (value_traits<process_path_ex>::find_end (args));
+
+ if (b->pair || i != b + 1) // First is a pair or pairs after.
+ {
+ pp = convert<process_path> (
+ names (make_move_iterator (b),
+ make_move_iterator (b + (b->pair ? 2 : 1))));
+
+ erase = i - b;
+ }
}
- else
+
+ // Fallback to a path, if this is not a process path.
+ //
+ if (!pp)
{
// Strip the builtin-escaping '^' character, if present.
//
@@ -254,7 +274,7 @@ namespace build2
fail << "invalid process." << fn << "() executable path: " << e;
}
- return pair<process_path, strings> (move (pp),
+ return pair<process_path, strings> (move (*pp),
program_args (move (args), fn));
}
diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx
index e0502ef..9009fdc 100644
--- a/libbuild2/variable.cxx
+++ b/libbuild2/variable.cxx
@@ -1083,7 +1083,7 @@ namespace build2
const string& k ((i++)->value);
- // NOTE: see also build::script::parser::parse_program().
+ // NOTE: see also find_end() below.
//
if (k == "name")
{
@@ -1107,6 +1107,19 @@ namespace build2
return pp;
}
+ names::iterator value_traits<process_path_ex>::
+ find_end (names& ns)
+ {
+ auto b (ns.begin ()), i (b), e (ns.end ());
+ for (i += i->pair ? 2 : 1; i != e && i->pair; i += 2)
+ {
+ if (!i->simple () || (i->value != "name" && i->value != "checksum"))
+ break;
+ }
+
+ return i;
+ }
+
static void
process_path_ex_assign (value& v, names&& ns, const variable* var)
{
diff --git a/libbuild2/variable.hxx b/libbuild2/variable.hxx
index 9febe5e..c1cfa84 100644
--- a/libbuild2/variable.hxx
+++ b/libbuild2/variable.hxx
@@ -881,8 +881,8 @@ namespace build2
static_assert (sizeof (process_path) <= value::size_,
"insufficient space");
- // Represented as a @-pair of names. As a result it cannot be stored in a
- // container.
+ // Represented as a potential @-pair of name(s). As a result it cannot be
+ // stored in a container.
//
static process_path convert (name&&, name*);
static void assign (value&, process_path&&);
@@ -902,8 +902,9 @@ namespace build2
static_assert (sizeof (process_path_ex) <= value::size_,
"insufficient space");
- // Represented as a @-pair of names corresponding to process_path followed
- // by the name@ and checksum@ pairs. So it's a container-like.
+ // Represented as a potential @-pair of name(s) corresponding to
+ // process_path followed by the name@ and checksum@ pairs. So it's a
+ // container-like.
//
static process_path_ex convert (names&&);
static void assign (value&, process_path_ex&&);
@@ -912,6 +913,11 @@ namespace build2
static const bool empty_value = true;
static const char* const type_name;
static const build2::value_type value_type;
+
+ // Find the end of the process_path_ex value representation assuming
+ // the first name or name pair is the process_path representation.
+ //
+ static names::iterator find_end (names&);
};
// target_triplet