aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-10-13 11:49:18 -0700
committerH. Peter Anvin <hpa@zytor.com>2018-10-13 11:49:18 -0700
commit3dd0c0cfae9890be98d6b2593bf58a6f53011a0a (patch)
tree3b633991083d6eb7fd8571f668fb1eed3fca1cc9
parent3fd11c029bb6e7b075eb75a18f53681800aee4be (diff)
downloadgrv-3dd0c0cfae9890be98d6b2593bf58a6f53011a0a.tar.gz
grv-3dd0c0cfae9890be98d6b2593bf58a6f53011a0a.tar.xz
grv-3dd0c0cfae9890be98d6b2593bf58a6f53011a0a.zip
Switch Makefile to autoconf
-rw-r--r--.gitignore9
-rw-r--r--Makefile55
-rw-r--r--Makefile.in51
-rw-r--r--autoconf/m4/pa_add_cflags.m49
-rw-r--r--autoconf/m4/pa_add_cppflags.m49
-rw-r--r--autoconf/m4/pa_add_flags.m420
-rw-r--r--autoconf/m4/pa_add_headers.m412
-rw-r--r--autoconf/m4/pa_arg_bool.m419
-rw-r--r--autoconf/m4/pa_arg_enabled.m44
-rw-r--r--autoconf/m4/pa_check_bad_stdc_inline.m426
-rw-r--r--autoconf/m4/pa_func_attribute.m427
-rw-r--r--autoconf/m4/pa_func_attribute_error.m424
-rw-r--r--autoconf/m4/pa_have_func.m420
-rw-r--r--autoconf/m4/pa_sym.m47
-rwxr-xr-xautogen.sh20
-rw-r--r--clib/asprintf.c37
-rw-r--r--clib/inttypes.h201
-rw-r--r--compiler.h182
-rw-r--r--configure.ac208
-rw-r--r--grv.c6
-rw-r--r--grv.h4
-rw-r--r--grvscored.c4
-rw-r--r--random.c2
23 files changed, 893 insertions, 63 deletions
diff --git a/.gitignore b/.gitignore
index 1ffec11..d03e5ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,9 +3,18 @@
*.i
*.s
*~
+*.bak
+\#*
*.exe
*.zip
*.app
grv
grvscored
grvfont.c
+/config
+/configure
+/config.status
+/config.log
+/autoconf/aux
+/autoconf/aclocal.m4
+/Makefile
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 9dee60d..0000000
--- a/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-CC = gcc
-
-SDLFLAGS := $(shell sdl-config --cflags)
-SDLLIBS := $(shell sdl-config --libs)
-
-CWARN = -W -Wall -Wno-pointer-sign -Wno-stringop-truncation
-REQFLAGS = -D_REENTRANT
-OPTFLAGS = -O2 -g
-CPPFLAGS = $(REQFLAGS) $(INCLUDE) $(SDLFLAGS)
-CFLAGS = $(CPPFLAGS) $(CWARN) $(OPTFLAGS)
-LDFLAGS = $(CFLAGS)
-LIBS = $(SDLLIBS) -lm
-PERL = perl
-
-ALL = grv grvscored
-
-OBJS = grv.o drawlevel.o play.o action.o bullets.o mystery.o \
- prefs.o intro.o \
- utils.o scoretbl.o highscore.o \
- netopen.o keyboard.o graphics.o grvfont.o random.o \
- sysrand.o homedir.o
-
-SCORED = grvscored.o scoretbl.o
-
-.SUFFIXES: .c .o .i .s
-
-all: $(ALL)
-
-grv: $(OBJS)
- $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
-
-grvscored: $(SCORED)
- $(CC) $(LDFLAGS) -o $@ $(SCORED)
-
-.c.o:
- $(CC) $(CFLAGS) -c -o $@ $<
-
-.c.i:
- $(CC) $(CFLAGS) -E -o $@ $<
-
-.c.s:
- $(CC) $(CFLAGS) -S -o $@ $<
-
-grvfont.c: grvfont.psf psftoc.pl
- $(PERL) psftoc.pl < $< > $@ || rm -f $@
-
-clean:
- rm -f *.o *.i *.s *.exe $(ALL)
-
-#
-# To do a Win32 build on a Fedora Linux host
-#
-win32:
- make -f Makefile.w32 CC=i686-pc-mingw32-gcc \
- SDL=/usr/i686-pc-mingw32/sys-root/mingw
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..f75f0c9
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,51 @@
+CC = @CC@
+
+SDLFLAGS := $(shell sdl-config --cflags)
+SDLLIBS := $(shell sdl-config --libs)
+
+CPPFLAGS = @CPPFLAGS@ @DEFS@ $(SDLFLAGS)
+CFLAGS = @CFLAGS@ $(CPPFLAGS)
+LDFLAGS = @LDFLAGS@ $(CFLAGS)
+LIBS = $(SDLLIBS) @LIBS@
+PERL = perl
+
+O = @OBJEXT@
+X = @EXEEXT@
+
+ALL = grv$(X) grvscored$(X)
+
+OBJS = grv.$(O) drawlevel.$(O) play.$(O) action.$(O) bullets.$(O) mystery.$(O) \
+ prefs.$(O) intro.$(O) \
+ utils.$(O) scoretbl.$(O) highscore.$(O) \
+ netopen.$(O) keyboard.$(O) graphics.$(O) grvfont.$(O) random.$(O) \
+ sysrand.$(O) homedir.$(O)
+
+SCORED = grvscored.$(O) scoretbl.$(O)
+
+.SUFFIXES: .c .$(O) .i .s
+
+all: $(ALL)
+
+grv$(X): $(OBJS)
+ $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+grvscored$(X): $(SCORED)
+ $(CC) $(LDFLAGS) -o $@ $(SCORED)
+
+.c.$(O):
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.c.i:
+ $(CC) $(CFLAGS) -E -o $@ $<
+
+.c.s:
+ $(CC) $(CFLAGS) -S -o $@ $<
+
+grvfont.c: grvfont.psf psftoc.pl
+ $(PERL) psftoc.pl < $< > $@ || rm -f $@
+
+clean:
+ rm -f *.$(O) *.i *.s *.exe $(ALL)
+
+spotless: clean
+ rm -f Makefile configure config.h config.h.in
diff --git a/autoconf/m4/pa_add_cflags.m4 b/autoconf/m4/pa_add_cflags.m4
new file mode 100644
index 0000000..fc2223c
--- /dev/null
+++ b/autoconf/m4/pa_add_cflags.m4
@@ -0,0 +1,9 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ADD_CFLAGS(variable, flag [,actual_flag])
+dnl
+dnl Attempt to add the given option to xFLAGS, if it doesn't break
+dnl compilation. If the option to be tested is different than the
+dnl option that should actually be added, add the option to be
+dnl actually added as a second argument.
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_ADD_CFLAGS], [PA_ADD_FLAGS(CFLAGS, [$1], [$2])])
diff --git a/autoconf/m4/pa_add_cppflags.m4 b/autoconf/m4/pa_add_cppflags.m4
new file mode 100644
index 0000000..bfab231
--- /dev/null
+++ b/autoconf/m4/pa_add_cppflags.m4
@@ -0,0 +1,9 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ADD_CPPFLAGS(variable, flag [,actual_flag])
+dnl
+dnl Attempt to add the given option to xFLAGS, if it doesn't break
+dnl compilation. If the option to be tested is different than the
+dnl option that should actually be added, add the option to be
+dnl actually added as a second argument.
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_ADD_CPPFLAGS], [PA_ADD_FLAGS(CPPFLAGS, [$1], [$2])])
diff --git a/autoconf/m4/pa_add_flags.m4 b/autoconf/m4/pa_add_flags.m4
new file mode 100644
index 0000000..5a88d16
--- /dev/null
+++ b/autoconf/m4/pa_add_flags.m4
@@ -0,0 +1,20 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ADD_FLAGS(variable, flag [,actual_flag])
+dnl
+dnl Attempt to add the given option to CPPFLAGS, if it doesn't break
+dnl compilation. If the option to be tested is different than the
+dnl option that should actually be added, add the option to be
+dnl actually added as a second argument.
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_ADD_FLAGS],
+[AC_MSG_CHECKING([if $CC accepts $2])
+ pa_add_flags__old_flags="$$1"
+ $1="$$1 $2"
+ AC_TRY_LINK(AC_INCLUDES_DEFAULT,
+ [printf("Hello, World!\n");],
+ [AC_MSG_RESULT([yes])
+ $1="$pa_add_flags__old_flags ifelse([$3],[],[$2],[$3])"
+ AC_DEFINE(PA_SYM([$1_],[$2]), 1,
+ [Define to 1 if compiled with the `$2' compiler flag])],
+ [AC_MSG_RESULT([no])
+ $1="$pa_add_flags__old_flags"])])
diff --git a/autoconf/m4/pa_add_headers.m4 b/autoconf/m4/pa_add_headers.m4
new file mode 100644
index 0000000..6aeab89
--- /dev/null
+++ b/autoconf/m4/pa_add_headers.m4
@@ -0,0 +1,12 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ADD_HEADERS(headers...)
+dnl
+dnl Call AC_CHECK_HEADERS(), and add to ac_includes_default if found
+dnl --------------------------------------------------------------------------
+AC_DEFUN([_PA_ADD_HEADER],
+[AC_CHECK_HEADERS([$1],[ac_includes_default="$ac_includes_default
+#include <$1>"
+])])
+
+AC_DEFUN([PA_ADD_HEADERS],
+[m4_map_args_w([$1],[_PA_ADD_HEADER(],[)])])
diff --git a/autoconf/m4/pa_arg_bool.m4 b/autoconf/m4/pa_arg_bool.m4
new file mode 100644
index 0000000..92f5765
--- /dev/null
+++ b/autoconf/m4/pa_arg_bool.m4
@@ -0,0 +1,19 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ARG_BOOL(option,helptext,default,enabled_action,disabled_action)
+dnl
+dnl The last three arguments are optional; default can be yes or no.
+dnl
+dnl Simpler-to-use versions of AC_ARG_ENABLED, that include the
+dnl test for $enableval and the AS_HELP_STRING definition. This is only
+dnl to be used for boolean options.
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_ARG_BOOL],
+[m4_pushdef([pa_enableval],m4_default(m4_normalize([$3]),[yes]))
+ m4_pushdef([pa_option],m4_case([pa_enableval],[no],[disable],[enable]))
+ AC_ARG_ENABLE([$1],
+ [AS_HELP_STRING([--]m4_defn([pa_option])[-$1],[$2])],
+ [[pa_arg_bool_enableval="]m4_defn([pa_enableval])["]],
+ [pa_arg_bool_enableval=no])
+ m4_popdef([pa_enableval],[pa_option])
+ AS_IF([test x"$pa_arg_bool_enableval" != xno], [$4], [$5])
+])
diff --git a/autoconf/m4/pa_arg_enabled.m4 b/autoconf/m4/pa_arg_enabled.m4
new file mode 100644
index 0000000..f08c9e0
--- /dev/null
+++ b/autoconf/m4/pa_arg_enabled.m4
@@ -0,0 +1,4 @@
+dnl --------------------------------------------------------------------------
+dnl PA_ARG_ENABLED(option,helptext,enabled_action,disabled_action)
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_ARG_ENABLED],[PA_ARG_BOOL([$1],[$2],yes,[$3],[$4])])
diff --git a/autoconf/m4/pa_check_bad_stdc_inline.m4 b/autoconf/m4/pa_check_bad_stdc_inline.m4
new file mode 100644
index 0000000..267a8ce
--- /dev/null
+++ b/autoconf/m4/pa_check_bad_stdc_inline.m4
@@ -0,0 +1,26 @@
+dnl --------------------------------------------------------------------------
+dnl PA_CHECK_BAD_STDC_INLINE
+dnl
+dnl Some versions of gcc seem to apply -Wmissing-prototypes to C99
+dnl inline functions, which means we need to use GNU inline syntax
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_CHECK_BAD_STDC_INLINE],
+[AC_MSG_CHECKING([if $CC supports C99 external inlines])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+AC_INCLUDES_DEFAULT
+
+/* Don't mistake GNU inlines for c99 */
+#ifdef __GNUC_GNU_INLINE__
+# error "Using gnu inline standard"
+#endif
+
+inline int foo(int x)
+{
+ return x+1;
+}
+ ])],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_STDC_INLINE], 1,
+ [Define to 1 if your compiler supports C99 extern inline])],
+ [AC_MSG_RESULT([no])
+ PA_ADD_CFLAGS([-fgnu89-inline])])])
diff --git a/autoconf/m4/pa_func_attribute.m4 b/autoconf/m4/pa_func_attribute.m4
new file mode 100644
index 0000000..74d3569
--- /dev/null
+++ b/autoconf/m4/pa_func_attribute.m4
@@ -0,0 +1,27 @@
+dnl --------------------------------------------------------------------------
+dnl PA_FUNC_ATTRIBUTE(attribute_name)
+dnl
+dnl See if this compiler supports the equivalent of a specific gcc
+dnl attribute on a function, using the __attribute__(()) syntax.
+dnl All arguments except the attribute name are optional.
+dnl PA_FUNC_ATTRIBUTE(attribute, attribute_opts, return_type,
+dnl prototype_args, call_args)
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_FUNC_ATTRIBUTE],
+[AC_MSG_CHECKING([if $CC supports the $1 function attribute])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+AC_INCLUDES_DEFAULT
+extern ifelse([$3],[],[void *],[$3]) __attribute__(($1$2))
+ bar(ifelse([$4],[],[int],[$4]));
+ifelse([$3],[],[void *],[$3]) foo(void);
+ifelse([$3],[],[void *],[$3]) foo(void)
+{
+ ifelse([$3],[void],[],[return])
+ bar(ifelse([$5],[],[1],[$5]));
+}
+ ])],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE(PA_SYM([HAVE_FUNC_ATTRIBUTE_],[$1]), 1,
+ [Define to 1 if your compiler supports __attribute__(($1)) on functions])],
+ [AC_MSG_RESULT([no])])
+])
diff --git a/autoconf/m4/pa_func_attribute_error.m4 b/autoconf/m4/pa_func_attribute_error.m4
new file mode 100644
index 0000000..5f87a3b
--- /dev/null
+++ b/autoconf/m4/pa_func_attribute_error.m4
@@ -0,0 +1,24 @@
+dnl --------------------------------------------------------------------------
+dnl PA_FUNC_ATTRIBUTE_ERROR
+dnl
+dnl See if this compiler supports __attribute__((error("foo")))
+dnl The generic version of this doesn't work as it makes the compiler
+dnl throw an error by design.
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_FUNC_ATTRIBUTE_ERROR],
+[AC_MSG_CHECKING([if $CC supports the error function attribute])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+AC_INCLUDES_DEFAULT
+extern void __attribute__((error("message"))) barf(void);
+void foo(void);
+void foo(void)
+{
+ if (0)
+ barf();
+}
+ ])],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_FUNC_ATTRIBUTE_ERROR], 1,
+ [Define to 1 if your compiler supports __attribute__((error)) on functions])],
+ [AC_MSG_RESULT([no])])
+])
diff --git a/autoconf/m4/pa_have_func.m4 b/autoconf/m4/pa_have_func.m4
new file mode 100644
index 0000000..b00145a
--- /dev/null
+++ b/autoconf/m4/pa_have_func.m4
@@ -0,0 +1,20 @@
+dnl --------------------------------------------------------------------------
+dnl PA_HAVE_FUNC(func_name)
+dnl
+dnl Look for a function with the specified arguments which could be
+dnl a builtin/intrinsic function.
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_HAVE_FUNC],
+[AC_MSG_CHECKING([for $1])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([
+AC_INCLUDES_DEFAULT
+int main(void) {
+ (void)$1$2;
+ return 0;
+}
+ ])],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE(AS_TR_CPP([HAVE_$1]), 1,
+ [Define to 1 if you have the `$1' intrinsic function.])],
+ [AC_MSG_RESULT([no])])
+])
diff --git a/autoconf/m4/pa_sym.m4 b/autoconf/m4/pa_sym.m4
new file mode 100644
index 0000000..742a534
--- /dev/null
+++ b/autoconf/m4/pa_sym.m4
@@ -0,0 +1,7 @@
+dnl --------------------------------------------------------------------------
+dnl PA_SYM(prefix, string)
+dnl
+dnl Convert a (semi-) arbitrary string to a CPP symbol
+dnl --------------------------------------------------------------------------
+AC_DEFUN([PA_SYM],
+[m4_normalize([$1])m4_bpatsubsts(m4_toupper([$2]),[[^ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]+],[_],[^._?\(.*\)_.$],[[\1]])])
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..b7633c6
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,20 @@
+#!/bin/sh -xe
+#
+# Run this script to regenerate autoconf files
+#
+mkdir -p autoconf autoconf/aux config
+autolib="`automake --print-libdir`"
+for prg in install-sh compile config.guess config.sub; do
+ cp -f "$autolib"/"$prg" autoconf/aux
+done
+rm -f autoconf/aclocal.m4
+mkdir -p autoconf/m4.old autoconf/m4
+mv -f autoconf/m4/*.m4 autoconf/m4.old/ 2>/dev/null || true
+ACLOCAL_PATH="${ACLOCAL_PATH}${ACLOCAL_PATH:+:}`pwd`/autoconf/m4.old"
+export ACLOCAL_PATH
+aclocal --install --output=autoconf/aclocal.m4 -I autoconf/m4
+test -f autoconf/aclocal.m4
+rm -rf autoconf/m4.old
+autoheader -B autoconf
+autoconf -B autoconf
+rm -rf autom4te.cache config.log config.status config/config.h Makefile
diff --git a/clib/asprintf.c b/clib/asprintf.c
new file mode 100644
index 0000000..cb55411
--- /dev/null
+++ b/clib/asprintf.c
@@ -0,0 +1,37 @@
+#include "compiler.h"
+
+#ifndef HAVE_ASPRINTF
+
+int asprintf(char **strp, const char *fmt, ...)
+{
+ char *buf;
+ int len, out;
+ va_list ap;
+
+ *strp = NULL;
+
+ va_start(ap, fmt);
+ len = vsnprintf(NULL, 0, fmt, ap);
+ va_end(ap);
+ if (len < 0)
+ return -1;
+
+ buf = malloc(len+1);
+ if (!buf)
+ return -1;
+
+ va_start(ap, fmt);
+ out = vsnprintf(buf, len+1, fmt, ap);
+ if (out < 0 || out >= len) {
+ /* Size of output changed behind our back?! */
+ free(buf);
+ errno = EAGAIN; /* You can try again if you want... */
+ return -1;
+ }
+ va_end(ap);
+
+ *strp = buf;
+ return out;
+}
+
+#endif
diff --git a/clib/inttypes.h b/clib/inttypes.h
new file mode 100644
index 0000000..e353aa9
--- /dev/null
+++ b/clib/inttypes.h
@@ -0,0 +1,201 @@
+/*
+ * inttypes.h
+ *
+ * Small ersatz subset of <inttypes.h>, deriving the types from
+ * <limits.h>.
+ *
+ * Important: the preprocessor may truncate numbers too large for it.
+ * Therefore, test the signed types only ... truncation won't generate
+ * a 01111111... bit pattern.
+ */
+
+#ifndef INTTYPES_H
+#define INTTYPES_H
+
+#include <limits.h>
+
+/*** 64-bit type: long or long long ***/
+
+/* Some old versions of gcc <limits.h> omit LLONG_MAX */
+#ifndef LLONG_MAX
+# ifdef __LONG_LONG_MAX__
+# define LLONG_MAX __LONG_LONG_MAX__
+# else
+# define LLONG_MAX 0 /* Assume long long is unusable */
+# endif
+#endif
+
+#if LONG_MAX == 9223372036854775807L
+
+/* long is 64 bits */
+typedef signed long int64_t;
+typedef unsigned long uint64_t;
+#define _scn64 "l"
+#define _pri64 "l"
+#define INT64_C(x) x ## L
+#define UINT64_C(x) x ## UL
+
+#elif LLONG_MAX == 9223372036854775807LL
+
+/* long long is 64 bits */
+typedef signed long long int64_t;
+typedef unsigned long long uint64_t;
+#define _scn64 "ll"
+#define _pri64 "ll"
+#define INT64_C(x) x ## LL
+#define UINT64_C(x) x ## ULL
+
+#else
+
+#error "Neither long nor long long is 64 bits in size"
+
+#endif
+
+/*** 32-bit type: int or long ***/
+
+#if INT_MAX == 2147483647
+
+/* int is 32 bits */
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+#define _scn32 ""
+#define _pri32 ""
+#define INT32_C(x) x
+#define UINT32_C(x) x ## U
+
+#elif LONG_MAX == 2147483647L
+
+/* long is 32 bits */
+typedef signed long int32_t;
+typedef unsigned long uint32_t;
+#define _scn32 "l"
+#define _pri32 "l"
+#define INT32_C(x) x ## L
+#define UINT32_C(x) x ## UL
+
+#else
+
+#error "Neither int nor long is 32 bits in size"
+
+#endif
+
+/*** 16-bit size: int or short ***/
+
+#if INT_MAX == 32767
+
+/* int is 16 bits */
+typedef signed int int16_t;
+typedef unsigned int uint16_t;
+#define _scn16 ""
+#define _pri16 ""
+#define INT16_C(x) x
+#define UINT16_C(x) x ## U
+
+#elif SHRT_MAX == 32767
+
+/* short is 16 bits */
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+#define _scn16 "h"
+#define _pri16 ""
+#define INT16_C(x) x
+#define UINT16_C(x) x ## U
+
+#else
+
+#error "Neither short nor int is 16 bits in size"
+
+#endif
+
+/*** 8-bit size: char ***/
+
+#if SCHAR_MAX == 127
+
+/* char is 8 bits */
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+#define _scn8 "hh"
+#define _pri8 ""
+#define INT8_C(x) x
+#define UINT8_C(x) x ## U
+
+#else
+
+#error "char is not 8 bits in size"
+
+#endif
+
+/* The rest of this is common to all models */
+
+#define PRId8 _pri8 "d"
+#define PRId16 _pri16 "d"
+#define PRId32 _pri32 "d"
+#define PRId64 _pri64 "d"
+
+#define PRIi8 _pri8 "i"
+#define PRIi16 _pri16 "i"
+#define PRIi32 _pri32 "i"
+#define PRIi64 _pri64 "i"
+
+#define PRIo8 _pri8 "o"
+#define PRIo16 _pri16 "o"
+#define PRIo32 _pri32 "o"
+#define PRIo64 _pri64 "o"
+
+#define PRIu8 _pri8 "u"
+#define PRIu16 _pri16 "u"
+#define PRIu32 _pri32 "u"
+#define PRIu64 _pri64 "u"
+
+#define PRIx8 _pri8 "x"
+#define PRIx16 _pri16 "x"
+#define PRIx32 _pri32 "x"
+#define PRIx64 _pri64 "x"
+
+#define PRIX8 _pri8 "X"
+#define PRIX16 _pri16 "X"
+#define PRIX32 _pri32 "X"
+#define PRIX64 _pri64 "X"
+
+#define SCNd8 _scn8 "d"
+#define SCNd16 _scn16 "d"
+#define SCNd32 _scn32 "d"
+#define SCNd64 _scn64 "d"
+
+#define SCNi8 _scn8 "i"
+#define SCNi16 _scn16 "i"
+#define SCNi32 _scn32 "i"
+#define SCNi64 _scn64 "i"
+
+#define SCNo8 _scn8 "o"
+#define SCNo16 _scn16 "o"
+#define SCNo32 _scn32 "o"
+#define SCNo64 _scn64 "o"
+
+#define SCNu8 _scn8 "u"
+#define SCNu16 _scn16 "u"
+#define SCNu32 _scn32 "u"
+#define SCNu64 _scn64 "u"
+
+#define SCNx8 _scn8 "x"
+#define SCNx16 _scn16 "x"
+#define SCNx32 _scn32 "x"
+#define SCNx64 _scn64 "x"
+
+#define INT8_MIN INT8_C(-128)
+#define INT8_MAX INT8_C(127)
+#define UINT8_MAX UINT8_C(255)
+
+#define INT16_MIN INT16_C(-32768)
+#define INT16_MAX INT16_C(32767)
+#define UINT16_MAX UINT16_C(65535)
+
+#define INT32_MIN INT32_C(-2147483648)
+#define INT32_MAX INT32_C(2147483647)
+#define UINT32_MAX UINT32_C(4294967295)
+
+#define INT64_MIN INT64_C(-9223372036854775808)
+#define INT64_MAX INT64_C(9223372036854775807)
+#define UINT64_MAX UINT64_C(18446744073709551615)
+
+#endif /* INTTYPES_H */
diff --git a/compiler.h b/compiler.h
new file mode 100644
index 0000000..ea17381
--- /dev/null
+++ b/compiler.h
@@ -0,0 +1,182 @@
+/*
+ * Common definitions that we need for everything
+ */
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+#ifdef HAVE_CONFIG_H
+# include "config/config.h"
+#else
+# error "Need compiler-specific hacks here"
+#endif
+
+/* On Microsoft platforms we support multibyte character sets in filenames */
+#define _MBCS 1
+
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# include "clib/inttypes.h" /* Ersatz header file */
+#endif
+
+/* These header files should pretty much always be included... */
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#include <time.h>
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#endif
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+
+#ifdef HAVE_IO_H
+# include <io.h>
+#endif
+#ifdef HAVE_WINDOWS_H
+# include <windows.h>
+#endif
+#ifdef HAVE_DIRECT_H
+# include <direct.h>
+#endif
+
+#include <SDL.h> /* This includes endian definitions */
+
+#define WORDS_LITTLEENDIAN (SDL_BYTEORDER == SDL_LIL_ENDIAN)
+#define WORDS_BIGENDIAN (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+
+#ifndef __cplusplus /* C++ has false, true, bool as keywords */
+# ifdef HAVE_STDBOOL_H
+# include <stdbool.h>
+# else
+/* This is sort of dangerous, since casts will behave different than
+ casting to the standard boolean type. Always use !!, not (bool). */
+typedef enum bool { false, true } bool;
+# endif
+#endif
+
+/*
+ * mempcpy() replacement
+ */
+#ifndef HAVE_MEMPCPY
+static inline void *mempcpy(void *dest, const void *src, size_t n)
+{
+ memcpy(dest, src, n);
+ return (char *)dest + n;
+}
+#endif
+
+/*
+ * asprintf()
+ */
+#ifndef HAVE_ASPRINTF
+extern int asprintf(char **, const char *, ...);
+#endif
+
+/*
+ * Hack to support external-linkage inline functions
+ */
+#ifndef HAVE_STDC_INLINE
+# ifdef __GNUC__
+# ifdef __GNUC_STDC_INLINE__
+# define HAVE_STDC_INLINE
+# else
+# define HAVE_GNU_INLINE
+# endif
+# elif defined(__GNUC_GNU_INLINE__)
+/* Some other compiler implementing only GNU inline semantics? */
+# define HAVE_GNU_INLINE
+# elif defined(__STDC_VERSION__)
+# if __STDC_VERSION__ >= 199901L
+# define HAVE_STDC_INLINE
+# endif
+# endif
+#endif
+
+#ifdef HAVE_STDC_INLINE
+# define extern_inline inline
+#elif defined(HAVE_GNU_INLINE)
+# define extern_inline extern inline
+# define inline_prototypes
+#else
+# define inline_prototypes
+#endif
+
+/*
+ * Hints to the compiler that a particular branch of code is more or
+ * less likely to be taken.
+ */
+#if HAVE___BUILTIN_EXPECT
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#else
+# define likely(x) (!!(x))
+# define unlikely(x) (!!(x))
+#endif
+
+/*
+ * How to tell the compiler that a function doesn't return
+ */
+#ifdef HAVE_STDNORETURN_H
+# include <stdnoreturn.h>
+# define no_return noreturn void
+#elif defined(HAVE_FUNC_ATTRIBUTE_NORETURN)
+# define no_return void __attribute__((noreturn))
+#elif defined(_MSC_VER)
+# define no_return __declspec(noreturn) void
+#else
+# define no_return void
+#endif
+
+/*
+ * How to tell the compiler that a function is pure arithmetic
+ */
+#ifdef HAVE_FUNC_ATTRIBUTE_CONST
+# define const_func __attribute__((const))
+#else
+# define const_func
+#endif
+
+/*
+ * This function has no side effects, but depends on its arguments,
+ * memory pointed to by its arguments, or global variables.
+ * NOTE: functions that return a value by modifying memory pointed to
+ * by a pointer argument are *NOT* considered pure.
+ */
+#ifdef HAVE_FUNC_ATTRIBUTE_PURE
+# define pure_func __attribute__((pure))
+#else
+# define pure_func
+#endif
+
+/* Determine probabilistically if something is a compile-time constant */
+#ifdef HAVE___BUILTIN_CONSTANT_P
+# define is_constant(x) __builtin_constant_p(x)
+#else
+# define is_constant(x) false
+#endif
+
+#endif /* COMPILER_H */
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..2efcd99
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,208 @@
+dnl Process this file with autoconf 2.69 or later to produce
+dnl a configure script.
+AC_PREREQ([2.69])
+
+AC_CONFIG_MACRO_DIR(autoconf)
+AC_CONFIG_MACRO_DIRS(autoconf)
+
+AC_INIT(grv.c)
+AC_CONFIG_HEADERS(config/config.h)
+
+AC_CONFIG_AUX_DIR(autoconf/aux)
+
+dnl If we have wine installed, don't run it when checking for cross-compile
+WINELOADER=/dev/null
+export WINELOADER
+
+AC_PREFIX_PROGRAM(grv)
+
+dnl Get canonical target ("host") name
+AC_CANONICAL_HOST
+
+dnl Checks for programs.
+AC_USE_SYSTEM_EXTENSIONS
+AC_PROG_CC
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_C_RESTRICT
+AC_TYPE_SIZE_T
+
+dnl Checks for standard header files.
+AC_HEADER_STDC
+AC_HEADER_STDBOOL
+AC_CHECK_HEADERS(inttypes.h)
+AC_CHECK_HEADERS(stdnoreturn.h)
+
+dnl Force gcc and gcc-compatible compilers treat signed integers
+dnl as 2's complement
+PA_ADD_CFLAGS([-fwrapv])
+
+dnl Some environments abuse __STRICT_ANSI__ to disable some
+dnl function declarations
+PA_ADD_CPPFLAGS([-U__STRICT_ANSI__])
+
+dnl Don't put things in common if we can avoid it. We don't want to
+dnl assume all compilers support common, and this will help find those
+dnl problems. This also works around an OSX linker problem.
+PA_ADD_CFLAGS([-fno-common])
+
+dnl Compiler intrinsics
+PA_ADD_HEADERS(intrin.h)
+PA_HAVE_FUNC(__builtin_expect, (1,1))
+PA_HAVE_FUNC(__builtin_constant_p, (0))
+
+dnl See if we can find sdl-config
+AC_CHECK_TOOL([SDL_CONFIG], [sdl-config], [false])
+AS_IF(["$SDL_CONFIG" --cflags >/dev/null 2>&1],
+ [CPPFLAGS="$CPPFLAGS `"$SDL_CONFIG" --cflags`"
+ LIBS="$LIBS `"$SDL_CONFIG" --libs`"],
+ [AC_MSG_WARN([sdl-config not found or not functional, this is probably bad news])])
+
+AC_CHECK_HEADERS(SDL.h)
+
+AC_CHECK_HEADERS(sys/types.h)
+AC_CHECK_HEADERS(sys/stat.h)
+AC_CHECK_HEADERS(sys/time.h)
+AC_CHECK_HEADERS(unistd.h)
+AC_CHECK_HEADERS(fcntl.h)
+AC_CHECK_HEADERS(paths.h)
+AC_CHECK_HEADERS(io.h)
+AC_CHECK_HEADERS(windows.h)
+AC_CHECK_HEADERS(direct.h)
+
+dnl Useful functions which we may lack
+AC_CHECK_FUNCS([mempcpy])
+AC_CHECK_FUNCS([asprintf])
+
+dnl These types are POSIX-specific, and Windows does it differently...
+AC_CHECK_TYPES([struct _stat64])
+AC_CHECK_TYPES([struct stat])
+AC_CHECK_FUNCS([stat _stat64])
+AC_CHECK_FUNCS([fstat _fstat64])
+
+dnl Newer versions of POSIX have this
+AC_CHECK_TYPES(mode_t)
+
+dnl Temporary file functions
+AC_CHECK_FUNCS([mkstemp tempnam])
+
+dnl File attributes
+AC_CHECK_FUNCS([_setmode])
+
+dnl Console handling
+AC_CHECK_FUNCS(setsid)
+AC_FUNC_FORK
+
+dnl Math?
+AC_SEARCH_LIBS([exp],[m])
+
+dnl
+dnl Check for supported gcc attributes; some compilers (e.g. Sun CC)
+dnl support these, but don't define __GNUC__ as they don't support
+dnl some other features of gcc.
+dnl
+PA_ADD_CPPFLAGS([-Werror=attributes])
+PA_FUNC_ATTRIBUTE(noreturn)
+PA_FUNC_ATTRIBUTE(returns_nonnull)
+PA_FUNC_ATTRIBUTE(malloc)
+PA_FUNC_ATTRIBUTE(alloc_size, (1))
+PA_FUNC_ATTRIBUTE(sentinel,,, [const char *, ...], ["a","b",NULL])
+PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1])
+PA_FUNC_ATTRIBUTE(const)
+PA_FUNC_ATTRIBUTE(pure)
+PA_FUNC_ATTRIBUTE(cold)
+PA_FUNC_ATTRIBUTE_ERROR
+
+dnl
+dnl support function sections (if available)
+dnl
+PA_ARG_ENABLED([sections],
+ [compile with function/data section support],
+ [PA_ADD_CFLAGS([-ffunction-sections])
+ PA_ADD_CFLAGS([-fdata-sections])
+ PA_ADD_CFLAGS([-Wl,--gc-sections])],
+ [])
+
+dnl
+dnl support LTO
+dnl
+PA_ARG_ENABLED([lto],
+ [compile with gcc-style link time optimization],
+ [PA_ADD_CFLAGS([-flto])
+ dnl Note: we use _PROG rather than _TOOL since we are prepending the full
+ dnl CC name which ought to already contain the host triplet if needed
+ ccbase=`echo "$CC" | awk '{ print $1; }'`
+ AC_CHECK_PROGS(CC_AR, [${ccbase}-ar], [$ac_cv_prog_AR])
+ AR="$CC_AR"
+ AC_CHECK_PROGS(CC_RANLIB, [${ccbase}-ranlib], [$ac_cv_prog_RANLIB])
+ RANLIB="$CC_RANLIB"], [])
+
+dnl
+dnl support sanitizers (if available)
+dnl
+PA_ARG_ENABLED([sanitizer],
+ [compile with sanitizers enabled],
+ [PA_ADD_CFLAGS([-fno-omit-frame-pointer])
+ PA_ADD_CFLAGS([-fsanitize=address])
+ PA_ADD_CFLAGS([-fsanitize=undefined])])
+
+dnl
+dnl Don't make symbols visible, there is no point and it just
+dnl makes the code slower.
+dnl
+PA_ADD_CFLAGS([-fvisibility=hidden])
+
+dnl If we have gcc, add appropriate code cleanliness options
+PA_ADD_CPPFLAGS([-W])
+PA_ADD_CPPFLAGS([-Wall])
+PA_ADD_CPPFLAGS([-pedantic])
+dnl LLVM doesn't error out on invalid -W options unless this option is
+dnl specified first. Enable this so this script can actually discover
+dnl which -W options are possible for this compiler.
+PA_ADD_CPPFLAGS([-Werror=unknown-warning-option])
+
+dnl Suppress format warning on Windows targets due to their <inttypes.h>
+PA_ADD_CPPFLAGS([-Wpedantic-ms-format],[-Wno-pedantic-ms-format])
+
+dnl This is needed because we intentionally expect strncpy() to fill
+dnl in a zero-padded (not zero-terminated) buffer in several backends
+PA_ADD_CPPFLAGS([-Wstringop-truncation],[-Wno-stringop-truncation])
+
+PA_ADD_CPPFLAGS([-Wpointer-sign],[-Wno-pointer-sign])
+
+PA_ADD_CPPFLAGS([-Wwrite-strings])
+
+PA_ARG_ENABLED([werror],
+ [compile with -Werror to error out on any warning],
+ [PA_ADD_CPPFLAGS([-Werror])],
+ [PA_ADD_CPPFLAGS([-Werror=implicit])
+ PA_ADD_CPPFLAGS([-Werror=missing-braces])
+ PA_ADD_CPPFLAGS([-Werror=return-type])
+ PA_ADD_CPPFLAGS([-Werror=trigraphs])
+ PA_ADD_CPPFLAGS([-Werror=pointer-arith])
+ PA_ADD_CPPFLAGS([-Werror=strict-prototypes])
+ PA_ADD_CPPFLAGS([-Werror=missing-prototypes])
+ PA_ADD_CPPFLAGS([-Werror=missing-declarations])
+ PA_ADD_CPPFLAGS([-Werror=comment])
+ PA_ADD_CPPFLAGS([-Werror=vla])]
+)
+
+dnl
+dnl On some versions of gcc, -Werror=missing-prototypes causes problems
+dnl with C99-style external inlines. Test this *after* adding the -Werror
+dnl options.
+dnl
+PA_CHECK_BAD_STDC_INLINE
+
+dnl
+dnl support ccache
+dnl
+PA_ARG_ENABLED([ccache], [compile with ccache], [CC="ccache $CC"], [])
+
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
diff --git a/grv.c b/grv.c
index 718f202..a60af99 100644
--- a/grv.c
+++ b/grv.c
@@ -16,7 +16,7 @@
struct gameparams gp;
struct monster ghost[MAXGHOST];
-void init_gameparams(void)
+static void init_gameparams(void)
{
gp.Sc = gp.SBs = 0;
gp.Life = 3;
@@ -45,7 +45,7 @@ void initscreen(int w)
cls();
}
-void newlevel(void)
+static void newlevel(void)
{
gp.Bon = 0;
gp.TF = -1;
@@ -101,7 +101,7 @@ void newlevel(void)
play();
}
-void game(void)
+static void game(void)
{
init_gameparams();
while ( gp.Level < ELev && gp.Life >= 0 ) {
diff --git a/grv.h b/grv.h
index ea11e8e..8583ed9 100644
--- a/grv.h
+++ b/grv.h
@@ -1,7 +1,8 @@
#ifndef GRV_H
#define GRV_H 1
-#include <inttypes.h>
+#include "compiler.h"
+
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -22,7 +23,6 @@ int get_random_bytes(void *, int);
void randomize(void);
/* Get a random floating-point number between 0 and 1 */
-extern void init_genrand(unsigned long);
extern double genrand_res53(void);
extern unsigned long genrand_int32(void);
extern void init_by_array(const unsigned long *, unsigned long);
diff --git a/grvscored.c b/grvscored.c
index 01ce8f7..fd3c1be 100644
--- a/grvscored.c
+++ b/grvscored.c
@@ -17,7 +17,7 @@
#include "highscore.h"
-int score_send(const char *file)
+static int score_send(const char *file)
{
FILE *f = fopen(file, "r");
@@ -33,7 +33,7 @@ int score_send(const char *file)
return highscore_write(stdout, 0) ? 1 : 0;
}
-int score_recv(const char *file)
+static int score_recv(const char *file)
{
FILE *f = fopen(file, "r+");
FILE *t;
diff --git a/random.c b/random.c
index cbf0d56..f78ccad 100644
--- a/random.c
+++ b/random.c
@@ -41,7 +41,7 @@
email: matumoto@math.keio.ac.jp
*/
-#include <stdio.h>
+#include "grv.h"
/* Period parameters */
#define N 624