summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2022-08-13 18:53:27 +0100
committerMaxime Coste <mawww@kakoune.org>2022-08-20 11:03:03 +0200
commit021da117cf90bf25b65e3344fa8e43ab4262b714 (patch)
treef9d1a031d35992deb2c69f8964fbc6474ff834d4 /src
parent0c1d4808fa9301012c561614b0f4977a011c3209 (diff)
Add support for field width and digit grouping in format
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc40
-rw-r--r--src/string_utils.cc27
-rw-r--r--src/string_utils.hh6
3 files changed, 42 insertions, 31 deletions
diff --git a/src/commands.cc b/src/commands.cc
index 46481b9d..6715fd05 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -1499,43 +1499,29 @@ const CommandDesc debug_cmd = {
auto total = 0;
write_to_debug_buffer("Memory usage:");
const ColumnCount column_size = 17;
- write_to_debug_buffer(format("{} │{} │{} │{} ",
- left_pad("domain", column_size),
- left_pad("bytes", column_size),
- left_pad("active allocs", column_size),
- left_pad("total allocs", column_size)));
+ write_to_debug_buffer(format("{:17} │{:17} │{:17} │{:17} ",
+ "domain",
+ "bytes",
+ "active allocs",
+ "total allocs"));
write_to_debug_buffer(format("{0}┼{0}┼{0}┼{0}", String(Codepoint{0x2500}, column_size + 1)));
- auto group = [](StringView s) {
- String res;
- auto pos = 0_byte, len = s.length();
- if ((pos = len % 3) != 0)
- res += s.substr(0, pos);
- for (; pos != len; pos += 3)
- {
- if (not res.empty())
- res += ",";
- res += s.substr(pos, 3);
- }
- return res;
- };
-
for (int domain = 0; domain < (int)MemoryDomain::Count; ++domain)
{
auto& stats = memory_stats[domain];
total += stats.allocated_bytes;
- write_to_debug_buffer(format("{} │{} │{} │{} ",
- left_pad(domain_name((MemoryDomain)domain), column_size),
- left_pad(group(to_string(stats.allocated_bytes)), column_size),
- left_pad(group(to_string(stats.allocation_count)), column_size),
- left_pad(group(to_string(stats.total_allocation_count)), column_size)));
+ write_to_debug_buffer(format("{:17} │{:17} │{:17} │{:17} ",
+ domain_name((MemoryDomain)domain),
+ grouped(stats.allocated_bytes),
+ grouped(stats.allocation_count),
+ grouped(stats.total_allocation_count)));
}
write_to_debug_buffer({});
- write_to_debug_buffer(format(" Total: {}", group(to_string(total))));
+ write_to_debug_buffer(format(" Total: {}", grouped(total)));
#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33))
- write_to_debug_buffer(format(" Malloced: {}", group(to_string(mallinfo2().uordblks))));
+ write_to_debug_buffer(format(" Malloced: {}", grouped(mallinfo2().uordblks)));
#elif defined(__GLIBC__) || defined(__CYGWIN__)
- write_to_debug_buffer(format(" Malloced: {}", group(to_string(mallinfo().uordblks))));
+ write_to_debug_buffer(format(" Malloced: {}", grouped(mallinfo().uordblks)));
#endif
}
else if (parser[0] == "shared-strings")
diff --git a/src/string_utils.cc b/src/string_utils.cc
index 39205d7e..f34bde03 100644
--- a/src/string_utils.cc
+++ b/src/string_utils.cc
@@ -195,6 +195,20 @@ InplaceString<23> to_string(Hex val)
return to_string_impl<23>(val.val, 16);
}
+InplaceString<23> to_string(Grouped val)
+{
+ auto ungrouped = to_string_impl<23>(val.val);
+
+ InplaceString<23> res;
+ for (int pos = 0, len = ungrouped.m_length; pos != len; ++pos)
+ {
+ if (res.m_length and ((len - pos) % 3) == 0)
+ res.m_data[res.m_length++] = ',';
+ res.m_data[res.m_length++] = ungrouped.m_data[pos];
+ }
+ return res;
+}
+
InplaceString<23> to_string(float val)
{
#if defined(__cpp_lib_to_chars)
@@ -338,12 +352,19 @@ void format_impl(StringView fmt, ArrayView<const StringView> params, AppendFunc
if (closing == end)
throw runtime_error("format string error, unclosed '{'");
- const int index = (closing == opening + 1) ?
- implicitIndex : str_to_int({opening+1, closing});
+ auto format = std::find(opening+1, closing, ':');
+ const int index = opening+1 == format ? implicitIndex : str_to_int({opening+1, format});
if (index >= params.size())
throw runtime_error("format string parameter index too big");
+ if (format != closing)
+ {
+ for (ColumnCount width = str_to_int({format+1, closing}), len = params[index].column_length();
+ width > len; --width)
+ append(' ');
+ }
+
append(params[index]);
implicitIndex = index+1;
it = closing+1;
@@ -454,7 +475,7 @@ UnitTest test_string{[]()
kak_assert(subsequence_match("tchou kanaky", "tchou kanaky"));
kak_assert(not subsequence_match("tchou kanaky", "tchou kanaky"));
- kak_assert(format("Youhou {1} {} {0} \\{}", 10, "hehe", 5) == "Youhou hehe 5 10 {}");
+ kak_assert(format("Youhou {1} {} '{0:4}' \\{}", 10, "hehe", 5) == "Youhou hehe 5 ' 10' {}");
char buffer[20];
kak_assert(format_to(buffer, "Hey {}", 15) == "Hey 15");
diff --git a/src/string_utils.hh b/src/string_utils.hh
index b2dc3d30..13d15018 100644
--- a/src/string_utils.hh
+++ b/src/string_utils.hh
@@ -117,19 +117,23 @@ struct InplaceString
constexpr operator StringView() const { return {m_data, ByteCount{m_length}}; }
operator String() const { return {m_data, ByteCount{m_length}}; }
- unsigned char m_length;
+ unsigned char m_length{};
char m_data[N];
};
struct Hex { size_t val; };
constexpr Hex hex(size_t val) { return {val}; }
+struct Grouped { size_t val; };
+constexpr Grouped grouped(size_t val) { return {val}; }
+
InplaceString<15> to_string(int val);
InplaceString<15> to_string(unsigned val);
InplaceString<23> to_string(long int val);
InplaceString<23> to_string(unsigned long val);
InplaceString<23> to_string(long long int val);
InplaceString<23> to_string(Hex val);
+InplaceString<23> to_string(Grouped val);
InplaceString<23> to_string(float val);
InplaceString<7> to_string(Codepoint c);