]> code.delx.au - gnu-emacs/blobdiff - src/doc.c
(SETUP_SYNTAX_TABLE_FOR_OBJECT): Call bytepos_to_charpos.
[gnu-emacs] / src / doc.c
index 1839b1f16991fceea2147a5bb39a6c2905092c65..f91213a7cb647d7195bfdecdfbd2a34415b5ca0e 100644 (file)
--- a/src/doc.c
+++ b/src/doc.c
@@ -1,5 +1,5 @@
 /* Record indices of function doc strings stored in a file.
-   Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1985, 86, 93, 94, 95, 1997 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -70,6 +70,10 @@ munge_doc_file_name (name)
 #endif /* VMS */
 }
 
+/* Buffer used for reading from documentation file.  */
+static char *get_doc_string_buffer;
+static int get_doc_string_buffer_size;
+
 /* Extract a doc string from a file.  FILEPOS says where to get it.
    If it is an integer, use that position in the standard DOC-... file.
    If it is (FILE . INTEGER), use FILE as the file name
@@ -82,16 +86,12 @@ static Lisp_Object
 get_doc_string (filepos)
      Lisp_Object filepos;
 {
-  char buf[512 * 32 + 1];
-  char *buffer;
-  int buffer_size;
-  int free_it;
   char *from, *to;
   register int fd;
   register char *name;
   register char *p, *p1;
   int minsize;
-  int position;
+  int offset, position;
   Lisp_Object file, tem;
 
   if (INTEGERP (filepos))
@@ -150,53 +150,44 @@ get_doc_string (filepos)
          fd = open (name, O_RDONLY, 0);
        }
 #endif
-
       if (fd < 0)
        error ("Cannot open doc string file \"%s\"", name);
     }
 
-  if (0 > lseek (fd, position, 0))
+  /* Seek only to beginning of disk block.  */
+  offset = position % (8 * 1024);
+  if (0 > lseek (fd, position - offset, 0))
     {
       close (fd);
       error ("Position %ld out of range in doc string file \"%s\"",
             position, name);
     }
 
-  /* Read the doc string into a buffer.
-     Use the fixed buffer BUF if it is big enough;
-     otherwise allocate one and set FREE_IT.
-     We store the buffer in use in BUFFER and its size in BUFFER_SIZE.  */
+  /* Read the doc string into get_doc_string_buffer.
+     P points beyond the data just read.  */
 
-  buffer = buf;
-  buffer_size = sizeof buf;
-  free_it = 0;
-  p = buf;
+  p = get_doc_string_buffer;
   while (1)
     {
-      int space_left = buffer_size - (p - buffer);
+      int space_left = (get_doc_string_buffer_size
+                       - (p - get_doc_string_buffer));
       int nread;
 
-      /* Switch to a bigger buffer if we need one.  */
+      /* Allocate or grow the buffer if we need to.  */
       if (space_left == 0)
        {
-         if (free_it)
-           {
-             int offset = p - buffer;
-             buffer = (char *) xrealloc (buffer,
-                                         buffer_size *= 2);
-             p = buffer + offset;
-           }
-         else
-           {
-             buffer = (char *) xmalloc (buffer_size *= 2);
-             bcopy (buf, buffer, p - buf);
-             p = buffer + (p - buf);
-           }
-         free_it = 1;
-         space_left = buffer_size - (p - buffer);
+         int in_buffer = p - get_doc_string_buffer;
+         get_doc_string_buffer_size += 16 * 1024;
+         get_doc_string_buffer
+           = (char *) xrealloc (get_doc_string_buffer,
+                                get_doc_string_buffer_size + 1);
+         p = get_doc_string_buffer + in_buffer;
+         space_left = (get_doc_string_buffer_size
+                       - (p - get_doc_string_buffer));
        }
 
-      /* Don't read too too much at one go.  */
+      /* Read a disk block at a time.
+         If we read the same block last time, maybe skip this?  */
       if (space_left > 1024 * 8)
        space_left = 1024 * 8;
       nread = read (fd, p, space_left);
@@ -208,7 +199,10 @@ get_doc_string (filepos)
       p[nread] = 0;
       if (!nread)
        break;
-      p1 = index (p, '\037');
+      if (p == get_doc_string_buffer)
+       p1 = index (p + offset, '\037');
+      else
+       p1 = index (p, '\037');
       if (p1)
        {
          *p1 = 0;
@@ -221,8 +215,8 @@ get_doc_string (filepos)
 
   /* Scan the text and perform quoting with ^A (char code 1).
      ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_.  */
-  from = buffer;
-  to = buffer;
+  from = get_doc_string_buffer + offset;
+  to = get_doc_string_buffer + offset;
   while (from != p)
     {
       if (*from == 1)
@@ -244,11 +238,8 @@ get_doc_string (filepos)
        *to++ = *from++;
     }
 
-  tem = make_string (buffer, to - buffer);
-  if (free_it)
-    free (buffer);
-
-  return tem;
+  return make_string (get_doc_string_buffer + offset,
+                     to - (get_doc_string_buffer + offset));
 }
 
 /* Get a string from position FILEPOS and pass it through the Lisp reader.
@@ -669,7 +660,7 @@ thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ int
          else if (start[-1] == '<')
            keymap = tem;
          else
-           describe_map_tree (tem, 1, Qnil, Qnil, (char *)0, 1, 0);
+           describe_map_tree (tem, 1, Qnil, Qnil, (char *)0, 1, 0, 0);
          tem = Fbuffer_string ();
          Ferase_buffer ();
          set_buffer_internal (oldbuf);