aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2021-11-03 13:08:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2021-11-04 08:09:42 +0200
commit10e634e64b5fffaf19778d8fd3aa854118aa0d53 (patch)
tree99d09d1ae6a7024b7dbc6c436bf1bc780640fe16
parente612a49ef95cf9ce3d0b5496d724f73cae9aa333 (diff)
Add $size() function to get size of sequence (names, strings, etc)
-rw-r--r--libbuild2/functions-builtin.cxx21
-rw-r--r--libbuild2/functions-name.cxx41
-rw-r--r--libbuild2/functions-path.cxx54
-rw-r--r--libbuild2/functions-string.cxx6
-rw-r--r--tests/function/builtin/testscript7
-rw-r--r--tests/function/name/buildfile4
-rw-r--r--tests/function/name/testscript18
7 files changed, 106 insertions, 45 deletions
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(<names> [, <flags>])
+ // $size(<ints>)
//
- // 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<names> 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(<ints> [, <flags>])
//
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<names>); // 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(<names>)
+ //
+ // 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(<names> [, <flags>])
+ //
+ // Sort names in ascending order.
+ //
+ // The following flags are supported:
+ //
+ // dedup - in addition to sorting also remove duplicates
+ //
+ fn["sort"] += [] (names ns, optional<names> 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<dir_path> 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<dir_path> d)
{
for (dir_path& p: v)
- p = p.base ();
+ p = leaf (p, d);
return v;
};
- f[".base"] += [](names ns)
+ f[".leaf"] += [](names ns, optional<dir_path> 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<path> (move (n)).base ().string ();
+ n.value = leaf (convert<path> (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<dir_path> d)
+ f["base"] += [](paths v)
{
for (path& p: v)
- p = leaf (p, d);
+ p = p.base ();
return v;
};
- f["leaf"] += [](dir_paths v, optional<dir_path> 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<dir_path> 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<path> (move (n)), d).string ();
+ n.value = convert<path> (move (n)).base ().string ();
}
return ns;
};
@@ -414,6 +414,14 @@ namespace build2
return extension (convert<path> (move (ns)));
};
+ // $size(<paths>)
+ // $size(<dir_paths>)
+ //
+ // Return the number of elements in the sequence.
+ //
+ f["size"] += [] (paths v) {return v.size ();};
+ f["size"] += [] (dir_paths v) {return v.size ();};
+
// $sort(<paths> [, <flags>])
// $sort(<dir_paths> [, <flags>])
//
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<string> (move (s))))};
};
+ // $size(<strings>)
+ //
+ // Return the number of elements in the sequence.
+ //
+ f["size"] += [] (strings v) {return v.size ();};
+
// $sort(<strings> [, <flags>])
//
// Sort strings in ascending order.
diff --git a/tests/function/builtin/testscript b/tests/function/builtin/testscript
index 3853ec2..00d594b 100644
--- a/tests/function/builtin/testscript
+++ b/tests/function/builtin/testscript
@@ -80,11 +80,8 @@
: sort
:
{
- $* <'print $sort( d/t{a} t{c b} d/t{a})' >'t{b} t{c} d/t{a} d/t{a}' : name-basics
- $* <'print $sort( d/t{a} t{c b} d/t{a}, dedup)' >'t{b} t{c} d/t{a}' : name-dedup
-
- $* <'print $sort([uint64s] 0 2 1 000)' >'0 0 1 2' : int-basics
- $* <'print $sort([uint64s] 0 2 1 000, dedup)' >'0 1 2' : int-dedup
+ $* <'print $sort([uint64s] 0 2 1 000)' >'0 0 1 2' : basics
+ $* <'print $sort([uint64s] 0 2 1 000, dedup)' >'0 1 2' : dedup
}
: getenv
diff --git a/tests/function/name/buildfile b/tests/function/name/buildfile
new file mode 100644
index 0000000..48be4c3
--- /dev/null
+++ b/tests/function/name/buildfile
@@ -0,0 +1,4 @@
+# file : tests/function/name/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/function/name/testscript b/tests/function/name/testscript
new file mode 100644
index 0000000..2fe8e24
--- /dev/null
+++ b/tests/function/name/testscript
@@ -0,0 +1,18 @@
+# file : tests/function/name/testscript
+# license : MIT; see accompanying LICENSE file
+
+.include ../../common.testscript
+
+: size
+:
+{
+ $* <'print $size(a b c@./)' >'3' : basics
+ $* <'print $type($size(a))' >'uint64' : type
+}
+
+: sort
+:
+{
+ $* <'print $sort( d/t{a} t{c b} d/t{a})' >'t{b} t{c} d/t{a} d/t{a}' : basics
+ $* <'print $sort( d/t{a} t{c b} d/t{a}, dedup)' >'t{b} t{c} d/t{a}' : dedup
+}