diff options
Diffstat (limited to 'libbuild2/functions-builtin.cxx')
-rw-r--r-- | libbuild2/functions-builtin.cxx | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/libbuild2/functions-builtin.cxx b/libbuild2/functions-builtin.cxx index 93f2d0f..5129a05 100644 --- a/libbuild2/functions-builtin.cxx +++ b/libbuild2/functions-builtin.cxx @@ -32,6 +32,56 @@ 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) { @@ -77,7 +127,10 @@ namespace build2 // f["string"] += [](bool b) {return b ? "true" : "false";}; f["string"] += [](int64_t i) {return to_string (i);}; - f["string"] += [](uint64_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 |