degesch: hack together preliminary MODE parsing
This commit is contained in:
parent
9b1664f968
commit
c8aff23ab2
171
degesch.c
171
degesch.c
|
@ -3826,8 +3826,6 @@ irc_is_highlight (struct server *s, const char *message)
|
||||||
|
|
||||||
// --- Input handling ----------------------------------------------------------
|
// --- Input handling ----------------------------------------------------------
|
||||||
|
|
||||||
// TODO: we will need a proper mode parser; to be shared with kike
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_handle_join (struct server *s, const struct irc_message *msg)
|
irc_handle_join (struct server *s, const struct irc_message *msg)
|
||||||
{
|
{
|
||||||
|
@ -3932,6 +3930,170 @@ irc_handle_kick (struct server *s, const struct irc_message *msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
struct mode_processor
|
||||||
|
{
|
||||||
|
// Inputs to set after initialization:
|
||||||
|
|
||||||
|
char **params; ///< Mode string parameters
|
||||||
|
|
||||||
|
struct server *s; ///< Who does the changes
|
||||||
|
struct channel *channel; ///< The channel we're modifying
|
||||||
|
|
||||||
|
// Internals:
|
||||||
|
|
||||||
|
bool adding; ///< Currently adding modes
|
||||||
|
char mode_char; ///< Currently processed mode char
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
mode_processor_init (struct mode_processor *self)
|
||||||
|
{
|
||||||
|
memset (self, 0, sizeof *self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
mode_processor_next_param (struct mode_processor *self)
|
||||||
|
{
|
||||||
|
if (!*self->params)
|
||||||
|
return NULL;
|
||||||
|
return *self->params++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mode_processor_do_user (struct mode_processor *self)
|
||||||
|
{
|
||||||
|
const char *nickname;
|
||||||
|
struct user *user;
|
||||||
|
if (!(nickname = mode_processor_next_param (self))
|
||||||
|
|| !(user = str_map_find (&self->s->irc_users, nickname)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TODO: factor out, also use in unlink_user or whatever
|
||||||
|
struct channel_user *channel_user = NULL;
|
||||||
|
LIST_FOR_EACH (struct channel_user, iter, self->channel->users)
|
||||||
|
if (iter->user == user)
|
||||||
|
channel_user = iter;
|
||||||
|
if (!channel_user)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char prefix = self->s->irc_chanuser_prefixes
|
||||||
|
[strchr (self->s->irc_chanuser_modes, self->mode_char)
|
||||||
|
- self->s->irc_chanuser_modes];
|
||||||
|
|
||||||
|
// XXX: shouldn't this rather be a "struct str"?
|
||||||
|
char *modes = channel_user->modes;
|
||||||
|
char *pos = strchr (modes, self->mode_char);
|
||||||
|
if (self->adding == !!pos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (self->adding)
|
||||||
|
{
|
||||||
|
// FIXME: this doesn't give two fucks about the correct order
|
||||||
|
channel_user->modes = xstrdup_printf ("%s%c", modes, prefix);
|
||||||
|
free (modes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memmove (pos, pos + 1, strlen (pos + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mode_processor_do_param_always (struct mode_processor *self)
|
||||||
|
{
|
||||||
|
const char *param = NULL;
|
||||||
|
if (!(param = mode_processor_next_param (self)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
char key[2] = { self->mode_char, 0 };
|
||||||
|
if (self->adding)
|
||||||
|
str_map_set (&self->channel->param_modes, key, xstrdup (param));
|
||||||
|
else
|
||||||
|
str_map_set (&self->channel->param_modes, key, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mode_processor_do_param_when_set (struct mode_processor *self)
|
||||||
|
{
|
||||||
|
const char *param = NULL;
|
||||||
|
if (self->adding && !(param = mode_processor_next_param (self)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
char key[2] = { self->mode_char, 0 };
|
||||||
|
if (self->adding)
|
||||||
|
str_map_set (&self->channel->param_modes, key, xstrdup (param));
|
||||||
|
else
|
||||||
|
str_map_set (&self->channel->param_modes, key, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mode_processor_do_param_never (struct mode_processor *self)
|
||||||
|
{
|
||||||
|
struct str *modes = &self->channel->no_param_modes;
|
||||||
|
const char *pos = strchr (modes->str, self->mode_char);
|
||||||
|
if (self->adding == !!pos)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (self->adding)
|
||||||
|
{
|
||||||
|
str_append_c (modes, self->mode_char);
|
||||||
|
// TODO: sort the modes
|
||||||
|
}
|
||||||
|
else
|
||||||
|
str_remove_slice (modes, pos - modes->str, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
mode_processor_step (struct mode_processor *self, char mode_char)
|
||||||
|
{
|
||||||
|
struct server *s = self->s;
|
||||||
|
self->mode_char = mode_char;
|
||||||
|
|
||||||
|
if (mode_char == '+') self->adding = true;
|
||||||
|
else if (mode_char == '-') self->adding = false;
|
||||||
|
|
||||||
|
else if (strchr (s->irc_chanuser_modes, mode_char))
|
||||||
|
mode_processor_do_user (self);
|
||||||
|
|
||||||
|
else if (strchr (s->irc_chanmodes_list, mode_char))
|
||||||
|
// Nothing to do here, really
|
||||||
|
(void) mode_processor_next_param (self);
|
||||||
|
|
||||||
|
else if (strchr (s->irc_chanmodes_param_always, mode_char))
|
||||||
|
mode_processor_do_param_always (self);
|
||||||
|
else if (strchr (s->irc_chanmodes_param_when_set, mode_char))
|
||||||
|
mode_processor_do_param_when_set (self);
|
||||||
|
else if (strchr (s->irc_chanmodes_param_never, mode_char))
|
||||||
|
mode_processor_do_param_never (self);
|
||||||
|
else
|
||||||
|
// It's not safe to continue, results could be undesired
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static void
|
||||||
|
irc_handle_mode_channel
|
||||||
|
(struct server *s, struct channel *channel, char **params)
|
||||||
|
{
|
||||||
|
struct mode_processor p;
|
||||||
|
mode_processor_init (&p);
|
||||||
|
|
||||||
|
p.params = params;
|
||||||
|
p.s = s;
|
||||||
|
p.channel = channel;
|
||||||
|
|
||||||
|
const char *mode_string;
|
||||||
|
while ((mode_string = mode_processor_next_param (&p)))
|
||||||
|
{
|
||||||
|
mode_processor_step (&p, '+');
|
||||||
|
while (*mode_string)
|
||||||
|
if (!mode_processor_step (&p, *mode_string++))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_handle_mode (struct server *s, const struct irc_message *msg)
|
irc_handle_mode (struct server *s, const struct irc_message *msg)
|
||||||
{
|
{
|
||||||
|
@ -3950,7 +4112,7 @@ irc_handle_mode (struct server *s, const struct irc_message *msg)
|
||||||
char *modes = irc_to_utf8 (s->ctx, reconstructed);
|
char *modes = irc_to_utf8 (s->ctx, reconstructed);
|
||||||
free (reconstructed);
|
free (reconstructed);
|
||||||
|
|
||||||
// TODO: parse the mode change and apply it
|
// TODO: parse the mode change and apply it (our user & channel user modes)
|
||||||
|
|
||||||
if (irc_is_channel (s, context))
|
if (irc_is_channel (s, context))
|
||||||
{
|
{
|
||||||
|
@ -3959,6 +4121,9 @@ irc_handle_mode (struct server *s, const struct irc_message *msg)
|
||||||
hard_assert ((channel && buffer) ||
|
hard_assert ((channel && buffer) ||
|
||||||
(channel && !buffer) || (!channel && !buffer));
|
(channel && !buffer) || (!channel && !buffer));
|
||||||
|
|
||||||
|
if (channel)
|
||||||
|
irc_handle_mode_channel (s, channel, msg->params.vector + 1);
|
||||||
|
|
||||||
// FIXME: logging
|
// FIXME: logging
|
||||||
if (buffer)
|
if (buffer)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue