Mercurial > hg > xemacs-beta
comparison src/print.c @ 5027:22179cd0fe15
merge
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 10 Feb 2010 07:25:19 -0600 |
parents | c2e0c3af5fe3 |
children | b5df3737028a |
comparison
equal
deleted
inserted
replaced
5026:46cf825f6158 | 5027:22179cd0fe15 |
---|---|
135 Lisp_Object Vprint_length; | 135 Lisp_Object Vprint_length; |
136 Lisp_Object Vprint_level; | 136 Lisp_Object Vprint_level; |
137 Lisp_Object Vinhibit_quit; | 137 Lisp_Object Vinhibit_quit; |
138 }; | 138 }; |
139 | 139 |
140 static Lisp_Object debug_prin1_bindings; | 140 static int begin_inhibit_non_essential_conversion_operations (void); |
141 | |
141 | 142 |
142 | 143 |
143 int stdout_needs_newline; | 144 int stdout_needs_newline; |
144 int stdout_clear_before_next_output; | 145 int stdout_clear_before_next_output; |
145 | 146 |
360 Works like stderr_out(). */ | 361 Works like stderr_out(). */ |
361 | 362 |
362 void | 363 void |
363 debug_out (const CIbyte *fmt, ...) | 364 debug_out (const CIbyte *fmt, ...) |
364 { | 365 { |
366 int depth = begin_inhibit_non_essential_conversion_operations (); | |
365 va_list args; | 367 va_list args; |
366 va_start (args, fmt); | 368 va_start (args, fmt); |
367 write_string_to_external_output_va (fmt, args, EXT_PRINT_ALL); | 369 write_string_to_external_output_va (fmt, args, EXT_PRINT_ALL); |
368 va_end (args); | 370 va_end (args); |
371 unbind_to (depth); | |
369 } | 372 } |
370 | 373 |
371 DOESNT_RETURN | 374 DOESNT_RETURN |
372 fatal (const CIbyte *fmt, ...) | 375 fatal (const CIbyte *fmt, ...) |
373 { | 376 { |
1942 | 1945 |
1943 default: | 1946 default: |
1944 { | 1947 { |
1945 /* We're in trouble if this happens! */ | 1948 /* We're in trouble if this happens! */ |
1946 printing_major_badness (printcharfun, "ILLEGAL LISP OBJECT TAG TYPE", | 1949 printing_major_badness (printcharfun, "ILLEGAL LISP OBJECT TAG TYPE", |
1947 XTYPE (obj), LISP_TO_VOID (obj), 0, | 1950 XTYPE (obj), STORE_LISP_IN_VOID (obj), 0, |
1948 BADNESS_INTEGER_OBJECT); | 1951 BADNESS_INTEGER_OBJECT); |
1949 break; | 1952 break; |
1950 } | 1953 } |
1951 } | 1954 } |
1952 | 1955 |
2140 return; | 2143 return; |
2141 | 2144 |
2142 if (alternate_do_pointer + extlen >= alternate_do_size) | 2145 if (alternate_do_pointer + extlen >= alternate_do_size) |
2143 { | 2146 { |
2144 alternate_do_size = | 2147 alternate_do_size = |
2145 max(alternate_do_size * 2, alternate_do_pointer + extlen + 1); | 2148 max (alternate_do_size * 2, alternate_do_pointer + extlen + 1); |
2146 XREALLOC_ARRAY (alternate_do_string, char, alternate_do_size); | 2149 XREALLOC_ARRAY (alternate_do_string, CIbyte, alternate_do_size); |
2147 } | 2150 } |
2148 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); | 2151 memcpy (alternate_do_string + alternate_do_pointer, extptr, extlen); |
2149 alternate_do_pointer += extlen; | 2152 alternate_do_pointer += extlen; |
2150 alternate_do_string[alternate_do_pointer] = 0; | 2153 alternate_do_string[alternate_do_pointer] = 0; |
2151 } | 2154 } |
2258 report_file_error ("Opening termscript", filename); | 2261 report_file_error ("Opening termscript", filename); |
2259 } | 2262 } |
2260 return Qnil; | 2263 return Qnil; |
2261 } | 2264 } |
2262 | 2265 |
2266 static Lisp_Object | |
2267 restore_inhibit_non_essential_conversion_operations (Lisp_Object obj) | |
2268 { | |
2269 inhibit_non_essential_conversion_operations = XINT (obj); | |
2270 return Qnil; | |
2271 } | |
2272 | |
2273 /* Bind the value of inhibit_non_essential_conversion_operations to 1 | |
2274 in a way that involves no consing. */ | |
2275 static int | |
2276 begin_inhibit_non_essential_conversion_operations (void) | |
2277 { | |
2278 int depth = | |
2279 record_unwind_protect | |
2280 (restore_inhibit_non_essential_conversion_operations, | |
2281 make_int (inhibit_non_essential_conversion_operations)); | |
2282 inhibit_non_essential_conversion_operations = 1; | |
2283 return depth; | |
2284 } | |
2285 | |
2263 static int debug_print_length = 50; | 2286 static int debug_print_length = 50; |
2264 static int debug_print_level = 15; | 2287 static int debug_print_level = 15; |
2265 static int debug_print_readably = -1; | 2288 static int debug_print_readably = -1; |
2266 | 2289 |
2267 /* Restore values temporarily bound by debug_prin1. We use this approach to | 2290 /* Restore values temporarily bound by debug_prin1. We use this approach to |
2268 avoid consing in debug_prin1. That is verboten, since debug_prin1 can be | 2291 avoid consing in debug_prin1. That is verboten, since debug_print can be |
2269 called by cons debugging code. */ | 2292 called by cons debugging code. */ |
2270 static Lisp_Object | 2293 static Lisp_Object |
2271 debug_prin1_exit (Lisp_Object UNUSED (ignored)) | 2294 debug_print_exit (Lisp_Object val) |
2272 { | 2295 { |
2273 struct debug_bindings *bindings = | 2296 struct debug_bindings *bindings = |
2274 (struct debug_bindings *) XOPAQUE (debug_prin1_bindings)->data; | 2297 (struct debug_bindings *) GET_VOID_FROM_LISP (val); |
2275 inhibit_non_essential_conversion_operations = | 2298 inhibit_non_essential_conversion_operations = |
2276 bindings->inhibit_non_essential_conversion_operations; | 2299 bindings->inhibit_non_essential_conversion_operations; |
2277 print_depth = bindings->print_depth; | 2300 print_depth = bindings->print_depth; |
2278 print_readably = bindings->print_readably; | 2301 print_readably = bindings->print_readably; |
2279 print_unbuffered = bindings->print_unbuffered; | 2302 print_unbuffered = bindings->print_unbuffered; |
2283 Vprint_level = bindings->Vprint_level; | 2306 Vprint_level = bindings->Vprint_level; |
2284 Vinhibit_quit = bindings->Vinhibit_quit; | 2307 Vinhibit_quit = bindings->Vinhibit_quit; |
2285 return Qnil; | 2308 return Qnil; |
2286 } | 2309 } |
2287 | 2310 |
2288 /* Print an object, `prin1'-style, to various possible debugging outputs. | 2311 /* Save values and bind them to new values suitable for debug output. We |
2289 Make sure it's completely unbuffered so that, in the event of a crash | 2312 try very hard to avoid any Lisp allocation (i.e. consing) during the |
2290 somewhere, we see as much as possible that happened before it. | 2313 operation of debug printing, since we might be calling it from inside GC |
2291 */ | 2314 or other sensitive places. This means we have to be a bit careful with |
2292 static void | 2315 record_unwind_protect to not create any temporary Lisp objects. */ |
2293 debug_prin1 (Lisp_Object debug_print_obj, int flags) | 2316 |
2294 { | 2317 static int |
2295 /* This function can GC */ | 2318 debug_print_enter (struct debug_bindings *bindings) |
2296 | 2319 { |
2297 /* by doing this, we trick various things that are non-essential | 2320 /* by doing this, we trick various things that are non-essential |
2298 but might cause crashes into not getting executed. */ | 2321 but might cause crashes into not getting executed. */ |
2299 int specdepth; | 2322 int specdepth; |
2300 struct debug_bindings *bindings = | |
2301 (struct debug_bindings *) XOPAQUE (debug_prin1_bindings)->data; | |
2302 | 2323 |
2303 bindings->inhibit_non_essential_conversion_operations = | 2324 bindings->inhibit_non_essential_conversion_operations = |
2304 inhibit_non_essential_conversion_operations; | 2325 inhibit_non_essential_conversion_operations; |
2305 bindings->print_depth = print_depth; | 2326 bindings->print_depth = print_depth; |
2306 bindings->print_readably = print_readably; | 2327 bindings->print_readably = print_readably; |
2308 bindings->in_debug_print = in_debug_print; | 2329 bindings->in_debug_print = in_debug_print; |
2309 bindings->gc_currently_forbidden = gc_currently_forbidden; | 2330 bindings->gc_currently_forbidden = gc_currently_forbidden; |
2310 bindings->Vprint_length = Vprint_length; | 2331 bindings->Vprint_length = Vprint_length; |
2311 bindings->Vprint_level = Vprint_level; | 2332 bindings->Vprint_level = Vprint_level; |
2312 bindings->Vinhibit_quit = Vinhibit_quit; | 2333 bindings->Vinhibit_quit = Vinhibit_quit; |
2313 specdepth = record_unwind_protect (debug_prin1_exit, Qnil); | 2334 specdepth = record_unwind_protect (debug_print_exit, |
2335 STORE_VOID_IN_LISP (bindings)); | |
2314 | 2336 |
2315 inhibit_non_essential_conversion_operations = 1; | 2337 inhibit_non_essential_conversion_operations = 1; |
2316 print_depth = 0; | 2338 print_depth = 0; |
2317 print_readably = debug_print_readably != -1 ? debug_print_readably : 0; | 2339 print_readably = debug_print_readably != -1 ? debug_print_readably : 0; |
2318 print_unbuffered++; | 2340 print_unbuffered++; |
2322 Vprint_length = make_int (debug_print_length); | 2344 Vprint_length = make_int (debug_print_length); |
2323 if (debug_print_level > 0) | 2345 if (debug_print_level > 0) |
2324 Vprint_level = make_int (debug_print_level); | 2346 Vprint_level = make_int (debug_print_level); |
2325 Vinhibit_quit = Qt; | 2347 Vinhibit_quit = Qt; |
2326 | 2348 |
2349 return specdepth; | |
2350 } | |
2351 | |
2352 /* Print an object, `prin1'-style, to various possible debugging outputs. | |
2353 Make sure it's completely unbuffered so that, in the event of a crash | |
2354 somewhere, we see as much as possible that happened before it. | |
2355 */ | |
2356 static void | |
2357 debug_prin1 (Lisp_Object debug_print_obj, int flags) | |
2358 { | |
2359 /* This function cannot GC, since GC is forbidden */ | |
2360 struct debug_bindings bindings; | |
2361 int specdepth = debug_print_enter (&bindings); | |
2362 | |
2327 if ((flags & EXT_PRINT_STDOUT) || (flags & EXT_PRINT_STDERR)) | 2363 if ((flags & EXT_PRINT_STDOUT) || (flags & EXT_PRINT_STDERR)) |
2328 print_internal (debug_print_obj, Qexternal_debugging_output, 1); | 2364 print_internal (debug_print_obj, Qexternal_debugging_output, 1); |
2329 if (flags & EXT_PRINT_ALTERNATE) | 2365 if (flags & EXT_PRINT_ALTERNATE) |
2330 print_internal (debug_print_obj, Qalternate_debugging_output, 1); | 2366 print_internal (debug_print_obj, Qalternate_debugging_output, 1); |
2331 #ifdef WIN32_NATIVE | 2367 #ifdef WIN32_NATIVE |
2340 } | 2376 } |
2341 | 2377 |
2342 void | 2378 void |
2343 debug_p4 (Lisp_Object obj) | 2379 debug_p4 (Lisp_Object obj) |
2344 { | 2380 { |
2345 inhibit_non_essential_conversion_operations = 1; | |
2346 if (STRINGP (obj)) | 2381 if (STRINGP (obj)) |
2347 debug_out ("\"%s\"", XSTRING_DATA (obj)); | 2382 debug_out ("\"%s\"", XSTRING_DATA (obj)); |
2348 else if (CONSP (obj)) | 2383 else if (CONSP (obj)) |
2349 { | 2384 { |
2350 int first = 1; | 2385 int first = 1; |
2414 (EMACS_INT) (LHEADER_IMPLEMENTATION (header)->basic_p ? | 2449 (EMACS_INT) (LHEADER_IMPLEMENTATION (header)->basic_p ? |
2415 ((struct lrecord_header *) header)->uid : | 2450 ((struct lrecord_header *) header)->uid : |
2416 ((struct old_lcrecord_header *) header)->uid)); | 2451 ((struct old_lcrecord_header *) header)->uid)); |
2417 #endif /* not NEW_GC */ | 2452 #endif /* not NEW_GC */ |
2418 } | 2453 } |
2419 | 2454 } |
2420 inhibit_non_essential_conversion_operations = 0; | 2455 |
2421 } | 2456 static int |
2422 | |
2423 static void | |
2424 ext_print_begin (int dest) | 2457 ext_print_begin (int dest) |
2425 { | 2458 { |
2459 int depth = begin_inhibit_non_essential_conversion_operations (); | |
2426 if (dest & EXT_PRINT_ALTERNATE) | 2460 if (dest & EXT_PRINT_ALTERNATE) |
2427 alternate_do_pointer = 0; | 2461 alternate_do_pointer = 0; |
2428 if (dest & (EXT_PRINT_STDERR | EXT_PRINT_STDOUT)) | 2462 if (dest & (EXT_PRINT_STDERR | EXT_PRINT_STDOUT)) |
2429 stdout_clear_before_next_output = 1; | 2463 stdout_clear_before_next_output = 1; |
2464 return depth; | |
2430 } | 2465 } |
2431 | 2466 |
2432 static void | 2467 static void |
2433 ext_print_end (int dest) | 2468 ext_print_end (int dest, int depth) |
2434 { | 2469 { |
2435 if (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | EXT_PRINT_STDOUT)) | 2470 if (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | EXT_PRINT_STDOUT)) |
2436 external_out (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | | 2471 external_out (dest & (EXT_PRINT_MSWINDOWS | EXT_PRINT_STDERR | |
2437 EXT_PRINT_STDOUT), "\n"); | 2472 EXT_PRINT_STDOUT), "\n"); |
2473 unbind_to (depth); | |
2438 } | 2474 } |
2439 | 2475 |
2440 static void | 2476 static void |
2441 external_debug_print (Lisp_Object object, int dest) | 2477 external_debug_print (Lisp_Object object, int dest) |
2442 { | 2478 { |
2443 ext_print_begin (dest); | 2479 int depth = ext_print_begin (dest); |
2444 debug_prin1 (object, dest); | 2480 debug_prin1 (object, dest); |
2445 ext_print_end (dest); | 2481 ext_print_end (dest, depth); |
2446 } | 2482 } |
2447 | 2483 |
2448 void | 2484 void |
2449 debug_p3 (Lisp_Object obj) | 2485 debug_p3 (Lisp_Object obj) |
2450 { | 2486 { |
2451 debug_p4 (obj); | 2487 debug_p4 (obj); |
2452 inhibit_non_essential_conversion_operations = 1; | |
2453 debug_out ("\n"); | 2488 debug_out ("\n"); |
2454 inhibit_non_essential_conversion_operations = 0; | |
2455 } | 2489 } |
2456 | 2490 |
2457 void | 2491 void |
2458 debug_print (Lisp_Object debug_print_obj) | 2492 debug_print (Lisp_Object debug_print_obj) |
2459 { | 2493 { |
2481 /* Debugging kludge -- unbuffered */ | 2515 /* Debugging kludge -- unbuffered */ |
2482 /* This function provided for the benefit of the debugger. */ | 2516 /* This function provided for the benefit of the debugger. */ |
2483 void | 2517 void |
2484 debug_backtrace (void) | 2518 debug_backtrace (void) |
2485 { | 2519 { |
2486 /* This function can GC */ | 2520 /* This function cannot GC, since GC is forbidden */ |
2487 | 2521 struct debug_bindings bindings; |
2488 /* by doing this, we trick various things that are non-essential | 2522 int specdepth = debug_print_enter (&bindings); |
2489 but might cause crashes into not getting executed. */ | |
2490 int specdepth = | |
2491 internal_bind_int (&inhibit_non_essential_conversion_operations, 1); | |
2492 | |
2493 internal_bind_int (&print_depth, 0); | |
2494 internal_bind_int (&print_readably, 0); | |
2495 internal_bind_int (&print_unbuffered, print_unbuffered + 1); | |
2496 if (debug_print_length > 0) | |
2497 internal_bind_lisp_object (&Vprint_length, make_int (debug_print_length)); | |
2498 if (debug_print_level > 0) | |
2499 internal_bind_lisp_object (&Vprint_level, make_int (debug_print_level)); | |
2500 /* #### Do we need this? It was in the old code. */ | |
2501 internal_bind_lisp_object (&Vinhibit_quit, Vinhibit_quit); | |
2502 | 2523 |
2503 Fbacktrace (Qexternal_debugging_output, Qt); | 2524 Fbacktrace (Qexternal_debugging_output, Qt); |
2504 stderr_out ("\n"); | 2525 stderr_out ("\n"); |
2505 | 2526 |
2506 unbind_to (specdepth); | 2527 unbind_to (specdepth); |
2517 void | 2538 void |
2518 debug_short_backtrace (int length) | 2539 debug_short_backtrace (int length) |
2519 { | 2540 { |
2520 int first = 1; | 2541 int first = 1; |
2521 struct backtrace *bt = backtrace_list; | 2542 struct backtrace *bt = backtrace_list; |
2543 | |
2522 debug_out (" ["); | 2544 debug_out (" ["); |
2523 while (length > 0 && bt) | 2545 while (length > 0 && bt) |
2524 { | 2546 { |
2525 if (!first) | 2547 if (!first) |
2526 { | 2548 { |
2696 Label for minibuffer messages created with `print'. This should | 2718 Label for minibuffer messages created with `print'. This should |
2697 generally be bound with `let' rather than set. (See `display-message'.) | 2719 generally be bound with `let' rather than set. (See `display-message'.) |
2698 */ ); | 2720 */ ); |
2699 Vprint_message_label = Qprint; | 2721 Vprint_message_label = Qprint; |
2700 | 2722 |
2701 debug_prin1_bindings = | 2723 /* The exact size doesn't matter since we realloc when necessary. |
2702 make_opaque (OPAQUE_UNINIT, sizeof (struct debug_bindings)); | 2724 Use CIbyte instead of Ibyte so that debuggers show the associated |
2703 staticpro (&debug_prin1_bindings); | 2725 string automatically. */ |
2704 | |
2705 alternate_do_size = 5000; | 2726 alternate_do_size = 5000; |
2706 alternate_do_string = xnew_array(char, 5000); | 2727 alternate_do_string = xnew_array (CIbyte, 5000); |
2707 } | 2728 } |