*** empty log message ***
[bpt/guile.git] / libguile / init.c
CommitLineData
7dc6e754 1/* Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
0f2d19dd 41\f
bdca1083
JB
42/* Include the headers for just about everything.
43 We call all their initialization functions. */
0f2d19dd
JB
44
45#include <stdio.h>
46#include "_scm.h"
47
20e6290e
JB
48/* Everybody has an init function. */
49#include "alist.h"
20e6290e
JB
50#include "arbiters.h"
51#include "async.h"
0e44fcca 52#include "backtrace.h"
20e6290e
JB
53#include "boolean.h"
54#include "chars.h"
55#include "continuations.h"
56#ifdef DEBUG_EXTENSIONS
57#include "debug.h"
58#endif
70122cd3 59#include "dynl.h"
20e6290e
JB
60#include "dynwind.h"
61#include "eq.h"
62#include "error.h"
63#include "eval.h"
27a69f93 64#include "evalext.h"
20e6290e 65#include "feature.h"
20e6290e 66#include "filesys.h"
ee3ea81d 67#include "fluids.h"
20e6290e
JB
68#include "fports.h"
69#include "gc.h"
70#include "gdbint.h"
71#include "gsubr.h"
72#include "hash.h"
73#include "hashtab.h"
44e8413c
MD
74#ifdef GUILE_ISELECT
75#include "iselect.h"
76#endif
20e6290e
JB
77#include "ioext.h"
78#include "kw.h"
79#include "list.h"
80#include "load.h"
27a69f93 81#include "macros.h"
20e6290e 82#include "mallocs.h"
370312ae 83#include "net_db.h"
20e6290e 84#include "numbers.h"
0c32d76c 85#include "objects.h"
20e6290e
JB
86#include "objprop.h"
87#include "options.h"
88#include "pairs.h"
89#include "ports.h"
90#include "posix.h"
f255378e
JB
91#ifdef HAVE_REGCOMP
92#include "regex-posix.h"
93#endif
20e6290e
JB
94#include "print.h"
95#include "procprop.h"
96#include "procs.h"
97#include "ramap.h"
98#include "read.h"
a2d4941f 99#include "readline.h"
20e6290e 100#include "scmsigs.h"
964edde7 101#include "script.h"
20e6290e 102#include "simpos.h"
a8be22fe 103#include "smob.h"
20e6290e
JB
104#include "socket.h"
105#include "srcprop.h"
106#include "stackchk.h"
0e44fcca 107#include "stacks.h"
20e6290e
JB
108#include "stime.h"
109#include "strings.h"
110#include "strop.h"
111#include "strorder.h"
112#include "strports.h"
113#include "struct.h"
114#include "symbols.h"
115#include "tag.h"
116#include "throw.h"
117#include "unif.h"
118#include "variable.h"
119#include "vectors.h"
120#include "version.h"
121#include "vports.h"
122#include "weaks.h"
123
a8be22fe
JB
124#include "init.h"
125
95b88819
GH
126#ifdef HAVE_STRING_H
127#include <string.h>
128#endif
129#ifdef HAVE_UNISTD_H
130#include <unistd.h>
131#endif
0f2d19dd 132\f
bdca1083 133/* Setting up the stack. */
0f2d19dd 134
a4156763
MD
135static void start_stack SCM_P ((void *base));
136static void restart_stack SCM_P ((void * base));
1cdaaafb
JB
137
138static void
a4156763 139start_stack (base)
0f2d19dd 140 void * base;
0f2d19dd 141{
9ef3d0ee 142 SCM root;
0f2d19dd 143
9ef3d0ee
MD
144 root = scm_permanent_object (scm_make_root (SCM_UNDEFINED));
145 scm_set_root (SCM_ROOT_STATE (root));
0f2d19dd
JB
146 scm_stack_base = base;
147
0f2d19dd
JB
148 scm_exitval = SCM_BOOL_F; /* vestigial */
149
dc19d1d2 150 scm_top_level_lookup_closure_var = SCM_BOOL_F;
0f2d19dd
JB
151 scm_system_transformer = SCM_BOOL_F;
152
ee3ea81d
MV
153 scm_root->fluids = scm_make_initial_fluids ();
154
0f2d19dd
JB
155 /* Create an object to hold the root continuation.
156 */
157 SCM_NEWCELL (scm_rootcont);
1cdaaafb
JB
158 SCM_SETJMPBUF (scm_rootcont, scm_must_malloc ((long) sizeof (scm_contregs),
159 "continuation"));
898a256f 160 SCM_SETCAR (scm_rootcont, scm_tc7_contin);
4b5166ac 161 SCM_SEQ (scm_rootcont) = 0;
a4156763 162 /* The root continuation if further initialized by restart_stack. */
0f2d19dd
JB
163
164 /* Create the look-aside stack for variables that are shared between
165 * captured continuations.
166 */
a8741caa 167 scm_continuation_stack = scm_make_vector (SCM_MAKINUM (512), SCM_UNDEFINED);
a4156763 168 /* The continuation stack is further initialized by restart_stack. */
0f2d19dd 169
1cdaaafb
JB
170 /* The remainder of stack initialization is factored out to another
171 * function so that if this stack is ever exitted, it can be
a4156763
MD
172 * re-entered using restart_stack. */
173 restart_stack (base);
0f2d19dd
JB
174}
175
176
1cdaaafb 177static void
a4156763 178restart_stack (base)
0f2d19dd 179 void * base;
0f2d19dd
JB
180{
181 scm_dynwinds = SCM_EOL;
182 SCM_DYNENV (scm_rootcont) = SCM_EOL;
183 SCM_THROW_VALUE (scm_rootcont) = SCM_EOL;
4e1caa79 184#ifdef DEBUG_EXTENSIONS
4b5166ac 185 SCM_DFRAME (scm_rootcont) = scm_last_debug_frame = 0;
4e1caa79 186#endif
0f2d19dd
JB
187 SCM_BASE (scm_rootcont) = base;
188 scm_continuation_stack_ptr = SCM_MAKINUM (0);
189}
190
191#if 0
192static char remsg[] = "remove\n#define ", addmsg[] = "add\n#define ";
193
1cc91f1b
JB
194
195static void fixconfig SCM_P ((char *s1, char *s2, int s));
196
0f2d19dd
JB
197static void
198fixconfig (s1, s2, s)
199 char *s1;
200 char *s2;
201 int s;
0f2d19dd
JB
202{
203 fputs (s1, stderr);
204 fputs (s2, stderr);
205 fputs ("\nin ", stderr);
206 fputs (s ? "setjump" : "scmfig", stderr);
207 fputs (".h and recompile scm\n", stderr);
208 exit (1);
209}
210
211
1cc91f1b 212static void check_config SCM_P ((void));
0f2d19dd
JB
213
214static void
215check_config ()
216{
217 scm_sizet j;
218
219 j = HEAP_SEG_SIZE;
220 if (HEAP_SEG_SIZE != j)
221 fixconfig ("reduce", "size of HEAP_SEG_SIZE", 0);
222
223#ifdef SCM_SINGLES
224 if (sizeof (float) != sizeof (long))
225 fixconfig (remsg, "SCM_SINGLES", 0);
226#endif /* def SCM_SINGLES */
227
228
229#ifdef SCM_BIGDIG
230 if (2 * SCM_BITSPERDIG / SCM_CHAR_BIT > sizeof (long))
231 fixconfig (remsg, "SCM_BIGDIG", 0);
232#ifndef SCM_DIGSTOOBIG
233 if (SCM_DIGSPERLONG * sizeof (SCM_BIGDIG) > sizeof (long))
234 fixconfig (addmsg, "SCM_DIGSTOOBIG", 0);
235#endif
236#endif
237
238#ifdef SCM_STACK_GROWS_UP
239 if (((SCM_STACKITEM *) & j - stack_start_ptr) < 0)
240 fixconfig (remsg, "SCM_STACK_GROWS_UP", 1);
241#else
242 if ((stack_start_ptr - (SCM_STACKITEM *) & j) < 0)
243 fixconfig (addmsg, "SCM_STACK_GROWS_UP", 1);
244#endif
245}
246#endif
247
248
249\f
1cdaaafb
JB
250/* initializing standard and current I/O ports */
251
252/* Create standard ports from stdio stdin, stdout, and stderr. */
253static void
254scm_init_standard_ports ()
255{
94754080
JB
256 /* From the SCSH manual:
257
258 It can be useful to turn I/O buffering off in some cases, for
259 example when an I/O stream is to be shared by multiple
260 subprocesses. For this reason, scsh allocates an unbuffered port
261 for file descriptor 0 at start-up time.
262
263 Because shells frequently share stdin with subprocesses, if the
264 shell does buffered reads, it might ``steal'' input intended for
265 a subprocess. For this reason, all shells, including sh, csh,
266 and scsh, read stdin unbuffered. Applications that can tolerate
267 buffered input on stdin can reset \ex{(current-input-port)} to
268 block buffering for higher performance. */
bc45012d
JB
269 scm_def_inp
270 = scm_standard_stream_to_port (stdin,
1cdaaafb
JB
271 (isatty (fileno (stdin)) ? "r0" : "r"),
272 "standard input");
bc45012d
JB
273 scm_def_outp = scm_standard_stream_to_port (stdout, "w", "standard output");
274 scm_def_errp = scm_standard_stream_to_port (stderr, "w", "standard error");
1cdaaafb
JB
275
276 scm_cur_inp = scm_def_inp;
277 scm_cur_outp = scm_def_outp;
278 scm_cur_errp = scm_def_errp;
1a64191e 279 scm_cur_loadp = SCM_BOOL_F;
1cdaaafb
JB
280}
281
282
283\f
bdca1083
JB
284/* Loading the startup Scheme files. */
285
286/* The boot code "ice-9/boot-9" is only loaded by scm_boot_guile when
287 this is false. The unexec code uses this, to keep ice_9 from being
288 loaded into dumped guile executables. */
289int scm_ice_9_already_loaded = 0;
290
291void
292scm_load_startup_files ()
293{
294 /* We want a path only containing directories from GUILE_LOAD_PATH,
295 SCM_SITE_DIR and SCM_LIBRARY_DIR when searching for the site init
296 file, so we do this before loading Ice-9. */
297 SCM init_path = scm_sys_search_load_path (scm_makfrom0str ("init.scm"));
298
299 /* Load Ice-9. */
300 if (!scm_ice_9_already_loaded)
301 scm_primitive_load_path (scm_makfrom0str ("ice-9/boot-9.scm"));
302
303 /* Load the init.scm file. */
304 if (SCM_NFALSEP (init_path))
305 scm_primitive_load (init_path);
306}
307
308
309\f
310/* The main init code. */
311
0f2d19dd
JB
312#ifdef _UNICOS
313typedef int setjmp_type;
314#else
315typedef long setjmp_type;
316#endif
317
816a6f06
JB
318/* All the data needed to invoke the main function. */
319struct main_func_closure
320{
321 /* the function to call */
322 void (*main_func) SCM_P ((void *closure, int argc, char **argv));
323 void *closure; /* dummy data to pass it */
324 int argc;
325 char **argv; /* the argument list it should receive */
326};
327
328
329static void scm_boot_guile_1 SCM_P ((SCM_STACKITEM *base,
330 struct main_func_closure *closure));
39752bec 331static SCM invoke_main_func SCM_P ((void *body_data));
1cdaaafb
JB
332
333
334/* Fire up the Guile Scheme interpreter.
335
336 Call MAIN_FUNC, passing it CLOSURE, ARGC, and ARGV. MAIN_FUNC
337 should do all the work of the program (initializing other packages,
338 reading user input, etc.) before returning. When MAIN_FUNC
339 returns, call exit (0); this function never returns. If you want
340 some other exit value, MAIN_FUNC may call exit itself.
0f2d19dd 341
1cdaaafb
JB
342 scm_boot_guile arranges for program-arguments to return the strings
343 given by ARGC and ARGV. If MAIN_FUNC modifies ARGC/ARGV, should
344 call scm_set_program_arguments with the final list, so Scheme code
345 will know which arguments have been processed.
c275ddc7 346
816a6f06
JB
347 scm_boot_guile establishes a catch-all catch handler which prints
348 an error message and exits the process. This means that Guile
349 exits in a coherent way when system errors occur and the user isn't
350 prepared to handle it. If the user doesn't like this behavior,
351 they can establish their own universal catcher to shadow this one.
352
1cdaaafb
JB
353 Why must the caller do all the real work from MAIN_FUNC? The
354 garbage collector assumes that all local variables of type SCM will
355 be above scm_boot_guile's stack frame on the stack. If you try to
356 manipulate SCM values after this function returns, it's the luck of
357 the draw whether the GC will be able to find the objects you
358 allocate. So, scm_boot_guile function exits, rather than
359 returning, to discourage people from making that mistake. */
360
361
362void
363scm_boot_guile (argc, argv, main_func, closure)
0f2d19dd
JB
364 int argc;
365 char ** argv;
1cdaaafb
JB
366 void (*main_func) ();
367 void *closure;
c275ddc7 368{
1cdaaafb
JB
369 /* The garbage collector uses the address of this variable as one
370 end of the stack, and the address of one of its own local
371 variables as the other end. */
c275ddc7 372 SCM_STACKITEM dummy;
816a6f06 373 struct main_func_closure c;
c275ddc7 374
816a6f06
JB
375 c.main_func = main_func;
376 c.closure = closure;
377 c.argc = argc;
378 c.argv = argv;
379
1595aa56 380 scm_boot_guile_1 (&dummy, &c);
c275ddc7
JB
381}
382
816a6f06 383
70122cd3
MV
384/* Record here whether SCM_BOOT_GUILE_1 has already been called. This
385 variable is now here and not inside SCM_BOOT_GUILE_1 so that one
386 can tweak it. This is necessary for unexec to work. (Hey, "1-live"
387 is the name of a local radiostation...) */
388
389int scm_boot_guile_1_live = 0;
1cdaaafb
JB
390
391static void
816a6f06 392scm_boot_guile_1 (base, closure)
c275ddc7 393 SCM_STACKITEM *base;
816a6f06 394 struct main_func_closure *closure;
0f2d19dd
JB
395{
396 static int initialized = 0;
70122cd3 397 /* static int live = 0; */
0f2d19dd 398 setjmp_type setjmp_val;
0f2d19dd 399
1cdaaafb 400 /* This function is not re-entrant. */
70122cd3 401 if (scm_boot_guile_1_live)
1cdaaafb 402 abort ();
0f2d19dd 403
70122cd3 404 scm_boot_guile_1_live = 1;
0f2d19dd
JB
405
406 scm_ints_disabled = 1;
407 scm_block_gc = 1;
408
409 if (initialized)
410 {
a4156763 411 restart_stack (base);
0f2d19dd
JB
412 }
413 else
414 {
415 scm_ports_prehistory ();
416 scm_smob_prehistory ();
417 scm_tables_prehistory ();
418 scm_init_storage (0);
9ef3d0ee
MD
419 scm_init_root ();
420#ifdef USE_THREADS
a239e35b 421 scm_init_threads (base);
9ef3d0ee 422#endif
a4156763 423 start_stack (base);
0f2d19dd
JB
424 scm_init_gsubr ();
425 scm_init_feature ();
426 scm_init_alist ();
0f2d19dd
JB
427 scm_init_arbiters ();
428 scm_init_async ();
429 scm_init_boolean ();
430 scm_init_chars ();
431 scm_init_continuations ();
432 scm_init_dynwind ();
433 scm_init_eq ();
434 scm_init_error ();
ee3ea81d 435 scm_init_fluids ();
a5d6d578 436 scm_init_backtrace (); /* Requires fluids */
0f2d19dd 437 scm_init_fports ();
0f2d19dd
JB
438 scm_init_filesys ();
439 scm_init_gc ();
68cd9c71 440 scm_init_gdbint ();
0f2d19dd
JB
441 scm_init_hash ();
442 scm_init_hashtab ();
44e8413c
MD
443#ifdef GUILE_ISELECT
444 scm_init_iselect ();
445#endif
0f2d19dd
JB
446 scm_init_ioext ();
447 scm_init_kw ();
448 scm_init_list ();
27a69f93 449 scm_init_macros ();
0f2d19dd 450 scm_init_mallocs ();
370312ae 451 scm_init_net_db ();
0f2d19dd
JB
452 scm_init_numbers ();
453 scm_init_objprop ();
4e1caa79 454 scm_init_options ();
0f2d19dd
JB
455 scm_init_pairs ();
456 scm_init_ports ();
457 scm_init_posix ();
f255378e
JB
458#ifdef HAVE_REGCOMP
459 scm_init_regex_posix ();
460#endif
0f2d19dd
JB
461 scm_init_procs ();
462 scm_init_procprop ();
0f2d19dd
JB
463 scm_init_scmsigs ();
464 scm_init_socket ();
4e1caa79
MD
465#ifdef DEBUG_EXTENSIONS
466 scm_init_srcprop ();
467#endif
0f2d19dd 468 scm_init_stackchk ();
7439c0b9 469 scm_init_struct (); /* Requires struct */
0e44fcca 470 scm_init_stacks ();
0f2d19dd 471 scm_init_strports ();
0f2d19dd
JB
472 scm_init_symbols ();
473 scm_init_tag ();
474 scm_init_load ();
0c32d76c 475 scm_init_objects (); /* Requires struct */
90b826c9 476 scm_init_print (); /* Requires struct */
0f2d19dd 477 scm_init_read ();
0f2d19dd
JB
478 scm_init_stime ();
479 scm_init_strings ();
480 scm_init_strorder ();
0f2d19dd
JB
481 scm_init_strop ();
482 scm_init_throw ();
483 scm_init_variable ();
484 scm_init_vectors ();
9d7e1edf 485 scm_init_version ();
0f2d19dd
JB
486 scm_init_weaks ();
487 scm_init_vports ();
488 scm_init_eval ();
27a69f93 489 scm_init_evalext ();
0e44fcca
MD
490#ifdef DEBUG_EXTENSIONS
491 scm_init_debug (); /* Requires macro smobs */
492#endif
0f2d19dd
JB
493 scm_init_ramap ();
494 scm_init_unif ();
495 scm_init_simpos ();
24f93c27 496 scm_init_load_path ();
9623ba32 497#if defined (HAVE_RL_GETC_FUNCTION)
a2d4941f
JB
498 scm_init_readline ();
499#endif
1cdaaafb 500 scm_init_standard_ports ();
70122cd3 501 scm_init_dynamic_linking ();
0487b82f 502 scm_init_script ();
0f2d19dd
JB
503 initialized = 1;
504 }
505
506 scm_block_gc = 0; /* permit the gc to run */
507 /* ints still disabled */
508
1cdaaafb
JB
509#ifdef STACK_CHECKING
510 scm_stack_checking_enabled_p = SCM_STACK_CHECKING_P;
511#endif
0f2d19dd 512
1cdaaafb
JB
513 setjmp_val = setjmp (SCM_JMPBUF (scm_rootcont));
514 if (!setjmp_val)
515 {
816a6f06 516 scm_set_program_arguments (closure->argc, closure->argv, 0);
f64056d1
JB
517 scm_internal_lazy_catch (SCM_BOOL_T, invoke_main_func, closure,
518 scm_handle_by_message, 0);
1cdaaafb 519 }
0f2d19dd 520
1cdaaafb 521 scm_restore_signals ();
0f2d19dd 522
1cdaaafb
JB
523 /* This tick gives any pending
524 * asyncs a chance to run. This must be done after
525 * the call to scm_restore_signals.
526 */
527 SCM_ASYNC_TICK;
528
529 /* If the caller doesn't want this, they should return from
530 main_func themselves. */
531 exit (0);
0f2d19dd 532}
816a6f06
JB
533
534
535static SCM
39752bec 536invoke_main_func (body_data)
816a6f06 537 void *body_data;
816a6f06
JB
538{
539 struct main_func_closure *closure = (struct main_func_closure *) body_data;
540
bdca1083
JB
541 scm_load_startup_files ();
542
816a6f06
JB
543 (*closure->main_func) (closure->closure, closure->argc, closure->argv);
544
545 /* never reached */
546 return SCM_UNDEFINED;
547}