Add format_to allowing formating to an existing buffer
This commit is contained in:
parent
8ff63198bc
commit
f6c7948c12
|
@ -231,10 +231,13 @@ void write_buffer_to_backup_file(Buffer& buffer)
|
|||
StringView dir, file;
|
||||
std::tie(dir,file) = split_path(path);
|
||||
|
||||
String pattern = dir.empty() ? format(".{}.kak.XXXXXX", file)
|
||||
: format("{}/.{}.kak.XXXXXX", dir, file);
|
||||
char pattern[PATH_MAX];
|
||||
if (dir.empty())
|
||||
format_to(pattern, ".{}.kak.XXXXXX", file);
|
||||
else
|
||||
format_to(pattern, "{}/.{}.kak.XXXXXX", dir, file);
|
||||
|
||||
int fd = mkstemp(&pattern[0]);
|
||||
int fd = mkstemp(pattern);
|
||||
if (fd >= 0)
|
||||
{
|
||||
write_buffer_to_fd(buffer, fd);
|
||||
|
|
|
@ -214,29 +214,28 @@ Vector<StringView> wrap_lines(StringView text, CharCount max_width)
|
|||
return lines;
|
||||
}
|
||||
|
||||
String format(StringView fmt, ArrayView<const StringView> params)
|
||||
template<typename AppendFunc>
|
||||
void format_impl(StringView fmt, ArrayView<const StringView> params, AppendFunc append)
|
||||
{
|
||||
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 && *(opening-1) == '\\')
|
||||
{
|
||||
res.back() = '{';
|
||||
append(StringView{it, opening});
|
||||
break;
|
||||
}
|
||||
else if (opening != it and *(opening-1) == '\\')
|
||||
{
|
||||
append(StringView{it, opening-1});
|
||||
append('{');
|
||||
it = opening + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto closing = std::find(it, end, '}');
|
||||
append(StringView{it, opening});
|
||||
auto closing = std::find(opening, end, '}');
|
||||
if (closing == end)
|
||||
throw runtime_error("Format string error, unclosed '{'");
|
||||
int index;
|
||||
|
@ -248,11 +247,40 @@ String format(StringView fmt, ArrayView<const StringView> params)
|
|||
if (index >= params.size())
|
||||
throw runtime_error("Format string parameter index too big");
|
||||
|
||||
res += params[index];
|
||||
append(params[index]);
|
||||
implicitIndex = index+1;
|
||||
it = closing+1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
char* ptr = buffer.begin();
|
||||
const char* end = buffer.end();
|
||||
format_impl(fmt, params, [&](StringView s) mutable {
|
||||
for (auto c : s)
|
||||
{
|
||||
if (ptr == end)
|
||||
throw runtime_error("buffer is too small");
|
||||
*ptr++ = c;
|
||||
}
|
||||
});
|
||||
if (ptr == end)
|
||||
throw runtime_error("buffer is too small");
|
||||
*ptr = 0;
|
||||
|
||||
return { buffer.begin(), ptr };
|
||||
}
|
||||
|
||||
String format(StringView fmt, ArrayView<const StringView> params)
|
||||
{
|
||||
ByteCount size = fmt.length();
|
||||
for (auto& s : params) size += s.length();
|
||||
String res;
|
||||
res.reserve(size);
|
||||
|
||||
format_impl(fmt, params, [&](StringView s) { res += s; });
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -311,6 +311,14 @@ String format(StringView fmt, Types... params)
|
|||
return format(fmt, ArrayView<const StringView>{detail::format_param(params)...});
|
||||
}
|
||||
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, ArrayView<const StringView> params);
|
||||
|
||||
template<typename... Types>
|
||||
StringView format_to(ArrayView<char> buffer, StringView fmt, Types... params)
|
||||
{
|
||||
return format_to(buffer, fmt, ArrayView<const StringView>{detail::format_param(params)...});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // string_hh_INCLUDED
|
||||
|
|
|
@ -140,6 +140,9 @@ void test_string()
|
|||
|
||||
kak_assert(format("Youhou {1} {} {0} \\{}", 10, "hehe", 5) == "Youhou hehe 5 10 {}");
|
||||
|
||||
char buffer[20];
|
||||
kak_assert(format_to(buffer, "Hey {}", 15) == "Hey 15");
|
||||
|
||||
kak_assert(str_to_int("5") == 5);
|
||||
kak_assert(str_to_int(to_string(INT_MAX)) == INT_MAX);
|
||||
kak_assert(str_to_int(to_string(INT_MIN)) == INT_MIN);
|
||||
|
|
Loading…
Reference in New Issue
Block a user