summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/_safety.h26
-rw-r--r--src/stdio/__printf.c3
-rw-r--r--src/stdio/__scanf.c14
-rw-r--r--src/stdio/_stdio.h2
4 files changed, 44 insertions, 1 deletions
diff --git a/src/_safety.h b/src/_safety.h
index 8f157b7b..5f8dadc4 100644
--- a/src/_safety.h
+++ b/src/_safety.h
@@ -53,6 +53,18 @@ extern struct __dangerous {
(__count)++; \
} while (0)
+#define ADD_PREV_STRING(__val, __arr, __count) do { \
+ void *tmp = realloc((__arr), ((__count) + 1) * sizeof((__arr)[0])); \
+ if (tmp == NULL) { \
+ fprintf(stderr, "Out of memory tracking values\n"); \
+ abort(); \
+ } \
+ (__arr) = tmp; \
+ printf("Adding %s\n", (__val)); \
+ (__arr)[__count] = strdup(__val); \
+ (__count)++; \
+} while (0)
+
#define ASSERT_PREV(__val, __arr, __count, __prev) do { \
int __found = 0; \
for (size_t __i = 0; __i < (__count); __i++) { \
@@ -66,6 +78,20 @@ extern struct __dangerous {
} \
} while (0)
+#define ASSERT_PREV_STRING(__val, __arr, __count, __prev) do { \
+ int __found = 0; \
+ for (size_t __i = 0; __i < (__count); __i++) { \
+ printf("checking '%s' vs [%zu] '%s'\n", (__val), __i, (__arr)[__i]); \
+ if (strcmp((__arr)[__i], (__val)) == 0) { \
+ __found = 1; \
+ break; \
+ } \
+ } \
+ if (!__found) { \
+ UNDEFINED("In call to %s(): %s was not returned by a previous call to %s", __func__, __val, __prev); \
+ } \
+} while (0)
+
#define ASSERT_NONNULL(__ptr) do { \
if (!__ptr) { \
UNDEFINED("In call to %s(), parameter %s cannot be NULL", __func__, #__ptr); \
diff --git a/src/stdio/__printf.c b/src/stdio/__printf.c
index 1ee488d7..05c79747 100644
--- a/src/stdio/__printf.c
+++ b/src/stdio/__printf.c
@@ -11,6 +11,7 @@
#endif
#include "_forced/strtoumax.h"
+#include "_forced/strdup.h"
#include "_stdio.h"
@@ -339,9 +340,11 @@ int (__printf)(struct io_options *opt, const char * format, va_list arg)
UNDEFINED("In call to %s(): Precision with %%p conversion", opt->fnname);
}
argptr = va_arg(arg, void *);
+ char *s_to_track = s + nout;
nout = __append(s, "0x", nout, n);
__itos(numbuf, (intptr_t)argptr, ZERO, sizeof(argptr) * 2, 16);
nout = __append(s, numbuf, nout, n);
+ ADD_PREV_STRING(s_to_track, __stdio.formatted_pointers, __stdio.nformatted_pointers);
break;
case 'n': /* write-back */
diff --git a/src/stdio/__scanf.c b/src/stdio/__scanf.c
index f746a6ab..75e42942 100644
--- a/src/stdio/__scanf.c
+++ b/src/stdio/__scanf.c
@@ -230,7 +230,7 @@ int __scanf(struct io_options *opt, const char * format, va_list arg)
char *str = va_arg(arg, char *);
- /* TODO: only use widht if conv.has_width == 1 */
+ /* TODO: only use width if conv.has_width == 1 */
for (uintmax_t i = 0; i < conv.width; i++) {
int c = __get(opt);
if (isspace(c)) {
@@ -248,6 +248,18 @@ int __scanf(struct io_options *opt, const char * format, va_list arg)
case 'p':
/* previous printf("%p"); */
+ char str_ptr[sizeof(void *) * 2 + 3];
+ for (size_t i = 0; i < sizeof(str_ptr); i++) {
+ /* TODO: error checking */
+ str_ptr[i] = __get(opt);
+ }
+ ASSERT_PREV_STRING(str_ptr, __stdio.formatted_pointers, __stdio.nformatted_pointers, "printf() or similar");
+ void **ptr = va_arg(arg, void **);
+ if (ptr == NULL) {
+ UNDEFINED("parameter is NULL");
+ }
+ *ptr = (void*)strtoumax(str_ptr, NULL, 0);
+ break;
case 'n':
/* output a number */
diff --git a/src/stdio/_stdio.h b/src/stdio/_stdio.h
index f363bd75..57d33e63 100644
--- a/src/stdio/_stdio.h
+++ b/src/stdio/_stdio.h
@@ -130,6 +130,8 @@ int __scanf(struct io_options * restrict, const char * restrict, va_list);
struct __stdio {
struct __FILE FILES[FOPEN_MAX];
+ char **formatted_pointers;
+ size_t nformatted_pointers;
};
extern struct __stdio __stdio;