From 0c35525e30f7e817c2e8850d228534483f2ffdc3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicolas=20L=C3=A9veill=C3=A9?= <nicolas@uucidl.com>
Date: Sun, 9 Aug 2015 18:38:27 +0200
Subject: [PATCH] Convert usages of errx to h_platform_errx

This BSD call will have to be implemented on windows. Right now
we have a stub that just exits the process.
---
 src/SConscript           |  2 ++
 src/backends/packrat.c   |  6 +++---
 src/compiler_specifics.h | 16 ++++++++++++++++
 src/hammer.c             |  1 -
 src/hammer.h             |  6 +-----
 src/internal.h           |  4 ++--
 src/parsers/many.c       |  2 +-
 src/platform.h           | 18 ++++++++++++++++++
 src/platform_bsdlike.c   | 10 ++++++++++
 src/platform_win32.c     | 10 ++++++++++
 10 files changed, 63 insertions(+), 12 deletions(-)
 create mode 100644 src/compiler_specifics.h
 create mode 100644 src/platform.h
 create mode 100644 src/platform_bsdlike.c
 create mode 100644 src/platform_win32.c

diff --git a/src/SConscript b/src/SConscript
index e192b05e..05ffa983 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -5,6 +5,7 @@ Import('env testruns')
 dist_headers = [
     "hammer.h",
     "allocator.h",
+    "compiler_specifics.h",
     "glue.h",
     "internal.h"
 ]
@@ -61,6 +62,7 @@ misc_hammer_parts = [
     'desugar.c',
     'glue.c',
     'hammer.c',
+    'platform_bsdlike.c',
     'pprint.c',
     'registry.c',
     'system_allocator.c']
diff --git a/src/backends/packrat.c b/src/backends/packrat.c
index 33082c6c..e6f86f29 100644
--- a/src/backends/packrat.c
+++ b/src/backends/packrat.c
@@ -126,7 +126,7 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head)
   h_hashtable_put(state->recursion_heads, &k->input_pos, head);
   HParserCacheValue *old_cached = h_hashtable_get(state->cache, k);
   if (!old_cached || PC_LEFT == old_cached->value_type)
-    errx(1, "impossible match");
+    h_platform_errx(1, "impossible match");
   HParseResult *old_res = old_cached->right;
 
   // rewind the input
@@ -148,7 +148,7 @@ HParseResult* grow(HParserCacheKey *k, HParseState *state, HRecursionHead *head)
         state->input_stream = cached->input_stream;
 	return cached->right;
       } else {
-	errx(1, "impossible match");
+	h_platform_errx(1, "impossible match");
       }
     }
   } else {
@@ -173,7 +173,7 @@ HParseResult* lr_answer(HParserCacheKey *k, HParseState *state, HLeftRec *growab
 	return grow(k, state, growable->head);
     }
   } else {
-    errx(1, "lrAnswer with no head");
+    h_platform_errx(1, "lrAnswer with no head");
   }
 }
 
diff --git a/src/compiler_specifics.h b/src/compiler_specifics.h
new file mode 100644
index 00000000..ed09d664
--- /dev/null
+++ b/src/compiler_specifics.h
@@ -0,0 +1,16 @@
+#ifndef HAMMER_COMPILER_SPECIFICS__H
+#define HAMMER_COMPILER_SPECIFICS__H
+
+#if defined(__clang__) || defined(__GNUC__)
+#define H_GCC_ATTRIBUTE(x) __attribute__(x)
+#else
+#define H_GCC_ATTRIBUTE(x)
+#endif
+
+#if defined(_MSC_VER)
+#define H_MSVC_DECLSPEC(x) __declspec(x)
+#else
+#define H_MSVC_DECLSPEC(x)
+#endif
+
+#endif
diff --git a/src/hammer.c b/src/hammer.c
index 6bb9ebb4..443c77b7 100644
--- a/src/hammer.c
+++ b/src/hammer.c
@@ -17,7 +17,6 @@
 
 #include <assert.h>
 #include <ctype.h>
-#include <err.h>
 #include <limits.h>
 #include <stdarg.h>
 #include <string.h>
diff --git a/src/hammer.h b/src/hammer.h
index 95f8c981..42c73458 100644
--- a/src/hammer.h
+++ b/src/hammer.h
@@ -18,11 +18,7 @@
 #ifndef HAMMER_HAMMER__H
 #define HAMMER_HAMMER__H
 
-#if defined(__clang__) || defined(__GNUC__)
-#define H_GCC_ATTRIBUTE(x) __attribute__(x)
-#else
-#define H_GCC_ATTRIBUTE(x)
-#endif
+#include "compiler_specifics.h"
 
 #ifndef HAMMER_INTERNAL__NO_STDARG_H
 #include <stdarg.h>
diff --git a/src/internal.h b/src/internal.h
index ed1bd085..9aac4ee7 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -24,9 +24,9 @@
 #define HAMMER_INTERNAL__H
 #include <stdint.h>
 #include <assert.h>
-#include <err.h>
 #include <string.h>
 #include "hammer.h"
+#include "platform.h"
 
 /* "Internal" in this case means "we're not ready to commit
  * to a public API." Many structures and routines here will be
@@ -38,7 +38,7 @@
 #else
 #define assert_message(check, message) do {				\
     if (!(check))							\
-      errx(1, "Assertion failed (programmer error): %s", message);	\
+      h_platform_errx(1, "Assertion failed (programmer error): %s", message);	\
   } while(0)
 #endif
 
diff --git a/src/parsers/many.c b/src/parsers/many.c
index 1e3b0221..51d733fc 100644
--- a/src/parsers/many.c
+++ b/src/parsers/many.c
@@ -246,7 +246,7 @@ static HParseResult* parse_length_value(void *env, HParseState *state) {
   if (!len)
     return NULL;
   if (len->ast->token_type != TT_UINT)
-    errx(1, "Length parser must return an unsigned integer");
+    h_platform_errx(1, "Length parser must return an unsigned integer");
   // TODO: allocate this using public functions
   HRepeat repeat = {
     .p = lv->value,
diff --git a/src/platform.h b/src/platform.h
new file mode 100644
index 00000000..0c05bfe2
--- /dev/null
+++ b/src/platform.h
@@ -0,0 +1,18 @@
+#ifndef HAMMER_PLATFORM__H
+#define HAMMER_PLATFORM__H
+
+/**
+ * @file interface between hammer and the operating system /
+ * underlying platform.
+ */
+
+#include "compiler_specifics.h"
+
+/* Error Reporting */
+
+/* BSD errx function, seen in err.h */
+H_MSVC_DECLSPEC(noreturn) \
+void h_platform_errx(int err, const char* format, ...)	\
+  H_GCC_ATTRIBUTE((noreturn, format (printf,2,3)));
+
+#endif
diff --git a/src/platform_bsdlike.c b/src/platform_bsdlike.c
new file mode 100644
index 00000000..ebb38d9d
--- /dev/null
+++ b/src/platform_bsdlike.c
@@ -0,0 +1,10 @@
+#include "platform.h"
+
+#include <err.h>
+#include <stdarg.h>
+
+void h_platform_errx(int err, const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  verrx(err, format, ap);
+}
diff --git a/src/platform_win32.c b/src/platform_win32.c
new file mode 100644
index 00000000..30af1681
--- /dev/null
+++ b/src/platform_win32.c
@@ -0,0 +1,10 @@
+#include "platform.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include "windows.h"
+
+void h_platform_errx(int err, const char* format, ...) {
+  // FIXME(windows) TODO(uucidl): to be implemented
+  ExitProcess(err);
+}
+
-- 
GitLab