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