This is the mail archive of the guile@cygnus.com mailing list for the guile project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
I found and fixed a bug in Guile 1.3; the description of the bug and the fix
follow.
The basic problem is that the Guile init/boot code is not called until the
repl-loop is started. So, if you are using the gh interface and have started
some code via gh_enter, any scheme commands that you execute or load cannot use
things like "load" "defmacro" etcetera. This was not the case with Guile 1.2.
Here is a minimal program that demonstrates the bug:
#include <guile/gh.h>
void main_entry(int argc, char *argv[])
{
gh_eval_str("(display defmacro)");
}
int main (int argc, char *argv[])
{
gh_enter (argc, argv, main_entry);
return 0;
}
When run under Guile 1.3, this program will exit with an error, complaining that
defmacro is not defined. (I reported this earlier to bug-guile@gnu.org.)
My solution was to separate the code that loads the init files into a separate
routine, scm_load_init (it was previously a part of scm_compile_shell_switches).
This function is called by scm_compile_shell_switches and by gh_enter (actually,
gh_launch_pad), so that the init files are guaranteed to be loaded before any
user code executes. scm_load_init maintains a static already_called variable to
make sure it is only executed once, making it safe to call gh_repl (which also
results in scm_load_init being called via scm_shell).
My patches, applied to the 5/19 snapshot of Guile 1.3, are as follows (diff
output for gh_init.c, script.h, and script.c):
diff gh_init.c.old gh_init.c
60a61
> scm_load_init(); /* load the boot code, etcetera */
diff script.h.old script.h
56a57
> extern void scm_load_init(void);
diff script.c.old script.c
452a453,479
> /* Load initialization files (e.g. the ice-9 system). This is called
> by scm_shell (or rather, by scm_compile_shell_switches), but you
> need to call it separately if you want to use the Scheme functions
> defined in this file when running non-interactively. For example,
> it is called via gh_enter so that gh user code can use things
> like load, defmacro, etcetera. */
> void scm_load_init(void)
> {
> static int already_called = 0; /* we only want to do this once */
> if (!already_called) {
> /* We want a path only containing directories from GUILE_LOAD_PATH,
> SCM_SITE_DIR and SCM_LIBRARY_DIR when searching for the site init
> file, so we do this before loading Ice-9. */
> SCM init_path = scm_sys_search_load_path (scm_makfrom0str ("init.scm"));
>
> /* Load Ice-9. */
> if (!scm_ice_9_already_loaded)
> scm_primitive_load_path (scm_makfrom0str ("ice-9/boot-9.scm"));
>
> /* Load the init.scm file. */
> if (SCM_NFALSEP (init_path))
> scm_primitive_load (init_path);
>
> already_called = 1; /* don't call next time */
> }
> }
>
623,627d649
< {
< /* We want a path only containing directories from GUILE_LOAD_PATH,
< SCM_SITE_DIR and SCM_LIBRARY_DIR when searching for the site init
< file, so we do this before loading Ice-9. */
< SCM init_path = scm_sys_search_load_path (scm_makfrom0str ("init.scm"));
629,636c651,652
< /* Load Ice-9. */
< if (!scm_ice_9_already_loaded)
< scm_primitive_load_path (scm_makfrom0str ("ice-9/boot-9.scm"));
<
< /* Load the init.scm file. */
< if (SCM_NFALSEP (init_path))
< scm_primitive_load (init_path);
< }
---
> /* load initialization files */
> scm_load_init();