diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/irc/irc-info.c | 2 | ||||
-rw-r--r-- | src/plugins/irc/irc-message.c | 161 | ||||
-rw-r--r-- | src/plugins/irc/irc-message.h | 3 | ||||
-rw-r--r-- | src/plugins/irc/irc-notify.c | 41 | ||||
-rw-r--r-- | src/plugins/irc/irc-raw.c | 20 | ||||
-rw-r--r-- | src/plugins/irc/irc-server.c | 79 |
6 files changed, 268 insertions, 38 deletions
diff --git a/src/plugins/irc/irc-info.c b/src/plugins/irc/irc-info.c index 892c1f3ed..c41e2970b 100644 --- a/src/plugins/irc/irc-info.c +++ b/src/plugins/irc/irc-info.c @@ -1192,6 +1192,8 @@ irc_info_init () "\"channel\": channel, " "\"arguments\": arguments (includes channel), " "\"text\": text (for example user message), " + "\"param1\" ... \"paramN\": parsed command parameters, " + "\"num_params\": number of parsed command parameters, " "\"pos_command\": index of \"command\" message (\"-1\" if " "\"command\" was not found), " "\"pos_arguments\": index of \"arguments\" message (\"-1\" if " diff --git a/src/plugins/irc/irc-message.c b/src/plugins/irc/irc-message.c index eeaf91d6a..b80a268d0 100644 --- a/src/plugins/irc/irc-message.c +++ b/src/plugins/irc/irc-message.c @@ -35,6 +35,107 @@ /* + * Parses command arguments and returns: + * - params (array of strings) + * - num_params (integer) + * + * Leading spaces are skipped, trailing spaces are preserved. + * + * Trailing parameters (if starting with ":") are returned as a single + * parameter. + * + * Example: + * + * " #channel nick :trailing parameters " + * + * ==> params[0] == "#channel" + * params[1] == "nick" + * params[2] == "trailing parameters " + * params[3] == NULL + * num_params = 3 + */ + +void +irc_message_parse_params (const char *parameters, + char ***params, int *num_params) +{ + const char *ptr_params, *pos_end, *pos_next; + int alloc_params, trailing; + + if (!params && !num_params) + return; + + if (params) + *params = NULL; + if (num_params) + *num_params = 0; + + if (!parameters) + return; + + alloc_params = 0; + if (params) + { + *params = malloc ((alloc_params + 1) * sizeof ((*params)[0])); + if (!*params) + return; + *params[0] = NULL; + } + + ptr_params = parameters; + while (ptr_params[0] == ' ') + { + ptr_params++; + } + + trailing = 0; + while (1) + { + pos_end = NULL; + if (ptr_params[0] == ':') + { + ptr_params++; + trailing = 1; + } + else + { + pos_end = strchr (ptr_params, ' '); + } + if (!pos_end) + pos_end = ptr_params + strlen (ptr_params); + pos_next = pos_end; + while (pos_next[0] == ' ') + { + pos_next++; + } + if (!pos_next[0]) + pos_end = pos_next; + if (params) + { + alloc_params++; + *params = realloc (*params, + (alloc_params + 1) * sizeof ((*params)[0])); + if (!*params) + return; + (*params)[alloc_params - 1] = weechat_strndup (ptr_params, + pos_end - ptr_params); + (*params)[alloc_params] = NULL; + } + if (num_params) + *num_params += 1; + if (trailing) + break; + ptr_params = pos_end; + while (ptr_params[0] == ' ') + { + ptr_params++; + } + if (!ptr_params[0]) + break; + } +} + +/* * Parses an IRC message and returns: * - tags (string) * - message without tags (string) @@ -44,24 +145,26 @@ * - channel (string) * - arguments (string) * - text (string) + * - params (array of strings) + * - num_params (integer) * - pos_command (integer: command index in message) * - pos_arguments (integer: arguments index in message) * - pos_channel (integer: channel index in message) * - pos_text (integer: text index in message) * * Example: - * @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello! + * @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :Hello world! * * Result: * tags: "time=2015-06-27T16:40:35.000Z" - * msg_without_tags: ":nick!user@host PRIVMSG #weechat :hello!" + * msg_without_tags: ":nick!user@host PRIVMSG #weechat :Hello world!" * nick: "nick" * user: "user" * host: "nick!user@host" * command: "PRIVMSG" * channel: "#weechat" - * arguments: "#weechat :hello!" - * text: "hello!" + * arguments: "#weechat :Hello world!" + * text: "Hello world!" * pos_command: 47 * pos_arguments: 55 * pos_channel: 55 @@ -73,6 +176,7 @@ irc_message_parse (struct t_irc_server *server, const char *message, char **tags, char **message_without_tags, char **nick, char **user, char **host, char **command, char **channel, char **arguments, char **text, + char ***params, int *num_params, int *pos_command, int *pos_arguments, int *pos_channel, int *pos_text) { @@ -96,6 +200,10 @@ irc_message_parse (struct t_irc_server *server, const char *message, *arguments = NULL; if (text) *text = NULL; + if (params) + *params = NULL; + if (num_params) + *num_params = 0; if (pos_command) *pos_command = -1; if (pos_arguments) @@ -113,7 +221,7 @@ irc_message_parse (struct t_irc_server *server, const char *message, /* * we will use this message as example: * - * @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello! + * @time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :Hello world! */ if (ptr_message[0] == '@') @@ -142,7 +250,7 @@ irc_message_parse (struct t_irc_server *server, const char *message, if (message_without_tags) *message_without_tags = strdup (ptr_message); - /* now we have: ptr_message --> ":nick!user@host PRIVMSG #weechat :hello!" */ + /* now we have: ptr_message --> ":nick!user@host PRIVMSG #weechat :Hello world!" */ if (ptr_message[0] == ':') { /* read host/nick */ @@ -185,7 +293,7 @@ irc_message_parse (struct t_irc_server *server, const char *message, } } - /* now we have: ptr_message --> "PRIVMSG #weechat :hello!" */ + /* now we have: ptr_message --> "PRIVMSG #weechat :Hello world!" */ if (ptr_message[0]) { pos = strchr (ptr_message, ' '); @@ -200,11 +308,12 @@ irc_message_parse (struct t_irc_server *server, const char *message, { pos++; } - /* now we have: pos --> "#weechat :hello!" */ + /* now we have: pos --> "#weechat :Hello world!" */ if (arguments) *arguments = strdup (pos); if (pos_arguments) *pos_arguments = pos - message; + irc_message_parse_params (pos, params, num_params); if ((pos[0] == ':') && ((strncmp (ptr_message, "JOIN ", 5) == 0) || (strncmp (ptr_message, "PART ", 5) == 0))) @@ -336,6 +445,8 @@ irc_message_parse (struct t_irc_server *server, const char *message, * - channel * - arguments * - text + * - num_params + * - param1, param2, ..., paramN * - pos_command * - pos_arguments * - pos_channel @@ -349,13 +460,14 @@ irc_message_parse_to_hashtable (struct t_irc_server *server, const char *message) { char *tags, *message_without_tags, *nick, *user, *host, *command, *channel; - char *arguments, *text, str_pos[32]; + char *arguments, *text, **params, str_key[64], str_pos[32]; char empty_str[1] = { '\0' }; - int pos_command, pos_arguments, pos_channel, pos_text; + int i, num_params, pos_command, pos_arguments, pos_channel, pos_text; struct t_hashtable *hashtable; irc_message_parse (server, message, &tags, &message_without_tags, &nick, &user, &host, &command, &channel, &arguments, &text, + ¶ms, &num_params, &pos_command, &pos_arguments, &pos_channel, &pos_text); hashtable = weechat_hashtable_new (32, @@ -384,6 +496,13 @@ irc_message_parse_to_hashtable (struct t_irc_server *server, (arguments) ? arguments : empty_str); weechat_hashtable_set (hashtable, "text", (text) ? text : empty_str); + snprintf (str_pos, sizeof (str_pos), "%d", num_params); + weechat_hashtable_set (hashtable, "num_params", str_pos); + for (i = 0; i < num_params; i++) + { + snprintf (str_key, sizeof (str_key), "param%d", i + 1); + weechat_hashtable_set (hashtable, str_key, params[i]); + } snprintf (str_pos, sizeof (str_pos), "%d", pos_command); weechat_hashtable_set (hashtable, "pos_command", str_pos); snprintf (str_pos, sizeof (str_pos), "%d", pos_arguments); @@ -562,11 +681,23 @@ irc_message_ignored (struct t_irc_server *server, const char *message) return 0; /* parse raw message */ - irc_message_parse (server, message, - NULL, NULL, &nick, NULL, &host, - NULL, &channel, NULL, - NULL, NULL, NULL, - NULL, NULL); + irc_message_parse (server, + message, + NULL, /* tags */ + NULL, /* message_without_tags */ + &nick, + NULL, /* user */ + &host, + NULL, /* command */ + &channel, + NULL, /* arguments */ + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + NULL, /* pos_channel */ + NULL); /* pos_text */ /* remove colors from host */ host_no_color = (host) ? irc_color_decode (host, 0) : NULL; diff --git a/src/plugins/irc/irc-message.h b/src/plugins/irc/irc-message.h index 5b118128b..cb6d168ed 100644 --- a/src/plugins/irc/irc-message.h +++ b/src/plugins/irc/irc-message.h @@ -23,11 +23,14 @@ struct t_irc_server; struct t_irc_channel; +extern void irc_message_parse_params (const char *parameters, + char ***params, int *num_params); extern void irc_message_parse (struct t_irc_server *server, const char *message, char **tags, char **message_without_tags, char **nick, char **user, char **host, char **command, char **channel, char **arguments, char **text, + char ***params, int *num_params, int *pos_command, int *pos_arguments, int *pos_channel, int *pos_text); extern struct t_hashtable *irc_message_parse_to_hashtable (struct t_irc_server *server, diff --git a/src/plugins/irc/irc-notify.c b/src/plugins/irc/irc-notify.c index 53695f173..56d8a2860 100644 --- a/src/plugins/irc/irc-notify.c +++ b/src/plugins/irc/irc-notify.c @@ -868,9 +868,23 @@ irc_notify_hsignal_cb (const void *pointer, void *data, const char *signal, } for (i = 0; i < num_messages; i++) { - irc_message_parse (ptr_server, messages[i], NULL, NULL, NULL, - NULL, NULL, NULL, NULL, &arguments, NULL, - NULL, NULL, NULL, NULL); + irc_message_parse (ptr_server, + messages[i], + NULL, /* tags */ + NULL, /* message_without_tags */ + NULL, /* nick */ + NULL, /* user */ + NULL, /* host */ + NULL, /* command */ + NULL, /* channel */ + &arguments, + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + NULL, /* pos_channel */ + NULL); /* pos_text */ if (arguments) { pos = strchr (arguments, ' '); @@ -966,10 +980,23 @@ irc_notify_hsignal_cb (const void *pointer, void *data, const char *signal, { for (i = 0; i < num_messages; i++) { - irc_message_parse (ptr_server, messages[i], NULL, NULL, - NULL, NULL, NULL, &irc_cmd, NULL, - &arguments, NULL, NULL, NULL, NULL, - NULL); + irc_message_parse (ptr_server, + messages[i], + NULL, /* tags */ + NULL, /* message_without_tags */ + NULL, /* nick */ + NULL, /* user */ + NULL, /* host */ + &irc_cmd, + NULL, /* channel */ + &arguments, + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + NULL, /* pos_channel */ + NULL); /* pos_text */ if (irc_cmd && arguments) { if (strcmp (irc_cmd, "401") == 0) diff --git a/src/plugins/irc/irc-raw.c b/src/plugins/irc/irc-raw.c index c81a0814c..a2a3abde4 100644 --- a/src/plugins/irc/irc-raw.c +++ b/src/plugins/irc/irc-raw.c @@ -160,9 +160,23 @@ irc_raw_message_match_filter (struct t_irc_raw_message *raw_message, else if (strncmp (filter, "m:", 2) == 0) { /* filter by IRC command */ - irc_message_parse (raw_message->server, raw_message->message, - NULL, NULL, NULL, NULL, NULL, &command, NULL, - NULL, NULL, NULL, NULL, NULL, NULL); + irc_message_parse (raw_message->server, + raw_message->message, + NULL, /* tags */ + NULL, /* message_without_tags */ + NULL, /* nick */ + NULL, /* user */ + NULL, /* host */ + &command, + NULL, /* channel */ + NULL, /* arguments */ + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + NULL, /* pos_channel */ + NULL); /* pos_text */ match = (command && (weechat_strcasecmp (command, filter + 2) == 0)) ? 1 : 0; if (command) diff --git a/src/plugins/irc/irc-server.c b/src/plugins/irc/irc-server.c index a0d27bc86..f396c1c9b 100644 --- a/src/plugins/irc/irc-server.c +++ b/src/plugins/irc/irc-server.c @@ -2740,8 +2740,22 @@ irc_server_send_one_msg (struct t_irc_server *server, int flags, ptr_msg = (new_msg) ? new_msg : message; msg_encoded = NULL; - irc_message_parse (server, ptr_msg, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, &pos_channel, + irc_message_parse (server, + ptr_msg, + NULL, /* tags */ + NULL, /* message_without_tags */ + NULL, /* nick */ + NULL, /* user */ + NULL, /* host */ + NULL, /* command */ + NULL, /* channel */ + NULL, /* arguments */ + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + &pos_channel, &pos_text); switch (IRC_SERVER_OPTION_INTEGER(server, IRC_SERVER_OPTION_CHARSET_MESSAGE)) @@ -2957,9 +2971,23 @@ irc_server_sendf (struct t_irc_server *server, int flags, const char *tags, for (i = 0; i < items_count; i++) { /* run modifier "irc_out1_xxx" (like "irc_out_xxx", but before split) */ - irc_message_parse (server, items[i], NULL, NULL, - &nick, NULL, NULL, &command, &channel, NULL, NULL, - NULL, NULL, NULL, NULL); + irc_message_parse (server, + items[i], + NULL, /* tags */ + NULL, /* message_without_tags */ + &nick, + NULL, /* user */ + NULL, /* host */ + &command, + &channel, + NULL, /* arguments */ + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + NULL, /* pos_channel */ + NULL); /* pos_text */ snprintf (str_modifier, sizeof (str_modifier), "irc_out1_%s", (command) ? command : "unknown"); @@ -3224,9 +3252,22 @@ irc_server_msgq_flush () ptr_data); irc_message_parse (irc_recv_msgq->server, - ptr_data, NULL, NULL, NULL, NULL, NULL, - &command, NULL, NULL, NULL, NULL, NULL, - NULL, NULL); + ptr_data, + NULL, /* tags */ + NULL, /* message_without_tags */ + NULL, /* nick */ + NULL, /* user */ + NULL, /* host */ + &command, + NULL, /* channel */ + NULL, /* arguments */ + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + NULL, /* pos_channel */ + NULL); /* pos_text */ snprintf (str_modifier, sizeof (str_modifier), "irc_in_%s", (command) ? command : "unknown"); @@ -3264,11 +3305,23 @@ irc_server_msgq_flush () ptr_msg); } - irc_message_parse (irc_recv_msgq->server, ptr_msg, - NULL, NULL, &nick, NULL, &host, - &command, &channel, &arguments, - NULL, NULL, NULL, - &pos_channel, &pos_text); + irc_message_parse (irc_recv_msgq->server, + ptr_msg, + NULL, /* tags */ + NULL, /* message_without_tags */ + &nick, + NULL, /* user */ + &host, + &command, + &channel, + &arguments, + NULL, /* text */ + NULL, /* params */ + NULL, /* num_params */ + NULL, /* pos_command */ + NULL, /* pos_arguments */ + &pos_channel, + &pos_text); msg_decoded = NULL; |