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