diff options
Diffstat (limited to 'configure')
| -rwxr-xr-x | configure | 2566 |
1 files changed, 2566 insertions, 0 deletions
diff --git a/configure b/configure new file mode 100755 index 0000000..8ae6a78 --- /dev/null +++ b/configure @@ -0,0 +1,2566 @@ +#! /bin/sh +# +# Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2017, 2018 Kristaps Dzonsons <kristaps@bsd.lv> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +OCONFIGURE_VERSION="0.3.13" + +# +# This script outputs two files: config.h and Makefile.configure. +# It tries to read from configure.local, which contains predefined +# values we won't autoconfigure. +# +# If you want to use configure with your project, have your GNUmakefile +# or BSDmakefile---whichever---try to import/include Makefile.configure +# at the beginning of the file. +# +# Like so (note no quotes, no period, etc.): +# +# include Makefile.configure +# +# If it exists, configure was run; otherwise, it wasn't. +# +# You'll probably want to change parts of this file. I've noted the +# parts that you'll probably change in the section documentation. +# +# See https://github.com/kristapsdz/oconfigure for more. + +set -e + +#---------------------------------------------------------------------- +# Prepare for running: move aside previous configure runs. +# Output file descriptor usage: +# 1 (stdout): config.h or Makefile.configure +# 2 (stderr): original stderr, usually to the console +# 3: config.log +# You DO NOT want to change this. +#---------------------------------------------------------------------- + +[ -w config.log ] && mv config.log config.log.old +[ -w config.h ] && mv config.h config.h.old + +exec 3> config.log +echo "config.log: writing..." + +# GNU submake prints different output if invoked recursively, which +# messes up CC and CFLAGS detection. Pass --no-print-directory if +# we have a MAKELEVEL (GNU and FreeBSD make) and the argument is +# allowed. + +MAKE_FLAGS="" + +if [ -n "${MAKELEVEL}" ]; then + if [ "${MAKELEVEL}" -gt 0 ] ; then + MAKE_FLAGS="--no-print-directory" + echo "all:" | make ${MAKE_FLAGS} -sf - 2>/dev/null || MAKE_FLAGS="" + fi +fi + +if [ -n "$MAKE_FLAGS" ]; then + echo "GNU submake detected: using --no-print-directory" 1>&2 + echo "GNU submake detected: using --no-print-directory" 1>&3 +fi + +#---------------------------------------------------------------------- +# Initialise all variables here such that nothing can leak in from the +# environment except for AR, CC and CFLAGS, which we might have passed +# in. +#---------------------------------------------------------------------- + +AR=`printf "all:\\n\\t@echo \\\$(AR)\\n" | make ${MAKE_FLAGS} -sf -` +CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make ${MAKE_FLAGS} -sf -` +CFLAGS=`printf "all:\\n\\t@echo \\\$(CFLAGS)\\n" | make ${MAKE_FLAGS} -sf -` +CFLAGS="${CFLAGS} -g -W -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes" +CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter" +LDLIBS= +LDADD= +LDADD_B64_NTOP= +LDADD_CRYPT= +LDADD_MD5= +LDADD_SHA2= +LDADD_LIB_SOCKET= +LDADD_SCAN_SCALED= +LDADD_STATIC= +CPPFLAGS= +LDFLAGS= +LINKER_SONAME= +DESTDIR= +PREFIX="/usr/local" +BINDIR= +SBINDIR= +INCLUDEDIR= +LIBDIR= +MANDIR= +SHAREDIR= +INSTALL="install" +INSTALL_PROGRAM= +INSTALL_LIB= +INSTALL_MAN= +INSTALL_DATA= + +# SunOS sets "cc", but this doesn't exist. +# It does have gcc, so try that instead. +# Prefer clang, though. + +command -v ${CC} 2>/dev/null 1>&2 || { + echo "${CC} not found: trying clang" 1>&2 + echo "${CC} not found: trying clang" 1>&3 + CC=clang + command -v ${CC} 2>/dev/null 1>&2 || { + echo "${CC} not found: trying gcc" 1>&2 + echo "${CC} not found: trying gcc" 1>&3 + CC=gcc + command -v ${CC} 2>/dev/null 1>&2 || { + echo "gcc not found: giving up" 1>&2 + echo "gcc not found: giving up" 1>&3 + exit 1 + } + } +} + +#---------------------------------------------------------------------- +# Allow certain variables to be overriden on the command line. +#---------------------------------------------------------------------- + +for keyvals in "$@" +do + key=`echo $keyvals | cut -s -d '=' -f 1` + if [ -z "$key" ] + then + echo "$0: invalid key-value: $keyvals" 1>&2 + exit 1 + fi + val=`echo $keyvals | cut -d '=' -f 2-` + case "$key" in + LDADD) + LDADD="$val" ;; + LDLIBS) + LDLIBS="$val" ;; + LDFLAGS) + LDFLAGS="$val" ;; + LINKER_SONAME) + LINKER_SONAME="$val" ;; + CPPFLAGS) + CPPFLAGS="$val" ;; + DESTDIR) + DESTDIR="$val" ;; + PREFIX) + PREFIX="$val" ;; + MANDIR) + MANDIR="$val" ;; + LIBDIR) + LIBDIR="$val" ;; + BINDIR) + BINDIR="$val" ;; + SHAREDIR) + SHAREDIR="$val" ;; + SBINDIR) + SBINDIR="$val" ;; + INCLUDEDIR) + INCLUDEDIR="$val" ;; + *) + echo "$0: invalid key: $key" 1>&2 + exit 1 + esac +done + +#---------------------------------------------------------------------- +# If the user doesn't specify whether we want "-soname" or +# "-install_name" for the linker option to generate shared libraries, +# try to figure it out here. If we can't figure it out, just set it to +# -soname and let the user figure it out. + +if [ -z "$LINKER_SONAME" ] +then + test_soname="`mktemp`" || { + echo "mktemp: failed" 1>&2 + echo "mktemp: failed" 1>&3 + exit 1 + } + echo "int foo(void) { return 1; }" > "${test_soname}.c" + ${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c || { + echo "${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c: failed" 1>&2 + echo "${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c: failed" 1>&3 + } + LINKER_SONAME="-soname" + echo "LINKER_SONAME: testing -soname" 1>&3 + ${CC} -shared -o ${test_soname}.so.0 ${test_soname}.o -Wl,${LINKER_SONAME},${test_soname}.so.0 || { + LINKER_SONAME="-install_name" + echo "LINKER_SONAME: testing -install_name" 1>&3 + ${CC} -shared -o ${test_soname}.so.0 ${test_soname}.o -Wl,-install_name,${test_soname}.so.0 || { + echo "LINKER_SONAME: cannot determine: default to -soname" 1>&2 + echo "LINKER_SONAME: cannot determine: default to -soname" 1>&3 + LINKER_SONAME="-soname" + } + } + echo "LINKER_SONAME: $LINKER_SONAME" 1>&3 + rm -f "$test_soname" "${test_soname}.*" +fi + +#---------------------------------------------------------------------- +# These are the values that will be pushed into config.h after we test +# for whether they're supported or not. +# Each of these must have a runtest(), below. +# Please sort by alpha, for clarity. +# You WANT to change this. +#---------------------------------------------------------------------- + +HAVE_ARC4RANDOM= +HAVE_B64_NTOP= +HAVE_CAPSICUM= +HAVE_CRYPT= +HAVE_CRYPT_NEWHASH= +HAVE_ENDIAN_H= +HAVE_ERR= +HAVE_EXPLICIT_BZERO= +HAVE_FTS= +HAVE_GETEXECNAME= +HAVE_GETPROGNAME= +HAVE_INFTIM= +HAVE_LANDLOCK= +HAVE_MD5= +HAVE_MEMMEM= +HAVE_MEMRCHR= +HAVE_MEMSET_S= +HAVE_MKFIFOAT= +HAVE_MKNODAT= +HAVE_OSBYTEORDER_H= +HAVE_PATH_MAX= +HAVE_PLEDGE= +HAVE_PROGRAM_INVOCATION_SHORT_NAME= +HAVE_READPASSPHRASE= +HAVE_REALLOCARRAY= +HAVE_RECALLOCARRAY= +HAVE_SANDBOX_INIT= +HAVE_SCAN_SCALED= +HAVE_SECCOMP_FILTER= +HAVE_SETRESGID= +HAVE_SETRESUID= +HAVE_SOCK_NONBLOCK= +HAVE_SHA2= +HAVE_SHA2_H= +HAVE_STRLCAT= +HAVE_STRLCPY= +HAVE_STRNDUP= +HAVE_STRNLEN= +HAVE_STRTONUM= +HAVE_SYS_BYTEORDER_H= +HAVE_SYS_ENDIAN_H= +HAVE_SYS_MKDEV_H= +HAVE_SYS_QUEUE= +HAVE_SYS_SYSMACROS= +HAVE_SYS_TREE= +HAVE_SYSTRACE=0 +HAVE_TERMIOS= +HAVE_UNVEIL= +HAVE_WAIT_ANY= +HAVE___PROGNAME= + +#---------------------------------------------------------------------- +# Allow configure.local to override all variables, default settings, +# command-line arguments, and tested features, above. +# You PROBABLY DO NOT want to change this. +#---------------------------------------------------------------------- + +if [ -r ./configure.local ]; then + echo "configure.local: reading..." 1>&2 + echo "configure.local: reading..." 1>&3 + cat ./configure.local 1>&3 + . ./configure.local +else + echo "configure.local: no (fully automatic configuration)" 1>&2 + echo "configure.local: no (fully automatic configuration)" 1>&3 +fi + +echo 1>&3 + +#---------------------------------------------------------------------- +# Infrastructure for running tests. +# These consists of a series of functions that will attempt to run the +# given test file and record its exit into a HAVE_xxx variable. +# You DO NOT want to change this. +#---------------------------------------------------------------------- + +COMP="${CC} ${CFLAGS} ${CPPFLAGS} -Wno-unused -Werror" + +# Check whether this HAVE_ setting is manually overridden. +# If yes, use the override, if no, do not decide anything yet. +# Arguments: lower-case test name, manual value + +ismanual() { + [ -z "${3}" ] && return 1 + echo "${1}: manual (HAVE_${2}=${3})" 1>&2 + echo "${1}: manual (HAVE_${2}=${3})" 1>&3 + echo 1>&3 + return 0 +} + +# Run a single autoconfiguration test. +# In case of success, enable the feature. +# In case of failure, do not decide anything yet. +# Arguments: lower-case test name, upper-case test name, additional +# CFLAGS, additional LIBS. + +singletest() { + extralib="" + cat 1>&3 << __HEREDOC__ +${1}: testing... +${COMP} -DTEST_${2} ${3} -o test-${1} tests.c ${LDFLAGS} ${4} +__HEREDOC__ + if ${COMP} -DTEST_${2} ${3} -o "test-${1}" tests.c ${LDFLAGS} ${4} 1>&3 2>&3; then + echo "${1}: ${CC} succeeded" 1>&3 + else + if [ -n "${5}" ] ; then + echo "${1}: ${CC} failed with $? (retrying)" 1>&3 + cat 1>&3 << __HEREDOC__ +${1}: testing... +${COMP} -DTEST_${2} ${3} -o test-${1} tests.c ${LDFLAGS} ${5} +__HEREDOC__ + if ${COMP} -DTEST_${2} ${3} -o "test-${1}" tests.c ${LDFLAGS} ${5} 1>&3 2>&3; then + echo "${1}: ${CC} succeeded" 1>&3 + extralib="(with ${5})" + else + echo "${1}: ${CC} failed with $?" 1>&3 + echo 1>&3 + return 1 + fi + else + echo "${1}: ${CC} failed with $?" 1>&3 + echo 1>&3 + return 1 + fi + fi + + if [ -n "${extralib}" ] + then + eval "LDADD_${2}=\"${5}\"" + elif [ -n "${4}" ] + then + eval "LDADD_${2}=\"${4}\"" + fi + + echo "${1}: yes ${extralib}" 1>&2 + echo "${1}: yes ${extralib}" 1>&3 + echo 1>&3 + eval HAVE_${2}=1 + rm "test-${1}" + return 0 +} + +# Run a complete autoconfiguration test, including the check for +# a manual override and disabling the feature on failure. +# Arguments: lower case name, upper case name, additional CFLAGS, +# additional LDADD, alternative LDADD. + +runtest() { + eval _manual=\${HAVE_${2}} + ismanual "${1}" "${2}" "${_manual}" && return 0 + singletest "${1}" "${2}" "${3}" "${4}" "${5}" && return 0 + echo "${1}: no" 1>&2 + eval HAVE_${2}=0 + return 1 +} + +#---------------------------------------------------------------------- +# Begin running the tests themselves. +# All of your tests must be defined here. +# Please sort as the HAVE_xxxx values were defined. +# You WANT to change this. +# It consists of the following columns: +# runtest +# (1) test file +# (2) macro to set +# (3) argument to cc *before* -o +# (4) argument to cc *after* +# (5) alternative argument to cc *after* +#---------------------------------------------------------------------- + +runtest arc4random ARC4RANDOM || true +runtest b64_ntop B64_NTOP "" "" "-lresolv" || true +runtest capsicum CAPSICUM || true +runtest crypt CRYPT "" "" "-lcrypt" || true +runtest crypt_newhash CRYPT_NEWHASH || true +runtest endian_h ENDIAN_H || true +runtest err ERR || true +runtest explicit_bzero EXPLICIT_BZERO || true +runtest fts FTS || true +runtest getexecname GETEXECNAME || true +runtest getprogname GETPROGNAME || true +runtest INFTIM INFTIM || true +runtest landlock LANDLOCK || true +runtest lib_socket LIB_SOCKET "" "" "-lsocket -lnsl" || true +runtest md5 MD5 "" "" "-lmd" || true +runtest memmem MEMMEM || true +runtest memrchr MEMRCHR || true +runtest memset_s MEMSET_S || true +runtest mkfifoat MKFIFOAT || true +runtest mknodat MKNODAT || true +runtest osbyteorder_h OSBYTEORDER_H || true +runtest PATH_MAX PATH_MAX || true +runtest pledge PLEDGE || true +runtest program_invocation_short_name PROGRAM_INVOCATION_SHORT_NAME || true +runtest readpassphrase READPASSPHRASE || true +runtest reallocarray REALLOCARRAY || true +runtest recallocarray RECALLOCARRAY || true +runtest sandbox_init SANDBOX_INIT "-Wno-deprecated" || true +runtest scan_scaled SCAN_SCALED "" "" "-lutil" || true +runtest seccomp-filter SECCOMP_FILTER || true +runtest setresgid SETRESGID || true +runtest setresuid SETRESUID || true +runtest sha2 SHA2 "" "" "-lmd" || true +runtest SOCK_NONBLOCK SOCK_NONBLOCK || true +runtest static STATIC "" "-static" || true +runtest strlcat STRLCAT || true +runtest strlcpy STRLCPY || true +runtest strndup STRNDUP || true +runtest strnlen STRNLEN || true +runtest strtonum STRTONUM || true +runtest sys_byteorder_h SYS_BYTEORDER_H || true +runtest sys_endian_h SYS_ENDIAN_H || true +runtest sys_mkdev_h SYS_MKDEV_H || true +runtest sys_sysmacros_h SYS_SYSMACROS_H || true +runtest sys_queue SYS_QUEUE || true +runtest sys_tree SYS_TREE || true +runtest termios TERMIOS || true +runtest unveil UNVEIL || true +runtest WAIT_ANY WAIT_ANY || true +runtest __progname __PROGNAME || true + +#---------------------------------------------------------------------- +# Output writing: generate the config.h file. +# This file contains all of the HAVE_xxxx variables necessary for +# compiling your source. +# You must include "config.h" BEFORE any other variables. +# You WANT to change this. +#---------------------------------------------------------------------- + +exec > config.h + +# Start with prologue. + +cat << __HEREDOC__ +#ifndef OCONFIGURE_CONFIG_H +#define OCONFIGURE_CONFIG_H + +#ifdef __cplusplus +# error "Do not use C++: this is a C application." +#endif +#if !defined(__GNUC__) || (__GNUC__ < 4) +# define __attribute__(x) +#endif +#if defined(__linux__) || defined(__MINT__) || defined(__wasi__) +# define _GNU_SOURCE /* memmem, memrchr, setresuid... */ +# define _DEFAULT_SOURCE /* le32toh, crypt, ... */ +#endif +#if defined(__NetBSD__) +# define _OPENBSD_SOURCE /* reallocarray, etc. */ +#endif +#if defined(__sun) +# ifndef _XOPEN_SOURCE /* SunOS already defines */ +# define _XOPEN_SOURCE /* XPGx */ +# endif +# define _XOPEN_SOURCE_EXTENDED 1 /* XPG4v2 */ +# ifndef __EXTENSIONS__ /* SunOS already defines */ +# define __EXTENSIONS__ /* reallocarray, etc. */ +# endif +#endif +#if !defined(__BEGIN_DECLS) +# define __BEGIN_DECLS +#endif +#if !defined(__END_DECLS) +# define __END_DECLS +#endif + +__HEREDOC__ + +# This is just for size_t, mode_t, and dev_t. +# Most of these functions, in the real world, pull in <string.h> or +# someting that pulls in support for size_t. +# Our function declarations are standalone, so specify them here. + +if [ ${HAVE_FTS} -eq 0 -o \ + ${HAVE_MD5} -eq 0 -o \ + ${HAVE_MEMMEM} -eq 0 -o \ + ${HAVE_MEMRCHR} -eq 0 -o \ + ${HAVE_MKFIFOAT} -eq 0 -o \ + ${HAVE_MKNODAT} -eq 0 -o \ + ${HAVE_READPASSPHRASE} -eq 0 -o \ + ${HAVE_REALLOCARRAY} -eq 0 -o \ + ${HAVE_RECALLOCARRAY} -eq 0 -o \ + ${HAVE_SETRESGID} -eq 0 -o \ + ${HAVE_SETRESUID} -eq 0 -o \ + ${HAVE_SHA2} -eq 0 -o \ + ${HAVE_STRLCAT} -eq 0 -o \ + ${HAVE_STRLCPY} -eq 0 -o \ + ${HAVE_STRNDUP} -eq 0 -o \ + ${HAVE_STRNLEN} -eq 0 ] +then + echo "#include <sys/types.h> /* size_t, mode_t, dev_t */ " + echo +fi + +if [ ${HAVE_MD5} -eq 0 -o \ + ${HAVE_SHA2} -eq 0 ] +then + echo "#include <stdint.h> /* C99 [u]int[nn]_t types */" + echo +fi + +if [ ${HAVE_ERR} -eq 0 ] +then + echo "#include <stdarg.h> /* err(3) */" + echo +fi + +# Now we handle our HAVE_xxxx values. +# Most will just be defined as 0 or 1. + +if [ ${HAVE_PATH_MAX} -eq 0 ] +then + echo "#define PATH_MAX 4096" + echo +fi + +if [ ${HAVE_WAIT_ANY} -eq 0 ] +then + echo "#define WAIT_ANY (-1) /* sys/wait.h */" + echo "#define WAIT_MYPGRP 0" + echo +fi + + +if [ ${HAVE_INFTIM} -eq 0 ] +then + echo "#define INFTIM (-1) /* poll.h */" + echo +fi + +cat << __HEREDOC__ +/* + * Results of configuration feature-testing. + */ +#define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM} +#define HAVE_B64_NTOP ${HAVE_B64_NTOP} +#define HAVE_CAPSICUM ${HAVE_CAPSICUM} +#define HAVE_CRYPT ${HAVE_CRYPT} +#define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH} +#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H} +#define HAVE_ERR ${HAVE_ERR} +#define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO} +#define HAVE_FTS ${HAVE_FTS} +#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME} +#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME} +#define HAVE_INFTIM ${HAVE_INFTIM} +#define HAVE_LANDLOCK ${HAVE_LANDLOCK} +#define HAVE_MD5 ${HAVE_MD5} +#define HAVE_MEMMEM ${HAVE_MEMMEM} +#define HAVE_MEMRCHR ${HAVE_MEMRCHR} +#define HAVE_MEMSET_S ${HAVE_MEMSET_S} +#define HAVE_MKFIFOAT ${HAVE_MKFIFOAT} +#define HAVE_MKNODAT ${HAVE_MKNODAT} +#define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H} +#define HAVE_PATH_MAX ${HAVE_PATH_MAX} +#define HAVE_PLEDGE ${HAVE_PLEDGE} +#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME} +#define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE} +#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY} +#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY} +#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT} +#define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED} +#define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER} +#define HAVE_SETRESGID ${HAVE_SETRESGID} +#define HAVE_SETRESUID ${HAVE_SETRESUID} +#define HAVE_SHA2 ${HAVE_SHA2} +#define HAVE_SHA2_H ${HAVE_SHA2} +#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK} +#define HAVE_STRLCAT ${HAVE_STRLCAT} +#define HAVE_STRLCPY ${HAVE_STRLCPY} +#define HAVE_STRNDUP ${HAVE_STRNDUP} +#define HAVE_STRNLEN ${HAVE_STRNLEN} +#define HAVE_STRTONUM ${HAVE_STRTONUM} +#define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H} +#define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H} +#define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H} +#define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE} +#define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H} +#define HAVE_SYS_TREE ${HAVE_SYS_TREE} +#define HAVE_SYSTRACE ${HAVE_SYSTRACE} +#define HAVE_UNVEIL ${HAVE_UNVEIL} +#define HAVE_TERMIOS ${HAVE_TERMIOS} +#define HAVE_WAIT_ANY ${HAVE_WAIT_ANY} +#define HAVE___PROGNAME ${HAVE___PROGNAME} + +__HEREDOC__ + +# Compat for libkern/OSByteOrder.h in place of endian.h. + +[ ${HAVE_OSBYTEORDER_H} -eq 1 -a \ + ${HAVE_ENDIAN_H} -eq 0 -a \ + ${HAVE_SYS_BYTEORDER_H} -eq 0 -a \ + ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ + && cat << __HEREDOC__ +/* + * endian.h compatibility with libkern/OSByteOrder.h. + */ +#define htobe16(x) OSSwapHostToBigInt16(x) +#define htole16(x) OSSwapHostToLittleInt16(x) +#define be16toh(x) OSSwapBigToHostInt16(x) +#define le16toh(x) OSSwapLittleToHostInt16(x) +#define htobe32(x) OSSwapHostToBigInt32(x) +#define htole32(x) OSSwapHostToLittleInt32(x) +#define be32toh(x) OSSwapBigToHostInt32(x) +#define le32toh(x) OSSwapLittleToHostInt32(x) +#define htobe64(x) OSSwapHostToBigInt64(x) +#define htole64(x) OSSwapHostToLittleInt64(x) +#define be64toh(x) OSSwapBigToHostInt64(x) +#define le64toh(x) OSSwapLittleToHostInt64(x) + +__HEREDOC__ + +[ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \ + ${HAVE_ENDIAN_H} -eq 0 -a \ + ${HAVE_OSBYTEORDER_H} -eq 0 -a \ + ${HAVE_SYS_ENDIAN_H} -eq 0 ] \ + && cat << __HEREDOC__ +/* + * endian.h compatibility with sys/byteorder.h. + */ +#define htobe16(x) BE_16(x) +#define htole16(x) LE_16(x) +#define be16toh(x) BE_16(x) +#define le16toh(x) LE_16(x) +#define htobe32(x) BE_32(x) +#define htole32(x) LE_32(x) +#define be32toh(x) BE_32(x) +#define le32toh(x) LE_32(x) +#define htobe64(x) BE_64(x) +#define htole64(x) LE_64(x) +#define be64toh(x) BE_64(x) +#define le64toh(x) LE_64(x) + +__HEREDOC__ + +# Make minor()/major()/makedev() easier to use. + +cat << __HEREDOC__ +/* + * Handle the various major()/minor() header files. + * Use sys/mkdev.h before sys/sysmacros.h because SunOS + * has both, where only the former works properly. + */ +#if HAVE_SYS_MKDEV_H +# define COMPAT_MAJOR_MINOR_H <sys/mkdev.h> +#elif HAVE_SYS_SYSMACROS_H +# define COMPAT_MAJOR_MINOR_H <sys/sysmacros.h> +#else +# define COMPAT_MAJOR_MINOR_H <sys/types.h> +#endif + +__HEREDOC__ + +# Make endian.h easier by providing a COMPAT_ENDIAN_H. + +cat << __HEREDOC__ +/* + * Make it easier to include endian.h forms. + */ +#if HAVE_ENDIAN_H +# define COMPAT_ENDIAN_H <endian.h> +#elif HAVE_SYS_ENDIAN_H +# define COMPAT_ENDIAN_H <sys/endian.h> +#elif HAVE_OSBYTEORDER_H +# define COMPAT_ENDIAN_H <libkern/OSByteOrder.h> +#elif HAVE_SYS_BYTEORDER_H +# define COMPAT_ENDIAN_H <sys/byteorder.h> +#else +# warning No suitable endian.h could be found. +# warning Please e-mail the maintainers with your OS. +# define COMPAT_ENDIAN_H <endian.h> +#endif + +__HEREDOC__ + +# Now we do our function declarations for missing functions. + +[ ${HAVE_ERR} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility functions for err(3). + */ +extern void err(int, const char *, ...) __attribute__((noreturn)); +extern void errc(int, int, const char *, ...) __attribute__((noreturn)); +extern void errx(int, const char *, ...) __attribute__((noreturn)); +extern void verr(int, const char *, va_list) __attribute__((noreturn)); +extern void verrc(int, int, const char *, va_list) __attribute__((noreturn)); +extern void verrx(int, const char *, va_list) __attribute__((noreturn)); +extern void warn(const char *, ...); +extern void warnx(const char *, ...); +extern void warnc(int, const char *, ...); +extern void vwarn(const char *, va_list); +extern void vwarnc(int, const char *, va_list); +extern void vwarnx(const char *, va_list); + +__HEREDOC__ + +[ ${HAVE_MD5} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for md4(3). + */ +#define MD5_BLOCK_LENGTH 64 +#define MD5_DIGEST_LENGTH 16 +#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1) + +typedef struct MD5Context { + uint32_t state[4]; + uint64_t count; + uint8_t buffer[MD5_BLOCK_LENGTH]; +} MD5_CTX; + +extern void MD5Init(MD5_CTX *); +extern void MD5Update(MD5_CTX *, const uint8_t *, size_t); +extern void MD5Pad(MD5_CTX *); +extern void MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH]); +extern char *MD5End(MD5_CTX *, char *); +extern void MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *); + +__HEREDOC__ + +[ ${HAVE_SHA2} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for sha2(3). + */ + +/*** SHA-256/384/512 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) +#define SHA384_BLOCK_LENGTH 128 +#define SHA384_DIGEST_LENGTH 48 +#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) +#define SHA512_BLOCK_LENGTH 128 +#define SHA512_DIGEST_LENGTH 64 +#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) +#define SHA512_256_BLOCK_LENGTH 128 +#define SHA512_256_DIGEST_LENGTH 32 +#define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1) + +/*** SHA-224/256/384/512 Context Structure *******************************/ +typedef struct _SHA2_CTX { + union { + uint32_t st32[8]; + uint64_t st64[8]; + } state; + uint64_t bitcount[2]; + uint8_t buffer[SHA512_BLOCK_LENGTH]; +} SHA2_CTX; + +void SHA256Init(SHA2_CTX *); +void SHA256Transform(uint32_t state[8], const uint8_t [SHA256_BLOCK_LENGTH]); +void SHA256Update(SHA2_CTX *, const uint8_t *, size_t); +void SHA256Pad(SHA2_CTX *); +void SHA256Final(uint8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *); +char *SHA256End(SHA2_CTX *, char *); +char *SHA256File(const char *, char *); +char *SHA256FileChunk(const char *, char *, off_t, off_t); +char *SHA256Data(const uint8_t *, size_t, char *); + +void SHA384Init(SHA2_CTX *); +void SHA384Transform(uint64_t state[8], const uint8_t [SHA384_BLOCK_LENGTH]); +void SHA384Update(SHA2_CTX *, const uint8_t *, size_t); +void SHA384Pad(SHA2_CTX *); +void SHA384Final(uint8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *); +char *SHA384End(SHA2_CTX *, char *); +char *SHA384File(const char *, char *); +char *SHA384FileChunk(const char *, char *, off_t, off_t); +char *SHA384Data(const uint8_t *, size_t, char *); + +void SHA512Init(SHA2_CTX *); +void SHA512Transform(uint64_t state[8], const uint8_t [SHA512_BLOCK_LENGTH]); +void SHA512Update(SHA2_CTX *, const uint8_t *, size_t); +void SHA512Pad(SHA2_CTX *); +void SHA512Final(uint8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *); +char *SHA512End(SHA2_CTX *, char *); +char *SHA512File(const char *, char *); +char *SHA512FileChunk(const char *, char *, off_t, off_t); +char *SHA512Data(const uint8_t *, size_t, char *); + +__HEREDOC__ + +if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then + seccomp_audit_arch= + arch=$(uname -m 2>/dev/null || echo unknown) + case "$arch" in + x86_64) + seccomp_audit_arch=AUDIT_ARCH_X86_64 + ;; + i*86) + seccomp_audit_arch=AUDIT_ARCH_I386 + ;; + arm*) + seccomp_audit_arch=AUDIT_ARCH_ARM + ;; + aarch64*) + seccomp_audit_arch=AUDIT_ARCH_AARCH64 + ;; + s390x) + seccomp_audit_arch=AUDIT_ARCH_S390X + ;; + s390) + seccomp_audit_arch=AUDIT_ARCH_S390 + ;; + ppc) + seccomp_audit_arch=AUDIT_ARCH_PPC + ;; + ppc64) + seccomp_audit_arch=AUDIT_ARCH_PPC64 + ;; + ppc64le) + seccomp_audit_arch=AUDIT_ARCH_PPC64LE + ;; + mips) + seccomp_audit_arch=AUDIT_ARCH_MIPS + ;; + mipsel) + seccomp_audit_arch=AUDIT_ARCH_MIPSEL + ;; + riscv64) + seccomp_audit_arch=AUDIT_ARCH_RISCV64 + ;; + esac + if [ -n "$seccomp_audit_arch" ] + then + echo "seccomp-arch: $seccomp_audit_arch" 1>&2 + cat << __HEREDOC__ +/* + * Seccomp is both available and has a recognised architecture. + */ +#define HAVE_SECCOMP_FILTER 1 +#define SECCOMP_AUDIT_ARCH $seccomp_audit_arch + +__HEREDOC__ + else + echo "seccomp-arch: disabling (unknown: `uname -m`)" 1>&2 + cat << __HEREDOC__ +/** + * Seccomp is available, but not with a recognised architecture. + * Please submit your architecture (via uname -m) to the oconfigure + * maintainers. + */ +#define HAVE_SECCOMP_FILTER 0 + +__HEREDOC__ + fi +else + cat << __HEREDOC__ +#define HAVE_SECCOMP_FILTER 0 + +__HEREDOC__ +fi + +[ ${HAVE_B64_NTOP} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for b64_ntop(3). + */ +extern int b64_ntop(unsigned char const *, size_t, char *, size_t); +extern int b64_pton(char const *, unsigned char *, size_t); + +__HEREDOC__ + +[ ${HAVE_SCAN_SCALED} -eq 0 ] && \ + cat << __HEREDOC__ +#define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */ +int fmt_scaled(long long, char *); +int scan_scaled(char *, long long *); +__HEREDOC__ + +[ ${HAVE_EXPLICIT_BZERO} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for explicit_bzero(3). + */ +extern void explicit_bzero(void *, size_t); + +__HEREDOC__ + +[ ${HAVE_MEMMEM} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for memmem(3). + */ +void *memmem(const void *, size_t, const void *, size_t); + +__HEREDOC__ + +[ ${HAVE_MEMRCHR} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for memrchr(3). + */ +void *memrchr(const void *b, int, size_t); + +__HEREDOC__ + +[ ${HAVE_GETPROGNAME} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for getprogname(3). + */ +extern const char *getprogname(void); + +__HEREDOC__ + +[ ${HAVE_READPASSPHRASE} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Macros and function required for readpassphrase(3). + */ +#define RPP_ECHO_OFF 0x00 +#define RPP_ECHO_ON 0x01 +#define RPP_REQUIRE_TTY 0x02 +#define RPP_FORCELOWER 0x04 +#define RPP_FORCEUPPER 0x08 +#define RPP_SEVENBIT 0x10 +#define RPP_STDIN 0x20 +char *readpassphrase(const char *, char *, size_t, int); + +__HEREDOC__ + +[ ${HAVE_REALLOCARRAY} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for reallocarray(3). + */ +extern void *reallocarray(void *, size_t, size_t); + +__HEREDOC__ + +[ ${HAVE_RECALLOCARRAY} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for recallocarray(3). + */ +extern void *recallocarray(void *, size_t, size_t, size_t); + +__HEREDOC__ + +[ ${HAVE_STRLCAT} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for strlcat(3). + */ +extern size_t strlcat(char *, const char *, size_t); + +__HEREDOC__ + +[ ${HAVE_STRLCPY} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for strlcpy(3). + */ +extern size_t strlcpy(char *, const char *, size_t); + +__HEREDOC__ + +[ ${HAVE_STRNDUP} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for strndup(3). + */ +extern char *strndup(const char *, size_t); + +__HEREDOC__ + +[ ${HAVE_STRNLEN} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for strnlen(3). + */ +extern size_t strnlen(const char *, size_t); + +__HEREDOC__ + +[ ${HAVE_STRTONUM} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for strotnum(3). + */ +extern long long strtonum(const char *, long long, long long, const char **); + +__HEREDOC__ + +[ ${HAVE_MKFIFOAT} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for mkfifoat(2). + */ +int mkfifoat(int, const char *, mode_t); + +__HEREDOC__ + +[ ${HAVE_MKNODAT} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for mknodat(2). + */ +int mknodat(int, const char *, mode_t, dev_t); + +__HEREDOC__ + +[ ${HAVE_SETRESGID} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for setresgid(2). + */ +int setresgid(gid_t rgid, gid_t egid, gid_t sgid); + +__HEREDOC__ + +[ ${HAVE_SETRESUID} -eq 0 ] && \ + cat << __HEREDOC__ +/* + * Compatibility for setresuid(2). + */ +int setresuid(uid_t ruid, uid_t euid, uid_t suid); + +__HEREDOC__ + +if [ ${HAVE_SYS_QUEUE} -eq 0 ]; then + cat << __HEREDOC__ +/* + * A compatible version of OpenBSD <sys/queue.h>. + */ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +/* OPENBSD ORIGINAL: sys/sys/queue.h */ + +/* + * Require for OS/X and other platforms that have old/broken/incomplete + * <sys/queue.h>. + */ + +#undef LIST_EMPTY +#undef LIST_END +#undef LIST_ENTRY +#undef LIST_FIRST +#undef LIST_FOREACH +#undef LIST_FOREACH_SAFE +#undef LIST_HEAD +#undef LIST_HEAD_INITIALIZER +#undef LIST_INIT +#undef LIST_INSERT_AFTER +#undef LIST_INSERT_BEFORE +#undef LIST_INSERT_HEAD +#undef LIST_NEXT +#undef LIST_REMOVE +#undef LIST_REPLACE +#undef SIMPLEQ_CONCAT +#undef SIMPLEQ_EMPTY +#undef SIMPLEQ_END +#undef SIMPLEQ_ENTRY +#undef SIMPLEQ_FIRST +#undef SIMPLEQ_FOREACH +#undef SIMPLEQ_FOREACH_SAFE +#undef SIMPLEQ_HEAD +#undef SIMPLEQ_HEAD_INITIALIZER +#undef SIMPLEQ_INIT +#undef SIMPLEQ_INSERT_AFTER +#undef SIMPLEQ_INSERT_HEAD +#undef SIMPLEQ_INSERT_TAIL +#undef SIMPLEQ_NEXT +#undef SIMPLEQ_REMOVE_AFTER +#undef SIMPLEQ_REMOVE_HEAD +#undef SLIST_EMPTY +#undef SLIST_END +#undef SLIST_ENTRY +#undef SLIST_FIRST +#undef SLIST_FOREACH +#undef SLIST_FOREACH_SAFE +#undef SLIST_HEAD +#undef SLIST_HEAD_INITIALIZER +#undef SLIST_INIT +#undef SLIST_INSERT_AFTER +#undef SLIST_INSERT_HEAD +#undef SLIST_NEXT +#undef SLIST_REMOVE +#undef SLIST_REMOVE_AFTER +#undef SLIST_REMOVE_HEAD +#undef TAILQ_CONCAT +#undef TAILQ_EMPTY +#undef TAILQ_END +#undef TAILQ_ENTRY +#undef TAILQ_FIRST +#undef TAILQ_FOREACH +#undef TAILQ_FOREACH_REVERSE +#undef TAILQ_FOREACH_REVERSE_SAFE +#undef TAILQ_FOREACH_SAFE +#undef TAILQ_HEAD +#undef TAILQ_HEAD_INITIALIZER +#undef TAILQ_INIT +#undef TAILQ_INSERT_AFTER +#undef TAILQ_INSERT_BEFORE +#undef TAILQ_INSERT_HEAD +#undef TAILQ_INSERT_TAIL +#undef TAILQ_LAST +#undef TAILQ_NEXT +#undef TAILQ_PREV +#undef TAILQ_REMOVE +#undef TAILQ_REPLACE +#undef XSIMPLEQ_EMPTY +#undef XSIMPLEQ_END +#undef XSIMPLEQ_ENTRY +#undef XSIMPLEQ_FIRST +#undef XSIMPLEQ_FOREACH +#undef XSIMPLEQ_FOREACH_SAFE +#undef XSIMPLEQ_HEAD +#undef XSIMPLEQ_INIT +#undef XSIMPLEQ_INSERT_AFTER +#undef XSIMPLEQ_INSERT_HEAD +#undef XSIMPLEQ_INSERT_TAIL +#undef XSIMPLEQ_NEXT +#undef XSIMPLEQ_REMOVE_AFTER +#undef XSIMPLEQ_REMOVE_HEAD +#undef XSIMPLEQ_XOR + +/* + * This file defines five types of data structures: singly-linked lists, + * lists, simple queues, tail queues and XOR simple queues. + * + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A simple queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are singly + * linked to save space, so elements can only be removed from the + * head of the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the + * list. A simple queue may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * An XOR simple queue is used in the same way as a regular simple queue. + * The difference is that the head structure also includes a "cookie" that + * is XOR'd with the queue pointer (first, last or next) to generate the + * real pointer value. + * + * For details on the use of these macros, see the queue(3) manual page. + */ + +#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC)) +#define _Q_INVALID ((void *)-1) +#define _Q_INVALIDATE(a) (a) = _Q_INVALID +#else +#define _Q_INVALIDATE(a) +#endif + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \\ +struct name { \\ + struct type *slh_first; /* first element */ \\ +} + +#define SLIST_HEAD_INITIALIZER(head) \\ + { NULL } + +#define SLIST_ENTRY(type) \\ +struct { \\ + struct type *sle_next; /* next element */ \\ +} + +/* + * Singly-linked List access methods. + */ +#define SLIST_FIRST(head) ((head)->slh_first) +#define SLIST_END(head) NULL +#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_FOREACH(var, head, field) \\ + for((var) = SLIST_FIRST(head); \\ + (var) != SLIST_END(head); \\ + (var) = SLIST_NEXT(var, field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \\ + for ((var) = SLIST_FIRST(head); \\ + (var) && ((tvar) = SLIST_NEXT(var, field), 1); \\ + (var) = (tvar)) + +/* + * Singly-linked List functions. + */ +#define SLIST_INIT(head) { \\ + SLIST_FIRST(head) = SLIST_END(head); \\ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \\ + (elm)->field.sle_next = (slistelm)->field.sle_next; \\ + (slistelm)->field.sle_next = (elm); \\ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \\ + (elm)->field.sle_next = (head)->slh_first; \\ + (head)->slh_first = (elm); \\ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \\ + (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \\ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \\ + (head)->slh_first = (head)->slh_first->field.sle_next; \\ +} while (0) + +#define SLIST_REMOVE(head, elm, type, field) do { \\ + if ((head)->slh_first == (elm)) { \\ + SLIST_REMOVE_HEAD((head), field); \\ + } else { \\ + struct type *curelm = (head)->slh_first; \\ + \\ + while (curelm->field.sle_next != (elm)) \\ + curelm = curelm->field.sle_next; \\ + curelm->field.sle_next = \\ + curelm->field.sle_next->field.sle_next; \\ + } \\ + _Q_INVALIDATE((elm)->field.sle_next); \\ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \\ +struct name { \\ + struct type *lh_first; /* first element */ \\ +} + +#define LIST_HEAD_INITIALIZER(head) \\ + { NULL } + +#define LIST_ENTRY(type) \\ +struct { \\ + struct type *le_next; /* next element */ \\ + struct type **le_prev; /* address of previous next element */ \\ +} + +/* + * List access methods. + */ +#define LIST_FIRST(head) ((head)->lh_first) +#define LIST_END(head) NULL +#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_FOREACH(var, head, field) \\ + for((var) = LIST_FIRST(head); \\ + (var)!= LIST_END(head); \\ + (var) = LIST_NEXT(var, field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \\ + for ((var) = LIST_FIRST(head); \\ + (var) && ((tvar) = LIST_NEXT(var, field), 1); \\ + (var) = (tvar)) + +/* + * List functions. + */ +#define LIST_INIT(head) do { \\ + LIST_FIRST(head) = LIST_END(head); \\ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \\ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \\ + (listelm)->field.le_next->field.le_prev = \\ + &(elm)->field.le_next; \\ + (listelm)->field.le_next = (elm); \\ + (elm)->field.le_prev = &(listelm)->field.le_next; \\ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \\ + (elm)->field.le_prev = (listelm)->field.le_prev; \\ + (elm)->field.le_next = (listelm); \\ + *(listelm)->field.le_prev = (elm); \\ + (listelm)->field.le_prev = &(elm)->field.le_next; \\ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \\ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \\ + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\\ + (head)->lh_first = (elm); \\ + (elm)->field.le_prev = &(head)->lh_first; \\ +} while (0) + +#define LIST_REMOVE(elm, field) do { \\ + if ((elm)->field.le_next != NULL) \\ + (elm)->field.le_next->field.le_prev = \\ + (elm)->field.le_prev; \\ + *(elm)->field.le_prev = (elm)->field.le_next; \\ + _Q_INVALIDATE((elm)->field.le_prev); \\ + _Q_INVALIDATE((elm)->field.le_next); \\ +} while (0) + +#define LIST_REPLACE(elm, elm2, field) do { \\ + if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \\ + (elm2)->field.le_next->field.le_prev = \\ + &(elm2)->field.le_next; \\ + (elm2)->field.le_prev = (elm)->field.le_prev; \\ + *(elm2)->field.le_prev = (elm2); \\ + _Q_INVALIDATE((elm)->field.le_prev); \\ + _Q_INVALIDATE((elm)->field.le_next); \\ +} while (0) + +/* + * Simple queue definitions. + */ +#define SIMPLEQ_HEAD(name, type) \\ +struct name { \\ + struct type *sqh_first; /* first element */ \\ + struct type **sqh_last; /* addr of last next element */ \\ +} + +#define SIMPLEQ_HEAD_INITIALIZER(head) \\ + { NULL, &(head).sqh_first } + +#define SIMPLEQ_ENTRY(type) \\ +struct { \\ + struct type *sqe_next; /* next element */ \\ +} + +/* + * Simple queue access methods. + */ +#define SIMPLEQ_FIRST(head) ((head)->sqh_first) +#define SIMPLEQ_END(head) NULL +#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) +#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) + +#define SIMPLEQ_FOREACH(var, head, field) \\ + for((var) = SIMPLEQ_FIRST(head); \\ + (var) != SIMPLEQ_END(head); \\ + (var) = SIMPLEQ_NEXT(var, field)) + +#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \\ + for ((var) = SIMPLEQ_FIRST(head); \\ + (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \\ + (var) = (tvar)) + +/* + * Simple queue functions. + */ +#define SIMPLEQ_INIT(head) do { \\ + (head)->sqh_first = NULL; \\ + (head)->sqh_last = &(head)->sqh_first; \\ +} while (0) + +#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \\ + if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \\ + (head)->sqh_last = &(elm)->field.sqe_next; \\ + (head)->sqh_first = (elm); \\ +} while (0) + +#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \\ + (elm)->field.sqe_next = NULL; \\ + *(head)->sqh_last = (elm); \\ + (head)->sqh_last = &(elm)->field.sqe_next; \\ +} while (0) + +#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \\ + if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\\ + (head)->sqh_last = &(elm)->field.sqe_next; \\ + (listelm)->field.sqe_next = (elm); \\ +} while (0) + +#define SIMPLEQ_REMOVE_HEAD(head, field) do { \\ + if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \\ + (head)->sqh_last = &(head)->sqh_first; \\ +} while (0) + +#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \\ + if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \\ + == NULL) \\ + (head)->sqh_last = &(elm)->field.sqe_next; \\ +} while (0) + +#define SIMPLEQ_CONCAT(head1, head2) do { \\ + if (!SIMPLEQ_EMPTY((head2))) { \\ + *(head1)->sqh_last = (head2)->sqh_first; \\ + (head1)->sqh_last = (head2)->sqh_last; \\ + SIMPLEQ_INIT((head2)); \\ + } \\ +} while (0) + +/* + * XOR Simple queue definitions. + */ +#define XSIMPLEQ_HEAD(name, type) \\ +struct name { \\ + struct type *sqx_first; /* first element */ \\ + struct type **sqx_last; /* addr of last next element */ \\ + unsigned long sqx_cookie; \\ +} + +#define XSIMPLEQ_ENTRY(type) \\ +struct { \\ + struct type *sqx_next; /* next element */ \\ +} + +/* + * XOR Simple queue access methods. + */ +#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \\ + (unsigned long)(ptr))) +#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first)) +#define XSIMPLEQ_END(head) NULL +#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head)) +#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next)) + + +#define XSIMPLEQ_FOREACH(var, head, field) \\ + for ((var) = XSIMPLEQ_FIRST(head); \\ + (var) != XSIMPLEQ_END(head); \\ + (var) = XSIMPLEQ_NEXT(head, var, field)) + +#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \\ + for ((var) = XSIMPLEQ_FIRST(head); \\ + (var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \\ + (var) = (tvar)) + +/* + * XOR Simple queue functions. + */ +#define XSIMPLEQ_INIT(head) do { \\ + arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \\ + (head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \\ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \\ +} while (0) + +#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \\ + if (((elm)->field.sqx_next = (head)->sqx_first) == \\ + XSIMPLEQ_XOR(head, NULL)) \\ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ + (head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \\ +} while (0) + +#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \\ + (elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \\ + *(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \\ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ +} while (0) + +#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \\ + if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \\ + XSIMPLEQ_XOR(head, NULL)) \\ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ + (listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \\ +} while (0) + +#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \\ + if (((head)->sqx_first = XSIMPLEQ_XOR(head, \\ + (head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \\ + (head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \\ +} while (0) + +#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \\ + if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \\ + (elm)->field.sqx_next)->field.sqx_next) \\ + == XSIMPLEQ_XOR(head, NULL)) \\ + (head)->sqx_last = \\ + XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\ +} while (0) + + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \\ +struct name { \\ + struct type *tqh_first; /* first element */ \\ + struct type **tqh_last; /* addr of last next element */ \\ +} + +#define TAILQ_HEAD_INITIALIZER(head) \\ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \\ +struct { \\ + struct type *tqe_next; /* next element */ \\ + struct type **tqe_prev; /* address of previous next element */ \\ +} + +/* + * Tail queue access methods. + */ +#define TAILQ_FIRST(head) ((head)->tqh_first) +#define TAILQ_END(head) NULL +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) +#define TAILQ_LAST(head, headname) \\ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) +/* XXX */ +#define TAILQ_PREV(elm, headname, field) \\ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) +#define TAILQ_EMPTY(head) \\ + (TAILQ_FIRST(head) == TAILQ_END(head)) + +#define TAILQ_FOREACH(var, head, field) \\ + for((var) = TAILQ_FIRST(head); \\ + (var) != TAILQ_END(head); \\ + (var) = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \\ + for ((var) = TAILQ_FIRST(head); \\ + (var) != TAILQ_END(head) && \\ + ((tvar) = TAILQ_NEXT(var, field), 1); \\ + (var) = (tvar)) + + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \\ + for((var) = TAILQ_LAST(head, headname); \\ + (var) != TAILQ_END(head); \\ + (var) = TAILQ_PREV(var, headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \\ + for ((var) = TAILQ_LAST(head, headname); \\ + (var) != TAILQ_END(head) && \\ + ((tvar) = TAILQ_PREV(var, headname, field), 1); \\ + (var) = (tvar)) + +/* + * Tail queue functions. + */ +#define TAILQ_INIT(head) do { \\ + (head)->tqh_first = NULL; \\ + (head)->tqh_last = &(head)->tqh_first; \\ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \\ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \\ + (head)->tqh_first->field.tqe_prev = \\ + &(elm)->field.tqe_next; \\ + else \\ + (head)->tqh_last = &(elm)->field.tqe_next; \\ + (head)->tqh_first = (elm); \\ + (elm)->field.tqe_prev = &(head)->tqh_first; \\ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \\ + (elm)->field.tqe_next = NULL; \\ + (elm)->field.tqe_prev = (head)->tqh_last; \\ + *(head)->tqh_last = (elm); \\ + (head)->tqh_last = &(elm)->field.tqe_next; \\ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \\ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\\ + (elm)->field.tqe_next->field.tqe_prev = \\ + &(elm)->field.tqe_next; \\ + else \\ + (head)->tqh_last = &(elm)->field.tqe_next; \\ + (listelm)->field.tqe_next = (elm); \\ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \\ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \\ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \\ + (elm)->field.tqe_next = (listelm); \\ + *(listelm)->field.tqe_prev = (elm); \\ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \\ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \\ + if (((elm)->field.tqe_next) != NULL) \\ + (elm)->field.tqe_next->field.tqe_prev = \\ + (elm)->field.tqe_prev; \\ + else \\ + (head)->tqh_last = (elm)->field.tqe_prev; \\ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \\ + _Q_INVALIDATE((elm)->field.tqe_prev); \\ + _Q_INVALIDATE((elm)->field.tqe_next); \\ +} while (0) + +#define TAILQ_REPLACE(head, elm, elm2, field) do { \\ + if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \\ + (elm2)->field.tqe_next->field.tqe_prev = \\ + &(elm2)->field.tqe_next; \\ + else \\ + (head)->tqh_last = &(elm2)->field.tqe_next; \\ + (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \\ + *(elm2)->field.tqe_prev = (elm2); \\ + _Q_INVALIDATE((elm)->field.tqe_prev); \\ + _Q_INVALIDATE((elm)->field.tqe_next); \\ +} while (0) + +#define TAILQ_CONCAT(head1, head2, field) do { \\ + if (!TAILQ_EMPTY(head2)) { \\ + *(head1)->tqh_last = (head2)->tqh_first; \\ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \\ + (head1)->tqh_last = (head2)->tqh_last; \\ + TAILQ_INIT((head2)); \\ + } \\ +} while (0) + +__HEREDOC__ +fi + +if [ ${HAVE_SYS_TREE} -eq 0 ]; then + cat << __HEREDOC__ +/* + * A compatible version of OpenBSD <sys/tree.h>. + */ +/* + * Copyright 2002 Niels Provos <provos@citi.umich.edu> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* OPENBSD ORIGINAL: sys/sys/tree.h */ + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \\ +struct name { \\ + struct type *sph_root; /* root of the tree */ \\ +} + +#define SPLAY_INITIALIZER(root) \\ + { NULL } + +#define SPLAY_INIT(root) do { \\ + (root)->sph_root = NULL; \\ +} while (0) + +#define SPLAY_ENTRY(type) \\ +struct { \\ + struct type *spe_left; /* left element */ \\ + struct type *spe_right; /* right element */ \\ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \\ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \\ + (head)->sph_root = tmp; \\ +} while (0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \\ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \\ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \\ + (head)->sph_root = tmp; \\ +} while (0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \\ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \\ + tmp = (head)->sph_root; \\ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \\ +} while (0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \\ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \\ + tmp = (head)->sph_root; \\ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \\ +} while (0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \\ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \\ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\\ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \\ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \\ +} while (0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \\ +void name##_SPLAY(struct name *, struct type *); \\ +void name##_SPLAY_MINMAX(struct name *, int); \\ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \\ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \\ + \\ +/* Finds the node with the same key as elm */ \\ +static __inline struct type * \\ +name##_SPLAY_FIND(struct name *head, struct type *elm) \\ +{ \\ + if (SPLAY_EMPTY(head)) \\ + return(NULL); \\ + name##_SPLAY(head, elm); \\ + if ((cmp)(elm, (head)->sph_root) == 0) \\ + return (head->sph_root); \\ + return (NULL); \\ +} \\ + \\ +static __inline struct type * \\ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \\ +{ \\ + name##_SPLAY(head, elm); \\ + if (SPLAY_RIGHT(elm, field) != NULL) { \\ + elm = SPLAY_RIGHT(elm, field); \\ + while (SPLAY_LEFT(elm, field) != NULL) { \\ + elm = SPLAY_LEFT(elm, field); \\ + } \\ + } else \\ + elm = NULL; \\ + return (elm); \\ +} \\ + \\ +static __inline struct type * \\ +name##_SPLAY_MIN_MAX(struct name *head, int val) \\ +{ \\ + name##_SPLAY_MINMAX(head, val); \\ + return (SPLAY_ROOT(head)); \\ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \\ +struct type * \\ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \\ +{ \\ + if (SPLAY_EMPTY(head)) { \\ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \\ + } else { \\ + int __comp; \\ + name##_SPLAY(head, elm); \\ + __comp = (cmp)(elm, (head)->sph_root); \\ + if(__comp < 0) { \\ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\\ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \\ + SPLAY_LEFT((head)->sph_root, field) = NULL; \\ + } else if (__comp > 0) { \\ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\\ + SPLAY_LEFT(elm, field) = (head)->sph_root; \\ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \\ + } else \\ + return ((head)->sph_root); \\ + } \\ + (head)->sph_root = (elm); \\ + return (NULL); \\ +} \\ + \\ +struct type * \\ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \\ +{ \\ + struct type *__tmp; \\ + if (SPLAY_EMPTY(head)) \\ + return (NULL); \\ + name##_SPLAY(head, elm); \\ + if ((cmp)(elm, (head)->sph_root) == 0) { \\ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \\ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\\ + } else { \\ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \\ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\\ + name##_SPLAY(head, elm); \\ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \\ + } \\ + return (elm); \\ + } \\ + return (NULL); \\ +} \\ + \\ +void \\ +name##_SPLAY(struct name *head, struct type *elm) \\ +{ \\ + struct type __node, *__left, *__right, *__tmp; \\ + int __comp; \\ +\\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\ + __left = __right = &__node; \\ +\\ + while ((__comp = (cmp)(elm, (head)->sph_root))) { \\ + if (__comp < 0) { \\ + __tmp = SPLAY_LEFT((head)->sph_root, field); \\ + if (__tmp == NULL) \\ + break; \\ + if ((cmp)(elm, __tmp) < 0){ \\ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \\ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\ + break; \\ + } \\ + SPLAY_LINKLEFT(head, __right, field); \\ + } else if (__comp > 0) { \\ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \\ + if (__tmp == NULL) \\ + break; \\ + if ((cmp)(elm, __tmp) > 0){ \\ + SPLAY_ROTATE_LEFT(head, __tmp, field); \\ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\ + break; \\ + } \\ + SPLAY_LINKRIGHT(head, __left, field); \\ + } \\ + } \\ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \\ +} \\ + \\ +/* Splay with either the minimum or the maximum element \\ + * Used to find minimum or maximum element in tree. \\ + */ \\ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \\ +{ \\ + struct type __node, *__left, *__right, *__tmp; \\ +\\ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\ + __left = __right = &__node; \\ +\\ + while (1) { \\ + if (__comp < 0) { \\ + __tmp = SPLAY_LEFT((head)->sph_root, field); \\ + if (__tmp == NULL) \\ + break; \\ + if (__comp < 0){ \\ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \\ + if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\ + break; \\ + } \\ + SPLAY_LINKLEFT(head, __right, field); \\ + } else if (__comp > 0) { \\ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \\ + if (__tmp == NULL) \\ + break; \\ + if (__comp > 0) { \\ + SPLAY_ROTATE_LEFT(head, __tmp, field); \\ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\ + break; \\ + } \\ + SPLAY_LINKRIGHT(head, __left, field); \\ + } \\ + } \\ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \\ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \\ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \\ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \\ + for ((x) = SPLAY_MIN(name, head); \\ + (x) != NULL; \\ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-black tree */ +#define RB_HEAD(name, type) \\ +struct name { \\ + struct type *rbh_root; /* root of the tree */ \\ +} + +#define RB_INITIALIZER(root) \\ + { NULL } + +#define RB_INIT(root) do { \\ + (root)->rbh_root = NULL; \\ +} while (0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \\ +struct { \\ + struct type *rbe_left; /* left element */ \\ + struct type *rbe_right; /* right element */ \\ + struct type *rbe_parent; /* parent element */ \\ + int rbe_color; /* node color */ \\ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \\ + RB_PARENT(elm, field) = parent; \\ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \\ + RB_COLOR(elm, field) = RB_RED; \\ +} while (0) + +#define RB_SET_BLACKRED(black, red, field) do { \\ + RB_COLOR(black, field) = RB_BLACK; \\ + RB_COLOR(red, field) = RB_RED; \\ +} while (0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) do {} while (0) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \\ + (tmp) = RB_RIGHT(elm, field); \\ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \\ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \\ + } \\ + RB_AUGMENT(elm); \\ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \\ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \\ + else \\ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\ + } else \\ + (head)->rbh_root = (tmp); \\ + RB_LEFT(tmp, field) = (elm); \\ + RB_PARENT(elm, field) = (tmp); \\ + RB_AUGMENT(tmp); \\ + if ((RB_PARENT(tmp, field))) \\ + RB_AUGMENT(RB_PARENT(tmp, field)); \\ +} while (0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \\ + (tmp) = RB_LEFT(elm, field); \\ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \\ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \\ + } \\ + RB_AUGMENT(elm); \\ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \\ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \\ + else \\ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\ + } else \\ + (head)->rbh_root = (tmp); \\ + RB_RIGHT(tmp, field) = (elm); \\ + RB_PARENT(elm, field) = (tmp); \\ + RB_AUGMENT(tmp); \\ + if ((RB_PARENT(tmp, field))) \\ + RB_AUGMENT(RB_PARENT(tmp, field)); \\ +} while (0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \\ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \\ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \\ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \\ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \\ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \\ +attr struct type *name##_RB_FIND(struct name *, struct type *); \\ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \\ +attr struct type *name##_RB_NEXT(struct type *); \\ +attr struct type *name##_RB_PREV(struct type *); \\ +attr struct type *name##_RB_MINMAX(struct name *, int); \\ + \\ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \\ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \\ + RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \\ +attr void \\ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \\ +{ \\ + struct type *parent, *gparent, *tmp; \\ + while ((parent = RB_PARENT(elm, field)) && \\ + RB_COLOR(parent, field) == RB_RED) { \\ + gparent = RB_PARENT(parent, field); \\ + if (parent == RB_LEFT(gparent, field)) { \\ + tmp = RB_RIGHT(gparent, field); \\ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \\ + RB_COLOR(tmp, field) = RB_BLACK; \\ + RB_SET_BLACKRED(parent, gparent, field);\\ + elm = gparent; \\ + continue; \\ + } \\ + if (RB_RIGHT(parent, field) == elm) { \\ + RB_ROTATE_LEFT(head, parent, tmp, field);\\ + tmp = parent; \\ + parent = elm; \\ + elm = tmp; \\ + } \\ + RB_SET_BLACKRED(parent, gparent, field); \\ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \\ + } else { \\ + tmp = RB_LEFT(gparent, field); \\ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \\ + RB_COLOR(tmp, field) = RB_BLACK; \\ + RB_SET_BLACKRED(parent, gparent, field);\\ + elm = gparent; \\ + continue; \\ + } \\ + if (RB_LEFT(parent, field) == elm) { \\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\\ + tmp = parent; \\ + parent = elm; \\ + elm = tmp; \\ + } \\ + RB_SET_BLACKRED(parent, gparent, field); \\ + RB_ROTATE_LEFT(head, gparent, tmp, field); \\ + } \\ + } \\ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \\ +} \\ + \\ +attr void \\ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \\ +{ \\ + struct type *tmp; \\ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \\ + elm != RB_ROOT(head)) { \\ + if (RB_LEFT(parent, field) == elm) { \\ + tmp = RB_RIGHT(parent, field); \\ + if (RB_COLOR(tmp, field) == RB_RED) { \\ + RB_SET_BLACKRED(tmp, parent, field); \\ + RB_ROTATE_LEFT(head, parent, tmp, field);\\ + tmp = RB_RIGHT(parent, field); \\ + } \\ + if ((RB_LEFT(tmp, field) == NULL || \\ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\ + (RB_RIGHT(tmp, field) == NULL || \\ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\ + RB_COLOR(tmp, field) = RB_RED; \\ + elm = parent; \\ + parent = RB_PARENT(elm, field); \\ + } else { \\ + if (RB_RIGHT(tmp, field) == NULL || \\ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\\ + struct type *oleft; \\ + if ((oleft = RB_LEFT(tmp, field)))\\ + RB_COLOR(oleft, field) = RB_BLACK;\\ + RB_COLOR(tmp, field) = RB_RED; \\ + RB_ROTATE_RIGHT(head, tmp, oleft, field);\\ + tmp = RB_RIGHT(parent, field); \\ + } \\ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\ + RB_COLOR(parent, field) = RB_BLACK; \\ + if (RB_RIGHT(tmp, field)) \\ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\\ + RB_ROTATE_LEFT(head, parent, tmp, field);\\ + elm = RB_ROOT(head); \\ + break; \\ + } \\ + } else { \\ + tmp = RB_LEFT(parent, field); \\ + if (RB_COLOR(tmp, field) == RB_RED) { \\ + RB_SET_BLACKRED(tmp, parent, field); \\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\\ + tmp = RB_LEFT(parent, field); \\ + } \\ + if ((RB_LEFT(tmp, field) == NULL || \\ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\ + (RB_RIGHT(tmp, field) == NULL || \\ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\ + RB_COLOR(tmp, field) = RB_RED; \\ + elm = parent; \\ + parent = RB_PARENT(elm, field); \\ + } else { \\ + if (RB_LEFT(tmp, field) == NULL || \\ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\\ + struct type *oright; \\ + if ((oright = RB_RIGHT(tmp, field)))\\ + RB_COLOR(oright, field) = RB_BLACK;\\ + RB_COLOR(tmp, field) = RB_RED; \\ + RB_ROTATE_LEFT(head, tmp, oright, field);\\ + tmp = RB_LEFT(parent, field); \\ + } \\ + RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\ + RB_COLOR(parent, field) = RB_BLACK; \\ + if (RB_LEFT(tmp, field)) \\ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\\ + RB_ROTATE_RIGHT(head, parent, tmp, field);\\ + elm = RB_ROOT(head); \\ + break; \\ + } \\ + } \\ + } \\ + if (elm) \\ + RB_COLOR(elm, field) = RB_BLACK; \\ +} \\ + \\ +attr struct type * \\ +name##_RB_REMOVE(struct name *head, struct type *elm) \\ +{ \\ + struct type *child, *parent, *old = elm; \\ + int color; \\ + if (RB_LEFT(elm, field) == NULL) \\ + child = RB_RIGHT(elm, field); \\ + else if (RB_RIGHT(elm, field) == NULL) \\ + child = RB_LEFT(elm, field); \\ + else { \\ + struct type *left; \\ + elm = RB_RIGHT(elm, field); \\ + while ((left = RB_LEFT(elm, field))) \\ + elm = left; \\ + child = RB_RIGHT(elm, field); \\ + parent = RB_PARENT(elm, field); \\ + color = RB_COLOR(elm, field); \\ + if (child) \\ + RB_PARENT(child, field) = parent; \\ + if (parent) { \\ + if (RB_LEFT(parent, field) == elm) \\ + RB_LEFT(parent, field) = child; \\ + else \\ + RB_RIGHT(parent, field) = child; \\ + RB_AUGMENT(parent); \\ + } else \\ + RB_ROOT(head) = child; \\ + if (RB_PARENT(elm, field) == old) \\ + parent = elm; \\ + (elm)->field = (old)->field; \\ + if (RB_PARENT(old, field)) { \\ + if (RB_LEFT(RB_PARENT(old, field), field) == old)\\ + RB_LEFT(RB_PARENT(old, field), field) = elm;\\ + else \\ + RB_RIGHT(RB_PARENT(old, field), field) = elm;\\ + RB_AUGMENT(RB_PARENT(old, field)); \\ + } else \\ + RB_ROOT(head) = elm; \\ + RB_PARENT(RB_LEFT(old, field), field) = elm; \\ + if (RB_RIGHT(old, field)) \\ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \\ + if (parent) { \\ + left = parent; \\ + do { \\ + RB_AUGMENT(left); \\ + } while ((left = RB_PARENT(left, field))); \\ + } \\ + goto color; \\ + } \\ + parent = RB_PARENT(elm, field); \\ + color = RB_COLOR(elm, field); \\ + if (child) \\ + RB_PARENT(child, field) = parent; \\ + if (parent) { \\ + if (RB_LEFT(parent, field) == elm) \\ + RB_LEFT(parent, field) = child; \\ + else \\ + RB_RIGHT(parent, field) = child; \\ + RB_AUGMENT(parent); \\ + } else \\ + RB_ROOT(head) = child; \\ +color: \\ + if (color == RB_BLACK) \\ + name##_RB_REMOVE_COLOR(head, parent, child); \\ + return (old); \\ +} \\ + \\ +/* Inserts a node into the RB tree */ \\ +attr struct type * \\ +name##_RB_INSERT(struct name *head, struct type *elm) \\ +{ \\ + struct type *tmp; \\ + struct type *parent = NULL; \\ + int comp = 0; \\ + tmp = RB_ROOT(head); \\ + while (tmp) { \\ + parent = tmp; \\ + comp = (cmp)(elm, parent); \\ + if (comp < 0) \\ + tmp = RB_LEFT(tmp, field); \\ + else if (comp > 0) \\ + tmp = RB_RIGHT(tmp, field); \\ + else \\ + return (tmp); \\ + } \\ + RB_SET(elm, parent, field); \\ + if (parent != NULL) { \\ + if (comp < 0) \\ + RB_LEFT(parent, field) = elm; \\ + else \\ + RB_RIGHT(parent, field) = elm; \\ + RB_AUGMENT(parent); \\ + } else \\ + RB_ROOT(head) = elm; \\ + name##_RB_INSERT_COLOR(head, elm); \\ + return (NULL); \\ +} \\ + \\ +/* Finds the node with the same key as elm */ \\ +attr struct type * \\ +name##_RB_FIND(struct name *head, struct type *elm) \\ +{ \\ + struct type *tmp = RB_ROOT(head); \\ + int comp; \\ + while (tmp) { \\ + comp = cmp(elm, tmp); \\ + if (comp < 0) \\ + tmp = RB_LEFT(tmp, field); \\ + else if (comp > 0) \\ + tmp = RB_RIGHT(tmp, field); \\ + else \\ + return (tmp); \\ + } \\ + return (NULL); \\ +} \\ + \\ +/* Finds the first node greater than or equal to the search key */ \\ +attr struct type * \\ +name##_RB_NFIND(struct name *head, struct type *elm) \\ +{ \\ + struct type *tmp = RB_ROOT(head); \\ + struct type *res = NULL; \\ + int comp; \\ + while (tmp) { \\ + comp = cmp(elm, tmp); \\ + if (comp < 0) { \\ + res = tmp; \\ + tmp = RB_LEFT(tmp, field); \\ + } \\ + else if (comp > 0) \\ + tmp = RB_RIGHT(tmp, field); \\ + else \\ + return (tmp); \\ + } \\ + return (res); \\ +} \\ + \\ +/* ARGSUSED */ \\ +attr struct type * \\ +name##_RB_NEXT(struct type *elm) \\ +{ \\ + if (RB_RIGHT(elm, field)) { \\ + elm = RB_RIGHT(elm, field); \\ + while (RB_LEFT(elm, field)) \\ + elm = RB_LEFT(elm, field); \\ + } else { \\ + if (RB_PARENT(elm, field) && \\ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \\ + elm = RB_PARENT(elm, field); \\ + else { \\ + while (RB_PARENT(elm, field) && \\ + (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\\ + elm = RB_PARENT(elm, field); \\ + elm = RB_PARENT(elm, field); \\ + } \\ + } \\ + return (elm); \\ +} \\ + \\ +/* ARGSUSED */ \\ +attr struct type * \\ +name##_RB_PREV(struct type *elm) \\ +{ \\ + if (RB_LEFT(elm, field)) { \\ + elm = RB_LEFT(elm, field); \\ + while (RB_RIGHT(elm, field)) \\ + elm = RB_RIGHT(elm, field); \\ + } else { \\ + if (RB_PARENT(elm, field) && \\ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \\ + elm = RB_PARENT(elm, field); \\ + else { \\ + while (RB_PARENT(elm, field) && \\ + (elm == RB_LEFT(RB_PARENT(elm, field), field)))\\ + elm = RB_PARENT(elm, field); \\ + elm = RB_PARENT(elm, field); \\ + } \\ + } \\ + return (elm); \\ +} \\ + \\ +attr struct type * \\ +name##_RB_MINMAX(struct name *head, int val) \\ +{ \\ + struct type *tmp = RB_ROOT(head); \\ + struct type *parent = NULL; \\ + while (tmp) { \\ + parent = tmp; \\ + if (val < 0) \\ + tmp = RB_LEFT(tmp, field); \\ + else \\ + tmp = RB_RIGHT(tmp, field); \\ + } \\ + return (parent); \\ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \\ + for ((x) = RB_MIN(name, head); \\ + (x) != NULL; \\ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_SAFE(x, name, head, y) \\ + for ((x) = RB_MIN(name, head); \\ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \\ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \\ + for ((x) = RB_MAX(name, head); \\ + (x) != NULL; \\ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \\ + for ((x) = RB_MAX(name, head); \\ + ((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \\ + (x) = (y)) + +__HEREDOC__ +fi + +if [ ${HAVE_FTS} -eq 0 ]; then + cat << __HEREDOC__ +/* + * Compatibility for fts(3) functions. + */ +typedef struct { + struct _ftsent *fts_cur; /* current node */ + struct _ftsent *fts_child; /* linked list of children */ + struct _ftsent **fts_array; /* sort array */ + dev_t fts_dev; /* starting device # */ + char *fts_path; /* path for this descent */ + int fts_rfd; /* fd for root */ + size_t fts_pathlen; /* sizeof(path) */ + int fts_nitems; /* elements in the sort array */ + int (*fts_compar)(const struct _ftsent **, const struct _ftsent **); /* compare function */ +#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */ +#define FTS_LOGICAL 0x0002 /* logical walk */ +#define FTS_NOCHDIR 0x0004 /* don't change directories */ +#define FTS_NOSTAT 0x0008 /* don't get stat info */ +#define FTS_PHYSICAL 0x0010 /* physical walk */ +#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */ +#define FTS_XDEV 0x0040 /* don't cross devices */ +#define FTS_OPTIONMASK 0x00ff /* valid user option mask */ +#define FTS_NAMEONLY 0x1000 /* (private) child names only */ +#define FTS_STOP 0x2000 /* (private) unrecoverable error */ + int fts_options; /* fts_open options, global flags */ +} FTS; + +typedef struct _ftsent { + struct _ftsent *fts_cycle; /* cycle node */ + struct _ftsent *fts_parent; /* parent directory */ + struct _ftsent *fts_link; /* next file in directory */ + long fts_number; /* local numeric value */ + void *fts_pointer; /* local address value */ + char *fts_accpath; /* access path */ + char *fts_path; /* root path */ + int fts_errno; /* errno for this node */ + int fts_symfd; /* fd for symlink */ + size_t fts_pathlen; /* strlen(fts_path) */ + size_t fts_namelen; /* strlen(fts_name) */ + ino_t fts_ino; /* inode */ + dev_t fts_dev; /* device */ + nlink_t fts_nlink; /* link count */ +#define FTS_ROOTPARENTLEVEL -1 +#define FTS_ROOTLEVEL 0 +#define FTS_MAXLEVEL 0x7fffffff + int fts_level; /* depth (-1 to N) */ +#define FTS_D 1 /* preorder directory */ +#define FTS_DC 2 /* directory that causes cycles */ +#define FTS_DEFAULT 3 /* none of the above */ +#define FTS_DNR 4 /* unreadable directory */ +#define FTS_DOT 5 /* dot or dot-dot */ +#define FTS_DP 6 /* postorder directory */ +#define FTS_ERR 7 /* error; errno is set */ +#define FTS_F 8 /* regular file */ +#define FTS_INIT 9 /* initialized only */ +#define FTS_NS 10 /* stat(2) failed */ +#define FTS_NSOK 11 /* no stat(2) requested */ +#define FTS_SL 12 /* symbolic link */ +#define FTS_SLNONE 13 /* symbolic link without target */ + unsigned short fts_info; /* user flags for FTSENT structure */ +#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */ +#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */ + unsigned short fts_flags; /* private flags for FTSENT structure */ +#define FTS_AGAIN 1 /* read node again */ +#define FTS_FOLLOW 2 /* follow symbolic link */ +#define FTS_NOINSTR 3 /* no instructions */ +#define FTS_SKIP 4 /* discard node */ + unsigned short fts_instr; /* fts_set() instructions */ + unsigned short fts_spare; /* unused */ + struct stat *fts_statp; /* stat(2) information */ + char fts_name[1]; /* file name */ +} FTSENT; + +FTSENT *fts_children(FTS *, int); +int fts_close(FTS *); +FTS *fts_open(char * const *, int, + int (*)(const FTSENT **, const FTSENT **)); +FTSENT *fts_read(FTS *); +int fts_set(FTS *, FTSENT *, int); + +__HEREDOC__ +fi + +cat << __HEREDOC__ +#endif /*!OCONFIGURE_CONFIG_H*/ +__HEREDOC__ + +echo "config.h: written" 1>&2 +echo "config.h: written" 1>&3 + +#---------------------------------------------------------------------- +# Now we go to generate our Makefile.configure. +# This file is simply a bunch of Makefile variables. +# They'll work in both GNUmakefile and BSDmakefile. +# You MIGHT want to change this. +#---------------------------------------------------------------------- + +exec > Makefile.configure + +[ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin" +[ -z "${SBINDIR}" ] && SBINDIR="${PREFIX}/sbin" +[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include" +[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib" +[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man" +[ -z "${SHAREDIR}" ] && SHAREDIR="${PREFIX}/share" + +[ -z "${INSTALL_PROGRAM}" ] && INSTALL_PROGRAM="${INSTALL} -m 0555" +[ -z "${INSTALL_LIB}" ] && INSTALL_LIB="${INSTALL} -m 0444" +[ -z "${INSTALL_MAN}" ] && INSTALL_MAN="${INSTALL} -m 0444" +[ -z "${INSTALL_DATA}" ] && INSTALL_DATA="${INSTALL} -m 0444" + +cat << __HEREDOC__ +AR = ${AR} +CC = ${CC} +CFLAGS = ${CFLAGS} +CPPFLAGS = ${CPPFLAGS} +LDLIBS = ${LDLIBS} +LDADD = ${LDADD} +LDADD_B64_NTOP = ${LDADD_B64_NTOP} +LDADD_CRYPT = ${LDADD_CRYPT} +LDADD_LIB_SOCKET = ${LDADD_LIB_SOCKET} +LDADD_MD5 = ${LDADD_MD5} +LDADD_SHA2 = ${LDADD_SHA2} +LDADD_SCAN_SCALED= ${LDADD_SCAN_SCALED} +LDADD_STATIC = ${LDADD_STATIC} +LDFLAGS = ${LDFLAGS} +LINKER_SONAME = ${LINKER_SONAME} +STATIC = ${STATIC} +PREFIX = ${PREFIX} +BINDIR = ${BINDIR} +SHAREDIR = ${SHAREDIR} +SBINDIR = ${SBINDIR} +INCLUDEDIR = ${INCLUDEDIR} +LIBDIR = ${LIBDIR} +MANDIR = ${MANDIR} +INSTALL = ${INSTALL} +INSTALL_PROGRAM = ${INSTALL_PROGRAM} +INSTALL_LIB = ${INSTALL_LIB} +INSTALL_MAN = ${INSTALL_MAN} +INSTALL_DATA = ${INSTALL_DATA} +__HEREDOC__ + +echo "Makefile.configure: written" 1>&2 +echo "Makefile.configure: written" 1>&3 + +exit 0 |
