comparison src/print.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents fdefd0186b75
children e38acbeb1cae
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Lisp object printing and output streams. 1 /* Lisp object printing and output streams.
2 Copyright (C) 1985, 1986, 1988, 1992-1995 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1986, 1988, 1992-1995 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996, 2000 Ben Wing. 3 Copyright (C) 1995, 1996, 2000, 2001 Ben Wing.
4 4
5 This file is part of XEmacs. 5 This file is part of XEmacs.
6 6
7 XEmacs is free software; you can redistribute it and/or modify it 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 8 under the terms of the GNU General Public License as published by the
21 21
22 /* Synched up with: Not synched with FSF. */ 22 /* Synched up with: Not synched with FSF. */
23 23
24 /* This file has been Mule-ized. */ 24 /* This file has been Mule-ized. */
25 25
26 /* Seriously hacked on by Ben Wing for Mule. */ 26 /* Seriously divergent from FSF by this point.
27
28 Seriously hacked on by Ben Wing for Mule. All stdio code also by Ben,
29 as well as the debugging code (initial version of debug_print(), though,
30 by Jamie Zawinski) and the _fmt interfaces. Also a fair amount of work
31 by Hrvoje, e.g. floating-point code and rewriting to avoid O(N^2)
32 consing when outputting to the echo area. Print-circularity code by
33 Martin? */
27 34
28 #include <config.h> 35 #include <config.h>
29 #include "lisp.h" 36 #include "lisp.h"
30 37
31 #include "backtrace.h" 38 #include "backtrace.h"
35 #include "console-stream.h" 42 #include "console-stream.h"
36 #include "extents.h" 43 #include "extents.h"
37 #include "frame.h" 44 #include "frame.h"
38 #include "insdel.h" 45 #include "insdel.h"
39 #include "lstream.h" 46 #include "lstream.h"
47 #include "opaque.h"
40 #include "sysfile.h" 48 #include "sysfile.h"
41 #ifdef WIN32_NATIVE 49 #ifdef WIN32_NATIVE
42 #include "console-msw.h" 50 #include "console-msw.h"
43 #endif 51 #endif
44 52
103 /* Force immediate output of all printed data. Used for debugging. */ 111 /* Force immediate output of all printed data. Used for debugging. */
104 int print_unbuffered; 112 int print_unbuffered;
105 113
106 FILE *termscript; /* Stdio stream being used for copy of all output. */ 114 FILE *termscript; /* Stdio stream being used for copy of all output. */
107 115
116 static void write_string_to_alternate_debugging_output (Intbyte *str,
117 Bytecount len);
118
108 119
109 120
110 int stdout_needs_newline; 121 int stdout_needs_newline;
111 122
123 /* Basic function to actually write to a stdio stream or TTY console. */
124
112 static void 125 static void
113 std_handle_out_external (FILE *stream, Lisp_Object lstream, 126 write_string_to_stdio_stream (FILE *stream, struct console *con,
114 const Extbyte *extptr, Bytecount extlen, 127 const Intbyte *ptr, Bytecount len,
115 /* is this really stdout/stderr? 128 int must_flush)
116 (controls termscript writing) */ 129 {
117 int output_is_std_handle, 130 Extbyte *extptr = 0;
118 int must_flush) 131 Bytecount extlen = 0;
119 { 132 int output_is_std_handle =
133 stream ? stream == stdout || stream == stderr :
134 CONSOLE_TTY_DATA (con)->is_stdio;
135
136 if (stream || output_is_std_handle)
137 {
138 if (initialized && !inhibit_non_essential_printing_operations)
139 TO_EXTERNAL_FORMAT (DATA, (ptr, len),
140 ALLOCA, (extptr, extlen),
141 Qterminal);
142 else
143 {
144 extptr = (Extbyte *) ptr;
145 extlen = (Bytecount) len;
146 }
147 }
148
120 if (stream) 149 if (stream)
121 { 150 {
122 #ifdef WIN32_NATIVE 151 #ifdef WIN32_NATIVE
123 HANDLE errhand = GetStdHandle (STD_INPUT_HANDLE); 152 HANDLE errhand = GetStdHandle (STD_INPUT_HANDLE);
124 int no_useful_stderr = errhand == 0 || errhand == INVALID_HANDLE_VALUE; 153 int no_useful_stderr = errhand == 0 || errhand == INVALID_HANDLE_VALUE;
126 if (!no_useful_stderr) 155 if (!no_useful_stderr)
127 no_useful_stderr = !PeekNamedPipe (errhand, 0, 0, 0, 0, 0); 156 no_useful_stderr = !PeekNamedPipe (errhand, 0, 0, 0, 0, 0);
128 /* we typically have no useful stdout/stderr under windows if we're 157 /* we typically have no useful stdout/stderr under windows if we're
129 being invoked graphically. */ 158 being invoked graphically. */
130 if (no_useful_stderr) 159 if (no_useful_stderr)
131 mswindows_output_console_string (extptr, extlen); 160 mswindows_output_console_string (ptr, len);
132 else 161 else
133 #endif 162 #endif
134 { 163 {
135 fwrite (extptr, 1, extlen, stream); 164 retry_fwrite (extptr, 1, extlen, stream);
136 #ifdef WIN32_NATIVE 165 #ifdef WIN32_NATIVE
137 /* Q122442 says that pipes are "treated as files, not as 166 /* Q122442 says that pipes are "treated as files, not as
138 devices", and that this is a feature. Before I found that 167 devices", and that this is a feature. Before I found that
139 article, I thought it was a bug. Thanks MS, I feel much 168 article, I thought it was a bug. Thanks MS, I feel much
140 better now. - kkm */ 169 better now. - kkm */
143 if (must_flush) 172 if (must_flush)
144 fflush (stream); 173 fflush (stream);
145 } 174 }
146 } 175 }
147 else 176 else
148 Lstream_write (XLSTREAM (lstream), extptr, extlen); 177 /* The stream itself does conversion to external format */
178 Lstream_write (XLSTREAM (CONSOLE_TTY_DATA (con)->outstream), ptr, len);
149 179
150 if (output_is_std_handle) 180 if (output_is_std_handle)
151 { 181 {
152 if (termscript) 182 if (termscript)
153 { 183 {
154 fwrite (extptr, 1, extlen, termscript); 184 retry_fwrite (extptr, 1, extlen, termscript);
155 fflush (termscript); 185 fflush (termscript);
156 } 186 }
157 stdout_needs_newline = (extptr[extlen - 1] != '\n'); 187 stdout_needs_newline = (ptr[extlen - 1] != '\n');
158 } 188 }
159 } 189 }
160 190
161 /* #### The following function should be replaced a call to the 191 /* #### The following function should be replaced a call to the
162 emacs_doprnt_*() functions. This is the only way to ensure that 192 emacs_vsprintf_*() functions. This is the only way to ensure that
163 I18N3 works properly (many implementations of the *printf() 193 I18N3 works properly (many implementations of the *printf()
164 functions, including the ones included in glibc, do not implement 194 functions, including the ones included in glibc, do not implement
165 the %###$ argument-positioning syntax). 195 the %###$ argument-positioning syntax).
166 196
167 Note, however, that to do this, we'd have to 197 Note, however, that to do this, we'd have to
171 called from fatal_error_signal(). 201 called from fatal_error_signal().
172 202
173 2) (to be really correct) make a new lstream that outputs using 203 2) (to be really correct) make a new lstream that outputs using
174 mswindows_output_console_string(). */ 204 mswindows_output_console_string(). */
175 205
176 static int 206 static void
177 std_handle_out_va (FILE *stream, const char *fmt, va_list args) 207 std_handle_out_va (FILE *stream, const CIntbyte *fmt, va_list args,
208 int debug_output_as_well)
178 { 209 {
179 Intbyte kludge[8192]; 210 Intbyte kludge[8192];
180 Extbyte *extptr; 211 Bytecount kludgelen;
181 Bytecount extlen; 212
182 int retval; 213 if (initialized && !inhibit_non_essential_printing_operations)
183 214 fmt = GETTEXT (fmt);
184 retval = vsprintf ((char *) kludge, fmt, args); 215 vsprintf ((CIntbyte *) kludge, fmt, args);
185 if (initialized && !fatal_error_in_progress) 216 kludgelen = qxestrlen (kludge);
186 TO_EXTERNAL_FORMAT (DATA, (kludge, strlen ((char *) kludge)), 217
187 ALLOCA, (extptr, extlen), 218 write_string_to_stdio_stream (stream, 0, kludge, kludgelen, 1);
188 Qnative); 219 if (debug_output_as_well)
189 else 220 {
190 { 221 write_string_to_alternate_debugging_output (kludge, kludgelen);
191 extptr = (Extbyte *) kludge; 222 #ifdef WIN32_NATIVE
192 extlen = (Bytecount) strlen ((char *) kludge); 223 write_string_to_mswindows_debugging_output (kludge, kludgelen);
193 } 224 #endif
194 225 }
195 std_handle_out_external (stream, Qnil, extptr, extlen, 1, 1); 226 }
196 return retval; 227
197 } 228 /* Output portably to stderr or its equivalent (i.e. may be a console
198 229 window under MS Windows); do external-format conversion and call GETTEXT
199 /* Output portably to stderr or its equivalent; call GETTEXT on the 230 on the format string. Automatically flush when done.
200 format string. Automatically flush when done. */ 231
201 232 This is safe even when not initialized or when dying -- we don't do
202 int 233 conversion in such cases. */
203 stderr_out (const char *fmt, ...) 234
204 { 235 void
205 int retval; 236 stderr_out (const CIntbyte *fmt, ...)
237 {
206 va_list args; 238 va_list args;
207 va_start (args, fmt); 239 va_start (args, fmt);
208 retval = 240 std_handle_out_va (stderr, fmt, args, 0);
209 std_handle_out_va
210 (stderr, initialized && !fatal_error_in_progress ? GETTEXT (fmt) : fmt,
211 args);
212 va_end (args); 241 va_end (args);
213 return retval; 242 }
214 } 243
215 244 /* Output portably to stdout or its equivalent (i.e. may be a console
216 /* Output portably to stdout or its equivalent; call GETTEXT on the 245 window under MS Windows). Works like stderr_out(). */
217 format string. Automatically flush when done. */ 246
218 247 void
219 int 248 stdout_out (const CIntbyte *fmt, ...)
220 stdout_out (const char *fmt, ...) 249 {
221 {
222 int retval;
223 va_list args; 250 va_list args;
224 va_start (args, fmt); 251 va_start (args, fmt);
225 retval = 252 std_handle_out_va (stdout, fmt, args, 0);
226 std_handle_out_va
227 (stdout, initialized && !fatal_error_in_progress ? GETTEXT (fmt) : fmt,
228 args);
229 va_end (args); 253 va_end (args);
230 return retval; 254 }
231 } 255
232 256 /* Output portably to stderr or its equivalent (i.e. may be a console
233 DOESNT_RETURN 257 window under MS Windows), as well as alternate-debugging-output and
234 fatal (const char *fmt, ...) 258 (under MS Windows) the C debugging output, i.e. OutputDebugString().
259 Works like stderr_out(). */
260
261 void
262 debug_out (const CIntbyte *fmt, ...)
235 { 263 {
236 va_list args; 264 va_list args;
237 va_start (args, fmt); 265 va_start (args, fmt);
238 266 std_handle_out_va (stderr, fmt, args, 1);
239 stderr_out ("\nXEmacs: "); 267 va_end (args);
240 std_handle_out_va (stderr, GETTEXT (fmt), args); 268 }
269
270 DOESNT_RETURN
271 fatal (const CIntbyte *fmt, ...)
272 {
273 va_list args;
274 va_start (args, fmt);
275
276 stderr_out ("\nXEmacs: fatal error: ");
277 std_handle_out_va (stderr, fmt, args, 0);
241 stderr_out ("\n"); 278 stderr_out ("\n");
242 279
243 va_end (args); 280 va_end (args);
244 exit (1); 281 exit (1);
245 } 282 }
246 283
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 Intbyte *str,
252 Bytecount offset, Bytecount len,
253 Lisp_Object coding_system,
254 int must_flush)
255 {
256 Bytecount 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 Intbyte *puta = (Intbyte *) 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. 284 /* Write a string to the output location specified in FUNCTION.
282 Arguments NONRELOC, RELOC, OFFSET, and LEN are as in 285 Arguments NONRELOC, RELOC, OFFSET, and LEN are as in
283 buffer_insert_string_1() in insdel.c. */ 286 buffer_insert_string_1() in insdel.c.
287
288 FUNCTION is one of
289
290 -- an lstream
291 -- a buffer (insert at point and advance point)
292 -- a marker (insert at marker and advance marker)
293 -- a frame (append to echo area; clear echo area first if
294 `print-message-label' has changed since the last time)
295 -- t or nil (send to stdout)
296 -- a Lisp function of one argument (call to get data output)
297
298 Use Qexternal_debugging_output to get output to stderr.
299 */
284 300
285 static void 301 static void
286 output_string (Lisp_Object function, const Intbyte *nonreloc, 302 output_string (Lisp_Object function, const Intbyte *nonreloc,
287 Lisp_Object reloc, Bytecount offset, Bytecount len) 303 Lisp_Object reloc, Bytecount offset, Bytecount len)
288 { 304 {
295 fixup_internal_substring() may get triggered. */ 311 fixup_internal_substring() may get triggered. */
296 const Intbyte *newnonreloc = nonreloc; 312 const Intbyte *newnonreloc = nonreloc;
297 struct gcpro gcpro1, gcpro2; 313 struct gcpro gcpro1, gcpro2;
298 314
299 /* Emacs won't print while GCing, but an external debugger might */ 315 /* Emacs won't print while GCing, but an external debugger might */
316 #ifdef NO_PRINT_DURING_GC
300 if (gc_in_progress) return; 317 if (gc_in_progress) return;
318 #endif
301 319
302 /* Perhaps not necessary but probably safer. */ 320 /* Perhaps not necessary but probably safer. */
303 GCPRO2 (function, reloc); 321 GCPRO2 (function, reloc);
304 322
305 fixup_internal_substring (newnonreloc, reloc, offset, &len); 323 fixup_internal_substring (newnonreloc, reloc, offset, &len);
306 324
307 if (STRINGP (reloc)) 325 if (STRINGP (reloc))
308 newnonreloc = XSTRING_DATA (reloc); 326 {
309 327 cclen = XSTRING_OFFSET_BYTE_TO_CHAR_LEN (reloc, offset, len);
310 cclen = bytecount_to_charcount (newnonreloc + offset, len); 328 newnonreloc = XSTRING_DATA (reloc);
329 }
330 else
331 cclen = bytecount_to_charcount (newnonreloc + offset, len);
311 332
312 if (LSTREAMP (function)) 333 if (LSTREAMP (function))
313 { 334 {
314 if (STRINGP (reloc)) 335 if (STRINGP (reloc))
315 { 336 {
323 memcpy (copied, newnonreloc + offset, len); 344 memcpy (copied, newnonreloc + offset, len);
324 Lstream_write (XLSTREAM (function), copied, len); 345 Lstream_write (XLSTREAM (function), copied, len);
325 } 346 }
326 else 347 else
327 { 348 {
328 int speccount = specpdl_depth (); 349 int speccount = begin_gc_forbidden ();
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); 350 Lstream_write (XLSTREAM (function), newnonreloc + offset, len);
333 unbind_to (speccount, Qnil); 351 unbind_to (speccount);
334 } 352 }
335 } 353 }
336 else 354 else
337 Lstream_write (XLSTREAM (function), newnonreloc + offset, len); 355 Lstream_write (XLSTREAM (function), newnonreloc + offset, len);
338 356
366 clear_echo_area_from_print (f, Qnil, 1); 384 clear_echo_area_from_print (f, Qnil, 1);
367 echo_area_append (f, nonreloc, reloc, offset, len, Vprint_message_label); 385 echo_area_append (f, nonreloc, reloc, offset, len, Vprint_message_label);
368 } 386 }
369 else if (EQ (function, Qt) || EQ (function, Qnil)) 387 else if (EQ (function, Qt) || EQ (function, Qnil))
370 { 388 {
371 write_string_to_stdio_stream (stdout, 0, newnonreloc, offset, len, 389 write_string_to_stdio_stream (stdout, 0, newnonreloc + offset, len,
372 Qterminal, print_unbuffered); 390 print_unbuffered);
391 }
392 else if (EQ (function, Qexternal_debugging_output))
393 {
394 /* This is not strictly necessary, and somewhat of a hack, but it
395 avoids having each character passed separately to
396 `external-debugging-output'. #### Why do we pass each character
397 separately, anyway?
398 */
399 write_string_to_stdio_stream (stderr, 0, newnonreloc + offset, len,
400 print_unbuffered);
373 } 401 }
374 else 402 else
375 { 403 {
376 Charcount ccoff = bytecount_to_charcount (newnonreloc, offset); 404 Charcount ccoff;
377 Charcount iii; 405 Charcount iii;
378 406
379 for (iii = ccoff; iii < cclen + ccoff; iii++) 407 if (STRINGP (reloc))
408 ccoff = XSTRING_INDEX_BYTE_TO_CHAR (reloc, offset);
409 else
410 ccoff = bytecount_to_charcount (newnonreloc, offset);
411
412 if (STRINGP (reloc))
380 { 413 {
381 call1 (function, 414 for (iii = ccoff; iii < cclen + ccoff; iii++)
382 make_char (charptr_emchar_n (newnonreloc, iii))); 415 {
383 if (STRINGP (reloc)) 416 call1 (function, make_char (XSTRING_CHAR (reloc, iii)));
384 newnonreloc = XSTRING_DATA (reloc); 417 if (STRINGP (reloc))
418 newnonreloc = XSTRING_DATA (reloc);
419 }
420 }
421 else
422 {
423 for (iii = ccoff; iii < cclen + ccoff; iii++)
424 {
425 call1 (function,
426 make_char (charptr_emchar_n (newnonreloc, iii)));
427 }
385 } 428 }
386 } 429 }
387 430
388 UNGCPRO; 431 UNGCPRO;
389 } 432 }
407 450
408 static Lisp_Object 451 static Lisp_Object
409 print_prepare (Lisp_Object printcharfun, Lisp_Object *frame_kludge) 452 print_prepare (Lisp_Object printcharfun, Lisp_Object *frame_kludge)
410 { 453 {
411 /* Emacs won't print while GCing, but an external debugger might */ 454 /* Emacs won't print while GCing, but an external debugger might */
455 #ifdef NO_PRINT_DURING_GC
412 if (gc_in_progress) 456 if (gc_in_progress)
413 return Qnil; 457 return Qnil;
414 458 #endif
459
415 RESET_PRINT_GENSYM; 460 RESET_PRINT_GENSYM;
416 461
417 printcharfun = canonicalize_printcharfun (printcharfun); 462 printcharfun = canonicalize_printcharfun (printcharfun);
418 463
419 /* Here we could safely return the canonicalized PRINTCHARFUN. 464 /* Here we could safely return the canonicalized PRINTCHARFUN.
452 497
453 static void 498 static void
454 print_finish (Lisp_Object stream, Lisp_Object frame_kludge) 499 print_finish (Lisp_Object stream, Lisp_Object frame_kludge)
455 { 500 {
456 /* Emacs won't print while GCing, but an external debugger might */ 501 /* Emacs won't print while GCing, but an external debugger might */
502 #ifdef NO_PRINT_DURING_GC
457 if (gc_in_progress) 503 if (gc_in_progress)
458 return; 504 return;
459 505 #endif
506
460 RESET_PRINT_GENSYM; 507 RESET_PRINT_GENSYM;
461 508
462 /* See the comment in print_prepare(). */ 509 /* See the comment in print_prepare(). */
463 if (FRAMEP (frame_kludge)) 510 if (FRAMEP (frame_kludge))
464 { 511 {
479 /* Used for printing a single-byte character (*not* any Emchar). */ 526 /* Used for printing a single-byte character (*not* any Emchar). */
480 #define write_char_internal(string_of_length_1, stream) \ 527 #define write_char_internal(string_of_length_1, stream) \
481 output_string (stream, (const Intbyte *) (string_of_length_1), \ 528 output_string (stream, (const Intbyte *) (string_of_length_1), \
482 Qnil, 0, 1) 529 Qnil, 0, 1)
483 530
484 /* NOTE: Do not call this with the data of a Lisp_String, as 531 /* Write internal-format data to STREAM. See output_string() for
532 interpretation of STREAM.
533
534 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 535 printcharfun might cause a GC, which might cause the string's data
486 to be relocated. To princ a Lisp string, use: 536 to be relocated. To princ a Lisp string, use:
487 537
488 print_internal (string, printcharfun, 0); 538 print_internal (string, printcharfun, 0);
489 539
499 #endif 549 #endif
500 output_string (stream, str, Qnil, 0, size); 550 output_string (stream, str, Qnil, 0, size);
501 } 551 }
502 552
503 void 553 void
504 write_c_string (const char *str, Lisp_Object stream) 554 write_string (const Intbyte *str, Lisp_Object stream)
555 {
556 /* This function can GC */
557 write_string_1 (str, qxestrlen (str), stream);
558 }
559
560 void
561 write_c_string (const CIntbyte *str, Lisp_Object stream)
505 { 562 {
506 /* This function can GC */ 563 /* This function can GC */
507 write_string_1 ((const Intbyte *) str, strlen (str), stream); 564 write_string_1 ((const Intbyte *) str, strlen (str), stream);
565 }
566
567 /* Write a printf-style string to STREAM; see output_string(). */
568
569 void
570 write_fmt_string (Lisp_Object stream, const CIntbyte *fmt, ...)
571 {
572 va_list va;
573 Intbyte *str;
574 Bytecount len;
575 int count;
576
577 va_start (va, fmt);
578 str = emacs_vsprintf_malloc (fmt, va, &len);
579 va_end (va);
580 count = record_unwind_protect_freeing (str);
581 write_string_1 (str, len, stream);
582 unbind_to (count);
583 }
584
585 /* Write a printf-style string to STREAM, where the arguments are
586 Lisp objects and not C strings or integers; see output_string().
587
588 #### It shouldn't be necessary to specify the number of arguments.
589 This would require some rewriting of the doprnt() functions, though. */
590
591 void
592 write_fmt_string_lisp (Lisp_Object stream, const CIntbyte *fmt, int nargs, ...)
593 {
594 Lisp_Object *args = alloca_array (Lisp_Object, nargs);
595 va_list va;
596 int i;
597 Intbyte *str;
598 Bytecount len;
599 int count;
600
601 va_start (va, nargs);
602 for (i = 0; i < nargs; i++)
603 args[i] = va_arg (va, Lisp_Object);
604 va_end (va);
605 str = emacs_vsprintf_malloc_lisp (fmt, Qnil, nargs, args, &len);
606 count = record_unwind_protect_freeing (str);
607 write_string_1 (str, len, stream);
608 unbind_to (count);
609 }
610
611 void
612 stderr_out_lisp (const CIntbyte *fmt, int nargs, ...)
613 {
614 Lisp_Object *args = alloca_array (Lisp_Object, nargs);
615 va_list va;
616 int i;
617 Intbyte *str;
618 Bytecount len;
619 int count;
620
621 va_start (va, nargs);
622 for (i = 0; i < nargs; i++)
623 args[i] = va_arg (va, Lisp_Object);
624 va_end (va);
625 str = emacs_vsprintf_malloc_lisp (fmt, Qnil, nargs, args, &len);
626 count = record_unwind_protect_freeing (str);
627 write_string_1 (str, len, Qexternal_debugging_output);
628 unbind_to (count);
508 } 629 }
509 630
510 631
511 DEFUN ("write-char", Fwrite_char, 1, 2, 0, /* 632 DEFUN ("write-char", Fwrite_char, 1, 2, 0, /*
512 Output character CHARACTER to stream STREAM. 633 Output character CHARACTER to stream STREAM.
565 arg = (*function) (arg); 686 arg = (*function) (arg);
566 687
567 temp_output_buffer_show (buf, same_frame); 688 temp_output_buffer_show (buf, same_frame);
568 UNGCPRO; 689 UNGCPRO;
569 690
570 return unbind_to (speccount, arg); 691 return unbind_to_1 (speccount, arg);
571 } 692 }
572 693
573 DEFUN ("with-output-to-temp-buffer", Fwith_output_to_temp_buffer, 1, UNEVALLED, 0, /* 694 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. 695 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. 696 The buffer is cleared out initially, and marked as unmodified when done.
603 724
604 val = Fprogn (XCDR (args)); 725 val = Fprogn (XCDR (args));
605 726
606 temp_output_buffer_show (Vstandard_output, Qnil); 727 temp_output_buffer_show (Vstandard_output, Qnil);
607 728
608 return unbind_to (speccount, val); 729 return unbind_to_1 (speccount, val);
609 } 730 }
610 731
611 DEFUN ("terpri", Fterpri, 0, 1, 0, /* 732 DEFUN ("terpri", Fterpri, 0, 1, 0, /*
612 Output a newline to STREAM. 733 Output a newline to STREAM.
613 If STREAM is omitted or nil, the value of `standard-output' is used. 734 If STREAM is omitted or nil, the value of `standard-output' is used.
793 tail = Fcdr (tail); 914 tail = Fcdr (tail);
794 first = 0; 915 first = 0;
795 } 916 }
796 print_finish (stream, frame); 917 print_finish (stream, frame);
797 UNGCPRO; 918 UNGCPRO;
798 unbind_to (speccount, Qnil); 919 unbind_to (speccount);
799 return; 920 return;
800 /* not reached */ 921 /* not reached */
801 } 922 }
802 923
803 error_throw: 924 error_throw:
1168 1289
1169 if (INTP (Vprint_string_length) && 1290 if (INTP (Vprint_string_length) &&
1170 XINT (Vprint_string_length) < max) 1291 XINT (Vprint_string_length) < max)
1171 { 1292 {
1172 max = XINT (Vprint_string_length); 1293 max = XINT (Vprint_string_length);
1173 bcmax = charcount_to_bytecount (string_data (s), max); 1294 bcmax = string_index_char_to_byte (s, max);
1174 } 1295 }
1175 if (max < 0) 1296 if (max < 0)
1176 { 1297 {
1177 max = 0; 1298 max = 0;
1178 bcmax = 0; 1299 bcmax = 0;
1263 { 1384 {
1264 /* This function can GC */ 1385 /* This function can GC */
1265 1386
1266 QUIT; 1387 QUIT;
1267 1388
1389 #ifdef NO_PRINT_DURING_GC
1268 /* Emacs won't print while GCing, but an external debugger might */ 1390 /* Emacs won't print while GCing, but an external debugger might */
1269 if (gc_in_progress) return; 1391 if (gc_in_progress) return;
1392 #endif
1393
1394 /* Try to check for a bogus pointer if we're in a situation where it may
1395 be likely. In such cases, crashing is counterproductive. */
1396 if (inhibit_non_essential_printing_operations || print_unbuffered)
1397 {
1398 if (XTYPE (obj) == Lisp_Type_Record)
1399 {
1400 struct lrecord_header *lheader = XRECORD_LHEADER (obj);
1401
1402 if (!debug_can_access_memory (lheader, sizeof (*lheader)))
1403 {
1404 char buf[128];
1405
1406 sprintf (buf, "#<EMACS BUG: BAD MEMORY %p>", lheader);
1407 write_c_string (buf, printcharfun);
1408 return;
1409 }
1410 else
1411 {
1412 const struct lrecord_implementation *impl;
1413
1414 if ((int) lheader->type >= lrecord_type_count)
1415 {
1416 char buf[128];
1417
1418 sprintf (buf, "#<EMACS BUG: bad type %d BAD MEMORY %p>",
1419 lheader->type, lheader);
1420 write_c_string (buf, printcharfun);
1421 return;
1422 }
1423
1424 impl = LHEADER_IMPLEMENTATION (lheader);
1425 if (!debug_can_access_memory
1426 (lheader,
1427 (impl->size_in_bytes_method ?
1428 impl->size_in_bytes_method (lheader) :
1429 impl->static_size)))
1430 {
1431 char buf[128];
1432
1433 sprintf (buf, "#<EMACS BUG: type %s BAD MEMORY %p>",
1434 impl->name, lheader);
1435 write_c_string (buf, printcharfun);
1436 return;
1437 }
1438
1439 if (STRINGP (obj))
1440 {
1441 Lisp_String *l = (Lisp_String *) lheader;
1442 if (!debug_can_access_memory
1443 (l->data, l->size))
1444 {
1445 char buf[128];
1446
1447 sprintf (buf, "#<EMACS BUG: %p (BAD STRING DATA %p)>",
1448 lheader, l->data);
1449 write_c_string (buf, printcharfun);
1450 return;
1451 }
1452 }
1453 }
1454 }
1455 }
1270 1456
1271 #ifdef I18N3 1457 #ifdef I18N3
1272 /* #### Both input and output streams should have a flag associated 1458 /* #### Both input and output streams should have a flag associated
1273 with them indicating whether output to that stream, or strings 1459 with them indicating whether output to that stream, or strings
1274 read from the stream, get translated using Fgettext(). Such a 1460 read from the stream, get translated using Fgettext(). Such a
1591 */ 1777 */
1592 (character)) 1778 (character))
1593 { 1779 {
1594 Intbyte str[MAX_EMCHAR_LEN]; 1780 Intbyte str[MAX_EMCHAR_LEN];
1595 Bytecount len; 1781 Bytecount len;
1782
1783 CHECK_CHAR_COERCE_INT (character);
1784 len = set_charptr_emchar (str, XCHAR (character));
1785 write_string_to_alternate_debugging_output (str, len);
1786
1787 return character;
1788 }
1789
1790 static void
1791 write_string_to_alternate_debugging_output (Intbyte *str, Bytecount len)
1792 {
1596 int extlen; 1793 int extlen;
1597 const Extbyte *extptr; 1794 const Extbyte *extptr;
1598 1795 #if 0 /* We want to see the internal representation, don't we? */
1599 CHECK_CHAR_COERCE_INT (character); 1796 if (initialized && !inhibit_non_essential_printing_operations)
1600 len = set_charptr_emchar (str, XCHAR (character)); 1797 TO_EXTERNAL_FORMAT (DATA, (str, len),
1601 TO_EXTERNAL_FORMAT (DATA, (str, len), 1798 ALLOCA, (extptr, extlen),
1602 ALLOCA, (extptr, extlen), 1799 Qterminal);
1603 Qterminal); 1800 else
1801 #endif /* 0 */
1802 {
1803 extlen = len;
1804 extptr = (Extbyte *) str;
1805 }
1604 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); 1806 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen);
1605 alternate_do_pointer += extlen; 1807 alternate_do_pointer += extlen;
1606 alternate_do_string[alternate_do_pointer] = 0; 1808 alternate_do_string[alternate_do_pointer] = 0;
1607 return character;
1608 } 1809 }
1609 1810
1610 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* 1811 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /*
1611 Write CHAR-OR-STRING to stderr or stdout. 1812 Write CHAR-OR-STRING to stderr or stdout.
1612 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write 1813 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write
1648 } 1849 }
1649 1850
1650 if (STRINGP (char_or_string)) 1851 if (STRINGP (char_or_string))
1651 write_string_to_stdio_stream (file, con, 1852 write_string_to_stdio_stream (file, con,
1652 XSTRING_DATA (char_or_string), 1853 XSTRING_DATA (char_or_string),
1653 0, XSTRING_LENGTH (char_or_string), 1854 XSTRING_LENGTH (char_or_string),
1654 Qterminal, 1); 1855 print_unbuffered);
1655 else 1856 else
1656 { 1857 {
1657 Intbyte str[MAX_EMCHAR_LEN]; 1858 Intbyte str[MAX_EMCHAR_LEN];
1658 Bytecount len; 1859 Bytecount len;
1659 1860
1660 CHECK_CHAR_COERCE_INT (char_or_string); 1861 CHECK_CHAR_COERCE_INT (char_or_string);
1661 len = set_charptr_emchar (str, XCHAR (char_or_string)); 1862 len = set_charptr_emchar (str, XCHAR (char_or_string));
1662 write_string_to_stdio_stream (file, con, str, 0, len, Qterminal, 1); 1863 write_string_to_stdio_stream (file, con, str, len, print_unbuffered);
1663 } 1864 }
1664 1865
1665 return char_or_string; 1866 return char_or_string;
1666 } 1867 }
1667 1868
1672 (filename)) 1873 (filename))
1673 { 1874 {
1674 /* This function can GC */ 1875 /* This function can GC */
1675 if (termscript != 0) 1876 if (termscript != 0)
1676 { 1877 {
1677 fclose (termscript); 1878 retry_fclose (termscript);
1678 termscript = 0; 1879 termscript = 0;
1679 } 1880 }
1680 1881
1681 if (! NILP (filename)) 1882 if (! NILP (filename))
1682 { 1883 {
1683 filename = Fexpand_file_name (filename, Qnil); 1884 filename = Fexpand_file_name (filename, Qnil);
1684 termscript = fopen ((char *) XSTRING_DATA (filename), "w"); 1885 termscript = qxe_fopen (XSTRING_DATA (filename), "w");
1685 if (termscript == NULL) 1886 if (termscript == NULL)
1686 report_file_error ("Opening termscript", filename); 1887 report_file_error ("Opening termscript", filename);
1687 } 1888 }
1688 return Qnil; 1889 return Qnil;
1689 } 1890 }
1690 1891
1691 #if 1
1692 /* Debugging kludge -- unbuffered */
1693 static int debug_print_length = 50; 1892 static int debug_print_length = 50;
1694 static int debug_print_level = 15; 1893 static int debug_print_level = 15;
1695 static int debug_print_readably = -1; 1894 static int debug_print_readably = -1;
1696 1895
1896 /* Debugging kludge -- unbuffered */
1697 static void 1897 static void
1698 debug_print_no_newline (Lisp_Object debug_print_obj) 1898 debug_print_no_newline (Lisp_Object debug_print_obj)
1699 { 1899 {
1700 /* This function can GC */ 1900 /* This function can GC */
1701 int save_print_readably = print_readably; 1901 int save_print_readably = print_readably;
1704 Lisp_Object save_Vprint_level = Vprint_level; 1904 Lisp_Object save_Vprint_level = Vprint_level;
1705 Lisp_Object save_Vinhibit_quit = Vinhibit_quit; 1905 Lisp_Object save_Vinhibit_quit = Vinhibit_quit;
1706 struct gcpro gcpro1, gcpro2, gcpro3; 1906 struct gcpro gcpro1, gcpro2, gcpro3;
1707 GCPRO3 (save_Vprint_level, save_Vprint_length, save_Vinhibit_quit); 1907 GCPRO3 (save_Vprint_level, save_Vprint_length, save_Vinhibit_quit);
1708 1908
1709 if (gc_in_progress)
1710 stderr_out ("** gc-in-progress! Bad idea to print anything! **\n");
1711
1712 print_depth = 0; 1909 print_depth = 0;
1713 print_readably = debug_print_readably != -1 ? debug_print_readably : 0; 1910 print_readably = debug_print_readably != -1 ? debug_print_readably : 0;
1714 print_unbuffered++; 1911 print_unbuffered++;
1715 /* Could use unwind-protect, but why bother? */ 1912 /* Could use unwind-protect, but why bother? */
1716 if (debug_print_length > 0) 1913 if (debug_print_length > 0)
1737 1934
1738 void 1935 void
1739 debug_print (Lisp_Object debug_print_obj) 1936 debug_print (Lisp_Object debug_print_obj)
1740 { 1937 {
1741 debug_print_no_newline (debug_print_obj); 1938 debug_print_no_newline (debug_print_obj);
1742 stderr_out ("\n"); 1939 debug_out ("\n");
1743 } 1940 }
1744 1941
1745 /* Debugging kludge -- unbuffered */ 1942 /* Debugging kludge -- unbuffered */
1746 /* This function provided for the benefit of the debugger. */ 1943 /* This function provided for the benefit of the debugger. */
1747 void debug_backtrace (void);
1748 void 1944 void
1749 debug_backtrace (void) 1945 debug_backtrace (void)
1750 { 1946 {
1751 /* This function can GC */ 1947 /* This function can GC */
1752 int old_print_readably = print_readably; 1948 int old_print_readably = print_readably;
1755 Lisp_Object old_print_level = Vprint_level; 1951 Lisp_Object old_print_level = Vprint_level;
1756 Lisp_Object old_inhibit_quit = Vinhibit_quit; 1952 Lisp_Object old_inhibit_quit = Vinhibit_quit;
1757 1953
1758 struct gcpro gcpro1, gcpro2, gcpro3; 1954 struct gcpro gcpro1, gcpro2, gcpro3;
1759 GCPRO3 (old_print_level, old_print_length, old_inhibit_quit); 1955 GCPRO3 (old_print_level, old_print_length, old_inhibit_quit);
1760
1761 if (gc_in_progress)
1762 stderr_out ("** gc-in-progress! Bad idea to print anything! **\n");
1763 1956
1764 print_depth = 0; 1957 print_depth = 0;
1765 print_readably = 0; 1958 print_readably = 0;
1766 print_unbuffered++; 1959 print_unbuffered++;
1767 /* Could use unwind-protect, but why bother? */ 1960 /* Could use unwind-protect, but why bother? */
1786 void 1979 void
1787 debug_short_backtrace (int length) 1980 debug_short_backtrace (int length)
1788 { 1981 {
1789 int first = 1; 1982 int first = 1;
1790 struct backtrace *bt = backtrace_list; 1983 struct backtrace *bt = backtrace_list;
1791 stderr_out (" ["); 1984 debug_out (" [");
1792 while (length > 0 && bt) 1985 while (length > 0 && bt)
1793 { 1986 {
1794 if (!first) 1987 if (!first)
1795 { 1988 {
1796 stderr_out (", "); 1989 debug_out (", ");
1797 } 1990 }
1798 if (COMPILED_FUNCTIONP (*bt->function)) 1991 if (COMPILED_FUNCTIONP (*bt->function))
1799 { 1992 {
1800 #if defined(COMPILED_FUNCTION_ANNOTATION_HACK) 1993 #if defined(COMPILED_FUNCTION_ANNOTATION_HACK)
1801 Lisp_Object ann = 1994 Lisp_Object ann =
1803 #else 1996 #else
1804 Lisp_Object ann = Qnil; 1997 Lisp_Object ann = Qnil;
1805 #endif 1998 #endif
1806 if (!NILP (ann)) 1999 if (!NILP (ann))
1807 { 2000 {
1808 stderr_out ("<compiled-function from "); 2001 debug_out ("<compiled-function from ");
1809 debug_print_no_newline (ann); 2002 debug_print_no_newline (ann);
1810 stderr_out (">"); 2003 debug_out (">");
1811 } 2004 }
1812 else 2005 else
1813 { 2006 {
1814 stderr_out ("<compiled-function of unknown origin>"); 2007 debug_out ("<compiled-function of unknown origin>");
1815 } 2008 }
1816 } 2009 }
1817 else 2010 else
1818 debug_print_no_newline (*bt->function); 2011 debug_print_no_newline (*bt->function);
1819 first = 0; 2012 first = 0;
1820 length--; 2013 length--;
1821 bt = bt->next; 2014 bt = bt->next;
1822 } 2015 }
1823 stderr_out ("]\n"); 2016 debug_out ("]\n");
1824 } 2017 }
1825
1826 #endif /* debugging kludge */
1827 2018
1828 2019
1829 void 2020 void
1830 syms_of_print (void) 2021 syms_of_print (void)
1831 { 2022 {