detect and consume byte-order marks for textual ports
[bpt/guile.git] / libguile / load.c
CommitLineData
c12da2be 1/* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2004, 2006, 2008,
f6fd2c03 2 * 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
0f2d19dd 3 *
73be1d9e 4 * This library is free software; you can redistribute it and/or
53befeb7
NJ
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
0f2d19dd 8 *
53befeb7
NJ
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
0f2d19dd 13 *
73be1d9e
MV
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
53befeb7
NJ
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
73be1d9e 18 */
1bbd0b84 19
1bbd0b84 20
0f2d19dd
JB
21\f
22
dbb605f5 23#ifdef HAVE_CONFIG_H
cbd41c89
RB
24# include <config.h>
25#endif
26
13070bd3 27#include <string.h>
7d04d68b 28#include <stdio.h>
13070bd3 29
a0599745 30#include "libguile/_scm.h"
655aadf4 31#include "libguile/private-gc.h" /* scm_getenv_int */
a0599745
MD
32#include "libguile/libpath.h"
33#include "libguile/fports.h"
34#include "libguile/read.h"
35#include "libguile/eval.h"
36#include "libguile/throw.h"
37#include "libguile/alist.h"
38#include "libguile/dynwind.h"
39#include "libguile/root.h"
40#include "libguile/strings.h"
f33b174d 41#include "libguile/modules.h"
7d04d68b 42#include "libguile/chars.h"
c44ca4fe 43#include "libguile/srfi-13.h"
a0599745
MD
44
45#include "libguile/validate.h"
46#include "libguile/load.h"
ec3a8ace 47#include "libguile/fluids.h"
06721500 48
22f4ee48
AW
49#include "libguile/vm.h" /* for load-compiled/vm */
50
06721500
JB
51#include <sys/types.h>
52#include <sys/stat.h>
53
54#ifdef HAVE_UNISTD_H
55#include <unistd.h>
56#endif /* HAVE_UNISTD_H */
57
5b197db8
AW
58#ifdef HAVE_PWD_H
59#include <pwd.h>
60#endif /* HAVE_PWD_H */
61
06721500
JB
62#ifndef R_OK
63#define R_OK 4
64#endif
0f2d19dd 65
abca59fe
LC
66#include <stat-time.h>
67
0f2d19dd 68\f
06721500 69/* Loading a file, given an absolute filename. */
0f2d19dd 70
26544b96
JB
71/* Hook to run when we load a file, perhaps to announce the fact somewhere.
72 Applied to the full name of the file. */
73static SCM *scm_loc_load_hook;
74
ec3a8ace
NJ
75/* The current reader (a fluid). */
76static SCM the_reader = SCM_BOOL_F;
8b039053 77
ec3a8ace 78
3b3b36dd 79SCM_DEFINE (scm_primitive_load, "primitive-load", 1, 0, 0,
1bbd0b84 80 (SCM filename),
67e8151b
MG
81 "Load the file named @var{filename} and evaluate its contents in\n"
82 "the top-level environment. The load paths are not searched;\n"
83 "@var{filename} must either be a full pathname or be a pathname\n"
84 "relative to the current directory. If the variable\n"
85 "@code{%load-hook} is defined, it should be bound to a procedure\n"
86 "that will be called before any code is loaded. See the\n"
87 "documentation for @code{%load-hook} later in this section.")
1bbd0b84 88#define FUNC_NAME s_scm_primitive_load
0f2d19dd 89{
26544b96 90 SCM hook = *scm_loc_load_hook;
017eb4a6 91 SCM ret = SCM_UNSPECIFIED;
889975e5 92 char *encoding;
017eb4a6 93
a6d9e5ab 94 SCM_VALIDATE_STRING (1, filename);
bc36d050 95 if (scm_is_true (hook) && scm_is_false (scm_procedure_p (hook)))
2ade72d7
DH
96 SCM_MISC_ERROR ("value of %load-hook is neither a procedure nor #f",
97 SCM_EOL);
26544b96 98
bc36d050 99 if (!scm_is_false (hook))
fdc28395 100 scm_call_1 (hook, filename);
26544b96 101
017eb4a6
AW
102 {
103 SCM port;
104
105 port = scm_open_file (filename, scm_from_locale_string ("r"));
661ae7ab
MV
106 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
107 scm_i_dynwind_current_load_port (port);
f8a1c9a8 108
b2cb557d
AW
109 /* FIXME: For better or for worse, scm_open_file already scans the
110 file for an encoding. This scans again; necessary for this
111 logic, but unnecessary overall. */
f8a1c9a8 112 encoding = scm_i_scan_for_encoding (port);
889975e5 113 if (encoding)
f8a1c9a8 114 scm_i_set_port_encoding_x (port, encoding);
889975e5 115 else
eb7a16a9
AW
116 /* The file has no encoding declared. We'll presume UTF-8, like
117 compile-file does. */
118 scm_i_set_port_encoding_x (port, "UTF-8");
f8a1c9a8 119
b5623573
MV
120 while (1)
121 {
ec3a8ace
NJ
122 SCM reader, form;
123
124 /* Lookup and use the current reader to read the next
125 expression. */
8b039053 126 reader = scm_fluid_ref (the_reader);
393baa8a 127 if (scm_is_false (reader))
ec3a8ace
NJ
128 form = scm_read (port);
129 else
130 form = scm_call_1 (reader, port);
131
b5623573
MV
132 if (SCM_EOF_OBJECT_P (form))
133 break;
ec3a8ace 134
017eb4a6 135 ret = scm_primitive_eval_x (form);
b5623573
MV
136 }
137
661ae7ab 138 scm_dynwind_end ();
0f2d19dd
JB
139 scm_close_port (port);
140 }
017eb4a6 141 return ret;
0f2d19dd 142}
1bbd0b84 143#undef FUNC_NAME
0f2d19dd 144
c519b272
MV
145SCM
146scm_c_primitive_load (const char *filename)
147{
cc95e00a 148 return scm_primitive_load (scm_from_locale_string (filename));
c519b272
MV
149}
150
0f2d19dd 151\f
3feedb00
MD
152/* Builtin path to scheme library files. */
153#ifdef SCM_PKGDATA_DIR
a1ec6916 154SCM_DEFINE (scm_sys_package_data_dir, "%package-data-dir", 0, 0, 0,
1bbd0b84 155 (),
b380b885
MD
156 "Return the name of the directory where Scheme packages, modules and\n"
157 "libraries are kept. On most Unix systems, this will be\n"
158 "@samp{/usr/local/share/guile}.")
1bbd0b84 159#define FUNC_NAME s_scm_sys_package_data_dir
3feedb00 160{
cc95e00a 161 return scm_from_locale_string (SCM_PKGDATA_DIR);
3feedb00 162}
1bbd0b84 163#undef FUNC_NAME
3feedb00
MD
164#endif /* SCM_PKGDATA_DIR */
165
e8e9b690 166#ifdef SCM_LIBRARY_DIR
a1ec6916 167SCM_DEFINE (scm_sys_library_dir, "%library-dir", 0,0,0,
e8e9b690 168 (),
b380b885
MD
169 "Return the directory where the Guile Scheme library files are installed.\n"
170 "E.g., may return \"/usr/share/guile/1.3.5\".")
e8e9b690
GB
171#define FUNC_NAME s_scm_sys_library_dir
172{
cc95e00a 173 return scm_from_locale_string (SCM_LIBRARY_DIR);
e8e9b690
GB
174}
175#undef FUNC_NAME
176#endif /* SCM_LIBRARY_DIR */
177
178#ifdef SCM_SITE_DIR
a1ec6916 179SCM_DEFINE (scm_sys_site_dir, "%site-dir", 0,0,0,
e8e9b690 180 (),
bc325e76
AW
181 "Return the directory where users should install Scheme code for use\n"
182 "with this version of Guile.\n\n"
183 "E.g., may return \"/usr/share/guile/site/" SCM_EFFECTIVE_VERSION "\".")
e8e9b690
GB
184#define FUNC_NAME s_scm_sys_site_dir
185{
cc95e00a 186 return scm_from_locale_string (SCM_SITE_DIR);
e8e9b690
GB
187}
188#undef FUNC_NAME
189#endif /* SCM_SITE_DIR */
190
bc325e76
AW
191#ifdef SCM_GLOBAL_SITE_DIR
192SCM_DEFINE (scm_sys_global_site_dir, "%global-site-dir", 0,0,0,
193 (),
194 "Return the directory where users should install Scheme code for use\n"
195 "with all versions of Guile.\n\n"
196 "E.g., may return \"/usr/share/guile/site\".")
197#define FUNC_NAME s_scm_sys_global_site_dir
198{
199 return scm_from_locale_string (SCM_GLOBAL_SITE_DIR);
200}
201#undef FUNC_NAME
202#endif /* SCM_GLOBAL_SITE_DIR */
e8e9b690
GB
203
204
3feedb00 205\f
06721500 206/* Initializing the load path, and searching it. */
0f2d19dd 207
26544b96 208/* List of names of directories we search for files to load. */
06721500
JB
209static SCM *scm_loc_load_path;
210
26544b96
JB
211/* List of extensions we try adding to the filenames. */
212static SCM *scm_loc_load_extensions;
213
5b197db8
AW
214/* Like %load-path and %load-extensions, but for compiled files. */
215static SCM *scm_loc_load_compiled_path;
22f4ee48
AW
216static SCM *scm_loc_load_compiled_extensions;
217
ee001750 218/* Whether we should try to auto-compile. */
6f06e8d3 219static SCM *scm_loc_load_should_auto_compile;
01cddfc1 220
1e56cff2
AW
221/* Whether to treat all auto-compiled files as stale. */
222static SCM *scm_loc_fresh_auto_compile;
223
6f06e8d3 224/* The fallback path for auto-compilation */
5ea401bf 225static SCM *scm_loc_compile_fallback_path;
01cddfc1 226
bd31bce6
MW
227/* Ellipsis: "..." */
228static SCM scm_ellipsis;
229
a1ec6916 230SCM_DEFINE (scm_parse_path, "parse-path", 1, 1, 0,
1bbd0b84 231 (SCM path, SCM tail),
d91788cb
MG
232 "Parse @var{path}, which is expected to be a colon-separated\n"
233 "string, into a list and return the resulting list with\n"
234 "@var{tail} appended. If @var{path} is @code{#f}, @var{tail}\n"
235 "is returned.")
1bbd0b84 236#define FUNC_NAME s_scm_parse_path
04e8fb0a 237{
7d04d68b
MV
238#ifdef __MINGW32__
239 SCM sep = SCM_MAKE_CHAR (';');
240#else
241 SCM sep = SCM_MAKE_CHAR (':');
242#endif
243
04e8fb0a
MD
244 if (SCM_UNBNDP (tail))
245 tail = SCM_EOL;
7888309b 246 return (scm_is_false (path)
04e8fb0a 247 ? tail
7d04d68b 248 : scm_append_x (scm_list_2 (scm_string_split (path, sep), tail)));
04e8fb0a 249}
1bbd0b84 250#undef FUNC_NAME
04e8fb0a 251
bd31bce6
MW
252SCM_DEFINE (scm_parse_path_with_ellipsis, "parse-path-with-ellipsis", 2, 0, 0,
253 (SCM path, SCM base),
254 "Parse @var{path}, which is expected to be a colon-separated\n"
255 "string, into a list and return the resulting list with\n"
256 "@var{base} (a list) spliced in place of the @code{...} path\n"
257 "component, if present, or else @var{base} is added to the end.\n"
258 "If @var{path} is @code{#f}, @var{base} is returned.")
259#define FUNC_NAME s_scm_parse_path_with_ellipsis
260{
261 SCM lst = scm_parse_path (path, SCM_EOL);
262 SCM walk = lst;
263 SCM *prev = &lst;
264
265 while (!scm_is_null (walk) &&
266 scm_is_false (scm_equal_p (scm_car (walk), scm_ellipsis)))
267 {
268 prev = SCM_CDRLOC (walk);
269 walk = *prev;
270 }
271 *prev = scm_is_null (walk)
272 ? base
273 : scm_append (scm_list_2 (base, scm_cdr (walk)));
274 return lst;
275}
276#undef FUNC_NAME
277
04e8fb0a 278
06721500 279/* Initialize the global variable %load-path, given the value of the
3feedb00 280 SCM_SITE_DIR and SCM_LIBRARY_DIR preprocessor symbols and the
01cddfc1 281 GUILE_LOAD_PATH environment variable. */
0f2d19dd 282void
06721500
JB
283scm_init_load_path ()
284{
11c5e0bf 285 char *env;
06721500 286 SCM path = SCM_EOL;
5b197db8 287 SCM cpath = SCM_EOL;
06721500 288
3feedb00 289#ifdef SCM_LIBRARY_DIR
02b84691
AW
290 env = getenv ("GUILE_SYSTEM_PATH");
291 if (env && strcmp (env, "") == 0)
292 /* special-case interpret system-path=="" as meaning no system path instead
293 of '("") */
294 ;
295 else if (env)
296 path = scm_parse_path (scm_from_locale_string (env), path);
297 else
bc325e76 298 path = scm_list_4 (scm_from_locale_string (SCM_LIBRARY_DIR),
3c98a49c 299 scm_from_locale_string (SCM_SITE_DIR),
bc325e76 300 scm_from_locale_string (SCM_GLOBAL_SITE_DIR),
02b84691 301 scm_from_locale_string (SCM_PKGDATA_DIR));
5b197db8
AW
302
303 env = getenv ("GUILE_SYSTEM_COMPILED_PATH");
304 if (env && strcmp (env, "") == 0)
305 /* like above */
306 ;
307 else if (env)
308 cpath = scm_parse_path (scm_from_locale_string (env), cpath);
309 else
9957641b
AW
310 {
311 cpath = scm_list_2 (scm_from_locale_string (SCM_CCACHE_DIR),
312 scm_from_locale_string (SCM_SITE_CCACHE_DIR));
313 }
3c997c4b 314
3feedb00 315#endif /* SCM_LIBRARY_DIR */
06721500 316
3c997c4b 317 {
179fe336
AW
318 char cachedir[1024];
319 char *e;
320#ifdef HAVE_GETPWENT
321 struct passwd *pwd;
322#endif
5b197db8 323
6e5c02b8
AW
324#define FALLBACK_DIR \
325 "guile/ccache/" SCM_EFFECTIVE_VERSION "-" SCM_OBJCODE_MACHINE_VERSION_STRING
179fe336
AW
326
327 if ((e = getenv ("XDG_CACHE_HOME")))
48a0fe4d 328 snprintf (cachedir, sizeof(cachedir), "%s/" FALLBACK_DIR, e);
179fe336
AW
329 else if ((e = getenv ("HOME")))
330 snprintf (cachedir, sizeof(cachedir), "%s/.cache/" FALLBACK_DIR, e);
5b197db8 331#ifdef HAVE_GETPWENT
179fe336
AW
332 else if ((pwd = getpwuid (getuid ())) && pwd->pw_dir)
333 snprintf (cachedir, sizeof(cachedir), "%s/.cache/" FALLBACK_DIR,
334 pwd->pw_dir);
5b197db8 335#endif /* HAVE_GETPWENT */
284019a2
JN
336#ifdef __MINGW32__
337 else if ((e = getenv ("LOCALAPPDATA")))
338 snprintf (cachedir, sizeof (cachedir), "%s/.cache/" FALLBACK_DIR, e);
339 else if ((e = getenv ("APPDATA")))
340 snprintf (cachedir, sizeof (cachedir), "%s/.cache/" FALLBACK_DIR, e);
341#endif /* __MINGW32__ */
179fe336
AW
342 else
343 cachedir[0] = 0;
344
345 if (cachedir[0])
346 *scm_loc_compile_fallback_path = scm_from_locale_string (cachedir);
3c997c4b 347 }
06721500 348
11c5e0bf
MV
349 env = getenv ("GUILE_LOAD_PATH");
350 if (env)
bd31bce6 351 path = scm_parse_path_with_ellipsis (scm_from_locale_string (env), path);
01cddfc1 352
5b197db8
AW
353 env = getenv ("GUILE_LOAD_COMPILED_PATH");
354 if (env)
bd31bce6 355 cpath = scm_parse_path_with_ellipsis (scm_from_locale_string (env), cpath);
5b197db8 356
06721500 357 *scm_loc_load_path = path;
5b197db8 358 *scm_loc_load_compiled_path = cpath;
06721500
JB
359}
360
04e8fb0a 361SCM scm_listofnullstr;
06721500 362
7d04d68b
MV
363/* Utility functions for assembling C strings in a buffer.
364 */
365
366struct stringbuf {
367 char *buf, *ptr;
368 size_t buf_len;
369};
370
371static void
372stringbuf_free (void *data)
373{
374 struct stringbuf *buf = (struct stringbuf *)data;
375 free (buf->buf);
376}
377
378static void
379stringbuf_grow (struct stringbuf *buf)
380{
381 size_t ptroff = buf->ptr - buf->buf;
382 buf->buf_len *= 2;
7d04d68b
MV
383 buf->buf = scm_realloc (buf->buf, buf->buf_len);
384 buf->ptr = buf->buf + ptroff;
385}
386
387static void
388stringbuf_cat_locale_string (struct stringbuf *buf, SCM str)
389{
390 size_t max_len = buf->buf_len - (buf->ptr - buf->buf) - 1;
391 size_t len = scm_to_locale_stringbuf (str, buf->ptr, max_len);
392 if (len > max_len)
393 {
394 /* buffer is too small, double its size and try again.
395 */
396 stringbuf_grow (buf);
397 stringbuf_cat_locale_string (buf, str);
398 }
399 else
400 {
401 /* string fits, terminate it and check for embedded '\0'.
402 */
403 buf->ptr[len] = '\0';
404 if (strlen (buf->ptr) != len)
405 scm_misc_error (NULL,
406 "string contains #\\nul character: ~S",
407 scm_list_1 (str));
408 buf->ptr += len;
409 }
410}
411
412static void
413stringbuf_cat (struct stringbuf *buf, char *str)
414{
415 size_t max_len = buf->buf_len - (buf->ptr - buf->buf) - 1;
416 size_t len = strlen (str);
417 if (len > max_len)
418 {
419 /* buffer is too small, double its size and try again.
420 */
421 stringbuf_grow (buf);
422 stringbuf_cat (buf, str);
423 }
424 else
425 {
426 /* string fits, copy it into buffer.
427 */
428 strcpy (buf->ptr, str);
429 buf->ptr += len;
430 }
431}
432
433
22f4ee48
AW
434static int
435scm_c_string_has_an_ext (char *str, size_t len, SCM extensions)
436{
437 for (; !scm_is_null (extensions); extensions = SCM_CDR (extensions))
438 {
439 char *ext;
440 size_t extlen;
441 int match;
442 ext = scm_to_locale_string (SCM_CAR (extensions));
443 extlen = strlen (ext);
444 match = (len > extlen && str[len - extlen - 1] == '.'
445 && strncmp (str + (len - extlen), ext, extlen) == 0);
446 free (ext);
447 if (match)
448 return 1;
449 }
450 return 0;
451}
452
04e8fb0a 453/* Search PATH for a directory containing a file named FILENAME.
06721500 454 The file must be readable, and not a directory.
c12da2be 455 If we find one, return its full pathname; otherwise, return #f.
56384176 456 If FILENAME is absolute, return it unchanged.
c12da2be 457 We also fill *stat_buf corresponding to the returned pathname.
56384176
JB
458 If given, EXTENSIONS is a list of strings; for each directory
459 in PATH, we search for FILENAME concatenated with each EXTENSION. */
a6e1e050
AW
460static SCM
461search_path (SCM path, SCM filename, SCM extensions, SCM require_exts,
462 struct stat *stat_buf)
06721500 463{
7d04d68b 464 struct stringbuf buf;
56384176 465 char *filename_chars;
7d04d68b
MV
466 size_t filename_len;
467 SCM result = SCM_BOOL_F;
06721500 468
a6e1e050
AW
469 if (scm_ilength (path) < 0)
470 scm_misc_error ("%search-path", "path is not a proper list: ~a",
471 scm_list_1 (path));
472 if (scm_ilength (extensions) < 0)
473 scm_misc_error ("%search-path", "bad extensions list: ~a",
474 scm_list_1 (extensions));
22f4ee48 475
661ae7ab 476 scm_dynwind_begin (0);
7d04d68b
MV
477
478 filename_chars = scm_to_locale_string (filename);
479 filename_len = strlen (filename_chars);
661ae7ab 480 scm_dynwind_free (filename_chars);
06721500 481
c12da2be 482 /* If FILENAME is absolute and is still valid, return it unchanged. */
2e945bcc
SJ
483#ifdef __MINGW32__
484 if (((filename_len >= 1) &&
485 (filename_chars[0] == '/' || filename_chars[0] == '\\')) ||
486 ((filename_len >= 3) && filename_chars[1] == ':' &&
487 ((filename_chars[0] >= 'a' && filename_chars[0] <= 'z') ||
488 (filename_chars[0] >= 'A' && filename_chars[0] <= 'Z')) &&
489 (filename_chars[2] == '/' || filename_chars[2] == '\\')))
490#else
56384176 491 if (filename_len >= 1 && filename_chars[0] == '/')
2e945bcc 492#endif
7d04d68b 493 {
c12da2be
MW
494 if ((scm_is_false (require_exts) ||
495 scm_c_string_has_an_ext (filename_chars, filename_len,
22f4ee48 496 extensions))
c12da2be
MW
497 && stat (filename_chars, stat_buf) == 0
498 && !(stat_buf->st_mode & S_IFDIR))
499 result = filename;
500 goto end;
7d04d68b 501 }
26544b96 502
56384176
JB
503 /* If FILENAME has an extension, don't try to add EXTENSIONS to it. */
504 {
505 char *endp;
506
507 for (endp = filename_chars + filename_len - 1;
508 endp >= filename_chars;
509 endp--)
510 {
511 if (*endp == '.')
512 {
22f4ee48
AW
513 if (scm_is_true (require_exts) &&
514 !scm_c_string_has_an_ext (filename_chars, filename_len,
515 extensions))
516 {
517 /* This filename has an extension, but not one of the right
518 ones... */
c12da2be 519 goto end;
22f4ee48 520 }
56384176
JB
521 /* This filename already has an extension, so cancel the
522 list of extensions. */
523 extensions = SCM_EOL;
524 break;
525 }
2e945bcc
SJ
526#ifdef __MINGW32__
527 else if (*endp == '/' || *endp == '\\')
528#else
56384176 529 else if (*endp == '/')
2e945bcc 530#endif
56384176
JB
531 /* This filename has no extension, so keep the current list
532 of extensions. */
533 break;
534 }
535 }
536
7d04d68b
MV
537 /* This simplifies the loop below a bit.
538 */
d2e53ed6 539 if (scm_is_null (extensions))
7d04d68b 540 extensions = scm_listofnullstr;
06721500 541
7d04d68b
MV
542 buf.buf_len = 512;
543 buf.buf = scm_malloc (buf.buf_len);
661ae7ab 544 scm_dynwind_unwind_handler (stringbuf_free, &buf, SCM_F_WIND_EXPLICITLY);
0a74e31d 545
7d04d68b
MV
546 /* Try every path element.
547 */
d2e53ed6 548 for (; scm_is_pair (path); path = SCM_CDR (path))
7d04d68b
MV
549 {
550 SCM dir = SCM_CAR (path);
551 SCM exts;
552 size_t sans_ext_len;
553
554 buf.ptr = buf.buf;
555 stringbuf_cat_locale_string (&buf, dir);
556
557 /* Concatenate the path name and the filename. */
558
2e945bcc 559#ifdef __MINGW32__
5a6d139b 560 if ((buf.ptr > buf.buf) && (buf.ptr[-1] != '/') && (buf.ptr[-1] != '\\'))
2e945bcc 561#else
5a6d139b 562 if ((buf.ptr > buf.buf) && (buf.ptr[-1] != '/'))
2e945bcc 563#endif
7d04d68b
MV
564 stringbuf_cat (&buf, "/");
565
566 stringbuf_cat (&buf, filename_chars);
567 sans_ext_len = buf.ptr - buf.buf;
568
569 /* Try every extension. */
d2e53ed6 570 for (exts = extensions; scm_is_pair (exts); exts = SCM_CDR (exts))
7d04d68b
MV
571 {
572 SCM ext = SCM_CAR (exts);
7d04d68b
MV
573
574 buf.ptr = buf.buf + sans_ext_len;
575 stringbuf_cat_locale_string (&buf, ext);
576
577 /* If the file exists at all, we should return it. If the
578 file is inaccessible, then that's an error. */
579
a6e1e050
AW
580 if (stat (buf.buf, stat_buf) == 0
581 && ! (stat_buf->st_mode & S_IFDIR))
7d04d68b
MV
582 {
583 result = scm_from_locale_string (buf.buf);
584 goto end;
585 }
586 }
587
588 if (!SCM_NULL_OR_NIL_P (exts))
589 scm_wrong_type_arg_msg (NULL, 0, extensions, "proper list");
590 }
56384176 591
7d04d68b
MV
592 if (!SCM_NULL_OR_NIL_P (path))
593 scm_wrong_type_arg_msg (NULL, 0, path, "proper list");
56384176 594
7d04d68b 595 end:
661ae7ab 596 scm_dynwind_end ();
7d04d68b 597 return result;
06721500 598}
a6e1e050
AW
599
600SCM_DEFINE (scm_search_path, "search-path", 2, 0, 1,
601 (SCM path, SCM filename, SCM rest),
602 "Search @var{path} for a directory containing a file named\n"
603 "@var{filename}. The file must be readable, and not a directory.\n"
604 "If we find one, return its full filename; otherwise, return\n"
605 "@code{#f}. If @var{filename} is absolute, return it unchanged.\n"
b7e64f8b 606 "If given, @var{rest} is a list of extension strings; for each\n"
a6e1e050 607 "directory in @var{path}, we search for @var{filename}\n"
b7e64f8b 608 "concatenated with each extension.")
a6e1e050
AW
609#define FUNC_NAME s_scm_search_path
610{
611 SCM extensions, require_exts;
612 struct stat stat_buf;
613
614 if (SCM_UNBNDP (rest) || scm_is_null (rest))
615 {
616 /* Called either by Scheme code that didn't provide the optional
617 arguments, or C code that used the Guile 1.8 signature (2 required,
618 1 optional arg) and passed '() or nothing as the EXTENSIONS
619 argument. */
620 extensions = SCM_EOL;
621 require_exts = SCM_UNDEFINED;
622 }
623 else
624 {
625 if (scm_is_null (SCM_CAR (rest)) || scm_is_pair (SCM_CAR (rest)))
626 {
627 /* Called by Scheme code written for 1.9. */
628 extensions = SCM_CAR (rest);
629 if (scm_is_null (SCM_CDR (rest)))
630 require_exts = SCM_UNDEFINED;
631 else
632 {
633 require_exts = SCM_CADR (rest);
634 if (SCM_UNLIKELY (!scm_is_null (SCM_CDDR (rest))))
635 scm_wrong_num_args (scm_from_locale_string (FUNC_NAME));
636 }
637 }
638 else
639 {
640 /* Called by C code that uses the 1.8 signature, i.e., which
641 expects the 3rd argument to be EXTENSIONS. */
642 extensions = rest;
643 require_exts = SCM_UNDEFINED;
644 }
645 }
646
647 if (SCM_UNBNDP (extensions))
648 extensions = SCM_EOL;
649
650 if (SCM_UNBNDP (require_exts))
651 require_exts = SCM_BOOL_F;
652
653 return search_path (path, filename, extensions, require_exts, &stat_buf);
654}
1bbd0b84 655#undef FUNC_NAME
06721500
JB
656
657
04e8fb0a
MD
658/* Search %load-path for a directory containing a file named FILENAME.
659 The file must be readable, and not a directory.
660 If we find one, return its full filename; otherwise, return #f.
661 If FILENAME is absolute, return it unchanged. */
3b3b36dd 662SCM_DEFINE (scm_sys_search_load_path, "%search-load-path", 1, 0, 0,
67e8151b
MG
663 (SCM filename),
664 "Search @var{%load-path} for the file named @var{filename},\n"
665 "which must be readable by the current user. If @var{filename}\n"
666 "is found in the list of paths to search or is an absolute\n"
667 "pathname, return its full pathname. Otherwise, return\n"
668 "@code{#f}. Filenames may have any of the optional extensions\n"
669 "in the @code{%load-extensions} list; @code{%search-load-path}\n"
670 "will try each extension automatically.")
1bbd0b84 671#define FUNC_NAME s_scm_sys_search_load_path
04e8fb0a 672{
a6e1e050
AW
673 struct stat stat_buf;
674
a6d9e5ab 675 SCM_VALIDATE_STRING (1, filename);
1bbd0b84 676
a6e1e050
AW
677 return search_path (*scm_loc_load_path, filename, *scm_loc_load_extensions,
678 SCM_BOOL_F, &stat_buf);
04e8fb0a 679}
1bbd0b84 680#undef FUNC_NAME
04e8fb0a
MD
681
682
abca59fe 683/* Return true if COMPILED_FILENAME is newer than source file
a6e1e050 684 FULL_FILENAME, false otherwise. */
1d022387 685static int
a6e1e050
AW
686compiled_is_fresh (SCM full_filename, SCM compiled_filename,
687 struct stat *stat_source, struct stat *stat_compiled)
1d022387 688{
722a4fb9 689 int compiled_is_newer;
a6e1e050 690 struct timespec source_mtime, compiled_mtime;
1d022387 691
a6e1e050
AW
692 source_mtime = get_stat_mtime (stat_source);
693 compiled_mtime = get_stat_mtime (stat_compiled);
fefd60ba 694
a6e1e050
AW
695 if (source_mtime.tv_sec < compiled_mtime.tv_sec
696 || (source_mtime.tv_sec == compiled_mtime.tv_sec
697 && source_mtime.tv_nsec <= compiled_mtime.tv_nsec))
698 compiled_is_newer = 1;
699 else
1d022387 700 {
a6e1e050
AW
701 compiled_is_newer = 0;
702 scm_puts (";;; note: source file ", scm_current_error_port ());
703 scm_display (full_filename, scm_current_error_port ());
704 scm_puts ("\n;;; newer than compiled ", scm_current_error_port ());
705 scm_display (compiled_filename, scm_current_error_port ());
706 scm_puts ("\n", scm_current_error_port ());
1d022387 707 }
abca59fe
LC
708
709 return compiled_is_newer;
1d022387
AW
710}
711
87c595c7 712SCM_KEYWORD (kw_env, "env");
5a79300f
LC
713SCM_KEYWORD (kw_opts, "opts");
714
715SCM_SYMBOL (sym_compile_file, "compile-file");
716SCM_SYMBOL (sym_auto_compilation_options, "%auto-compilation-options");
87c595c7 717
1d022387 718static SCM
6f06e8d3 719do_try_auto_compile (void *data)
1d022387 720{
3c997c4b
AW
721 SCM source = PTR2SCM (data);
722 SCM comp_mod, compile_file;
ee001750
AW
723
724 scm_puts (";;; compiling ", scm_current_error_port ());
3c997c4b 725 scm_display (source, scm_current_error_port ());
ee001750
AW
726 scm_newline (scm_current_error_port ());
727
728 comp_mod = scm_c_resolve_module ("system base compile");
5a79300f 729 compile_file = scm_module_variable (comp_mod, sym_compile_file);
ee001750 730
3c997c4b
AW
731 if (scm_is_true (compile_file))
732 {
87c595c7 733 /* Auto-compile in the context of the current module. */
5a79300f
LC
734 SCM res, opts;
735 SCM args[5];
736
737 opts = scm_module_variable (scm_the_root_module (),
738 sym_auto_compilation_options);
739 if (SCM_VARIABLEP (opts))
740 opts = SCM_VARIABLE_REF (opts);
741 else
742 opts = SCM_EOL;
743
744 args[0] = source;
745 args[1] = kw_opts;
746 args[2] = opts;
747 args[3] = kw_env;
748 args[4] = scm_current_module ();
749
750 /* Assume `*current-warning-prefix*' has an appropriate value. */
751 res = scm_call_n (scm_variable_ref (compile_file), args, 5);
752
3c997c4b
AW
753 scm_puts (";;; compiled ", scm_current_error_port ());
754 scm_display (res, scm_current_error_port ());
755 scm_newline (scm_current_error_port ());
756 return res;
757 }
758 else
759 {
760 scm_puts (";;; it seems ", scm_current_error_port ());
761 scm_display (source, scm_current_error_port ());
6f06e8d3 762 scm_puts ("\n;;; is part of the compiler; skipping auto-compilation\n",
3c997c4b
AW
763 scm_current_error_port ());
764 return SCM_BOOL_F;
765 }
ee001750
AW
766}
767
768static SCM
6f06e8d3 769auto_compile_catch_handler (void *data, SCM tag, SCM throw_args)
ee001750 770{
3c997c4b 771 SCM source = PTR2SCM (data);
669ea4eb
AW
772 SCM oport, lines;
773
774 oport = scm_open_output_string ();
775 scm_print_exception (oport, SCM_BOOL_F, tag, throw_args);
776
2c27dd57
AW
777 scm_puts (";;; WARNING: compilation of ", scm_current_warning_port ());
778 scm_display (source, scm_current_warning_port ());
779 scm_puts (" failed:\n", scm_current_warning_port ());
669ea4eb
AW
780
781 lines = scm_string_split (scm_get_output_string (oport),
782 SCM_MAKE_CHAR ('\n'));
783 for (; scm_is_pair (lines); lines = scm_cdr (lines))
784 if (scm_c_string_length (scm_car (lines)))
785 {
2c27dd57
AW
786 scm_puts (";;; ", scm_current_warning_port ());
787 scm_display (scm_car (lines), scm_current_warning_port ());
788 scm_newline (scm_current_warning_port ());
669ea4eb
AW
789 }
790
791 scm_close_port (oport);
792
1d022387
AW
793 return SCM_BOOL_F;
794}
795
6f06e8d3 796SCM_DEFINE (scm_sys_warn_auto_compilation_enabled, "%warn-auto-compilation-enabled", 0, 0, 0,
9591a2b0 797 (void), "")
6f06e8d3 798#define FUNC_NAME s_scm_sys_warn_auto_compilation_enabled
ee001750
AW
799{
800 static int message_shown = 0;
ee001750
AW
801
802 if (!message_shown)
803 {
6f06e8d3
AW
804 scm_puts (";;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0\n"
805 ";;; or pass the --no-auto-compile argument to disable.\n",
2c27dd57 806 scm_current_warning_port ());
ee001750
AW
807 message_shown = 1;
808 }
809
9591a2b0
AW
810 return SCM_UNSPECIFIED;
811}
15058484 812#undef FUNC_NAME
9591a2b0 813
9591a2b0 814static SCM
6f06e8d3 815scm_try_auto_compile (SCM source)
9591a2b0 816{
6f06e8d3 817 if (scm_is_false (*scm_loc_load_should_auto_compile))
9591a2b0
AW
818 return SCM_BOOL_F;
819
6f06e8d3 820 scm_sys_warn_auto_compilation_enabled ();
ee001750 821 return scm_c_catch (SCM_BOOL_T,
6f06e8d3 822 do_try_auto_compile,
3c997c4b 823 SCM2PTR (source),
6f06e8d3 824 auto_compile_catch_handler,
3c997c4b 825 SCM2PTR (source),
ee001750
AW
826 NULL, NULL);
827}
828
6934d9e7
AW
829/* See also (system base compile):compiled-file-name. */
830static SCM
e4f6e855 831canonical_suffix (SCM fname)
6934d9e7 832{
e4f6e855
AW
833 SCM canon;
834 size_t len;
835
836 canon = scm_canonicalize_path (fname);
837 len = scm_c_string_length (canon);
6934d9e7
AW
838
839 if (len > 1 && scm_is_eq (scm_c_string_ref (canon, 0), SCM_MAKE_CHAR ('/')))
840 return canon;
841 else if (len > 2 && scm_is_eq (scm_c_string_ref (canon, 1), SCM_MAKE_CHAR (':')))
842 return scm_string_append (scm_list_3 (scm_from_latin1_string ("/"),
843 scm_c_substring (canon, 0, 1),
844 scm_c_substring (canon, 2, len)));
845 else
846 return canon;
847}
848
31ab99de
LC
849SCM_DEFINE (scm_primitive_load_path, "primitive-load-path", 0, 0, 1,
850 (SCM args),
67e8151b 851 "Search @var{%load-path} for the file named @var{filename} and\n"
f6fd2c03
AW
852 "load it into the top-level environment.\n\n"
853 "If @var{filename} is a relative pathname and is not found in\n"
854 "the list of search paths, one of three things may happen,\n"
855 "depending on the optional second argument,\n"
856 "@var{exception_on_not_found}. If it is @code{#f}, @code{#f}\n"
857 "will be returned. If it is a procedure, it will be called\n"
858 "with no arguments. Otherwise an error is signalled.")
1bbd0b84 859#define FUNC_NAME s_scm_primitive_load_path
06721500 860{
31ab99de 861 SCM filename, exception_on_not_found;
22f4ee48 862 SCM full_filename, compiled_filename;
628132c5 863 int compiled_is_fallback = 0;
dcada7d8 864 SCM hook = *scm_loc_load_hook;
a6e1e050 865 struct stat stat_source, stat_compiled;
dcada7d8
AW
866
867 if (scm_is_true (hook) && scm_is_false (scm_procedure_p (hook)))
868 SCM_MISC_ERROR ("value of %load-hook is neither a procedure nor #f",
869 SCM_EOL);
26544b96 870
31ab99de
LC
871 if (scm_is_string (args))
872 {
873 /* C code written for 1.8 and earlier expects this function to take a
874 single argument (the file name). */
875 filename = args;
876 exception_on_not_found = SCM_UNDEFINED;
877 }
878 else
879 {
880 /* Starting from 1.9, this function takes 1 required and 1 optional
881 argument. */
882 long len;
883
884 SCM_VALIDATE_LIST_COPYLEN (SCM_ARG1, args, len);
885 if (len < 1 || len > 2)
886 scm_error_num_args_subr (FUNC_NAME);
887
888 filename = SCM_CAR (args);
889 SCM_VALIDATE_STRING (SCM_ARG1, filename);
890
891 exception_on_not_found = len > 1 ? SCM_CADR (args) : SCM_UNDEFINED;
892 }
893
0fb81f95
AW
894 if (SCM_UNBNDP (exception_on_not_found))
895 exception_on_not_found = SCM_BOOL_T;
26544b96 896
a6e1e050
AW
897 full_filename = search_path (*scm_loc_load_path, filename,
898 *scm_loc_load_extensions, SCM_BOOL_F,
899 &stat_source);
eba5ea7a 900
88cbb421 901 compiled_filename =
a6e1e050
AW
902 search_path (*scm_loc_load_compiled_path, filename,
903 *scm_loc_load_compiled_extensions, SCM_BOOL_T,
904 &stat_compiled);
88cbb421 905
5ea401bf
AW
906 if (scm_is_false (compiled_filename)
907 && scm_is_true (full_filename)
3c997c4b 908 && scm_is_true (*scm_loc_compile_fallback_path)
1e56cff2 909 && scm_is_false (*scm_loc_fresh_auto_compile)
3c997c4b
AW
910 && scm_is_pair (*scm_loc_load_compiled_extensions)
911 && scm_is_string (scm_car (*scm_loc_load_compiled_extensions)))
5ea401bf 912 {
a6e1e050
AW
913 SCM fallback;
914 char *fallback_chars;
915
916 fallback = scm_string_append
3c997c4b 917 (scm_list_3 (*scm_loc_compile_fallback_path,
e4f6e855 918 canonical_suffix (full_filename),
3c997c4b 919 scm_car (*scm_loc_load_compiled_extensions)));
a6e1e050
AW
920
921 fallback_chars = scm_to_locale_string (fallback);
922 if (stat (fallback_chars, &stat_compiled) == 0)
628132c5
AW
923 {
924 compiled_filename = fallback;
925 compiled_is_fallback = 1;
926 }
a6e1e050 927 free (fallback_chars);
5ea401bf
AW
928 }
929
22f4ee48 930 if (scm_is_false (full_filename) && scm_is_false (compiled_filename))
0fb81f95 931 {
f6fd2c03
AW
932 if (scm_is_true (scm_procedure_p (exception_on_not_found)))
933 return scm_call_0 (exception_on_not_found);
934 else if (scm_is_false (exception_on_not_found))
935 return SCM_BOOL_F;
936 else
0fb81f95
AW
937 SCM_MISC_ERROR ("Unable to find file ~S in load path",
938 scm_list_1 (filename));
0fb81f95 939 }
22f4ee48 940
dcada7d8
AW
941 if (!scm_is_false (hook))
942 scm_call_1 (hook, (scm_is_true (full_filename)
943 ? full_filename : compiled_filename));
944
1d022387
AW
945 if (scm_is_false (full_filename)
946 || (scm_is_true (compiled_filename)
a6e1e050
AW
947 && compiled_is_fresh (full_filename, compiled_filename,
948 &stat_source, &stat_compiled)))
22f4ee48
AW
949 return scm_load_compiled_with_vm (compiled_filename);
950
628132c5
AW
951 /* Perhaps there was the installed .go that was stale, but our fallback is
952 fresh. Let's try that. Duplicating code, but perhaps that's OK. */
953
954 if (!compiled_is_fallback
955 && scm_is_true (*scm_loc_compile_fallback_path)
1e56cff2 956 && scm_is_false (*scm_loc_fresh_auto_compile)
628132c5
AW
957 && scm_is_pair (*scm_loc_load_compiled_extensions)
958 && scm_is_string (scm_car (*scm_loc_load_compiled_extensions)))
959 {
a6e1e050
AW
960 SCM fallback;
961 char *fallback_chars;
962 int stat_ret;
963
964 fallback = scm_string_append
628132c5 965 (scm_list_3 (*scm_loc_compile_fallback_path,
e4f6e855 966 canonical_suffix (full_filename),
628132c5 967 scm_car (*scm_loc_load_compiled_extensions)));
a6e1e050
AW
968
969 fallback_chars = scm_to_locale_string (fallback);
970 stat_ret = stat (fallback_chars, &stat_compiled);
971 free (fallback_chars);
972
973 if (stat_ret == 0 && compiled_is_fresh (full_filename, fallback,
974 &stat_source, &stat_compiled))
628132c5 975 {
2c27dd57
AW
976 scm_puts (";;; found fresh local cache at ", scm_current_warning_port ());
977 scm_display (fallback, scm_current_warning_port ());
978 scm_newline (scm_current_warning_port ());
5950cc3f 979 return scm_load_compiled_with_vm (fallback);
628132c5 980 }
3c997c4b 981 }
628132c5
AW
982
983 /* Otherwise, we bottom out here. */
22f4ee48 984 {
6f06e8d3 985 SCM freshly_compiled = scm_try_auto_compile (full_filename);
22f4ee48 986
628132c5
AW
987 if (scm_is_true (freshly_compiled))
988 return scm_load_compiled_with_vm (freshly_compiled);
22f4ee48 989 else
628132c5 990 return scm_primitive_load (full_filename);
22f4ee48 991 }
06721500 992}
1bbd0b84 993#undef FUNC_NAME
06721500 994
c519b272
MV
995SCM
996scm_c_primitive_load_path (const char *filename)
997{
31ab99de 998 return scm_primitive_load_path (scm_from_locale_string (filename));
c519b272
MV
999}
1000
5f161164
AW
1001void
1002scm_init_eval_in_scheme (void)
1003{
1004 SCM eval_scm, eval_go;
a6e1e050
AW
1005 struct stat stat_source, stat_compiled;
1006
1007 eval_scm = search_path (*scm_loc_load_path,
1008 scm_from_locale_string ("ice-9/eval.scm"),
1009 SCM_EOL, SCM_BOOL_F, &stat_source);
1010 eval_go = search_path (*scm_loc_load_compiled_path,
1011 scm_from_locale_string ("ice-9/eval.go"),
1012 SCM_EOL, SCM_BOOL_F, &stat_compiled);
5f161164
AW
1013
1014 if (scm_is_true (eval_scm) && scm_is_true (eval_go)
a6e1e050
AW
1015 && compiled_is_fresh (eval_scm, eval_go,
1016 &stat_source, &stat_compiled))
5f161164 1017 scm_load_compiled_with_vm (eval_go);
ed1bf2c8
AW
1018 else
1019 /* if we have no eval.go, we shouldn't load any compiled code at all */
1020 *scm_loc_load_compiled_path = SCM_EOL;
5f161164
AW
1021}
1022
06721500 1023\f
e151bee6 1024/* Information about the build environment. */
06721500 1025
d7a22073
LC
1026SCM_VARIABLE_INIT (sys_host_type, "%host-type",
1027 scm_from_locale_string (HOST_TYPE));
1028
1029
e151bee6
JB
1030/* Initialize the scheme variable %guile-build-info, based on data
1031 provided by the Makefile, via libpath.h. */
1032static void
1033init_build_info ()
1034{
1035 static struct { char *name; char *value; } info[] = SCM_BUILD_INFO;
86d31dfe 1036 SCM *loc = SCM_VARIABLE_LOC (scm_c_define ("%guile-build-info", SCM_EOL));
c014a02e 1037 unsigned long i;
e151bee6
JB
1038
1039 for (i = 0; i < (sizeof (info) / sizeof (info[0])); i++)
cc95e00a
MV
1040 {
1041 SCM key = scm_from_locale_symbol (info[i].name);
1042 SCM val = scm_from_locale_string (info[i].value);
1043 *loc = scm_acons (key, val, *loc);
1044 }
26ac1e3f
AW
1045#ifdef PACKAGE_PACKAGER
1046 *loc = scm_acons (scm_from_latin1_symbol ("packager"),
1047 scm_from_latin1_string (PACKAGE_PACKAGER),
1048 *loc);
1049#endif
1050#ifdef PACKAGE_PACKAGER_VERSION
1051 *loc = scm_acons (scm_from_latin1_symbol ("packager-version"),
1052 scm_from_latin1_string (PACKAGE_PACKAGER_VERSION),
1053 *loc);
1054#endif
1055#ifdef PACKAGE_PACKAGER_BUG_REPORTS
1056 *loc = scm_acons (scm_from_latin1_symbol ("packager-bug-reports"),
1057 scm_from_latin1_string (PACKAGE_PACKAGER_BUG_REPORTS),
1058 *loc);
1059#endif
e151bee6
JB
1060}
1061
e151bee6 1062\f
0f2d19dd
JB
1063void
1064scm_init_load ()
0f2d19dd 1065{
f39448c5 1066 scm_listofnullstr = scm_list_1 (scm_nullstr);
86d31dfe 1067 scm_loc_load_path = SCM_VARIABLE_LOC (scm_c_define ("%load-path", SCM_EOL));
26544b96 1068 scm_loc_load_extensions
86d31dfe 1069 = SCM_VARIABLE_LOC (scm_c_define ("%load-extensions",
cc95e00a
MV
1070 scm_list_2 (scm_from_locale_string (".scm"),
1071 scm_nullstr)));
5b197db8
AW
1072 scm_loc_load_compiled_path
1073 = SCM_VARIABLE_LOC (scm_c_define ("%load-compiled-path", SCM_EOL));
22f4ee48
AW
1074 scm_loc_load_compiled_extensions
1075 = SCM_VARIABLE_LOC (scm_c_define ("%load-compiled-extensions",
1076 scm_list_1 (scm_from_locale_string (".go"))));
86d31dfe 1077 scm_loc_load_hook = SCM_VARIABLE_LOC (scm_c_define ("%load-hook", SCM_BOOL_F));
06721500 1078
5ea401bf
AW
1079 scm_loc_compile_fallback_path
1080 = SCM_VARIABLE_LOC (scm_c_define ("%compile-fallback-path", SCM_BOOL_F));
6f06e8d3
AW
1081 scm_loc_load_should_auto_compile
1082 = SCM_VARIABLE_LOC (scm_c_define ("%load-should-auto-compile", SCM_BOOL_F));
1e56cff2
AW
1083 scm_loc_fresh_auto_compile
1084 = SCM_VARIABLE_LOC (scm_c_define ("%fresh-auto-compile", SCM_BOOL_F));
5ea401bf 1085
bd31bce6
MW
1086 scm_ellipsis = scm_from_latin1_string ("...");
1087
c81c2ad3 1088 the_reader = scm_make_fluid_with_default (SCM_BOOL_F);
ec3a8ace
NJ
1089 scm_c_define("current-reader", the_reader);
1090
a6029b97
AW
1091 scm_c_define ("load-compiled",
1092 scm_c_make_gsubr ("load-compiled/vm", 1, 0, 0,
1093 scm_load_compiled_with_vm));
1094
e151bee6
JB
1095 init_build_info ();
1096
a0599745 1097#include "libguile/load.x"
0f2d19dd 1098}
89e00824 1099
6128f34c 1100void
6f06e8d3 1101scm_init_load_should_auto_compile ()
6128f34c 1102{
1e56cff2
AW
1103 char *auto_compile = getenv ("GUILE_AUTO_COMPILE");
1104
1105 if (auto_compile && strcmp (auto_compile, "0") == 0)
1106 {
1107 *scm_loc_load_should_auto_compile = SCM_BOOL_F;
1108 *scm_loc_fresh_auto_compile = SCM_BOOL_F;
1109 }
1110 /* Allow "freshen" also. */
1111 else if (auto_compile && strncmp (auto_compile, "fresh", 5) == 0)
1112 {
1113 *scm_loc_load_should_auto_compile = SCM_BOOL_T;
1114 *scm_loc_fresh_auto_compile = SCM_BOOL_T;
1115 }
1116 else
1117 {
1118 *scm_loc_load_should_auto_compile = SCM_BOOL_T;
1119 *scm_loc_fresh_auto_compile = SCM_BOOL_F;
1120 }
6128f34c
AW
1121}
1122
1123
1124
89e00824
ML
1125/*
1126 Local Variables:
1127 c-file-style: "gnu"
1128 End:
1129*/