summaryrefslogtreecommitdiff
path: root/src/string.cc
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2015-03-30 23:05:24 +0100
committerMaxime Coste <frrrwww@gmail.com>2015-03-30 23:05:24 +0100
commit13a5af70aebd85f5c21cba346f22eadd98fe333c (patch)
tree3f628b894fe7dbb76026e219def4294cfc3cc44a /src/string.cc
parent8761fc34f4dedee89f8cd61be8d08845d09f211e (diff)
Add a format function for printf like formatting
Diffstat (limited to 'src/string.cc')
-rw-r--r--src/string.cc42
1 files changed, 42 insertions, 0 deletions
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<StringView> wrap_lines(StringView text, CharCount max_width)
return lines;
}
+String format(StringView fmt, ArrayView<const StringView> 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;
+}
+
}