]> code.delx.au - gnu-emacs/blobdiff - src/doc.c
(struct gl_state_s): New field `offset'.
[gnu-emacs] / src / doc.c
index 9c8ed95561f536e1d593f922d2f5fb53c7382b0e..5c26e6c6a33b4d693af3c37c876b5148b3a89c8a 100644 (file)
--- a/src/doc.c
+++ b/src/doc.c
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 
 #include <config.h>
@@ -69,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
@@ -81,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))
@@ -149,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);
@@ -207,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;
@@ -220,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)
@@ -243,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.