diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2015-04-25 01:34:31 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2015-04-25 01:35:24 +0200 |
commit | b2cfbf1501e5649dd2cf5348aaced0e9a4231cc4 (patch) | |
tree | 2719313a87c36e9394b01c011c2e99856e268a28 | |
parent | 6ef472beb240d01b8e681735e5c0d4f15a64b0ad (diff) | |
download | xK-b2cfbf1501e5649dd2cf5348aaced0e9a4231cc4.tar.gz xK-b2cfbf1501e5649dd2cf5348aaced0e9a4231cc4.tar.xz xK-b2cfbf1501e5649dd2cf5348aaced0e9a4231cc4.zip |
degesch: refactor wrap_text()
It wasn't very readable.
-rw-r--r-- | degesch.c | 134 |
1 files changed, 68 insertions, 66 deletions
@@ -2406,89 +2406,91 @@ irc_process_message (const struct irc_message *msg, // This is the most basic acceptable algorithm; something like ICU with proper // locale specification would be needed to make it work better. -static bool -wrap_text (const char *message, - int line_max, struct str_vector *output, struct error **e) +static size_t +wrap_text_for_single_line (const char *text, size_t text_len, + size_t line_len, struct str *output) { - // Initialize to the first word, even if it's empty - const char *word_end = message + strcspn (message, " "); + int eaten = 0; - for (int message_left = strlen (message); message_left; ) + // First try going word by word + const char *word_start; + const char *word_end = text + strcspn (text, " "); + size_t word_len = word_end - text; + while (line_len && word_len <= line_len) { - struct str m; - str_init (&m); - - int part_left = MIN (line_max, message_left); - bool empty = true; - - // First try going word by word - const char *word_start; - int word_len = word_end - message; - while (part_left && word_len <= part_left) + if (word_len) { - if (word_len) - { - str_append_data (&m, message, word_len); - message += word_len; - message_left -= word_len; - part_left -= word_len; - empty = false; - } - - // Find the next word's end - word_start = message + strspn (message, " "); - word_end = word_start + strcspn (word_start, " "); - word_len = word_end - message; + str_append_data (output, text, word_len); + + text += word_len; + eaten += word_len; + line_len -= word_len; } - if (!empty) - { - // Discard whitespace between words if split - message_left -= word_start - message; - message = word_start; + // Find the next word's end + word_start = text + strspn (text, " "); + word_end = word_start + strcspn (word_start, " "); + word_len = word_end - text; + } - str_vector_add (output, m.str); - str_free (&m); - continue; - } + if (eaten) + // Discard whitespace between words if split + return eaten + (word_start - text); - // And if that doesn't help, cut the longest valid block of characters. - // Note that we never get to the end of the word, so "word_end" stays. - while (true) - { - const char *next = utf8_next (message, message_left); - hard_assert (next); + // And if that doesn't help, cut the longest valid block of characters + while (true) + { + const char *next = utf8_next (text, text_len - eaten); + hard_assert (next); - int char_len = next - message; - if (char_len > part_left) - break; + size_t char_len = next - text; + if (char_len > line_len) + break; - str_append_data (&m, message, char_len); + str_append_data (output, text, char_len); - message += char_len; - message_left -= char_len; - part_left -= char_len; - empty = false; - } + text += char_len; + eaten += char_len; + line_len -= char_len; + } + return eaten; +} - if (!empty) - str_vector_add (output, m.str); +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - str_free (&m); +static bool +wrap_message (const char *message, + int line_max, struct str_vector *output, struct error **e) +{ + if (line_max <= 0) + goto error; - if (!empty) - continue; + for (size_t message_left = strlen (message); message_left; ) + { + struct str m; + str_init (&m); - // Well, that's just weird - error_set (e, - "Message splitting was unsuccessful as there was " - "too little room for UTF-8 characters"); - return false; + size_t eaten = wrap_text_for_single_line (message, + MIN ((size_t) line_max, message_left), message_left, &m); + if (!eaten) + { + str_free (&m); + goto error; + } + + str_vector_add_owned (output, str_steal (&m)); + message += eaten; + message_left -= eaten; } return true; -} -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +error: + // Well, that's just weird + error_set (e, + "Message splitting was unsuccessful as there was " + "too little room for UTF-8 characters"); + return false; +} /// Automatically splits messages that arrive at other clients with our prefix /// so that they don't arrive cut off by the server @@ -2507,7 +2509,7 @@ irc_autosplit_message (struct app_context *ctx, const char *message, // However we don't always have the full info for message splitting if (!space_in_one_message) str_vector_add (output, message); - else if (!wrap_text (message, space_in_one_message, output, e)) + else if (!wrap_message (message, space_in_one_message, output, e)) return false; return true; } |