X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/31ca4639ad1bfaa355a3f30ef92eb977bd2c6b78..207cb73c182d432a00fef797428d3b79ab519287:/src/print.c diff --git a/src/print.c b/src/print.c index 2158d06dbc..ccf0e8ed7c 100644 --- a/src/print.c +++ b/src/print.c @@ -21,10 +21,10 @@ along with GNU Emacs. If not, see . */ #include #include -#include + #include "lisp.h" -#include "buffer.h" #include "character.h" +#include "buffer.h" #include "charset.h" #include "keyboard.h" #include "frame.h" @@ -45,15 +45,9 @@ static Lisp_Object Qtemp_buffer_setup_hook; static Lisp_Object Qfloat_output_format; -#include #include #include -/* Default to values appropriate for IEEE floating point. */ -#ifndef DBL_DIG -#define DBL_DIG 15 -#endif - /* Avoid actual stack overflow in print. */ static ptrdiff_t print_depth; @@ -157,7 +151,7 @@ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; else \ { \ int new_size = 1000; \ - print_buffer = (char *) xmalloc (new_size); \ + print_buffer = xmalloc (new_size); \ print_buffer_size = new_size; \ free_print_buffer = 1; \ } \ @@ -173,8 +167,7 @@ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; if (print_buffer_pos != print_buffer_pos_byte \ && NILP (BVAR (current_buffer, enable_multibyte_characters))) \ { \ - unsigned char *temp \ - = (unsigned char *) alloca (print_buffer_pos + 1); \ + unsigned char *temp = alloca (print_buffer_pos + 1); \ copy_text ((unsigned char *) print_buffer, temp, \ print_buffer_pos_byte, 1, 0); \ insert_1_both ((char *) temp, print_buffer_pos, \ @@ -198,8 +191,7 @@ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; ? PT - start_point : 0), \ old_point_byte + (old_point_byte >= start_point_byte \ ? PT_BYTE - start_point_byte : 0)); \ - if (old != current_buffer) \ - set_buffer_internal (old); + set_buffer_internal (old); #define PRINTCHAR(ch) printchar (ch, printcharfun) @@ -393,16 +385,14 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) { /* Output to echo area. */ ptrdiff_t nbytes = SBYTES (string); - char *buffer; /* Copy the string contents so that relocation of STRING by GC does not cause trouble. */ USE_SAFE_ALLOCA; - - SAFE_ALLOCA (buffer, char *, nbytes); + char *buffer = SAFE_ALLOCA (nbytes); memcpy (buffer, SDATA (string), nbytes); - strout (buffer, chars, SBYTES (string), printcharfun); + strout (buffer, chars, nbytes, printcharfun); SAFE_FREE (); } @@ -491,20 +481,20 @@ temp_output_buffer_setup (const char *bufname) register struct buffer *old = current_buffer; register Lisp_Object buf; - record_unwind_protect (set_buffer_if_live, Fcurrent_buffer ()); + record_unwind_current_buffer (); Fset_buffer (Fget_buffer_create (build_string (bufname))); Fkill_all_local_variables (); delete_all_overlays (current_buffer); - BVAR (current_buffer, directory) = BVAR (old, directory); - BVAR (current_buffer, read_only) = Qnil; - BVAR (current_buffer, filename) = Qnil; - BVAR (current_buffer, undo_list) = Qt; + bset_directory (current_buffer, BVAR (old, directory)); + bset_read_only (current_buffer, Qnil); + bset_filename (current_buffer, Qnil); + bset_undo_list (current_buffer, Qt); eassert (current_buffer->overlays_before == NULL); eassert (current_buffer->overlays_after == NULL); - BVAR (current_buffer, enable_multibyte_characters) - = BVAR (&buffer_defaults, enable_multibyte_characters); + bset_enable_multibyte_characters + (current_buffer, BVAR (&buffer_defaults, enable_multibyte_characters)); specbind (Qinhibit_read_only, Qt); specbind (Qinhibit_modification_hooks, Qt); Ferase_buffer (); @@ -589,6 +579,7 @@ A printed representation of an object is text which describes that object. */) (Lisp_Object object, Lisp_Object noescape) { Lisp_Object printcharfun; + bool prev_abort_on_gc; /* struct gcpro gcpro1, gcpro2; */ Lisp_Object save_deactivate_mark; ptrdiff_t count = SPECPDL_INDEX (); @@ -604,7 +595,8 @@ A printed representation of an object is text which describes that object. */) No need for specbind, since errors deactivate the mark. */ save_deactivate_mark = Vdeactivate_mark; /* GCPRO2 (object, save_deactivate_mark); */ - abort_on_gc++; + prev_abort_on_gc = abort_on_gc; + abort_on_gc = 1; printcharfun = Vprin1_to_string_buffer; PRINTPREPARE; @@ -628,7 +620,7 @@ A printed representation of an object is text which describes that object. */) Vdeactivate_mark = save_deactivate_mark; /* UNGCPRO; */ - abort_on_gc--; + abort_on_gc = prev_abort_on_gc; return unbind_to (count, object); } @@ -761,9 +753,9 @@ append to existing target file. */) { if (initial_stderr_stream != NULL) { - BLOCK_INPUT; + block_input (); fclose (stderr); - UNBLOCK_INPUT; + unblock_input (); } stderr = initial_stderr_stream; initial_stderr_stream = NULL; @@ -863,11 +855,11 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, if (!NILP (caller) && SYMBOLP (caller)) { Lisp_Object cname = SYMBOL_NAME (caller); - char *name; + ptrdiff_t cnamelen = SBYTES (cname); USE_SAFE_ALLOCA; - SAFE_ALLOCA (name, char *, SBYTES (cname)); - memcpy (name, SDATA (cname), SBYTES (cname)); - message_dolog (name, SBYTES (cname), 0, 0); + char *name = SAFE_ALLOCA (cnamelen); + memcpy (name, SDATA (cname), cnamelen); + message_dolog (name, cnamelen, 0, 0); message_dolog (": ", 2, 0, 0); SAFE_FREE (); } @@ -912,7 +904,7 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, for (; CONSP (tail); tail = XCDR (tail), sep = ", ") { Lisp_Object obj; - + if (sep) write_string_1 (sep, 2, stream); obj = XCAR (tail); @@ -944,43 +936,49 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, * Given the above, the buffer must be least FLOAT_TO_STRING_BUFSIZE bytes. */ -void +int float_to_string (char *buf, double data) { char *cp; int width; + int len; /* Check for plus infinity in a way that won't lose if there is no plus infinity. */ if (data == data / 2 && data > 1.0) { - strcpy (buf, "1.0e+INF"); - return; + static char const infinity_string[] = "1.0e+INF"; + strcpy (buf, infinity_string); + return sizeof infinity_string - 1; } /* Likewise for minus infinity. */ if (data == data / 2 && data < -1.0) { - strcpy (buf, "-1.0e+INF"); - return; + static char const minus_infinity_string[] = "-1.0e+INF"; + strcpy (buf, minus_infinity_string); + return sizeof minus_infinity_string - 1; } /* Check for NaN in a way that won't fail if there are no NaNs. */ if (! (data * 0.0 >= 0.0)) { /* Prepend "-" if the NaN's sign bit is negative. The sign bit of a double is the bit that is 1 in -0.0. */ + static char const NaN_string[] = "0.0e+NaN"; int i; union { double d; char c[sizeof (double)]; } u_data, u_minus_zero; + int negative = 0; u_data.d = data; u_minus_zero.d = - 0.0; for (i = 0; i < sizeof (double); i++) if (u_data.c[i] & u_minus_zero.c[i]) { - *buf++ = '-'; + *buf = '-'; + negative = 1; break; } - strcpy (buf, "0.0e+NaN"); - return; + strcpy (buf + negative, NaN_string); + return negative + sizeof NaN_string - 1; } if (NILP (Vfloat_output_format) @@ -989,7 +987,7 @@ float_to_string (char *buf, double data) { /* Generate the fewest number of digits that represent the floating point value without losing information. */ - dtoastr (buf, FLOAT_TO_STRING_BUFSIZE - 2, 0, 0, data); + len = dtoastr (buf, FLOAT_TO_STRING_BUFSIZE - 2, 0, 0, data); /* The decimal point must be printed, or the byte compiler can get confused (Bug#8033). */ width = 1; @@ -1032,7 +1030,7 @@ float_to_string (char *buf, double data) if (cp[1] != 0) goto lose; - sprintf (buf, SSDATA (Vfloat_output_format), data); + len = sprintf (buf, SSDATA (Vfloat_output_format), data); } /* Make sure there is a decimal point with digit after, or an @@ -1049,14 +1047,18 @@ float_to_string (char *buf, double data) { cp[1] = '0'; cp[2] = 0; + len++; } else if (*cp == 0) { *cp++ = '.'; *cp++ = '0'; *cp++ = 0; + len += 2; } } + + return len; } @@ -1187,7 +1189,7 @@ print_preprocess (Lisp_Object obj) { case Lisp_String: /* A string may have text properties, which can be circular. */ - traverse_intervals_noorder (STRING_INTERVALS (obj), + traverse_intervals_noorder (string_intervals (obj), print_preprocess_string, Qnil); break; @@ -1208,7 +1210,7 @@ print_preprocess (Lisp_Object obj) if (size & PSEUDOVECTOR_FLAG) size &= PSEUDOVECTOR_SIZE_MASK; for (i = 0; i < size; i++) - print_preprocess (XVECTOR (obj)->contents[i]); + print_preprocess (AREF (obj, i)); if (HASH_TABLE_P (obj)) { /* For hash tables, the key_and_value slot is past `size' because it needs to be marked specially in case @@ -1290,7 +1292,7 @@ static Lisp_Object print_prune_string_charset (Lisp_Object string) { print_check_string_result = 0; - traverse_intervals (STRING_INTERVALS (string), 0, + traverse_intervals (string_intervals (string), 0, print_check_string_charset_prop, string); if (! (print_check_string_result & PRINT_STRING_UNSAFE_CHARSET_FOUND)) { @@ -1332,8 +1334,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag for (i = 0; i < print_depth; i++) if (EQ (obj, being_printed[i])) { - sprintf (buf, "#%d", i); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "#%d", i); + strout (buf, len, len, printcharfun); return; } being_printed[print_depth] = obj; @@ -1348,16 +1350,16 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag if (n < 0) { /* Add a prefix #n= if OBJ has not yet been printed; that is, its status field is nil. */ - sprintf (buf, "#%"pI"d=", -n); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "#%"pI"d=", -n); + strout (buf, len, len, printcharfun); /* OBJ is going to be printed. Remember that fact. */ Fputhash (obj, make_number (- n), Vprint_number_table); } else { /* Just print #n# if OBJ has already been printed. */ - sprintf (buf, "#%"pI"d#", n); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "#%"pI"d#", n); + strout (buf, len, len, printcharfun); return; } } @@ -1368,16 +1370,17 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag switch (XTYPE (obj)) { case_Lisp_Int: - sprintf (buf, "%"pI"d", XINT (obj)); - strout (buf, -1, -1, printcharfun); + { + int len = sprintf (buf, "%"pI"d", XINT (obj)); + strout (buf, len, len, printcharfun); + } break; case Lisp_Float: { char pigbuf[FLOAT_TO_STRING_BUFSIZE]; - - float_to_string (pigbuf, XFLOAT_DATA (obj)); - strout (pigbuf, -1, -1, printcharfun); + int len = float_to_string (pigbuf, XFLOAT_DATA (obj)); + strout (pigbuf, len, len, printcharfun); } break; @@ -1400,7 +1403,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag if (! EQ (Vprint_charset_text_property, Qt)) obj = print_prune_string_charset (obj); - if (!NULL_INTERVAL_P (STRING_INTERVALS (obj))) + if (string_intervals (obj)) { PRINTCHAR ('#'); PRINTCHAR ('('); @@ -1447,15 +1450,16 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag when found in a multibyte string, always use a hex escape so it reads back as multibyte. */ char outbuf[50]; + int len; if (CHAR_BYTE8_P (c)) - sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c)); + len = sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c)); else { - sprintf (outbuf, "\\x%04x", c); + len = sprintf (outbuf, "\\x%04x", c); need_nonhex = 1; } - strout (outbuf, -1, -1, printcharfun); + strout (outbuf, len, len, printcharfun); } else if (! multibyte && SINGLE_BYTE_CHAR_P (c) && ! ASCII_BYTE_P (c) @@ -1466,8 +1470,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag print single-byte non-ASCII string chars using octal escapes. */ char outbuf[5]; - sprintf (outbuf, "\\%03o", c); - strout (outbuf, -1, -1, printcharfun); + int len = sprintf (outbuf, "\\%03o", c); + strout (outbuf, len, len, printcharfun); } else { @@ -1490,9 +1494,9 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } PRINTCHAR ('\"'); - if (!NULL_INTERVAL_P (STRING_INTERVALS (obj))) + if (string_intervals (obj)) { - traverse_intervals (STRING_INTERVALS (obj), + traverse_intervals (string_intervals (obj), 0, print_interval, printcharfun); PRINTCHAR (')'); } @@ -1632,8 +1636,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag /* Simple but incomplete way. */ if (i != 0 && EQ (obj, halftail)) { - sprintf (buf, " . #%"pMd, i / 2); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, " . #%"pMd, i / 2); + strout (buf, len, len, printcharfun); goto end_of_list; } } @@ -1697,7 +1701,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag else if (BOOL_VECTOR_P (obj)) { ptrdiff_t i; - register unsigned char c; + int len; + unsigned char c; struct gcpro gcpro1; ptrdiff_t size_in_chars = ((XBOOL_VECTOR (obj)->size + BOOL_VECTOR_BITS_PER_CHAR - 1) @@ -1707,8 +1712,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag PRINTCHAR ('#'); PRINTCHAR ('&'); - sprintf (buf, "%"pI"d", XBOOL_VECTOR (obj)->size); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%"pI"d", XBOOL_VECTOR (obj)->size); + strout (buf, len, len, printcharfun); PRINTCHAR ('\"'); /* Don't print more characters than the specified maximum. @@ -1759,22 +1764,25 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (WINDOWP (obj)) { + int len; strout ("#sequence_number)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%d", XWINDOW (obj)->sequence_number); + strout (buf, len, len, printcharfun); if (!NILP (XWINDOW (obj)->buffer)) { strout (" on ", -1, -1, printcharfun); - print_string (BVAR (XBUFFER (XWINDOW (obj)->buffer), name), printcharfun); + print_string (BVAR (XBUFFER (XWINDOW (obj)->buffer), name), + printcharfun); } PRINTCHAR ('>'); } else if (TERMINALP (obj)) { + int len; struct terminal *t = XTERMINAL (obj); strout ("#id); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%d", t->id); + strout (buf, len, len, printcharfun); if (t->name) { strout (" on ", -1, -1, printcharfun); @@ -1787,6 +1795,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag struct Lisp_Hash_Table *h = XHASH_TABLE (obj); ptrdiff_t i; ptrdiff_t real_size, size; + int len; #if 0 strout ("#test)) @@ -1797,18 +1806,18 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag PRINTCHAR (' '); strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun); PRINTCHAR (' '); - sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next)); + strout (buf, len, len, printcharfun); } - sprintf (buf, " %p", h); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, " %p", h); + strout (buf, len, len, printcharfun); PRINTCHAR ('>'); #endif /* Implement a readable output, e.g.: #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ /* Always print the size. */ - sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); + strout (buf, len, len, printcharfun); if (!NILP (h->test)) { @@ -1864,7 +1873,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (BUFFERP (obj)) { - if (NILP (BVAR (XBUFFER (obj), name))) + if (!BUFFER_LIVE_P (XBUFFER (obj))) strout ("#", -1, -1, printcharfun); else if (escapeflag) { @@ -1881,12 +1890,24 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (FRAMEP (obj)) { + int len; + Lisp_Object frame_name = XFRAME (obj)->name; + strout ((FRAME_LIVE_P (XFRAME (obj)) ? "#name, printcharfun); - sprintf (buf, " %p", XFRAME (obj)); - strout (buf, -1, -1, printcharfun); + if (!STRINGP (frame_name)) + { + /* A frame could be too young and have no name yet; + don't crash. */ + if (SYMBOLP (frame_name)) + frame_name = Fsymbol_name (frame_name); + else /* can't happen: name should be either nil or string */ + frame_name = build_string ("*INVALID*FRAME*NAME*"); + } + print_string (frame_name, printcharfun); + len = sprintf (buf, " %p", XFRAME (obj)); + strout (buf, len, len, printcharfun); PRINTCHAR ('>'); } else if (FONTP (obj)) @@ -1960,7 +1981,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag for (i = 0; i < size; i++) { if (i) PRINTCHAR (' '); - tem = XVECTOR (obj)->contents[i]; + tem = AREF (obj, i); print_object (tem, printcharfun, escapeflag); } if (size < real_size) @@ -1982,8 +2003,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag strout ("in no buffer", -1, -1, printcharfun); else { - sprintf (buf, "at %"pD"d", marker_position (obj)); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "at %"pD"d", marker_position (obj)); + strout (buf, len, len, printcharfun); strout (" in ", -1, -1, printcharfun); print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun); } @@ -1996,10 +2017,10 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag strout ("in no buffer", -1, -1, printcharfun); else { - sprintf (buf, "from %"pD"d to %"pD"d in ", - marker_position (OVERLAY_START (obj)), - marker_position (OVERLAY_END (obj))); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "from %"pD"d to %"pD"d in ", + marker_position (OVERLAY_START (obj)), + marker_position (OVERLAY_END (obj))); + strout (buf, len, len, printcharfun); print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name), printcharfun); } @@ -2014,10 +2035,12 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag case Lisp_Misc_Save_Value: strout ("#pointer, - XSAVE_VALUE (obj)->integer); - strout (buf, -1, -1, printcharfun); + { + int len = sprintf (buf, "ptr=%p int=%"pD"d", + XSAVE_VALUE (obj)->pointer, + XSAVE_VALUE (obj)->integer); + strout (buf, len, len, printcharfun); + } PRINTCHAR ('>'); break; @@ -2029,16 +2052,17 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag default: badtype: { + int len; /* We're in trouble if this happens! - Probably should just abort () */ + Probably should just emacs_abort (). */ strout ("#", -1, -1, printcharfun); } @@ -2051,7 +2075,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag /* Print a description of INTERVAL using PRINTCHARFUN. This is part of printing a string that has text properties. */ -void +static void print_interval (INTERVAL interval, Lisp_Object printcharfun) { if (NILP (interval->plist))