diff options
| author | Eli Zaretskii | 2013-09-05 11:01:04 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-09-05 11:01:04 +0300 |
| commit | 41306318777a942420bc4feadbfacf662ea179dc (patch) | |
| tree | 669e5cca02f95d6064ce73c0d3fbbf91b8c8b563 /src/doc.c | |
| parent | 141f1ff7a40cda10f0558e891dd196a943a5082e (diff) | |
| parent | 257b3b03cb1cff917e0b3b7832ad3eab5b59f257 (diff) | |
| download | emacs-41306318777a942420bc4feadbfacf662ea179dc.tar.gz emacs-41306318777a942420bc4feadbfacf662ea179dc.zip | |
Merge from trunk after a lot of time.
Diffstat (limited to 'src/doc.c')
| -rw-r--r-- | src/doc.c | 231 |
1 files changed, 112 insertions, 119 deletions
| @@ -1,6 +1,7 @@ | |||
| 1 | /* Record indices of function doc strings stored in a file. | 1 | /* Record indices of function doc strings stored in a file. |
| 2 | 2 | ||
| 3 | Copyright (C) 1985-1986, 1993-1995, 1997-2012 Free Software Foundation, Inc. | 3 | Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software Foundation, |
| 4 | Inc. | ||
| 4 | 5 | ||
| 5 | This file is part of GNU Emacs. | 6 | This file is part of GNU Emacs. |
| 6 | 7 | ||
| @@ -20,37 +21,33 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 20 | 21 | ||
| 21 | #include <config.h> | 22 | #include <config.h> |
| 22 | 23 | ||
| 24 | #include <errno.h> | ||
| 23 | #include <sys/types.h> | 25 | #include <sys/types.h> |
| 24 | #include <sys/file.h> /* Must be after sys/types.h for USG*/ | 26 | #include <sys/file.h> /* Must be after sys/types.h for USG. */ |
| 25 | #include <ctype.h> | ||
| 26 | #include <setjmp.h> | ||
| 27 | #include <fcntl.h> | 27 | #include <fcntl.h> |
| 28 | #include <unistd.h> | 28 | #include <unistd.h> |
| 29 | 29 | ||
| 30 | #include <c-ctype.h> | ||
| 31 | |||
| 30 | #include "lisp.h" | 32 | #include "lisp.h" |
| 33 | #include "character.h" | ||
| 31 | #include "buffer.h" | 34 | #include "buffer.h" |
| 32 | #include "keyboard.h" | 35 | #include "keyboard.h" |
| 33 | #include "character.h" | ||
| 34 | #include "keymap.h" | 36 | #include "keymap.h" |
| 35 | #include "buildobj.h" | ||
| 36 | 37 | ||
| 37 | Lisp_Object Qfunction_documentation; | 38 | Lisp_Object Qfunction_documentation; |
| 38 | 39 | ||
| 39 | extern Lisp_Object Qclosure; | ||
| 40 | /* Buffer used for reading from documentation file. */ | 40 | /* Buffer used for reading from documentation file. */ |
| 41 | static char *get_doc_string_buffer; | 41 | static char *get_doc_string_buffer; |
| 42 | static ptrdiff_t get_doc_string_buffer_size; | 42 | static ptrdiff_t get_doc_string_buffer_size; |
| 43 | 43 | ||
| 44 | static unsigned char *read_bytecode_pointer; | 44 | static unsigned char *read_bytecode_pointer; |
| 45 | static Lisp_Object Fdocumentation_property (Lisp_Object, Lisp_Object, | ||
| 46 | Lisp_Object); | ||
| 47 | static Lisp_Object Fsnarf_documentation (Lisp_Object); | ||
| 48 | 45 | ||
| 49 | /* readchar in lread.c calls back here to fetch the next byte. | 46 | /* `readchar' in lread.c calls back here to fetch the next byte. |
| 50 | If UNREADFLAG is 1, we unread a byte. */ | 47 | If UNREADFLAG is 1, we unread a byte. */ |
| 51 | 48 | ||
| 52 | int | 49 | int |
| 53 | read_bytecode_char (int unreadflag) | 50 | read_bytecode_char (bool unreadflag) |
| 54 | { | 51 | { |
| 55 | if (unreadflag) | 52 | if (unreadflag) |
| 56 | { | 53 | { |
| @@ -61,7 +58,7 @@ read_bytecode_char (int unreadflag) | |||
| 61 | } | 58 | } |
| 62 | 59 | ||
| 63 | /* Extract a doc string from a file. FILEPOS says where to get it. | 60 | /* Extract a doc string from a file. FILEPOS says where to get it. |
| 64 | If it is an integer, use that position in the standard DOC-... file. | 61 | If it is an integer, use that position in the standard DOC file. |
| 65 | If it is (FILE . INTEGER), use FILE as the file name | 62 | If it is (FILE . INTEGER), use FILE as the file name |
| 66 | and INTEGER as the position in that file. | 63 | and INTEGER as the position in that file. |
| 67 | But if INTEGER is negative, make it positive. | 64 | But if INTEGER is negative, make it positive. |
| @@ -72,41 +69,39 @@ read_bytecode_char (int unreadflag) | |||
| 72 | (e.g. because the file has been modified and the location is stale), | 69 | (e.g. because the file has been modified and the location is stale), |
| 73 | return nil. | 70 | return nil. |
| 74 | 71 | ||
| 75 | If UNIBYTE is nonzero, always make a unibyte string. | 72 | If UNIBYTE, always make a unibyte string. |
| 76 | 73 | ||
| 77 | If DEFINITION is nonzero, assume this is for reading | 74 | If DEFINITION, assume this is for reading |
| 78 | a dynamic function definition; convert the bytestring | 75 | a dynamic function definition; convert the bytestring |
| 79 | and the constants vector with appropriate byte handling, | 76 | and the constants vector with appropriate byte handling, |
| 80 | and return a cons cell. */ | 77 | and return a cons cell. */ |
| 81 | 78 | ||
| 82 | Lisp_Object | 79 | Lisp_Object |
| 83 | get_doc_string (Lisp_Object filepos, int unibyte, int definition) | 80 | get_doc_string (Lisp_Object filepos, bool unibyte, bool definition) |
| 84 | { | 81 | { |
| 85 | char *from, *to; | 82 | char *from, *to, *name, *p, *p1; |
| 86 | register int fd; | 83 | int fd; |
| 87 | register char *name; | ||
| 88 | register char *p, *p1; | ||
| 89 | ptrdiff_t minsize; | 84 | ptrdiff_t minsize; |
| 90 | int offset; | 85 | int offset; |
| 91 | EMACS_INT position; | 86 | EMACS_INT position; |
| 92 | Lisp_Object file, tem; | 87 | Lisp_Object file, tem, pos; |
| 88 | ptrdiff_t count; | ||
| 93 | USE_SAFE_ALLOCA; | 89 | USE_SAFE_ALLOCA; |
| 94 | 90 | ||
| 95 | if (INTEGERP (filepos)) | 91 | if (INTEGERP (filepos)) |
| 96 | { | 92 | { |
| 97 | file = Vdoc_file_name; | 93 | file = Vdoc_file_name; |
| 98 | position = XINT (filepos); | 94 | pos = filepos; |
| 99 | } | 95 | } |
| 100 | else if (CONSP (filepos)) | 96 | else if (CONSP (filepos)) |
| 101 | { | 97 | { |
| 102 | file = XCAR (filepos); | 98 | file = XCAR (filepos); |
| 103 | position = XINT (XCDR (filepos)); | 99 | pos = XCDR (filepos); |
| 104 | } | 100 | } |
| 105 | else | 101 | else |
| 106 | return Qnil; | 102 | return Qnil; |
| 107 | 103 | ||
| 108 | if (position < 0) | 104 | position = eabs (XINT (pos)); |
| 109 | position = - position; | ||
| 110 | 105 | ||
| 111 | if (!STRINGP (Vdoc_directory)) | 106 | if (!STRINGP (Vdoc_directory)) |
| 112 | return Qnil; | 107 | return Qnil; |
| @@ -126,7 +121,7 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 126 | /* sizeof ("../etc/") == 8 */ | 121 | /* sizeof ("../etc/") == 8 */ |
| 127 | if (minsize < 8) | 122 | if (minsize < 8) |
| 128 | minsize = 8; | 123 | minsize = 8; |
| 129 | SAFE_ALLOCA (name, char *, minsize + SCHARS (file) + 8); | 124 | name = SAFE_ALLOCA (minsize + SCHARS (file) + 8); |
| 130 | strcpy (name, SSDATA (docdir)); | 125 | strcpy (name, SSDATA (docdir)); |
| 131 | strcat (name, SSDATA (file)); | 126 | strcat (name, SSDATA (file)); |
| 132 | } | 127 | } |
| @@ -150,8 +145,14 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 150 | } | 145 | } |
| 151 | #endif | 146 | #endif |
| 152 | if (fd < 0) | 147 | if (fd < 0) |
| 153 | error ("Cannot open doc string file \"%s\"", name); | 148 | { |
| 149 | SAFE_FREE (); | ||
| 150 | return concat3 (build_string ("Cannot open doc string file \""), | ||
| 151 | file, build_string ("\"\n")); | ||
| 152 | } | ||
| 154 | } | 153 | } |
| 154 | count = SPECPDL_INDEX (); | ||
| 155 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 155 | 156 | ||
| 156 | /* Seek only to beginning of disk block. */ | 157 | /* Seek only to beginning of disk block. */ |
| 157 | /* Make sure we read at least 1024 bytes before `position' | 158 | /* Make sure we read at least 1024 bytes before `position' |
| @@ -159,13 +160,8 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 159 | offset = min (position, max (1024, position % (8 * 1024))); | 160 | offset = min (position, max (1024, position % (8 * 1024))); |
| 160 | if (TYPE_MAXIMUM (off_t) < position | 161 | if (TYPE_MAXIMUM (off_t) < position |
| 161 | || lseek (fd, position - offset, 0) < 0) | 162 | || lseek (fd, position - offset, 0) < 0) |
| 162 | { | 163 | error ("Position %"pI"d out of range in doc string file \"%s\"", |
| 163 | emacs_close (fd); | 164 | position, name); |
| 164 | error ("Position %"pI"d out of range in doc string file \"%s\"", | ||
| 165 | position, name); | ||
| 166 | } | ||
| 167 | |||
| 168 | SAFE_FREE (); | ||
| 169 | 165 | ||
| 170 | /* Read the doc string into get_doc_string_buffer. | 166 | /* Read the doc string into get_doc_string_buffer. |
| 171 | P points beyond the data just read. */ | 167 | P points beyond the data just read. */ |
| @@ -181,9 +177,9 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 181 | if (space_left <= 0) | 177 | if (space_left <= 0) |
| 182 | { | 178 | { |
| 183 | ptrdiff_t in_buffer = p - get_doc_string_buffer; | 179 | ptrdiff_t in_buffer = p - get_doc_string_buffer; |
| 184 | get_doc_string_buffer = | 180 | get_doc_string_buffer |
| 185 | xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, | 181 | = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size, |
| 186 | 16 * 1024, -1, 1); | 182 | 16 * 1024, -1, 1); |
| 187 | p = get_doc_string_buffer + in_buffer; | 183 | p = get_doc_string_buffer + in_buffer; |
| 188 | space_left = (get_doc_string_buffer_size - 1 | 184 | space_left = (get_doc_string_buffer_size - 1 |
| 189 | - (p - get_doc_string_buffer)); | 185 | - (p - get_doc_string_buffer)); |
| @@ -195,10 +191,7 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 195 | space_left = 1024 * 8; | 191 | space_left = 1024 * 8; |
| 196 | nread = emacs_read (fd, p, space_left); | 192 | nread = emacs_read (fd, p, space_left); |
| 197 | if (nread < 0) | 193 | if (nread < 0) |
| 198 | { | 194 | report_file_error ("Read error on documentation file", file); |
| 199 | emacs_close (fd); | ||
| 200 | error ("Read error on documentation file"); | ||
| 201 | } | ||
| 202 | p[nread] = 0; | 195 | p[nread] = 0; |
| 203 | if (!nread) | 196 | if (!nread) |
| 204 | break; | 197 | break; |
| @@ -214,20 +207,27 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition) | |||
| 214 | } | 207 | } |
| 215 | p += nread; | 208 | p += nread; |
| 216 | } | 209 | } |
| 217 | emacs_close (fd); | 210 | unbind_to (count, Qnil); |
| 211 | SAFE_FREE (); | ||
| 218 | 212 | ||
| 219 | /* Sanity checking. */ | 213 | /* Sanity checking. */ |
| 220 | if (CONSP (filepos)) | 214 | if (CONSP (filepos)) |
| 221 | { | 215 | { |
| 222 | int test = 1; | 216 | int test = 1; |
| 223 | if (get_doc_string_buffer[offset - test++] != ' ') | 217 | /* A dynamic docstring should be either at the very beginning of a "#@ |
| 224 | return Qnil; | 218 | comment" or right after a dynamic docstring delimiter (in case we |
| 225 | while (get_doc_string_buffer[offset - test] >= '0' | 219 | pack several such docstrings within the same comment). */ |
| 226 | && get_doc_string_buffer[offset - test] <= '9') | 220 | if (get_doc_string_buffer[offset - test] != '\037') |
| 227 | test++; | 221 | { |
| 228 | if (get_doc_string_buffer[offset - test++] != '@' | 222 | if (get_doc_string_buffer[offset - test++] != ' ') |
| 229 | || get_doc_string_buffer[offset - test] != '#') | 223 | return Qnil; |
| 230 | return Qnil; | 224 | while (get_doc_string_buffer[offset - test] >= '0' |
| 225 | && get_doc_string_buffer[offset - test] <= '9') | ||
| 226 | test++; | ||
| 227 | if (get_doc_string_buffer[offset - test++] != '@' | ||
| 228 | || get_doc_string_buffer[offset - test] != '#') | ||
| 229 | return Qnil; | ||
| 230 | } | ||
| 231 | } | 231 | } |
| 232 | else | 232 | else |
| 233 | { | 233 | { |
| @@ -284,10 +284,10 @@ Invalid data in documentation file -- %c followed by code %03o", | |||
| 284 | else | 284 | else |
| 285 | { | 285 | { |
| 286 | /* The data determines whether the string is multibyte. */ | 286 | /* The data determines whether the string is multibyte. */ |
| 287 | ptrdiff_t nchars = | 287 | ptrdiff_t nchars |
| 288 | multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer | 288 | = multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer |
| 289 | + offset), | 289 | + offset), |
| 290 | to - (get_doc_string_buffer + offset)); | 290 | to - (get_doc_string_buffer + offset)); |
| 291 | return make_string_from_bytes (get_doc_string_buffer + offset, | 291 | return make_string_from_bytes (get_doc_string_buffer + offset, |
| 292 | nchars, | 292 | nchars, |
| 293 | to - (get_doc_string_buffer + offset)); | 293 | to - (get_doc_string_buffer + offset)); |
| @@ -304,7 +304,7 @@ read_doc_string (Lisp_Object filepos) | |||
| 304 | return get_doc_string (filepos, 0, 1); | 304 | return get_doc_string (filepos, 0, 1); |
| 305 | } | 305 | } |
| 306 | 306 | ||
| 307 | static int | 307 | static bool |
| 308 | reread_doc_file (Lisp_Object file) | 308 | reread_doc_file (Lisp_Object file) |
| 309 | { | 309 | { |
| 310 | #if 0 | 310 | #if 0 |
| @@ -337,7 +337,7 @@ string is passed through `substitute-command-keys'. */) | |||
| 337 | Lisp_Object fun; | 337 | Lisp_Object fun; |
| 338 | Lisp_Object funcar; | 338 | Lisp_Object funcar; |
| 339 | Lisp_Object doc; | 339 | Lisp_Object doc; |
| 340 | int try_reload = 1; | 340 | bool try_reload = 1; |
| 341 | 341 | ||
| 342 | documentation: | 342 | documentation: |
| 343 | 343 | ||
| @@ -352,6 +352,8 @@ string is passed through `substitute-command-keys'. */) | |||
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | fun = Findirect_function (function, Qnil); | 354 | fun = Findirect_function (function, Qnil); |
| 355 | if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) | ||
| 356 | fun = XCDR (fun); | ||
| 355 | if (SUBRP (fun)) | 357 | if (SUBRP (fun)) |
| 356 | { | 358 | { |
| 357 | if (XSUBR (fun)->doc == 0) | 359 | if (XSUBR (fun)->doc == 0) |
| @@ -384,7 +386,7 @@ string is passed through `substitute-command-keys'. */) | |||
| 384 | } | 386 | } |
| 385 | else if (CONSP (fun)) | 387 | else if (CONSP (fun)) |
| 386 | { | 388 | { |
| 387 | funcar = Fcar (fun); | 389 | funcar = XCAR (fun); |
| 388 | if (!SYMBOLP (funcar)) | 390 | if (!SYMBOLP (funcar)) |
| 389 | xsignal1 (Qinvalid_function, fun); | 391 | xsignal1 (Qinvalid_function, fun); |
| 390 | else if (EQ (funcar, Qkeymap)) | 392 | else if (EQ (funcar, Qkeymap)) |
| @@ -405,8 +407,6 @@ string is passed through `substitute-command-keys'. */) | |||
| 405 | else | 407 | else |
| 406 | return Qnil; | 408 | return Qnil; |
| 407 | } | 409 | } |
| 408 | else if (EQ (funcar, Qmacro)) | ||
| 409 | return Fdocumentation (Fcdr (fun), raw); | ||
| 410 | else | 410 | else |
| 411 | goto oops; | 411 | goto oops; |
| 412 | } | 412 | } |
| @@ -416,16 +416,19 @@ string is passed through `substitute-command-keys'. */) | |||
| 416 | xsignal1 (Qinvalid_function, fun); | 416 | xsignal1 (Qinvalid_function, fun); |
| 417 | } | 417 | } |
| 418 | 418 | ||
| 419 | /* Check for an advised function. Its doc string | 419 | /* Check for a dynamic docstring. These come with |
| 420 | has an `ad-advice-info' text property. */ | 420 | a dynamic-docstring-function text property. */ |
| 421 | if (STRINGP (doc)) | 421 | if (STRINGP (doc)) |
| 422 | { | 422 | { |
| 423 | Lisp_Object innerfunc; | 423 | Lisp_Object func |
| 424 | innerfunc = Fget_text_property (make_number (0), | 424 | = Fget_text_property (make_number (0), |
| 425 | intern ("ad-advice-info"), | 425 | intern ("dynamic-docstring-function"), |
| 426 | doc); | 426 | doc); |
| 427 | if (! NILP (innerfunc)) | 427 | if (!NILP (func)) |
| 428 | doc = call1 (intern ("ad-make-advised-docstring"), innerfunc); | 428 | /* Pass both `doc' and `function' since `function' can be needed, and |
| 429 | finding `doc' can be annoying: calling `documentation' is not an | ||
| 430 | option because it would infloop. */ | ||
| 431 | doc = call2 (func, doc, function); | ||
| 429 | } | 432 | } |
| 430 | 433 | ||
| 431 | /* If DOC is 0, it's typically because of a dumped file missing | 434 | /* If DOC is 0, it's typically because of a dumped file missing |
| @@ -469,7 +472,7 @@ This differs from `get' in that it can refer to strings stored in the | |||
| 469 | aren't strings. */) | 472 | aren't strings. */) |
| 470 | (Lisp_Object symbol, Lisp_Object prop, Lisp_Object raw) | 473 | (Lisp_Object symbol, Lisp_Object prop, Lisp_Object raw) |
| 471 | { | 474 | { |
| 472 | int try_reload = 1; | 475 | bool try_reload = 1; |
| 473 | Lisp_Object tem; | 476 | Lisp_Object tem; |
| 474 | 477 | ||
| 475 | documentation_property: | 478 | documentation_property: |
| @@ -533,6 +536,8 @@ store_function_docstring (Lisp_Object obj, ptrdiff_t offset) | |||
| 533 | { | 536 | { |
| 534 | tem = Fcdr (Fcdr (fun)); | 537 | tem = Fcdr (Fcdr (fun)); |
| 535 | if (CONSP (tem) && INTEGERP (XCAR (tem))) | 538 | if (CONSP (tem) && INTEGERP (XCAR (tem))) |
| 539 | /* FIXME: This modifies typically pure hash-cons'd data, so its | ||
| 540 | correctness is quite delicate. */ | ||
| 536 | XSETCAR (tem, make_number (offset)); | 541 | XSETCAR (tem, make_number (offset)); |
| 537 | } | 542 | } |
| 538 | else if (EQ (tem, Qmacro)) | 543 | else if (EQ (tem, Qmacro)) |
| @@ -549,7 +554,6 @@ store_function_docstring (Lisp_Object obj, ptrdiff_t offset) | |||
| 549 | } | 554 | } |
| 550 | } | 555 | } |
| 551 | 556 | ||
| 552 | static const char buildobj[] = BUILDOBJ; | ||
| 553 | 557 | ||
| 554 | DEFUN ("Snarf-documentation", Fsnarf_documentation, Ssnarf_documentation, | 558 | DEFUN ("Snarf-documentation", Fsnarf_documentation, Ssnarf_documentation, |
| 555 | 1, 1, 0, | 559 | 1, 1, 0, |
| @@ -564,12 +568,12 @@ the same file name is found in the `doc-directory'. */) | |||
| 564 | { | 568 | { |
| 565 | int fd; | 569 | int fd; |
| 566 | char buf[1024 + 1]; | 570 | char buf[1024 + 1]; |
| 567 | register int filled; | 571 | int filled; |
| 568 | register EMACS_INT pos; | 572 | EMACS_INT pos; |
| 569 | register char *p; | ||
| 570 | Lisp_Object sym; | 573 | Lisp_Object sym; |
| 571 | char *name; | 574 | char *p, *name; |
| 572 | int skip_file = 0; | 575 | bool skip_file = 0; |
| 576 | ptrdiff_t count; | ||
| 573 | 577 | ||
| 574 | CHECK_STRING (filename); | 578 | CHECK_STRING (filename); |
| 575 | 579 | ||
| @@ -580,46 +584,39 @@ the same file name is found in the `doc-directory'. */) | |||
| 580 | (0) | 584 | (0) |
| 581 | #endif /* CANNOT_DUMP */ | 585 | #endif /* CANNOT_DUMP */ |
| 582 | { | 586 | { |
| 583 | name = (char *) alloca (SCHARS (filename) + 14); | 587 | name = alloca (SCHARS (filename) + 14); |
| 584 | strcpy (name, "../etc/"); | 588 | strcpy (name, "../etc/"); |
| 585 | } | 589 | } |
| 586 | else | 590 | else |
| 587 | { | 591 | { |
| 588 | CHECK_STRING (Vdoc_directory); | 592 | CHECK_STRING (Vdoc_directory); |
| 589 | name = (char *) alloca (SCHARS (filename) | 593 | name = alloca (SCHARS (filename) + SCHARS (Vdoc_directory) + 1); |
| 590 | + SCHARS (Vdoc_directory) + 1); | ||
| 591 | strcpy (name, SSDATA (Vdoc_directory)); | 594 | strcpy (name, SSDATA (Vdoc_directory)); |
| 592 | } | 595 | } |
| 593 | strcat (name, SSDATA (filename)); /*** Add this line ***/ | 596 | strcat (name, SSDATA (filename)); /*** Add this line ***/ |
| 594 | 597 | ||
| 595 | /* Vbuild_files is nil when temacs is run, and non-nil after that. */ | 598 | /* Vbuild_files is nil when temacs is run, and non-nil after that. */ |
| 596 | if (NILP (Vbuild_files)) | 599 | if (NILP (Vbuild_files)) |
| 597 | { | 600 | { |
| 598 | const char *beg, *end; | 601 | static char const *const buildobj[] = |
| 599 | 602 | { | |
| 600 | for (beg = buildobj; *beg; beg = end) | 603 | #include "buildobj.h" |
| 601 | { | 604 | }; |
| 602 | ptrdiff_t len; | 605 | int i = sizeof buildobj / sizeof *buildobj; |
| 603 | 606 | while (0 <= --i) | |
| 604 | while (*beg && isspace (*beg)) ++beg; | 607 | Vbuild_files = Fcons (build_string (buildobj[i]), Vbuild_files); |
| 605 | 608 | Vbuild_files = Fpurecopy (Vbuild_files); | |
| 606 | for (end = beg; *end && ! isspace (*end); ++end) | 609 | } |
| 607 | if (*end == '/') beg = end+1; /* skip directory part */ | ||
| 608 | |||
| 609 | len = end - beg; | ||
| 610 | if (len > 4 && end[-4] == '.' && end[-3] == 'o') | ||
| 611 | len -= 2; /* Just take .o if it ends in .obj */ | ||
| 612 | |||
| 613 | if (len > 0) | ||
| 614 | Vbuild_files = Fcons (make_string (beg, len), Vbuild_files); | ||
| 615 | } | ||
| 616 | Vbuild_files = Fpurecopy (Vbuild_files); | ||
| 617 | } | ||
| 618 | 610 | ||
| 619 | fd = emacs_open (name, O_RDONLY, 0); | 611 | fd = emacs_open (name, O_RDONLY, 0); |
| 620 | if (fd < 0) | 612 | if (fd < 0) |
| 621 | report_file_error ("Opening doc string file", | 613 | { |
| 622 | Fcons (build_string (name), Qnil)); | 614 | int open_errno = errno; |
| 615 | report_file_errno ("Opening doc string file", build_string (name), | ||
| 616 | open_errno); | ||
| 617 | } | ||
| 618 | count = SPECPDL_INDEX (); | ||
| 619 | record_unwind_protect_int (close_file_unwind, fd); | ||
| 623 | Vdoc_file_name = filename; | 620 | Vdoc_file_name = filename; |
| 624 | filled = 0; | 621 | filled = 0; |
| 625 | pos = 0; | 622 | pos = 0; |
| @@ -632,11 +629,10 @@ the same file name is found in the `doc-directory'. */) | |||
| 632 | break; | 629 | break; |
| 633 | 630 | ||
| 634 | buf[filled] = 0; | 631 | buf[filled] = 0; |
| 635 | p = buf; | ||
| 636 | end = buf + (filled < 512 ? filled : filled - 128); | 632 | end = buf + (filled < 512 ? filled : filled - 128); |
| 637 | while (p != end && *p != '\037') p++; | 633 | p = memchr (buf, '\037', end - buf); |
| 638 | /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ | 634 | /* p points to ^_Ffunctionname\n or ^_Vvarname\n or ^_Sfilename\n. */ |
| 639 | if (p != end) | 635 | if (p) |
| 640 | { | 636 | { |
| 641 | end = strchr (p, '\n'); | 637 | end = strchr (p, '\n'); |
| 642 | 638 | ||
| @@ -649,7 +645,7 @@ the same file name is found in the `doc-directory'. */) | |||
| 649 | { | 645 | { |
| 650 | ptrdiff_t len = end - p - 2; | 646 | ptrdiff_t len = end - p - 2; |
| 651 | char *fromfile = alloca (len + 1); | 647 | char *fromfile = alloca (len + 1); |
| 652 | strncpy (fromfile, &p[2], len); | 648 | memcpy (fromfile, &p[2], len); |
| 653 | fromfile[len] = 0; | 649 | fromfile[len] = 0; |
| 654 | if (fromfile[len-1] == 'c') | 650 | if (fromfile[len-1] == 'c') |
| 655 | fromfile[len-1] = 'o'; | 651 | fromfile[len-1] = 'o'; |
| @@ -698,8 +694,7 @@ the same file name is found in the `doc-directory'. */) | |||
| 698 | filled -= end - buf; | 694 | filled -= end - buf; |
| 699 | memmove (buf, end, filled); | 695 | memmove (buf, end, filled); |
| 700 | } | 696 | } |
| 701 | emacs_close (fd); | 697 | return unbind_to (count, Qnil); |
| 702 | return Qnil; | ||
| 703 | } | 698 | } |
| 704 | 699 | ||
| 705 | DEFUN ("substitute-command-keys", Fsubstitute_command_keys, | 700 | DEFUN ("substitute-command-keys", Fsubstitute_command_keys, |
| @@ -725,9 +720,9 @@ Otherwise, return a new string, without any text properties. */) | |||
| 725 | (Lisp_Object string) | 720 | (Lisp_Object string) |
| 726 | { | 721 | { |
| 727 | char *buf; | 722 | char *buf; |
| 728 | int changed = 0; | 723 | bool changed = 0; |
| 729 | register unsigned char *strp; | 724 | unsigned char *strp; |
| 730 | register char *bufp; | 725 | char *bufp; |
| 731 | ptrdiff_t idx; | 726 | ptrdiff_t idx; |
| 732 | ptrdiff_t bsize; | 727 | ptrdiff_t bsize; |
| 733 | Lisp_Object tem; | 728 | Lisp_Object tem; |
| @@ -736,7 +731,7 @@ Otherwise, return a new string, without any text properties. */) | |||
| 736 | ptrdiff_t length, length_byte; | 731 | ptrdiff_t length, length_byte; |
| 737 | Lisp_Object name; | 732 | Lisp_Object name; |
| 738 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | 733 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; |
| 739 | int multibyte; | 734 | bool multibyte; |
| 740 | ptrdiff_t nchars; | 735 | ptrdiff_t nchars; |
| 741 | 736 | ||
| 742 | if (NILP (string)) | 737 | if (NILP (string)) |
| @@ -755,12 +750,10 @@ Otherwise, return a new string, without any text properties. */) | |||
| 755 | or a specified local map (which means search just that and the | 750 | or a specified local map (which means search just that and the |
| 756 | global map). If non-nil, it might come from Voverriding_local_map, | 751 | global map). If non-nil, it might come from Voverriding_local_map, |
| 757 | or from a \\<mapname> construct in STRING itself.. */ | 752 | or from a \\<mapname> construct in STRING itself.. */ |
| 758 | keymap = KVAR (current_kboard, Voverriding_terminal_local_map); | 753 | keymap = Voverriding_local_map; |
| 759 | if (NILP (keymap)) | ||
| 760 | keymap = Voverriding_local_map; | ||
| 761 | 754 | ||
| 762 | bsize = SBYTES (string); | 755 | bsize = SBYTES (string); |
| 763 | bufp = buf = (char *) xmalloc (bsize); | 756 | bufp = buf = xmalloc (bsize); |
| 764 | 757 | ||
| 765 | strp = SDATA (string); | 758 | strp = SDATA (string); |
| 766 | while (strp < SDATA (string) + SBYTES (string)) | 759 | while (strp < SDATA (string) + SBYTES (string)) |
| @@ -790,7 +783,7 @@ Otherwise, return a new string, without any text properties. */) | |||
| 790 | else if (strp[0] == '\\' && strp[1] == '[') | 783 | else if (strp[0] == '\\' && strp[1] == '[') |
| 791 | { | 784 | { |
| 792 | ptrdiff_t start_idx; | 785 | ptrdiff_t start_idx; |
| 793 | int follow_remap = 1; | 786 | bool follow_remap = 1; |
| 794 | 787 | ||
| 795 | changed = 1; | 788 | changed = 1; |
| 796 | strp += 2; /* skip \[ */ | 789 | strp += 2; /* skip \[ */ |
| @@ -831,7 +824,7 @@ Otherwise, return a new string, without any text properties. */) | |||
| 831 | ptrdiff_t offset = bufp - buf; | 824 | ptrdiff_t offset = bufp - buf; |
| 832 | if (STRING_BYTES_BOUND - 4 < bsize) | 825 | if (STRING_BYTES_BOUND - 4 < bsize) |
| 833 | string_overflow (); | 826 | string_overflow (); |
| 834 | buf = (char *) xrealloc (buf, bsize += 4); | 827 | buf = xrealloc (buf, bsize += 4); |
| 835 | bufp = buf + offset; | 828 | bufp = buf + offset; |
| 836 | memcpy (bufp, "M-x ", 4); | 829 | memcpy (bufp, "M-x ", 4); |
| 837 | bufp += 4; | 830 | bufp += 4; |
| @@ -897,11 +890,11 @@ Otherwise, return a new string, without any text properties. */) | |||
| 897 | if (NILP (tem)) | 890 | if (NILP (tem)) |
| 898 | { | 891 | { |
| 899 | name = Fsymbol_name (name); | 892 | name = Fsymbol_name (name); |
| 900 | insert_string ("\nUses keymap \""); | 893 | insert_string ("\nUses keymap `"); |
| 901 | insert_from_string (name, 0, 0, | 894 | insert_from_string (name, 0, 0, |
| 902 | SCHARS (name), | 895 | SCHARS (name), |
| 903 | SBYTES (name), 1); | 896 | SBYTES (name), 1); |
| 904 | insert_string ("\", which is not currently defined.\n"); | 897 | insert_string ("', which is not currently defined.\n"); |
| 905 | if (start[-1] == '<') keymap = Qnil; | 898 | if (start[-1] == '<') keymap = Qnil; |
| 906 | } | 899 | } |
| 907 | else if (start[-1] == '<') | 900 | else if (start[-1] == '<') |
| @@ -912,7 +905,7 @@ Otherwise, return a new string, without any text properties. */) | |||
| 912 | If this one's not active, get nil. */ | 905 | If this one's not active, get nil. */ |
| 913 | earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps))); | 906 | earlier_maps = Fcdr (Fmemq (tem, Freverse (active_maps))); |
| 914 | describe_map_tree (tem, 1, Fnreverse (earlier_maps), | 907 | describe_map_tree (tem, 1, Fnreverse (earlier_maps), |
| 915 | Qnil, (char *)0, 1, 0, 0, 1); | 908 | Qnil, 0, 1, 0, 0, 1); |
| 916 | } | 909 | } |
| 917 | tem = Fbuffer_string (); | 910 | tem = Fbuffer_string (); |
| 918 | Ferase_buffer (); | 911 | Ferase_buffer (); |
| @@ -927,7 +920,7 @@ Otherwise, return a new string, without any text properties. */) | |||
| 927 | ptrdiff_t offset = bufp - buf; | 920 | ptrdiff_t offset = bufp - buf; |
| 928 | if (STRING_BYTES_BOUND - length_byte < bsize) | 921 | if (STRING_BYTES_BOUND - length_byte < bsize) |
| 929 | string_overflow (); | 922 | string_overflow (); |
| 930 | buf = (char *) xrealloc (buf, bsize += length_byte); | 923 | buf = xrealloc (buf, bsize += length_byte); |
| 931 | bufp = buf + offset; | 924 | bufp = buf + offset; |
| 932 | memcpy (bufp, start, length_byte); | 925 | memcpy (bufp, start, length_byte); |
| 933 | bufp += length_byte; | 926 | bufp += length_byte; |