1 // BotInterp.C -*- C++ -*-
2 // Copyright (c) 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005 Clinton Ebadi
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "BotInterp.H"
33 #include <libguile/regex-posix.h>
36 BotInterp::BotInterp(Bot *b, String fn)
39 logPort = scm_open_file (Utils::str2scm (fn),
40 Utils::str2scm ("a"));
42 scm_gc_protect_object(logPort);
46 BotInterp::Execute(String command)
48 Interp::Execute(bot, command);
52 BotInterp::LoadScript(String filename)
54 Interp::LoadScript(bot, filename);
58 BotInterp::ScriptLog()
65 bool hptr_lt (const Hook* h, const Hook* h1)
66 // Hook Pointer less than
67 // Used to sort the Hooks list
72 BotInterp::AddHook(int hooktype, SCM regex, SCM function, int pri, bool fall,
74 if (scm_string_p(regex) == SCM_BOOL_F)
76 String rx = Utils::to_upper (Utils::scm2str (regex));
77 SCM r = scm_make_regexp(regex,
78 scm_listify (gh_lookup("regexp/icase"),
80 scm_gc_protect_object(r);
81 scm_gc_protect_object(function);
82 // First, we check if an hook doesn't exist yet
83 std::list<Hook *>::iterator it = hooksMap[hooktype].begin();
84 std::list<Hook *>::iterator it2 = hooksMap[hooktype].end();
86 for ( ; it != it2; ++it)
87 // It exists, we replace it.
88 if ((*it)->regex_str == rx && (*it)->name == name) {
89 scm_gc_unprotect_object((*it)->function);
90 scm_gc_unprotect_object (r);
91 (*it)->function = function;
92 (*it)->priority = pri;
93 (*it)->fallthru = fall;
94 hooksMap[hooktype].sort (hptr_lt);
97 // It does not exist, we create it
98 hooksMap[hooktype].push_back (new Hook(hooktype, rx, r,
99 function, pri, fall, name));
100 hooksMap[hooktype].sort (hptr_lt);
105 BotInterp::RunHooks(int hooktype, String match, SCM args)
108 // We want to execute higher priority hooks first, so we start at
109 // the end of the list instead of the beggining
110 std::list<Hook *>::reverse_iterator it = hooksMap[hooktype].rbegin();
111 std::list<Hook *>::reverse_iterator it2 = hooksMap[hooktype].rend();
114 for ( ; it != it2; ++it) {
115 if (scm_regexp_exec((*it)->regex, Utils::str2scm (match),
116 SCM_UNDEFINED, SCM_UNDEFINED) != SCM_BOOL_F)
118 wd.func = (*it)->function;
119 result = scm_internal_catch(SCM_BOOL_T,
121 Interp::LazyApplyWrapper,
122 static_cast<void *> (&wd),
123 (scm_t_catch_handler) Interp::EmptyHandler, 0);
124 if (! (*it)->fallthru)
132 BotInterp::AddTimer(int delay, SCM function)
134 int when = time(NULL) + delay;
136 scm_gc_protect_object(function);
137 Timer *t = new Timer(c, when, function);
138 timersList.push_back(t);
139 return scm_long2num (c);
143 BotInterp::DelTimer(SCM timer)
145 int count = scm_num2long(timer, SCM_ARG1, "BotInterp::DelTimer");
146 std::list<Timer *>::iterator it = timersList.begin();
147 std::list<Timer *>::iterator it2 = timersList.end();
149 for ( ; it != it2; ++it) {
150 if ((*it)->count == count) {
151 scm_gc_unprotect_object((*it)->function);
153 timersList.erase(it);
161 BotInterp::RunTimers(int now)
163 std::list<Timer *>::iterator it = timersList.begin();
164 std::list<Timer *>::iterator it2 = timersList.end();
165 std::list<Timer *>::iterator it3;
167 struct wrapper_data wd;
168 wd.args = scm_listify (SCM_UNDEFINED);
171 if ((*it)->when <= now) {
172 wd.func = (*it)->function;
173 scm_internal_catch(SCM_BOOL_T,
174 (scm_t_catch_body) Interp::LazyApplyWrapper, (void *)&wd,
175 (scm_t_catch_handler) Interp::EmptyHandler, 0);
176 scm_gc_unprotect_object(wd.func);
180 timersList.erase(it);