X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/2d809ffafd3e1bde360c08f3be4b7d9a43ff5f0e..251d6798c1556b66bf3f1d88659c94c1a43d060c:/src/print.c
diff --git a/src/print.c b/src/print.c
index 811ab5011c..672a780792 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-2013 Free Software
+Copyright (C) 1985-1986, 1988, 1993-1995, 1997-2014 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
@@ -20,7 +20,7 @@ along with GNU Emacs. If not, see . */
#include
-#include
+#include "sysstdio.h"
#include "lisp.h"
#include "character.h"
@@ -96,11 +96,12 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
Use PRINTCHAR to output one character,
or call strout to output a block of characters. */
+/* {{coccinelle:skip_start}} */
#define PRINTDECLARE \
struct buffer *old = current_buffer; \
ptrdiff_t old_point = -1, start_point = -1; \
ptrdiff_t old_point_byte = -1, start_point_byte = -1; \
- ptrdiff_t specpdl_count = SPECPDL_INDEX (); \
+ dynwind_begin (); \
bool free_print_buffer = 0; \
bool multibyte \
= !NILP (BVAR (current_buffer, enable_multibyte_characters)); \
@@ -124,7 +125,8 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
set_buffer_internal (XMARKER (printcharfun)->buffer); \
marker_pos = marker_position (printcharfun); \
if (marker_pos < BEGV || marker_pos > ZV) \
- error ("Marker is outside the accessible part of the buffer"); \
+ signal_error ("Marker is outside the accessible " \
+ "part of the buffer", printcharfun); \
old_point = PT; \
old_point_byte = PT_BYTE; \
SET_PT_BOTH (marker_pos, \
@@ -136,10 +138,10 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
if (NILP (printcharfun)) \
{ \
Lisp_Object string; \
- if (NILP (BVAR (current_buffer, enable_multibyte_characters)) \
+ if (NILP (BVAR (current_buffer, enable_multibyte_characters)) \
&& ! print_escape_multibyte) \
specbind (Qprint_escape_multibyte, Qt); \
- if (! NILP (BVAR (current_buffer, enable_multibyte_characters)) \
+ if (! NILP (BVAR (current_buffer, enable_multibyte_characters)) \
&& ! print_escape_nonascii) \
specbind (Qprint_escape_nonascii, Qt); \
if (print_buffer != 0) \
@@ -152,7 +154,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
else \
{ \
int new_size = 1000; \
- print_buffer = xmalloc (new_size); \
+ print_buffer = xmalloc_atomic (new_size); \
print_buffer_size = new_size; \
free_print_buffer = 1; \
} \
@@ -166,7 +168,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
if (NILP (printcharfun)) \
{ \
if (print_buffer_pos != print_buffer_pos_byte \
- && NILP (BVAR (current_buffer, enable_multibyte_characters))) \
+ && NILP (BVAR (current_buffer, enable_multibyte_characters)))\
{ \
unsigned char *temp = alloca (print_buffer_pos + 1); \
copy_text ((unsigned char *) print_buffer, temp, \
@@ -184,7 +186,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
xfree (print_buffer); \
print_buffer = 0; \
} \
- unbind_to (specpdl_count, Qnil); \
+ dynwind_end (); \
if (MARKERP (original)) \
set_marker_both (original, Qnil, PT, PT_BYTE); \
if (old_point >= 0) \
@@ -195,15 +197,15 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
set_buffer_internal (old);
#define PRINTCHAR(ch) printchar (ch, printcharfun)
+/* {{coccinelle:skip_end}} */
/* This is used to restore the saved contents of print_buffer
when there is a recursive call to print. */
-static Lisp_Object
+static void
print_unwind (Lisp_Object saved_text)
{
memcpy (print_buffer, SDATA (saved_text), SCHARS (saved_text));
- return Qnil;
}
@@ -478,10 +480,10 @@ write_string_1 (const char *data, int size, Lisp_Object printcharfun)
void
temp_output_buffer_setup (const char *bufname)
{
- ptrdiff_t count = SPECPDL_INDEX ();
register struct buffer *old = current_buffer;
register Lisp_Object buf;
+ dynwind_begin ();
record_unwind_current_buffer ();
Fset_buffer (Fget_buffer_create (build_string (bufname)));
@@ -503,7 +505,7 @@ temp_output_buffer_setup (const char *bufname)
Frun_hooks (1, &Qtemp_buffer_setup_hook);
- unbind_to (count, Qnil);
+ dynwind_end ();
specbind (Qstandard_output, buf);
}
@@ -583,9 +585,9 @@ A printed representation of an object is text which describes that object. */)
bool prev_abort_on_gc;
/* struct gcpro gcpro1, gcpro2; */
Lisp_Object save_deactivate_mark;
- ptrdiff_t count = SPECPDL_INDEX ();
struct buffer *previous;
+ dynwind_begin ();
specbind (Qinhibit_modification_hooks, Qt);
{
@@ -596,8 +598,6 @@ 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); */
- prev_abort_on_gc = abort_on_gc;
- abort_on_gc = 1;
printcharfun = Vprin1_to_string_buffer;
PRINTPREPARE;
@@ -621,8 +621,8 @@ A printed representation of an object is text which describes that object. */)
Vdeactivate_mark = save_deactivate_mark;
/* UNGCPRO; */
- abort_on_gc = prev_abort_on_gc;
- return unbind_to (count, object);
+ dynwind_end ();
+ return object;
}
DEFUN ("princ", Fprinc, Sprinc, 1, 2, 0,
@@ -709,17 +709,36 @@ You can call print while debugging emacs, and pass it this function
to make it write to the debugging output. */)
(Lisp_Object character)
{
- CHECK_NUMBER (character);
- putc (XINT (character) & 0xFF, stderr);
+ unsigned int ch;
-#ifdef WINDOWSNT
- /* Send the output to a debugger (nothing happens if there isn't one). */
- if (print_output_debug_flag)
+ CHECK_NUMBER (character);
+ ch = XINT (character);
+ if (ASCII_CHAR_P (ch))
{
- char buf[2] = {(char) XINT (character), '\0'};
- OutputDebugString (buf);
+ putc (ch, stderr);
+#ifdef WINDOWSNT
+ /* Send the output to a debugger (nothing happens if there isn't
+ one). */
+ if (print_output_debug_flag)
+ {
+ char buf[2] = {(char) XINT (character), '\0'};
+ OutputDebugString (buf);
+ }
+#endif
}
+ else
+ {
+ unsigned char mbstr[MAX_MULTIBYTE_LENGTH];
+ ptrdiff_t len = CHAR_STRING (ch, mbstr);
+ Lisp_Object encoded_ch =
+ ENCODE_SYSTEM (make_multibyte_string ((char *) mbstr, 1, len));
+
+ fwrite (SSDATA (encoded_ch), SBYTES (encoded_ch), 1, stderr);
+#ifdef WINDOWSNT
+ if (print_output_debug_flag)
+ OutputDebugString (SSDATA (encoded_ch));
#endif
+ }
return character;
}
@@ -765,13 +784,12 @@ append to existing target file. */)
{
file = Fexpand_file_name (file, Qnil);
initial_stderr_stream = stderr;
- stderr = fopen (SSDATA (file), NILP (append) ? "w" : "a");
+ stderr = emacs_fopen (SSDATA (file), NILP (append) ? "w" : "a");
if (stderr == NULL)
{
stderr = initial_stderr_stream;
initial_stderr_stream = NULL;
- report_file_error ("Cannot open debugging output stream",
- Fcons (file, Qnil));
+ report_file_error ("Cannot open debugging output stream", file);
}
}
return Qnil;
@@ -1120,7 +1138,7 @@ print (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
string (its text properties will be traced), or a symbol that has
no obarray (this is for the print-gensym feature).
The status fields of Vprint_number_table mean whether each object appears
- more than once in OBJ: Qnil at the first time, and Qt after that . */
+ more than once in OBJ: Qnil at the first time, and Qt after that. */
static void
print_preprocess (Lisp_Object obj)
{
@@ -1301,7 +1319,7 @@ print_prune_string_charset (Lisp_Object string)
if (print_check_string_result & PRINT_STRING_NON_CHARSET_FOUND)
{
if (NILP (print_prune_charset_plist))
- print_prune_charset_plist = Fcons (Qcharset, Qnil);
+ print_prune_charset_plist = list1 (Qcharset);
Fremove_text_properties (make_number (0),
make_number (SCHARS (string)),
print_prune_charset_plist, string);
@@ -1390,9 +1408,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
print_string (obj, printcharfun);
else
{
- register ptrdiff_t i_byte;
+ register ptrdiff_t i, i_byte;
struct gcpro gcpro1;
- unsigned char *str;
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. */
@@ -1411,23 +1428,15 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
PRINTCHAR ('\"');
- str = SDATA (obj);
size_byte = SBYTES (obj);
- for (i_byte = 0; i_byte < size_byte;)
+ for (i = 0, i_byte = 0; i_byte < size_byte;)
{
/* Here, we must convert each multi-byte form to the
corresponding character code before handing it to PRINTCHAR. */
- int len;
int c;
- if (multibyte)
- {
- c = STRING_CHAR_AND_LENGTH (str + i_byte, len);
- i_byte += len;
- }
- else
- c = str[i_byte++];
+ FETCH_STRING_CHAR_ADVANCE (c, obj, i, i_byte);
QUIT;
@@ -1463,7 +1472,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
strout (outbuf, len, len, printcharfun);
}
else if (! multibyte
- && SINGLE_BYTE_CHAR_P (c) && ! ASCII_BYTE_P (c)
+ && SINGLE_BYTE_CHAR_P (c) && ! ASCII_CHAR_P (c)
&& print_escape_nonascii)
{
/* When printing in a multibyte buffer
@@ -1705,15 +1714,14 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
int len;
unsigned char c;
struct gcpro gcpro1;
- ptrdiff_t size_in_chars
- = ((XBOOL_VECTOR (obj)->size + BOOL_VECTOR_BITS_PER_CHAR - 1)
- / BOOL_VECTOR_BITS_PER_CHAR);
-
+ EMACS_INT size = bool_vector_size (obj);
+ ptrdiff_t size_in_chars = bool_vector_bytes (size);
+ ptrdiff_t real_size_in_chars = size_in_chars;
GCPRO1 (obj);
PRINTCHAR ('#');
PRINTCHAR ('&');
- len = sprintf (buf, "%"pI"d", XBOOL_VECTOR (obj)->size);
+ len = sprintf (buf, "%"pI"d", size);
strout (buf, len, len, printcharfun);
PRINTCHAR ('\"');
@@ -1727,7 +1735,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
for (i = 0; i < size_in_chars; i++)
{
QUIT;
- c = XBOOL_VECTOR (obj)->data[i];
+ c = bool_vector_uchar_data (obj)[i];
if (c == '\n' && print_escape_newlines)
{
PRINTCHAR ('\\');
@@ -1753,6 +1761,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
PRINTCHAR (c);
}
}
+
+ if (size_in_chars < real_size_in_chars)
+ strout (" ...", 4, 4, printcharfun);
PRINTCHAR ('\"');
UNGCPRO;
@@ -1767,7 +1778,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
{
int len;
strout ("#sequence_number);
strout (buf, len, len, printcharfun);
if (BUFFERP (XWINDOW (obj)->contents))
{
@@ -1798,6 +1809,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
ptrdiff_t real_size, size;
int len;
#if 0
+ void *ptr = h;
strout ("#test))
{
@@ -1810,9 +1822,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
len = sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next));
strout (buf, len, len, printcharfun);
}
- len = sprintf (buf, " %p", h);
+ len = sprintf (buf, " %p>", ptr);
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)) */
@@ -1892,6 +1903,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
else if (FRAMEP (obj))
{
int len;
+ void *ptr = XFRAME (obj);
Lisp_Object frame_name = XFRAME (obj)->name;
strout ((FRAME_LIVE_P (XFRAME (obj))
@@ -1907,9 +1919,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
frame_name = build_string ("*INVALID*FRAME*NAME*");
}
print_string (frame_name, printcharfun);
- len = sprintf (buf, " %p", XFRAME (obj));
+ len = sprintf (buf, " %p>", ptr);
strout (buf, len, len, printcharfun);
- PRINTCHAR ('>');
}
else if (FONTP (obj))
{
@@ -2103,6 +2114,12 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
v->data[index].pointer);
break;
+ case SAVE_FUNCPOINTER:
+ i = sprintf (buf, "",
+ ((void *) (intptr_t)
+ v->data[index].funcpointer));
+ break;
+
case SAVE_INTEGER:
i = sprintf (buf, "",
v->data[index].integer);
@@ -2112,6 +2129,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
print_object (v->data[index].object, printcharfun,
escapeflag);
continue;
+
+ default:
+ emacs_abort ();
}
strout (buf, i, i, printcharfun);
@@ -2126,6 +2146,19 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
break;
+ case Lisp_Other:
+ {
+ SCM port = scm_open_output_string ();
+ if (escapeflag)
+ scm_display (obj, port);
+ else
+ scm_write (obj, port);
+ strout (scm_to_locale_string (scm_get_output_string (port)),
+ -1, -1, printcharfun);
+ scm_close_port (port);
+ }
+ break;
+
default:
badtype:
{
@@ -2179,6 +2212,8 @@ init_print_once (void)
void
syms_of_print (void)
{
+#include "print.x"
+
DEFSYM (Qtemp_buffer_setup_hook, "temp-buffer-setup-hook");
DEFVAR_LISP ("standard-output", Vstandard_output,
@@ -2300,17 +2335,6 @@ priorities. */);
/* prin1_to_string_buffer initialized in init_buffer_once in buffer.c */
staticpro (&Vprin1_to_string_buffer);
- defsubr (&Sprin1);
- defsubr (&Sprin1_to_string);
- defsubr (&Serror_message_string);
- defsubr (&Sprinc);
- defsubr (&Sprint);
- defsubr (&Sterpri);
- defsubr (&Swrite_char);
-#ifdef WITH_REDIRECT_DEBUGGING_OUTPUT
- defsubr (&Sredirect_debugging_output);
-#endif
-
DEFSYM (Qprint_escape_newlines, "print-escape-newlines");
DEFSYM (Qprint_escape_multibyte, "print-escape-multibyte");
DEFSYM (Qprint_escape_nonascii, "print-escape-nonascii");