/* Routines for processing message tokens.
*
* IRC Services is copyright (c) 1996-2007 Andrew Church.
* E-mail: <achurch@achurch.org>
* 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);
}
/*************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1