Mercurial > hg > xemacs-beta
comparison src/print.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 9d177e8d4150 |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
1 /* Lisp object printing and output streams. | |
2 Copyright (C) 1985, 1986, 1988, 1992-1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1995, 1996 Ben Wing. | |
4 | |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not synched with FSF. */ | |
23 | |
24 /* This file has been Mule-ized. */ | |
25 | |
26 /* Seriously hacked on by Ben Wing for Mule. */ | |
27 | |
28 #include <config.h> | |
29 #include "lisp.h" | |
30 | |
31 #include "backtrace.h" | |
32 #include "buffer.h" | |
33 #include "bytecode.h" | |
34 #include "console-tty.h" | |
35 #include "console-stream.h" | |
36 #include "extents.h" | |
37 #include "frame.h" | |
38 #include "insdel.h" | |
39 #include "lstream.h" | |
40 #include "sysfile.h" | |
41 | |
42 #include <limits.h> | |
43 #include <float.h> | |
44 /* Define if not in float.h */ | |
45 #ifndef DBL_DIG | |
46 #define DBL_DIG 16 | |
47 #endif | |
48 | |
49 Lisp_Object Vstandard_output, Qstandard_output; | |
50 | |
51 /* The subroutine object for external-debugging-output is kept here | |
52 for the convenience of the debugger. */ | |
53 Lisp_Object Qexternal_debugging_output; | |
54 | |
55 /* Avoid actual stack overflow in print. */ | |
56 static int print_depth; | |
57 | |
58 /* Detect most circularities to print finite output. */ | |
59 #define PRINT_CIRCLE 200 | |
60 static Lisp_Object being_printed[PRINT_CIRCLE]; | |
61 | |
62 /* Maximum length of list or vector to print in full; noninteger means | |
63 effectively infinity */ | |
64 | |
65 Lisp_Object Vprint_length; | |
66 Lisp_Object Qprint_length; | |
67 | |
68 /* Maximum length of string to print in full; noninteger means | |
69 effectively infinity */ | |
70 | |
71 Lisp_Object Vprint_string_length; | |
72 Lisp_Object Qprint_string_length; | |
73 | |
74 /* Maximum depth of list to print in full; noninteger means | |
75 effectively infinity. */ | |
76 | |
77 Lisp_Object Vprint_level; | |
78 | |
79 /* Label to use when making echo-area messages. */ | |
80 | |
81 Lisp_Object Vprint_message_label; | |
82 | |
83 /* Nonzero means print newlines in strings as \n. */ | |
84 | |
85 int print_escape_newlines; | |
86 int print_readably; | |
87 | |
88 /* Non-nil means print #: before uninterned symbols. | |
89 Neither t nor nil means so that and don't clear Vprint_gensym_alist | |
90 on entry to and exit from print functions. */ | |
91 Lisp_Object Vprint_gensym; | |
92 Lisp_Object Vprint_gensym_alist; | |
93 | |
94 Lisp_Object Qdisplay_error; | |
95 Lisp_Object Qprint_message_label; | |
96 | |
97 /* Force immediate output of all printed data. Used for debugging. */ | |
98 int print_unbuffered; | |
99 | |
100 FILE *termscript; /* Stdio stream being used for copy of all output. */ | |
101 | |
102 | |
103 | |
104 int stdout_needs_newline; | |
105 | |
106 /* Write a string (in internal format) to stdio stream STREAM. */ | |
107 | |
108 void | |
109 write_string_to_stdio_stream (FILE *stream, struct console *con, | |
110 CONST Bufbyte *str, | |
111 Bytecount offset, Bytecount len, | |
112 enum external_data_format fmt) | |
113 { | |
114 int extlen; | |
115 CONST Extbyte *extptr; | |
116 | |
117 GET_CHARPTR_EXT_DATA_ALLOCA (str + offset, len, fmt, extptr, extlen); | |
118 if (stream) | |
119 { | |
120 fwrite (extptr, 1, extlen, stream); | |
121 #ifdef WINDOWSNT | |
122 /* Q122442 says that pipes are "treated as files, not as | |
123 devices", and that this is a feature. Before I found that | |
124 article, I thought it was a bug. Thanks MS, I feel much | |
125 better now. - kkm */ | |
126 if (stream == stdout || stream == stderr) | |
127 fflush (stream); | |
128 #endif | |
129 } | |
130 else | |
131 { | |
132 assert (CONSOLE_TTY_P (con)); | |
133 Lstream_write (XLSTREAM (CONSOLE_TTY_DATA (con)->outstream), | |
134 extptr, extlen); | |
135 } | |
136 if (stream == stdout || stream == stderr || | |
137 (!stream && CONSOLE_TTY_DATA (con)->is_stdio)) | |
138 { | |
139 if (termscript) | |
140 { | |
141 fwrite (extptr, 1, extlen, termscript); | |
142 fflush (termscript); | |
143 } | |
144 stdout_needs_newline = (extptr[extlen - 1] != '\n'); | |
145 } | |
146 } | |
147 | |
148 /* Write a string to the output location specified in FUNCTION. | |
149 Arguments NONRELOC, RELOC, OFFSET, and LEN are as in | |
150 buffer_insert_string_1() in insdel.c. */ | |
151 | |
152 static void | |
153 output_string (Lisp_Object function, CONST Bufbyte *nonreloc, | |
154 Lisp_Object reloc, Bytecount offset, Bytecount len) | |
155 { | |
156 /* This function can GC */ | |
157 Charcount cclen; | |
158 /* We change the value of nonreloc (fetching it from reloc as | |
159 necessary), but we don't want to pass this changed value on to | |
160 other functions that take both a nonreloc and a reloc, or things | |
161 may get confused and an assertion failure in | |
162 fixup_internal_substring() may get triggered. */ | |
163 CONST Bufbyte *newnonreloc = nonreloc; | |
164 struct gcpro gcpro1, gcpro2; | |
165 | |
166 /* Emacs won't print while GCing, but an external debugger might */ | |
167 if (gc_in_progress) return; | |
168 | |
169 /* Perhaps not necessary but probably safer. */ | |
170 GCPRO2 (function, reloc); | |
171 | |
172 fixup_internal_substring (newnonreloc, reloc, offset, &len); | |
173 | |
174 if (STRINGP (reloc)) | |
175 newnonreloc = XSTRING_DATA (reloc); | |
176 | |
177 cclen = bytecount_to_charcount (newnonreloc + offset, len); | |
178 | |
179 if (LSTREAMP (function)) | |
180 { | |
181 if (STRINGP (reloc)) | |
182 { | |
183 /* Protect against Lstream_write() causing a GC and | |
184 relocating the string. For small strings, we do it by | |
185 alloc'ing the string and using a copy; for large strings, | |
186 we inhibit GC. */ | |
187 if (len < 65536) | |
188 { | |
189 Bufbyte *copied = alloca_array (Bufbyte, len); | |
190 memcpy (copied, newnonreloc + offset, len); | |
191 Lstream_write (XLSTREAM (function), copied, len); | |
192 } | |
193 else | |
194 { | |
195 int speccount = specpdl_depth (); | |
196 record_unwind_protect (restore_gc_inhibit, | |
197 make_int (gc_currently_forbidden)); | |
198 gc_currently_forbidden = 1; | |
199 Lstream_write (XLSTREAM (function), newnonreloc + offset, len); | |
200 unbind_to (speccount, Qnil); | |
201 } | |
202 } | |
203 else | |
204 Lstream_write (XLSTREAM (function), newnonreloc + offset, len); | |
205 | |
206 if (print_unbuffered) | |
207 Lstream_flush (XLSTREAM (function)); | |
208 } | |
209 else if (BUFFERP (function)) | |
210 { | |
211 CHECK_LIVE_BUFFER (function); | |
212 buffer_insert_string (XBUFFER (function), nonreloc, reloc, offset, len); | |
213 } | |
214 else if (MARKERP (function)) | |
215 { | |
216 /* marker_position() will err if marker doesn't point anywhere. */ | |
217 Bufpos spoint = marker_position (function); | |
218 | |
219 buffer_insert_string_1 (XMARKER (function)->buffer, | |
220 spoint, nonreloc, reloc, offset, len, | |
221 0); | |
222 Fset_marker (function, make_int (spoint + cclen), | |
223 Fmarker_buffer (function)); | |
224 } | |
225 else if (FRAMEP (function)) | |
226 { | |
227 /* This gets used by functions not invoking print_prepare(), | |
228 such as Fwrite_char, Fterpri, etc.. */ | |
229 struct frame *f = XFRAME (function); | |
230 CHECK_LIVE_FRAME (function); | |
231 | |
232 if (!EQ (Vprint_message_label, echo_area_status (f))) | |
233 clear_echo_area_from_print (f, Qnil, 1); | |
234 echo_area_append (f, nonreloc, reloc, offset, len, Vprint_message_label); | |
235 } | |
236 else if (EQ (function, Qt) || EQ (function, Qnil)) | |
237 { | |
238 write_string_to_stdio_stream (stdout, 0, newnonreloc, offset, len, | |
239 FORMAT_TERMINAL); | |
240 } | |
241 else | |
242 { | |
243 Charcount ccoff = bytecount_to_charcount (newnonreloc, offset); | |
244 Charcount iii; | |
245 | |
246 for (iii = ccoff; iii < cclen + ccoff; iii++) | |
247 { | |
248 call1 (function, | |
249 make_char (charptr_emchar_n (newnonreloc, iii))); | |
250 if (STRINGP (reloc)) | |
251 newnonreloc = XSTRING_DATA (reloc); | |
252 } | |
253 } | |
254 | |
255 UNGCPRO; | |
256 } | |
257 | |
258 #define RESET_PRINT_GENSYM do { \ | |
259 if (!CONSP (Vprint_gensym)) \ | |
260 Vprint_gensym_alist = Qnil; \ | |
261 } while (0) | |
262 | |
263 static Lisp_Object | |
264 canonicalize_printcharfun (Lisp_Object printcharfun) | |
265 { | |
266 if (NILP (printcharfun)) | |
267 printcharfun = Vstandard_output; | |
268 | |
269 if (EQ (printcharfun, Qt) || NILP (printcharfun)) | |
270 printcharfun = Fselected_frame (Qnil); /* print to minibuffer */ | |
271 | |
272 return printcharfun; | |
273 } | |
274 | |
275 static Lisp_Object | |
276 print_prepare (Lisp_Object printcharfun, Lisp_Object *frame_kludge) | |
277 { | |
278 /* Emacs won't print while GCing, but an external debugger might */ | |
279 if (gc_in_progress) | |
280 return Qnil; | |
281 | |
282 RESET_PRINT_GENSYM; | |
283 | |
284 printcharfun = canonicalize_printcharfun (printcharfun); | |
285 | |
286 /* Here we could safely return the canonicalized PRINTCHARFUN. | |
287 However, if PRINTCHARFUN is a frame, printing of complex | |
288 structures becomes very expensive, because `append-message' | |
289 (called by echo_area_append) gets called as many times as | |
290 output_string() is called (and that's a *lot*). append-message | |
291 tries to keep top of the message-stack in sync with the contents | |
292 of " *Echo Area" buffer, consing a new string for each component | |
293 of the printed structure. For instance, if you print (a a), | |
294 append-message will cons up the following strings: | |
295 | |
296 "(" | |
297 "(a" | |
298 "(a " | |
299 "(a a" | |
300 "(a a)" | |
301 | |
302 and will use only the last one. With larger objects, this turns | |
303 into an O(n^2) consing frenzy that locks up XEmacs in incessant | |
304 garbage collection. | |
305 | |
306 We prevent this by creating a resizing_buffer stream and letting | |
307 the printer write into it. print_finish() will notice this | |
308 stream, and invoke echo_area_append() with the stream's buffer, | |
309 only once. */ | |
310 if (FRAMEP (printcharfun)) | |
311 { | |
312 CHECK_LIVE_FRAME (printcharfun); | |
313 *frame_kludge = printcharfun; | |
314 printcharfun = make_resizing_buffer_output_stream (); | |
315 } | |
316 | |
317 return printcharfun; | |
318 } | |
319 | |
320 static void | |
321 print_finish (Lisp_Object stream, Lisp_Object frame_kludge) | |
322 { | |
323 /* Emacs won't print while GCing, but an external debugger might */ | |
324 if (gc_in_progress) | |
325 return; | |
326 | |
327 RESET_PRINT_GENSYM; | |
328 | |
329 /* See the comment in print_prepare(). */ | |
330 if (FRAMEP (frame_kludge)) | |
331 { | |
332 struct frame *f = XFRAME (frame_kludge); | |
333 Lstream *str = XLSTREAM (stream); | |
334 CHECK_LIVE_FRAME (frame_kludge); | |
335 | |
336 Lstream_flush (str); | |
337 if (!EQ (Vprint_message_label, echo_area_status (f))) | |
338 clear_echo_area_from_print (f, Qnil, 1); | |
339 echo_area_append (f, resizing_buffer_stream_ptr (str), | |
340 Qnil, 0, Lstream_byte_count (str), | |
341 Vprint_message_label); | |
342 Lstream_delete (str); | |
343 } | |
344 } | |
345 | |
346 /* Used for printing a single-byte character (*not* any Emchar). */ | |
347 #define write_char_internal(string_of_length_1, stream) \ | |
348 output_string (stream, (CONST Bufbyte *) (string_of_length_1), \ | |
349 Qnil, 0, 1) | |
350 | |
351 /* NOTE: Do not call this with the data of a Lisp_String, as | |
352 printcharfun might cause a GC, which might cause the string's data | |
353 to be relocated. To princ a Lisp string, use: | |
354 | |
355 print_internal (string, printcharfun, 0); | |
356 | |
357 Also note that STREAM should be the result of | |
358 canonicalize_printcharfun() (i.e. Qnil means stdout, not | |
359 Vstandard_output, etc.) */ | |
360 void | |
361 write_string_1 (CONST Bufbyte *str, Bytecount size, Lisp_Object stream) | |
362 { | |
363 /* This function can GC */ | |
364 #ifdef ERROR_CHECK_BUFPOS | |
365 assert (size >= 0); | |
366 #endif | |
367 output_string (stream, str, Qnil, 0, size); | |
368 } | |
369 | |
370 void | |
371 write_c_string (CONST char *str, Lisp_Object stream) | |
372 { | |
373 /* This function can GC */ | |
374 write_string_1 ((CONST Bufbyte *) str, strlen (str), stream); | |
375 } | |
376 | |
377 | |
378 DEFUN ("write-char", Fwrite_char, 1, 2, 0, /* | |
379 Output character CH to stream STREAM. | |
380 STREAM defaults to the value of `standard-output' (which see). | |
381 */ | |
382 (ch, stream)) | |
383 { | |
384 /* This function can GC */ | |
385 Bufbyte str[MAX_EMCHAR_LEN]; | |
386 Bytecount len; | |
387 | |
388 CHECK_CHAR_COERCE_INT (ch); | |
389 len = set_charptr_emchar (str, XCHAR (ch)); | |
390 output_string (canonicalize_printcharfun (stream), str, Qnil, 0, len); | |
391 return ch; | |
392 } | |
393 | |
394 void | |
395 temp_output_buffer_setup (Lisp_Object bufname) | |
396 { | |
397 /* This function can GC */ | |
398 struct buffer *old = current_buffer; | |
399 Lisp_Object buf; | |
400 | |
401 #ifdef I18N3 | |
402 /* #### This function should accept a Lisp_Object instead of a char *, | |
403 so that proper translation on the buffer name can occur. */ | |
404 #endif | |
405 | |
406 Fset_buffer (Fget_buffer_create (bufname)); | |
407 | |
408 current_buffer->read_only = Qnil; | |
409 Ferase_buffer (Qnil); | |
410 | |
411 XSETBUFFER (buf, current_buffer); | |
412 specbind (Qstandard_output, buf); | |
413 | |
414 set_buffer_internal (old); | |
415 } | |
416 | |
417 Lisp_Object | |
418 internal_with_output_to_temp_buffer (Lisp_Object bufname, | |
419 Lisp_Object (*function) (Lisp_Object arg), | |
420 Lisp_Object arg, | |
421 Lisp_Object same_frame) | |
422 { | |
423 int speccount = specpdl_depth (); | |
424 struct gcpro gcpro1, gcpro2, gcpro3; | |
425 Lisp_Object buf = Qnil; | |
426 | |
427 GCPRO3 (buf, arg, same_frame); | |
428 | |
429 temp_output_buffer_setup (bufname); | |
430 buf = Vstandard_output; | |
431 | |
432 arg = (*function) (arg); | |
433 | |
434 temp_output_buffer_show (buf, same_frame); | |
435 UNGCPRO; | |
436 | |
437 return unbind_to (speccount, arg); | |
438 } | |
439 | |
440 DEFUN ("with-output-to-temp-buffer", Fwith_output_to_temp_buffer, 1, UNEVALLED, 0, /* | |
441 Bind `standard-output' to buffer BUFNAME, eval BODY, then show that buffer. | |
442 The buffer is cleared out initially, and marked as unmodified when done. | |
443 All output done by BODY is inserted in that buffer by default. | |
444 The buffer is displayed in another window, but not selected. | |
445 The value of the last form in BODY is returned. | |
446 If BODY does not finish normally, the buffer BUFNAME is not displayed. | |
447 | |
448 If variable `temp-buffer-show-function' is non-nil, call it at the end | |
449 to get the buffer displayed. It gets one argument, the buffer to display. | |
450 */ | |
451 (args)) | |
452 { | |
453 /* This function can GC */ | |
454 Lisp_Object name = Qnil; | |
455 int speccount = specpdl_depth (); | |
456 struct gcpro gcpro1, gcpro2; | |
457 Lisp_Object val = Qnil; | |
458 | |
459 #ifdef I18N3 | |
460 /* #### should set the buffer to be translating. See print_internal(). */ | |
461 #endif | |
462 | |
463 GCPRO2 (name, val); | |
464 name = Feval (XCAR (args)); | |
465 | |
466 CHECK_STRING (name); | |
467 | |
468 temp_output_buffer_setup (name); | |
469 UNGCPRO; | |
470 | |
471 val = Fprogn (XCDR (args)); | |
472 | |
473 temp_output_buffer_show (Vstandard_output, Qnil); | |
474 | |
475 return unbind_to (speccount, val); | |
476 } | |
477 | |
478 DEFUN ("terpri", Fterpri, 0, 1, 0, /* | |
479 Output a newline to STREAM. | |
480 If STREAM is omitted or nil, the value of `standard-output' is used. | |
481 */ | |
482 (stream)) | |
483 { | |
484 /* This function can GC */ | |
485 write_char_internal ("\n", canonicalize_printcharfun (stream)); | |
486 return Qt; | |
487 } | |
488 | |
489 DEFUN ("prin1", Fprin1, 1, 2, 0, /* | |
490 Output the printed representation of OBJECT, any Lisp object. | |
491 Quoting characters are printed when needed to make output that `read' | |
492 can handle, whenever this is possible. | |
493 Output stream is STREAM, or value of `standard-output' (which see). | |
494 */ | |
495 (object, stream)) | |
496 { | |
497 /* This function can GC */ | |
498 Lisp_Object frame = Qnil; | |
499 struct gcpro gcpro1, gcpro2; | |
500 GCPRO2 (object, stream); | |
501 | |
502 print_depth = 0; | |
503 stream = print_prepare (stream, &frame); | |
504 print_internal (object, stream, 1); | |
505 print_finish (stream, frame); | |
506 | |
507 UNGCPRO; | |
508 return object; | |
509 } | |
510 | |
511 DEFUN ("prin1-to-string", Fprin1_to_string, 1, 2, 0, /* | |
512 Return a string containing the printed representation of OBJECT, | |
513 any Lisp object. Quoting characters are used when needed to make output | |
514 that `read' can handle, whenever this is possible, unless the optional | |
515 second argument NOESCAPE is non-nil. | |
516 */ | |
517 (object, noescape)) | |
518 { | |
519 /* This function can GC */ | |
520 Lisp_Object result = Qnil; | |
521 Lisp_Object stream = make_resizing_buffer_output_stream (); | |
522 Lstream *str = XLSTREAM (stream); | |
523 /* gcpro OBJECT in case a caller forgot to do so */ | |
524 struct gcpro gcpro1, gcpro2, gcpro3; | |
525 GCPRO3 (object, stream, result); | |
526 | |
527 print_depth = 0; | |
528 RESET_PRINT_GENSYM; | |
529 print_internal (object, stream, NILP (noescape)); | |
530 RESET_PRINT_GENSYM; | |
531 Lstream_flush (str); | |
532 UNGCPRO; | |
533 result = make_string (resizing_buffer_stream_ptr (str), | |
534 Lstream_byte_count (str)); | |
535 Lstream_delete (str); | |
536 return result; | |
537 } | |
538 | |
539 DEFUN ("princ", Fprinc, 1, 2, 0, /* | |
540 Output the printed representation of OBJECT, any Lisp object. | |
541 No quoting characters are used; no delimiters are printed around | |
542 the contents of strings. | |
543 Output stream is STREAM, or value of standard-output (which see). | |
544 */ | |
545 (object, stream)) | |
546 { | |
547 /* This function can GC */ | |
548 Lisp_Object frame = Qnil; | |
549 struct gcpro gcpro1, gcpro2; | |
550 | |
551 GCPRO2 (object, stream); | |
552 stream = print_prepare (stream, &frame); | |
553 print_depth = 0; | |
554 print_internal (object, stream, 0); | |
555 print_finish (stream, frame); | |
556 UNGCPRO; | |
557 return object; | |
558 } | |
559 | |
560 DEFUN ("print", Fprint, 1, 2, 0, /* | |
561 Output the printed representation of OBJECT, with newlines around it. | |
562 Quoting characters are printed when needed to make output that `read' | |
563 can handle, whenever this is possible. | |
564 Output stream is STREAM, or value of `standard-output' (which see). | |
565 */ | |
566 (object, stream)) | |
567 { | |
568 /* This function can GC */ | |
569 Lisp_Object frame = Qnil; | |
570 struct gcpro gcpro1, gcpro2; | |
571 | |
572 GCPRO2 (object, stream); | |
573 stream = print_prepare (stream, &frame); | |
574 print_depth = 0; | |
575 write_char_internal ("\n", stream); | |
576 print_internal (object, stream, 1); | |
577 write_char_internal ("\n", stream); | |
578 print_finish (stream, frame); | |
579 UNGCPRO; | |
580 return object; | |
581 } | |
582 | |
583 /* Print an error message for the error DATA to STREAM. This is a | |
584 complete implementation of `display-error', which used to be in | |
585 Lisp (see prim/cmdloop.el). It was ported to C so it can be used | |
586 efficiently by Ferror_message_string. Fdisplay_error and | |
587 Ferror_message_string are trivial wrappers around this function. | |
588 | |
589 STREAM should be the result of canonicalize_printcharfun(). */ | |
590 static void | |
591 print_error_message (Lisp_Object error_object, Lisp_Object stream) | |
592 { | |
593 /* This function can GC */ | |
594 Lisp_Object type = Fcar_safe (error_object); | |
595 Lisp_Object method = Qnil; | |
596 Lisp_Object tail; | |
597 | |
598 /* No need to GCPRO anything under the assumption that ERROR_OBJECT | |
599 is GCPRO'd. */ | |
600 | |
601 if (! (CONSP (error_object) && SYMBOLP (type) | |
602 && CONSP (Fget (type, Qerror_conditions, Qnil)))) | |
603 goto error_throw; | |
604 | |
605 tail = XCDR (error_object); | |
606 while (!NILP (tail)) | |
607 { | |
608 if (CONSP (tail)) | |
609 tail = XCDR (tail); | |
610 else | |
611 goto error_throw; | |
612 } | |
613 tail = Fget (type, Qerror_conditions, Qnil); | |
614 while (!NILP (tail)) | |
615 { | |
616 if (!(CONSP (tail) && SYMBOLP (XCAR (tail)))) | |
617 goto error_throw; | |
618 else if (!NILP (Fget (XCAR (tail), Qdisplay_error, Qnil))) | |
619 { | |
620 method = Fget (XCAR (tail), Qdisplay_error, Qnil); | |
621 goto error_throw; | |
622 } | |
623 else | |
624 tail = XCDR (tail); | |
625 } | |
626 /* Default method */ | |
627 { | |
628 int first = 1; | |
629 int speccount = specpdl_depth (); | |
630 | |
631 specbind (Qprint_message_label, Qerror); | |
632 tail = Fcdr (error_object); | |
633 if (EQ (type, Qerror)) | |
634 { | |
635 print_internal (Fcar (tail), stream, 0); | |
636 tail = Fcdr (tail); | |
637 } | |
638 else | |
639 { | |
640 Lisp_Object errmsg = Fget (type, Qerror_message, Qnil); | |
641 if (NILP (errmsg)) | |
642 print_internal (type, stream, 0); | |
643 else | |
644 print_internal (LISP_GETTEXT (errmsg), stream, 0); | |
645 } | |
646 while (!NILP (tail)) | |
647 { | |
648 write_c_string (first ? ": " : ", ", stream); | |
649 print_internal (Fcar (tail), stream, 1); | |
650 tail = Fcdr (tail); | |
651 first = 0; | |
652 } | |
653 unbind_to (speccount, Qnil); | |
654 return; | |
655 /* not reached */ | |
656 } | |
657 | |
658 error_throw: | |
659 if (NILP (method)) | |
660 { | |
661 write_c_string (GETTEXT ("Peculiar error "), stream); | |
662 print_internal (error_object, stream, 1); | |
663 return; | |
664 } | |
665 else | |
666 { | |
667 call2 (method, error_object, stream); | |
668 } | |
669 } | |
670 | |
671 DEFUN ("error-message-string", Ferror_message_string, 1, 1, 0, /* | |
672 Convert ERROR-OBJECT to an error message, and return it. | |
673 | |
674 The format of ERROR-OBJECT should be (ERROR-SYMBOL . DATA). The | |
675 message is equivalent to the one that would be issued by | |
676 `display-error' with the same argument. | |
677 */ | |
678 (error_object)) | |
679 { | |
680 /* This function can GC */ | |
681 Lisp_Object result = Qnil; | |
682 Lisp_Object stream = make_resizing_buffer_output_stream (); | |
683 struct gcpro gcpro1; | |
684 GCPRO1 (stream); | |
685 | |
686 print_error_message (error_object, stream); | |
687 Lstream_flush (XLSTREAM (stream)); | |
688 result = make_string (resizing_buffer_stream_ptr (XLSTREAM (stream)), | |
689 Lstream_byte_count (XLSTREAM (stream))); | |
690 Lstream_delete (XLSTREAM (stream)); | |
691 | |
692 UNGCPRO; | |
693 return result; | |
694 } | |
695 | |
696 DEFUN ("display-error", Fdisplay_error, 2, 2, 0, /* | |
697 Display ERROR-OBJECT on STREAM in a user-friendly way. | |
698 */ | |
699 (error_object, stream)) | |
700 { | |
701 /* This function can GC */ | |
702 print_error_message (error_object, canonicalize_printcharfun (stream)); | |
703 return Qnil; | |
704 } | |
705 | |
706 | |
707 #ifdef LISP_FLOAT_TYPE | |
708 | |
709 Lisp_Object Vfloat_output_format; | |
710 | |
711 /* | |
712 * This buffer should be at least as large as the max string size of the | |
713 * largest float, printed in the biggest notation. This is undoubtably | |
714 * 20d float_output_format, with the negative of the C-constant "HUGE" | |
715 * from <math.h>. | |
716 * | |
717 * On the vax the worst case is -1e38 in 20d format which takes 61 bytes. | |
718 * | |
719 * I assume that IEEE-754 format numbers can take 329 bytes for the worst | |
720 * case of -1e307 in 20d float_output_format. What is one to do (short of | |
721 * re-writing _doprnt to be more sane)? | |
722 * -wsr | |
723 */ | |
724 void | |
725 float_to_string (char *buf, double data) | |
726 { | |
727 Bufbyte *cp, c; | |
728 int width; | |
729 | |
730 if (NILP (Vfloat_output_format) | |
731 || !STRINGP (Vfloat_output_format)) | |
732 lose: | |
733 sprintf (buf, "%.16g", data); | |
734 else /* oink oink */ | |
735 { | |
736 /* Check that the spec we have is fully valid. | |
737 This means not only valid for printf, | |
738 but meant for floats, and reasonable. */ | |
739 cp = XSTRING_DATA (Vfloat_output_format); | |
740 | |
741 if (cp[0] != '%') | |
742 goto lose; | |
743 if (cp[1] != '.') | |
744 goto lose; | |
745 | |
746 cp += 2; | |
747 for (width = 0; (c = *cp, isdigit (c)); cp++) | |
748 { | |
749 width *= 10; | |
750 width += c - '0'; | |
751 } | |
752 | |
753 if (*cp != 'e' && *cp != 'f' && *cp != 'g' && *cp != 'E' && *cp != 'G') | |
754 goto lose; | |
755 | |
756 if (width < (int) (*cp != 'e' && *cp != 'E') || width > DBL_DIG) | |
757 goto lose; | |
758 | |
759 if (cp[1] != 0) | |
760 goto lose; | |
761 | |
762 sprintf (buf, (char *) XSTRING_DATA (Vfloat_output_format), | |
763 data); | |
764 } | |
765 | |
766 /* added by jwz: don't allow "1.0" to print as "1"; that destroys | |
767 the read-equivalence of lisp objects. (* x 1) and (* x 1.0) do | |
768 not do the same thing, so it's important that the printed | |
769 representation of that form not be corrupted by the printer. | |
770 */ | |
771 { | |
772 Bufbyte *s = (Bufbyte *) buf; /* don't use signed chars here! | |
773 isdigit() can't hack them! */ | |
774 if (*s == '-') s++; | |
775 for (; *s; s++) | |
776 /* if there's a non-digit, then there is a decimal point, or | |
777 it's in exponential notation, both of which are ok. */ | |
778 if (!isdigit (*s)) | |
779 goto DONE_LABEL; | |
780 /* otherwise, we need to hack it. */ | |
781 *s++ = '.'; | |
782 *s++ = '0'; | |
783 *s = 0; | |
784 } | |
785 DONE_LABEL: | |
786 | |
787 /* Some machines print "0.4" as ".4". I don't like that. */ | |
788 if (buf [0] == '.' || (buf [0] == '-' && buf [1] == '.')) | |
789 { | |
790 int i; | |
791 for (i = strlen (buf) + 1; i >= 0; i--) | |
792 buf [i+1] = buf [i]; | |
793 buf [(buf [0] == '-' ? 1 : 0)] = '0'; | |
794 } | |
795 } | |
796 #endif /* LISP_FLOAT_TYPE */ | |
797 | |
798 /* Print NUMBER to BUFFER. The digits are first written in reverse | |
799 order (the least significant digit first), and are then reversed. | |
800 This is equivalent to sprintf(buffer, "%ld", number), only much | |
801 faster. | |
802 | |
803 BUFFER should accept 24 bytes. This should suffice for the longest | |
804 numbers on 64-bit machines, including the `-' sign and the trailing | |
805 \0. */ | |
806 void | |
807 long_to_string (char *buffer, long number) | |
808 { | |
809 #if (SIZEOF_LONG != 4) && (SIZEOF_LONG != 8) | |
810 /* Huh? */ | |
811 sprintf (buffer, "%ld", number); | |
812 #else /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ | |
813 char *p = buffer; | |
814 int force = 0; | |
815 | |
816 if (number < 0) | |
817 { | |
818 *p++ = '-'; | |
819 number = -number; | |
820 } | |
821 | |
822 #define FROB(figure) do { \ | |
823 if (force || number >= figure) \ | |
824 *p++ = number / figure + '0', number %= figure, force = 1; \ | |
825 } while (0) | |
826 #if SIZEOF_LONG == 8 | |
827 FROB (1000000000000000000L); | |
828 FROB (100000000000000000L); | |
829 FROB (10000000000000000L); | |
830 FROB (1000000000000000L); | |
831 FROB (100000000000000L); | |
832 FROB (10000000000000L); | |
833 FROB (1000000000000L); | |
834 FROB (100000000000L); | |
835 FROB (10000000000L); | |
836 #endif /* SIZEOF_LONG == 8 */ | |
837 FROB (1000000000); | |
838 FROB (100000000); | |
839 FROB (10000000); | |
840 FROB (1000000); | |
841 FROB (100000); | |
842 FROB (10000); | |
843 FROB (1000); | |
844 FROB (100); | |
845 FROB (10); | |
846 #undef FROB | |
847 *p++ = number + '0'; | |
848 *p = '\0'; | |
849 #endif /* (SIZEOF_LONG == 4) || (SIZEOF_LONG == 8) */ | |
850 } | |
851 | |
852 static void | |
853 print_vector_internal (CONST char *start, CONST char *end, | |
854 Lisp_Object obj, | |
855 Lisp_Object printcharfun, int escapeflag) | |
856 { | |
857 /* This function can GC */ | |
858 int i; | |
859 int len = XVECTOR_LENGTH (obj); | |
860 int last = len; | |
861 struct gcpro gcpro1, gcpro2; | |
862 GCPRO2 (obj, printcharfun); | |
863 | |
864 if (INTP (Vprint_length)) | |
865 { | |
866 int max = XINT (Vprint_length); | |
867 if (max < len) last = max; | |
868 } | |
869 | |
870 write_c_string (start, printcharfun); | |
871 for (i = 0; i < last; i++) | |
872 { | |
873 Lisp_Object elt = XVECTOR_DATA (obj)[i]; | |
874 if (i != 0) write_char_internal (" ", printcharfun); | |
875 print_internal (elt, printcharfun, escapeflag); | |
876 } | |
877 UNGCPRO; | |
878 if (last != len) | |
879 write_c_string (" ...", printcharfun); | |
880 write_c_string (end, printcharfun); | |
881 } | |
882 | |
883 void | |
884 print_cons (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
885 { | |
886 /* This function can GC */ | |
887 struct gcpro gcpro1, gcpro2; | |
888 | |
889 /* If print_readably is on, print (quote -foo-) as '-foo- | |
890 (Yeah, this should really be what print-pretty does, but we | |
891 don't have the rest of a pretty printer, and this actually | |
892 has non-negligible impact on size/speed of .elc files.) | |
893 */ | |
894 if (print_readably && | |
895 EQ (XCAR (obj), Qquote) && | |
896 CONSP (XCDR (obj)) && | |
897 NILP (XCDR (XCDR (obj)))) | |
898 { | |
899 obj = XCAR (XCDR (obj)); | |
900 GCPRO2 (obj, printcharfun); | |
901 write_char_internal ("\'", printcharfun); | |
902 UNGCPRO; | |
903 print_internal (obj, printcharfun, escapeflag); | |
904 return; | |
905 } | |
906 | |
907 GCPRO2 (obj, printcharfun); | |
908 write_char_internal ("(", printcharfun); | |
909 | |
910 { | |
911 int len; | |
912 int max = INTP (Vprint_length) ? XINT (Vprint_length) : INT_MAX; | |
913 Lisp_Object tortoise; | |
914 /* Use tortoise/hare to make sure circular lists don't infloop */ | |
915 | |
916 for (tortoise = obj, len = 0; | |
917 CONSP (obj); | |
918 obj = XCDR (obj), len++) | |
919 { | |
920 if (len > 0) | |
921 write_char_internal (" ", printcharfun); | |
922 if (EQ (obj, tortoise) && len > 0) | |
923 { | |
924 if (print_readably) | |
925 error ("printing unreadable circular list"); | |
926 else | |
927 write_c_string ("... <circular list>", printcharfun); | |
928 break; | |
929 } | |
930 if (len & 1) | |
931 tortoise = XCDR (tortoise); | |
932 if (len > max) | |
933 { | |
934 write_c_string ("...", printcharfun); | |
935 break; | |
936 } | |
937 print_internal (XCAR (obj), printcharfun, escapeflag); | |
938 } | |
939 } | |
940 if (!LISTP (obj)) | |
941 { | |
942 write_c_string (" . ", printcharfun); | |
943 print_internal (obj, printcharfun, escapeflag); | |
944 } | |
945 UNGCPRO; | |
946 | |
947 write_char_internal (")", printcharfun); | |
948 return; | |
949 } | |
950 | |
951 void | |
952 print_vector (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
953 { | |
954 print_vector_internal ("[", "]", obj, printcharfun, escapeflag); | |
955 } | |
956 | |
957 void | |
958 print_string (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
959 { | |
960 struct Lisp_String *s = XSTRING (obj); | |
961 /* We distinguish between Bytecounts and Charcounts, to make | |
962 Vprint_string_length work correctly under Mule. */ | |
963 Charcount size = string_char_length (s); | |
964 Charcount max = size; | |
965 Bytecount bcmax = string_length (s); | |
966 struct gcpro gcpro1, gcpro2; | |
967 GCPRO2 (obj, printcharfun); | |
968 | |
969 if (INTP (Vprint_string_length) && | |
970 XINT (Vprint_string_length) < max) | |
971 { | |
972 max = XINT (Vprint_string_length); | |
973 bcmax = charcount_to_bytecount (string_data (s), max); | |
974 } | |
975 if (max < 0) | |
976 { | |
977 max = 0; | |
978 bcmax = 0; | |
979 } | |
980 | |
981 if (!escapeflag) | |
982 { | |
983 /* This deals with GC-relocation and Mule. */ | |
984 output_string (printcharfun, 0, obj, 0, bcmax); | |
985 if (max < size) | |
986 write_c_string (" ...", printcharfun); | |
987 } | |
988 else | |
989 { | |
990 Bytecount i, last = 0; | |
991 | |
992 write_char_internal ("\"", printcharfun); | |
993 for (i = 0; i < bcmax; i++) | |
994 { | |
995 Bufbyte ch = string_byte (s, i); | |
996 if (ch == '\"' || ch == '\\' | |
997 || (ch == '\n' && print_escape_newlines)) | |
998 { | |
999 if (i > last) | |
1000 { | |
1001 output_string (printcharfun, 0, obj, last, | |
1002 i - last); | |
1003 } | |
1004 if (ch == '\n') | |
1005 { | |
1006 write_c_string ("\\n", printcharfun); | |
1007 } | |
1008 else | |
1009 { | |
1010 write_char_internal ("\\", printcharfun); | |
1011 /* This is correct for Mule because the | |
1012 character is either \ or " */ | |
1013 write_char_internal (string_data (s) + i, printcharfun); | |
1014 } | |
1015 last = i + 1; | |
1016 } | |
1017 } | |
1018 if (bcmax > last) | |
1019 { | |
1020 output_string (printcharfun, 0, obj, last, | |
1021 bcmax - last); | |
1022 } | |
1023 if (max < size) | |
1024 write_c_string (" ...", printcharfun); | |
1025 write_char_internal ("\"", printcharfun); | |
1026 } | |
1027 UNGCPRO; | |
1028 } | |
1029 | |
1030 static void | |
1031 default_object_printer (Lisp_Object obj, Lisp_Object printcharfun, | |
1032 int escapeflag) | |
1033 { | |
1034 struct lcrecord_header *header = | |
1035 (struct lcrecord_header *) XPNTR (obj); | |
1036 char buf[200]; | |
1037 | |
1038 if (print_readably) | |
1039 error ("printing unreadable object #<%s 0x%x>", | |
1040 LHEADER_IMPLEMENTATION (&header->lheader)->name, | |
1041 header->uid); | |
1042 | |
1043 sprintf (buf, "#<%s 0x%x>", | |
1044 LHEADER_IMPLEMENTATION (&header->lheader)->name, | |
1045 header->uid); | |
1046 write_c_string (buf, printcharfun); | |
1047 } | |
1048 | |
1049 void | |
1050 internal_object_printer (Lisp_Object obj, Lisp_Object printcharfun, | |
1051 int escapeflag) | |
1052 { | |
1053 char buf[200]; | |
1054 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (%s) 0x%lx>", | |
1055 XRECORD_LHEADER_IMPLEMENTATION (obj)->name, | |
1056 (unsigned long) XPNTR (obj)); | |
1057 write_c_string (buf, printcharfun); | |
1058 } | |
1059 | |
1060 void | |
1061 print_internal (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
1062 { | |
1063 /* This function can GC */ | |
1064 | |
1065 QUIT; | |
1066 | |
1067 /* Emacs won't print while GCing, but an external debugger might */ | |
1068 if (gc_in_progress) return; | |
1069 | |
1070 #ifdef I18N3 | |
1071 /* #### Both input and output streams should have a flag associated | |
1072 with them indicating whether output to that stream, or strings | |
1073 read from the stream, get translated using Fgettext(). Such a | |
1074 stream is called a "translating stream". For the minibuffer and | |
1075 external-debugging-output this is always true on output, and | |
1076 with-output-to-temp-buffer sets the flag to true for the buffer | |
1077 it creates. This flag should also be user-settable. Perhaps it | |
1078 should be split up into two flags, one for input and one for | |
1079 output. */ | |
1080 #endif | |
1081 | |
1082 /* Detect circularities and truncate them. | |
1083 No need to offer any alternative--this is better than an error. */ | |
1084 if (CONSP (obj) || VECTORP (obj) || COMPILED_FUNCTIONP (obj)) | |
1085 { | |
1086 int i; | |
1087 for (i = 0; i < print_depth; i++) | |
1088 if (EQ (obj, being_printed[i])) | |
1089 { | |
1090 char buf[32]; | |
1091 *buf = '#'; | |
1092 long_to_string (buf + 1, i); | |
1093 write_c_string (buf, printcharfun); | |
1094 return; | |
1095 } | |
1096 } | |
1097 | |
1098 being_printed[print_depth] = obj; | |
1099 print_depth++; | |
1100 | |
1101 if (print_depth > PRINT_CIRCLE) | |
1102 error ("Apparently circular structure being printed"); | |
1103 | |
1104 switch (XTYPE (obj)) | |
1105 { | |
1106 case Lisp_Type_Int_Even: | |
1107 case Lisp_Type_Int_Odd: | |
1108 { | |
1109 char buf[24]; | |
1110 long_to_string (buf, XINT (obj)); | |
1111 write_c_string (buf, printcharfun); | |
1112 break; | |
1113 } | |
1114 | |
1115 case Lisp_Type_Char: | |
1116 { | |
1117 /* God intended that this be #\..., you know. */ | |
1118 char buf[16]; | |
1119 Emchar ch = XCHAR (obj); | |
1120 char *p = buf; | |
1121 *p++ = '?'; | |
1122 if (ch == '\n') | |
1123 *p++ = '\\', *p++ = 'n'; | |
1124 else if (ch == '\r') | |
1125 *p++ = '\\', *p++ = 'r'; | |
1126 else if (ch == '\t') | |
1127 *p++ = '\\', *p++ = 't'; | |
1128 else if (ch < 32) | |
1129 { | |
1130 *p++ = '\\', *p++ = '^'; | |
1131 *p++ = ch + 64; | |
1132 if ((ch + 64) == '\\') | |
1133 *p++ = '\\'; | |
1134 } | |
1135 else if (ch == 127) | |
1136 *p++ = '\\', *p++ = '^', *p++ = '?'; | |
1137 else if (ch >= 128 && ch < 160) | |
1138 { | |
1139 *p++ = '\\', *p++ = '^'; | |
1140 p += set_charptr_emchar ((Bufbyte *)p, ch + 64); | |
1141 } | |
1142 else if (ch < 127 | |
1143 && !isdigit (ch) | |
1144 && !isalpha (ch) | |
1145 && ch != '^') /* must not backslash this or it will | |
1146 be interpreted as the start of a | |
1147 control char */ | |
1148 *p++ = '\\', *p++ = ch; | |
1149 else | |
1150 p += set_charptr_emchar ((Bufbyte *)p, ch); | |
1151 output_string (printcharfun, (Bufbyte *)buf, Qnil, 0, p - buf); | |
1152 break; | |
1153 } | |
1154 | |
1155 case Lisp_Type_Record: | |
1156 { | |
1157 struct lrecord_header *lheader = XRECORD_LHEADER (obj); | |
1158 struct gcpro gcpro1, gcpro2; | |
1159 | |
1160 if (CONSP (obj) || VECTORP(obj)) | |
1161 { | |
1162 /* If deeper than spec'd depth, print placeholder. */ | |
1163 if (INTP (Vprint_level) | |
1164 && print_depth > XINT (Vprint_level)) | |
1165 { | |
1166 GCPRO2 (obj, printcharfun); | |
1167 write_c_string ("...", printcharfun); | |
1168 UNGCPRO; | |
1169 break; | |
1170 } | |
1171 } | |
1172 | |
1173 GCPRO2 (obj, printcharfun); | |
1174 if (LHEADER_IMPLEMENTATION (lheader)->printer) | |
1175 ((LHEADER_IMPLEMENTATION (lheader)->printer) | |
1176 (obj, printcharfun, escapeflag)); | |
1177 else | |
1178 default_object_printer (obj, printcharfun, escapeflag); | |
1179 UNGCPRO; | |
1180 break; | |
1181 } | |
1182 | |
1183 default: | |
1184 { | |
1185 #ifdef ERROR_CHECK_TYPECHECK | |
1186 abort (); | |
1187 #else /* not ERROR_CHECK_TYPECHECK */ | |
1188 char buf[128]; | |
1189 /* We're in trouble if this happens! */ | |
1190 if (print_readably) | |
1191 error ("printing illegal data type #o%03o", | |
1192 (int) XTYPE (obj)); | |
1193 write_c_string ("#<EMACS BUG: ILLEGAL DATATYPE ", | |
1194 printcharfun); | |
1195 sprintf (buf, "(#o%3o)", (int) XTYPE (obj)); | |
1196 write_c_string (buf, printcharfun); | |
1197 write_c_string | |
1198 (" Save your buffers immediately and please report this bug>", | |
1199 printcharfun); | |
1200 #endif /* not ERROR_CHECK_TYPECHECK */ | |
1201 break; | |
1202 } | |
1203 } | |
1204 | |
1205 print_depth--; | |
1206 } | |
1207 | |
1208 | |
1209 #ifdef LISP_FLOAT_TYPE | |
1210 void | |
1211 print_float (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
1212 { | |
1213 char pigbuf[350]; /* see comments in float_to_string */ | |
1214 | |
1215 float_to_string (pigbuf, XFLOAT_DATA (obj)); | |
1216 write_c_string (pigbuf, printcharfun); | |
1217 } | |
1218 #endif /* LISP_FLOAT_TYPE */ | |
1219 | |
1220 void | |
1221 print_symbol (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
1222 { | |
1223 /* This function can GC */ | |
1224 /* #### Bug!! (intern "") isn't printed in some distinguished way */ | |
1225 /* #### (the reader also loses on it) */ | |
1226 struct Lisp_String *name = symbol_name (XSYMBOL (obj)); | |
1227 Bytecount size = string_length (name); | |
1228 struct gcpro gcpro1, gcpro2; | |
1229 | |
1230 if (!escapeflag) | |
1231 { | |
1232 /* This deals with GC-relocation */ | |
1233 Lisp_Object nameobj; | |
1234 XSETSTRING (nameobj, name); | |
1235 output_string (printcharfun, 0, nameobj, 0, size); | |
1236 return; | |
1237 } | |
1238 GCPRO2 (obj, printcharfun); | |
1239 | |
1240 /* If we print an uninterned symbol as part of a complex object and | |
1241 the flag print-gensym is non-nil, prefix it with #n= to read the | |
1242 object back with the #n# reader syntax later if needed. */ | |
1243 if (!NILP (Vprint_gensym) | |
1244 /* #### Test whether this produces a noticable slow-down for | |
1245 printing when print-gensym is non-nil. */ | |
1246 && !EQ (obj, oblookup (Vobarray, | |
1247 string_data (symbol_name (XSYMBOL (obj))), | |
1248 string_length (symbol_name (XSYMBOL (obj)))))) | |
1249 { | |
1250 if (print_depth > 1) | |
1251 { | |
1252 Lisp_Object tem = Fassq (obj, Vprint_gensym_alist); | |
1253 if (CONSP (tem)) | |
1254 { | |
1255 write_char_internal ("#", printcharfun); | |
1256 print_internal (XCDR (tem), printcharfun, escapeflag); | |
1257 write_char_internal ("#", printcharfun); | |
1258 return; | |
1259 } | |
1260 else | |
1261 { | |
1262 if (CONSP (Vprint_gensym_alist)) | |
1263 { | |
1264 /* Vprint_gensym_alist is exposed to Lisp, so we | |
1265 have to be careful. */ | |
1266 CHECK_CONS (XCAR (Vprint_gensym_alist)); | |
1267 CHECK_INT (XCDR (XCAR (Vprint_gensym_alist))); | |
1268 XSETINT (tem, XINT (XCDR (XCAR (Vprint_gensym_alist))) + 1); | |
1269 } | |
1270 else | |
1271 XSETINT (tem, 1); | |
1272 Vprint_gensym_alist = Fcons (Fcons (obj, tem), Vprint_gensym_alist); | |
1273 | |
1274 write_char_internal ("#", printcharfun); | |
1275 print_internal (tem, printcharfun, escapeflag); | |
1276 write_char_internal ("=", printcharfun); | |
1277 } | |
1278 } | |
1279 write_c_string ("#:", printcharfun); | |
1280 } | |
1281 | |
1282 /* Does it look like an integer or a float? */ | |
1283 { | |
1284 Bufbyte *data = string_data (name); | |
1285 Bytecount confusing = 0; | |
1286 | |
1287 if (size == 0) | |
1288 goto not_yet_confused; /* Really confusing */ | |
1289 else if (isdigit (data[0])) | |
1290 confusing = 0; | |
1291 else if (size == 1) | |
1292 goto not_yet_confused; | |
1293 else if (data[0] == '-' || data[0] == '+') | |
1294 confusing = 1; | |
1295 else | |
1296 goto not_yet_confused; | |
1297 | |
1298 for (; confusing < size; confusing++) | |
1299 { | |
1300 if (!isdigit (data[confusing])) | |
1301 { | |
1302 confusing = 0; | |
1303 break; | |
1304 } | |
1305 } | |
1306 not_yet_confused: | |
1307 | |
1308 #ifdef LISP_FLOAT_TYPE | |
1309 if (!confusing) | |
1310 /* #### Ugh, this is needlessly complex and slow for what we | |
1311 need here. It might be a good idea to copy equivalent code | |
1312 from FSF. --hniksic */ | |
1313 confusing = isfloat_string ((char *) data); | |
1314 #endif | |
1315 if (confusing) | |
1316 write_char_internal ("\\", printcharfun); | |
1317 } | |
1318 | |
1319 { | |
1320 Lisp_Object nameobj; | |
1321 Bytecount i; | |
1322 Bytecount last = 0; | |
1323 | |
1324 XSETSTRING (nameobj, name); | |
1325 for (i = 0; i < size; i++) | |
1326 { | |
1327 switch (string_byte (name, i)) | |
1328 { | |
1329 case 0: case 1: case 2: case 3: | |
1330 case 4: case 5: case 6: case 7: | |
1331 case 8: case 9: case 10: case 11: | |
1332 case 12: case 13: case 14: case 15: | |
1333 case 16: case 17: case 18: case 19: | |
1334 case 20: case 21: case 22: case 23: | |
1335 case 24: case 25: case 26: case 27: | |
1336 case 28: case 29: case 30: case 31: | |
1337 case ' ': case '\"': case '\\': case '\'': | |
1338 case ';': case '#' : case '(' : case ')': | |
1339 case ',': case '.' : case '`' : | |
1340 case '[': case ']' : case '?' : | |
1341 if (i > last) | |
1342 output_string (printcharfun, 0, nameobj, last, i - last); | |
1343 write_char_internal ("\\", printcharfun); | |
1344 last = i; | |
1345 } | |
1346 } | |
1347 output_string (printcharfun, 0, nameobj, last, size - last); | |
1348 } | |
1349 UNGCPRO; | |
1350 } | |
1351 | |
1352 /* #ifdef DEBUG_XEMACS */ | |
1353 | |
1354 /* I don't like seeing `Note: Strange doc (not fboundp) for function | |
1355 alternate-debugging-output @ 429542' -slb */ | |
1356 /* #### Eek! Any clue how to get rid of it? In fact, how about | |
1357 getting rid of this function altogether? Does anything actually | |
1358 *use* it? --hniksic */ | |
1359 | |
1360 static int alternate_do_pointer; | |
1361 static char alternate_do_string[5000]; | |
1362 | |
1363 DEFUN ("alternate-debugging-output", Falternate_debugging_output, 1, 1, 0, /* | |
1364 Append CHARACTER to the array `alternate_do_string'. | |
1365 This can be used in place of `external-debugging-output' as a function | |
1366 to be passed to `print'. Before calling `print', set `alternate_do_pointer' | |
1367 to 0. | |
1368 */ | |
1369 (character)) | |
1370 { | |
1371 Bufbyte str[MAX_EMCHAR_LEN]; | |
1372 Bytecount len; | |
1373 int extlen; | |
1374 CONST Extbyte *extptr; | |
1375 | |
1376 CHECK_CHAR_COERCE_INT (character); | |
1377 len = set_charptr_emchar (str, XCHAR (character)); | |
1378 GET_CHARPTR_EXT_DATA_ALLOCA (str, len, FORMAT_TERMINAL, extptr, extlen); | |
1379 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); | |
1380 alternate_do_pointer += extlen; | |
1381 alternate_do_string[alternate_do_pointer] = 0; | |
1382 return character; | |
1383 } | |
1384 /* #endif / * DEBUG_XEMACS */ | |
1385 | |
1386 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* | |
1387 Write CHAR-OR-STRING to stderr or stdout. | |
1388 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write | |
1389 to stderr. You can use this function to write directly to the terminal. | |
1390 This function can be used as the STREAM argument of Fprint() or the like. | |
1391 | |
1392 If you have opened a termscript file (using `open-termscript'), then | |
1393 the output also will be logged to this file. | |
1394 */ | |
1395 (char_or_string, stdout_p, device)) | |
1396 { | |
1397 FILE *file = 0; | |
1398 struct console *con = 0; | |
1399 | |
1400 if (NILP (device)) | |
1401 { | |
1402 if (!NILP (stdout_p)) | |
1403 file = stdout; | |
1404 else | |
1405 file = stderr; | |
1406 } | |
1407 else | |
1408 { | |
1409 CHECK_LIVE_DEVICE (device); | |
1410 if (!DEVICE_TTY_P (XDEVICE (device)) && | |
1411 !DEVICE_STREAM_P (XDEVICE (device))) | |
1412 signal_simple_error ("Must be tty or stream device", device); | |
1413 con = XCONSOLE (DEVICE_CONSOLE (XDEVICE (device))); | |
1414 if (DEVICE_TTY_P (XDEVICE (device))) | |
1415 file = 0; | |
1416 else if (!NILP (stdout_p)) | |
1417 file = CONSOLE_STREAM_DATA (con)->out; | |
1418 else | |
1419 file = CONSOLE_STREAM_DATA (con)->err; | |
1420 } | |
1421 | |
1422 if (STRINGP (char_or_string)) | |
1423 write_string_to_stdio_stream (file, con, | |
1424 XSTRING_DATA (char_or_string), | |
1425 0, XSTRING_LENGTH (char_or_string), | |
1426 FORMAT_TERMINAL); | |
1427 else | |
1428 { | |
1429 Bufbyte str[MAX_EMCHAR_LEN]; | |
1430 Bytecount len; | |
1431 | |
1432 CHECK_CHAR_COERCE_INT (char_or_string); | |
1433 len = set_charptr_emchar (str, XCHAR (char_or_string)); | |
1434 write_string_to_stdio_stream (file, con, str, 0, len, FORMAT_TERMINAL); | |
1435 } | |
1436 | |
1437 return char_or_string; | |
1438 } | |
1439 | |
1440 DEFUN ("open-termscript", Fopen_termscript, 1, 1, "FOpen termscript file: ", /* | |
1441 Start writing all terminal output to FILE as well as the terminal. | |
1442 FILE = nil means just close any termscript file currently open. | |
1443 */ | |
1444 (file)) | |
1445 { | |
1446 /* This function can GC */ | |
1447 if (termscript != 0) | |
1448 fclose (termscript); | |
1449 termscript = 0; | |
1450 | |
1451 if (! NILP (file)) | |
1452 { | |
1453 file = Fexpand_file_name (file, Qnil); | |
1454 termscript = fopen ((char *) XSTRING_DATA (file), "w"); | |
1455 if (termscript == NULL) | |
1456 report_file_error ("Opening termscript", list1 (file)); | |
1457 } | |
1458 return Qnil; | |
1459 } | |
1460 | |
1461 #if 1 | |
1462 /* Debugging kludge -- unbuffered */ | |
1463 static int debug_print_length = 50; | |
1464 static int debug_print_level = 15; | |
1465 | |
1466 static void | |
1467 debug_print_no_newline (Lisp_Object debug_print_obj) | |
1468 { | |
1469 /* This function can GC */ | |
1470 int old_print_readably = print_readably; | |
1471 int old_print_depth = print_depth; | |
1472 Lisp_Object old_print_length = Vprint_length; | |
1473 Lisp_Object old_print_level = Vprint_level; | |
1474 Lisp_Object old_inhibit_quit = Vinhibit_quit; | |
1475 struct gcpro gcpro1, gcpro2, gcpro3; | |
1476 GCPRO3 (old_print_level, old_print_length, old_inhibit_quit); | |
1477 | |
1478 if (gc_in_progress) | |
1479 stderr_out ("** gc-in-progress! Bad idea to print anything! **\n"); | |
1480 | |
1481 print_depth = 0; | |
1482 print_readably = 0; | |
1483 print_unbuffered++; | |
1484 /* Could use unwind-protect, but why bother? */ | |
1485 if (debug_print_length > 0) | |
1486 Vprint_length = make_int (debug_print_length); | |
1487 if (debug_print_level > 0) | |
1488 Vprint_level = make_int (debug_print_level); | |
1489 print_internal (debug_print_obj, Qexternal_debugging_output, 1); | |
1490 Vinhibit_quit = old_inhibit_quit; | |
1491 Vprint_level = old_print_level; | |
1492 Vprint_length = old_print_length; | |
1493 print_depth = old_print_depth; | |
1494 print_readably = old_print_readably; | |
1495 print_unbuffered--; | |
1496 UNGCPRO; | |
1497 } | |
1498 | |
1499 void | |
1500 debug_print (Lisp_Object debug_print_obj) | |
1501 { | |
1502 debug_print_no_newline (debug_print_obj); | |
1503 stderr_out ("\n"); | |
1504 fflush (stderr); | |
1505 } | |
1506 | |
1507 /* Debugging kludge -- unbuffered */ | |
1508 /* This function provided for the benefit of the debugger. */ | |
1509 void debug_backtrace (void); | |
1510 void | |
1511 debug_backtrace (void) | |
1512 { | |
1513 /* This function can GC */ | |
1514 int old_print_readably = print_readably; | |
1515 int old_print_depth = print_depth; | |
1516 Lisp_Object old_print_length = Vprint_length; | |
1517 Lisp_Object old_print_level = Vprint_level; | |
1518 Lisp_Object old_inhibit_quit = Vinhibit_quit; | |
1519 | |
1520 struct gcpro gcpro1, gcpro2, gcpro3; | |
1521 GCPRO3 (old_print_level, old_print_length, old_inhibit_quit); | |
1522 | |
1523 if (gc_in_progress) | |
1524 stderr_out ("** gc-in-progress! Bad idea to print anything! **\n"); | |
1525 | |
1526 print_depth = 0; | |
1527 print_readably = 0; | |
1528 print_unbuffered++; | |
1529 /* Could use unwind-protect, but why bother? */ | |
1530 if (debug_print_length > 0) | |
1531 Vprint_length = make_int (debug_print_length); | |
1532 if (debug_print_level > 0) | |
1533 Vprint_level = make_int (debug_print_level); | |
1534 | |
1535 Fbacktrace (Qexternal_debugging_output, Qt); | |
1536 stderr_out ("\n"); | |
1537 fflush (stderr); | |
1538 | |
1539 Vinhibit_quit = old_inhibit_quit; | |
1540 Vprint_level = old_print_level; | |
1541 Vprint_length = old_print_length; | |
1542 print_depth = old_print_depth; | |
1543 print_readably = old_print_readably; | |
1544 print_unbuffered--; | |
1545 | |
1546 UNGCPRO; | |
1547 } | |
1548 | |
1549 void | |
1550 debug_short_backtrace (int length) | |
1551 { | |
1552 int first = 1; | |
1553 struct backtrace *bt = backtrace_list; | |
1554 stderr_out (" ["); | |
1555 fflush (stderr); | |
1556 while (length > 0 && bt) | |
1557 { | |
1558 if (!first) | |
1559 { | |
1560 stderr_out (", "); | |
1561 fflush (stderr); | |
1562 } | |
1563 if (COMPILED_FUNCTIONP (*bt->function)) | |
1564 { | |
1565 #if defined(COMPILED_FUNCTION_ANNOTATION_HACK) | |
1566 Lisp_Object ann = | |
1567 compiled_function_annotation (XCOMPILED_FUNCTION (*bt->function)); | |
1568 #else | |
1569 Lisp_Object ann = Qnil; | |
1570 #endif | |
1571 if (!NILP (ann)) | |
1572 { | |
1573 stderr_out ("<compiled-function from "); | |
1574 fflush (stderr); | |
1575 debug_print_no_newline (ann); | |
1576 stderr_out (">"); | |
1577 fflush (stderr); | |
1578 } | |
1579 else | |
1580 { | |
1581 stderr_out ("<compiled-function of unknown origin>"); | |
1582 fflush (stderr); | |
1583 } | |
1584 } | |
1585 else | |
1586 debug_print_no_newline (*bt->function); | |
1587 first = 0; | |
1588 length--; | |
1589 bt = bt->next; | |
1590 } | |
1591 stderr_out ("]\n"); | |
1592 fflush (stderr); | |
1593 } | |
1594 | |
1595 #endif /* debugging kludge */ | |
1596 | |
1597 | |
1598 void | |
1599 syms_of_print (void) | |
1600 { | |
1601 defsymbol (&Qstandard_output, "standard-output"); | |
1602 | |
1603 defsymbol (&Qprint_length, "print-length"); | |
1604 | |
1605 defsymbol (&Qprint_string_length, "print-string-length"); | |
1606 | |
1607 defsymbol (&Qdisplay_error, "display-error"); | |
1608 defsymbol (&Qprint_message_label, "print-message-label"); | |
1609 | |
1610 DEFSUBR (Fprin1); | |
1611 DEFSUBR (Fprin1_to_string); | |
1612 DEFSUBR (Fprinc); | |
1613 DEFSUBR (Fprint); | |
1614 DEFSUBR (Ferror_message_string); | |
1615 DEFSUBR (Fdisplay_error); | |
1616 DEFSUBR (Fterpri); | |
1617 DEFSUBR (Fwrite_char); | |
1618 DEFSUBR (Falternate_debugging_output); | |
1619 DEFSUBR (Fexternal_debugging_output); | |
1620 DEFSUBR (Fopen_termscript); | |
1621 defsymbol (&Qexternal_debugging_output, "external-debugging-output"); | |
1622 DEFSUBR (Fwith_output_to_temp_buffer); | |
1623 } | |
1624 | |
1625 void | |
1626 reinit_vars_of_print (void) | |
1627 { | |
1628 alternate_do_pointer = 0; | |
1629 } | |
1630 | |
1631 void | |
1632 vars_of_print (void) | |
1633 { | |
1634 reinit_vars_of_print (); | |
1635 | |
1636 DEFVAR_LISP ("standard-output", &Vstandard_output /* | |
1637 Output stream `print' uses by default for outputting a character. | |
1638 This may be any function of one argument. | |
1639 It may also be a buffer (output is inserted before point) | |
1640 or a marker (output is inserted and the marker is advanced) | |
1641 or the symbol t (output appears in the minibuffer line). | |
1642 */ ); | |
1643 Vstandard_output = Qt; | |
1644 | |
1645 #ifdef LISP_FLOAT_TYPE | |
1646 DEFVAR_LISP ("float-output-format", &Vfloat_output_format /* | |
1647 The format descriptor string that lisp uses to print floats. | |
1648 This is a %-spec like those accepted by `printf' in C, | |
1649 but with some restrictions. It must start with the two characters `%.'. | |
1650 After that comes an integer precision specification, | |
1651 and then a letter which controls the format. | |
1652 The letters allowed are `e', `f' and `g'. | |
1653 Use `e' for exponential notation "DIG.DIGITSeEXPT" | |
1654 Use `f' for decimal point notation "DIGITS.DIGITS". | |
1655 Use `g' to choose the shorter of those two formats for the number at hand. | |
1656 The precision in any of these cases is the number of digits following | |
1657 the decimal point. With `f', a precision of 0 means to omit the | |
1658 decimal point. 0 is not allowed with `f' or `g'. | |
1659 | |
1660 A value of nil means to use `%.16g'. | |
1661 | |
1662 Regardless of the value of `float-output-format', a floating point number | |
1663 will never be printed in such a way that it is ambiguous with an integer; | |
1664 that is, a floating-point number will always be printed with a decimal | |
1665 point and/or an exponent, even if the digits following the decimal point | |
1666 are all zero. This is to preserve read-equivalence. | |
1667 */ ); | |
1668 Vfloat_output_format = Qnil; | |
1669 #endif /* LISP_FLOAT_TYPE */ | |
1670 | |
1671 DEFVAR_LISP ("print-length", &Vprint_length /* | |
1672 Maximum length of list or vector to print before abbreviating. | |
1673 A value of nil means no limit. | |
1674 */ ); | |
1675 Vprint_length = Qnil; | |
1676 | |
1677 DEFVAR_LISP ("print-string-length", &Vprint_string_length /* | |
1678 Maximum length of string to print before abbreviating. | |
1679 A value of nil means no limit. | |
1680 */ ); | |
1681 Vprint_string_length = Qnil; | |
1682 | |
1683 DEFVAR_LISP ("print-level", &Vprint_level /* | |
1684 Maximum depth of list nesting to print before abbreviating. | |
1685 A value of nil means no limit. | |
1686 */ ); | |
1687 Vprint_level = Qnil; | |
1688 | |
1689 DEFVAR_BOOL ("print-escape-newlines", &print_escape_newlines /* | |
1690 Non-nil means print newlines in strings as backslash-n. | |
1691 */ ); | |
1692 print_escape_newlines = 0; | |
1693 | |
1694 DEFVAR_BOOL ("print-readably", &print_readably /* | |
1695 If non-nil, then all objects will be printed in a readable form. | |
1696 If an object has no readable representation, then an error is signalled. | |
1697 When print-readably is true, compiled-function objects will be written in | |
1698 #[...] form instead of in #<compiled-function [...]> form, and two-element | |
1699 lists of the form (quote object) will be written as the equivalent 'object. | |
1700 Do not SET this variable; bind it instead. | |
1701 */ ); | |
1702 print_readably = 0; | |
1703 | |
1704 /* #### I think this should default to t. But we'd better wait | |
1705 until we see that it works out. */ | |
1706 DEFVAR_LISP ("print-gensym", &Vprint_gensym /* | |
1707 If non-nil, then uninterned symbols will be printed specially. | |
1708 Uninterned symbols are those which are not present in `obarray', that is, | |
1709 those which were made with `make-symbol' or by calling `intern' with a | |
1710 second argument. | |
1711 | |
1712 When print-gensym is true, such symbols will be preceded by "#:", | |
1713 which causes the reader to create a new symbol instead of interning | |
1714 and returning an existing one. Beware: the #: syntax creates a new | |
1715 symbol each time it is seen, so if you print an object which contains | |
1716 two pointers to the same uninterned symbol, `read' will not duplicate | |
1717 that structure. | |
1718 | |
1719 If the value of `print-gensym' is a cons cell, then in addition | |
1720 refrain from clearing `print-gensym-alist' on entry to and exit from | |
1721 printing functions, so that the use of #...# and #...= can carry over | |
1722 for several separately printed objects. | |
1723 */ ); | |
1724 Vprint_gensym = Qnil; | |
1725 | |
1726 DEFVAR_LISP ("print-gensym-alist", &Vprint_gensym_alist /* | |
1727 Association list of elements (GENSYM . N) to guide use of #N# and #N=. | |
1728 In each element, GENSYM is an uninterned symbol that has been associated | |
1729 with #N= for the specified value of N. | |
1730 */ ); | |
1731 Vprint_gensym_alist = Qnil; | |
1732 | |
1733 DEFVAR_LISP ("print-message-label", &Vprint_message_label /* | |
1734 Label for minibuffer messages created with `print'. This should | |
1735 generally be bound with `let' rather than set. (See `display-message'.) | |
1736 */ ); | |
1737 Vprint_message_label = Qprint; | |
1738 } |