From b91e48d2a19d9bc1e1807f27db06988a7104ce37 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 5 Apr 2024 01:26:02 +0900 Subject: [PATCH] added hcl_seterrbfmtloc() and hcl_seterrufmtloc() added the errloc field to hcl_t to capture the exception location --- bin/main.c | 31 ++++++++++++++++++++++--------- lib/err.c | 27 ++++++++++++++++++++++++++- lib/exec.c | 13 +++++++++++-- lib/hcl.h | 25 +++++++++++++++++++++++-- t/class-5001.err | 32 +++++++++++++++++++++++--------- 5 files changed, 105 insertions(+), 23 deletions(-) diff --git a/bin/main.c b/bin/main.c index b0bb1c9..df3cc68 100644 --- a/bin/main.c +++ b/bin/main.c @@ -378,13 +378,9 @@ static void print_synerr (hcl_t* hcl) hcl_logbfmt (hcl,HCL_LOG_STDERR, "ERROR: "); if (synerr.loc.file) - { hcl_logbfmt (hcl, HCL_LOG_STDERR, "%js", synerr.loc.file); - } else - { hcl_logbfmt (hcl, HCL_LOG_STDERR, "%hs", xtn->cci_path); - } hcl_logbfmt (hcl, HCL_LOG_STDERR, "[%zu,%zu] %js", synerr.loc.line, synerr.loc.colm, @@ -392,18 +388,35 @@ static void print_synerr (hcl_t* hcl) ); if (synerr.tgt.len > 0) - { hcl_logbfmt (hcl, HCL_LOG_STDERR, " - %.*js", synerr.tgt.len, synerr.tgt.val); - } hcl_logbfmt (hcl, HCL_LOG_STDERR, "\n"); } +static void print_other_error (hcl_t* hcl) +{ + xtn_t* xtn; + hcl_loc_t loc; + + xtn = (xtn_t*)hcl_getxtn(hcl); + hcl_geterrloc(hcl, &loc); + + hcl_logbfmt (hcl,HCL_LOG_STDERR, "ERROR: "); + if (loc.file) + hcl_logbfmt (hcl, HCL_LOG_STDERR, "%js", loc.file); + else + hcl_logbfmt (hcl, HCL_LOG_STDERR, "%hs", xtn->cci_path); + + hcl_logbfmt (hcl, HCL_LOG_STDERR, "[%zu,%zu] %js", loc.line, loc.colm, hcl_geterrmsg(hcl)); + + hcl_logbfmt (hcl, HCL_LOG_STDERR, "\n"); +} static void print_error (hcl_t* hcl, const hcl_bch_t* msghdr) { if (HCL_ERRNUM(hcl) == HCL_ESYNERR) print_synerr (hcl); - else hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: %hs - [%d] %js\n", msghdr, hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); + else print_other_error (hcl); + /*else hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: %hs - [%d] %js\n", msghdr, hcl_geterrnum(hcl), hcl_geterrmsg(hcl));*/ } static void show_prompt (hcl_t* hcl, int level) @@ -429,7 +442,7 @@ static hcl_oop_t execute_in_interactive_mode (hcl_t* hcl) if (!retv) { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot execute - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); + print_error (hcl, "cannot execute"); } else { @@ -486,7 +499,7 @@ static hcl_oop_t execute_in_batch_mode(hcl_t* hcl, int verbose) if (!retv) { - hcl_logbfmt (hcl, HCL_LOG_STDERR, "ERROR: cannot execute - [%d] %js\n", hcl_geterrnum(hcl), hcl_geterrmsg(hcl)); + print_error (hcl, "cannot execute"); } else if (verbose) { diff --git a/lib/err.c b/lib/err.c index 7c07864..1a25fd5 100644 --- a/lib/err.c +++ b/lib/err.c @@ -286,6 +286,12 @@ void hcl_seterrnum (hcl_t* hcl, hcl_errnum_t errnum) if (hcl->shuterr) return; hcl->errnum = errnum; hcl->errmsg.len = 0; + HCL_MEMSET (&hcl->errloc, 0, HCL_SIZEOF(hcl->errloc)); +} + +void hcl_geterrloc (hcl_t* hcl, hcl_loc_t* loc) +{ + if (loc) *loc = hcl->errloc; } void hcl_seterrbmsg (hcl_t* hcl, hcl_errnum_t errnum, const hcl_bch_t* errmsg) @@ -293,7 +299,6 @@ void hcl_seterrbmsg (hcl_t* hcl, hcl_errnum_t errnum, const hcl_bch_t* errmsg) hcl_seterrbfmt(hcl, errnum, "%hs", errmsg); } - void hcl_seterrumsg (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* errmsg) { hcl_seterrbfmt(hcl, errnum, "%ls", errmsg); @@ -363,6 +368,7 @@ void hcl_seterrbfmt (hcl_t* hcl, hcl_errnum_t errnum, const hcl_bch_t* fmt, ...) va_end (ap); hcl->errnum = errnum; + HCL_MEMSET (&hcl->errloc, 0, HCL_SIZEOF(hcl->errloc)); } void hcl_seterrufmt (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, ...) @@ -384,6 +390,7 @@ void hcl_seterrufmt (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, ...) va_end (ap); hcl->errnum = errnum; + HCL_MEMSET (&hcl->errloc, 0, HCL_SIZEOF(hcl->errloc)); } @@ -403,6 +410,7 @@ void hcl_seterrbfmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_bch_t* fmt, va_ hcl_bfmt_outv (&fo, fmt, ap); hcl->errnum = errnum; + HCL_MEMSET (&hcl->errloc, 0, HCL_SIZEOF(hcl->errloc)); } void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_list ap) @@ -421,9 +429,26 @@ void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_ hcl_ufmt_outv (&fo, fmt, ap); hcl->errnum = errnum; + HCL_MEMSET (&hcl->errloc, 0, HCL_SIZEOF(hcl->errloc)); } +void hcl_seterrbfmtloc (hcl_t* hcl, hcl_errnum_t errnum, const hcl_loc_t* loc, const hcl_bch_t* fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + hcl_seterrbfmtv (hcl, errnum, fmt, ap); + va_end (ap); + hcl->errloc = *loc; +} +void hcl_seterrufmtloc (hcl_t* hcl, hcl_errnum_t errnum, const hcl_loc_t* loc, const hcl_uch_t* fmt, ...) +{ + va_list ap; + va_start (ap, fmt); + hcl_seterrufmtv (hcl, errnum, fmt, ap); + va_end (ap); + hcl->errloc = *loc; +} void hcl_seterrwithsyserr (hcl_t* hcl, int syserr_type, int syserr_code) { diff --git a/lib/exec.c b/lib/exec.c index 1ad7a70..d502ddd 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -2310,9 +2310,15 @@ static HCL_INLINE int do_throw (hcl_t* hcl, hcl_oop_t val, hcl_ooi_t ip) if (hcl->active_function->dbgi != hcl->_nil) { hcl_dbgi_t* dbgi; + hcl_loc_t loc; + dbgi = (hcl_dbgi_t*)HCL_OBJ_GET_BYTE_SLOT(hcl->active_function->dbgi); HCL_LOG3 (hcl, HCL_LOG_IC | HCL_LOG_WARN, "Warning - exception not handled %js:%zu- %O", (dbgi[ip].fname? dbgi[ip].fname: oocstr_dash), dbgi[ip].sline, val); - hcl_seterrbfmt (hcl, HCL_EEXCEPT, "exception not handled in %js:%zu - %O", (dbgi[ip].fname? dbgi[ip].fname: oocstr_dash), dbgi[ip].sline, val); + HCL_MEMSET (&loc, 0, HCL_SIZEOF(loc)); + loc.file = dbgi[ip].fname; + loc.line = dbgi[ip].sline; + hcl_seterrbfmtloc (hcl, HCL_EEXCEPT, &loc, "exception not handled - %O", val); + /* column number is not available */ } else { @@ -2360,14 +2366,17 @@ static void supplement_errmsg (hcl_t* hcl, hcl_ooi_t ip) if (hcl->active_function->dbgi != hcl->_nil) { hcl_dbgi_t* dbgi; + hcl_loc_t orgloc = hcl->errloc; const hcl_ooch_t* orgmsg = hcl_backuperrmsg(hcl); hcl_errnum_t orgnum = HCL_ERRNUM(hcl); HCL_ASSERT (hcl, HCL_IS_BYTEARRAY(hcl, hcl->active_function->dbgi)); dbgi = (hcl_dbgi_t*)HCL_OBJ_GET_BYTE_SLOT(hcl->active_function->dbgi); - hcl_seterrbfmt (hcl, orgnum, "%js (%js:%zu)", orgmsg, + hcl_seterrbfmtloc (hcl, orgnum, &orgloc, "%js (%js:%zu)", orgmsg, (dbgi[ip].fname? dbgi[ip].fname: oocstr_dash), dbgi[ip].sline); + + /* no column info available */ } } diff --git a/lib/hcl.h b/lib/hcl.h index d534cf4..fe6811b 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -1513,7 +1513,6 @@ struct hcl_synerr_t } tgt; }; - typedef struct hcl_dbgi_t hcl_dbgi_t; struct hcl_dbgi_t { @@ -1590,6 +1589,7 @@ struct hcl_t hcl_oow_t len; } errmsg; + hcl_loc_t errloc; int shuterr; struct @@ -2164,6 +2164,11 @@ HCL_EXPORT void hcl_seterrnum ( hcl_errnum_t errnum ); +HCL_EXPORT void hcl_geterrloc ( + hcl_t* hcl, + hcl_loc_t* loc +); + HCL_EXPORT void hcl_seterrbmsg ( hcl_t* hcl, hcl_errnum_t errnum, @@ -2212,6 +2217,22 @@ HCL_EXPORT void hcl_seterrufmt ( ... ); +HCL_EXPORT void hcl_seterrbfmtloc ( + hcl_t* hcl, + hcl_errnum_t errnum, + const hcl_loc_t* loc, + const hcl_bch_t* fmt, + ... +); + +HCL_EXPORT void hcl_seterrufmtloc ( + hcl_t* hcl, + hcl_errnum_t errnum, + const hcl_loc_t* loc, + const hcl_uch_t* fmt, + ... +); + HCL_EXPORT void hcl_seterrbfmtv ( hcl_t* hcl, hcl_errnum_t errnum, @@ -2226,6 +2247,7 @@ HCL_EXPORT void hcl_seterrufmtv ( va_list ap ); + HCL_EXPORT const hcl_ooch_t* hcl_geterrstr ( hcl_t* hcl ); @@ -2536,7 +2558,6 @@ static HCL_INLINE hcl_ooi_t hcl_getip (hcl_t* hcl) { return hcl->ip; } # define hcl_getip(hcl) ((hcl)->ip) #endif - /* ========================================================================= * SYNTAX ERROR HANDLING * ========================================================================= */ diff --git a/t/class-5001.err b/t/class-5001.err index 3cc1131..acb3877 100644 --- a/t/class-5001.err +++ b/t/class-5001.err @@ -25,15 +25,29 @@ defclass X :: B | a b | { --- defclass X { - defun :* xxx() { - return X; - } - defun :* qqq() { - return "hello" - } + defun :* xxx() { + return X; + } + defun :* qqq() { + return "hello" + } - defun String:length() { ##ERROR: syntax error - function name not valid - return (str.length self) - } + defun String:length() { ##ERROR: syntax error - function name not valid + return (str.length self) + } } +--- +defclass X { + defun :* xxx() { + return X; + } + defun :* qqq() { + return "hello" + } +} + +## this will trigger a runtime error as J isn't a class name +defun J:ccc() { ##ERROR: exception not handled + return 999 +}