aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1996-02-12 09:49:01 +0000
committerRichard M. Stallman1996-02-12 09:49:01 +0000
commit0fded513b962b00fab277902d7d4ff30399818fb (patch)
tree0d3ee7b1eb531044a35c9578ea55c7be8b9f23db /src
parent48919e0ff43dd48bedb1d51fd13f5a681ddf789d (diff)
downloademacs-0fded513b962b00fab277902d7d4ff30399818fb.tar.gz
emacs-0fded513b962b00fab277902d7d4ff30399818fb.zip
(get_doc_string): Always read entire disk blocks.
Diffstat (limited to 'src')
-rw-r--r--src/doc.c63
1 files changed, 24 insertions, 39 deletions
diff --git a/src/doc.c b/src/doc.c
index 1839b1f1699..9ba3ca7c95d 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -82,16 +82,15 @@ static Lisp_Object
82get_doc_string (filepos) 82get_doc_string (filepos)
83 Lisp_Object filepos; 83 Lisp_Object filepos;
84{ 84{
85 char buf[512 * 32 + 1]; 85 static char *buffer;
86 char *buffer; 86 static int buffer_size;
87 int buffer_size; 87
88 int free_it;
89 char *from, *to; 88 char *from, *to;
90 register int fd; 89 register int fd;
91 register char *name; 90 register char *name;
92 register char *p, *p1; 91 register char *p, *p1;
93 int minsize; 92 int minsize;
94 int position; 93 int offset, position;
95 Lisp_Object file, tem; 94 Lisp_Object file, tem;
96 95
97 if (INTEGERP (filepos)) 96 if (INTEGERP (filepos))
@@ -150,12 +149,13 @@ get_doc_string (filepos)
150 fd = open (name, O_RDONLY, 0); 149 fd = open (name, O_RDONLY, 0);
151 } 150 }
152#endif 151#endif
153
154 if (fd < 0) 152 if (fd < 0)
155 error ("Cannot open doc string file \"%s\"", name); 153 error ("Cannot open doc string file \"%s\"", name);
156 } 154 }
157 155
158 if (0 > lseek (fd, position, 0)) 156 /* Seek only to beginning of disk block. */
157 offset = position % (8 * 1024);
158 if (0 > lseek (fd, position - offset, 0))
159 { 159 {
160 close (fd); 160 close (fd);
161 error ("Position %ld out of range in doc string file \"%s\"", 161 error ("Position %ld out of range in doc string file \"%s\"",
@@ -163,40 +163,26 @@ get_doc_string (filepos)
163 } 163 }
164 164
165 /* Read the doc string into a buffer. 165 /* Read the doc string into a buffer.
166 Use the fixed buffer BUF if it is big enough; 166 p points beyond the data just read. */
167 otherwise allocate one and set FREE_IT. 167
168 We store the buffer in use in BUFFER and its size in BUFFER_SIZE. */ 168 p = buffer;
169
170 buffer = buf;
171 buffer_size = sizeof buf;
172 free_it = 0;
173 p = buf;
174 while (1) 169 while (1)
175 { 170 {
176 int space_left = buffer_size - (p - buffer); 171 int space_left = buffer_size - (p - buffer);
177 int nread; 172 int nread;
178 173
179 /* Switch to a bigger buffer if we need one. */ 174 /* Allocate or grow the buffer if we need to. */
180 if (space_left == 0) 175 if (space_left == 0)
181 { 176 {
182 if (free_it) 177 int in_buffer = p - buffer;
183 { 178 buffer_size += 16 * 1024;
184 int offset = p - buffer; 179 buffer = (char *) xrealloc (buffer, buffer_size + 1);
185 buffer = (char *) xrealloc (buffer, 180 p = buffer + in_buffer;
186 buffer_size *= 2);
187 p = buffer + offset;
188 }
189 else
190 {
191 buffer = (char *) xmalloc (buffer_size *= 2);
192 bcopy (buf, buffer, p - buf);
193 p = buffer + (p - buf);
194 }
195 free_it = 1;
196 space_left = buffer_size - (p - buffer); 181 space_left = buffer_size - (p - buffer);
197 } 182 }
198 183
199 /* Don't read too too much at one go. */ 184 /* Read a disk block at a time.
185 If we read the same block last time, maybe skip this? */
200 if (space_left > 1024 * 8) 186 if (space_left > 1024 * 8)
201 space_left = 1024 * 8; 187 space_left = 1024 * 8;
202 nread = read (fd, p, space_left); 188 nread = read (fd, p, space_left);
@@ -208,7 +194,10 @@ get_doc_string (filepos)
208 p[nread] = 0; 194 p[nread] = 0;
209 if (!nread) 195 if (!nread)
210 break; 196 break;
211 p1 = index (p, '\037'); 197 if (p == buffer)
198 p1 = index (p + offset, '\037');
199 else
200 p1 = index (p, '\037');
212 if (p1) 201 if (p1)
213 { 202 {
214 *p1 = 0; 203 *p1 = 0;
@@ -221,8 +210,8 @@ get_doc_string (filepos)
221 210
222 /* Scan the text and perform quoting with ^A (char code 1). 211 /* Scan the text and perform quoting with ^A (char code 1).
223 ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */ 212 ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */
224 from = buffer; 213 from = buffer + offset;
225 to = buffer; 214 to = buffer + offset;
226 while (from != p) 215 while (from != p)
227 { 216 {
228 if (*from == 1) 217 if (*from == 1)
@@ -244,11 +233,7 @@ get_doc_string (filepos)
244 *to++ = *from++; 233 *to++ = *from++;
245 } 234 }
246 235
247 tem = make_string (buffer, to - buffer); 236 return make_string (buffer + offset, to - (buffer + offset));
248 if (free_it)
249 free (buffer);
250
251 return tem;
252} 237}
253 238
254/* Get a string from position FILEPOS and pass it through the Lisp reader. 239/* Get a string from position FILEPOS and pass it through the Lisp reader.