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