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 }