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