summaryrefslogtreecommitdiff
path: root/build-aux
diff options
context:
space:
mode:
authorZack Weinberg <zackw@panix.com>2020-12-14 18:13:44 -0500
committerZack Weinberg <zackw@panix.com>2020-12-31 17:01:35 -0500
commit3436c6a94b8d565bf236bb916ebd3ade28834496 (patch)
treefa51a2c9e57f45aee0b42fa5368cca48e9c823be /build-aux
parent941a32bb879d5228246bdb162c9fb44788c8387a (diff)
downloadlibxcrypt-3436c6a94b8d565bf236bb916ebd3ade28834496.tar.gz
libxcrypt-3436c6a94b8d565bf236bb916ebd3ade28834496.tar.bz2
libxcrypt-3436c6a94b8d565bf236bb916ebd3ade28834496.zip
Move most scripts to top-level build-aux directory.
Since we might not want to keep the build scripts as a combination of sh + awk forever, move most of them to a new top-level directory and rename them without any .sh or .awk suffixes. This directory is named build-aux, consistent with the recommendations in the autoconf manual, and all of the .m4 files extending autoconf move there as well. The shell scripts in test/ remain there, so that all of the tests stay together, and they keep their .sh suffix, because this is how Automake knows that they are not C programs.
Diffstat (limited to 'build-aux')
-rw-r--r--build-aux/ax_append_compile_flags.m446
-rw-r--r--build-aux/ax_append_flag.m450
-rw-r--r--build-aux/ax_check_compile_flag.m453
-rw-r--r--build-aux/ax_check_vscript.m4142
-rw-r--r--build-aux/ax_require_defined.m437
-rw-r--r--build-aux/ax_valgrind_check.m4239
-rwxr-xr-xbuild-aux/clang-gcov-wrapper2
-rw-r--r--build-aux/expand-selected-hashes136
-rw-r--r--build-aux/gen-crypt-h62
-rw-r--r--build-aux/gen-crypt-hashes-h172
-rw-r--r--build-aux/gen-crypt-symbol-vers-h211
-rw-r--r--build-aux/gen-libcrypt-map147
-rw-r--r--build-aux/pkg_installdir_compat.m447
-rwxr-xr-xbuild-aux/skip-if-exec-format-error28
-rwxr-xr-xbuild-aux/travis-after-success49
-rwxr-xr-xbuild-aux/travis-before28
-rwxr-xr-xbuild-aux/travis-build163
-rwxr-xr-xbuild-aux/travis-install7
-rw-r--r--build-aux/zw_alignment.m490
-rw-r--r--build-aux/zw_automodern.m4307
-rw-r--r--build-aux/zw_endianness.m4152
-rw-r--r--build-aux/zw_ld_wrap.m447
-rw-r--r--build-aux/zw_simple_warnings.m4150
-rw-r--r--build-aux/zw_static_assert.m468
24 files changed, 2433 insertions, 0 deletions
diff --git a/build-aux/ax_append_compile_flags.m4 b/build-aux/ax_append_compile_flags.m4
new file mode 100644
index 0000000..9c85635
--- /dev/null
+++ b/build-aux/ax_append_compile_flags.m4
@@ -0,0 +1,46 @@
+# ============================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
+# ============================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# For every FLAG1, FLAG2 it is checked whether the compiler works with the
+# flag. If it does, the flag is added FLAGS-VARIABLE
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. During the check the flag is always added to the
+# current language's flags.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: This macro depends on the AX_APPEND_FLAG and
+# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
+# AX_APPEND_LINK_FLAGS.
+#
+# LICENSE
+#
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 7
+
+AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
+[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
+AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
+for flag in $1; do
+ AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4])
+done
+])dnl AX_APPEND_COMPILE_FLAGS
diff --git a/build-aux/ax_append_flag.m4 b/build-aux/ax_append_flag.m4
new file mode 100644
index 0000000..dd6d8b6
--- /dev/null
+++ b/build-aux/ax_append_flag.m4
@@ -0,0 +1,50 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
+#
+# DESCRIPTION
+#
+# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
+# added in between.
+#
+# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
+# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
+# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
+# FLAG.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 8
+
+AC_DEFUN([AX_APPEND_FLAG],
+[dnl
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
+AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
+AS_VAR_SET_IF(FLAGS,[
+ AS_CASE([" AS_VAR_GET(FLAGS) "],
+ [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
+ [
+ AS_VAR_APPEND(FLAGS,[" $1"])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+ ],
+ [
+ AS_VAR_SET(FLAGS,[$1])
+ AC_RUN_LOG([: FLAGS="$FLAGS"])
+ ])
+AS_VAR_POPDEF([FLAGS])dnl
+])dnl AX_APPEND_FLAG
diff --git a/build-aux/ax_check_compile_flag.m4 b/build-aux/ax_check_compile_flag.m4
new file mode 100644
index 0000000..bd753b3
--- /dev/null
+++ b/build-aux/ax_check_compile_flag.m4
@@ -0,0 +1,53 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
+#
+# DESCRIPTION
+#
+# Check whether the given FLAG works with the current language's compiler
+# or gives an error. (Warnings, however, are ignored)
+#
+# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
+# success/failure.
+#
+# If EXTRA-FLAGS is defined, it is added to the current language's default
+# flags (e.g. CFLAGS) when the check is done. The check is thus made with
+# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
+# force the compiler to issue an error when a bad flag is given.
+#
+# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
+#
+# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
+# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
+#
+# LICENSE
+#
+# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 6
+
+AC_DEFUN([AX_CHECK_COMPILE_FLAG],
+[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
+AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
+ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
+ _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
+ AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
+ [AS_VAR_SET(CACHEVAR,[yes])],
+ [AS_VAR_SET(CACHEVAR,[no])])
+ _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
+AS_VAR_IF(CACHEVAR,yes,
+ [m4_default([$2], :)],
+ [m4_default([$3], :)])
+AS_VAR_POPDEF([CACHEVAR])dnl
+])dnl AX_CHECK_COMPILE_FLAGS
diff --git a/build-aux/ax_check_vscript.m4 b/build-aux/ax_check_vscript.m4
new file mode 100644
index 0000000..9851f32
--- /dev/null
+++ b/build-aux/ax_check_vscript.m4
@@ -0,0 +1,142 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_check_vscript.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_CHECK_VSCRIPT
+#
+# DESCRIPTION
+#
+# Check whether the linker supports version scripts. Version scripts are
+# used when building shared libraries to bind symbols to version nodes
+# (helping to detect incompatibilities) or to limit the visibility of
+# non-public symbols.
+#
+# Output:
+#
+# If version scripts are supported, VSCRIPT_LDFLAGS will contain the
+# appropriate flag to pass to the linker. On GNU systems this would
+# typically be "-Wl,--version-script", and on Solaris it would typically
+# be "-Wl,-M".
+#
+# Two Automake conditionals are also set:
+#
+# HAVE_VSCRIPT is true if the linker supports version scripts with
+# entries that use simple wildcards, like "local: *".
+#
+# HAVE_VSCRIPT_COMPLEX is true if the linker supports version scripts with
+# pattern matching wildcards, like "global: Java_*".
+#
+# On systems that do not support symbol versioning, such as Mac OS X, both
+# conditionals will be false. They will also be false if the user passes
+# "--disable-symvers" on the configure command line.
+#
+# Example:
+#
+# configure.ac:
+#
+# AX_CHECK_VSCRIPT
+#
+# Makefile.am:
+#
+# if HAVE_VSCRIPT
+# libfoo_la_LDFLAGS += $(VSCRIPT_LDFLAGS),@srcdir@/libfoo.map
+# endif
+#
+# if HAVE_VSCRIPT_COMPLEX
+# libbar_la_LDFLAGS += $(VSCRIPT_LDFLAGS),@srcdir@/libbar.map
+# endif
+#
+# LICENSE
+#
+# Copyright (c) 2014 Kevin Cernekee <cernekee@gmail.com>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+# _AX_CHECK_VSCRIPT(flag, global-sym, action-if-link-succeeds, [junk-file=no])
+AC_DEFUN([_AX_CHECK_VSCRIPT], [
+ AC_LANG_PUSH([C])
+ ax_check_vscript_save_flags="$LDFLAGS"
+ echo "V1 { global: $2; local: *; };" > conftest.map
+ AS_IF([test x$4 = xyes], [
+ echo "{" >> conftest.map
+ ])
+ LDFLAGS="$LDFLAGS -Wl,$1,conftest.map"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[int show, hide;]], [])], [$3])
+ LDFLAGS="$ax_check_vscript_save_flags"
+ rm -f conftest.map
+ AC_LANG_POP([C])
+]) dnl _AX_CHECK_VSCRIPT
+
+AC_DEFUN([AX_CHECK_VSCRIPT], [
+
+ AC_ARG_ENABLE([symvers],
+ AS_HELP_STRING([--disable-symvers],
+ [disable library symbol versioning [default=auto]]),
+ [want_symvers=$enableval],
+ [want_symvers=yes]
+ )
+
+ AS_IF([test x$want_symvers = xyes], [
+
+ dnl First test --version-script and -M with a simple wildcard.
+
+ AC_CACHE_CHECK([linker version script flag], ax_cv_check_vscript_flag, [
+ ax_cv_check_vscript_flag=unsupported
+ _AX_CHECK_VSCRIPT([--version-script], [show], [
+ ax_cv_check_vscript_flag=--version-script
+ ])
+ AS_IF([test x$ax_cv_check_vscript_flag = xunsupported], [
+ _AX_CHECK_VSCRIPT([-M], [show], [ax_cv_check_vscript_flag=-M])
+ ])
+
+ dnl The linker may interpret -M (no argument) as "produce a load map."
+ dnl If "-M conftest.map" doesn't fail when conftest.map contains
+ dnl obvious syntax errors, assume this is the case.
+
+ AS_IF([test x$ax_cv_check_vscript_flag != xunsupported], [
+ _AX_CHECK_VSCRIPT([$ax_cv_check_vscript_flag], [show],
+ [ax_cv_check_vscript_flag=unsupported], [yes])
+ ])
+ ])
+
+ dnl If the simple wildcard worked, retest with a complex wildcard.
+
+ AS_IF([test x$ax_cv_check_vscript_flag != xunsupported], [
+ ax_check_vscript_flag=$ax_cv_check_vscript_flag
+ AC_CACHE_CHECK([if version scripts can use complex wildcards],
+ ax_cv_check_vscript_complex_wildcards, [
+ ax_cv_check_vscript_complex_wildcards=no
+ _AX_CHECK_VSCRIPT([$ax_cv_check_vscript_flag], [sh*], [
+ ax_cv_check_vscript_complex_wildcards=yes])
+ ])
+ ax_check_vscript_complex_wildcards="$ax_cv_check_vscript_complex_wildcards"
+ ], [
+ ax_check_vscript_flag=
+ ax_check_vscript_complex_wildcards=no
+ ])
+ ], [
+ AC_MSG_CHECKING([linker version script flag])
+ AC_MSG_RESULT([disabled])
+
+ ax_check_vscript_flag=
+ ax_check_vscript_complex_wildcards=no
+ ])
+
+ AS_IF([test x$ax_check_vscript_flag != x], [
+ VSCRIPT_LDFLAGS="-Wl,$ax_check_vscript_flag"
+ AC_SUBST([VSCRIPT_LDFLAGS])
+ ])
+
+ AM_CONDITIONAL([HAVE_VSCRIPT],
+ [test x$ax_check_vscript_flag != x])
+ AM_CONDITIONAL([HAVE_VSCRIPT_COMPLEX],
+ [test x$ax_check_vscript_complex_wildcards = xyes])
+
+]) dnl AX_CHECK_VSCRIPT
diff --git a/build-aux/ax_require_defined.m4 b/build-aux/ax_require_defined.m4
new file mode 100644
index 0000000..17c3eab
--- /dev/null
+++ b/build-aux/ax_require_defined.m4
@@ -0,0 +1,37 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_REQUIRE_DEFINED(MACRO)
+#
+# DESCRIPTION
+#
+# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
+# been defined and thus are available for use. This avoids random issues
+# where a macro isn't expanded. Instead the configure script emits a
+# non-fatal:
+#
+# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
+#
+# It's like AC_REQUIRE except it doesn't expand the required macro.
+#
+# Here's an example:
+#
+# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
+#
+# LICENSE
+#
+# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 2
+
+AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
+ m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
+])dnl AX_REQUIRE_DEFINED
diff --git a/build-aux/ax_valgrind_check.m4 b/build-aux/ax_valgrind_check.m4
new file mode 100644
index 0000000..b2297e1
--- /dev/null
+++ b/build-aux/ax_valgrind_check.m4
@@ -0,0 +1,239 @@
+# ===========================================================================
+# https://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off)
+# AX_VALGRIND_CHECK()
+#
+# DESCRIPTION
+#
+# AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows
+# running `make check` under a variety of Valgrind tools to check for
+# memory and threading errors.
+#
+# Defines VALGRIND_CHECK_RULES which should be substituted in your
+# Makefile; and $enable_valgrind which can be used in subsequent configure
+# output. VALGRIND_ENABLED is defined and substituted, and corresponds to
+# the value of the --enable-valgrind option, which defaults to being
+# enabled if Valgrind is installed and disabled otherwise. Individual
+# Valgrind tools can be disabled via --disable-valgrind-<tool>, the
+# default is configurable via the AX_VALGRIND_DFLT command or is to use
+# all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT
+# calls must be made before the call to AX_VALGRIND_CHECK.
+#
+# If unit tests are written using a shell script and automake's
+# LOG_COMPILER system, the $(VALGRIND) variable can be used within the
+# shell scripts to enable Valgrind, as described here:
+#
+# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html
+#
+# Usage example:
+#
+# configure.ac:
+#
+# AX_VALGRIND_DFLT([sgcheck], [off])
+# AX_VALGRIND_CHECK
+#
+# in each Makefile.am with tests:
+#
+# @VALGRIND_CHECK_RULES@
+# VALGRIND_SUPPRESSIONS_FILES = my-project.supp
+# EXTRA_DIST = my-project.supp
+#
+# This results in a "check-valgrind" rule being added. Running `make
+# check-valgrind` in that directory will recursively run the module's test
+# suite (`make check`) once for each of the available Valgrind tools (out
+# of memcheck, helgrind and drd) while the sgcheck will be skipped unless
+# enabled again on the commandline with --enable-valgrind-sgcheck. The
+# results for each check will be output to test-suite-$toolname.log. The
+# target will succeed if there are zero errors and fail otherwise.
+#
+# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in
+# memcheck, helgrind, drd and sgcheck. These are useful because often only
+# some of those tools can be ran cleanly on a codebase.
+#
+# The macro supports running with and without libtool.
+#
+# LICENSE
+#
+# Copyright (c) 2014, 2015, 2016 Philip Withnall <philip.withnall@collabora.co.uk>
+#
+# Copying and distribution of this file, with or without modification, are
+# permitted in any medium without royalty provided the copyright notice
+# and this notice are preserved. This file is offered as-is, without any
+# warranty.
+
+#serial 17
+
+dnl Configured tools
+m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]])
+m4_set_add_all([valgrind_exp_tool_set], [sgcheck])
+m4_foreach([vgtool], [valgrind_tool_list],
+ [m4_define([en_dflt_valgrind_]vgtool, [on])])
+
+AC_DEFUN([AX_VALGRIND_DFLT],[
+ m4_define([en_dflt_valgrind_$1], [$2])
+])dnl
+
+AM_EXTRA_RECURSIVE_TARGETS([check-valgrind])
+m4_foreach([vgtool], [valgrind_tool_list],
+ [AM_EXTRA_RECURSIVE_TARGETS([check-valgrind-]vgtool)])
+
+AC_DEFUN([AX_VALGRIND_CHECK],[
+ dnl Check for --enable-valgrind
+ AC_ARG_ENABLE([valgrind],
+ [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])],
+ [enable_valgrind=$enableval],[enable_valgrind=])
+
+ AS_IF([test "$enable_valgrind" != "no"],[
+ # Check for Valgrind.
+ AC_PATH_PROG([VALGRIND],[valgrind])
+ AS_IF([test "$VALGRIND" = ""],[
+ AS_IF([test "$enable_valgrind" = "yes"],[
+ AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind])
+ ],[
+ enable_valgrind=no
+ ])
+ ],[
+ enable_valgrind=yes
+ ])
+ ])
+
+ AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"])
+ AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind])
+
+ # Check for Valgrind tools we care about.
+ [valgrind_enabled_tools=]
+ m4_foreach([vgtool],[valgrind_tool_list],[
+ AC_ARG_ENABLE([valgrind-]vgtool,
+ m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl
+[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl
+[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]),
+ [enable_valgrind_]vgtool[=$enableval],
+ [enable_valgrind_]vgtool[=])
+ AS_IF([test "$enable_valgrind" = "no"],[
+ enable_valgrind_]vgtool[=no],
+ [test "$enable_valgrind_]vgtool[" ]dnl
+m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[
+ AC_CACHE_CHECK([for Valgrind tool ]vgtool,
+ [ax_cv_valgrind_tool_]vgtool,[
+ ax_cv_valgrind_tool_]vgtool[=no
+ m4_set_contains([valgrind_exp_tool_set],vgtool,
+ [m4_define([vgtoolx],[exp-]vgtool)],
+ [m4_define([vgtoolx],vgtool)])
+ AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[
+ ax_cv_valgrind_tool_]vgtool[=yes
+ ])
+ ])
+ AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[
+ AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[
+ AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool)
+ ],[
+ enable_valgrind_]vgtool[=no
+ ])
+ ],[
+ enable_valgrind_]vgtool[=yes
+ ])
+ ])
+ AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[
+ valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])["
+ ])
+ AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool)
+ ])
+ AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["])
+ AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools])
+
+[VALGRIND_CHECK_RULES='
+# Valgrind check
+#
+# Optional:
+# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions
+# files to load. (Default: empty)
+# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools.
+# (Default: --num-callers=30)
+# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of:
+# memcheck, helgrind, drd, sgcheck). (Default: various)
+
+# Optional variables
+VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES))
+VALGRIND_FLAGS ?= --num-callers=30
+VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no
+VALGRIND_helgrind_FLAGS ?= --history-level=approx
+VALGRIND_drd_FLAGS ?=
+VALGRIND_sgcheck_FLAGS ?=
+
+# Internal use
+valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools)))
+
+valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS)
+valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS)
+valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS)
+valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS)
+
+valgrind_quiet = $(valgrind_quiet_$(V))
+valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY))
+valgrind_quiet_0 = --quiet
+valgrind_v_use = $(valgrind_v_use_$(V))
+valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY))
+valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%-am,%,$''@):;
+
+# Support running with and without libtool.
+ifneq ($(LIBTOOL),)
+valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute
+else
+valgrind_lt =
+endif
+
+# Use recursive makes in order to ignore errors during check
+check-valgrind-am:
+ifeq ($(VALGRIND_ENABLED),yes)
+ $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \
+ $(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool))
+else
+ @echo "Need to reconfigure with --enable-valgrind"
+endif
+
+# Valgrind running
+VALGRIND_TESTS_ENVIRONMENT = \
+ $(TESTS_ENVIRONMENT) \
+ env VALGRIND=$(VALGRIND) \
+ G_SLICE=always-malloc,debug-blocks \
+ G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly
+
+VALGRIND_LOG_COMPILER = \
+ $(valgrind_lt) \
+ $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS)
+
+define valgrind_tool_rule
+check-valgrind-$(1)-am:
+ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes)
+ifneq ($$(TESTS),)
+ $$(valgrind_v_use)$$(MAKE) check-TESTS \
+ TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \
+ LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \
+ LOG_FLAGS="$$(valgrind_$(1)_flags)" \
+ TEST_SUITE_LOG=test-suite-$(1).log
+endif
+else ifeq ($$(VALGRIND_ENABLED),yes)
+ @echo "Need to reconfigure with --enable-valgrind-$(1)"
+else
+ @echo "Need to reconfigure with --enable-valgrind"
+endif
+endef
+
+$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool))))
+
+A''M_DISTCHECK_CONFIGURE_FLAGS ?=
+A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind
+
+MOSTLYCLEANFILES ?=
+MOSTLYCLEANFILES += $(valgrind_log_files)
+
+.PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools))
+']
+
+ AC_SUBST([VALGRIND_CHECK_RULES])
+ m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])])
+])
diff --git a/build-aux/clang-gcov-wrapper b/build-aux/clang-gcov-wrapper
new file mode 100755
index 0000000..4e320d8
--- /dev/null
+++ b/build-aux/clang-gcov-wrapper
@@ -0,0 +1,2 @@
+#!/bin/bash
+exec llvm-cov gcov "$@"
diff --git a/build-aux/expand-selected-hashes b/build-aux/expand-selected-hashes
new file mode 100644
index 0000000..da6cfd7
--- /dev/null
+++ b/build-aux/expand-selected-hashes
@@ -0,0 +1,136 @@
+# Expand a list of selected hashes to a list of enabled hashes, using
+# the information in hashes.conf.
+#
+# Copyright 2018 Zack Weinberg
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+BEGIN {
+ enable_all = 0
+ enable_strong = 0
+ enable_glibc = 0
+ enable_alt = 0
+ enable_fedora = 0
+ enable_freebsd = 0
+ enable_netbsd = 0
+ enable_openbsd = 0
+ enable_osx = 0
+ enable_owl = 0
+ enable_solaris = 0
+ enable_suse = 0
+ error = 0
+ split(SELECTED_HASHES, selected_hashes_list, ",")
+ for (i in selected_hashes_list) {
+ h = selected_hashes_list[i]
+ if (h == "all") {
+ enable_all = 1
+ } else if (h == "strong") {
+ enable_strong = 1
+ } else if (h == "glibc") {
+ enable_glibc = 1
+ } else if (h == "alt") {
+ enable_alt = 1
+ } else if (h == "fedora") {
+ enable_fedora = 1
+ } else if (h == "freebsd") {
+ enable_freebsd = 1
+ } else if (h == "netbsd") {
+ enable_netbsd = 1
+ } else if (h == "openbsd") {
+ enable_openbsd = 1
+ } else if (h == "osx") {
+ enable_osx = 1
+ } else if (h == "owl") {
+ enable_owl = 1
+ } else if (h == "solaris") {
+ enable_solaris = 1
+ } else if (h == "suse") {
+ enable_suse = 1
+ } else {
+ enable_some = 1
+ selected_hashes[h] = 1
+ }
+ }
+ if (enable_all && (enable_strong || enable_glibc || enable_some || \
+ enable_alt || enable_fedora || enable_freebsd || \
+ enable_netbsd || enable_openbsd || enable_osx || \
+ enable_owl || enable_solaris || enable_suse)) {
+ error = 1
+ exit 1
+ }
+}
+
+/^#/ {
+ next
+}
+
+{
+ if (enable_all || $1 in selected_hashes) {
+ enabled_hashes[$1] = 1
+ } else {
+ enabled_hashes[$1] = 0
+
+ split($4, flags, ",")
+ for (i in flags) {
+ flag = flags[i]
+ if (flag == "STRONG" && enable_strong) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "GLIBC" && enable_glibc) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "ALT" && enable_alt) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "FEDORA" && enable_fedora) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "FREEBSD" && enable_freebsd) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "NETBSD" && enable_netbsd) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "OPENBSD" && enable_openbsd) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "OSX" && enable_osx) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "OWL" && enable_owl) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "SOLARIS" && enable_solaris) {
+ enabled_hashes[$1] = 1
+ } else if (flag == "SUSE" && enable_suse) {
+ enabled_hashes[$1] = 1
+ }
+ }
+ }
+}
+
+
+END {
+ if (error) {
+ exit 1
+ }
+
+ # Check for individual selected hashes that didn't appear in
+ # hashes.conf.
+ for (h in selected_hashes) {
+ if (!(h in enabled_hashes)) {
+ exit 1
+ }
+ }
+
+ enabled_hash_list = ","
+ for (i in enabled_hashes) {
+ if (enabled_hashes[i]) {
+ enabled_hash_list = enabled_hash_list i ","
+ }
+ }
+ print enabled_hash_list
+}
diff --git a/build-aux/gen-crypt-h b/build-aux/gen-crypt-h
new file mode 100644
index 0000000..d7ca1a2
--- /dev/null
+++ b/build-aux/gen-crypt-h
@@ -0,0 +1,62 @@
+# Generation of crypt.h from crypt.h.in and config.h.
+#
+# Written by Zack Weinberg <zackw at panix.com> in 2017.
+# To the extent possible under law, Zack Weinberg has waived all
+# copyright and related or neighboring rights to this work.
+#
+# See https://creativecommons.org/publicdomain/zero/1.0/ for further
+# details.
+
+BEGIN {
+ HAVE_SYS_CDEFS_H = 0
+ HAVE_SYS_CDEFS_BEGIN_END_DECLS = 0
+ HAVE_SYS_CDEFS_THROW = 0
+}
+END {
+ if (!HAVE_SYS_CDEFS_H &&
+ (HAVE_SYS_CDEFS_BEGIN_END_DECLS ||
+ HAVE_SYS_CDEFS_THROW)) {
+ print "config.h is inconsistent" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+}
+FILENAME ~ /config\.h$/ {
+ if ($0 ~ /^#define HAVE_SYS_CDEFS_H 1$/) {
+ HAVE_SYS_CDEFS_H = 1
+ } else if ($0 ~ /^#define HAVE_SYS_CDEFS_BEGIN_END_DECLS 1$/) {
+ HAVE_SYS_CDEFS_BEGIN_END_DECLS = 1
+ } else if ($0 ~ /^#define HAVE_SYS_CDEFS_THROW 1$/) {
+ HAVE_SYS_CDEFS_THROW = 1
+ }
+}
+FILENAME !~ /config\.h$/ {
+ if ($0 ~ /^\/\*HEADER\*\/$/) {
+ if (HAVE_SYS_CDEFS_H) {
+ print "#include <sys/cdefs.h>"
+ }
+ if (!HAVE_SYS_CDEFS_THROW) {
+ print "#define __THROW /* nothing */"
+ }
+ print ""
+ if (HAVE_SYS_CDEFS_BEGIN_END_DECLS) {
+ print "__BEGIN_DECLS"
+ } else {
+ print "#ifdef __cplusplus"
+ print "extern \"C\" {"
+ print "#endif"
+ }
+
+ } else if ($0 ~ /^\/\*TRAILER\*\/$/) {
+ if (HAVE_SYS_CDEFS_BEGIN_END_DECLS) {
+ print "__END_DECLS"
+ } else {
+ print "#ifdef __cplusplus"
+ print "} /* extern \"C\" */"
+ print "#endif"
+ }
+
+ } else {
+ print;
+ }
+}
diff --git a/build-aux/gen-crypt-hashes-h b/build-aux/gen-crypt-hashes-h
new file mode 100644
index 0000000..d042456
--- /dev/null
+++ b/build-aux/gen-crypt-hashes-h
@@ -0,0 +1,172 @@
+# Generate crypt-hashes.h from hashes.conf and configure settings.
+#
+# Copyright 2018 Zack Weinberg
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public License
+# as published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, see
+# <https://www.gnu.org/licenses/>.
+
+BEGIN {
+ next_output = 0
+ error = 0
+ default_prefix = ""
+
+ # ENABLED_HASHES is set on the command line.
+ split(ENABLED_HASHES, enabled_hashes_list, ",")
+ for (i in enabled_hashes_list) {
+ h = enabled_hashes_list[i]
+ if (h != "") {
+ hash_enabled[h] = 1
+ }
+ }
+}
+
+/^#/ {
+ next
+}
+
+{
+ if ($1 == ":") {
+ printf("%s:%d: error: method name cannot be blank\n", FILENAME, NR) \
+ > "/dev/stderr"
+ error = 1
+ }
+ # No two hashing method names can be the same.
+ if ($1 in line_index) {
+ printf("%s:%d: error: method name '%s' reused\n", FILENAME, NR, $1);
+ printf("%s: note: previous use was here\n", line_index[$1]);
+ error = 1
+ } else {
+ line_index[$1] = sprintf("%s:%d", FILENAME, NR);
+ if (!($1 in hash_enabled)) {
+ hash_enabled[$1] = 0
+ }
+ default_cand[$1] = ""
+ output_order[next_output++] = $1
+ }
+ if ($2 == ":") $2 = ""
+ prefixes[$1] = $2
+ if ($3 !~ /^[0-9]+$/ || $3 == 0) {
+ printf("%s:%d: nrbytes must be a positive integer\n", FILENAME, NR) \
+ > "/dev/stderr"
+ error = 1
+ }
+
+ crypt_fn = "crypt_" $1 "_rn"
+ gensalt_fn = "gensalt_" $1 "_rn"
+
+ renames[$1] = \
+ "#define " crypt_fn " _crypt_" crypt_fn "\n" \
+ "#define " gensalt_fn " _crypt_" gensalt_fn "\n"
+ prototypes[$1] = \
+ "extern void " crypt_fn " (const char *, size_t, const char *,\n" \
+ " size_t, uint8_t *, size_t, void *, size_t);\n" \
+ "extern void " gensalt_fn " (unsigned long,\n" \
+ " const uint8_t *, size_t, uint8_t *, size_t);\n"
+
+ table_entry[$1] = sprintf(" { \"%s\", %d, %s, %s, %d }, \\",
+ $2, length($2), crypt_fn, gensalt_fn, $3)
+
+ if ($4 == ":") $4 = ""
+ split($4, flags, ",")
+ for (i in flags) {
+ flag = flags[i]
+ if (flag == "DEFAULT") {
+ default_cand[$1] = $2
+ } else if (flag == "STRONG" || flag == "GLIBC" || \
+ flag == "ALT" || flag == "FEDORA" || \
+ flag == "FREEBSD" || flag == "NETBSD" || \
+ flag == "OPENBSD" || flag == "OSX" || \
+ flag == "OWL" || flag == "SOLARIS" || \
+ flag == "SUSE") {
+ # handled in expand-selected-hashes
+ } else {
+ printf("%s:%d: unrecognized flag %s\n", FILENAME, NR, flag) \
+ > "/dev/stderr"
+ error = 1
+ }
+ }
+}
+
+
+END {
+ # No hash prefix can be a prefix of any other hash prefix, except
+ # for the empty prefix.
+ for (i in prefixes) {
+ a = prefixes[i]
+ if (a == "") { continue }
+ for (j in prefixes) {
+ if (i == j) { continue }
+ b = prefixes[j]
+ if (b == "") { continue }
+ if (substr(b, 1, length(a)) == a) {
+ printf("%s: error: prefix collision: '%s' begins with '%s'\n",
+ line_index[j], b, a) > "/dev/stderr"
+ printf("%s: note: '%s' is used here\n", line_index[i], a) \
+ > "/dev/stderr"
+ error = 1
+ }
+ }
+ }
+
+ if (error) {
+ exit 1
+ }
+
+ print "/* Generated by gen-crypt-hashes-h from hashes.conf. DO NOT EDIT. */"
+ print ""
+ print "#ifndef _CRYPT_HASHES_H"
+ print "#define _CRYPT_HASHES_H 1"
+
+ print ""
+ for (i = 0; i < next_output; ++i) {
+ hash = output_order[i]
+ printf("#define INCLUDE_%-13s %d\n", hash, hash_enabled[hash])
+ if (hash_enabled[hash] && default_cand[hash] != "" && default_prefix == "") {
+ default_prefix = default_cand[hash]
+ }
+ }
+
+ print ""
+ print "/* Internal symbol renames for static linkage, see crypt-port.h. */"
+ for (i = 0; i < next_output; ++i) {
+ hash = output_order[i]
+ if (hash_enabled[hash]) {
+ print renames[hash]
+ }
+ }
+
+ print "/* Prototypes for hash algorithm entry points. */"
+ for (i = 0; i < next_output; ++i) {
+ hash = output_order[i]
+ if (hash_enabled[hash]) {
+ print prototypes[hash]
+ }
+ }
+
+ print "#define HASH_ALGORITHM_TABLE_ENTRIES \\"
+ for (i = 0; i < next_output; ++i) {
+ hash = output_order[i]
+ if (hash_enabled[hash]) {
+ print table_entry[hash]
+ }
+ }
+ print " { 0, 0, 0, 0, 0 }"
+
+ print ""
+ if (default_prefix != "") {
+ print "#define HASH_ALGORITHM_DEFAULT \"" default_prefix "\""
+ print ""
+ }
+ print "#endif /* crypt-hashes.h */"
+}
diff --git a/build-aux/gen-crypt-symbol-vers-h b/build-aux/gen-crypt-symbol-vers-h
new file mode 100644
index 0000000..5cc046d
--- /dev/null
+++ b/build-aux/gen-crypt-symbol-vers-h
@@ -0,0 +1,211 @@
+# Generate macros that control the symbol versions of the public
+# library API, from a .map.in file.
+#
+# Written by Zack Weinberg <zackw at panix.com> in 2017.
+# To the extent possible under law, Zack Weinberg has waived all
+# copyright and related or neighboring rights to this work.
+#
+# See https://creativecommons.org/publicdomain/zero/1.0/ for further
+# details.
+
+# The .map.in file is the first input file, and we expect the Makefile
+# to have set the variables SYMVER_MIN, SYMVER_FLOOR, and COMPAT_ABI.
+# See libcrypt.map.in and gen-libcrypt-map for explanations of the format
+# of .map.in files. See crypt-port.h for an explanation of how to use
+# the macros generated by this program.
+#
+# Note: if you change the format of .map.in files you probably need to
+# update gen-libcrypt-map too.
+#
+# Note: we currently don't support compatibility symbols that need
+# a different definition from the default version.
+
+BEGIN {
+ split("", SYMBOLS) # ensure SYMBOLS is an array
+ split("", VCHAIN) # ditto VCHAIN
+ NVCHAIN = 0
+
+ # This arranges for sorted output if gawk is in use, and is
+ # harmless otherwise.
+ PROCINFO["sorted_in"] = "@ind_str_asc"
+}
+
+NF == 0 { next } # blank line, discard
+$1 == "#" { next } # comment, discard
+$1 == "%chain" {
+ for (i = 2; i <= NF; i++) {
+ VCHAIN[++NVCHAIN] = $i
+ }
+ next
+}
+
+{
+ if ($2 == "-") {
+ compat_only[$1] = 1
+ } else {
+ compat_only[$1] = 0
+ if ($2 in SYMBOLS) {
+ SYMBOLS[$2] = SYMBOLS[$2] SUBSEP $1
+ } else {
+ SYMBOLS[$2] = $1
+ }
+ }
+ for (i = 3; i <= NF; i++) {
+ sym=$i
+ n=split(sym, a, ":")
+ if (n > 1) {
+ sym=""
+ for (j = 2; j <= n; j++) {
+ if (COMPAT_ABI == "yes" || COMPAT_ABI == a[j]) {
+ sym=a[1]
+ }
+ }
+ }
+ if (sym != "") {
+ if (sym in SYMBOLS) {
+ SYMBOLS[sym] = SYMBOLS[sym] SUBSEP $1
+ } else {
+ SYMBOLS[sym] = $1
+ }
+ }
+ }
+}
+
+END {
+ if (NVCHAIN == 0) {
+ print ARGV[1] ": error: missing %chain directive" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+ symver_min_idx = 0
+ symver_floor_idx = 0
+ for (i = 1; i <= NVCHAIN; i++) {
+ if (VCHAIN[i] == SYMVER_MIN) {
+ symver_min_idx = i
+ }
+ if (VCHAIN[i] == SYMVER_FLOOR) {
+ symver_floor_idx = i
+ }
+ }
+ if (symver_min_idx == 0) {
+ print ARGV[1] ": error: SYMVER_MIN (" SYMVER_MIN ") " \
+ "not found in %chain directives" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+ if (symver_floor_idx == 0) {
+ print ARGV[1] ": error: SYMVER_FLOOR (" SYMVER_FLOOR ") " \
+ "not found in %chain directives" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+ if (symver_floor_idx < symver_min_idx) {
+ print ARGV[1] ": error: SYMVER_FLOOR (" SYMVER_FLOOR ") " \
+ "is lower than SYMVER_MIN (" SYMVER_MIN ")" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+
+ # Construct a pruned set of symbols and versions, including only
+ # versions with symbols, discarding all symbols associated with
+ # versions below SYMVER_MIN, raising symbols below SYMVER_FLOOR to
+ # SYMVER_FLOOR, and removing duplicates.
+ # Note: unlike in gen-libcrypt-map, symbols all of whose versions are
+ # below SYMVER_MIN must still be counted in 'allsyms' so their
+ # INCLUDE macros are generated.
+ for (i = 1; i <= NVCHAIN; i++) {
+ v = VCHAIN[i]
+ if (v in SYMBOLS) {
+ nsyms = split(SYMBOLS[v], syms, SUBSEP)
+ j = i;
+ if (j < symver_floor_idx)
+ j = symver_floor_idx;
+ vr = VCHAIN[j]
+ for (s = 1; s <= nsyms; s++) {
+ if (syms[s]) {
+ allsyms[syms[s]] = 1
+ if (i >= symver_min_idx) {
+ symset[vr, syms[s]] = 1
+ }
+ }
+ }
+ }
+ }
+
+ print "/* Generated from " ARGV[1] " by gen-crypt-symbol-vers-h. DO NOT EDIT. */"
+ print ""
+ print "#ifndef _CRYPT_SYMBOL_VERS_H"
+ print "#define _CRYPT_SYMBOL_VERS_H 1"
+
+ print ""
+ print "/* For each public symbol <sym>, INCLUDE_<sym> is true if it"
+ print " has any versions above the backward compatibility minimum."
+ print " Compatibility-only symbols are not included in the static"
+ print " library, or in the shared library when configured with"
+ print " --disable-obsolete-api. */"
+ print "#if defined PIC && ENABLE_OBSOLETE_API"
+ print ""
+ for (sym in allsyms) {
+ include = 0
+ for (i = symver_floor_idx; i <= NVCHAIN; i++) {
+ if ((VCHAIN[i], sym) in symset) {
+ include++
+ }
+ }
+ includesym[sym] = include
+ printf("#define INCLUDE_%s %d\n", sym, include)
+ }
+ print ""
+ print "#else"
+ print ""
+ for (sym in allsyms) {
+ printf("#define INCLUDE_%s %d\n", sym,
+ (includesym[sym] && !compat_only[sym]))
+ }
+ print ""
+ print "#endif"
+
+ print ""
+ print "/* For each public symbol <sym> that is included, define its"
+ print " highest version as the default, and aliases at each"
+ print " compatibility version. */"
+
+ for (sym in allsyms) {
+ if (includesym[sym]) {
+ seq = 0
+ for (i = NVCHAIN; i >= symver_floor_idx; i--) {
+ v = VCHAIN[i]
+ if ((v, sym) in symset) {
+ if (seq == 0) {
+ if (compat_only[sym] || includesym[sym] > 0) {
+ printf("#ifdef PIC\n#define %s _crypt_%s\n#endif\n",
+ sym, sym);
+ }
+ printf("#define SYMVER_%s \\\n", sym)
+ if (compat_only[sym]) {
+ printf(" symver_compat0 (\"%s\", %s, %s)", sym, sym, v)
+ } else if (includesym[sym] > 0) {
+ printf(" symver_default (\"%s\", %s, %s)", sym, sym, v)
+ } else {
+ # Due to what appears to be a bug in GNU ld,
+ # we must not issue symver_default() if there
+ # aren't going to be any other versions.
+ printf(" symver_nop ()")
+ }
+ } else {
+ printf("; \\\n symver_compat (%d, \"%s\", %s, %s, %s)",
+ seq, sym, sym, sym, v)
+ }
+ seq++
+ }
+ }
+ print ""
+ } else {
+ printf("#define SYMVER_%s symver_nop()\n", sym)
+ }
+ }
+
+
+ print ""
+ print "#endif /* crypt-symbol-vers.h */"
+}
diff --git a/build-aux/gen-libcrypt-map b/build-aux/gen-libcrypt-map
new file mode 100644
index 0000000..e4383b6
--- /dev/null
+++ b/build-aux/gen-libcrypt-map
@@ -0,0 +1,147 @@
+# Generate a version map file from a .map.in file.
+#
+# Written by Zack Weinberg <zackw at panix.com> in 2017.
+# To the extent possible under law, Zack Weinberg has waived all
+# copyright and related or neighboring rights to this work.
+#
+# See https://creativecommons.org/publicdomain/zero/1.0/ for further
+# details.
+
+# The .map.in file is the first input file, and we expect the Makefile
+# to have set the variables SYMVER_MIN, SYMVER_FLOOR, and COMPAT_ABI.
+# All compat symbol versions that do not match COMPAT_ABI are ignored.
+# All symbol versions lower than SYMVER_MIN are discarded from the output.
+# All symbol versions lower than SYMVER_FLOOR are replaced with SYMVER_FLOOR.
+# SYMVER_FLOOR must be greater than or equal to SYMVER_MIN.
+#
+# The ordering of symbol versions is entirely controlled by the %chain
+# directive, which must therefore list both all of the versions
+# actually used for symbols, and all of the versions that might be
+# used as SYMVER_MIN or SYMVER_FLOOR.
+#
+# Note: if you change the format of .map.in files you probably need to
+# update gen-crypt-symbol-vers-h too.
+
+BEGIN {
+ split("", SYMBOLS) # ensure SYMBOLS is an array
+ split("", VCHAIN) # ditto VCHAIN
+ NVCHAIN = 0
+
+ # This arranges for sorted output if gawk is in use, and is
+ # harmless otherwise.
+ PROCINFO["sorted_in"] = "@ind_str_asc"
+}
+
+NF == 0 { next } # blank line, discard
+$1 == "#" { next } # comment, discard
+$1 == "%chain" {
+ for (i = 2; i <= NF; i++) {
+ VCHAIN[++NVCHAIN] = $i
+ }
+ next
+}
+
+{
+ for (i = 2; i <= NF; i++) {
+ sym=$i
+ if (sym != "-") {
+ n=split(sym, a, ":")
+ if (n > 1) {
+ sym="-"
+ for (j = 2; j <= n; j++) {
+ if (COMPAT_ABI == "yes" || COMPAT_ABI == a[j]) {
+ sym=a[1]
+ }
+ }
+ }
+ }
+ if (sym != "-") {
+ if (sym in SYMBOLS) {
+ SYMBOLS[sym] = SYMBOLS[sym] SUBSEP $1
+ } else {
+ SYMBOLS[sym] = $1
+ }
+ }
+ }
+}
+
+END {
+ if (NVCHAIN == 0) {
+ print ARGV[1] ": error: missing %chain directive" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+ symver_min_idx = 0
+ symver_floor_idx = 0
+ for (i = 1; i <= NVCHAIN; i++) {
+ if (VCHAIN[i] == SYMVER_MIN) {
+ symver_min_idx = i
+ }
+ if (VCHAIN[i] == SYMVER_FLOOR) {
+ symver_floor_idx = i
+ }
+ }
+ if (symver_min_idx == 0) {
+ print ARGV[1] ": error: SYMVER_MIN (" SYMVER_MIN ") " \
+ "not found in %chain directives" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+ if (symver_floor_idx == 0) {
+ print ARGV[1] ": error: SYMVER_FLOOR (" SYMVER_FLOOR ") " \
+ "not found in %chain directives" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+ if (symver_floor_idx < symver_min_idx) {
+ print ARGV[1] ": error: SYMVER_FLOOR (" SYMVER_FLOOR ") " \
+ "is lower than SYMVER_MIN (" SYMVER_MIN ")" > "/dev/stderr"
+ close("/dev/stderr")
+ exit 1
+ }
+
+ # Construct a pruned set of symbols and versions, including only
+ # versions with symbols, discarding all symbols associated with
+ # versions below SYMVER_MIN, raising symbols below SYMVER_FLOOR to
+ # SYMVER_FLOOR, and removing duplicates.
+ for (i = symver_min_idx; i <= NVCHAIN; i++) {
+ v = VCHAIN[i]
+ if (v in SYMBOLS) {
+ nsyms = split(SYMBOLS[v], syms, SUBSEP)
+ j = i;
+ if (j < symver_floor_idx)
+ j = symver_floor_idx;
+ vr = VCHAIN[j]
+ for (s = 1; s <= nsyms; s++) {
+ if (syms[s]) {
+ symset[vr, syms[s]] = 1
+ allsyms[syms[s]] = 1
+ }
+ }
+ }
+ }
+
+ vp = ""
+ for (i = symver_floor_idx; i <= NVCHAIN; i++) {
+ v = VCHAIN[i]
+ split("", osyms)
+ j = 0
+ for (sym in allsyms) {
+ if ((v, sym) in symset) {
+ osyms[++j] = sym
+ }
+ }
+ if (j > 0) {
+ printf("%s {\n global:\n", v);
+ for (s = 1; s <= j; s++) {
+ printf(" %s;\n", osyms[s]);
+ }
+ if (vp == "") {
+ vp = v
+ printf(" local:\n *;\n};\n");
+ } else {
+ printf("} %s;\n", vp);
+ }
+ }
+ }
+}
diff --git a/build-aux/pkg_installdir_compat.m4 b/build-aux/pkg_installdir_compat.m4
new file mode 100644
index 0000000..2bbe156
--- /dev/null
+++ b/build-aux/pkg_installdir_compat.m4
@@ -0,0 +1,47 @@
+# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
+# serial 11 (pkg-config-0.29.1)
+
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
+# Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program.
+
+# PKG_INSTALLDIR_COMPAT([DIRECTORY])
+# -------------------------
+# Backported from pkg-config 0.27.
+#
+# Substitutes the variable pkgconfigdir as the location where a module
+# should install pkg-config .pc files. By default the directory is
+# $libdir/pkgconfig, but the default can be changed by passing
+# DIRECTORY. The user can override through the --with-pkgconfigdir
+# parameter.
+AC_DEFUN([PKG_INSTALLDIR_COMPAT],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+ [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+ [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])
diff --git a/build-aux/skip-if-exec-format-error b/build-aux/skip-if-exec-format-error
new file mode 100755
index 0000000..901e6bb
--- /dev/null
+++ b/build-aux/skip-if-exec-format-error
@@ -0,0 +1,28 @@
+#! /bin/sh
+# Run a test given as "$@" and then munge its exit code to 77 if it
+# failed because of an "exec format error."
+#
+# Written by Zack Weinberg <zackw at panix.com> in 2017.
+# To the extent possible under law, Zack Weinberg has waived all
+# copyright and related or neighboring rights to this work.
+#
+# See https://creativecommons.org/publicdomain/zero/1.0/ for further
+# details.
+
+set -u
+
+tmplog=`mktemp -p "${TMPDIR:-/tmp}" tmplog.XXXXXXXXXX` || exit 99
+trap "rm -f '$tmplog'" 0
+
+"$@" > "$tmplog" 2>&1
+status="$?"
+cat "$tmplog" || exit 99
+
+case "$status" in
+ 0|77|99) exit "$status";;
+esac
+
+if grep -q '[eE]xec format error' "$tmplog"
+then exit 77
+else exit "$status"
+fi
diff --git a/build-aux/travis-after-success b/build-aux/travis-after-success
new file mode 100755
index 0000000..fee3d5d
--- /dev/null
+++ b/build-aux/travis-after-success
@@ -0,0 +1,49 @@
+#! /bin/sh
+set -e
+
+if [ "$PERFORM_COVERITY_SCAN" = 1 ] || [ "$DISTCHECK" = 1 ]; then
+ exit 0
+fi
+
+GCOV=gcov
+
+if [ "$TRAVIS_OS_NAME" = osx ]; then
+ case "$CC" in
+ gcc*)
+ GCC_VER="$( (brew list --versions gcc || echo gcc 0) |
+ sed 's/^gcc \([0-9]*\)\..*$/\1/' )"
+ if command -V "gcov-$GCC_VER"; then
+ GCOV="gcov-$GCC_VER"
+ fi
+ ;;
+ esac
+
+elif [ "$TRAVIS_OS_NAME" = linux ]; then
+ if [ "$CC" = clang ]; then
+ GCOV="$PWD/build-aux/clang-gcov-wrapper"
+ fi
+
+fi
+export GCOV
+
+# Log the identities and versions of the coverage tools.
+for tool in "$GCOV" lcov codecov
+do
+ # $tool might include mandatory command-line arguments.
+ # Interpret it the same way Make would.
+ set fnord $tool
+ shift
+ if command -V $1; then
+ echo + "$@" --version
+ "$@" --version
+ fi
+ echo
+done
+set fnord; shift # clear $@
+
+set -x
+lcov --gcov-tool $GCOV --directory . --capture --output-file all_coverage.info
+lcov --gcov-tool $GCOV --remove all_coverage.info \
+ '/usr/*' '*test*' > coverage.info
+rm all_coverage.info
+codecov -X gcov
diff --git a/build-aux/travis-before b/build-aux/travis-before
new file mode 100755
index 0000000..abe48e5
--- /dev/null
+++ b/build-aux/travis-before
@@ -0,0 +1,28 @@
+#! /bin/sh
+set -e
+
+# Log the identities and versions of the build tools.
+for tool in \
+ "${CC-cc}" \
+ "${AUTOCONF-autoconf}" \
+ "${AUTOMAKE-automake}" \
+ "${LIBTOOLIZE-libtoolize}" \
+ "${PKG_CONFIG-pkg-config}" \
+ "${PERL-perl}" \
+ "${PYTHON-python3}"
+do
+ # $tool might include mandatory command-line arguments.
+ # Interpret it the same way Make would.
+ set fnord $tool
+ shift
+ if command -V $1; then
+ echo + "$@" --version
+ "$@" --version
+ fi
+ echo
+done
+set fnord; shift # clear $@
+
+# Prepare the configure scripts.
+set -x
+. ./autogen.sh
diff --git a/build-aux/travis-build b/build-aux/travis-build
new file mode 100755
index 0000000..36a84b1
--- /dev/null
+++ b/build-aux/travis-build
@@ -0,0 +1,163 @@
+#!/bin/bash
+set -e
+
+log_time () {
+ local duration="$SECONDS"
+ local secs=$((duration % 60)); duration=$((duration / 60))
+ local mins=$((duration % 60)); duration=$((duration / 60))
+ local hours=$duration
+ if [ $hours -gt 0 ]; then
+ txt="${hours}h ${mins}m ${secs}s"
+ elif [[ $mins -gt 0 ]]; then
+ txt="${mins}m ${secs}s"
+ else
+ txt="${secs}s"
+ fi
+ printf 'time for %s: %s\n' "$1" "$txt"
+ SECONDS=0
+}
+
+# travis_wait is not a proper command, it's a bash function, so it is
+# not available to this script. This is a simplification of code from
+# https://github.com/travis-ci/travis-build/lib/travis/build/bash/
+travis_jigger () {
+ local cmd_pid="$1"
+ local timeout="$2"
+ local count=0
+
+ while [[ "$count" -lt "$timeout" ]]; do
+ sleep 60
+ count="$((count + 1))"
+ echo "Long job still running (${count}m / ${timeout}m)"
+ done
+ printf '\033[33;1m%s\033[0m\n' "Timeout, terminating long job."
+ # Use a negative process ID to target the entire process group of
+ # the background job.
+ kill -15 "-$cmd_pid"
+ sleep 60
+ printf '\033[31;1m%s\033[0m\n' "Timeout, killing long job."
+ kill -9 "-$cmd_pid"
+ # Ensure, as best we can, that this PID sticks around to be killed
+ # by travis_wait.
+ sleep 3600
+}
+travis_wait () {
+ local timeout="${1}"
+ if [[ "${timeout}" =~ ^[0-9]+$ ]]; then
+ shift
+ else
+ timeout=20
+ fi
+
+ # The background jobs we're about to start must be run in separate
+ # process groups, so we can kill them off all at once later.
+ set -m
+
+ "$@" &
+ local cmd_pid="$!"
+
+ travis_jigger "$cmd_pid" "$timeout" &
+ local jigger_pid="$!"
+
+ # ... but don't print reports when they finish.
+ set +m
+
+ wait "$cmd_pid" 2>/dev/null
+ local result="$?"
+ if [[ "$result" -eq 0 ]]; then
+ : # successful completion
+ elif [[ "$result" -eq -15 || $result -eq -9 ]]; then
+ : # terminated, error already printed
+ elif [[ "$result" -lt 0 ]]; then
+ printf '\033[31;1m%s\033[0m\n' "Long job killed by signal ${result#-}"
+ else
+ printf '\033[33;1m%s\033[0m\n' "Long job exited with status ${result}"
+ fi
+ kill -15 "-$jigger_pid"
+ wait "$jigger_pid"
+ return "$result"
+}
+
+
+export NPROCS="$((`nproc --all 2>/dev/null || sysctl -n hw.ncpu` * 2))"
+echo paralleism is $NPROCS
+
+if [[ "$PERFORM_COVERITY_SCAN" == "1" ]]; then
+ TAG_VERSION="`echo ${TRAVIS_BRANCH} | sed -e 's/^v//g'`"
+ curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" \
+ --output /tmp/travisci_build_coverity_scan.sh
+ sed -i -e "s/--form version=\$SHA/--form version=\"${TAG_VERSION}\"/g" \
+ -e "s/--form description=\"Travis CI build\"/--form description=\"${SHA}\"/g" \
+ -e "s/201/200/g" /tmp/travisci_build_coverity_scan.sh
+ bash /tmp/travisci_build_coverity_scan.sh
+ exit 0
+fi
+
+if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
+ export CFLAGS="-O2 -g -arch i386 -arch x86_64 --coverage"
+ export CXXFLAGS="$CFLAGS"
+ export LDFLAGS="-arch i386 -arch x86_64 --coverage"
+ if [[ "$CC" == "gcc" ]]; then
+ GCC_VER="$(brew list --versions gcc | sed 's/^gcc \([0-9]*\)\..*$/\1/')"
+ export CC="gcc-$GCC_VER"
+ export CPP="cpp-$GCC_VER"
+ export CXX="g++-$GCC_VER"
+ export AR="gcc-ar-$GCC_VER"
+ export NM="gcc-nm-$GCC_VER"
+ export RANLIB="gcc-ranlib-$GCC_VER"
+ $CC --version
+ fi
+elif [[ "$CODECOV" == "1" ]]; then
+ export CFLAGS="-O0 -g --coverage"
+ export CXXFLAGS="$CFLAGS"
+else
+ export DEB_BUILD_MAINT_OPTIONS="hardening=+all"
+ export CPPFLAGS="$(dpkg-buildflags --get CPPFLAGS)"
+ export CFLAGS="$(dpkg-buildflags --get CFLAGS) --coverage"
+ export CXXFLAGS="$(dpkg-buildflags --get CXXFLAGS) --coverage"
+ export LDFLAGS="$(dpkg-buildflags --get LDFLAGS) --coverage"
+fi
+
+if [[ "$CC" == "clang" ]]; then
+ export CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage"
+ export CXXFLAGS="$CXXFLAGS -fprofile-arcs -ftest-coverage"
+fi
+
+MAKE_ARGS=
+if [[ "$SANITIZER" == "1" ]]; then
+ # ASan is incompatible with -z defs.
+ MAKE_ARGS="UNDEF_FLAG="
+ export CFLAGS="$CFLAGS -fsanitize=undefined,address"
+ export CXXFLAGS="$CXXFLAGS -fsanitize=undefined,address"
+fi
+
+mkdir build
+pushd build
+log_time preparation
+
+$(cd .. && pwd)/configure --disable-silent-rules $CONF || \
+ (cat config.log && exit 1)
+log_time configure
+
+if [[ "$DISTCHECK" == "1" ]]; then
+ make -j$NPROCS $MAKE_ARGS distcheck
+ log_time distcheck
+else
+ make -j$NPROCS $MAKE_ARGS all
+ log_time build
+ travis_wait 60 \
+ make -j$NPROCS $MAKE_ARGS check || (cat test-suite.log && exit 1)
+ log_time test
+fi
+
+if [[ "$VALGRIND" == "1" ]]; then
+ # This step can take considerably longer than the default
+ # Travis no-output timeout on individual tests, just because
+ # that's how slow memcheck is.
+ travis_wait 60 \
+ make -j$NPROCS $MAKE_ARGS check-valgrind-memcheck || \
+ (cat test-suite-memcheck.log && exit 1)
+ log_time test-memcheck
+fi
+
+popd
diff --git a/build-aux/travis-install b/build-aux/travis-install
new file mode 100755
index 0000000..3fc154b
--- /dev/null
+++ b/build-aux/travis-install
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+if [ "$PERFORM_COVERITY_SCAN" = 1 ] || [ "$DISTCHECK" = 1 ]; then
+ exit 0
+fi
+set -x
+pip install --user codecov
diff --git a/build-aux/zw_alignment.m4 b/build-aux/zw_alignment.m4
new file mode 100644
index 0000000..a714196
--- /dev/null
+++ b/build-aux/zw_alignment.m4
@@ -0,0 +1,90 @@
+dnl Written by Zack Weinberg <zackw at panix.com> in 2017.
+dnl To the extent possible under law, Zack Weinberg has waived all
+dnl copyright and related or neighboring rights to this work.
+dnl
+dnl See https://creativecommons.org/publicdomain/zero/1.0/ for further
+dnl details.
+dnl
+dnl Find out how to query and set data alignment.
+dnl Currently knows about C11's _Alignas and _Alignof,
+dnl and GCC's __attribute__ ((aligned)) and __alignof.
+dnl
+dnl Note: AC_PROG_CC_C11 includes a test for _Alignas and _Alignof,
+dnl but not for <stdalign.h>, which we don't bother using anyway.
+dnl
+dnl Compatibility note: alignas (TYPE) does not work when alignas() is
+dnl defined using __attribute__ ((aligned)). Use alignas (alignof (TYPE))
+dnl instead.
+AC_DEFUN([zw_C_ALIGNAS],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([how to control data alignment], [zw_cv_c_alignas],
+ [AS_IF([test x$ac_prog_cc_stdc = xc11],
+ [zw_cv_c_alignas=_Alignas],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ int __attribute__((__aligned__(8))) global;
+ struct __attribute__((__aligned__(8))) aggregate { int x, y; };
+ ]], [[
+ int __attribute__((__aligned__(8))) local;
+ ]])],
+ [zw_cv_c_alignas=__attribute__],
+ [zw_cv_c_alignas=unknown])
+ ])
+ ])
+ AS_IF([test x$zw_cv_c_alignas = x_Alignas],
+ [zw_c_alignas_expr="_Alignas(n)"],
+ [test x$zw_cv_c_alignas = x__attribute__],
+ [zw_c_alignas_expr="__attribute__((__aligned__(n)))"],
+ [AC_MSG_FAILURE([could not find a way to control data alignment])])
+ AC_DEFINE_UNQUOTED([alignas(n)], [$zw_c_alignas_expr],
+ [Define as a type specifier which sets the alignment of a variable or type
+ to N bytes. C11 alignas(TYPE) does not need to be supported.])
+])
+
+AC_DEFUN([zw_C_ALIGNOF],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([how to query data alignment], [zw_cv_c_alignof],
+ [AS_IF([test x$ac_prog_cc_stdc = xc11],
+ [zw_cv_c_alignof=_Alignof],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ struct agg { int x, y; };
+ extern const char align_int[__alignof__(int)];
+ extern const char align_agg[__alignof__(struct agg)];
+ ]], [[
+ double d;
+ char align_var[__alignof__(d)];
+ ]])],
+ [zw_cv_c_alignof=__alignof__],
+ [zw_cv_c_alignof=unknown])
+ ])
+ ])
+ AS_IF([test x$zw_cv_c_alignof = x_Alignof],
+ [zw_c_alignof_expr="_Alignof(thing)"],
+ [test x$zw_cv_c_alignof = x__alignof__],
+ [zw_c_alignof_expr="__alignof__(thing)"],
+ [AC_MSG_FAILURE([could not find a way to query data alignment])])
+ AC_DEFINE_UNQUOTED([alignof(thing)], [$zw_c_alignof_expr],
+ [Define as an expression which evaluates to the alignment of THING.
+ Must be computed at compile time (an "integer constant expression").])
+])
+
+AC_DEFUN([zw_C_MAX_ALIGN_T],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([zw_C_ALIGNOF])
+ AC_CACHE_CHECK([for max_align_t in stddef.h], [zw_cv_c_max_align_t],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #include <stddef.h>
+ ]], [[
+ max_align_t var;
+ return alignof(var);
+ ]])],
+ [zw_cv_c_max_align_t=yes],
+ [zw_cv_c_max_align_t=no])
+ ])
+ AS_IF([test x$zw_cv_c_max_align_t = xyes],
+ [AC_DEFINE([HAVE_MAX_ALIGN_T], 1,
+ [Define if stddef.h provides max_align_t.])
+ ])
+])
diff --git a/build-aux/zw_automodern.m4 b/build-aux/zw_automodern.m4
new file mode 100644
index 0000000..8451b20
--- /dev/null
+++ b/build-aux/zw_automodern.m4
@@ -0,0 +1,307 @@
+dnl Copyright 2017 Zack Weinberg <zackw at panix.com>.
+dnl Partially based on Autoconf, copyright 1992-2017 Free Software Foundation.
+dnl
+dnl This program is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation, either version 3 of the
+dnl License, or (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl Under Section 7 of GPL version 3, you are granted additional
+dnl permissions described in the Autoconf Configure Script Exception,
+dnl version 3.0, as published by the Free Software Foundation.
+dnl
+dnl Because only two files in this source tree are released
+dnl under GPLv3 with exceptions, neither the GPLv3 nor the exception are
+dnl distributed with this source tree. Copies can be retrieved from
+dnl https://www.gnu.org/licenses/
+dnl
+dnl As of this writing (September 2017), Autoconf 2.70 is not yet released.
+dnl Backport some improvements:
+dnl - switch AC_CHECK_HEADER to compile-only
+dnl - eliminate unnecessary tests in AC_INCLUDES_DEFAULT
+dnl - Darwin (OSX) support in AC_USE_SYSTEM_EXTENSIONS
+dnl - C11 mode by default in AC_PROG_CC, falling back to C99
+AC_PREREQ([2.62])dnl earliest version with working m4_version_prereq
+m4_version_prereq([2.70], [], [
+
+ m4_define([AC_CHECK_HEADER], [_AC_CHECK_HEADER_COMPILE($@)])
+
+ AC_DEFUN_ONCE([_AC_INCLUDES_DEFAULT_REQUIREMENTS],
+[m4_divert_text([DEFAULTS],
+[# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+])]dnl
+[AC_CHECK_HEADERS(
+ [sys/types.h sys/stat.h strings.h inttypes.h stdint.h unistd.h],,,[/**/])]dnl
+dnl For backward compatibility, provide unconditional AC_DEFINEs of
+dnl HAVE_STDLIB_H, HAVE_STRING_H, and STDC_HEADERS.
+[AC_DEFINE([HAVE_STDLIB_H], [1],
+ [Always define to 1, for backward compatibility.
+ You can assume <stdlib.h> exists.])]dnl
+[AC_DEFINE([HAVE_STRING_H], [1],
+ [Always define to 1, for backward compatibility.
+ You can assume <string.h> exists.])]dnl
+[AC_DEFINE([STDC_HEADERS], [1],
+ [Always define to 1, for backward compatibility.
+ You can assume the C90 standard headers exist.])])
+
+ m4_define([AC_USE_SYSTEM_EXTENSIONS],
+ m4_defn([AC_USE_SYSTEM_EXTENSIONS])[
+ AH_VERBATIM([USE_SYSTEM_EXTENSIONS_270],
+[/* Enable general extensions on OSX. */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+])
+ AC_DEFINE([_DARWIN_C_SOURCE])
+ ])
+
+dnl Prior to 2.70, AC_PROG_CC ends with an unconditional call to
+dnl _AC_PROG_CC_C89. Use this as an extension hook, replacing it with
+dnl the logic that will be used in 2.70.
+m4_define([_AC_PROG_CC_C89_original], m4_defn([_AC_PROG_CC_C89]))
+m4_define([_AC_PROG_CC_C89], [dnl
+dnl Set ac_prog_cc_stdc to the supported C version.
+dnl Also set the documented variable ac_cv_prog_cc_stdc;
+dnl its name was chosen when it was cached, but it is no longer cached.
+_AC_PROG_CC_C11([ac_prog_cc_stdc=c11
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11],
+ [_AC_PROG_CC_C99([ac_prog_cc_stdc=c99
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99],
+ [_AC_PROG_CC_C89_original([ac_prog_cc_stdc=c89
+ ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89],
+ [ac_prog_cc_stdc=no
+ ac_cv_prog_cc_stdc=no])])])
+])
+dnl Must also supply the definition of _AC_PROG_CC_C11.
+dnl This is also taken verbatim from Autoconf trunk.
+dnl I regret the bulk.
+AC_DEFUN([_AC_PROG_CC_C11],
+[_AC_C_STD_TRY([c11],
+[[#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <stdio.h>
+
+// Check varargs macros. These examples are taken from C99 6.10.3.5.
+#define debug(...) fprintf (stderr, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+ int x = 1234;
+ int y = 5678;
+ debug ("Flag");
+ debug ("X = %d\n", x);
+ showlist (The first, second, and third items.);
+ report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+ your preprocessor is broken;
+#endif
+#if BIG_OK
+#else
+ your preprocessor is broken;
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+ int datasize;
+ double data[];
+};
+
+struct named_init {
+ int number;
+ const wchar_t *name;
+ double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+ // See if C++-style comments work.
+ // Iterate through items via the restricted pointer.
+ // Also check for declarations in for loops.
+ for (unsigned int i = 0; *(text+i) != '\0'; ++i)
+ continue;
+ return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+ va_list args;
+ va_start (args, format);
+ va_list args_copy;
+ va_copy (args_copy, args);
+
+ const char *str = "";
+ int number = 0;
+ float fnumber = 0;
+
+ while (*format)
+ {
+ switch (*format++)
+ {
+ case 's': // string
+ str = va_arg (args_copy, const char *);
+ break;
+ case 'd': // int
+ number = va_arg (args_copy, int);
+ break;
+ case 'f': // float
+ fnumber = va_arg (args_copy, double);
+ break;
+ default:
+ break;
+ }
+ }
+ va_end (args_copy);
+ va_end (args);
+
+ return *str && number && fnumber;
+}
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+ int_alignment = _Alignof (int),
+ int_array_alignment = _Alignof (int[100]),
+ char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+ int x;
+ _Static_assert (sizeof (int) <= sizeof (long int),
+ "_Static_assert does not work in struct");
+ long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+ union {
+ struct { int i; int j; };
+ struct { int k; long int l; } w;
+ };
+ int m;
+} v1;
+]],
+[[
+ // Check bool.
+ _Bool success = false;
+
+ // Check restrict.
+ if (test_restrict ("String literal") == 0)
+ success = true;
+ char *restrict newvar = "Another string";
+
+ // Check varargs.
+ success &= test_varargs ("s, d' f .", "string", 65, 34.234);
+ test_varargs_macros ();
+
+ // Check flexible array members.
+ struct incomplete_array *ia =
+ malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+ ia->datasize = 10;
+ for (int i = 0; i < ia->datasize; ++i)
+ ia->data[i] = i * 1.234;
+
+ // Check named initializers.
+ struct named_init ni = {
+ .number = 34,
+ .name = L"Test wide string",
+ .average = 543.34343,
+ };
+
+ ni.number = 58;
+
+ int dynamic_array[ni.number];
+ dynamic_array[ni.number - 1] = 543;
+
+ // work around unused variable warnings
+ return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x'
+ || dynamic_array[ni.number - 1] != 543);
+
+ v1.i = 2;
+ v1.w.k = 5;
+ _Static_assert ((offsetof (struct anonymous, i)
+ == offsetof (struct anonymous, w.k)),
+ "Anonymous union alignment botch");
+]],
+dnl Try
+dnl GCC -std=gnu11 (unused restrictive mode: -std=c11)
+dnl with extended modes being tried first.
+dnl
+dnl Do not try -qlanglvl=extc1x, because IBM XL C V12.1 (the latest version as
+dnl of September 2012) does not pass the C11 test. For now, try extc1x when
+dnl compiling the C99 test instead, since it enables _Static_assert and
+dnl _Noreturn, which is a win. If -qlanglvl=extc11 or -qlanglvl=extc1x passes
+dnl the C11 test in some future version of IBM XL C, we'll add it here,
+dnl preferably extc11.
+[[-std=gnu11]], [$1], [$2])[]dnl
+])# _AC_PROG_CC_C11
+
+
+])dnl m4_version_prereq([2.70], ...)
diff --git a/build-aux/zw_endianness.m4 b/build-aux/zw_endianness.m4
new file mode 100644
index 0000000..9513216
--- /dev/null
+++ b/build-aux/zw_endianness.m4
@@ -0,0 +1,152 @@
+dnl Written by Zack Weinberg <zackw at panix.com> in 2018.
+dnl To the extent possible under law, Zack Weinberg has waived all
+dnl copyright and related or neighboring rights to this work.
+dnl
+dnl See https://creativecommons.org/publicdomain/zero/1.0/ for further
+dnl details.
+dnl
+dnl This macro is like AC_C_BIGENDIAN, but it doesn't try to determine
+dnl a final value at configure time. Instead, it probes for a set of
+dnl headers and compile-time macros that may or may not be available,
+dnl and uses them to guide preprocessor logic that makes the final
+dnl determination. This works better with MacOS "universal binaries",
+dnl which may involve compiling the program twice under opposite
+dnl endiannesses; no fixed byte-order macro is correct in that case,
+dnl but the compiler's built-ins will be. This approach is also
+dnl friendlier to cross-compilation.
+dnl
+dnl This is the preprocessor logic that should be put in an appropriate
+dnl location, after including config.h:
+dnl
+dnl #include <limits.h>
+dnl #ifdef HAVE_ENDIAN_H
+dnl #include <endian.h>
+dnl #endif
+dnl #ifdef HAVE_SYS_ENDIAN_H
+dnl #include <sys/endian.h>
+dnl #endif
+dnl #ifdef HAVE_SYS_PARAM_H
+dnl #include <sys/param.h>
+dnl #endif
+dnl
+dnl #if ENDIANNESS_IS_BIG
+dnl # define ENDIAN_BIG
+dnl #elif ENDIANNESS_IS_LITTLE
+dnl # define ENDIAN_LITTLE
+dnl #elif ENDIANNESS_IS_PDP
+dnl # define ENDIAN_PDP
+dnl #else
+dnl # error "Unable to determine byte order"
+dnl #endif
+dnl ------------------------------------------------
+
+dnl There's no good way to implement this macro as a _shell_ loop, but we
+dnl can reasonably implement it as an _m4_ loop that expands to a sequence
+dnl of conditionals. Actually two sequences of conditionals, one inside
+dnl AC_CACHE_CHECK and one outside.
+
+m4_define([zw_C_ENDIANNESS_options], [
+[ [BYTE_ORDER and xxx_ENDIAN],
+ [defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN && BIG_ENDIAN != LITTLE_ENDIAN],
+ [BYTE_ORDER == BIG_ENDIAN],
+ [BYTE_ORDER == LITTLE_ENDIAN],
+ [BYTE_ORDER == PDP_ENDIAN],
+],
+[ [__BYTE_ORDER and __xxx_ENDIAN],
+ [defined __BYTE_ORDER && defined __BIG_ENDIAN && defined __LITTLE_ENDIAN && __BIG_ENDIAN != __LITTLE_ENDIAN],
+ [__BYTE_ORDER == __BIG_ENDIAN],
+ [__BYTE_ORDER == __LITTLE_ENDIAN],
+ [__BYTE_ORDER == __PDP_ENDIAN],
+],
+[ [__BYTE_ORDER__ and __xxx_ENDIAN__],
+ [defined __BYTE_ORDER__ && defined __BIG_ENDIAN__ && defined __LITTLE_ENDIAN__ && __BIG_ENDIAN__ != __LITTLE_ENDIAN__],
+ [__BYTE_ORDER__ == __BIG_ENDIAN__],
+ [__BYTE_ORDER__ == __LITTLE_ENDIAN__],
+ [__BYTE_ORDER__ == __PDP_ENDIAN__],
+],
+[ [__BYTE_ORDER__ and __ORDER_xxx_ENDIAN__],
+ [defined __BYTE_ORDER__ && defined __ORDER_BIG_ENDIAN__ && defined __ORDER_LITTLE_ENDIAN__ && __ORDER_BIG_ENDIAN__ != __ORDER_LITTLE_ENDIAN__],
+ [__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__],
+ [__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__],
+ [__BYTE_ORDER__ == __ORDER_PDP_ENDIAN__],
+],
+[ [_BIG_ENDIAN and _LITTLE_ENDIAN],
+ [(defined _BIG_ENDIAN) != (defined _LITTLE_ENDIAN)],
+ [defined _BIG_ENDIAN], [defined _LITTLE_ENDIAN], [0],
+],
+[ [__BIG_ENDIAN__ and __LITTLE_ENDIAN__],
+ [(defined __BIG_ENDIAN__) != (defined __LITTLE_ENDIAN__)],
+ [defined __BIG_ENDIAN__], [defined __LITTLE_ENDIAN__], [0],
+],
+[ [__ARMEB__ and __ARMEL__],
+ [(defined __ARMEB__) != (defined __ARMEL__)],
+ [defined __ARMEB__], [defined __ARMEL__], [0],
+],
+[ [__THUMBEB__ and __THUMBEL__],
+ [(defined __THUMBEB__) != (defined __THUMBEL__)],
+ [defined __THUMBEB__], [defined __THUMBEL__], [0],
+],
+[ [__AARCH64EB__ and __AARCH64EL__],
+ [(defined __AARCH64EB__) != (defined __AARCH64EL__)],
+ [defined __AARCH64EB__], [defined __AARCH64EL__], [0],
+],
+[ [__MIPSEB__ and __MIPSEL__],
+ [(defined __MIPSEB__) != (defined __MIPSEL__)],
+ [defined __MIPSEB__], [defined __MIPSEL__], [0],
+],
+[ [__MIPSEB and __MIPSEL],
+ [(defined __MIPSEB) != (defined __MIPSEL)],
+ [defined __MIPSEB], [defined __MIPSEL], [0],
+],
+[ [_MIPSEB and _MIPSEL],
+ [(defined _MIPSEB) != (defined _MIPSEL)],
+ [defined _MIPSEB], [defined _MIPSEL], [0],
+]
+])
+
+m4_define([zw_C_ENDIANNESS_test_one], [
+if test "$[]ac_cv_c_byte_order_macros" = unknown; then
+ AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[
+#include <limits.h>
+#ifdef HAVE_ENDIAN_H
+#include <endian.h>
+#endif
+#ifdef HAVE_SYS_ENDIAN_H
+#include <sys/endian.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#if !($2)
+#error fail
+#endif
+]])],
+ [ac_cv_c_byte_order_macros="$1"])
+fi])
+
+m4_define([zw_C_ENDIANNESS_case_one],
+ [["$1"], [
+ zw_C_ENDIANNESS_IS_BIG="($3)"
+ zw_C_ENDIANNESS_IS_LIT="($4)"
+ zw_C_ENDIANNESS_IS_PDP="($5)"]])
+
+AC_DEFUN([zw_C_ENDIANNESS], [
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+AC_CHECK_HEADERS_ONCE([endian.h sys/endian.h sys/param.h])
+AC_CACHE_CHECK([for byte order macros],
+ [ac_cv_c_byte_order_macros], [
+ ac_cv_c_byte_order_macros=unknown
+ m4_map([zw_C_ENDIANNESS_test_one], [zw_C_ENDIANNESS_options])])
+
+AS_CASE([$ac_cv_c_byte_order_macros],
+ m4_map_sep([zw_C_ENDIANNESS_case_one], [,], [zw_C_ENDIANNESS_options]),
+ [AC_MSG_ERROR([unable to determine byte order at compile time])])
+
+AC_DEFINE_UNQUOTED([ENDIANNESS_IS_BIG], [$zw_C_ENDIANNESS_IS_BIG],
+ [Define as an @%:@if expression that is true when compiling for a big-endian CPU.])
+AC_DEFINE_UNQUOTED([ENDIANNESS_IS_LITTLE], [$zw_C_ENDIANNESS_IS_LIT],
+ [Define as an @%:@if expression that is true when compiling for a little-endian CPU.])
+AC_DEFINE_UNQUOTED([ENDIANNESS_IS_PDP], [$zw_C_ENDIANNESS_IS_PDP],
+ [Define as an @%:@if expression that is true when compiling for a PDP-endian CPU.])
+])
diff --git a/build-aux/zw_ld_wrap.m4 b/build-aux/zw_ld_wrap.m4
new file mode 100644
index 0000000..87b22e7
--- /dev/null
+++ b/build-aux/zw_ld_wrap.m4
@@ -0,0 +1,47 @@
+dnl Written by Zack Weinberg <zackw at panix.com> in 2018.
+dnl To the extent possible under law, Zack Weinberg has waived all
+dnl copyright and related or neighboring rights to this work.
+dnl
+dnl See https://creativecommons.org/publicdomain/zero/1.0/ for further
+dnl details.
+dnl
+dnl Find out whether ld --wrap is supported.
+AC_DEFUN([zw_PROG_LD_WRAP],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([for ld --wrap], [zw_cv_prog_ld_wrap],
+ [save_LDFLAGS="$LDFLAGS"
+ save_LIBS="$LIBS"
+ LDFLAGS=""
+ LIBS=""
+ AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE([[
+ extern void bar(void);
+ void foo(void) { bar(); }
+ ]])],
+ [mv conftest.$OBJEXT conftest2.$OBJEXT
+ LDFLAGS="-Wl,--wrap,bar"
+ LIBS="conftest2.$OBJEXT"
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[
+ extern void foo(void);
+ void __wrap_bar(void) {}
+ ]], [[
+ foo();
+ ]])],
+ [zw_cv_prog_ld_wrap=yes],
+ [zw_cv_prog_ld_wrap=no])
+ rm -f conftest2.$OBJEXT
+ ],
+ [zw_cv_prog_ld_wrap=no])
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"])
+ if test x$zw_cv_prog_ld_wrap = xyes; then
+ have_ld_wrap=yes
+ AC_DEFINE([HAVE_LD_WRAP], 1,
+ [Define to 1 if -Wl,--wrap,SYMBOL can be used to intercept
+ calls to SYMBOL at link time.])
+ else
+ have_ld_wrap=no
+ fi
+ AM_CONDITIONAL([HAVE_LD_WRAP], [test $have_ld_wrap = yes])
+])
diff --git a/build-aux/zw_simple_warnings.m4 b/build-aux/zw_simple_warnings.m4
new file mode 100644
index 0000000..fef1312
--- /dev/null
+++ b/build-aux/zw_simple_warnings.m4
@@ -0,0 +1,150 @@
+# serial 1
+dnl Copyright 2017 Zack Weinberg <zackw at panix.com>.
+dnl Partially based on Autoconf, copyright 1992-2017 Free Software Foundation.
+dnl
+dnl This program is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU General Public License as
+dnl published by the Free Software Foundation, either version 3 of the
+dnl License, or (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl Under Section 7 of GPL version 3, you are granted additional
+dnl permissions described in the Autoconf Configure Script Exception,
+dnl version 3.0, as published by the Free Software Foundation.
+dnl
+dnl Because only two files in this source tree are released
+dnl under GPLv3 with exceptions, neither the GPLv3 nor the exception are
+dnl distributed with this source tree. Copies can be retrieved from
+dnl https://www.gnu.org/licenses/
+dnl
+dnl Autoconf core has no good way of enabling compiler warnings.
+dnl This is a cut-down version of the elaborate thing in the extras
+dnl archive, which we do not need nearly all of.
+dnl
+dnl Partly based on:
+dnl https://www.gnu.org/software/autoconf-archive/ax_compiler_flags_cflags.html
+
+AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
+
+AC_DEFUN([zw_SIMPLE_ENABLE_WARNINGS],
+[
+AC_ARG_ENABLE(
+ [werror],
+ AS_HELP_STRING(
+ [--disable-werror],
+ [do not treat all warnings as errors]
+ ),
+ [case "${enableval}" in
+ yes) warnings_are_errors=true ;;
+ no) warnings_are_errors=false ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for --enable-werror]) ;;
+ esac],
+ [warnings_are_errors=true]
+)
+
+ # Always pass -Werror=unknown-warning-option to get Clang to fail
+ # on bad flags, otherwise they are always appended to the
+ # warn_cflags variable, and Clang warns on them for every
+ # compilation unit. If this is passed to GCC, it will explode, so
+ # the flag must be enabled conditionally.
+ AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[
+ ax_compiler_flags_test="-Werror=unknown-warning-option"
+ ],[
+ ax_compiler_flags_test=""
+ ])
+
+ # Don't enable -pedantic if we don't have C11, or we may get junk
+ # warnings about static_assert.
+ ax_candidate_warnings="dnl
+ -Wall dnl
+ -Wextra dnl
+ -Walloc-zero dnl
+ -Walloca dnl
+ -Wbad-function-cast dnl
+ -Wcast-align dnl
+ -Wcast-qual dnl
+ -Wconversion dnl
+ -Wformat=2 dnl
+ -Wformat-overflow=2 dnl
+ -Wformat-signedness dnl
+ -Wformat-truncation=1 dnl
+ -Wlogical-op dnl
+ -Wmissing-declarations dnl
+ -Wmissing-prototypes dnl
+ -Wnested-externs dnl
+ -Wnull-dereference dnl
+ -Wold-style-definition dnl
+ -Wpointer-arith dnl
+ -Wrestrict dnl
+ -Wshadow dnl
+ -Wstrict-overflow=2 dnl
+ -Wstrict-prototypes dnl
+ -Wundef dnl
+ -Wvla dnl
+ -Wwrite-strings dnl
+ "
+ if test x$ac_prog_cc_stdc = xc11; then
+ ax_candidate_warnings="$ax_candidate_warnings -Wpedantic"
+ fi
+ if test x$warnings_are_errors = xtrue; then
+ ax_candidate_warnings="$ax_candidate_warnings -Werror"
+ fi
+
+ # If we are building for OSX, turn -Wdeprecated-declarations off.
+ # Apple is a little too trigger-happy with deprecations.
+ case "$host_os" in
+ (*darwin*)
+ ax_candidate_warnings="$ax_candidate_warnings -Wno-deprecated-declarations"
+ ;;
+ esac
+
+ AX_APPEND_COMPILE_FLAGS(
+ [$ax_candidate_warnings], [WARN_CFLAGS],
+ [$ax_compiler_flags_test])
+
+ AC_SUBST(WARN_CFLAGS)
+
+ if test $cross_compiling = yes; then
+ # Repeat the above logic for the build compiler.
+
+ save_cross_compiling=$cross_compiling
+ save_ac_tool_prefix=$ac_tool_prefix
+ save_CC="$CC"
+ save_CFLAGS="$CFLAGS"
+ save_CPPFLAGS="$CPPFLAGS"
+ save_LDFLAGS="$LDFLAGS"
+
+ cross_compiling=no
+ ac_tool_prefix=
+ CC="$CC_FOR_BUILD"
+ CFLAGS="$CFLAGS_FOR_BUILD"
+ CPPFLAGS="$CPPFLAGS_FOR_BUILD"
+ LDFLAGS="$LDFLAGS_FOR_BUILD"
+
+ pushdef([_AC_LANG_ABBREV],[build_c])
+
+ AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[
+ ax_compiler_flags_test="-Werror=unknown-warning-option"
+ ],[
+ ax_compiler_flags_test=""
+ ])
+ AX_APPEND_COMPILE_FLAGS(
+ [$ax_candidate_warnings], [WARN_CFLAGS_FOR_BUILD],
+ [$ax_compiler_flags_test])
+
+ popdef([_AC_LANG_ABBREV])
+
+ AC_SUBST(WARN_CFLAGS_FOR_BUILD)
+
+ cross_compiling=$save_cross_compiling
+ ac_tool_prefix=$save_ac_tool_prefix
+ CC="$save_CC"
+ CFLAGS="$save_CFLAGS"
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ fi # cross_compiling
+])
diff --git a/build-aux/zw_static_assert.m4 b/build-aux/zw_static_assert.m4
new file mode 100644
index 0000000..e33931a
--- /dev/null
+++ b/build-aux/zw_static_assert.m4
@@ -0,0 +1,68 @@
+dnl Written by Zack Weinberg <zackw at panix.com> in 2017.
+dnl To the extent possible under law, Zack Weinberg has waived all
+dnl copyright and related or neighboring rights to this work.
+dnl
+dnl See https://creativecommons.org/publicdomain/zero/1.0/ for further
+dnl details.
+dnl
+dnl Check for static_assert in <assert.h>; failing that, check for intrinsic
+dnl support for C11 _Static_assert.
+dnl assert.h itself is in C89 and does not need to be probed for;
+dnl moreover, AC_PROG_CC's check for C11 includes _Static_assert (but not
+dnl static_assert).
+dnl Some logic borrowed from gnulib's assert_h.m4.
+dnl 2*2 != 7 is tested in honor of Stanisław Lem.
+AC_DEFUN([zw_C_STATIC_ASSERT],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_CACHE_CHECK([for static_assert in assert.h],
+ [zw_cv_c_assert_h_static_assert],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #undef NDEBUG
+ #include <assert.h>
+ static_assert(2 + 2 == 4, "arithmetic does not work");
+ ]], [[
+ static_assert(sizeof (char) == 1, "sizeof does not work");
+ ]])],
+ [static_assert_true=yes],
+ [static_assert_true=no])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ #undef NDEBUG
+ #include <assert.h>
+ static_assert(2 * 2 == 7, "this assertion should fail");
+ ]])],
+ [static_assert_false=no],
+ [static_assert_false=yes])
+ AS_IF([test $static_assert_false$static_assert_true = yesyes],
+ [zw_cv_c_assert_h_static_assert=yes],
+ [zw_cv_c_assert_h_static_assert=no])])
+ AS_IF([test $zw_cv_c_assert_h_static_assert = yes],
+ [AC_DEFINE([HAVE_STATIC_ASSERT_IN_ASSERT_H], 1,
+ [Define if <assert.h> defines static_assert.])],
+ [AC_CACHE_CHECK([for _Static_assert],
+ [zw_cv_c__Static_assert],
+ [AS_IF([test x$ac_prog_cc_stdc = xc11],
+ [zw_cv_c__Static_assert=yes],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ _Static_assert(2 + 2 == 4, "arithmetic does not work");
+ ]], [[
+ _Static_assert(sizeof (char) == 1, "sizeof does not work");
+ ]])],
+ [_Static_assert_true=yes],
+ [_Static_assert_true=no])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ _Static_assert(2 * 2 == 7, "this assertion should fail");
+ ]])],
+ [_Static_assert_false=no],
+ [_Static_assert_false=yes])
+ AS_IF([test $static_assert_false$static_assert_true = yesyes],
+ [zw_cv_c__Static_assert=yes],
+ [zw_cv_c__Static_assert=no])])])
+ AS_IF([test $zw_cv_c__Static_assert = yes],
+ [AC_DEFINE([HAVE__STATIC_ASSERT], 1,
+ [Define if the compiler supports the _Static_assert intrinsic.])])
+ ])
+])