From 9557448ae65c8f767a3f42826ddff8b4334c3104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C3=A9veill=C3=A9?= <nicolas@uucidl.com> Date: Sun, 16 Aug 2015 16:46:52 +0200 Subject: [PATCH] Introduce {v,}asprintf for windows We have now again two functions called h_platform_vasprintf and h_platform_asprintf. On windows they are implemented in terms of vsnprint and the like. On BSD/GNU libraries we use the supplied vasprintf and asprintf. --- src/backends/regex_debug.c | 5 ++--- src/platform.h | 9 +++++++++ src/platform_bsdlike.c | 19 +++++++++++++++++- src/platform_win32.c | 41 +++++++++++++++++++++++++++++++++++++- src/pprint.c | 30 +++++++++++++++++++--------- 5 files changed, 90 insertions(+), 14 deletions(-) diff --git a/src/backends/regex_debug.c b/src/backends/regex_debug.c index d28f9b2b..5207d9e1 100644 --- a/src/backends/regex_debug.c +++ b/src/backends/regex_debug.c @@ -1,6 +1,5 @@ // Intended to be included from regex_debug.c -#define _GNU_SOURCE -#include <stdio.h> +#include "../platform.h" #include <stdlib.h> #define USE_DLADDR (0) @@ -22,7 +21,7 @@ char* getsym(HSVMActionFunc addr) { return retstr; } else #endif - if (asprintf(&retstr, "%p", addr) > 0) + if (h_platform_asprintf(&retstr, "%p", addr) > 0) return retstr; else return NULL; diff --git a/src/platform.h b/src/platform.h index 21760dd9..e6eb7ec4 100644 --- a/src/platform.h +++ b/src/platform.h @@ -8,8 +8,17 @@ #include "compiler_specifics.h" +#include <stdarg.h> #include <stdint.h> +/* String Formatting */ + +/** see GNU C asprintf */ +int h_platform_asprintf(char **strp, const char *fmt, ...); + +/** see GNU C vasprintf */ +int h_platform_vasprintf(char **strp, const char *fmt, va_list arg); + /* Error Reporting */ /* BSD errx function, seen in err.h */ diff --git a/src/platform_bsdlike.c b/src/platform_bsdlike.c index 7d892cf9..2ccf8742 100644 --- a/src/platform_bsdlike.c +++ b/src/platform_bsdlike.c @@ -1,5 +1,8 @@ +#define _GNU_SOURCE // to obtain asprintf/vasprintf #include "platform.h" +#include <stdio.h> + #include <err.h> #include <stdarg.h> @@ -12,6 +15,20 @@ #include <sys/resource.h> #endif +int h_platform_asprintf(char **strp, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int res = h_platform_vasprintf(strp, fmt, ap); + va_end(ap); + return res; +} + +int h_platform_vasprintf(char **strp, const char *fmt, va_list arg) +{ + return vasprintf(strp, fmt, arg); +} + void h_platform_errx(int err, const char* format, ...) { va_list ap; va_start(ap, format); @@ -62,5 +79,5 @@ int64_t h_platform_stopwatch_ns(struct HStopWatch* stopwatch) { // time_diff is in ns return (ts_now.tv_sec - stopwatch->start.tv_sec) * 1000000000 - + (ts_now.tv_nsec - stopwatch->start.tv_nsec); + + (ts_now.tv_nsec - stopwatch->start.tv_nsec); } diff --git a/src/platform_win32.c b/src/platform_win32.c index 94f80bd8..9824b526 100644 --- a/src/platform_win32.c +++ b/src/platform_win32.c @@ -1,7 +1,46 @@ #include "platform.h" +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> #define WIN32_LEAN_AND_MEAN -#include "windows.h" +#include <windows.h> + +int h_platform_asprintf(char**strp, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + int res = h_platform_vasprintf(strp, fmt, ap); + va_end(ap); + return res; +} + +int h_platform_vasprintf(char**strp, const char *fmt, va_list args) +{ + va_list ap; + va_copy(ap, args); + int non_null_char_count = _vscprintf(fmt, ap); + va_end(ap); + + if (non_null_char_count < 0) { + return -1; + } + + size_t buffer_size = 1 + non_null_char_count; + char* buffer = malloc(buffer_size); + + va_copy(ap, args); + int res = vsnprintf_s(buffer, buffer_size, non_null_char_count, fmt, ap); + if (res < 0) { + free(buffer); + } else { + buffer[non_null_char_count] = 0; + *strp = buffer; + } + va_end(ap); + + return res; +} void h_platform_errx(int err, const char* format, ...) { // FIXME(windows) TODO(uucidl): to be implemented diff --git a/src/pprint.c b/src/pprint.c index b2290dda..11ec3d67 100644 --- a/src/pprint.c +++ b/src/pprint.c @@ -15,7 +15,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define _GNU_SOURCE +#include "platform.h" + #include <stdio.h> #include <string.h> #include "hammer.h" @@ -114,9 +115,24 @@ static inline bool append_buf_c(struct result_buf *buf, char v) { } } -static void unamb_sub(const HParsedToken* tok, struct result_buf *buf) { +/** append a formatted string to the result buffer */ +static inline bool append_buf_formatted(struct result_buf *buf, char* format, ...) +{ char* tmpbuf; int len; + bool result; + va_list ap; + + va_start(ap, format); + len = h_platform_vasprintf(&tmpbuf, format, ap); + result = append_buf(buf, tmpbuf, len); + free(tmpbuf); + va_end(ap); + + return result; +} + +static void unamb_sub(const HParsedToken* tok, struct result_buf *buf) { if (!tok) { append_buf(buf, "NULL", 4); return; @@ -141,16 +157,12 @@ static void unamb_sub(const HParsedToken* tok, struct result_buf *buf) { break; case TT_SINT: if (tok->sint < 0) - len = asprintf(&tmpbuf, "s-%#" PRIx64, -tok->sint); + append_buf_formatted(buf, "s-%#" PRIx64, -tok->sint); else - len = asprintf(&tmpbuf, "s%#" PRIx64, tok->sint); - append_buf(buf, tmpbuf, len); - free(tmpbuf); + append_buf_formatted(buf, "s%#" PRIx64, tok->sint); break; case TT_UINT: - len = asprintf(&tmpbuf, "u%#" PRIx64, tok->uint); - append_buf(buf, tmpbuf, len); - free(tmpbuf); + append_buf_formatted(buf, "u%#" PRIx64, tok->uint); break; case TT_ERR: append_buf(buf, "ERR", 3); -- GitLab