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