]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Simplify string wrap algorithm
authorVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 22 Jan 2023 13:02:44 +0000 (13:02 +0000)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 22 Jan 2023 13:02:44 +0000 (13:02 +0000)
Submitted by: @amishmm
Closes: #4378
src/client/rspamc.cxx

index a2bf4c783c0bec14bb9752eb4a244a944272b6c3..c725dcd9007082a9306b6149a466fb4936a91326 100644 (file)
@@ -831,41 +831,29 @@ rspamc_print_indented_line(FILE *out, std::string_view line) -> void
 {
        static_assert(maxlen > 0, "maxlen must be > 0");
        static_assert(maxlen > indent, "maxlen must be more than indent");
+       using namespace std::literals;
+
+       constexpr const auto whitespace = " \f\n\r\t\v"sv;
+       constexpr const auto break_begin = " \f\n\r\t\v?.,;\"'<({[~!@#$%^&*+:-_=/\\|"sv;
+       constexpr const auto break_end = " \f\n\r\t\v?.,;\"']})>~!@#$%^&*+:-_=/\\|"sv;
 
        for (size_t pos = 0; pos < line.size(); ) {
-               /*
-                * First, find the longest sequence of words, delimited by space of punctuation,
-                * and adjust `maxlen` if needed
-                */
-               auto split_len = pos ? (maxlen-indent) : maxlen;
-               auto word_len = 0ul;
-               auto suffix = line.substr(pos);
-               for (;;) {
-                       auto delim_pos = suffix.find_first_of(" \t,;[]():");
-                       if (word_len + delim_pos + 1 < split_len && delim_pos != std::string_view::npos && delim_pos < suffix.size()) {
-                               word_len += delim_pos + 1;
-                               suffix = suffix.substr(delim_pos + 1);
-                       }
-                       else {
-                               /* Check if we can include one last word */
-                               if (delim_pos == std::string_view::npos && word_len + suffix.size() < split_len) {
-                                       word_len += suffix.size();
-                               }
-                               break;
+               auto len = pos ? (maxlen-indent) : maxlen;
+               auto s = line.substr(pos, len);
+               if (s.size() == len && // is string long enough?
+                       (pos + s.size()) < line.size() && // reached EOL?
+                       line.find_first_of(break_begin, pos + s.size()) != 0 // new word next?
+                       ) {
+                       auto wrap_at = s.find_last_of(break_end);
+                       if (wrap_at != std::string_view::npos) {
+                               s = line.substr(pos, wrap_at + 1);
                        }
                }
-
-               if (word_len > 0 && word_len < split_len && line.size() + pos > split_len) {
-                       split_len = word_len;
-               }
-
-               auto s = line.substr(pos, split_len);
                if (indent && pos) {
                        fmt::print(out, "{:>{}}", " ", indent);
                }
-
                fmt::print(out, "{}\n", s);
-               pos += s.size();
+               pos = line.find_first_not_of(whitespace, pos + s.size()); //skip leading whitespace
        }
 }