diff --git a/src/backends/regex_debug.c b/src/backends/regex_debug.c
index d28f9b2b7a0ce919fa6c30f80c26be1732dd120e..5207d9e19a320df5620276a5a0503ffad854ddc0 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 21760dd9322d3dc60cc66683a53d17a42cda58f0..e6eb7ec4d97ec5a47d5d613e1a67c5fc4d9f2dd8 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 7d892cf9c7c8a35dc795447f0d98664a997a51c6..2ccf874264a740e0784e8fba14e2ae78a337fa08 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 94f80bd86502bfe4bcf53bc11cfd168129160b69..9824b526d0bf0273660088f0cf24cb81507dad82 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 b2290dda99601fb38db7604ddd7fd23371713b94..11ec3d67411df66043ddd7880edeb22cb5d7db51 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);