(Fload): Add "source is newer" info to the "loading" and "done" messages.
[bpt/emacs.git] / src / lread.c
1 /* Lisp parsing and input streams.
2 Copyright (C) 1985, 1986, 1987, 1988, 1989,
3 1993, 1994, 1995 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, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/file.h>
28 #include <errno.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 #include "termhooks.h"
37 #endif
38
39 #ifdef lint
40 #include <sys/inode.h>
41 #endif /* lint */
42
43 #ifdef MSDOS
44 #if __DJGPP__ < 2
45 #include <unistd.h> /* to get X_OK */
46 #endif
47 #include "msdos.h"
48 #endif
49
50 #ifndef X_OK
51 #define X_OK 01
52 #endif
53
54 #ifdef LISP_FLOAT_TYPE
55 #ifdef STDC_HEADERS
56 #include <stdlib.h>
57 #endif
58
59 #include <math.h>
60 #endif /* LISP_FLOAT_TYPE */
61
62 #ifdef HAVE_SETLOCALE
63 #include <locale.h>
64 #endif /* HAVE_SETLOCALE */
65
66 #ifndef O_RDONLY
67 #define O_RDONLY 0
68 #endif
69
70 extern int errno;
71
72 Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list;
73 Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist;
74 Lisp_Object Qascii_character, Qload, Qload_file_name;
75 Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
76
77 extern Lisp_Object Qevent_symbol_element_mask;
78
79 /* non-zero if inside `load' */
80 int load_in_progress;
81
82 /* Directory in which the sources were found. */
83 Lisp_Object Vsource_directory;
84
85 /* Search path for files to be loaded. */
86 Lisp_Object Vload_path;
87
88 /* This is the user-visible association list that maps features to
89 lists of defs in their load files. */
90 Lisp_Object Vload_history;
91
92 /* This is used to build the load history. */
93 Lisp_Object Vcurrent_load_list;
94
95 /* Name of file actually being read by `load'. */
96 Lisp_Object Vload_file_name;
97
98 /* Function to use for reading, in `load' and friends. */
99 Lisp_Object Vload_read_function;
100
101 /* Nonzero means load should forcibly load all dynamic doc strings. */
102 static int load_force_doc_strings;
103
104 /* List of descriptors now open for Fload. */
105 static Lisp_Object load_descriptor_list;
106
107 /* File for get_file_char to read from. Use by load. */
108 static FILE *instream;
109
110 /* When nonzero, read conses in pure space */
111 static int read_pure;
112
113 /* For use within read-from-string (this reader is non-reentrant!!) */
114 static int read_from_string_index;
115 static int read_from_string_limit;
116
117 /* This contains the last string skipped with #@. */
118 static char *saved_doc_string;
119 /* Length of buffer allocated in saved_doc_string. */
120 static int saved_doc_string_size;
121 /* Length of actual data in saved_doc_string. */
122 static int saved_doc_string_length;
123 /* This is the file position that string came from. */
124 static int saved_doc_string_position;
125
126 /* Nonzero means inside a new-style backquote
127 with no surrounding parentheses.
128 Fread initializes this to zero, so we need not specbind it
129 or worry about what happens to it when there is an error. */
130 static int new_backquote_flag;
131 \f
132 /* Handle unreading and rereading of characters.
133 Write READCHAR to read a character,
134 UNREAD(c) to unread c to be read again. */
135
136 #define READCHAR readchar (readcharfun)
137 #define UNREAD(c) unreadchar (readcharfun, c)
138
139 static int
140 readchar (readcharfun)
141 Lisp_Object readcharfun;
142 {
143 Lisp_Object tem;
144 register struct buffer *inbuffer;
145 register int c, mpos;
146
147 if (BUFFERP (readcharfun))
148 {
149 inbuffer = XBUFFER (readcharfun);
150
151 if (BUF_PT (inbuffer) >= BUF_ZV (inbuffer))
152 return -1;
153 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, BUF_PT (inbuffer));
154 SET_BUF_PT (inbuffer, BUF_PT (inbuffer) + 1);
155
156 return c;
157 }
158 if (MARKERP (readcharfun))
159 {
160 inbuffer = XMARKER (readcharfun)->buffer;
161
162 mpos = marker_position (readcharfun);
163
164 if (mpos > BUF_ZV (inbuffer) - 1)
165 return -1;
166 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, mpos);
167 if (mpos != BUF_GPT (inbuffer))
168 XMARKER (readcharfun)->bufpos++;
169 else
170 Fset_marker (readcharfun, make_number (mpos + 1),
171 Fmarker_buffer (readcharfun));
172 return c;
173 }
174 if (EQ (readcharfun, Qget_file_char))
175 {
176 c = getc (instream);
177 #ifdef EINTR
178 /* Interrupted reads have been observed while reading over the network */
179 while (c == EOF && ferror (instream) && errno == EINTR)
180 {
181 clearerr (instream);
182 c = getc (instream);
183 }
184 #endif
185 return c;
186 }
187
188 if (STRINGP (readcharfun))
189 {
190 register int c;
191 /* This used to be return of a conditional expression,
192 but that truncated -1 to a char on VMS. */
193 if (read_from_string_index < read_from_string_limit)
194 c = XSTRING (readcharfun)->data[read_from_string_index++];
195 else
196 c = -1;
197 return c;
198 }
199
200 tem = call0 (readcharfun);
201
202 if (NILP (tem))
203 return -1;
204 return XINT (tem);
205 }
206
207 /* Unread the character C in the way appropriate for the stream READCHARFUN.
208 If the stream is a user function, call it with the char as argument. */
209
210 static void
211 unreadchar (readcharfun, c)
212 Lisp_Object readcharfun;
213 int c;
214 {
215 if (c == -1)
216 /* Don't back up the pointer if we're unreading the end-of-input mark,
217 since readchar didn't advance it when we read it. */
218 ;
219 else if (BUFFERP (readcharfun))
220 {
221 if (XBUFFER (readcharfun) == current_buffer)
222 SET_PT (point - 1);
223 else
224 SET_BUF_PT (XBUFFER (readcharfun), BUF_PT (XBUFFER (readcharfun)) - 1);
225 }
226 else if (MARKERP (readcharfun))
227 XMARKER (readcharfun)->bufpos--;
228 else if (STRINGP (readcharfun))
229 read_from_string_index--;
230 else if (EQ (readcharfun, Qget_file_char))
231 ungetc (c, instream);
232 else
233 call1 (readcharfun, make_number (c));
234 }
235
236 static Lisp_Object read0 (), read1 (), read_list (), read_vector ();
237 \f
238 /* get a character from the tty */
239
240 extern Lisp_Object read_char ();
241
242 /* Read input events until we get one that's acceptable for our purposes.
243
244 If NO_SWITCH_FRAME is non-zero, switch-frame events are stashed
245 until we get a character we like, and then stuffed into
246 unread_switch_frame.
247
248 If ASCII_REQUIRED is non-zero, we check function key events to see
249 if the unmodified version of the symbol has a Qascii_character
250 property, and use that character, if present.
251
252 If ERROR_NONASCII is non-zero, we signal an error if the input we
253 get isn't an ASCII character with modifiers. If it's zero but
254 ASCII_REQUIRED is non-zero, we just re-read until we get an ASCII
255 character. */
256
257 Lisp_Object
258 read_filtered_event (no_switch_frame, ascii_required, error_nonascii)
259 int no_switch_frame, ascii_required, error_nonascii;
260 {
261 #ifdef standalone
262 return make_number (getchar ());
263 #else
264 register Lisp_Object val, delayed_switch_frame;
265
266 delayed_switch_frame = Qnil;
267
268 /* Read until we get an acceptable event. */
269 retry:
270 val = read_char (0, 0, 0, Qnil, 0);
271
272 if (BUFFERP (val))
273 goto retry;
274
275 /* switch-frame events are put off until after the next ASCII
276 character. This is better than signaling an error just because
277 the last characters were typed to a separate minibuffer frame,
278 for example. Eventually, some code which can deal with
279 switch-frame events will read it and process it. */
280 if (no_switch_frame
281 && EVENT_HAS_PARAMETERS (val)
282 && EQ (EVENT_HEAD (val), Qswitch_frame))
283 {
284 delayed_switch_frame = val;
285 goto retry;
286 }
287
288 if (ascii_required)
289 {
290 /* Convert certain symbols to their ASCII equivalents. */
291 if (SYMBOLP (val))
292 {
293 Lisp_Object tem, tem1, tem2;
294 tem = Fget (val, Qevent_symbol_element_mask);
295 if (!NILP (tem))
296 {
297 tem1 = Fget (Fcar (tem), Qascii_character);
298 /* Merge this symbol's modifier bits
299 with the ASCII equivalent of its basic code. */
300 if (!NILP (tem1))
301 XSETFASTINT (val, XINT (tem1) | XINT (Fcar (Fcdr (tem))));
302 }
303 }
304
305 /* If we don't have a character now, deal with it appropriately. */
306 if (!INTEGERP (val))
307 {
308 if (error_nonascii)
309 {
310 Vunread_command_events = Fcons (val, Qnil);
311 error ("Non-character input-event");
312 }
313 else
314 goto retry;
315 }
316 }
317
318 if (! NILP (delayed_switch_frame))
319 unread_switch_frame = delayed_switch_frame;
320
321 return val;
322 #endif
323 }
324
325 DEFUN ("read-char", Fread_char, Sread_char, 0, 0, 0,
326 "Read a character from the command input (keyboard or macro).\n\
327 It is returned as a number.\n\
328 If the user generates an event which is not a character (i.e. a mouse\n\
329 click or function key event), `read-char' signals an error. As an\n\
330 exception, switch-frame events are put off until non-ASCII events can\n\
331 be read.\n\
332 If you want to read non-character events, or ignore them, call\n\
333 `read-event' or `read-char-exclusive' instead.")
334 ()
335 {
336 return read_filtered_event (1, 1, 1);
337 }
338
339 DEFUN ("read-event", Fread_event, Sread_event, 0, 0, 0,
340 "Read an event object from the input stream.")
341 ()
342 {
343 return read_filtered_event (0, 0, 0);
344 }
345
346 DEFUN ("read-char-exclusive", Fread_char_exclusive, Sread_char_exclusive, 0, 0, 0,
347 "Read a character from the command input (keyboard or macro).\n\
348 It is returned as a number. Non-character events are ignored.")
349 ()
350 {
351 return read_filtered_event (1, 1, 0);
352 }
353
354 DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
355 "Don't use this yourself.")
356 ()
357 {
358 register Lisp_Object val;
359 XSETINT (val, getc (instream));
360 return val;
361 }
362 \f
363 static void readevalloop ();
364 static Lisp_Object load_unwind ();
365 static Lisp_Object load_descriptor_unwind ();
366
367 DEFUN ("load", Fload, Sload, 1, 4, 0,
368 "Execute a file of Lisp code named FILE.\n\
369 First try FILE with `.elc' appended, then try with `.el',\n\
370 then try FILE unmodified.\n\
371 This function searches the directories in `load-path'.\n\
372 If optional second arg NOERROR is non-nil,\n\
373 report no error if FILE doesn't exist.\n\
374 Print messages at start and end of loading unless\n\
375 optional third arg NOMESSAGE is non-nil.\n\
376 If optional fourth arg NOSUFFIX is non-nil, don't try adding\n\
377 suffixes `.elc' or `.el' to the specified name FILE.\n\
378 Return t if file exists.")
379 (file, noerror, nomessage, nosuffix)
380 Lisp_Object file, noerror, nomessage, nosuffix;
381 {
382 register FILE *stream;
383 register int fd = -1;
384 register Lisp_Object lispstream;
385 int count = specpdl_ptr - specpdl;
386 Lisp_Object temp;
387 struct gcpro gcpro1;
388 Lisp_Object found;
389 /* 1 means we printed the ".el is newer" message. */
390 int newer = 0;
391 /* 1 means we are loading a compiled file. */
392 int compiled = 0;
393 Lisp_Object handler;
394 #ifdef DOS_NT
395 char *dosmode = "rt";
396 #endif /* DOS_NT */
397
398 CHECK_STRING (file, 0);
399
400 /* If file name is magic, call the handler. */
401 handler = Ffind_file_name_handler (file, Qload);
402 if (!NILP (handler))
403 return call5 (handler, Qload, file, noerror, nomessage, nosuffix);
404
405 /* Do this after the handler to avoid
406 the need to gcpro noerror, nomessage and nosuffix.
407 (Below here, we care only whether they are nil or not.) */
408 file = Fsubstitute_in_file_name (file);
409
410 /* Avoid weird lossage with null string as arg,
411 since it would try to load a directory as a Lisp file */
412 if (XSTRING (file)->size > 0)
413 {
414 GCPRO1 (file);
415 fd = openp (Vload_path, file, !NILP (nosuffix) ? "" : ".elc:.el:",
416 &found, 0);
417 UNGCPRO;
418 }
419
420 if (fd < 0)
421 {
422 if (NILP (noerror))
423 while (1)
424 Fsignal (Qfile_error, Fcons (build_string ("Cannot open load file"),
425 Fcons (file, Qnil)));
426 else
427 return Qnil;
428 }
429
430 if (!bcmp (&(XSTRING (found)->data[XSTRING (found)->size - 4]),
431 ".elc", 4))
432 {
433 struct stat s1, s2;
434 int result;
435
436 compiled = 1;
437
438 #ifdef DOS_NT
439 dosmode = "rb";
440 #endif /* DOS_NT */
441 stat ((char *)XSTRING (found)->data, &s1);
442 XSTRING (found)->data[XSTRING (found)->size - 1] = 0;
443 result = stat ((char *)XSTRING (found)->data, &s2);
444 if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime)
445 {
446 /* Make the progress messages mention that source is newer. */
447 newer = 1;
448
449 /* If we won't print another message, mention this anyway. */
450 if (! NILP (nomessage))
451 message ("Source file `%s' newer than byte-compiled file",
452 XSTRING (found)->data);
453 }
454 XSTRING (found)->data[XSTRING (found)->size - 1] = 'c';
455 }
456
457 #ifdef DOS_NT
458 close (fd);
459 stream = fopen ((char *) XSTRING (found)->data, dosmode);
460 #else /* not DOS_NT */
461 stream = fdopen (fd, "r");
462 #endif /* not DOS_NT */
463 if (stream == 0)
464 {
465 close (fd);
466 error ("Failure to create stdio stream for %s", XSTRING (file)->data);
467 }
468
469 if (NILP (nomessage))
470 {
471 if (newer)
472 message ("Loading %s... (compiled; note, source file is newer)",
473 XSTRING (file)->data);
474 else if (compiled)
475 message ("Loading %s... (compiled)", XSTRING (file)->data);
476 else
477 message ("Loading %s...", XSTRING (file)->data);
478 }
479
480 GCPRO1 (file);
481 lispstream = Fcons (Qnil, Qnil);
482 XSETFASTINT (XCONS (lispstream)->car, (EMACS_UINT)stream >> 16);
483 XSETFASTINT (XCONS (lispstream)->cdr, (EMACS_UINT)stream & 0xffff);
484 record_unwind_protect (load_unwind, lispstream);
485 record_unwind_protect (load_descriptor_unwind, load_descriptor_list);
486 specbind (Qload_file_name, found);
487 load_descriptor_list
488 = Fcons (make_number (fileno (stream)), load_descriptor_list);
489 load_in_progress++;
490 readevalloop (Qget_file_char, stream, file, Feval, 0);
491 unbind_to (count, Qnil);
492
493 /* Run any load-hooks for this file. */
494 temp = Fassoc (file, Vafter_load_alist);
495 if (!NILP (temp))
496 Fprogn (Fcdr (temp));
497 UNGCPRO;
498
499 if (saved_doc_string)
500 free (saved_doc_string);
501 saved_doc_string = 0;
502 saved_doc_string_size = 0;
503
504 if (!noninteractive && NILP (nomessage))
505 {
506 if (newer)
507 message ("Loading %s...done (compiled; note, source file is newer)",
508 XSTRING (file)->data);
509 else if (compiled)
510 message ("Loading %s...done (compiled)", XSTRING (file)->data);
511 else
512 message ("Loading %s...done", XSTRING (file)->data);
513 }
514 return Qt;
515 }
516
517 static Lisp_Object
518 load_unwind (stream) /* used as unwind-protect function in load */
519 Lisp_Object stream;
520 {
521 fclose ((FILE *) (XFASTINT (XCONS (stream)->car) << 16
522 | XFASTINT (XCONS (stream)->cdr)));
523 if (--load_in_progress < 0) load_in_progress = 0;
524 return Qnil;
525 }
526
527 static Lisp_Object
528 load_descriptor_unwind (oldlist)
529 Lisp_Object oldlist;
530 {
531 load_descriptor_list = oldlist;
532 return Qnil;
533 }
534
535 /* Close all descriptors in use for Floads.
536 This is used when starting a subprocess. */
537
538 void
539 close_load_descs ()
540 {
541 #ifndef WINDOWSNT
542 Lisp_Object tail;
543 for (tail = load_descriptor_list; !NILP (tail); tail = XCONS (tail)->cdr)
544 close (XFASTINT (XCONS (tail)->car));
545 #endif
546 }
547 \f
548 static int
549 complete_filename_p (pathname)
550 Lisp_Object pathname;
551 {
552 register unsigned char *s = XSTRING (pathname)->data;
553 return (IS_DIRECTORY_SEP (s[0])
554 || (XSTRING (pathname)->size > 2
555 && IS_DEVICE_SEP (s[1]) && IS_DIRECTORY_SEP (s[2]))
556 #ifdef ALTOS
557 || *s == '@'
558 #endif
559 #ifdef VMS
560 || index (s, ':')
561 #endif /* VMS */
562 );
563 }
564
565 /* Search for a file whose name is STR, looking in directories
566 in the Lisp list PATH, and trying suffixes from SUFFIX.
567 SUFFIX is a string containing possible suffixes separated by colons.
568 On success, returns a file descriptor. On failure, returns -1.
569
570 EXEC_ONLY nonzero means don't open the files,
571 just look for one that is executable. In this case,
572 returns 1 on success.
573
574 If STOREPTR is nonzero, it points to a slot where the name of
575 the file actually found should be stored as a Lisp string.
576 Nil is stored there on failure. */
577
578 int
579 openp (path, str, suffix, storeptr, exec_only)
580 Lisp_Object path, str;
581 char *suffix;
582 Lisp_Object *storeptr;
583 int exec_only;
584 {
585 register int fd;
586 int fn_size = 100;
587 char buf[100];
588 register char *fn = buf;
589 int absolute = 0;
590 int want_size;
591 register Lisp_Object filename;
592 struct stat st;
593 struct gcpro gcpro1;
594
595 GCPRO1 (str);
596 if (storeptr)
597 *storeptr = Qnil;
598
599 if (complete_filename_p (str))
600 absolute = 1;
601
602 for (; !NILP (path); path = Fcdr (path))
603 {
604 char *nsuffix;
605
606 filename = Fexpand_file_name (str, Fcar (path));
607 if (!complete_filename_p (filename))
608 /* If there are non-absolute elts in PATH (eg ".") */
609 /* Of course, this could conceivably lose if luser sets
610 default-directory to be something non-absolute... */
611 {
612 filename = Fexpand_file_name (filename, current_buffer->directory);
613 if (!complete_filename_p (filename))
614 /* Give up on this path element! */
615 continue;
616 }
617
618 /* Calculate maximum size of any filename made from
619 this path element/specified file name and any possible suffix. */
620 want_size = strlen (suffix) + XSTRING (filename)->size + 1;
621 if (fn_size < want_size)
622 fn = (char *) alloca (fn_size = 100 + want_size);
623
624 nsuffix = suffix;
625
626 /* Loop over suffixes. */
627 while (1)
628 {
629 char *esuffix = (char *) index (nsuffix, ':');
630 int lsuffix = esuffix ? esuffix - nsuffix : strlen (nsuffix);
631
632 /* Concatenate path element/specified name with the suffix. */
633 strncpy (fn, XSTRING (filename)->data, XSTRING (filename)->size);
634 fn[XSTRING (filename)->size] = 0;
635 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */
636 strncat (fn, nsuffix, lsuffix);
637
638 /* Ignore file if it's a directory. */
639 if (stat (fn, &st) >= 0
640 && (st.st_mode & S_IFMT) != S_IFDIR)
641 {
642 /* Check that we can access or open it. */
643 if (exec_only)
644 fd = (access (fn, X_OK) == 0) ? 1 : -1;
645 else
646 fd = open (fn, O_RDONLY, 0);
647
648 if (fd >= 0)
649 {
650 /* We succeeded; return this descriptor and filename. */
651 if (storeptr)
652 *storeptr = build_string (fn);
653 UNGCPRO;
654 return fd;
655 }
656 }
657
658 /* Advance to next suffix. */
659 if (esuffix == 0)
660 break;
661 nsuffix += lsuffix + 1;
662 }
663 if (absolute)
664 break;
665 }
666
667 UNGCPRO;
668 return -1;
669 }
670
671 \f
672 /* Merge the list we've accumulated of globals from the current input source
673 into the load_history variable. The details depend on whether
674 the source has an associated file name or not. */
675
676 static void
677 build_load_history (stream, source)
678 FILE *stream;
679 Lisp_Object source;
680 {
681 register Lisp_Object tail, prev, newelt;
682 register Lisp_Object tem, tem2;
683 register int foundit, loading;
684
685 /* Don't bother recording anything for preloaded files. */
686 if (!NILP (Vpurify_flag))
687 return;
688
689 loading = stream || !NARROWED;
690
691 tail = Vload_history;
692 prev = Qnil;
693 foundit = 0;
694 while (!NILP (tail))
695 {
696 tem = Fcar (tail);
697
698 /* Find the feature's previous assoc list... */
699 if (!NILP (Fequal (source, Fcar (tem))))
700 {
701 foundit = 1;
702
703 /* If we're loading, remove it. */
704 if (loading)
705 {
706 if (NILP (prev))
707 Vload_history = Fcdr (tail);
708 else
709 Fsetcdr (prev, Fcdr (tail));
710 }
711
712 /* Otherwise, cons on new symbols that are not already members. */
713 else
714 {
715 tem2 = Vcurrent_load_list;
716
717 while (CONSP (tem2))
718 {
719 newelt = Fcar (tem2);
720
721 if (NILP (Fmemq (newelt, tem)))
722 Fsetcar (tail, Fcons (Fcar (tem),
723 Fcons (newelt, Fcdr (tem))));
724
725 tem2 = Fcdr (tem2);
726 QUIT;
727 }
728 }
729 }
730 else
731 prev = tail;
732 tail = Fcdr (tail);
733 QUIT;
734 }
735
736 /* If we're loading, cons the new assoc onto the front of load-history,
737 the most-recently-loaded position. Also do this if we didn't find
738 an existing member for the current source. */
739 if (loading || !foundit)
740 Vload_history = Fcons (Fnreverse (Vcurrent_load_list),
741 Vload_history);
742 }
743
744 Lisp_Object
745 unreadpure () /* Used as unwind-protect function in readevalloop */
746 {
747 read_pure = 0;
748 return Qnil;
749 }
750
751 static void
752 readevalloop (readcharfun, stream, sourcename, evalfun, printflag)
753 Lisp_Object readcharfun;
754 FILE *stream;
755 Lisp_Object sourcename;
756 Lisp_Object (*evalfun) ();
757 int printflag;
758 {
759 register int c;
760 register Lisp_Object val;
761 int count = specpdl_ptr - specpdl;
762 struct gcpro gcpro1;
763 struct buffer *b = 0;
764
765 if (BUFFERP (readcharfun))
766 b = XBUFFER (readcharfun);
767 else if (MARKERP (readcharfun))
768 b = XMARKER (readcharfun)->buffer;
769
770 specbind (Qstandard_input, readcharfun);
771 specbind (Qcurrent_load_list, Qnil);
772
773 GCPRO1 (sourcename);
774
775 LOADHIST_ATTACH (sourcename);
776
777 while (1)
778 {
779 if (b != 0 && NILP (b->name))
780 error ("Reading from killed buffer");
781
782 instream = stream;
783 c = READCHAR;
784 if (c == ';')
785 {
786 while ((c = READCHAR) != '\n' && c != -1);
787 continue;
788 }
789 if (c < 0) break;
790
791 /* Ignore whitespace here, so we can detect eof. */
792 if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')
793 continue;
794
795 if (!NILP (Vpurify_flag) && c == '(')
796 {
797 int count1 = specpdl_ptr - specpdl;
798 record_unwind_protect (unreadpure, Qnil);
799 val = read_list (-1, readcharfun);
800 unbind_to (count1, Qnil);
801 }
802 else
803 {
804 UNREAD (c);
805 if (NILP (Vload_read_function))
806 val = read0 (readcharfun);
807 else
808 val = call1 (Vload_read_function, readcharfun);
809 }
810
811 val = (*evalfun) (val);
812 if (printflag)
813 {
814 Vvalues = Fcons (val, Vvalues);
815 if (EQ (Vstandard_output, Qt))
816 Fprin1 (val, Qnil);
817 else
818 Fprint (val, Qnil);
819 }
820 }
821
822 build_load_history (stream, sourcename);
823 UNGCPRO;
824
825 unbind_to (count, Qnil);
826 }
827
828 #ifndef standalone
829
830 DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 2, "",
831 "Execute the current buffer as Lisp code.\n\
832 Programs can pass two arguments, BUFFER and PRINTFLAG.\n\
833 BUFFER is the buffer to evaluate (nil means use current buffer).\n\
834 PRINTFLAG controls printing of output:\n\
835 nil means discard it; anything else is stream for print.\n\
836 \n\
837 If there is no error, point does not move. If there is an error,\n\
838 point remains at the end of the last character read from the buffer.")
839 (buffer, printflag)
840 Lisp_Object buffer, printflag;
841 {
842 int count = specpdl_ptr - specpdl;
843 Lisp_Object tem, buf;
844
845 if (NILP (buffer))
846 buf = Fcurrent_buffer ();
847 else
848 buf = Fget_buffer (buffer);
849 if (NILP (buf))
850 error ("No such buffer.");
851
852 if (NILP (printflag))
853 tem = Qsymbolp;
854 else
855 tem = printflag;
856 specbind (Qstandard_output, tem);
857 record_unwind_protect (save_excursion_restore, save_excursion_save ());
858 BUF_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf)));
859 readevalloop (buf, 0, XBUFFER (buf)->filename, Feval, !NILP (printflag));
860 unbind_to (count, Qnil);
861
862 return Qnil;
863 }
864
865 #if 0
866 DEFUN ("eval-current-buffer", Feval_current_buffer, Seval_current_buffer, 0, 1, "",
867 "Execute the current buffer as Lisp code.\n\
868 Programs can pass argument PRINTFLAG which controls printing of output:\n\
869 nil means discard it; anything else is stream for print.\n\
870 \n\
871 If there is no error, point does not move. If there is an error,\n\
872 point remains at the end of the last character read from the buffer.")
873 (printflag)
874 Lisp_Object printflag;
875 {
876 int count = specpdl_ptr - specpdl;
877 Lisp_Object tem, cbuf;
878
879 cbuf = Fcurrent_buffer ()
880
881 if (NILP (printflag))
882 tem = Qsymbolp;
883 else
884 tem = printflag;
885 specbind (Qstandard_output, tem);
886 record_unwind_protect (save_excursion_restore, save_excursion_save ());
887 SET_PT (BEGV);
888 readevalloop (cbuf, 0, XBUFFER (cbuf)->filename, Feval, !NILP (printflag));
889 return unbind_to (count, Qnil);
890 }
891 #endif
892
893 DEFUN ("eval-region", Feval_region, Seval_region, 2, 3, "r",
894 "Execute the region as Lisp code.\n\
895 When called from programs, expects two arguments,\n\
896 giving starting and ending indices in the current buffer\n\
897 of the text to be executed.\n\
898 Programs can pass third argument PRINTFLAG which controls output:\n\
899 nil means discard it; anything else is stream for printing it.\n\
900 \n\
901 If there is no error, point does not move. If there is an error,\n\
902 point remains at the end of the last character read from the buffer.")
903 (start, end, printflag)
904 Lisp_Object start, end, printflag;
905 {
906 int count = specpdl_ptr - specpdl;
907 Lisp_Object tem, cbuf;
908
909 cbuf = Fcurrent_buffer ();
910
911 if (NILP (printflag))
912 tem = Qsymbolp;
913 else
914 tem = printflag;
915 specbind (Qstandard_output, tem);
916
917 if (NILP (printflag))
918 record_unwind_protect (save_excursion_restore, save_excursion_save ());
919 record_unwind_protect (save_restriction_restore, save_restriction_save ());
920
921 /* This both uses start and checks its type. */
922 Fgoto_char (start);
923 Fnarrow_to_region (make_number (BEGV), end);
924 readevalloop (cbuf, 0, XBUFFER (cbuf)->filename, Feval, !NILP (printflag));
925
926 return unbind_to (count, Qnil);
927 }
928
929 #endif /* standalone */
930 \f
931 DEFUN ("read", Fread, Sread, 0, 1, 0,
932 "Read one Lisp expression as text from STREAM, return as Lisp object.\n\
933 If STREAM is nil, use the value of `standard-input' (which see).\n\
934 STREAM or the value of `standard-input' may be:\n\
935 a buffer (read from point and advance it)\n\
936 a marker (read from where it points and advance it)\n\
937 a function (call it with no arguments for each character,\n\
938 call it with a char as argument to push a char back)\n\
939 a string (takes text from string, starting at the beginning)\n\
940 t (read text line using minibuffer and use it).")
941 (stream)
942 Lisp_Object stream;
943 {
944 extern Lisp_Object Fread_minibuffer ();
945
946 if (NILP (stream))
947 stream = Vstandard_input;
948 if (EQ (stream, Qt))
949 stream = Qread_char;
950
951 new_backquote_flag = 0;
952
953 #ifndef standalone
954 if (EQ (stream, Qread_char))
955 return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
956 #endif
957
958 if (STRINGP (stream))
959 return Fcar (Fread_from_string (stream, Qnil, Qnil));
960
961 return read0 (stream);
962 }
963
964 DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
965 "Read one Lisp expression which is represented as text by STRING.\n\
966 Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).\n\
967 START and END optionally delimit a substring of STRING from which to read;\n\
968 they default to 0 and (length STRING) respectively.")
969 (string, start, end)
970 Lisp_Object string, start, end;
971 {
972 int startval, endval;
973 Lisp_Object tem;
974
975 CHECK_STRING (string,0);
976
977 if (NILP (end))
978 endval = XSTRING (string)->size;
979 else
980 { CHECK_NUMBER (end,2);
981 endval = XINT (end);
982 if (endval < 0 || endval > XSTRING (string)->size)
983 args_out_of_range (string, end);
984 }
985
986 if (NILP (start))
987 startval = 0;
988 else
989 { CHECK_NUMBER (start,1);
990 startval = XINT (start);
991 if (startval < 0 || startval > endval)
992 args_out_of_range (string, start);
993 }
994
995 read_from_string_index = startval;
996 read_from_string_limit = endval;
997
998 new_backquote_flag = 0;
999
1000 tem = read0 (string);
1001 return Fcons (tem, make_number (read_from_string_index));
1002 }
1003 \f
1004 /* Use this for recursive reads, in contexts where internal tokens
1005 are not allowed. */
1006 static Lisp_Object
1007 read0 (readcharfun)
1008 Lisp_Object readcharfun;
1009 {
1010 register Lisp_Object val;
1011 char c;
1012
1013 val = read1 (readcharfun, &c, 0);
1014 if (c)
1015 Fsignal (Qinvalid_read_syntax, Fcons (make_string (&c, 1), Qnil));
1016
1017 return val;
1018 }
1019 \f
1020 static int read_buffer_size;
1021 static char *read_buffer;
1022
1023 static int
1024 read_escape (readcharfun)
1025 Lisp_Object readcharfun;
1026 {
1027 register int c = READCHAR;
1028 switch (c)
1029 {
1030 case -1:
1031 error ("End of file");
1032
1033 case 'a':
1034 return '\007';
1035 case 'b':
1036 return '\b';
1037 case 'd':
1038 return 0177;
1039 case 'e':
1040 return 033;
1041 case 'f':
1042 return '\f';
1043 case 'n':
1044 return '\n';
1045 case 'r':
1046 return '\r';
1047 case 't':
1048 return '\t';
1049 case 'v':
1050 return '\v';
1051 case '\n':
1052 return -1;
1053
1054 case 'M':
1055 c = READCHAR;
1056 if (c != '-')
1057 error ("Invalid escape character syntax");
1058 c = READCHAR;
1059 if (c == '\\')
1060 c = read_escape (readcharfun);
1061 return c | meta_modifier;
1062
1063 case 'S':
1064 c = READCHAR;
1065 if (c != '-')
1066 error ("Invalid escape character syntax");
1067 c = READCHAR;
1068 if (c == '\\')
1069 c = read_escape (readcharfun);
1070 return c | shift_modifier;
1071
1072 case 'H':
1073 c = READCHAR;
1074 if (c != '-')
1075 error ("Invalid escape character syntax");
1076 c = READCHAR;
1077 if (c == '\\')
1078 c = read_escape (readcharfun);
1079 return c | hyper_modifier;
1080
1081 case 'A':
1082 c = READCHAR;
1083 if (c != '-')
1084 error ("Invalid escape character syntax");
1085 c = READCHAR;
1086 if (c == '\\')
1087 c = read_escape (readcharfun);
1088 return c | alt_modifier;
1089
1090 case 's':
1091 c = READCHAR;
1092 if (c != '-')
1093 error ("Invalid escape character syntax");
1094 c = READCHAR;
1095 if (c == '\\')
1096 c = read_escape (readcharfun);
1097 return c | super_modifier;
1098
1099 case 'C':
1100 c = READCHAR;
1101 if (c != '-')
1102 error ("Invalid escape character syntax");
1103 case '^':
1104 c = READCHAR;
1105 if (c == '\\')
1106 c = read_escape (readcharfun);
1107 if ((c & 0177) == '?')
1108 return 0177 | c;
1109 /* ASCII control chars are made from letters (both cases),
1110 as well as the non-letters within 0100...0137. */
1111 else if ((c & 0137) >= 0101 && (c & 0137) <= 0132)
1112 return (c & (037 | ~0177));
1113 else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
1114 return (c & (037 | ~0177));
1115 else
1116 return c | ctrl_modifier;
1117
1118 case '0':
1119 case '1':
1120 case '2':
1121 case '3':
1122 case '4':
1123 case '5':
1124 case '6':
1125 case '7':
1126 /* An octal escape, as in ANSI C. */
1127 {
1128 register int i = c - '0';
1129 register int count = 0;
1130 while (++count < 3)
1131 {
1132 if ((c = READCHAR) >= '0' && c <= '7')
1133 {
1134 i *= 8;
1135 i += c - '0';
1136 }
1137 else
1138 {
1139 UNREAD (c);
1140 break;
1141 }
1142 }
1143 return i;
1144 }
1145
1146 case 'x':
1147 /* A hex escape, as in ANSI C. */
1148 {
1149 int i = 0;
1150 while (1)
1151 {
1152 c = READCHAR;
1153 if (c >= '0' && c <= '9')
1154 {
1155 i *= 16;
1156 i += c - '0';
1157 }
1158 else if ((c >= 'a' && c <= 'f')
1159 || (c >= 'A' && c <= 'F'))
1160 {
1161 i *= 16;
1162 if (c >= 'a' && c <= 'f')
1163 i += c - 'a' + 10;
1164 else
1165 i += c - 'A' + 10;
1166 }
1167 else
1168 {
1169 UNREAD (c);
1170 break;
1171 }
1172 }
1173 return i;
1174 }
1175
1176 default:
1177 return c;
1178 }
1179 }
1180
1181 /* If the next token is ')' or ']' or '.', we store that character
1182 in *PCH and the return value is not interesting. Else, we store
1183 zero in *PCH and we read and return one lisp object.
1184
1185 FIRST_IN_LIST is nonzero if this is the first element of a list. */
1186
1187 static Lisp_Object
1188 read1 (readcharfun, pch, first_in_list)
1189 register Lisp_Object readcharfun;
1190 char *pch;
1191 int first_in_list;
1192 {
1193 register int c;
1194 *pch = 0;
1195
1196 retry:
1197
1198 c = READCHAR;
1199 if (c < 0) return Fsignal (Qend_of_file, Qnil);
1200
1201 switch (c)
1202 {
1203 case '(':
1204 return read_list (0, readcharfun);
1205
1206 case '[':
1207 return read_vector (readcharfun);
1208
1209 case ')':
1210 case ']':
1211 {
1212 *pch = c;
1213 return Qnil;
1214 }
1215
1216 case '#':
1217 c = READCHAR;
1218 if (c == '^')
1219 {
1220 c = READCHAR;
1221 if (c == '[')
1222 {
1223 Lisp_Object tmp;
1224 tmp = read_vector (readcharfun);
1225 if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS
1226 || XVECTOR (tmp)->size > CHAR_TABLE_STANDARD_SLOTS + 10)
1227 error ("Invalid size char-table");
1228 XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp));
1229 return tmp;
1230 }
1231 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#^", 2), Qnil));
1232 }
1233 if (c == '&')
1234 {
1235 Lisp_Object length;
1236 length = read1 (readcharfun, pch, first_in_list);
1237 c = READCHAR;
1238 if (c == '"')
1239 {
1240 Lisp_Object tmp, val;
1241 int size_in_chars = ((XFASTINT (length) + BITS_PER_CHAR)
1242 / BITS_PER_CHAR);
1243
1244 UNREAD (c);
1245 tmp = read1 (readcharfun, pch, first_in_list);
1246 if (size_in_chars != XSTRING (tmp)->size)
1247 Fsignal (Qinvalid_read_syntax,
1248 Fcons (make_string ("#&", 2), Qnil));
1249
1250 val = Fmake_bool_vector (length, Qnil);
1251 bcopy (XSTRING (tmp)->data, XBOOL_VECTOR (val)->data,
1252 size_in_chars);
1253 return val;
1254 }
1255 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#&", 2), Qnil));
1256 }
1257 if (c == '[')
1258 {
1259 /* Accept compiled functions at read-time so that we don't have to
1260 build them using function calls. */
1261 Lisp_Object tmp;
1262 tmp = read_vector (readcharfun);
1263 return Fmake_byte_code (XVECTOR (tmp)->size,
1264 XVECTOR (tmp)->contents);
1265 }
1266 #ifdef USE_TEXT_PROPERTIES
1267 if (c == '(')
1268 {
1269 Lisp_Object tmp;
1270 struct gcpro gcpro1;
1271 char ch;
1272
1273 /* Read the string itself. */
1274 tmp = read1 (readcharfun, &ch, 0);
1275 if (ch != 0 || !STRINGP (tmp))
1276 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
1277 GCPRO1 (tmp);
1278 /* Read the intervals and their properties. */
1279 while (1)
1280 {
1281 Lisp_Object beg, end, plist;
1282
1283 beg = read1 (readcharfun, &ch, 0);
1284 if (ch == ')')
1285 break;
1286 if (ch == 0)
1287 end = read1 (readcharfun, &ch, 0);
1288 if (ch == 0)
1289 plist = read1 (readcharfun, &ch, 0);
1290 if (ch)
1291 Fsignal (Qinvalid_read_syntax,
1292 Fcons (build_string ("invalid string property list"),
1293 Qnil));
1294 Fset_text_properties (beg, end, plist, tmp);
1295 }
1296 UNGCPRO;
1297 return tmp;
1298 }
1299 #endif
1300 /* #@NUMBER is used to skip NUMBER following characters.
1301 That's used in .elc files to skip over doc strings
1302 and function definitions. */
1303 if (c == '@')
1304 {
1305 int i, nskip = 0;
1306
1307 /* Read a decimal integer. */
1308 while ((c = READCHAR) >= 0
1309 && c >= '0' && c <= '9')
1310 {
1311 nskip *= 10;
1312 nskip += c - '0';
1313 }
1314 if (c >= 0)
1315 UNREAD (c);
1316
1317 #ifndef DOS_NT /* I don't know if filepos works right on MSDOS and Windoze. */
1318 if (load_force_doc_strings && EQ (readcharfun, Qget_file_char))
1319 {
1320 /* If we are supposed to force doc strings into core right now,
1321 record the last string that we skipped,
1322 and record where in the file it comes from. */
1323 if (saved_doc_string_size == 0)
1324 {
1325 saved_doc_string_size = nskip + 100;
1326 saved_doc_string = (char *) xmalloc (saved_doc_string_size);
1327 }
1328 if (nskip > saved_doc_string_size)
1329 {
1330 saved_doc_string_size = nskip + 100;
1331 saved_doc_string = (char *) xrealloc (saved_doc_string,
1332 saved_doc_string_size);
1333 }
1334
1335 saved_doc_string_position = ftell (instream);
1336
1337 /* Copy that many characters into saved_doc_string. */
1338 for (i = 0; i < nskip && c >= 0; i++)
1339 saved_doc_string[i] = c = READCHAR;
1340
1341 saved_doc_string_length = i;
1342 }
1343 else
1344 #endif /* not DOS_NT */
1345 {
1346 /* Skip that many characters. */
1347 for (i = 0; i < nskip && c >= 0; i++)
1348 c = READCHAR;
1349 }
1350 goto retry;
1351 }
1352 if (c == '$')
1353 return Vload_file_name;
1354 if (c == '\'')
1355 return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil));
1356
1357
1358 UNREAD (c);
1359 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
1360
1361 case ';':
1362 while ((c = READCHAR) >= 0 && c != '\n');
1363 goto retry;
1364
1365 case '\'':
1366 {
1367 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
1368 }
1369
1370 case '`':
1371 if (first_in_list)
1372 goto default_label;
1373 else
1374 {
1375 Lisp_Object value;
1376
1377 new_backquote_flag = 1;
1378 value = read0 (readcharfun);
1379 new_backquote_flag = 0;
1380
1381 return Fcons (Qbackquote, Fcons (value, Qnil));
1382 }
1383
1384 case ',':
1385 if (new_backquote_flag)
1386 {
1387 Lisp_Object comma_type = Qnil;
1388 Lisp_Object value;
1389 int ch = READCHAR;
1390
1391 if (ch == '@')
1392 comma_type = Qcomma_at;
1393 else if (ch == '.')
1394 comma_type = Qcomma_dot;
1395 else
1396 {
1397 if (ch >= 0) UNREAD (ch);
1398 comma_type = Qcomma;
1399 }
1400
1401 new_backquote_flag = 0;
1402 value = read0 (readcharfun);
1403 new_backquote_flag = 1;
1404 return Fcons (comma_type, Fcons (value, Qnil));
1405 }
1406 else
1407 goto default_label;
1408
1409 case '?':
1410 {
1411 register Lisp_Object val;
1412
1413 c = READCHAR;
1414 if (c < 0) return Fsignal (Qend_of_file, Qnil);
1415
1416 if (c == '\\')
1417 XSETINT (val, read_escape (readcharfun));
1418 else
1419 XSETINT (val, c);
1420
1421 return val;
1422 }
1423
1424 case '\"':
1425 {
1426 register char *p = read_buffer;
1427 register char *end = read_buffer + read_buffer_size;
1428 register int c;
1429 int cancel = 0;
1430
1431 while ((c = READCHAR) >= 0
1432 && c != '\"')
1433 {
1434 if (p == end)
1435 {
1436 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
1437 p += new - read_buffer;
1438 read_buffer += new - read_buffer;
1439 end = read_buffer + read_buffer_size;
1440 }
1441 if (c == '\\')
1442 c = read_escape (readcharfun);
1443 /* c is -1 if \ newline has just been seen */
1444 if (c == -1)
1445 {
1446 if (p == read_buffer)
1447 cancel = 1;
1448 }
1449 else
1450 {
1451 /* Allow `\C- ' and `\C-?'. */
1452 if (c == (CHAR_CTL | ' '))
1453 c = 0;
1454 else if (c == (CHAR_CTL | '?'))
1455 c = 127;
1456
1457 if (c & CHAR_META)
1458 /* Move the meta bit to the right place for a string. */
1459 c = (c & ~CHAR_META) | 0x80;
1460 if (c & ~0xff)
1461 error ("Invalid modifier in string");
1462 *p++ = c;
1463 }
1464 }
1465 if (c < 0) return Fsignal (Qend_of_file, Qnil);
1466
1467 /* If purifying, and string starts with \ newline,
1468 return zero instead. This is for doc strings
1469 that we are really going to find in etc/DOC.nn.nn */
1470 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
1471 return make_number (0);
1472
1473 if (read_pure)
1474 return make_pure_string (read_buffer, p - read_buffer);
1475 else
1476 return make_string (read_buffer, p - read_buffer);
1477 }
1478
1479 case '.':
1480 {
1481 #ifdef LISP_FLOAT_TYPE
1482 /* If a period is followed by a number, then we should read it
1483 as a floating point number. Otherwise, it denotes a dotted
1484 pair. */
1485 int next_char = READCHAR;
1486 UNREAD (next_char);
1487
1488 if (! (next_char >= '0' && next_char <= '9'))
1489 #endif
1490 {
1491 *pch = c;
1492 return Qnil;
1493 }
1494
1495 /* Otherwise, we fall through! Note that the atom-reading loop
1496 below will now loop at least once, assuring that we will not
1497 try to UNREAD two characters in a row. */
1498 }
1499 default:
1500 default_label:
1501 if (c <= 040) goto retry;
1502 {
1503 register char *p = read_buffer;
1504 int quoted = 0;
1505
1506 {
1507 register char *end = read_buffer + read_buffer_size;
1508
1509 while (c > 040 &&
1510 !(c == '\"' || c == '\'' || c == ';' || c == '?'
1511 || c == '(' || c == ')'
1512 #ifndef LISP_FLOAT_TYPE
1513 /* If we have floating-point support, then we need
1514 to allow <digits><dot><digits>. */
1515 || c =='.'
1516 #endif /* not LISP_FLOAT_TYPE */
1517 || c == '[' || c == ']' || c == '#'
1518 ))
1519 {
1520 if (p == end)
1521 {
1522 register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
1523 p += new - read_buffer;
1524 read_buffer += new - read_buffer;
1525 end = read_buffer + read_buffer_size;
1526 }
1527 if (c == '\\')
1528 {
1529 c = READCHAR;
1530 quoted = 1;
1531 }
1532 *p++ = c;
1533 c = READCHAR;
1534 }
1535
1536 if (p == end)
1537 {
1538 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
1539 p += new - read_buffer;
1540 read_buffer += new - read_buffer;
1541 /* end = read_buffer + read_buffer_size; */
1542 }
1543 *p = 0;
1544 if (c >= 0)
1545 UNREAD (c);
1546 }
1547
1548 if (!quoted)
1549 {
1550 register char *p1;
1551 register Lisp_Object val;
1552 p1 = read_buffer;
1553 if (*p1 == '+' || *p1 == '-') p1++;
1554 /* Is it an integer? */
1555 if (p1 != p)
1556 {
1557 while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++;
1558 #ifdef LISP_FLOAT_TYPE
1559 /* Integers can have trailing decimal points. */
1560 if (p1 > read_buffer && p1 < p && *p1 == '.') p1++;
1561 #endif
1562 if (p1 == p)
1563 /* It is an integer. */
1564 {
1565 #ifdef LISP_FLOAT_TYPE
1566 if (p1[-1] == '.')
1567 p1[-1] = '\0';
1568 #endif
1569 if (sizeof (int) == sizeof (EMACS_INT))
1570 XSETINT (val, atoi (read_buffer));
1571 else if (sizeof (long) == sizeof (EMACS_INT))
1572 XSETINT (val, atol (read_buffer));
1573 else
1574 abort ();
1575 return val;
1576 }
1577 }
1578 #ifdef LISP_FLOAT_TYPE
1579 if (isfloat_string (read_buffer))
1580 return make_float (atof (read_buffer));
1581 #endif
1582 }
1583
1584 return intern (read_buffer);
1585 }
1586 }
1587 }
1588 \f
1589 #ifdef LISP_FLOAT_TYPE
1590
1591 #define LEAD_INT 1
1592 #define DOT_CHAR 2
1593 #define TRAIL_INT 4
1594 #define E_CHAR 8
1595 #define EXP_INT 16
1596
1597 int
1598 isfloat_string (cp)
1599 register char *cp;
1600 {
1601 register state;
1602
1603 state = 0;
1604 if (*cp == '+' || *cp == '-')
1605 cp++;
1606
1607 if (*cp >= '0' && *cp <= '9')
1608 {
1609 state |= LEAD_INT;
1610 while (*cp >= '0' && *cp <= '9')
1611 cp++;
1612 }
1613 if (*cp == '.')
1614 {
1615 state |= DOT_CHAR;
1616 cp++;
1617 }
1618 if (*cp >= '0' && *cp <= '9')
1619 {
1620 state |= TRAIL_INT;
1621 while (*cp >= '0' && *cp <= '9')
1622 cp++;
1623 }
1624 if (*cp == 'e')
1625 {
1626 state |= E_CHAR;
1627 cp++;
1628 if (*cp == '+' || *cp == '-')
1629 cp++;
1630 }
1631
1632 if (*cp >= '0' && *cp <= '9')
1633 {
1634 state |= EXP_INT;
1635 while (*cp >= '0' && *cp <= '9')
1636 cp++;
1637 }
1638 return (((*cp == 0) || (*cp == ' ') || (*cp == '\t') || (*cp == '\n') || (*cp == '\r') || (*cp == '\f'))
1639 && (state == (LEAD_INT|DOT_CHAR|TRAIL_INT)
1640 || state == (DOT_CHAR|TRAIL_INT)
1641 || state == (LEAD_INT|E_CHAR|EXP_INT)
1642 || state == (LEAD_INT|DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)
1643 || state == (DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)));
1644 }
1645 #endif /* LISP_FLOAT_TYPE */
1646 \f
1647 static Lisp_Object
1648 read_vector (readcharfun)
1649 Lisp_Object readcharfun;
1650 {
1651 register int i;
1652 register int size;
1653 register Lisp_Object *ptr;
1654 register Lisp_Object tem, vector;
1655 register struct Lisp_Cons *otem;
1656 Lisp_Object len;
1657
1658 tem = read_list (1, readcharfun);
1659 len = Flength (tem);
1660 vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
1661
1662
1663 size = XVECTOR (vector)->size;
1664 ptr = XVECTOR (vector)->contents;
1665 for (i = 0; i < size; i++)
1666 {
1667 ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem);
1668 otem = XCONS (tem);
1669 tem = Fcdr (tem);
1670 free_cons (otem);
1671 }
1672 return vector;
1673 }
1674
1675 /* flag = 1 means check for ] to terminate rather than ) and .
1676 flag = -1 means check for starting with defun
1677 and make structure pure. */
1678
1679 static Lisp_Object
1680 read_list (flag, readcharfun)
1681 int flag;
1682 register Lisp_Object readcharfun;
1683 {
1684 /* -1 means check next element for defun,
1685 0 means don't check,
1686 1 means already checked and found defun. */
1687 int defunflag = flag < 0 ? -1 : 0;
1688 Lisp_Object val, tail;
1689 register Lisp_Object elt, tem;
1690 struct gcpro gcpro1, gcpro2;
1691 /* 0 is the normal case.
1692 1 means this list is a doc reference; replace it with the number 0.
1693 2 means this list is a doc reference; replace it with the doc string. */
1694 int doc_reference = 0;
1695
1696 /* Initialize this to 1 if we are reading a list. */
1697 int first_in_list = flag <= 0;
1698
1699 val = Qnil;
1700 tail = Qnil;
1701
1702 while (1)
1703 {
1704 char ch;
1705 GCPRO2 (val, tail);
1706 elt = read1 (readcharfun, &ch, first_in_list);
1707 UNGCPRO;
1708
1709 first_in_list = 0;
1710
1711 /* While building, if the list starts with #$, treat it specially. */
1712 if (EQ (elt, Vload_file_name)
1713 && !NILP (Vpurify_flag))
1714 {
1715 if (NILP (Vdoc_file_name))
1716 /* We have not yet called Snarf-documentation, so assume
1717 this file is described in the DOC-MM.NN file
1718 and Snarf-documentation will fill in the right value later.
1719 For now, replace the whole list with 0. */
1720 doc_reference = 1;
1721 else
1722 /* We have already called Snarf-documentation, so make a relative
1723 file name for this file, so it can be found properly
1724 in the installed Lisp directory.
1725 We don't use Fexpand_file_name because that would make
1726 the directory absolute now. */
1727 elt = concat2 (build_string ("../lisp/"),
1728 Ffile_name_nondirectory (elt));
1729 }
1730 else if (EQ (elt, Vload_file_name)
1731 && load_force_doc_strings)
1732 doc_reference = 2;
1733
1734 if (ch)
1735 {
1736 if (flag > 0)
1737 {
1738 if (ch == ']')
1739 return val;
1740 Fsignal (Qinvalid_read_syntax,
1741 Fcons (make_string (") or . in a vector", 18), Qnil));
1742 }
1743 if (ch == ')')
1744 return val;
1745 if (ch == '.')
1746 {
1747 GCPRO2 (val, tail);
1748 if (!NILP (tail))
1749 XCONS (tail)->cdr = read0 (readcharfun);
1750 else
1751 val = read0 (readcharfun);
1752 read1 (readcharfun, &ch, 0);
1753 UNGCPRO;
1754 if (ch == ')')
1755 {
1756 if (doc_reference == 1)
1757 return make_number (0);
1758 if (doc_reference == 2)
1759 {
1760 /* Get a doc string from the file we are loading.
1761 If it's in saved_doc_string, get it from there. */
1762 int pos = XINT (XCONS (val)->cdr);
1763 if (pos >= saved_doc_string_position
1764 && pos < (saved_doc_string_position
1765 + saved_doc_string_length))
1766 {
1767 int start = pos - saved_doc_string_position;
1768 int from, to;
1769
1770 /* Process quoting with ^A,
1771 and find the end of the string,
1772 which is marked with ^_ (037). */
1773 for (from = start, to = start;
1774 saved_doc_string[from] != 037;)
1775 {
1776 int c = saved_doc_string[from++];
1777 if (c == 1)
1778 {
1779 c = saved_doc_string[from++];
1780 if (c == 1)
1781 saved_doc_string[to++] = c;
1782 else if (c == '0')
1783 saved_doc_string[to++] = 0;
1784 else if (c == '_')
1785 saved_doc_string[to++] = 037;
1786 }
1787 else
1788 saved_doc_string[to++] = c;
1789 }
1790
1791 return make_string (saved_doc_string + start,
1792 to - start);
1793 }
1794 else
1795 return read_doc_string (val);
1796 }
1797
1798 return val;
1799 }
1800 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil));
1801 }
1802 return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("] in a list", 11), Qnil));
1803 }
1804 tem = (read_pure && flag <= 0
1805 ? pure_cons (elt, Qnil)
1806 : Fcons (elt, Qnil));
1807 if (!NILP (tail))
1808 XCONS (tail)->cdr = tem;
1809 else
1810 val = tem;
1811 tail = tem;
1812 if (defunflag < 0)
1813 defunflag = EQ (elt, Qdefun);
1814 else if (defunflag > 0)
1815 read_pure = 1;
1816 }
1817 }
1818 \f
1819 Lisp_Object Vobarray;
1820 Lisp_Object initial_obarray;
1821
1822 /* oblookup stores the bucket number here, for the sake of Funintern. */
1823
1824 int oblookup_last_bucket_number;
1825
1826 static int hash_string ();
1827 Lisp_Object oblookup ();
1828
1829 /* Get an error if OBARRAY is not an obarray.
1830 If it is one, return it. */
1831
1832 Lisp_Object
1833 check_obarray (obarray)
1834 Lisp_Object obarray;
1835 {
1836 while (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
1837 {
1838 /* If Vobarray is now invalid, force it to be valid. */
1839 if (EQ (Vobarray, obarray)) Vobarray = initial_obarray;
1840
1841 obarray = wrong_type_argument (Qvectorp, obarray);
1842 }
1843 return obarray;
1844 }
1845
1846 /* Intern the C string STR: return a symbol with that name,
1847 interned in the current obarray. */
1848
1849 Lisp_Object
1850 intern (str)
1851 char *str;
1852 {
1853 Lisp_Object tem;
1854 int len = strlen (str);
1855 Lisp_Object obarray;
1856
1857 obarray = Vobarray;
1858 if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
1859 obarray = check_obarray (obarray);
1860 tem = oblookup (obarray, str, len);
1861 if (SYMBOLP (tem))
1862 return tem;
1863 return Fintern ((!NILP (Vpurify_flag)
1864 ? make_pure_string (str, len)
1865 : make_string (str, len)),
1866 obarray);
1867 }
1868 \f
1869 DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
1870 "Return the canonical symbol whose name is STRING.\n\
1871 If there is none, one is created by this function and returned.\n\
1872 A second optional argument specifies the obarray to use;\n\
1873 it defaults to the value of `obarray'.")
1874 (string, obarray)
1875 Lisp_Object string, obarray;
1876 {
1877 register Lisp_Object tem, sym, *ptr;
1878
1879 if (NILP (obarray)) obarray = Vobarray;
1880 obarray = check_obarray (obarray);
1881
1882 CHECK_STRING (string, 0);
1883
1884 tem = oblookup (obarray, XSTRING (string)->data, XSTRING (string)->size);
1885 if (!INTEGERP (tem))
1886 return tem;
1887
1888 if (!NILP (Vpurify_flag))
1889 string = Fpurecopy (string);
1890 sym = Fmake_symbol (string);
1891
1892 ptr = &XVECTOR (obarray)->contents[XINT (tem)];
1893 if (SYMBOLP (*ptr))
1894 XSYMBOL (sym)->next = XSYMBOL (*ptr);
1895 else
1896 XSYMBOL (sym)->next = 0;
1897 *ptr = sym;
1898 return sym;
1899 }
1900
1901 DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
1902 "Return the canonical symbol whose name is STRING, or nil if none exists.\n\
1903 A second optional argument specifies the obarray to use;\n\
1904 it defaults to the value of `obarray'.")
1905 (string, obarray)
1906 Lisp_Object string, obarray;
1907 {
1908 register Lisp_Object tem;
1909
1910 if (NILP (obarray)) obarray = Vobarray;
1911 obarray = check_obarray (obarray);
1912
1913 CHECK_STRING (string, 0);
1914
1915 tem = oblookup (obarray, XSTRING (string)->data, XSTRING (string)->size);
1916 if (!INTEGERP (tem))
1917 return tem;
1918 return Qnil;
1919 }
1920 \f
1921 DEFUN ("unintern", Funintern, Sunintern, 1, 2, 0,
1922 "Delete the symbol named NAME, if any, from OBARRAY.\n\
1923 The value is t if a symbol was found and deleted, nil otherwise.\n\
1924 NAME may be a string or a symbol. If it is a symbol, that symbol\n\
1925 is deleted, if it belongs to OBARRAY--no other symbol is deleted.\n\
1926 OBARRAY defaults to the value of the variable `obarray'.")
1927 (name, obarray)
1928 Lisp_Object name, obarray;
1929 {
1930 register Lisp_Object string, tem;
1931 int hash;
1932
1933 if (NILP (obarray)) obarray = Vobarray;
1934 obarray = check_obarray (obarray);
1935
1936 if (SYMBOLP (name))
1937 XSETSTRING (string, XSYMBOL (name)->name);
1938 else
1939 {
1940 CHECK_STRING (name, 0);
1941 string = name;
1942 }
1943
1944 tem = oblookup (obarray, XSTRING (string)->data, XSTRING (string)->size);
1945 if (INTEGERP (tem))
1946 return Qnil;
1947 /* If arg was a symbol, don't delete anything but that symbol itself. */
1948 if (SYMBOLP (name) && !EQ (name, tem))
1949 return Qnil;
1950
1951 hash = oblookup_last_bucket_number;
1952
1953 if (EQ (XVECTOR (obarray)->contents[hash], tem))
1954 {
1955 if (XSYMBOL (tem)->next)
1956 XSETSYMBOL (XVECTOR (obarray)->contents[hash], XSYMBOL (tem)->next);
1957 else
1958 XSETINT (XVECTOR (obarray)->contents[hash], 0);
1959 }
1960 else
1961 {
1962 Lisp_Object tail, following;
1963
1964 for (tail = XVECTOR (obarray)->contents[hash];
1965 XSYMBOL (tail)->next;
1966 tail = following)
1967 {
1968 XSETSYMBOL (following, XSYMBOL (tail)->next);
1969 if (EQ (following, tem))
1970 {
1971 XSYMBOL (tail)->next = XSYMBOL (following)->next;
1972 break;
1973 }
1974 }
1975 }
1976
1977 return Qt;
1978 }
1979 \f
1980 /* Return the symbol in OBARRAY whose names matches the string
1981 of SIZE characters at PTR. If there is no such symbol in OBARRAY,
1982 return nil.
1983
1984 Also store the bucket number in oblookup_last_bucket_number. */
1985
1986 Lisp_Object
1987 oblookup (obarray, ptr, size)
1988 Lisp_Object obarray;
1989 register char *ptr;
1990 register int size;
1991 {
1992 int hash;
1993 int obsize;
1994 register Lisp_Object tail;
1995 Lisp_Object bucket, tem;
1996
1997 if (!VECTORP (obarray)
1998 || (obsize = XVECTOR (obarray)->size) == 0)
1999 {
2000 obarray = check_obarray (obarray);
2001 obsize = XVECTOR (obarray)->size;
2002 }
2003 /* This is sometimes needed in the middle of GC. */
2004 obsize &= ~ARRAY_MARK_FLAG;
2005 /* Combining next two lines breaks VMS C 2.3. */
2006 hash = hash_string (ptr, size);
2007 hash %= obsize;
2008 bucket = XVECTOR (obarray)->contents[hash];
2009 oblookup_last_bucket_number = hash;
2010 if (XFASTINT (bucket) == 0)
2011 ;
2012 else if (!SYMBOLP (bucket))
2013 error ("Bad data in guts of obarray"); /* Like CADR error message */
2014 else
2015 for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->next))
2016 {
2017 if (XSYMBOL (tail)->name->size == size
2018 && !bcmp (XSYMBOL (tail)->name->data, ptr, size))
2019 return tail;
2020 else if (XSYMBOL (tail)->next == 0)
2021 break;
2022 }
2023 XSETINT (tem, hash);
2024 return tem;
2025 }
2026
2027 static int
2028 hash_string (ptr, len)
2029 unsigned char *ptr;
2030 int len;
2031 {
2032 register unsigned char *p = ptr;
2033 register unsigned char *end = p + len;
2034 register unsigned char c;
2035 register int hash = 0;
2036
2037 while (p != end)
2038 {
2039 c = *p++;
2040 if (c >= 0140) c -= 40;
2041 hash = ((hash<<3) + (hash>>28) + c);
2042 }
2043 return hash & 07777777777;
2044 }
2045 \f
2046 void
2047 map_obarray (obarray, fn, arg)
2048 Lisp_Object obarray;
2049 int (*fn) ();
2050 Lisp_Object arg;
2051 {
2052 register int i;
2053 register Lisp_Object tail;
2054 CHECK_VECTOR (obarray, 1);
2055 for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
2056 {
2057 tail = XVECTOR (obarray)->contents[i];
2058 if (XFASTINT (tail) != 0)
2059 while (1)
2060 {
2061 (*fn) (tail, arg);
2062 if (XSYMBOL (tail)->next == 0)
2063 break;
2064 XSETSYMBOL (tail, XSYMBOL (tail)->next);
2065 }
2066 }
2067 }
2068
2069 mapatoms_1 (sym, function)
2070 Lisp_Object sym, function;
2071 {
2072 call1 (function, sym);
2073 }
2074
2075 DEFUN ("mapatoms", Fmapatoms, Smapatoms, 1, 2, 0,
2076 "Call FUNCTION on every symbol in OBARRAY.\n\
2077 OBARRAY defaults to the value of `obarray'.")
2078 (function, obarray)
2079 Lisp_Object function, obarray;
2080 {
2081 Lisp_Object tem;
2082
2083 if (NILP (obarray)) obarray = Vobarray;
2084 obarray = check_obarray (obarray);
2085
2086 map_obarray (obarray, mapatoms_1, function);
2087 return Qnil;
2088 }
2089
2090 #define OBARRAY_SIZE 1511
2091
2092 void
2093 init_obarray ()
2094 {
2095 Lisp_Object oblength;
2096 int hash;
2097 Lisp_Object *tem;
2098
2099 XSETFASTINT (oblength, OBARRAY_SIZE);
2100
2101 Qnil = Fmake_symbol (make_pure_string ("nil", 3));
2102 Vobarray = Fmake_vector (oblength, make_number (0));
2103 initial_obarray = Vobarray;
2104 staticpro (&initial_obarray);
2105 /* Intern nil in the obarray */
2106 /* These locals are to kludge around a pyramid compiler bug. */
2107 hash = hash_string ("nil", 3);
2108 /* Separate statement here to avoid VAXC bug. */
2109 hash %= OBARRAY_SIZE;
2110 tem = &XVECTOR (Vobarray)->contents[hash];
2111 *tem = Qnil;
2112
2113 Qunbound = Fmake_symbol (make_pure_string ("unbound", 7));
2114 XSYMBOL (Qnil)->function = Qunbound;
2115 XSYMBOL (Qunbound)->value = Qunbound;
2116 XSYMBOL (Qunbound)->function = Qunbound;
2117
2118 Qt = intern ("t");
2119 XSYMBOL (Qnil)->value = Qnil;
2120 XSYMBOL (Qnil)->plist = Qnil;
2121 XSYMBOL (Qt)->value = Qt;
2122
2123 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
2124 Vpurify_flag = Qt;
2125
2126 Qvariable_documentation = intern ("variable-documentation");
2127
2128 read_buffer_size = 100;
2129 read_buffer = (char *) malloc (read_buffer_size);
2130 }
2131 \f
2132 void
2133 defsubr (sname)
2134 struct Lisp_Subr *sname;
2135 {
2136 Lisp_Object sym;
2137 sym = intern (sname->symbol_name);
2138 XSETSUBR (XSYMBOL (sym)->function, sname);
2139 }
2140
2141 #ifdef NOTDEF /* use fset in subr.el now */
2142 void
2143 defalias (sname, string)
2144 struct Lisp_Subr *sname;
2145 char *string;
2146 {
2147 Lisp_Object sym;
2148 sym = intern (string);
2149 XSETSUBR (XSYMBOL (sym)->function, sname);
2150 }
2151 #endif /* NOTDEF */
2152
2153 /* Define an "integer variable"; a symbol whose value is forwarded
2154 to a C variable of type int. Sample call: */
2155 /* DEFVAR_INT ("indent-tabs-mode", &indent_tabs_mode, "Documentation"); */
2156 void
2157 defvar_int (namestring, address)
2158 char *namestring;
2159 int *address;
2160 {
2161 Lisp_Object sym, val;
2162 sym = intern (namestring);
2163 val = allocate_misc ();
2164 XMISCTYPE (val) = Lisp_Misc_Intfwd;
2165 XINTFWD (val)->intvar = address;
2166 XSYMBOL (sym)->value = val;
2167 }
2168
2169 /* Similar but define a variable whose value is T if address contains 1,
2170 NIL if address contains 0 */
2171 void
2172 defvar_bool (namestring, address)
2173 char *namestring;
2174 int *address;
2175 {
2176 Lisp_Object sym, val;
2177 sym = intern (namestring);
2178 val = allocate_misc ();
2179 XMISCTYPE (val) = Lisp_Misc_Boolfwd;
2180 XBOOLFWD (val)->boolvar = address;
2181 XSYMBOL (sym)->value = val;
2182 }
2183
2184 /* Similar but define a variable whose value is the Lisp Object stored
2185 at address. Two versions: with and without gc-marking of the C
2186 variable. The nopro version is used when that variable will be
2187 gc-marked for some other reason, since marking the same slot twice
2188 can cause trouble with strings. */
2189 void
2190 defvar_lisp_nopro (namestring, address)
2191 char *namestring;
2192 Lisp_Object *address;
2193 {
2194 Lisp_Object sym, val;
2195 sym = intern (namestring);
2196 val = allocate_misc ();
2197 XMISCTYPE (val) = Lisp_Misc_Objfwd;
2198 XOBJFWD (val)->objvar = address;
2199 XSYMBOL (sym)->value = val;
2200 }
2201
2202 void
2203 defvar_lisp (namestring, address)
2204 char *namestring;
2205 Lisp_Object *address;
2206 {
2207 defvar_lisp_nopro (namestring, address);
2208 staticpro (address);
2209 }
2210
2211 #ifndef standalone
2212
2213 /* Similar but define a variable whose value is the Lisp Object stored in
2214 the current buffer. address is the address of the slot in the buffer
2215 that is current now. */
2216
2217 void
2218 defvar_per_buffer (namestring, address, type, doc)
2219 char *namestring;
2220 Lisp_Object *address;
2221 Lisp_Object type;
2222 char *doc;
2223 {
2224 Lisp_Object sym, val;
2225 int offset;
2226 extern struct buffer buffer_local_symbols;
2227
2228 sym = intern (namestring);
2229 val = allocate_misc ();
2230 offset = (char *)address - (char *)current_buffer;
2231
2232 XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd;
2233 XBUFFER_OBJFWD (val)->offset = offset;
2234 XSYMBOL (sym)->value = val;
2235 *(Lisp_Object *)(offset + (char *)&buffer_local_symbols) = sym;
2236 *(Lisp_Object *)(offset + (char *)&buffer_local_types) = type;
2237 if (XINT (*(Lisp_Object *)(offset + (char *)&buffer_local_flags)) == 0)
2238 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
2239 slot of buffer_local_flags */
2240 abort ();
2241 }
2242
2243 #endif /* standalone */
2244
2245 /* Similar but define a variable whose value is the Lisp Object stored
2246 at a particular offset in the current kboard object. */
2247
2248 void
2249 defvar_kboard (namestring, offset)
2250 char *namestring;
2251 int offset;
2252 {
2253 Lisp_Object sym, val;
2254 sym = intern (namestring);
2255 val = allocate_misc ();
2256 XMISCTYPE (val) = Lisp_Misc_Kboard_Objfwd;
2257 XKBOARD_OBJFWD (val)->offset = offset;
2258 XSYMBOL (sym)->value = val;
2259 }
2260 \f
2261 /* Record the value of load-path used at the start of dumping
2262 so we can see if the site changed it later during dumping. */
2263 static Lisp_Object dump_path;
2264
2265 init_lread ()
2266 {
2267 char *normal;
2268 int turn_off_warning = 0;
2269
2270 #ifdef HAVE_SETLOCALE
2271 /* Make sure numbers are parsed as we expect. */
2272 setlocale (LC_NUMERIC, "C");
2273 #endif /* HAVE_SETLOCALE */
2274
2275 /* Compute the default load-path. */
2276 #ifdef CANNOT_DUMP
2277 normal = PATH_LOADSEARCH;
2278 Vload_path = decode_env_path (0, normal);
2279 #else
2280 if (NILP (Vpurify_flag))
2281 normal = PATH_LOADSEARCH;
2282 else
2283 normal = PATH_DUMPLOADSEARCH;
2284
2285 /* In a dumped Emacs, we normally have to reset the value of
2286 Vload_path from PATH_LOADSEARCH, since the value that was dumped
2287 uses ../lisp, instead of the path of the installed elisp
2288 libraries. However, if it appears that Vload_path was changed
2289 from the default before dumping, don't override that value. */
2290 if (initialized)
2291 {
2292 if (! NILP (Fequal (dump_path, Vload_path)))
2293 {
2294 Vload_path = decode_env_path (0, normal);
2295 if (!NILP (Vinstallation_directory))
2296 {
2297 /* Add to the path the lisp subdir of the
2298 installation dir, if it exists. */
2299 Lisp_Object tem, tem1;
2300 tem = Fexpand_file_name (build_string ("lisp"),
2301 Vinstallation_directory);
2302 tem1 = Ffile_exists_p (tem);
2303 if (!NILP (tem1))
2304 {
2305 if (NILP (Fmember (tem, Vload_path)))
2306 {
2307 turn_off_warning = 1;
2308 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
2309 }
2310 }
2311 else
2312 /* That dir doesn't exist, so add the build-time
2313 Lisp dirs instead. */
2314 Vload_path = nconc2 (Vload_path, dump_path);
2315
2316 /* Add site-list under the installation dir, if it exists. */
2317 tem = Fexpand_file_name (build_string ("site-lisp"),
2318 Vinstallation_directory);
2319 tem1 = Ffile_exists_p (tem);
2320 if (!NILP (tem1))
2321 {
2322 if (NILP (Fmember (tem, Vload_path)))
2323 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
2324 }
2325 }
2326 }
2327 }
2328 else
2329 {
2330 /* ../lisp refers to the build directory.
2331 NORMAL refers to the lisp dir in the source directory. */
2332 Vload_path = Fcons (build_string ("../lisp"),
2333 decode_env_path (0, normal));
2334 dump_path = Vload_path;
2335 }
2336 #endif
2337
2338 #ifndef WINDOWSNT
2339 /* When Emacs is invoked over network shares on NT, PATH_LOADSEARCH is
2340 almost never correct, thereby causing a warning to be printed out that
2341 confuses users. Since PATH_LOADSEARCH is always overridden by the
2342 EMACSLOADPATH environment variable below, disable the warning on NT. */
2343
2344 /* Warn if dirs in the *standard* path don't exist. */
2345 if (!turn_off_warning)
2346 {
2347 Lisp_Object path_tail;
2348
2349 for (path_tail = Vload_path;
2350 !NILP (path_tail);
2351 path_tail = XCONS (path_tail)->cdr)
2352 {
2353 Lisp_Object dirfile;
2354 dirfile = Fcar (path_tail);
2355 if (STRINGP (dirfile))
2356 {
2357 dirfile = Fdirectory_file_name (dirfile);
2358 if (access (XSTRING (dirfile)->data, 0) < 0)
2359 fprintf (stderr,
2360 "Warning: Lisp directory `%s' does not exist.\n",
2361 XSTRING (Fcar (path_tail))->data);
2362 }
2363 }
2364 }
2365 #endif /* WINDOWSNT */
2366
2367 /* If the EMACSLOADPATH environment variable is set, use its value.
2368 This doesn't apply if we're dumping. */
2369 #ifndef CANNOT_DUMP
2370 if (NILP (Vpurify_flag)
2371 && egetenv ("EMACSLOADPATH"))
2372 #endif
2373 Vload_path = decode_env_path ("EMACSLOADPATH", normal);
2374
2375 Vvalues = Qnil;
2376
2377 load_in_progress = 0;
2378 Vload_file_name = Qnil;
2379
2380 load_descriptor_list = Qnil;
2381 }
2382
2383 void
2384 syms_of_lread ()
2385 {
2386 defsubr (&Sread);
2387 defsubr (&Sread_from_string);
2388 defsubr (&Sintern);
2389 defsubr (&Sintern_soft);
2390 defsubr (&Sunintern);
2391 defsubr (&Sload);
2392 defsubr (&Seval_buffer);
2393 defsubr (&Seval_region);
2394 defsubr (&Sread_char);
2395 defsubr (&Sread_char_exclusive);
2396 defsubr (&Sread_event);
2397 defsubr (&Sget_file_char);
2398 defsubr (&Smapatoms);
2399
2400 DEFVAR_LISP ("obarray", &Vobarray,
2401 "Symbol table for use by `intern' and `read'.\n\
2402 It is a vector whose length ought to be prime for best results.\n\
2403 The vector's contents don't make sense if examined from Lisp programs;\n\
2404 to find all the symbols in an obarray, use `mapatoms'.");
2405
2406 DEFVAR_LISP ("values", &Vvalues,
2407 "List of values of all expressions which were read, evaluated and printed.\n\
2408 Order is reverse chronological.");
2409
2410 DEFVAR_LISP ("standard-input", &Vstandard_input,
2411 "Stream for read to get input from.\n\
2412 See documentation of `read' for possible values.");
2413 Vstandard_input = Qt;
2414
2415 DEFVAR_LISP ("load-path", &Vload_path,
2416 "*List of directories to search for files to load.\n\
2417 Each element is a string (directory name) or nil (try default directory).\n\
2418 Initialized based on EMACSLOADPATH environment variable, if any,\n\
2419 otherwise to default specified by file `paths.h' when Emacs was built.");
2420
2421 DEFVAR_BOOL ("load-in-progress", &load_in_progress,
2422 "Non-nil iff inside of `load'.");
2423
2424 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
2425 "An alist of expressions to be evalled when particular files are loaded.\n\
2426 Each element looks like (FILENAME FORMS...).\n\
2427 When `load' is run and the file-name argument is FILENAME,\n\
2428 the FORMS in the corresponding element are executed at the end of loading.\n\n\
2429 FILENAME must match exactly! Normally FILENAME is the name of a library,\n\
2430 with no directory specified, since that is how `load' is normally called.\n\
2431 An error in FORMS does not undo the load,\n\
2432 but does prevent execution of the rest of the FORMS.");
2433 Vafter_load_alist = Qnil;
2434
2435 DEFVAR_LISP ("load-history", &Vload_history,
2436 "Alist mapping source file names to symbols and features.\n\
2437 Each alist element is a list that starts with a file name,\n\
2438 except for one element (optional) that starts with nil and describes\n\
2439 definitions evaluated from buffers not visiting files.\n\
2440 The remaining elements of each list are symbols defined as functions\n\
2441 or variables, and cons cells `(provide . FEATURE)' and `(require . FEATURE)'.");
2442 Vload_history = Qnil;
2443
2444 DEFVAR_LISP ("load-file-name", &Vload_file_name,
2445 "Full name of file being loaded by `load'.");
2446 Vload_file_name = Qnil;
2447
2448 DEFVAR_LISP ("current-load-list", &Vcurrent_load_list,
2449 "Used for internal purposes by `load'.");
2450 Vcurrent_load_list = Qnil;
2451
2452 DEFVAR_LISP ("load-read-function", &Vload_read_function,
2453 "Function used by `load' and `eval-region' for reading expressions.\n\
2454 The default is nil, which means use the function `read'.");
2455 Vload_read_function = Qnil;
2456
2457 DEFVAR_BOOL ("load-force-doc-strings", &load_force_doc_strings,
2458 "Non-nil means `load' should force-load all dynamic doc strings.\n\
2459 This is useful when the file being loaded is a temporary copy.");
2460 load_force_doc_strings = 0;
2461
2462 DEFVAR_LISP ("source-directory", &Vsource_directory,
2463 "Directory in which Emacs sources were found when Emacs was built.\n\
2464 You cannot count on them to still be there!");
2465 Vsource_directory
2466 = Fexpand_file_name (build_string ("../"),
2467 Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH)));
2468
2469 /* Vsource_directory was initialized in init_lread. */
2470
2471 load_descriptor_list = Qnil;
2472 staticpro (&load_descriptor_list);
2473
2474 Qcurrent_load_list = intern ("current-load-list");
2475 staticpro (&Qcurrent_load_list);
2476
2477 Qstandard_input = intern ("standard-input");
2478 staticpro (&Qstandard_input);
2479
2480 Qread_char = intern ("read-char");
2481 staticpro (&Qread_char);
2482
2483 Qget_file_char = intern ("get-file-char");
2484 staticpro (&Qget_file_char);
2485
2486 Qbackquote = intern ("`");
2487 staticpro (&Qbackquote);
2488 Qcomma = intern (",");
2489 staticpro (&Qcomma);
2490 Qcomma_at = intern (",@");
2491 staticpro (&Qcomma_at);
2492 Qcomma_dot = intern (",.");
2493 staticpro (&Qcomma_dot);
2494
2495 Qascii_character = intern ("ascii-character");
2496 staticpro (&Qascii_character);
2497
2498 Qfunction = intern ("function");
2499 staticpro (&Qfunction);
2500
2501 Qload = intern ("load");
2502 staticpro (&Qload);
2503
2504 Qload_file_name = intern ("load-file-name");
2505 staticpro (&Qload_file_name);
2506
2507 staticpro (&dump_path);
2508 }