diff options
author | Jakob Kaivo <jkk@ung.org> | 2023-11-27 14:08:35 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2023-11-27 14:08:35 -0500 |
commit | 43bc9bea0773cce280c4d4442a494fe24f8e92bd (patch) | |
tree | 3fbc8ec51783b86d6eb8fbfc2ddc14d2fc46c40f | |
parent | 4d16801b9a6727d39a49dde70daa29eeac15a16c (diff) |
add framework for marking function call location in diagnostics
-rw-r--r-- | src/__checked_call.c | 6 | ||||
-rw-r--r-- | src/__checked_i.c | 41 | ||||
-rw-r--r-- | src/_assert.h | 11 | ||||
-rw-r--r-- | src/stdlib/abort_handler_s.c | 12 |
4 files changed, 67 insertions, 3 deletions
diff --git a/src/__checked_call.c b/src/__checked_call.c new file mode 100644 index 00000000..c44ad8f3 --- /dev/null +++ b/src/__checked_call.c @@ -0,0 +1,6 @@ +#include "_assert.h" + +#ifdef THREADS +_Thread_local +#endif +struct __checked_call __checked_call = { 0 }; diff --git a/src/__checked_i.c b/src/__checked_i.c new file mode 100644 index 00000000..f3b62bcf --- /dev/null +++ b/src/__checked_i.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <ctype.h> +#include <stdarg.h> +#include "_assert.h" + +#define F(fn) (int(*)())(fn) + +int __checked_i(const char *file, const char *func, unsigned long long line, int (*fn)(), ...) +{ + va_list ap; + int ret = -1; + + __checked_call.func = (char*)func; + __checked_call.file = (char*)file; + __checked_call.line = line; + + va_start(ap, fn); + + if (fn == F(isalpha) + || fn == F(isdigit) + || fn == F(isupper) + || fn == F(islower) + || fn == F(toupper) + || fn == F(tolower) + ) { + int arg = va_arg(ap, int); + ret = fn(arg); + } + + va_end(ap); + + __checked_call.func = NULL; + __checked_call.file = NULL; + __checked_call.line = 0; + + return ret; +} + +/* +STDC(0) +*/ diff --git a/src/_assert.h b/src/_assert.h index 1d7b1637..2466455f 100644 --- a/src/_assert.h +++ b/src/_assert.h @@ -5,13 +5,22 @@ #include <stdio.h> #include "stdlib/_stdlib.h" +#ifdef THREADS +_Thread_local +#endif +extern struct __checked_call { + char *file; + char *func; + unsigned long long line; +} __checked_call; + #ifndef NDEBUG #define ASSERT_NONNULL(__ptr) do { \ if (!__ptr) { \ struct __constraint_info _ci = {0}; \ _ci.func = __func__; \ __stdlib.constraint_handler("Undefined behavior: " \ - "Parameter " #__ptr " can not be NULL", &_ci, EFAULT); \ + "Parameter " #__ptr " can not be NULL", &_ci, 0 /* was EFAULT */); \ } \ } while (0) diff --git a/src/stdlib/abort_handler_s.c b/src/stdlib/abort_handler_s.c index c35148a7..f6471151 100644 --- a/src/stdlib/abort_handler_s.c +++ b/src/stdlib/abort_handler_s.c @@ -4,6 +4,7 @@ //#include <errno.h> #include "errno/errno_t.h" #include "_stdlib.h" +#include "_assert.h" void abort_handler_s(const char * restrict msg, void * restrict ptr, errno_t error) { @@ -11,8 +12,15 @@ void abort_handler_s(const char * restrict msg, void * restrict ptr, errno_t err puts(msg); if (ci) { - printf("In call to %s\n", ci->func); - printf("value %x\n", ci->value); + printf("In call to %s()", ci->func); + if (__checked_call.file) { + printf(" ("); + if (__checked_call.func) { + printf("in %s(), ", __checked_call.func); + } + printf("at %s:%llu)", __checked_call.file, __checked_call.line); + } + printf(", value %x\n", ci->value); } if (error != 0) { printf("Provided error: %s (%d)\n", strerror(error), error); |