From 57d6297a35f52a61a803bb042eb64011333ef8ad Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Sun, 23 Mar 2008 11:50:47 -0400 Subject: [PATCH] Check for and use appropriate type of variadic macro arguments. src/common.h: Define GCC_VARMACROS and C99_VARMACROS where appropriate. src/chanserv.c (DEFINE_COMMAND): src/global.c (global_notice): Likewise. src/helpfile.h (send_channel_message): Likewise. (send_channel_notice): Likewise. (send_channel_wallops): Likewise. src/mod-blacklist.c (blacklist_debug): Likewise. src/mod-helpserv.c (helpserv_msguser): Likewise. (helpserv_user_reply): Likewise. (helpserv_notice): Likewise. (helpserv_notify): Likewise. (helpserv_page): Likewise. (helpserv_get_page_type): New helper function to reduce size of the expanded code for helpserv_page(). src/mod-snoop.c (SNOOP): Expand appropriately for varmacros type. src/modcmd.h (reply): Likewise. src/opserv.c (opserv_debug): Likewise. (opserv_alert): Likewise. (opserv_custom_alert): Likewise. --- src/chanserv.c | 6 ++++- src/common.h | 8 +++++- src/global.c | 6 ++++- src/helpfile.h | 12 ++++++--- src/mod-blacklist.c | 6 ++++- src/mod-helpserv.c | 61 ++++++++++++++++++++++++++++++++------------- src/mod-snoop.c | 6 ++++- src/modcmd.h | 9 ++++--- src/opserv.c | 12 ++++++--- 9 files changed, 94 insertions(+), 32 deletions(-) diff --git a/src/chanserv.c b/src/chanserv.c index 4fc9bb9..971fbd8 100644 --- a/src/chanserv.c +++ b/src/chanserv.c @@ -7716,7 +7716,11 @@ chanserv_db_cleanup(void) { } } -#define DEFINE_COMMAND(NAME, MIN_ARGC, FLAGS, OPTIONS...) modcmd_register(chanserv_module, #NAME, cmd_##NAME, MIN_ARGC, FLAGS, ## OPTIONS) +#if defined(GCC_VARMACROS) +# define DEFINE_COMMAND(NAME, MIN_ARGC, FLAGS, ARGS...) modcmd_register(chanserv_module, #NAME, cmd_##NAME, MIN_ARGC, FLAGS, ARGS) +#elif defined(C99_VARMACROS) +# define DEFINE_COMMAND(NAME, MIN_ARGC, FLAGS, ...) modcmd_register(chanserv_module, #NAME, cmd_##NAME, MIN_ARGC, FLAGS, __VA_ARGS__) +#endif #define DEFINE_CHANNEL_OPTION(NAME) modcmd_register(chanserv_module, "set "#NAME, chan_opt_##NAME, 1, 0, NULL) #define DEFINE_USER_OPTION(NAME) modcmd_register(chanserv_module, "uset "#NAME, user_opt_##NAME, 1, MODCMD_REQUIRE_REGCHAN, NULL) diff --git a/src/common.h b/src/common.h index 09bc4d1..f8e4de5 100644 --- a/src/common.h +++ b/src/common.h @@ -41,7 +41,7 @@ extern struct tm *localtime_r(const time_t *clock, struct tm *res); #define ArrayLength(x) (sizeof(x)/sizeof(x[0])) #define safestrncpy(dest, src, len) do { char *d = (dest); const char *s = (src); size_t l = strlen(s)+1; if ((len) < l) l = (len); memmove(d, s, l); d[l-1] = 0; } while (0) -#ifdef __GNUC__ +#if __GNUC__ #define PRINTF_LIKE(M,N) __attribute__((format (printf, M, N))) #else #define PRINTF_LIKE(M,N) @@ -56,6 +56,12 @@ extern struct tm *localtime_r(const time_t *clock, struct tm *res); #define UNUSED_ARG(ARG) ARG #endif +#if defined(__GNUC__) && (__GNUC__ < 3) +# define GCC_VARMACROS 1 +#elif !defined(S_SPLINT_S) +# define C99_VARMACROS 1 +#endif + #if defined(WITH_MALLOC_DMALLOC) # define DMALLOC_FUNC_CHECK 1 # include diff --git a/src/global.c b/src/global.c index 69ab616..cadbf3c 100644 --- a/src/global.c +++ b/src/global.c @@ -94,7 +94,11 @@ static struct unsigned long db_backup_frequency; } global_conf; -#define global_notice(target, format...) send_message(target , global , ## format) +#if defined(GCC_VARMACROS) +# define global_notice(target, ARGS...) send_message(target, global, ARGS) +#elif defined(C99_VARMACROS) +# define global_notice(target, ...) send_message(target, global, __VA_ARGS__) +#endif void message_expire(void *data); diff --git a/src/helpfile.h b/src/helpfile.h index 4833d80..435f5b4 100644 --- a/src/helpfile.h +++ b/src/helpfile.h @@ -86,9 +86,15 @@ int send_help(struct userNode *dest, struct userNode *src, struct helpfile *hf, * irc_send is either irc_privmsg or irc_notice; NULL means figure it out. */ void table_send(struct userNode *from, const char *to, unsigned int size, irc_send_func irc_send, struct helpfile_table table); -#define send_channel_message(CHANNEL, ARGS...) send_target_message(5, (CHANNEL)->name, ARGS) -#define send_channel_notice(CHANNEL, ARGS...) send_target_message(4, (CHANNEL)->name, ARGS) -#define send_channel_wallchops(CHANNEL, ARGS...) send_target_message(6, (CHANNEL)->name, ARGS) +#if defined(GCC_VARMACROS) +# define send_channel_message(CHANNEL, ARGS...) send_target_message(5, (CHANNEL)->name, ARGS) +# define send_channel_notice(CHANNEL, ARGS...) send_target_message(4, (CHANNEL)->name, ARGS) +# define send_channel_wallchops(CHANNEL, ARGS...) send_target_message(6, (CHANNEL)->name, ARGS) +#elif defined(C99_VARMACROS) +# define send_channel_message(CHANNEL, ...) send_target_message(5, (CHANNEL)->name, __VA_ARGS__) +# define send_channel_notice(CHANNEL, ...) send_target_message(4, (CHANNEL)->name, __VA_ARGS__) +# define send_channel_wallchops(CHANNEL, ...) send_target_message(6, (CHANNEL)->name, __VA_ARGS__) +#endif struct message_entry { diff --git a/src/mod-blacklist.c b/src/mod-blacklist.c index 5c39a1e..0e8efbe 100644 --- a/src/mod-blacklist.c +++ b/src/mod-blacklist.c @@ -52,7 +52,11 @@ static struct { unsigned long gline_duration; } conf; -#define blacklist_debug(format...) do { if (conf.debug_bot && conf.debug_channel) send_channel_notice(conf.debug_channel , conf.debug_bot , ## format); } while (0) +#if defined(GCC_VARMACROS) +# define blacklist_debug(ARGS...) do { if (conf.debug_bot && conf.debug_channel) send_channel_notice(conf.debug_channel, conf.debug_bot, ARGS); } while (0) +#elif defined(C99_VARMACROS) +# define blacklist_debug(...) do { if (conf.debug_bot && conf.debug_channel) send_channel_notice(conf.debug_channel, conf.debug_bot, __VA_ARGS__); } while (0) +#endif static void do_expandos(char *output, unsigned int out_len, const char *input, ...) diff --git a/src/mod-helpserv.c b/src/mod-helpserv.c index b211da2..7eabafd 100644 --- a/src/mod-helpserv.c +++ b/src/mod-helpserv.c @@ -623,31 +623,37 @@ static HELPSERV_FUNC(cmd_help); return 0; } /* For messages going to users being helped */ -#define helpserv_msguser(target, format...) send_message_type((from_opserv ? 0 : hs->privmsg_only), (target), (from_opserv ? opserv : hs->helpserv) , ## format) -#define helpserv_user_reply(format...) send_message_type(req->hs->privmsg_only, req->user, req->hs->helpserv , ## format) +#if defined(GCC_VARMACROS) +# define helpserv_msguser(target, ARGS...) send_message_type((from_opserv ? 0 : hs->privmsg_only), (target), (from_opserv ? opserv : hs->helpserv), ARGS) +# define helpserv_user_reply(ARGS...) send_message_type(req->hs->privmsg_only, req->user, req->hs->helpserv, ARGS) /* For messages going to helpers */ -#define helpserv_notice(target, format...) send_message((target), (from_opserv ? opserv : hs->helpserv) , ## format) -#define helpserv_notify(helper, format...) do { struct userNode *_target; for (_target = (helper)->handle->users; _target; _target = _target->next_authed) { \ - send_message(_target, (helper)->hs->helpserv, ## format); \ +# define helpserv_notice(target, ARGS...) send_message((target), (from_opserv ? opserv : hs->helpserv), ARGS) +# define helpserv_notify(helper, ARGS...) do { struct userNode *_target; for (_target = (helper)->handle->users; _target; _target = _target->next_authed) { \ + send_message(_target, (helper)->hs->helpserv, ARGS); \ } } while (0) +# define helpserv_page(TYPE, ARGS...) do { \ + int msg_type=0; struct chanNode *target=helpserv_get_page_type(hs, (TYPE), &msg_type); \ + if (target) send_target_message(msg_type, target->name, hs->helpserv, ARGS); \ + } while (0) +#elif defined(C99_VARMACROS) +# define helpserv_msguser(target, ...) send_message_type((from_opserv ? 0 : hs->privmsg_only), (target), (from_opserv ? opserv : hs->helpserv), __VA_ARGS__) +# define helpserv_user_reply(...) send_message_type(req->hs->privmsg_only, req->user, req->hs->helpserv, __VA_ARGS__) +/* For messages going to helpers */ +# define helpserv_notice(target, ...) send_message((target), (from_opserv ? opserv : hs->helpserv), __VA_ARGS__) +# define helpserv_notify(helper, ...) do { struct userNode *_target; for (_target = (helper)->handle->users; _target; _target = _target->next_authed) { \ + send_message(_target, (helper)->hs->helpserv, __VA_ARGS__); \ + } } while (0) +# define helpserv_page(TYPE, ...) do { \ + int msg_type=0; struct chanNode *target=helpserv_get_page_type(hs, (TYPE), &msg_type); \ + if (target) send_target_message(msg_type, target->name, hs->helpserv, __VA_ARGS__); \ + } while (0) +#endif #define helpserv_message(hs, target, id) do { if ((hs)->messages[id]) { \ if (from_opserv) \ send_message_type(4, (target), opserv, "%s", (hs)->messages[id]); \ else \ send_message_type(4 | hs->privmsg_only, (target), hs->helpserv, "%s", (hs)->messages[id]); \ } } while (0) -#define helpserv_page(TYPE, FORMAT...) do { \ - struct chanNode *target=NULL; int msg_type=0; \ - target = hs->page_targets[TYPE]; \ - switch (hs->page_types[TYPE]) { \ - case PAGE_NOTICE: msg_type = 0; break; \ - case PAGE_PRIVMSG: msg_type = 1; break; \ - case PAGE_ONOTICE: msg_type = 2; break; \ - default: log_module(HS_LOG, LOG_ERROR, "helpserv_page() called but %s has an invalid page type %d.", hs->helpserv->nick, TYPE); \ - case PAGE_NONE: target = NULL; break; \ - } \ - if (target) send_target_message(msg_type, target->name, hs->helpserv, ## FORMAT); \ - } while (0) #define helpserv_get_handle_info(user, text) smart_get_handle_info((from_opserv ? opserv : hs->helpserv) , (user), (text)) struct helpserv_cmd { @@ -725,6 +731,27 @@ static void helpserv_log_request(struct helpserv_request *req, const char *reaso } } +static struct chanNode *helpserv_get_page_type(struct helpserv_bot *hs, enum page_source type, int *msg_type) +{ + switch (hs->page_types[type]) { + case PAGE_NOTICE: + *msg_type = 0; + break; + case PAGE_PRIVMSG: + *msg_type = 1; + break; + case PAGE_ONOTICE: + *msg_type = 2; + break; + default: + log_module(HS_LOG, LOG_ERROR, "helpserv_page() called but %s has an invalid page type %d.", hs->helpserv->nick, type); + /* and fall through */ + case PAGE_NONE: + return NULL; + } + return hs->page_targets[type]; +} + /* Searches for a request by number, nick, or account (num|nick|*account). * As there can potentially be >1 match, it takes a reqlist. The return * value is the "best" request found (explained in the comment block below). diff --git a/src/mod-snoop.c b/src/mod-snoop.c index 899309d..84ecd66 100644 --- a/src/mod-snoop.c +++ b/src/mod-snoop.c @@ -54,7 +54,11 @@ const char *snoop_module_deps[] = { NULL }; static int finalized; int snoop_finalize(void); -#define SNOOP(FORMAT, ARGS...) send_channel_message(snoop_cfg.channel, snoop_cfg.bot, "%s "FORMAT, timestamp , ## ARGS) +#if defined(GCC_VARMACROS) +# define SNOOP(FORMAT, ARGS...) send_channel_message(snoop_cfg.channel, snoop_cfg.bot, "%s "FORMAT, timestamp, ARGS) +#elif defined(C99_VARMACROS) +# define SNOOP(FORMAT, ...) send_channel_message(snoop_cfg.channel, snoop_cfg.bot, "%s "FORMAT, timestamp, __VA_ARGS__) +#endif #define UPDATE_TIMESTAMP() do { time_t feh = now; strftime(timestamp, sizeof(timestamp), "[%H:%M:%S]", localtime(&feh)); } while (0) static void diff --git a/src/modcmd.h b/src/modcmd.h index 9ef35dc..a2996ab 100644 --- a/src/modcmd.h +++ b/src/modcmd.h @@ -38,11 +38,12 @@ typedef SVCMSG_HOOK(svcmsg_hook_t); DECLARE_LIST(svccmd_list, struct svccmd*); DECLARE_LIST(module_list, struct module*); -#if defined(__GNUC__) && (__GNUC__ < 3) -#define reply(FMT...) send_message(user, cmd->parent->bot, FMT) -#elif !defined(S_SPLINT_S) /* doesn't recognize C99 variadic macros */ -#define reply(...) send_message(user, cmd->parent->bot, __VA_ARGS__) +#if defined(GCC_VARMACROS) +# define reply(ARGS...) send_message(user, cmd->parent->bot, ARGS) +#elif defined(C99_VARMACROS) +# define reply(...) send_message(user, cmd->parent->bot, __VA_ARGS__) #endif + #define modcmd_get_handle_info(USER, NAME) smart_get_handle_info(cmd->parent->bot, USER, NAME) #define modcmd_chanmode_announce(CHANGE) mod_chanmode_announce(cmd->parent->bot, channel, CHANGE) #define modcmd_chanmode(ARGV, ARGC, FLAGS) mod_chanmode(cmd->parent->bot, channel, ARGV, ARGC, FLAGS) diff --git a/src/opserv.c b/src/opserv.c index 10c6c45..689b72a 100644 --- a/src/opserv.c +++ b/src/opserv.c @@ -380,9 +380,15 @@ opserv_free_user_alert(void *data) free(alert); } -#define opserv_debug(format...) do { if (opserv_conf.debug_channel) send_channel_notice(opserv_conf.debug_channel , opserv , ## format); } while (0) -#define opserv_alert(format...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel , opserv , ## format); } while (0) -#define opserv_custom_alert(chan, format...) do { if (chan) send_target_message(4 , chan , opserv , ## format); else if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel , opserv , ## format); } while (0) +#if defined(GCC_VARMACROS) +# define opserv_debug(ARGS...) do { if (opserv_conf.debug_channel) send_channel_notice(opserv_conf.debug_channel, opserv, ARGS); } while (0) +# define opserv_alert(ARGS...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, ARGS); } while (0) +# define opserv_custom_alert(CHAN, ARGS...) do { if (CHAN) send_target_message(4, (CHAN), opserv, ARGS); else if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, ARGS); } while (0) +#elif defined(C99_VARMACROS) +# define opserv_debug(...) do { if (opserv_conf.debug_channel) send_channel_notice(opserv_conf.debug_channel, opserv, __VA_ARGS__); } while (0) +# define opserv_alert(...) do { if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, __VA_ARGS__); } while (0) +# define opserv_custom_alert(chan, ...) do { if (chan) send_target_message(4, chan, opserv, __VA_ARGS__); else if (opserv_conf.alert_channel) send_channel_notice(opserv_conf.alert_channel, opserv, __VA_ARGS__); } while (0) +#endif /* A lot of these commands are very similar to what ChanServ can do, * but OpServ can do them even on channels that aren't registered. -- 2.20.1