aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbuild2/function.cxx4
-rw-r--r--libbuild2/functions-bool.cxx20
-rw-r--r--libbuild2/functions-builtin.cxx158
-rw-r--r--libbuild2/functions-integer.cxx178
-rw-r--r--tests/function/builtin/testscript41
-rw-r--r--tests/function/integer/buildfile4
-rw-r--r--tests/function/integer/testscript41
7 files changed, 249 insertions, 197 deletions
diff --git a/libbuild2/function.cxx b/libbuild2/function.cxx
index eaf3f9e..ae69730 100644
--- a/libbuild2/function.cxx
+++ b/libbuild2/function.cxx
@@ -349,8 +349,10 @@ namespace build2
// Static-initialize the function map and populate with builtin functions.
//
+ void bool_functions (function_map&); // functions-bool.cxx
void builtin_functions (function_map&); // functions-builtin.cxx
void filesystem_functions (function_map&); // functions-filesystem.cxx
+ void integer_functions (function_map&); // functions-integer.cxx
void name_functions (function_map&); // functions-name.cxx
void path_functions (function_map&); // functions-path.cxx
void process_functions (function_map&); // functions-process.cxx
@@ -363,8 +365,10 @@ namespace build2
void
insert_builtin_functions (function_map& m)
{
+ bool_functions (m);
builtin_functions (m);
filesystem_functions (m);
+ integer_functions (m);
name_functions (m);
path_functions (m);
process_functions (m);
diff --git a/libbuild2/functions-bool.cxx b/libbuild2/functions-bool.cxx
new file mode 100644
index 0000000..1ae89d2
--- /dev/null
+++ b/libbuild2/functions-bool.cxx
@@ -0,0 +1,20 @@
+// file : libbuild2/functions-bool.cxx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+#include <libbuild2/function.hxx>
+#include <libbuild2/variable.hxx>
+
+using namespace std;
+
+namespace build2
+{
+ void
+ bool_functions (function_map& m)
+ {
+ function_family f (m, "bool");
+
+ // $string(<bool>)
+ //
+ f["string"] += [](bool b) {return b ? "true" : "false";};
+ }
+}
diff --git a/libbuild2/functions-builtin.cxx b/libbuild2/functions-builtin.cxx
index de79538..9785f3a 100644
--- a/libbuild2/functions-builtin.cxx
+++ b/libbuild2/functions-builtin.cxx
@@ -32,56 +32,6 @@ namespace build2
return r;
};
- static const char hex_digits[] = "0123456789abcdef";
-
- static string
- to_string (uint64_t i, optional<value> base, optional<value> width)
- {
- uint64_t b (base ? convert<uint64_t> (move (*base)) : 10);
- size_t w (width
- ? static_cast<size_t> (convert<uint64_t> (move (*width)))
- : 0);
-
- // One day we can switch to C++17 std::to_chars().
- //
- string r;
- switch (b)
- {
- case 10:
- {
- r = to_string (i);
- if (w > r.size ())
- r.insert (0, w - r.size (), '0');
- break;
- }
- case 16:
- {
- r.reserve (18);
- r += "0x";
-
- for (size_t j (64); j != 0; )
- {
- j -= 4;
- size_t d ((i >> j) & 0x0f);
-
- // Omit leading zeros but watch out for the i==0 corner case.
- //
- if (d != 0 || r.size () != 2 || j == 0)
- r += hex_digits[d];
- }
-
- if (w > r.size () - 2)
- r.insert (2, w - (r.size () - 2), '0');
-
- break;
- }
- default:
- throw invalid_argument ("unsupported base");
- }
-
- return r;
- }
-
void
builtin_functions (function_map& m)
{
@@ -123,46 +73,6 @@ namespace build2
f["identity"] += [](value* v) {return move (*v);};
- // $integer_sequence(<begin>, <end>[, <step>])
- //
- // Return the list of uint64 integers starting from <begin> (including) to
- // <end> (excluding) with the specified <step> or 1 if unspecified. If
- // <begin> is greater than <end>, empty list is returned.
- //
- // Note that currently negative numbers are not supported but this could
- // be handled if required (e.g., by returning int64s in this case).
- //
- // Note also that we could improve this by adding a shortcut to get the
- // indexes of a list (for example, $indexes(<list>) plus potentially a
- // similar $keys() function for maps).
- //
- f["integer_sequence"] += [](value begin, value end, optional<value> step)
- {
- uint64_t b (convert<uint64_t> (move (begin)));
- uint64_t e (convert<uint64_t> (move (end)));
- uint64_t s (step ? convert<uint64_t> (move (*step)) : 1);
-
- uint64s r;
- if (b < e)
- {
- r.reserve (static_cast<size_t> ((e - b) / s + 1));
-
- for (; b < e; b += s)
- r.push_back (static_cast<size_t> (b));
- }
-
- return r;
- };
-
- // string
- //
- f["string"] += [](bool b) {return b ? "true" : "false";};
- f["string"] += [](int64_t i) {return to_string (i);};
- f["string"] += [](uint64_t i, optional<value> base, optional<value> width)
- {
- return to_string (i, move (base), move (width));
- };
-
// Quote a value returning its string representation. If escape is 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
@@ -184,74 +94,6 @@ namespace build2
return os.str ();
};
- // $size(<ints>)
- //
- // Return the number of elements in the sequence.
- //
- f["size"] += [] (int64s v) {return v.size ();};
- f["size"] += [] (uint64s v) {return v.size ();};
-
- // $sort(<ints> [, <flags>])
- //
- // Sort integers in ascending order.
- //
- // The following flags are supported:
- //
- // dedup - in addition to sorting also remove duplicates
- //
- f["sort"] += [](int64s 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["sort"] += [](uint64s 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;
- };
-
- // $find(<ints>, <int>)
- //
- // Return true if the integer sequence contains the specified integer.
- //
- f["find"] += [](int64s vs, value v)
- {
- return find (vs.begin (), vs.end (),
- convert<int64_t> (move (v))) != vs.end ();
- };
-
- f["find"] += [](uint64s vs, value v)
- {
- return find (vs.begin (), vs.end (),
- convert<uint64_t> (move (v))) != vs.end ();
- };
-
- // $find_index(<ints>, <int>)
- //
- // Return the index of the first element in the integer sequence that is
- // equal to the specified integer or $size(<ints>) if none is found.
- //
- f["find_index"] += [](int64s vs, value v)
- {
- auto i (find (vs.begin (), vs.end (), convert<int64_t> (move (v))));
- return i != vs.end () ? i - vs.begin () : vs.size ();
- };
-
- f["find_index"] += [](uint64s vs, value v)
- {
- auto i (find (vs.begin (), vs.end (), convert<uint64_t> (move (v))));
- return i != vs.end () ? i - vs.begin () : vs.size ();
- };
-
// getenv
//
// Return NULL if the environment variable is not set, untyped value
diff --git a/libbuild2/functions-integer.cxx b/libbuild2/functions-integer.cxx
new file mode 100644
index 0000000..ddfc250
--- /dev/null
+++ b/libbuild2/functions-integer.cxx
@@ -0,0 +1,178 @@
+// file : libbuild2/functions-integer.cxx -*- C++ -*-
+// license : MIT; see accompanying LICENSE file
+
+#include <libbuild2/function.hxx>
+#include <libbuild2/variable.hxx>
+
+using namespace std;
+
+namespace build2
+{
+ extern bool
+ functions_sort_flags (optional<names>); // functions-builtin.cxx
+
+ static const char hex_digits[] = "0123456789abcdef";
+
+ static string
+ to_string (uint64_t i, optional<value> base, optional<value> width)
+ {
+ uint64_t b (base ? convert<uint64_t> (move (*base)) : 10);
+ size_t w (width
+ ? static_cast<size_t> (convert<uint64_t> (move (*width)))
+ : 0);
+
+ // One day we can switch to C++17 std::to_chars().
+ //
+ string r;
+ switch (b)
+ {
+ case 10:
+ {
+ r = to_string (i);
+ if (w > r.size ())
+ r.insert (0, w - r.size (), '0');
+ break;
+ }
+ case 16:
+ {
+ r.reserve (18);
+ r += "0x";
+
+ for (size_t j (64); j != 0; )
+ {
+ j -= 4;
+ size_t d ((i >> j) & 0x0f);
+
+ // Omit leading zeros but watch out for the i==0 corner case.
+ //
+ if (d != 0 || r.size () != 2 || j == 0)
+ r += hex_digits[d];
+ }
+
+ if (w > r.size () - 2)
+ r.insert (2, w - (r.size () - 2), '0');
+
+ break;
+ }
+ default:
+ throw invalid_argument ("unsupported base");
+ }
+
+ return r;
+ }
+
+ void
+ integer_functions (function_map& m)
+ {
+ function_family f (m, "integer");
+
+ // $string(<int64>)
+ // $string(<uint64>[, <base>[, <width>]])
+ //
+ f["string"] += [](int64_t i) {return to_string (i);};
+
+ f["string"] += [](uint64_t i, optional<value> base, optional<value> width)
+ {
+ return to_string (i, move (base), move (width));
+ };
+
+ // $integer_sequence(<begin>, <end>[, <step>])
+ //
+ // Return the list of uint64 integers starting from <begin> (including) to
+ // <end> (excluding) with the specified <step> or 1 if unspecified. If
+ // <begin> is greater than <end>, empty list is returned.
+ //
+ // Note that currently negative numbers are not supported but this could
+ // be handled if required (e.g., by returning int64s in this case).
+ //
+ // Note also that we could improve this by adding a shortcut to get the
+ // indexes of a list (for example, $indexes(<list>) plus potentially a
+ // similar $keys() function for maps).
+ //
+ f["integer_sequence"] += [](value begin, value end, optional<value> step)
+ {
+ uint64_t b (convert<uint64_t> (move (begin)));
+ uint64_t e (convert<uint64_t> (move (end)));
+ uint64_t s (step ? convert<uint64_t> (move (*step)) : 1);
+
+ uint64s r;
+ if (b < e)
+ {
+ r.reserve (static_cast<size_t> ((e - b) / s + 1));
+
+ for (; b < e; b += s)
+ r.push_back (static_cast<size_t> (b));
+ }
+
+ return r;
+ };
+
+ // $size(<ints>)
+ //
+ // Return the number of elements in the sequence.
+ //
+ f["size"] += [] (int64s v) {return v.size ();};
+ f["size"] += [] (uint64s v) {return v.size ();};
+
+ // $sort(<ints> [, <flags>])
+ //
+ // Sort integers in ascending order.
+ //
+ // The following flags are supported:
+ //
+ // dedup - in addition to sorting also remove duplicates
+ //
+ f["sort"] += [](int64s 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["sort"] += [](uint64s 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;
+ };
+
+ // $find(<ints>, <int>)
+ //
+ // Return true if the integer sequence contains the specified integer.
+ //
+ f["find"] += [](int64s vs, value v)
+ {
+ return find (vs.begin (), vs.end (),
+ convert<int64_t> (move (v))) != vs.end ();
+ };
+
+ f["find"] += [](uint64s vs, value v)
+ {
+ return find (vs.begin (), vs.end (),
+ convert<uint64_t> (move (v))) != vs.end ();
+ };
+
+ // $find_index(<ints>, <int>)
+ //
+ // Return the index of the first element in the integer sequence that is
+ // equal to the specified integer or $size(<ints>) if none is found.
+ //
+ f["find_index"] += [](int64s vs, value v)
+ {
+ auto i (find (vs.begin (), vs.end (), convert<int64_t> (move (v))));
+ return i != vs.end () ? i - vs.begin () : vs.size ();
+ };
+
+ f["find_index"] += [](uint64s vs, value v)
+ {
+ auto i (find (vs.begin (), vs.end (), convert<uint64_t> (move (v))));
+ return i != vs.end () ? i - vs.begin () : vs.size ();
+ };
+ }
+}
diff --git a/tests/function/builtin/testscript b/tests/function/builtin/testscript
index 3c430d7..714a38d 100644
--- a/tests/function/builtin/testscript
+++ b/tests/function/builtin/testscript
@@ -77,43 +77,6 @@
$* <'print $type($identity(abc))' >'' : untyped
}
-: integer-sequence
-:
-{
- $* <'print $integer_sequence(1, 3)' >'1 2' : basics
- $* <'print $integer_sequence(1, 0)' >'' : empty
- $* <'print $integer_sequence(0, 8, 2)' >'0 2 4 6' : step
-}
-
-: string
-:
-{
- $* <'print $string([uint64] 0xffff)' >'65535' : uint
- $* <'print $string([uint64] 0xffff, 16)' >'0xffff' : uint-hex
- $* <'print $string([uint64] 0xffff, 16, 8)' >'0x0000ffff' : uint-hex-width
-}
-
-: sort
-:
-{
- $* <'print $sort([uint64s] 0 2 1 000)' >'0 0 1 2' : basics
- $* <'print $sort([uint64s] 0 2 1 000, dedup)' >'0 1 2' : dedup
-}
-
-: find
-:
-{
- $* <'print $find([uint64s] 1 2 3, 2)' >'true' : basics-true
- $* <'print $find([uint64s] 1 2 3, 0)' >'false' : basics-false
-}
-
-: find_index
-:
-{
- $* <'print $find_index([int64s] -1 -2 -3, -2)' >'1' : basics-true
- $* <'print $find_index([int64s] -1 -2 -3, 0)' >'3' : basics-false
-}
-
: getenv
:
{
@@ -123,8 +86,8 @@
: likely is set at the time of login, and on Windows it is set by build2 on
: startup.
:
- : @@ Use a custom variable, when an ability to set environment variables in
- : testscript is implemented.
+ : @@ TMP Use a custom variable, when an ability to set environment variables
+ : in testscript is implemented. It is now!
:
{
: string
diff --git a/tests/function/integer/buildfile b/tests/function/integer/buildfile
new file mode 100644
index 0000000..308fe09
--- /dev/null
+++ b/tests/function/integer/buildfile
@@ -0,0 +1,4 @@
+# file : tests/function/integer/buildfile
+# license : MIT; see accompanying LICENSE file
+
+./: testscript $b
diff --git a/tests/function/integer/testscript b/tests/function/integer/testscript
new file mode 100644
index 0000000..ad2d3bb
--- /dev/null
+++ b/tests/function/integer/testscript
@@ -0,0 +1,41 @@
+# file : tests/function/integer/testscript
+# license : MIT; see accompanying LICENSE file
+
+.include ../../common.testscript
+
+: integer-sequence
+:
+{
+ $* <'print $integer_sequence(1, 3)' >'1 2' : basics
+ $* <'print $integer_sequence(1, 0)' >'' : empty
+ $* <'print $integer_sequence(0, 8, 2)' >'0 2 4 6' : step
+}
+
+: string
+:
+{
+ $* <'print $string([uint64] 0xffff)' >'65535' : uint
+ $* <'print $string([uint64] 0xffff, 16)' >'0xffff' : uint-hex
+ $* <'print $string([uint64] 0xffff, 16, 8)' >'0x0000ffff' : uint-hex-width
+}
+
+: sort
+:
+{
+ $* <'print $sort([uint64s] 0 2 1 000)' >'0 0 1 2' : basics
+ $* <'print $sort([uint64s] 0 2 1 000, dedup)' >'0 1 2' : dedup
+}
+
+: find
+:
+{
+ $* <'print $find([uint64s] 1 2 3, 2)' >'true' : basics-true
+ $* <'print $find([uint64s] 1 2 3, 0)' >'false' : basics-false
+}
+
+: find_index
+:
+{
+ $* <'print $find_index([int64s] -1 -2 -3, -2)' >'1' : basics-true
+ $* <'print $find_index([int64s] -1 -2 -3, 0)' >'3' : basics-false
+}