From 7bbe8042dbbea81c713576e1ce69d00bbba5d4b6 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 12 Feb 2024 05:44:51 +0200 Subject: Move to_string(uint64_t,base,width) to utility, use everywhere --- libbuild2/functions-integer.cxx | 46 +++++------------------------------------ libbuild2/utility.cxx | 45 ++++++++++++++++++++++++++++++++++++++++ libbuild2/utility.hxx | 8 ++++++- 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); // functions-builtin.cxx - static const char hex_digits[] = "0123456789abcdef"; - static string to_string (uint64_t i, optional base, optional width) { - uint64_t b (base ? convert (move (*base)) : 10); + int b (base ? + static_cast (convert (move (*base))) + : 10); + size_t w (width ? static_cast (convert (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); + // // 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 -#include // snprintf() #include // memcmp(), memcpy() #include @@ -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 (v.unsigned_number)); - - ns.push_back (name (string (buf))); + ns.push_back (name (to_string (v.unsigned_number, 16))); break; } case json_type::string: -- cgit v1.1