From a0e1171e7b5b01c683230d9db8cca478e2a19f0e Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 18 Feb 2024 11:27:22 +0000 Subject: [PATCH] Option --exit-severity now also controls exit status. Fixes #850 --- NEWS.md | 2 ++ nvc.1 | 8 +++++++- src/nvc.c | 9 ++++++++- src/rt/assert.c | 16 ++++++++++++++++ src/rt/assert.h | 2 ++ src/rt/model.c | 5 +---- test/regress/issue850.sh | 21 +++++++++++++++++++++ test/regress/testlist.txt | 1 + 8 files changed, 58 insertions(+), 6 deletions(-) create mode 100644 test/regress/issue850.sh diff --git a/NEWS.md b/NEWS.md index 9c6b9512..655569d8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,6 +14,8 @@ - Fixed a bug where `'last_value` could give the wrong result if the signal has multiple sources. - Updated to OSVVM 2023.09a and UVVM 2023.09.16 for `nvc --install`. +- The `--exit-severity=` option now also controls which severity level + results in a non-zero exit code (#850). ## Version 1.11.3 - 2024-02-04 - Fixed incorrect effective value when a signal has multiple sources due diff --git a/nvc.1 b/nvc.1 index 2177a829..5ec04cfb 100644 --- a/nvc.1 +++ b/nvc.1 @@ -337,7 +337,13 @@ Valid levels are and .Cm failure . The default is -.Cm error . +.Cm failure . +.Pp +This option also overrides the minimum severity level which causes the +program to return a non-zero status code. +The default is +.Cm error +which allows assertion violations to be detected easily. .\" --format .It Fl \-format= Ns Ar fmt Generate waveform data in format diff --git a/src/nvc.c b/src/nvc.c index 254dacd3..ac0f670c 100644 --- a/src/nvc.c +++ b/src/nvc.c @@ -571,6 +571,13 @@ static vhdl_severity_t parse_severity(const char *str) fatal("invalid severity level: %s", str); } +static void parse_exit_severity(const char *str) +{ + const vhdl_severity_t s = parse_severity(optarg); + set_exit_severity(s); + set_status_severity(s); +} + static int parse_stop_delta(const char *str) { const int ival = parse_int(str); @@ -728,7 +735,7 @@ static int run_cmd(int argc, char **argv, cmd_state_t *state) vhpi_plugins = optarg; break; case 'x': - set_exit_severity(parse_severity(optarg)); + parse_exit_severity(optarg); break; case 'I': opt_set_int(OPT_IEEE_WARNINGS, parse_on_off(optarg)); diff --git a/src/rt/assert.c b/src/rt/assert.c index 378c8d65..8fe78e1f 100644 --- a/src/rt/assert.c +++ b/src/rt/assert.c @@ -76,6 +76,7 @@ static const struct { static format_part_t *format[SEVERITY_FAILURE + 1]; static vhdl_severity_t exit_severity = SEVERITY_FAILURE; +static vhdl_severity_t status_severity = SEVERITY_ERROR; static unsigned counts[SEVERITY_FAILURE + 1]; static unsigned enable_mask = ~0u; @@ -498,6 +499,11 @@ void set_stderr_severity(vhdl_severity_t severity) opt_set_int(OPT_STDERR_LEVEL, get_diag_severity(severity)); } +void set_status_severity(vhdl_severity_t severity) +{ + status_severity = severity; +} + int64_t get_vhdl_assert_count(vhdl_severity_t severity) { assert(severity <= SEVERITY_FAILURE); @@ -525,3 +531,13 @@ bool get_vhdl_assert_enable(vhdl_severity_t severity) assert(severity <= SEVERITY_FAILURE); return !!(enable_mask & (1 << severity)); } + +int get_vhdl_assert_exit_status(void) +{ + for (int s = status_severity; s <= SEVERITY_FAILURE; s++) { + if (counts[s] > 0) + return EXIT_FAILURE; + } + + return 0; +} diff --git a/src/rt/assert.h b/src/rt/assert.h index b55a05fe..6971f868 100644 --- a/src/rt/assert.h +++ b/src/rt/assert.h @@ -31,11 +31,13 @@ typedef enum { diag_level_t vhdl_to_diag_severity(vhdl_severity_t severity); vhdl_severity_t set_exit_severity(vhdl_severity_t severity); +void set_status_severity(vhdl_severity_t severity); void set_stderr_severity(vhdl_severity_t severity); int64_t get_vhdl_assert_count(vhdl_severity_t severity); void clear_vhdl_assert(void); void set_vhdl_assert_enable(vhdl_severity_t severity, bool enable); bool get_vhdl_assert_enable(vhdl_severity_t severity); +int get_vhdl_assert_exit_status(void); #endif // _RT_ASSERT_H diff --git a/src/rt/model.c b/src/rt/model.c index 0519544f..8e5d5160 100644 --- a/src/rt/model.c +++ b/src/rt/model.c @@ -3464,13 +3464,10 @@ int model_exit_status(rt_model_t *m) int status; if (jit_exit_status(m->jit, &status)) return status; - else if (get_vhdl_assert_count(SEVERITY_ERROR) > 0 - || get_vhdl_assert_count(SEVERITY_FAILURE) > 0) - return EXIT_FAILURE; else if (m->stop_delta > 0 && m->iteration == m->stop_delta) return EXIT_FAILURE; else - return 0; + return get_vhdl_assert_exit_status(); } // TODO: this interface should be removed eventually diff --git a/test/regress/issue850.sh b/test/regress/issue850.sh new file mode 100644 index 00000000..0056a127 --- /dev/null +++ b/test/regress/issue850.sh @@ -0,0 +1,21 @@ +set -xe + +pwd +which nvc + +nvc -a - -e issue850 <