Mercurial > hg > xemacs-beta
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 { |