summaryrefslogtreecommitdiffstats
path: root/unwind.c
diff options
context:
space:
mode:
Diffstat (limited to 'unwind.c')
-rw-r--r--unwind.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/unwind.c b/unwind.c
index 5a880acc..4c839735 100644
--- a/unwind.c
+++ b/unwind.c
@@ -59,6 +59,8 @@ static val sys_cont_free_s, sys_capture_cont_s;
static val frame_type, catch_frame_type, handle_frame_type;
+static val deferred_warnings;
+
/* C99 inline instantiations. */
#if __STDC_VERSION__ >= 199901L
val uw_block_return(val tag, val result);
@@ -578,7 +580,10 @@ val uw_throw(val sym, val args)
if (sym == warning_s) {
--reentry_count;
- format(std_error, lit("warning: ~a\n"), car(args), nao);
+ if (cdr(args))
+ uw_defer_warning(args);
+ else
+ format(std_error, lit("warning: ~a\n"), car(args), nao);
uw_throw(continue_s, nil);
abort();
}
@@ -669,6 +674,30 @@ val type_mismatch(val fmt, ...)
abort();
}
+val uw_defer_warning(val args)
+{
+ push(args, &deferred_warnings);
+ return nil;
+}
+
+val uw_dump_deferred_warnings(val stream)
+{
+ val wl = nreverse(zap(&deferred_warnings));
+
+ for (; wl; wl = cdr(wl)) {
+ val args = car(wl);
+ format(stream, lit("warning: ~a\n"), car(args), nao);
+ }
+
+ return nil;
+}
+
+val uw_purge_deferred_warning(val tag)
+{
+ deferred_warnings = remqual(tag, deferred_warnings, cdr_f);
+ return nil;
+}
+
val uw_register_subtype(val sub, val sup)
{
val t_entry = assoc(t, exception_subtypes);
@@ -969,7 +998,7 @@ void uw_init(void)
void uw_late_init(void)
{
protect(&frame_type, &catch_frame_type, &handle_frame_type,
- convert(val *, 0));
+ &deferred_warnings, convert(val *, 0));
types_s = intern(lit("types"), user_package);
jump_s = intern(lit("jump"), user_package);
sys_cont_s = intern(lit("cont"), system_package);