diff --git a/include/QF/progs.h b/include/QF/progs.h index c615e6d14..e2c077e02 100644 --- a/include/QF/progs.h +++ b/include/QF/progs.h @@ -1690,6 +1690,15 @@ typedef struct { strref_t *tstr; ///< Linked list of temporary strings. } prstack_t; +typedef enum { + prd_none, + prd_trace, + prd_breakpoint, + prd_watchpoint, + prd_runerror, + prd_error, // lower level error thann prd_runerror +} prdebug_t; + struct progs_s { int (*parse_field) (progs_t *pr, const char *key, const char *value); @@ -1831,7 +1840,9 @@ struct progs_s { /// \name debugging ///@{ struct prdeb_resources_s *pr_debug_resources; - void (*breakpoint_handler) (progs_t *pr); + void (*debug_handler) (prdebug_t event, void *data); + void *debug_data; + const char *error_string; pr_type_t *watch; int wp_conditional; pr_type_t wp_val; diff --git a/libs/gamecode/pr_exec.c b/libs/gamecode/pr_exec.c index 397eb7bde..94018943b 100644 --- a/libs/gamecode/pr_exec.c +++ b/libs/gamecode/pr_exec.c @@ -62,6 +62,12 @@ PR_RunError (progs_t * pr, const char *error, ...) dvsprintf (string, error, argptr); va_end (argptr); + if (pr->debug_handler) { + pr->error_string = string->str; + pr->debug_handler (prd_runerror, pr->debug_data); + // not expected to return, but if so, behave as if there was no handler + } + Sys_Printf ("%s\n", string->str); PR_DumpState (pr); @@ -477,12 +483,17 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum) op_b = pr->pr_globals + st->b; op_c = pr->pr_globals + st->c; - if (pr->pr_trace) - PR_PrintStatement (pr, st, 1); + if (pr->pr_trace) { + if (pr->debug_handler) { + pr->debug_handler (prd_trace, pr->debug_data); + } else { + PR_PrintStatement (pr, st, 1); + } + } if (st->op & OP_BREAK) { - if (pr->breakpoint_handler) { - pr->breakpoint_handler (pr); + if (pr->debug_handler) { + pr->debug_handler (prd_breakpoint, pr->debug_data); } else { PR_RunError (pr, "breakpoint hit"); } @@ -1701,8 +1712,12 @@ op_call: if (watch && watch->integer_var != old_val.integer_var) { if (!pr->wp_conditional || watch->integer_var == pr->wp_val.integer_var) { - PR_RunError (pr, "watchpoint hit: %d -> %d", - old_val.integer_var, watch->integer_var); + if (pr->debug_handler) { + pr->debug_handler (prd_watchpoint, pr->debug_data); + } else { + PR_RunError (pr, "watchpoint hit: %d -> %d", + old_val.integer_var, watch->integer_var); + } } old_val.integer_var = watch->integer_var; } diff --git a/libs/gamecode/pr_load.c b/libs/gamecode/pr_load.c index d385dff12..2bae32dfe 100644 --- a/libs/gamecode/pr_load.c +++ b/libs/gamecode/pr_load.c @@ -323,6 +323,7 @@ PR_LoadProgsFile (progs_t *pr, QFile *file, int size) def->type_encoding = xdef->type; } } + pr->error_string = 0; pr->pr_trace = 0; pr->pr_trace_depth = 0; pr->pr_xfunction = 0; @@ -485,5 +486,10 @@ PR_Error (progs_t *pr, const char *error, ...) dvsprintf (string, error, argptr); va_end (argptr); + if (pr->debug_handler) { + pr->error_string = string->str; + pr->debug_handler (prd_error, pr->debug_data); + // not expected to return, but if so, behave as if there was no handler + } Sys_Error ("%s: %s", pr->progs_name, string->str); }