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();