[USE_CRT_DLL]: Remove unnecessary extern, which
[bpt/emacs.git] / src / lread.c
CommitLineData
078e7b4a 1/* Lisp parsing and input streams.
68c45bf0 2 Copyright (C) 1985, 86, 87, 88, 89, 93, 94, 95, 97, 98, 1999
33046fc9 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 29#include "lisp.h"
95384e1e 30#include "intervals.h"
078e7b4a 31#include "buffer.h"
fe0e03f3 32#include "charset.h"
57bda87a 33#include <epaths.h>
078e7b4a 34#include "commands.h"
e37c0805 35#include "keyboard.h"
7bd279cd 36#include "termhooks.h"
078e7b4a
JB
37
38#ifdef lint
39#include <sys/inode.h>
40#endif /* lint */
41
79051982
RS
42#ifdef MSDOS
43#if __DJGPP__ < 2
44#include <unistd.h> /* to get X_OK */
45#endif
46#include "msdos.h"
47#endif
48
c1a2f60a
AS
49#ifdef HAVE_UNISTD_H
50#include <unistd.h>
51#endif
52
078e7b4a
JB
53#ifndef X_OK
54#define X_OK 01
55#endif
56
078e7b4a 57#include <math.h>
078e7b4a 58
c011e9a5
RS
59#ifdef HAVE_SETLOCALE
60#include <locale.h>
61#endif /* HAVE_SETLOCALE */
62
f7d279f0
RS
63#ifndef O_RDONLY
64#define O_RDONLY 0
65#endif
66
68c45bf0
PE
67#ifdef HAVE_FTELLO
68#define file_offset off_t
69#define file_tell ftello
70#else
71#define file_offset long
72#define file_tell ftell
73#endif
74
03695ace 75#ifndef USE_CRT_DLL
2c1b5dbe 76extern int errno;
03695ace 77#endif
2c1b5dbe 78
8a1f1537 79Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list;
078e7b4a 80Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist;
20ea2964 81Lisp_Object Qascii_character, Qload, Qload_file_name;
2b6cae0c 82Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
74549846 83Lisp_Object Qinhibit_file_name_operation;
7bd279cd
RS
84
85extern Lisp_Object Qevent_symbol_element_mask;
74549846 86extern Lisp_Object Qfile_exists_p;
078e7b4a
JB
87
88/* non-zero if inside `load' */
89int load_in_progress;
90
1521a8fa
RS
91/* Directory in which the sources were found. */
92Lisp_Object Vsource_directory;
93
078e7b4a
JB
94/* Search path for files to be loaded. */
95Lisp_Object Vload_path;
96
4116ab9f
KH
97/* File name of user's init file. */
98Lisp_Object Vuser_init_file;
99
ae321d28
RS
100/* This is the user-visible association list that maps features to
101 lists of defs in their load files. */
102Lisp_Object Vload_history;
103
20ea2964 104/* This is used to build the load history. */
ae321d28
RS
105Lisp_Object Vcurrent_load_list;
106
4b104c41
RS
107/* List of files that were preloaded. */
108Lisp_Object Vpreloaded_file_list;
109
20ea2964
RS
110/* Name of file actually being read by `load'. */
111Lisp_Object Vload_file_name;
112
84a15045
RS
113/* Function to use for reading, in `load' and friends. */
114Lisp_Object Vload_read_function;
115
4ad679f9
EN
116/* The association list of objects read with the #n=object form.
117 Each member of the list has the form (n . object), and is used to
118 look up the object for the corresponding #n# construct.
119 It must be set to nil before all top-level calls to read0. */
120Lisp_Object read_objects;
121
b2a30870
RS
122/* Nonzero means load should forcibly load all dynamic doc strings. */
123static int load_force_doc_strings;
124
94e554db
RS
125/* Nonzero means read should convert strings to unibyte. */
126static int load_convert_to_unibyte;
127
fe0e03f3
KH
128/* Function to use for loading an Emacs lisp source file (not
129 compiled) instead of readevalloop. */
130Lisp_Object Vload_source_file_function;
131
1ffcc3b1
DL
132/* List of all DEFVAR_BOOL variables. Used by the byte optimizer. */
133Lisp_Object Vbyte_boolean_vars;
134
d2c6be7f
RS
135/* List of descriptors now open for Fload. */
136static Lisp_Object load_descriptor_list;
137
b2a30870 138/* File for get_file_char to read from. Use by load. */
078e7b4a
JB
139static FILE *instream;
140
141/* When nonzero, read conses in pure space */
142static int read_pure;
143
b2a30870 144/* For use within read-from-string (this reader is non-reentrant!!) */
078e7b4a 145static int read_from_string_index;
bed23cb2 146static int read_from_string_index_byte;
078e7b4a 147static int read_from_string_limit;
17634846 148
6f7f43d5
RS
149/* Number of bytes left to read in the buffer character
150 that `readchar' has already advanced over. */
151static int readchar_backlog;
152
c15cfd1f 153/* This contains the last string skipped with #@. */
b2a30870
RS
154static char *saved_doc_string;
155/* Length of buffer allocated in saved_doc_string. */
156static int saved_doc_string_size;
157/* Length of actual data in saved_doc_string. */
158static int saved_doc_string_length;
159/* This is the file position that string came from. */
68c45bf0 160static file_offset saved_doc_string_position;
b2a30870 161
c15cfd1f
RS
162/* This contains the previous string skipped with #@.
163 We copy it from saved_doc_string when a new string
164 is put in saved_doc_string. */
165static char *prev_saved_doc_string;
166/* Length of buffer allocated in prev_saved_doc_string. */
167static int prev_saved_doc_string_size;
168/* Length of actual data in prev_saved_doc_string. */
169static int prev_saved_doc_string_length;
170/* This is the file position that string came from. */
68c45bf0 171static file_offset prev_saved_doc_string_position;
c15cfd1f 172
17634846
RS
173/* Nonzero means inside a new-style backquote
174 with no surrounding parentheses.
175 Fread initializes this to zero, so we need not specbind it
176 or worry about what happens to it when there is an error. */
177static int new_backquote_flag;
078e7b4a
JB
178\f
179/* Handle unreading and rereading of characters.
180 Write READCHAR to read a character,
fe0e03f3
KH
181 UNREAD(c) to unread c to be read again.
182
183 These macros actually read/unread a byte code, multibyte characters
184 are not handled here. The caller should manage them if necessary.
185 */
078e7b4a
JB
186
187#define READCHAR readchar (readcharfun)
188#define UNREAD(c) unreadchar (readcharfun, c)
189
190static int
191readchar (readcharfun)
192 Lisp_Object readcharfun;
193{
194 Lisp_Object tem;
95384e1e 195 register int c;
078e7b4a 196
cfff016d 197 if (BUFFERP (readcharfun))
078e7b4a 198 {
bed23cb2 199 register struct buffer *inbuffer = XBUFFER (readcharfun);
078e7b4a 200
bed23cb2
RS
201 int pt_byte = BUF_PT_BYTE (inbuffer);
202 int orig_pt_byte = pt_byte;
6f7f43d5 203
00a9a935
RS
204 if (readchar_backlog > 0)
205 /* We get the address of the byte just passed,
206 which is the last byte of the character.
207 The other bytes in this character are consecutive with it,
208 because the gap can't be in the middle of a character. */
209 return *(BUF_BYTE_ADDRESS (inbuffer, BUF_PT_BYTE (inbuffer) - 1)
210 - --readchar_backlog);
211
bed23cb2
RS
212 if (pt_byte >= BUF_ZV_BYTE (inbuffer))
213 return -1;
078e7b4a 214
00a9a935
RS
215 readchar_backlog = -1;
216
bed23cb2
RS
217 if (! NILP (inbuffer->enable_multibyte_characters))
218 {
00a9a935 219 /* Fetch the character code from the buffer. */
bed23cb2
RS
220 unsigned char *p = BUF_BYTE_ADDRESS (inbuffer, pt_byte);
221 BUF_INC_POS (inbuffer, pt_byte);
222 c = STRING_CHAR (p, pt_byte - orig_pt_byte);
223 }
224 else
225 {
226 c = BUF_FETCH_BYTE (inbuffer, pt_byte);
227 pt_byte++;
6f7f43d5 228 }
bed23cb2 229 SET_BUF_PT_BOTH (inbuffer, BUF_PT (inbuffer) + 1, pt_byte);
6f7f43d5 230
bed23cb2 231 return c;
078e7b4a 232 }
cfff016d 233 if (MARKERP (readcharfun))
078e7b4a 234 {
bed23cb2 235 register struct buffer *inbuffer = XMARKER (readcharfun)->buffer;
078e7b4a 236
bed23cb2
RS
237 int bytepos = marker_byte_position (readcharfun);
238 int orig_bytepos = bytepos;
6f7f43d5 239
00a9a935
RS
240 if (readchar_backlog > 0)
241 /* We get the address of the byte just passed,
242 which is the last byte of the character.
243 The other bytes in this character are consecutive with it,
244 because the gap can't be in the middle of a character. */
245 return *(BUF_BYTE_ADDRESS (inbuffer, XMARKER (readcharfun)->bytepos - 1)
246 - --readchar_backlog);
247
bed23cb2
RS
248 if (bytepos >= BUF_ZV_BYTE (inbuffer))
249 return -1;
6f7f43d5 250
00a9a935
RS
251 readchar_backlog = -1;
252
bed23cb2
RS
253 if (! NILP (inbuffer->enable_multibyte_characters))
254 {
00a9a935 255 /* Fetch the character code from the buffer. */
bed23cb2
RS
256 unsigned char *p = BUF_BYTE_ADDRESS (inbuffer, bytepos);
257 BUF_INC_POS (inbuffer, bytepos);
258 c = STRING_CHAR (p, bytepos - orig_bytepos);
259 }
260 else
261 {
262 c = BUF_FETCH_BYTE (inbuffer, bytepos);
263 bytepos++;
6f7f43d5
RS
264 }
265
bed23cb2
RS
266 XMARKER (readcharfun)->bytepos = bytepos;
267 XMARKER (readcharfun)->charpos++;
268
269 return c;
078e7b4a 270 }
ad0153e4
RS
271
272 if (EQ (readcharfun, Qlambda))
273 return read_bytecode_char (0);
274
078e7b4a 275 if (EQ (readcharfun, Qget_file_char))
2c1b5dbe
KH
276 {
277 c = getc (instream);
278#ifdef EINTR
279 /* Interrupted reads have been observed while reading over the network */
280 while (c == EOF && ferror (instream) && errno == EINTR)
281 {
282 clearerr (instream);
283 c = getc (instream);
284 }
285#endif
286 return c;
287 }
078e7b4a 288
cfff016d 289 if (STRINGP (readcharfun))
078e7b4a 290 {
bed23cb2 291 if (read_from_string_index >= read_from_string_limit)
078e7b4a 292 c = -1;
f0354c03 293 else
bed23cb2
RS
294 FETCH_STRING_CHAR_ADVANCE (c, readcharfun,
295 read_from_string_index,
296 read_from_string_index_byte);
6f7f43d5 297
078e7b4a
JB
298 return c;
299 }
300
301 tem = call0 (readcharfun);
302
265a9e55 303 if (NILP (tem))
078e7b4a
JB
304 return -1;
305 return XINT (tem);
306}
307
308/* Unread the character C in the way appropriate for the stream READCHARFUN.
309 If the stream is a user function, call it with the char as argument. */
310
311static void
312unreadchar (readcharfun, c)
313 Lisp_Object readcharfun;
314 int c;
315{
92fddec9
KH
316 if (c == -1)
317 /* Don't back up the pointer if we're unreading the end-of-input mark,
318 since readchar didn't advance it when we read it. */
319 ;
cfff016d 320 else if (BUFFERP (readcharfun))
d7760ca9 321 {
bed23cb2
RS
322 struct buffer *b = XBUFFER (readcharfun);
323 int bytepos = BUF_PT_BYTE (b);
d7760ca9 324
00a9a935
RS
325 if (readchar_backlog >= 0)
326 readchar_backlog++;
bed23cb2 327 else
00a9a935
RS
328 {
329 BUF_PT (b)--;
330 if (! NILP (b->enable_multibyte_characters))
331 BUF_DEC_POS (b, bytepos);
332 else
333 bytepos--;
d7760ca9 334
00a9a935
RS
335 BUF_PT_BYTE (b) = bytepos;
336 }
d7760ca9 337 }
cfff016d 338 else if (MARKERP (readcharfun))
d7760ca9 339 {
bed23cb2
RS
340 struct buffer *b = XMARKER (readcharfun)->buffer;
341 int bytepos = XMARKER (readcharfun)->bytepos;
d7760ca9 342
00a9a935
RS
343 if (readchar_backlog >= 0)
344 readchar_backlog++;
bed23cb2 345 else
00a9a935
RS
346 {
347 XMARKER (readcharfun)->charpos--;
348 if (! NILP (b->enable_multibyte_characters))
349 BUF_DEC_POS (b, bytepos);
350 else
351 bytepos--;
d7760ca9 352
00a9a935
RS
353 XMARKER (readcharfun)->bytepos = bytepos;
354 }
d7760ca9 355 }
cfff016d 356 else if (STRINGP (readcharfun))
bed23cb2
RS
357 {
358 read_from_string_index--;
359 read_from_string_index_byte
360 = string_char_to_byte (readcharfun, read_from_string_index);
361 }
ad0153e4
RS
362 else if (EQ (readcharfun, Qlambda))
363 read_bytecode_char (1);
078e7b4a
JB
364 else if (EQ (readcharfun, Qget_file_char))
365 ungetc (c, instream);
366 else
367 call1 (readcharfun, make_number (c));
368}
369
370static Lisp_Object read0 (), read1 (), read_list (), read_vector ();
6f7f43d5 371static int read_multibyte ();
9e062b6c
RS
372static Lisp_Object substitute_object_recurse ();
373static void substitute_object_in_subtree (), substitute_in_interval ();
374
078e7b4a 375\f
bed23cb2 376/* Get a character from the tty. */
078e7b4a 377
3d9b22be
JB
378extern Lisp_Object read_char ();
379
f42be754
JB
380/* Read input events until we get one that's acceptable for our purposes.
381
382 If NO_SWITCH_FRAME is non-zero, switch-frame events are stashed
383 until we get a character we like, and then stuffed into
384 unread_switch_frame.
385
386 If ASCII_REQUIRED is non-zero, we check function key events to see
387 if the unmodified version of the symbol has a Qascii_character
388 property, and use that character, if present.
389
390 If ERROR_NONASCII is non-zero, we signal an error if the input we
391 get isn't an ASCII character with modifiers. If it's zero but
392 ASCII_REQUIRED is non-zero, we just re-read until we get an ASCII
bb49a192
RS
393 character.
394
395 If INPUT_METHOD is nonzero, we invoke the current input method
396 if the character warrants that. */
cc39bc38 397
f42be754 398Lisp_Object
bb49a192
RS
399read_filtered_event (no_switch_frame, ascii_required, error_nonascii,
400 input_method)
401 int no_switch_frame, ascii_required, error_nonascii, input_method;
f42be754 402{
153a17b7
KH
403 register Lisp_Object val, delayed_switch_frame;
404
5dbf89bc
GM
405#ifdef HAVE_WINDOW_SYSTEM
406 if (display_busy_cursor_p)
407 cancel_busy_cursor ();
408#endif
409
153a17b7 410 delayed_switch_frame = Qnil;
f42be754
JB
411
412 /* Read until we get an acceptable event. */
413 retry:
bb49a192
RS
414 val = read_char (0, 0, 0,
415 (input_method ? Qnil : Qt),
416 0);
f42be754 417
cfff016d 418 if (BUFFERP (val))
6c82d689
KH
419 goto retry;
420
f42be754 421 /* switch-frame events are put off until after the next ASCII
8e6208c5 422 character. This is better than signaling an error just because
f42be754
JB
423 the last characters were typed to a separate minibuffer frame,
424 for example. Eventually, some code which can deal with
425 switch-frame events will read it and process it. */
426 if (no_switch_frame
427 && EVENT_HAS_PARAMETERS (val)
428 && EQ (EVENT_HEAD (val), Qswitch_frame))
429 {
430 delayed_switch_frame = val;
431 goto retry;
432 }
433
434 if (ascii_required)
435 {
436 /* Convert certain symbols to their ASCII equivalents. */
cfff016d 437 if (SYMBOLP (val))
f42be754 438 {
95384e1e 439 Lisp_Object tem, tem1;
f42be754
JB
440 tem = Fget (val, Qevent_symbol_element_mask);
441 if (!NILP (tem))
442 {
443 tem1 = Fget (Fcar (tem), Qascii_character);
444 /* Merge this symbol's modifier bits
445 with the ASCII equivalent of its basic code. */
446 if (!NILP (tem1))
baf69866 447 XSETFASTINT (val, XINT (tem1) | XINT (Fcar (Fcdr (tem))));
f42be754
JB
448 }
449 }
450
451 /* If we don't have a character now, deal with it appropriately. */
cfff016d 452 if (!INTEGERP (val))
f42be754
JB
453 {
454 if (error_nonascii)
455 {
1ec84625 456 Vunread_command_events = Fcons (val, Qnil);
f42be754
JB
457 error ("Non-character input-event");
458 }
459 else
460 goto retry;
461 }
462 }
463
464 if (! NILP (delayed_switch_frame))
465 unread_switch_frame = delayed_switch_frame;
466
5dbf89bc
GM
467#ifdef HAVE_WINDOW_SYSTEM
468 if (display_busy_cursor_p)
469 start_busy_cursor ();
470#endif
f42be754 471 return val;
f42be754
JB
472}
473
bb49a192 474DEFUN ("read-char", Fread_char, Sread_char, 0, 2, 0,
078e7b4a 475 "Read a character from the command input (keyboard or macro).\n\
e51e47f7
JB
476It is returned as a number.\n\
477If the user generates an event which is not a character (i.e. a mouse\n\
e37c0805
JB
478click or function key event), `read-char' signals an error. As an\n\
479exception, switch-frame events are put off until non-ASCII events can\n\
480be read.\n\
481If you want to read non-character events, or ignore them, call\n\
bb49a192
RS
482`read-event' or `read-char-exclusive' instead.\n\
483\n\
484If the optional argument PROMPT is non-nil, display that as a prompt.\n\
fc351d2f
KH
485If the optional argument INHERIT-INPUT-METHOD is non-nil and some\n\
486input method is turned on in the current buffer, that input method\n\
487is used for reading a character.")
488 (prompt, inherit_input_method)
489 Lisp_Object prompt, inherit_input_method;
078e7b4a 490{
bb49a192
RS
491 if (! NILP (prompt))
492 message_with_string ("%s", prompt, 0);
fc351d2f 493 return read_filtered_event (1, 1, 1, ! NILP (inherit_input_method));
078e7b4a
JB
494}
495
bb49a192
RS
496DEFUN ("read-event", Fread_event, Sread_event, 0, 2, 0,
497 "Read an event object from the input stream.\n\
498If the optional argument PROMPT is non-nil, display that as a prompt.\n\
fc351d2f
KH
499If the optional argument INHERIT-INPUT-METHOD is non-nil and some\n\
500input method is turned on in the current buffer, that input method\n\
501is used for reading a character.")
502 (prompt, inherit_input_method)
503 Lisp_Object prompt, inherit_input_method;
078e7b4a 504{
bb49a192
RS
505 if (! NILP (prompt))
506 message_with_string ("%s", prompt, 0);
fc351d2f 507 return read_filtered_event (0, 0, 0, ! NILP (inherit_input_method));
078e7b4a
JB
508}
509
bb49a192 510DEFUN ("read-char-exclusive", Fread_char_exclusive, Sread_char_exclusive, 0, 2, 0,
078e7b4a 511 "Read a character from the command input (keyboard or macro).\n\
bb49a192
RS
512It is returned as a number. Non-character events are ignored.\n\
513\n\
514If the optional argument PROMPT is non-nil, display that as a prompt.\n\
fc351d2f
KH
515If the optional argument INHERIT-INPUT-METHOD is non-nil and some\n\
516input method is turned on in the current buffer, that input method\n\
517is used for reading a character.")
518 (prompt, inherit_input_method)
519 Lisp_Object prompt, inherit_input_method;
078e7b4a 520{
bb49a192
RS
521 if (! NILP (prompt))
522 message_with_string ("%s", prompt, 0);
fc351d2f 523 return read_filtered_event (1, 1, 0, ! NILP (inherit_input_method));
078e7b4a 524}
078e7b4a
JB
525
526DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
527 "Don't use this yourself.")
528 ()
529{
530 register Lisp_Object val;
1805de4f 531 XSETINT (val, getc (instream));
078e7b4a
JB
532 return val;
533}
534\f
232ccf27
DL
535static void readevalloop P_ ((Lisp_Object, FILE*, Lisp_Object,
536 Lisp_Object (*) (), int,
537 Lisp_Object, Lisp_Object));
538static Lisp_Object load_unwind P_ ((Lisp_Object));
539static Lisp_Object load_descriptor_unwind P_ ((Lisp_Object));
078e7b4a 540
da84f340
GM
541/* Non-zero means load dangerous compiled Lisp files. */
542
543int load_dangerous_libraries;
544
545/* A regular expression used to detect files compiled with Emacs. */
546
547static Lisp_Object Vbytecomp_version_regexp;
548
549
550/* Value is non-zero if the file asswociated with file descriptor FD
551 is a compiled Lisp file that's safe to load. Only files compiled
552 with Emacs are safe to load. Files compiled with XEmacs can lead
553 to a crash in Fbyte_code because of an incompatible change in the
554 byte compiler. */
555
556static int
557safe_to_load_p (fd)
558 int fd;
559{
560 char buf[512];
561 int nbytes, i;
562 int safe_p = 1;
563
564 /* Read the first few bytes from the file, and look for a line
565 specifying the byte compiler version used. */
566 nbytes = emacs_read (fd, buf, sizeof buf - 1);
567 if (nbytes > 0)
568 {
569 buf[nbytes] = '\0';
570
571 /* Skip to the next newline, skipping over the initial `ELC'
572 with NUL bytes following it. */
573 for (i = 0; i < nbytes && buf[i] != '\n'; ++i)
574 ;
575
576 if (i < nbytes
577 && fast_c_string_match_ignore_case (Vbytecomp_version_regexp,
578 buf + i) < 0)
579 safe_p = 0;
580 }
581
582 lseek (fd, 0, SEEK_SET);
583 return safe_p;
584}
585
586
f0a50954 587DEFUN ("load", Fload, Sload, 1, 5, 0,
078e7b4a
JB
588 "Execute a file of Lisp code named FILE.\n\
589First try FILE with `.elc' appended, then try with `.el',\n\
590 then try FILE unmodified.\n\
591This function searches the directories in `load-path'.\n\
592If optional second arg NOERROR is non-nil,\n\
593 report no error if FILE doesn't exist.\n\
594Print messages at start and end of loading unless\n\
595 optional third arg NOMESSAGE is non-nil.\n\
596If optional fourth arg NOSUFFIX is non-nil, don't try adding\n\
597 suffixes `.elc' or `.el' to the specified name FILE.\n\
211f7dcd 598If optional fifth arg MUST-SUFFIX is non-nil, insist on\n\
7b88a4cf 599 the suffix `.elc' or `.el'; don't accept just FILE unless\n\
211f7dcd 600 it ends in one of those suffixes or includes a directory name.\n\
078e7b4a 601Return t if file exists.")
f0a50954
RS
602 (file, noerror, nomessage, nosuffix, must_suffix)
603 Lisp_Object file, noerror, nomessage, nosuffix, must_suffix;
078e7b4a
JB
604{
605 register FILE *stream;
606 register int fd = -1;
607 register Lisp_Object lispstream;
078e7b4a
JB
608 int count = specpdl_ptr - specpdl;
609 Lisp_Object temp;
610 struct gcpro gcpro1;
611 Lisp_Object found;
04fc68e7
RS
612 /* 1 means we printed the ".el is newer" message. */
613 int newer = 0;
614 /* 1 means we are loading a compiled file. */
615 int compiled = 0;
c2225d00 616 Lisp_Object handler;
456c67a4 617 int safe_p = 1;
229ba775 618 char *fmode = "r";
317073d5 619#ifdef DOS_NT
229ba775 620 fmode = "rt";
317073d5 621#endif /* DOS_NT */
078e7b4a 622
0745dce9 623 CHECK_STRING (file, 0);
078e7b4a 624
c2225d00 625 /* If file name is magic, call the handler. */
0745dce9 626 handler = Ffind_file_name_handler (file, Qload);
c2225d00 627 if (!NILP (handler))
0745dce9 628 return call5 (handler, Qload, file, noerror, nomessage, nosuffix);
c2225d00 629
07a0bda3
RS
630 /* Do this after the handler to avoid
631 the need to gcpro noerror, nomessage and nosuffix.
632 (Below here, we care only whether they are nil or not.) */
0745dce9 633 file = Fsubstitute_in_file_name (file);
07a0bda3 634
078e7b4a
JB
635 /* Avoid weird lossage with null string as arg,
636 since it would try to load a directory as a Lisp file */
0745dce9 637 if (XSTRING (file)->size > 0)
078e7b4a 638 {
471aa4a0 639 int size = STRING_BYTES (XSTRING (file));
211f7dcd 640
0745dce9 641 GCPRO1 (file);
211f7dcd
RS
642
643 if (! NILP (must_suffix))
644 {
645 /* Don't insist on adding a suffix if FILE already ends with one. */
646 if (size > 3
647 && !strcmp (XSTRING (file)->data + size - 3, ".el"))
648 must_suffix = Qnil;
649 else if (size > 4
650 && !strcmp (XSTRING (file)->data + size - 4, ".elc"))
651 must_suffix = Qnil;
652 /* Don't insist on adding a suffix
653 if the argument includes a directory name. */
654 else if (! NILP (Ffile_name_directory (file)))
655 must_suffix = Qnil;
656 }
657
f0a50954
RS
658 fd = openp (Vload_path, file,
659 (!NILP (nosuffix) ? ""
9b7c9ebd
DL
660 : ! NILP (must_suffix) ? ".elc.gz:.elc:.el.gz:.el"
661 : ".elc:.elc.gz:.el.gz:.el:"),
078e7b4a 662 &found, 0);
5a6e5452 663 UNGCPRO;
078e7b4a
JB
664 }
665
666 if (fd < 0)
667 {
265a9e55 668 if (NILP (noerror))
078e7b4a
JB
669 while (1)
670 Fsignal (Qfile_error, Fcons (build_string ("Cannot open load file"),
0745dce9 671 Fcons (file, Qnil)));
078e7b4a
JB
672 else
673 return Qnil;
674 }
675
ba0d1195 676 /* Tell startup.el whether or not we found the user's init file. */
4116ab9f
KH
677 if (EQ (Qt, Vuser_init_file))
678 Vuser_init_file = found;
679
5e24a1f7 680 /* If FD is 0, that means openp found a magic file. */
74549846
RS
681 if (fd == 0)
682 {
5e24a1f7
KH
683 if (NILP (Fequal (found, file)))
684 /* If FOUND is a different file name from FILE,
685 find its handler even if we have already inhibited
686 the `load' operation on FILE. */
687 handler = Ffind_file_name_handler (found, Qt);
688 else
689 handler = Ffind_file_name_handler (found, Qload);
690 if (! NILP (handler))
691 return call5 (handler, Qload, found, noerror, nomessage, Qt);
74549846
RS
692 }
693
5e24a1f7
KH
694 /* Load .elc files directly, but not when they are
695 remote and have no handler! */
471aa4a0 696 if (!bcmp (&(XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 4]),
5e24a1f7
KH
697 ".elc", 4)
698 && fd != 0)
078e7b4a
JB
699 {
700 struct stat s1, s2;
701 int result;
702
da84f340
GM
703 if (!safe_to_load_p (fd))
704 {
705 safe_p = 0;
706 if (!load_dangerous_libraries)
707 error ("File `%s' was not compiled in Emacs",
708 XSTRING (found)->data);
709 else if (!NILP (nomessage))
710 message_with_string ("File `%s' not compiled in Emacs", found, 1);
711 }
712
04fc68e7
RS
713 compiled = 1;
714
317073d5 715#ifdef DOS_NT
229ba775 716 fmode = "rb";
317073d5 717#endif /* DOS_NT */
4ff37b08 718 stat ((char *)XSTRING (found)->data, &s1);
471aa4a0 719 XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 1] = 0;
4ff37b08 720 result = stat ((char *)XSTRING (found)->data, &s2);
078e7b4a 721 if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime)
51ac6f83 722 {
04fc68e7
RS
723 /* Make the progress messages mention that source is newer. */
724 newer = 1;
725
726 /* If we won't print another message, mention this anyway. */
727 if (! NILP (nomessage))
e28552a4
RS
728 message_with_string ("Source file `%s' newer than byte-compiled file",
729 found, 1);
51ac6f83 730 }
471aa4a0 731 XSTRING (found)->data[STRING_BYTES (XSTRING (found)) - 1] = 'c';
078e7b4a 732 }
fe0e03f3
KH
733 else
734 {
da84f340
GM
735 load_source:
736
fe0e03f3
KH
737 /* We are loading a source file (*.el). */
738 if (!NILP (Vload_source_file_function))
739 {
5e24a1f7 740 if (fd != 0)
68c45bf0 741 emacs_close (fd);
7075e5a5 742 return call4 (Vload_source_file_function, found, file,
fe0e03f3
KH
743 NILP (noerror) ? Qnil : Qt,
744 NILP (nomessage) ? Qnil : Qt);
745 }
746 }
078e7b4a 747
229ba775 748#ifdef WINDOWSNT
68c45bf0 749 emacs_close (fd);
229ba775
EZ
750 stream = fopen ((char *) XSTRING (found)->data, fmode);
751#else /* not WINDOWSNT */
752 stream = fdopen (fd, fmode);
753#endif /* not WINDOWSNT */
078e7b4a
JB
754 if (stream == 0)
755 {
68c45bf0 756 emacs_close (fd);
0745dce9 757 error ("Failure to create stdio stream for %s", XSTRING (file)->data);
078e7b4a
JB
758 }
759
4b104c41
RS
760 if (! NILP (Vpurify_flag))
761 Vpreloaded_file_list = Fcons (file, Vpreloaded_file_list);
762
04fc68e7
RS
763 if (NILP (nomessage))
764 {
da84f340
GM
765 if (!safe_p)
766 message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...",
767 file, 1);
768 else if (!compiled)
e28552a4 769 message_with_string ("Loading %s (source)...", file, 1);
db5cae4b 770 else if (newer)
e28552a4
RS
771 message_with_string ("Loading %s (compiled; note, source file is newer)...",
772 file, 1);
db5cae4b 773 else /* The typical case; compiled file newer than source file. */
e28552a4 774 message_with_string ("Loading %s...", file, 1);
04fc68e7 775 }
078e7b4a 776
0745dce9 777 GCPRO1 (file);
838abf56 778 lispstream = Fcons (Qnil, Qnil);
c1d497be
KR
779 XSETFASTINT (XCAR (lispstream), (EMACS_UINT)stream >> 16);
780 XSETFASTINT (XCDR (lispstream), (EMACS_UINT)stream & 0xffff);
078e7b4a 781 record_unwind_protect (load_unwind, lispstream);
d2c6be7f 782 record_unwind_protect (load_descriptor_unwind, load_descriptor_list);
20ea2964 783 specbind (Qload_file_name, found);
74549846 784 specbind (Qinhibit_file_name_operation, Qnil);
d2c6be7f
RS
785 load_descriptor_list
786 = Fcons (make_number (fileno (stream)), load_descriptor_list);
078e7b4a 787 load_in_progress++;
976350af 788 readevalloop (Qget_file_char, stream, file, Feval, 0, Qnil, Qnil);
078e7b4a
JB
789 unbind_to (count, Qnil);
790
791 /* Run any load-hooks for this file. */
0745dce9 792 temp = Fassoc (file, Vafter_load_alist);
265a9e55 793 if (!NILP (temp))
078e7b4a
JB
794 Fprogn (Fcdr (temp));
795 UNGCPRO;
796
b2a30870
RS
797 if (saved_doc_string)
798 free (saved_doc_string);
799 saved_doc_string = 0;
800 saved_doc_string_size = 0;
801
c15cfd1f 802 if (prev_saved_doc_string)
3cb65b0e 803 xfree (prev_saved_doc_string);
c15cfd1f
RS
804 prev_saved_doc_string = 0;
805 prev_saved_doc_string_size = 0;
806
265a9e55 807 if (!noninteractive && NILP (nomessage))
04fc68e7 808 {
da84f340
GM
809 if (!safe_p)
810 message_with_string ("Loading %s (compiled; note unsafe, not compiled in Emacs)...done",
811 file, 1);
812 else if (!compiled)
e28552a4 813 message_with_string ("Loading %s (source)...done", file, 1);
db5cae4b 814 else if (newer)
e28552a4
RS
815 message_with_string ("Loading %s (compiled; note, source file is newer)...done",
816 file, 1);
db5cae4b 817 else /* The typical case; compiled file newer than source file. */
e28552a4 818 message_with_string ("Loading %s...done", file, 1);
04fc68e7 819 }
078e7b4a
JB
820 return Qt;
821}
822
823static Lisp_Object
824load_unwind (stream) /* used as unwind-protect function in load */
825 Lisp_Object stream;
826{
c1d497be
KR
827 fclose ((FILE *) (XFASTINT (XCAR (stream)) << 16
828 | XFASTINT (XCDR (stream))));
078e7b4a
JB
829 if (--load_in_progress < 0) load_in_progress = 0;
830 return Qnil;
831}
832
d2c6be7f
RS
833static Lisp_Object
834load_descriptor_unwind (oldlist)
835 Lisp_Object oldlist;
836{
837 load_descriptor_list = oldlist;
838abf56 838 return Qnil;
d2c6be7f
RS
839}
840
841/* Close all descriptors in use for Floads.
842 This is used when starting a subprocess. */
843
844void
845close_load_descs ()
846{
f3849f25 847#ifndef WINDOWSNT
d2c6be7f 848 Lisp_Object tail;
c1d497be 849 for (tail = load_descriptor_list; !NILP (tail); tail = XCDR (tail))
68c45bf0 850 emacs_close (XFASTINT (XCAR (tail)));
f3849f25 851#endif
d2c6be7f 852}
078e7b4a
JB
853\f
854static int
855complete_filename_p (pathname)
856 Lisp_Object pathname;
857{
858 register unsigned char *s = XSTRING (pathname)->data;
317073d5
RS
859 return (IS_DIRECTORY_SEP (s[0])
860 || (XSTRING (pathname)->size > 2
861 && IS_DEVICE_SEP (s[1]) && IS_DIRECTORY_SEP (s[2]))
078e7b4a
JB
862#ifdef ALTOS
863 || *s == '@'
864#endif
865#ifdef VMS
866 || index (s, ':')
867#endif /* VMS */
868 );
869}
870
871/* Search for a file whose name is STR, looking in directories
872 in the Lisp list PATH, and trying suffixes from SUFFIX.
873 SUFFIX is a string containing possible suffixes separated by colons.
874 On success, returns a file descriptor. On failure, returns -1.
875
876 EXEC_ONLY nonzero means don't open the files,
877 just look for one that is executable. In this case,
878 returns 1 on success.
879
880 If STOREPTR is nonzero, it points to a slot where the name of
881 the file actually found should be stored as a Lisp string.
74549846
RS
882 nil is stored there on failure.
883
884 If the file we find is remote, return 0
885 but store the found remote file name in *STOREPTR.
886 We do not check for remote files if EXEC_ONLY is nonzero. */
078e7b4a
JB
887
888int
889openp (path, str, suffix, storeptr, exec_only)
890 Lisp_Object path, str;
891 char *suffix;
892 Lisp_Object *storeptr;
893 int exec_only;
894{
895 register int fd;
896 int fn_size = 100;
897 char buf[100];
898 register char *fn = buf;
899 int absolute = 0;
900 int want_size;
74549846 901 Lisp_Object filename;
078e7b4a 902 struct stat st;
5a6e5452 903 struct gcpro gcpro1;
078e7b4a 904
5a6e5452 905 GCPRO1 (str);
078e7b4a
JB
906 if (storeptr)
907 *storeptr = Qnil;
908
909 if (complete_filename_p (str))
910 absolute = 1;
911
265a9e55 912 for (; !NILP (path); path = Fcdr (path))
078e7b4a
JB
913 {
914 char *nsuffix;
915
916 filename = Fexpand_file_name (str, Fcar (path));
917 if (!complete_filename_p (filename))
918 /* If there are non-absolute elts in PATH (eg ".") */
919 /* Of course, this could conceivably lose if luser sets
920 default-directory to be something non-absolute... */
921 {
922 filename = Fexpand_file_name (filename, current_buffer->directory);
923 if (!complete_filename_p (filename))
924 /* Give up on this path element! */
925 continue;
926 }
927
928 /* Calculate maximum size of any filename made from
929 this path element/specified file name and any possible suffix. */
471aa4a0 930 want_size = strlen (suffix) + STRING_BYTES (XSTRING (filename)) + 1;
078e7b4a
JB
931 if (fn_size < want_size)
932 fn = (char *) alloca (fn_size = 100 + want_size);
933
934 nsuffix = suffix;
935
936 /* Loop over suffixes. */
937 while (1)
938 {
939 char *esuffix = (char *) index (nsuffix, ':');
940 int lsuffix = esuffix ? esuffix - nsuffix : strlen (nsuffix);
74549846 941 Lisp_Object handler;
078e7b4a 942
c49afcd7
RS
943 /* Concatenate path element/specified name with the suffix.
944 If the directory starts with /:, remove that. */
945 if (XSTRING (filename)->size > 2
946 && XSTRING (filename)->data[0] == '/'
947 && XSTRING (filename)->data[1] == ':')
948 {
949 strncpy (fn, XSTRING (filename)->data + 2,
471aa4a0
KH
950 STRING_BYTES (XSTRING (filename)) - 2);
951 fn[STRING_BYTES (XSTRING (filename)) - 2] = 0;
c49afcd7
RS
952 }
953 else
954 {
471aa4a0
KH
955 strncpy (fn, XSTRING (filename)->data,
956 STRING_BYTES (XSTRING (filename)));
957 fn[STRING_BYTES (XSTRING (filename))] = 0;
c49afcd7
RS
958 }
959
078e7b4a
JB
960 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */
961 strncat (fn, nsuffix, lsuffix);
962
74549846
RS
963 /* Check that the file exists and is not a directory. */
964 if (absolute)
965 handler = Qnil;
966 else
967 handler = Ffind_file_name_handler (filename, Qfile_exists_p);
968 if (! NILP (handler) && ! exec_only)
078e7b4a 969 {
74549846
RS
970 Lisp_Object string;
971 int exists;
078e7b4a 972
74549846
RS
973 string = build_string (fn);
974 exists = ! NILP (exec_only ? Ffile_executable_p (string)
975 : Ffile_readable_p (string));
976 if (exists
977 && ! NILP (Ffile_directory_p (build_string (fn))))
978 exists = 0;
979
980 if (exists)
078e7b4a
JB
981 {
982 /* We succeeded; return this descriptor and filename. */
983 if (storeptr)
984 *storeptr = build_string (fn);
5ef2a3c0 985 UNGCPRO;
74549846
RS
986 return 0;
987 }
988 }
989 else
990 {
991 int exists = (stat (fn, &st) >= 0
992 && (st.st_mode & S_IFMT) != S_IFDIR);
993 if (exists)
994 {
995 /* Check that we can access or open it. */
996 if (exec_only)
997 fd = (access (fn, X_OK) == 0) ? 1 : -1;
998 else
68c45bf0 999 fd = emacs_open (fn, O_RDONLY, 0);
74549846
RS
1000
1001 if (fd >= 0)
1002 {
1003 /* We succeeded; return this descriptor and filename. */
1004 if (storeptr)
1005 *storeptr = build_string (fn);
1006 UNGCPRO;
1007 return fd;
1008 }
078e7b4a
JB
1009 }
1010 }
1011
1012 /* Advance to next suffix. */
1013 if (esuffix == 0)
1014 break;
1015 nsuffix += lsuffix + 1;
1016 }
5a6e5452 1017 if (absolute)
5ef2a3c0 1018 break;
078e7b4a
JB
1019 }
1020
5ef2a3c0
KH
1021 UNGCPRO;
1022 return -1;
078e7b4a
JB
1023}
1024
1025\f
ae321d28
RS
1026/* Merge the list we've accumulated of globals from the current input source
1027 into the load_history variable. The details depend on whether
1028 the source has an associated file name or not. */
1029
1030static void
1031build_load_history (stream, source)
1032 FILE *stream;
1033 Lisp_Object source;
1034{
1035 register Lisp_Object tail, prev, newelt;
1036 register Lisp_Object tem, tem2;
1037 register int foundit, loading;
1038
1039 loading = stream || !NARROWED;
1040
1041 tail = Vload_history;
1042 prev = Qnil;
1043 foundit = 0;
1044 while (!NILP (tail))
1045 {
1046 tem = Fcar (tail);
1047
1048 /* Find the feature's previous assoc list... */
1049 if (!NILP (Fequal (source, Fcar (tem))))
1050 {
1051 foundit = 1;
1052
1053 /* If we're loading, remove it. */
1054 if (loading)
1055 {
1056 if (NILP (prev))
1057 Vload_history = Fcdr (tail);
1058 else
1059 Fsetcdr (prev, Fcdr (tail));
1060 }
1061
1062 /* Otherwise, cons on new symbols that are not already members. */
1063 else
1064 {
1065 tem2 = Vcurrent_load_list;
1066
1067 while (CONSP (tem2))
1068 {
1069 newelt = Fcar (tem2);
1070
1071 if (NILP (Fmemq (newelt, tem)))
1072 Fsetcar (tail, Fcons (Fcar (tem),
1073 Fcons (newelt, Fcdr (tem))));
1074
1075 tem2 = Fcdr (tem2);
1076 QUIT;
1077 }
1078 }
1079 }
1080 else
1081 prev = tail;
1082 tail = Fcdr (tail);
1083 QUIT;
1084 }
1085
8a1f1537
RS
1086 /* If we're loading, cons the new assoc onto the front of load-history,
1087 the most-recently-loaded position. Also do this if we didn't find
1088 an existing member for the current source. */
1089 if (loading || !foundit)
1090 Vload_history = Fcons (Fnreverse (Vcurrent_load_list),
1091 Vload_history);
ae321d28
RS
1092}
1093
078e7b4a 1094Lisp_Object
232ccf27
DL
1095unreadpure (junk) /* Used as unwind-protect function in readevalloop */
1096 Lisp_Object junk;
078e7b4a
JB
1097{
1098 read_pure = 0;
1099 return Qnil;
1100}
1101
94e554db
RS
1102static Lisp_Object
1103readevalloop_1 (old)
1104 Lisp_Object old;
1105{
1106 load_convert_to_unibyte = ! NILP (old);
1107 return Qnil;
1108}
1109
9c97398c
GM
1110/* Signal an `end-of-file' error, if possible with file name
1111 information. */
1112
1113static void
1114end_of_file_error ()
1115{
1116 Lisp_Object data;
1117
1118 if (STRINGP (Vload_file_name))
1119 data = Fcons (Vload_file_name, Qnil);
1120 else
1121 data = Qnil;
1122
1123 Fsignal (Qend_of_file, data);
1124}
1125
94e554db 1126/* UNIBYTE specifies how to set load_convert_to_unibyte
976350af
RS
1127 for this invocation.
1128 READFUN, if non-nil, is used instead of `read'. */
94e554db 1129
078e7b4a 1130static void
976350af 1131readevalloop (readcharfun, stream, sourcename, evalfun, printflag, unibyte, readfun)
078e7b4a 1132 Lisp_Object readcharfun;
ae321d28
RS
1133 FILE *stream;
1134 Lisp_Object sourcename;
078e7b4a
JB
1135 Lisp_Object (*evalfun) ();
1136 int printflag;
976350af 1137 Lisp_Object unibyte, readfun;
078e7b4a
JB
1138{
1139 register int c;
1140 register Lisp_Object val;
1141 int count = specpdl_ptr - specpdl;
8a1f1537 1142 struct gcpro gcpro1;
49cf7ff4 1143 struct buffer *b = 0;
f38952fe 1144 int continue_reading_p;
49cf7ff4
RS
1145
1146 if (BUFFERP (readcharfun))
1147 b = XBUFFER (readcharfun);
1148 else if (MARKERP (readcharfun))
1149 b = XMARKER (readcharfun)->buffer;
078e7b4a
JB
1150
1151 specbind (Qstandard_input, readcharfun);
8a1f1537 1152 specbind (Qcurrent_load_list, Qnil);
94e554db
RS
1153 record_unwind_protect (readevalloop_1, load_convert_to_unibyte ? Qt : Qnil);
1154 load_convert_to_unibyte = !NILP (unibyte);
078e7b4a 1155
00a9a935 1156 readchar_backlog = -1;
6f7f43d5 1157
8a1f1537 1158 GCPRO1 (sourcename);
ae321d28 1159
ae321d28
RS
1160 LOADHIST_ATTACH (sourcename);
1161
f38952fe
GM
1162 continue_reading_p = 1;
1163 while (continue_reading_p)
078e7b4a 1164 {
49cf7ff4
RS
1165 if (b != 0 && NILP (b->name))
1166 error ("Reading from killed buffer");
1167
078e7b4a
JB
1168 instream = stream;
1169 c = READCHAR;
1170 if (c == ';')
1171 {
1172 while ((c = READCHAR) != '\n' && c != -1);
1173 continue;
1174 }
1175 if (c < 0) break;
6069d957
RS
1176
1177 /* Ignore whitespace here, so we can detect eof. */
1178 if (c == ' ' || c == '\t' || c == '\n' || c == '\f' || c == '\r')
1179 continue;
078e7b4a 1180
265a9e55 1181 if (!NILP (Vpurify_flag) && c == '(')
078e7b4a 1182 {
0e326373 1183 int count1 = specpdl_ptr - specpdl;
078e7b4a
JB
1184 record_unwind_protect (unreadpure, Qnil);
1185 val = read_list (-1, readcharfun);
0e326373 1186 unbind_to (count1, Qnil);
078e7b4a
JB
1187 }
1188 else
1189 {
1190 UNREAD (c);
4ad679f9 1191 read_objects = Qnil;
f38952fe
GM
1192 if (!NILP (readfun))
1193 {
1194 val = call1 (readfun, readcharfun);
1195
1196 /* If READCHARFUN has set point to ZV, we should
1197 stop reading, even if the form read sets point
1198 to a different value when evaluated. */
1199 if (BUFFERP (readcharfun))
1200 {
1201 struct buffer *b = XBUFFER (readcharfun);
1202 if (BUF_PT (b) == BUF_ZV (b))
1203 continue_reading_p = 0;
1204 }
1205 }
976350af 1206 else if (! NILP (Vload_read_function))
84a15045 1207 val = call1 (Vload_read_function, readcharfun);
976350af
RS
1208 else
1209 val = read0 (readcharfun);
078e7b4a
JB
1210 }
1211
1212 val = (*evalfun) (val);
f38952fe 1213
078e7b4a
JB
1214 if (printflag)
1215 {
1216 Vvalues = Fcons (val, Vvalues);
1217 if (EQ (Vstandard_output, Qt))
1218 Fprin1 (val, Qnil);
1219 else
1220 Fprint (val, Qnil);
1221 }
1222 }
1223
ae321d28 1224 build_load_history (stream, sourcename);
ae321d28
RS
1225 UNGCPRO;
1226
078e7b4a
JB
1227 unbind_to (count, Qnil);
1228}
1229
1076254d 1230DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 5, "",
94b304d7
RS
1231 "Execute the current buffer as Lisp code.\n\
1232Programs can pass two arguments, BUFFER and PRINTFLAG.\n\
1233BUFFER is the buffer to evaluate (nil means use current buffer).\n\
1234PRINTFLAG controls printing of output:\n\
228d4b1c
JA
1235nil means discard it; anything else is stream for print.\n\
1236\n\
13febd85
RS
1237If the optional third argument FILENAME is non-nil,\n\
1238it specifies the file name to use for `load-history'.\n\
1076254d
RS
1239The optional fourth argument UNIBYTE specifies `load-convert-to-unibyte'\n\
1240for this invocation.\n\
1241\n\
1242The optional fifth argument DO-ALLOW-PRINT, if not-nil, specifies that\n\
1243`print' and related functions should work normally even if PRINTFLAG is nil.\n\
13febd85 1244\n\
d331bcad 1245This function preserves the position of point.")
1076254d
RS
1246 (buffer, printflag, filename, unibyte, do_allow_print)
1247 Lisp_Object buffer, printflag, filename, unibyte, do_allow_print;
228d4b1c
JA
1248{
1249 int count = specpdl_ptr - specpdl;
1250 Lisp_Object tem, buf;
1251
9391b698 1252 if (NILP (buffer))
228d4b1c
JA
1253 buf = Fcurrent_buffer ();
1254 else
9391b698 1255 buf = Fget_buffer (buffer);
dfdb645c 1256 if (NILP (buf))
13febd85 1257 error ("No such buffer");
228d4b1c 1258
1076254d 1259 if (NILP (printflag) && NILP (do_allow_print))
228d4b1c
JA
1260 tem = Qsymbolp;
1261 else
1262 tem = printflag;
13febd85
RS
1263
1264 if (NILP (filename))
1265 filename = XBUFFER (buf)->filename;
1266
228d4b1c
JA
1267 specbind (Qstandard_output, tem);
1268 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1269 BUF_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf)));
976350af 1270 readevalloop (buf, 0, filename, Feval, !NILP (printflag), unibyte, Qnil);
cb09ab7a 1271 unbind_to (count, Qnil);
228d4b1c
JA
1272
1273 return Qnil;
1274}
1275
1276#if 0
c23edb78 1277XDEFUN ("eval-current-buffer", Feval_current_buffer, Seval_current_buffer, 0, 1, "",
078e7b4a
JB
1278 "Execute the current buffer as Lisp code.\n\
1279Programs can pass argument PRINTFLAG which controls printing of output:\n\
1280nil means discard it; anything else is stream for print.\n\
1281\n\
1282If there is no error, point does not move. If there is an error,\n\
1283point remains at the end of the last character read from the buffer.")
1284 (printflag)
1285 Lisp_Object printflag;
1286{
1287 int count = specpdl_ptr - specpdl;
ae321d28
RS
1288 Lisp_Object tem, cbuf;
1289
1290 cbuf = Fcurrent_buffer ()
078e7b4a 1291
265a9e55 1292 if (NILP (printflag))
078e7b4a
JB
1293 tem = Qsymbolp;
1294 else
1295 tem = printflag;
1296 specbind (Qstandard_output, tem);
1297 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1298 SET_PT (BEGV);
94e554db 1299 readevalloop (cbuf, 0, XBUFFER (cbuf)->filename, Feval,
976350af 1300 !NILP (printflag), Qnil, Qnil);
078e7b4a
JB
1301 return unbind_to (count, Qnil);
1302}
228d4b1c 1303#endif
078e7b4a 1304
976350af 1305DEFUN ("eval-region", Feval_region, Seval_region, 2, 4, "r",
078e7b4a
JB
1306 "Execute the region as Lisp code.\n\
1307When called from programs, expects two arguments,\n\
1308giving starting and ending indices in the current buffer\n\
1309of the text to be executed.\n\
1310Programs can pass third argument PRINTFLAG which controls output:\n\
1311nil means discard it; anything else is stream for printing it.\n\
976350af
RS
1312Also the fourth argument READ-FUNCTION, if non-nil, is used\n\
1313instead of `read' to read each expression. It gets one argument\n\
1314which is the input stream for reading characters.\n\
078e7b4a 1315\n\
83f0c0c7 1316This function does not move point.")
976350af
RS
1317 (start, end, printflag, read_function)
1318 Lisp_Object start, end, printflag, read_function;
078e7b4a
JB
1319{
1320 int count = specpdl_ptr - specpdl;
ae321d28
RS
1321 Lisp_Object tem, cbuf;
1322
1323 cbuf = Fcurrent_buffer ();
078e7b4a 1324
265a9e55 1325 if (NILP (printflag))
078e7b4a
JB
1326 tem = Qsymbolp;
1327 else
1328 tem = printflag;
1329 specbind (Qstandard_output, tem);
1330
265a9e55 1331 if (NILP (printflag))
078e7b4a
JB
1332 record_unwind_protect (save_excursion_restore, save_excursion_save ());
1333 record_unwind_protect (save_restriction_restore, save_restriction_save ());
1334
9391b698
EN
1335 /* This both uses start and checks its type. */
1336 Fgoto_char (start);
1337 Fnarrow_to_region (make_number (BEGV), end);
94e554db 1338 readevalloop (cbuf, 0, XBUFFER (cbuf)->filename, Feval,
976350af 1339 !NILP (printflag), Qnil, read_function);
078e7b4a
JB
1340
1341 return unbind_to (count, Qnil);
1342}
1343
078e7b4a
JB
1344\f
1345DEFUN ("read", Fread, Sread, 0, 1, 0,
1346 "Read one Lisp expression as text from STREAM, return as Lisp object.\n\
1347If STREAM is nil, use the value of `standard-input' (which see).\n\
1348STREAM or the value of `standard-input' may be:\n\
1349 a buffer (read from point and advance it)\n\
1350 a marker (read from where it points and advance it)\n\
1351 a function (call it with no arguments for each character,\n\
1352 call it with a char as argument to push a char back)\n\
1353 a string (takes text from string, starting at the beginning)\n\
dcd46557
DL
1354 t (read text line using minibuffer and use it, or read from\n\
1355 standard input in batch mode).")
5be02dff
KH
1356 (stream)
1357 Lisp_Object stream;
078e7b4a
JB
1358{
1359 extern Lisp_Object Fread_minibuffer ();
1360
5be02dff
KH
1361 if (NILP (stream))
1362 stream = Vstandard_input;
1363 if (EQ (stream, Qt))
1364 stream = Qread_char;
078e7b4a 1365
00a9a935 1366 readchar_backlog = -1;
17634846 1367 new_backquote_flag = 0;
4ad679f9 1368 read_objects = Qnil;
17634846 1369
5be02dff 1370 if (EQ (stream, Qread_char))
078e7b4a 1371 return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
078e7b4a 1372
5be02dff
KH
1373 if (STRINGP (stream))
1374 return Fcar (Fread_from_string (stream, Qnil, Qnil));
078e7b4a 1375
5be02dff 1376 return read0 (stream);
078e7b4a
JB
1377}
1378
1379DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
1380 "Read one Lisp expression which is represented as text by STRING.\n\
1381Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).\n\
1382START and END optionally delimit a substring of STRING from which to read;\n\
1383 they default to 0 and (length STRING) respectively.")
1384 (string, start, end)
1385 Lisp_Object string, start, end;
1386{
1387 int startval, endval;
1388 Lisp_Object tem;
1389
1390 CHECK_STRING (string,0);
1391
265a9e55 1392 if (NILP (end))
bed23cb2 1393 endval = XSTRING (string)->size;
078e7b4a 1394 else
e28552a4
RS
1395 {
1396 CHECK_NUMBER (end, 2);
8028e0ed 1397 endval = XINT (end);
bed23cb2 1398 if (endval < 0 || endval > XSTRING (string)->size)
078e7b4a
JB
1399 args_out_of_range (string, end);
1400 }
1401
265a9e55 1402 if (NILP (start))
078e7b4a
JB
1403 startval = 0;
1404 else
e28552a4
RS
1405 {
1406 CHECK_NUMBER (start, 1);
8028e0ed 1407 startval = XINT (start);
078e7b4a
JB
1408 if (startval < 0 || startval > endval)
1409 args_out_of_range (string, start);
1410 }
1411
1412 read_from_string_index = startval;
bed23cb2 1413 read_from_string_index_byte = string_char_to_byte (string, startval);
078e7b4a
JB
1414 read_from_string_limit = endval;
1415
17634846 1416 new_backquote_flag = 0;
4ad679f9 1417 read_objects = Qnil;
17634846 1418
078e7b4a 1419 tem = read0 (string);
bed23cb2 1420 return Fcons (tem, make_number (read_from_string_index));
078e7b4a
JB
1421}
1422\f
6428369f
KH
1423/* Use this for recursive reads, in contexts where internal tokens
1424 are not allowed. */
e28552a4 1425
078e7b4a
JB
1426static Lisp_Object
1427read0 (readcharfun)
1428 Lisp_Object readcharfun;
1429{
1430 register Lisp_Object val;
e28552a4 1431 int c;
078e7b4a 1432
17634846 1433 val = read1 (readcharfun, &c, 0);
6428369f 1434 if (c)
93d75e4c
RS
1435 Fsignal (Qinvalid_read_syntax, Fcons (Fmake_string (make_number (1),
1436 make_number (c)),
e28552a4 1437 Qnil));
078e7b4a
JB
1438
1439 return val;
1440}
1441\f
1442static int read_buffer_size;
1443static char *read_buffer;
1444
fe0e03f3
KH
1445/* Read multibyte form and return it as a character. C is a first
1446 byte of multibyte form, and rest of them are read from
1447 READCHARFUN. */
6f7f43d5 1448
fe0e03f3
KH
1449static int
1450read_multibyte (c, readcharfun)
1451 register int c;
1452 Lisp_Object readcharfun;
1453{
1454 /* We need the actual character code of this multibyte
1455 characters. */
449fea39 1456 unsigned char str[MAX_MULTIBYTE_LENGTH];
fe0e03f3
KH
1457 int len = 0;
1458
1459 str[len++] = c;
1460 while ((c = READCHAR) >= 0xA0
449fea39 1461 && len < MAX_MULTIBYTE_LENGTH)
fe0e03f3
KH
1462 str[len++] = c;
1463 UNREAD (c);
1464 return STRING_CHAR (str, len);
1465}
1466
6f7f43d5
RS
1467/* Read a \-escape sequence, assuming we already read the `\'. */
1468
078e7b4a 1469static int
e7fc914b 1470read_escape (readcharfun, stringp)
078e7b4a 1471 Lisp_Object readcharfun;
e7fc914b 1472 int stringp;
078e7b4a
JB
1473{
1474 register int c = READCHAR;
1475 switch (c)
1476 {
f3849f25
RS
1477 case -1:
1478 error ("End of file");
1479
078e7b4a 1480 case 'a':
265a9e55 1481 return '\007';
078e7b4a
JB
1482 case 'b':
1483 return '\b';
f405a585
RS
1484 case 'd':
1485 return 0177;
078e7b4a
JB
1486 case 'e':
1487 return 033;
1488 case 'f':
1489 return '\f';
1490 case 'n':
1491 return '\n';
1492 case 'r':
1493 return '\r';
1494 case 't':
1495 return '\t';
1496 case 'v':
1497 return '\v';
1498 case '\n':
1499 return -1;
e28552a4 1500 case ' ':
e7fc914b
KH
1501 if (stringp)
1502 return -1;
1503 return ' ';
078e7b4a
JB
1504
1505 case 'M':
1506 c = READCHAR;
1507 if (c != '-')
1508 error ("Invalid escape character syntax");
1509 c = READCHAR;
1510 if (c == '\\')
e7fc914b 1511 c = read_escape (readcharfun, 0);
7bd279cd 1512 return c | meta_modifier;
f405a585
RS
1513
1514 case 'S':
1515 c = READCHAR;
1516 if (c != '-')
1517 error ("Invalid escape character syntax");
1518 c = READCHAR;
1519 if (c == '\\')
e7fc914b 1520 c = read_escape (readcharfun, 0);
7bd279cd
RS
1521 return c | shift_modifier;
1522
1523 case 'H':
1524 c = READCHAR;
1525 if (c != '-')
1526 error ("Invalid escape character syntax");
1527 c = READCHAR;
1528 if (c == '\\')
e7fc914b 1529 c = read_escape (readcharfun, 0);
7bd279cd
RS
1530 return c | hyper_modifier;
1531
1532 case 'A':
1533 c = READCHAR;
1534 if (c != '-')
1535 error ("Invalid escape character syntax");
1536 c = READCHAR;
1537 if (c == '\\')
e7fc914b 1538 c = read_escape (readcharfun, 0);
7bd279cd
RS
1539 return c | alt_modifier;
1540
1541 case 's':
1542 c = READCHAR;
1543 if (c != '-')
1544 error ("Invalid escape character syntax");
1545 c = READCHAR;
1546 if (c == '\\')
e7fc914b 1547 c = read_escape (readcharfun, 0);
7bd279cd 1548 return c | super_modifier;
078e7b4a
JB
1549
1550 case 'C':
1551 c = READCHAR;
1552 if (c != '-')
1553 error ("Invalid escape character syntax");
1554 case '^':
1555 c = READCHAR;
1556 if (c == '\\')
e7fc914b 1557 c = read_escape (readcharfun, 0);
164d590d
KH
1558 if ((c & ~CHAR_MODIFIER_MASK) == '?')
1559 return 0177 | (c & CHAR_MODIFIER_MASK);
1560 else if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
1561 return c | ctrl_modifier;
f405a585
RS
1562 /* ASCII control chars are made from letters (both cases),
1563 as well as the non-letters within 0100...0137. */
1564 else if ((c & 0137) >= 0101 && (c & 0137) <= 0132)
1565 return (c & (037 | ~0177));
1566 else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
1567 return (c & (037 | ~0177));
078e7b4a 1568 else
7bd279cd 1569 return c | ctrl_modifier;
078e7b4a
JB
1570
1571 case '0':
1572 case '1':
1573 case '2':
1574 case '3':
1575 case '4':
1576 case '5':
1577 case '6':
1578 case '7':
1579 /* An octal escape, as in ANSI C. */
1580 {
1581 register int i = c - '0';
1582 register int count = 0;
1583 while (++count < 3)
1584 {
1585 if ((c = READCHAR) >= '0' && c <= '7')
1586 {
1587 i *= 8;
1588 i += c - '0';
1589 }
1590 else
1591 {
1592 UNREAD (c);
1593 break;
1594 }
1595 }
1596 return i;
1597 }
1598
1599 case 'x':
1600 /* A hex escape, as in ANSI C. */
1601 {
1602 int i = 0;
1603 while (1)
1604 {
1605 c = READCHAR;
1606 if (c >= '0' && c <= '9')
1607 {
1608 i *= 16;
1609 i += c - '0';
1610 }
1611 else if ((c >= 'a' && c <= 'f')
1612 || (c >= 'A' && c <= 'F'))
1613 {
1614 i *= 16;
1615 if (c >= 'a' && c <= 'f')
1616 i += c - 'a' + 10;
1617 else
1618 i += c - 'A' + 10;
1619 }
1620 else
1621 {
1622 UNREAD (c);
1623 break;
1624 }
1625 }
1626 return i;
1627 }
1628
1629 default:
fe0e03f3
KH
1630 if (BASE_LEADING_CODE_P (c))
1631 c = read_multibyte (c, readcharfun);
078e7b4a
JB
1632 return c;
1633 }
1634}
1635
bf5d1a17
GM
1636
1637/* Read an integer in radix RADIX using READCHARFUN to read
1638 characters. RADIX must be in the interval [2..36]; if it isn't, a
1639 read error is signaled . Value is the integer read. Signals an
1640 error if encountering invalid read syntax or if RADIX is out of
1641 range. */
1642
1643static Lisp_Object
1644read_integer (readcharfun, radix)
1645 Lisp_Object readcharfun;
1646 int radix;
1647{
1648 int number, ndigits, invalid_p, c, sign;
1649
1650 if (radix < 2 || radix > 36)
1651 invalid_p = 1;
1652 else
1653 {
1654 number = ndigits = invalid_p = 0;
1655 sign = 1;
1656
1657 c = READCHAR;
1658 if (c == '-')
1659 {
1660 c = READCHAR;
1661 sign = -1;
1662 }
1663 else if (c == '+')
1664 c = READCHAR;
1665
1666 while (c >= 0)
1667 {
1668 int digit;
1669
1670 if (c >= '0' && c <= '9')
1671 digit = c - '0';
1672 else if (c >= 'a' && c <= 'z')
1673 digit = c - 'a' + 10;
1674 else if (c >= 'A' && c <= 'Z')
1675 digit = c - 'A' + 10;
1676 else
b632fa48
GM
1677 {
1678 UNREAD (c);
1679 break;
1680 }
bf5d1a17
GM
1681
1682 if (digit < 0 || digit >= radix)
1683 invalid_p = 1;
1684
1685 number = radix * number + digit;
1686 ++ndigits;
1687 c = READCHAR;
1688 }
1689 }
1690
1691 if (ndigits == 0 || invalid_p)
1692 {
1693 char buf[50];
1694 sprintf (buf, "integer, radix %d", radix);
1695 Fsignal (Qinvalid_read_syntax, Fcons (build_string (buf), Qnil));
1696 }
1697
1698 return make_number (sign * number);
1699}
1700
1701
6428369f
KH
1702/* If the next token is ')' or ']' or '.', we store that character
1703 in *PCH and the return value is not interesting. Else, we store
17634846
RS
1704 zero in *PCH and we read and return one lisp object.
1705
1706 FIRST_IN_LIST is nonzero if this is the first element of a list. */
1707
078e7b4a 1708static Lisp_Object
17634846 1709read1 (readcharfun, pch, first_in_list)
078e7b4a 1710 register Lisp_Object readcharfun;
e28552a4 1711 int *pch;
17634846 1712 int first_in_list;
078e7b4a
JB
1713{
1714 register int c;
4ad679f9
EN
1715 int uninterned_symbol = 0;
1716
6428369f 1717 *pch = 0;
078e7b4a
JB
1718
1719 retry:
1720
1721 c = READCHAR;
9c97398c
GM
1722 if (c < 0)
1723 end_of_file_error ();
078e7b4a
JB
1724
1725 switch (c)
1726 {
1727 case '(':
1728 return read_list (0, readcharfun);
1729
1730 case '[':
c15cfd1f 1731 return read_vector (readcharfun, 0);
078e7b4a
JB
1732
1733 case ')':
1734 case ']':
078e7b4a 1735 {
6428369f
KH
1736 *pch = c;
1737 return Qnil;
078e7b4a
JB
1738 }
1739
1740 case '#':
200f684e 1741 c = READCHAR;
c2390933
RS
1742 if (c == '^')
1743 {
1744 c = READCHAR;
1745 if (c == '[')
1746 {
1747 Lisp_Object tmp;
c15cfd1f 1748 tmp = read_vector (readcharfun, 0);
c2390933
RS
1749 if (XVECTOR (tmp)->size < CHAR_TABLE_STANDARD_SLOTS
1750 || XVECTOR (tmp)->size > CHAR_TABLE_STANDARD_SLOTS + 10)
1751 error ("Invalid size char-table");
1752 XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp));
3701b5de 1753 XCHAR_TABLE (tmp)->top = Qt;
c2390933
RS
1754 return tmp;
1755 }
3701b5de
KH
1756 else if (c == '^')
1757 {
1758 c = READCHAR;
1759 if (c == '[')
1760 {
1761 Lisp_Object tmp;
c15cfd1f 1762 tmp = read_vector (readcharfun, 0);
3701b5de
KH
1763 if (XVECTOR (tmp)->size != SUB_CHAR_TABLE_STANDARD_SLOTS)
1764 error ("Invalid size char-table");
1765 XSETCHAR_TABLE (tmp, XCHAR_TABLE (tmp));
1766 XCHAR_TABLE (tmp)->top = Qnil;
1767 return tmp;
1768 }
1769 Fsignal (Qinvalid_read_syntax,
1770 Fcons (make_string ("#^^", 3), Qnil));
1771 }
c2390933
RS
1772 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#^", 2), Qnil));
1773 }
1774 if (c == '&')
1775 {
1776 Lisp_Object length;
1777 length = read1 (readcharfun, pch, first_in_list);
1778 c = READCHAR;
1779 if (c == '"')
1780 {
1781 Lisp_Object tmp, val;
90ed3ec5 1782 int size_in_chars = ((XFASTINT (length) + BITS_PER_CHAR - 1)
68be917d 1783 / BITS_PER_CHAR);
c2390933
RS
1784
1785 UNREAD (c);
1786 tmp = read1 (readcharfun, pch, first_in_list);
90ed3ec5
RS
1787 if (size_in_chars != XSTRING (tmp)->size
1788 /* We used to print 1 char too many
1789 when the number of bits was a multiple of 8.
1790 Accept such input in case it came from an old version. */
1791 && ! (XFASTINT (length)
1792 == (XSTRING (tmp)->size - 1) * BITS_PER_CHAR))
c2390933 1793 Fsignal (Qinvalid_read_syntax,
ec3bbd7d 1794 Fcons (make_string ("#&...", 5), Qnil));
c2390933
RS
1795
1796 val = Fmake_bool_vector (length, Qnil);
1797 bcopy (XSTRING (tmp)->data, XBOOL_VECTOR (val)->data,
1798 size_in_chars);
67d3b149
EZ
1799 /* Clear the extraneous bits in the last byte. */
1800 if (XINT (length) != size_in_chars * BITS_PER_CHAR)
1801 XBOOL_VECTOR (val)->data[size_in_chars - 1]
1802 &= (1 << (XINT (length) % BITS_PER_CHAR)) - 1;
c2390933
RS
1803 return val;
1804 }
ec3bbd7d 1805 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#&...", 5),
039dc30b 1806 Qnil));
c2390933 1807 }
200f684e
RS
1808 if (c == '[')
1809 {
1810 /* Accept compiled functions at read-time so that we don't have to
1811 build them using function calls. */
748ef62f 1812 Lisp_Object tmp;
c15cfd1f 1813 tmp = read_vector (readcharfun, 1);
748ef62f
RS
1814 return Fmake_byte_code (XVECTOR (tmp)->size,
1815 XVECTOR (tmp)->contents);
200f684e 1816 }
748ef62f
RS
1817 if (c == '(')
1818 {
1819 Lisp_Object tmp;
1820 struct gcpro gcpro1;
e28552a4 1821 int ch;
748ef62f
RS
1822
1823 /* Read the string itself. */
17634846 1824 tmp = read1 (readcharfun, &ch, 0);
6428369f 1825 if (ch != 0 || !STRINGP (tmp))
748ef62f
RS
1826 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
1827 GCPRO1 (tmp);
1828 /* Read the intervals and their properties. */
1829 while (1)
1830 {
1831 Lisp_Object beg, end, plist;
1832
17634846 1833 beg = read1 (readcharfun, &ch, 0);
6428369f
KH
1834 if (ch == ')')
1835 break;
1836 if (ch == 0)
17634846 1837 end = read1 (readcharfun, &ch, 0);
6428369f 1838 if (ch == 0)
17634846 1839 plist = read1 (readcharfun, &ch, 0);
6428369f 1840 if (ch)
748ef62f 1841 Fsignal (Qinvalid_read_syntax,
6428369f
KH
1842 Fcons (build_string ("invalid string property list"),
1843 Qnil));
748ef62f
RS
1844 Fset_text_properties (beg, end, plist, tmp);
1845 }
1846 UNGCPRO;
1847 return tmp;
1848 }
339ee979 1849
20ea2964
RS
1850 /* #@NUMBER is used to skip NUMBER following characters.
1851 That's used in .elc files to skip over doc strings
1852 and function definitions. */
1853 if (c == '@')
1854 {
1855 int i, nskip = 0;
1856
1857 /* Read a decimal integer. */
1858 while ((c = READCHAR) >= 0
1859 && c >= '0' && c <= '9')
1860 {
1861 nskip *= 10;
1862 nskip += c - '0';
1863 }
1864 if (c >= 0)
1865 UNREAD (c);
1866
b2a30870
RS
1867 if (load_force_doc_strings && EQ (readcharfun, Qget_file_char))
1868 {
1869 /* If we are supposed to force doc strings into core right now,
1870 record the last string that we skipped,
1871 and record where in the file it comes from. */
c15cfd1f
RS
1872
1873 /* But first exchange saved_doc_string
1874 with prev_saved_doc_string, so we save two strings. */
1875 {
1876 char *temp = saved_doc_string;
1877 int temp_size = saved_doc_string_size;
68c45bf0 1878 file_offset temp_pos = saved_doc_string_position;
c15cfd1f
RS
1879 int temp_len = saved_doc_string_length;
1880
1881 saved_doc_string = prev_saved_doc_string;
1882 saved_doc_string_size = prev_saved_doc_string_size;
1883 saved_doc_string_position = prev_saved_doc_string_position;
1884 saved_doc_string_length = prev_saved_doc_string_length;
1885
1886 prev_saved_doc_string = temp;
1887 prev_saved_doc_string_size = temp_size;
1888 prev_saved_doc_string_position = temp_pos;
1889 prev_saved_doc_string_length = temp_len;
1890 }
1891
b2a30870
RS
1892 if (saved_doc_string_size == 0)
1893 {
1894 saved_doc_string_size = nskip + 100;
11938f10 1895 saved_doc_string = (char *) xmalloc (saved_doc_string_size);
b2a30870
RS
1896 }
1897 if (nskip > saved_doc_string_size)
1898 {
1899 saved_doc_string_size = nskip + 100;
11938f10
KH
1900 saved_doc_string = (char *) xrealloc (saved_doc_string,
1901 saved_doc_string_size);
b2a30870
RS
1902 }
1903
68c45bf0 1904 saved_doc_string_position = file_tell (instream);
b2a30870
RS
1905
1906 /* Copy that many characters into saved_doc_string. */
1907 for (i = 0; i < nskip && c >= 0; i++)
1908 saved_doc_string[i] = c = READCHAR;
1909
1910 saved_doc_string_length = i;
1911 }
1912 else
b2a30870
RS
1913 {
1914 /* Skip that many characters. */
1915 for (i = 0; i < nskip && c >= 0; i++)
1916 c = READCHAR;
1917 }
d49f0c1a 1918
20ea2964
RS
1919 goto retry;
1920 }
1921 if (c == '$')
1922 return Vload_file_name;
2b6cae0c
RS
1923 if (c == '\'')
1924 return Fcons (Qfunction, Fcons (read0 (readcharfun), Qnil));
4ad679f9
EN
1925 /* #:foo is the uninterned symbol named foo. */
1926 if (c == ':')
1927 {
1928 uninterned_symbol = 1;
1929 c = READCHAR;
1930 goto default_label;
1931 }
1932 /* Reader forms that can reuse previously read objects. */
1933 if (c >= '0' && c <= '9')
1934 {
1935 int n = 0;
1936 Lisp_Object tem;
2b6cae0c 1937
4ad679f9
EN
1938 /* Read a non-negative integer. */
1939 while (c >= '0' && c <= '9')
1940 {
1941 n *= 10;
1942 n += c - '0';
1943 c = READCHAR;
1944 }
1945 /* #n=object returns object, but associates it with n for #n#. */
1946 if (c == '=')
1947 {
9e062b6c
RS
1948 /* Make a placeholder for #n# to use temporarily */
1949 Lisp_Object placeholder;
1950 Lisp_Object cell;
1951
1952 placeholder = Fcons(Qnil, Qnil);
1953 cell = Fcons (make_number (n), placeholder);
1954 read_objects = Fcons (cell, read_objects);
1955
1956 /* Read the object itself. */
4ad679f9 1957 tem = read0 (readcharfun);
9e062b6c
RS
1958
1959 /* Now put it everywhere the placeholder was... */
1960 substitute_object_in_subtree (tem, placeholder);
1961
1962 /* ...and #n# will use the real value from now on. */
1963 Fsetcdr (cell, tem);
1964
4ad679f9
EN
1965 return tem;
1966 }
1967 /* #n# returns a previously read object. */
1968 if (c == '#')
1969 {
1970 tem = Fassq (make_number (n), read_objects);
1971 if (CONSP (tem))
1972 return XCDR (tem);
1973 /* Fall through to error message. */
1974 }
bf5d1a17
GM
1975 else if (c == 'r' || c == 'R')
1976 return read_integer (readcharfun, n);
1977
4ad679f9
EN
1978 /* Fall through to error message. */
1979 }
bf5d1a17
GM
1980 else if (c == 'x' || c == 'X')
1981 return read_integer (readcharfun, 16);
1982 else if (c == 'o' || c == 'O')
1983 return read_integer (readcharfun, 8);
1984 else if (c == 'b' || c == 'B')
1985 return read_integer (readcharfun, 2);
20ea2964 1986
200f684e 1987 UNREAD (c);
748ef62f 1988 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
078e7b4a
JB
1989
1990 case ';':
1991 while ((c = READCHAR) >= 0 && c != '\n');
1992 goto retry;
1993
1994 case '\'':
1995 {
1996 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
1997 }
1998
17634846
RS
1999 case '`':
2000 if (first_in_list)
2001 goto default_label;
2002 else
2003 {
2004 Lisp_Object value;
2005
2006 new_backquote_flag = 1;
2007 value = read0 (readcharfun);
2008 new_backquote_flag = 0;
2009
2010 return Fcons (Qbackquote, Fcons (value, Qnil));
2011 }
2012
2013 case ',':
2014 if (new_backquote_flag)
2015 {
2016 Lisp_Object comma_type = Qnil;
2017 Lisp_Object value;
2018 int ch = READCHAR;
2019
2020 if (ch == '@')
2021 comma_type = Qcomma_at;
2022 else if (ch == '.')
2023 comma_type = Qcomma_dot;
2024 else
2025 {
2026 if (ch >= 0) UNREAD (ch);
2027 comma_type = Qcomma;
2028 }
2029
2030 new_backquote_flag = 0;
2031 value = read0 (readcharfun);
2032 new_backquote_flag = 1;
2033 return Fcons (comma_type, Fcons (value, Qnil));
2034 }
2035 else
2036 goto default_label;
2037
078e7b4a
JB
2038 case '?':
2039 {
078e7b4a 2040 c = READCHAR;
9c97398c
GM
2041 if (c < 0)
2042 end_of_file_error ();
078e7b4a
JB
2043
2044 if (c == '\\')
e7fc914b 2045 c = read_escape (readcharfun, 0);
fe0e03f3
KH
2046 else if (BASE_LEADING_CODE_P (c))
2047 c = read_multibyte (c, readcharfun);
078e7b4a 2048
6f7f43d5 2049 return make_number (c);
078e7b4a
JB
2050 }
2051
00a9a935 2052 case '"':
078e7b4a
JB
2053 {
2054 register char *p = read_buffer;
2055 register char *end = read_buffer + read_buffer_size;
2056 register int c;
e7fc914b
KH
2057 /* Nonzero if we saw an escape sequence specifying
2058 a multibyte character. */
2059 int force_multibyte = 0;
2060 /* Nonzero if we saw an escape sequence specifying
2061 a single-byte character. */
2062 int force_singlebyte = 0;
078e7b4a 2063 int cancel = 0;
e7fc914b 2064 int nchars;
078e7b4a
JB
2065
2066 while ((c = READCHAR) >= 0
2067 && c != '\"')
2068 {
449fea39 2069 if (end - p < MAX_MULTIBYTE_LENGTH)
078e7b4a
JB
2070 {
2071 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
2072 p += new - read_buffer;
2073 read_buffer += new - read_buffer;
2074 end = read_buffer + read_buffer_size;
2075 }
bed23cb2 2076
078e7b4a 2077 if (c == '\\')
03e88613 2078 {
e7fc914b 2079 c = read_escape (readcharfun, 1);
bed23cb2
RS
2080
2081 /* C is -1 if \ newline has just been seen */
2082 if (c == -1)
03e88613 2083 {
bed23cb2
RS
2084 if (p == read_buffer)
2085 cancel = 1;
03e88613
RS
2086 continue;
2087 }
bed23cb2 2088
94e554db
RS
2089 /* If an escape specifies a non-ASCII single-byte character,
2090 this must be a unibyte string. */
164d590d
KH
2091 if (SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK))
2092 && ! ASCII_BYTE_P ((c & ~CHAR_MODIFIER_MASK)))
e7fc914b 2093 force_singlebyte = 1;
03e88613 2094 }
6f7f43d5 2095
164d590d 2096 if (! SINGLE_BYTE_CHAR_P ((c & ~CHAR_MODIFIER_MASK)))
078e7b4a 2097 {
164d590d
KH
2098 /* Any modifiers for a multibyte character are invalid. */
2099 if (c & CHAR_MODIFIER_MASK)
2100 error ("Invalid modifier in string");
449fea39
KH
2101 p += CHAR_STRING (c, p);
2102 force_multibyte = 1;
078e7b4a
JB
2103 }
2104 else
f943104a 2105 {
988c2f83
RS
2106 /* Allow `\C- ' and `\C-?'. */
2107 if (c == (CHAR_CTL | ' '))
2108 c = 0;
2109 else if (c == (CHAR_CTL | '?'))
2110 c = 127;
2111
164d590d
KH
2112 if (c & CHAR_SHIFT)
2113 {
2114 /* Shift modifier is valid only with [A-Za-z]. */
2115 if ((c & 0377) >= 'A' && (c & 0377) <= 'Z')
2116 c &= ~CHAR_SHIFT;
2117 else if ((c & 0377) >= 'a' && (c & 0377) <= 'z')
2118 c = (c & ~CHAR_SHIFT) - ('a' - 'A');
2119 }
2120
f943104a
KH
2121 if (c & CHAR_META)
2122 /* Move the meta bit to the right place for a string. */
2123 c = (c & ~CHAR_META) | 0x80;
2124 if (c & ~0xff)
2125 error ("Invalid modifier in string");
2126 *p++ = c;
2127 }
078e7b4a 2128 }
6f7f43d5 2129 if (c < 0)
9c97398c 2130 end_of_file_error ();
078e7b4a
JB
2131
2132 /* If purifying, and string starts with \ newline,
2133 return zero instead. This is for doc strings
08564963 2134 that we are really going to find in etc/DOC.nn.nn */
265a9e55 2135 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
078e7b4a
JB
2136 return make_number (0);
2137
6f46329a 2138 if (force_multibyte)
f0354c03
KH
2139 p = read_buffer + str_as_multibyte (read_buffer, end - read_buffer,
2140 p - read_buffer, &nchars);
6f46329a
RS
2141 else if (force_singlebyte)
2142 nchars = p - read_buffer;
94e554db
RS
2143 else if (load_convert_to_unibyte)
2144 {
2145 Lisp_Object string;
f0354c03
KH
2146 p = read_buffer + str_as_multibyte (read_buffer, end - read_buffer,
2147 p - read_buffer, &nchars);
94e554db
RS
2148 if (p - read_buffer != nchars)
2149 {
2150 string = make_multibyte_string (read_buffer, nchars,
2151 p - read_buffer);
2152 return Fstring_make_unibyte (string);
2153 }
2154 }
8db9dc66
RS
2155 else if (EQ (readcharfun, Qget_file_char)
2156 || EQ (readcharfun, Qlambda))
f0354c03
KH
2157 /* Nowadays, reading directly from a file is used only for
2158 compiled Emacs Lisp files, and those always use the
2159 Emacs internal encoding. Meanwhile, Qlambda is used
2160 for reading dynamic byte code (compiled with
2161 byte-compile-dynamic = t). */
2162 p = read_buffer + str_as_multibyte (read_buffer, end - read_buffer,
2163 p - read_buffer, &nchars);
e28552a4 2164 else
bed23cb2
RS
2165 /* In all other cases, if we read these bytes as
2166 separate characters, treat them as separate characters now. */
e7fc914b
KH
2167 nchars = p - read_buffer;
2168
2169 if (read_pure)
491f16a2
RS
2170 return make_pure_string (read_buffer, nchars, p - read_buffer,
2171 (force_multibyte
2172 || (p - read_buffer != nchars)));
2173 return make_specified_string (read_buffer, nchars, p - read_buffer,
2174 (force_multibyte
2175 || (p - read_buffer != nchars)));
078e7b4a
JB
2176 }
2177
109d300c
JB
2178 case '.':
2179 {
109d300c
JB
2180 int next_char = READCHAR;
2181 UNREAD (next_char);
2182
035eec48
GM
2183 if (next_char <= 040
2184 || index ("\"'`,(", next_char))
109d300c 2185 {
6428369f
KH
2186 *pch = c;
2187 return Qnil;
109d300c
JB
2188 }
2189
2190 /* Otherwise, we fall through! Note that the atom-reading loop
2191 below will now loop at least once, assuring that we will not
2192 try to UNREAD two characters in a row. */
2193 }
078e7b4a 2194 default:
17634846 2195 default_label:
078e7b4a
JB
2196 if (c <= 040) goto retry;
2197 {
2198 register char *p = read_buffer;
481c6336 2199 int quoted = 0;
078e7b4a
JB
2200
2201 {
2202 register char *end = read_buffer + read_buffer_size;
2203
6f7f43d5
RS
2204 while (c > 040
2205 && !(c == '\"' || c == '\'' || c == ';' || c == '?'
2206 || c == '(' || c == ')'
6f7f43d5
RS
2207 || c == '[' || c == ']' || c == '#'
2208 ))
078e7b4a 2209 {
449fea39 2210 if (end - p < MAX_MULTIBYTE_LENGTH)
078e7b4a
JB
2211 {
2212 register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
2213 p += new - read_buffer;
2214 read_buffer += new - read_buffer;
2215 end = read_buffer + read_buffer_size;
2216 }
2217 if (c == '\\')
481c6336
RS
2218 {
2219 c = READCHAR;
2220 quoted = 1;
2221 }
6f7f43d5 2222
bed23cb2 2223 if (! SINGLE_BYTE_CHAR_P (c))
449fea39 2224 p += CHAR_STRING (c, p);
bed23cb2
RS
2225 else
2226 *p++ = c;
6f7f43d5 2227
078e7b4a
JB
2228 c = READCHAR;
2229 }
2230
2231 if (p == end)
2232 {
2233 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
2234 p += new - read_buffer;
2235 read_buffer += new - read_buffer;
2236/* end = read_buffer + read_buffer_size; */
2237 }
2238 *p = 0;
2239 if (c >= 0)
2240 UNREAD (c);
2241 }
2242
4ad679f9 2243 if (!quoted && !uninterned_symbol)
481c6336
RS
2244 {
2245 register char *p1;
2246 register Lisp_Object val;
2247 p1 = read_buffer;
2248 if (*p1 == '+' || *p1 == '-') p1++;
2249 /* Is it an integer? */
2250 if (p1 != p)
2251 {
2252 while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++;
481c6336
RS
2253 /* Integers can have trailing decimal points. */
2254 if (p1 > read_buffer && p1 < p && *p1 == '.') p1++;
481c6336
RS
2255 if (p1 == p)
2256 /* It is an integer. */
2257 {
481c6336
RS
2258 if (p1[-1] == '.')
2259 p1[-1] = '\0';
faca07fb
RS
2260 if (sizeof (int) == sizeof (EMACS_INT))
2261 XSETINT (val, atoi (read_buffer));
2262 else if (sizeof (long) == sizeof (EMACS_INT))
2263 XSETINT (val, atol (read_buffer));
2264 else
2265 abort ();
481c6336
RS
2266 return val;
2267 }
2268 }
481c6336 2269 if (isfloat_string (read_buffer))
eb659c41 2270 {
a8972052
PE
2271 /* Compute NaN and infinities using 0.0 in a variable,
2272 to cope with compilers that think they are smarter
5e24a1f7 2273 than we are. */
3c329963 2274 double zero = 0.0;
a8972052
PE
2275
2276 double value;
2277
2278 /* Negate the value ourselves. This treats 0, NaNs,
2279 and infinity properly on IEEE floating point hosts,
2280 and works around a common bug where atof ("-0.0")
2281 drops the sign. */
2282 int negative = read_buffer[0] == '-';
2283
2284 /* The only way p[-1] can be 'F' or 'N', after isfloat_string
eb659c41 2285 returns 1, is if the input ends in e+INF or e+NaN. */
a8972052 2286 switch (p[-1])
eb659c41 2287 {
a8972052
PE
2288 case 'F':
2289 value = 1.0 / zero;
2290 break;
2291 case 'N':
2292 value = zero / zero;
2293 break;
2294 default:
2295 value = atof (read_buffer + negative);
2296 break;
eb659c41 2297 }
a8972052
PE
2298
2299 return make_float (negative ? - value : value);
eb659c41 2300 }
481c6336 2301 }
078e7b4a 2302
4ad679f9
EN
2303 if (uninterned_symbol)
2304 return make_symbol (read_buffer);
2305 else
2306 return intern (read_buffer);
078e7b4a
JB
2307 }
2308 }
2309}
2310\f
9e062b6c
RS
2311
2312/* List of nodes we've seen during substitute_object_in_subtree. */
2313static Lisp_Object seen_list;
2314
2315static void
2316substitute_object_in_subtree (object, placeholder)
2317 Lisp_Object object;
2318 Lisp_Object placeholder;
2319{
2320 Lisp_Object check_object;
2321
2322 /* We haven't seen any objects when we start. */
2323 seen_list = Qnil;
2324
2325 /* Make all the substitutions. */
2326 check_object
2327 = substitute_object_recurse (object, placeholder, object);
2328
2329 /* Clear seen_list because we're done with it. */
2330 seen_list = Qnil;
2331
2332 /* The returned object here is expected to always eq the
2333 original. */
2334 if (!EQ (check_object, object))
2335 error ("Unexpected mutation error in reader");
2336}
2337
2338/* Feval doesn't get called from here, so no gc protection is needed. */
2339#define SUBSTITUTE(get_val, set_val) \
2340{ \
2341 Lisp_Object old_value = get_val; \
2342 Lisp_Object true_value \
2343 = substitute_object_recurse (object, placeholder,\
2344 old_value); \
2345 \
2346 if (!EQ (old_value, true_value)) \
2347 { \
2348 set_val; \
2349 } \
2350}
2351
2352static Lisp_Object
2353substitute_object_recurse (object, placeholder, subtree)
2354 Lisp_Object object;
2355 Lisp_Object placeholder;
2356 Lisp_Object subtree;
2357{
2358 /* If we find the placeholder, return the target object. */
2359 if (EQ (placeholder, subtree))
2360 return object;
2361
2362 /* If we've been to this node before, don't explore it again. */
2363 if (!EQ (Qnil, Fmemq (subtree, seen_list)))
2364 return subtree;
2365
2366 /* If this node can be the entry point to a cycle, remember that
2367 we've seen it. It can only be such an entry point if it was made
2368 by #n=, which means that we can find it as a value in
2369 read_objects. */
2370 if (!EQ (Qnil, Frassq (subtree, read_objects)))
2371 seen_list = Fcons (subtree, seen_list);
2372
2373 /* Recurse according to subtree's type.
2374 Every branch must return a Lisp_Object. */
2375 switch (XTYPE (subtree))
2376 {
2377 case Lisp_Vectorlike:
2378 {
2379 int i;
7c752c80 2380 int length = XINT (Flength(subtree));
9e062b6c
RS
2381 for (i = 0; i < length; i++)
2382 {
2383 Lisp_Object idx = make_number (i);
2384 SUBSTITUTE (Faref (subtree, idx),
2385 Faset (subtree, idx, true_value));
2386 }
2387 return subtree;
2388 }
2389
2390 case Lisp_Cons:
2391 {
2392 SUBSTITUTE (Fcar_safe (subtree),
2393 Fsetcar (subtree, true_value));
2394 SUBSTITUTE (Fcdr_safe (subtree),
2395 Fsetcdr (subtree, true_value));
2396 return subtree;
2397 }
2398
9e062b6c
RS
2399 case Lisp_String:
2400 {
2401 /* Check for text properties in each interval.
2402 substitute_in_interval contains part of the logic. */
2403
2404 INTERVAL root_interval = XSTRING (subtree)->intervals;
2405 Lisp_Object arg = Fcons (object, placeholder);
2406
2407 traverse_intervals (root_interval, 1, 0,
2408 &substitute_in_interval, arg);
2409
2410 return subtree;
2411 }
9e062b6c
RS
2412
2413 /* Other types don't recurse any further. */
2414 default:
2415 return subtree;
2416 }
2417}
2418
2419/* Helper function for substitute_object_recurse. */
2420static void
2421substitute_in_interval (interval, arg)
2422 INTERVAL interval;
2423 Lisp_Object arg;
2424{
2425 Lisp_Object object = Fcar (arg);
2426 Lisp_Object placeholder = Fcdr (arg);
2427
2428 SUBSTITUTE(interval->plist, interval->plist = true_value);
2429}
2430
2431\f
078e7b4a
JB
2432#define LEAD_INT 1
2433#define DOT_CHAR 2
2434#define TRAIL_INT 4
2435#define E_CHAR 8
2436#define EXP_INT 16
2437
2438int
2439isfloat_string (cp)
2440 register char *cp;
2441{
c1a2f60a 2442 register int state;
078e7b4a 2443
d8578e58
RS
2444 char *start = cp;
2445
078e7b4a
JB
2446 state = 0;
2447 if (*cp == '+' || *cp == '-')
2448 cp++;
2449
075027b1 2450 if (*cp >= '0' && *cp <= '9')
078e7b4a
JB
2451 {
2452 state |= LEAD_INT;
075027b1
RS
2453 while (*cp >= '0' && *cp <= '9')
2454 cp++;
078e7b4a
JB
2455 }
2456 if (*cp == '.')
2457 {
2458 state |= DOT_CHAR;
2459 cp++;
2460 }
075027b1 2461 if (*cp >= '0' && *cp <= '9')
078e7b4a
JB
2462 {
2463 state |= TRAIL_INT;
075027b1 2464 while (*cp >= '0' && *cp <= '9')
078e7b4a
JB
2465 cp++;
2466 }
a35f88bf 2467 if (*cp == 'e' || *cp == 'E')
078e7b4a
JB
2468 {
2469 state |= E_CHAR;
2470 cp++;
e73997a1
RS
2471 if (*cp == '+' || *cp == '-')
2472 cp++;
078e7b4a 2473 }
078e7b4a 2474
075027b1 2475 if (*cp >= '0' && *cp <= '9')
078e7b4a
JB
2476 {
2477 state |= EXP_INT;
075027b1 2478 while (*cp >= '0' && *cp <= '9')
078e7b4a
JB
2479 cp++;
2480 }
d8578e58
RS
2481 else if (cp == start)
2482 ;
eb659c41
RS
2483 else if (cp[-1] == '+' && cp[0] == 'I' && cp[1] == 'N' && cp[2] == 'F')
2484 {
2485 state |= EXP_INT;
2486 cp += 3;
2487 }
2488 else if (cp[-1] == '+' && cp[0] == 'N' && cp[1] == 'a' && cp[2] == 'N')
2489 {
2490 state |= EXP_INT;
2491 cp += 3;
2492 }
2493
37579d7c 2494 return (((*cp == 0) || (*cp == ' ') || (*cp == '\t') || (*cp == '\n') || (*cp == '\r') || (*cp == '\f'))
078e7b4a 2495 && (state == (LEAD_INT|DOT_CHAR|TRAIL_INT)
151bdc83 2496 || state == (DOT_CHAR|TRAIL_INT)
078e7b4a 2497 || state == (LEAD_INT|E_CHAR|EXP_INT)
151bdc83
JB
2498 || state == (LEAD_INT|DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)
2499 || state == (DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)));
078e7b4a 2500}
cc94f3b2 2501
078e7b4a
JB
2502\f
2503static Lisp_Object
c15cfd1f 2504read_vector (readcharfun, bytecodeflag)
078e7b4a 2505 Lisp_Object readcharfun;
c15cfd1f 2506 int bytecodeflag;
078e7b4a
JB
2507{
2508 register int i;
2509 register int size;
2510 register Lisp_Object *ptr;
c15cfd1f 2511 register Lisp_Object tem, item, vector;
078e7b4a
JB
2512 register struct Lisp_Cons *otem;
2513 Lisp_Object len;
2514
2515 tem = read_list (1, readcharfun);
2516 len = Flength (tem);
2517 vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
2518
078e7b4a
JB
2519 size = XVECTOR (vector)->size;
2520 ptr = XVECTOR (vector)->contents;
2521 for (i = 0; i < size; i++)
2522 {
c15cfd1f
RS
2523 item = Fcar (tem);
2524 /* If `load-force-doc-strings' is t when reading a lazily-loaded
2525 bytecode object, the docstring containing the bytecode and
2526 constants values must be treated as unibyte and passed to
2527 Fread, to get the actual bytecode string and constants vector. */
2528 if (bytecodeflag && load_force_doc_strings)
2529 {
2530 if (i == COMPILED_BYTECODE)
2531 {
2532 if (!STRINGP (item))
2533 error ("invalid byte code");
2534
2535 /* Delay handling the bytecode slot until we know whether
2536 it is lazily-loaded (we can tell by whether the
2537 constants slot is nil). */
2538 ptr[COMPILED_CONSTANTS] = item;
2539 item = Qnil;
2540 }
2541 else if (i == COMPILED_CONSTANTS)
2542 {
2543 Lisp_Object bytestr = ptr[COMPILED_CONSTANTS];
2544
2545 if (NILP (item))
2546 {
2547 /* Coerce string to unibyte (like string-as-unibyte,
2548 but without generating extra garbage and
2549 guaranteeing no change in the contents). */
2550 XSTRING (bytestr)->size = STRING_BYTES (XSTRING (bytestr));
2551 SET_STRING_BYTES (XSTRING (bytestr), -1);
2552
2553 item = Fread (bytestr);
2554 if (!CONSP (item))
2555 error ("invalid byte code");
2556
2557 otem = XCONS (item);
c1d497be
KR
2558 bytestr = XCAR (item);
2559 item = XCDR (item);
c15cfd1f
RS
2560 free_cons (otem);
2561 }
2562
2563 /* Now handle the bytecode slot. */
2564 ptr[COMPILED_BYTECODE] = read_pure ? Fpurecopy (bytestr) : bytestr;
2565 }
2566 }
2567 ptr[i] = read_pure ? Fpurecopy (item) : item;
078e7b4a
JB
2568 otem = XCONS (tem);
2569 tem = Fcdr (tem);
2570 free_cons (otem);
2571 }
2572 return vector;
2573}
2574
6f7f43d5
RS
2575/* FLAG = 1 means check for ] to terminate rather than ) and .
2576 FLAG = -1 means check for starting with defun
078e7b4a
JB
2577 and make structure pure. */
2578
2579static Lisp_Object
2580read_list (flag, readcharfun)
2581 int flag;
2582 register Lisp_Object readcharfun;
2583{
2584 /* -1 means check next element for defun,
2585 0 means don't check,
2586 1 means already checked and found defun. */
2587 int defunflag = flag < 0 ? -1 : 0;
2588 Lisp_Object val, tail;
2589 register Lisp_Object elt, tem;
2590 struct gcpro gcpro1, gcpro2;
821d417e 2591 /* 0 is the normal case.
b2a30870
RS
2592 1 means this list is a doc reference; replace it with the number 0.
2593 2 means this list is a doc reference; replace it with the doc string. */
821d417e 2594 int doc_reference = 0;
078e7b4a 2595
17634846
RS
2596 /* Initialize this to 1 if we are reading a list. */
2597 int first_in_list = flag <= 0;
2598
078e7b4a
JB
2599 val = Qnil;
2600 tail = Qnil;
2601
2602 while (1)
2603 {
e28552a4 2604 int ch;
078e7b4a 2605 GCPRO2 (val, tail);
17634846 2606 elt = read1 (readcharfun, &ch, first_in_list);
078e7b4a 2607 UNGCPRO;
20ea2964 2608
17634846
RS
2609 first_in_list = 0;
2610
821d417e 2611 /* While building, if the list starts with #$, treat it specially. */
20ea2964 2612 if (EQ (elt, Vload_file_name)
d49f0c1a 2613 && ! NILP (elt)
821d417e
RS
2614 && !NILP (Vpurify_flag))
2615 {
2616 if (NILP (Vdoc_file_name))
2617 /* We have not yet called Snarf-documentation, so assume
2618 this file is described in the DOC-MM.NN file
2619 and Snarf-documentation will fill in the right value later.
2620 For now, replace the whole list with 0. */
2621 doc_reference = 1;
2622 else
2623 /* We have already called Snarf-documentation, so make a relative
2624 file name for this file, so it can be found properly
2625 in the installed Lisp directory.
2626 We don't use Fexpand_file_name because that would make
2627 the directory absolute now. */
2628 elt = concat2 (build_string ("../lisp/"),
2629 Ffile_name_nondirectory (elt));
2630 }
b2a30870 2631 else if (EQ (elt, Vload_file_name)
d49f0c1a 2632 && ! NILP (elt)
b2a30870
RS
2633 && load_force_doc_strings)
2634 doc_reference = 2;
20ea2964 2635
6428369f 2636 if (ch)
078e7b4a
JB
2637 {
2638 if (flag > 0)
2639 {
6428369f 2640 if (ch == ']')
078e7b4a 2641 return val;
821d417e
RS
2642 Fsignal (Qinvalid_read_syntax,
2643 Fcons (make_string (") or . in a vector", 18), Qnil));
078e7b4a 2644 }
6428369f 2645 if (ch == ')')
078e7b4a 2646 return val;
6428369f 2647 if (ch == '.')
078e7b4a
JB
2648 {
2649 GCPRO2 (val, tail);
265a9e55 2650 if (!NILP (tail))
c1d497be 2651 XCDR (tail) = read0 (readcharfun);
078e7b4a
JB
2652 else
2653 val = read0 (readcharfun);
17634846 2654 read1 (readcharfun, &ch, 0);
078e7b4a 2655 UNGCPRO;
6428369f 2656 if (ch == ')')
821d417e
RS
2657 {
2658 if (doc_reference == 1)
2659 return make_number (0);
b2a30870
RS
2660 if (doc_reference == 2)
2661 {
2662 /* Get a doc string from the file we are loading.
2663 If it's in saved_doc_string, get it from there. */
c1d497be 2664 int pos = XINT (XCDR (val));
c15cfd1f
RS
2665 /* Position is negative for user variables. */
2666 if (pos < 0) pos = -pos;
b2a30870
RS
2667 if (pos >= saved_doc_string_position
2668 && pos < (saved_doc_string_position
2669 + saved_doc_string_length))
2670 {
2671 int start = pos - saved_doc_string_position;
2672 int from, to;
2673
2674 /* Process quoting with ^A,
2675 and find the end of the string,
2676 which is marked with ^_ (037). */
2677 for (from = start, to = start;
2678 saved_doc_string[from] != 037;)
2679 {
2680 int c = saved_doc_string[from++];
2681 if (c == 1)
2682 {
2683 c = saved_doc_string[from++];
2684 if (c == 1)
2685 saved_doc_string[to++] = c;
2686 else if (c == '0')
2687 saved_doc_string[to++] = 0;
2688 else if (c == '_')
2689 saved_doc_string[to++] = 037;
2690 }
2691 else
2692 saved_doc_string[to++] = c;
2693 }
2694
2695 return make_string (saved_doc_string + start,
2696 to - start);
2697 }
c15cfd1f
RS
2698 /* Look in prev_saved_doc_string the same way. */
2699 else if (pos >= prev_saved_doc_string_position
2700 && pos < (prev_saved_doc_string_position
2701 + prev_saved_doc_string_length))
2702 {
2703 int start = pos - prev_saved_doc_string_position;
2704 int from, to;
2705
2706 /* Process quoting with ^A,
2707 and find the end of the string,
2708 which is marked with ^_ (037). */
2709 for (from = start, to = start;
2710 prev_saved_doc_string[from] != 037;)
2711 {
2712 int c = prev_saved_doc_string[from++];
2713 if (c == 1)
2714 {
2715 c = prev_saved_doc_string[from++];
2716 if (c == 1)
2717 prev_saved_doc_string[to++] = c;
2718 else if (c == '0')
2719 prev_saved_doc_string[to++] = 0;
2720 else if (c == '_')
2721 prev_saved_doc_string[to++] = 037;
2722 }
2723 else
2724 prev_saved_doc_string[to++] = c;
2725 }
2726
2727 return make_string (prev_saved_doc_string + start,
2728 to - start);
2729 }
b2a30870 2730 else
6fe9cce5 2731 return get_doc_string (val, 0, 0);
b2a30870
RS
2732 }
2733
821d417e
RS
2734 return val;
2735 }
078e7b4a
JB
2736 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil));
2737 }
2738 return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("] in a list", 11), Qnil));
2739 }
2740 tem = (read_pure && flag <= 0
2741 ? pure_cons (elt, Qnil)
2742 : Fcons (elt, Qnil));
265a9e55 2743 if (!NILP (tail))
c1d497be 2744 XCDR (tail) = tem;
078e7b4a
JB
2745 else
2746 val = tem;
2747 tail = tem;
2748 if (defunflag < 0)
2749 defunflag = EQ (elt, Qdefun);
2750 else if (defunflag > 0)
2751 read_pure = 1;
2752 }
2753}
2754\f
2755Lisp_Object Vobarray;
2756Lisp_Object initial_obarray;
2757
d007f5c8
RS
2758/* oblookup stores the bucket number here, for the sake of Funintern. */
2759
2760int oblookup_last_bucket_number;
2761
2762static int hash_string ();
2763Lisp_Object oblookup ();
2764
2765/* Get an error if OBARRAY is not an obarray.
2766 If it is one, return it. */
2767
078e7b4a
JB
2768Lisp_Object
2769check_obarray (obarray)
2770 Lisp_Object obarray;
2771{
cfff016d 2772 while (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
078e7b4a
JB
2773 {
2774 /* If Vobarray is now invalid, force it to be valid. */
2775 if (EQ (Vobarray, obarray)) Vobarray = initial_obarray;
2776
2777 obarray = wrong_type_argument (Qvectorp, obarray);
2778 }
2779 return obarray;
2780}
2781
d007f5c8
RS
2782/* Intern the C string STR: return a symbol with that name,
2783 interned in the current obarray. */
078e7b4a
JB
2784
2785Lisp_Object
2786intern (str)
2787 char *str;
2788{
2789 Lisp_Object tem;
2790 int len = strlen (str);
153a17b7 2791 Lisp_Object obarray;
078e7b4a 2792
153a17b7 2793 obarray = Vobarray;
cfff016d 2794 if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
078e7b4a 2795 obarray = check_obarray (obarray);
e28552a4 2796 tem = oblookup (obarray, str, len, len);
cfff016d 2797 if (SYMBOLP (tem))
078e7b4a 2798 return tem;
87631ef7 2799 return Fintern (make_string (str, len), obarray);
078e7b4a 2800}
4ad679f9
EN
2801
2802/* Create an uninterned symbol with name STR. */
2803
2804Lisp_Object
2805make_symbol (str)
2806 char *str;
2807{
2808 int len = strlen (str);
2809
2810 return Fmake_symbol ((!NILP (Vpurify_flag)
491f16a2 2811 ? make_pure_string (str, len, len, 0)
4ad679f9
EN
2812 : make_string (str, len)));
2813}
d007f5c8 2814\f
078e7b4a
JB
2815DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
2816 "Return the canonical symbol whose name is STRING.\n\
2817If there is none, one is created by this function and returned.\n\
2818A second optional argument specifies the obarray to use;\n\
2819it defaults to the value of `obarray'.")
9391b698
EN
2820 (string, obarray)
2821 Lisp_Object string, obarray;
078e7b4a
JB
2822{
2823 register Lisp_Object tem, sym, *ptr;
2824
265a9e55 2825 if (NILP (obarray)) obarray = Vobarray;
078e7b4a
JB
2826 obarray = check_obarray (obarray);
2827
9391b698 2828 CHECK_STRING (string, 0);
078e7b4a 2829
e28552a4
RS
2830 tem = oblookup (obarray, XSTRING (string)->data,
2831 XSTRING (string)->size,
fc932ac6 2832 STRING_BYTES (XSTRING (string)));
cfff016d 2833 if (!INTEGERP (tem))
078e7b4a
JB
2834 return tem;
2835
265a9e55 2836 if (!NILP (Vpurify_flag))
9391b698
EN
2837 string = Fpurecopy (string);
2838 sym = Fmake_symbol (string);
4ad679f9 2839 XSYMBOL (sym)->obarray = obarray;
078e7b4a 2840
bdd47b1c 2841 if ((XSTRING (string)->data[0] == ':')
a458d45d 2842 && EQ (obarray, initial_obarray))
a0549832
RS
2843 XSYMBOL (sym)->value = sym;
2844
078e7b4a 2845 ptr = &XVECTOR (obarray)->contents[XINT (tem)];
cfff016d 2846 if (SYMBOLP (*ptr))
078e7b4a
JB
2847 XSYMBOL (sym)->next = XSYMBOL (*ptr);
2848 else
2849 XSYMBOL (sym)->next = 0;
2850 *ptr = sym;
2851 return sym;
2852}
2853
2854DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
b55048d4 2855 "Return the canonical symbol named NAME, or nil if none exists.\n\
3ccf78e0
DL
2856NAME may be a string or a symbol. If it is a symbol, that exact\n\
2857symbol is searched for.\n\
078e7b4a
JB
2858A second optional argument specifies the obarray to use;\n\
2859it defaults to the value of `obarray'.")
b55048d4
GM
2860 (name, obarray)
2861 Lisp_Object name, obarray;
078e7b4a
JB
2862{
2863 register Lisp_Object tem;
b55048d4 2864 struct Lisp_String *string;
078e7b4a 2865
265a9e55 2866 if (NILP (obarray)) obarray = Vobarray;
078e7b4a
JB
2867 obarray = check_obarray (obarray);
2868
b55048d4
GM
2869 if (!SYMBOLP (name))
2870 {
2871 CHECK_STRING (name, 0);
2872 string = XSTRING (name);
2873 }
2874 else
2875 string = XSYMBOL (name)->name;
078e7b4a 2876
b55048d4
GM
2877 tem = oblookup (obarray, string->data, string->size, STRING_BYTES (string));
2878 if (INTEGERP (tem) || (SYMBOLP (name) && !EQ (name, tem)))
2879 return Qnil;
2880 else
078e7b4a 2881 return tem;
078e7b4a 2882}
d007f5c8
RS
2883\f
2884DEFUN ("unintern", Funintern, Sunintern, 1, 2, 0,
2885 "Delete the symbol named NAME, if any, from OBARRAY.\n\
2886The value is t if a symbol was found and deleted, nil otherwise.\n\
2887NAME may be a string or a symbol. If it is a symbol, that symbol\n\
2888is deleted, if it belongs to OBARRAY--no other symbol is deleted.\n\
2889OBARRAY defaults to the value of the variable `obarray'.")
2890 (name, obarray)
2891 Lisp_Object name, obarray;
2892{
2893 register Lisp_Object string, tem;
2894 int hash;
2895
2896 if (NILP (obarray)) obarray = Vobarray;
2897 obarray = check_obarray (obarray);
2898
2899 if (SYMBOLP (name))
2900 XSETSTRING (string, XSYMBOL (name)->name);
2901 else
2902 {
2903 CHECK_STRING (name, 0);
2904 string = name;
2905 }
2906
e28552a4
RS
2907 tem = oblookup (obarray, XSTRING (string)->data,
2908 XSTRING (string)->size,
fc932ac6 2909 STRING_BYTES (XSTRING (string)));
d007f5c8
RS
2910 if (INTEGERP (tem))
2911 return Qnil;
2912 /* If arg was a symbol, don't delete anything but that symbol itself. */
2913 if (SYMBOLP (name) && !EQ (name, tem))
2914 return Qnil;
2915
ca69c42f
RS
2916 XSYMBOL (tem)->obarray = Qnil;
2917
d007f5c8
RS
2918 hash = oblookup_last_bucket_number;
2919
2920 if (EQ (XVECTOR (obarray)->contents[hash], tem))
b2a30870
RS
2921 {
2922 if (XSYMBOL (tem)->next)
2923 XSETSYMBOL (XVECTOR (obarray)->contents[hash], XSYMBOL (tem)->next);
2924 else
2925 XSETINT (XVECTOR (obarray)->contents[hash], 0);
2926 }
d007f5c8
RS
2927 else
2928 {
2929 Lisp_Object tail, following;
2930
2931 for (tail = XVECTOR (obarray)->contents[hash];
2932 XSYMBOL (tail)->next;
2933 tail = following)
2934 {
2935 XSETSYMBOL (following, XSYMBOL (tail)->next);
2936 if (EQ (following, tem))
2937 {
2938 XSYMBOL (tail)->next = XSYMBOL (following)->next;
2939 break;
2940 }
2941 }
2942 }
2943
2944 return Qt;
2945}
2946\f
2947/* Return the symbol in OBARRAY whose names matches the string
e28552a4
RS
2948 of SIZE characters (SIZE_BYTE bytes) at PTR.
2949 If there is no such symbol in OBARRAY, return nil.
d007f5c8
RS
2950
2951 Also store the bucket number in oblookup_last_bucket_number. */
078e7b4a
JB
2952
2953Lisp_Object
e28552a4 2954oblookup (obarray, ptr, size, size_byte)
078e7b4a
JB
2955 Lisp_Object obarray;
2956 register char *ptr;
e28552a4 2957 int size, size_byte;
078e7b4a 2958{
7a70b397
RS
2959 int hash;
2960 int obsize;
078e7b4a
JB
2961 register Lisp_Object tail;
2962 Lisp_Object bucket, tem;
2963
cfff016d 2964 if (!VECTORP (obarray)
7c79a684 2965 || (obsize = XVECTOR (obarray)->size) == 0)
078e7b4a
JB
2966 {
2967 obarray = check_obarray (obarray);
2968 obsize = XVECTOR (obarray)->size;
2969 }
519418b3
RS
2970 /* This is sometimes needed in the middle of GC. */
2971 obsize &= ~ARRAY_MARK_FLAG;
078e7b4a 2972 /* Combining next two lines breaks VMS C 2.3. */
e28552a4 2973 hash = hash_string (ptr, size_byte);
078e7b4a
JB
2974 hash %= obsize;
2975 bucket = XVECTOR (obarray)->contents[hash];
d007f5c8 2976 oblookup_last_bucket_number = hash;
078e7b4a
JB
2977 if (XFASTINT (bucket) == 0)
2978 ;
cfff016d 2979 else if (!SYMBOLP (bucket))
078e7b4a 2980 error ("Bad data in guts of obarray"); /* Like CADR error message */
d007f5c8
RS
2981 else
2982 for (tail = bucket; ; XSETSYMBOL (tail, XSYMBOL (tail)->next))
078e7b4a 2983 {
fc932ac6 2984 if (STRING_BYTES (XSYMBOL (tail)->name) == size_byte
e28552a4
RS
2985 && XSYMBOL (tail)->name->size == size
2986 && !bcmp (XSYMBOL (tail)->name->data, ptr, size_byte))
078e7b4a
JB
2987 return tail;
2988 else if (XSYMBOL (tail)->next == 0)
2989 break;
2990 }
1805de4f 2991 XSETINT (tem, hash);
078e7b4a
JB
2992 return tem;
2993}
2994
2995static int
2996hash_string (ptr, len)
2997 unsigned char *ptr;
2998 int len;
2999{
3000 register unsigned char *p = ptr;
3001 register unsigned char *end = p + len;
3002 register unsigned char c;
3003 register int hash = 0;
3004
3005 while (p != end)
3006 {
3007 c = *p++;
3008 if (c >= 0140) c -= 40;
3009 hash = ((hash<<3) + (hash>>28) + c);
3010 }
3011 return hash & 07777777777;
3012}
d007f5c8 3013\f
078e7b4a
JB
3014void
3015map_obarray (obarray, fn, arg)
3016 Lisp_Object obarray;
d5b28a9d 3017 void (*fn) P_ ((Lisp_Object, Lisp_Object));
078e7b4a
JB
3018 Lisp_Object arg;
3019{
3020 register int i;
3021 register Lisp_Object tail;
3022 CHECK_VECTOR (obarray, 1);
3023 for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
3024 {
3025 tail = XVECTOR (obarray)->contents[i];
4f5c4403 3026 if (SYMBOLP (tail))
078e7b4a
JB
3027 while (1)
3028 {
3029 (*fn) (tail, arg);
3030 if (XSYMBOL (tail)->next == 0)
3031 break;
1805de4f 3032 XSETSYMBOL (tail, XSYMBOL (tail)->next);
078e7b4a
JB
3033 }
3034 }
3035}
3036
d5b28a9d 3037void
078e7b4a
JB
3038mapatoms_1 (sym, function)
3039 Lisp_Object sym, function;
3040{
3041 call1 (function, sym);
3042}
3043
3044DEFUN ("mapatoms", Fmapatoms, Smapatoms, 1, 2, 0,
3045 "Call FUNCTION on every symbol in OBARRAY.\n\
3046OBARRAY defaults to the value of `obarray'.")
3047 (function, obarray)
3048 Lisp_Object function, obarray;
3049{
265a9e55 3050 if (NILP (obarray)) obarray = Vobarray;
078e7b4a
JB
3051 obarray = check_obarray (obarray);
3052
3053 map_obarray (obarray, mapatoms_1, function);
3054 return Qnil;
3055}
3056
5e88a39e 3057#define OBARRAY_SIZE 1511
078e7b4a
JB
3058
3059void
3060init_obarray ()
3061{
3062 Lisp_Object oblength;
3063 int hash;
3064 Lisp_Object *tem;
3065
baf69866 3066 XSETFASTINT (oblength, OBARRAY_SIZE);
078e7b4a 3067
491f16a2 3068 Qnil = Fmake_symbol (make_pure_string ("nil", 3, 3, 0));
078e7b4a
JB
3069 Vobarray = Fmake_vector (oblength, make_number (0));
3070 initial_obarray = Vobarray;
3071 staticpro (&initial_obarray);
3072 /* Intern nil in the obarray */
4ad679f9 3073 XSYMBOL (Qnil)->obarray = Vobarray;
078e7b4a
JB
3074 /* These locals are to kludge around a pyramid compiler bug. */
3075 hash = hash_string ("nil", 3);
3076 /* Separate statement here to avoid VAXC bug. */
3077 hash %= OBARRAY_SIZE;
3078 tem = &XVECTOR (Vobarray)->contents[hash];
3079 *tem = Qnil;
3080
491f16a2 3081 Qunbound = Fmake_symbol (make_pure_string ("unbound", 7, 7, 0));
078e7b4a
JB
3082 XSYMBOL (Qnil)->function = Qunbound;
3083 XSYMBOL (Qunbound)->value = Qunbound;
3084 XSYMBOL (Qunbound)->function = Qunbound;
3085
3086 Qt = intern ("t");
3087 XSYMBOL (Qnil)->value = Qnil;
3088 XSYMBOL (Qnil)->plist = Qnil;
3089 XSYMBOL (Qt)->value = Qt;
3090
3091 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
3092 Vpurify_flag = Qt;
3093
3094 Qvariable_documentation = intern ("variable-documentation");
0f73bb1c 3095 staticpro (&Qvariable_documentation);
078e7b4a 3096
449fea39 3097 read_buffer_size = 100 + MAX_MULTIBYTE_LENGTH;
3cb65b0e 3098 read_buffer = (char *) xmalloc (read_buffer_size);
078e7b4a
JB
3099}
3100\f
3101void
3102defsubr (sname)
3103 struct Lisp_Subr *sname;
3104{
3105 Lisp_Object sym;
3106 sym = intern (sname->symbol_name);
1805de4f 3107 XSETSUBR (XSYMBOL (sym)->function, sname);
078e7b4a
JB
3108}
3109
3110#ifdef NOTDEF /* use fset in subr.el now */
3111void
3112defalias (sname, string)
3113 struct Lisp_Subr *sname;
3114 char *string;
3115{
3116 Lisp_Object sym;
3117 sym = intern (string);
1805de4f 3118 XSETSUBR (XSYMBOL (sym)->function, sname);
078e7b4a
JB
3119}
3120#endif /* NOTDEF */
3121
078e7b4a 3122/* Define an "integer variable"; a symbol whose value is forwarded
1a0f90f7 3123 to a C variable of type int. Sample call: */
950c215d 3124 /* DEFVAR_INT ("indent-tabs-mode", &indent_tabs_mode, "Documentation"); */
078e7b4a 3125void
e9e00ff2 3126defvar_int (namestring, address)
078e7b4a
JB
3127 char *namestring;
3128 int *address;
078e7b4a 3129{
1a0f90f7 3130 Lisp_Object sym, val;
078e7b4a 3131 sym = intern (namestring);
1a0f90f7 3132 val = allocate_misc ();
47e28b2c 3133 XMISCTYPE (val) = Lisp_Misc_Intfwd;
fc1e7df5 3134 XINTFWD (val)->intvar = address;
1a0f90f7 3135 XSYMBOL (sym)->value = val;
078e7b4a
JB
3136}
3137
3138/* Similar but define a variable whose value is T if address contains 1,
1a0f90f7 3139 NIL if address contains 0 */
078e7b4a 3140void
e9e00ff2 3141defvar_bool (namestring, address)
078e7b4a
JB
3142 char *namestring;
3143 int *address;
078e7b4a 3144{
1a0f90f7 3145 Lisp_Object sym, val;
078e7b4a 3146 sym = intern (namestring);
1a0f90f7 3147 val = allocate_misc ();
47e28b2c 3148 XMISCTYPE (val) = Lisp_Misc_Boolfwd;
fc1e7df5 3149 XBOOLFWD (val)->boolvar = address;
1a0f90f7 3150 XSYMBOL (sym)->value = val;
1ffcc3b1 3151 Vbyte_boolean_vars = Fcons (sym, Vbyte_boolean_vars);
078e7b4a
JB
3152}
3153
1a0f90f7
KH
3154/* Similar but define a variable whose value is the Lisp Object stored
3155 at address. Two versions: with and without gc-marking of the C
3156 variable. The nopro version is used when that variable will be
3157 gc-marked for some other reason, since marking the same slot twice
3158 can cause trouble with strings. */
078e7b4a 3159void
1a0f90f7 3160defvar_lisp_nopro (namestring, address)
078e7b4a
JB
3161 char *namestring;
3162 Lisp_Object *address;
078e7b4a 3163{
1a0f90f7 3164 Lisp_Object sym, val;
078e7b4a 3165 sym = intern (namestring);
1a0f90f7 3166 val = allocate_misc ();
47e28b2c 3167 XMISCTYPE (val) = Lisp_Misc_Objfwd;
fc1e7df5 3168 XOBJFWD (val)->objvar = address;
1a0f90f7 3169 XSYMBOL (sym)->value = val;
078e7b4a
JB
3170}
3171
078e7b4a 3172void
1a0f90f7 3173defvar_lisp (namestring, address)
078e7b4a
JB
3174 char *namestring;
3175 Lisp_Object *address;
078e7b4a 3176{
1a0f90f7
KH
3177 defvar_lisp_nopro (namestring, address);
3178 staticpro (address);
078e7b4a
JB
3179}
3180
078e7b4a 3181/* Similar but define a variable whose value is the Lisp Object stored in
2836d9a4
KH
3182 the current buffer. address is the address of the slot in the buffer
3183 that is current now. */
078e7b4a
JB
3184
3185void
4360b0c6 3186defvar_per_buffer (namestring, address, type, doc)
078e7b4a
JB
3187 char *namestring;
3188 Lisp_Object *address;
4360b0c6 3189 Lisp_Object type;
078e7b4a
JB
3190 char *doc;
3191{
1a0f90f7 3192 Lisp_Object sym, val;
078e7b4a
JB
3193 int offset;
3194 extern struct buffer buffer_local_symbols;
3195
3196 sym = intern (namestring);
1a0f90f7 3197 val = allocate_misc ();
078e7b4a
JB
3198 offset = (char *)address - (char *)current_buffer;
3199
47e28b2c 3200 XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd;
fc1e7df5 3201 XBUFFER_OBJFWD (val)->offset = offset;
1a0f90f7 3202 XSYMBOL (sym)->value = val;
11fd416e
GM
3203 PER_BUFFER_SYMBOL (offset) = sym;
3204 PER_BUFFER_TYPE (offset) = type;
cf611f01 3205
11fd416e 3206 if (PER_BUFFER_IDX (offset) == 0)
078e7b4a
JB
3207 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
3208 slot of buffer_local_flags */
3209 abort ();
3210}
3211
950c215d
KH
3212
3213/* Similar but define a variable whose value is the Lisp Object stored
4ac38690 3214 at a particular offset in the current kboard object. */
950c215d
KH
3215
3216void
4ac38690 3217defvar_kboard (namestring, offset)
950c215d
KH
3218 char *namestring;
3219 int offset;
3220{
3221 Lisp_Object sym, val;
3222 sym = intern (namestring);
3223 val = allocate_misc ();
47e28b2c 3224 XMISCTYPE (val) = Lisp_Misc_Kboard_Objfwd;
4ac38690 3225 XKBOARD_OBJFWD (val)->offset = offset;
950c215d
KH
3226 XSYMBOL (sym)->value = val;
3227}
078e7b4a 3228\f
11938f10
KH
3229/* Record the value of load-path used at the start of dumping
3230 so we can see if the site changed it later during dumping. */
3231static Lisp_Object dump_path;
3232
d5b28a9d 3233void
279499f0 3234init_lread ()
078e7b4a 3235{
46947372 3236 char *normal;
e73997a1 3237 int turn_off_warning = 0;
078e7b4a 3238
279499f0 3239 /* Compute the default load-path. */
46947372
JB
3240#ifdef CANNOT_DUMP
3241 normal = PATH_LOADSEARCH;
e065a56e 3242 Vload_path = decode_env_path (0, normal);
46947372
JB
3243#else
3244 if (NILP (Vpurify_flag))
3245 normal = PATH_LOADSEARCH;
279499f0 3246 else
46947372 3247 normal = PATH_DUMPLOADSEARCH;
279499f0 3248
46947372
JB
3249 /* In a dumped Emacs, we normally have to reset the value of
3250 Vload_path from PATH_LOADSEARCH, since the value that was dumped
3251 uses ../lisp, instead of the path of the installed elisp
3252 libraries. However, if it appears that Vload_path was changed
3253 from the default before dumping, don't override that value. */
4746118a
JB
3254 if (initialized)
3255 {
4746118a 3256 if (! NILP (Fequal (dump_path, Vload_path)))
80667d53
RS
3257 {
3258 Vload_path = decode_env_path (0, normal);
74180aa4 3259 if (!NILP (Vinstallation_directory))
80667d53 3260 {
74180aa4 3261 /* Add to the path the lisp subdir of the
3a3056e5
RS
3262 installation dir, if it exists. */
3263 Lisp_Object tem, tem1;
74180aa4
RS
3264 tem = Fexpand_file_name (build_string ("lisp"),
3265 Vinstallation_directory);
3a3056e5
RS
3266 tem1 = Ffile_exists_p (tem);
3267 if (!NILP (tem1))
3268 {
3269 if (NILP (Fmember (tem, Vload_path)))
e73997a1
RS
3270 {
3271 turn_off_warning = 1;
3272 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
3273 }
3a3056e5
RS
3274 }
3275 else
3276 /* That dir doesn't exist, so add the build-time
3277 Lisp dirs instead. */
3278 Vload_path = nconc2 (Vload_path, dump_path);
c478f98c 3279
9fbc0116
RS
3280 /* Add leim under the installation dir, if it exists. */
3281 tem = Fexpand_file_name (build_string ("leim"),
3282 Vinstallation_directory);
3283 tem1 = Ffile_exists_p (tem);
3284 if (!NILP (tem1))
3285 {
3286 if (NILP (Fmember (tem, Vload_path)))
3287 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
3288 }
3289
c478f98c
RS
3290 /* Add site-list under the installation dir, if it exists. */
3291 tem = Fexpand_file_name (build_string ("site-lisp"),
3292 Vinstallation_directory);
3293 tem1 = Ffile_exists_p (tem);
3294 if (!NILP (tem1))
3295 {
3296 if (NILP (Fmember (tem, Vload_path)))
3297 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
3298 }
0f337465
RS
3299
3300 /* If Emacs was not built in the source directory,
9fbc0116
RS
3301 and it is run from where it was built, add to load-path
3302 the lisp, leim and site-lisp dirs under that directory. */
0f337465
RS
3303
3304 if (NILP (Fequal (Vinstallation_directory, Vsource_directory)))
3305 {
33046fc9
RS
3306 Lisp_Object tem2;
3307
0f337465
RS
3308 tem = Fexpand_file_name (build_string ("src/Makefile"),
3309 Vinstallation_directory);
3310 tem1 = Ffile_exists_p (tem);
33046fc9
RS
3311
3312 /* Don't be fooled if they moved the entire source tree
3313 AFTER dumping Emacs. If the build directory is indeed
3314 different from the source dir, src/Makefile.in and
3315 src/Makefile will not be found together. */
3316 tem = Fexpand_file_name (build_string ("src/Makefile.in"),
3317 Vinstallation_directory);
3318 tem2 = Ffile_exists_p (tem);
3319 if (!NILP (tem1) && NILP (tem2))
0f337465
RS
3320 {
3321 tem = Fexpand_file_name (build_string ("lisp"),
3322 Vsource_directory);
3323
3324 if (NILP (Fmember (tem, Vload_path)))
3325 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
3326
9fbc0116
RS
3327 tem = Fexpand_file_name (build_string ("leim"),
3328 Vsource_directory);
3329
3330 if (NILP (Fmember (tem, Vload_path)))
3331 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
3332
0f337465
RS
3333 tem = Fexpand_file_name (build_string ("site-lisp"),
3334 Vsource_directory);
3335
3336 if (NILP (Fmember (tem, Vload_path)))
3337 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
3338 }
3339 }
80667d53
RS
3340 }
3341 }
4746118a
JB
3342 }
3343 else
11938f10 3344 {
7b396c6c
RS
3345 /* NORMAL refers to the lisp dir in the source directory. */
3346 /* We used to add ../lisp at the front here, but
3347 that caused trouble because it was copied from dump_path
3348 into Vload_path, aboe, when Vinstallation_directory was non-nil.
3349 It should be unnecessary. */
3350 Vload_path = decode_env_path (0, normal);
11938f10
KH
3351 dump_path = Vload_path;
3352 }
46947372 3353#endif
279499f0 3354
317073d5
RS
3355#ifndef WINDOWSNT
3356 /* When Emacs is invoked over network shares on NT, PATH_LOADSEARCH is
3357 almost never correct, thereby causing a warning to be printed out that
8e6208c5 3358 confuses users. Since PATH_LOADSEARCH is always overridden by the
317073d5
RS
3359 EMACSLOADPATH environment variable below, disable the warning on NT. */
3360
078e7b4a 3361 /* Warn if dirs in the *standard* path don't exist. */
e73997a1
RS
3362 if (!turn_off_warning)
3363 {
3364 Lisp_Object path_tail;
078e7b4a 3365
e73997a1
RS
3366 for (path_tail = Vload_path;
3367 !NILP (path_tail);
c1d497be 3368 path_tail = XCDR (path_tail))
e73997a1
RS
3369 {
3370 Lisp_Object dirfile;
3371 dirfile = Fcar (path_tail);
3372 if (STRINGP (dirfile))
3373 {
3374 dirfile = Fdirectory_file_name (dirfile);
3375 if (access (XSTRING (dirfile)->data, 0) < 0)
85496b8c 3376 dir_warning ("Warning: Lisp directory `%s' does not exist.\n",
c1d497be 3377 XCAR (path_tail));
e73997a1
RS
3378 }
3379 }
3380 }
317073d5 3381#endif /* WINDOWSNT */
46947372
JB
3382
3383 /* If the EMACSLOADPATH environment variable is set, use its value.
3384 This doesn't apply if we're dumping. */
ffd9c2a1 3385#ifndef CANNOT_DUMP
46947372
JB
3386 if (NILP (Vpurify_flag)
3387 && egetenv ("EMACSLOADPATH"))
ffd9c2a1 3388#endif
279499f0 3389 Vload_path = decode_env_path ("EMACSLOADPATH", normal);
279499f0
JB
3390
3391 Vvalues = Qnil;
3392
078e7b4a 3393 load_in_progress = 0;
4e53f562 3394 Vload_file_name = Qnil;
d2c6be7f
RS
3395
3396 load_descriptor_list = Qnil;
8f6b0411
RS
3397
3398 Vstandard_input = Qt;
078e7b4a
JB
3399}
3400
85496b8c
RS
3401/* Print a warning, using format string FORMAT, that directory DIRNAME
3402 does not exist. Print it on stderr and put it in *Message*. */
3403
d5b28a9d 3404void
85496b8c
RS
3405dir_warning (format, dirname)
3406 char *format;
3407 Lisp_Object dirname;
3408{
3409 char *buffer
3410 = (char *) alloca (XSTRING (dirname)->size + strlen (format) + 5);
3411
3412 fprintf (stderr, format, XSTRING (dirname)->data);
3413 sprintf (buffer, format, XSTRING (dirname)->data);
9b69357e
GV
3414 /* Don't log the warning before we've initialized!! */
3415 if (initialized)
3416 message_dolog (buffer, strlen (buffer), 0, STRING_MULTIBYTE (dirname));
85496b8c
RS
3417}
3418
078e7b4a 3419void
279499f0 3420syms_of_lread ()
078e7b4a
JB
3421{
3422 defsubr (&Sread);
3423 defsubr (&Sread_from_string);
3424 defsubr (&Sintern);
3425 defsubr (&Sintern_soft);
d007f5c8 3426 defsubr (&Sunintern);
078e7b4a 3427 defsubr (&Sload);
228d4b1c 3428 defsubr (&Seval_buffer);
078e7b4a
JB
3429 defsubr (&Seval_region);
3430 defsubr (&Sread_char);
3431 defsubr (&Sread_char_exclusive);
078e7b4a 3432 defsubr (&Sread_event);
078e7b4a
JB
3433 defsubr (&Sget_file_char);
3434 defsubr (&Smapatoms);
3435
3436 DEFVAR_LISP ("obarray", &Vobarray,
3437 "Symbol table for use by `intern' and `read'.\n\
3438It is a vector whose length ought to be prime for best results.\n\
3439The vector's contents don't make sense if examined from Lisp programs;\n\
3440to find all the symbols in an obarray, use `mapatoms'.");
3441
3442 DEFVAR_LISP ("values", &Vvalues,
3443 "List of values of all expressions which were read, evaluated and printed.\n\
3444Order is reverse chronological.");
3445
3446 DEFVAR_LISP ("standard-input", &Vstandard_input,
3447 "Stream for read to get input from.\n\
3448See documentation of `read' for possible values.");
3449 Vstandard_input = Qt;
3450
3451 DEFVAR_LISP ("load-path", &Vload_path,
3452 "*List of directories to search for files to load.\n\
3453Each element is a string (directory name) or nil (try default directory).\n\
3454Initialized based on EMACSLOADPATH environment variable, if any,\n\
57bda87a 3455otherwise to default specified by file `epaths.h' when Emacs was built.");
078e7b4a
JB
3456
3457 DEFVAR_BOOL ("load-in-progress", &load_in_progress,
3458 "Non-nil iff inside of `load'.");
3459
3460 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
3461 "An alist of expressions to be evalled when particular files are loaded.\n\
3462Each element looks like (FILENAME FORMS...).\n\
3463When `load' is run and the file-name argument is FILENAME,\n\
3464the FORMS in the corresponding element are executed at the end of loading.\n\n\
3465FILENAME must match exactly! Normally FILENAME is the name of a library,\n\
3466with no directory specified, since that is how `load' is normally called.\n\
3467An error in FORMS does not undo the load,\n\
3468but does prevent execution of the rest of the FORMS.");
3469 Vafter_load_alist = Qnil;
3470
ae321d28
RS
3471 DEFVAR_LISP ("load-history", &Vload_history,
3472 "Alist mapping source file names to symbols and features.\n\
3473Each alist element is a list that starts with a file name,\n\
3474except for one element (optional) that starts with nil and describes\n\
3475definitions evaluated from buffers not visiting files.\n\
3476The remaining elements of each list are symbols defined as functions\n\
e8c7d424 3477or variables, and cons cells `(provide . FEATURE)', `(require . FEATURE)',\n\
7973e637 3478and `(autoload . SYMBOL)'.");
ae321d28
RS
3479 Vload_history = Qnil;
3480
20ea2964
RS
3481 DEFVAR_LISP ("load-file-name", &Vload_file_name,
3482 "Full name of file being loaded by `load'.");
3483 Vload_file_name = Qnil;
3484
4116ab9f 3485 DEFVAR_LISP ("user-init-file", &Vuser_init_file,
d750b1f5
AI
3486 "File name, including directory, of user's initialization file.\n\
3487If the file loaded had extension `.elc' and there was a corresponding `.el'\n\
3488file, this variable contains the name of the .el file, suitable for use\n\
d826d78b 3489by functions like `custom-save-all' which edit the init file.");
4116ab9f
KH
3490 Vuser_init_file = Qnil;
3491
8a1f1537
RS
3492 DEFVAR_LISP ("current-load-list", &Vcurrent_load_list,
3493 "Used for internal purposes by `load'.");
ae321d28
RS
3494 Vcurrent_load_list = Qnil;
3495
84a15045
RS
3496 DEFVAR_LISP ("load-read-function", &Vload_read_function,
3497 "Function used by `load' and `eval-region' for reading expressions.\n\
3498The default is nil, which means use the function `read'.");
3499 Vload_read_function = Qnil;
3500
fe0e03f3
KH
3501 DEFVAR_LISP ("load-source-file-function", &Vload_source_file_function,
3502 "Function called in `load' for loading an Emacs lisp source file.\n\
3503This function is for doing code conversion before reading the source file.\n\
3504If nil, loading is done without any code conversion.\n\
3505Arguments are FULLNAME, FILE, NOERROR, NOMESSAGE, where\n\
3506 FULLNAME is the full name of FILE.\n\
3507See `load' for the meaning of the remaining arguments.");
3508 Vload_source_file_function = Qnil;
3509
b2a30870
RS
3510 DEFVAR_BOOL ("load-force-doc-strings", &load_force_doc_strings,
3511 "Non-nil means `load' should force-load all dynamic doc strings.\n\
3512This is useful when the file being loaded is a temporary copy.");
3513 load_force_doc_strings = 0;
3514
94e554db 3515 DEFVAR_BOOL ("load-convert-to-unibyte", &load_convert_to_unibyte,
afdca070
RS
3516 "Non-nil means `read' converts strings to unibyte whenever possible.\n\
3517This is normally bound by `load' and `eval-buffer' to control `read',\n\
3518and is not meant for users to change.");
94e554db
RS
3519 load_convert_to_unibyte = 0;
3520
1521a8fa
RS
3521 DEFVAR_LISP ("source-directory", &Vsource_directory,
3522 "Directory in which Emacs sources were found when Emacs was built.\n\
3523You cannot count on them to still be there!");
a90ba1e2
KH
3524 Vsource_directory
3525 = Fexpand_file_name (build_string ("../"),
3526 Fcar (decode_env_path (0, PATH_DUMPLOADSEARCH)));
3527
4b104c41
RS
3528 DEFVAR_LISP ("preloaded-file-list", &Vpreloaded_file_list,
3529 "List of files that were preloaded (when dumping Emacs).");
3530 Vpreloaded_file_list = Qnil;
3531
1ffcc3b1
DL
3532 DEFVAR_LISP ("byte-boolean-vars", &Vbyte_boolean_vars,
3533 "List of all DEFVAR_BOOL variables, used by the byte code optimizer.");
3534 Vbyte_boolean_vars = Qnil;
3535
da84f340
GM
3536 DEFVAR_BOOL ("load-dangerous-libraries", &load_dangerous_libraries,
3537 "Non-nil means load dangerous compiled Lisp files.\n\
3538Some versions of XEmacs use different byte codes than Emacs. These\n\
3539incompatible byte codes can make Emacs crash when it tries to execute\n\
3540them.");
3541 load_dangerous_libraries = 0;
3542
3543 Vbytecomp_version_regexp = build_string ("^;;;.in Emacs version");
3544 staticpro (&Vbytecomp_version_regexp);
3545
a90ba1e2
KH
3546 /* Vsource_directory was initialized in init_lread. */
3547
d2c6be7f
RS
3548 load_descriptor_list = Qnil;
3549 staticpro (&load_descriptor_list);
3550
8a1f1537
RS
3551 Qcurrent_load_list = intern ("current-load-list");
3552 staticpro (&Qcurrent_load_list);
3553
078e7b4a
JB
3554 Qstandard_input = intern ("standard-input");
3555 staticpro (&Qstandard_input);
3556
3557 Qread_char = intern ("read-char");
3558 staticpro (&Qread_char);
3559
3560 Qget_file_char = intern ("get-file-char");
3561 staticpro (&Qget_file_char);
7bd279cd 3562
17634846
RS
3563 Qbackquote = intern ("`");
3564 staticpro (&Qbackquote);
3565 Qcomma = intern (",");
3566 staticpro (&Qcomma);
3567 Qcomma_at = intern (",@");
3568 staticpro (&Qcomma_at);
3569 Qcomma_dot = intern (",.");
3570 staticpro (&Qcomma_dot);
3571
74549846
RS
3572 Qinhibit_file_name_operation = intern ("inhibit-file-name-operation");
3573 staticpro (&Qinhibit_file_name_operation);
3574
7bd279cd
RS
3575 Qascii_character = intern ("ascii-character");
3576 staticpro (&Qascii_character);
c2225d00 3577
2b6cae0c
RS
3578 Qfunction = intern ("function");
3579 staticpro (&Qfunction);
3580
c2225d00
RS
3581 Qload = intern ("load");
3582 staticpro (&Qload);
20ea2964
RS
3583
3584 Qload_file_name = intern ("load-file-name");
3585 staticpro (&Qload_file_name);
11938f10
KH
3586
3587 staticpro (&dump_path);
4ad679f9
EN
3588
3589 staticpro (&read_objects);
3590 read_objects = Qnil;
9e062b6c
RS
3591 staticpro (&seen_list);
3592
078e7b4a 3593}