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