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