[Implement `bot:channel-users' Scheme function clinton@unknownlamer.org**20090224080204 Ignore-this: b85ffcca945a431327c5d83212b29528 Returns a list of users in a channel. The user objects are opaque and should only be accessed via the accessors: * `bot:channel-user-nick' user => nickname * `bot:channel-user-user/host' user => user@host string * `bot:channel-user-mode' user => channel mode bitvector The channel mode bitvector may further inspected using: * `bot:channel-user-has-modes?' user . modes => boolean Where MODES is a list of mode identifiers. Valid values are: * `bot:mode/op' * `bot:mode/voice' * `bot:mode/away' * `bot:mode/ircop' Convenience functions for checking individual mode flags are available: * `bot:channel-user-op?' user => boolean * `bot:channel-user-voice?' user => boolean * `bot:channel-user-away?' user => boolean * `bot:channel-user-ircop' user => boolean Additionally some futzing with other bits are included because C++ is an evil language and I had to beat it gently with a hammer until it did what I wanted. ] { hunk ./scripts/bobot-utils.scm 12 -(use-modules (srfi srfi-13)) +(use-modules (srfi srfi-1) + (srfi srfi-13)) hunk ./scripts/bobot-utils.scm 129 + +;;; bot:channel-users user object accessors +(define-public (bot:channel-user-nick cu) + (first cu)) + +(define-public (bot:channel-user-user/host cu) + (second cu)) + +(define-public (bot:channel-user-mode cu) + (third cu)) + +(define-public (bot:channel-user-has-modes? cu . modes) + (let ((mode (apply logior modes))) + (= (logand (bot:channel-user-mode cu)) mode mode))) + +(define-public (bot:channel-user-op? cu) + (bot:channel-user-has-modes? cu bot:mode/op)) + +(define-public (bot:channel-user-voice? cu) + (bot:channel-user-has-modes? cu bot:mode/voice)) + +(define-public (bot:channel-user-away? cu) + (bot:channel-user-has-modes? cu bot:mode/away)) hunk ./scripts/bobot-utils.scm 153 - +(define-public (bot:channel-user-ircop? cu) + (bot:channel-user-has-modes? cu bot:mode/op)) hunk ./source/ChannelUserList.H 74 - void foreach (const T & fun) + void foreach (T & fun) hunk ./source/Interp.C 134 + // user channel modes + scm_c_define ("bot:mode/op", scm_from_int (User::OP_MODE)); + scm_c_define ("bot:mode/voice", scm_from_int (User::VOICE_MODE)); + scm_c_define ("bot:mode/away", scm_from_int (User::AWAY_MODE)); + scm_c_define ("bot:mode/ircop", scm_from_int (User::IRCOP_MODE)); + hunk ./source/Interp.C 208 + scm_c_define_gsubr ("bot:channel-users", 1, 0, 0, + (SCMFunc)ScriptCommands::ChannelUsers); hunk ./source/ScriptCommands.C 3 -// Copyright (C) 2002,2005,2008 Clinton Ebadi +// Copyright (C) 2002,2005,2008,2009 Clinton Ebadi hunk ./source/ScriptCommands.C 32 +#include "ChannelList.H" hunk ./source/ScriptCommands.C 185 + +void +ScriptCommands::collect_channel_users::operator() (SCM *list, User user) + const +{ + *list = scm_cons (scm_list_n (Utils::str2scm (user.get_nick()), + Utils::str2scm (user.get_userhost ()), + scm_from_int (user.get_mode ()), + SCM_UNDEFINED), + *list); +} + +SCM +ScriptCommands::ChannelUsers (SCM channel_name) +{ + VERIFY_STRING (channel_name); + + Channel *channel = Interp::bot->channelList->getChannel (Utils::scm2str (channel_name)); + + if (!channel) + return SCM_BOOL_F; + + SCM* list = (SCM*)scm_gc_malloc (sizeof (SCM), "ScriptCommands::ChannelUsers"); + *list = SCM_EOL; + + collect_channel_users c; + + channel->for_each_channel_users (std::bind1st (c, list)); + + scm_remember_upto_here_1 (list); + return scm_reverse_x (*list, SCM_UNDEFINED); +} + hunk ./source/ScriptCommands.H 31 +#include + +class User; + hunk ./source/ScriptCommands.H 43 + static SCM ChannelUsers (SCM); hunk ./source/ScriptCommands.H 117 +private: + struct collect_channel_users : std::binary_function + { + void operator() (SCM*, User) const; + }; hunk ./source/User.H 70 + std::string get_nick () const { return nick; } + std::string get_userhost () const { return userhost; } + int get_mode () const { return mode; } + hunk ./source/User.H 81 + friend class ScriptCommands; }