Mercurial > hg > xemacs-beta
annotate src/doc.c @ 5795:d2c0ff38ad5c
Report lstream errors when encoding/decoding.
See <CAHCOHQ=FAieD-2nP303fMvwkii8HK2z+X7gRZ2+4PH1CA5_-NA@mail.gmail.com> in
xemacs-patches.
author | Jerry James <james@xemacs.org> |
---|---|
date | Wed, 14 May 2014 14:16:24 -0600 |
parents | 72c5d36ba3b6 |
children | a216b3c2b09e |
rev | line source |
---|---|
428 | 1 /* Record indices of function doc strings stored in a file. |
2 Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995 | |
3 Free Software Foundation, Inc. | |
2367 | 4 Copyright (C) 2001, 2002, 2004 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5206
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
428 | 9 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5206
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5206
diff
changeset
|
11 option) any later version. |
428 | 12 |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
5206
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 20 |
21 /* Synched up with: FSF 19.30. */ | |
22 | |
814 | 23 /* This file has been Mule-ized. */ |
428 | 24 |
25 #include <config.h> | |
26 #include "lisp.h" | |
27 | |
28 #include "buffer.h" | |
29 #include "bytecode.h" | |
814 | 30 #include "file-coding.h" |
428 | 31 #include "insdel.h" |
32 #include "keymap.h" | |
814 | 33 #include "lstream.h" |
428 | 34 #include "sysfile.h" |
35 | |
36 Lisp_Object Vinternal_doc_file_name; | |
37 | |
4367
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
38 Lisp_Object QSsubstitute, Qdefvar; |
428 | 39 |
5789
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
40 Lisp_Object Qfunction_documentation; |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
41 |
3368 | 42 /* Work out what source file a function or variable came from, taking the |
43 information from the documentation file. */ | |
44 | |
45 static Lisp_Object | |
46 extract_object_file_name (int fd, EMACS_INT doc_pos, | |
47 Ibyte *name_nonreloc, Lisp_Object name_reloc, | |
48 int standard_doc_file) | |
49 { | |
3383 | 50 Ibyte buf[DOC_MAX_FILENAME_LENGTH+1]; |
3368 | 51 Ibyte *buffer = buf; |
3411 | 52 int buffer_size = sizeof (buf) - 1, space_left; |
3368 | 53 Ibyte *from, *to; |
54 REGISTER Ibyte *p = buffer; | |
55 Lisp_Object return_me; | |
56 Lisp_Object fdstream = Qnil, instream = Qnil; | |
57 struct gcpro gcpro1, gcpro2; | |
58 EMACS_INT position, seenS = 0; | |
59 | |
60 GCPRO2 (fdstream, instream); | |
61 | |
3411 | 62 position = doc_pos > buffer_size ? |
63 doc_pos - buffer_size : 0; | |
3368 | 64 |
65 if (0 > lseek (fd, position, 0)) | |
66 { | |
67 if (name_nonreloc) | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
68 name_reloc = build_istring (name_nonreloc); |
3368 | 69 return_me = list3 (build_msg_string |
70 ("Position out of range in doc string file"), | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
71 name_reloc, make_fixnum (position)); |
3368 | 72 goto done; |
73 } | |
74 | |
75 fdstream = make_filedesc_input_stream (fd, 0, -1, 0); | |
76 Lstream_set_buffering (XLSTREAM (fdstream), LSTREAM_UNBUFFERED, 0); | |
77 instream = | |
78 make_coding_input_stream | |
79 (XLSTREAM (fdstream), standard_doc_file ? Qescape_quoted : Qbinary, | |
80 CODING_DECODE, 0); | |
81 Lstream_set_buffering (XLSTREAM (instream), LSTREAM_UNBUFFERED, 0); | |
82 | |
83 space_left = buffer_size - (p - buffer); | |
84 while (space_left > 0) | |
85 { | |
86 int nread; | |
87 | |
88 nread = Lstream_read (XLSTREAM (instream), p, space_left); | |
89 if (nread < 0) | |
90 { | |
91 return_me = list1 (build_msg_string | |
92 ("Read error on documentation file")); | |
93 goto done; | |
94 } | |
95 | |
96 p[nread] = 0; | |
97 | |
98 if (!nread) | |
99 break; | |
100 | |
101 p += nread; | |
102 space_left = buffer_size - (p - buffer); | |
103 } | |
104 | |
105 /* First, search backward for the "\037S" that marks the beginning of the | |
106 file name, then search forward from that to the newline or to the end | |
107 of the buffer. */ | |
108 from = p; | |
109 | |
110 while (from > buf) | |
111 { | |
112 --from; | |
113 if (seenS) | |
114 { | |
115 if ('\037' == *from) | |
116 { | |
117 /* Got a file name; adjust `from' to point to it, break out of | |
118 the loop. */ | |
119 from += 2; | |
120 break; | |
121 } | |
122 } | |
123 /* Is *from 'S' ? */ | |
124 seenS = ('S' == *from); | |
125 } | |
126 | |
127 if (buf == from) | |
128 { | |
129 /* We've scanned back to the beginning of the buffer without hitting | |
130 the file name. Either the file name plus the symbol name is longer | |
131 than DOC_MAX_FILENAME_LENGTH--which shouldn't happen, because it'll | |
132 trigger an assertion failure in make-docfile, the DOC file is | |
133 corrupt, or it was produced by a version of make-docfile that | |
134 doesn't store the file name with the symbol name and docstring. */ | |
135 return_me = list1 (build_msg_string | |
136 ("Object file name not stored in doc file")); | |
137 goto done; | |
138 } | |
139 | |
140 to = from; | |
141 /* Search for the end of the file name. */ | |
142 while (++to < p) | |
143 { | |
144 if ('\n' == *to || '\037' == *to) | |
145 { | |
146 break; | |
147 } | |
148 } | |
149 | |
150 /* Don't require the file name to end in a newline. */ | |
151 return_me = make_string (from, to - from); | |
152 | |
153 done: | |
154 if (!NILP (instream)) | |
155 { | |
156 Lstream_delete (XLSTREAM (instream)); | |
157 Lstream_delete (XLSTREAM (fdstream)); | |
158 } | |
159 | |
160 UNGCPRO; | |
161 return return_me; | |
162 } | |
428 | 163 |
164 Lisp_Object | |
165 unparesseuxify_doc_string (int fd, EMACS_INT position, | |
867 | 166 Ibyte *name_nonreloc, Lisp_Object name_reloc, |
814 | 167 int standard_doc_file) |
428 | 168 { |
867 | 169 Ibyte buf[512 * 32 + 1]; |
170 Ibyte *buffer = buf; | |
3411 | 171 int buffer_size = sizeof (buf) - 1; |
867 | 172 Ibyte *from, *to; |
173 REGISTER Ibyte *p = buffer; | |
428 | 174 Lisp_Object return_me; |
814 | 175 Lisp_Object fdstream = Qnil, instream = Qnil; |
176 struct gcpro gcpro1, gcpro2; | |
177 | |
178 GCPRO2 (fdstream, instream); | |
428 | 179 |
180 if (0 > lseek (fd, position, 0)) | |
181 { | |
182 if (name_nonreloc) | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
183 name_reloc = build_istring (name_nonreloc); |
771 | 184 return_me = list3 (build_msg_string |
428 | 185 ("Position out of range in doc string file"), |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
186 name_reloc, make_fixnum (position)); |
428 | 187 goto done; |
188 } | |
189 | |
814 | 190 fdstream = make_filedesc_input_stream (fd, 0, -1, 0); |
191 Lstream_set_buffering (XLSTREAM (fdstream), LSTREAM_UNBUFFERED, 0); | |
192 instream = | |
193 make_coding_input_stream | |
194 /* Major trouble if we are too clever when reading byte-code | |
195 instructions! | |
196 | |
197 #### We should have a way of handling escape-quoted elc files | |
198 (i.e. files with non-ASCII/Latin-1 chars in them). Currently this | |
199 is "solved" in bytecomp.el by never inserting lazy references in | |
200 such files. */ | |
826 | 201 (XLSTREAM (fdstream), standard_doc_file ? Qescape_quoted : Qbinary, |
814 | 202 CODING_DECODE, 0); |
203 Lstream_set_buffering (XLSTREAM (instream), LSTREAM_UNBUFFERED, 0); | |
204 | |
428 | 205 /* Read the doc string into a buffer. |
206 Use the fixed buffer BUF if it is big enough; otherwise allocate one. | |
207 We store the buffer in use in BUFFER and its size in BUFFER_SIZE. */ | |
208 | |
209 while (1) | |
210 { | |
211 int space_left = buffer_size - (p - buffer); | |
212 int nread; | |
213 | |
214 /* Switch to a bigger buffer if we need one. */ | |
215 if (space_left == 0) | |
216 { | |
867 | 217 Ibyte *old_buffer = buffer; |
3411 | 218 buffer_size *= 2; |
219 | |
771 | 220 if (buffer == buf) |
221 { | |
3411 | 222 buffer = xnew_ibytes (buffer_size + 1); |
771 | 223 memcpy (buffer, old_buffer, p - old_buffer); |
224 } | |
225 else | |
3411 | 226 XREALLOC_ARRAY (buffer, Ibyte, buffer_size + 1); |
428 | 227 p += buffer - old_buffer; |
228 space_left = buffer_size - (p - buffer); | |
229 } | |
230 | |
231 /* Don't read too much at one go. */ | |
232 if (space_left > 1024 * 8) | |
233 space_left = 1024 * 8; | |
814 | 234 nread = Lstream_read (XLSTREAM (instream), p, space_left); |
428 | 235 if (nread < 0) |
236 { | |
771 | 237 return_me = list1 (build_msg_string |
428 | 238 ("Read error on documentation file")); |
239 goto done; | |
240 } | |
241 p[nread] = 0; | |
242 if (!nread) | |
243 break; | |
244 { | |
867 | 245 Ibyte *p1 = qxestrchr (p, '\037'); /* End of doc string marker */ |
814 | 246 if (p1) |
247 { | |
248 *p1 = 0; | |
249 p = p1; | |
250 break; | |
251 } | |
428 | 252 } |
253 p += nread; | |
254 } | |
255 | |
256 /* Scan the text and remove quoting with ^A (char code 1). | |
257 ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_. */ | |
258 from = to = buffer; | |
259 while (from < p) | |
260 { | |
261 if (*from != 1 /*^A*/) | |
262 *to++ = *from++; | |
263 else | |
264 { | |
265 int c = *(++from); | |
266 | |
267 from++; | |
268 switch (c) | |
269 { | |
270 case 1: *to++ = c; break; | |
271 case '0': *to++ = '\0'; break; | |
272 case '_': *to++ = '\037'; break; | |
273 default: | |
771 | 274 return_me = list2 (build_msg_string |
428 | 275 ("Invalid data in documentation file -- ^A followed by weird code"), |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
276 make_fixnum (c)); |
428 | 277 goto done; |
278 } | |
279 } | |
280 } | |
281 | |
814 | 282 return_me = make_string (buffer, to - buffer); |
428 | 283 |
284 done: | |
814 | 285 if (!NILP (instream)) |
286 { | |
287 Lstream_delete (XLSTREAM (instream)); | |
288 Lstream_delete (XLSTREAM (fdstream)); | |
289 } | |
290 UNGCPRO; | |
428 | 291 if (buffer != buf) /* We must have allocated buffer above */ |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
292 xfree (buffer); |
428 | 293 return return_me; |
294 } | |
295 | |
771 | 296 #define string_join(dest, s1, s2) \ |
297 memcpy (dest, XSTRING_DATA (s1), XSTRING_LENGTH (s1)); \ | |
298 memcpy (dest + XSTRING_LENGTH (s1), XSTRING_DATA (s2), \ | |
299 XSTRING_LENGTH (s2)); \ | |
428 | 300 dest[XSTRING_LENGTH (s1) + XSTRING_LENGTH (s2)] = '\0' |
301 | |
302 /* Extract a doc string from a file. FILEPOS says where to get it. | |
303 (This could actually be byte code instructions/constants instead | |
304 of a doc string.) | |
305 If it is an integer, use that position in the standard DOC file. | |
306 If it is (FILE . INTEGER), use FILE as the file name | |
307 and INTEGER as the position in that file. | |
308 But if INTEGER is negative, make it positive. | |
309 (A negative integer is used for user variables, so we can distinguish | |
310 them without actually fetching the doc string.) */ | |
311 | |
312 static Lisp_Object | |
313 get_doc_string (Lisp_Object filepos) | |
314 { | |
315 REGISTER int fd; | |
867 | 316 REGISTER Ibyte *name_nonreloc = 0; |
428 | 317 EMACS_INT position; |
318 Lisp_Object file, tem; | |
319 Lisp_Object name_reloc = Qnil; | |
814 | 320 int standard_doc_file = 0; |
428 | 321 |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
322 if (FIXNUMP (filepos)) |
428 | 323 { |
324 file = Vinternal_doc_file_name; | |
814 | 325 standard_doc_file = 1; |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
326 position = XFIXNUM (filepos); |
428 | 327 } |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
328 else if (CONSP (filepos) && FIXNUMP (XCDR (filepos))) |
428 | 329 { |
330 file = XCAR (filepos); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
331 position = XFIXNUM (XCDR (filepos)); |
428 | 332 if (position < 0) |
333 position = - position; | |
334 } | |
335 else | |
336 return Qnil; | |
337 | |
338 if (!STRINGP (file)) | |
339 return Qnil; | |
340 | |
341 /* Put the file name in NAME as a C string. | |
342 If it is relative, combine it with Vdoc_directory. */ | |
343 | |
344 tem = Ffile_name_absolute_p (file); | |
345 if (NILP (tem)) | |
346 { | |
647 | 347 Bytecount minsize; |
428 | 348 /* XEmacs: Move this check here. OK if called during loadup to |
349 load byte code instructions. */ | |
350 if (!STRINGP (Vdoc_directory)) | |
351 return Qnil; | |
352 | |
353 minsize = XSTRING_LENGTH (Vdoc_directory); | |
354 /* sizeof ("../lib-src/") == 12 */ | |
355 if (minsize < 12) | |
356 minsize = 12; | |
867 | 357 name_nonreloc = alloca_ibytes (minsize + XSTRING_LENGTH (file) + 8); |
428 | 358 string_join (name_nonreloc, Vdoc_directory, file); |
359 } | |
360 else | |
361 name_reloc = file; | |
362 | |
771 | 363 fd = qxe_open (name_nonreloc ? name_nonreloc : |
364 XSTRING_DATA (name_reloc), O_RDONLY | OPEN_BINARY, 0); | |
428 | 365 if (fd < 0) |
366 { | |
367 if (purify_flag) | |
368 { | |
369 /* sizeof ("../lib-src/") == 12 */ | |
2367 | 370 name_nonreloc = alloca_ibytes (12 + XSTRING_LENGTH (file) + 8); |
428 | 371 /* Preparing to dump; DOC file is probably not installed. |
372 So check in ../lib-src. */ | |
2367 | 373 qxestrcpy_ascii (name_nonreloc, "../lib-src/"); |
771 | 374 qxestrcat (name_nonreloc, XSTRING_DATA (file)); |
428 | 375 |
771 | 376 fd = qxe_open (name_nonreloc, O_RDONLY | OPEN_BINARY, 0); |
428 | 377 } |
378 | |
379 if (fd < 0) | |
814 | 380 report_file_error ("Cannot open doc string file", |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
381 name_nonreloc ? build_istring (name_nonreloc) : |
814 | 382 name_reloc); |
428 | 383 } |
384 | |
814 | 385 tem = unparesseuxify_doc_string (fd, position, name_nonreloc, name_reloc, |
386 standard_doc_file); | |
771 | 387 retry_close (fd); |
428 | 388 |
389 if (!STRINGP (tem)) | |
563 | 390 signal_error_1 (Qinvalid_byte_code, tem); |
428 | 391 |
392 return tem; | |
393 } | |
394 | |
395 /* Get a string from position FILEPOS and pass it through the Lisp reader. | |
396 We use this for fetching the bytecode string and constants vector | |
397 of a compiled function from the .elc file. */ | |
398 | |
399 Lisp_Object | |
400 read_doc_string (Lisp_Object filepos) | |
401 { | |
402 Lisp_Object string = get_doc_string (filepos); | |
403 | |
404 if (!STRINGP (string)) | |
563 | 405 invalid_state ("loading bytecode failed to return string", string); |
428 | 406 return Fread (string); |
407 } | |
408 | |
3368 | 409 static Lisp_Object |
410 get_object_file_name (Lisp_Object filepos) | |
411 { | |
412 REGISTER int fd; | |
413 REGISTER Ibyte *name_nonreloc = 0; | |
414 EMACS_INT position; | |
415 Lisp_Object file, tem; | |
416 Lisp_Object name_reloc = Qnil; | |
417 int standard_doc_file = 0; | |
418 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
419 if (FIXNUMP (filepos)) |
3368 | 420 { |
421 file = Vinternal_doc_file_name; | |
422 standard_doc_file = 1; | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
423 position = XFIXNUM (filepos); |
3368 | 424 } |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
425 else if (CONSP (filepos) && FIXNUMP (XCDR (filepos))) |
3368 | 426 { |
427 file = XCAR (filepos); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
428 position = XFIXNUM (XCDR (filepos)); |
3368 | 429 if (position < 0) |
430 position = - position; | |
431 } | |
432 else | |
433 return Qnil; | |
434 | |
435 if (!STRINGP (file)) | |
436 return Qnil; | |
437 | |
438 /* Put the file name in NAME as a C string. | |
439 If it is relative, combine it with Vdoc_directory. */ | |
440 | |
441 tem = Ffile_name_absolute_p (file); | |
442 if (NILP (tem)) | |
443 { | |
444 Bytecount minsize; | |
445 /* XEmacs: Move this check here. OK if called during loadup to | |
446 load byte code instructions. */ | |
447 if (!STRINGP (Vdoc_directory)) | |
448 return Qnil; | |
449 | |
450 minsize = XSTRING_LENGTH (Vdoc_directory); | |
451 /* sizeof ("../lib-src/") == 12 */ | |
452 if (minsize < 12) | |
453 minsize = 12; | |
454 name_nonreloc = alloca_ibytes (minsize + XSTRING_LENGTH (file) + 8); | |
455 string_join (name_nonreloc, Vdoc_directory, file); | |
456 } | |
457 else | |
458 name_reloc = file; | |
459 | |
460 fd = qxe_open (name_nonreloc ? name_nonreloc : | |
461 XSTRING_DATA (name_reloc), O_RDONLY | OPEN_BINARY, 0); | |
462 if (fd < 0) | |
463 { | |
464 if (purify_flag) | |
465 { | |
466 /* sizeof ("../lib-src/") == 12 */ | |
467 name_nonreloc = alloca_ibytes (12 + XSTRING_LENGTH (file) + 8); | |
468 /* Preparing to dump; DOC file is probably not installed. | |
469 So check in ../lib-src. */ | |
470 qxestrcpy_ascii (name_nonreloc, "../lib-src/"); | |
471 qxestrcat (name_nonreloc, XSTRING_DATA (file)); | |
472 | |
473 fd = qxe_open (name_nonreloc, O_RDONLY | OPEN_BINARY, 0); | |
474 } | |
475 | |
476 if (fd < 0) | |
477 report_file_error ("Cannot open doc string file", | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
478 name_nonreloc ? build_istring (name_nonreloc) : |
3368 | 479 name_reloc); |
480 } | |
481 | |
482 tem = extract_object_file_name (fd, position, name_nonreloc, name_reloc, | |
483 standard_doc_file); | |
484 retry_close (fd); | |
485 | |
486 if (!STRINGP (tem)) | |
487 signal_error_1 (Qinvalid_byte_code, tem); | |
488 | |
489 return tem; | |
490 } | |
491 | |
492 | |
493 static void | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
494 weird_doc (Lisp_Object sym, const Ascbyte *weirdness, const Ascbyte *type, |
3368 | 495 int pos) |
496 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
497 if (!strcmp (weirdness, "duplicate")) return; |
3368 | 498 message ("Note: Strange doc (%s) for %s %s @ %d", |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
499 GETTEXT (weirdness), GETTEXT (type), |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
500 XSTRING_DATA (XSYMBOL (sym)->name), pos); |
3368 | 501 } |
502 | |
4367
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
503 DEFUN ("built-in-symbol-file", Fbuilt_in_symbol_file, 1, 2, 0, /* |
3368 | 504 Return the C source file built-in symbol SYM comes from. |
505 Don't use this. Use the more general `symbol-file' (q.v.) instead. | |
4367
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
506 |
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
507 If TYPE is nil or omitted, any kind of definition is acceptable. |
4905
755ae5b97edb
Change "special form" to "special operator" in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4539
diff
changeset
|
508 If TYPE is `defun', then function, subr, special operator or macro definitions |
4367
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
509 are acceptable. |
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
510 If TYPE is `defvar', then variable definitions are acceptable. |
3368 | 511 */ |
4367
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
512 (symbol, type)) |
3368 | 513 { |
514 /* This function can GC */ | |
515 Lisp_Object fun; | |
516 Lisp_Object filename = Qnil; | |
517 | |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
518 CHECK_SYMBOL (symbol); |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
519 |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
520 if (!UNBOUNDP (XSYMBOL_FUNCTION (symbol)) |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
521 && (NILP (type) || EQ (type, Qdefun))) |
3368 | 522 { |
523 fun = Findirect_function (symbol); | |
524 | |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
525 if (EQ (Qmacro, Fcar_safe (fun))) |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
526 { |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
527 fun = XCDR (fun); |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
528 } |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
529 |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
530 if (SUBRP (fun)) |
3368 | 531 { |
532 if (XSUBR (fun)->doc == 0) | |
533 return Qnil; | |
534 | |
535 if ((EMACS_INT) XSUBR (fun)->doc >= 0) | |
536 { | |
537 weird_doc (symbol, "No file info available for function", | |
538 GETTEXT("function"), 0); | |
539 return Qnil; | |
540 } | |
541 else | |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
542 { |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
543 filename = get_object_file_name |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
544 (make_fixnum (- (EMACS_INT) XSUBR (fun)->doc)); |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
545 return filename; |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
546 } |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
547 } |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
548 |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
549 if (COMPILED_FUNCTIONP (fun)) |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
550 { |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
551 Lisp_Object tem; |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
552 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun); |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
553 |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
554 if (! (f->flags.documentationp)) |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
555 return Qnil; |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
556 tem = compiled_function_documentation (f); |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
557 if (NATNUMP (tem)) |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
558 { |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
559 return get_object_file_name (tem); |
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
560 } |
3368 | 561 } |
562 } | |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
563 |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
564 if (!UNBOUNDP (XSYMBOL_VALUE (symbol)) && (NILP (type) || EQ (type, Qdefvar))) |
3368 | 565 { |
566 Lisp_Object doc_offset = Fget (symbol, Qvariable_documentation, Qnil); | |
567 | |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
568 if (!NILP (doc_offset)) |
3368 | 569 { |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
570 if (FIXNUMP (doc_offset)) |
3368 | 571 { |
5596
3b1d4fa716a4
Ignore lazy docstring info, #'built-in-symbol-file; nothing built-in uses it.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5581
diff
changeset
|
572 filename = get_object_file_name |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
573 (XFIXNUM (doc_offset) > 0 ? doc_offset |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
574 : make_fixnum (- XFIXNUM (doc_offset))); |
3368 | 575 } |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
576 return filename; |
3368 | 577 } |
578 } | |
4539
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
579 |
061e030e3270
Fix some bugs in load-history construction, built-in symbol file names.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4381
diff
changeset
|
580 return Qnil; |
3368 | 581 } |
582 | |
5789
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
583 DEFUN ("documentation-property", Fdocumentation_property, 2, 3, 0, /* |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
584 Return the documentation string that is SYMBOL's PROP property. |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
585 This is like `get', but it can refer to strings stored in the |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
586 `doc-directory/DOC' file; and if the value is a string, it is passed |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
587 through `substitute-command-keys'. A non-nil third argument avoids this |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
588 translation. |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
589 */ |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
590 (symbol, prop, raw)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
591 { |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
592 /* This function can GC */ |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
593 Lisp_Object doc = Qnil; |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
594 #ifdef I18N3 |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
595 REGISTER Lisp_Object domain; |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
596 #endif |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
597 struct gcpro gcpro1; |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
598 |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
599 GCPRO1 (doc); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
600 |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
601 doc = Fget (symbol, prop, Qnil); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
602 if (FIXNUMP (doc)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
603 doc = get_doc_string (XFIXNUM (doc) > 0 ? doc : make_fixnum (- XFIXNUM (doc))); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
604 else if (CONSP (doc)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
605 doc = get_doc_string (doc); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
606 #ifdef I18N3 |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
607 if (!NILP (doc)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
608 { |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
609 domain = Fget (symbol, Qvariable_domain, Qnil); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
610 if (NILP (domain)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
611 doc = Fgettext (doc); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
612 else |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
613 doc = Fdgettext (domain, doc); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
614 } |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
615 #endif |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
616 if (NILP (raw) && STRINGP (doc)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
617 doc = Fsubstitute_command_keys (doc); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
618 UNGCPRO; |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
619 return doc; |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
620 } |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
621 |
428 | 622 DEFUN ("documentation", Fdocumentation, 1, 2, 0, /* |
623 Return the documentation string of FUNCTION. | |
444 | 624 Unless a non-nil second argument RAW is given, the |
428 | 625 string is passed through `substitute-command-keys'. |
626 */ | |
627 (function, raw)) | |
628 { | |
629 /* This function can GC */ | |
630 Lisp_Object fun; | |
631 Lisp_Object doc; | |
632 | |
5789
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
633 if (SYMBOLP (function)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
634 { |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
635 Lisp_Object tem = Fget (function, Qfunction_documentation, Qnil); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
636 if (!NILP (tem)) |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
637 return Fdocumentation_property (function, Qfunction_documentation, |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
638 raw); |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
639 } |
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
640 |
428 | 641 fun = Findirect_function (function); |
642 | |
643 if (SUBRP (fun)) | |
644 { | |
645 if (XSUBR (fun)->doc == 0) | |
646 return Qnil; | |
647 if ((EMACS_INT) XSUBR (fun)->doc >= 0) | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
648 doc = build_cistring (XSUBR (fun)->doc); |
428 | 649 else |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
650 doc = get_doc_string (make_fixnum (- (EMACS_INT) XSUBR (fun)->doc)); |
428 | 651 } |
652 else if (COMPILED_FUNCTIONP (fun)) | |
653 { | |
654 Lisp_Object tem; | |
440 | 655 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun); |
428 | 656 if (! (f->flags.documentationp)) |
657 return Qnil; | |
658 tem = compiled_function_documentation (f); | |
659 if (STRINGP (tem)) | |
660 doc = tem; | |
661 else if (NATNUMP (tem) || CONSP (tem)) | |
5206
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
662 { |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
663 doc = get_doc_string (tem); |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
664 /* We may have zero length strings in the docfile for file |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
665 information. */ |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
666 if (STRINGP (doc) && 0 == XSTRING_LENGTH (doc)) |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
667 { |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
668 return Qnil; |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
669 } |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
670 } |
428 | 671 else |
672 return Qnil; | |
673 } | |
674 else if (KEYMAPP (fun)) | |
771 | 675 return build_msg_string ("Prefix command (definition is a keymap of subcommands)."); |
428 | 676 else if (STRINGP (fun) || VECTORP (fun)) |
771 | 677 return build_msg_string ("Keyboard macro."); |
428 | 678 else if (CONSP (fun)) |
679 { | |
680 Lisp_Object funcar = Fcar (fun); | |
681 | |
682 if (!SYMBOLP (funcar)) | |
683 return Fsignal (Qinvalid_function, list1 (fun)); | |
684 else if (EQ (funcar, Qlambda) | |
685 || EQ (funcar, Qautoload)) | |
686 { | |
687 Lisp_Object tem, tem1; | |
688 tem1 = Fcdr (Fcdr (fun)); | |
689 tem = Fcar (tem1); | |
690 if (STRINGP (tem)) | |
691 doc = tem; | |
692 /* Handle a doc reference--but these never come last | |
693 in the function body, so reject them if they are last. */ | |
694 else if ((NATNUMP (tem) || CONSP (tem)) | |
695 && ! NILP (XCDR (tem1))) | |
696 doc = get_doc_string (tem); | |
697 else | |
698 return Qnil; | |
699 } | |
700 else if (EQ (funcar, Qmacro)) | |
701 return Fdocumentation (Fcdr (fun), raw); | |
702 else | |
703 goto oops; | |
704 } | |
705 else | |
706 { | |
707 oops: | |
708 return Fsignal (Qinvalid_function, list1 (fun)); | |
709 } | |
710 | |
711 if (NILP (raw)) | |
712 { | |
713 struct gcpro gcpro1; | |
714 #ifdef I18N3 | |
715 Lisp_Object domain = Qnil; | |
716 if (COMPILED_FUNCTIONP (fun)) | |
717 domain = compiled_function_domain (XCOMPILED_FUNCTION (fun)); | |
718 if (NILP (domain)) | |
719 doc = Fgettext (doc); | |
720 else | |
721 doc = Fdgettext (domain, doc); | |
722 #endif | |
723 | |
724 GCPRO1 (doc); | |
725 doc = Fsubstitute_command_keys (doc); | |
726 UNGCPRO; | |
727 } | |
728 return doc; | |
729 } | |
730 | |
731 | |
732 DEFUN ("Snarf-documentation", Fsnarf_documentation, 1, 1, 0, /* | |
733 Used during Emacs initialization, before dumping runnable Emacs, | |
734 to find pointers to doc strings stored in `.../lib-src/DOC' and | |
735 record them in function definitions. | |
736 One arg, FILENAME, a string which does not include a directory. | |
737 The file is written to `../lib-src', and later found in `exec-directory' | |
738 when doc strings are referred to in the dumped Emacs. | |
739 */ | |
740 (filename)) | |
741 { | |
742 int fd; | |
867 | 743 Ibyte buf[1024 + 1]; |
428 | 744 REGISTER int filled; |
745 REGISTER int pos; | |
867 | 746 REGISTER Ibyte *p, *end; |
428 | 747 Lisp_Object sym, fun, tem; |
867 | 748 Ibyte *name; |
428 | 749 |
814 | 750 /* This function should not pass the data it's reading through a coding |
751 stream. The reason is that the only purpose of this function is to | |
752 find the file offsets for the documentation of the various functions, | |
753 not do anything with the documentation itself. If we pass through a | |
754 coding stream, the pointers will get messed up when we start reading | |
755 ISO 2022 data because our pointers will reflect internal format, not | |
756 external format. */ | |
757 | |
428 | 758 if (!purify_flag) |
563 | 759 invalid_operation ("Snarf-documentation can only be called in an undumped Emacs", Qunbound); |
428 | 760 |
761 CHECK_STRING (filename); | |
762 | |
1330 | 763 { |
764 name = alloca_ibytes (XSTRING_LENGTH (filename) + 14); | |
2367 | 765 qxestrcpy_ascii (name, "../lib-src/"); |
1330 | 766 } |
428 | 767 |
771 | 768 qxestrcat (name, XSTRING_DATA (filename)); |
428 | 769 |
771 | 770 fd = qxe_open (name, O_RDONLY | OPEN_BINARY, 0); |
428 | 771 if (fd < 0) |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
772 report_file_error ("Opening doc string file", build_istring (name)); |
428 | 773 Vinternal_doc_file_name = filename; |
774 filled = 0; | |
775 pos = 0; | |
776 while (1) | |
777 { | |
778 if (filled < 512) | |
771 | 779 filled += retry_read (fd, &buf[filled], sizeof (buf) - 1 - filled); |
428 | 780 if (!filled) |
781 break; | |
782 | |
783 buf[filled] = 0; | |
784 p = buf; | |
785 end = buf + (filled < 512 ? filled : filled - 128); | |
786 while (p != end && *p != '\037') p++; | |
787 /* p points to ^_Ffunctionname\n or ^_Vvarname\n. */ | |
788 if (p != end) | |
789 { | |
771 | 790 end = qxestrchr (p, '\n'); |
3548 | 791 /* If you trigger a failure with this assertion, you probably |
792 configured with --quick-build and need to rebuild your DOC | |
3545 | 793 file. */ |
794 assert((end - p - 2) > -1); | |
771 | 795 sym = oblookup (Vobarray, p + 2, end - p - 2); |
428 | 796 if (SYMBOLP (sym)) |
797 { | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
798 Lisp_Object offset = make_fixnum (pos + end + 1 - buf); |
428 | 799 /* Attach a docstring to a variable */ |
800 if (p[1] == 'V') | |
801 { | |
802 /* Install file-position as variable-documentation property | |
803 and make it negative for a user-variable | |
804 (doc starts with a `*'). */ | |
805 Lisp_Object old = Fget (sym, Qvariable_documentation, Qzero); | |
806 if (!ZEROP (old)) | |
807 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
808 weird_doc (sym, "duplicate", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
809 "variable", pos); |
428 | 810 /* In the case of duplicate doc file entries, always |
811 take the later one. But if the doc is not an int | |
812 (a string, say) leave it alone. */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
813 if (!FIXNUMP (old)) |
428 | 814 goto weird; |
815 } | |
816 Fput (sym, Qvariable_documentation, | |
817 ((end[1] == '*') | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
818 ? make_fixnum (- XFIXNUM (offset)) |
428 | 819 : offset)); |
820 } | |
821 /* Attach a docstring to a function. | |
822 The type determines where the docstring is stored. */ | |
823 else if (p[1] == 'F') | |
824 { | |
825 fun = indirect_function (sym,0); | |
826 | |
827 if (CONSP (fun) && EQ (XCAR (fun), Qmacro)) | |
828 fun = XCDR (fun); | |
829 | |
830 if (UNBOUNDP (fun)) | |
831 { | |
771 | 832 #if 0 /* There are lots of legitimate cases where this message will appear |
833 (e.g. any function that's only defined when MULE is defined, | |
834 provided that the function is used somewhere in a dumped Lisp | |
835 file, so that the symbol is interned in the dumped XEmacs), and | |
836 there's not a lot that can be done to eliminate the warning other | |
837 than kludges like moving the function to a Mule-only source file, | |
838 which often results in ugly code. Furthermore, the only point of | |
839 this warning is to warn you when you have a DEFUN that you forget | |
840 to DEFSUBR, but the compiler will also warn you, because the DEFUN | |
841 declares a static object, and the object will be unused -- you'll | |
842 get something like | |
843 | |
844 /src/xemacs/mule/src/abbrev.c:269: warning: `SFexpand_abbrev' defined but not used | |
845 | |
846 So I'm disabling this. --ben */ | |
847 | |
428 | 848 /* May have been #if'ed out or something */ |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
849 weird_doc (sym, "not fboundp", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
850 "function", pos); |
771 | 851 #endif |
428 | 852 goto weird; |
853 } | |
854 else if (SUBRP (fun)) | |
855 { | |
856 /* Lisp_Subrs have a slot for it. */ | |
857 if (XSUBR (fun)->doc) | |
858 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
859 weird_doc (sym, "duplicate", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
860 "subr", pos); |
428 | 861 goto weird; |
862 } | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
863 XSUBR (fun)->doc = (char *) (- XFIXNUM (offset)); |
428 | 864 } |
865 else if (CONSP (fun)) | |
866 { | |
867 /* If it's a lisp form, stick it in the form. */ | |
868 tem = XCAR (fun); | |
869 if (EQ (tem, Qlambda) || EQ (tem, Qautoload)) | |
870 { | |
871 tem = Fcdr (Fcdr (fun)); | |
872 if (CONSP (tem) && | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
873 FIXNUMP (XCAR (tem))) |
428 | 874 { |
875 Lisp_Object old = XCAR (tem); | |
876 if (!ZEROP (old)) | |
877 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
878 if (EQ (tem, Qlambda)) |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
879 weird_doc (sym, "duplicate", "lambda", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
880 pos); |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
881 else |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
882 weird_doc (sym, "duplicate", "autoload", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
883 pos); |
428 | 884 /* In the case of duplicate doc file entries, |
885 always take the later one. But if the doc | |
886 is not an int (a string, say) leave it | |
887 alone. */ | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
888 if (!FIXNUMP (old)) |
428 | 889 goto weird; |
890 } | |
891 XCAR (tem) = offset; | |
892 } | |
893 else if (!CONSP (tem)) | |
894 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
895 weird_doc (sym, "!CONSP(tem)", "function", pos); |
428 | 896 goto cont; |
897 } | |
898 else | |
899 { | |
900 /* DOC string is a string not integer 0 */ | |
901 #if 0 | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
902 weird_doc (sym, "!FIXNUMP(XCAR(tem))", |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
903 "function", pos); |
428 | 904 #endif |
905 goto cont; | |
906 } | |
907 } | |
908 else | |
909 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
910 weird_doc (sym, "not lambda or autoload", |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
911 "function", pos); |
428 | 912 goto cont; |
913 } | |
914 } | |
915 else if (COMPILED_FUNCTIONP (fun)) | |
916 { | |
917 /* Compiled-Function objects sometimes have | |
918 slots for it. */ | |
440 | 919 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun); |
428 | 920 |
5206
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
921 /* If there were multiple definitions for this function, |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
922 and the latter one didn't |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
923 have any doc, warn and don't blow up. */ |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
924 Lisp_Object old = |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
925 compiled_function_documentation (f); |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
926 if (!ZEROP (old) && !NILP (old)) |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
927 { |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
928 weird_doc (sym, "duplicate", "bytecode", pos); |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
929 /* In the case of duplicate doc file entries, |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
930 always take the later one. But if the doc is |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
931 not an int (a string, say) leave it alone. */ |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
932 if (!FIXNUMP (old)) |
5206
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
933 goto weird; |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
934 } |
428 | 935 |
5206
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
936 /* This may be a function or variable where we want |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
937 to make the file name available. */ |
39d74978fd32
Keep around file info for dumped functions and variables without docstrings.
Aidan Kehoe <kehoea@parhasard.net>
parents:
4976
diff
changeset
|
938 set_compiled_function_documentation (f, offset); |
428 | 939 } |
940 else | |
941 { | |
942 /* Otherwise the function is undefined or | |
943 otherwise weird. Ignore it. */ | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
944 weird_doc (sym, "weird function", "function", pos); |
428 | 945 goto weird; |
946 } | |
947 } | |
948 else | |
949 { | |
950 /* lose: */ | |
771 | 951 signal_error (Qfile_error, "DOC file invalid at position", |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
952 make_fixnum (pos)); |
428 | 953 weird: |
954 /* goto lose */; | |
955 } | |
956 } | |
957 } | |
958 cont: | |
959 pos += end - buf; | |
960 filled -= end - buf; | |
961 memmove (buf, end, filled); | |
962 } | |
771 | 963 retry_close (fd); |
428 | 964 return Qnil; |
965 } | |
966 | |
967 #if 1 /* Don't warn about functions whose doc was lost because they were | |
968 wrapped by advice-freeze.el... */ | |
969 static int | |
970 kludgily_ignore_lost_doc_p (Lisp_Object sym) | |
971 { | |
972 # define kludge_prefix "ad-Orig-" | |
793 | 973 Lisp_Object name = XSYMBOL (sym)->name; |
974 return (XSTRING_LENGTH (name) > (Bytecount) (sizeof (kludge_prefix)) && | |
2367 | 975 !qxestrncmp_ascii (XSTRING_DATA (name), kludge_prefix, |
793 | 976 sizeof (kludge_prefix) - 1)); |
428 | 977 # undef kludge_prefix |
978 } | |
979 #else | |
980 # define kludgily_ignore_lost_doc_p(sym) 0 | |
981 #endif | |
982 | |
983 | |
984 static int | |
5634
2014ff433daf
Support hash COLLECTIONs, #'{all,try}-completion{s,}; add #'test-completion
Aidan Kehoe <kehoea@parhasard.net>
parents:
5596
diff
changeset
|
985 verify_doc_mapper (Lisp_Object UNUSED (key), Lisp_Object sym, void *arg) |
428 | 986 { |
793 | 987 Lisp_Object closure = * (Lisp_Object *) arg; |
428 | 988 |
989 if (!NILP (Ffboundp (sym))) | |
990 { | |
991 int doc = 0; | |
992 Lisp_Object fun = XSYMBOL (sym)->function; | |
993 if (CONSP (fun) && | |
994 EQ (XCAR (fun), Qmacro)) | |
995 fun = XCDR (fun); | |
996 | |
997 if (SUBRP (fun)) | |
998 doc = (EMACS_INT) XSUBR (fun)->doc; | |
999 else if (SYMBOLP (fun)) | |
1000 doc = -1; | |
1001 else if (KEYMAPP (fun)) | |
1002 doc = -1; | |
1003 else if (CONSP (fun)) | |
1004 { | |
1005 Lisp_Object tem = XCAR (fun); | |
1006 if (EQ (tem, Qlambda) || EQ (tem, Qautoload)) | |
1007 { | |
1008 doc = -1; | |
1009 tem = Fcdr (Fcdr (fun)); | |
1010 if (CONSP (tem) && | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
1011 FIXNUMP (XCAR (tem))) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
1012 doc = XFIXNUM (XCAR (tem)); |
428 | 1013 } |
1014 } | |
1015 else if (COMPILED_FUNCTIONP (fun)) | |
1016 { | |
440 | 1017 Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (fun); |
428 | 1018 if (! (f->flags.documentationp)) |
1019 doc = -1; | |
1020 else | |
1021 { | |
1022 Lisp_Object tem = compiled_function_documentation (f); | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
1023 if (FIXNUMP (tem)) |
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
1024 doc = XFIXNUM (tem); |
428 | 1025 } |
1026 } | |
1027 | |
1028 if (doc == 0 && !kludgily_ignore_lost_doc_p (sym)) | |
1029 { | |
1030 message ("Warning: doc lost for function %s.", | |
793 | 1031 XSTRING_DATA (XSYMBOL (sym)->name)); |
428 | 1032 XCDR (closure) = Qt; |
1033 } | |
1034 } | |
1035 if (!NILP (Fboundp (sym))) | |
1036 { | |
1037 Lisp_Object doc = Fget (sym, Qvariable_documentation, Qnil); | |
1038 if (ZEROP (doc)) | |
1039 { | |
1040 message ("Warning: doc lost for variable %s.", | |
793 | 1041 XSTRING_DATA (XSYMBOL (sym)->name)); |
428 | 1042 XCDR (closure) = Qt; |
1043 } | |
1044 } | |
1045 return 0; /* Never stop */ | |
1046 } | |
1047 | |
1048 DEFUN ("Verify-documentation", Fverify_documentation, 0, 0, 0, /* | |
1049 Used to make sure everything went well with Snarf-documentation. | |
1050 Writes to stderr if not. | |
1051 */ | |
1052 ()) | |
1053 { | |
1054 Lisp_Object closure = Fcons (Qnil, Qnil); | |
1055 struct gcpro gcpro1; | |
1056 GCPRO1 (closure); | |
1057 map_obarray (Vobarray, verify_doc_mapper, &closure); | |
1058 if (!NILP (Fcdr (closure))) | |
1059 message ("\n" | |
1060 "This is usually because some files were preloaded by loaddefs.el or\n" | |
1061 "site-load.el, but were not passed to make-docfile by Makefile.\n"); | |
1062 UNGCPRO; | |
1063 return NILP (Fcdr (closure)) ? Qt : Qnil; | |
1064 } | |
1065 | |
1066 | |
1067 DEFUN ("substitute-command-keys", Fsubstitute_command_keys, 1, 1, 0, /* | |
1068 Substitute key descriptions for command names in STRING. | |
1069 Return a new string which is STRING with substrings of the form \\=\\[COMMAND] | |
1070 replaced by either: a keystroke sequence that will invoke COMMAND, | |
1071 or "M-x COMMAND" if COMMAND is not on any keys. | |
1072 Substrings of the form \\=\\{MAPVAR} are replaced by summaries | |
444 | 1073 \(made by `describe-bindings') of the value of MAPVAR, taken as a keymap. |
428 | 1074 Substrings of the form \\=\\<MAPVAR> specify to use the value of MAPVAR |
1075 as the keymap for future \\=\\[COMMAND] substrings. | |
1076 \\=\\= quotes the following character and is discarded; | |
1077 thus, \\=\\=\\=\\= puts \\=\\= into the output, and \\=\\=\\=\\[ puts \\=\\[ into the output. | |
1078 */ | |
444 | 1079 (string)) |
428 | 1080 { |
1081 /* This function can GC */ | |
867 | 1082 Ibyte *buf; |
428 | 1083 int changed = 0; |
867 | 1084 REGISTER Ibyte *strdata; |
1085 REGISTER Ibyte *bufp; | |
428 | 1086 Bytecount strlength; |
1087 Bytecount idx; | |
1088 Bytecount bsize; | |
3025 | 1089 Ibyte *new_; |
444 | 1090 Lisp_Object tem = Qnil; |
1091 Lisp_Object keymap = Qnil; | |
1092 Lisp_Object name = Qnil; | |
867 | 1093 Ibyte *start; |
428 | 1094 Bytecount length; |
1095 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
1096 | |
444 | 1097 if (NILP (string)) |
428 | 1098 return Qnil; |
1099 | |
444 | 1100 CHECK_STRING (string); |
1101 GCPRO4 (string, tem, keymap, name); | |
428 | 1102 |
1103 /* There is the possibility that the string is not destined for a | |
1104 translating stream, and it could be argued that we should do the | |
1105 same thing here as in Fformat(), but there are very few times | |
1106 when this will be the case and many calls to this function | |
1107 would have to have `gettext' calls added. (I18N3) */ | |
444 | 1108 string = LISP_GETTEXT (string); |
428 | 1109 |
1110 /* KEYMAP is either nil (which means search all the active keymaps) | |
1111 or a specified local map (which means search just that and the | |
1112 global map). If non-nil, it might come from Voverriding_local_map, | |
444 | 1113 or from a \\<mapname> construct in STRING itself.. */ |
428 | 1114 #if 0 /* FSFmacs */ |
1115 /* This is really weird and garbagey. If keymap is nil and there's | |
1116 an overriding-local-map, `where-is-internal' will correctly note | |
1117 this, so there's no reason to do it here. Maybe FSFmacs | |
1118 `where-is-internal' is broken. */ | |
1119 /* | |
1120 keymap = current_kboard->Voverriding_terminal_local_map; | |
1121 if (NILP (keymap)) | |
1122 keymap = Voverriding_local_map; | |
1123 */ | |
1124 #endif | |
1125 | |
444 | 1126 strlength = XSTRING_LENGTH (string); |
2367 | 1127 bsize = ITEXT_ZTERM_SIZE + strlength; |
1128 buf = xnew_ibytes (bsize); | |
428 | 1129 bufp = buf; |
1130 | |
1131 /* Have to reset strdata every time GC might be called */ | |
444 | 1132 strdata = XSTRING_DATA (string); |
428 | 1133 for (idx = 0; idx < strlength; ) |
1134 { | |
867 | 1135 Ibyte *strp = strdata + idx; |
428 | 1136 |
1137 if (strp[0] != '\\') | |
1138 { | |
1139 /* just copy other chars */ | |
1140 /* As it happens, this will work with Mule even if the | |
1141 character quoted is multi-byte; the remaining multi-byte | |
1142 characters will just be copied by this loop. */ | |
1143 *bufp++ = *strp; | |
1144 idx++; | |
1145 } | |
1146 else switch (strp[1]) | |
1147 { | |
1148 default: | |
1149 { | |
1150 /* just copy unknown escape sequences */ | |
1151 *bufp++ = *strp; | |
1152 idx++; | |
1153 break; | |
1154 } | |
1155 case '=': | |
1156 { | |
1157 /* \= quotes the next character; | |
1158 thus, to put in \[ without its special meaning, use \=\[. */ | |
1159 /* As it happens, this will work with Mule even if the | |
1160 character quoted is multi-byte; the remaining multi-byte | |
1161 characters will just be copied by this loop. */ | |
1162 changed = 1; | |
1163 *bufp++ = strp[2]; | |
1164 idx += 3; | |
1165 break; | |
1166 } | |
1167 case '[': | |
1168 { | |
1169 changed = 1; | |
1170 idx += 2; /* skip \[ */ | |
1171 strp += 2; | |
1172 start = strp; | |
1173 | |
1174 while ((idx < strlength) | |
1175 && *strp != ']') | |
1176 { | |
1177 strp++; | |
1178 idx++; | |
1179 } | |
1180 length = strp - start; | |
1181 idx++; /* skip ] */ | |
1182 | |
1183 tem = Fintern (make_string (start, length), Qnil); | |
1184 tem = Fwhere_is_internal (tem, keymap, Qt, Qnil, Qnil); | |
1185 | |
1186 #if 0 /* FSFmacs */ | |
444 | 1187 /* Disregard menu bar bindings; it is positively annoying to |
1188 mention them when there's no menu bar, and it isn't terribly | |
1189 useful even when there is a menu bar. */ | |
1190 if (!NILP (tem)) | |
1191 { | |
1192 firstkey = Faref (tem, Qzero); | |
1193 if (EQ (firstkey, Qmenu_bar)) | |
1194 tem = Qnil; | |
1195 } | |
428 | 1196 #endif |
1197 | |
1198 if (NILP (tem)) /* but not on any keys */ | |
1199 { | |
3025 | 1200 new_ = (Ibyte *) xrealloc (buf, bsize += 4); |
1201 bufp += new_ - buf; | |
1202 buf = new_; | |
428 | 1203 memcpy (bufp, "M-x ", 4); |
1204 bufp += 4; | |
1205 goto subst; | |
1206 } | |
1207 else | |
1208 { /* function is on a key */ | |
1209 tem = Fkey_description (tem); | |
1210 goto subst_string; | |
1211 } | |
1212 } | |
1213 case '{': | |
1214 case '<': | |
1215 { | |
444 | 1216 Lisp_Object buffer = Fget_buffer_create (QSsubstitute); |
1217 struct buffer *buf_ = XBUFFER (buffer); | |
428 | 1218 |
1219 Fbuffer_disable_undo (buffer); | |
1220 Ferase_buffer (buffer); | |
1221 | |
1222 /* \{foo} is replaced with a summary of keymap (symbol-value foo). | |
1223 \<foo> just sets the keymap used for \[cmd]. */ | |
1224 changed = 1; | |
1225 idx += 2; /* skip \{ or \< */ | |
1226 strp += 2; | |
1227 start = strp; | |
1228 | |
1229 while ((idx < strlength) | |
1230 && *strp != '}' && *strp != '>') | |
1231 { | |
1232 strp++; | |
1233 idx++; | |
1234 } | |
1235 length = strp - start; | |
1236 idx++; /* skip } or > */ | |
1237 | |
1238 /* Get the value of the keymap in TEM, or nil if undefined. | |
1239 Do this while still in the user's current buffer | |
1240 in case it is a local variable. */ | |
1241 name = Fintern (make_string (start, length), Qnil); | |
1242 tem = Fboundp (name); | |
1243 if (! NILP (tem)) | |
1244 { | |
1245 tem = Fsymbol_value (name); | |
1246 if (! NILP (tem)) | |
1247 tem = get_keymap (tem, 0, 1); | |
1248 } | |
1249 | |
1250 if (NILP (tem)) | |
1251 { | |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1252 buffer_insert_ascstring (buf_, "(uses keymap \""); |
444 | 1253 buffer_insert_lisp_string (buf_, Fsymbol_name (name)); |
4953
304aebb79cd3
function renamings to track names of char typedefs
Ben Wing <ben@xemacs.org>
parents:
4952
diff
changeset
|
1254 buffer_insert_ascstring (buf_, "\", which is not currently defined) "); |
428 | 1255 |
1256 if (start[-1] == '<') keymap = Qnil; | |
1257 } | |
1258 else if (start[-1] == '<') | |
1259 keymap = tem; | |
1260 else | |
1261 describe_map_tree (tem, 1, Qnil, Qnil, 0, buffer); | |
1262 | |
1263 tem = make_string_from_buffer (buf_, BUF_BEG (buf_), | |
1264 BUF_Z (buf_) - BUF_BEG (buf_)); | |
1265 Ferase_buffer (buffer); | |
444 | 1266 } |
1267 goto subst_string; | |
428 | 1268 |
444 | 1269 subst_string: |
1270 start = XSTRING_DATA (tem); | |
1271 length = XSTRING_LENGTH (tem); | |
1272 subst: | |
1273 bsize += length; | |
3025 | 1274 new_ = (Ibyte *) xrealloc (buf, bsize); |
1275 bufp += new_ - buf; | |
1276 buf = new_; | |
444 | 1277 memcpy (bufp, start, length); |
1278 bufp += length; | |
428 | 1279 |
444 | 1280 /* Reset STRDATA in case gc relocated it. */ |
1281 strdata = XSTRING_DATA (string); | |
428 | 1282 |
444 | 1283 break; |
428 | 1284 } |
1285 } | |
1286 | |
1287 if (changed) /* don't bother if nothing substituted */ | |
1288 tem = make_string (buf, bufp - buf); | |
1289 else | |
444 | 1290 tem = string; |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1291 xfree (buf); |
428 | 1292 UNGCPRO; |
1293 return tem; | |
1294 } | |
1295 | |
1296 | |
1297 /************************************************************************/ | |
1298 /* initialization */ | |
1299 /************************************************************************/ | |
1300 | |
1301 void | |
1302 syms_of_doc (void) | |
1303 { | |
3368 | 1304 DEFSUBR (Fbuilt_in_symbol_file); |
428 | 1305 DEFSUBR (Fdocumentation); |
1306 DEFSUBR (Fdocumentation_property); | |
1307 DEFSUBR (Fsnarf_documentation); | |
1308 DEFSUBR (Fverify_documentation); | |
1309 DEFSUBR (Fsubstitute_command_keys); | |
4367
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
1310 |
69e6352406f0
Handle macros, autoloads correctly in symbol-file. Add an incomplete TYPE arg.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3548
diff
changeset
|
1311 DEFSYMBOL (Qdefvar); |
5789
72c5d36ba3b6
Make `define-function' accept docstring, as in GNU Emacs.
Mike Sperber <sperber@deinprogramm.de>
parents:
5634
diff
changeset
|
1312 DEFSYMBOL (Qfunction_documentation); |
428 | 1313 } |
1314 | |
1315 void | |
1316 vars_of_doc (void) | |
1317 { | |
1318 DEFVAR_LISP ("internal-doc-file-name", &Vinternal_doc_file_name /* | |
1319 Name of file containing documentation strings of built-in symbols. | |
1320 */ ); | |
1321 Vinternal_doc_file_name = Qnil; | |
1322 | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4539
diff
changeset
|
1323 QSsubstitute = build_ascstring (" *substitute*"); |
428 | 1324 staticpro (&QSsubstitute); |
1325 } |