X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/1c262cae409ec55a234c89b3b74a13a77c7f595a..e5560ff7d28c684003ed598a9390e17f9fb92d34:/src/print.c diff --git a/src/print.c b/src/print.c index d67149a40a..a388832b07 100644 --- a/src/print.c +++ b/src/print.c @@ -1,6 +1,6 @@ /* Lisp object printing and output streams. -Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2011 +Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2012 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -23,8 +23,8 @@ along with GNU Emacs. If not, see . */ #include #include #include "lisp.h" -#include "buffer.h" #include "character.h" +#include "buffer.h" #include "charset.h" #include "keyboard.h" #include "frame.h" @@ -55,10 +55,10 @@ static Lisp_Object Qfloat_output_format; #endif /* Avoid actual stack overflow in print. */ -static int print_depth; +static ptrdiff_t print_depth; /* Level of nesting inside outputting backquote in new style. */ -static int new_backquote_output; +static ptrdiff_t new_backquote_output; /* Detect most circularities to print finite output. */ #define PRINT_CIRCLE 200 @@ -69,11 +69,11 @@ static Lisp_Object being_printed[PRINT_CIRCLE]; static char *print_buffer; /* Size allocated in print_buffer. */ -static EMACS_INT print_buffer_size; +static ptrdiff_t print_buffer_size; /* Chars stored in print_buffer. */ -static EMACS_INT print_buffer_pos; +static ptrdiff_t print_buffer_pos; /* Bytes stored in print_buffer. */ -static EMACS_INT print_buffer_pos_byte; +static ptrdiff_t print_buffer_pos_byte; Lisp_Object Qprint_escape_newlines; static Lisp_Object Qprint_escape_multibyte, Qprint_escape_nonascii; @@ -86,27 +86,27 @@ static Lisp_Object Qprint_escape_multibyte, Qprint_escape_nonascii; N the object has been printed so we can refer to it as #N#. print_number_index holds the largest N already used. N has to be striclty larger than 0 since we need to distinguish -N. */ -static int print_number_index; +static ptrdiff_t print_number_index; static void print_interval (INTERVAL interval, Lisp_Object printcharfun); /* GDB resets this to zero on W32 to disable OutputDebugString calls. */ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; -/* Low level output routines for characters and strings */ +/* Low level output routines for characters and strings. */ /* Lisp functions to do output using a stream must have the stream in a variable called printcharfun and must start with PRINTPREPARE, end with PRINTFINISH, and use PRINTDECLARE to declare common variables. Use PRINTCHAR to output one character, - or call strout to output a block of characters. */ + or call strout to output a block of characters. */ #define PRINTDECLARE \ struct buffer *old = current_buffer; \ - EMACS_INT old_point = -1, start_point = -1; \ - EMACS_INT old_point_byte = -1, start_point_byte = -1; \ - int specpdl_count = SPECPDL_INDEX (); \ + ptrdiff_t old_point = -1, start_point = -1; \ + ptrdiff_t old_point_byte = -1, start_point_byte = -1; \ + ptrdiff_t specpdl_count = SPECPDL_INDEX (); \ int free_print_buffer = 0; \ int multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters)); \ Lisp_Object original @@ -122,7 +122,7 @@ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; } \ if (MARKERP (printcharfun)) \ { \ - EMACS_INT marker_pos; \ + ptrdiff_t marker_pos; \ if (! XMARKER (printcharfun)->buffer) \ error ("Marker does not point anywhere"); \ if (XMARKER (printcharfun)->buffer != current_buffer) \ @@ -156,7 +156,7 @@ int print_output_debug_flag EXTERNALLY_VISIBLE = 1; } \ else \ { \ - ptrdiff_t new_size = 1000; \ + int new_size = 1000; \ print_buffer = (char *) xmalloc (new_size); \ print_buffer_size = new_size; \ free_print_buffer = 1; \ @@ -233,15 +233,10 @@ printchar (unsigned int ch, Lisp_Object fun) if (NILP (fun)) { - if (print_buffer_size - len <= print_buffer_pos_byte) - { - ptrdiff_t new_size; - if (STRING_BYTES_BOUND / 2 < print_buffer_size) - string_overflow (); - new_size = print_buffer_size * 2; - print_buffer = (char *) xrealloc (print_buffer, new_size); - print_buffer_size = new_size; - } + ptrdiff_t incr = len - (print_buffer_size - print_buffer_pos_byte); + if (0 < incr) + print_buffer = + xpalloc (print_buffer, &print_buffer_size, incr, -1, 1); memcpy (print_buffer + print_buffer_pos_byte, str, len); print_buffer_pos += 1; print_buffer_pos_byte += len; @@ -276,7 +271,7 @@ printchar (unsigned int ch, Lisp_Object fun) to data in a Lisp string. Otherwise that is not safe. */ static void -strout (const char *ptr, EMACS_INT size, EMACS_INT size_byte, +strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte, Lisp_Object printcharfun) { if (size < 0) @@ -284,15 +279,9 @@ strout (const char *ptr, EMACS_INT size, EMACS_INT size_byte, if (NILP (printcharfun)) { - if (print_buffer_size - size_byte < print_buffer_pos_byte) - { - ptrdiff_t new_size; - if (STRING_BYTES_BOUND / 2 - size_byte < print_buffer_size) - string_overflow (); - new_size = print_buffer_size * 2 + size_byte; - print_buffer = (char *) xrealloc (print_buffer, new_size); - print_buffer_size = new_size; - } + ptrdiff_t incr = size_byte - (print_buffer_size - print_buffer_pos_byte); + if (0 < incr) + print_buffer = xpalloc (print_buffer, &print_buffer_size, incr, -1, 1); memcpy (print_buffer + print_buffer_pos_byte, ptr, size_byte); print_buffer_pos += size; print_buffer_pos_byte += size_byte; @@ -333,7 +322,7 @@ strout (const char *ptr, EMACS_INT size, EMACS_INT size_byte, else { /* PRINTCHARFUN is a Lisp function. */ - EMACS_INT i = 0; + ptrdiff_t i = 0; if (size == size_byte) { @@ -369,7 +358,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) { if (EQ (printcharfun, Qt) || NILP (printcharfun)) { - EMACS_INT chars; + ptrdiff_t chars; if (print_escape_nonascii) string = string_escape_byte8 (string); @@ -385,7 +374,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) convert STRING to a multibyte string containing the same character codes. */ Lisp_Object newstr; - EMACS_INT bytes; + ptrdiff_t bytes; chars = SBYTES (string); bytes = count_size_as_multibyte (SDATA (string), chars); @@ -403,7 +392,7 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) if (EQ (printcharfun, Qt)) { /* Output to echo area. */ - EMACS_INT nbytes = SBYTES (string); + ptrdiff_t nbytes = SBYTES (string); char *buffer; /* Copy the string contents so that relocation of STRING by @@ -425,9 +414,9 @@ print_string (Lisp_Object string, Lisp_Object printcharfun) { /* Otherwise, string may be relocated by printing one char. So re-fetch the string address for each character. */ - EMACS_INT i; - EMACS_INT size = SCHARS (string); - EMACS_INT size_byte = SBYTES (string); + ptrdiff_t i; + ptrdiff_t size = SCHARS (string); + ptrdiff_t size_byte = SBYTES (string); struct gcpro gcpro1; GCPRO1 (string); if (size == size_byte) @@ -498,7 +487,7 @@ write_string_1 (const char *data, int size, Lisp_Object printcharfun) void temp_output_buffer_setup (const char *bufname) { - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); register struct buffer *old = current_buffer; register Lisp_Object buf; @@ -602,7 +591,7 @@ A printed representation of an object is text which describes that object. */) Lisp_Object printcharfun; /* struct gcpro gcpro1, gcpro2; */ Lisp_Object save_deactivate_mark; - int count = SPECPDL_INDEX (); + ptrdiff_t count = SPECPDL_INDEX (); struct buffer *previous; specbind (Qinhibit_modification_hooks, Qt); @@ -620,7 +609,7 @@ A printed representation of an object is text which describes that object. */) printcharfun = Vprin1_to_string_buffer; PRINTPREPARE; print (object, printcharfun, NILP (noescape)); - /* Make Vprin1_to_string_buffer be the default buffer after PRINTFINSH */ + /* Make Vprin1_to_string_buffer be the default buffer after PRINTFINISH */ PRINTFINISH; } @@ -728,7 +717,7 @@ to make it write to the debugging output. */) (Lisp_Object character) { CHECK_NUMBER (character); - putc ((int) XINT (character), stderr); + putc (XINT (character) & 0xFF, stderr); #ifdef WINDOWSNT /* Send the output to a debugger (nothing happens if there isn't one). */ @@ -865,7 +854,6 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, { Lisp_Object errname, errmsg, file_error, tail; struct gcpro gcpro1; - int i; if (context != 0) write_string_1 (context, -1, stream); @@ -875,10 +863,13 @@ 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 = alloca (SBYTES (cname)); + char *name; + USE_SAFE_ALLOCA; + SAFE_ALLOCA (name, char *, SBYTES (cname)); memcpy (name, SDATA (cname), SBYTES (cname)); message_dolog (name, SBYTES (cname), 0, 0); message_dolog (": ", 2, 0, 0); + SAFE_FREE (); } errname = Fcar (data); @@ -893,9 +884,8 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, } else { - Lisp_Object error_conditions; + Lisp_Object error_conditions = Fget (errname, Qerror_conditions); errmsg = Fget (errname, Qerror_message); - error_conditions = Fget (errname, Qerror_conditions); file_error = Fmemq (Qfile_error, error_conditions); } @@ -909,22 +899,30 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, if (!NILP (file_error) && CONSP (tail)) errmsg = XCAR (tail), tail = XCDR (tail); - if (STRINGP (errmsg)) - Fprinc (errmsg, stream); - else - write_string_1 ("peculiar error", -1, stream); + { + const char *sep = ": "; - for (i = 0; CONSP (tail); tail = XCDR (tail), i = 1) - { - Lisp_Object obj; + if (!STRINGP (errmsg)) + write_string_1 ("peculiar error", -1, stream); + else if (SCHARS (errmsg)) + Fprinc (errmsg, stream); + else + sep = NULL; - write_string_1 (i ? ", " : ": ", 2, stream); - obj = XCAR (tail); - if (!NILP (file_error) || EQ (errname, Qend_of_file)) - Fprinc (obj, stream); - else - Fprin1 (obj, stream); - } + for (; CONSP (tail); tail = XCDR (tail), sep = ", ") + { + Lisp_Object obj; + + if (sep) + write_string_1 (sep, 2, stream); + obj = XCAR (tail); + if (!NILP (file_error) + || EQ (errname, Qend_of_file) || EQ (errname, Quser_error)) + Fprinc (obj, stream); + else + Fprin1 (obj, stream); + } + } UNGCPRO; } @@ -1088,11 +1086,9 @@ print (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag) if (HASH_TABLE_P (Vprint_number_table)) { /* Remove unnecessary objects, which appear only once in OBJ; - that is, whose status is Qt. - Maybe a better way to do that is to copy elements to - a new hash table. */ + that is, whose status is Qt. */ struct Lisp_Hash_Table *h = XHASH_TABLE (Vprint_number_table); - EMACS_INT i; + ptrdiff_t i; for (i = 0; i < HASH_TABLE_SIZE (h); ++i) if (!NILP (HASH_HASH (h, i)) @@ -1126,19 +1122,19 @@ static void print_preprocess (Lisp_Object obj) { int i; - EMACS_INT size; + ptrdiff_t size; int loop_count = 0; Lisp_Object halftail; - /* Give up if we go so deep that print_object will get an error. */ - /* See similar code in print_object. */ - if (print_depth >= PRINT_CIRCLE) - error ("Apparently circular structure being printed"); - /* Avoid infinite recursion for circular nested structure in the case where Vprint_circle is nil. */ if (NILP (Vprint_circle)) { + /* Give up if we go so deep that print_object will get an error. */ + /* See similar code in print_object. */ + if (print_depth >= PRINT_CIRCLE) + error ("Apparently circular structure being printed"); + for (i = 0; i < print_depth; i++) if (EQ (obj, being_printed[i])) return; @@ -1240,7 +1236,7 @@ static void print_check_string_charset_prop (INTERVAL interval, Lisp_Object stri #define PRINT_STRING_NON_CHARSET_FOUND 1 #define PRINT_STRING_UNSAFE_CHARSET_FOUND 2 -/* Bitwise or of the above macros. */ +/* Bitwise or of the above macros. */ static int print_check_string_result; static void @@ -1269,8 +1265,8 @@ print_check_string_charset_prop (INTERVAL interval, Lisp_Object string) || ! (print_check_string_result & PRINT_STRING_UNSAFE_CHARSET_FOUND)) { int i, c; - EMACS_INT charpos = interval->position; - EMACS_INT bytepos = string_char_to_byte (string, charpos); + ptrdiff_t charpos = interval->position; + ptrdiff_t bytepos = string_char_to_byte (string, charpos); Lisp_Object charset; charset = XCAR (XCDR (val)); @@ -1323,48 +1319,46 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag QUIT; - /* See similar code in print_preprocess. */ - if (print_depth >= PRINT_CIRCLE) - error ("Apparently circular structure being printed"); - /* Detect circularities and truncate them. */ - if (PRINT_CIRCLE_CANDIDATE_P (obj)) + if (NILP (Vprint_circle)) { - if (NILP (Vprint_circle) && NILP (Vprint_gensym)) - { - /* Simple but incomplete way. */ - int i; - for (i = 0; i < print_depth; i++) - if (EQ (obj, being_printed[i])) - { - sprintf (buf, "#%d", i); - strout (buf, -1, -1, printcharfun); - return; - } - being_printed[print_depth] = obj; - } - else + /* Simple but incomplete way. */ + int i; + + /* See similar code in print_preprocess. */ + if (print_depth >= PRINT_CIRCLE) + error ("Apparently circular structure being printed"); + + for (i = 0; i < print_depth; i++) + if (EQ (obj, being_printed[i])) + { + sprintf (buf, "#%d", i); + strout (buf, -1, -1, printcharfun); + return; + } + being_printed[print_depth] = obj; + } + else if (PRINT_CIRCLE_CANDIDATE_P (obj)) + { + /* With the print-circle feature. */ + Lisp_Object num = Fgethash (obj, Vprint_number_table, Qnil); + if (INTEGERP (num)) { - /* With the print-circle feature. */ - Lisp_Object num = Fgethash (obj, Vprint_number_table, Qnil); - if (INTEGERP (num)) + EMACS_INT n = XINT (num); + 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); + /* OBJ is going to be printed. Remember that fact. */ + Fputhash (obj, make_number (- n), Vprint_number_table); + } + else { - EMACS_INT n = XINT (num); - 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); - /* 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); - return; - } + /* Just print #n# if OBJ has already been printed. */ + sprintf (buf, "#%"pI"d#", n); + strout (buf, -1, -1, printcharfun); + return; } } } @@ -1392,10 +1386,10 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag print_string (obj, printcharfun); else { - register EMACS_INT i_byte; + register ptrdiff_t i_byte; struct gcpro gcpro1; unsigned char *str; - EMACS_INT size_byte; + ptrdiff_t size_byte; /* 1 means we must ensure that the next character we output cannot be taken as part of a hex character escape. */ int need_nonhex = 0; @@ -1513,8 +1507,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag register unsigned char *p = SDATA (SYMBOL_NAME (obj)); register unsigned char *end = p + SBYTES (SYMBOL_NAME (obj)); register int c; - int i, i_byte; - EMACS_INT size_byte; + ptrdiff_t i, i_byte; + ptrdiff_t size_byte; Lisp_Object name; name = SYMBOL_NAME (obj); @@ -1635,7 +1629,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag /* Detect circular list. */ if (NILP (Vprint_circle)) { - /* Simple but imcomplete way. */ + /* Simple but incomplete way. */ if (i != 0 && EQ (obj, halftail)) { sprintf (buf, " . #%"pMd, i / 2); @@ -1705,7 +1699,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag ptrdiff_t i; register unsigned char c; struct gcpro gcpro1; - EMACS_INT size_in_chars + ptrdiff_t size_in_chars = ((XBOOL_VECTOR (obj)->size + BOOL_VECTOR_BITS_PER_CHAR - 1) / BOOL_VECTOR_BITS_PER_CHAR); @@ -1791,8 +1785,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag else if (HASH_TABLE_P (obj)) { struct Lisp_Hash_Table *h = XHASH_TABLE (obj); - int i; - EMACS_INT real_size, size; + ptrdiff_t i; + ptrdiff_t real_size, size; #if 0 strout ("#test)) @@ -1803,7 +1797,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag PRINTCHAR (' '); strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun); PRINTCHAR (' '); - sprintf (buf, "%"pI"d/%"pI"d", h->count, ASIZE (h->next)); + sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next)); strout (buf, -1, -1, printcharfun); } sprintf (buf, " %p", h); @@ -1813,7 +1807,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag /* 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 %"pI"d", ASIZE (h->next)); + sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); strout (buf, -1, -1, printcharfun); if (!NILP (h->test)) @@ -1897,7 +1891,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (FONTP (obj)) { - EMACS_INT i; + int i; if (! FONT_OBJECT_P (obj)) { @@ -1925,7 +1919,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else { - EMACS_INT size = ASIZE (obj); + ptrdiff_t size = ASIZE (obj); if (COMPILEDP (obj)) { PRINTCHAR ('#'); @@ -1956,7 +1950,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag { register int i; register Lisp_Object tem; - EMACS_INT real_size = size; + ptrdiff_t real_size = size; /* Don't print more elements than the specified maximum. */ if (NATNUMP (Vprint_length) @@ -1988,7 +1982,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag strout ("in no buffer", -1, -1, printcharfun); else { - sprintf (buf, "at %"pI"d", marker_position (obj)); + sprintf (buf, "at %"pD"d", marker_position (obj)); strout (buf, -1, -1, printcharfun); strout (" in ", -1, -1, printcharfun); print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun); @@ -2002,7 +1996,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag strout ("in no buffer", -1, -1, printcharfun); else { - sprintf (buf, "from %"pI"d to %"pI"d in ", + sprintf (buf, "from %"pD"d to %"pD"d in ", marker_position (OVERLAY_START (obj)), marker_position (OVERLAY_END (obj))); strout (buf, -1, -1, printcharfun); @@ -2020,9 +2014,9 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag case Lisp_Misc_Save_Value: strout ("#pointer, - XSAVE_VALUE (obj)->integer); + sprintf (buf, "ptr=%p int=%"pD"d", + XSAVE_VALUE (obj)->pointer, + XSAVE_VALUE (obj)->integer); strout (buf, -1, -1, printcharfun); PRINTCHAR ('>'); break; @@ -2041,7 +2035,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag if (MISCP (obj)) sprintf (buf, "(MISC 0x%04x)", (int) XMISCTYPE (obj)); else if (VECTORLIKEP (obj)) - sprintf (buf, "(PVEC 0x%08"pI"x)", ASIZE (obj)); + sprintf (buf, "(PVEC 0x%08"pD"x)", ASIZE (obj)); else sprintf (buf, "(0x%02x)", (int) XTYPE (obj)); strout (buf, -1, -1, printcharfun); @@ -2149,7 +2143,7 @@ shared once again when the text is read back. */); Vprint_gensym = Qnil; DEFVAR_LISP ("print-circle", Vprint_circle, - doc: /* *Non-nil means print recursive structures using #N= and #N# syntax. + doc: /* Non-nil means print recursive structures using #N= and #N# syntax. If nil, printing proceeds recursively and may lead to `max-lisp-eval-depth' being exceeded or an error may occur: \"Apparently circular structure being printed.\" Also see @@ -2161,7 +2155,7 @@ where N is a positive decimal integer. */); Vprint_circle = Qnil; DEFVAR_LISP ("print-continuous-numbering", Vprint_continuous_numbering, - doc: /* *Non-nil means number continuously across print calls. + doc: /* Non-nil means number continuously across print calls. This affects the numbers printed for #N= labels and #M# references. See also `print-circle', `print-gensym', and `print-number-table'. This variable should not be set with `setq'; bind it with a `let' instead. */);