Mercurial > emacs
comparison src/doc.c @ 44324:def57419f6ec
(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.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Mon, 01 Apr 2002 23:04:46 +0000 |
parents | 5943cc278b4c |
children | 80c9e94bec17 |
comparison
equal
deleted
inserted
replaced
44323:fcc0f55d734f | 44324:def57419f6ec |
---|---|
103 If it is (FILE . INTEGER), use FILE as the file name | 103 If it is (FILE . INTEGER), use FILE as the file name |
104 and INTEGER as the position in that file. | 104 and INTEGER as the position in that file. |
105 But if INTEGER is negative, make it positive. | 105 But if INTEGER is negative, make it positive. |
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 | |
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. | |
108 | 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 |
112 a dynamic function definition; convert the bytestring | 116 a dynamic function definition; convert the bytestring |
186 if (fd < 0) | 190 if (fd < 0) |
187 error ("Cannot open doc string file \"%s\"", name); | 191 error ("Cannot open doc string file \"%s\"", name); |
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); |
195 error ("Position %ld out of range in doc string file \"%s\"", | 201 error ("Position %ld out of range in doc string file \"%s\"", |
196 position, name); | 202 position, name); |
243 break; | 249 break; |
244 } | 250 } |
245 p += nread; | 251 p += nread; |
246 } | 252 } |
247 emacs_close (fd); | 253 emacs_close (fd); |
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 } | |
248 | 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; |
252 to = get_doc_string_buffer + offset; | 282 to = get_doc_string_buffer + offset; |
301 Lisp_Object | 331 Lisp_Object |
302 read_doc_string (filepos) | 332 read_doc_string (filepos) |
303 Lisp_Object filepos; | 333 Lisp_Object filepos; |
304 { | 334 { |
305 return get_doc_string (filepos, 0, 1); | 335 return get_doc_string (filepos, 0, 1); |
336 } | |
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); | |
306 } | 356 } |
307 | 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 |
382 oops: | 432 oops: |
383 Fsignal (Qinvalid_function, Fcons (fun, Qnil)); | 433 Fsignal (Qinvalid_function, Fcons (fun, Qnil)); |
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); |
391 return doc; | 455 return doc; |
392 } | 456 } |
405 { | 469 { |
406 Lisp_Object tem; | 470 Lisp_Object tem; |
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); |
414 | 490 |
415 if (NILP (raw) && STRINGP (tem)) | 491 if (NILP (raw) && STRINGP (tem)) |
478 register int pos; | 554 register int pos; |
479 register char *p, *end; | 555 register char *p, *end; |
480 Lisp_Object sym; | 556 Lisp_Object sym; |
481 char *name; | 557 char *name; |
482 | 558 |
559 CHECK_STRING (filename); | |
560 | |
561 if | |
483 #ifndef CANNOT_DUMP | 562 #ifndef CANNOT_DUMP |
484 if (NILP (Vpurify_flag)) | 563 (!NILP (Vpurify_flag)) |
485 error ("Snarf-documentation can only be called in an undumped Emacs"); | |
486 #endif | |
487 | |
488 CHECK_STRING (filename); | |
489 | |
490 #ifndef CANNOT_DUMP | |
491 name = (char *) alloca (XSTRING (filename)->size + 14); | |
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 | 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 | |
496 + XSTRING (Vdoc_directory)->size + 1); | 575 + XSTRING (Vdoc_directory)->size + 1); |
497 strcpy (name, XSTRING (Vdoc_directory)->data); | 576 strcpy (name, XSTRING (Vdoc_directory)->data); |
498 #endif /* CANNOT_DUMP */ | 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 |
502 /* For VMS versions with limited file name syntax, | 581 /* For VMS versions with limited file name syntax, |
503 convert the name to something VMS will allow. */ | 582 convert the name to something VMS will allow. */ |