Only compile regex's once

This commit is contained in:
2014-07-13 04:30:23 +02:00
parent 4904128c98
commit 475c83618a
3 changed files with 126 additions and 70 deletions

View File

@@ -118,6 +118,7 @@ enum
struct bot_context
{
struct str_map config; ///< User configuration
regex_t *admin_re; ///< Regex to match our administrator
int irc_fd; ///< Socket FD of the server
struct str read_buffer; ///< Input yet to be processed
@@ -140,6 +141,7 @@ bot_context_init (struct bot_context *self)
str_map_init (&self->config);
self->config.free = free;
load_config_defaults (&self->config, g_config_table);
self->admin_re = NULL;
self->irc_fd = -1;
str_init (&self->read_buffer);
@@ -160,6 +162,8 @@ static void
bot_context_free (struct bot_context *self)
{
str_map_free (&self->config);
if (self->admin_re)
regex_free (self->admin_re);
str_free (&self->read_buffer);
// TODO: terminate the plugins properly before this is called
@@ -1110,25 +1114,10 @@ is_private_message (const struct irc_message *msg)
static bool
is_sent_by_admin (struct bot_context *ctx, const struct irc_message *msg)
{
const char *admin = str_map_find (&ctx->config, "admin");
// No administrator set -> everyone is an administrator
if (!admin)
if (!ctx->admin_re)
return true;
// TODO: precompile the regex
struct error *e = NULL;
if (regex_match (admin, msg->prefix, NULL))
return true;
if (e)
{
print_error ("%s: %s", "invalid admin mask", e->message);
error_free (e);
return true;
}
return false;
return regexec (ctx->admin_re, msg->prefix, 0, NULL, 0) != REG_NOMATCH;
}
static void respond_to_user (struct bot_context *ctx, const struct
@@ -1591,6 +1580,26 @@ irc_connect (struct bot_context *ctx, struct error **e)
return true;
}
static bool
load_admin_regex (struct bot_context *ctx)
{
hard_assert (!ctx->admin_re);
const char *admin = str_map_find (&ctx->config, "admin");
if (!admin)
return true;
struct error *e = NULL;
ctx->admin_re = regex_compile (admin, REG_EXTENDED | REG_NOSUB, &e);
if (!e)
return true;
print_error ("invalid configuration value for `%s': %s",
"admin", e->message);
error_free (e);
return false;
}
static void
on_signal_pipe_readable (const struct pollfd *fd, struct bot_context *ctx)
{
@@ -1758,6 +1767,8 @@ main (int argc, char *argv[])
(poller_dispatcher_func) on_signal_pipe_readable, &ctx);
plugin_load_all_from_config (&ctx);
if (!load_admin_regex (&ctx))
exit (EXIT_FAILURE);
if (!irc_connect (&ctx, &e))
{
print_error ("%s", e->message);