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