~rcr/rirc

654efd8a4279488d5a4c0e939580b8b36b86f236 — Richard Robbins 2 months ago 12f1e22
add ircv3 cap key=val parsing
4 files changed, 49 insertions(+), 8 deletions(-)

M src/components/ircv3.c
M src/components/ircv3.h
M src/handlers/ircv3.c
M test/handlers/ircv3.c
M src/components/ircv3.c => src/components/ircv3.c +4 -0
@@ 1,5 1,6 @@
#include "src/components/ircv3.h"

#include <stdlib.h>
#include <string.h>

struct ircv3_cap*


@@ 18,6 19,7 @@ void
ircv3_caps(struct ircv3_caps *caps)
{
	#define X(CAP, VAR, ATTRS) \
	caps->VAR.val = NULL; \
	caps->VAR.req = 0; \
	caps->VAR.set = 0; \
	caps->VAR.supported = 0; \


@@ 32,6 34,8 @@ void
ircv3_caps_reset(struct ircv3_caps *caps)
{
	#define X(CAP, VAR, ATTRS) \
	free((void *)caps->VAR.val); \
	caps->VAR.val = NULL; \
	caps->VAR.req = 0; \
	caps->VAR.set = 0; \
	caps->VAR.supported = 0;

M src/components/ircv3.h => src/components/ircv3.h +1 -0
@@ 26,6 26,7 @@

struct ircv3_cap
{
	const char *val;           /* cap key=val */
	unsigned req          : 1; /* cap REQ sent */
	unsigned req_auto     : 1; /* cap REQ sent automatically */
	unsigned set          : 1; /* cap is unset/set */

M src/handlers/ircv3.c => src/handlers/ircv3.c +10 -4
@@ 68,7 68,8 @@ ircv3_recv_cap_LS(struct server *s, struct irc_message *m)
	 * CAP <targ> LS [*] :[<cap_1> [...]]
	 */

	char *cap;
	char *cap_key;
	char *cap_val;
	char *caps;
	char *multiline;



@@ 94,14 95,18 @@ ircv3_recv_cap_LS(struct server *s, struct irc_message *m)
		return 0;
	}

	while ((cap = irc_strsep(&(caps)))) {
	while ((cap_key = irc_strsep(&(caps)))) {

		struct ircv3_cap *c;

		if (!(c = ircv3_cap_get(&(s->ircv3_caps), cap)))
		if ((cap_val = strchr(cap_key, '=')))
			*cap_val++ = 0;

		if (!(c = ircv3_cap_get(&(s->ircv3_caps), cap_key)))
			continue;

		c->supported = 1;
		c->val = (cap_val ? strdup(cap_val) : NULL);

		if (c->req_auto)
			c->req = 1;


@@ 217,7 222,8 @@ ircv3_recv_cap_ACK(struct server *s, struct irc_message *m)
		c->req = 0;
		c->set = !unset;

		server_info(s, "capability change accepted: %s%s", (unset ? "-" : ""), cap);
		server_info(s, "capability change accepted: %s%s%s%s",
			(unset ? "-" : ""), cap, (c->val ? "=" : ""), (c->val ? c->val : ""));

	} while ((cap = irc_strsep(&(caps))));


M test/handlers/ircv3.c => test/handlers/ircv3.c +34 -4
@@ 135,6 135,20 @@ test_ircv3_CAP_LS(void)
	assert_eq(s->ircv3_caps.cap_2.supported, 1);
	assert_eq(s->ircv3_caps.cap_3.supported, 1);

	/* test cap key=val */
	mock_reset();
	ircv3_caps_reset(&(s->ircv3_caps));
	IRC_MESSAGE_PARSE("CAP * LS :cap-1=foo cap-3 cap-4=bar");
	assert_eq(irc_recv(s, &m), 0);
	assert_eq(mock_send_n, 1);
	assert_strcmp(mock_send[0], "CAP REQ :cap-1 cap-3 cap-4");
	assert_eq(s->ircv3_caps.cap_1.supported, 1);
	assert_eq(s->ircv3_caps.cap_3.supported, 1);
	assert_eq(s->ircv3_caps.cap_4.supported, 1);
	assert_strcmp(s->ircv3_caps.cap_1.val, "foo");
	assert_strcmp(s->ircv3_caps.cap_3.val, NULL);
	assert_strcmp(s->ircv3_caps.cap_4.val, "bar");

	/* test multiline */
	mock_reset();
	ircv3_caps_reset(&(s->ircv3_caps));


@@ 254,7 268,23 @@ test_ircv3_CAP_ACK(void)
	assert_eq(mock_line_n, 1);
	assert_strcmp(mock_line[0], "CAP ACK: parameter is empty");

	/* unregisterd, error */
	/* test ack key=val */
	mock_reset();
	s->ircv3_caps.cap_1.req = 1;
	s->ircv3_caps.cap_2.req = 1;
	s->ircv3_caps.cap_3.req = 1;
	s->ircv3_caps.cap_1.val = strdup("foo");
	s->ircv3_caps.cap_3.val = strdup("bar");
	IRC_MESSAGE_PARSE("CAP * ACK :cap-1 cap-2 cap-3");
	assert_eq(irc_recv(s, &m), 0);
	assert_eq(mock_send_n, 1);
	assert_eq(mock_line_n, 3);
	assert_strcmp(mock_line[0], "capability change accepted: cap-1=foo");
	assert_strcmp(mock_line[1], "capability change accepted: cap-2");
	assert_strcmp(mock_line[2], "capability change accepted: cap-3=bar");
	assert_strcmp(mock_send[0], "CAP END");

	/* test unregisterd, error */
	mock_reset();
	s->ircv3_caps.cap_1.set = 0;
	s->ircv3_caps.cap_2.set = 0;


@@ 270,7 300,7 @@ test_ircv3_CAP_ACK(void)
	assert_strcmp(mock_line[3], "CAP ACK: 'cap-bbb' not supported");
	assert_strcmp(mock_line[4], "CAP ACK: parameter errors");

	/* unregistered, no error */
	/* test unregistered, no error */
	mock_reset();
	s->ircv3_caps.cap_1.set = 0;
	s->ircv3_caps.cap_2.set = 1;


@@ 293,7 323,7 @@ test_ircv3_CAP_ACK(void)
	assert_strcmp(mock_line[2], "capability change accepted: -cap-3");
	assert_strcmp(mock_send[0], "CAP END");

	/* registered, error */
	/* test registered, error */
	mock_reset();
	s->registered = 1;
	s->ircv3_caps.cap_1.set = 0;


@@ 314,7 344,7 @@ test_ircv3_CAP_ACK(void)
	assert_strcmp(mock_line[3], "CAP ACK: '-cap-4' was not requested");
	assert_strcmp(mock_line[4], "CAP ACK: parameter errors");

	/* registered, no error */
	/* test registered, no error */
	mock_reset();
	s->registered = 1;
	s->ircv3_caps.cap_1.set = 0;