~rcr/rirc

dec876940ebc67047b1f6fafb4b6f60a78308265 — Richard Robbins a month ago 3e7e541
cleanup mode prfxmode handling
4 files changed, 29 insertions(+), 75 deletions(-)

M src/components/mode.c
M src/components/mode.h
M src/handlers/irc_recv.c
M test/components/mode.c
M src/components/mode.c => src/components/mode.c +13 -41
@@ 145,15 145,23 @@ mode_chanmode_set(struct mode *m, const struct mode_cfg *cfg, int flag, int set)
enum mode_err
mode_prfxmode_set(struct mode *m, const struct mode_cfg *cfg, int flag, int set)
{
	/* Set/unset prfxmode flags and mode prefix */

	if (!strchr(cfg->PREFIX.F, flag))
		return MODE_ERR_INVALID_FLAG;
	/* Set/unset prfxmode flag or prefix */

	const char *f = cfg->PREFIX.F;
	const char *t = cfg->PREFIX.T;

	mode_set(m, flag, set);
	while (*f && *t && *f != flag && *t != flag) {
		f++;
		t++;
	}

	if (!*f || !*t)
		return MODE_ERR_INVALID_FLAG;

	mode_set(m, *f, set);

	f = cfg->PREFIX.F;
	t = cfg->PREFIX.T;

	while (*f) {



@@ 182,42 190,6 @@ mode_usermode_set(struct mode *m, const struct mode_cfg *cfg, int flag, int set)
	return MODE_ERR_NONE;
}

enum mode_err
mode_prfxmode_prefix(struct mode *m, const struct mode_cfg *cfg, int flag)
{
	/* Set prfxmode flag and prefix given the prefix character, e.g.: 
	 *
	 * - if "ov" maps to "@+", then:
	 *   - prfxmode_prefix(cfg, mode, '@')   sets mode flag 'o'
	 *   - prfxmode_prefix(cfg, mode, '+')   sets mode flag 'v'
	 */

	const char *f = cfg->PREFIX.F;
	const char *t = cfg->PREFIX.T;

	while (*t && *t != flag) {
		f++;
		t++;
	}

	if (*t == 0)
		return MODE_ERR_INVALID_PREFIX;

	mode_set(m, *f, 1);

	f = cfg->PREFIX.F,
	t = cfg->PREFIX.T;

	while (!mode_isset(m, *f)) {
		f++;
		t++;
	}

	m->prefix = *t;

	return MODE_ERR_NONE;
}

const char*
mode_str(const struct mode *m, struct mode_str *m_str)
{

M src/components/mode.h => src/components/mode.h +0 -1
@@ 108,7 108,6 @@ const char* mode_str(const struct mode*, struct mode_str*);

enum mode_err mode_cfg(struct mode_cfg*, const char*, enum mode_cfg_type);
enum mode_err mode_chanmode_set(struct mode*, const struct mode_cfg*, int, int);
enum mode_err mode_prfxmode_prefix(struct mode*, const struct mode_cfg*, int);
enum mode_err mode_prfxmode_set(struct mode*, const struct mode_cfg*, int, int);
enum mode_err mode_usermode_set(struct mode*, const struct mode_cfg*, int, int);


M src/handlers/irc_recv.c => src/handlers/irc_recv.c +1 -1
@@ 560,7 560,7 @@ irc_numeric_353(struct server *s, struct irc_message *m)

		struct mode m = MODE_EMPTY;

		while (mode_prfxmode_prefix(&m, &(s->mode_cfg), *nick) == MODE_ERR_NONE)
		while (mode_prfxmode_set(&m, &(s->mode_cfg), *nick, 1) == MODE_ERR_NONE)
			nick++;

		if (*nick == 0)

M test/components/mode.c => test/components/mode.c +15 -32
@@ 101,42 101,12 @@ test_mode_chanmode_set(void)
}

static void
test_mode_prfxmode_prefix(void)
{
	/* Test setting prfxmode by prefix */

	struct mode m = MODE_EMPTY;
	struct mode_str str = { .type = MODE_STR_PRFXMODE };

	struct mode_cfg cfg = {
		.PREFIX = {
			.F = "abc",
			.T = "123"
		}
	};

	mode_cfg_chanmodes(&cfg, "abc");

	/* Test setting invalid prfxmode prefix */
	assert_eq(mode_prfxmode_prefix(&m, &cfg, 0),   MODE_ERR_INVALID_PREFIX);
	assert_eq(mode_prfxmode_prefix(&m, &cfg, '0'), MODE_ERR_INVALID_PREFIX);
	assert_eq(mode_prfxmode_prefix(&m, &cfg, '4'), MODE_ERR_INVALID_PREFIX);

	/* Test setting valid prfxmode prefix */
	assert_eq(mode_prfxmode_prefix(&m, &cfg, '2'), MODE_ERR_NONE);
	assert_eq(mode_prfxmode_prefix(&m, &cfg, '3'), MODE_ERR_NONE);

	assert_strcmp(mode_str(&m, &str), "bc");
	assert_eq(m.prefix, '2');
}

static void
test_mode_prfxmode_set(void)
{
	/* Test setting/unsetting prfxmode flag and prefix */

	struct mode m = MODE_EMPTY;

	struct mode_str str = { .type = MODE_STR_PRFXMODE };
	struct mode_cfg cfg = {
		.PREFIX = {
			.F = "abc",


@@ 152,6 122,12 @@ test_mode_prfxmode_set(void)
	assert_eq(mode_prfxmode_set(&m, &cfg, 'd', 0), MODE_ERR_INVALID_FLAG);
	assert_eq(m.prefix, 0);

	/* Test setting/unsetting invalid prfxmode prefix */
	assert_eq(mode_prfxmode_set(&m, &cfg, '4', 1), MODE_ERR_INVALID_FLAG);
	assert_eq(m.prefix, 0);
	assert_eq(mode_prfxmode_set(&m, &cfg, '4', 0), MODE_ERR_INVALID_FLAG);
	assert_eq(m.prefix, 0);

	/* Test setting valid flags respects PREFIX precedence */
	assert_eq(mode_prfxmode_set(&m, &cfg, 'b', 1), MODE_ERR_NONE);
	assert_eq(m.prefix, '2');


@@ 167,6 143,14 @@ test_mode_prfxmode_set(void)
	assert_eq(m.prefix, '3');
	assert_eq(mode_prfxmode_set(&m, &cfg, 'c', 0), MODE_ERR_NONE);
	assert_eq(m.prefix, 0);

	/* Test setting valid prefixes */
	assert_eq(mode_prfxmode_set(&m, &cfg, '2', 1), MODE_ERR_NONE);
	assert_eq(m.prefix, '2');
	assert_eq(mode_prfxmode_set(&m, &cfg, '3', 1), MODE_ERR_NONE);
	assert_eq(m.prefix, '2');

	assert_strcmp(mode_str(&m, &str), "bc");
}

static void


@@ 406,7 390,6 @@ main(void)
		TESTCASE(test_mode_bit),
		TESTCASE(test_mode_str),
		TESTCASE(test_mode_chanmode_set),
		TESTCASE(test_mode_prfxmode_prefix),
		TESTCASE(test_mode_prfxmode_set),
		TESTCASE(test_mode_usermode_set),
		TESTCASE(test_mode_cfg_usermodes),