297
|
1 /* Record indices of function doc strings stored in a file.
|
27560
|
2 Copyright (C) 1985, 86,93,94,95,97,98,99, 2000 Free Software Foundation, Inc.
|
297
|
3
|
|
4 This file is part of GNU Emacs.
|
|
5
|
|
6 GNU Emacs is free software; you can redistribute it and/or modify
|
|
7 it under the terms of the GNU General Public License as published by
|
10344
a6e8525a1a9d
(store_function_docstring, Fdocumentation): Use & PSEUDOVECTOR_SIZE_MASK on
Roland McGrath <roland@gnu.org>
diff
changeset
|
8 the Free Software Foundation; either version 2, or (at your option)
|
297
|
9 any later version.
|
|
10
|
|
11 GNU Emacs is distributed in the hope that it will be useful,
|
|
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14 GNU General Public License for more details.
|
|
15
|
|
16 You should have received a copy of the GNU General Public License
|
|
17 along with GNU Emacs; see the file COPYING. If not, write to
|
14186
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
19 Boston, MA 02111-1307, USA. */
|
297
|
20
|
|
21
|
4696
|
22 #include <config.h>
|
297
|
23
|
|
24 #include <sys/types.h>
|
|
25 #include <sys/file.h> /* Must be after sys/types.h for USG and BSD4_1*/
|
|
26
|
51402
|
27 #ifdef HAVE_FCNTL_H
|
297
|
28 #include <fcntl.h>
|
|
29 #endif
|
|
30
|
6862
|
31 #ifdef HAVE_UNISTD_H
|
|
32 #include <unistd.h>
|
|
33 #endif
|
|
34
|
297
|
35 #ifndef O_RDONLY
|
|
36 #define O_RDONLY 0
|
|
37 #endif
|
|
38
|
|
39 #include "lisp.h"
|
|
40 #include "buffer.h"
|
1511
|
41 #include "keyboard.h"
|
20619
|
42 #include "charset.h"
|
39697
|
43 #include "keymap.h"
|
297
|
44
|
31336
|
45 #ifdef HAVE_INDEX
|
|
46 extern char *index P_ ((const char *, int));
|
31225
|
47 #endif
|
|
48
|
40139
|
49 Lisp_Object Vdoc_file_name;
|
297
|
50
|
28334
|
51 Lisp_Object Qfunction_documentation;
|
|
52
|
5784
|
53 extern Lisp_Object Voverriding_local_map;
|
|
54
|
9087
|
55 /* For VMS versions with limited file name syntax,
|
|
56 convert the name to something VMS will allow. */
|
|
57 static void
|
|
58 munge_doc_file_name (name)
|
|
59 char *name;
|
297
|
60 {
|
|
61 #ifdef VMS
|
|
62 #ifndef VMS4_4
|
|
63 /* For VMS versions with limited file name syntax,
|
|
64 convert the name to something VMS will allow. */
|
|
65 p = name;
|
|
66 while (*p)
|
|
67 {
|
|
68 if (*p == '-')
|
|
69 *p = '_';
|
|
70 p++;
|
|
71 }
|
|
72 #endif /* not VMS4_4 */
|
|
73 #ifdef VMS4_4
|
|
74 strcpy (name, sys_translate_unix (name));
|
|
75 #endif /* VMS4_4 */
|
|
76 #endif /* VMS */
|
9087
|
77 }
|
|
78
|
14648
|
79 /* Buffer used for reading from documentation file. */
|
|
80 static char *get_doc_string_buffer;
|
|
81 static int get_doc_string_buffer_size;
|
|
82
|
22690
|
83 static unsigned char *read_bytecode_pointer;
|
41823
|
84 Lisp_Object Fsnarf_documentation P_ ((Lisp_Object));
|
22690
|
85
|
|
86 /* readchar in lread.c calls back here to fetch the next byte.
|
|
87 If UNREADFLAG is 1, we unread a byte. */
|
|
88
|
|
89 int
|
|
90 read_bytecode_char (unreadflag)
|
25758
|
91 int unreadflag;
|
22690
|
92 {
|
|
93 if (unreadflag)
|
|
94 {
|
|
95 read_bytecode_pointer--;
|
|
96 return 0;
|
|
97 }
|
|
98 return *read_bytecode_pointer++;
|
|
99 }
|
|
100
|
10202
|
101 /* Extract a doc string from a file. FILEPOS says where to get it.
|
|
102 If it is an integer, use that position in the standard DOC-... file.
|
|
103 If it is (FILE . INTEGER), use FILE as the file name
|
11252
|
104 and INTEGER as the position in that file.
|
|
105 But if INTEGER is negative, make it positive.
|
|
106 (A negative integer is used for user variables, so we can distinguish
|
22043
|
107 them without actually fetching the doc string.)
|
|
108
|
44324
|
109 If the location does not point to the beginning of a docstring
|
|
110 (e.g. because the file has been modified and the location is stale),
|
|
111 return nil.
|
|
112
|
22602
|
113 If UNIBYTE is nonzero, always make a unibyte string.
|
|
114
|
22562
|
115 If DEFINITION is nonzero, assume this is for reading
|
|
116 a dynamic function definition; convert the bytestring
|
|
117 and the constants vector with appropriate byte handling,
|
|
118 and return a cons cell. */
|
10202
|
119
|
22268
|
120 Lisp_Object
|
22602
|
121 get_doc_string (filepos, unibyte, definition)
|
10202
|
122 Lisp_Object filepos;
|
22602
|
123 int unibyte, definition;
|
9087
|
124 {
|
10202
|
125 char *from, *to;
|
9087
|
126 register int fd;
|
|
127 register char *name;
|
|
128 register char *p, *p1;
|
|
129 int minsize;
|
14552
|
130 int offset, position;
|
10202
|
131 Lisp_Object file, tem;
|
9087
|
132
|
10202
|
133 if (INTEGERP (filepos))
|
|
134 {
|
|
135 file = Vdoc_file_name;
|
|
136 position = XINT (filepos);
|
|
137 }
|
|
138 else if (CONSP (filepos))
|
|
139 {
|
25662
0a7261c1d487
Use XCAR, XCDR, and XFLOAT_DATA instead of explicit member access.
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
140 file = XCAR (filepos);
|
0a7261c1d487
Use XCAR, XCDR, and XFLOAT_DATA instead of explicit member access.
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
141 position = XINT (XCDR (filepos));
|
10202
|
142 }
|
|
143 else
|
|
144 return Qnil;
|
|
145
|
41823
|
146 if (position < 0)
|
|
147 position = - position;
|
|
148
|
10202
|
149 if (!STRINGP (Vdoc_directory))
|
9087
|
150 return Qnil;
|
|
151
|
10202
|
152 if (!STRINGP (file))
|
|
153 return Qnil;
|
49600
|
154
|
10202
|
155 /* Put the file name in NAME as a C string.
|
|
156 If it is relative, combine it with Vdoc_directory. */
|
|
157
|
|
158 tem = Ffile_name_absolute_p (file);
|
|
159 if (NILP (tem))
|
|
160 {
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
161 minsize = SCHARS (Vdoc_directory);
|
10202
|
162 /* sizeof ("../etc/") == 8 */
|
|
163 if (minsize < 8)
|
|
164 minsize = 8;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
165 name = (char *) alloca (minsize + SCHARS (file) + 8);
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
166 strcpy (name, SDATA (Vdoc_directory));
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
167 strcat (name, SDATA (file));
|
10202
|
168 munge_doc_file_name (name);
|
|
169 }
|
|
170 else
|
|
171 {
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
172 name = (char *) SDATA (file);
|
10202
|
173 }
|
297
|
174
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
175 fd = emacs_open (name, O_RDONLY, 0);
|
297
|
176 if (fd < 0)
|
9087
|
177 {
|
|
178 #ifndef CANNOT_DUMP
|
|
179 if (!NILP (Vpurify_flag))
|
|
180 {
|
|
181 /* Preparing to dump; DOC file is probably not installed.
|
|
182 So check in ../etc. */
|
|
183 strcpy (name, "../etc/");
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
184 strcat (name, SDATA (file));
|
9087
|
185 munge_doc_file_name (name);
|
|
186
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
187 fd = emacs_open (name, O_RDONLY, 0);
|
9087
|
188 }
|
|
189 #endif
|
|
190 if (fd < 0)
|
|
191 error ("Cannot open doc string file \"%s\"", name);
|
|
192 }
|
|
193
|
14552
|
194 /* Seek only to beginning of disk block. */
|
44324
|
195 /* Make sure we read at least 1024 bytes before `position'
|
|
196 so we can check the leading text for consistency. */
|
|
197 offset = min (position, max (1024, position % (8 * 1024)));
|
14552
|
198 if (0 > lseek (fd, position - offset, 0))
|
297
|
199 {
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
200 emacs_close (fd);
|
297
|
201 error ("Position %ld out of range in doc string file \"%s\"",
|
10202
|
202 position, name);
|
297
|
203 }
|
10202
|
204
|
14648
|
205 /* Read the doc string into get_doc_string_buffer.
|
|
206 P points beyond the data just read. */
|
10202
|
207
|
14648
|
208 p = get_doc_string_buffer;
|
10202
|
209 while (1)
|
297
|
210 {
|
14648
|
211 int space_left = (get_doc_string_buffer_size
|
|
212 - (p - get_doc_string_buffer));
|
10202
|
213 int nread;
|
|
214
|
14552
|
215 /* Allocate or grow the buffer if we need to. */
|
10202
|
216 if (space_left == 0)
|
|
217 {
|
14648
|
218 int in_buffer = p - get_doc_string_buffer;
|
|
219 get_doc_string_buffer_size += 16 * 1024;
|
|
220 get_doc_string_buffer
|
|
221 = (char *) xrealloc (get_doc_string_buffer,
|
|
222 get_doc_string_buffer_size + 1);
|
|
223 p = get_doc_string_buffer + in_buffer;
|
|
224 space_left = (get_doc_string_buffer_size
|
|
225 - (p - get_doc_string_buffer));
|
10202
|
226 }
|
|
227
|
14552
|
228 /* Read a disk block at a time.
|
|
229 If we read the same block last time, maybe skip this? */
|
10202
|
230 if (space_left > 1024 * 8)
|
|
231 space_left = 1024 * 8;
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
232 nread = emacs_read (fd, p, space_left);
|
10202
|
233 if (nread < 0)
|
|
234 {
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
235 emacs_close (fd);
|
10202
|
236 error ("Read error on documentation file");
|
|
237 }
|
|
238 p[nread] = 0;
|
|
239 if (!nread)
|
297
|
240 break;
|
14648
|
241 if (p == get_doc_string_buffer)
|
31225
|
242 p1 = (char *) index (p + offset, '\037');
|
14552
|
243 else
|
31225
|
244 p1 = (char *) index (p, '\037');
|
297
|
245 if (p1)
|
|
246 {
|
|
247 *p1 = 0;
|
|
248 p = p1;
|
|
249 break;
|
|
250 }
|
10202
|
251 p += nread;
|
297
|
252 }
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
253 emacs_close (fd);
|
10202
|
254
|
44324
|
255 /* Sanity checking. */
|
|
256 if (CONSP (filepos))
|
|
257 {
|
|
258 int test = 1;
|
|
259 if (get_doc_string_buffer[offset - test++] != ' ')
|
|
260 return Qnil;
|
|
261 while (get_doc_string_buffer[offset - test] >= '0'
|
|
262 && get_doc_string_buffer[offset - test] <= '9')
|
|
263 test++;
|
|
264 if (get_doc_string_buffer[offset - test++] != '@'
|
|
265 || get_doc_string_buffer[offset - test] != '#')
|
|
266 return Qnil;
|
|
267 }
|
|
268 else
|
|
269 {
|
|
270 int test = 1;
|
|
271 if (get_doc_string_buffer[offset - test++] != '\n')
|
|
272 return Qnil;
|
|
273 while (get_doc_string_buffer[offset - test] > ' ')
|
|
274 test++;
|
|
275 if (get_doc_string_buffer[offset - test] != '\037')
|
|
276 return Qnil;
|
|
277 }
|
|
278
|
10202
|
279 /* Scan the text and perform quoting with ^A (char code 1).
|
|
280 ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */
|
14648
|
281 from = get_doc_string_buffer + offset;
|
|
282 to = get_doc_string_buffer + offset;
|
10202
|
283 while (from != p)
|
|
284 {
|
|
285 if (*from == 1)
|
|
286 {
|
|
287 int c;
|
|
288
|
|
289 from++;
|
|
290 c = *from++;
|
|
291 if (c == 1)
|
|
292 *to++ = c;
|
|
293 else if (c == '0')
|
|
294 *to++ = 0;
|
|
295 else if (c == '_')
|
|
296 *to++ = 037;
|
|
297 else
|
|
298 error ("Invalid data in documentation file -- ^A followed by code 0%o", c);
|
|
299 }
|
|
300 else
|
|
301 *to++ = *from++;
|
|
302 }
|
|
303
|
22690
|
304 /* If DEFINITION, read from this buffer
|
|
305 the same way we would read bytes from a file. */
|
22562
|
306 if (definition)
|
|
307 {
|
22690
|
308 read_bytecode_pointer = get_doc_string_buffer + offset;
|
|
309 return Fread (Qlambda);
|
22562
|
310 }
|
|
311
|
22602
|
312 if (unibyte)
|
|
313 return make_unibyte_string (get_doc_string_buffer + offset,
|
|
314 to - (get_doc_string_buffer + offset));
|
|
315 else
|
24573
|
316 {
|
|
317 /* Let the data determine whether the string is multibyte,
|
|
318 even if Emacs is running in --unibyte mode. */
|
|
319 int nchars = multibyte_chars_in_text (get_doc_string_buffer + offset,
|
|
320 to - (get_doc_string_buffer + offset));
|
|
321 return make_string_from_bytes (get_doc_string_buffer + offset,
|
|
322 nchars,
|
|
323 to - (get_doc_string_buffer + offset));
|
|
324 }
|
10202
|
325 }
|
|
326
|
|
327 /* Get a string from position FILEPOS and pass it through the Lisp reader.
|
|
328 We use this for fetching the bytecode string and constants vector
|
|
329 of a compiled function from the .elc file. */
|
|
330
|
|
331 Lisp_Object
|
|
332 read_doc_string (filepos)
|
|
333 Lisp_Object filepos;
|
|
334 {
|
22602
|
335 return get_doc_string (filepos, 0, 1);
|
297
|
336 }
|
|
337
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
338 static int
|
44324
|
339 reread_doc_file (file)
|
44355
|
340 Lisp_Object file;
|
44324
|
341 {
|
45368
|
342 #if 0
|
44324
|
343 Lisp_Object reply, prompt[3];
|
|
344 struct gcpro gcpro1;
|
|
345 GCPRO1 (file);
|
|
346 prompt[0] = build_string ("File ");
|
|
347 prompt[1] = NILP (file) ? Vdoc_file_name : file;
|
45368
|
348 prompt[2] = build_string (" is out of sync. Reload? ");
|
44324
|
349 reply = Fy_or_n_p (Fconcat (3, prompt));
|
|
350 UNGCPRO;
|
|
351 if (NILP (reply))
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
352 return 0;
|
45368
|
353 #endif
|
44324
|
354
|
|
355 if (NILP (file))
|
|
356 Fsnarf_documentation (Vdoc_file_name);
|
|
357 else
|
|
358 Fload (file, Qt, Qt, Qt, Qnil);
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
359
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
360 return 1;
|
44324
|
361 }
|
|
362
|
570
|
363 DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0,
|
41001
|
364 doc: /* Return the documentation string of FUNCTION.
|
|
365 Unless a non-nil second argument RAW is given, the
|
|
366 string is passed through `substitute-command-keys'. */)
|
|
367 (function, raw)
|
647
|
368 Lisp_Object function, raw;
|
297
|
369 {
|
|
370 Lisp_Object fun;
|
|
371 Lisp_Object funcar;
|
570
|
372 Lisp_Object tem, doc;
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
373 int try_reload = 1;
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
374
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
375 documentation:
|
297
|
376
|
34363
|
377 doc = Qnil;
|
49600
|
378
|
28334
|
379 if (SYMBOLP (function)
|
|
380 && (tem = Fget (function, Qfunction_documentation),
|
|
381 !NILP (tem)))
|
|
382 return Fdocumentation_property (function, Qfunction_documentation, raw);
|
49600
|
383
|
647
|
384 fun = Findirect_function (function);
|
10002
|
385 if (SUBRP (fun))
|
297
|
386 {
|
28334
|
387 if (XSUBR (fun)->doc == 0)
|
|
388 return Qnil;
|
|
389 else if ((EMACS_INT) XSUBR (fun)->doc >= 0)
|
570
|
390 doc = build_string (XSUBR (fun)->doc);
|
297
|
391 else
|
41823
|
392 doc = make_number ((EMACS_INT) XSUBR (fun)->doc);
|
10002
|
393 }
|
|
394 else if (COMPILEDP (fun))
|
|
395 {
|
41823
|
396 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) <= COMPILED_DOC_STRING)
|
297
|
397 return Qnil;
|
41823
|
398 tem = AREF (fun, COMPILED_DOC_STRING);
|
9133
|
399 if (STRINGP (tem))
|
570
|
400 doc = tem;
|
10202
|
401 else if (NATNUMP (tem) || CONSP (tem))
|
41823
|
402 doc = tem;
|
570
|
403 else
|
|
404 return Qnil;
|
10002
|
405 }
|
|
406 else if (STRINGP (fun) || VECTORP (fun))
|
|
407 {
|
297
|
408 return build_string ("Keyboard macro.");
|
10002
|
409 }
|
|
410 else if (CONSP (fun))
|
|
411 {
|
297
|
412 funcar = Fcar (fun);
|
9133
|
413 if (!SYMBOLP (funcar))
|
297
|
414 return Fsignal (Qinvalid_function, Fcons (fun, Qnil));
|
647
|
415 else if (EQ (funcar, Qkeymap))
|
23921
|
416 return build_string ("Prefix command (definition is a keymap associating keystrokes with commands).");
|
647
|
417 else if (EQ (funcar, Qlambda)
|
|
418 || EQ (funcar, Qautoload))
|
297
|
419 {
|
13521
|
420 Lisp_Object tem1;
|
|
421 tem1 = Fcdr (Fcdr (fun));
|
|
422 tem = Fcar (tem1);
|
9133
|
423 if (STRINGP (tem))
|
570
|
424 doc = tem;
|
13521
|
425 /* Handle a doc reference--but these never come last
|
|
426 in the function body, so reject them if they are last. */
|
41823
|
427 else if ((NATNUMP (tem) || (CONSP (tem) && INTEGERP (XCDR (tem))))
|
|
428 && !NILP (XCDR (tem1)))
|
|
429 doc = tem;
|
570
|
430 else
|
|
431 return Qnil;
|
297
|
432 }
|
647
|
433 else if (EQ (funcar, Qmacro))
|
570
|
434 return Fdocumentation (Fcdr (fun), raw);
|
10002
|
435 else
|
|
436 goto oops;
|
|
437 }
|
|
438 else
|
|
439 {
|
|
440 oops:
|
|
441 Fsignal (Qinvalid_function, Fcons (fun, Qnil));
|
297
|
442 }
|
570
|
443
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
444 /* If DOC is 0, it's typically because of a dumped file missing
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
445 from the DOC file (bug in src/Makefile.in). */
|
44385
|
446 if (EQ (doc, make_number (0)))
|
|
447 doc = Qnil;
|
44381
15b5489c78d6
(Fdocumentation, Fdocumentation_property): When the doc
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
448 if (INTEGERP (doc) || CONSP (doc))
|
44324
|
449 {
|
|
450 Lisp_Object tem;
|
|
451 tem = get_doc_string (doc, 0, 0);
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
452 if (NILP (tem) && try_reload)
|
44324
|
453 {
|
|
454 /* The file is newer, we need to reset the pointers. */
|
|
455 struct gcpro gcpro1, gcpro2;
|
|
456 GCPRO2 (function, raw);
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
457 try_reload = reread_doc_file (Fcar_safe (doc));
|
44324
|
458 UNGCPRO;
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
459 if (try_reload)
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
460 {
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
461 try_reload = 0;
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
462 goto documentation;
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
463 }
|
44324
|
464 }
|
|
465 else
|
|
466 doc = tem;
|
|
467 }
|
41823
|
468
|
577
|
469 if (NILP (raw))
|
26471
|
470 doc = Fsubstitute_command_keys (doc);
|
570
|
471 return doc;
|
297
|
472 }
|
|
473
|
28036
|
474 DEFUN ("documentation-property", Fdocumentation_property,
|
|
475 Sdocumentation_property, 2, 3, 0,
|
41001
|
476 doc: /* Return the documentation string that is SYMBOL's PROP property.
|
|
477 Third argument RAW omitted or nil means pass the result through
|
|
478 `substitute-command-keys' if it is a string.
|
|
479
|
|
480 This differs from `get' in that it can refer to strings stored in the
|
|
481 `etc/DOC' file; and that it evaluates documentation properties that
|
|
482 aren't strings. */)
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
483 (symbol, prop, raw)
|
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
484 Lisp_Object symbol, prop, raw;
|
297
|
485 {
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
486 int try_reload = 1;
|
26076
|
487 Lisp_Object tem;
|
297
|
488
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
489 documentation_property:
|
49600
|
490
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
491 tem = Fget (symbol, prop);
|
44383
|
492 if (EQ (tem, make_number (0)))
|
44385
|
493 tem = Qnil;
|
44381
15b5489c78d6
(Fdocumentation, Fdocumentation_property): When the doc
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
494 if (INTEGERP (tem) || (CONSP (tem) && INTEGERP (XCDR (tem))))
|
44324
|
495 {
|
|
496 Lisp_Object doc = tem;
|
|
497 tem = get_doc_string (tem, 0, 0);
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
498 if (NILP (tem) && try_reload)
|
44324
|
499 {
|
|
500 /* The file is newer, we need to reset the pointers. */
|
|
501 struct gcpro gcpro1, gcpro2, gcpro3;
|
|
502 GCPRO3 (symbol, prop, raw);
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
503 try_reload = reread_doc_file (Fcar_safe (doc));
|
44324
|
504 UNGCPRO;
|
44348
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
505 if (try_reload)
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
506 {
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
507 try_reload = 0;
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
508 goto documentation_property;
|
80c9e94bec17
(reread_doc_file): Return whether reload was attempted.
Stefan Monnier <monnier@iro.umontreal.ca>
diff
changeset
|
509 }
|
44324
|
510 }
|
|
511 }
|
28036
|
512 else if (!STRINGP (tem))
|
|
513 /* Feval protects its argument. */
|
|
514 tem = Feval (tem);
|
49600
|
515
|
9133
|
516 if (NILP (raw) && STRINGP (tem))
|
26420
|
517 tem = Fsubstitute_command_keys (tem);
|
312
|
518 return tem;
|
297
|
519 }
|
|
520
|
1651
|
521 /* Scanning the DOC files and placing docstring offsets into functions. */
|
|
522
|
|
523 static void
|
|
524 store_function_docstring (fun, offset)
|
|
525 Lisp_Object fun;
|
10330
|
526 /* Use EMACS_INT because we get this from pointer subtraction. */
|
|
527 EMACS_INT offset;
|
1651
|
528 {
|
|
529 fun = indirect_function (fun);
|
|
530
|
|
531 /* The type determines where the docstring is stored. */
|
|
532
|
|
533 /* Lisp_Subrs have a slot for it. */
|
9133
|
534 if (SUBRP (fun))
|
1651
|
535 XSUBR (fun)->doc = (char *) - offset;
|
|
536
|
|
537 /* If it's a lisp form, stick it in the form. */
|
|
538 else if (CONSP (fun))
|
|
539 {
|
|
540 Lisp_Object tem;
|
|
541
|
25662
0a7261c1d487
Use XCAR, XCDR, and XFLOAT_DATA instead of explicit member access.
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
542 tem = XCAR (fun);
|
1651
|
543 if (EQ (tem, Qlambda) || EQ (tem, Qautoload))
|
|
544 {
|
|
545 tem = Fcdr (Fcdr (fun));
|
25662
0a7261c1d487
Use XCAR, XCDR, and XFLOAT_DATA instead of explicit member access.
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
546 if (CONSP (tem) && INTEGERP (XCAR (tem)))
|
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
547 XSETCARFASTINT (tem, offset);
|
1651
|
548 }
|
|
549 else if (EQ (tem, Qmacro))
|
25662
0a7261c1d487
Use XCAR, XCDR, and XFLOAT_DATA instead of explicit member access.
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
550 store_function_docstring (XCDR (fun), offset);
|
1651
|
551 }
|
|
552
|
|
553 /* Bytecode objects sometimes have slots for it. */
|
9133
|
554 else if (COMPILEDP (fun))
|
1651
|
555 {
|
|
556 /* This bytecode object must have a slot for the
|
|
557 docstring, since we've found a docstring for it. */
|
41823
|
558 if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_DOC_STRING)
|
|
559 XSETFASTINT (AREF (fun, COMPILED_DOC_STRING), offset);
|
1651
|
560 }
|
|
561 }
|
|
562
|
|
563
|
297
|
564 DEFUN ("Snarf-documentation", Fsnarf_documentation, Ssnarf_documentation,
|
41001
|
565 1, 1, 0,
|
41218
|
566 doc: /* Used during Emacs initialization to scan the `etc/DOC...' file.
|
|
567 This searches the `etc/DOC...' file for doc strings and
|
|
568 records them in function and variable definitions.
|
|
569 The function takes one argument, FILENAME, a string;
|
|
570 it specifies the file name (without a directory) of the DOC file.
|
|
571 That file is found in `../etc' now; later, when the dumped Emacs is run,
|
|
572 the same file name is found in the `data-directory'. */)
|
41001
|
573 (filename)
|
297
|
574 Lisp_Object filename;
|
|
575 {
|
|
576 int fd;
|
|
577 char buf[1024 + 1];
|
|
578 register int filled;
|
|
579 register int pos;
|
|
580 register char *p, *end;
|
34963
|
581 Lisp_Object sym;
|
297
|
582 char *name;
|
|
583
|
40656
|
584 CHECK_STRING (filename);
|
297
|
585
|
44324
|
586 if
|
297
|
587 #ifndef CANNOT_DUMP
|
44324
|
588 (!NILP (Vpurify_flag))
|
297
|
589 #else /* CANNOT_DUMP */
|
44324
|
590 (0)
|
|
591 #endif /* CANNOT_DUMP */
|
|
592 {
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
593 name = (char *) alloca (SCHARS (filename) + 14);
|
44324
|
594 strcpy (name, "../etc/");
|
|
595 }
|
|
596 else
|
|
597 {
|
|
598 CHECK_STRING (Vdoc_directory);
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
599 name = (char *) alloca (SCHARS (filename)
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
600 + SCHARS (Vdoc_directory) + 1);
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
601 strcpy (name, SDATA (Vdoc_directory));
|
44324
|
602 }
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
603 strcat (name, SDATA (filename)); /*** Add this line ***/
|
297
|
604 #ifdef VMS
|
|
605 #ifndef VMS4_4
|
|
606 /* For VMS versions with limited file name syntax,
|
|
607 convert the name to something VMS will allow. */
|
|
608 p = name;
|
|
609 while (*p)
|
|
610 {
|
|
611 if (*p == '-')
|
|
612 *p = '_';
|
|
613 p++;
|
|
614 }
|
|
615 #endif /* not VMS4_4 */
|
|
616 #ifdef VMS4_4
|
|
617 strcpy (name, sys_translate_unix (name));
|
|
618 #endif /* VMS4_4 */
|
|
619 #endif /* VMS */
|
|
620
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
621 fd = emacs_open (name, O_RDONLY, 0);
|
297
|
622 if (fd < 0)
|
|
623 report_file_error ("Opening doc string file",
|
|
624 Fcons (build_string (name), Qnil));
|
|
625 Vdoc_file_name = filename;
|
|
626 filled = 0;
|
|
627 pos = 0;
|
|
628 while (1)
|
|
629 {
|
|
630 if (filled < 512)
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
631 filled += emacs_read (fd, &buf[filled], sizeof buf - 1 - filled);
|
297
|
632 if (!filled)
|
|
633 break;
|
|
634
|
|
635 buf[filled] = 0;
|
|
636 p = buf;
|
|
637 end = buf + (filled < 512 ? filled : filled - 128);
|
|
638 while (p != end && *p != '\037') p++;
|
|
639 /* p points to ^_Ffunctionname\n or ^_Vvarname\n. */
|
|
640 if (p != end)
|
|
641 {
|
31225
|
642 end = (char *) index (p, '\n');
|
20619
|
643 sym = oblookup (Vobarray, p + 2,
|
|
644 multibyte_chars_in_text (p + 2, end - p - 2),
|
|
645 end - p - 2);
|
9133
|
646 if (SYMBOLP (sym))
|
297
|
647 {
|
|
648 /* Attach a docstring to a variable? */
|
|
649 if (p[1] == 'V')
|
|
650 {
|
|
651 /* Install file-position as variable-documentation property
|
|
652 and make it negative for a user-variable
|
|
653 (doc starts with a `*'). */
|
|
654 Fput (sym, Qvariable_documentation,
|
|
655 make_number ((pos + end + 1 - buf)
|
|
656 * (end[1] == '*' ? -1 : 1)));
|
|
657 }
|
|
658
|
1651
|
659 /* Attach a docstring to a function? */
|
297
|
660 else if (p[1] == 'F')
|
1651
|
661 store_function_docstring (sym, pos + end + 1 - buf);
|
297
|
662
|
1651
|
663 else
|
|
664 error ("DOC file invalid at position %d", pos);
|
297
|
665 }
|
|
666 }
|
|
667 pos += end - buf;
|
|
668 filled -= end - buf;
|
|
669 bcopy (end, buf, filled);
|
|
670 }
|
26088
b7aa6ac26872
Add support for large files, 64-bit Solaris, system locale codings.
Paul Eggert <eggert@twinsun.com>
diff
changeset
|
671 emacs_close (fd);
|
297
|
672 return Qnil;
|
|
673 }
|
|
674
|
|
675 DEFUN ("substitute-command-keys", Fsubstitute_command_keys,
|
41001
|
676 Ssubstitute_command_keys, 1, 1, 0,
|
|
677 doc: /* Substitute key descriptions for command names in STRING.
|
|
678 Return a new string which is STRING with substrings of the form \\=\\[COMMAND]
|
|
679 replaced by either: a keystroke sequence that will invoke COMMAND,
|
|
680 or "M-x COMMAND" if COMMAND is not on any keys.
|
|
681 Substrings of the form \\=\\{MAPVAR} are replaced by summaries
|
|
682 \(made by describe-bindings) of the value of MAPVAR, taken as a keymap.
|
|
683 Substrings of the form \\=\\<MAPVAR> specify to use the value of MAPVAR
|
|
684 as the keymap for future \\=\\[COMMAND] substrings.
|
|
685 \\=\\= quotes the following character and is discarded;
|
|
686 thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ into the output. */)
|
|
687 (string)
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
688 Lisp_Object string;
|
297
|
689 {
|
|
690 unsigned char *buf;
|
|
691 int changed = 0;
|
|
692 register unsigned char *strp;
|
|
693 register unsigned char *bufp;
|
|
694 int idx;
|
|
695 int bsize;
|
1511
|
696 Lisp_Object tem;
|
297
|
697 Lisp_Object keymap;
|
|
698 unsigned char *start;
|
20802
|
699 int length, length_byte;
|
1511
|
700 Lisp_Object name;
|
|
701 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
|
20619
|
702 int multibyte;
|
|
703 int nchars;
|
297
|
704
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
705 if (NILP (string))
|
297
|
706 return Qnil;
|
|
707
|
40656
|
708 CHECK_STRING (string);
|
1511
|
709 tem = Qnil;
|
|
710 keymap = Qnil;
|
|
711 name = Qnil;
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
712 GCPRO4 (string, tem, keymap, name);
|
297
|
713
|
20619
|
714 multibyte = STRING_MULTIBYTE (string);
|
|
715 nchars = 0;
|
|
716
|
5784
|
717 /* KEYMAP is either nil (which means search all the active keymaps)
|
|
718 or a specified local map (which means search just that and the
|
|
719 global map). If non-nil, it might come from Voverriding_local_map,
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
720 or from a \\<mapname> construct in STRING itself.. */
|
12261
|
721 keymap = current_kboard->Voverriding_terminal_local_map;
|
|
722 if (NILP (keymap))
|
|
723 keymap = Voverriding_local_map;
|
297
|
724
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
725 bsize = SBYTES (string);
|
297
|
726 bufp = buf = (unsigned char *) xmalloc (bsize);
|
|
727
|
50629
|
728 strp = SDATA (string);
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
729 while (strp < SDATA (string) + SBYTES (string))
|
297
|
730 {
|
|
731 if (strp[0] == '\\' && strp[1] == '=')
|
|
732 {
|
|
733 /* \= quotes the next character;
|
|
734 thus, to put in \[ without its special meaning, use \=\[. */
|
|
735 changed = 1;
|
20619
|
736 strp += 2;
|
|
737 if (multibyte)
|
|
738 {
|
|
739 int len;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
740 int maxlen = SDATA (string) + SBYTES (string) - strp;
|
20619
|
741
|
|
742 STRING_CHAR_AND_LENGTH (strp, maxlen, len);
|
|
743 if (len == 1)
|
|
744 *bufp = *strp;
|
|
745 else
|
|
746 bcopy (strp, bufp, len);
|
|
747 strp += len;
|
|
748 bufp += len;
|
|
749 nchars++;
|
|
750 }
|
|
751 else
|
|
752 *bufp++ = *strp++, nchars++;
|
297
|
753 }
|
|
754 else if (strp[0] == '\\' && strp[1] == '[')
|
|
755 {
|
5248
|
756 Lisp_Object firstkey;
|
30154
|
757 int start_idx;
|
5248
|
758
|
297
|
759 changed = 1;
|
|
760 strp += 2; /* skip \[ */
|
|
761 start = strp;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
762 start_idx = start - SDATA (string);
|
297
|
763
|
50629
|
764 while ((strp - SDATA (string)
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
765 < SBYTES (string))
|
297
|
766 && *strp != ']')
|
|
767 strp++;
|
20619
|
768 length_byte = strp - start;
|
|
769
|
297
|
770 strp++; /* skip ] */
|
|
771
|
|
772 /* Save STRP in IDX. */
|
50629
|
773 idx = strp - SDATA (string);
|
20619
|
774 tem = Fintern (make_string (start, length_byte), Qnil);
|
30154
|
775
|
|
776 /* Note the Fwhere_is_internal can GC, so we have to take
|
|
777 relocation of string contents into account. */
|
43155
|
778 tem = Fwhere_is_internal (tem, keymap, Qt, Qnil, Qnil);
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
779 strp = SDATA (string) + idx;
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
780 start = SDATA (string) + start_idx;
|
297
|
781
|
5248
|
782 /* Disregard menu bar bindings; it is positively annoying to
|
|
783 mention them when there's no menu bar, and it isn't terribly
|
|
784 useful even when there is a menu bar. */
|
5377
|
785 if (!NILP (tem))
|
|
786 {
|
|
787 firstkey = Faref (tem, make_number (0));
|
|
788 if (EQ (firstkey, Qmenu_bar))
|
|
789 tem = Qnil;
|
|
790 }
|
5248
|
791
|
485
|
792 if (NILP (tem)) /* but not on any keys */
|
297
|
793 {
|
34363
|
794 int offset = bufp - buf;
|
|
795 buf = (unsigned char *) xrealloc (buf, bsize += 4);
|
|
796 bufp = buf + offset;
|
297
|
797 bcopy ("M-x ", bufp, 4);
|
|
798 bufp += 4;
|
20619
|
799 nchars += 4;
|
|
800 if (multibyte)
|
|
801 length = multibyte_chars_in_text (start, length_byte);
|
|
802 else
|
|
803 length = length_byte;
|
297
|
804 goto subst;
|
|
805 }
|
|
806 else
|
|
807 { /* function is on a key */
|
|
808 tem = Fkey_description (tem);
|
|
809 goto subst_string;
|
|
810 }
|
|
811 }
|
|
812 /* \{foo} is replaced with a summary of the keymap (symbol-value foo).
|
|
813 \<foo> just sets the keymap used for \[cmd]. */
|
|
814 else if (strp[0] == '\\' && (strp[1] == '{' || strp[1] == '<'))
|
|
815 {
|
|
816 struct buffer *oldbuf;
|
30154
|
817 int start_idx;
|
297
|
818
|
|
819 changed = 1;
|
|
820 strp += 2; /* skip \{ or \< */
|
|
821 start = strp;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
822 start_idx = start - SDATA (string);
|
297
|
823
|
50629
|
824 while ((strp - SDATA (string) < SCHARS (string))
|
297
|
825 && *strp != '}' && *strp != '>')
|
|
826 strp++;
|
20619
|
827
|
|
828 length_byte = strp - start;
|
297
|
829 strp++; /* skip } or > */
|
|
830
|
|
831 /* Save STRP in IDX. */
|
50629
|
832 idx = strp - SDATA (string);
|
297
|
833
|
|
834 /* Get the value of the keymap in TEM, or nil if undefined.
|
|
835 Do this while still in the user's current buffer
|
|
836 in case it is a local variable. */
|
20619
|
837 name = Fintern (make_string (start, length_byte), Qnil);
|
297
|
838 tem = Fboundp (name);
|
485
|
839 if (! NILP (tem))
|
297
|
840 {
|
|
841 tem = Fsymbol_value (name);
|
485
|
842 if (! NILP (tem))
|
30154
|
843 {
|
32988
|
844 tem = get_keymap (tem, 0, 1);
|
|
845 /* Note that get_keymap can GC. */
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
846 strp = SDATA (string) + idx;
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
847 start = SDATA (string) + start_idx;
|
30154
|
848 }
|
297
|
849 }
|
|
850
|
|
851 /* Now switch to a temp buffer. */
|
|
852 oldbuf = current_buffer;
|
|
853 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
|
|
854
|
485
|
855 if (NILP (tem))
|
297
|
856 {
|
|
857 name = Fsymbol_name (name);
|
|
858 insert_string ("\nUses keymap \"");
|
20619
|
859 insert_from_string (name, 0, 0,
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
860 SCHARS (name),
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
861 SBYTES (name), 1);
|
297
|
862 insert_string ("\", which is not currently defined.\n");
|
|
863 if (start[-1] == '<') keymap = Qnil;
|
|
864 }
|
|
865 else if (start[-1] == '<')
|
|
866 keymap = tem;
|
|
867 else
|
18746
c7ada1684ebb
(Fsubstitute_command_keys): Add missing describe_map_tree argument.
Richard M. Stallman <rms@gnu.org>
diff
changeset
|
868 describe_map_tree (tem, 1, Qnil, Qnil, (char *)0, 1, 0, 0);
|
297
|
869 tem = Fbuffer_string ();
|
|
870 Ferase_buffer ();
|
|
871 set_buffer_internal (oldbuf);
|
|
872
|
|
873 subst_string:
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
874 start = SDATA (tem);
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
875 length = SCHARS (tem);
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
876 length_byte = SBYTES (tem);
|
297
|
877 subst:
|
34363
|
878 {
|
|
879 int offset = bufp - buf;
|
|
880 buf = (unsigned char *) xrealloc (buf, bsize += length_byte);
|
|
881 bufp = buf + offset;
|
|
882 bcopy (start, bufp, length_byte);
|
|
883 bufp += length_byte;
|
|
884 nchars += length;
|
|
885 /* Check STRING again in case gc relocated it. */
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
886 strp = (unsigned char *) SDATA (string) + idx;
|
34363
|
887 }
|
297
|
888 }
|
20619
|
889 else if (! multibyte) /* just copy other chars */
|
|
890 *bufp++ = *strp++, nchars++;
|
|
891 else
|
|
892 {
|
|
893 int len;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
894 int maxlen = SDATA (string) + SBYTES (string) - strp;
|
20619
|
895
|
|
896 STRING_CHAR_AND_LENGTH (strp, maxlen, len);
|
|
897 if (len == 1)
|
|
898 *bufp = *strp;
|
|
899 else
|
|
900 bcopy (strp, bufp, len);
|
|
901 strp += len;
|
|
902 bufp += len;
|
|
903 nchars++;
|
|
904 }
|
297
|
905 }
|
|
906
|
|
907 if (changed) /* don't bother if nothing substituted */
|
21252
|
908 tem = make_string_from_bytes (buf, nchars, bufp - buf);
|
297
|
909 else
|
14069
a45a97ebdf1c
(Fdocumentation, Fdocumentation_property, Fsubstitute_command_keys):
Erik Naggum <erik@naggum.no>
diff
changeset
|
910 tem = string;
|
2439
|
911 xfree (buf);
|
1511
|
912 RETURN_UNGCPRO (tem);
|
297
|
913 }
|
|
914
|
21514
|
915 void
|
297
|
916 syms_of_doc ()
|
|
917 {
|
28334
|
918 Qfunction_documentation = intern ("function-documentation");
|
|
919 staticpro (&Qfunction_documentation);
|
49600
|
920
|
297
|
921 DEFVAR_LISP ("internal-doc-file-name", &Vdoc_file_name,
|
41001
|
922 doc: /* Name of file containing documentation strings of built-in symbols. */);
|
297
|
923 Vdoc_file_name = Qnil;
|
|
924
|
|
925 defsubr (&Sdocumentation);
|
|
926 defsubr (&Sdocumentation_property);
|
|
927 defsubr (&Ssnarf_documentation);
|
|
928 defsubr (&Ssubstitute_command_keys);
|
|
929 }
|
52401
|
930
|
|
931 /* arch-tag: 56281d4d-6949-43e2-be2e-f6517de744ba
|
|
932 (do not change this comment) */
|