diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2024-02-12 05:44:51 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2024-02-12 05:44:51 +0200 |
commit | 7bbe8042dbbea81c713576e1ce69d00bbba5d4b6 (patch) | |
tree | 2e0fe544517e6251b18c0c5ba6f57dd74c3a19aa | |
parent | 0249399f06ab77c58e02698a6a0b2352f0dbf1ae (diff) |
Move to_string(uint64_t,base,width) to utility, use everywhere
-rw-r--r-- | libbuild2/functions-integer.cxx | 46 | ||||
-rw-r--r-- | libbuild2/utility.cxx | 45 | ||||
-rw-r--r-- | libbuild2/utility.hxx | 8 | ||||
-rw-r--r-- | libbuild2/variable.cxx | 11 |
4 files changed, 58 insertions, 52 deletions
diff --git a/libbuild2/functions-integer.cxx b/libbuild2/functions-integer.cxx index 934f753..8f9e2cf 100644 --- a/libbuild2/functions-integer.cxx +++ b/libbuild2/functions-integer.cxx @@ -11,54 +11,18 @@ 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); + int b (base ? + static_cast<int> (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; + return (to_string (i, b, w)); } void diff --git a/libbuild2/utility.cxx b/libbuild2/utility.cxx index 909db07..1135851 100644 --- a/libbuild2/utility.cxx +++ b/libbuild2/utility.cxx @@ -86,6 +86,51 @@ namespace build2 // namespace build2 { + static const char hex_digits[] = "0123456789abcdef"; + + string + to_string (uint64_t i, int b, size_t w) + { + // 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 (*terminate) (bool); process_path argv0; diff --git a/libbuild2/utility.hxx b/libbuild2/utility.hxx index 594808c..b534f41 100644 --- a/libbuild2/utility.hxx +++ b/libbuild2/utility.hxx @@ -52,10 +52,16 @@ namespace build2 using std::make_shared; using std::make_move_iterator; using std::back_inserter; - using std::to_string; using std::stoul; using std::stoull; + using std::to_string; + + // Currently only supports base 10 and 16. Note: adds `0x` if base 16. + // + LIBBUILD2_SYMEXPORT string + to_string (uint64_t, int base, size_t width = 0); + // <libbutl/utility.hxx> // using butl::reverse_iterate; diff --git a/libbuild2/variable.cxx b/libbuild2/variable.cxx index 3db0fd0..795af6c 100644 --- a/libbuild2/variable.cxx +++ b/libbuild2/variable.cxx @@ -3,7 +3,6 @@ #include <libbuild2/variable.hxx> -#include <cstdio> // snprintf() #include <cstring> // memcmp(), memcpy() #include <libbutl/path-pattern.hxx> @@ -1830,15 +1829,7 @@ namespace build2 } case json_type::hexadecimal_number: { - // Hexadecimal representation of 64-bit integers requires a maximum of - // 10 character (plus '\0'): 0xffffffff. - // - char buf[11]; - snprintf (buf, sizeof (buf), - "0x%llx", - static_cast<unsigned long long> (v.unsigned_number)); - - ns.push_back (name (string (buf))); + ns.push_back (name (to_string (v.unsigned_number, 16))); break; } case json_type::string: |