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