BSD 4_4 development
[unix-history] / usr / src / contrib / emacs-18.57 / src / print.c
CommitLineData
cd689596
C
1/* Lisp object printing and output streams.
2 Copyright (C) 1985, 1986, 1990 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include <stdio.h>
23#undef NULL
24#include "lisp.h"
25
26#ifndef standalone
27#include "buffer.h"
28#include "window.h"
29#include "process.h"
30#include "dispextern.h"
31#include "termchar.h"
32#endif /* not standalone */
33
34Lisp_Object Vstandard_output, Qstandard_output;
35
36/* Avoid actual stack overflow in print. */
37int print_depth;
38
39/* Maximum length of list to print in full; noninteger means
40 effectively infinity */
41
42Lisp_Object Vprint_length;
43
44/* Nonzero means print newlines in strings as \n. */
45
46int print_escape_newlines;
47
48/* Nonzero means print newline before next minibuffer message.
49 Defined in xdisp.c */
50
51extern int noninteractive_need_newline;
52#ifdef MAX_PRINT_CHARS
53static int print_chars;
54static int max_print;
55#endif /* MAX_PRINT_CHARS */
56\f
57/* Low level output routines for charaters and strings */
58
59/* Lisp functions to do output using a stream
60 must have the stream in a variable called printcharfun
61 and must start with PRINTPREPARE and end with PRINTFINISH.
62 Use PRINTCHAR to output one character,
63 or call strout to output a block of characters.
64 Also, each one must have the declarations
65 struct buffer *old = current_buffer;
66 int old_point = -1, start_point;
67 Lisp_Object original;
68*/
69
70#define PRINTPREPARE \
71 original = printcharfun; \
72 if (NULL (printcharfun)) printcharfun = Qt; \
73 if (XTYPE (printcharfun) == Lisp_Buffer) \
74 { if (XBUFFER (printcharfun) != current_buffer) Fset_buffer (printcharfun); \
75 printcharfun = Qnil;}\
76 if (XTYPE (printcharfun) == Lisp_Marker) \
77 { if (XMARKER (original)->buffer != current_buffer) \
78 set_buffer_internal (XMARKER (original)->buffer); \
79 old_point = point; \
80 SET_PT (marker_position (printcharfun)); \
81 start_point = point; \
82 printcharfun = Qnil;}
83
84#define PRINTFINISH \
85 if (XTYPE (original) == Lisp_Marker) \
86 Fset_marker (original, make_number (point), Qnil); \
87 if (old_point >= 0) \
88 SET_PT ((old_point >= start_point ? point - start_point : 0) + old_point); \
89 if (old != current_buffer) \
90 set_buffer_internal (old)
91
92#define PRINTCHAR(ch) printchar (ch, printcharfun)
93
94/* Index of first unused element of message_buf. */
95static int printbufidx;
96
97static void
98printchar (ch, fun)
99 unsigned char ch;
100 Lisp_Object fun;
101{
102 Lisp_Object ch1;
103
104#ifdef MAX_PRINT_CHARS
105 if (max_print)
106 print_chars++;
107#endif /* MAX_PRINT_CHARS */
108#ifndef standalone
109 if (EQ (fun, Qnil))
110 {
111 QUIT;
112 insert (&ch, 1);
113 return;
114 }
115 if (EQ (fun, Qt))
116 {
117 if (noninteractive)
118 {
119 putchar (ch);
120 noninteractive_need_newline = 1;
121 return;
122 }
123 if (echo_area_contents != message_buf)
124 echo_area_contents = message_buf, printbufidx = 0;
125 if (printbufidx < screen_width)
126 message_buf[printbufidx++] = ch;
127 message_buf[printbufidx] = 0;
128 return;
129 }
130#endif /* not standalone */
131
132 XFASTINT (ch1) = ch;
133 call1 (fun, ch1);
134}
135
136static void
137strout (ptr, size, printcharfun)
138 char *ptr;
139 int size;
140 Lisp_Object printcharfun;
141{
142 int i = 0;
143
144 if (EQ (printcharfun, Qnil))
145 {
146 insert (ptr, size >= 0 ? size : strlen (ptr));
147#ifdef MAX_PRINT_CHARS
148 if (max_print)
149 print_chars += size >= 0 ? size : strlen(ptr);
150#endif /* MAX_PRINT_CHARS */
151 return;
152 }
153 if (EQ (printcharfun, Qt))
154 {
155 i = size >= 0 ? size : strlen (ptr);
156#ifdef MAX_PRINT_CHARS
157 if (max_print)
158 print_chars += i;
159#endif /* MAX_PRINT_CHARS */
160 if (noninteractive)
161 {
162 fwrite (ptr, 1, i, stdout);
163 noninteractive_need_newline = 1;
164 return;
165 }
166 if (echo_area_contents != message_buf)
167 echo_area_contents = message_buf, printbufidx = 0;
168 if (i > screen_width - printbufidx)
169 i = screen_width - printbufidx;
170 bcopy (ptr, &message_buf[printbufidx], i);
171 printbufidx += i;
172 message_buf[printbufidx] = 0;
173 return;
174 }
175 if (size >= 0)
176 while (i < size)
177 PRINTCHAR (ptr[i++]);
178 else
179 while (ptr[i])
180 PRINTCHAR (ptr[i++]);
181}
182\f
183DEFUN ("write-char", Fwrite_char, Swrite_char, 1, 2, 0,
184 "Output character CHAR to stream STREAM.\n\
185STREAM defaults to the value of `standard-output' (which see).")
186 (ch, printcharfun)
187 Lisp_Object ch, printcharfun;
188{
189 struct buffer *old = current_buffer;
190 int old_point = -1;
191 int start_point;
192 Lisp_Object original;
193
194 if (NULL (printcharfun))
195 printcharfun = Vstandard_output;
196 CHECK_NUMBER (ch, 0);
197 PRINTPREPARE;
198 PRINTCHAR (XINT (ch));
199 PRINTFINISH;
200 return ch;
201}
202
203write_string (data, size)
204 char *data;
205 int size;
206{
207 struct buffer *old = current_buffer;
208 Lisp_Object printcharfun;
209 int old_point = -1;
210 int start_point;
211 Lisp_Object original;
212
213 printcharfun = Vstandard_output;
214
215 PRINTPREPARE;
216 strout (data, size, printcharfun);
217 PRINTFINISH;
218}
219
220write_string_1 (data, size, printcharfun)
221 char *data;
222 int size;
223 Lisp_Object printcharfun;
224{
225 struct buffer *old = current_buffer;
226 int old_point = -1;
227 int start_point;
228 Lisp_Object original;
229
230 PRINTPREPARE;
231 strout (data, size, printcharfun);
232 PRINTFINISH;
233}
234
235
236#ifndef standalone
237
238temp_output_buffer_setup (bufname)
239 char *bufname;
240{
241 register struct buffer *old = current_buffer;
242 register Lisp_Object buf;
243
244 Fset_buffer (Fget_buffer_create (build_string (bufname)));
245
246 current_buffer->read_only = Qnil;
247 Ferase_buffer ();
248
249 XSET (buf, Lisp_Buffer, current_buffer);
250 specbind (Qstandard_output, buf);
251
252 set_buffer_internal (old);
253}
254
255Lisp_Object
256internal_with_output_to_temp_buffer (bufname, function, args)
257 char *bufname;
258 Lisp_Object (*function) ();
259 Lisp_Object args;
260{
261 int count = specpdl_ptr - specpdl;
262 Lisp_Object buf, val;
263
264 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
265 temp_output_buffer_setup (bufname);
266 buf = Vstandard_output;
267
268 val = (*function) (args);
269
270 temp_output_buffer_show (buf);
271
272 unbind_to (count);
273 return val;
274}
275
276DEFUN ("with-output-to-temp-buffer", Fwith_output_to_temp_buffer, Swith_output_to_temp_buffer,
277 1, UNEVALLED, 0,
278 "Binding `standard-output' to buffer named BUFNAME, execute BODY then display that buffer.\n\
279The buffer is cleared out initially, and marked as unmodified when done.\n\
280All output done by BODY is inserted in that buffer by default.\n\
281It is displayed in another window, but not selected.\n\
282The value of the last form in BODY is returned.\n\
283If variable `temp-buffer-show-hook' is non-nil, call it at the end\n\
284to get the buffer displayed. It gets one argument, the buffer to display.")
285 (args)
286 Lisp_Object args;
287{
288 struct gcpro gcpro1;
289 Lisp_Object name;
290 int count = specpdl_ptr - specpdl;
291 Lisp_Object buf, val;
292
293 GCPRO1(args);
294 name = Feval (Fcar (args));
295 UNGCPRO;
296
297 CHECK_STRING (name, 0);
298 temp_output_buffer_setup (XSTRING (name)->data);
299 buf = Vstandard_output;
300
301 val = Fprogn (Fcdr (args));
302
303 temp_output_buffer_show (buf);
304
305 unbind_to (count);
306 return val;
307}
308#endif /* not standalone */
309\f
310static void print ();
311
312DEFUN ("terpri", Fterpri, Sterpri, 0, 1, 0,
313 "Output a newline to STREAM (or value of standard-output).")
314 (printcharfun)
315 Lisp_Object printcharfun;
316{
317 struct buffer *old = current_buffer;
318 int old_point = -1;
319 int start_point;
320 Lisp_Object original;
321
322 if (NULL (printcharfun))
323 printcharfun = Vstandard_output;
324 PRINTPREPARE;
325 PRINTCHAR ('\n');
326 PRINTFINISH;
327 return Qt;
328}
329
330DEFUN ("prin1", Fprin1, Sprin1, 1, 2, 0,
331 "Output the printed representation of OBJECT, any Lisp object.\n\
332Quoting characters are printed when needed to make output that `read'\n\
333can handle, whenever this is possible.\n\
334Output stream is STREAM, or value of `standard-output' (which see).")
335 (obj, printcharfun)
336 Lisp_Object obj, printcharfun;
337{
338 struct buffer *old = current_buffer;
339 int old_point = -1;
340 int start_point;
341 Lisp_Object original;
342
343#ifdef MAX_PRINT_CHARS
344 max_print = 0;
345#endif /* MAX_PRINT_CHARS */
346 if (NULL (printcharfun))
347 printcharfun = Vstandard_output;
348 PRINTPREPARE;
349 print_depth = 0;
350 print (obj, printcharfun, 1);
351 PRINTFINISH;
352 return obj;
353}
354
355/* a buffer which is used to hold output being built by prin1-to-string */
356Lisp_Object Vprin1_to_string_buffer;
357
358DEFUN ("prin1-to-string", Fprin1_to_string, Sprin1_to_string, 1, 1, 0,
359 "Return a string containing the printed representation of OBJECT,\n\
360any Lisp object. Quoting characters are used when needed to make output\n\
361that `read' can handle, whenever this is possible.")
362 (obj)
363 Lisp_Object obj;
364{
365 struct buffer *old = current_buffer;
366 int old_point = -1;
367 int start_point;
368 Lisp_Object original, printcharfun;
369 struct gcpro gcpro1;
370
371 printcharfun = Vprin1_to_string_buffer;
372 PRINTPREPARE;
373 print_depth = 0;
374 print (obj, printcharfun, 1);
375 /* Make Vprin1_to_string_buffer be the default buffer after PRINTFINSH */
376 PRINTFINISH;
377 set_buffer_internal (XBUFFER (Vprin1_to_string_buffer));
378 obj = Fbuffer_string ();
379 GCPRO1 (obj);
380 Ferase_buffer ();
381 set_buffer_internal (old);
382 UNGCPRO;
383 return obj;
384}
385
386DEFUN ("princ", Fprinc, Sprinc, 1, 2, 0,
387 "Output the printed representation of OBJECT, any Lisp object.\n\
388No quoting characters are used; no delimiters are printed around\n\
389the contents of strings.\n\
390Output stream is STREAM, or value of standard-output (which see).")
391 (obj, printcharfun)
392 Lisp_Object obj, printcharfun;
393{
394 struct buffer *old = current_buffer;
395 int old_point = -1;
396 int start_point;
397 Lisp_Object original;
398
399 if (NULL (printcharfun))
400 printcharfun = Vstandard_output;
401 PRINTPREPARE;
402 print_depth = 0;
403 print (obj, printcharfun, 0);
404 PRINTFINISH;
405 return obj;
406}
407
408DEFUN ("print", Fprint, Sprint, 1, 2, 0,
409 "Output the printed representation of OBJECT, with newlines around it.\n\
410Quoting characters are printed when needed to make output that `read'\n\
411can handle, whenever this is possible.\n\
412Output stream is STREAM, or value of `standard-output' (which see).")
413 (obj, printcharfun)
414 Lisp_Object obj, printcharfun;
415{
416 struct buffer *old = current_buffer;
417 int old_point = -1;
418 int start_point;
419 Lisp_Object original;
420 struct gcpro gcpro1;
421
422#ifdef MAX_PRINT_CHARS
423 print_chars = 0;
424 max_print = MAX_PRINT_CHARS;
425#endif /* MAX_PRINT_CHARS */
426 if (NULL (printcharfun))
427 printcharfun = Vstandard_output;
428 GCPRO1 (obj);
429 PRINTPREPARE;
430 print_depth = 0;
431 PRINTCHAR ('\n');
432 print (obj, printcharfun, 1);
433 PRINTCHAR ('\n');
434 PRINTFINISH;
435#ifdef MAX_PRINT_CHARS
436 max_print = 0;
437 print_chars = 0;
438#endif /* MAX_PRINT_CHARS */
439 UNGCPRO;
440 return obj;
441}
442\f
443static void
444print (obj, printcharfun, escapeflag)
445#ifndef RTPC_REGISTER_BUG
446 register Lisp_Object obj;
447#else
448 Lisp_Object obj;
449#endif
450 register Lisp_Object printcharfun;
451 int escapeflag;
452{
453 char buf[30];
454
455 QUIT;
456
457 print_depth++;
458 if (print_depth > 200)
459 error ("Apparently circular structure being printed");
460#ifdef MAX_PRINT_CHARS
461 if (max_print && print_chars > max_print)
462 {
463 PRINTCHAR ('\n');
464 print_chars = 0;
465 }
466#endif /* MAX_PRINT_CHARS */
467
468#ifdef SWITCH_ENUM_BUG
469 switch ((int) XTYPE (obj))
470#else
471 switch (XTYPE (obj))
472#endif
473 {
474 default:
475 /* We're in trouble if this happens!
476 Probably should just abort () */
477 strout ("#<EMACS BUG: INVALID DATATYPE ", -1, printcharfun);
478 sprintf (buf, "(#o%3o)", (int) XTYPE (obj));
479 strout (buf, -1, printcharfun);
480 strout (" Save your buffers immediately and please report this bug>",
481 -1, printcharfun);
482 break;
483
484 case Lisp_Int:
485 sprintf (buf, "%d", XINT (obj));
486 strout (buf, -1, printcharfun);
487 break;
488
489 case Lisp_String:
490 if (!escapeflag)
491 strout (XSTRING (obj)->data, XSTRING (obj)->size, printcharfun);
492 else
493 {
494 register int i;
495 register unsigned char *p = XSTRING (obj)->data;
496 register unsigned char c;
497
498 PRINTCHAR ('\"');
499 for (i = XSTRING (obj)->size; i > 0; i--)
500 {
501 QUIT;
502 c = *p++;
503 if (c == '\n' && print_escape_newlines)
504 {
505 PRINTCHAR ('\\');
506 PRINTCHAR ('n');
507 }
508 else
509 {
510 if (c == '\"' || c == '\\')
511 PRINTCHAR ('\\');
512 PRINTCHAR (c);
513 }
514 }
515 PRINTCHAR ('\"');
516 }
517 break;
518
519 case Lisp_Symbol:
520 {
521 register int confusing;
522 register unsigned char *p = XSYMBOL (obj)->name->data;
523 register unsigned char *end = p + XSYMBOL (obj)->name->size;
524 register unsigned char c;
525
526 if (p != end && (*p == '-' || *p == '+')) p++;
527 if (p == end)
528 confusing = 0;
529 else
530 {
531 while (p != end && *p >= '0' && *p <= '9')
532 p++;
533 confusing = (end == p);
534 }
535
536 p = XSYMBOL (obj)->name->data;
537 while (p != end)
538 {
539 QUIT;
540 c = *p++;
541 if (escapeflag)
542 {
543 if (c == '\"' || c == '\\' || c == '\'' || c == ';' || c == '#' ||
544 c == '(' || c == ')' || c == ',' || c =='.' || c == '`' ||
545 c == '[' || c == ']' || c == '?' || c <= 040 || confusing)
546 PRINTCHAR ('\\'), confusing = 0;
547 }
548 PRINTCHAR (c);
549 }
550 }
551 break;
552
553 case Lisp_Cons:
554 PRINTCHAR ('(');
555 {
556 register int i = 0;
557 register int max = 0;
558
559 if (XTYPE (Vprint_length) == Lisp_Int)
560 max = XINT (Vprint_length);
561 while (CONSP (obj))
562 {
563 if (i++)
564 PRINTCHAR (' ');
565 if (max && i > max)
566 {
567 strout ("...", 3, printcharfun);
568 break;
569 }
570 print (Fcar (obj), printcharfun, escapeflag);
571 obj = Fcdr (obj);
572 }
573 }
574 if (!NULL (obj) && !CONSP (obj))
575 {
576 strout (" . ", 3, printcharfun);
577 print (obj, printcharfun, escapeflag);
578 }
579 PRINTCHAR (')');
580 break;
581
582 case Lisp_Vector:
583 PRINTCHAR ('[');
584 {
585 register int i;
586 register Lisp_Object tem;
587 for (i = 0; i < XVECTOR (obj)->size; i++)
588 {
589 if (i) PRINTCHAR (' ');
590 tem = XVECTOR (obj)->contents[i];
591 print (tem, printcharfun, escapeflag);
592 }
593 }
594 PRINTCHAR (']');
595 break;
596
597#ifndef standalone
598 case Lisp_Buffer:
599 if (NULL (XBUFFER (obj)->name))
600 strout ("#<killed buffer>", -1, printcharfun);
601 else if (escapeflag)
602 {
603 strout ("#<buffer ", -1, printcharfun);
604 strout (XSTRING (XBUFFER (obj)->name)->data, -1, printcharfun);
605 PRINTCHAR ('>');
606 }
607 else
608 strout (XSTRING (XBUFFER (obj)->name)->data, -1, printcharfun);
609 break;
610
611 case Lisp_Process:
612 if (escapeflag)
613 {
614 strout ("#<process ", -1, printcharfun);
615 strout (XSTRING (XPROCESS (obj)->name)->data, -1, printcharfun);
616 PRINTCHAR ('>');
617 }
618 else
619 strout (XSTRING (XPROCESS (obj)->name)->data, -1, printcharfun);
620 break;
621
622 case Lisp_Window:
623 strout ("#<window ", -1, printcharfun);
624 sprintf (buf, "%d", XFASTINT (XWINDOW (obj)->sequence_number));
625 strout (buf, -1, printcharfun);
626 if (!NULL (XWINDOW (obj)->buffer))
627 {
628 unsigned char *p = XSTRING (XBUFFER (XWINDOW (obj)->buffer)->name)->data;
629 strout (" on ", -1, printcharfun);
630 strout (p, -1, printcharfun);
631 }
632 PRINTCHAR ('>');
633 break;
634
635 case Lisp_Window_Configuration:
636 strout ("#<window-configuration>", -1, printcharfun);
637 break;
638
639 case Lisp_Marker:
640 strout ("#<marker ", -1, printcharfun);
641 if (!(XMARKER (obj)->buffer))
642 strout ("in no buffer", -1, printcharfun);
643 else
644 {
645 sprintf (buf, "at %d", marker_position (obj));
646 strout (buf, -1, printcharfun);
647 strout (" in ", -1, printcharfun);
648 strout (XSTRING (XMARKER (obj)->buffer->name)->data, -1, printcharfun);
649 }
650 PRINTCHAR ('>');
651 break;
652#endif /* standalone */
653
654 case Lisp_Subr:
655 strout ("#<subr ", -1, printcharfun);
656 strout (XSUBR (obj)->symbol_name, -1, printcharfun);
657 PRINTCHAR ('>');
658 break;
659 }
660
661 print_depth--;
662}
663\f
664void
665syms_of_print ()
666{
667 DEFVAR_LISP ("standard-output", &Vstandard_output,
668 "Function print uses by default for outputting a character.\n\
669This may be any function of one argument.\n\
670It may also be a buffer (output is inserted before point)\n\
671or a marker (output is inserted and the marker is advanced)\n\
672or the symbol t (output appears in the minibuffer line).");
673 Vstandard_output = Qt;
674 Qstandard_output = intern ("standard-output");
675 staticpro (&Qstandard_output);
676
677 DEFVAR_LISP ("print-length", &Vprint_length,
678 "Maximum length of list to print before abbreviating.\
679`nil' means no limit.");
680 Vprint_length = Qnil;
681
682 DEFVAR_BOOL ("print-escape-newlines", &print_escape_newlines,
683 "Non-nil means print newlines in strings as backslash-n.");
684 print_escape_newlines = 0;
685
686 /* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */
687 staticpro (&Vprin1_to_string_buffer);
688
689 defsubr (&Sprin1);
690 defsubr (&Sprin1_to_string);
691 defsubr (&Sprinc);
692 defsubr (&Sprint);
693 defsubr (&Sterpri);
694 defsubr (&Swrite_char);
695#ifndef standalone
696 defsubr (&Swith_output_to_temp_buffer);
697#endif /* not standalone */
698}