(mail-mode): Make adaptive-fill-regexp
[bpt/emacs.git] / src / print.c
CommitLineData
38010d50 1/* Lisp object printing and output streams.
f8c25f1b 2 Copyright (C) 1985, 86, 88, 93, 94, 95 Free Software Foundation, Inc.
38010d50
JB
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
4746118a 8the Free Software Foundation; either version 2, or (at your option)
38010d50
JB
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
3b7ad313
EN
18the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
38010d50
JB
20
21
18160b98 22#include <config.h>
38010d50 23#include <stdio.h>
38010d50
JB
24#include "lisp.h"
25
26#ifndef standalone
27#include "buffer.h"
087e3c46 28#include "charset.h"
0137dbf7 29#include "frame.h"
38010d50
JB
30#include "window.h"
31#include "process.h"
32#include "dispextern.h"
33#include "termchar.h"
077d751f 34#include "keyboard.h"
38010d50
JB
35#endif /* not standalone */
36
7651e1f5
RS
37#ifdef USE_TEXT_PROPERTIES
38#include "intervals.h"
39#endif
40
38010d50
JB
41Lisp_Object Vstandard_output, Qstandard_output;
42
2f100b5c
EN
43/* These are used to print like we read. */
44extern Lisp_Object Qbackquote, Qcomma, Qcomma_at, Qcomma_dot, Qfunction;
45
38010d50
JB
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
ec838c39
RS
53/* Detect most circularities to print finite output. */
54#define PRINT_CIRCLE 200
55Lisp_Object being_printed[PRINT_CIRCLE];
56
6fec5601
RS
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
38010d50
JB
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
2f100b5c
EN
82/* Nonzero means print (quote foo) forms as 'foo, etc. */
83
84int print_quoted;
85
e0f69431
RS
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. */
081e0581 89
e0f69431 90Lisp_Object Vprint_gensym;
081e0581
EN
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
e0f69431 96Lisp_Object Vprint_gensym_alist;
2f100b5c 97
5259c737 98/* Nonzero means print newline to stdout before next minibuffer message.
38010d50
JB
99 Defined in xdisp.c */
100
101extern int noninteractive_need_newline;
5259c737 102
38010d50
JB
103#ifdef MAX_PRINT_CHARS
104static int print_chars;
105static int max_print;
106#endif /* MAX_PRINT_CHARS */
7651e1f5
RS
107
108void print_interval ();
38010d50
JB
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
eb8c3be9 162/* Low level output routines for characters and strings */
38010d50
JB
163
164/* Lisp functions to do output using a stream
081e0581
EN
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.
38010d50
JB
170*/
171
081e0581
EN
172#define PRINTDECLARE \
173 struct buffer *old = current_buffer; \
174 int old_point = -1, start_point; \
08e8d297
RS
175 int specpdl_count = specpdl_ptr - specpdl; \
176 int free_print_buffer = 0; \
081e0581
EN
177 Lisp_Object original
178
cdaa87fd
RS
179#define PRINTPREPARE \
180 original = printcharfun; \
181 if (NILP (printcharfun)) printcharfun = Qt; \
d4ae1f7e 182 if (BUFFERP (printcharfun)) \
08e8d297
RS
183 { \
184 if (XBUFFER (printcharfun) != current_buffer) \
cdaa87fd 185 Fset_buffer (printcharfun); \
08e8d297
RS
186 printcharfun = Qnil; \
187 } \
d4ae1f7e 188 if (MARKERP (printcharfun)) \
08e8d297
RS
189 { \
190 if (!(XMARKER (original)->buffer)) \
cdaa87fd
RS
191 error ("Marker does not point anywhere"); \
192 if (XMARKER (original)->buffer != current_buffer) \
193 set_buffer_internal (XMARKER (original)->buffer); \
6ec8bbd2 194 old_point = PT; \
cdaa87fd 195 SET_PT (marker_position (printcharfun)); \
6ec8bbd2 196 start_point = PT; \
08e8d297
RS
197 printcharfun = Qnil; \
198 } \
6fec5601
RS
199 if (NILP (printcharfun)) \
200 { \
08e8d297
RS
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); \
b3da2c73 209 free_print_buffer = 1; \
08e8d297 210 } \
6fec5601 211 print_buffer_pos = 0; \
6fec5601 212 } \
e0f69431
RS
213 if (!CONSP (Vprint_gensym)) \
214 Vprint_gensym_alist = Qnil
38010d50 215
cdaa87fd 216#define PRINTFINISH \
6fec5601
RS
217 if (NILP (printcharfun)) \
218 insert (print_buffer, print_buffer_pos); \
08e8d297 219 if (free_print_buffer) \
09eddb56 220 { \
99351a0d 221 xfree (print_buffer); \
09eddb56
RS
222 print_buffer = 0; \
223 } \
08e8d297 224 unbind_to (specpdl_count, Qnil); \
d4ae1f7e 225 if (MARKERP (original)) \
6ec8bbd2 226 Fset_marker (original, make_number (PT), Qnil); \
cdaa87fd
RS
227 if (old_point >= 0) \
228 SET_PT (old_point + (old_point >= start_point \
6ec8bbd2 229 ? PT - start_point : 0)); \
cdaa87fd 230 if (old != current_buffer) \
081e0581 231 set_buffer_internal (old); \
e0f69431
RS
232 if (!CONSP (Vprint_gensym)) \
233 Vprint_gensym_alist = Qnil
38010d50
JB
234
235#define PRINTCHAR(ch) printchar (ch, printcharfun)
236
09eddb56
RS
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
08e8d297
RS
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
09eddb56 253/* Index of first unused element of FRAME_MESSAGE_BUF (mini_frame). */
38010d50
JB
254static int printbufidx;
255
256static void
257printchar (ch, fun)
087e3c46 258 unsigned int ch;
38010d50
JB
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 {
087e3c46
KH
270 int len;
271 char work[4], *str;
272
38010d50 273 QUIT;
087e3c46
KH
274 len = CHAR_STRING (ch, work, str);
275 if (print_buffer_pos + len >= print_buffer_size)
6fec5601
RS
276 print_buffer = (char *) xrealloc (print_buffer,
277 print_buffer_size *= 2);
087e3c46
KH
278 bcopy (str, print_buffer + print_buffer_pos, len);
279 print_buffer_pos += len;
38010d50
JB
280 return;
281 }
282
283 if (EQ (fun, Qt))
284 {
c217b048 285 FRAME_PTR mini_frame
b8b1b8fd 286 = XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)));
087e3c46
KH
287 unsigned char work[4], *str;
288 int len = CHAR_STRING (ch, work, str);
b8b1b8fd 289
09eddb56
RS
290 QUIT;
291
38010d50
JB
292 if (noninteractive)
293 {
087e3c46
KH
294 while (len--)
295 putchar (*str), str++;
38010d50
JB
296 noninteractive_need_newline = 1;
297 return;
298 }
299
b8b1b8fd 300 if (echo_area_glyphs != FRAME_MESSAGE_BUF (mini_frame)
38010d50
JB
301 || !message_buf_print)
302 {
aee72e4f 303 message_log_maybe_newline ();
b8b1b8fd 304 echo_area_glyphs = FRAME_MESSAGE_BUF (mini_frame);
38010d50 305 printbufidx = 0;
708d172a 306 echo_area_glyphs_length = 0;
38010d50
JB
307 message_buf_print = 1;
308 }
309
087e3c46
KH
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;
b8b1b8fd 314 FRAME_MESSAGE_BUF (mini_frame)[printbufidx] = 0;
708d172a 315 echo_area_glyphs_length = printbufidx;
38010d50
JB
316
317 return;
318 }
319#endif /* not standalone */
320
b5d25c37 321 XSETFASTINT (ch1, ch);
38010d50
JB
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
087e3c46
KH
333 if (size < 0)
334 size = strlen (ptr);
335
38010d50
JB
336 if (EQ (printcharfun, Qnil))
337 {
6fec5601
RS
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
38010d50
JB
347#ifdef MAX_PRINT_CHARS
348 if (max_print)
6fec5601 349 print_chars += size;
38010d50
JB
350#endif /* MAX_PRINT_CHARS */
351 return;
352 }
353 if (EQ (printcharfun, Qt))
354 {
c217b048 355 FRAME_PTR mini_frame
b8b1b8fd
RS
356 = XFRAME (WINDOW_FRAME (XWINDOW (minibuf_window)));
357
09eddb56
RS
358 QUIT;
359
38010d50
JB
360#ifdef MAX_PRINT_CHARS
361 if (max_print)
087e3c46 362 print_chars += size;
38010d50
JB
363#endif /* MAX_PRINT_CHARS */
364
365 if (noninteractive)
366 {
087e3c46 367 fwrite (ptr, 1, size, stdout);
38010d50
JB
368 noninteractive_need_newline = 1;
369 return;
370 }
371
b8b1b8fd 372 if (echo_area_glyphs != FRAME_MESSAGE_BUF (mini_frame)
38010d50
JB
373 || !message_buf_print)
374 {
aee72e4f 375 message_log_maybe_newline ();
b8b1b8fd 376 echo_area_glyphs = FRAME_MESSAGE_BUF (mini_frame);
38010d50 377 printbufidx = 0;
708d172a 378 echo_area_glyphs_length = 0;
38010d50
JB
379 message_buf_print = 1;
380 }
381
087e3c46
KH
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;
708d172a 391 echo_area_glyphs_length = printbufidx;
b8b1b8fd 392 FRAME_MESSAGE_BUF (mini_frame) [printbufidx] = 0;
38010d50
JB
393
394 return;
395 }
396
087e3c46
KH
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 }
38010d50
JB
408}
409
410/* Print the contents of a string STRING using PRINTCHARFUN.
ed2c35ef
RS
411 It isn't safe to use strout in many cases,
412 because printing one char can relocate. */
38010d50
JB
413
414print_string (string, printcharfun)
415 Lisp_Object string;
416 Lisp_Object printcharfun;
417{
6fec5601
RS
418 if (EQ (printcharfun, Qt) || NILP (printcharfun))
419 /* strout is safe for output to a frame (echo area) or to print_buffer. */
38010d50
JB
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,
3738a371 435 "Output character CHARACTER to stream PRINTCHARFUN.\n\
57c9eb68 436PRINTCHARFUN defaults to the value of `standard-output' (which see).")
3738a371
EN
437 (character, printcharfun)
438 Lisp_Object character, printcharfun;
38010d50 439{
081e0581 440 PRINTDECLARE;
38010d50 441
10eebdbb 442 if (NILP (printcharfun))
38010d50 443 printcharfun = Vstandard_output;
3738a371 444 CHECK_NUMBER (character, 0);
38010d50 445 PRINTPREPARE;
3738a371 446 PRINTCHAR (XINT (character));
38010d50 447 PRINTFINISH;
3738a371 448 return character;
38010d50
JB
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{
081e0581 459 PRINTDECLARE;
38010d50 460 Lisp_Object printcharfun;
38010d50
JB
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{
081e0581 478 PRINTDECLARE;
38010d50
JB
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
2a1c968a 497 current_buffer->directory = old->directory;
38010d50
JB
498 current_buffer->read_only = Qnil;
499 Ferase_buffer ();
500
633307b5 501 XSETBUFFER (buf, current_buffer);
38010d50
JB
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;
0ab39c81 515 struct gcpro gcpro1;
38010d50 516
0ab39c81 517 GCPRO1 (args);
38010d50
JB
518 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
519 temp_output_buffer_setup (bufname);
520 buf = Vstandard_output;
0ab39c81 521 UNGCPRO;
38010d50
JB
522
523 val = (*function) (args);
524
0ab39c81 525 GCPRO1 (val);
38010d50 526 temp_output_buffer_show (buf);
0ab39c81 527 UNGCPRO;
38010d50
JB
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\
483288d7 540If variable `temp-buffer-show-function' is non-nil, call it at the end\n\
38010d50
JB
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,
57c9eb68
KH
569 "Output a newline to stream PRINTCHARFUN.\n\
570If PRINTCHARFUN is omitted or nil, the value of `standard-output' is used.")
38010d50
JB
571 (printcharfun)
572 Lisp_Object printcharfun;
573{
081e0581 574 PRINTDECLARE;
38010d50 575
10eebdbb 576 if (NILP (printcharfun))
38010d50
JB
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\
57c9eb68 588Output stream is PRINTCHARFUN, or value of `standard-output' (which see).")
3738a371
EN
589 (object, printcharfun)
590 Lisp_Object object, printcharfun;
38010d50 591{
081e0581 592 PRINTDECLARE;
38010d50
JB
593
594#ifdef MAX_PRINT_CHARS
595 max_print = 0;
596#endif /* MAX_PRINT_CHARS */
10eebdbb 597 if (NILP (printcharfun))
38010d50
JB
598 printcharfun = Vstandard_output;
599 PRINTPREPARE;
600 print_depth = 0;
3738a371 601 print (object, printcharfun, 1);
38010d50 602 PRINTFINISH;
3738a371 603 return object;
38010d50
JB
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.")
3738a371
EN
614 (object, noescape)
615 Lisp_Object object, noescape;
38010d50 616{
081e0581
EN
617 PRINTDECLARE;
618 Lisp_Object printcharfun;
2a42e8f6
KH
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);
38010d50
JB
627
628 printcharfun = Vprin1_to_string_buffer;
629 PRINTPREPARE;
630 print_depth = 0;
3738a371 631 print (object, printcharfun, NILP (noescape));
38010d50
JB
632 /* Make Vprin1_to_string_buffer be the default buffer after PRINTFINSH */
633 PRINTFINISH;
634 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
3738a371 635 object = Fbuffer_string ();
38010d50 636
38010d50
JB
637 Ferase_buffer ();
638 set_buffer_internal (old);
2a42e8f6
KH
639
640 Vdeactivate_mark = tem;
38010d50
JB
641 UNGCPRO;
642
3738a371 643 return object;
38010d50
JB
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\
57c9eb68 650Output stream is PRINTCHARFUN, or value of standard-output (which see).")
3738a371
EN
651 (object, printcharfun)
652 Lisp_Object object, printcharfun;
38010d50 653{
081e0581 654 PRINTDECLARE;
38010d50 655
10eebdbb 656 if (NILP (printcharfun))
38010d50
JB
657 printcharfun = Vstandard_output;
658 PRINTPREPARE;
659 print_depth = 0;
3738a371 660 print (object, printcharfun, 0);
38010d50 661 PRINTFINISH;
3738a371 662 return object;
38010d50
JB
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\
57c9eb68 669Output stream is PRINTCHARFUN, or value of `standard-output' (which see).")
3738a371
EN
670 (object, printcharfun)
671 Lisp_Object object, printcharfun;
38010d50 672{
081e0581 673 PRINTDECLARE;
38010d50
JB
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 */
10eebdbb 680 if (NILP (printcharfun))
38010d50 681 printcharfun = Vstandard_output;
3738a371 682 GCPRO1 (object);
38010d50
JB
683 PRINTPREPARE;
684 print_depth = 0;
685 PRINTCHAR ('\n');
3738a371 686 print (object, printcharfun, 1);
38010d50
JB
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;
3738a371 694 return object;
38010d50
JB
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
4746118a
JB
701DEFUN ("external-debugging-output", Fexternal_debugging_output, Sexternal_debugging_output, 1, 1, 0,
702 "Write CHARACTER to stderr.\n\
38010d50
JB
703You can call print while debugging emacs, and pass it this function\n\
704to make it write to the debugging output.\n")
4746118a
JB
705 (character)
706 Lisp_Object character;
38010d50
JB
707{
708 CHECK_NUMBER (character, 0);
709 putc (XINT (character), stderr);
710
711 return character;
712}
cf1bb91b
RS
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);
3684eb78 721 fprintf (stderr, "\r\n");
cf1bb91b 722}
38010d50 723\f
113620cc
KH
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
0872e11f
RS
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
113620cc
KH
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
38010d50
JB
808#ifdef LISP_FLOAT_TYPE
809
38010d50 810/*
edb2a707 811 * The buffer should be at least as large as the max string size of the
8e6208c5 812 * largest float, printed in the biggest notation. This is undoubtedly
38010d50
JB
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 */
edb2a707
RS
823
824void
825float_to_string (buf, data)
8b24d146 826 unsigned char *buf;
38010d50
JB
827 double data;
828{
c7b14277 829 unsigned char *cp;
322890c4 830 int width;
38010d50 831
10eebdbb 832 if (NILP (Vfloat_output_format)
d4ae1f7e 833 || !STRINGP (Vfloat_output_format))
38010d50 834 lose:
322890c4
RS
835 {
836 sprintf (buf, "%.17g", data);
837 width = -1;
838 }
38010d50
JB
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;
c7b14277
JB
852
853 /* Check the width specification. */
322890c4 854 width = -1;
c7b14277 855 if ('0' <= *cp && *cp <= '9')
381cd4bb
KH
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 }
38010d50
JB
867
868 if (*cp != 'e' && *cp != 'f' && *cp != 'g')
869 goto lose;
870
38010d50
JB
871 if (cp[1] != 0)
872 goto lose;
873
874 sprintf (buf, XSTRING (Vfloat_output_format)->data, data);
875 }
edb2a707 876
c7b14277
JB
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
322890c4
RS
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)
0601fd3d 882 {
c7b14277
JB
883 for (cp = buf; *cp; cp++)
884 if ((*cp < '0' || *cp > '9') && *cp != '-')
885 break;
0601fd3d 886
c7b14277
JB
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 }
edb2a707 899 }
38010d50
JB
900}
901#endif /* LISP_FLOAT_TYPE */
902\f
903static void
904print (obj, printcharfun, escapeflag)
38010d50 905 Lisp_Object obj;
38010d50
JB
906 register Lisp_Object printcharfun;
907 int escapeflag;
908{
909 char buf[30];
910
911 QUIT;
912
ec838c39
RS
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. */
d4ae1f7e 916 if (CONSP (obj) || VECTORP (obj) || COMPILEDP (obj))
ec838c39
RS
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;
38010d50
JB
930 print_depth++;
931
ec838c39 932 if (print_depth > PRINT_CIRCLE)
38010d50
JB
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
ca0569ad 942 switch (XGCTYPE (obj))
38010d50 943 {
ca0569ad 944 case Lisp_Int:
b8180922
RS
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 ();
38010d50 951 strout (buf, -1, printcharfun);
ca0569ad
RS
952 break;
953
e0f93814 954#ifdef LISP_FLOAT_TYPE
ca0569ad
RS
955 case Lisp_Float:
956 {
957 char pigbuf[350]; /* see comments in float_to_string */
38010d50 958
ca0569ad
RS
959 float_to_string (pigbuf, XFLOAT(obj)->data);
960 strout (pigbuf, -1, printcharfun);
961 }
962 break;
e0f93814 963#endif
ca0569ad
RS
964
965 case Lisp_String:
38010d50
JB
966 if (!escapeflag)
967 print_string (obj, printcharfun);
968 else
969 {
970 register int i;
971 register unsigned char c;
38010d50
JB
972 struct gcpro gcpro1;
973
7651e1f5
RS
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
38010d50
JB
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 }
c6f7982f
RM
994 else if (c == '\f' && print_escape_newlines)
995 {
996 PRINTCHAR ('\\');
997 PRINTCHAR ('f');
998 }
38010d50
JB
999 else
1000 {
1001 if (c == '\"' || c == '\\')
1002 PRINTCHAR ('\\');
1003 PRINTCHAR (c);
1004 }
1005 }
1006 PRINTCHAR ('\"');
7651e1f5
RS
1007
1008#ifdef USE_TEXT_PROPERTIES
1009 if (!NULL_INTERVAL_P (XSTRING (obj)->intervals))
1010 {
7651e1f5
RS
1011 traverse_intervals (XSTRING (obj)->intervals,
1012 0, 0, print_interval, printcharfun);
1013 PRINTCHAR (')');
1014 }
1015#endif
1016
38010d50
JB
1017 UNGCPRO;
1018 }
ca0569ad 1019 break;
38010d50 1020
ca0569ad
RS
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;
09eddb56 1027 int i;
ca0569ad
RS
1028
1029 if (p != end && (*p == '-' || *p == '+')) p++;
1030 if (p == end)
1031 confusing = 0;
d27497e3
RS
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')
ca0569ad 1041 {
e837058b
RS
1042 while (p != end && ((*p >= '0' && *p <= '9')
1043 /* Needed for \2e10. */
1044 || *p == 'e'))
ca0569ad
RS
1045 p++;
1046 confusing = (end == p);
1047 }
d27497e3
RS
1048 else
1049 confusing = 0;
ca0569ad 1050
081e0581
EN
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. */
e0f69431 1054 if (! NILP (Vprint_gensym) && NILP (XSYMBOL (obj)->obarray))
081e0581
EN
1055 {
1056 if (print_depth > 1)
1057 {
1058 Lisp_Object tem;
e0f69431 1059 tem = Fassq (obj, Vprint_gensym_alist);
081e0581
EN
1060 if (CONSP (tem))
1061 {
1062 PRINTCHAR ('#');
1063 print (XCDR (tem), printcharfun, escapeflag);
1064 PRINTCHAR ('#');
1065 break;
1066 }
1067 else
1068 {
e0f69431
RS
1069 if (CONSP (Vprint_gensym_alist))
1070 XSETFASTINT (tem, XFASTINT (XCDR (XCAR (Vprint_gensym_alist))) + 1);
081e0581
EN
1071 else
1072 XSETFASTINT (tem, 1);
e0f69431 1073 Vprint_gensym_alist = Fcons (Fcons (obj, tem), Vprint_gensym_alist);
081e0581
EN
1074
1075 PRINTCHAR ('#');
1076 print (tem, printcharfun, escapeflag);
1077 PRINTCHAR ('=');
1078 }
1079 }
1080 PRINTCHAR ('#');
1081 PRINTCHAR (':');
1082 }
1083
09eddb56 1084 for (i = 0; i < XSYMBOL (obj)->name->size; i++)
ca0569ad
RS
1085 {
1086 QUIT;
09eddb56
RS
1087 c = XSYMBOL (obj)->name->data[i];
1088
ca0569ad
RS
1089 if (escapeflag)
1090 {
09eddb56
RS
1091 if (c == '\"' || c == '\\' || c == '\''
1092 || c == ';' || c == '#' || c == '(' || c == ')'
1093 || c == ',' || c =='.' || c == '`'
1094 || c == '[' || c == ']' || c == '?' || c <= 040
1095 || confusing)
ca0569ad
RS
1096 PRINTCHAR ('\\'), confusing = 0;
1097 }
1098 PRINTCHAR (c);
1099 }
1100 }
1101 break;
1102
1103 case Lisp_Cons:
38010d50 1104 /* If deeper than spec'd depth, print placeholder. */
d4ae1f7e 1105 if (INTEGERP (Vprint_level)
38010d50 1106 && print_depth > XINT (Vprint_level))
e0f93814 1107 strout ("...", -1, printcharfun);
2f100b5c
EN
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 }
e0f93814 1130 else
38010d50 1131 {
e0f93814 1132 PRINTCHAR ('(');
38010d50 1133 {
e0f93814
KH
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))
38010d50 1143 {
e0f93814
KH
1144 if (i++)
1145 PRINTCHAR (' ');
1146 if (max && i > max)
1147 {
1148 strout ("...", 3, printcharfun);
1149 break;
1150 }
2f100b5c
EN
1151 print (XCAR (obj), printcharfun, escapeflag);
1152 obj = XCDR (obj);
38010d50 1153 }
38010d50 1154 }
2f100b5c 1155 if (!NILP (obj))
e0f93814
KH
1156 {
1157 strout (" . ", 3, printcharfun);
1158 print (obj, printcharfun, escapeflag);
1159 }
1160 PRINTCHAR (')');
38010d50 1161 }
ca0569ad
RS
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 }
ed2c35ef
RS
1176 else if (BOOL_VECTOR_P (obj))
1177 {
1178 register int i;
1179 register unsigned char c;
1180 struct gcpro gcpro1;
ed2c35ef 1181 int size_in_chars
1bad7c59 1182 = (XBOOL_VECTOR (obj)->size + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
ed2c35ef
RS
1183
1184 GCPRO1 (obj);
1185
1186 PRINTCHAR ('#');
1187 PRINTCHAR ('&');
1188 sprintf (buf, "%d", XBOOL_VECTOR (obj)->size);
1189 strout (buf, -1, printcharfun);
1190 PRINTCHAR ('\"');
a40384bc
RS
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
ed2c35ef
RS
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 }
ca0569ad
RS
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 }
908b0ae5
RS
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 }
ca0569ad
RS
1254 else if (WINDOW_CONFIGURATIONP (obj))
1255 {
1256 strout ("#<window-configuration>", -1, printcharfun);
1257 }
ca0569ad
RS
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 }
ca0569ad
RS
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 }
ed2c35ef
RS
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 ('^');
3701b5de
KH
1284 if (SUB_CHAR_TABLE_P (obj))
1285 PRINTCHAR ('^');
ed2c35ef
RS
1286 size &= PSEUDOVECTOR_SIZE_MASK;
1287 }
00d76abc
KH
1288 if (size & PSEUDOVECTOR_FLAG)
1289 goto badtype;
ca0569ad
RS
1290
1291 PRINTCHAR ('[');
38010d50 1292 {
ca0569ad
RS
1293 register int i;
1294 register Lisp_Object tem;
a40384bc
RS
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
ca0569ad
RS
1301 for (i = 0; i < size; i++)
1302 {
1303 if (i) PRINTCHAR (' ');
1304 tem = XVECTOR (obj)->contents[i];
1305 print (tem, printcharfun, escapeflag);
1306 }
38010d50 1307 }
ca0569ad
RS
1308 PRINTCHAR (']');
1309 }
1310 break;
1311
38010d50 1312#ifndef standalone
ca0569ad 1313 case Lisp_Misc:
5db20f08 1314 switch (XMISCTYPE (obj))
38010d50 1315 {
00d76abc 1316 case Lisp_Misc_Marker:
ca0569ad 1317 strout ("#<marker ", -1, printcharfun);
087e3c46
KH
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 */
ca0569ad
RS
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 }
38010d50 1332 PRINTCHAR ('>');
908b0ae5 1333 break;
00d76abc
KH
1334
1335 case Lisp_Misc_Overlay:
ca0569ad
RS
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 ('>');
908b0ae5 1349 break;
00d76abc
KH
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:
f7779190 1369 strout ("#<objfwd to ", -1, printcharfun);
00d76abc
KH
1370 print (*XOBJFWD (obj)->objvar, printcharfun, escapeflag);
1371 PRINTCHAR ('>');
1372 break;
1373
1374 case Lisp_Misc_Buffer_Objfwd:
f7779190 1375 strout ("#<buffer_objfwd to ", -1, printcharfun);
3ac613c1
KH
1376 print (*(Lisp_Object *)((char *)current_buffer
1377 + XBUFFER_OBJFWD (obj)->offset),
1378 printcharfun, escapeflag);
1379 PRINTCHAR ('>');
1380 break;
1381
fb917148 1382 case Lisp_Misc_Kboard_Objfwd:
f7779190 1383 strout ("#<kboard_objfwd to ", -1, printcharfun);
fb917148
KH
1384 print (*(Lisp_Object *)((char *) current_kboard
1385 + XKBOARD_OBJFWD (obj)->offset),
7ae137a9 1386 printcharfun, escapeflag);
00d76abc
KH
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;
e0f93814 1412 }
00d76abc 1413 break;
38010d50 1414#endif /* standalone */
ca0569ad
RS
1415
1416 default:
00d76abc 1417 badtype:
ca0569ad
RS
1418 {
1419 /* We're in trouble if this happens!
1420 Probably should just abort () */
1421 strout ("#<EMACS BUG: INVALID DATATYPE ", -1, printcharfun);
00d76abc 1422 if (MISCP (obj))
5db20f08 1423 sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj));
00d76abc
KH
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));
ca0569ad
RS
1428 strout (buf, -1, printcharfun);
1429 strout (" Save your buffers immediately and please report this bug>",
1430 -1, printcharfun);
1431 }
38010d50
JB
1432 }
1433
1434 print_depth--;
1435}
1436\f
7651e1f5
RS
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{
30503c0b 1447 PRINTCHAR (' ');
7651e1f5
RS
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);
7651e1f5
RS
1454}
1455
1456#endif /* USE_TEXT_PROPERTIES */
1457\f
38010d50
JB
1458void
1459syms_of_print ()
1460{
38010d50
JB
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\
113620cc 1466or the symbol t (output appears in the echo area).");
38010d50
JB
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,
06ef7355 1473 "The format descriptor string used to print floats.\n\
38010d50
JB
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\
c7b14277 1484decimal point. 0 is not allowed with `e' or `g'.\n\n\
322890c4 1485A value of nil means to use `%.17g'.");
38010d50
JB
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,
aa734e17 1492 "Maximum length of list to print before abbreviating.\n\
38010d50
JB
1493A value of nil means no limit.");
1494 Vprint_length = Qnil;
1495
1496 DEFVAR_LISP ("print-level", &Vprint_level,
aa734e17 1497 "Maximum depth of list nesting to print before abbreviating.\n\
38010d50
JB
1498A value of nil means no limit.");
1499 Vprint_level = Qnil;
1500
1501 DEFVAR_BOOL ("print-escape-newlines", &print_escape_newlines,
a8920a17 1502 "Non-nil means print newlines in strings as backslash-n.\n\
c6f7982f 1503Also print formfeeds as backslash-f.");
38010d50
JB
1504 print_escape_newlines = 0;
1505
2f100b5c
EN
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
e0f69431 1512 DEFVAR_LISP ("print-gensym", &Vprint_gensym,
081e0581 1513 "Non-nil means print uninterned symbols so they will read as uninterned.\n\
e0f69431
RS
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;
081e0581 1531
38010d50
JB
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);
113620cc 1537 defsubr (&Serror_message_string);
38010d50
JB
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
2f100b5c
EN
1547 Qprint_escape_newlines = intern ("print-escape-newlines");
1548 staticpro (&Qprint_escape_newlines);
1549
38010d50
JB
1550#ifndef standalone
1551 defsubr (&Swith_output_to_temp_buffer);
1552#endif /* not standalone */
1553}