]> code.delx.au - gnu-emacs/blob - src/print.c
(read_minibuf): Use FRAME_LEFT_SCROLL_BAR_WIDTH
[gnu-emacs] / src / print.c
1 /* Lisp object printing and output streams.
2 Copyright (C) 1985, 86, 88, 93, 94, 95 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include <config.h>
23 #include <stdio.h>
24 #include "lisp.h"
25
26 #ifndef standalone
27 #include "buffer.h"
28 #include "frame.h"
29 #include "window.h"
30 #include "process.h"
31 #include "dispextern.h"
32 #include "termchar.h"
33 #include "keyboard.h"
34 #endif /* not standalone */
35
36 #ifdef USE_TEXT_PROPERTIES
37 #include "intervals.h"
38 #endif
39
40 Lisp_Object Vstandard_output, Qstandard_output;
41
42 /* These are used to print like we read. */
43 extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
44
45 #ifdef LISP_FLOAT_TYPE
46 Lisp_Object Vfloat_output_format, Qfloat_output_format;
47 #endif /* LISP_FLOAT_TYPE */
48
49 /* Avoid actual stack overflow in print. */
50 int print_depth;
51
52 /* Detect most circularities to print finite output. */
53 #define PRINT_CIRCLE 200
54 Lisp_Object being_printed[PRINT_CIRCLE];
55
56 /* When printing into a buffer, first we put the text in this
57 block, then insert it all at once. */
58 char *print_buffer;
59
60 /* Size allocated in print_buffer. */
61 int print_buffer_size;
62 /* Size used in print_buffer. */
63 int print_buffer_pos;
64
65 /* Maximum length of list to print in full; noninteger means
66 effectively infinity */
67
68 Lisp_Object Vprint_length;
69
70 /* Maximum depth of list to print in full; noninteger means
71 effectively infinity. */
72
73 Lisp_Object Vprint_level;
74
75 /* Nonzero means print newlines in strings as \n. */
76
77 int print_escape_newlines;
78
79 Lisp_Object Qprint_escape_newlines;
80
81 /* Nonzero means print (quote foo) forms as 'foo, etc. */
82
83 int print_quoted;
84
85 /* Nonzero means print #: before uninterned symbols. */
86
87 int print_gensym;
88
89 /* Association list of certain objects that are `eq' in the form being
90 printed and which should be `eq' when read back in, using the #n=object
91 and #n# reader forms. Each element has the form (object . n). */
92
93 Lisp_Object printed_gensyms;
94
95 /* Nonzero means print newline to stdout before next minibuffer message.
96 Defined in xdisp.c */
97
98 extern int noninteractive_need_newline;
99
100 #ifdef MAX_PRINT_CHARS
101 static int print_chars;
102 static int max_print;
103 #endif /* MAX_PRINT_CHARS */
104
105 void print_interval ();
106 \f
107 #if 0
108 /* Convert between chars and GLYPHs */
109
110 int
111 glyphlen (glyphs)
112 register GLYPH *glyphs;
113 {
114 register int i = 0;
115
116 while (glyphs[i])
117 i++;
118 return i;
119 }
120
121 void
122 str_to_glyph_cpy (str, glyphs)
123 char *str;
124 GLYPH *glyphs;
125 {
126 register GLYPH *gp = glyphs;
127 register char *cp = str;
128
129 while (*cp)
130 *gp++ = *cp++;
131 }
132
133 void
134 str_to_glyph_ncpy (str, glyphs, n)
135 char *str;
136 GLYPH *glyphs;
137 register int n;
138 {
139 register GLYPH *gp = glyphs;
140 register char *cp = str;
141
142 while (n-- > 0)
143 *gp++ = *cp++;
144 }
145
146 void
147 glyph_to_str_cpy (glyphs, str)
148 GLYPH *glyphs;
149 char *str;
150 {
151 register GLYPH *gp = glyphs;
152 register char *cp = str;
153
154 while (*gp)
155 *str++ = *gp++ & 0377;
156 }
157 #endif
158 \f
159 /* Low level output routines for characters and strings */
160
161 /* Lisp functions to do output using a stream
162 must have the stream in a variable called printcharfun
163 and must start with PRINTPREPARE, end with PRINTFINISH,
164 and use PRINTDECLARE to declare common variables.
165 Use PRINTCHAR to output one character,
166 or call strout to output a block of characters.
167 */
168
169 #define PRINTDECLARE \
170 struct buffer *old = current_buffer; \
171 int old_point = -1, start_point; \
172 Lisp_Object original
173
174 #define PRINTPREPARE \
175 original = printcharfun; \
176 if (NILP (printcharfun)) printcharfun = Qt; \
177 if (BUFFERP (printcharfun)) \
178 { if (XBUFFER (printcharfun) != current_buffer) \
179 Fset_buffer (printcharfun); \
180 printcharfun = Qnil;} \
181 if (MARKERP (printcharfun)) \
182 { if (!(XMARKER (original)->buffer)) \
183 error ("Marker does not point anywhere"); \
184 if (XMARKER (original)->buffer != current_buffer) \
185 set_buffer_internal (XMARKER (original)->buffer); \
186 old_point = PT; \
187 SET_PT (marker_position (printcharfun)); \
188 start_point = PT; \
189 printcharfun = Qnil;} \
190 if (NILP (printcharfun)) \
191 { \
192 print_buffer_pos = 0; \
193 print_buffer_size = 1000; \
194 print_buffer = (char *) xmalloc (print_buffer_size); \
195 } \
196 else \
197 print_buffer = 0; \
198 printed_gensyms = Qnil
199
200 #define PRINTFINISH \
201 if (NILP (printcharfun)) \
202 insert (print_buffer, print_buffer_pos); \
203 if (print_buffer) free (print_buffer); \
204 if (MARKERP (original)) \
205 Fset_marker (original, make_number (PT), Qnil); \
206 if (old_point >= 0) \
207 SET_PT (old_point + (old_point >= start_point \
208 ? PT - start_point : 0)); \
209 if (old != current_buffer) \
210 set_buffer_internal (old); \
211 printed_gensyms = Qnil
212
213 #define PRINTCHAR(ch) printchar (ch, printcharfun)
214
215 /* Index of first unused element of FRAME_MESSAGE_BUF(mini_frame). */
216 static int printbufidx;
217
218 static void
219 printchar (ch, fun)
220 unsigned char ch;
221 Lisp_Object fun;
222 {
223 Lisp_Object ch1;
224
225 #ifdef MAX_PRINT_CHARS
226 if (max_print)
227 print_chars++;
228 #endif /* MAX_PRINT_CHARS */
229 #ifndef standalone
230 if (EQ (fun, Qnil))
231 {
232 QUIT;
233 if (print_buffer_pos == print_buffer_size)
234 print_buffer = (char *) xrealloc (print_buffer,
235 print_buffer_size *= 2);
236 print_buffer[print_buffer_pos++] = ch;
237 return;
238 }
239
240 if (EQ (fun, Qt))
241 {
242 FRAME_PTR mini_frame
243 = XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)));
244
245 if (noninteractive)
246 {
247 putchar (ch);
248 noninteractive_need_newline = 1;
249 return;
250 }
251
252 if (echo_area_glyphs != FRAME_MESSAGE_BUF (mini_frame)
253 || !message_buf_print)
254 {
255 message_log_maybe_newline ();
256 echo_area_glyphs = FRAME_MESSAGE_BUF (mini_frame);
257 printbufidx = 0;
258 echo_area_glyphs_length = 0;
259 message_buf_print = 1;
260 }
261
262 message_dolog (&ch, 1, 0);
263 if (printbufidx < FRAME_WIDTH (mini_frame) - 1)
264 FRAME_MESSAGE_BUF (mini_frame)[printbufidx++] = ch;
265 FRAME_MESSAGE_BUF (mini_frame)[printbufidx] = 0;
266 echo_area_glyphs_length = printbufidx;
267
268 return;
269 }
270 #endif /* not standalone */
271
272 XSETFASTINT (ch1, ch);
273 call1 (fun, ch1);
274 }
275
276 static void
277 strout (ptr, size, printcharfun)
278 char *ptr;
279 int size;
280 Lisp_Object printcharfun;
281 {
282 int i = 0;
283
284 if (EQ (printcharfun, Qnil))
285 {
286 if (size < 0)
287 size = strlen (ptr);
288
289 if (print_buffer_pos + size > print_buffer_size)
290 {
291 print_buffer_size = print_buffer_size * 2 + size;
292 print_buffer = (char *) xrealloc (print_buffer,
293 print_buffer_size);
294 }
295 bcopy (ptr, print_buffer + print_buffer_pos, size);
296 print_buffer_pos += size;
297
298 #ifdef MAX_PRINT_CHARS
299 if (max_print)
300 print_chars += size;
301 #endif /* MAX_PRINT_CHARS */
302 return;
303 }
304 if (EQ (printcharfun, Qt))
305 {
306 FRAME_PTR mini_frame
307 = XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)));
308
309 i = size >= 0 ? size : strlen (ptr);
310 #ifdef MAX_PRINT_CHARS
311 if (max_print)
312 print_chars += i;
313 #endif /* MAX_PRINT_CHARS */
314
315 if (noninteractive)
316 {
317 fwrite (ptr, 1, i, stdout);
318 noninteractive_need_newline = 1;
319 return;
320 }
321
322 if (echo_area_glyphs != FRAME_MESSAGE_BUF (mini_frame)
323 || !message_buf_print)
324 {
325 message_log_maybe_newline ();
326 echo_area_glyphs = FRAME_MESSAGE_BUF (mini_frame);
327 printbufidx = 0;
328 echo_area_glyphs_length = 0;
329 message_buf_print = 1;
330 }
331
332 message_dolog (ptr, i, 0);
333 if (i > FRAME_WIDTH (mini_frame) - printbufidx - 1)
334 i = FRAME_WIDTH (mini_frame) - printbufidx - 1;
335 bcopy (ptr, &FRAME_MESSAGE_BUF (mini_frame) [printbufidx], i);
336 printbufidx += i;
337 echo_area_glyphs_length = printbufidx;
338 FRAME_MESSAGE_BUF (mini_frame) [printbufidx] = 0;
339
340 return;
341 }
342
343 if (size >= 0)
344 while (i < size)
345 PRINTCHAR (ptr[i++]);
346 else
347 while (ptr[i])
348 PRINTCHAR (ptr[i++]);
349 }
350
351 /* Print the contents of a string STRING using PRINTCHARFUN.
352 It isn't safe to use strout in many cases,
353 because printing one char can relocate. */
354
355 print_string (string, printcharfun)
356 Lisp_Object string;
357 Lisp_Object printcharfun;
358 {
359 if (EQ (printcharfun, Qt) || NILP (printcharfun))
360 /* strout is safe for output to a frame (echo area) or to print_buffer. */
361 strout (XSTRING (string)->data, XSTRING (string)->size, printcharfun);
362 else
363 {
364 /* Otherwise, fetch the string address for each character. */
365 int i;
366 int size = XSTRING (string)->size;
367 struct gcpro gcpro1;
368 GCPRO1 (string);
369 for (i = 0; i < size; i++)
370 PRINTCHAR (XSTRING (string)->data[i]);
371 UNGCPRO;
372 }
373 }
374 \f
375 DEFUN ("write-char", Fwrite_char, Swrite_char, 1, 2, 0,
376 "Output character CHARACTER to stream PRINTCHARFUN.\n\
377 PRINTCHARFUN defaults to the value of `standard-output' (which see).")
378 (character, printcharfun)
379 Lisp_Object character, printcharfun;
380 {
381 PRINTDECLARE;
382
383 if (NILP (printcharfun))
384 printcharfun = Vstandard_output;
385 CHECK_NUMBER (character, 0);
386 PRINTPREPARE;
387 PRINTCHAR (XINT (character));
388 PRINTFINISH;
389 return character;
390 }
391
392 /* Used from outside of print.c to print a block of SIZE chars at DATA
393 on the default output stream.
394 Do not use this on the contents of a Lisp string. */
395
396 write_string (data, size)
397 char *data;
398 int size;
399 {
400 PRINTDECLARE;
401 Lisp_Object printcharfun;
402
403 printcharfun = Vstandard_output;
404
405 PRINTPREPARE;
406 strout (data, size, printcharfun);
407 PRINTFINISH;
408 }
409
410 /* Used from outside of print.c to print a block of SIZE chars at DATA
411 on a specified stream PRINTCHARFUN.
412 Do not use this on the contents of a Lisp string. */
413
414 write_string_1 (data, size, printcharfun)
415 char *data;
416 int size;
417 Lisp_Object printcharfun;
418 {
419 PRINTDECLARE;
420
421 PRINTPREPARE;
422 strout (data, size, printcharfun);
423 PRINTFINISH;
424 }
425
426
427 #ifndef standalone
428
429 void
430 temp_output_buffer_setup (bufname)
431 char *bufname;
432 {
433 register struct buffer *old = current_buffer;
434 register Lisp_Object buf;
435
436 Fset_buffer (Fget_buffer_create (build_string (bufname)));
437
438 current_buffer->directory = old->directory;
439 current_buffer->read_only = Qnil;
440 Ferase_buffer ();
441
442 XSETBUFFER (buf, current_buffer);
443 specbind (Qstandard_output, buf);
444
445 set_buffer_internal (old);
446 }
447
448 Lisp_Object
449 internal_with_output_to_temp_buffer (bufname, function, args)
450 char *bufname;
451 Lisp_Object (*function) ();
452 Lisp_Object args;
453 {
454 int count = specpdl_ptr - specpdl;
455 Lisp_Object buf, val;
456 struct gcpro gcpro1;
457
458 GCPRO1 (args);
459 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
460 temp_output_buffer_setup (bufname);
461 buf = Vstandard_output;
462 UNGCPRO;
463
464 val = (*function) (args);
465
466 GCPRO1 (val);
467 temp_output_buffer_show (buf);
468 UNGCPRO;
469
470 return unbind_to (count, val);
471 }
472
473 DEFUN ("with-output-to-temp-buffer", Fwith_output_to_temp_buffer, Swith_output_to_temp_buffer,
474 1, UNEVALLED, 0,
475 "Bind `standard-output' to buffer BUFNAME, eval BODY, then show that buffer.\n\
476 The buffer is cleared out initially, and marked as unmodified when done.\n\
477 All output done by BODY is inserted in that buffer by default.\n\
478 The buffer is displayed in another window, but not selected.\n\
479 The value of the last form in BODY is returned.\n\
480 If BODY does not finish normally, the buffer BUFNAME is not displayed.\n\n\
481 If variable `temp-buffer-show-function' is non-nil, call it at the end\n\
482 to get the buffer displayed. It gets one argument, the buffer to display.")
483 (args)
484 Lisp_Object args;
485 {
486 struct gcpro gcpro1;
487 Lisp_Object name;
488 int count = specpdl_ptr - specpdl;
489 Lisp_Object buf, val;
490
491 GCPRO1(args);
492 name = Feval (Fcar (args));
493 UNGCPRO;
494
495 CHECK_STRING (name, 0);
496 temp_output_buffer_setup (XSTRING (name)->data);
497 buf = Vstandard_output;
498
499 val = Fprogn (Fcdr (args));
500
501 temp_output_buffer_show (buf);
502
503 return unbind_to (count, val);
504 }
505 #endif /* not standalone */
506 \f
507 static void print ();
508
509 DEFUN ("terpri", Fterpri, Sterpri, 0, 1, 0,
510 "Output a newline to stream PRINTCHARFUN.\n\
511 If PRINTCHARFUN is omitted or nil, the value of `standard-output' is used.")
512 (printcharfun)
513 Lisp_Object printcharfun;
514 {
515 PRINTDECLARE;
516
517 if (NILP (printcharfun))
518 printcharfun = Vstandard_output;
519 PRINTPREPARE;
520 PRINTCHAR ('\n');
521 PRINTFINISH;
522 return Qt;
523 }
524
525 DEFUN ("prin1", Fprin1, Sprin1, 1, 2, 0,
526 "Output the printed representation of OBJECT, any Lisp object.\n\
527 Quoting characters are printed when needed to make output that `read'\n\
528 can handle, whenever this is possible.\n\
529 Output stream is PRINTCHARFUN, or value of `standard-output' (which see).")
530 (object, printcharfun)
531 Lisp_Object object, printcharfun;
532 {
533 PRINTDECLARE;
534
535 #ifdef MAX_PRINT_CHARS
536 max_print = 0;
537 #endif /* MAX_PRINT_CHARS */
538 if (NILP (printcharfun))
539 printcharfun = Vstandard_output;
540 PRINTPREPARE;
541 print_depth = 0;
542 print (object, printcharfun, 1);
543 PRINTFINISH;
544 return object;
545 }
546
547 /* a buffer which is used to hold output being built by prin1-to-string */
548 Lisp_Object Vprin1_to_string_buffer;
549
550 DEFUN ("prin1-to-string", Fprin1_to_string, Sprin1_to_string, 1, 2, 0,
551 "Return a string containing the printed representation of OBJECT,\n\
552 any Lisp object. Quoting characters are used when needed to make output\n\
553 that `read' can handle, whenever this is possible, unless the optional\n\
554 second argument NOESCAPE is non-nil.")
555 (object, noescape)
556 Lisp_Object object, noescape;
557 {
558 PRINTDECLARE;
559 Lisp_Object printcharfun;
560 struct gcpro gcpro1, gcpro2;
561 Lisp_Object tem;
562
563 /* Save and restore this--we are altering a buffer
564 but we don't want to deactivate the mark just for that.
565 No need for specbind, since errors deactivate the mark. */
566 tem = Vdeactivate_mark;
567 GCPRO2 (object, tem);
568
569 printcharfun = Vprin1_to_string_buffer;
570 PRINTPREPARE;
571 print_depth = 0;
572 print (object, printcharfun, NILP (noescape));
573 /* Make Vprin1_to_string_buffer be the default buffer after PRINTFINSH */
574 PRINTFINISH;
575 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
576 object = Fbuffer_string ();
577
578 Ferase_buffer ();
579 set_buffer_internal (old);
580
581 Vdeactivate_mark = tem;
582 UNGCPRO;
583
584 return object;
585 }
586
587 DEFUN ("princ", Fprinc, Sprinc, 1, 2, 0,
588 "Output the printed representation of OBJECT, any Lisp object.\n\
589 No quoting characters are used; no delimiters are printed around\n\
590 the contents of strings.\n\
591 Output stream is PRINTCHARFUN, or value of standard-output (which see).")
592 (object, printcharfun)
593 Lisp_Object object, printcharfun;
594 {
595 PRINTDECLARE;
596
597 if (NILP (printcharfun))
598 printcharfun = Vstandard_output;
599 PRINTPREPARE;
600 print_depth = 0;
601 print (object, printcharfun, 0);
602 PRINTFINISH;
603 return object;
604 }
605
606 DEFUN ("print", Fprint, Sprint, 1, 2, 0,
607 "Output the printed representation of OBJECT, with newlines around it.\n\
608 Quoting characters are printed when needed to make output that `read'\n\
609 can handle, whenever this is possible.\n\
610 Output stream is PRINTCHARFUN, or value of `standard-output' (which see).")
611 (object, printcharfun)
612 Lisp_Object object, printcharfun;
613 {
614 PRINTDECLARE;
615 struct gcpro gcpro1;
616
617 #ifdef MAX_PRINT_CHARS
618 print_chars = 0;
619 max_print = MAX_PRINT_CHARS;
620 #endif /* MAX_PRINT_CHARS */
621 if (NILP (printcharfun))
622 printcharfun = Vstandard_output;
623 GCPRO1 (object);
624 PRINTPREPARE;
625 print_depth = 0;
626 PRINTCHAR ('\n');
627 print (object, printcharfun, 1);
628 PRINTCHAR ('\n');
629 PRINTFINISH;
630 #ifdef MAX_PRINT_CHARS
631 max_print = 0;
632 print_chars = 0;
633 #endif /* MAX_PRINT_CHARS */
634 UNGCPRO;
635 return object;
636 }
637
638 /* The subroutine object for external-debugging-output is kept here
639 for the convenience of the debugger. */
640 Lisp_Object Qexternal_debugging_output;
641
642 DEFUN ("external-debugging-output", Fexternal_debugging_output, Sexternal_debugging_output, 1, 1, 0,
643 "Write CHARACTER to stderr.\n\
644 You can call print while debugging emacs, and pass it this function\n\
645 to make it write to the debugging output.\n")
646 (character)
647 Lisp_Object character;
648 {
649 CHECK_NUMBER (character, 0);
650 putc (XINT (character), stderr);
651
652 return character;
653 }
654
655 /* This is the interface for debugging printing. */
656
657 void
658 debug_print (arg)
659 Lisp_Object arg;
660 {
661 Fprin1 (arg, Qexternal_debugging_output);
662 fprintf (stderr, "\r\n");
663 }
664 \f
665 DEFUN ("error-message-string", Ferror_message_string, Serror_message_string,
666 1, 1, 0,
667 "Convert an error value (ERROR-SYMBOL . DATA) to an error message.")
668 (obj)
669 Lisp_Object obj;
670 {
671 struct buffer *old = current_buffer;
672 Lisp_Object original, printcharfun, value;
673 struct gcpro gcpro1;
674
675 print_error_message (obj, Vprin1_to_string_buffer, NULL);
676
677 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
678 value = Fbuffer_string ();
679
680 GCPRO1 (value);
681 Ferase_buffer ();
682 set_buffer_internal (old);
683 UNGCPRO;
684
685 return value;
686 }
687
688 /* Print an error message for the error DATA
689 onto Lisp output stream STREAM (suitable for the print functions). */
690
691 print_error_message (data, stream)
692 Lisp_Object data, stream;
693 {
694 Lisp_Object errname, errmsg, file_error, tail;
695 struct gcpro gcpro1;
696 int i;
697
698 errname = Fcar (data);
699
700 if (EQ (errname, Qerror))
701 {
702 data = Fcdr (data);
703 if (!CONSP (data)) data = Qnil;
704 errmsg = Fcar (data);
705 file_error = Qnil;
706 }
707 else
708 {
709 errmsg = Fget (errname, Qerror_message);
710 file_error = Fmemq (Qfile_error,
711 Fget (errname, Qerror_conditions));
712 }
713
714 /* Print an error message including the data items. */
715
716 tail = Fcdr_safe (data);
717 GCPRO1 (tail);
718
719 /* For file-error, make error message by concatenating
720 all the data items. They are all strings. */
721 if (!NILP (file_error) && !NILP (tail))
722 errmsg = XCONS (tail)->car, tail = XCONS (tail)->cdr;
723
724 if (STRINGP (errmsg))
725 Fprinc (errmsg, stream);
726 else
727 write_string_1 ("peculiar error", -1, stream);
728
729 for (i = 0; CONSP (tail); tail = Fcdr (tail), i++)
730 {
731 write_string_1 (i ? ", " : ": ", 2, stream);
732 if (!NILP (file_error))
733 Fprinc (Fcar (tail), stream);
734 else
735 Fprin1 (Fcar (tail), stream);
736 }
737 UNGCPRO;
738 }
739 \f
740 #ifdef LISP_FLOAT_TYPE
741
742 /*
743 * The buffer should be at least as large as the max string size of the
744 * largest float, printed in the biggest notation. This is undoubtedly
745 * 20d float_output_format, with the negative of the C-constant "HUGE"
746 * from <math.h>.
747 *
748 * On the vax the worst case is -1e38 in 20d format which takes 61 bytes.
749 *
750 * I assume that IEEE-754 format numbers can take 329 bytes for the worst
751 * case of -1e307 in 20d float_output_format. What is one to do (short of
752 * re-writing _doprnt to be more sane)?
753 * -wsr
754 */
755
756 void
757 float_to_string (buf, data)
758 unsigned char *buf;
759 double data;
760 {
761 unsigned char *cp;
762 int width;
763
764 if (NILP (Vfloat_output_format)
765 || !STRINGP (Vfloat_output_format))
766 lose:
767 {
768 sprintf (buf, "%.17g", data);
769 width = -1;
770 }
771 else /* oink oink */
772 {
773 /* Check that the spec we have is fully valid.
774 This means not only valid for printf,
775 but meant for floats, and reasonable. */
776 cp = XSTRING (Vfloat_output_format)->data;
777
778 if (cp[0] != '%')
779 goto lose;
780 if (cp[1] != '.')
781 goto lose;
782
783 cp += 2;
784
785 /* Check the width specification. */
786 width = -1;
787 if ('0' <= *cp && *cp <= '9')
788 {
789 width = 0;
790 do
791 width = (width * 10) + (*cp++ - '0');
792 while (*cp >= '0' && *cp <= '9');
793
794 /* A precision of zero is valid only for %f. */
795 if (width > DBL_DIG
796 || (width == 0 && *cp != 'f'))
797 goto lose;
798 }
799
800 if (*cp != 'e' && *cp != 'f' && *cp != 'g')
801 goto lose;
802
803 if (cp[1] != 0)
804 goto lose;
805
806 sprintf (buf, XSTRING (Vfloat_output_format)->data, data);
807 }
808
809 /* Make sure there is a decimal point with digit after, or an
810 exponent, so that the value is readable as a float. But don't do
811 this with "%.0f"; it's valid for that not to produce a decimal
812 point. Note that width can be 0 only for %.0f. */
813 if (width != 0)
814 {
815 for (cp = buf; *cp; cp++)
816 if ((*cp < '0' || *cp > '9') && *cp != '-')
817 break;
818
819 if (*cp == '.' && cp[1] == 0)
820 {
821 cp[1] = '0';
822 cp[2] = 0;
823 }
824
825 if (*cp == 0)
826 {
827 *cp++ = '.';
828 *cp++ = '0';
829 *cp++ = 0;
830 }
831 }
832 }
833 #endif /* LISP_FLOAT_TYPE */
834 \f
835 static void
836 print (obj, printcharfun, escapeflag)
837 Lisp_Object obj;
838 register Lisp_Object printcharfun;
839 int escapeflag;
840 {
841 char buf[30];
842
843 QUIT;
844
845 #if 1 /* I'm not sure this is really worth doing. */
846 /* Detect circularities and truncate them.
847 No need to offer any alternative--this is better than an error. */
848 if (CONSP (obj) || VECTORP (obj) || COMPILEDP (obj))
849 {
850 int i;
851 for (i = 0; i < print_depth; i++)
852 if (EQ (obj, being_printed[i]))
853 {
854 sprintf (buf, "#%d", i);
855 strout (buf, -1, printcharfun);
856 return;
857 }
858 }
859 #endif
860
861 being_printed[print_depth] = obj;
862 print_depth++;
863
864 if (print_depth > PRINT_CIRCLE)
865 error ("Apparently circular structure being printed");
866 #ifdef MAX_PRINT_CHARS
867 if (max_print && print_chars > max_print)
868 {
869 PRINTCHAR ('\n');
870 print_chars = 0;
871 }
872 #endif /* MAX_PRINT_CHARS */
873
874 switch (XGCTYPE (obj))
875 {
876 case Lisp_Int:
877 if (sizeof (int) == sizeof (EMACS_INT))
878 sprintf (buf, "%d", XINT (obj));
879 else if (sizeof (long) == sizeof (EMACS_INT))
880 sprintf (buf, "%ld", XINT (obj));
881 else
882 abort ();
883 strout (buf, -1, printcharfun);
884 break;
885
886 #ifdef LISP_FLOAT_TYPE
887 case Lisp_Float:
888 {
889 char pigbuf[350]; /* see comments in float_to_string */
890
891 float_to_string (pigbuf, XFLOAT(obj)->data);
892 strout (pigbuf, -1, printcharfun);
893 }
894 break;
895 #endif
896
897 case Lisp_String:
898 if (!escapeflag)
899 print_string (obj, printcharfun);
900 else
901 {
902 register int i;
903 register unsigned char c;
904 struct gcpro gcpro1;
905
906 GCPRO1 (obj);
907
908 #ifdef USE_TEXT_PROPERTIES
909 if (!NULL_INTERVAL_P (XSTRING (obj)->intervals))
910 {
911 PRINTCHAR ('#');
912 PRINTCHAR ('(');
913 }
914 #endif
915
916 PRINTCHAR ('\"');
917 for (i = 0; i < XSTRING (obj)->size; i++)
918 {
919 QUIT;
920 c = XSTRING (obj)->data[i];
921 if (c == '\n' && print_escape_newlines)
922 {
923 PRINTCHAR ('\\');
924 PRINTCHAR ('n');
925 }
926 else if (c == '\f' && print_escape_newlines)
927 {
928 PRINTCHAR ('\\');
929 PRINTCHAR ('f');
930 }
931 else
932 {
933 if (c == '\"' || c == '\\')
934 PRINTCHAR ('\\');
935 PRINTCHAR (c);
936 }
937 }
938 PRINTCHAR ('\"');
939
940 #ifdef USE_TEXT_PROPERTIES
941 if (!NULL_INTERVAL_P (XSTRING (obj)->intervals))
942 {
943 traverse_intervals (XSTRING (obj)->intervals,
944 0, 0, print_interval, printcharfun);
945 PRINTCHAR (')');
946 }
947 #endif
948
949 UNGCPRO;
950 }
951 break;
952
953 case Lisp_Symbol:
954 {
955 register int confusing;
956 register unsigned char *p = XSYMBOL (obj)->name->data;
957 register unsigned char *end = p + XSYMBOL (obj)->name->size;
958 register unsigned char c;
959
960 if (p != end && (*p == '-' || *p == '+')) p++;
961 if (p == end)
962 confusing = 0;
963 else
964 {
965 while (p != end && *p >= '0' && *p <= '9')
966 p++;
967 confusing = (end == p);
968 }
969
970 /* If we print an uninterned symbol as part of a complex object and
971 the flag print-gensym is non-nil, prefix it with #n= to read the
972 object back with the #n# reader syntax later if needed. */
973 if (print_gensym && NILP (XSYMBOL (obj)->obarray))
974 {
975 if (print_depth > 1)
976 {
977 Lisp_Object tem;
978 tem = Fassq (obj, printed_gensyms);
979 if (CONSP (tem))
980 {
981 PRINTCHAR ('#');
982 print (XCDR (tem), printcharfun, escapeflag);
983 PRINTCHAR ('#');
984 break;
985 }
986 else
987 {
988 if (CONSP (printed_gensyms))
989 XSETFASTINT (tem, XCDR (XCAR (printed_gensyms)) + 1);
990 else
991 XSETFASTINT (tem, 1);
992 printed_gensyms = Fcons (Fcons (obj, tem), printed_gensyms);
993
994 PRINTCHAR ('#');
995 print (tem, printcharfun, escapeflag);
996 PRINTCHAR ('=');
997 }
998 }
999 PRINTCHAR ('#');
1000 PRINTCHAR (':');
1001 }
1002
1003 p = XSYMBOL (obj)->name->data;
1004 while (p != end)
1005 {
1006 QUIT;
1007 c = *p++;
1008 if (escapeflag)
1009 {
1010 if (c == '\"' || c == '\\' || c == '\'' || c == ';' || c == '#' ||
1011 c == '(' || c == ')' || c == ',' || c =='.' || c == '`' ||
1012 c == '[' || c == ']' || c == '?' || c <= 040 || confusing)
1013 PRINTCHAR ('\\'), confusing = 0;
1014 }
1015 PRINTCHAR (c);
1016 }
1017 }
1018 break;
1019
1020 case Lisp_Cons:
1021 /* If deeper than spec'd depth, print placeholder. */
1022 if (INTEGERP (Vprint_level)
1023 && print_depth > XINT (Vprint_level))
1024 strout ("...", -1, printcharfun);
1025 else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
1026 && (EQ (XCAR (obj), Qquote)))
1027 {
1028 PRINTCHAR ('\'');
1029 print (XCAR (XCDR (obj)), printcharfun, escapeflag);
1030 }
1031 else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
1032 && (EQ (XCAR (obj), Qfunction)))
1033 {
1034 PRINTCHAR ('#');
1035 PRINTCHAR ('\'');
1036 print (XCAR (XCDR (obj)), printcharfun, escapeflag);
1037 }
1038 else if (print_quoted && CONSP (XCDR (obj)) && NILP (XCDR (XCDR (obj)))
1039 && ((EQ (XCAR (obj), Qbackquote)
1040 || EQ (XCAR (obj), Qcomma)
1041 || EQ (XCAR (obj), Qcomma_at)
1042 || EQ (XCAR (obj), Qcomma_dot))))
1043 {
1044 print (XCAR (obj), printcharfun, 0);
1045 print (XCAR (XCDR (obj)), printcharfun, escapeflag);
1046 }
1047 else
1048 {
1049 PRINTCHAR ('(');
1050 {
1051 register int i = 0;
1052 register int max = 0;
1053
1054 if (INTEGERP (Vprint_length))
1055 max = XINT (Vprint_length);
1056 /* Could recognize circularities in cdrs here,
1057 but that would make printing of long lists quadratic.
1058 It's not worth doing. */
1059 while (CONSP (obj))
1060 {
1061 if (i++)
1062 PRINTCHAR (' ');
1063 if (max && i > max)
1064 {
1065 strout ("...", 3, printcharfun);
1066 break;
1067 }
1068 print (XCAR (obj), printcharfun, escapeflag);
1069 obj = XCDR (obj);
1070 }
1071 }
1072 if (!NILP (obj))
1073 {
1074 strout (" . ", 3, printcharfun);
1075 print (obj, printcharfun, escapeflag);
1076 }
1077 PRINTCHAR (')');
1078 }
1079 break;
1080
1081 case Lisp_Vectorlike:
1082 if (PROCESSP (obj))
1083 {
1084 if (escapeflag)
1085 {
1086 strout ("#<process ", -1, printcharfun);
1087 print_string (XPROCESS (obj)->name, printcharfun);
1088 PRINTCHAR ('>');
1089 }
1090 else
1091 print_string (XPROCESS (obj)->name, printcharfun);
1092 }
1093 else if (BOOL_VECTOR_P (obj))
1094 {
1095 register int i;
1096 register unsigned char c;
1097 struct gcpro gcpro1;
1098 int size_in_chars
1099 = (XBOOL_VECTOR (obj)->size + BITS_PER_CHAR) / BITS_PER_CHAR;
1100
1101 GCPRO1 (obj);
1102
1103 PRINTCHAR ('#');
1104 PRINTCHAR ('&');
1105 sprintf (buf, "%d", XBOOL_VECTOR (obj)->size);
1106 strout (buf, -1, printcharfun);
1107 PRINTCHAR ('\"');
1108
1109 /* Don't print more characters than the specified maximum. */
1110 if (INTEGERP (Vprint_length)
1111 && XINT (Vprint_length) < size_in_chars)
1112 size_in_chars = XINT (Vprint_length);
1113
1114 for (i = 0; i < size_in_chars; i++)
1115 {
1116 QUIT;
1117 c = XBOOL_VECTOR (obj)->data[i];
1118 if (c == '\n' && print_escape_newlines)
1119 {
1120 PRINTCHAR ('\\');
1121 PRINTCHAR ('n');
1122 }
1123 else if (c == '\f' && print_escape_newlines)
1124 {
1125 PRINTCHAR ('\\');
1126 PRINTCHAR ('f');
1127 }
1128 else
1129 {
1130 if (c == '\"' || c == '\\')
1131 PRINTCHAR ('\\');
1132 PRINTCHAR (c);
1133 }
1134 }
1135 PRINTCHAR ('\"');
1136
1137 UNGCPRO;
1138 }
1139 else if (SUBRP (obj))
1140 {
1141 strout ("#<subr ", -1, printcharfun);
1142 strout (XSUBR (obj)->symbol_name, -1, printcharfun);
1143 PRINTCHAR ('>');
1144 }
1145 #ifndef standalone
1146 else if (WINDOWP (obj))
1147 {
1148 strout ("#<window ", -1, printcharfun);
1149 sprintf (buf, "%d", XFASTINT (XWINDOW (obj)->sequence_number));
1150 strout (buf, -1, printcharfun);
1151 if (!NILP (XWINDOW (obj)->buffer))
1152 {
1153 strout (" on ", -1, printcharfun);
1154 print_string (XBUFFER (XWINDOW (obj)->buffer)->name, printcharfun);
1155 }
1156 PRINTCHAR ('>');
1157 }
1158 else if (BUFFERP (obj))
1159 {
1160 if (NILP (XBUFFER (obj)->name))
1161 strout ("#<killed buffer>", -1, printcharfun);
1162 else if (escapeflag)
1163 {
1164 strout ("#<buffer ", -1, printcharfun);
1165 print_string (XBUFFER (obj)->name, printcharfun);
1166 PRINTCHAR ('>');
1167 }
1168 else
1169 print_string (XBUFFER (obj)->name, printcharfun);
1170 }
1171 else if (WINDOW_CONFIGURATIONP (obj))
1172 {
1173 strout ("#<window-configuration>", -1, printcharfun);
1174 }
1175 else if (FRAMEP (obj))
1176 {
1177 strout ((FRAME_LIVE_P (XFRAME (obj))
1178 ? "#<frame " : "#<dead frame "),
1179 -1, printcharfun);
1180 print_string (XFRAME (obj)->name, printcharfun);
1181 sprintf (buf, " 0x%lx", (unsigned long) (XFRAME (obj)));
1182 strout (buf, -1, printcharfun);
1183 PRINTCHAR ('>');
1184 }
1185 #endif /* not standalone */
1186 else
1187 {
1188 int size = XVECTOR (obj)->size;
1189 if (COMPILEDP (obj))
1190 {
1191 PRINTCHAR ('#');
1192 size &= PSEUDOVECTOR_SIZE_MASK;
1193 }
1194 if (CHAR_TABLE_P (obj))
1195 {
1196 /* We print a char-table as if it were a vector,
1197 lumping the parent and default slots in with the
1198 character slots. But we add #^ as a prefix. */
1199 PRINTCHAR ('#');
1200 PRINTCHAR ('^');
1201 size &= PSEUDOVECTOR_SIZE_MASK;
1202 }
1203 if (size & PSEUDOVECTOR_FLAG)
1204 goto badtype;
1205
1206 PRINTCHAR ('[');
1207 {
1208 register int i;
1209 register Lisp_Object tem;
1210
1211 /* Don't print more elements than the specified maximum. */
1212 if (INTEGERP (Vprint_length)
1213 && XINT (Vprint_length) < size)
1214 size = XINT (Vprint_length);
1215
1216 for (i = 0; i < size; i++)
1217 {
1218 if (i) PRINTCHAR (' ');
1219 tem = XVECTOR (obj)->contents[i];
1220 print (tem, printcharfun, escapeflag);
1221 }
1222 }
1223 PRINTCHAR (']');
1224 }
1225 break;
1226
1227 #ifndef standalone
1228 case Lisp_Misc:
1229 switch (XMISCTYPE (obj))
1230 {
1231 case Lisp_Misc_Marker:
1232 strout ("#<marker ", -1, printcharfun);
1233 if (!(XMARKER (obj)->buffer))
1234 strout ("in no buffer", -1, printcharfun);
1235 else
1236 {
1237 sprintf (buf, "at %d", marker_position (obj));
1238 strout (buf, -1, printcharfun);
1239 strout (" in ", -1, printcharfun);
1240 print_string (XMARKER (obj)->buffer->name, printcharfun);
1241 }
1242 PRINTCHAR ('>');
1243 break;
1244
1245 case Lisp_Misc_Overlay:
1246 strout ("#<overlay ", -1, printcharfun);
1247 if (!(XMARKER (OVERLAY_START (obj))->buffer))
1248 strout ("in no buffer", -1, printcharfun);
1249 else
1250 {
1251 sprintf (buf, "from %d to %d in ",
1252 marker_position (OVERLAY_START (obj)),
1253 marker_position (OVERLAY_END (obj)));
1254 strout (buf, -1, printcharfun);
1255 print_string (XMARKER (OVERLAY_START (obj))->buffer->name,
1256 printcharfun);
1257 }
1258 PRINTCHAR ('>');
1259 break;
1260
1261 /* Remaining cases shouldn't happen in normal usage, but let's print
1262 them anyway for the benefit of the debugger. */
1263 case Lisp_Misc_Free:
1264 strout ("#<misc free cell>", -1, printcharfun);
1265 break;
1266
1267 case Lisp_Misc_Intfwd:
1268 sprintf (buf, "#<intfwd to %d>", *XINTFWD (obj)->intvar);
1269 strout (buf, -1, printcharfun);
1270 break;
1271
1272 case Lisp_Misc_Boolfwd:
1273 sprintf (buf, "#<boolfwd to %s>",
1274 (*XBOOLFWD (obj)->boolvar ? "t" : "nil"));
1275 strout (buf, -1, printcharfun);
1276 break;
1277
1278 case Lisp_Misc_Objfwd:
1279 strout ("#<objfwd to ", -1, printcharfun);
1280 print (*XOBJFWD (obj)->objvar, printcharfun, escapeflag);
1281 PRINTCHAR ('>');
1282 break;
1283
1284 case Lisp_Misc_Buffer_Objfwd:
1285 strout ("#<buffer_objfwd to ", -1, printcharfun);
1286 print (*(Lisp_Object *)((char *)current_buffer
1287 + XBUFFER_OBJFWD (obj)->offset),
1288 printcharfun, escapeflag);
1289 PRINTCHAR ('>');
1290 break;
1291
1292 case Lisp_Misc_Kboard_Objfwd:
1293 strout ("#<kboard_objfwd to ", -1, printcharfun);
1294 print (*(Lisp_Object *)((char *) current_kboard
1295 + XKBOARD_OBJFWD (obj)->offset),
1296 printcharfun, escapeflag);
1297 PRINTCHAR ('>');
1298 break;
1299
1300 case Lisp_Misc_Buffer_Local_Value:
1301 strout ("#<buffer_local_value ", -1, printcharfun);
1302 goto do_buffer_local;
1303 case Lisp_Misc_Some_Buffer_Local_Value:
1304 strout ("#<some_buffer_local_value ", -1, printcharfun);
1305 do_buffer_local:
1306 strout ("[realvalue] ", -1, printcharfun);
1307 print (XBUFFER_LOCAL_VALUE (obj)->car, printcharfun, escapeflag);
1308 strout ("[buffer] ", -1, printcharfun);
1309 print (XCONS (XBUFFER_LOCAL_VALUE (obj)->cdr)->car,
1310 printcharfun, escapeflag);
1311 strout ("[alist-elt] ", -1, printcharfun);
1312 print (XCONS (XCONS (XBUFFER_LOCAL_VALUE (obj)->cdr)->cdr)->car,
1313 printcharfun, escapeflag);
1314 strout ("[default-value] ", -1, printcharfun);
1315 print (XCONS (XCONS (XBUFFER_LOCAL_VALUE (obj)->cdr)->cdr)->cdr,
1316 printcharfun, escapeflag);
1317 PRINTCHAR ('>');
1318 break;
1319
1320 default:
1321 goto badtype;
1322 }
1323 break;
1324 #endif /* standalone */
1325
1326 default:
1327 badtype:
1328 {
1329 /* We're in trouble if this happens!
1330 Probably should just abort () */
1331 strout ("#<EMACS BUG: INVALID DATATYPE ", -1, printcharfun);
1332 if (MISCP (obj))
1333 sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj));
1334 else if (VECTORLIKEP (obj))
1335 sprintf (buf, "(PVEC 0x%08x)", (int) XVECTOR (obj)->size);
1336 else
1337 sprintf (buf, "(0x%02x)", (int) XTYPE (obj));
1338 strout (buf, -1, printcharfun);
1339 strout (" Save your buffers immediately and please report this bug>",
1340 -1, printcharfun);
1341 }
1342 }
1343
1344 print_depth--;
1345 }
1346 \f
1347 #ifdef USE_TEXT_PROPERTIES
1348
1349 /* Print a description of INTERVAL using PRINTCHARFUN.
1350 This is part of printing a string that has text properties. */
1351
1352 void
1353 print_interval (interval, printcharfun)
1354 INTERVAL interval;
1355 Lisp_Object printcharfun;
1356 {
1357 PRINTCHAR (' ');
1358 print (make_number (interval->position), printcharfun, 1);
1359 PRINTCHAR (' ');
1360 print (make_number (interval->position + LENGTH (interval)),
1361 printcharfun, 1);
1362 PRINTCHAR (' ');
1363 print (interval->plist, printcharfun, 1);
1364 }
1365
1366 #endif /* USE_TEXT_PROPERTIES */
1367 \f
1368 void
1369 syms_of_print ()
1370 {
1371 DEFVAR_LISP ("standard-output", &Vstandard_output,
1372 "Output stream `print' uses by default for outputting a character.\n\
1373 This may be any function of one argument.\n\
1374 It may also be a buffer (output is inserted before point)\n\
1375 or a marker (output is inserted and the marker is advanced)\n\
1376 or the symbol t (output appears in the echo area).");
1377 Vstandard_output = Qt;
1378 Qstandard_output = intern ("standard-output");
1379 staticpro (&Qstandard_output);
1380
1381 #ifdef LISP_FLOAT_TYPE
1382 DEFVAR_LISP ("float-output-format", &Vfloat_output_format,
1383 "The format descriptor string used to print floats.\n\
1384 This is a %-spec like those accepted by `printf' in C,\n\
1385 but with some restrictions. It must start with the two characters `%.'.\n\
1386 After that comes an integer precision specification,\n\
1387 and then a letter which controls the format.\n\
1388 The letters allowed are `e', `f' and `g'.\n\
1389 Use `e' for exponential notation \"DIG.DIGITSeEXPT\"\n\
1390 Use `f' for decimal point notation \"DIGITS.DIGITS\".\n\
1391 Use `g' to choose the shorter of those two formats for the number at hand.\n\
1392 The precision in any of these cases is the number of digits following\n\
1393 the decimal point. With `f', a precision of 0 means to omit the\n\
1394 decimal point. 0 is not allowed with `e' or `g'.\n\n\
1395 A value of nil means to use `%.17g'.");
1396 Vfloat_output_format = Qnil;
1397 Qfloat_output_format = intern ("float-output-format");
1398 staticpro (&Qfloat_output_format);
1399 #endif /* LISP_FLOAT_TYPE */
1400
1401 DEFVAR_LISP ("print-length", &Vprint_length,
1402 "Maximum length of list to print before abbreviating.\n\
1403 A value of nil means no limit.");
1404 Vprint_length = Qnil;
1405
1406 DEFVAR_LISP ("print-level", &Vprint_level,
1407 "Maximum depth of list nesting to print before abbreviating.\n\
1408 A value of nil means no limit.");
1409 Vprint_level = Qnil;
1410
1411 DEFVAR_BOOL ("print-escape-newlines", &print_escape_newlines,
1412 "Non-nil means print newlines in strings as backslash-n.\n\
1413 Also print formfeeds as backslash-f.");
1414 print_escape_newlines = 0;
1415
1416 DEFVAR_BOOL ("print-quoted", &print_quoted,
1417 "Non-nil means print quoted forms with reader syntax.\n\
1418 I.e., (quote foo) prints as 'foo, (function foo) as #'foo, and, backquoted\n\
1419 forms print in the new syntax.");
1420 print_quoted = 0;
1421
1422 DEFVAR_BOOL ("print-gensym", &print_gensym,
1423 "Non-nil means print uninterned symbols so they will read as uninterned.\n\
1424 I.e., the value of (make-symbol "foobar") prints as #:foobar.");
1425 print_gensym = 0;
1426
1427 /* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */
1428 staticpro (&Vprin1_to_string_buffer);
1429
1430 defsubr (&Sprin1);
1431 defsubr (&Sprin1_to_string);
1432 defsubr (&Serror_message_string);
1433 defsubr (&Sprinc);
1434 defsubr (&Sprint);
1435 defsubr (&Sterpri);
1436 defsubr (&Swrite_char);
1437 defsubr (&Sexternal_debugging_output);
1438
1439 Qexternal_debugging_output = intern ("external-debugging-output");
1440 staticpro (&Qexternal_debugging_output);
1441
1442 Qprint_escape_newlines = intern ("print-escape-newlines");
1443 staticpro (&Qprint_escape_newlines);
1444
1445 staticpro (&printed_gensyms);
1446 printed_gensyms = Qnil;
1447
1448 #ifndef standalone
1449 defsubr (&Swith_output_to_temp_buffer);
1450 #endif /* not standalone */
1451 }