Implement parsing of IRC 3.2 message tags

It's still in the making and we don't use it, but let's not fail on it if e.g.
a plugin decides to enable it.
This commit is contained in:
Přemysl Eric Janouch 2014-07-12 19:27:37 +02:00
parent 651d49ca9b
commit 1edcbc5f3d
1 changed files with 43 additions and 3 deletions

View File

@ -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);