Mercurial > hg > xemacs-beta
diff src/print.c @ 1346:01c57eb70ae9
[xemacs-hg @ 2003-03-09 02:27:27 by ben]
To: xemacs-patches@xemacs.org
i.c: Sleep between calls to check for I/O, since these calls are non-blocking.
behavior.el: Allow other keywords for forward compatibility.
cl-macs.el: Rewrite to eliminate byte-compiler warning when `return' is used
without `finally'.
cmdloop.el: Avoid truncated error messages for `end-of-file' and the like.
cmdloop.el: Avoid char-int error after syncing.
files.el: Eliminate byte-compile warnings.
printer.el: Fix line-width calculations.
#### This used to work. Someone's changes (perhaps by
Michael Sperber?) seem to have messed something up.
simple.el: Use new clear-left-side functions to avoid messages ending up on
the same line as other output.
xemacs.mak: Add override for info/ as well when separate source/build dirs.
xemacs.mak: Order sections in main build process and add comments. Add
additional dependencies to try and prevent later steps from
happening when failures in earlier steps have occurred.
Makefile.in.in: Order sections in main build process and add comments. Add
additional dependencies to try and prevent later steps from
happening when failures in earlier steps have occurred.
alloc.c: Don't arbitrarily clear Vconfigure_info_directory since it
messes up separate build/source dirs.
console.c, console.h, device-msw.c, device.c: Add accidentally omitted msprinter console and data descriptions.
print.c, console-msw.c: Add clear-left-side functionality to help keep stdio/stderr
output from separate sources on separate lines. Generalize
the different kinds of debugging output. Add dpa().
profile.c: Add better docs on Unix/Windows differences.
regex.c: Fix problems with rel-alloc compilation caused by previous patch.
emacs.c: Seg fault rather than abort on Cygwin, since gdb doesn't trap
aborts properly.
console-gtk-impl.h, console-gtk.h, console-msw.h, console-x-impl.h, console-x.h, dialog-gtk.c, dialog-x.c, event-msw.c, frame-gtk.c, frame-x.c, frameslots.h, glyphs-gtk.c, glyphs-x.c, gui-gtk.c, gui-x.c, inline.c, menubar-gtk.c, menubar-msw.c, menubar-x.c, scrollbar-gtk.c, scrollbar-x.c, ui-gtk.c: Delete popup-data object. Delete menubar_data field from frames,
since its usage is frame-specific. Delete menubar-msw.h,
gui-x.h, gui-gtk.h. Clean up handling of lwlib callback data
GCPRO'ing and add missing GCPRO recomputation in widget code.
author | ben |
---|---|
date | Sun, 09 Mar 2003 02:27:46 +0000 |
parents | 465bd3c7d932 |
children | 59e1bbea04fe |
line wrap: on
line diff
--- a/src/print.c Sat Mar 08 22:52:26 2003 +0000 +++ b/src/print.c Sun Mar 09 02:27:46 2003 +0000 @@ -116,19 +116,20 @@ FILE *termscript; /* Stdio stream being used for copy of all output. */ -static void write_string_to_alternate_debugging_output (Ibyte *str, +static void write_string_to_alternate_debugging_output (const Ibyte *str, Bytecount len); int stdout_needs_newline; +int stdout_clear_before_next_output; /* Basic function to actually write to a stdio stream or TTY console. */ static void -write_string_to_stdio_stream (FILE *stream, struct console *con, - const Ibyte *ptr, Bytecount len, - int must_flush) +write_string_to_stdio_stream_1 (FILE *stream, struct console *con, + const Ibyte *ptr, Bytecount len, + int must_flush) { Extbyte *extptr = 0; Bytecount extlen = 0; @@ -187,15 +188,74 @@ retry_fwrite (extptr, 1, extlen, termscript); fflush (termscript); } - stdout_needs_newline = (ptr[extlen - 1] != '\n'); + stdout_needs_newline = (ptr[len - 1] != '\n'); } } -/* #### The following function should be replaced a call to the - emacs_vsprintf_*() functions. This is the only way to ensure that - I18N3 works properly (many implementations of the *printf() - functions, including the ones included in glibc, do not implement - the %###$ argument-positioning syntax). +/* Write to a stdio stream or TTY console, first clearing the left side + if necessary. */ + +static void +write_string_to_stdio_stream (FILE *stream, struct console *con, + const Ibyte *ptr, Bytecount len, + int must_flush) +{ + if (stdout_clear_before_next_output && + (stream ? stream == stdout || stream == stderr : + CONSOLE_TTY_DATA (con)->is_stdio)) + { + if (stdout_needs_newline) + write_string_to_stdio_stream_1 (stream, con, (Ibyte *) "\n", 1, + must_flush); + stdout_clear_before_next_output = 0; + } + + write_string_to_stdio_stream_1 (stream, con, ptr, len, must_flush); +} + +/* + EXT_PRINT_STDOUT = stdout or its equivalent (may be a + console window under MS Windows) + EXT_PRINT_STDERR = stderr or its equivalent (may be a + console window under MS Windows) + EXT_PRINT_ALTERNATE = an internal character array; see + `alternate-debugging-output' + EXT_PRINT_MSWINDOWS = Under MS Windows, the "debugging output" that + debuggers can hook into; uses OutputDebugString() + system call + EXT_PRINT_ALL = all of the above except stdout +*/ + +enum ext_print + { + EXT_PRINT_STDOUT = 1, + EXT_PRINT_STDERR = 2, + EXT_PRINT_ALTERNATE = 4, + EXT_PRINT_MSWINDOWS = 8, + EXT_PRINT_ALL = 14 + }; + +static void +write_string_to_external_output (const Ibyte *ptr, Bytecount len, + int dest) +{ + if (dest & EXT_PRINT_STDOUT) + write_string_to_stdio_stream (stdout, 0, ptr, len, 1); + if (dest & EXT_PRINT_STDERR) + write_string_to_stdio_stream (stderr, 0, ptr, len, 1); + if (dest & EXT_PRINT_ALTERNATE) + write_string_to_alternate_debugging_output (ptr, len); +#ifdef WIN32_NATIVE + if (dest & EXT_PRINT_MSWINDOWS) + write_string_to_mswindows_debugging_output (ptr, len); +#endif +} + +/* #### The following function should make use of a call to the + emacs_vsprintf_*() functions rather than just using vsprintf. This is + the only way to ensure that I18N3 works properly (many implementations + of the *printf() functions, including the ones included in glibc, do not + implement the %###$ argument-positioning syntax). Note, however, that to do this, we'd have to @@ -204,11 +264,14 @@ called from fatal_error_signal(). 2) (to be really correct) make a new lstream that outputs using - mswindows_output_console_string(). */ + mswindows_output_console_string(). + + 3) A reasonable compromise might be to use emacs_vsprintf() when we're + in a safe state, and when not, use plain vsprintf(). */ static void -std_handle_out_va (FILE *stream, const CIbyte *fmt, va_list args, - int debug_output_as_well) +write_string_to_external_output_va (const CIbyte *fmt, va_list args, + int dest) { Ibyte kludge[8192]; Bytecount kludgelen; @@ -217,15 +280,7 @@ fmt = GETTEXT (fmt); vsprintf ((CIbyte *) kludge, fmt, args); kludgelen = qxestrlen (kludge); - - write_string_to_stdio_stream (stream, 0, kludge, kludgelen, 1); - if (debug_output_as_well) - { - write_string_to_alternate_debugging_output (kludge, kludgelen); -#ifdef WIN32_NATIVE - write_string_to_mswindows_debugging_output (kludge, kludgelen); -#endif - } + write_string_to_external_output (kludge, kludgelen, dest); } /* Output portably to stderr or its equivalent (i.e. may be a console @@ -240,7 +295,7 @@ { va_list args; va_start (args, fmt); - std_handle_out_va (stderr, fmt, args, 0); + write_string_to_external_output_va (fmt, args, EXT_PRINT_STDERR); va_end (args); } @@ -252,7 +307,18 @@ { va_list args; va_start (args, fmt); - std_handle_out_va (stdout, fmt, args, 0); + write_string_to_external_output_va (fmt, args, EXT_PRINT_STDOUT); + va_end (args); +} + +/* Output portably to print destination as specified by DEST. */ + +void +external_out (int dest, const CIbyte *fmt, ...) +{ + va_list args; + va_start (args, fmt); + write_string_to_external_output_va (fmt, args, dest); va_end (args); } @@ -266,7 +332,7 @@ { va_list args; va_start (args, fmt); - std_handle_out_va (stderr, fmt, args, 1); + write_string_to_external_output_va (fmt, args, EXT_PRINT_ALL); va_end (args); } @@ -277,7 +343,7 @@ va_start (args, fmt); stderr_out ("\nXEmacs: fatal error: "); - std_handle_out_va (stderr, fmt, args, 0); + write_string_to_external_output_va (fmt, args, EXT_PRINT_STDERR); stderr_out ("\n"); va_end (args); @@ -1812,7 +1878,7 @@ } static void -write_string_to_alternate_debugging_output (Ibyte *str, Bytecount len) +write_string_to_alternate_debugging_output (const Ibyte *str, Bytecount len) { int extlen; const Extbyte *extptr; @@ -1832,6 +1898,35 @@ alternate_do_string[alternate_do_pointer] = 0; } + +DEFUN ("set-device-clear-left-side", Fset_device_clear_left_side, 2, 2, 0, /* +Set whether to output a newline before the next output to a stream device. +This will happen only if the most recently-outputted character was not +a newline -- i.e. it will make sure the left side is "clear" of text. +*/ + (device, value)) +{ + if (!NILP (device)) + CHECK_LIVE_DEVICE (device); + if (NILP (device) || DEVICE_STREAM_P (XDEVICE (device))) + /* #### This should be per-device */ + stdout_clear_before_next_output = !NILP (value); + return Qnil; +} + +DEFUN ("device-left-side-clear-p", Fdevice_left_side_clear_p, 0, 1, 0, /* +For stream devices, true if the most recent-outputted character was a newline. +*/ + (device)) +{ + if (!NILP (device)) + CHECK_LIVE_DEVICE (device); + if (NILP (device) || DEVICE_STREAM_P (XDEVICE (device))) + /* #### This should be per-device */ + return stdout_needs_newline ? Qt : Qnil; + return Qnil; +} + DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* Write CHAR-OR-STRING to stderr or stdout. If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write @@ -1917,9 +2012,14 @@ static int debug_print_level = 15; static int debug_print_readably = -1; -/* Debugging kludge -- unbuffered */ +/* Print an object, `prin1'-style, to various possible debugging outputs. + Make sure it's completely unbuffered so that, in the event of a crash + somewhere, we see as much as possible that happened before it. + + + */ static void -debug_print_no_newline (Lisp_Object debug_print_obj) +debug_prin1 (Lisp_Object debug_print_obj, int flags) { /* This function can GC */ @@ -1938,13 +2038,17 @@ internal_bind_lisp_object (&Vprint_level, make_int (debug_print_level)); /* #### Do we need this? It was in the old code. */ internal_bind_lisp_object (&Vinhibit_quit, Vinhibit_quit); - - print_internal (debug_print_obj, Qexternal_debugging_output, 1); - alternate_do_pointer = 0; - print_internal (debug_print_obj, Qalternate_debugging_output, 1); + + if ((flags & EXT_PRINT_STDOUT) || (flags & EXT_PRINT_STDERR)) + print_internal (debug_print_obj, Qexternal_debugging_output, 1); + if (flags & EXT_PRINT_ALTERNATE) + print_internal (debug_print_obj, Qalternate_debugging_output, 1); #ifdef WIN32_NATIVE - /* Write out to the debugger, as well */ - print_internal (debug_print_obj, Qmswindows_debugging_output, 1); + if (flags & EXT_PRINT_MSWINDOWS) + { + /* Write out to the debugger, as well */ + print_internal (debug_print_obj, Qmswindows_debugging_output, 1); + } #endif unbind_to (specdepth); @@ -2023,6 +2127,31 @@ inhibit_non_essential_printing_operations = 0; } +static void +ext_print_begin (int dest) +{ + if (dest & EXT_PRINT_ALTERNATE) + alternate_do_pointer = 0; + if (dest & (EXT_PRINT_STDERR | EXT_PRINT_STDOUT)) + stdout_clear_before_next_output = 1; +} + +static void +ext_print_end (int dest) +{ + if (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | EXT_PRINT_STDOUT)) + external_out (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | + EXT_PRINT_STDOUT), "\n"); +} + +static void +external_debug_print (Lisp_Object object, int dest) +{ + ext_print_begin (dest); + debug_prin1 (object, dest); + ext_print_end (dest); +} + void debug_p3 (Lisp_Object obj) { @@ -2035,8 +2164,7 @@ void debug_print (Lisp_Object debug_print_obj) { - debug_print_no_newline (debug_print_obj); - debug_out ("\n"); + external_debug_print (debug_print_obj, EXT_PRINT_ALL); } /* Getting tired of typing debug_print() ... */ @@ -2047,6 +2175,16 @@ debug_print (debug_print_obj); } +/* Alternate debug printer: Return a char * pointer to the output */ +char *dpa (Lisp_Object debug_print_obj); +char * +dpa (Lisp_Object debug_print_obj) +{ + external_debug_print (debug_print_obj, EXT_PRINT_ALTERNATE); + + return alternate_do_string; +} + /* Debugging kludge -- unbuffered */ /* This function provided for the benefit of the debugger. */ void @@ -2097,7 +2235,7 @@ } if (COMPILED_FUNCTIONP (*bt->function)) { -#if defined(COMPILED_FUNCTION_ANNOTATION_HACK) +#if defined (COMPILED_FUNCTION_ANNOTATION_HACK) Lisp_Object ann = compiled_function_annotation (XCOMPILED_FUNCTION (*bt->function)); #else @@ -2106,7 +2244,7 @@ if (!NILP (ann)) { debug_out ("<compiled-function from "); - debug_print_no_newline (ann); + debug_prin1 (ann, EXT_PRINT_ALL); debug_out (">"); } else @@ -2115,7 +2253,7 @@ } } else - debug_print_no_newline (*bt->function); + debug_prin1 (*bt->function, EXT_PRINT_ALL); first = 0; length--; bt = bt->next; @@ -2145,6 +2283,8 @@ DEFSUBR (Fterpri); DEFSUBR (Fwrite_char); DEFSUBR (Falternate_debugging_output); + DEFSUBR (Fset_device_clear_left_side); + DEFSUBR (Fdevice_left_side_clear_p); DEFSUBR (Fexternal_debugging_output); DEFSUBR (Fopen_termscript); DEFSYMBOL (Qexternal_debugging_output);