diff options
-rw-r--r-- | degesch.c | 56 |
1 files changed, 43 insertions, 13 deletions
@@ -2722,27 +2722,57 @@ send_message_to_target (struct app_context *ctx, return; } - int one_message = 0; + // We don't always have the full info for message splitting + int space_in_one_message = 0; if (ctx->irc_user_host) // :<nick>!<user>@<host> PRIVMSG <target> :<message> - one_message = 510 - 1 - (int) strlen (ctx->irc_user->nickname) + space_in_one_message = 510 + - 1 - (int) strlen (ctx->irc_user->nickname) - 1 - (int) strlen (ctx->irc_user_host) - 1 - 7 - 1 - strlen (target) - 1 - 1; - // FIXME: UTF-8 sequences - int left = strlen (message); - while (left) + // Attempt to split the message if it doesn't completely fit into + // a single IRC protocol message while trying not to break UTF-8. + // Unicode can still end up being wrong, though. + // TODO: at least try to word-wrap if nothing else + for (int message_left = strlen (message); message_left; ) { - int part = MIN (one_message, left); - if (!one_message) - part = left; + struct str m; + str_init (&m); - irc_send (ctx, "PRIVMSG %s :%.*s", target, part, message); - buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0, - ctx->irc_user->nickname, NULL, "%.*s", part, message); + int part_left = MIN (space_in_one_message, message_left); + if (!space_in_one_message) + part_left = message_left; + + bool empty = true; + while (true) + { + const char *next = utf8_next (message, message_left); + hard_assert (next); + + int char_len = message - next; + if (char_len > part_left) + break; + + str_append_data (&m, message, char_len); - left -= part; - message += part; + message += char_len; + message_left -= char_len; + empty = false; + } + if (empty) + { + // Well, that's just weird + buffer_send_error (ctx, buffer, "%s", + "Message splitting was unsuccessful as there was " + "too little room for UTF-8 characters"); + message_left = 0; + } + + irc_send (ctx, "PRIVMSG %s :%s", target, m.str); + buffer_send (ctx, buffer, BUFFER_LINE_PRIVMSG, 0, + ctx->irc_user->nickname, NULL, "%s", m.str); + str_free (&m); } } |