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