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