*** empty log message ***
[bpt/emacs.git] / src / lread.c
CommitLineData
078e7b4a 1/* Lisp parsing and input streams.
508b171c
JA
2 Copyright (C) 1985, 1986, 1987, 1988, 1989,
3 1992 Free Software Foundation, Inc.
078e7b4a
JB
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
46947372 9the Free Software Foundation; either version 2, or (at your option)
078e7b4a
JB
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22#include <stdio.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <sys/file.h>
26#undef NULL
27#include "config.h"
28#include "lisp.h"
29
30#ifndef standalone
31#include "buffer.h"
32#include "paths.h"
33#include "commands.h"
34#endif
35
36#ifdef lint
37#include <sys/inode.h>
38#endif /* lint */
39
40#ifndef X_OK
41#define X_OK 01
42#endif
43
44#ifdef LISP_FLOAT_TYPE
45#include <math.h>
46#endif /* LISP_FLOAT_TYPE */
47
48Lisp_Object Qread_char, Qget_file_char, Qstandard_input;
49Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist;
50
51/* non-zero if inside `load' */
52int load_in_progress;
53
54/* Search path for files to be loaded. */
55Lisp_Object Vload_path;
56
57/* File for get_file_char to read from. Use by load */
58static FILE *instream;
59
60/* When nonzero, read conses in pure space */
61static int read_pure;
62
63/* For use within read-from-string (this reader is non-reentrant!!) */
64static int read_from_string_index;
65static int read_from_string_limit;
66\f
67/* Handle unreading and rereading of characters.
68 Write READCHAR to read a character,
69 UNREAD(c) to unread c to be read again. */
70
71#define READCHAR readchar (readcharfun)
72#define UNREAD(c) unreadchar (readcharfun, c)
73
74static int
75readchar (readcharfun)
76 Lisp_Object readcharfun;
77{
78 Lisp_Object tem;
79 register struct buffer *inbuffer;
80 register int c, mpos;
81
82 if (XTYPE (readcharfun) == Lisp_Buffer)
83 {
84 inbuffer = XBUFFER (readcharfun);
85
86 if (BUF_PT (inbuffer) >= BUF_ZV (inbuffer))
87 return -1;
88 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, BUF_PT (inbuffer));
89 SET_BUF_PT (inbuffer, BUF_PT (inbuffer) + 1);
90
91 return c;
92 }
93 if (XTYPE (readcharfun) == Lisp_Marker)
94 {
95 inbuffer = XMARKER (readcharfun)->buffer;
96
97 mpos = marker_position (readcharfun);
98
99 if (mpos > BUF_ZV (inbuffer) - 1)
100 return -1;
101 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, mpos);
102 if (mpos != BUF_GPT (inbuffer))
103 XMARKER (readcharfun)->bufpos++;
104 else
105 Fset_marker (readcharfun, make_number (mpos + 1),
106 Fmarker_buffer (readcharfun));
107 return c;
108 }
109 if (EQ (readcharfun, Qget_file_char))
110 return getc (instream);
111
112 if (XTYPE (readcharfun) == Lisp_String)
113 {
114 register int c;
115 /* This used to be return of a conditional expression,
116 but that truncated -1 to a char on VMS. */
117 if (read_from_string_index < read_from_string_limit)
118 c = XSTRING (readcharfun)->data[read_from_string_index++];
119 else
120 c = -1;
121 return c;
122 }
123
124 tem = call0 (readcharfun);
125
265a9e55 126 if (NILP (tem))
078e7b4a
JB
127 return -1;
128 return XINT (tem);
129}
130
131/* Unread the character C in the way appropriate for the stream READCHARFUN.
132 If the stream is a user function, call it with the char as argument. */
133
134static void
135unreadchar (readcharfun, c)
136 Lisp_Object readcharfun;
137 int c;
138{
139 if (XTYPE (readcharfun) == Lisp_Buffer)
140 {
141 if (XBUFFER (readcharfun) == current_buffer)
142 SET_PT (point - 1);
143 else
144 SET_BUF_PT (XBUFFER (readcharfun), BUF_PT (XBUFFER (readcharfun)) - 1);
145 }
146 else if (XTYPE (readcharfun) == Lisp_Marker)
147 XMARKER (readcharfun)->bufpos--;
148 else if (XTYPE (readcharfun) == Lisp_String)
149 read_from_string_index--;
150 else if (EQ (readcharfun, Qget_file_char))
151 ungetc (c, instream);
152 else
153 call1 (readcharfun, make_number (c));
154}
155
156static Lisp_Object read0 (), read1 (), read_list (), read_vector ();
157\f
158/* get a character from the tty */
159
160DEFUN ("read-char", Fread_char, Sread_char, 0, 0, 0,
161 "Read a character from the command input (keyboard or macro).\n\
162It is returned as a number.")
163 ()
164{
165 register Lisp_Object val;
166
167#ifndef standalone
168 val = read_char (0);
169 if (XTYPE (val) != Lisp_Int)
170 {
171 unread_command_char = val;
172 error ("Object read was not a character");
173 }
174#else
175 val = getchar ();
176#endif
177
178 return val;
179}
180
181#ifdef HAVE_X_WINDOWS
182DEFUN ("read-event", Fread_event, Sread_event, 0, 0, 0,
183 "Read an event object from the input stream.")
184 ()
185{
186 register Lisp_Object val;
187
188 val = read_char (0);
189 return val;
190}
e5d77022 191#endif
078e7b4a
JB
192
193DEFUN ("read-char-exclusive", Fread_char_exclusive, Sread_char_exclusive, 0, 0, 0,
194 "Read a character from the command input (keyboard or macro).\n\
195It is returned as a number. Non character events are ignored.")
196 ()
197{
198 register Lisp_Object val;
199
200#ifndef standalone
201 val = read_char (0);
202 while (XTYPE (val) != Lisp_Int)
203 val = read_char (0);
204#else
205 val = getchar ();
206#endif
207
208 return val;
209}
078e7b4a
JB
210
211DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
212 "Don't use this yourself.")
213 ()
214{
215 register Lisp_Object val;
216 XSET (val, Lisp_Int, getc (instream));
217 return val;
218}
219\f
220static void readevalloop ();
221static Lisp_Object load_unwind ();
222
223DEFUN ("load", Fload, Sload, 1, 4, 0,
224 "Execute a file of Lisp code named FILE.\n\
225First try FILE with `.elc' appended, then try with `.el',\n\
226 then try FILE unmodified.\n\
227This function searches the directories in `load-path'.\n\
228If optional second arg NOERROR is non-nil,\n\
229 report no error if FILE doesn't exist.\n\
230Print messages at start and end of loading unless\n\
231 optional third arg NOMESSAGE is non-nil.\n\
232If optional fourth arg NOSUFFIX is non-nil, don't try adding\n\
233 suffixes `.elc' or `.el' to the specified name FILE.\n\
234Return t if file exists.")
235 (str, noerror, nomessage, nosuffix)
236 Lisp_Object str, noerror, nomessage, nosuffix;
237{
238 register FILE *stream;
239 register int fd = -1;
240 register Lisp_Object lispstream;
241 register FILE **ptr;
242 int count = specpdl_ptr - specpdl;
243 Lisp_Object temp;
244 struct gcpro gcpro1;
245 Lisp_Object found;
246
247 CHECK_STRING (str, 0);
248 str = Fsubstitute_in_file_name (str);
249
250 /* Avoid weird lossage with null string as arg,
251 since it would try to load a directory as a Lisp file */
252 if (XSTRING (str)->size > 0)
253 {
265a9e55 254 fd = openp (Vload_path, str, !NILP (nosuffix) ? "" : ".elc:.el:",
078e7b4a
JB
255 &found, 0);
256 }
257
258 if (fd < 0)
259 {
265a9e55 260 if (NILP (noerror))
078e7b4a
JB
261 while (1)
262 Fsignal (Qfile_error, Fcons (build_string ("Cannot open load file"),
263 Fcons (str, Qnil)));
264 else
265 return Qnil;
266 }
267
268 if (!bcmp (&(XSTRING (found)->data[XSTRING (found)->size - 4]),
269 ".elc", 4))
270 {
271 struct stat s1, s2;
272 int result;
273
274 stat (XSTRING (found)->data, &s1);
275 XSTRING (found)->data[XSTRING (found)->size - 1] = 0;
276 result = stat (XSTRING (found)->data, &s2);
277 if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime)
278 message ("Source file `%s' newer than byte-compiled file",
279 XSTRING (found)->data);
280 XSTRING (found)->data[XSTRING (found)->size - 1] = 'c';
281 }
282
283 stream = fdopen (fd, "r");
284 if (stream == 0)
285 {
286 close (fd);
287 error ("Failure to create stdio stream for %s", XSTRING (str)->data);
288 }
289
265a9e55 290 if (NILP (nomessage))
078e7b4a
JB
291 message ("Loading %s...", XSTRING (str)->data);
292
293 GCPRO1 (str);
294 /* We may not be able to store STREAM itself as a Lisp_Object pointer
295 since that is guaranteed to work only for data that has been malloc'd.
296 So malloc a full-size pointer, and record the address of that pointer. */
297 ptr = (FILE **) xmalloc (sizeof (FILE *));
298 *ptr = stream;
299 XSET (lispstream, Lisp_Internal_Stream, (int) ptr);
300 record_unwind_protect (load_unwind, lispstream);
301 load_in_progress++;
302 readevalloop (Qget_file_char, stream, Feval, 0);
303 unbind_to (count, Qnil);
304
305 /* Run any load-hooks for this file. */
306 temp = Fassoc (str, Vafter_load_alist);
265a9e55 307 if (!NILP (temp))
078e7b4a
JB
308 Fprogn (Fcdr (temp));
309 UNGCPRO;
310
265a9e55 311 if (!noninteractive && NILP (nomessage))
078e7b4a
JB
312 message ("Loading %s...done", XSTRING (str)->data);
313 return Qt;
314}
315
316static Lisp_Object
317load_unwind (stream) /* used as unwind-protect function in load */
318 Lisp_Object stream;
319{
320 fclose (*(FILE **) XSTRING (stream));
321 free (XPNTR (stream));
322 if (--load_in_progress < 0) load_in_progress = 0;
323 return Qnil;
324}
325
326\f
327static int
328complete_filename_p (pathname)
329 Lisp_Object pathname;
330{
331 register unsigned char *s = XSTRING (pathname)->data;
332 return (*s == '/'
333#ifdef ALTOS
334 || *s == '@'
335#endif
336#ifdef VMS
337 || index (s, ':')
338#endif /* VMS */
339 );
340}
341
342/* Search for a file whose name is STR, looking in directories
343 in the Lisp list PATH, and trying suffixes from SUFFIX.
344 SUFFIX is a string containing possible suffixes separated by colons.
345 On success, returns a file descriptor. On failure, returns -1.
346
347 EXEC_ONLY nonzero means don't open the files,
348 just look for one that is executable. In this case,
349 returns 1 on success.
350
351 If STOREPTR is nonzero, it points to a slot where the name of
352 the file actually found should be stored as a Lisp string.
353 Nil is stored there on failure. */
354
355int
356openp (path, str, suffix, storeptr, exec_only)
357 Lisp_Object path, str;
358 char *suffix;
359 Lisp_Object *storeptr;
360 int exec_only;
361{
362 register int fd;
363 int fn_size = 100;
364 char buf[100];
365 register char *fn = buf;
366 int absolute = 0;
367 int want_size;
368 register Lisp_Object filename;
369 struct stat st;
370
371 if (storeptr)
372 *storeptr = Qnil;
373
374 if (complete_filename_p (str))
375 absolute = 1;
376
265a9e55 377 for (; !NILP (path); path = Fcdr (path))
078e7b4a
JB
378 {
379 char *nsuffix;
380
381 filename = Fexpand_file_name (str, Fcar (path));
382 if (!complete_filename_p (filename))
383 /* If there are non-absolute elts in PATH (eg ".") */
384 /* Of course, this could conceivably lose if luser sets
385 default-directory to be something non-absolute... */
386 {
387 filename = Fexpand_file_name (filename, current_buffer->directory);
388 if (!complete_filename_p (filename))
389 /* Give up on this path element! */
390 continue;
391 }
392
393 /* Calculate maximum size of any filename made from
394 this path element/specified file name and any possible suffix. */
395 want_size = strlen (suffix) + XSTRING (filename)->size + 1;
396 if (fn_size < want_size)
397 fn = (char *) alloca (fn_size = 100 + want_size);
398
399 nsuffix = suffix;
400
401 /* Loop over suffixes. */
402 while (1)
403 {
404 char *esuffix = (char *) index (nsuffix, ':');
405 int lsuffix = esuffix ? esuffix - nsuffix : strlen (nsuffix);
406
407 /* Concatenate path element/specified name with the suffix. */
408 strncpy (fn, XSTRING (filename)->data, XSTRING (filename)->size);
409 fn[XSTRING (filename)->size] = 0;
410 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */
411 strncat (fn, nsuffix, lsuffix);
412
413 /* Ignore file if it's a directory. */
414 if (stat (fn, &st) >= 0
415 && (st.st_mode & S_IFMT) != S_IFDIR)
416 {
417 /* Check that we can access or open it. */
418 if (exec_only)
419 fd = (access (fn, X_OK) == 0) ? 1 : -1;
420 else
421 fd = open (fn, 0, 0);
422
423 if (fd >= 0)
424 {
425 /* We succeeded; return this descriptor and filename. */
426 if (storeptr)
427 *storeptr = build_string (fn);
428 return fd;
429 }
430 }
431
432 /* Advance to next suffix. */
433 if (esuffix == 0)
434 break;
435 nsuffix += lsuffix + 1;
436 }
437 if (absolute) return -1;
438 }
439
440 return -1;
441}
442
443\f
444Lisp_Object
445unreadpure () /* Used as unwind-protect function in readevalloop */
446{
447 read_pure = 0;
448 return Qnil;
449}
450
451static void
452readevalloop (readcharfun, stream, evalfun, printflag)
453 Lisp_Object readcharfun;
454 FILE *stream;
455 Lisp_Object (*evalfun) ();
456 int printflag;
457{
458 register int c;
459 register Lisp_Object val;
460 int count = specpdl_ptr - specpdl;
461
462 specbind (Qstandard_input, readcharfun);
463
464 while (1)
465 {
466 instream = stream;
467 c = READCHAR;
468 if (c == ';')
469 {
470 while ((c = READCHAR) != '\n' && c != -1);
471 continue;
472 }
473 if (c < 0) break;
474 if (c == ' ' || c == '\t' || c == '\n' || c == '\f') continue;
475
265a9e55 476 if (!NILP (Vpurify_flag) && c == '(')
078e7b4a
JB
477 {
478 record_unwind_protect (unreadpure, Qnil);
479 val = read_list (-1, readcharfun);
480 unbind_to (count + 1, Qnil);
481 }
482 else
483 {
484 UNREAD (c);
485 val = read0 (readcharfun);
486 }
487
488 val = (*evalfun) (val);
489 if (printflag)
490 {
491 Vvalues = Fcons (val, Vvalues);
492 if (EQ (Vstandard_output, Qt))
493 Fprin1 (val, Qnil);
494 else
495 Fprint (val, Qnil);
496 }
497 }
498
499 unbind_to (count, Qnil);
500}
501
502#ifndef standalone
503
e5d77022 504DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 2, "",
94b304d7
RS
505 "Execute the current buffer as Lisp code.\n\
506Programs can pass two arguments, BUFFER and PRINTFLAG.\n\
507BUFFER is the buffer to evaluate (nil means use current buffer).\n\
508PRINTFLAG controls printing of output:\n\
228d4b1c
JA
509nil means discard it; anything else is stream for print.\n\
510\n\
511If there is no error, point does not move. If there is an error,\n\
512point remains at the end of the last character read from the buffer.")
513 (bufname, printflag)
514 Lisp_Object bufname, printflag;
515{
516 int count = specpdl_ptr - specpdl;
517 Lisp_Object tem, buf;
518
dfdb645c 519 if (NILP (bufname))
228d4b1c
JA
520 buf = Fcurrent_buffer ();
521 else
522 buf = Fget_buffer (bufname);
dfdb645c 523 if (NILP (buf))
228d4b1c
JA
524 error ("No such buffer.");
525
dfdb645c 526 if (NILP (printflag))
228d4b1c
JA
527 tem = Qsymbolp;
528 else
529 tem = printflag;
530 specbind (Qstandard_output, tem);
531 record_unwind_protect (save_excursion_restore, save_excursion_save ());
532 BUF_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf)));
dfdb645c 533 readevalloop (buf, 0, Feval, !NILP (printflag));
228d4b1c
JA
534 unbind_to (count);
535
536 return Qnil;
537}
538
539#if 0
078e7b4a
JB
540DEFUN ("eval-current-buffer", Feval_current_buffer, Seval_current_buffer, 0, 1, "",
541 "Execute the current buffer as Lisp code.\n\
542Programs can pass argument PRINTFLAG which controls printing of output:\n\
543nil means discard it; anything else is stream for print.\n\
544\n\
545If there is no error, point does not move. If there is an error,\n\
546point remains at the end of the last character read from the buffer.")
547 (printflag)
548 Lisp_Object printflag;
549{
550 int count = specpdl_ptr - specpdl;
551 Lisp_Object tem;
552
265a9e55 553 if (NILP (printflag))
078e7b4a
JB
554 tem = Qsymbolp;
555 else
556 tem = printflag;
557 specbind (Qstandard_output, tem);
558 record_unwind_protect (save_excursion_restore, save_excursion_save ());
559 SET_PT (BEGV);
265a9e55 560 readevalloop (Fcurrent_buffer (), 0, Feval, !NILP (printflag));
078e7b4a
JB
561 return unbind_to (count, Qnil);
562}
228d4b1c 563#endif
078e7b4a
JB
564
565DEFUN ("eval-region", Feval_region, Seval_region, 2, 3, "r",
566 "Execute the region as Lisp code.\n\
567When called from programs, expects two arguments,\n\
568giving starting and ending indices in the current buffer\n\
569of the text to be executed.\n\
570Programs can pass third argument PRINTFLAG which controls output:\n\
571nil means discard it; anything else is stream for printing it.\n\
572\n\
573If there is no error, point does not move. If there is an error,\n\
574point remains at the end of the last character read from the buffer.")
575 (b, e, printflag)
576 Lisp_Object b, e, printflag;
577{
578 int count = specpdl_ptr - specpdl;
579 Lisp_Object tem;
580
265a9e55 581 if (NILP (printflag))
078e7b4a
JB
582 tem = Qsymbolp;
583 else
584 tem = printflag;
585 specbind (Qstandard_output, tem);
586
265a9e55 587 if (NILP (printflag))
078e7b4a
JB
588 record_unwind_protect (save_excursion_restore, save_excursion_save ());
589 record_unwind_protect (save_restriction_restore, save_restriction_save ());
590
591 /* This both uses b and checks its type. */
592 Fgoto_char (b);
593 Fnarrow_to_region (make_number (BEGV), e);
265a9e55 594 readevalloop (Fcurrent_buffer (), 0, Feval, !NILP (printflag));
078e7b4a
JB
595
596 return unbind_to (count, Qnil);
597}
598
599#endif /* standalone */
600\f
601DEFUN ("read", Fread, Sread, 0, 1, 0,
602 "Read one Lisp expression as text from STREAM, return as Lisp object.\n\
603If STREAM is nil, use the value of `standard-input' (which see).\n\
604STREAM or the value of `standard-input' may be:\n\
605 a buffer (read from point and advance it)\n\
606 a marker (read from where it points and advance it)\n\
607 a function (call it with no arguments for each character,\n\
608 call it with a char as argument to push a char back)\n\
609 a string (takes text from string, starting at the beginning)\n\
610 t (read text line using minibuffer and use it).")
611 (readcharfun)
612 Lisp_Object readcharfun;
613{
614 extern Lisp_Object Fread_minibuffer ();
615
265a9e55 616 if (NILP (readcharfun))
078e7b4a
JB
617 readcharfun = Vstandard_input;
618 if (EQ (readcharfun, Qt))
619 readcharfun = Qread_char;
620
621#ifndef standalone
622 if (EQ (readcharfun, Qread_char))
623 return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
624#endif
625
626 if (XTYPE (readcharfun) == Lisp_String)
627 return Fcar (Fread_from_string (readcharfun, Qnil, Qnil));
628
629 return read0 (readcharfun);
630}
631
632DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
633 "Read one Lisp expression which is represented as text by STRING.\n\
634Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).\n\
635START and END optionally delimit a substring of STRING from which to read;\n\
636 they default to 0 and (length STRING) respectively.")
637 (string, start, end)
638 Lisp_Object string, start, end;
639{
640 int startval, endval;
641 Lisp_Object tem;
642
643 CHECK_STRING (string,0);
644
265a9e55 645 if (NILP (end))
078e7b4a
JB
646 endval = XSTRING (string)->size;
647 else
648 { CHECK_NUMBER (end,2);
649 endval = XINT (end);
650 if (endval < 0 || endval > XSTRING (string)->size)
651 args_out_of_range (string, end);
652 }
653
265a9e55 654 if (NILP (start))
078e7b4a
JB
655 startval = 0;
656 else
657 { CHECK_NUMBER (start,1);
658 startval = XINT (start);
659 if (startval < 0 || startval > endval)
660 args_out_of_range (string, start);
661 }
662
663 read_from_string_index = startval;
664 read_from_string_limit = endval;
665
666 tem = read0 (string);
667 return Fcons (tem, make_number (read_from_string_index));
668}
669\f
670/* Use this for recursive reads, in contexts where internal tokens are not allowed. */
671
672static Lisp_Object
673read0 (readcharfun)
674 Lisp_Object readcharfun;
675{
676 register Lisp_Object val;
677 char c;
678
679 val = read1 (readcharfun);
680 if (XTYPE (val) == Lisp_Internal)
681 {
682 c = XINT (val);
683 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (&c, 1), Qnil));
684 }
685
686 return val;
687}
688\f
689static int read_buffer_size;
690static char *read_buffer;
691
692static int
693read_escape (readcharfun)
694 Lisp_Object readcharfun;
695{
696 register int c = READCHAR;
697 switch (c)
698 {
699 case 'a':
265a9e55 700 return '\007';
078e7b4a
JB
701 case 'b':
702 return '\b';
703 case 'e':
704 return 033;
705 case 'f':
706 return '\f';
707 case 'n':
708 return '\n';
709 case 'r':
710 return '\r';
711 case 't':
712 return '\t';
713 case 'v':
714 return '\v';
715 case '\n':
716 return -1;
717
718 case 'M':
719 c = READCHAR;
720 if (c != '-')
721 error ("Invalid escape character syntax");
722 c = READCHAR;
723 if (c == '\\')
724 c = read_escape (readcharfun);
725 return c | 0200;
726
727 case 'C':
728 c = READCHAR;
729 if (c != '-')
730 error ("Invalid escape character syntax");
731 case '^':
732 c = READCHAR;
733 if (c == '\\')
734 c = read_escape (readcharfun);
735 if (c == '?')
736 return 0177;
737 else
738 return (c & (0200 | 037));
739
740 case '0':
741 case '1':
742 case '2':
743 case '3':
744 case '4':
745 case '5':
746 case '6':
747 case '7':
748 /* An octal escape, as in ANSI C. */
749 {
750 register int i = c - '0';
751 register int count = 0;
752 while (++count < 3)
753 {
754 if ((c = READCHAR) >= '0' && c <= '7')
755 {
756 i *= 8;
757 i += c - '0';
758 }
759 else
760 {
761 UNREAD (c);
762 break;
763 }
764 }
765 return i;
766 }
767
768 case 'x':
769 /* A hex escape, as in ANSI C. */
770 {
771 int i = 0;
772 while (1)
773 {
774 c = READCHAR;
775 if (c >= '0' && c <= '9')
776 {
777 i *= 16;
778 i += c - '0';
779 }
780 else if ((c >= 'a' && c <= 'f')
781 || (c >= 'A' && c <= 'F'))
782 {
783 i *= 16;
784 if (c >= 'a' && c <= 'f')
785 i += c - 'a' + 10;
786 else
787 i += c - 'A' + 10;
788 }
789 else
790 {
791 UNREAD (c);
792 break;
793 }
794 }
795 return i;
796 }
797
798 default:
799 return c;
800 }
801}
802
803static Lisp_Object
804read1 (readcharfun)
805 register Lisp_Object readcharfun;
806{
807 register int c;
808
809 retry:
810
811 c = READCHAR;
812 if (c < 0) return Fsignal (Qend_of_file, Qnil);
813
814 switch (c)
815 {
816 case '(':
817 return read_list (0, readcharfun);
818
819 case '[':
820 return read_vector (readcharfun);
821
822 case ')':
823 case ']':
078e7b4a
JB
824 {
825 register Lisp_Object val;
826 XSET (val, Lisp_Internal, c);
827 return val;
828 }
829
830 case '#':
200f684e
RS
831 c = READCHAR;
832 if (c == '[')
833 {
834 /* Accept compiled functions at read-time so that we don't have to
835 build them using function calls. */
836 Lisp_Object tmp = read_vector (readcharfun);
837 return Fmake_byte_code (XVECTOR(tmp)->size, XVECTOR (tmp)->contents);
838 }
839 UNREAD (c);
078e7b4a
JB
840 return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
841
842 case ';':
843 while ((c = READCHAR) >= 0 && c != '\n');
844 goto retry;
845
846 case '\'':
847 {
848 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
849 }
850
851 case '?':
852 {
853 register Lisp_Object val;
854
855 c = READCHAR;
856 if (c < 0) return Fsignal (Qend_of_file, Qnil);
857
858 if (c == '\\')
859 XSET (val, Lisp_Int, read_escape (readcharfun));
860 else
861 XSET (val, Lisp_Int, c);
862
863 return val;
864 }
865
866 case '\"':
867 {
868 register char *p = read_buffer;
869 register char *end = read_buffer + read_buffer_size;
870 register int c;
871 int cancel = 0;
872
873 while ((c = READCHAR) >= 0
874 && c != '\"')
875 {
876 if (p == end)
877 {
878 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
879 p += new - read_buffer;
880 read_buffer += new - read_buffer;
881 end = read_buffer + read_buffer_size;
882 }
883 if (c == '\\')
884 c = read_escape (readcharfun);
885 /* c is -1 if \ newline has just been seen */
886 if (c < 0)
887 {
888 if (p == read_buffer)
889 cancel = 1;
890 }
891 else
892 *p++ = c;
893 }
894 if (c < 0) return Fsignal (Qend_of_file, Qnil);
895
896 /* If purifying, and string starts with \ newline,
897 return zero instead. This is for doc strings
08564963 898 that we are really going to find in etc/DOC.nn.nn */
265a9e55 899 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
078e7b4a
JB
900 return make_number (0);
901
902 if (read_pure)
903 return make_pure_string (read_buffer, p - read_buffer);
904 else
905 return make_string (read_buffer, p - read_buffer);
906 }
907
109d300c
JB
908 case '.':
909 {
910#ifdef LISP_FLOAT_TYPE
911 /* If a period is followed by a number, then we should read it
912 as a floating point number. Otherwise, it denotes a dotted
913 pair. */
914 int next_char = READCHAR;
915 UNREAD (next_char);
916
917 if (! isdigit (next_char))
918#endif
919 {
920 register Lisp_Object val;
921 XSET (val, Lisp_Internal, c);
922 return val;
923 }
924
925 /* Otherwise, we fall through! Note that the atom-reading loop
926 below will now loop at least once, assuring that we will not
927 try to UNREAD two characters in a row. */
928 }
078e7b4a
JB
929 default:
930 if (c <= 040) goto retry;
931 {
932 register char *p = read_buffer;
933
934 {
935 register char *end = read_buffer + read_buffer_size;
936
937 while (c > 040 &&
938 !(c == '\"' || c == '\'' || c == ';' || c == '?'
939 || c == '(' || c == ')'
109d300c
JB
940#ifndef LISP_FLOAT_TYPE
941 /* If we have floating-point support, then we need
942 to allow <digits><dot><digits>. */
078e7b4a
JB
943 || c =='.'
944#endif /* not LISP_FLOAT_TYPE */
945 || c == '[' || c == ']' || c == '#'
946 ))
947 {
948 if (p == end)
949 {
950 register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
951 p += new - read_buffer;
952 read_buffer += new - read_buffer;
953 end = read_buffer + read_buffer_size;
954 }
955 if (c == '\\')
956 c = READCHAR;
957 *p++ = c;
958 c = READCHAR;
959 }
960
961 if (p == end)
962 {
963 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
964 p += new - read_buffer;
965 read_buffer += new - read_buffer;
966/* end = read_buffer + read_buffer_size; */
967 }
968 *p = 0;
969 if (c >= 0)
970 UNREAD (c);
971 }
972
973 /* Is it an integer? */
974 {
975 register char *p1;
976 register Lisp_Object val;
977 p1 = read_buffer;
978 if (*p1 == '+' || *p1 == '-') p1++;
979 if (p1 != p)
980 {
981 while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++;
982 if (p1 == p)
983 /* It is. */
984 {
985 XSET (val, Lisp_Int, atoi (read_buffer));
986 return val;
987 }
988 }
989#ifdef LISP_FLOAT_TYPE
990 if (isfloat_string (read_buffer))
991 return make_float (atof (read_buffer));
992#endif
993 }
994
995 return intern (read_buffer);
996 }
997 }
998}
999\f
1000#ifdef LISP_FLOAT_TYPE
1001
1002#include <ctype.h>
1003#define LEAD_INT 1
1004#define DOT_CHAR 2
1005#define TRAIL_INT 4
1006#define E_CHAR 8
1007#define EXP_INT 16
1008
1009int
1010isfloat_string (cp)
1011 register char *cp;
1012{
1013 register state;
1014
1015 state = 0;
1016 if (*cp == '+' || *cp == '-')
1017 cp++;
1018
1019 if (isdigit(*cp))
1020 {
1021 state |= LEAD_INT;
1022 while (isdigit (*cp))
1023 cp ++;
1024 }
1025 if (*cp == '.')
1026 {
1027 state |= DOT_CHAR;
1028 cp++;
1029 }
1030 if (isdigit(*cp))
1031 {
1032 state |= TRAIL_INT;
1033 while (isdigit (*cp))
1034 cp++;
1035 }
1036 if (*cp == 'e')
1037 {
1038 state |= E_CHAR;
1039 cp++;
1040 }
1041 if ((*cp == '+') || (*cp == '-'))
1042 cp++;
1043
1044 if (isdigit (*cp))
1045 {
1046 state |= EXP_INT;
1047 while (isdigit (*cp))
1048 cp++;
1049 }
1050 return (*cp == 0
1051 && (state == (LEAD_INT|DOT_CHAR|TRAIL_INT)
1052 || state == (LEAD_INT|E_CHAR|EXP_INT)
1053 || state == (LEAD_INT|DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)));
1054}
1055#endif /* LISP_FLOAT_TYPE */
1056\f
1057static Lisp_Object
1058read_vector (readcharfun)
1059 Lisp_Object readcharfun;
1060{
1061 register int i;
1062 register int size;
1063 register Lisp_Object *ptr;
1064 register Lisp_Object tem, vector;
1065 register struct Lisp_Cons *otem;
1066 Lisp_Object len;
1067
1068 tem = read_list (1, readcharfun);
1069 len = Flength (tem);
1070 vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
1071
1072
1073 size = XVECTOR (vector)->size;
1074 ptr = XVECTOR (vector)->contents;
1075 for (i = 0; i < size; i++)
1076 {
1077 ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem);
1078 otem = XCONS (tem);
1079 tem = Fcdr (tem);
1080 free_cons (otem);
1081 }
1082 return vector;
1083}
1084
1085/* flag = 1 means check for ] to terminate rather than ) and .
1086 flag = -1 means check for starting with defun
1087 and make structure pure. */
1088
1089static Lisp_Object
1090read_list (flag, readcharfun)
1091 int flag;
1092 register Lisp_Object readcharfun;
1093{
1094 /* -1 means check next element for defun,
1095 0 means don't check,
1096 1 means already checked and found defun. */
1097 int defunflag = flag < 0 ? -1 : 0;
1098 Lisp_Object val, tail;
1099 register Lisp_Object elt, tem;
1100 struct gcpro gcpro1, gcpro2;
1101
1102 val = Qnil;
1103 tail = Qnil;
1104
1105 while (1)
1106 {
1107 GCPRO2 (val, tail);
1108 elt = read1 (readcharfun);
1109 UNGCPRO;
1110 if (XTYPE (elt) == Lisp_Internal)
1111 {
1112 if (flag > 0)
1113 {
1114 if (XINT (elt) == ']')
1115 return val;
1116 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (") or . in a vector", 18), Qnil));
1117 }
1118 if (XINT (elt) == ')')
1119 return val;
1120 if (XINT (elt) == '.')
1121 {
1122 GCPRO2 (val, tail);
265a9e55 1123 if (!NILP (tail))
078e7b4a
JB
1124 XCONS (tail)->cdr = read0 (readcharfun);
1125 else
1126 val = read0 (readcharfun);
1127 elt = read1 (readcharfun);
1128 UNGCPRO;
1129 if (XTYPE (elt) == Lisp_Internal && XINT (elt) == ')')
1130 return val;
1131 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil));
1132 }
1133 return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("] in a list", 11), Qnil));
1134 }
1135 tem = (read_pure && flag <= 0
1136 ? pure_cons (elt, Qnil)
1137 : Fcons (elt, Qnil));
265a9e55 1138 if (!NILP (tail))
078e7b4a
JB
1139 XCONS (tail)->cdr = tem;
1140 else
1141 val = tem;
1142 tail = tem;
1143 if (defunflag < 0)
1144 defunflag = EQ (elt, Qdefun);
1145 else if (defunflag > 0)
1146 read_pure = 1;
1147 }
1148}
1149\f
1150Lisp_Object Vobarray;
1151Lisp_Object initial_obarray;
1152
1153Lisp_Object
1154check_obarray (obarray)
1155 Lisp_Object obarray;
1156{
1157 while (XTYPE (obarray) != Lisp_Vector || XVECTOR (obarray)->size == 0)
1158 {
1159 /* If Vobarray is now invalid, force it to be valid. */
1160 if (EQ (Vobarray, obarray)) Vobarray = initial_obarray;
1161
1162 obarray = wrong_type_argument (Qvectorp, obarray);
1163 }
1164 return obarray;
1165}
1166
1167static int hash_string ();
1168Lisp_Object oblookup ();
1169
1170Lisp_Object
1171intern (str)
1172 char *str;
1173{
1174 Lisp_Object tem;
1175 int len = strlen (str);
1176 Lisp_Object obarray = Vobarray;
1177
1178 if (XTYPE (obarray) != Lisp_Vector || XVECTOR (obarray)->size == 0)
1179 obarray = check_obarray (obarray);
1180 tem = oblookup (obarray, str, len);
1181 if (XTYPE (tem) == Lisp_Symbol)
1182 return tem;
265a9e55 1183 return Fintern ((!NILP (Vpurify_flag)
078e7b4a
JB
1184 ? make_pure_string (str, len)
1185 : make_string (str, len)),
1186 obarray);
1187}
1188
1189DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
1190 "Return the canonical symbol whose name is STRING.\n\
1191If there is none, one is created by this function and returned.\n\
1192A second optional argument specifies the obarray to use;\n\
1193it defaults to the value of `obarray'.")
1194 (str, obarray)
1195 Lisp_Object str, obarray;
1196{
1197 register Lisp_Object tem, sym, *ptr;
1198
265a9e55 1199 if (NILP (obarray)) obarray = Vobarray;
078e7b4a
JB
1200 obarray = check_obarray (obarray);
1201
1202 CHECK_STRING (str, 0);
1203
1204 tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
1205 if (XTYPE (tem) != Lisp_Int)
1206 return tem;
1207
265a9e55 1208 if (!NILP (Vpurify_flag))
078e7b4a
JB
1209 str = Fpurecopy (str);
1210 sym = Fmake_symbol (str);
1211
1212 ptr = &XVECTOR (obarray)->contents[XINT (tem)];
1213 if (XTYPE (*ptr) == Lisp_Symbol)
1214 XSYMBOL (sym)->next = XSYMBOL (*ptr);
1215 else
1216 XSYMBOL (sym)->next = 0;
1217 *ptr = sym;
1218 return sym;
1219}
1220
1221DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
1222 "Return the canonical symbol whose name is STRING, or nil if none exists.\n\
1223A second optional argument specifies the obarray to use;\n\
1224it defaults to the value of `obarray'.")
1225 (str, obarray)
1226 Lisp_Object str, obarray;
1227{
1228 register Lisp_Object tem;
1229
265a9e55 1230 if (NILP (obarray)) obarray = Vobarray;
078e7b4a
JB
1231 obarray = check_obarray (obarray);
1232
1233 CHECK_STRING (str, 0);
1234
1235 tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
1236 if (XTYPE (tem) != Lisp_Int)
1237 return tem;
1238 return Qnil;
1239}
1240
1241Lisp_Object
1242oblookup (obarray, ptr, size)
1243 Lisp_Object obarray;
1244 register char *ptr;
1245 register int size;
1246{
1247 int hash, obsize;
1248 register Lisp_Object tail;
1249 Lisp_Object bucket, tem;
1250
1251 if (XTYPE (obarray) != Lisp_Vector ||
1252 (obsize = XVECTOR (obarray)->size) == 0)
1253 {
1254 obarray = check_obarray (obarray);
1255 obsize = XVECTOR (obarray)->size;
1256 }
1257 /* Combining next two lines breaks VMS C 2.3. */
1258 hash = hash_string (ptr, size);
1259 hash %= obsize;
1260 bucket = XVECTOR (obarray)->contents[hash];
1261 if (XFASTINT (bucket) == 0)
1262 ;
1263 else if (XTYPE (bucket) != Lisp_Symbol)
1264 error ("Bad data in guts of obarray"); /* Like CADR error message */
1265 else for (tail = bucket; ; XSET (tail, Lisp_Symbol, XSYMBOL (tail)->next))
1266 {
1267 if (XSYMBOL (tail)->name->size == size &&
1268 !bcmp (XSYMBOL (tail)->name->data, ptr, size))
1269 return tail;
1270 else if (XSYMBOL (tail)->next == 0)
1271 break;
1272 }
1273 XSET (tem, Lisp_Int, hash);
1274 return tem;
1275}
1276
1277static int
1278hash_string (ptr, len)
1279 unsigned char *ptr;
1280 int len;
1281{
1282 register unsigned char *p = ptr;
1283 register unsigned char *end = p + len;
1284 register unsigned char c;
1285 register int hash = 0;
1286
1287 while (p != end)
1288 {
1289 c = *p++;
1290 if (c >= 0140) c -= 40;
1291 hash = ((hash<<3) + (hash>>28) + c);
1292 }
1293 return hash & 07777777777;
1294}
1295
1296void
1297map_obarray (obarray, fn, arg)
1298 Lisp_Object obarray;
1299 int (*fn) ();
1300 Lisp_Object arg;
1301{
1302 register int i;
1303 register Lisp_Object tail;
1304 CHECK_VECTOR (obarray, 1);
1305 for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
1306 {
1307 tail = XVECTOR (obarray)->contents[i];
1308 if (XFASTINT (tail) != 0)
1309 while (1)
1310 {
1311 (*fn) (tail, arg);
1312 if (XSYMBOL (tail)->next == 0)
1313 break;
1314 XSET (tail, Lisp_Symbol, XSYMBOL (tail)->next);
1315 }
1316 }
1317}
1318
1319mapatoms_1 (sym, function)
1320 Lisp_Object sym, function;
1321{
1322 call1 (function, sym);
1323}
1324
1325DEFUN ("mapatoms", Fmapatoms, Smapatoms, 1, 2, 0,
1326 "Call FUNCTION on every symbol in OBARRAY.\n\
1327OBARRAY defaults to the value of `obarray'.")
1328 (function, obarray)
1329 Lisp_Object function, obarray;
1330{
1331 Lisp_Object tem;
1332
265a9e55 1333 if (NILP (obarray)) obarray = Vobarray;
078e7b4a
JB
1334 obarray = check_obarray (obarray);
1335
1336 map_obarray (obarray, mapatoms_1, function);
1337 return Qnil;
1338}
1339
1340#define OBARRAY_SIZE 509
1341
1342void
1343init_obarray ()
1344{
1345 Lisp_Object oblength;
1346 int hash;
1347 Lisp_Object *tem;
1348
1349 XFASTINT (oblength) = OBARRAY_SIZE;
1350
1351 Qnil = Fmake_symbol (make_pure_string ("nil", 3));
1352 Vobarray = Fmake_vector (oblength, make_number (0));
1353 initial_obarray = Vobarray;
1354 staticpro (&initial_obarray);
1355 /* Intern nil in the obarray */
1356 /* These locals are to kludge around a pyramid compiler bug. */
1357 hash = hash_string ("nil", 3);
1358 /* Separate statement here to avoid VAXC bug. */
1359 hash %= OBARRAY_SIZE;
1360 tem = &XVECTOR (Vobarray)->contents[hash];
1361 *tem = Qnil;
1362
1363 Qunbound = Fmake_symbol (make_pure_string ("unbound", 7));
1364 XSYMBOL (Qnil)->function = Qunbound;
1365 XSYMBOL (Qunbound)->value = Qunbound;
1366 XSYMBOL (Qunbound)->function = Qunbound;
1367
1368 Qt = intern ("t");
1369 XSYMBOL (Qnil)->value = Qnil;
1370 XSYMBOL (Qnil)->plist = Qnil;
1371 XSYMBOL (Qt)->value = Qt;
1372
1373 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
1374 Vpurify_flag = Qt;
1375
1376 Qvariable_documentation = intern ("variable-documentation");
1377
1378 read_buffer_size = 100;
1379 read_buffer = (char *) malloc (read_buffer_size);
1380}
1381\f
1382void
1383defsubr (sname)
1384 struct Lisp_Subr *sname;
1385{
1386 Lisp_Object sym;
1387 sym = intern (sname->symbol_name);
1388 XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
1389}
1390
1391#ifdef NOTDEF /* use fset in subr.el now */
1392void
1393defalias (sname, string)
1394 struct Lisp_Subr *sname;
1395 char *string;
1396{
1397 Lisp_Object sym;
1398 sym = intern (string);
1399 XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
1400}
1401#endif /* NOTDEF */
1402
1403/* New replacement for DefIntVar; it ignores the doc string argument
1404 on the assumption that make-docfile will handle that. */
1405/* Define an "integer variable"; a symbol whose value is forwarded
1406 to a C variable of type int. Sample call: */
1407 /* DEFVARINT ("indent-tabs-mode", &indent_tabs_mode, "Documentation"); */
1408
1409void
1410defvar_int (namestring, address, doc)
1411 char *namestring;
1412 int *address;
1413 char *doc;
1414{
1415 Lisp_Object sym;
1416 sym = intern (namestring);
1417 XSET (XSYMBOL (sym)->value, Lisp_Intfwd, address);
1418}
1419
1420/* Similar but define a variable whose value is T if address contains 1,
1421 NIL if address contains 0 */
1422
1423void
1424defvar_bool (namestring, address, doc)
1425 char *namestring;
1426 int *address;
1427 char *doc;
1428{
1429 Lisp_Object sym;
1430 sym = intern (namestring);
1431 XSET (XSYMBOL (sym)->value, Lisp_Boolfwd, address);
1432}
1433
1434/* Similar but define a variable whose value is the Lisp Object stored at address. */
1435
1436void
1437defvar_lisp (namestring, address, doc)
1438 char *namestring;
1439 Lisp_Object *address;
1440 char *doc;
1441{
1442 Lisp_Object sym;
1443 sym = intern (namestring);
1444 XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
1445 staticpro (address);
1446}
1447
1448/* Similar but don't request gc-marking of the C variable.
1449 Used when that variable will be gc-marked for some other reason,
1450 since marking the same slot twice can cause trouble with strings. */
1451
1452void
1453defvar_lisp_nopro (namestring, address, doc)
1454 char *namestring;
1455 Lisp_Object *address;
1456 char *doc;
1457{
1458 Lisp_Object sym;
1459 sym = intern (namestring);
1460 XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
1461}
1462
1463#ifndef standalone
1464
1465/* Similar but define a variable whose value is the Lisp Object stored in
1466 the current buffer. address is the address of the slot in the buffer that is current now. */
1467
1468void
1469defvar_per_buffer (namestring, address, doc)
1470 char *namestring;
1471 Lisp_Object *address;
1472 char *doc;
1473{
1474 Lisp_Object sym;
1475 int offset;
1476 extern struct buffer buffer_local_symbols;
1477
1478 sym = intern (namestring);
1479 offset = (char *)address - (char *)current_buffer;
1480
1481 XSET (XSYMBOL (sym)->value, Lisp_Buffer_Objfwd,
1482 (Lisp_Object *) offset);
1483 *(Lisp_Object *)(offset + (char *)&buffer_local_symbols) = sym;
1484 if (*(int *)(offset + (char *)&buffer_local_flags) == 0)
1485 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
1486 slot of buffer_local_flags */
1487 abort ();
1488}
1489
1490#endif /* standalone */
1491\f
279499f0 1492init_lread ()
078e7b4a 1493{
46947372 1494 char *normal;
078e7b4a 1495
279499f0 1496 /* Compute the default load-path. */
46947372
JB
1497#ifdef CANNOT_DUMP
1498 normal = PATH_LOADSEARCH;
e065a56e 1499 Vload_path = decode_env_path (0, normal);
46947372
JB
1500#else
1501 if (NILP (Vpurify_flag))
1502 normal = PATH_LOADSEARCH;
279499f0 1503 else
46947372 1504 normal = PATH_DUMPLOADSEARCH;
279499f0 1505
46947372
JB
1506 /* In a dumped Emacs, we normally have to reset the value of
1507 Vload_path from PATH_LOADSEARCH, since the value that was dumped
1508 uses ../lisp, instead of the path of the installed elisp
1509 libraries. However, if it appears that Vload_path was changed
1510 from the default before dumping, don't override that value. */
4746118a
JB
1511 if (initialized)
1512 {
1513 Lisp_Object dump_path;
46947372 1514
e065a56e 1515 dump_path = decode_env_path (0, PATH_DUMPLOADSEARCH);
4746118a 1516 if (! NILP (Fequal (dump_path, Vload_path)))
e065a56e 1517 Vload_path = decode_env_path (0, normal);
4746118a
JB
1518 }
1519 else
e065a56e 1520 Vload_path = decode_env_path (0, normal);
46947372 1521#endif
279499f0 1522
078e7b4a 1523 /* Warn if dirs in the *standard* path don't exist. */
46947372
JB
1524 {
1525 Lisp_Object path_tail;
078e7b4a 1526
46947372
JB
1527 for (path_tail = Vload_path;
1528 !NILP (path_tail);
1529 path_tail = XCONS (path_tail)->cdr)
1530 {
1531 Lisp_Object dirfile;
1532 dirfile = Fcar (path_tail);
1533 if (XTYPE (dirfile) == Lisp_String)
1534 {
1535 dirfile = Fdirectory_file_name (dirfile);
1536 if (access (XSTRING (dirfile)->data, 0) < 0)
1537 printf ("Warning: lisp library (%s) does not exist.\n",
1538 XSTRING (Fcar (path_tail))->data);
1539 }
1540 }
1541 }
1542
1543 /* If the EMACSLOADPATH environment variable is set, use its value.
1544 This doesn't apply if we're dumping. */
1545 if (NILP (Vpurify_flag)
1546 && egetenv ("EMACSLOADPATH"))
279499f0 1547 Vload_path = decode_env_path ("EMACSLOADPATH", normal);
279499f0
JB
1548
1549 Vvalues = Qnil;
1550
078e7b4a
JB
1551 load_in_progress = 0;
1552}
1553
1554void
279499f0 1555syms_of_lread ()
078e7b4a
JB
1556{
1557 defsubr (&Sread);
1558 defsubr (&Sread_from_string);
1559 defsubr (&Sintern);
1560 defsubr (&Sintern_soft);
1561 defsubr (&Sload);
228d4b1c 1562 defsubr (&Seval_buffer);
078e7b4a
JB
1563 defsubr (&Seval_region);
1564 defsubr (&Sread_char);
1565 defsubr (&Sread_char_exclusive);
1566#ifdef HAVE_X_WINDOWS
1567 defsubr (&Sread_event);
1568#endif /* HAVE_X_WINDOWS */
1569 defsubr (&Sget_file_char);
1570 defsubr (&Smapatoms);
1571
1572 DEFVAR_LISP ("obarray", &Vobarray,
1573 "Symbol table for use by `intern' and `read'.\n\
1574It is a vector whose length ought to be prime for best results.\n\
1575The vector's contents don't make sense if examined from Lisp programs;\n\
1576to find all the symbols in an obarray, use `mapatoms'.");
1577
1578 DEFVAR_LISP ("values", &Vvalues,
1579 "List of values of all expressions which were read, evaluated and printed.\n\
1580Order is reverse chronological.");
1581
1582 DEFVAR_LISP ("standard-input", &Vstandard_input,
1583 "Stream for read to get input from.\n\
1584See documentation of `read' for possible values.");
1585 Vstandard_input = Qt;
1586
1587 DEFVAR_LISP ("load-path", &Vload_path,
1588 "*List of directories to search for files to load.\n\
1589Each element is a string (directory name) or nil (try default directory).\n\
1590Initialized based on EMACSLOADPATH environment variable, if any,\n\
1591otherwise to default specified in by file `paths.h' when Emacs was built.");
1592
1593 DEFVAR_BOOL ("load-in-progress", &load_in_progress,
1594 "Non-nil iff inside of `load'.");
1595
1596 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
1597 "An alist of expressions to be evalled when particular files are loaded.\n\
1598Each element looks like (FILENAME FORMS...).\n\
1599When `load' is run and the file-name argument is FILENAME,\n\
1600the FORMS in the corresponding element are executed at the end of loading.\n\n\
1601FILENAME must match exactly! Normally FILENAME is the name of a library,\n\
1602with no directory specified, since that is how `load' is normally called.\n\
1603An error in FORMS does not undo the load,\n\
1604but does prevent execution of the rest of the FORMS.");
1605 Vafter_load_alist = Qnil;
1606
1607 Qstandard_input = intern ("standard-input");
1608 staticpro (&Qstandard_input);
1609
1610 Qread_char = intern ("read-char");
1611 staticpro (&Qread_char);
1612
1613 Qget_file_char = intern ("get-file-char");
1614 staticpro (&Qget_file_char);
1615}