JimB's changes since January 18th
[bpt/emacs.git] / src / lread.c
1 /* Lisp parsing and input streams.
2 Copyright (C) 1985, 1986, 1987, 1988, 1989,
3 1992 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the 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 #include <ctype.h>
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"
35 #include "keyboard.h"
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
50 Lisp_Object Qread_char, Qget_file_char, Qstandard_input;
51 Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist;
52
53 /* non-zero if inside `load' */
54 int load_in_progress;
55
56 /* Search path for files to be loaded. */
57 Lisp_Object Vload_path;
58
59 /* File for get_file_char to read from. Use by load */
60 static FILE *instream;
61
62 /* When nonzero, read conses in pure space */
63 static int read_pure;
64
65 /* For use within read-from-string (this reader is non-reentrant!!) */
66 static int read_from_string_index;
67 static 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
76 static int
77 readchar (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
128 if (NILP (tem))
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
136 static void
137 unreadchar (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
158 static Lisp_Object read0 (), read1 (), read_list (), read_vector ();
159 \f
160 /* get a character from the tty */
161
162 extern Lisp_Object read_char ();
163
164 DEFUN ("read-char", Fread_char, Sread_char, 0, 0, 0,
165 "Read a character from the command input (keyboard or macro).\n\
166 It is returned as a number.\n\
167 If the user generates an event which is not a character (i.e. a mouse\n\
168 click or function key event), `read-char' signals an error. As an\n\
169 exception, switch-frame events are put off until non-ASCII events can\n\
170 be read.\n\
171 If you want to read non-character events, or ignore them, call\n\
172 `read-event' or `read-char-exclusive' instead.")
173 ()
174 {
175 register Lisp_Object val;
176
177 #ifndef standalone
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_events = Fcons (val, Qnil);
207 error ("Object read was not a character");
208 }
209 }
210 #else
211 val = getchar ();
212 #endif
213
214 return val;
215 }
216
217 DEFUN ("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
223 val = read_char (0, 0, 0, Qnil, 0);
224 return val;
225 }
226
227 DEFUN ("read-char-exclusive", Fread_char_exclusive, Sread_char_exclusive, 0, 0, 0,
228 "Read a character from the command input (keyboard or macro).\n\
229 It is returned as a number. Non character events are ignored.")
230 ()
231 {
232 register Lisp_Object val;
233
234 #ifndef standalone
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 }
263 #else
264 val = getchar ();
265 #endif
266
267 return val;
268 }
269
270 DEFUN ("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
279 static void readevalloop ();
280 static Lisp_Object load_unwind ();
281
282 DEFUN ("load", Fload, Sload, 1, 4, 0,
283 "Execute a file of Lisp code named FILE.\n\
284 First try FILE with `.elc' appended, then try with `.el',\n\
285 then try FILE unmodified.\n\
286 This function searches the directories in `load-path'.\n\
287 If optional second arg NOERROR is non-nil,\n\
288 report no error if FILE doesn't exist.\n\
289 Print messages at start and end of loading unless\n\
290 optional third arg NOMESSAGE is non-nil.\n\
291 If optional fourth arg NOSUFFIX is non-nil, don't try adding\n\
292 suffixes `.elc' or `.el' to the specified name FILE.\n\
293 Return 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;
305 /* 1 means inhibit the message at the beginning. */
306 int nomessage1 = 0;
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 {
315 fd = openp (Vload_path, str, !NILP (nosuffix) ? "" : ".elc:.el:",
316 &found, 0);
317 }
318
319 if (fd < 0)
320 {
321 if (NILP (noerror))
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)
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 }
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
356 if (NILP (nomessage) && !nomessage1)
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);
373 if (!NILP (temp))
374 Fprogn (Fcdr (temp));
375 UNGCPRO;
376
377 if (!noninteractive && NILP (nomessage))
378 message ("Loading %s...done", XSTRING (str)->data);
379 return Qt;
380 }
381
382 static Lisp_Object
383 load_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
393 static int
394 complete_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
421 int
422 openp (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
443 for (; !NILP (path); path = Fcdr (path))
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
510 Lisp_Object
511 unreadpure () /* Used as unwind-protect function in readevalloop */
512 {
513 read_pure = 0;
514 return Qnil;
515 }
516
517 static void
518 readevalloop (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
542 if (!NILP (Vpurify_flag) && c == '(')
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
570 DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 2, "",
571 "Execute the current buffer as Lisp code.\n\
572 Programs can pass two arguments, BUFFER and PRINTFLAG.\n\
573 BUFFER is the buffer to evaluate (nil means use current buffer).\n\
574 PRINTFLAG controls printing of output:\n\
575 nil means discard it; anything else is stream for print.\n\
576 \n\
577 If there is no error, point does not move. If there is an error,\n\
578 point 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
585 if (NILP (bufname))
586 buf = Fcurrent_buffer ();
587 else
588 buf = Fget_buffer (bufname);
589 if (NILP (buf))
590 error ("No such buffer.");
591
592 if (NILP (printflag))
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)));
599 readevalloop (buf, 0, Feval, !NILP (printflag));
600 unbind_to (count);
601
602 return Qnil;
603 }
604
605 #if 0
606 DEFUN ("eval-current-buffer", Feval_current_buffer, Seval_current_buffer, 0, 1, "",
607 "Execute the current buffer as Lisp code.\n\
608 Programs can pass argument PRINTFLAG which controls printing of output:\n\
609 nil means discard it; anything else is stream for print.\n\
610 \n\
611 If there is no error, point does not move. If there is an error,\n\
612 point 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
619 if (NILP (printflag))
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);
626 readevalloop (Fcurrent_buffer (), 0, Feval, !NILP (printflag));
627 return unbind_to (count, Qnil);
628 }
629 #endif
630
631 DEFUN ("eval-region", Feval_region, Seval_region, 2, 3, "r",
632 "Execute the region as Lisp code.\n\
633 When called from programs, expects two arguments,\n\
634 giving starting and ending indices in the current buffer\n\
635 of the text to be executed.\n\
636 Programs can pass third argument PRINTFLAG which controls output:\n\
637 nil means discard it; anything else is stream for printing it.\n\
638 \n\
639 If there is no error, point does not move. If there is an error,\n\
640 point 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
647 if (NILP (printflag))
648 tem = Qsymbolp;
649 else
650 tem = printflag;
651 specbind (Qstandard_output, tem);
652
653 if (NILP (printflag))
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);
660 readevalloop (Fcurrent_buffer (), 0, Feval, !NILP (printflag));
661
662 return unbind_to (count, Qnil);
663 }
664
665 #endif /* standalone */
666 \f
667 DEFUN ("read", Fread, Sread, 0, 1, 0,
668 "Read one Lisp expression as text from STREAM, return as Lisp object.\n\
669 If STREAM is nil, use the value of `standard-input' (which see).\n\
670 STREAM 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
682 if (NILP (readcharfun))
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
698 DEFUN ("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\
700 Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).\n\
701 START 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
711 if (NILP (end))
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
720 if (NILP (start))
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
738 static Lisp_Object
739 read0 (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
755 static int read_buffer_size;
756 static char *read_buffer;
757
758 static int
759 read_escape (readcharfun)
760 Lisp_Object readcharfun;
761 {
762 register int c = READCHAR;
763 switch (c)
764 {
765 case 'a':
766 return '\007';
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
869 static Lisp_Object
870 read1 (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 ']':
890 {
891 register Lisp_Object val;
892 XSET (val, Lisp_Internal, c);
893 return val;
894 }
895
896 case '#':
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);
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
964 that we are really going to find in etc/DOC.nn.nn */
965 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
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
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 }
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 == ')'
1006 #ifndef LISP_FLOAT_TYPE
1007 /* If we have floating-point support, then we need
1008 to allow <digits><dot><digits>. */
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 #ifdef LISP_FLOAT_TYPE
1049 /* Integers can have trailing decimal points. */
1050 if (p1 < p && *p1 == '.') p1++;
1051 #endif
1052 if (p1 == p)
1053 /* It is an integer. */
1054 {
1055 #ifdef LISP_FLOAT_TYPE
1056 if (p1[-1] == '.')
1057 p1[-1] = '\0';
1058 #endif
1059 XSET (val, Lisp_Int, atoi (read_buffer));
1060 return val;
1061 }
1062 }
1063 #ifdef LISP_FLOAT_TYPE
1064 if (isfloat_string (read_buffer))
1065 return make_float (atof (read_buffer));
1066 #endif
1067 }
1068
1069 return intern (read_buffer);
1070 }
1071 }
1072 }
1073 \f
1074 #ifdef LISP_FLOAT_TYPE
1075
1076 #define LEAD_INT 1
1077 #define DOT_CHAR 2
1078 #define TRAIL_INT 4
1079 #define E_CHAR 8
1080 #define EXP_INT 16
1081
1082 int
1083 isfloat_string (cp)
1084 register char *cp;
1085 {
1086 register state;
1087
1088 state = 0;
1089 if (*cp == '+' || *cp == '-')
1090 cp++;
1091
1092 if (isdigit(*cp))
1093 {
1094 state |= LEAD_INT;
1095 while (isdigit (*cp))
1096 cp ++;
1097 }
1098 if (*cp == '.')
1099 {
1100 state |= DOT_CHAR;
1101 cp++;
1102 }
1103 if (isdigit(*cp))
1104 {
1105 state |= TRAIL_INT;
1106 while (isdigit (*cp))
1107 cp++;
1108 }
1109 if (*cp == 'e')
1110 {
1111 state |= E_CHAR;
1112 cp++;
1113 }
1114 if ((*cp == '+') || (*cp == '-'))
1115 cp++;
1116
1117 if (isdigit (*cp))
1118 {
1119 state |= EXP_INT;
1120 while (isdigit (*cp))
1121 cp++;
1122 }
1123 return (*cp == 0
1124 && (state == (LEAD_INT|DOT_CHAR|TRAIL_INT)
1125 || state == (DOT_CHAR|TRAIL_INT)
1126 || state == (LEAD_INT|E_CHAR|EXP_INT)
1127 || state == (LEAD_INT|DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)
1128 || state == (DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)));
1129 }
1130 #endif /* LISP_FLOAT_TYPE */
1131 \f
1132 static Lisp_Object
1133 read_vector (readcharfun)
1134 Lisp_Object readcharfun;
1135 {
1136 register int i;
1137 register int size;
1138 register Lisp_Object *ptr;
1139 register Lisp_Object tem, vector;
1140 register struct Lisp_Cons *otem;
1141 Lisp_Object len;
1142
1143 tem = read_list (1, readcharfun);
1144 len = Flength (tem);
1145 vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
1146
1147
1148 size = XVECTOR (vector)->size;
1149 ptr = XVECTOR (vector)->contents;
1150 for (i = 0; i < size; i++)
1151 {
1152 ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem);
1153 otem = XCONS (tem);
1154 tem = Fcdr (tem);
1155 free_cons (otem);
1156 }
1157 return vector;
1158 }
1159
1160 /* flag = 1 means check for ] to terminate rather than ) and .
1161 flag = -1 means check for starting with defun
1162 and make structure pure. */
1163
1164 static Lisp_Object
1165 read_list (flag, readcharfun)
1166 int flag;
1167 register Lisp_Object readcharfun;
1168 {
1169 /* -1 means check next element for defun,
1170 0 means don't check,
1171 1 means already checked and found defun. */
1172 int defunflag = flag < 0 ? -1 : 0;
1173 Lisp_Object val, tail;
1174 register Lisp_Object elt, tem;
1175 struct gcpro gcpro1, gcpro2;
1176
1177 val = Qnil;
1178 tail = Qnil;
1179
1180 while (1)
1181 {
1182 GCPRO2 (val, tail);
1183 elt = read1 (readcharfun);
1184 UNGCPRO;
1185 if (XTYPE (elt) == Lisp_Internal)
1186 {
1187 if (flag > 0)
1188 {
1189 if (XINT (elt) == ']')
1190 return val;
1191 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (") or . in a vector", 18), Qnil));
1192 }
1193 if (XINT (elt) == ')')
1194 return val;
1195 if (XINT (elt) == '.')
1196 {
1197 GCPRO2 (val, tail);
1198 if (!NILP (tail))
1199 XCONS (tail)->cdr = read0 (readcharfun);
1200 else
1201 val = read0 (readcharfun);
1202 elt = read1 (readcharfun);
1203 UNGCPRO;
1204 if (XTYPE (elt) == Lisp_Internal && XINT (elt) == ')')
1205 return val;
1206 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil));
1207 }
1208 return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("] in a list", 11), Qnil));
1209 }
1210 tem = (read_pure && flag <= 0
1211 ? pure_cons (elt, Qnil)
1212 : Fcons (elt, Qnil));
1213 if (!NILP (tail))
1214 XCONS (tail)->cdr = tem;
1215 else
1216 val = tem;
1217 tail = tem;
1218 if (defunflag < 0)
1219 defunflag = EQ (elt, Qdefun);
1220 else if (defunflag > 0)
1221 read_pure = 1;
1222 }
1223 }
1224 \f
1225 Lisp_Object Vobarray;
1226 Lisp_Object initial_obarray;
1227
1228 Lisp_Object
1229 check_obarray (obarray)
1230 Lisp_Object obarray;
1231 {
1232 while (XTYPE (obarray) != Lisp_Vector || XVECTOR (obarray)->size == 0)
1233 {
1234 /* If Vobarray is now invalid, force it to be valid. */
1235 if (EQ (Vobarray, obarray)) Vobarray = initial_obarray;
1236
1237 obarray = wrong_type_argument (Qvectorp, obarray);
1238 }
1239 return obarray;
1240 }
1241
1242 static int hash_string ();
1243 Lisp_Object oblookup ();
1244
1245 Lisp_Object
1246 intern (str)
1247 char *str;
1248 {
1249 Lisp_Object tem;
1250 int len = strlen (str);
1251 Lisp_Object obarray = Vobarray;
1252
1253 if (XTYPE (obarray) != Lisp_Vector || XVECTOR (obarray)->size == 0)
1254 obarray = check_obarray (obarray);
1255 tem = oblookup (obarray, str, len);
1256 if (XTYPE (tem) == Lisp_Symbol)
1257 return tem;
1258 return Fintern ((!NILP (Vpurify_flag)
1259 ? make_pure_string (str, len)
1260 : make_string (str, len)),
1261 obarray);
1262 }
1263
1264 DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
1265 "Return the canonical symbol whose name is STRING.\n\
1266 If there is none, one is created by this function and returned.\n\
1267 A second optional argument specifies the obarray to use;\n\
1268 it defaults to the value of `obarray'.")
1269 (str, obarray)
1270 Lisp_Object str, obarray;
1271 {
1272 register Lisp_Object tem, sym, *ptr;
1273
1274 if (NILP (obarray)) obarray = Vobarray;
1275 obarray = check_obarray (obarray);
1276
1277 CHECK_STRING (str, 0);
1278
1279 tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
1280 if (XTYPE (tem) != Lisp_Int)
1281 return tem;
1282
1283 if (!NILP (Vpurify_flag))
1284 str = Fpurecopy (str);
1285 sym = Fmake_symbol (str);
1286
1287 ptr = &XVECTOR (obarray)->contents[XINT (tem)];
1288 if (XTYPE (*ptr) == Lisp_Symbol)
1289 XSYMBOL (sym)->next = XSYMBOL (*ptr);
1290 else
1291 XSYMBOL (sym)->next = 0;
1292 *ptr = sym;
1293 return sym;
1294 }
1295
1296 DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
1297 "Return the canonical symbol whose name is STRING, or nil if none exists.\n\
1298 A second optional argument specifies the obarray to use;\n\
1299 it defaults to the value of `obarray'.")
1300 (str, obarray)
1301 Lisp_Object str, obarray;
1302 {
1303 register Lisp_Object tem;
1304
1305 if (NILP (obarray)) obarray = Vobarray;
1306 obarray = check_obarray (obarray);
1307
1308 CHECK_STRING (str, 0);
1309
1310 tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
1311 if (XTYPE (tem) != Lisp_Int)
1312 return tem;
1313 return Qnil;
1314 }
1315
1316 Lisp_Object
1317 oblookup (obarray, ptr, size)
1318 Lisp_Object obarray;
1319 register char *ptr;
1320 register int size;
1321 {
1322 int hash, obsize;
1323 register Lisp_Object tail;
1324 Lisp_Object bucket, tem;
1325
1326 if (XTYPE (obarray) != Lisp_Vector ||
1327 (obsize = XVECTOR (obarray)->size) == 0)
1328 {
1329 obarray = check_obarray (obarray);
1330 obsize = XVECTOR (obarray)->size;
1331 }
1332 /* Combining next two lines breaks VMS C 2.3. */
1333 hash = hash_string (ptr, size);
1334 hash %= obsize;
1335 bucket = XVECTOR (obarray)->contents[hash];
1336 if (XFASTINT (bucket) == 0)
1337 ;
1338 else if (XTYPE (bucket) != Lisp_Symbol)
1339 error ("Bad data in guts of obarray"); /* Like CADR error message */
1340 else for (tail = bucket; ; XSET (tail, Lisp_Symbol, XSYMBOL (tail)->next))
1341 {
1342 if (XSYMBOL (tail)->name->size == size &&
1343 !bcmp (XSYMBOL (tail)->name->data, ptr, size))
1344 return tail;
1345 else if (XSYMBOL (tail)->next == 0)
1346 break;
1347 }
1348 XSET (tem, Lisp_Int, hash);
1349 return tem;
1350 }
1351
1352 static int
1353 hash_string (ptr, len)
1354 unsigned char *ptr;
1355 int len;
1356 {
1357 register unsigned char *p = ptr;
1358 register unsigned char *end = p + len;
1359 register unsigned char c;
1360 register int hash = 0;
1361
1362 while (p != end)
1363 {
1364 c = *p++;
1365 if (c >= 0140) c -= 40;
1366 hash = ((hash<<3) + (hash>>28) + c);
1367 }
1368 return hash & 07777777777;
1369 }
1370
1371 void
1372 map_obarray (obarray, fn, arg)
1373 Lisp_Object obarray;
1374 int (*fn) ();
1375 Lisp_Object arg;
1376 {
1377 register int i;
1378 register Lisp_Object tail;
1379 CHECK_VECTOR (obarray, 1);
1380 for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
1381 {
1382 tail = XVECTOR (obarray)->contents[i];
1383 if (XFASTINT (tail) != 0)
1384 while (1)
1385 {
1386 (*fn) (tail, arg);
1387 if (XSYMBOL (tail)->next == 0)
1388 break;
1389 XSET (tail, Lisp_Symbol, XSYMBOL (tail)->next);
1390 }
1391 }
1392 }
1393
1394 mapatoms_1 (sym, function)
1395 Lisp_Object sym, function;
1396 {
1397 call1 (function, sym);
1398 }
1399
1400 DEFUN ("mapatoms", Fmapatoms, Smapatoms, 1, 2, 0,
1401 "Call FUNCTION on every symbol in OBARRAY.\n\
1402 OBARRAY defaults to the value of `obarray'.")
1403 (function, obarray)
1404 Lisp_Object function, obarray;
1405 {
1406 Lisp_Object tem;
1407
1408 if (NILP (obarray)) obarray = Vobarray;
1409 obarray = check_obarray (obarray);
1410
1411 map_obarray (obarray, mapatoms_1, function);
1412 return Qnil;
1413 }
1414
1415 #define OBARRAY_SIZE 509
1416
1417 void
1418 init_obarray ()
1419 {
1420 Lisp_Object oblength;
1421 int hash;
1422 Lisp_Object *tem;
1423
1424 XFASTINT (oblength) = OBARRAY_SIZE;
1425
1426 Qnil = Fmake_symbol (make_pure_string ("nil", 3));
1427 Vobarray = Fmake_vector (oblength, make_number (0));
1428 initial_obarray = Vobarray;
1429 staticpro (&initial_obarray);
1430 /* Intern nil in the obarray */
1431 /* These locals are to kludge around a pyramid compiler bug. */
1432 hash = hash_string ("nil", 3);
1433 /* Separate statement here to avoid VAXC bug. */
1434 hash %= OBARRAY_SIZE;
1435 tem = &XVECTOR (Vobarray)->contents[hash];
1436 *tem = Qnil;
1437
1438 Qunbound = Fmake_symbol (make_pure_string ("unbound", 7));
1439 XSYMBOL (Qnil)->function = Qunbound;
1440 XSYMBOL (Qunbound)->value = Qunbound;
1441 XSYMBOL (Qunbound)->function = Qunbound;
1442
1443 Qt = intern ("t");
1444 XSYMBOL (Qnil)->value = Qnil;
1445 XSYMBOL (Qnil)->plist = Qnil;
1446 XSYMBOL (Qt)->value = Qt;
1447
1448 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
1449 Vpurify_flag = Qt;
1450
1451 Qvariable_documentation = intern ("variable-documentation");
1452
1453 read_buffer_size = 100;
1454 read_buffer = (char *) malloc (read_buffer_size);
1455 }
1456 \f
1457 void
1458 defsubr (sname)
1459 struct Lisp_Subr *sname;
1460 {
1461 Lisp_Object sym;
1462 sym = intern (sname->symbol_name);
1463 XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
1464 }
1465
1466 #ifdef NOTDEF /* use fset in subr.el now */
1467 void
1468 defalias (sname, string)
1469 struct Lisp_Subr *sname;
1470 char *string;
1471 {
1472 Lisp_Object sym;
1473 sym = intern (string);
1474 XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
1475 }
1476 #endif /* NOTDEF */
1477
1478 /* New replacement for DefIntVar; it ignores the doc string argument
1479 on the assumption that make-docfile will handle that. */
1480 /* Define an "integer variable"; a symbol whose value is forwarded
1481 to a C variable of type int. Sample call: */
1482 /* DEFVARINT ("indent-tabs-mode", &indent_tabs_mode, "Documentation"); */
1483
1484 void
1485 defvar_int (namestring, address, doc)
1486 char *namestring;
1487 int *address;
1488 char *doc;
1489 {
1490 Lisp_Object sym;
1491 sym = intern (namestring);
1492 XSET (XSYMBOL (sym)->value, Lisp_Intfwd, address);
1493 }
1494
1495 /* Similar but define a variable whose value is T if address contains 1,
1496 NIL if address contains 0 */
1497
1498 void
1499 defvar_bool (namestring, address, doc)
1500 char *namestring;
1501 int *address;
1502 char *doc;
1503 {
1504 Lisp_Object sym;
1505 sym = intern (namestring);
1506 XSET (XSYMBOL (sym)->value, Lisp_Boolfwd, address);
1507 }
1508
1509 /* Similar but define a variable whose value is the Lisp Object stored at address. */
1510
1511 void
1512 defvar_lisp (namestring, address, doc)
1513 char *namestring;
1514 Lisp_Object *address;
1515 char *doc;
1516 {
1517 Lisp_Object sym;
1518 sym = intern (namestring);
1519 XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
1520 staticpro (address);
1521 }
1522
1523 /* Similar but don't request gc-marking of the C variable.
1524 Used when that variable will be gc-marked for some other reason,
1525 since marking the same slot twice can cause trouble with strings. */
1526
1527 void
1528 defvar_lisp_nopro (namestring, address, doc)
1529 char *namestring;
1530 Lisp_Object *address;
1531 char *doc;
1532 {
1533 Lisp_Object sym;
1534 sym = intern (namestring);
1535 XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
1536 }
1537
1538 #ifndef standalone
1539
1540 /* Similar but define a variable whose value is the Lisp Object stored in
1541 the current buffer. address is the address of the slot in the buffer that is current now. */
1542
1543 void
1544 defvar_per_buffer (namestring, address, type, doc)
1545 char *namestring;
1546 Lisp_Object *address;
1547 Lisp_Object type;
1548 char *doc;
1549 {
1550 Lisp_Object sym;
1551 int offset;
1552 extern struct buffer buffer_local_symbols;
1553
1554 sym = intern (namestring);
1555 offset = (char *)address - (char *)current_buffer;
1556
1557 XSET (XSYMBOL (sym)->value, Lisp_Buffer_Objfwd,
1558 (Lisp_Object *) offset);
1559 *(Lisp_Object *)(offset + (char *)&buffer_local_symbols) = sym;
1560 *(Lisp_Object *)(offset + (char *)&buffer_local_types) = type;
1561 if (*(int *)(offset + (char *)&buffer_local_flags) == 0)
1562 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
1563 slot of buffer_local_flags */
1564 abort ();
1565 }
1566
1567 #endif /* standalone */
1568 \f
1569 init_lread ()
1570 {
1571 char *normal;
1572
1573 /* Compute the default load-path. */
1574 #ifdef CANNOT_DUMP
1575 normal = PATH_LOADSEARCH;
1576 Vload_path = decode_env_path (0, normal);
1577 #else
1578 if (NILP (Vpurify_flag))
1579 normal = PATH_LOADSEARCH;
1580 else
1581 normal = PATH_DUMPLOADSEARCH;
1582
1583 /* In a dumped Emacs, we normally have to reset the value of
1584 Vload_path from PATH_LOADSEARCH, since the value that was dumped
1585 uses ../lisp, instead of the path of the installed elisp
1586 libraries. However, if it appears that Vload_path was changed
1587 from the default before dumping, don't override that value. */
1588 if (initialized)
1589 {
1590 Lisp_Object dump_path;
1591
1592 dump_path = decode_env_path (0, PATH_DUMPLOADSEARCH);
1593 if (! NILP (Fequal (dump_path, Vload_path)))
1594 Vload_path = decode_env_path (0, normal);
1595 }
1596 else
1597 Vload_path = decode_env_path (0, normal);
1598 #endif
1599
1600 /* Warn if dirs in the *standard* path don't exist. */
1601 {
1602 Lisp_Object path_tail;
1603
1604 for (path_tail = Vload_path;
1605 !NILP (path_tail);
1606 path_tail = XCONS (path_tail)->cdr)
1607 {
1608 Lisp_Object dirfile;
1609 dirfile = Fcar (path_tail);
1610 if (XTYPE (dirfile) == Lisp_String)
1611 {
1612 dirfile = Fdirectory_file_name (dirfile);
1613 if (access (XSTRING (dirfile)->data, 0) < 0)
1614 printf ("Warning: lisp library (%s) does not exist.\n",
1615 XSTRING (Fcar (path_tail))->data);
1616 }
1617 }
1618 }
1619
1620 /* If the EMACSLOADPATH environment variable is set, use its value.
1621 This doesn't apply if we're dumping. */
1622 if (NILP (Vpurify_flag)
1623 && egetenv ("EMACSLOADPATH"))
1624 Vload_path = decode_env_path ("EMACSLOADPATH", normal);
1625
1626 Vvalues = Qnil;
1627
1628 load_in_progress = 0;
1629 }
1630
1631 void
1632 syms_of_lread ()
1633 {
1634 defsubr (&Sread);
1635 defsubr (&Sread_from_string);
1636 defsubr (&Sintern);
1637 defsubr (&Sintern_soft);
1638 defsubr (&Sload);
1639 defsubr (&Seval_buffer);
1640 defsubr (&Seval_region);
1641 defsubr (&Sread_char);
1642 defsubr (&Sread_char_exclusive);
1643 defsubr (&Sread_event);
1644 defsubr (&Sget_file_char);
1645 defsubr (&Smapatoms);
1646
1647 DEFVAR_LISP ("obarray", &Vobarray,
1648 "Symbol table for use by `intern' and `read'.\n\
1649 It is a vector whose length ought to be prime for best results.\n\
1650 The vector's contents don't make sense if examined from Lisp programs;\n\
1651 to find all the symbols in an obarray, use `mapatoms'.");
1652
1653 DEFVAR_LISP ("values", &Vvalues,
1654 "List of values of all expressions which were read, evaluated and printed.\n\
1655 Order is reverse chronological.");
1656
1657 DEFVAR_LISP ("standard-input", &Vstandard_input,
1658 "Stream for read to get input from.\n\
1659 See documentation of `read' for possible values.");
1660 Vstandard_input = Qt;
1661
1662 DEFVAR_LISP ("load-path", &Vload_path,
1663 "*List of directories to search for files to load.\n\
1664 Each element is a string (directory name) or nil (try default directory).\n\
1665 Initialized based on EMACSLOADPATH environment variable, if any,\n\
1666 otherwise to default specified in by file `paths.h' when Emacs was built.");
1667
1668 DEFVAR_BOOL ("load-in-progress", &load_in_progress,
1669 "Non-nil iff inside of `load'.");
1670
1671 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
1672 "An alist of expressions to be evalled when particular files are loaded.\n\
1673 Each element looks like (FILENAME FORMS...).\n\
1674 When `load' is run and the file-name argument is FILENAME,\n\
1675 the FORMS in the corresponding element are executed at the end of loading.\n\n\
1676 FILENAME must match exactly! Normally FILENAME is the name of a library,\n\
1677 with no directory specified, since that is how `load' is normally called.\n\
1678 An error in FORMS does not undo the load,\n\
1679 but does prevent execution of the rest of the FORMS.");
1680 Vafter_load_alist = Qnil;
1681
1682 Qstandard_input = intern ("standard-input");
1683 staticpro (&Qstandard_input);
1684
1685 Qread_char = intern ("read-char");
1686 staticpro (&Qread_char);
1687
1688 Qget_file_char = intern ("get-file-char");
1689 staticpro (&Qget_file_char);
1690 }