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