aboutsummaryrefslogtreecommitdiffstats
path: root/src/doc.c
diff options
context:
space:
mode:
authorRichard M. Stallman1994-12-21 18:16:35 +0000
committerRichard M. Stallman1994-12-21 18:16:35 +0000
commit700ea80976440f7fedd5bca03bf02066eeb7a584 (patch)
tree467220298ba997c948e176c6c4bd74dbfe825a0e /src/doc.c
parentca248607edd25a3d4385da7b084a15111b68466c (diff)
downloademacs-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.c177
1 files changed, 149 insertions, 28 deletions
diff --git a/src/doc.c b/src/doc.c
index d6c76592e78..67f91a4209f 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -41,6 +41,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
41 41
42Lisp_Object Vdoc_file_name; 42Lisp_Object Vdoc_file_name;
43 43
44extern char *index ();
45
44extern Lisp_Object Voverriding_local_map; 46extern 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
70Lisp_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
77static Lisp_Object
71get_doc_string (filepos) 78get_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
252Lisp_Object
253read_doc_string (filepos)
254 Lisp_Object filepos;
255{
256 return Fread (get_doc_string (filepos));
138} 257}
139 258
140DEFUN ("documentation", Fdocumentation, Sdocumentation, 1, 2, 0, 259DEFUN ("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;