aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2002-04-01 23:04:46 +0000
committerStefan Monnier2002-04-01 23:04:46 +0000
commita154a4efcee75765250f28c607bb038dfdd22615 (patch)
treef5d5f784774f946f507eb5efb547bcbd77c1a050 /src
parent02dcfd842feb9e299bec8a9571a1ee8e8bac6d98 (diff)
downloademacs-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.c107
1 files changed, 93 insertions, 14 deletions
diff --git a/src/doc.c b/src/doc.c
index 8bb8bef7884..71a9368d6f2 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -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
338static void
339reread_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
308DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, 358DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0,
309 doc: /* Return the documentation string of FUNCTION. 359 doc: /* Return the documentation string of FUNCTION.
310Unless a non-nil second argument RAW is given, the 360Unless 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