commit 0128db9: [Minor] Simplify string wrap algorithm

Vsevolod Stakhov vsevolod at rspamd.com
Sun Jan 22 13:07:03 UTC 2023


Author: Vsevolod Stakhov
Date: 2023-01-22 13:02:44 +0000
URL: https://github.com/rspamd/rspamd/commit/0128db9e5cb057c34adaad7c25619107104707e0

[Minor] Simplify string wrap algorithm
Submitted by: @amishmm
Closes: #4378

---
 src/client/rspamc.cxx | 42 +++++++++++++++---------------------------
 1 file changed, 15 insertions(+), 27 deletions(-)

diff --git a/src/client/rspamc.cxx b/src/client/rspamc.cxx
index a2bf4c783..c725dcd90 100644
--- a/src/client/rspamc.cxx
+++ b/src/client/rspamc.cxx
@@ -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
 	}
 }
 


More information about the Commits mailing list