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