Mercurial > hg > xemacs-beta
diff src/print.c @ 280:7df0dd720c89 r21-0b38
Import from CVS: tag r21-0b38
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:32:22 +0200 |
parents | 90d73dddcdc4 |
children | c42ec1d1cded |
line wrap: on
line diff
--- a/src/print.c Mon Aug 13 10:31:30 2007 +0200 +++ b/src/print.c Mon Aug 13 10:32:22 2007 +0200 @@ -45,8 +45,6 @@ #define DBL_DIG 16 #endif -static void print_error_message (Lisp_Object data, Lisp_Object stream); - Lisp_Object Vstandard_output, Qstandard_output; /* The subroutine object for external-debugging-output is kept here @@ -220,7 +218,7 @@ else if (FRAMEP (function)) { /* This gets used by functions not invoking print_prepare(), - such as Fwrite_char. */ + such as Fwrite_char, Fterpri, etc.. */ struct frame *f = XFRAME (function); CHECK_LIVE_FRAME (function); @@ -337,21 +335,21 @@ Lstream_delete (str); } } - -/* Used for printing a character. STRING_OF_LENGTH_1 must contain a - single-byte character, not just any emchar. */ + +/* Used for printing a single-byte character (*not* any Emchar). */ #define write_char_internal(string_of_length_1, stream) \ - output_string ((stream), (CONST Bufbyte *) (string_of_length_1), \ + output_string (stream, (CONST Bufbyte *) (string_of_length_1), \ Qnil, 0, 1) -/* NOTE: Do not call this with the data of a Lisp_String, - * as printcharfun might cause a GC, which might cause - * the string's data to be relocated. - * Use print_internal (string, printcharfun, 0) - * to princ a Lisp_String - * Note: "stream" should be the result of "canonicalize_printcharfun" - * (ie Qnil means stdout, not Vstandard_output, etc) - */ +/* NOTE: Do not call this with the data of a Lisp_String, as + printcharfun might cause a GC, which might cause the string's data + to be relocated. To princ a Lisp string, use: + + print_internal (string, printcharfun, 0); + + Also note that STREAM should be the result of + canonicalize_printcharfun() (i.e. Qnil means stdout, not + Vstandard_output, etc.) */ void write_string_1 (CONST Bufbyte *str, Bytecount size, Lisp_Object stream) { @@ -381,10 +379,8 @@ Bytecount len; CHECK_CHAR_COERCE_INT (ch); - RESET_PRINT_GENSYM; len = set_charptr_emchar (str, XCHAR (ch)); output_string (canonicalize_printcharfun (stream), str, Qnil, 0, len); - RESET_PRINT_GENSYM; return ch; } @@ -478,9 +474,7 @@ (stream)) { /* This function can GC */ - Bufbyte str[1]; - str[0] = '\n'; - output_string (canonicalize_printcharfun (stream), str, Qnil, 0, 1); + write_char_internal ("\n", canonicalize_printcharfun (stream)); return Qt; } @@ -493,14 +487,15 @@ (object, stream)) { /* This function can GC */ - Lisp_Object the_stream = Qnil, frame = Qnil; - struct gcpro gcpro1, gcpro2, gcpro3; + Lisp_Object frame = Qnil; + struct gcpro gcpro1, gcpro2; + GCPRO2 (object, stream); - GCPRO3 (object, stream, the_stream); print_depth = 0; - the_stream = print_prepare (stream, &frame); - print_internal (object, the_stream, 1); - print_finish (the_stream, frame); + stream = print_prepare (stream, &frame); + print_internal (object, stream, 1); + print_finish (stream, frame); + UNGCPRO; return object; } @@ -514,23 +509,23 @@ (object, noescape)) { /* This function can GC */ - Lisp_Object stream; - Lstream *str; - struct gcpro gcpro1, gcpro2; + Lisp_Object result = Qnil; + Lisp_Object stream = make_resizing_buffer_output_stream (); + Lstream *str = XLSTREAM (stream); + /* gcpro OBJECT in case a caller forgot to do so */ + struct gcpro gcpro1, gcpro2, gcpro3; + GCPRO3 (object, stream, result); - stream = make_resizing_buffer_output_stream (); - str = XLSTREAM (stream); - - /* Protect OBJECT, in case a caller forgot to protect. */ - GCPRO2 (object, stream); print_depth = 0; RESET_PRINT_GENSYM; print_internal (object, stream, NILP (noescape)); RESET_PRINT_GENSYM; Lstream_flush (str); UNGCPRO; - return make_string (resizing_buffer_stream_ptr (str), - Lstream_byte_count (str)); + result = make_string (resizing_buffer_stream_ptr (str), + Lstream_byte_count (str)); + Lstream_delete (str); + return result; } DEFUN ("princ", Fprinc, 1, 2, 0, /* @@ -539,19 +534,19 @@ the contents of strings. Output stream is STREAM, or value of standard-output (which see). */ - (obj, stream)) + (object, stream)) { /* This function can GC */ - Lisp_Object the_stream = Qnil, frame = Qnil; - struct gcpro gcpro1, gcpro2, gcpro3; + Lisp_Object frame = Qnil; + struct gcpro gcpro1, gcpro2; - GCPRO3 (obj, stream, the_stream); - the_stream = print_prepare (stream, &frame); + GCPRO2 (object, stream); + stream = print_prepare (stream, &frame); print_depth = 0; - print_internal (obj, the_stream, 0); - print_finish (the_stream, frame); + print_internal (object, stream, 0); + print_finish (stream, frame); UNGCPRO; - return obj; + return object; } DEFUN ("print", Fprint, 1, 2, 0, /* @@ -560,62 +555,40 @@ can handle, whenever this is possible. Output stream is STREAM, or value of `standard-output' (which see). */ - (obj, stream)) + (object, stream)) { /* This function can GC */ - Lisp_Object the_stream = Qnil, frame = Qnil; - struct gcpro gcpro1, gcpro2, gcpro3; + Lisp_Object frame = Qnil; + struct gcpro gcpro1, gcpro2; - GCPRO3 (obj, stream, the_stream); - the_stream = print_prepare (stream, &frame); + GCPRO2 (object, stream); + stream = print_prepare (stream, &frame); print_depth = 0; - write_char_internal ("\n", the_stream); - print_internal (obj, the_stream, 1); - write_char_internal ("\n", the_stream); - print_finish (the_stream, frame); + write_char_internal ("\n", stream); + print_internal (object, stream, 1); + write_char_internal ("\n", stream); + print_finish (stream, frame); UNGCPRO; - return obj; + return object; } - -/* Synched with Emacs 19.34 -- underlying implementation (incarnated - in print_error_message) is completely divergent, though. */ -DEFUN ("error-message-string", Ferror_message_string, 1, 1, 0, /* -Convert an error value (ERROR-SYMBOL . DATA) to an error message. -*/ - (data)) -{ - /* This function can GC */ - Lisp_Object stream = make_resizing_buffer_output_stream (); - struct gcpro gcpro1; - GCPRO1 (stream); +/* Print an error message for the error DATA to STREAM. This is a + complete implementation of `display-error', which used to be in + Lisp (see prim/cmdloop.el). It was ported to C so it can be used + efficiently by Ferror_message_string. Fdisplay_error and + Ferror_message_string are trivial wrappers around this function. - print_error_message (data, stream); - Lstream_flush (XLSTREAM (stream)); - UNGCPRO; - return make_string (resizing_buffer_stream_ptr (XLSTREAM (stream)), - Lstream_byte_count (XLSTREAM (stream))); -} - -/* Print an error message for the error DATA onto Lisp output stream - STREAM (suitable for the print functions). - - This is a complete implementation of `display-error', which used to - be in Lisp (see prim/cmdloop.el). It was ported to C so we can use - it in Ferror_message_string. Fdisplay_error and - Ferror_message_string are trivial wrappers to this function. */ + STREAM should be the result of canonicalize_printcharfun(). */ static void print_error_message (Lisp_Object error_object, Lisp_Object stream) { /* This function can GC */ - Lisp_Object type; + Lisp_Object type = Fcar_safe (error_object); Lisp_Object method = Qnil; - Lisp_Object tail = Qnil; - struct gcpro gcpro1; + Lisp_Object tail; - GCPRO1 (tail); - - type = Fcar_safe (error_object); + /* No need to GCPRO anything under the assumption that ERROR_OBJECT + is GCPRO'd. */ if (! (CONSP (error_object) && SYMBOLP (type) && CONSP (Fget (type, Qerror_conditions, Qnil)))) @@ -645,44 +618,40 @@ /* Default method */ { int first = 1; - Lisp_Object printcharfun = canonicalize_printcharfun (stream); int speccount = specpdl_depth (); specbind (Qprint_message_label, Qerror); tail = Fcdr (error_object); if (EQ (type, Qerror)) { - Fprinc (Fcar (tail), stream); + print_internal (Fcar (tail), stream, 0); tail = Fcdr (tail); } else { Lisp_Object errmsg = Fget (type, Qerror_message, Qnil); if (NILP (errmsg)) - Fprinc (type, stream); + print_internal (type, stream, 0); else - Fprinc (errmsg, stream); + print_internal (LISP_GETTEXT (errmsg), stream, 0); } while (!NILP (tail)) { - write_c_string (first ? ": " : ", ", printcharfun); - Fprin1 (Fcar (tail), stream); + write_c_string (first ? ": " : ", ", stream); + print_internal (Fcar (tail), stream, 1); tail = Fcdr (tail); first = 0; } unbind_to (speccount, Qnil); - UNGCPRO; return; - /* Unreached */ + /* not reached */ } error_throw: - UNGCPRO; if (NILP (method)) { - write_c_string ("Peculiar error ", - canonicalize_printcharfun (stream)); - Fprin1 (error_object, stream); + write_c_string (GETTEXT ("Peculiar error "), stream); + print_internal (error_object, stream, 1); return; } else @@ -691,13 +660,38 @@ } } +DEFUN ("error-message-string", Ferror_message_string, 1, 1, 0, /* +Convert ERROR-OBJECT to an error message, and return it. + +The format of ERROR-OBJECT should be (ERROR-SYMBOL . DATA). The +message is equivalent to the one that would be issued by +`display-error' with the same argument. +*/ + (error_object)) +{ + /* This function can GC */ + Lisp_Object result = Qnil; + Lisp_Object stream = make_resizing_buffer_output_stream (); + struct gcpro gcpro1; + GCPRO1 (stream); + + print_error_message (error_object, stream); + Lstream_flush (XLSTREAM (stream)); + result = make_string (resizing_buffer_stream_ptr (XLSTREAM (stream)), + Lstream_byte_count (XLSTREAM (stream))); + Lstream_delete (XLSTREAM (stream)); + + UNGCPRO; + return result; +} + DEFUN ("display-error", Fdisplay_error, 2, 2, 0, /* -Display an error message for ERROR-OBJECT to STREAM. +Display ERROR-OBJECT on STREAM in a user-friendly way. */ (error_object, stream)) { /* This function can GC */ - print_error_message (error_object, stream); + print_error_message (error_object, canonicalize_printcharfun (stream)); return Qnil; } @@ -707,8 +701,6 @@ Lisp_Object Vfloat_output_format; Lisp_Object Qfloat_output_format; -void -float_to_string (char *buf, double data) /* * This buffer should be at least as large as the max string size of the * largest float, printed in the biggest notation. This is undoubtably @@ -722,6 +714,8 @@ * re-writing _doprnt to be more sane)? * -wsr */ +void +float_to_string (char *buf, double data) { Bufbyte *cp, c; int width; @@ -797,12 +791,15 @@ /* Print NUMBER to BUFFER. The digits are first written in reverse order (the least significant digit first), and are then reversed. This is equivalent to sprintf(buffer, "%ld", number), only much - faster. */ + faster. + + BUFFER should accept 24 bytes. This should suffice for the longest + numbers on 64-bit machines. */ void long_to_string (char *buffer, long number) { char *p; - int i, l; + int i, len; if (number < 0) { @@ -810,6 +807,7 @@ number = -number; } p = buffer; + /* Print the digits to the string. */ do { @@ -817,15 +815,16 @@ number /= 10; } while (number); + /* And reverse them. */ - l = p - buffer - 1; - for (i = l/2; i >= 0; i--) + len = p - buffer - 1; + for (i = len / 2; i >= 0; i--) { char c = buffer[i]; - buffer[i] = buffer[l - i]; - buffer[l - i] = c; + buffer[i] = buffer[len - i]; + buffer[len - i] = c; } - buffer[l + 1] = '\0'; + buffer[len + 1] = '\0'; } static void @@ -877,7 +876,7 @@ { obj = XCAR (XCDR (obj)); GCPRO2 (obj, printcharfun); - write_char_internal ("'", printcharfun); + write_char_internal ("\'", printcharfun); UNGCPRO; print_internal (obj, printcharfun, escapeflag); return; @@ -885,6 +884,7 @@ GCPRO2 (obj, printcharfun); write_char_internal ("(", printcharfun); + { int i = 0; int max = 0; @@ -1028,7 +1028,6 @@ print_internal (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) { /* This function can GC */ - char buf[256]; QUIT; @@ -1055,13 +1054,14 @@ for (i = 0; i < print_depth; i++) if (EQ (obj, being_printed[i])) { - sprintf (buf, "#%d", i); + char buf[32]; + *buf = '#'; + long_to_string (buf + 1, i); write_c_string (buf, printcharfun); return; } } - being_printed[print_depth] = obj; print_depth++; @@ -1077,6 +1077,7 @@ case Lisp_Type_Int: #endif { + char buf[24]; long_to_string (buf, XINT (obj)); write_c_string (buf, printcharfun); break; @@ -1085,6 +1086,7 @@ case Lisp_Type_Char: { /* God intended that this be #\..., you know. */ + char buf[16]; Emchar ch = XCHAR (obj); char *p = buf; *p++ = '?'; @@ -1209,8 +1211,9 @@ default: { - /* We're in trouble if this happens! - Probably should just abort () */ + char buf[128]; + /* We're in trouble if this happens! Probably should just + abort () */ if (print_readably) error ("printing illegal data type #o%03o", (int) XTYPE (obj)); @@ -1436,8 +1439,13 @@ } /* #ifdef DEBUG_XEMACS */ -/* I don't like seeing `Note: Strange doc (not fboundp) for function */ -/* alternate-debugging-output @ 429542' -slb */ + +/* I don't like seeing `Note: Strange doc (not fboundp) for function + alternate-debugging-output @ 429542' -slb */ +/* #### Eek! Any clue how to get rid of it? In fact, how about + getting rid of this function altogether? Does anything actually + *use* it? --hniksic */ + int alternate_do_pointer; char alternate_do_string[5000]; @@ -1462,7 +1470,7 @@ alternate_do_string[alternate_do_pointer] = 0; return character; } -/* #endif /* DEBUG_XEMACS */ +/* #endif / * DEBUG_XEMACS */ DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* Write CHAR-OR-STRING to stderr or stdout.