diff options
| author | Richard M. Stallman | 1996-02-12 09:49:01 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1996-02-12 09:49:01 +0000 |
| commit | 0fded513b962b00fab277902d7d4ff30399818fb (patch) | |
| tree | 0d3ee7b1eb531044a35c9578ea55c7be8b9f23db /src | |
| parent | 48919e0ff43dd48bedb1d51fd13f5a681ddf789d (diff) | |
| download | emacs-0fded513b962b00fab277902d7d4ff30399818fb.tar.gz emacs-0fded513b962b00fab277902d7d4ff30399818fb.zip | |
(get_doc_string): Always read entire disk blocks.
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc.c | 63 |
1 files changed, 24 insertions, 39 deletions
| @@ -82,16 +82,15 @@ static Lisp_Object | |||
| 82 | get_doc_string (filepos) | 82 | get_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. |