degesch: refactor MODE processing
This commit is contained in:
		
							
								
								
									
										84
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										84
									
								
								degesch.c
									
									
									
									
									
								
							@@ -3959,24 +3959,18 @@ irc_handle_kick (struct server *s, const struct irc_message *msg)
 | 
			
		||||
 | 
			
		||||
struct mode_processor
 | 
			
		||||
{
 | 
			
		||||
	// Inputs to set after initialization:
 | 
			
		||||
 | 
			
		||||
	char **params;                      ///< Mode string parameters
 | 
			
		||||
	bool adding;                        ///< Currently adding modes
 | 
			
		||||
	char mode_char;                     ///< Currently processed mode char
 | 
			
		||||
 | 
			
		||||
	// User data:
 | 
			
		||||
 | 
			
		||||
	struct server *s;                   ///< Server
 | 
			
		||||
	struct channel *channel;            ///< The channel being modified
 | 
			
		||||
 | 
			
		||||
	// 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);
 | 
			
		||||
}
 | 
			
		||||
/// Process a single mode character
 | 
			
		||||
typedef bool (*mode_processor_fn) (struct mode_processor *, char);
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
mode_processor_next_param (struct mode_processor *self)
 | 
			
		||||
@@ -3986,6 +3980,26 @@ mode_processor_next_param (struct mode_processor *self)
 | 
			
		||||
	return *self->params++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mode_processor_run (struct mode_processor *self,
 | 
			
		||||
	char **params, mode_processor_fn apply_cb)
 | 
			
		||||
{
 | 
			
		||||
	self->params = params;
 | 
			
		||||
 | 
			
		||||
	const char *mode_string;
 | 
			
		||||
	while ((mode_string = mode_processor_next_param (self)))
 | 
			
		||||
	{
 | 
			
		||||
		self->adding = true;
 | 
			
		||||
		while ((self->mode_char = *mode_string++))
 | 
			
		||||
		{
 | 
			
		||||
			if      (self->mode_char == '+') self->adding = true;
 | 
			
		||||
			else if (self->mode_char == '-') self->adding = false;
 | 
			
		||||
			else if (!apply_cb (self, self->mode_char))
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -4068,15 +4082,11 @@ mode_processor_do_param_never (struct mode_processor *self)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
mode_processor_step (struct mode_processor *self, char mode_char)
 | 
			
		||||
mode_processor_apply_channel (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))
 | 
			
		||||
	if      (strchr (s->irc_chanuser_modes,           mode_char))
 | 
			
		||||
		mode_processor_do_user           (self);
 | 
			
		||||
 | 
			
		||||
	else if (strchr (s->irc_chanmodes_list,           mode_char))
 | 
			
		||||
@@ -4099,33 +4109,17 @@ 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;
 | 
			
		||||
	}
 | 
			
		||||
	struct mode_processor p = { .s = s, .channel = channel };
 | 
			
		||||
	mode_processor_run (&p, params, mode_processor_apply_channel);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
mode_processor_step_user (struct mode_processor *self, char mode_char)
 | 
			
		||||
mode_processor_apply_user (struct mode_processor *self, char mode_char)
 | 
			
		||||
{
 | 
			
		||||
	struct server *s = self->s;
 | 
			
		||||
 | 
			
		||||
	if (mode_char == '+') { self->adding = true;  return true; }
 | 
			
		||||
	if (mode_char == '-') { self->adding = false; return true; }
 | 
			
		||||
 | 
			
		||||
	struct str *modes = &s->irc_user_mode;
 | 
			
		||||
	const char *pos = strchr (modes->str, mode_char);
 | 
			
		||||
	if (self->adding == !!pos)
 | 
			
		||||
@@ -4144,20 +4138,8 @@ mode_processor_step_user (struct mode_processor *self, char mode_char)
 | 
			
		||||
static void
 | 
			
		||||
irc_handle_mode_user (struct server *s, char **params)
 | 
			
		||||
{
 | 
			
		||||
	struct mode_processor p;
 | 
			
		||||
	mode_processor_init (&p);
 | 
			
		||||
 | 
			
		||||
	p.params = params;
 | 
			
		||||
	p.s = s;
 | 
			
		||||
 | 
			
		||||
	const char *mode_string;
 | 
			
		||||
	while ((mode_string = mode_processor_next_param (&p)))
 | 
			
		||||
	{
 | 
			
		||||
		mode_processor_step (&p, '+');
 | 
			
		||||
		while (*mode_string)
 | 
			
		||||
			if (!mode_processor_step_user (&p, *mode_string++))
 | 
			
		||||
				break;
 | 
			
		||||
	}
 | 
			
		||||
	struct mode_processor p = { .s = s };
 | 
			
		||||
	mode_processor_run (&p, params, mode_processor_apply_user);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user