(unexec): Add casts for some comparisons.
[bpt/emacs.git] / src / lread.c
1 /* Lisp parsing and input streams.
2 Copyright (C) 1985, 1986, 1987, 1988, 1989,
3 1993 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <sys/file.h>
26 #include <ctype.h>
27 #include "config.h"
28 #include "lisp.h"
29
30 #ifndef standalone
31 #include "buffer.h"
32 #include "paths.h"
33 #include "commands.h"
34 #include "keyboard.h"
35 #include "termhooks.h"
36 #endif
37
38 #ifdef lint
39 #include <sys/inode.h>
40 #endif /* lint */
41
42 #ifndef X_OK
43 #define X_OK 01
44 #endif
45
46 #ifdef LISP_FLOAT_TYPE
47 #ifdef STDC_HEADERS
48 #include <stdlib.h>
49 #endif
50 #include <math.h>
51 #endif /* LISP_FLOAT_TYPE */
52
53 Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list;
54 Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist;
55 Lisp_Object Qascii_character, Qload;
56
57 extern Lisp_Object Qevent_symbol_element_mask;
58
59 /* non-zero if inside `load' */
60 int load_in_progress;
61
62 /* Search path for files to be loaded. */
63 Lisp_Object Vload_path;
64
65 /* This is the user-visible association list that maps features to
66 lists of defs in their load files. */
67 Lisp_Object Vload_history;
68
69 /* This is useud to build the load history. */
70 Lisp_Object Vcurrent_load_list;
71
72 /* File for get_file_char to read from. Use by load */
73 static FILE *instream;
74
75 /* When nonzero, read conses in pure space */
76 static int read_pure;
77
78 /* For use within read-from-string (this reader is non-reentrant!!) */
79 static int read_from_string_index;
80 static int read_from_string_limit;
81 \f
82 /* Handle unreading and rereading of characters.
83 Write READCHAR to read a character,
84 UNREAD(c) to unread c to be read again. */
85
86 #define READCHAR readchar (readcharfun)
87 #define UNREAD(c) unreadchar (readcharfun, c)
88
89 static int
90 readchar (readcharfun)
91 Lisp_Object readcharfun;
92 {
93 Lisp_Object tem;
94 register struct buffer *inbuffer;
95 register int c, mpos;
96
97 if (XTYPE (readcharfun) == Lisp_Buffer)
98 {
99 inbuffer = XBUFFER (readcharfun);
100
101 if (BUF_PT (inbuffer) >= BUF_ZV (inbuffer))
102 return -1;
103 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, BUF_PT (inbuffer));
104 SET_BUF_PT (inbuffer, BUF_PT (inbuffer) + 1);
105
106 return c;
107 }
108 if (XTYPE (readcharfun) == Lisp_Marker)
109 {
110 inbuffer = XMARKER (readcharfun)->buffer;
111
112 mpos = marker_position (readcharfun);
113
114 if (mpos > BUF_ZV (inbuffer) - 1)
115 return -1;
116 c = *(unsigned char *) BUF_CHAR_ADDRESS (inbuffer, mpos);
117 if (mpos != BUF_GPT (inbuffer))
118 XMARKER (readcharfun)->bufpos++;
119 else
120 Fset_marker (readcharfun, make_number (mpos + 1),
121 Fmarker_buffer (readcharfun));
122 return c;
123 }
124 if (EQ (readcharfun, Qget_file_char))
125 return getc (instream);
126
127 if (XTYPE (readcharfun) == Lisp_String)
128 {
129 register int c;
130 /* This used to be return of a conditional expression,
131 but that truncated -1 to a char on VMS. */
132 if (read_from_string_index < read_from_string_limit)
133 c = XSTRING (readcharfun)->data[read_from_string_index++];
134 else
135 c = -1;
136 return c;
137 }
138
139 tem = call0 (readcharfun);
140
141 if (NILP (tem))
142 return -1;
143 return XINT (tem);
144 }
145
146 /* Unread the character C in the way appropriate for the stream READCHARFUN.
147 If the stream is a user function, call it with the char as argument. */
148
149 static void
150 unreadchar (readcharfun, c)
151 Lisp_Object readcharfun;
152 int c;
153 {
154 if (XTYPE (readcharfun) == Lisp_Buffer)
155 {
156 if (XBUFFER (readcharfun) == current_buffer)
157 SET_PT (point - 1);
158 else
159 SET_BUF_PT (XBUFFER (readcharfun), BUF_PT (XBUFFER (readcharfun)) - 1);
160 }
161 else if (XTYPE (readcharfun) == Lisp_Marker)
162 XMARKER (readcharfun)->bufpos--;
163 else if (XTYPE (readcharfun) == Lisp_String)
164 read_from_string_index--;
165 else if (EQ (readcharfun, Qget_file_char))
166 ungetc (c, instream);
167 else
168 call1 (readcharfun, make_number (c));
169 }
170
171 static Lisp_Object read0 (), read1 (), read_list (), read_vector ();
172 \f
173 /* get a character from the tty */
174
175 extern Lisp_Object read_char ();
176
177 /* Read input events until we get one that's acceptable for our purposes.
178
179 If NO_SWITCH_FRAME is non-zero, switch-frame events are stashed
180 until we get a character we like, and then stuffed into
181 unread_switch_frame.
182
183 If ASCII_REQUIRED is non-zero, we check function key events to see
184 if the unmodified version of the symbol has a Qascii_character
185 property, and use that character, if present.
186
187 If ERROR_NONASCII is non-zero, we signal an error if the input we
188 get isn't an ASCII character with modifiers. If it's zero but
189 ASCII_REQUIRED is non-zero, we just re-read until we get an ASCII
190 character. */
191 Lisp_Object
192 read_filtered_event (no_switch_frame, ascii_required, error_nonascii)
193 int no_switch_frame, ascii_required, error_nonascii;
194 {
195 #ifdef standalone
196 return make_number (getchar ());
197 #else
198 register Lisp_Object val;
199 register Lisp_Object delayed_switch_frame = Qnil;
200
201 /* Read until we get an acceptable event. */
202 retry:
203 val = read_char (0, 0, 0, Qnil, 0);
204
205 /* switch-frame events are put off until after the next ASCII
206 character. This is better than signalling an error just because
207 the last characters were typed to a separate minibuffer frame,
208 for example. Eventually, some code which can deal with
209 switch-frame events will read it and process it. */
210 if (no_switch_frame
211 && EVENT_HAS_PARAMETERS (val)
212 && EQ (EVENT_HEAD (val), Qswitch_frame))
213 {
214 delayed_switch_frame = val;
215 goto retry;
216 }
217
218 if (ascii_required)
219 {
220 /* Convert certain symbols to their ASCII equivalents. */
221 if (XTYPE (val) == Lisp_Symbol)
222 {
223 Lisp_Object tem, tem1, tem2;
224 tem = Fget (val, Qevent_symbol_element_mask);
225 if (!NILP (tem))
226 {
227 tem1 = Fget (Fcar (tem), Qascii_character);
228 /* Merge this symbol's modifier bits
229 with the ASCII equivalent of its basic code. */
230 if (!NILP (tem1))
231 XFASTINT (val) = XINT (tem1) | XINT (Fcar (Fcdr (tem)));
232 }
233 }
234
235 /* If we don't have a character now, deal with it appropriately. */
236 if (XTYPE (val) != Lisp_Int)
237 {
238 if (error_nonascii)
239 {
240 unread_command_events = Fcons (val, Qnil);
241 error ("Non-character input-event");
242 }
243 else
244 goto retry;
245 }
246 }
247
248 if (! NILP (delayed_switch_frame))
249 unread_switch_frame = delayed_switch_frame;
250
251 return val;
252 #endif
253 }
254
255 DEFUN ("read-char", Fread_char, Sread_char, 0, 0, 0,
256 "Read a character from the command input (keyboard or macro).\n\
257 It is returned as a number.\n\
258 If the user generates an event which is not a character (i.e. a mouse\n\
259 click or function key event), `read-char' signals an error. As an\n\
260 exception, switch-frame events are put off until non-ASCII events can\n\
261 be read.\n\
262 If you want to read non-character events, or ignore them, call\n\
263 `read-event' or `read-char-exclusive' instead.")
264 ()
265 {
266 return read_filtered_event (1, 1, 1);
267 }
268
269 DEFUN ("read-event", Fread_event, Sread_event, 0, 0, 0,
270 "Read an event object from the input stream.")
271 ()
272 {
273 return read_filtered_event (0, 0, 0);
274 }
275
276 DEFUN ("read-char-exclusive", Fread_char_exclusive, Sread_char_exclusive, 0, 0, 0,
277 "Read a character from the command input (keyboard or macro).\n\
278 It is returned as a number. Non character events are ignored.")
279 ()
280 {
281 return read_filtered_event (1, 1, 0);
282 }
283
284 DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
285 "Don't use this yourself.")
286 ()
287 {
288 register Lisp_Object val;
289 XSET (val, Lisp_Int, getc (instream));
290 return val;
291 }
292 \f
293 static void readevalloop ();
294 static Lisp_Object load_unwind ();
295
296 DEFUN ("load", Fload, Sload, 1, 4, 0,
297 "Execute a file of Lisp code named FILE.\n\
298 First try FILE with `.elc' appended, then try with `.el',\n\
299 then try FILE unmodified.\n\
300 This function searches the directories in `load-path'.\n\
301 If optional second arg NOERROR is non-nil,\n\
302 report no error if FILE doesn't exist.\n\
303 Print messages at start and end of loading unless\n\
304 optional third arg NOMESSAGE is non-nil.\n\
305 If optional fourth arg NOSUFFIX is non-nil, don't try adding\n\
306 suffixes `.elc' or `.el' to the specified name FILE.\n\
307 Return t if file exists.")
308 (str, noerror, nomessage, nosuffix)
309 Lisp_Object str, noerror, nomessage, nosuffix;
310 {
311 register FILE *stream;
312 register int fd = -1;
313 register Lisp_Object lispstream;
314 register FILE **ptr;
315 int count = specpdl_ptr - specpdl;
316 Lisp_Object temp;
317 struct gcpro gcpro1;
318 Lisp_Object found;
319 /* 1 means inhibit the message at the beginning. */
320 int nomessage1 = 0;
321 Lisp_Object handler;
322
323 CHECK_STRING (str, 0);
324 str = Fsubstitute_in_file_name (str);
325
326 /* If file name is magic, call the handler. */
327 handler = Ffind_file_name_handler (str);
328 if (!NILP (handler))
329 return call5 (handler, Qload, str, noerror, nomessage, nosuffix);
330
331 /* Avoid weird lossage with null string as arg,
332 since it would try to load a directory as a Lisp file */
333 if (XSTRING (str)->size > 0)
334 {
335 fd = openp (Vload_path, str, !NILP (nosuffix) ? "" : ".elc:.el:",
336 &found, 0);
337 }
338
339 if (fd < 0)
340 {
341 if (NILP (noerror))
342 while (1)
343 Fsignal (Qfile_error, Fcons (build_string ("Cannot open load file"),
344 Fcons (str, Qnil)));
345 else
346 return Qnil;
347 }
348
349 if (!bcmp (&(XSTRING (found)->data[XSTRING (found)->size - 4]),
350 ".elc", 4))
351 {
352 struct stat s1, s2;
353 int result;
354
355 stat (XSTRING (found)->data, &s1);
356 XSTRING (found)->data[XSTRING (found)->size - 1] = 0;
357 result = stat (XSTRING (found)->data, &s2);
358 if (result >= 0 && (unsigned) s1.st_mtime < (unsigned) s2.st_mtime)
359 {
360 message ("Source file `%s' newer than byte-compiled file",
361 XSTRING (found)->data);
362 /* Don't immediately overwrite this message. */
363 if (!noninteractive)
364 nomessage1 = 1;
365 }
366 XSTRING (found)->data[XSTRING (found)->size - 1] = 'c';
367 }
368
369 stream = fdopen (fd, "r");
370 if (stream == 0)
371 {
372 close (fd);
373 error ("Failure to create stdio stream for %s", XSTRING (str)->data);
374 }
375
376 if (NILP (nomessage) && !nomessage1)
377 message ("Loading %s...", XSTRING (str)->data);
378
379 GCPRO1 (str);
380 /* We may not be able to store STREAM itself as a Lisp_Object pointer
381 since that is guaranteed to work only for data that has been malloc'd.
382 So malloc a full-size pointer, and record the address of that pointer. */
383 ptr = (FILE **) xmalloc (sizeof (FILE *));
384 *ptr = stream;
385 XSET (lispstream, Lisp_Internal_Stream, (int) ptr);
386 record_unwind_protect (load_unwind, lispstream);
387 load_in_progress++;
388 readevalloop (Qget_file_char, stream, str, Feval, 0);
389 unbind_to (count, Qnil);
390
391 /* Run any load-hooks for this file. */
392 temp = Fassoc (str, Vafter_load_alist);
393 if (!NILP (temp))
394 Fprogn (Fcdr (temp));
395 UNGCPRO;
396
397 if (!noninteractive && NILP (nomessage))
398 message ("Loading %s...done", XSTRING (str)->data);
399 return Qt;
400 }
401
402 static Lisp_Object
403 load_unwind (stream) /* used as unwind-protect function in load */
404 Lisp_Object stream;
405 {
406 fclose (*(FILE **) XSTRING (stream));
407 xfree (XPNTR (stream));
408 if (--load_in_progress < 0) load_in_progress = 0;
409 return Qnil;
410 }
411
412 \f
413 static int
414 complete_filename_p (pathname)
415 Lisp_Object pathname;
416 {
417 register unsigned char *s = XSTRING (pathname)->data;
418 return (*s == '/'
419 #ifdef ALTOS
420 || *s == '@'
421 #endif
422 #ifdef VMS
423 || index (s, ':')
424 #endif /* VMS */
425 );
426 }
427
428 /* Search for a file whose name is STR, looking in directories
429 in the Lisp list PATH, and trying suffixes from SUFFIX.
430 SUFFIX is a string containing possible suffixes separated by colons.
431 On success, returns a file descriptor. On failure, returns -1.
432
433 EXEC_ONLY nonzero means don't open the files,
434 just look for one that is executable. In this case,
435 returns 1 on success.
436
437 If STOREPTR is nonzero, it points to a slot where the name of
438 the file actually found should be stored as a Lisp string.
439 Nil is stored there on failure. */
440
441 int
442 openp (path, str, suffix, storeptr, exec_only)
443 Lisp_Object path, str;
444 char *suffix;
445 Lisp_Object *storeptr;
446 int exec_only;
447 {
448 register int fd;
449 int fn_size = 100;
450 char buf[100];
451 register char *fn = buf;
452 int absolute = 0;
453 int want_size;
454 register Lisp_Object filename;
455 struct stat st;
456
457 if (storeptr)
458 *storeptr = Qnil;
459
460 if (complete_filename_p (str))
461 absolute = 1;
462
463 for (; !NILP (path); path = Fcdr (path))
464 {
465 char *nsuffix;
466
467 filename = Fexpand_file_name (str, Fcar (path));
468 if (!complete_filename_p (filename))
469 /* If there are non-absolute elts in PATH (eg ".") */
470 /* Of course, this could conceivably lose if luser sets
471 default-directory to be something non-absolute... */
472 {
473 filename = Fexpand_file_name (filename, current_buffer->directory);
474 if (!complete_filename_p (filename))
475 /* Give up on this path element! */
476 continue;
477 }
478
479 /* Calculate maximum size of any filename made from
480 this path element/specified file name and any possible suffix. */
481 want_size = strlen (suffix) + XSTRING (filename)->size + 1;
482 if (fn_size < want_size)
483 fn = (char *) alloca (fn_size = 100 + want_size);
484
485 nsuffix = suffix;
486
487 /* Loop over suffixes. */
488 while (1)
489 {
490 char *esuffix = (char *) index (nsuffix, ':');
491 int lsuffix = esuffix ? esuffix - nsuffix : strlen (nsuffix);
492
493 /* Concatenate path element/specified name with the suffix. */
494 strncpy (fn, XSTRING (filename)->data, XSTRING (filename)->size);
495 fn[XSTRING (filename)->size] = 0;
496 if (lsuffix != 0) /* Bug happens on CCI if lsuffix is 0. */
497 strncat (fn, nsuffix, lsuffix);
498
499 /* Ignore file if it's a directory. */
500 if (stat (fn, &st) >= 0
501 && (st.st_mode & S_IFMT) != S_IFDIR)
502 {
503 /* Check that we can access or open it. */
504 if (exec_only)
505 fd = (access (fn, X_OK) == 0) ? 1 : -1;
506 else
507 fd = open (fn, 0, 0);
508
509 if (fd >= 0)
510 {
511 /* We succeeded; return this descriptor and filename. */
512 if (storeptr)
513 *storeptr = build_string (fn);
514 return fd;
515 }
516 }
517
518 /* Advance to next suffix. */
519 if (esuffix == 0)
520 break;
521 nsuffix += lsuffix + 1;
522 }
523 if (absolute) return -1;
524 }
525
526 return -1;
527 }
528
529 \f
530 /* Merge the list we've accumulated of globals from the current input source
531 into the load_history variable. The details depend on whether
532 the source has an associated file name or not. */
533
534 static void
535 build_load_history (stream, source)
536 FILE *stream;
537 Lisp_Object source;
538 {
539 register Lisp_Object tail, prev, newelt;
540 register Lisp_Object tem, tem2;
541 register int foundit, loading;
542
543 /* Don't bother recording anything for preloaded files. */
544 if (!NILP (Vpurify_flag))
545 return;
546
547 loading = stream || !NARROWED;
548
549 tail = Vload_history;
550 prev = Qnil;
551 foundit = 0;
552 while (!NILP (tail))
553 {
554 tem = Fcar (tail);
555
556 /* Find the feature's previous assoc list... */
557 if (!NILP (Fequal (source, Fcar (tem))))
558 {
559 foundit = 1;
560
561 /* If we're loading, remove it. */
562 if (loading)
563 {
564 if (NILP (prev))
565 Vload_history = Fcdr (tail);
566 else
567 Fsetcdr (prev, Fcdr (tail));
568 }
569
570 /* Otherwise, cons on new symbols that are not already members. */
571 else
572 {
573 tem2 = Vcurrent_load_list;
574
575 while (CONSP (tem2))
576 {
577 newelt = Fcar (tem2);
578
579 if (NILP (Fmemq (newelt, tem)))
580 Fsetcar (tail, Fcons (Fcar (tem),
581 Fcons (newelt, Fcdr (tem))));
582
583 tem2 = Fcdr (tem2);
584 QUIT;
585 }
586 }
587 }
588 else
589 prev = tail;
590 tail = Fcdr (tail);
591 QUIT;
592 }
593
594 /* If we're loading, cons the new assoc onto the front of load-history,
595 the most-recently-loaded position. Also do this if we didn't find
596 an existing member for the current source. */
597 if (loading || !foundit)
598 Vload_history = Fcons (Fnreverse (Vcurrent_load_list),
599 Vload_history);
600 }
601
602 Lisp_Object
603 unreadpure () /* Used as unwind-protect function in readevalloop */
604 {
605 read_pure = 0;
606 return Qnil;
607 }
608
609 static void
610 readevalloop (readcharfun, stream, sourcename, evalfun, printflag)
611 Lisp_Object readcharfun;
612 FILE *stream;
613 Lisp_Object sourcename;
614 Lisp_Object (*evalfun) ();
615 int printflag;
616 {
617 register int c;
618 register Lisp_Object val;
619 int count = specpdl_ptr - specpdl;
620 struct gcpro gcpro1;
621
622 specbind (Qstandard_input, readcharfun);
623 specbind (Qcurrent_load_list, Qnil);
624
625 GCPRO1 (sourcename);
626
627 LOADHIST_ATTACH (sourcename);
628
629 while (1)
630 {
631 instream = stream;
632 c = READCHAR;
633 if (c == ';')
634 {
635 while ((c = READCHAR) != '\n' && c != -1);
636 continue;
637 }
638 if (c < 0) break;
639 if (c == ' ' || c == '\t' || c == '\n' || c == '\f') continue;
640
641 if (!NILP (Vpurify_flag) && c == '(')
642 {
643 record_unwind_protect (unreadpure, Qnil);
644 val = read_list (-1, readcharfun);
645 unbind_to (count + 1, Qnil);
646 }
647 else
648 {
649 UNREAD (c);
650 val = read0 (readcharfun);
651 }
652
653 val = (*evalfun) (val);
654 if (printflag)
655 {
656 Vvalues = Fcons (val, Vvalues);
657 if (EQ (Vstandard_output, Qt))
658 Fprin1 (val, Qnil);
659 else
660 Fprint (val, Qnil);
661 }
662 }
663
664 build_load_history (stream, sourcename);
665 UNGCPRO;
666
667 unbind_to (count, Qnil);
668 }
669
670 #ifndef standalone
671
672 DEFUN ("eval-buffer", Feval_buffer, Seval_buffer, 0, 2, "",
673 "Execute the current buffer as Lisp code.\n\
674 Programs can pass two arguments, BUFFER and PRINTFLAG.\n\
675 BUFFER is the buffer to evaluate (nil means use current buffer).\n\
676 PRINTFLAG controls printing of output:\n\
677 nil means discard it; anything else is stream for print.\n\
678 \n\
679 If there is no error, point does not move. If there is an error,\n\
680 point remains at the end of the last character read from the buffer.")
681 (bufname, printflag)
682 Lisp_Object bufname, printflag;
683 {
684 int count = specpdl_ptr - specpdl;
685 Lisp_Object tem, buf;
686
687 if (NILP (bufname))
688 buf = Fcurrent_buffer ();
689 else
690 buf = Fget_buffer (bufname);
691 if (NILP (buf))
692 error ("No such buffer.");
693
694 if (NILP (printflag))
695 tem = Qsymbolp;
696 else
697 tem = printflag;
698 specbind (Qstandard_output, tem);
699 record_unwind_protect (save_excursion_restore, save_excursion_save ());
700 BUF_SET_PT (XBUFFER (buf), BUF_BEGV (XBUFFER (buf)));
701 readevalloop (buf, 0, XBUFFER (buf)->filename, Feval, !NILP (printflag));
702 unbind_to (count, Qnil);
703
704 return Qnil;
705 }
706
707 #if 0
708 DEFUN ("eval-current-buffer", Feval_current_buffer, Seval_current_buffer, 0, 1, "",
709 "Execute the current buffer as Lisp code.\n\
710 Programs can pass argument PRINTFLAG which controls printing of output:\n\
711 nil means discard it; anything else is stream for print.\n\
712 \n\
713 If there is no error, point does not move. If there is an error,\n\
714 point remains at the end of the last character read from the buffer.")
715 (printflag)
716 Lisp_Object printflag;
717 {
718 int count = specpdl_ptr - specpdl;
719 Lisp_Object tem, cbuf;
720
721 cbuf = Fcurrent_buffer ()
722
723 if (NILP (printflag))
724 tem = Qsymbolp;
725 else
726 tem = printflag;
727 specbind (Qstandard_output, tem);
728 record_unwind_protect (save_excursion_restore, save_excursion_save ());
729 SET_PT (BEGV);
730 readevalloop (cbuf, 0, XBUFFER (cbuf)->filename, Feval, !NILP (printflag));
731 return unbind_to (count, Qnil);
732 }
733 #endif
734
735 DEFUN ("eval-region", Feval_region, Seval_region, 2, 3, "r",
736 "Execute the region as Lisp code.\n\
737 When called from programs, expects two arguments,\n\
738 giving starting and ending indices in the current buffer\n\
739 of the text to be executed.\n\
740 Programs can pass third argument PRINTFLAG which controls output:\n\
741 nil means discard it; anything else is stream for printing it.\n\
742 \n\
743 If there is no error, point does not move. If there is an error,\n\
744 point remains at the end of the last character read from the buffer.")
745 (b, e, printflag)
746 Lisp_Object b, e, printflag;
747 {
748 int count = specpdl_ptr - specpdl;
749 Lisp_Object tem, cbuf;
750
751 cbuf = Fcurrent_buffer ();
752
753 if (NILP (printflag))
754 tem = Qsymbolp;
755 else
756 tem = printflag;
757 specbind (Qstandard_output, tem);
758
759 if (NILP (printflag))
760 record_unwind_protect (save_excursion_restore, save_excursion_save ());
761 record_unwind_protect (save_restriction_restore, save_restriction_save ());
762
763 /* This both uses b and checks its type. */
764 Fgoto_char (b);
765 Fnarrow_to_region (make_number (BEGV), e);
766 readevalloop (cbuf, 0, XBUFFER (cbuf)->filename, Feval, !NILP (printflag));
767
768 return unbind_to (count, Qnil);
769 }
770
771 #endif /* standalone */
772 \f
773 DEFUN ("read", Fread, Sread, 0, 1, 0,
774 "Read one Lisp expression as text from STREAM, return as Lisp object.\n\
775 If STREAM is nil, use the value of `standard-input' (which see).\n\
776 STREAM or the value of `standard-input' may be:\n\
777 a buffer (read from point and advance it)\n\
778 a marker (read from where it points and advance it)\n\
779 a function (call it with no arguments for each character,\n\
780 call it with a char as argument to push a char back)\n\
781 a string (takes text from string, starting at the beginning)\n\
782 t (read text line using minibuffer and use it).")
783 (readcharfun)
784 Lisp_Object readcharfun;
785 {
786 extern Lisp_Object Fread_minibuffer ();
787
788 if (NILP (readcharfun))
789 readcharfun = Vstandard_input;
790 if (EQ (readcharfun, Qt))
791 readcharfun = Qread_char;
792
793 #ifndef standalone
794 if (EQ (readcharfun, Qread_char))
795 return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
796 #endif
797
798 if (XTYPE (readcharfun) == Lisp_String)
799 return Fcar (Fread_from_string (readcharfun, Qnil, Qnil));
800
801 return read0 (readcharfun);
802 }
803
804 DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
805 "Read one Lisp expression which is represented as text by STRING.\n\
806 Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).\n\
807 START and END optionally delimit a substring of STRING from which to read;\n\
808 they default to 0 and (length STRING) respectively.")
809 (string, start, end)
810 Lisp_Object string, start, end;
811 {
812 int startval, endval;
813 Lisp_Object tem;
814
815 CHECK_STRING (string,0);
816
817 if (NILP (end))
818 endval = XSTRING (string)->size;
819 else
820 { CHECK_NUMBER (end,2);
821 endval = XINT (end);
822 if (endval < 0 || endval > XSTRING (string)->size)
823 args_out_of_range (string, end);
824 }
825
826 if (NILP (start))
827 startval = 0;
828 else
829 { CHECK_NUMBER (start,1);
830 startval = XINT (start);
831 if (startval < 0 || startval > endval)
832 args_out_of_range (string, start);
833 }
834
835 read_from_string_index = startval;
836 read_from_string_limit = endval;
837
838 tem = read0 (string);
839 return Fcons (tem, make_number (read_from_string_index));
840 }
841 \f
842 /* Use this for recursive reads, in contexts where internal tokens are not allowed. */
843
844 static Lisp_Object
845 read0 (readcharfun)
846 Lisp_Object readcharfun;
847 {
848 register Lisp_Object val;
849 char c;
850
851 val = read1 (readcharfun);
852 if (XTYPE (val) == Lisp_Internal)
853 {
854 c = XINT (val);
855 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (&c, 1), Qnil));
856 }
857
858 return val;
859 }
860 \f
861 static int read_buffer_size;
862 static char *read_buffer;
863
864 static int
865 read_escape (readcharfun)
866 Lisp_Object readcharfun;
867 {
868 register int c = READCHAR;
869 switch (c)
870 {
871 case 'a':
872 return '\007';
873 case 'b':
874 return '\b';
875 case 'd':
876 return 0177;
877 case 'e':
878 return 033;
879 case 'f':
880 return '\f';
881 case 'n':
882 return '\n';
883 case 'r':
884 return '\r';
885 case 't':
886 return '\t';
887 case 'v':
888 return '\v';
889 case '\n':
890 return -1;
891
892 case 'M':
893 c = READCHAR;
894 if (c != '-')
895 error ("Invalid escape character syntax");
896 c = READCHAR;
897 if (c == '\\')
898 c = read_escape (readcharfun);
899 return c | meta_modifier;
900
901 case 'S':
902 c = READCHAR;
903 if (c != '-')
904 error ("Invalid escape character syntax");
905 c = READCHAR;
906 if (c == '\\')
907 c = read_escape (readcharfun);
908 return c | shift_modifier;
909
910 case 'H':
911 c = READCHAR;
912 if (c != '-')
913 error ("Invalid escape character syntax");
914 c = READCHAR;
915 if (c == '\\')
916 c = read_escape (readcharfun);
917 return c | hyper_modifier;
918
919 case 'A':
920 c = READCHAR;
921 if (c != '-')
922 error ("Invalid escape character syntax");
923 c = READCHAR;
924 if (c == '\\')
925 c = read_escape (readcharfun);
926 return c | alt_modifier;
927
928 case 's':
929 c = READCHAR;
930 if (c != '-')
931 error ("Invalid escape character syntax");
932 c = READCHAR;
933 if (c == '\\')
934 c = read_escape (readcharfun);
935 return c | super_modifier;
936
937 case 'C':
938 c = READCHAR;
939 if (c != '-')
940 error ("Invalid escape character syntax");
941 case '^':
942 c = READCHAR;
943 if (c == '\\')
944 c = read_escape (readcharfun);
945 if ((c & 0177) == '?')
946 return 0177 | c;
947 /* ASCII control chars are made from letters (both cases),
948 as well as the non-letters within 0100...0137. */
949 else if ((c & 0137) >= 0101 && (c & 0137) <= 0132)
950 return (c & (037 | ~0177));
951 else if ((c & 0177) >= 0100 && (c & 0177) <= 0137)
952 return (c & (037 | ~0177));
953 else
954 return c | ctrl_modifier;
955
956 case '0':
957 case '1':
958 case '2':
959 case '3':
960 case '4':
961 case '5':
962 case '6':
963 case '7':
964 /* An octal escape, as in ANSI C. */
965 {
966 register int i = c - '0';
967 register int count = 0;
968 while (++count < 3)
969 {
970 if ((c = READCHAR) >= '0' && c <= '7')
971 {
972 i *= 8;
973 i += c - '0';
974 }
975 else
976 {
977 UNREAD (c);
978 break;
979 }
980 }
981 return i;
982 }
983
984 case 'x':
985 /* A hex escape, as in ANSI C. */
986 {
987 int i = 0;
988 while (1)
989 {
990 c = READCHAR;
991 if (c >= '0' && c <= '9')
992 {
993 i *= 16;
994 i += c - '0';
995 }
996 else if ((c >= 'a' && c <= 'f')
997 || (c >= 'A' && c <= 'F'))
998 {
999 i *= 16;
1000 if (c >= 'a' && c <= 'f')
1001 i += c - 'a' + 10;
1002 else
1003 i += c - 'A' + 10;
1004 }
1005 else
1006 {
1007 UNREAD (c);
1008 break;
1009 }
1010 }
1011 return i;
1012 }
1013
1014 default:
1015 return c;
1016 }
1017 }
1018
1019 static Lisp_Object
1020 read1 (readcharfun)
1021 register Lisp_Object readcharfun;
1022 {
1023 register int c;
1024
1025 retry:
1026
1027 c = READCHAR;
1028 if (c < 0) return Fsignal (Qend_of_file, Qnil);
1029
1030 switch (c)
1031 {
1032 case '(':
1033 return read_list (0, readcharfun);
1034
1035 case '[':
1036 return read_vector (readcharfun);
1037
1038 case ')':
1039 case ']':
1040 {
1041 register Lisp_Object val;
1042 XSET (val, Lisp_Internal, c);
1043 return val;
1044 }
1045
1046 case '#':
1047 c = READCHAR;
1048 if (c == '[')
1049 {
1050 /* Accept compiled functions at read-time so that we don't have to
1051 build them using function calls. */
1052 Lisp_Object tmp;
1053 tmp = read_vector (readcharfun);
1054 return Fmake_byte_code (XVECTOR (tmp)->size,
1055 XVECTOR (tmp)->contents);
1056 }
1057 #ifdef USE_TEXT_PROPERTIES
1058 if (c == '(')
1059 {
1060 Lisp_Object tmp;
1061 struct gcpro gcpro1;
1062
1063 /* Read the string itself. */
1064 tmp = read1 (readcharfun);
1065 if (XTYPE (tmp) != Lisp_String)
1066 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
1067 GCPRO1 (tmp);
1068 /* Read the intervals and their properties. */
1069 while (1)
1070 {
1071 Lisp_Object beg, end, plist;
1072
1073 beg = read1 (readcharfun);
1074 if (XTYPE (beg) == Lisp_Internal)
1075 {
1076 if (XINT (beg) == ')')
1077 break;
1078 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("invalid string property list", 28), Qnil));
1079 }
1080 end = read1 (readcharfun);
1081 if (XTYPE (end) == Lisp_Internal)
1082 Fsignal (Qinvalid_read_syntax,
1083 Fcons (make_string ("invalid string property list", 28), Qnil));
1084
1085 plist = read1 (readcharfun);
1086 if (XTYPE (plist) == Lisp_Internal)
1087 Fsignal (Qinvalid_read_syntax,
1088 Fcons (make_string ("invalid string property list", 28), Qnil));
1089 Fset_text_properties (beg, end, plist, tmp);
1090 }
1091 UNGCPRO;
1092 return tmp;
1093 }
1094 #endif
1095 UNREAD (c);
1096 Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
1097
1098 case ';':
1099 while ((c = READCHAR) >= 0 && c != '\n');
1100 goto retry;
1101
1102 case '\'':
1103 {
1104 return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
1105 }
1106
1107 case '?':
1108 {
1109 register Lisp_Object val;
1110
1111 c = READCHAR;
1112 if (c < 0) return Fsignal (Qend_of_file, Qnil);
1113
1114 if (c == '\\')
1115 XSET (val, Lisp_Int, read_escape (readcharfun));
1116 else
1117 XSET (val, Lisp_Int, c);
1118
1119 return val;
1120 }
1121
1122 case '\"':
1123 {
1124 register char *p = read_buffer;
1125 register char *end = read_buffer + read_buffer_size;
1126 register int c;
1127 int cancel = 0;
1128
1129 while ((c = READCHAR) >= 0
1130 && c != '\"')
1131 {
1132 if (p == end)
1133 {
1134 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
1135 p += new - read_buffer;
1136 read_buffer += new - read_buffer;
1137 end = read_buffer + read_buffer_size;
1138 }
1139 if (c == '\\')
1140 c = read_escape (readcharfun);
1141 /* c is -1 if \ newline has just been seen */
1142 if (c == -1)
1143 {
1144 if (p == read_buffer)
1145 cancel = 1;
1146 }
1147 else if (c & CHAR_META)
1148 /* Move the meta bit to the right place for a string. */
1149 *p++ = (c & ~CHAR_META) | 0x80;
1150 else
1151 *p++ = c;
1152 }
1153 if (c < 0) return Fsignal (Qend_of_file, Qnil);
1154
1155 /* If purifying, and string starts with \ newline,
1156 return zero instead. This is for doc strings
1157 that we are really going to find in etc/DOC.nn.nn */
1158 if (!NILP (Vpurify_flag) && NILP (Vdoc_file_name) && cancel)
1159 return make_number (0);
1160
1161 if (read_pure)
1162 return make_pure_string (read_buffer, p - read_buffer);
1163 else
1164 return make_string (read_buffer, p - read_buffer);
1165 }
1166
1167 case '.':
1168 {
1169 #ifdef LISP_FLOAT_TYPE
1170 /* If a period is followed by a number, then we should read it
1171 as a floating point number. Otherwise, it denotes a dotted
1172 pair. */
1173 int next_char = READCHAR;
1174 UNREAD (next_char);
1175
1176 if (! isdigit (next_char))
1177 #endif
1178 {
1179 register Lisp_Object val;
1180 XSET (val, Lisp_Internal, c);
1181 return val;
1182 }
1183
1184 /* Otherwise, we fall through! Note that the atom-reading loop
1185 below will now loop at least once, assuring that we will not
1186 try to UNREAD two characters in a row. */
1187 }
1188 default:
1189 if (c <= 040) goto retry;
1190 {
1191 register char *p = read_buffer;
1192
1193 {
1194 register char *end = read_buffer + read_buffer_size;
1195
1196 while (c > 040 &&
1197 !(c == '\"' || c == '\'' || c == ';' || c == '?'
1198 || c == '(' || c == ')'
1199 #ifndef LISP_FLOAT_TYPE
1200 /* If we have floating-point support, then we need
1201 to allow <digits><dot><digits>. */
1202 || c =='.'
1203 #endif /* not LISP_FLOAT_TYPE */
1204 || c == '[' || c == ']' || c == '#'
1205 ))
1206 {
1207 if (p == end)
1208 {
1209 register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
1210 p += new - read_buffer;
1211 read_buffer += new - read_buffer;
1212 end = read_buffer + read_buffer_size;
1213 }
1214 if (c == '\\')
1215 c = READCHAR;
1216 *p++ = c;
1217 c = READCHAR;
1218 }
1219
1220 if (p == end)
1221 {
1222 char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
1223 p += new - read_buffer;
1224 read_buffer += new - read_buffer;
1225 /* end = read_buffer + read_buffer_size; */
1226 }
1227 *p = 0;
1228 if (c >= 0)
1229 UNREAD (c);
1230 }
1231
1232 /* Is it an integer? */
1233 {
1234 register char *p1;
1235 register Lisp_Object val;
1236 p1 = read_buffer;
1237 if (*p1 == '+' || *p1 == '-') p1++;
1238 if (p1 != p)
1239 {
1240 while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++;
1241 #ifdef LISP_FLOAT_TYPE
1242 /* Integers can have trailing decimal points. */
1243 if (p1 > read_buffer && p1 < p && *p1 == '.') p1++;
1244 #endif
1245 if (p1 == p)
1246 /* It is an integer. */
1247 {
1248 #ifdef LISP_FLOAT_TYPE
1249 if (p1[-1] == '.')
1250 p1[-1] = '\0';
1251 #endif
1252 XSET (val, Lisp_Int, atoi (read_buffer));
1253 return val;
1254 }
1255 }
1256 #ifdef LISP_FLOAT_TYPE
1257 if (isfloat_string (read_buffer))
1258 return make_float (atof (read_buffer));
1259 #endif
1260 }
1261
1262 return intern (read_buffer);
1263 }
1264 }
1265 }
1266 \f
1267 #ifdef LISP_FLOAT_TYPE
1268
1269 #define LEAD_INT 1
1270 #define DOT_CHAR 2
1271 #define TRAIL_INT 4
1272 #define E_CHAR 8
1273 #define EXP_INT 16
1274
1275 int
1276 isfloat_string (cp)
1277 register char *cp;
1278 {
1279 register state;
1280
1281 state = 0;
1282 if (*cp == '+' || *cp == '-')
1283 cp++;
1284
1285 if (isdigit(*cp))
1286 {
1287 state |= LEAD_INT;
1288 while (isdigit (*cp))
1289 cp ++;
1290 }
1291 if (*cp == '.')
1292 {
1293 state |= DOT_CHAR;
1294 cp++;
1295 }
1296 if (isdigit(*cp))
1297 {
1298 state |= TRAIL_INT;
1299 while (isdigit (*cp))
1300 cp++;
1301 }
1302 if (*cp == 'e')
1303 {
1304 state |= E_CHAR;
1305 cp++;
1306 }
1307 if ((*cp == '+') || (*cp == '-'))
1308 cp++;
1309
1310 if (isdigit (*cp))
1311 {
1312 state |= EXP_INT;
1313 while (isdigit (*cp))
1314 cp++;
1315 }
1316 return (*cp == 0
1317 && (state == (LEAD_INT|DOT_CHAR|TRAIL_INT)
1318 || state == (DOT_CHAR|TRAIL_INT)
1319 || state == (LEAD_INT|E_CHAR|EXP_INT)
1320 || state == (LEAD_INT|DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)
1321 || state == (DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)));
1322 }
1323 #endif /* LISP_FLOAT_TYPE */
1324 \f
1325 static Lisp_Object
1326 read_vector (readcharfun)
1327 Lisp_Object readcharfun;
1328 {
1329 register int i;
1330 register int size;
1331 register Lisp_Object *ptr;
1332 register Lisp_Object tem, vector;
1333 register struct Lisp_Cons *otem;
1334 Lisp_Object len;
1335
1336 tem = read_list (1, readcharfun);
1337 len = Flength (tem);
1338 vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
1339
1340
1341 size = XVECTOR (vector)->size;
1342 ptr = XVECTOR (vector)->contents;
1343 for (i = 0; i < size; i++)
1344 {
1345 ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem);
1346 otem = XCONS (tem);
1347 tem = Fcdr (tem);
1348 free_cons (otem);
1349 }
1350 return vector;
1351 }
1352
1353 /* flag = 1 means check for ] to terminate rather than ) and .
1354 flag = -1 means check for starting with defun
1355 and make structure pure. */
1356
1357 static Lisp_Object
1358 read_list (flag, readcharfun)
1359 int flag;
1360 register Lisp_Object readcharfun;
1361 {
1362 /* -1 means check next element for defun,
1363 0 means don't check,
1364 1 means already checked and found defun. */
1365 int defunflag = flag < 0 ? -1 : 0;
1366 Lisp_Object val, tail;
1367 register Lisp_Object elt, tem;
1368 struct gcpro gcpro1, gcpro2;
1369
1370 val = Qnil;
1371 tail = Qnil;
1372
1373 while (1)
1374 {
1375 GCPRO2 (val, tail);
1376 elt = read1 (readcharfun);
1377 UNGCPRO;
1378 if (XTYPE (elt) == Lisp_Internal)
1379 {
1380 if (flag > 0)
1381 {
1382 if (XINT (elt) == ']')
1383 return val;
1384 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (") or . in a vector", 18), Qnil));
1385 }
1386 if (XINT (elt) == ')')
1387 return val;
1388 if (XINT (elt) == '.')
1389 {
1390 GCPRO2 (val, tail);
1391 if (!NILP (tail))
1392 XCONS (tail)->cdr = read0 (readcharfun);
1393 else
1394 val = read0 (readcharfun);
1395 elt = read1 (readcharfun);
1396 UNGCPRO;
1397 if (XTYPE (elt) == Lisp_Internal && XINT (elt) == ')')
1398 return val;
1399 return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil));
1400 }
1401 return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("] in a list", 11), Qnil));
1402 }
1403 tem = (read_pure && flag <= 0
1404 ? pure_cons (elt, Qnil)
1405 : Fcons (elt, Qnil));
1406 if (!NILP (tail))
1407 XCONS (tail)->cdr = tem;
1408 else
1409 val = tem;
1410 tail = tem;
1411 if (defunflag < 0)
1412 defunflag = EQ (elt, Qdefun);
1413 else if (defunflag > 0)
1414 read_pure = 1;
1415 }
1416 }
1417 \f
1418 Lisp_Object Vobarray;
1419 Lisp_Object initial_obarray;
1420
1421 Lisp_Object
1422 check_obarray (obarray)
1423 Lisp_Object obarray;
1424 {
1425 while (XTYPE (obarray) != Lisp_Vector || XVECTOR (obarray)->size == 0)
1426 {
1427 /* If Vobarray is now invalid, force it to be valid. */
1428 if (EQ (Vobarray, obarray)) Vobarray = initial_obarray;
1429
1430 obarray = wrong_type_argument (Qvectorp, obarray);
1431 }
1432 return obarray;
1433 }
1434
1435 static int hash_string ();
1436 Lisp_Object oblookup ();
1437
1438 Lisp_Object
1439 intern (str)
1440 char *str;
1441 {
1442 Lisp_Object tem;
1443 int len = strlen (str);
1444 Lisp_Object obarray = Vobarray;
1445
1446 if (XTYPE (obarray) != Lisp_Vector || XVECTOR (obarray)->size == 0)
1447 obarray = check_obarray (obarray);
1448 tem = oblookup (obarray, str, len);
1449 if (XTYPE (tem) == Lisp_Symbol)
1450 return tem;
1451 return Fintern ((!NILP (Vpurify_flag)
1452 ? make_pure_string (str, len)
1453 : make_string (str, len)),
1454 obarray);
1455 }
1456
1457 DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
1458 "Return the canonical symbol whose name is STRING.\n\
1459 If there is none, one is created by this function and returned.\n\
1460 A second optional argument specifies the obarray to use;\n\
1461 it defaults to the value of `obarray'.")
1462 (str, obarray)
1463 Lisp_Object str, obarray;
1464 {
1465 register Lisp_Object tem, sym, *ptr;
1466
1467 if (NILP (obarray)) obarray = Vobarray;
1468 obarray = check_obarray (obarray);
1469
1470 CHECK_STRING (str, 0);
1471
1472 tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
1473 if (XTYPE (tem) != Lisp_Int)
1474 return tem;
1475
1476 if (!NILP (Vpurify_flag))
1477 str = Fpurecopy (str);
1478 sym = Fmake_symbol (str);
1479
1480 ptr = &XVECTOR (obarray)->contents[XINT (tem)];
1481 if (XTYPE (*ptr) == Lisp_Symbol)
1482 XSYMBOL (sym)->next = XSYMBOL (*ptr);
1483 else
1484 XSYMBOL (sym)->next = 0;
1485 *ptr = sym;
1486 return sym;
1487 }
1488
1489 DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
1490 "Return the canonical symbol whose name is STRING, or nil if none exists.\n\
1491 A second optional argument specifies the obarray to use;\n\
1492 it defaults to the value of `obarray'.")
1493 (str, obarray)
1494 Lisp_Object str, obarray;
1495 {
1496 register Lisp_Object tem;
1497
1498 if (NILP (obarray)) obarray = Vobarray;
1499 obarray = check_obarray (obarray);
1500
1501 CHECK_STRING (str, 0);
1502
1503 tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
1504 if (XTYPE (tem) != Lisp_Int)
1505 return tem;
1506 return Qnil;
1507 }
1508
1509 Lisp_Object
1510 oblookup (obarray, ptr, size)
1511 Lisp_Object obarray;
1512 register char *ptr;
1513 register int size;
1514 {
1515 int hash, obsize;
1516 register Lisp_Object tail;
1517 Lisp_Object bucket, tem;
1518
1519 if (XTYPE (obarray) != Lisp_Vector ||
1520 (obsize = XVECTOR (obarray)->size) == 0)
1521 {
1522 obarray = check_obarray (obarray);
1523 obsize = XVECTOR (obarray)->size;
1524 }
1525 /* Combining next two lines breaks VMS C 2.3. */
1526 hash = hash_string (ptr, size);
1527 hash %= obsize;
1528 bucket = XVECTOR (obarray)->contents[hash];
1529 if (XFASTINT (bucket) == 0)
1530 ;
1531 else if (XTYPE (bucket) != Lisp_Symbol)
1532 error ("Bad data in guts of obarray"); /* Like CADR error message */
1533 else for (tail = bucket; ; XSET (tail, Lisp_Symbol, XSYMBOL (tail)->next))
1534 {
1535 if (XSYMBOL (tail)->name->size == size &&
1536 !bcmp (XSYMBOL (tail)->name->data, ptr, size))
1537 return tail;
1538 else if (XSYMBOL (tail)->next == 0)
1539 break;
1540 }
1541 XSET (tem, Lisp_Int, hash);
1542 return tem;
1543 }
1544
1545 static int
1546 hash_string (ptr, len)
1547 unsigned char *ptr;
1548 int len;
1549 {
1550 register unsigned char *p = ptr;
1551 register unsigned char *end = p + len;
1552 register unsigned char c;
1553 register int hash = 0;
1554
1555 while (p != end)
1556 {
1557 c = *p++;
1558 if (c >= 0140) c -= 40;
1559 hash = ((hash<<3) + (hash>>28) + c);
1560 }
1561 return hash & 07777777777;
1562 }
1563
1564 void
1565 map_obarray (obarray, fn, arg)
1566 Lisp_Object obarray;
1567 int (*fn) ();
1568 Lisp_Object arg;
1569 {
1570 register int i;
1571 register Lisp_Object tail;
1572 CHECK_VECTOR (obarray, 1);
1573 for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
1574 {
1575 tail = XVECTOR (obarray)->contents[i];
1576 if (XFASTINT (tail) != 0)
1577 while (1)
1578 {
1579 (*fn) (tail, arg);
1580 if (XSYMBOL (tail)->next == 0)
1581 break;
1582 XSET (tail, Lisp_Symbol, XSYMBOL (tail)->next);
1583 }
1584 }
1585 }
1586
1587 mapatoms_1 (sym, function)
1588 Lisp_Object sym, function;
1589 {
1590 call1 (function, sym);
1591 }
1592
1593 DEFUN ("mapatoms", Fmapatoms, Smapatoms, 1, 2, 0,
1594 "Call FUNCTION on every symbol in OBARRAY.\n\
1595 OBARRAY defaults to the value of `obarray'.")
1596 (function, obarray)
1597 Lisp_Object function, obarray;
1598 {
1599 Lisp_Object tem;
1600
1601 if (NILP (obarray)) obarray = Vobarray;
1602 obarray = check_obarray (obarray);
1603
1604 map_obarray (obarray, mapatoms_1, function);
1605 return Qnil;
1606 }
1607
1608 #define OBARRAY_SIZE 509
1609
1610 void
1611 init_obarray ()
1612 {
1613 Lisp_Object oblength;
1614 int hash;
1615 Lisp_Object *tem;
1616
1617 XFASTINT (oblength) = OBARRAY_SIZE;
1618
1619 Qnil = Fmake_symbol (make_pure_string ("nil", 3));
1620 Vobarray = Fmake_vector (oblength, make_number (0));
1621 initial_obarray = Vobarray;
1622 staticpro (&initial_obarray);
1623 /* Intern nil in the obarray */
1624 /* These locals are to kludge around a pyramid compiler bug. */
1625 hash = hash_string ("nil", 3);
1626 /* Separate statement here to avoid VAXC bug. */
1627 hash %= OBARRAY_SIZE;
1628 tem = &XVECTOR (Vobarray)->contents[hash];
1629 *tem = Qnil;
1630
1631 Qunbound = Fmake_symbol (make_pure_string ("unbound", 7));
1632 XSYMBOL (Qnil)->function = Qunbound;
1633 XSYMBOL (Qunbound)->value = Qunbound;
1634 XSYMBOL (Qunbound)->function = Qunbound;
1635
1636 Qt = intern ("t");
1637 XSYMBOL (Qnil)->value = Qnil;
1638 XSYMBOL (Qnil)->plist = Qnil;
1639 XSYMBOL (Qt)->value = Qt;
1640
1641 /* Qt is correct even if CANNOT_DUMP. loadup.el will set to nil at end. */
1642 Vpurify_flag = Qt;
1643
1644 Qvariable_documentation = intern ("variable-documentation");
1645
1646 read_buffer_size = 100;
1647 read_buffer = (char *) malloc (read_buffer_size);
1648 }
1649 \f
1650 void
1651 defsubr (sname)
1652 struct Lisp_Subr *sname;
1653 {
1654 Lisp_Object sym;
1655 sym = intern (sname->symbol_name);
1656 XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
1657 }
1658
1659 #ifdef NOTDEF /* use fset in subr.el now */
1660 void
1661 defalias (sname, string)
1662 struct Lisp_Subr *sname;
1663 char *string;
1664 {
1665 Lisp_Object sym;
1666 sym = intern (string);
1667 XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
1668 }
1669 #endif /* NOTDEF */
1670
1671 /* New replacement for DefIntVar; it ignores the doc string argument
1672 on the assumption that make-docfile will handle that. */
1673 /* Define an "integer variable"; a symbol whose value is forwarded
1674 to a C variable of type int. Sample call: */
1675 /* DEFVARINT ("indent-tabs-mode", &indent_tabs_mode, "Documentation"); */
1676
1677 void
1678 defvar_int (namestring, address, doc)
1679 char *namestring;
1680 int *address;
1681 char *doc;
1682 {
1683 Lisp_Object sym;
1684 sym = intern (namestring);
1685 XSET (XSYMBOL (sym)->value, Lisp_Intfwd, address);
1686 }
1687
1688 /* Similar but define a variable whose value is T if address contains 1,
1689 NIL if address contains 0 */
1690
1691 void
1692 defvar_bool (namestring, address, doc)
1693 char *namestring;
1694 int *address;
1695 char *doc;
1696 {
1697 Lisp_Object sym;
1698 sym = intern (namestring);
1699 XSET (XSYMBOL (sym)->value, Lisp_Boolfwd, address);
1700 }
1701
1702 /* Similar but define a variable whose value is the Lisp Object stored at address. */
1703
1704 void
1705 defvar_lisp (namestring, address, doc)
1706 char *namestring;
1707 Lisp_Object *address;
1708 char *doc;
1709 {
1710 Lisp_Object sym;
1711 sym = intern (namestring);
1712 XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
1713 staticpro (address);
1714 }
1715
1716 /* Similar but don't request gc-marking of the C variable.
1717 Used when that variable will be gc-marked for some other reason,
1718 since marking the same slot twice can cause trouble with strings. */
1719
1720 void
1721 defvar_lisp_nopro (namestring, address, doc)
1722 char *namestring;
1723 Lisp_Object *address;
1724 char *doc;
1725 {
1726 Lisp_Object sym;
1727 sym = intern (namestring);
1728 XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
1729 }
1730
1731 #ifndef standalone
1732
1733 /* Similar but define a variable whose value is the Lisp Object stored in
1734 the current buffer. address is the address of the slot in the buffer that is current now. */
1735
1736 void
1737 defvar_per_buffer (namestring, address, type, doc)
1738 char *namestring;
1739 Lisp_Object *address;
1740 Lisp_Object type;
1741 char *doc;
1742 {
1743 Lisp_Object sym;
1744 int offset;
1745 extern struct buffer buffer_local_symbols;
1746
1747 sym = intern (namestring);
1748 offset = (char *)address - (char *)current_buffer;
1749
1750 XSET (XSYMBOL (sym)->value, Lisp_Buffer_Objfwd,
1751 (Lisp_Object *) offset);
1752 *(Lisp_Object *)(offset + (char *)&buffer_local_symbols) = sym;
1753 *(Lisp_Object *)(offset + (char *)&buffer_local_types) = type;
1754 if (*(int *)(offset + (char *)&buffer_local_flags) == 0)
1755 /* Did a DEFVAR_PER_BUFFER without initializing the corresponding
1756 slot of buffer_local_flags */
1757 abort ();
1758 }
1759
1760 #endif /* standalone */
1761 \f
1762 init_lread ()
1763 {
1764 char *normal;
1765
1766 /* Compute the default load-path. */
1767 #ifdef CANNOT_DUMP
1768 normal = PATH_LOADSEARCH;
1769 Vload_path = decode_env_path (0, normal);
1770 #else
1771 if (NILP (Vpurify_flag))
1772 normal = PATH_LOADSEARCH;
1773 else
1774 normal = PATH_DUMPLOADSEARCH;
1775
1776 /* In a dumped Emacs, we normally have to reset the value of
1777 Vload_path from PATH_LOADSEARCH, since the value that was dumped
1778 uses ../lisp, instead of the path of the installed elisp
1779 libraries. However, if it appears that Vload_path was changed
1780 from the default before dumping, don't override that value. */
1781 if (initialized)
1782 {
1783 Lisp_Object dump_path;
1784
1785 dump_path = decode_env_path (0, PATH_DUMPLOADSEARCH);
1786 if (! NILP (Fequal (dump_path, Vload_path)))
1787 {
1788 Vload_path = decode_env_path (0, normal);
1789 if (!NILP (Vinvocation_directory))
1790 {
1791 /* Add to the path the ../lisp dir of the Emacs executable,
1792 if that dir exists. */
1793 Lisp_Object tem, tem1;
1794 tem = Fexpand_file_name (build_string ("../lisp"),
1795 Vinvocation_directory);
1796 tem1 = Ffile_exists_p (tem);
1797 if (!NILP (tem1) && NILP (Fmember (tem, Vload_path)))
1798 Vload_path = nconc2 (Vload_path, Fcons (tem, Qnil));
1799 }
1800 }
1801 }
1802 else
1803 Vload_path = decode_env_path (0, normal);
1804 #endif
1805
1806 /* Warn if dirs in the *standard* path don't exist. */
1807 {
1808 Lisp_Object path_tail;
1809
1810 for (path_tail = Vload_path;
1811 !NILP (path_tail);
1812 path_tail = XCONS (path_tail)->cdr)
1813 {
1814 Lisp_Object dirfile;
1815 dirfile = Fcar (path_tail);
1816 if (XTYPE (dirfile) == Lisp_String)
1817 {
1818 dirfile = Fdirectory_file_name (dirfile);
1819 if (access (XSTRING (dirfile)->data, 0) < 0)
1820 printf ("Warning: lisp library (%s) does not exist.\n",
1821 XSTRING (Fcar (path_tail))->data);
1822 }
1823 }
1824 }
1825
1826 /* If the EMACSLOADPATH environment variable is set, use its value.
1827 This doesn't apply if we're dumping. */
1828 if (NILP (Vpurify_flag)
1829 && egetenv ("EMACSLOADPATH"))
1830 Vload_path = decode_env_path ("EMACSLOADPATH", normal);
1831
1832 Vvalues = Qnil;
1833
1834 load_in_progress = 0;
1835 }
1836
1837 void
1838 syms_of_lread ()
1839 {
1840 defsubr (&Sread);
1841 defsubr (&Sread_from_string);
1842 defsubr (&Sintern);
1843 defsubr (&Sintern_soft);
1844 defsubr (&Sload);
1845 defsubr (&Seval_buffer);
1846 defsubr (&Seval_region);
1847 defsubr (&Sread_char);
1848 defsubr (&Sread_char_exclusive);
1849 defsubr (&Sread_event);
1850 defsubr (&Sget_file_char);
1851 defsubr (&Smapatoms);
1852
1853 DEFVAR_LISP ("obarray", &Vobarray,
1854 "Symbol table for use by `intern' and `read'.\n\
1855 It is a vector whose length ought to be prime for best results.\n\
1856 The vector's contents don't make sense if examined from Lisp programs;\n\
1857 to find all the symbols in an obarray, use `mapatoms'.");
1858
1859 DEFVAR_LISP ("values", &Vvalues,
1860 "List of values of all expressions which were read, evaluated and printed.\n\
1861 Order is reverse chronological.");
1862
1863 DEFVAR_LISP ("standard-input", &Vstandard_input,
1864 "Stream for read to get input from.\n\
1865 See documentation of `read' for possible values.");
1866 Vstandard_input = Qt;
1867
1868 DEFVAR_LISP ("load-path", &Vload_path,
1869 "*List of directories to search for files to load.\n\
1870 Each element is a string (directory name) or nil (try default directory).\n\
1871 Initialized based on EMACSLOADPATH environment variable, if any,\n\
1872 otherwise to default specified by file `paths.h' when Emacs was built.");
1873
1874 DEFVAR_BOOL ("load-in-progress", &load_in_progress,
1875 "Non-nil iff inside of `load'.");
1876
1877 DEFVAR_LISP ("after-load-alist", &Vafter_load_alist,
1878 "An alist of expressions to be evalled when particular files are loaded.\n\
1879 Each element looks like (FILENAME FORMS...).\n\
1880 When `load' is run and the file-name argument is FILENAME,\n\
1881 the FORMS in the corresponding element are executed at the end of loading.\n\n\
1882 FILENAME must match exactly! Normally FILENAME is the name of a library,\n\
1883 with no directory specified, since that is how `load' is normally called.\n\
1884 An error in FORMS does not undo the load,\n\
1885 but does prevent execution of the rest of the FORMS.");
1886 Vafter_load_alist = Qnil;
1887
1888 DEFVAR_LISP ("load-history", &Vload_history,
1889 "Alist mapping source file names to symbols and features.\n\
1890 Each alist element is a list that starts with a file name,\n\
1891 except for one element (optional) that starts with nil and describes\n\
1892 definitions evaluated from buffers not visiting files.\n\
1893 The remaining elements of each list are symbols defined as functions\n\
1894 or variables, and cons cells `(provide . FEATURE)' and `(require . FEATURE)'.");
1895 Vload_history = Qnil;
1896
1897 DEFVAR_LISP ("current-load-list", &Vcurrent_load_list,
1898 "Used for internal purposes by `load'.");
1899 Vcurrent_load_list = Qnil;
1900
1901 Qcurrent_load_list = intern ("current-load-list");
1902 staticpro (&Qcurrent_load_list);
1903
1904 Qstandard_input = intern ("standard-input");
1905 staticpro (&Qstandard_input);
1906
1907 Qread_char = intern ("read-char");
1908 staticpro (&Qread_char);
1909
1910 Qget_file_char = intern ("get-file-char");
1911 staticpro (&Qget_file_char);
1912
1913 Qascii_character = intern ("ascii-character");
1914 staticpro (&Qascii_character);
1915
1916 Qload = intern ("load");
1917 staticpro (&Qload);
1918 }