diff --git a/src/common.c b/src/common.c index be523a9..ae5814f 100644 --- a/src/common.c +++ b/src/common.c @@ -1483,18 +1483,57 @@ xssl_get_error (SSL *ssl, int result, const char **error_info) struct irc_message { - char *prefix; - char *command; - struct str_vector params; + struct str_map tags; ///< IRC 3.2 message tags + char *prefix; ///< Message prefix + char *command; ///< IRC command + struct str_vector params; ///< Command parameters }; +static void +irc_parse_message_tags (const char *tags, struct str_map *out) +{ + struct str_vector v; + str_vector_init (&v); + split_str_ignore_empty (tags, ';', &v); + + for (size_t i = 0; i < v.len; i++) + { + char *key = v.vector[i], *equal_sign = strchr (key, '='); + if (equal_sign) + { + *equal_sign = '\0'; + str_map_set (out, key, xstrdup (equal_sign + 1)); + } + else + str_map_set (out, key, xstrdup ("")); + } + + str_vector_free (&v); +} + static void irc_parse_message (struct irc_message *msg, const char *line) { + str_map_init (&msg->tags); + msg->tags.free = free; + msg->prefix = NULL; msg->command = NULL; str_vector_init (&msg->params); + // IRC 3.2 message tags + if (*line == '@') + { + size_t tags_len = strcspn (++line, " "); + char *tags = xstrndup (line, tags_len); + irc_parse_message_tags (tags, &msg->tags); + free (tags); + + line += tags_len; + while (*line == ' ') + line++; + } + // Prefix if (*line == ':') { @@ -1537,6 +1576,7 @@ irc_parse_message (struct irc_message *msg, const char *line) static void irc_free_message (struct irc_message *msg) { + str_map_free (&msg->tags); free (msg->prefix); free (msg->command); str_vector_free (&msg->params);