comparison 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
comparison
equal deleted inserted replaced
1345:3b27da507d56 1346:01c57eb70ae9
114 /* Force immediate output of all printed data. Used for debugging. */ 114 /* Force immediate output of all printed data. Used for debugging. */
115 int print_unbuffered; 115 int print_unbuffered;
116 116
117 FILE *termscript; /* Stdio stream being used for copy of all output. */ 117 FILE *termscript; /* Stdio stream being used for copy of all output. */
118 118
119 static void write_string_to_alternate_debugging_output (Ibyte *str, 119 static void write_string_to_alternate_debugging_output (const Ibyte *str,
120 Bytecount len); 120 Bytecount len);
121 121
122 122
123 123
124 int stdout_needs_newline; 124 int stdout_needs_newline;
125 int stdout_clear_before_next_output;
125 126
126 /* Basic function to actually write to a stdio stream or TTY console. */ 127 /* Basic function to actually write to a stdio stream or TTY console. */
127 128
128 static void 129 static void
129 write_string_to_stdio_stream (FILE *stream, struct console *con, 130 write_string_to_stdio_stream_1 (FILE *stream, struct console *con,
130 const Ibyte *ptr, Bytecount len, 131 const Ibyte *ptr, Bytecount len,
131 int must_flush) 132 int must_flush)
132 { 133 {
133 Extbyte *extptr = 0; 134 Extbyte *extptr = 0;
134 Bytecount extlen = 0; 135 Bytecount extlen = 0;
135 int output_is_std_handle = 136 int output_is_std_handle =
136 stream ? stream == stdout || stream == stderr : 137 stream ? stream == stdout || stream == stderr :
185 if (termscript) 186 if (termscript)
186 { 187 {
187 retry_fwrite (extptr, 1, extlen, termscript); 188 retry_fwrite (extptr, 1, extlen, termscript);
188 fflush (termscript); 189 fflush (termscript);
189 } 190 }
190 stdout_needs_newline = (ptr[extlen - 1] != '\n'); 191 stdout_needs_newline = (ptr[len - 1] != '\n');
191 } 192 }
192 } 193 }
193 194
194 /* #### The following function should be replaced a call to the 195 /* Write to a stdio stream or TTY console, first clearing the left side
195 emacs_vsprintf_*() functions. This is the only way to ensure that 196 if necessary. */
196 I18N3 works properly (many implementations of the *printf() 197
197 functions, including the ones included in glibc, do not implement 198 static void
198 the %###$ argument-positioning syntax). 199 write_string_to_stdio_stream (FILE *stream, struct console *con,
200 const Ibyte *ptr, Bytecount len,
201 int must_flush)
202 {
203 if (stdout_clear_before_next_output &&
204 (stream ? stream == stdout || stream == stderr :
205 CONSOLE_TTY_DATA (con)->is_stdio))
206 {
207 if (stdout_needs_newline)
208 write_string_to_stdio_stream_1 (stream, con, (Ibyte *) "\n", 1,
209 must_flush);
210 stdout_clear_before_next_output = 0;
211 }
212
213 write_string_to_stdio_stream_1 (stream, con, ptr, len, must_flush);
214 }
215
216 /*
217 EXT_PRINT_STDOUT = stdout or its equivalent (may be a
218 console window under MS Windows)
219 EXT_PRINT_STDERR = stderr or its equivalent (may be a
220 console window under MS Windows)
221 EXT_PRINT_ALTERNATE = an internal character array; see
222 `alternate-debugging-output'
223 EXT_PRINT_MSWINDOWS = Under MS Windows, the "debugging output" that
224 debuggers can hook into; uses OutputDebugString()
225 system call
226 EXT_PRINT_ALL = all of the above except stdout
227 */
228
229 enum ext_print
230 {
231 EXT_PRINT_STDOUT = 1,
232 EXT_PRINT_STDERR = 2,
233 EXT_PRINT_ALTERNATE = 4,
234 EXT_PRINT_MSWINDOWS = 8,
235 EXT_PRINT_ALL = 14
236 };
237
238 static void
239 write_string_to_external_output (const Ibyte *ptr, Bytecount len,
240 int dest)
241 {
242 if (dest & EXT_PRINT_STDOUT)
243 write_string_to_stdio_stream (stdout, 0, ptr, len, 1);
244 if (dest & EXT_PRINT_STDERR)
245 write_string_to_stdio_stream (stderr, 0, ptr, len, 1);
246 if (dest & EXT_PRINT_ALTERNATE)
247 write_string_to_alternate_debugging_output (ptr, len);
248 #ifdef WIN32_NATIVE
249 if (dest & EXT_PRINT_MSWINDOWS)
250 write_string_to_mswindows_debugging_output (ptr, len);
251 #endif
252 }
253
254 /* #### The following function should make use of a call to the
255 emacs_vsprintf_*() functions rather than just using vsprintf. This is
256 the only way to ensure that I18N3 works properly (many implementations
257 of the *printf() functions, including the ones included in glibc, do not
258 implement the %###$ argument-positioning syntax).
199 259
200 Note, however, that to do this, we'd have to 260 Note, however, that to do this, we'd have to
201 261
202 1) pre-allocate all the lstreams and do whatever else was necessary 262 1) pre-allocate all the lstreams and do whatever else was necessary
203 to make sure that no allocation occurs, since these functions may be 263 to make sure that no allocation occurs, since these functions may be
204 called from fatal_error_signal(). 264 called from fatal_error_signal().
205 265
206 2) (to be really correct) make a new lstream that outputs using 266 2) (to be really correct) make a new lstream that outputs using
207 mswindows_output_console_string(). */ 267 mswindows_output_console_string().
268
269 3) A reasonable compromise might be to use emacs_vsprintf() when we're
270 in a safe state, and when not, use plain vsprintf(). */
208 271
209 static void 272 static void
210 std_handle_out_va (FILE *stream, const CIbyte *fmt, va_list args, 273 write_string_to_external_output_va (const CIbyte *fmt, va_list args,
211 int debug_output_as_well) 274 int dest)
212 { 275 {
213 Ibyte kludge[8192]; 276 Ibyte kludge[8192];
214 Bytecount kludgelen; 277 Bytecount kludgelen;
215 278
216 if (initialized && !inhibit_non_essential_printing_operations) 279 if (initialized && !inhibit_non_essential_printing_operations)
217 fmt = GETTEXT (fmt); 280 fmt = GETTEXT (fmt);
218 vsprintf ((CIbyte *) kludge, fmt, args); 281 vsprintf ((CIbyte *) kludge, fmt, args);
219 kludgelen = qxestrlen (kludge); 282 kludgelen = qxestrlen (kludge);
220 283 write_string_to_external_output (kludge, kludgelen, dest);
221 write_string_to_stdio_stream (stream, 0, kludge, kludgelen, 1);
222 if (debug_output_as_well)
223 {
224 write_string_to_alternate_debugging_output (kludge, kludgelen);
225 #ifdef WIN32_NATIVE
226 write_string_to_mswindows_debugging_output (kludge, kludgelen);
227 #endif
228 }
229 } 284 }
230 285
231 /* Output portably to stderr or its equivalent (i.e. may be a console 286 /* Output portably to stderr or its equivalent (i.e. may be a console
232 window under MS Windows); do external-format conversion and call GETTEXT 287 window under MS Windows); do external-format conversion and call GETTEXT
233 on the format string. Automatically flush when done. 288 on the format string. Automatically flush when done.
238 void 293 void
239 stderr_out (const CIbyte *fmt, ...) 294 stderr_out (const CIbyte *fmt, ...)
240 { 295 {
241 va_list args; 296 va_list args;
242 va_start (args, fmt); 297 va_start (args, fmt);
243 std_handle_out_va (stderr, fmt, args, 0); 298 write_string_to_external_output_va (fmt, args, EXT_PRINT_STDERR);
244 va_end (args); 299 va_end (args);
245 } 300 }
246 301
247 /* Output portably to stdout or its equivalent (i.e. may be a console 302 /* Output portably to stdout or its equivalent (i.e. may be a console
248 window under MS Windows). Works like stderr_out(). */ 303 window under MS Windows). Works like stderr_out(). */
250 void 305 void
251 stdout_out (const CIbyte *fmt, ...) 306 stdout_out (const CIbyte *fmt, ...)
252 { 307 {
253 va_list args; 308 va_list args;
254 va_start (args, fmt); 309 va_start (args, fmt);
255 std_handle_out_va (stdout, fmt, args, 0); 310 write_string_to_external_output_va (fmt, args, EXT_PRINT_STDOUT);
311 va_end (args);
312 }
313
314 /* Output portably to print destination as specified by DEST. */
315
316 void
317 external_out (int dest, const CIbyte *fmt, ...)
318 {
319 va_list args;
320 va_start (args, fmt);
321 write_string_to_external_output_va (fmt, args, dest);
256 va_end (args); 322 va_end (args);
257 } 323 }
258 324
259 /* Output portably to stderr or its equivalent (i.e. may be a console 325 /* Output portably to stderr or its equivalent (i.e. may be a console
260 window under MS Windows), as well as alternate-debugging-output and 326 window under MS Windows), as well as alternate-debugging-output and
264 void 330 void
265 debug_out (const CIbyte *fmt, ...) 331 debug_out (const CIbyte *fmt, ...)
266 { 332 {
267 va_list args; 333 va_list args;
268 va_start (args, fmt); 334 va_start (args, fmt);
269 std_handle_out_va (stderr, fmt, args, 1); 335 write_string_to_external_output_va (fmt, args, EXT_PRINT_ALL);
270 va_end (args); 336 va_end (args);
271 } 337 }
272 338
273 DOESNT_RETURN 339 DOESNT_RETURN
274 fatal (const CIbyte *fmt, ...) 340 fatal (const CIbyte *fmt, ...)
275 { 341 {
276 va_list args; 342 va_list args;
277 va_start (args, fmt); 343 va_start (args, fmt);
278 344
279 stderr_out ("\nXEmacs: fatal error: "); 345 stderr_out ("\nXEmacs: fatal error: ");
280 std_handle_out_va (stderr, fmt, args, 0); 346 write_string_to_external_output_va (fmt, args, EXT_PRINT_STDERR);
281 stderr_out ("\n"); 347 stderr_out ("\n");
282 348
283 va_end (args); 349 va_end (args);
284 exit (1); 350 exit (1);
285 } 351 }
1810 1876
1811 return character; 1877 return character;
1812 } 1878 }
1813 1879
1814 static void 1880 static void
1815 write_string_to_alternate_debugging_output (Ibyte *str, Bytecount len) 1881 write_string_to_alternate_debugging_output (const Ibyte *str, Bytecount len)
1816 { 1882 {
1817 int extlen; 1883 int extlen;
1818 const Extbyte *extptr; 1884 const Extbyte *extptr;
1819 #if 0 /* We want to see the internal representation, don't we? */ 1885 #if 0 /* We want to see the internal representation, don't we? */
1820 if (initialized && !inhibit_non_essential_printing_operations) 1886 if (initialized && !inhibit_non_essential_printing_operations)
1828 extptr = (Extbyte *) str; 1894 extptr = (Extbyte *) str;
1829 } 1895 }
1830 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); 1896 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen);
1831 alternate_do_pointer += extlen; 1897 alternate_do_pointer += extlen;
1832 alternate_do_string[alternate_do_pointer] = 0; 1898 alternate_do_string[alternate_do_pointer] = 0;
1899 }
1900
1901
1902 DEFUN ("set-device-clear-left-side", Fset_device_clear_left_side, 2, 2, 0, /*
1903 Set whether to output a newline before the next output to a stream device.
1904 This will happen only if the most recently-outputted character was not
1905 a newline -- i.e. it will make sure the left side is "clear" of text.
1906 */
1907 (device, value))
1908 {
1909 if (!NILP (device))
1910 CHECK_LIVE_DEVICE (device);
1911 if (NILP (device) || DEVICE_STREAM_P (XDEVICE (device)))
1912 /* #### This should be per-device */
1913 stdout_clear_before_next_output = !NILP (value);
1914 return Qnil;
1915 }
1916
1917 DEFUN ("device-left-side-clear-p", Fdevice_left_side_clear_p, 0, 1, 0, /*
1918 For stream devices, true if the most recent-outputted character was a newline.
1919 */
1920 (device))
1921 {
1922 if (!NILP (device))
1923 CHECK_LIVE_DEVICE (device);
1924 if (NILP (device) || DEVICE_STREAM_P (XDEVICE (device)))
1925 /* #### This should be per-device */
1926 return stdout_needs_newline ? Qt : Qnil;
1927 return Qnil;
1833 } 1928 }
1834 1929
1835 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /* 1930 DEFUN ("external-debugging-output", Fexternal_debugging_output, 1, 3, 0, /*
1836 Write CHAR-OR-STRING to stderr or stdout. 1931 Write CHAR-OR-STRING to stderr or stdout.
1837 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write 1932 If optional arg STDOUT-P is non-nil, write to stdout; otherwise, write
1915 2010
1916 static int debug_print_length = 50; 2011 static int debug_print_length = 50;
1917 static int debug_print_level = 15; 2012 static int debug_print_level = 15;
1918 static int debug_print_readably = -1; 2013 static int debug_print_readably = -1;
1919 2014
1920 /* Debugging kludge -- unbuffered */ 2015 /* Print an object, `prin1'-style, to various possible debugging outputs.
2016 Make sure it's completely unbuffered so that, in the event of a crash
2017 somewhere, we see as much as possible that happened before it.
2018
2019
2020 */
1921 static void 2021 static void
1922 debug_print_no_newline (Lisp_Object debug_print_obj) 2022 debug_prin1 (Lisp_Object debug_print_obj, int flags)
1923 { 2023 {
1924 /* This function can GC */ 2024 /* This function can GC */
1925 2025
1926 /* by doing this, we trick various things that are non-essential 2026 /* by doing this, we trick various things that are non-essential
1927 but might cause crashes into not getting executed. */ 2027 but might cause crashes into not getting executed. */
1936 internal_bind_lisp_object (&Vprint_length, make_int (debug_print_length)); 2036 internal_bind_lisp_object (&Vprint_length, make_int (debug_print_length));
1937 if (debug_print_level > 0) 2037 if (debug_print_level > 0)
1938 internal_bind_lisp_object (&Vprint_level, make_int (debug_print_level)); 2038 internal_bind_lisp_object (&Vprint_level, make_int (debug_print_level));
1939 /* #### Do we need this? It was in the old code. */ 2039 /* #### Do we need this? It was in the old code. */
1940 internal_bind_lisp_object (&Vinhibit_quit, Vinhibit_quit); 2040 internal_bind_lisp_object (&Vinhibit_quit, Vinhibit_quit);
1941 2041
1942 print_internal (debug_print_obj, Qexternal_debugging_output, 1); 2042 if ((flags & EXT_PRINT_STDOUT) || (flags & EXT_PRINT_STDERR))
1943 alternate_do_pointer = 0; 2043 print_internal (debug_print_obj, Qexternal_debugging_output, 1);
1944 print_internal (debug_print_obj, Qalternate_debugging_output, 1); 2044 if (flags & EXT_PRINT_ALTERNATE)
2045 print_internal (debug_print_obj, Qalternate_debugging_output, 1);
1945 #ifdef WIN32_NATIVE 2046 #ifdef WIN32_NATIVE
1946 /* Write out to the debugger, as well */ 2047 if (flags & EXT_PRINT_MSWINDOWS)
1947 print_internal (debug_print_obj, Qmswindows_debugging_output, 1); 2048 {
2049 /* Write out to the debugger, as well */
2050 print_internal (debug_print_obj, Qmswindows_debugging_output, 1);
2051 }
1948 #endif 2052 #endif
1949 2053
1950 unbind_to (specdepth); 2054 unbind_to (specdepth);
1951 } 2055 }
1952 2056
2021 } 2125 }
2022 2126
2023 inhibit_non_essential_printing_operations = 0; 2127 inhibit_non_essential_printing_operations = 0;
2024 } 2128 }
2025 2129
2130 static void
2131 ext_print_begin (int dest)
2132 {
2133 if (dest & EXT_PRINT_ALTERNATE)
2134 alternate_do_pointer = 0;
2135 if (dest & (EXT_PRINT_STDERR | EXT_PRINT_STDOUT))
2136 stdout_clear_before_next_output = 1;
2137 }
2138
2139 static void
2140 ext_print_end (int dest)
2141 {
2142 if (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | EXT_PRINT_STDOUT))
2143 external_out (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR |
2144 EXT_PRINT_STDOUT), "\n");
2145 }
2146
2147 static void
2148 external_debug_print (Lisp_Object object, int dest)
2149 {
2150 ext_print_begin (dest);
2151 debug_prin1 (object, dest);
2152 ext_print_end (dest);
2153 }
2154
2026 void 2155 void
2027 debug_p3 (Lisp_Object obj) 2156 debug_p3 (Lisp_Object obj)
2028 { 2157 {
2029 debug_p4 (obj); 2158 debug_p4 (obj);
2030 inhibit_non_essential_printing_operations = 1; 2159 inhibit_non_essential_printing_operations = 1;
2033 } 2162 }
2034 2163
2035 void 2164 void
2036 debug_print (Lisp_Object debug_print_obj) 2165 debug_print (Lisp_Object debug_print_obj)
2037 { 2166 {
2038 debug_print_no_newline (debug_print_obj); 2167 external_debug_print (debug_print_obj, EXT_PRINT_ALL);
2039 debug_out ("\n");
2040 } 2168 }
2041 2169
2042 /* Getting tired of typing debug_print() ... */ 2170 /* Getting tired of typing debug_print() ... */
2043 void dp (Lisp_Object debug_print_obj); 2171 void dp (Lisp_Object debug_print_obj);
2044 void 2172 void
2045 dp (Lisp_Object debug_print_obj) 2173 dp (Lisp_Object debug_print_obj)
2046 { 2174 {
2047 debug_print (debug_print_obj); 2175 debug_print (debug_print_obj);
2176 }
2177
2178 /* Alternate debug printer: Return a char * pointer to the output */
2179 char *dpa (Lisp_Object debug_print_obj);
2180 char *
2181 dpa (Lisp_Object debug_print_obj)
2182 {
2183 external_debug_print (debug_print_obj, EXT_PRINT_ALTERNATE);
2184
2185 return alternate_do_string;
2048 } 2186 }
2049 2187
2050 /* Debugging kludge -- unbuffered */ 2188 /* Debugging kludge -- unbuffered */
2051 /* This function provided for the benefit of the debugger. */ 2189 /* This function provided for the benefit of the debugger. */
2052 void 2190 void
2095 { 2233 {
2096 debug_out (", "); 2234 debug_out (", ");
2097 } 2235 }
2098 if (COMPILED_FUNCTIONP (*bt->function)) 2236 if (COMPILED_FUNCTIONP (*bt->function))
2099 { 2237 {
2100 #if defined(COMPILED_FUNCTION_ANNOTATION_HACK) 2238 #if defined (COMPILED_FUNCTION_ANNOTATION_HACK)
2101 Lisp_Object ann = 2239 Lisp_Object ann =
2102 compiled_function_annotation (XCOMPILED_FUNCTION (*bt->function)); 2240 compiled_function_annotation (XCOMPILED_FUNCTION (*bt->function));
2103 #else 2241 #else
2104 Lisp_Object ann = Qnil; 2242 Lisp_Object ann = Qnil;
2105 #endif 2243 #endif
2106 if (!NILP (ann)) 2244 if (!NILP (ann))
2107 { 2245 {
2108 debug_out ("<compiled-function from "); 2246 debug_out ("<compiled-function from ");
2109 debug_print_no_newline (ann); 2247 debug_prin1 (ann, EXT_PRINT_ALL);
2110 debug_out (">"); 2248 debug_out (">");
2111 } 2249 }
2112 else 2250 else
2113 { 2251 {
2114 debug_out ("<compiled-function of unknown origin>"); 2252 debug_out ("<compiled-function of unknown origin>");
2115 } 2253 }
2116 } 2254 }
2117 else 2255 else
2118 debug_print_no_newline (*bt->function); 2256 debug_prin1 (*bt->function, EXT_PRINT_ALL);
2119 first = 0; 2257 first = 0;
2120 length--; 2258 length--;
2121 bt = bt->next; 2259 bt = bt->next;
2122 } 2260 }
2123 debug_out ("]\n"); 2261 debug_out ("]\n");
2143 DEFSUBR (Ferror_message_string); 2281 DEFSUBR (Ferror_message_string);
2144 DEFSUBR (Fdisplay_error); 2282 DEFSUBR (Fdisplay_error);
2145 DEFSUBR (Fterpri); 2283 DEFSUBR (Fterpri);
2146 DEFSUBR (Fwrite_char); 2284 DEFSUBR (Fwrite_char);
2147 DEFSUBR (Falternate_debugging_output); 2285 DEFSUBR (Falternate_debugging_output);
2286 DEFSUBR (Fset_device_clear_left_side);
2287 DEFSUBR (Fdevice_left_side_clear_p);
2148 DEFSUBR (Fexternal_debugging_output); 2288 DEFSUBR (Fexternal_debugging_output);
2149 DEFSUBR (Fopen_termscript); 2289 DEFSUBR (Fopen_termscript);
2150 DEFSYMBOL (Qexternal_debugging_output); 2290 DEFSYMBOL (Qexternal_debugging_output);
2151 DEFSYMBOL (Qalternate_debugging_output); 2291 DEFSYMBOL (Qalternate_debugging_output);
2152 #ifdef HAVE_MS_WINDOWS 2292 #ifdef HAVE_MS_WINDOWS