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