-;;; this is a library of stuff that bobot++ scripts would probably
-;;; want to use. This file is autoloaded by bobot++
-
-;;; This file is covered by the GPL version 2 or (at your option) any
-;;; later version
-
-;;; Why the GPL? Technically anything that uses Bobot++'s functions
-;;; must be GPLed, so all of your scripts have to be GPLed anyway
-;;; because you are really linking with Bobot++, a GPLed program.
-
-;;; Bot load (loads a file from %bot:loadpath)
-
-(define %bot:loadpath (list
- (string-append (getenv "HOME")
- "/.bobotpp/scripts/")
- bot:sys-scripts-dir))
-
-(define (bot:load file)
- (let loop ((load-path %bot:loadpath))
- (if (not (null? load-path))
- (if (catch 'system-error
- (lambda ()
- (load
- (string-append (car load-path)
- file)))
- (lambda args
- #f ))
- #t
- (loop (cdr load-path)))
- (begin (bot:log "ERROR: File " file " Not Found!\n") #f))))
-
-;;; REGEX UTILS
-
-;;; match-not-channel adds a prefix regex to your regex so it doesn't
-;;; match the sender or channel in a PUBLIC message
-(define (bot:match-not-channel regex)
- (string-append "^[[:graph:]]* [&#+!][^ ,\a]+ [[:graph:][:space:]]*" regex))
-
-;;; match-to-me matches text that was addressed to the bot with a
-;;; ':',',', or nothing after the bot name
-(define (bot:match-to-me regex)
- (string-append (match-not-channel (bot:getnickname))
- "[[:space:][:graph:]]*" regex))
-
-;;;; string-utils
-(define str-app string-append) ; shorter
-
-
-;;;; Misc UTILS
-
-;;; bot-log: Write as many messages as you want to the log. If the
-;;; arg is a thunk it will be executed and it's output will be
-;;; written to the log
-(define (bot:log . messages)
- (for-each
- (lambda (x)
- (if (thunk? x)
- (display (x) (bot-logport))
- (display x (bot-logport))))
- messages )
- (bot:flushport))
-
-;;; Message sending utils
-
-;;; returns the CTCP quoted message
-(define (ctcp-quote message)
- message) ; FIXME: fill me in
-
-;;; DEPRECATED FUNCTION NAMES
-;;; These are provided for backwards compatibility
-;;; and will be removed in the 2.3 dev tree
-
-(define bot-load bot:load)
-(define bot-action bot:action)
-(define bot-adduser bot:adduser)
-(define bot-addserver bot:addserver)
-(define bot-addshit bot:addshit)
-(define bot-ban bot:ban)
-(define bot-cycle bot:cycle)
-(define bot-deban bot:deban)
-(define bot-delserver bot:delserver)
-(define bot-deluser bot:deluser)
-(define bot-delshit bot:delshit)
-(define bot-deop bot:deop)
-(define bot-die bot:die)
-(define bot-do bot:do)
-(define bot-invite bot:invite)
-(define bot-join bot:join)
-(define bot-keep bot:keep)
-(define bot-kick bot:kick)
-(define bot-kickban bot:kickban)
-(define bot-lock bot:lock)
-(define bot-logport bot:logport)
-(define bot-mode bot:mode)
-(define bot-msg bot:msg)
-(define bot-nextserver bot:nextserver)
-(define bot-nick bot:nick)
-(define bot-op bot:op)
-(define bot-part bot:part)
-(define bot-reconnect bot:reconnect)
-(define bot-say bot:say)
-(define bot-server bot:server)
-(define bot-setversion bot:setversion)
-(define bot-tban bot:tban)
-(define bot-tkban bot:tkban)
-(define bot-topic bot:topic)
-(define bot-unlock bot:unlock)
-(define bot-getnickname bot:getnickname)
-(define bot-getserver bot:getserver)
-(define bot-getserverlist bot:getserverlist)
-(define bot-flush bot:flush)
-(define bot-flushport bot:flushport)
-(define bot-random bot:random)
-(define bot-addcommand bot:addcommand)
-(define bot-delcommand bot:delcommand)
-(define bot-addhook bot:addhook)
-(define bot-addtimer bot:addtimer)
-(define bot-deltimer bot:deltimer)
\ No newline at end of file
+;;; This file is automatically loaded by Bobot++. This is required for
+;;; the bot to function.
+
+;;; This file is covered by the GPL version 2 or (at your option) any
+;;; later version
+
+;;; the-bot-module must be available to guile-user so that scripts
+;;; loaded with Interp::Load have access to the bot: procedures
+(module-use! (resolve-module '(guile-user) #f)
+ the-bot-module)
+
+(define-public %bot:loadpath (list
+ (string-append (getenv "HOME")
+ "/.bobotpp/scripts/")
+ bot:sys-scripts-dir))
+(define-public %bot:load-extensions %load-extensions)
+
+;;; bot-log: Write as many messages as you want to the log. If the
+;;; arg is a thunk it will be executed and it's output will be
+;;; written to the log
+(define-public (bot:log . messages)
+ (for-each
+ (lambda (x)
+ (if (thunk? x)
+ (display (x) (bot-logport))
+ (display x (bot-logport))))
+ messages )
+ (bot:flushport))
+
+(define-public (bot:load file)
+ (let path-loop ((load-path %bot:loadpath))
+ (if (and (not (null? load-path))
+ (not
+ (let ext-loop ((extensions %bot:load-extensions))
+ (if (not (null? extensions))
+ (if (catch 'system-error
+ (lambda ()
+ (bot:log "path: " (car load-path)
+ " file: " file
+ " ext: " (car extensions)
+ "\n")
+ (load
+ (string-append (car load-path)
+ file
+ (car extensions))))
+ (lambda args
+ #f ))
+ #t
+ (ext-loop (cdr extensions)))
+ #f))))
+ (path-loop (cdr load-path))
+ (begin (bot:log "ERROR: File " file " Not Found!\n") #f))))
+
+(define-public (bot:load-module module-spec)
+ (let ((module->string
+ (lambda (module)
+ (apply
+ (lambda (s . rest)
+ (string-append
+ s
+ (apply string-append
+ (map (lambda (str) (string-append "/" str)) rest))))
+ (map symbol->string module))))
+ (new-module
+ (make-module))
+ (old-module (current-module)))
+ (module-use! new-module the-bot-module)
+ (set-current-module new-module)
+ (bot:load (module->string module-spec))
+ (set-current-module old-module)
+ new-module))
+
+(define-public (bot:use-module module-spec)
+ (module-use! (current-module)
+ (bot:load-module module-spec)))
+
+
+;;; REGEX UTILS
+
+;;; match-not-channel adds a prefix regex to your regex so it doesn't
+;;; match the sender or channel in a PUBLIC message
+(define-public (bot:match-not-channel regex)
+ (string-append "^[[:graph:]]* [&#+!][^ ,\a]+ [[:graph:][:space:]]*" regex))
+
+;;; match-to-me matches text that was addressed to the bot with a
+;;; ':',',', or nothing after the bot name
+(define-public (bot:match-to-me regex)
+ (string-append (bot:match-not-channel (bot:getnickname))
+ "[[:space:][:graph:]]*" regex))
+
+;;;; string-utils
+(define-public str-app string-append) ; shorter
+
+;;; Message sending utils
+
+;;; returns the CTCP quoted message
+(define-public (ctcp-quote message)
+ message) ; FIXME: fill me in
+
+;;; DEPRECATED FUNCTION NAMES
+;;; These are provided for backwards compatibility
+;;; and will be removed in the 2.3 dev tree
+
+(define-public bot-load bot:load)
+(define-public bot-action bot:action)
+(define-public bot-adduser bot:adduser)
+(define-public bot-addserver bot:addserver)
+(define-public bot-addshit bot:addshit)
+(define-public bot-ban bot:ban)
+(define-public bot-cycle bot:cycle)
+(define-public bot-deban bot:deban)
+(define-public bot-delserver bot:delserver)
+(define-public bot-deluser bot:deluser)
+(define-public bot-delshit bot:delshit)
+(define-public bot-deop bot:deop)
+(define-public bot-die bot:die)
+(define-public bot-do bot:do)
+(define-public bot-invite bot:invite)
+(define-public bot-join bot:join)
+(define-public bot-keep bot:keep)
+(define-public bot-kick bot:kick)
+(define-public bot-kickban bot:kickban)
+(define-public bot-lock bot:lock)
+(define-public bot-logport bot:logport)
+(define-public bot-mode bot:mode)
+(define-public bot-msg bot:msg)
+(define-public bot-nextserver bot:nextserver)
+(define-public bot-nick bot:nick)
+(define-public bot-op bot:op)
+(define-public bot-part bot:part)
+(define-public bot-reconnect bot:reconnect)
+(define-public bot-say bot:say)
+(define-public bot-server bot:server)
+(define-public bot-setversion bot:setversion)
+(define-public bot-tban bot:tban)
+(define-public bot-tkban bot:tkban)
+(define-public bot-topic bot:topic)
+(define-public bot-unlock bot:unlock)
+(define-public bot-getnickname bot:getnickname)
+(define-public bot-getserver bot:getserver)
+(define-public bot-getserverlist bot:getserverlist)
+(define-public bot-flush bot:flush)
+(define-public bot-flushport bot:flushport)
+(define-public bot-random bot:random)
+(define-public bot-addcommand bot:addcommand)
+(define-public bot-delcommand bot:delcommand)
+(define-public bot-addhook bot:addhook)
+(define-public bot-addtimer bot:addtimer)
+(define-public bot-deltimer bot:deltimer)
\ No newline at end of file
#include <libguile.h>
+// static class member initial definitions
Bot * Interp::bot = 0;
+SCM Interp::bot_module = 0;
#ifdef MULTITHREAD
pthread_mutex_t Interp::mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
return SCM_BOOL_T;
}
-#define bot_new_procedure(a, b, c, d, e) scm_c_define_gsubr (a, c, d, e, b)
+#define bot_new_procedure(a, b, c, d, e) scm_c_define_gsubr (a, c, d, e, b); scm_c_export (a, 0)
+#define scm_c_define_gsubr(a, b, c, d, e) scm_c_define_gsubr (a, b, c, d, e); scm_c_export (a, 0)
+#define scm_c_define(a, b) scm_c_define (a, b); scm_c_export (a, 0)
void
-Interp::Startup()
+interp_init_helper (void* unused)
{
+ scm_c_use_module ("guile-user");
// Hooks
scm_c_define ("bot:exit-hook", scm_make_hook (scm_long2num (0)));
// "Low Level" Message functuions
scm_c_define_gsubr ("bot:send-CTCP", 3, 0, 0,
(SCMFunc)ScriptCommands::sendCTCP);
+}
+
+#undef bot_new_procedure
+#undef scm_c_define_gsubr
+#undef scm_c_define
+
+SCM
+interp_post_startup_helper (void *bot_module)
+{
+ SCM module = static_cast<SCM> (bot_module);
+ scm_c_define ("the-bot-module", module);
+ scm_c_export ("the-bot-module", 0);
// load bobot-utils
scm_primitive_load
(scm_makfrom0str (String(PREFIX) +
"/share/bobotpp/scripts/bobot-utils.scm"));
+ return 0;
+}
-
+void
+Interp::Startup()
+{
+ bot_module = scm_c_define_module ("the-bot-module",
+ interp_init_helper, 0);
+ scm_c_call_with_current_module (bot_module,
+ interp_post_startup_helper,
+ bot_module);
}
void
#endif
}
+void load_script_helper (void* file)
+{
+ String filename = *static_cast<String*> (file);
+ scm_c_use_module ("guile-user");
+ gh_eval_file_with_catch(filename, Interp::ErrorHandler);
+}
+
void
Interp::LoadScript(Bot *b, String filename)
{
pthread_mutex_lock(&mutex);
#endif
bot = b;
+ //scm_c_define_module ("", load_script_helper, &filename);
gh_eval_file_with_catch(filename, ErrorHandler);
#ifdef MULTITHREAD
// We release the lock