diff options
Diffstat (limited to 'src/string_utils.cc')
| -rw-r--r-- | src/string_utils.cc | 244 |
1 files changed, 1 insertions, 243 deletions
diff --git a/src/string_utils.cc b/src/string_utils.cc index c614d485..d533a12b 100644 --- a/src/string_utils.cc +++ b/src/string_utils.cc @@ -3,9 +3,7 @@ #include "exception.hh" #include "utf8_iterator.hh" #include "unit_tests.hh" - -#include <charconv> -#include <cstdio> +#include "ranges.hh" namespace Kakoune { @@ -147,88 +145,6 @@ int str_to_int(StringView str) throw runtime_error{str + " is not a number"}; } -template<size_t N> -InplaceString<N> to_string_impl(auto val, auto format) -{ - InplaceString<N> res; - auto [end, errc] = std::to_chars(res.m_data, res.m_data + N, val, format); - if (errc != std::errc{}) - throw runtime_error("to_string error"); - res.m_length = end - res.m_data; - *end = '\0'; - return res; -} - -template<size_t N> -InplaceString<N> to_string_impl(auto val) -{ - return to_string_impl<N>(val, 10); -} - -InplaceString<15> to_string(int val) -{ - return to_string_impl<15>(val); -} - -InplaceString<15> to_string(unsigned val) -{ - return to_string_impl<15>(val); -} - -InplaceString<23> to_string(long int val) -{ - return to_string_impl<23>(val); -} - -InplaceString<23> to_string(long long int val) -{ - return to_string_impl<23>(val); -} - -InplaceString<23> to_string(unsigned long val) -{ - return to_string_impl<23>(val); -} - -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) - return to_string_impl<23>(val, std::chars_format::general); -#else - InplaceString<23> res; - res.m_length = snprintf(res.m_data, 23, "%f", val); - return res; -#endif -} - -InplaceString<7> to_string(Codepoint c) -{ - InplaceString<7> res; - char* ptr = res.m_data; - utf8::dump(ptr, c); - res.m_length = (int)(ptr - res.m_data); - return res; -} - bool subsequence_match(StringView str, StringView subseq) { auto it = str.begin(); @@ -270,149 +186,6 @@ String expand_tabs(StringView line, ColumnCount tabstop, ColumnCount col) return res; } -WrapView::Iterator::Iterator(StringView text, ColumnCount max_width) - : m_remaining{text}, m_max_width{max_width} -{ - if (max_width <= 0) - throw runtime_error("Invalid max width"); - ++*this; -} - -WrapView::Iterator& WrapView::Iterator::operator++() -{ - using Utf8It = utf8::iterator<const char*>; - Utf8It it{m_remaining.begin(), m_remaining}; - Utf8It last_word_end = it; - - while (it != m_remaining.end()) - { - const CharCategories cat = categorize(*it, {'_'}); - if (cat == CharCategories::EndOfLine) - { - m_current = StringView{m_remaining.begin(), it.base()}; - m_remaining = StringView{(it+1).base(), m_remaining.end()}; - return *this; - } - - Utf8It word_end = it+1; - while (word_end != m_remaining.end() and categorize(*word_end, {'_'}) == cat) - ++word_end; - - if (word_end > m_remaining.begin() and - utf8::column_distance(m_remaining.begin(), word_end.base()) >= m_max_width) - { - auto line_end = last_word_end <= m_remaining.begin() ? - Utf8It{utf8::advance(m_remaining.begin(), m_remaining.end(), m_max_width), m_remaining} - : last_word_end; - - m_current = StringView{m_remaining.begin(), line_end.base()}; - - while (line_end != m_remaining.end() and is_horizontal_blank(*line_end)) - ++line_end; - - if (line_end != m_remaining.end() and *line_end == '\n') - ++line_end; - - m_remaining = StringView{line_end.base(), m_remaining.end()}; - return *this; - } - if (cat == CharCategories::Word or cat == CharCategories::Punctuation) - last_word_end = word_end; - - if (word_end > m_remaining.begin()) - it = word_end; - } - m_current = m_remaining; - m_remaining = StringView{}; - return *this; -} - -template<typename AppendFunc> -void format_impl(StringView fmt, ArrayView<const StringView> params, AppendFunc append) -{ - int implicitIndex = 0; - for (auto it = fmt.begin(), end = fmt.end(); it != end;) - { - auto opening = std::find(it, end, '{'); - if (opening == end) - { - append(StringView{it, opening}); - break; - } - else if (opening != it and *(opening-1) == '\\') - { - append(StringView{it, opening-1}); - append('{'); - it = opening + 1; - } - else - { - append(StringView{it, opening}); - auto closing = std::find(opening, end, '}'); - if (closing == end) - throw runtime_error("format string error, unclosed '{'"); - - 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) - { - char padding = ' '; - if (*(++format) == '0') - { - padding = '0'; - ++format; - } - for (ColumnCount width = str_to_int({format, closing}), len = params[index].column_length(); - width > len; --width) - append(padding); - } - - 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 }; -} - -void format_with(FunctionRef<void (StringView)> append, StringView fmt, ArrayView<const StringView> params) -{ - format_impl(fmt, params, append); -} - -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; -} - String double_up(StringView s, StringView characters) { String res; @@ -444,21 +217,6 @@ UnitTest test_string{[]() kak_assert(StringView{"youpi"}.ends_with("youpi")); kak_assert(not StringView{"youpi"}.ends_with("oup")); - auto wrapped = "wrap this paragraph\n respecting whitespaces and much_too_long_words" | wrap_at(16) | gather<Vector<String>>(); - kak_assert(wrapped.size() == 6); - kak_assert(wrapped[0] == "wrap this"); - kak_assert(wrapped[1] == "paragraph"); - kak_assert(wrapped[2] == " respecting"); - kak_assert(wrapped[3] == "whitespaces and"); - kak_assert(wrapped[4] == "much_too_long_wo"); - kak_assert(wrapped[5] == "rds"); - - auto wrapped2 = "error: unknown type" | wrap_at(7) | gather<Vector<String>>(); - kak_assert(wrapped2.size() == 3); - kak_assert(wrapped2[0] == "error:"); - kak_assert(wrapped2[1] == "unknown"); - kak_assert(wrapped2[2] == "type"); - kak_assert(trim_indent(" ") == ""); kak_assert(trim_indent("no-indent") == "no-indent"); kak_assert(trim_indent("\nno-indent") == "no-indent"); |
