summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/__checked_call.c6
-rw-r--r--src/__checked_i.c41
-rw-r--r--src/_assert.h11
-rw-r--r--src/stdlib/abort_handler_s.c12
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);