From 10e634e64b5fffaf19778d8fd3aa854118aa0d53 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 3 Nov 2021 13:08:48 +0200 Subject: Add $size() function to get size of sequence (names, strings, etc) --- libbuild2/functions-builtin.cxx | 21 +++------------- libbuild2/functions-name.cxx | 41 +++++++++++++++++++++++++++++++ libbuild2/functions-path.cxx | 54 +++++++++++++++++++++++------------------ libbuild2/functions-string.cxx | 6 +++++ 4 files changed, 82 insertions(+), 40 deletions(-) (limited to 'libbuild2') diff --git a/libbuild2/functions-builtin.cxx b/libbuild2/functions-builtin.cxx index d040ba8..c013c3b 100644 --- a/libbuild2/functions-builtin.cxx +++ b/libbuild2/functions-builtin.cxx @@ -100,25 +100,12 @@ namespace build2 return os.str (); }; - // $sort( [, ]) + // $size() // - // Sort names in ascending order. + // Return the number of elements in the sequence. // - // See also type-specific overloads. - // - // The following flags are supported: - // - // dedup - in addition to sorting also remove duplicates - // - f["sort"] += [] (names v, optional fs) - { - sort (v.begin (), v.end ()); - - if (functions_sort_flags (move (fs))) - v.erase (unique (v.begin(), v.end()), v.end ()); - - return v; - }; + f["size"] += [] (int64s v) {return v.size ();}; + f["size"] += [] (uint64s v) {return v.size ();}; // $sort( [, ]) // diff --git a/libbuild2/functions-name.cxx b/libbuild2/functions-name.cxx index 9ba20a8..800c377 100644 --- a/libbuild2/functions-name.cxx +++ b/libbuild2/functions-name.cxx @@ -10,6 +10,9 @@ using namespace std; namespace build2 { + extern bool + functions_sort_flags (optional); // functions-builtin.cxx + // Convert name to target'ish name (see below for the 'ish part). Return // raw/unprocessed data in case this is an unknown target type (or called // out of scope). See scope::find_target_type() for details. Allow out- @@ -174,6 +177,44 @@ namespace build2 return to_target_name (s, move (n), o).first.proj; }; + // $size() + // + // Return the number of elements in the sequence. + // + fn["size"] += [] (names ns) + { + size_t n (0); + + for (auto i (ns.begin ()); i != ns.end (); ++i) + { + ++n; + if (i->pair && !(++i)->directory ()) + fail << "name pair in names"; + } + + return n; + }; + + // $sort( [, ]) + // + // Sort names in ascending order. + // + // The following flags are supported: + // + // dedup - in addition to sorting also remove duplicates + // + fn["sort"] += [] (names ns, optional fs) + { + //@@ TODO: shouldn't we do this in a pair-aware manner? + + sort (ns.begin (), ns.end ()); + + if (functions_sort_flags (move (fs))) + ns.erase (unique (ns.begin(), ns.end()), ns.end ()); + + return ns; + }; + // Functions that can be called only on real targets. // function_family ft (m, "target"); diff --git a/libbuild2/functions-path.cxx b/libbuild2/functions-path.cxx index d6ff83f..72597ff 100644 --- a/libbuild2/functions-path.cxx +++ b/libbuild2/functions-path.cxx @@ -332,25 +332,30 @@ namespace build2 return ns; }; - // base + // leaf // - f["base"] += &path::base; + f["leaf"] += &path::leaf; - f["base"] += [](paths v) + f["leaf"] += [](path p, dir_path d) + { + return leaf (p, move (d)); + }; + + f["leaf"] += [](paths v, optional d) { for (path& p: v) - p = p.base (); + p = leaf (p, d); return v; }; - f["base"] += [](dir_paths v) + f["leaf"] += [](dir_paths v, optional d) { for (dir_path& p: v) - p = p.base (); + p = leaf (p, d); return v; }; - f[".base"] += [](names ns) + f[".leaf"] += [](names ns, optional d) { // For each path decide based on the presence of a trailing slash // whether it is a directory. Return as untyped list of (potentially @@ -359,37 +364,32 @@ namespace build2 for (name& n: ns) { if (n.directory ()) - n.dir = n.dir.base (); + n.dir = leaf (n.dir, d); else - n.value = convert (move (n)).base ().string (); + n.value = leaf (convert (move (n)), d).string (); } return ns; }; - // leaf + // base // - f["leaf"] += &path::leaf; - - f["leaf"] += [](path p, dir_path d) - { - return leaf (p, move (d)); - }; + f["base"] += &path::base; - f["leaf"] += [](paths v, optional d) + f["base"] += [](paths v) { for (path& p: v) - p = leaf (p, d); + p = p.base (); return v; }; - f["leaf"] += [](dir_paths v, optional d) + f["base"] += [](dir_paths v) { for (dir_path& p: v) - p = leaf (p, d); + p = p.base (); return v; }; - f[".leaf"] += [](names ns, optional d) + f[".base"] += [](names ns) { // For each path decide based on the presence of a trailing slash // whether it is a directory. Return as untyped list of (potentially @@ -398,9 +398,9 @@ namespace build2 for (name& n: ns) { if (n.directory ()) - n.dir = leaf (n.dir, d); + n.dir = n.dir.base (); else - n.value = leaf (convert (move (n)), d).string (); + n.value = convert (move (n)).base ().string (); } return ns; }; @@ -414,6 +414,14 @@ namespace build2 return extension (convert (move (ns))); }; + // $size() + // $size() + // + // Return the number of elements in the sequence. + // + f["size"] += [] (paths v) {return v.size ();}; + f["size"] += [] (dir_paths v) {return v.size ();}; + // $sort( [, ]) // $sort( [, ]) // diff --git a/libbuild2/functions-string.cxx b/libbuild2/functions-string.cxx index 6e39c44..18a4ed6 100644 --- a/libbuild2/functions-string.cxx +++ b/libbuild2/functions-string.cxx @@ -77,6 +77,12 @@ namespace build2 return names {name (ucase (convert (move (s))))}; }; + // $size() + // + // Return the number of elements in the sequence. + // + f["size"] += [] (strings v) {return v.size ();}; + // $sort( [, ]) // // Sort strings in ascending order. -- cgit v1.1