diff options
-rw-r--r-- | src/_safety.h | 26 | ||||
-rw-r--r-- | src/stdio/__printf.c | 3 | ||||
-rw-r--r-- | src/stdio/__scanf.c | 14 | ||||
-rw-r--r-- | src/stdio/_stdio.h | 2 |
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; |