aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-11-02 10:18:50 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-11-02 10:18:50 +0200
commit1c6096e53a906d7821a401d91b32ca02df3d715f (patch)
tree380d7d9acc6fc186c7c7d18da025613e71526c71 /libbuild2
parent2a09b60a4169c151fa89e1d4c979a4b5c40a0252 (diff)
Add $first()/$second() pair functions
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/functions-builtin.cxx60
1 files changed, 59 insertions, 1 deletions
diff --git a/libbuild2/functions-builtin.cxx b/libbuild2/functions-builtin.cxx
index 13b315c..e24ff8e 100644
--- a/libbuild2/functions-builtin.cxx
+++ b/libbuild2/functions-builtin.cxx
@@ -101,6 +101,64 @@ namespace build2
//
f["empty"] += [](value* v) {return v->null || v->empty ();};
+
+ // $first(<value>[, <not_pair>])
+ // $second(<value>[, <not_pair>])
+ //
+ // Return the first or the second half of a pair, respectively. If a value
+ // is not a pair, then return `null` unless the <not_pair> argument is
+ // `true`, in which case return the non-pair value.
+ //
+ // If multiple pairs are specified, then return the list of first/second
+ // halfs. If an element is not a pair, then omit it from the resulting
+ // list unless the <not_pair> argument is `true`, in which case add the
+ // non-pair element to the list.
+ //
+ f["first"] += [] (names ns, optional<value> not_pair)
+ {
+ // @@ TODO: would be nice to return typed half if passed typed value.
+
+ bool np (not_pair && convert<bool> (move (*not_pair)));
+
+ names r;
+ for (auto i (ns.begin ()), e (ns.end ()); i != e; )
+ {
+ name& f (*i++);
+ name* s (f.pair ? &*i++ : nullptr);
+
+ if (s != nullptr || np)
+ {
+ f.pair = '\0';
+ r.push_back (move (f));
+ }
+ else if (ns.size () == 1)
+ return value (nullptr); // Single non-pair.
+ }
+
+ return value (move (r));
+ };
+
+ f["second"] += [] (names ns, optional<value> not_pair)
+ {
+ bool np (not_pair && convert<bool> (move (*not_pair)));
+
+ names r;
+ for (auto i (ns.begin ()), e (ns.end ()); i != e; )
+ {
+ name& f (*i++);
+ name* s (f.pair ? &*i++ : nullptr);
+
+ if (s != nullptr)
+ r.push_back (move (*s));
+ else if (np)
+ r.push_back (move (f));
+ else if (ns.size () == 1)
+ return value (nullptr); // Single non-pair.
+ }
+
+ return value (move (r));
+ };
+
// Leave this one undocumented for now since it's unclear why would anyone
// want to use it currently (we don't yet have any function composition
// facilities).
@@ -110,7 +168,7 @@ namespace build2
// $quote(<value>[, <escape>])
//
// Quote the value returning its string representation. If <escape> is
- // true, then also escape (with a backslash) the quote characters being
+ // `true`, then also escape (with a backslash) the quote characters being
// added (this is useful if the result will be re-parsed, for example as a
// script command line).
//