diff options
Diffstat (limited to 'src/doc.c')
| -rw-r--r-- | src/doc.c | 98 |
1 files changed, 61 insertions, 37 deletions
| @@ -36,12 +36,15 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 36 | 36 | ||
| 37 | Lisp_Object Qfunction_documentation; | 37 | Lisp_Object Qfunction_documentation; |
| 38 | 38 | ||
| 39 | extern Lisp_Object Qclosure; | ||
| 39 | /* Buffer used for reading from documentation file. */ | 40 | /* Buffer used for reading from documentation file. */ |
| 40 | static char *get_doc_string_buffer; | 41 | static char *get_doc_string_buffer; |
| 41 | static int get_doc_string_buffer_size; | 42 | static int get_doc_string_buffer_size; |
| 42 | 43 | ||
| 43 | static unsigned char *read_bytecode_pointer; | 44 | static unsigned char *read_bytecode_pointer; |
| 44 | Lisp_Object Fsnarf_documentation (Lisp_Object); | 45 | static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object, |
| 46 | Lisp_Object); | ||
| 47 | static Lisp_Object Fsnarf_documentation (Lisp_Object); | ||
| 45 | 48 | ||
| 46 | /* readchar in lread.c calls back here to fetch the next byte. | 49 | /* readchar in lread.c calls back here to fetch the next byte. |
| 47 | If UNREADFLAG is 1, we unread a byte. */ | 50 | If UNREADFLAG is 1, we unread a byte. */ |
| @@ -153,7 +156,7 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 153 | if (0 > lseek (fd, position - offset, 0)) | 156 | if (0 > lseek (fd, position - offset, 0)) |
| 154 | { | 157 | { |
| 155 | emacs_close (fd); | 158 | emacs_close (fd); |
| 156 | error ("Position %ld out of range in doc string file \"%s\"", | 159 | error ("Position %"pI"d out of range in doc string file \"%s\"", |
| 157 | position, name); | 160 | position, name); |
| 158 | } | 161 | } |
| 159 | 162 | ||
| @@ -250,7 +253,12 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 250 | else if (c == '_') | 253 | else if (c == '_') |
| 251 | *to++ = 037; | 254 | *to++ = 037; |
| 252 | else | 255 | else |
| 253 | error ("Invalid data in documentation file -- ^A followed by code 0%o", c); | 256 | { |
| 257 | unsigned char uc = c; | ||
| 258 | error ("\ | ||
| 259 | Invalid data in documentation file -- %c followed by code %03o", | ||
| 260 | 1, uc); | ||
| 261 | } | ||
| 254 | } | 262 | } |
| 255 | else | 263 | else |
| 256 | *to++ = *from++; | 264 | *to++ = *from++; |
| @@ -260,7 +268,7 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 260 | the same way we would read bytes from a file. */ | 268 | the same way we would read bytes from a file. */ |
| 261 | if (definition) | 269 | if (definition) |
| 262 | { | 270 | { |
| 263 | read_bytecode_pointer = get_doc_string_buffer + offset; | 271 | read_bytecode_pointer = (unsigned char *) get_doc_string_buffer + offset; |
| 264 | return Fread (Qlambda); | 272 | return Fread (Qlambda); |
| 265 | } | 273 | } |
| 266 | 274 | ||
| @@ -270,8 +278,10 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 270 | else | 278 | else |
| 271 | { | 279 | { |
| 272 | /* The data determines whether the string is multibyte. */ | 280 | /* The data determines whether the string is multibyte. */ |
| 273 | EMACS_INT nchars = multibyte_chars_in_text (get_doc_string_buffer + offset, | 281 | EMACS_INT nchars = |
| 274 | to - (get_doc_string_buffer + offset)); | 282 | multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer |
| 283 | + offset), | ||
| 284 | to - (get_doc_string_buffer + offset)); | ||
| 275 | return make_string_from_bytes (get_doc_string_buffer + offset, | 285 | return make_string_from_bytes (get_doc_string_buffer + offset, |
| 276 | nchars, | 286 | nchars, |
| 277 | to - (get_doc_string_buffer + offset)); | 287 | to - (get_doc_string_buffer + offset)); |
| @@ -320,39 +330,47 @@ string is passed through `substitute-command-keys'. */) | |||
| 320 | { | 330 | { |
| 321 | Lisp_Object fun; | 331 | Lisp_Object fun; |
| 322 | Lisp_Object funcar; | 332 | Lisp_Object funcar; |
| 323 | Lisp_Object tem, doc; | 333 | Lisp_Object doc; |
| 324 | int try_reload = 1; | 334 | int try_reload = 1; |
| 325 | 335 | ||
| 326 | documentation: | 336 | documentation: |
| 327 | 337 | ||
| 328 | doc = Qnil; | 338 | doc = Qnil; |
| 329 | 339 | ||
| 330 | if (SYMBOLP (function) | 340 | if (SYMBOLP (function)) |
| 331 | && (tem = Fget (function, Qfunction_documentation), | 341 | { |
| 332 | !NILP (tem))) | 342 | Lisp_Object tem = Fget (function, Qfunction_documentation); |
| 333 | return Fdocumentation_property (function, Qfunction_documentation, raw); | 343 | if (!NILP (tem)) |
| 344 | return Fdocumentation_property (function, Qfunction_documentation, | ||
| 345 | raw); | ||
| 346 | } | ||
| 334 | 347 | ||
| 335 | fun = Findirect_function (function, Qnil); | 348 | fun = Findirect_function (function, Qnil); |
| 336 | if (SUBRP (fun)) | 349 | if (SUBRP (fun)) |
| 337 | { | 350 | { |
| 338 | if (XSUBR (fun)->doc == 0) | 351 | if (XSUBR (fun)->doc == 0) |
| 339 | return Qnil; | 352 | return Qnil; |
| 340 | else if ((EMACS_INT) XSUBR (fun)->doc >= 0) | 353 | /* FIXME: This is not portable, as it assumes that string |
| 354 | pointers have the top bit clear. */ | ||
| 355 | else if ((intptr_t) XSUBR (fun)->doc >= 0) | ||
| 341 | doc = build_string (XSUBR (fun)->doc); | 356 | doc = build_string (XSUBR (fun)->doc); |
| 342 | else | 357 | else |
| 343 | doc = make_number ((EMACS_INT) XSUBR (fun)->doc); | 358 | doc = make_number ((intptr_t) XSUBR (fun)->doc); |
| 344 | } | 359 | } |
| 345 | else if (COMPILEDP (fun)) | 360 | else if (COMPILEDP (fun)) |
| 346 | { | 361 | { |
| 347 | if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) <= COMPILED_DOC_STRING) | 362 | if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) <= COMPILED_DOC_STRING) |
| 348 | return Qnil; | 363 | return Qnil; |
| 349 | tem = AREF (fun, COMPILED_DOC_STRING); | ||
| 350 | if (STRINGP (tem)) | ||
| 351 | doc = tem; | ||
| 352 | else if (NATNUMP (tem) || CONSP (tem)) | ||
| 353 | doc = tem; | ||
| 354 | else | 364 | else |
| 355 | return Qnil; | 365 | { |
| 366 | Lisp_Object tem = AREF (fun, COMPILED_DOC_STRING); | ||
| 367 | if (STRINGP (tem)) | ||
| 368 | doc = tem; | ||
| 369 | else if (NATNUMP (tem) || CONSP (tem)) | ||
| 370 | doc = tem; | ||
| 371 | else | ||
| 372 | return Qnil; | ||
| 373 | } | ||
| 356 | } | 374 | } |
| 357 | else if (STRINGP (fun) || VECTORP (fun)) | 375 | else if (STRINGP (fun) || VECTORP (fun)) |
| 358 | { | 376 | { |
| @@ -366,11 +384,11 @@ string is passed through `substitute-command-keys'. */) | |||
| 366 | else if (EQ (funcar, Qkeymap)) | 384 | else if (EQ (funcar, Qkeymap)) |
| 367 | return build_string ("Prefix command (definition is a keymap associating keystrokes with commands)."); | 385 | return build_string ("Prefix command (definition is a keymap associating keystrokes with commands)."); |
| 368 | else if (EQ (funcar, Qlambda) | 386 | else if (EQ (funcar, Qlambda) |
| 387 | || (EQ (funcar, Qclosure) && (fun = XCDR (fun), 1)) | ||
| 369 | || EQ (funcar, Qautoload)) | 388 | || EQ (funcar, Qautoload)) |
| 370 | { | 389 | { |
| 371 | Lisp_Object tem1; | 390 | Lisp_Object tem1 = Fcdr (Fcdr (fun)); |
| 372 | tem1 = Fcdr (Fcdr (fun)); | 391 | Lisp_Object tem = Fcar (tem1); |
| 373 | tem = Fcar (tem1); | ||
| 374 | if (STRINGP (tem)) | 392 | if (STRINGP (tem)) |
| 375 | doc = tem; | 393 | doc = tem; |
| 376 | /* Handle a doc reference--but these never come last | 394 | /* Handle a doc reference--but these never come last |
| @@ -473,7 +491,7 @@ aren't strings. */) | |||
| 473 | } | 491 | } |
| 474 | else if (!STRINGP (tem)) | 492 | else if (!STRINGP (tem)) |
| 475 | /* Feval protects its argument. */ | 493 | /* Feval protects its argument. */ |
| 476 | tem = Feval (tem); | 494 | tem = Feval (tem, Qnil); |
| 477 | 495 | ||
| 478 | if (NILP (raw) && STRINGP (tem)) | 496 | if (NILP (raw) && STRINGP (tem)) |
| 479 | tem = Fsubstitute_command_keys (tem); | 497 | tem = Fsubstitute_command_keys (tem); |
| @@ -492,7 +510,10 @@ store_function_docstring (Lisp_Object fun, EMACS_INT offset) | |||
| 492 | 510 | ||
| 493 | /* Lisp_Subrs have a slot for it. */ | 511 | /* Lisp_Subrs have a slot for it. */ |
| 494 | if (SUBRP (fun)) | 512 | if (SUBRP (fun)) |
| 495 | XSUBR (fun)->doc = (char *) - offset; | 513 | { |
| 514 | intptr_t negative_offset = - offset; | ||
| 515 | XSUBR (fun)->doc = (char *) negative_offset; | ||
| 516 | } | ||
| 496 | 517 | ||
| 497 | /* If it's a lisp form, stick it in the form. */ | 518 | /* If it's a lisp form, stick it in the form. */ |
| 498 | else if (CONSP (fun)) | 519 | else if (CONSP (fun)) |
| @@ -500,7 +521,8 @@ store_function_docstring (Lisp_Object fun, EMACS_INT offset) | |||
| 500 | Lisp_Object tem; | 521 | Lisp_Object tem; |
| 501 | 522 | ||
| 502 | tem = XCAR (fun); | 523 | tem = XCAR (fun); |
| 503 | if (EQ (tem, Qlambda) || EQ (tem, Qautoload)) | 524 | if (EQ (tem, Qlambda) || EQ (tem, Qautoload) |
| 525 | || (EQ (tem, Qclosure) && (fun = XCDR (fun), 1))) | ||
| 504 | { | 526 | { |
| 505 | tem = Fcdr (Fcdr (fun)); | 527 | tem = Fcdr (Fcdr (fun)); |
| 506 | if (CONSP (tem) && INTEGERP (XCAR (tem))) | 528 | if (CONSP (tem) && INTEGERP (XCAR (tem))) |
| @@ -537,7 +559,7 @@ the same file name is found in the `doc-directory'. */) | |||
| 537 | char buf[1024 + 1]; | 559 | char buf[1024 + 1]; |
| 538 | register EMACS_INT filled; | 560 | register EMACS_INT filled; |
| 539 | register EMACS_INT pos; | 561 | register EMACS_INT pos; |
| 540 | register char *p, *end; | 562 | register char *p; |
| 541 | Lisp_Object sym; | 563 | Lisp_Object sym; |
| 542 | char *name; | 564 | char *name; |
| 543 | int skip_file = 0; | 565 | int skip_file = 0; |
| @@ -596,6 +618,7 @@ the same file name is found in the `doc-directory'. */) | |||
| 596 | pos = 0; | 618 | pos = 0; |
| 597 | while (1) | 619 | while (1) |
| 598 | { | 620 | { |
| 621 | register char *end; | ||
| 599 | if (filled < 512) | 622 | if (filled < 512) |
| 600 | filled += emacs_read (fd, &buf[filled], sizeof buf - 1 - filled); | 623 | filled += emacs_read (fd, &buf[filled], sizeof buf - 1 - filled); |
| 601 | if (!filled) | 624 | if (!filled) |
| @@ -630,7 +653,8 @@ the same file name is found in the `doc-directory'. */) | |||
| 630 | } | 653 | } |
| 631 | 654 | ||
| 632 | sym = oblookup (Vobarray, p + 2, | 655 | sym = oblookup (Vobarray, p + 2, |
| 633 | multibyte_chars_in_text (p + 2, end - p - 2), | 656 | multibyte_chars_in_text ((unsigned char *) p + 2, |
| 657 | end - p - 2), | ||
| 634 | end - p - 2); | 658 | end - p - 2); |
| 635 | /* Check skip_file so that when a function is defined several | 659 | /* Check skip_file so that when a function is defined several |
| 636 | times in different files (typically, once in xterm, once in | 660 | times in different files (typically, once in xterm, once in |
| @@ -657,7 +681,7 @@ the same file name is found in the `doc-directory'. */) | |||
| 657 | ; /* Just a source file name boundary marker. Ignore it. */ | 681 | ; /* Just a source file name boundary marker. Ignore it. */ |
| 658 | 682 | ||
| 659 | else | 683 | else |
| 660 | error ("DOC file invalid at position %d", pos); | 684 | error ("DOC file invalid at position %"pI"d", pos); |
| 661 | } | 685 | } |
| 662 | } | 686 | } |
| 663 | pos += end - buf; | 687 | pos += end - buf; |
| @@ -685,10 +709,10 @@ Returns original STRING if no substitutions were made. Otherwise, | |||
| 685 | a new string, without any text properties, is returned. */) | 709 | a new string, without any text properties, is returned. */) |
| 686 | (Lisp_Object string) | 710 | (Lisp_Object string) |
| 687 | { | 711 | { |
| 688 | unsigned char *buf; | 712 | char *buf; |
| 689 | int changed = 0; | 713 | int changed = 0; |
| 690 | register unsigned char *strp; | 714 | register unsigned char *strp; |
| 691 | register unsigned char *bufp; | 715 | register char *bufp; |
| 692 | EMACS_INT idx; | 716 | EMACS_INT idx; |
| 693 | EMACS_INT bsize; | 717 | EMACS_INT bsize; |
| 694 | Lisp_Object tem; | 718 | Lisp_Object tem; |
| @@ -716,12 +740,12 @@ a new string, without any text properties, is returned. */) | |||
| 716 | or a specified local map (which means search just that and the | 740 | or a specified local map (which means search just that and the |
| 717 | global map). If non-nil, it might come from Voverriding_local_map, | 741 | global map). If non-nil, it might come from Voverriding_local_map, |
| 718 | or from a \\<mapname> construct in STRING itself.. */ | 742 | or from a \\<mapname> construct in STRING itself.. */ |
| 719 | keymap = current_kboard->Voverriding_terminal_local_map; | 743 | keymap = KVAR (current_kboard, Voverriding_terminal_local_map); |
| 720 | if (NILP (keymap)) | 744 | if (NILP (keymap)) |
| 721 | keymap = Voverriding_local_map; | 745 | keymap = Voverriding_local_map; |
| 722 | 746 | ||
| 723 | bsize = SBYTES (string); | 747 | bsize = SBYTES (string); |
| 724 | bufp = buf = (unsigned char *) xmalloc (bsize); | 748 | bufp = buf = (char *) xmalloc (bsize); |
| 725 | 749 | ||
| 726 | strp = SDATA (string); | 750 | strp = SDATA (string); |
| 727 | while (strp < SDATA (string) + SBYTES (string)) | 751 | while (strp < SDATA (string) + SBYTES (string)) |
| @@ -768,12 +792,12 @@ a new string, without any text properties, is returned. */) | |||
| 768 | 792 | ||
| 769 | /* Save STRP in IDX. */ | 793 | /* Save STRP in IDX. */ |
| 770 | idx = strp - SDATA (string); | 794 | idx = strp - SDATA (string); |
| 771 | name = Fintern (make_string (start, length_byte), Qnil); | 795 | name = Fintern (make_string ((char *) start, length_byte), Qnil); |
| 772 | 796 | ||
| 773 | do_remap: | 797 | do_remap: |
| 774 | tem = Fwhere_is_internal (name, keymap, Qt, Qnil, Qnil); | 798 | tem = Fwhere_is_internal (name, keymap, Qt, Qnil, Qnil); |
| 775 | 799 | ||
| 776 | if (VECTORP (tem) && XVECTOR (tem)->size > 1 | 800 | if (VECTORP (tem) && ASIZE (tem) > 1 |
| 777 | && EQ (AREF (tem, 0), Qremap) && SYMBOLP (AREF (tem, 1)) | 801 | && EQ (AREF (tem, 0), Qremap) && SYMBOLP (AREF (tem, 1)) |
| 778 | && follow_remap) | 802 | && follow_remap) |
| 779 | { | 803 | { |
| @@ -790,7 +814,7 @@ a new string, without any text properties, is returned. */) | |||
| 790 | if (NILP (tem)) /* but not on any keys */ | 814 | if (NILP (tem)) /* but not on any keys */ |
| 791 | { | 815 | { |
| 792 | EMACS_INT offset = bufp - buf; | 816 | EMACS_INT offset = bufp - buf; |
| 793 | buf = (unsigned char *) xrealloc (buf, bsize += 4); | 817 | buf = (char *) xrealloc (buf, bsize += 4); |
| 794 | bufp = buf + offset; | 818 | bufp = buf + offset; |
| 795 | memcpy (bufp, "M-x ", 4); | 819 | memcpy (bufp, "M-x ", 4); |
| 796 | bufp += 4; | 820 | bufp += 4; |
| @@ -835,7 +859,7 @@ a new string, without any text properties, is returned. */) | |||
| 835 | /* Get the value of the keymap in TEM, or nil if undefined. | 859 | /* Get the value of the keymap in TEM, or nil if undefined. |
| 836 | Do this while still in the user's current buffer | 860 | Do this while still in the user's current buffer |
| 837 | in case it is a local variable. */ | 861 | in case it is a local variable. */ |
| 838 | name = Fintern (make_string (start, length_byte), Qnil); | 862 | name = Fintern (make_string ((char *) start, length_byte), Qnil); |
| 839 | tem = Fboundp (name); | 863 | tem = Fboundp (name); |
| 840 | if (! NILP (tem)) | 864 | if (! NILP (tem)) |
| 841 | { | 865 | { |
| @@ -884,7 +908,7 @@ a new string, without any text properties, is returned. */) | |||
| 884 | subst: | 908 | subst: |
| 885 | { | 909 | { |
| 886 | EMACS_INT offset = bufp - buf; | 910 | EMACS_INT offset = bufp - buf; |
| 887 | buf = (unsigned char *) xrealloc (buf, bsize += length_byte); | 911 | buf = (char *) xrealloc (buf, bsize += length_byte); |
| 888 | bufp = buf + offset; | 912 | bufp = buf + offset; |
| 889 | memcpy (bufp, start, length_byte); | 913 | memcpy (bufp, start, length_byte); |
| 890 | bufp += length_byte; | 914 | bufp += length_byte; |