Mercurial > hg > xemacs-beta
comparison src/print.c @ 278:90d73dddcdc4 r21-0b37
Import from CVS: tag r21-0b37
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:31:29 +0200 |
parents | 6330739388db |
children | 7df0dd720c89 |
comparison
equal
deleted
inserted
replaced
277:cfdf3ff11843 | 278:90d73dddcdc4 |
---|---|
26 /* Seriously hacked on by Ben Wing for Mule. */ | 26 /* Seriously hacked on by Ben Wing for Mule. */ |
27 | 27 |
28 #include <config.h> | 28 #include <config.h> |
29 #include "lisp.h" | 29 #include "lisp.h" |
30 | 30 |
31 #ifndef standalone | |
32 #include "backtrace.h" | 31 #include "backtrace.h" |
33 #include "buffer.h" | 32 #include "buffer.h" |
34 #include "bytecode.h" | 33 #include "bytecode.h" |
35 #include "console-tty.h" | 34 #include "console-tty.h" |
36 #include "console-stream.h" | 35 #include "console-stream.h" |
38 #include "frame.h" | 37 #include "frame.h" |
39 #include "insdel.h" | 38 #include "insdel.h" |
40 #include "lstream.h" | 39 #include "lstream.h" |
41 #include "sysfile.h" | 40 #include "sysfile.h" |
42 | 41 |
43 #endif /* not standalone */ | |
44 | |
45 #include <float.h> | 42 #include <float.h> |
46 /* Define if not in float.h */ | 43 /* Define if not in float.h */ |
47 #ifndef DBL_DIG | 44 #ifndef DBL_DIG |
48 #define DBL_DIG 16 | 45 #define DBL_DIG 16 |
49 #endif | 46 #endif |
150 static void | 147 static void |
151 output_string (Lisp_Object function, CONST Bufbyte *nonreloc, | 148 output_string (Lisp_Object function, CONST Bufbyte *nonreloc, |
152 Lisp_Object reloc, Bytecount offset, Bytecount len) | 149 Lisp_Object reloc, Bytecount offset, Bytecount len) |
153 { | 150 { |
154 /* This function can GC */ | 151 /* This function can GC */ |
155 Charcount ccoff, cclen; | 152 Charcount cclen; |
156 /* We change the value of nonreloc (fetching it from reloc as | 153 /* We change the value of nonreloc (fetching it from reloc as |
157 necessary), but we don't want to pass this changed value on to | 154 necessary), but we don't want to pass this changed value on to |
158 other functions that take both a nonreloc and a reloc, or things | 155 other functions that take both a nonreloc and a reloc, or things |
159 may get confused and an assertion failure in | 156 may get confused and an assertion failure in |
160 fixup_internal_substring() may get triggered. */ | 157 fixup_internal_substring() may get triggered. */ |
170 fixup_internal_substring (newnonreloc, reloc, offset, &len); | 167 fixup_internal_substring (newnonreloc, reloc, offset, &len); |
171 | 168 |
172 if (STRINGP (reloc)) | 169 if (STRINGP (reloc)) |
173 newnonreloc = XSTRING_DATA (reloc); | 170 newnonreloc = XSTRING_DATA (reloc); |
174 | 171 |
175 ccoff = bytecount_to_charcount (newnonreloc, offset); | |
176 cclen = bytecount_to_charcount (newnonreloc + offset, len); | 172 cclen = bytecount_to_charcount (newnonreloc + offset, len); |
177 | 173 |
178 if (LSTREAMP (function)) | 174 if (LSTREAMP (function)) |
179 { | 175 { |
180 if (STRINGP (reloc)) | 176 if (STRINGP (reloc)) |
181 { | 177 { |
182 /* Protect against Lstream_write() causing a GC and | 178 /* Protect against Lstream_write() causing a GC and |
183 relocating the string. For small strings, we do it by | 179 relocating the string. For small strings, we do it by |
184 alloc'ing the string and using a copy; for large strings, | 180 alloc'ing the string and using a copy; for large strings, |
185 we inhibit GC. Now that print_streams are dead, this | 181 we inhibit GC. */ |
186 case should happen very rarely anyway. */ | |
187 if (len < 65536) | 182 if (len < 65536) |
188 { | 183 { |
189 Bufbyte *copied = alloca_array (Bufbyte, len); | 184 Bufbyte *copied = alloca_array (Bufbyte, len); |
190 memcpy (copied, newnonreloc + offset, len); | 185 memcpy (copied, newnonreloc + offset, len); |
191 Lstream_write (XLSTREAM (function), copied, len); | 186 Lstream_write (XLSTREAM (function), copied, len); |
204 Lstream_write (XLSTREAM (function), newnonreloc + offset, len); | 199 Lstream_write (XLSTREAM (function), newnonreloc + offset, len); |
205 | 200 |
206 if (print_unbuffered) | 201 if (print_unbuffered) |
207 Lstream_flush (XLSTREAM (function)); | 202 Lstream_flush (XLSTREAM (function)); |
208 } | 203 } |
209 | |
210 #ifndef standalone | |
211 else if (BUFFERP (function)) | 204 else if (BUFFERP (function)) |
212 { | 205 { |
213 CHECK_LIVE_BUFFER (function); | 206 CHECK_LIVE_BUFFER (function); |
214 buffer_insert_string (XBUFFER (function), nonreloc, reloc, offset, len); | 207 buffer_insert_string (XBUFFER (function), nonreloc, reloc, offset, len); |
215 } | 208 } |
216 else if (MARKERP (function)) | 209 else if (MARKERP (function)) |
217 { | 210 { |
218 /* marker_position will err if marker doesn't point anywhere */ | 211 /* marker_position() will err if marker doesn't point anywhere. */ |
219 Bufpos spoint = marker_position (function); | 212 Bufpos spoint = marker_position (function); |
220 | 213 |
221 buffer_insert_string_1 (XBUFFER (Fmarker_buffer (function)), | 214 buffer_insert_string_1 (XMARKER (function)->buffer, |
222 spoint, nonreloc, reloc, offset, len, | 215 spoint, nonreloc, reloc, offset, len, |
223 0); | 216 0); |
224 Fset_marker (function, make_int (spoint + cclen), | 217 Fset_marker (function, make_int (spoint + cclen), |
225 Fmarker_buffer (function)); | 218 Fmarker_buffer (function)); |
226 } | 219 } |
227 else if (FRAMEP (function)) | 220 else if (FRAMEP (function)) |
228 { | 221 { |
222 /* This gets used by functions not invoking print_prepare(), | |
223 such as Fwrite_char. */ | |
229 struct frame *f = XFRAME (function); | 224 struct frame *f = XFRAME (function); |
225 CHECK_LIVE_FRAME (function); | |
226 | |
230 if (!EQ (Vprint_message_label, echo_area_status (f))) | 227 if (!EQ (Vprint_message_label, echo_area_status (f))) |
231 clear_echo_area_from_print (f, Qnil, 1); | 228 clear_echo_area_from_print (f, Qnil, 1); |
232 echo_area_append (f, nonreloc, reloc, offset, len, Vprint_message_label); | 229 echo_area_append (f, nonreloc, reloc, offset, len, Vprint_message_label); |
233 } | 230 } |
234 #endif /* not standalone */ | |
235 else if (EQ (function, Qt) || EQ (function, Qnil)) | 231 else if (EQ (function, Qt) || EQ (function, Qnil)) |
236 { | 232 { |
237 write_string_to_stdio_stream (stdout, 0, newnonreloc, offset, len, | 233 write_string_to_stdio_stream (stdout, 0, newnonreloc, offset, len, |
238 FORMAT_TERMINAL); | 234 FORMAT_TERMINAL); |
239 } | 235 } |
240 else | 236 else |
241 { | 237 { |
238 Charcount ccoff = bytecount_to_charcount (newnonreloc, offset); | |
242 Charcount iii; | 239 Charcount iii; |
243 | 240 |
244 for (iii = ccoff; iii < cclen + ccoff; iii++) | 241 for (iii = ccoff; iii < cclen + ccoff; iii++) |
245 { | 242 { |
246 call1 (function, | 243 call1 (function, |
250 } | 247 } |
251 } | 248 } |
252 | 249 |
253 UNGCPRO; | 250 UNGCPRO; |
254 } | 251 } |
252 | |
253 #define RESET_PRINT_GENSYM do { \ | |
254 if (!CONSP (Vprint_gensym)) \ | |
255 Vprint_gensym_alist = Qnil; \ | |
256 } while (0) | |
255 | 257 |
256 static Lisp_Object | 258 static Lisp_Object |
257 canonicalize_printcharfun (Lisp_Object printcharfun) | 259 canonicalize_printcharfun (Lisp_Object printcharfun) |
258 { | 260 { |
259 if (NILP (printcharfun)) | 261 if (NILP (printcharfun)) |
260 printcharfun = Vstandard_output; | 262 printcharfun = Vstandard_output; |
261 | 263 |
262 if (EQ (printcharfun, Qt) || NILP (printcharfun)) | 264 if (EQ (printcharfun, Qt) || NILP (printcharfun)) |
263 { | 265 printcharfun = Fselected_frame (Qnil); /* print to minibuffer */ |
264 #ifndef standalone | 266 |
265 printcharfun = Fselected_frame (Qnil); /* print to minibuffer */ | |
266 #endif | |
267 } | |
268 return printcharfun; | 267 return printcharfun; |
269 } | 268 } |
270 | 269 |
271 /* Now that print_streams are dead, I wonder if the following two | |
272 functions are needed as separate entities. */ | |
273 | |
274 static Lisp_Object | 270 static Lisp_Object |
275 print_prepare (Lisp_Object printcharfun) | 271 print_prepare (Lisp_Object printcharfun, Lisp_Object *frame_kludge) |
276 { | 272 { |
277 /* Emacs won't print whilst GCing, but an external debugger might */ | 273 /* Emacs won't print whilst GCing, but an external debugger might */ |
278 if (gc_in_progress) | 274 if (gc_in_progress) |
279 return Qnil; | 275 return Qnil; |
280 | 276 |
277 RESET_PRINT_GENSYM; | |
278 | |
281 printcharfun = canonicalize_printcharfun (printcharfun); | 279 printcharfun = canonicalize_printcharfun (printcharfun); |
282 if (!CONSP (Vprint_gensym)) | 280 |
283 Vprint_gensym_alist = Qnil; | 281 /* Here we could safely return the canonicalized PRINTCHARFUN. |
282 However, if PRINTCHARFUN is a frame, printing of complex | |
283 structures becomes very expensive, because `append-message' | |
284 (called by echo_area_append) gets called as many times as | |
285 output_string() is called (and that's a *lot*). append-message | |
286 tries to keep top of the message-stack in sync with the contents | |
287 of " *Echo Area" buffer, consing a new string for each component | |
288 of the printed structure. For instance, if you print (a a), | |
289 append-message will cons up the following strings: | |
290 | |
291 "(" | |
292 "(a" | |
293 "(a " | |
294 "(a a" | |
295 "(a a)" | |
296 | |
297 and will use only the last one. With larger objects, this turns | |
298 into an O(n^2) consing frenzy that locks up XEmacs in incessant | |
299 garbage collection. | |
300 | |
301 We prevent this by creating a resizing_buffer stream and letting | |
302 the printer write into it. print_finish() will notice this | |
303 stream, and invoke echo_area_append() with the stream's buffer, | |
304 only once. */ | |
305 if (FRAMEP (printcharfun)) | |
306 { | |
307 CHECK_LIVE_FRAME (printcharfun); | |
308 *frame_kludge = printcharfun; | |
309 printcharfun = make_resizing_buffer_output_stream (); | |
310 } | |
284 | 311 |
285 return printcharfun; | 312 return printcharfun; |
286 } | 313 } |
287 | 314 |
288 static void | 315 static void |
289 print_finish (Lisp_Object stream) | 316 print_finish (Lisp_Object stream, Lisp_Object frame_kludge) |
290 { | 317 { |
291 /* Emacs won't print whilst GCing, but an external debugger might */ | 318 /* Emacs won't print whilst GCing, but an external debugger might */ |
292 if (gc_in_progress) | 319 if (gc_in_progress) |
293 return; | 320 return; |
294 | 321 |
295 if (!CONSP (Vprint_gensym)) | 322 RESET_PRINT_GENSYM; |
296 Vprint_gensym_alist = Qnil; | 323 |
297 } | 324 /* See the comment in print_prepare(). */ |
298 | 325 if (FRAMEP (frame_kludge)) |
299 #if 1 /* Prefer space over "speed" */ | 326 { |
300 #define write_char_internal(string_of_length_1, stream) \ | 327 struct frame *f = XFRAME (frame_kludge); |
301 write_string_1 ((CONST Bufbyte *) (string_of_length_1), 1, (stream)) | 328 Lstream *str = XLSTREAM (stream); |
302 #else | 329 CHECK_LIVE_FRAME (frame_kludge); |
303 #define write_char_internal(string_of_length_1, stream) \ | 330 |
304 output_string ((stream), (CONST Bufbyte *) (string_of_length_1), Qnil, 0, 1) | 331 Lstream_flush (str); |
305 #endif | 332 if (!EQ (Vprint_message_label, echo_area_status (f))) |
333 clear_echo_area_from_print (f, Qnil, 1); | |
334 echo_area_append (f, resizing_buffer_stream_ptr (str), | |
335 Qnil, 0, Lstream_byte_count (str), | |
336 Vprint_message_label); | |
337 Lstream_delete (str); | |
338 } | |
339 } | |
340 | |
341 /* Used for printing a character. STRING_OF_LENGTH_1 must contain a | |
342 single-byte character, not just any emchar. */ | |
343 #define write_char_internal(string_of_length_1, stream) \ | |
344 output_string ((stream), (CONST Bufbyte *) (string_of_length_1), \ | |
345 Qnil, 0, 1) | |
306 | 346 |
307 /* NOTE: Do not call this with the data of a Lisp_String, | 347 /* NOTE: Do not call this with the data of a Lisp_String, |
308 * as printcharfun might cause a GC, which might cause | 348 * as printcharfun might cause a GC, which might cause |
309 * the string's data to be relocated. | 349 * the string's data to be relocated. |
310 * Use print_object_internal (string, printcharfun, 0) | 350 * Use print_internal (string, printcharfun, 0) |
311 * to princ a Lisp_String | 351 * to princ a Lisp_String |
312 * Note: "stream" should be the result of "canonicalize_printcharfun" | 352 * Note: "stream" should be the result of "canonicalize_printcharfun" |
313 * (ie Qnil means stdout, not Vstandard_output, etc) | 353 * (ie Qnil means stdout, not Vstandard_output, etc) |
314 */ | 354 */ |
315 void | 355 void |
316 write_string_1 (CONST Bufbyte *str, Bytecount size, Lisp_Object stream) | 356 write_string_1 (CONST Bufbyte *str, Bytecount size, Lisp_Object stream) |
317 { | 357 { |
318 /* This function can GC */ | 358 /* This function can GC */ |
359 #ifdef ERROR_CHECK_BUFPOS | |
319 assert (size >= 0); | 360 assert (size >= 0); |
361 #endif | |
320 output_string (stream, str, Qnil, 0, size); | 362 output_string (stream, str, Qnil, 0, size); |
321 } | 363 } |
322 | 364 |
323 void | 365 void |
324 write_c_string (CONST char *str, Lisp_Object stream) | 366 write_c_string (CONST char *str, Lisp_Object stream) |
337 /* This function can GC */ | 379 /* This function can GC */ |
338 Bufbyte str[MAX_EMCHAR_LEN]; | 380 Bufbyte str[MAX_EMCHAR_LEN]; |
339 Bytecount len; | 381 Bytecount len; |
340 | 382 |
341 CHECK_CHAR_COERCE_INT (ch); | 383 CHECK_CHAR_COERCE_INT (ch); |
384 RESET_PRINT_GENSYM; | |
342 len = set_charptr_emchar (str, XCHAR (ch)); | 385 len = set_charptr_emchar (str, XCHAR (ch)); |
343 output_string (canonicalize_printcharfun (stream), str, Qnil, 0, len); | 386 output_string (canonicalize_printcharfun (stream), str, Qnil, 0, len); |
387 RESET_PRINT_GENSYM; | |
344 return ch; | 388 return ch; |
345 } | 389 } |
346 | |
347 #ifndef standalone | |
348 | 390 |
349 void | 391 void |
350 temp_output_buffer_setup (CONST char *bufname) | 392 temp_output_buffer_setup (CONST char *bufname) |
351 { | 393 { |
352 /* This function can GC */ | 394 /* This function can GC */ |
426 | 468 |
427 temp_output_buffer_show (Vstandard_output, Qnil); | 469 temp_output_buffer_show (Vstandard_output, Qnil); |
428 | 470 |
429 return unbind_to (speccount, val); | 471 return unbind_to (speccount, val); |
430 } | 472 } |
431 #endif /* not standalone */ | |
432 | 473 |
433 DEFUN ("terpri", Fterpri, 0, 1, 0, /* | 474 DEFUN ("terpri", Fterpri, 0, 1, 0, /* |
434 Output a newline to STREAM. | 475 Output a newline to STREAM. |
435 If STREAM is omitted or nil, the value of `standard-output' is used. | 476 If STREAM is omitted or nil, the value of `standard-output' is used. |
436 */ | 477 */ |
450 Output stream is STREAM, or value of `standard-output' (which see). | 491 Output stream is STREAM, or value of `standard-output' (which see). |
451 */ | 492 */ |
452 (object, stream)) | 493 (object, stream)) |
453 { | 494 { |
454 /* This function can GC */ | 495 /* This function can GC */ |
455 Lisp_Object the_stream = Qnil; | 496 Lisp_Object the_stream = Qnil, frame = Qnil; |
456 struct gcpro gcpro1, gcpro2, gcpro3; | 497 struct gcpro gcpro1, gcpro2, gcpro3; |
457 | 498 |
458 GCPRO3 (object, stream, the_stream); | 499 GCPRO3 (object, stream, the_stream); |
459 print_depth = 0; | 500 print_depth = 0; |
460 the_stream = print_prepare (stream); | 501 the_stream = print_prepare (stream, &frame); |
461 print_internal (object, the_stream, 1); | 502 print_internal (object, the_stream, 1); |
462 print_finish (the_stream); | 503 print_finish (the_stream, frame); |
463 UNGCPRO; | 504 UNGCPRO; |
464 return object; | 505 return object; |
465 } | 506 } |
466 | |
467 /* Stream to which prin1-to-string prints. */ | |
468 static Lisp_Object Vprin1_to_string_stream; | |
469 | 507 |
470 DEFUN ("prin1-to-string", Fprin1_to_string, 1, 2, 0, /* | 508 DEFUN ("prin1-to-string", Fprin1_to_string, 1, 2, 0, /* |
471 Return a string containing the printed representation of OBJECT, | 509 Return a string containing the printed representation of OBJECT, |
472 any Lisp object. Quoting characters are used when needed to make output | 510 any Lisp object. Quoting characters are used when needed to make output |
473 that `read' can handle, whenever this is possible, unless the optional | 511 that `read' can handle, whenever this is possible, unless the optional |
474 second argument NOESCAPE is non-nil. | 512 second argument NOESCAPE is non-nil. |
475 */ | 513 */ |
476 (object, noescape)) | 514 (object, noescape)) |
477 { | 515 { |
478 /* This function can GC */ | 516 /* This function can GC */ |
479 Lstream *stream; | 517 Lisp_Object stream; |
480 struct gcpro gcpro1; | 518 Lstream *str; |
481 | 519 struct gcpro gcpro1, gcpro2; |
482 /* We avoid creating a new stream for every invocation of | 520 |
483 prin1_to_string, for better memory usage. #### Is it necessary? */ | 521 stream = make_resizing_buffer_output_stream (); |
484 | 522 str = XLSTREAM (stream); |
485 if (NILP (Vprin1_to_string_stream)) | 523 |
486 Vprin1_to_string_stream = make_resizing_buffer_output_stream (); | 524 /* Protect OBJECT, in case a caller forgot to protect. */ |
487 stream = XLSTREAM (Vprin1_to_string_stream); | 525 GCPRO2 (object, stream); |
488 Lstream_rewind (stream); | |
489 | |
490 /* In case a caller forgot to protect. */ | |
491 GCPRO1 (object); | |
492 print_depth = 0; | 526 print_depth = 0; |
493 if (!CONSP (Vprint_gensym)) | 527 RESET_PRINT_GENSYM; |
494 Vprint_gensym_alist = Qnil; | 528 print_internal (object, stream, NILP (noescape)); |
495 print_internal (object, Vprin1_to_string_stream, NILP (noescape)); | 529 RESET_PRINT_GENSYM; |
496 if (!CONSP (Vprint_gensym)) | 530 Lstream_flush (str); |
497 Vprint_gensym_alist = Qnil; | |
498 Lstream_flush (stream); | |
499 UNGCPRO; | 531 UNGCPRO; |
500 return make_string (resizing_buffer_stream_ptr (stream), | 532 return make_string (resizing_buffer_stream_ptr (str), |
501 Lstream_byte_count (stream)); | 533 Lstream_byte_count (str)); |
502 } | 534 } |
503 | 535 |
504 DEFUN ("princ", Fprinc, 1, 2, 0, /* | 536 DEFUN ("princ", Fprinc, 1, 2, 0, /* |
505 Output the printed representation of OBJECT, any Lisp object. | 537 Output the printed representation of OBJECT, any Lisp object. |
506 No quoting characters are used; no delimiters are printed around | 538 No quoting characters are used; no delimiters are printed around |
508 Output stream is STREAM, or value of standard-output (which see). | 540 Output stream is STREAM, or value of standard-output (which see). |
509 */ | 541 */ |
510 (obj, stream)) | 542 (obj, stream)) |
511 { | 543 { |
512 /* This function can GC */ | 544 /* This function can GC */ |
513 Lisp_Object the_stream = Qnil; | 545 Lisp_Object the_stream = Qnil, frame = Qnil; |
514 struct gcpro gcpro1, gcpro2, gcpro3; | 546 struct gcpro gcpro1, gcpro2, gcpro3; |
515 | 547 |
516 GCPRO3 (obj, stream, the_stream); | 548 GCPRO3 (obj, stream, the_stream); |
517 the_stream = print_prepare (stream); | 549 the_stream = print_prepare (stream, &frame); |
518 print_depth = 0; | 550 print_depth = 0; |
519 print_internal (obj, the_stream, 0); | 551 print_internal (obj, the_stream, 0); |
520 print_finish (the_stream); | 552 print_finish (the_stream, frame); |
521 UNGCPRO; | 553 UNGCPRO; |
522 return obj; | 554 return obj; |
523 } | 555 } |
524 | 556 |
525 DEFUN ("print", Fprint, 1, 2, 0, /* | 557 DEFUN ("print", Fprint, 1, 2, 0, /* |
529 Output stream is STREAM, or value of `standard-output' (which see). | 561 Output stream is STREAM, or value of `standard-output' (which see). |
530 */ | 562 */ |
531 (obj, stream)) | 563 (obj, stream)) |
532 { | 564 { |
533 /* This function can GC */ | 565 /* This function can GC */ |
534 Lisp_Object the_stream = Qnil; | 566 Lisp_Object the_stream = Qnil, frame = Qnil; |
535 struct gcpro gcpro1, gcpro2, gcpro3; | 567 struct gcpro gcpro1, gcpro2, gcpro3; |
536 | 568 |
537 GCPRO3 (obj, stream, the_stream); | 569 GCPRO3 (obj, stream, the_stream); |
538 the_stream = print_prepare (stream); | 570 the_stream = print_prepare (stream, &frame); |
539 print_depth = 0; | 571 print_depth = 0; |
540 write_char_internal ("\n", the_stream); | 572 write_char_internal ("\n", the_stream); |
541 print_internal (obj, the_stream, 1); | 573 print_internal (obj, the_stream, 1); |
542 write_char_internal ("\n", the_stream); | 574 write_char_internal ("\n", the_stream); |
543 print_finish (the_stream); | 575 print_finish (the_stream, frame); |
544 UNGCPRO; | 576 UNGCPRO; |
545 return obj; | 577 return obj; |
546 } | 578 } |
547 | 579 |
548 | 580 |
759 buf [i+1] = buf [i]; | 791 buf [i+1] = buf [i]; |
760 buf [(buf [0] == '-' ? 1 : 0)] = '0'; | 792 buf [(buf [0] == '-' ? 1 : 0)] = '0'; |
761 } | 793 } |
762 } | 794 } |
763 #endif /* LISP_FLOAT_TYPE */ | 795 #endif /* LISP_FLOAT_TYPE */ |
796 | |
797 /* Print NUMBER to BUFFER. The digits are first written in reverse | |
798 order (the least significant digit first), and are then reversed. | |
799 This is equivalent to sprintf(buffer, "%ld", number), only much | |
800 faster. */ | |
801 void | |
802 long_to_string (char *buffer, long number) | |
803 { | |
804 char *p; | |
805 int i, l; | |
806 | |
807 if (number < 0) | |
808 { | |
809 *buffer++ = '-'; | |
810 number = -number; | |
811 } | |
812 p = buffer; | |
813 /* Print the digits to the string. */ | |
814 do | |
815 { | |
816 *p++ = number % 10 + '0'; | |
817 number /= 10; | |
818 } | |
819 while (number); | |
820 /* And reverse them. */ | |
821 l = p - buffer - 1; | |
822 for (i = l/2; i >= 0; i--) | |
823 { | |
824 char c = buffer[i]; | |
825 buffer[i] = buffer[l - i]; | |
826 buffer[l - i] = c; | |
827 } | |
828 buffer[l + 1] = '\0'; | |
829 } | |
764 | 830 |
765 static void | 831 static void |
766 print_vector_internal (CONST char *start, CONST char *end, | 832 print_vector_internal (CONST char *start, CONST char *end, |
767 Lisp_Object obj, | 833 Lisp_Object obj, |
768 Lisp_Object printcharfun, int escapeflag) | 834 Lisp_Object printcharfun, int escapeflag) |
909 else | 975 else |
910 { | 976 { |
911 write_char_internal ("\\", printcharfun); | 977 write_char_internal ("\\", printcharfun); |
912 /* This is correct for Mule because the | 978 /* This is correct for Mule because the |
913 character is either \ or " */ | 979 character is either \ or " */ |
914 write_char_internal ((char *) (string_data (s) + i), | 980 write_char_internal (string_data (s) + i, printcharfun); |
915 printcharfun); | |
916 } | 981 } |
917 last = i + 1; | 982 last = i + 1; |
918 } | 983 } |
919 } | 984 } |
920 if (bcmax > last) | 985 if (bcmax > last) |
925 if (max < size) | 990 if (max < size) |
926 write_c_string (" ...", printcharfun); | 991 write_c_string (" ...", printcharfun); |
927 write_char_internal ("\"", printcharfun); | 992 write_char_internal ("\"", printcharfun); |
928 } | 993 } |
929 UNGCPRO; | 994 UNGCPRO; |
930 return; | |
931 } | |
932 | |
933 /* Print NUMBER to BUFFER. The digits are first written in reverse | |
934 order (the least significant digit first), and are then reversed. | |
935 This is equivalent to sprintf(buffer, "%ld", number), only much | |
936 faster. */ | |
937 void | |
938 long_to_string (char *buffer, long number) | |
939 { | |
940 char *p; | |
941 int i, l; | |
942 | |
943 if (number < 0) | |
944 { | |
945 *buffer++ = '-'; | |
946 number = -number; | |
947 } | |
948 p = buffer; | |
949 /* Print the digits to the string. */ | |
950 do | |
951 { | |
952 *p++ = number % 10 + '0'; | |
953 number /= 10; | |
954 } | |
955 while (number); | |
956 /* And reverse them. */ | |
957 l = p - buffer - 1; | |
958 for (i = l/2; i >= 0; i--) | |
959 { | |
960 char c = buffer[i]; | |
961 buffer[i] = buffer[l - i]; | |
962 buffer[l - i] = c; | |
963 } | |
964 buffer[l + 1] = '\0'; | |
965 } | 995 } |
966 | 996 |
967 static void | 997 static void |
968 default_object_printer (Lisp_Object obj, Lisp_Object printcharfun, | 998 default_object_printer (Lisp_Object obj, Lisp_Object printcharfun, |
969 int escapeflag) | 999 int escapeflag) |
986 void | 1016 void |
987 internal_object_printer (Lisp_Object obj, Lisp_Object printcharfun, | 1017 internal_object_printer (Lisp_Object obj, Lisp_Object printcharfun, |
988 int escapeflag) | 1018 int escapeflag) |
989 { | 1019 { |
990 char buf[200]; | 1020 char buf[200]; |
991 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (%s) 0x%p>", | 1021 sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (%s) 0x%lx>", |
992 XRECORD_LHEADER_IMPLEMENTATION (obj)->name, | 1022 XRECORD_LHEADER_IMPLEMENTATION (obj)->name, |
993 (void *) XPNTR (obj)); | 1023 (unsigned long) XPNTR (obj)); |
994 write_c_string (buf, printcharfun); | 1024 write_c_string (buf, printcharfun); |
995 } | 1025 } |
996 | 1026 |
997 void | 1027 void |
998 print_internal (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 1028 print_internal (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
1054 | 1084 |
1055 case Lisp_Type_Char: | 1085 case Lisp_Type_Char: |
1056 { | 1086 { |
1057 /* God intended that this be #\..., you know. */ | 1087 /* God intended that this be #\..., you know. */ |
1058 Emchar ch = XCHAR (obj); | 1088 Emchar ch = XCHAR (obj); |
1059 write_c_string ("?", printcharfun); | 1089 char *p = buf; |
1090 *p++ = '?'; | |
1060 if (ch == '\n') | 1091 if (ch == '\n') |
1061 strcpy (buf, "\\n"); | 1092 *p++ = '\\', *p++ = 'n'; |
1062 else if (ch == '\r') | 1093 else if (ch == '\r') |
1063 strcpy (buf, "\\r"); | 1094 *p++ = '\\', *p++ = 'r'; |
1064 else if (ch == '\t') | 1095 else if (ch == '\t') |
1065 strcpy (buf, "\\t"); | 1096 *p++ = '\\', *p++ = 't'; |
1066 else if (ch < 32) { | 1097 else if (ch < 32) |
1067 sprintf (buf, "\\^%c", ch + 64); | 1098 { |
1068 if ((ch + 64) == '\\') { | 1099 *p++ = '\\', *p++ = '^'; |
1069 strcat(buf, "\\"); | 1100 *p++ = ch + 64; |
1101 if ((ch + 64) == '\\') | |
1102 *p++ = '\\'; | |
1070 } | 1103 } |
1071 } else if (ch == 127) | 1104 else if (ch == 127) |
1072 strcpy (buf, "\\^?"); | 1105 *p++ = '\\', *p++ = '^', *p++ = '?'; |
1073 else if (ch >= 128 && ch < 160) | 1106 else if (ch >= 128 && ch < 160) |
1074 { | 1107 { |
1075 Bytecount i; | 1108 *p++ = '\\', *p++ = '^'; |
1076 strcpy (buf, "\\^"); | 1109 p += set_charptr_emchar ((Bufbyte *)p, ch + 64); |
1077 i = set_charptr_emchar ((unsigned char *) (buf + 2), ch + 64); | |
1078 buf[2+i] = '\0'; | |
1079 } | 1110 } |
1080 else if (ch < 127 | 1111 else if (ch < 127 |
1081 && !isdigit (ch) | 1112 && !isdigit (ch) |
1082 && !isalpha (ch) | 1113 && !isalpha (ch) |
1083 && ch != '^') /* must not backslash this or it will | 1114 && ch != '^') /* must not backslash this or it will |
1084 be interpreted as the start of a | 1115 be interpreted as the start of a |
1085 control char */ | 1116 control char */ |
1086 sprintf (buf, "\\%c", ch); | 1117 *p++ = '\\', *p++ = ch; |
1087 else | 1118 else |
1088 { | 1119 p += set_charptr_emchar ((Bufbyte *)p, ch); |
1089 Bytecount i; | 1120 output_string (printcharfun, (Bufbyte *)buf, Qnil, 0, p - buf); |
1090 i = set_charptr_emchar ((unsigned char *) buf, ch); | |
1091 buf[i] = '\0'; | |
1092 } | |
1093 write_c_string (buf, printcharfun); | |
1094 break; | 1121 break; |
1095 } | 1122 } |
1096 | 1123 |
1097 #ifndef LRECORD_STRING | 1124 #ifndef LRECORD_STRING |
1098 case Lisp_Type_String: | 1125 case Lisp_Type_String: |
1099 { | 1126 { |
1100 print_string(obj, printcharfun, escapeflag); | 1127 print_string (obj, printcharfun, escapeflag); |
1101 break; | 1128 break; |
1102 } | 1129 } |
1103 #endif /* ! LRECORD_STRING */ | 1130 #endif /* ! LRECORD_STRING */ |
1104 | 1131 |
1105 #ifndef LRECORD_CONS | 1132 #ifndef LRECORD_CONS |
1123 #endif /* ! LRECORD_CONS */ | 1150 #endif /* ! LRECORD_CONS */ |
1124 | 1151 |
1125 #ifndef LRECORD_VECTOR | 1152 #ifndef LRECORD_VECTOR |
1126 case Lisp_Type_Vector: | 1153 case Lisp_Type_Vector: |
1127 { | 1154 { |
1128 struct gcpro gcpro1, gcpro2; | |
1129 | |
1130 /* If deeper than spec'd depth, print placeholder. */ | 1155 /* If deeper than spec'd depth, print placeholder. */ |
1131 if (INTP (Vprint_level) | 1156 if (INTP (Vprint_level) |
1132 && print_depth > XINT (Vprint_level)) | 1157 && print_depth > XINT (Vprint_level)) |
1133 { | 1158 { |
1159 struct gcpro gcpro1, gcpro2; | |
1134 GCPRO2 (obj, printcharfun); | 1160 GCPRO2 (obj, printcharfun); |
1135 write_c_string ("...", printcharfun); | 1161 write_c_string ("...", printcharfun); |
1136 UNGCPRO; | 1162 UNGCPRO; |
1137 break; | 1163 break; |
1138 } | 1164 } |
1291 print_symbol (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 1317 print_symbol (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
1292 { | 1318 { |
1293 /* This function can GC */ | 1319 /* This function can GC */ |
1294 /* #### Bug!! (intern "") isn't printed in some distinguished way */ | 1320 /* #### Bug!! (intern "") isn't printed in some distinguished way */ |
1295 /* #### (the reader also loses on it) */ | 1321 /* #### (the reader also loses on it) */ |
1296 struct Lisp_String *name = XSYMBOL (obj)->name; | 1322 struct Lisp_String *name = symbol_name (XSYMBOL (obj)); |
1297 Bytecount size = string_length (name); | 1323 Bytecount size = string_length (name); |
1298 struct gcpro gcpro1, gcpro2; | 1324 struct gcpro gcpro1, gcpro2; |
1299 | 1325 |
1300 if (!escapeflag) | 1326 if (!escapeflag) |
1301 { | 1327 { |
1370 } | 1396 } |
1371 not_yet_confused: | 1397 not_yet_confused: |
1372 | 1398 |
1373 #ifdef LISP_FLOAT_TYPE | 1399 #ifdef LISP_FLOAT_TYPE |
1374 if (!confusing) | 1400 if (!confusing) |
1401 /* #### Ugh, this is needlessly complex and slow for what we | |
1402 need here. It might be a good idea to copy equivalent code | |
1403 from FSF. --hniksic */ | |
1375 confusing = isfloat_string ((char *) data); | 1404 confusing = isfloat_string ((char *) data); |
1376 #endif | 1405 #endif |
1377 if (confusing) | 1406 if (confusing) |
1378 write_char_internal ("\\", printcharfun); | 1407 write_char_internal ("\\", printcharfun); |
1379 } | 1408 } |
1404 output_string (printcharfun, 0, nameobj, last, size - last); | 1433 output_string (printcharfun, 0, nameobj, last, size - last); |
1405 } | 1434 } |
1406 UNGCPRO; | 1435 UNGCPRO; |
1407 } | 1436 } |
1408 | 1437 |
1438 /* #ifdef DEBUG_XEMACS */ | |
1439 /* I don't like seeing `Note: Strange doc (not fboundp) for function */ | |
1440 /* alternate-debugging-output @ 429542' -slb */ | |
1409 int alternate_do_pointer; | 1441 int alternate_do_pointer; |
1410 char alternate_do_string[5000]; | 1442 char alternate_do_string[5000]; |
1411 | 1443 |
1412 DEFUN ("alternate-debugging-output", Falternate_debugging_output, 1, 1, 0, /* | 1444 DEFUN ("alternate-debugging-output", Falternate_debugging_output, 1, 1, 0, /* |
1413 Append CHARACTER to the array `alternate_do_string'. | 1445 Append CHARACTER to the array `alternate_do_string'. |
1414 This can be used in place of `external-debugging-output' as a function | 1446 This can be used in place of `external-debugging-output' as a function |
1415 to be passed to `print'. Before calling `print', set `alternate_do_pointer' | 1447 to be passed to `print'. Before calling `print', set `alternate_do_pointer' |
1416 to 0. | 1448 to 0. |
1417 | |
1418 */ | 1449 */ |
1419 (character)) | 1450 (character)) |
1420 { | 1451 { |
1421 Bufbyte str[MAX_EMCHAR_LEN]; | 1452 Bufbyte str[MAX_EMCHAR_LEN]; |
1422 Bytecount len; | 1453 Bytecount len; |
1429 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); | 1460 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); |
1430 alternate_do_pointer += extlen; | 1461 alternate_do_pointer += extlen; |
1431 alternate_do_string[alternate_do_pointer] = 0; | 1462 alternate_do_string[alternate_do_pointer] = 0; |
1432 return character; | 1463 return character; |
1433 } | 1464 } |
1465 /* #endif /* DEBUG_XEMACS */ | |
1434 | 1466 |
1435 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* | 1467 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* |
1436 Write CHAR-OR-STRING to stderr or stdout. | 1468 Write CHAR-OR-STRING to stderr or stdout. |
1437 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write | 1469 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write |
1438 to stderr. You can use this function to write directly to the terminal. | 1470 to stderr. You can use this function to write directly to the terminal. |
1500 if (! NILP (file)) | 1532 if (! NILP (file)) |
1501 { | 1533 { |
1502 file = Fexpand_file_name (file, Qnil); | 1534 file = Fexpand_file_name (file, Qnil); |
1503 termscript = fopen ((char *) XSTRING_DATA (file), "w"); | 1535 termscript = fopen ((char *) XSTRING_DATA (file), "w"); |
1504 if (termscript == NULL) | 1536 if (termscript == NULL) |
1505 report_file_error ("Opening termscript", Fcons (file, Qnil)); | 1537 report_file_error ("Opening termscript", list1 (file)); |
1506 } | 1538 } |
1507 return Qnil; | 1539 return Qnil; |
1508 } | 1540 } |
1509 | 1541 |
1510 #if 1 | 1542 #if 1 |
1670 DEFSUBR (Falternate_debugging_output); | 1702 DEFSUBR (Falternate_debugging_output); |
1671 defsymbol (&Qalternate_debugging_output, "alternate-debugging-output"); | 1703 defsymbol (&Qalternate_debugging_output, "alternate-debugging-output"); |
1672 DEFSUBR (Fexternal_debugging_output); | 1704 DEFSUBR (Fexternal_debugging_output); |
1673 DEFSUBR (Fopen_termscript); | 1705 DEFSUBR (Fopen_termscript); |
1674 defsymbol (&Qexternal_debugging_output, "external-debugging-output"); | 1706 defsymbol (&Qexternal_debugging_output, "external-debugging-output"); |
1675 #ifndef standalone | |
1676 DEFSUBR (Fwith_output_to_temp_buffer); | 1707 DEFSUBR (Fwith_output_to_temp_buffer); |
1677 #endif /* not standalone */ | |
1678 } | 1708 } |
1679 | 1709 |
1680 void | 1710 void |
1681 vars_of_print (void) | 1711 vars_of_print (void) |
1682 { | 1712 { |
1782 DEFVAR_LISP ("print-message-label", &Vprint_message_label /* | 1812 DEFVAR_LISP ("print-message-label", &Vprint_message_label /* |
1783 Label for minibuffer messages created with `print'. This should | 1813 Label for minibuffer messages created with `print'. This should |
1784 generally be bound with `let' rather than set. (See `display-message'.) | 1814 generally be bound with `let' rather than set. (See `display-message'.) |
1785 */ ); | 1815 */ ); |
1786 Vprint_message_label = Qprint; | 1816 Vprint_message_label = Qprint; |
1787 | 1817 } |
1788 Vprin1_to_string_stream = Qnil; | |
1789 staticpro (&Vprin1_to_string_stream); | |
1790 } |