diff options
| author | Stefan Monnier | 2002-04-01 23:04:46 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-04-01 23:04:46 +0000 |
| commit | a154a4efcee75765250f28c607bb038dfdd22615 (patch) | |
| tree | f5d5f784774f946f507eb5efb547bcbd77c1a050 /src | |
| parent | 02dcfd842feb9e299bec8a9571a1ee8e8bac6d98 (diff) | |
| download | emacs-a154a4efcee75765250f28c607bb038dfdd22615.tar.gz emacs-a154a4efcee75765250f28c607bb038dfdd22615.zip | |
(get_doc_string): Return nil of the location is wrong.
(reread_doc_file): New fun.
(Fdocumentation, Fdocumentation_property):
Call it if get_doc_string fails.
(Fsnarf_documentation): Make it work for a dumped Emacs.
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc.c | 107 |
1 files changed, 93 insertions, 14 deletions
| @@ -106,6 +106,10 @@ read_bytecode_char (unreadflag) | |||
| 106 | (A negative integer is used for user variables, so we can distinguish | 106 | (A negative integer is used for user variables, so we can distinguish |
| 107 | them without actually fetching the doc string.) | 107 | them without actually fetching the doc string.) |
| 108 | 108 | ||
| 109 | If the location does not point to the beginning of a docstring | ||
| 110 | (e.g. because the file has been modified and the location is stale), | ||
| 111 | return nil. | ||
| 112 | |||
| 109 | If UNIBYTE is nonzero, always make a unibyte string. | 113 | If UNIBYTE is nonzero, always make a unibyte string. |
| 110 | 114 | ||
| 111 | If DEFINITION is nonzero, assume this is for reading | 115 | If DEFINITION is nonzero, assume this is for reading |
| @@ -188,7 +192,9 @@ get_doc_string (filepos, unibyte, definition) | |||
| 188 | } | 192 | } |
| 189 | 193 | ||
| 190 | /* Seek only to beginning of disk block. */ | 194 | /* Seek only to beginning of disk block. */ |
| 191 | offset = position % (8 * 1024); | 195 | /* Make sure we read at least 1024 bytes before `position' |
| 196 | so we can check the leading text for consistency. */ | ||
| 197 | offset = min (position, max (1024, position % (8 * 1024))); | ||
| 192 | if (0 > lseek (fd, position - offset, 0)) | 198 | if (0 > lseek (fd, position - offset, 0)) |
| 193 | { | 199 | { |
| 194 | emacs_close (fd); | 200 | emacs_close (fd); |
| @@ -246,6 +252,30 @@ get_doc_string (filepos, unibyte, definition) | |||
| 246 | } | 252 | } |
| 247 | emacs_close (fd); | 253 | emacs_close (fd); |
| 248 | 254 | ||
| 255 | /* Sanity checking. */ | ||
| 256 | if (CONSP (filepos)) | ||
| 257 | { | ||
| 258 | int test = 1; | ||
| 259 | if (get_doc_string_buffer[offset - test++] != ' ') | ||
| 260 | return Qnil; | ||
| 261 | while (get_doc_string_buffer[offset - test] >= '0' | ||
| 262 | && get_doc_string_buffer[offset - test] <= '9') | ||
| 263 | test++; | ||
| 264 | if (get_doc_string_buffer[offset - test++] != '@' | ||
| 265 | || get_doc_string_buffer[offset - test] != '#') | ||
| 266 | return Qnil; | ||
| 267 | } | ||
| 268 | else | ||
| 269 | { | ||
| 270 | int test = 1; | ||
| 271 | if (get_doc_string_buffer[offset - test++] != '\n') | ||
| 272 | return Qnil; | ||
| 273 | while (get_doc_string_buffer[offset - test] > ' ') | ||
| 274 | test++; | ||
| 275 | if (get_doc_string_buffer[offset - test] != '\037') | ||
| 276 | return Qnil; | ||
| 277 | } | ||
| 278 | |||
| 249 | /* Scan the text and perform quoting with ^A (char code 1). | 279 | /* Scan the text and perform quoting with ^A (char code 1). |
| 250 | ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */ | 280 | ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */ |
| 251 | from = get_doc_string_buffer + offset; | 281 | from = get_doc_string_buffer + offset; |
| @@ -305,6 +335,26 @@ read_doc_string (filepos) | |||
| 305 | return get_doc_string (filepos, 0, 1); | 335 | return get_doc_string (filepos, 0, 1); |
| 306 | } | 336 | } |
| 307 | 337 | ||
| 338 | static void | ||
| 339 | reread_doc_file (file) | ||
| 340 | { | ||
| 341 | Lisp_Object reply, prompt[3]; | ||
| 342 | struct gcpro gcpro1; | ||
| 343 | GCPRO1 (file); | ||
| 344 | prompt[0] = build_string ("File "); | ||
| 345 | prompt[1] = NILP (file) ? Vdoc_file_name : file; | ||
| 346 | prompt[2] = build_string (" is out-of-sync. Reload? "); | ||
| 347 | reply = Fy_or_n_p (Fconcat (3, prompt)); | ||
| 348 | UNGCPRO; | ||
| 349 | if (NILP (reply)) | ||
| 350 | error ("Aborted"); | ||
| 351 | |||
| 352 | if (NILP (file)) | ||
| 353 | Fsnarf_documentation (Vdoc_file_name); | ||
| 354 | else | ||
| 355 | Fload (file, Qt, Qt, Qt, Qnil); | ||
| 356 | } | ||
| 357 | |||
| 308 | DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, | 358 | DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, |
| 309 | doc: /* Return the documentation string of FUNCTION. | 359 | doc: /* Return the documentation string of FUNCTION. |
| 310 | Unless a non-nil second argument RAW is given, the | 360 | Unless a non-nil second argument RAW is given, the |
| @@ -384,7 +434,21 @@ string is passed through `substitute-command-keys'. */) | |||
| 384 | } | 434 | } |
| 385 | 435 | ||
| 386 | if (INTEGERP (doc) || CONSP (doc)) | 436 | if (INTEGERP (doc) || CONSP (doc)) |
| 387 | doc = get_doc_string (doc, 0, 0); | 437 | { |
| 438 | Lisp_Object tem; | ||
| 439 | tem = get_doc_string (doc, 0, 0); | ||
| 440 | if (NILP (tem)) | ||
| 441 | { | ||
| 442 | /* The file is newer, we need to reset the pointers. */ | ||
| 443 | struct gcpro gcpro1, gcpro2; | ||
| 444 | GCPRO2 (function, raw); | ||
| 445 | reread_doc_file (Fcar_safe (doc)); | ||
| 446 | UNGCPRO; | ||
| 447 | return Fdocumentation (function, raw); | ||
| 448 | } | ||
| 449 | else | ||
| 450 | doc = tem; | ||
| 451 | } | ||
| 388 | 452 | ||
| 389 | if (NILP (raw)) | 453 | if (NILP (raw)) |
| 390 | doc = Fsubstitute_command_keys (doc); | 454 | doc = Fsubstitute_command_keys (doc); |
| @@ -407,7 +471,19 @@ aren't strings. */) | |||
| 407 | 471 | ||
| 408 | tem = Fget (symbol, prop); | 472 | tem = Fget (symbol, prop); |
| 409 | if (INTEGERP (tem) || (CONSP (tem) && INTEGERP (XCDR (tem)))) | 473 | if (INTEGERP (tem) || (CONSP (tem) && INTEGERP (XCDR (tem)))) |
| 410 | tem = get_doc_string (tem, 0, 0); | 474 | { |
| 475 | Lisp_Object doc = tem; | ||
| 476 | tem = get_doc_string (tem, 0, 0); | ||
| 477 | if (NILP (tem)) | ||
| 478 | { | ||
| 479 | /* The file is newer, we need to reset the pointers. */ | ||
| 480 | struct gcpro gcpro1, gcpro2, gcpro3; | ||
| 481 | GCPRO3 (symbol, prop, raw); | ||
| 482 | reread_doc_file (Fcar_safe (doc)); | ||
| 483 | UNGCPRO; | ||
| 484 | return Fdocumentation_property (symbol, prop, raw); | ||
| 485 | } | ||
| 486 | } | ||
| 411 | else if (!STRINGP (tem)) | 487 | else if (!STRINGP (tem)) |
| 412 | /* Feval protects its argument. */ | 488 | /* Feval protects its argument. */ |
| 413 | tem = Feval (tem); | 489 | tem = Feval (tem); |
| @@ -480,22 +556,25 @@ the same file name is found in the `data-directory'. */) | |||
| 480 | Lisp_Object sym; | 556 | Lisp_Object sym; |
| 481 | char *name; | 557 | char *name; |
| 482 | 558 | ||
| 483 | #ifndef CANNOT_DUMP | ||
| 484 | if (NILP (Vpurify_flag)) | ||
| 485 | error ("Snarf-documentation can only be called in an undumped Emacs"); | ||
| 486 | #endif | ||
| 487 | |||
| 488 | CHECK_STRING (filename); | 559 | CHECK_STRING (filename); |
| 489 | 560 | ||
| 561 | if | ||
| 490 | #ifndef CANNOT_DUMP | 562 | #ifndef CANNOT_DUMP |
| 491 | name = (char *) alloca (XSTRING (filename)->size + 14); | 563 | (!NILP (Vpurify_flag)) |
| 492 | strcpy (name, "../etc/"); | ||
| 493 | #else /* CANNOT_DUMP */ | 564 | #else /* CANNOT_DUMP */ |
| 494 | CHECK_STRING (Vdoc_directory); | 565 | (0) |
| 495 | name = (char *) alloca (XSTRING (filename)->size | ||
| 496 | + XSTRING (Vdoc_directory)->size + 1); | ||
| 497 | strcpy (name, XSTRING (Vdoc_directory)->data); | ||
| 498 | #endif /* CANNOT_DUMP */ | 566 | #endif /* CANNOT_DUMP */ |
| 567 | { | ||
| 568 | name = (char *) alloca (XSTRING (filename)->size + 14); | ||
| 569 | strcpy (name, "../etc/"); | ||
| 570 | } | ||
| 571 | else | ||
| 572 | { | ||
| 573 | CHECK_STRING (Vdoc_directory); | ||
| 574 | name = (char *) alloca (XSTRING (filename)->size | ||
| 575 | + XSTRING (Vdoc_directory)->size + 1); | ||
| 576 | strcpy (name, XSTRING (Vdoc_directory)->data); | ||
| 577 | } | ||
| 499 | strcat (name, XSTRING (filename)->data); /*** Add this line ***/ | 578 | strcat (name, XSTRING (filename)->data); /*** Add this line ***/ |
| 500 | #ifdef VMS | 579 | #ifdef VMS |
| 501 | #ifndef VMS4_4 | 580 | #ifndef VMS4_4 |