[project @ 2003-04-03 03:37:06 by unknown_lamer]
authorunknown_lamer <unknown>
Thu, 3 Apr 2003 03:37:06 +0000 (03:37 +0000)
committerunknown_lamer <unknown>
Thu, 3 Apr 2003 03:37:06 +0000 (03:37 +0000)
2003-04-02  Clinton Ebadi  <clinton@unknownlamer.org>

* scripts/bobot-utils.scm: Make exported symbols from
the-bot-module available in the guile-user module so that scripts
loaded with Interp::Load function.

2003-03-30  Clinton Ebadi  <clinton@unknownlamer.org>

* scripts/bobot-utils.scm (bot:load-module): Loads a file from the
%bot:loadpath into its own module and returns that (unnamed) module
(bot:use-module): Calls bot:load-module and then adds the newly
loaded module to the (current-module)'s use-list

* source/Interp.C (interp_init_helper): New procedure to initialize
the-bot-module (this is the old Interp::Startup verbatim)
(interp_post_startup_helper): New procedure to export
the-bot-module from bot_module
(Startup): Now calls interp_init_helper and
interp_post_startup_helper to initalize the bot module system

* source/Interp.H: Added private variable bot_module to Interp

ChangeLog
NEWS
TODO
bobot++.info
bobot++.texinfo
scripts/bobot-utils.scm
scripts/scheme_add_user
scripts/scripts.load
source/Interp.C
source/Interp.H

index 40026ff..7a04d6e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2003-04-02  Clinton Ebadi  <clinton@unknownlamer.org>
+
+       * scripts/bobot-utils.scm: Make exported symbols from
+       the-bot-module available in the guile-user module so that scripts
+       loaded with Interp::Load function.
+
+2003-03-30  Clinton Ebadi  <clinton@unknownlamer.org>
+
+       * scripts/bobot-utils.scm (bot:load-module): Loads a file from the
+       %bot:loadpath into its own module and returns that (unnamed) module
+       (bot:use-module): Calls bot:load-module and then adds the newly
+       loaded module to the (current-module)'s use-list
+
+       * source/Interp.C (interp_init_helper): New procedure to initialize
+       the-bot-module (this is the old Interp::Startup verbatim)
+       (interp_post_startup_helper): New procedure to export
+       the-bot-module from bot_module
+       (Startup): Now calls interp_init_helper and
+       interp_post_startup_helper to initalize the bot module system
+
+       * source/Interp.H: Added private variable bot_module to Interp
+
 2002-11-04  Clinton Ebadi  <clinton@unknownlamer.org>
 
        * scripts/bobot-utils.scm: Added bot: to regex functions (yes,
diff --git a/NEWS b/NEWS
index 502d4d7..3739eea 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,17 @@ Version 2.1.2: Llama
   bot:match-not-channel. Just use perl -pi -e
   "s/match-to-me/bot:match-to-me" SCRIPTS (change to match-not-channel
   for match-not-channel).
+- Each script is now loaded into its own module so namespace clashes
+  should no longer occur
+- New procedure: (bot:load-module INTERFACE-SPEC) will load a "bot
+  module" with the specified INTERFACE-SPEC (e.g. (foo bar)). A bot
+  module is the same as a system module except that you don't use
+  define-module to define it. The %bot:loadpath is searched for
+  INTERFACE-SPEC (when converted to a string) with an extension in
+  %bot:load-extensions. E.g. (foo bar) becomes "foo/bar".
+- New procedure: (bot:use-module INTERFACE-SPEC) is the same as
+  bot:load-module except it will make the exported bindings from
+  INTERFACE-SPEC available in the current-module.
 
 Version 2.1.1: foom
 
@@ -64,7 +75,7 @@ Version 2.1.0: Zug Zug
   bobotpp --help for the full list of commands you may use and how to
   use them).
 - Scripts are now stored in ~/.bobotpp/scripts/ or
