From 13a5af70aebd85f5c21cba346f22eadd98fe333c Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Mon, 30 Mar 2015 23:05:24 +0100 Subject: Add a format function for printf like formatting --- src/string.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'src/string.cc') diff --git a/src/string.cc b/src/string.cc index df7bfa68..ae454264 100644 --- a/src/string.cc +++ b/src/string.cc @@ -205,4 +205,46 @@ Vector wrap_lines(StringView text, CharCount max_width) return lines; } +String format(StringView fmt, ArrayView params) +{ + ByteCount size = fmt.length(); + for (auto& s : params) size += s.length(); + String res; + res.reserve(size); + + int implicitIndex = 0; + for (auto it = fmt.begin(), end = fmt.end(); it != end;) + { + auto opening = std::find(it, end, '{'); + res += StringView{it, opening}; + if (opening == end) + break; + + if (opening != it && res.back() == '\\') + { + res.back() = '{'; + it = opening + 1; + } + else + { + auto closing = std::find(it, end, '}'); + if (closing == end) + throw runtime_error("Format string error, unclosed '{'"); + int index; + if (closing == opening + 1) + index = implicitIndex; + else + index = str_to_int({opening+1, closing}); + + if (index >= params.size()) + throw runtime_error("Format string parameter index too big"); + + res += params[index]; + implicitIndex = index+1; + it = closing+1; + } + } + return res; +} + } -- cgit v1.2.3