/* Routines for processing message tokens. * * IRC Services is copyright (c) 1996-2007 Andrew Church. * E-mail: * Parts written by Andrew Kempe and others. * This program is free but copyrighted software; see the file COPYING for * details. */ #include "services.h" #include "modules.h" #include "messages.h" #include "token.h" /*************************************************************************/ static Module *module; /* Array of all possible 1- and 2-character tokens. */ static MessageFunc tokentable[65536]; /* Macro to get the token array entry for a given token. May be used as * an lvalue. */ #define TOKEN_ENTRY(token) \ tokentable[(uint8)((token)[0])<<8 | (uint8)((token)[1])] /* Dummy value to indicate a recognized-but-has-no-handler message. */ #define MSGFUNC_NONE ((MessageFunc)-1) /*************************************************************************/ /*************************************************************************/ /* Callback to check for and handle tokens. */ static int do_receive_message(char *source, char *cmd, int ac, char **av) { MessageFunc func; if ((cmd[1] && cmd[2]) || !(func = TOKEN_ENTRY(cmd))) return 0; if (func != MSGFUNC_NONE) func(source, ac, av); return 1; } /*************************************************************************/ /* Set up token handling. */ int init_token(Module *module_, TokenInfo *tokens) { int32 i; module = module_; /* Clear out token array, then copy token handler functions into array. * ANSI says NULL might not be binary 0, and this section isn't * particularly speed-critical, so we don't use memset(). */ for (i = 0; i < 65536; i++) tokentable[i] = NULL; for (i = 0; tokens[i].token; i++) { if (strlen(tokens[i].token) > 2) { module_log("warning: init_token(): token name `%s' too long" " (maximum 2 characters)", tokens[i].token); } else if (tokens[i].message) { Message *m = find_message(tokens[i].message); if (m) { TOKEN_ENTRY(tokens[i].token) = m->func ? m->func : MSGFUNC_NONE; } } } /* Add receive-message callback. */ if (!add_callback(NULL, "receive message", do_receive_message)) { module_log("Unable to add callback"); return 0; } return 1; } /*************************************************************************/ /* Clean up on module unload. */ void exit_token(void) { remove_callback(NULL, "receive message", do_receive_message); } /*************************************************************************/