-  PREFIX/bobotpp/scripts/ (where PREFIX is /usr/local unless you
+  PREFIX/share/bobotpp/scripts/ (where PREFIX is /usr/local unless you
   changed it with the --prefix arg to configure). The new function
   bot-load will take a filename and load it from these dirs, returning
   #t if the file was loaded and #f if it wasn't. You can modify the
diff --git a/TODO b/TODO
index 8822940..7f29cdb 100644 (file)
--- a/TODO
+++ b/TODO
@@ -19,7 +19,6 @@ Scripting:
   (e.g. bot:send-CTCP to send a CTCP message)
 * Add util functions for doing stuff like quoting CTCP messages
 * Finish adding hooks/send hooks
-* Lock around Guile Operations
 
 Networking:
 * Add a networked interface to guile repl
@@ -40,4 +39,6 @@ Other (post 2.2 release):
    CC++ sockets (this will require locking around everything Guile
    related). UPDATE[2002-11-02]: Guile CVS now has coop threads built
    on top of pthreads, which I could probably use when 1.8 nears
-   release.
\ No newline at end of file
+   release.
+   UPDATE[2002-12-22]: Guile CVS now has support for full pthreads, no
+   more coop stuff. After 1.8 is released threads will probably be used.
\ No newline at end of file
index 114707e..5cda927 100644 (file)
@@ -414,7 +414,7 @@ scripts. There is the simple, but rather limited, `bot:say',
 `bot:action' and `bot:msg', and the more powerful, but lower level,
 `bot:send-MESSAGE' functions. Most bots will probably only need the
 higher level functions, but for the sake of why-not Bobot++ lets you
-use the lower level functions.
+use the lower level functions (in progress).
 
 * Menu:
 
@@ -534,11 +534,11 @@ Node: Creating a Hook\7f6826
 Node: Hook Types\7f7965
 Node: Scheme User Levels\7f11439
 Node: Sending Messages\7f12568
-Node: High Level Message Functions\7f13165
-Node: Low Level Message Functions\7f13379
-Node: Misc Scripting Stuff\7f14132
-Node: Concept Index\7f14551
-Node: Function Index\7f14733
-Node: Variable Index\7f14994
+Node: High Level Message Functions\7f13179
+Node: Low Level Message Functions\7f13393
+Node: Misc Scripting Stuff\7f14146
+Node: Concept Index\7f14565
+Node: Function Index\7f14747
+Node: Variable Index\7f15008
 \1f
 End Tag Table
index b37b725..36f2838 100644 (file)
@@ -603,7 +603,7 @@ scripts. There is the simple, but rather limited, @code{bot:say},
 the more powerful, but lower level, @code{bot:send-MESSAGE}
 functions. Most bots will probably only need the higher level
 functions, but for the sake of why-not Bobot++ lets you use the lower
-level functions.
+level functions (in progress).
 
 @menu
 * High Level Message Functions::  
@@ -645,36 +645,6 @@ If you want to execute code when the bot exits, just do
 argumentless procedure (a thunk). When the bot exits your thunk will
 be called.
 
-@c Since a bot calls hooks on things it says, you have to be careful
-@c about hooks that output text that might match itself. E.g. if you have
-@c a hook that matches @code{"foo"} and the hook displays @code{"foo to
-@c the whatsit?"}, then the hook will call itself over and over until the
-@c stack overflows! To protect against this I wrote the macro
-@c @code{not-from-me}. You call it like this: @code{(not-from-me from
-@c (stmts if not from bot) (stmts if from bot))}. E.g. 
-
-@c @example
-@c (bot:addhook hooks/public "foo"
-@c              (lambda (f t p)
-@c                (not-from-me f ((bot:say t "foo to the what!")))))
-@c @end example
-
-@c This say ``foo to the what!'' to the channel that ``foo'' was said in
-@c and do nothing otherwise. You can optionally specify an action to be
-@c executed if the message is from the bot:
-
-@c @example
-@c (bot:addhook hooks/public "foo"
-@c              (lambda (f t p)
-@c                (not-from-me f ((bot:say t "foo to the what!"))
-@c                               ((bot:say t "moof")))))
-@c @end example
-
-@c That will do the same thing as the first example, but the bot will
-@c say ``moof'' if it said ``foo'' before. That probably isn't a very
-@c nice thing to do, but it works as an example. You can have as many
-@c staments as you want in the clauses.
-
 @node Concept Index, Function Index, Scripting, Top
 @unnumbered Concept Index
 @printindex cp
dissimilarity index 72%
index 6327ad5..87ee270 100644 (file)
-;;; 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
index 63db7bc..e893ae9 100644 (file)
@@ -1,6 +1,5 @@
 ;;; -*- guile-scheme -*-
 ;;; test of bot:adduser
-(load "bobot:utils.scm")
 
 ;;; test this!
 (define (scheme-adduser who channel level protect aop expire passwd)
index 18548e3..7c2a397 100644 (file)
@@ -1,7 +1,7 @@
-stupid_stuff/stupid_stuff
-country
-hello
-tamere
-uname
-uptime
-eval
\ No newline at end of file
+(stupid_stuff stupid_stuff)
+(country)
+(hello)
+(tamere)
+(uname)
+(uptime)
+(eval)
\ No newline at end of file
index 9c2ecd0..6d448f8 100644 (file)
@@ -29,7 +29,9 @@
 
 #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
@@ -53,11 +55,14 @@ scm_apply_wrapper(void *data)
   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)));
 
@@ -176,13 +181,34 @@ Interp::Startup()
   // "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
@@ -206,6 +232,13 @@ Interp::Execute(Bot *b, String command)
 #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)
 {
@@ -214,6 +247,7 @@ 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
index 56af98c..2b1c35b 100644 (file)
@@ -43,6 +43,7 @@ SCM scm_apply_wrapper(void *);
 class Interp {
 public:
   static Bot *bot;
+  static SCM bot_module;
 #ifdef MULTITHREAD
 private:
   static pthread_mutex_t mutex;