diff options
| author | Richard M. Stallman | 1994-12-21 18:16:35 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-12-21 18:16:35 +0000 |
| commit | 700ea80976440f7fedd5bca03bf02066eeb7a584 (patch) | |
| tree | 467220298ba997c948e176c6c4bd74dbfe825a0e /src/doc.c | |
| parent | ca248607edd25a3d4385da7b084a15111b68466c (diff) | |
| download | emacs-700ea80976440f7fedd5bca03bf02066eeb7a584.tar.gz emacs-700ea80976440f7fedd5bca03bf02066eeb7a584.zip | |
(get_doc_string): Now static. Arg now Lisp_Object.
Allow (FILE . POS) as position argument.
(Fdocumentation, Fdocumentation_property): Fix calls to get_doc_string.
(Fdocumentation_property): Handle cons as value via get_doc_string.
(read_doc_string): New function.
Diffstat (limited to 'src/doc.c')
| -rw-r--r-- | src/doc.c | 177 |
1 files changed, 149 insertions, 28 deletions
| @@ -41,6 +41,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |||
| 41 | 41 | ||
| 42 | Lisp_Object Vdoc_file_name; | 42 | Lisp_Object Vdoc_file_name; |
| 43 | 43 | ||
| 44 | extern char *index (); | ||
| 45 | |||
| 44 | extern Lisp_Object Voverriding_local_map; | 46 | extern Lisp_Object Voverriding_local_map; |
| 45 | 47 | ||
| 46 | /* For VMS versions with limited file name syntax, | 48 | /* For VMS versions with limited file name syntax, |
| @@ -67,29 +69,65 @@ munge_doc_file_name (name) | |||
| 67 | #endif /* VMS */ | 69 | #endif /* VMS */ |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | Lisp_Object | 72 | /* Extract a doc string from a file. FILEPOS says where to get it. |
| 73 | If it is an integer, use that position in the standard DOC-... file. | ||
| 74 | If it is (FILE . INTEGER), use FILE as the file name | ||
| 75 | and INTEGER as the position in that file. */ | ||
| 76 | |||
| 77 | static Lisp_Object | ||
| 71 | get_doc_string (filepos) | 78 | get_doc_string (filepos) |
| 72 | long filepos; | 79 | Lisp_Object filepos; |
| 73 | { | 80 | { |
| 74 | char buf[512 * 32 + 1]; | 81 | char buf[512 * 32 + 1]; |
| 82 | char *buffer; | ||
| 83 | int buffer_size; | ||
| 84 | int free_it; | ||
| 85 | char *from, *to; | ||
| 75 | register int fd; | 86 | register int fd; |
| 76 | register char *name; | 87 | register char *name; |
| 77 | register char *p, *p1; | 88 | register char *p, *p1; |
| 78 | register int count; | ||
| 79 | int minsize; | 89 | int minsize; |
| 80 | extern char *index (); | 90 | int position; |
| 91 | Lisp_Object file, tem; | ||
| 92 | |||
| 93 | if (INTEGERP (filepos)) | ||
| 94 | { | ||
| 95 | file = Vdoc_file_name; | ||
| 96 | position = XINT (filepos); | ||
| 97 | } | ||
| 98 | else if (CONSP (filepos)) | ||
| 99 | { | ||
| 100 | file = XCONS (filepos)->car; | ||
| 101 | position = XINT (XCONS (filepos)->cdr); | ||
| 102 | } | ||
| 103 | else | ||
| 104 | return Qnil; | ||
| 81 | 105 | ||
| 82 | if (!STRINGP (Vdoc_directory) || !STRINGP (Vdoc_file_name)) | 106 | if (!STRINGP (Vdoc_directory)) |
| 83 | return Qnil; | 107 | return Qnil; |
| 84 | 108 | ||
| 85 | minsize = XSTRING (Vdoc_directory)->size; | 109 | if (!STRINGP (file)) |
| 86 | /* sizeof ("../etc/") == 8 */ | 110 | return Qnil; |
| 87 | if (minsize < 8) | 111 | |
| 88 | minsize = 8; | 112 | /* Put the file name in NAME as a C string. |
| 89 | name = (char *) alloca (minsize + XSTRING (Vdoc_file_name)->size + 8); | 113 | If it is relative, combine it with Vdoc_directory. */ |
| 90 | strcpy (name, XSTRING (Vdoc_directory)->data); | 114 | |
| 91 | strcat (name, XSTRING (Vdoc_file_name)->data); | 115 | tem = Ffile_name_absolute_p (file); |
| 92 | munge_doc_file_name (name); | 116 | if (NILP (tem)) |
| 117 | { | ||
| 118 | minsize = XSTRING (Vdoc_directory)->size; | ||
| 119 | /* sizeof ("../etc/") == 8 */ | ||
| 120 | if (minsize < 8) | ||
| 121 | minsize = 8; | ||
| 122 | name = (char *) alloca (minsize + XSTRING (file)->size + 8); | ||
| 123 | strcpy (name, XSTRING (Vdoc_directory)->data); | ||
| 124 | strcat (name, XSTRING (file)->data); | ||
| 125 | munge_doc_file_name (name); | ||
| 126 | } | ||
| 127 | else | ||
| 128 | { | ||
| 129 | name = XSTRING (file)->data; | ||
| 130 | } | ||
| 93 | 131 | ||
| 94 | fd = open (name, O_RDONLY, 0); | 132 | fd = open (name, O_RDONLY, 0); |
| 95 | if (fd < 0) | 133 | if (fd < 0) |
| @@ -100,7 +138,7 @@ get_doc_string (filepos) | |||
| 100 | /* Preparing to dump; DOC file is probably not installed. | 138 | /* Preparing to dump; DOC file is probably not installed. |
| 101 | So check in ../etc. */ | 139 | So check in ../etc. */ |
| 102 | strcpy (name, "../etc/"); | 140 | strcpy (name, "../etc/"); |
| 103 | strcat (name, XSTRING (Vdoc_file_name)->data); | 141 | strcat (name, XSTRING (file)->data); |
| 104 | munge_doc_file_name (name); | 142 | munge_doc_file_name (name); |
| 105 | 143 | ||
| 106 | fd = open (name, O_RDONLY, 0); | 144 | fd = open (name, O_RDONLY, 0); |
| @@ -111,18 +149,58 @@ get_doc_string (filepos) | |||
| 111 | error ("Cannot open doc string file \"%s\"", name); | 149 | error ("Cannot open doc string file \"%s\"", name); |
| 112 | } | 150 | } |
| 113 | 151 | ||
| 114 | if (0 > lseek (fd, filepos, 0)) | 152 | if (0 > lseek (fd, position, 0)) |
| 115 | { | 153 | { |
| 116 | close (fd); | 154 | close (fd); |
| 117 | error ("Position %ld out of range in doc string file \"%s\"", | 155 | error ("Position %ld out of range in doc string file \"%s\"", |
| 118 | filepos, name); | 156 | position, name); |
| 119 | } | 157 | } |
| 158 | |||
| 159 | /* Read the doc string into a buffer. | ||
| 160 | Use the fixed buffer BUF if it is big enough; | ||
| 161 | otherwise allocate one and set FREE_IT. | ||
| 162 | We store the buffer in use in BUFFER and its size in BUFFER_SIZE. */ | ||
| 163 | |||
| 164 | buffer = buf; | ||
| 165 | buffer_size = sizeof buf; | ||
| 166 | free_it = 0; | ||
| 120 | p = buf; | 167 | p = buf; |
| 121 | while (p != buf + sizeof buf - 1) | 168 | while (1) |
| 122 | { | 169 | { |
| 123 | count = read (fd, p, 512); | 170 | int space_left = buffer_size - (p - buffer); |
| 124 | p[count] = 0; | 171 | int nread; |
| 125 | if (!count) | 172 | |
| 173 | /* Switch to a bigger buffer if we need one. */ | ||
| 174 | if (space_left == 0) | ||
| 175 | { | ||
| 176 | if (free_it) | ||
| 177 | { | ||
| 178 | int offset = p - buffer; | ||
| 179 | buffer = (char *) xrealloc (buffer, | ||
| 180 | buffer_size *= 2); | ||
| 181 | p = buffer + offset; | ||
| 182 | } | ||
| 183 | else | ||
| 184 | { | ||
| 185 | buffer = (char *) xmalloc (buffer_size *= 2); | ||
| 186 | bcopy (buf, buffer, p - buf); | ||
| 187 | p = buffer + (p - buf); | ||
| 188 | } | ||
| 189 | free_it = 1; | ||
| 190 | space_left = buffer_size - (p - buffer); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* Don't read too too much at one go. */ | ||
| 194 | if (space_left > 1024 * 8) | ||
| 195 | space_left = 1024 * 8; | ||
| 196 | nread = read (fd, p, space_left); | ||
| 197 | if (nread < 0) | ||
| 198 | { | ||
| 199 | close (fd); | ||
| 200 | error ("Read error on documentation file"); | ||
| 201 | } | ||
| 202 | p[nread] = 0; | ||
| 203 | if (!nread) | ||
| 126 | break; | 204 | break; |
| 127 | p1 = index (p, '\037'); | 205 | p1 = index (p, '\037'); |
| 128 | if (p1) | 206 | if (p1) |
| @@ -131,10 +209,51 @@ get_doc_string (filepos) | |||
| 131 | p = p1; | 209 | p = p1; |
| 132 | break; | 210 | break; |
| 133 | } | 211 | } |
| 134 | p += count; | 212 | p += nread; |
| 135 | } | 213 | } |
| 136 | close (fd); | 214 | close (fd); |
| 137 | return make_string (buf, p - buf); | 215 | |
| 216 | /* Scan the text and perform quoting with ^A (char code 1). | ||
| 217 | ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */ | ||
| 218 | from = buffer; | ||
| 219 | to = buffer; | ||
| 220 | while (from != p) | ||
| 221 | { | ||
| 222 | if (*from == 1) | ||
| 223 | { | ||
| 224 | int c; | ||
| 225 | |||
| 226 | from++; | ||
| 227 | c = *from++; | ||
| 228 | if (c == 1) | ||
| 229 | *to++ = c; | ||
| 230 | else if (c == '0') | ||
| 231 | *to++ = 0; | ||
| 232 | else if (c == '_') | ||
| 233 | *to++ = 037; | ||
| 234 | else | ||
| 235 | error ("Invalid data in documentation file -- ^A followed by code 0%o", c); | ||
| 236 | } | ||
| 237 | else | ||
| 238 | *to++ = *from++; | ||
| 239 | } | ||
| 240 | |||
| 241 | tem = make_string (buffer, to - buffer); | ||
| 242 | if (free_it) | ||
| 243 | free (buffer); | ||
| 244 | |||
| 245 | return tem; | ||
| 246 | } | ||
| 247 | |||
| 248 | /* Get a string from position FILEPOS and pass it through the Lisp reader. | ||
| 249 | We use this for fetching the bytecode string and constants vector | ||
| 250 | of a compiled function from the .elc file. */ | ||
| 251 | |||
| 252 | Lisp_Object | ||
| 253 | read_doc_string (filepos) | ||
| 254 | Lisp_Object filepos; | ||
| 255 | { | ||
| 256 | return Fread (get_doc_string (filepos)); | ||
| 138 | } | 257 | } |
| 139 | 258 | ||
| 140 | DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, | 259 | DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, |
| @@ -156,7 +275,7 @@ string is passed through `substitute-command-keys'.") | |||
| 156 | if ((EMACS_INT) XSUBR (fun)->doc >= 0) | 275 | if ((EMACS_INT) XSUBR (fun)->doc >= 0) |
| 157 | doc = build_string (XSUBR (fun)->doc); | 276 | doc = build_string (XSUBR (fun)->doc); |
| 158 | else | 277 | else |
| 159 | doc = get_doc_string (- (EMACS_INT) XSUBR (fun)->doc); | 278 | doc = get_doc_string (make_number (- (EMACS_INT) XSUBR (fun)->doc)); |
| 160 | } | 279 | } |
| 161 | else if (COMPILEDP (fun)) | 280 | else if (COMPILEDP (fun)) |
| 162 | { | 281 | { |
| @@ -165,8 +284,8 @@ string is passed through `substitute-command-keys'.") | |||
| 165 | tem = XVECTOR (fun)->contents[COMPILED_DOC_STRING]; | 284 | tem = XVECTOR (fun)->contents[COMPILED_DOC_STRING]; |
| 166 | if (STRINGP (tem)) | 285 | if (STRINGP (tem)) |
| 167 | doc = tem; | 286 | doc = tem; |
| 168 | else if (NATNUMP (tem)) | 287 | else if (NATNUMP (tem) || CONSP (tem)) |
| 169 | doc = get_doc_string (XFASTINT (tem)); | 288 | doc = get_doc_string (tem); |
| 170 | else | 289 | else |
| 171 | return Qnil; | 290 | return Qnil; |
| 172 | } | 291 | } |
| @@ -188,8 +307,8 @@ subcommands.)"); | |||
| 188 | tem = Fcar (Fcdr (Fcdr (fun))); | 307 | tem = Fcar (Fcdr (Fcdr (fun))); |
| 189 | if (STRINGP (tem)) | 308 | if (STRINGP (tem)) |
| 190 | doc = tem; | 309 | doc = tem; |
| 191 | else if (NATNUMP (tem)) | 310 | else if (NATNUMP (tem) || CONSP (tem)) |
| 192 | doc = get_doc_string (XFASTINT (tem)); | 311 | doc = get_doc_string (tem); |
| 193 | else | 312 | else |
| 194 | return Qnil; | 313 | return Qnil; |
| 195 | } | 314 | } |
| @@ -230,7 +349,9 @@ translation.") | |||
| 230 | 349 | ||
| 231 | tem = Fget (sym, prop); | 350 | tem = Fget (sym, prop); |
| 232 | if (INTEGERP (tem)) | 351 | if (INTEGERP (tem)) |
| 233 | tem = get_doc_string (XINT (tem) > 0 ? XINT (tem) : - XINT (tem)); | 352 | tem = get_doc_string (XINT (tem) > 0 ? tem : make_number (- XINT (tem))); |
| 353 | else if (CONSP (tem)) | ||
| 354 | tem = get_doc_string (tem); | ||
| 234 | if (NILP (raw) && STRINGP (tem)) | 355 | if (NILP (raw) && STRINGP (tem)) |
| 235 | return Fsubstitute_command_keys (tem); | 356 | return Fsubstitute_command_keys (tem); |
| 236 | return tem; | 357 | return tem; |