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