summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/irc/irc-info.c2
-rw-r--r--src/plugins/irc/irc-message.c161
-rw-r--r--src/plugins/irc/irc-message.h3
-rw-r--r--src/plugins/irc/irc-notify.c41
-rw-r--r--src/plugins/irc/irc-raw.c20
-rw-r--r--src/plugins/irc/irc-server.c79
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,
+ &params, &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;