ksgi
/
configure
2566 строк · 78.6 Кб
1#! /bin/sh
2#
3# Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org>
4# Copyright (c) 2017, 2018 Kristaps Dzonsons <kristaps@bsd.lv>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18OCONFIGURE_VERSION="0.3.13"19
20#
21# This script outputs two files: config.h and Makefile.configure.
22# It tries to read from configure.local, which contains predefined
23# values we won't autoconfigure.
24#
25# If you want to use configure with your project, have your GNUmakefile
26# or BSDmakefile---whichever---try to import/include Makefile.configure
27# at the beginning of the file.
28#
29# Like so (note no quotes, no period, etc.):
30#
31# include Makefile.configure
32#
33# If it exists, configure was run; otherwise, it wasn't.
34#
35# You'll probably want to change parts of this file. I've noted the
36# parts that you'll probably change in the section documentation.
37#
38# See https://github.com/kristapsdz/oconfigure for more.
39
40set -e41
42#----------------------------------------------------------------------
43# Prepare for running: move aside previous configure runs.
44# Output file descriptor usage:
45# 1 (stdout): config.h or Makefile.configure
46# 2 (stderr): original stderr, usually to the console
47# 3: config.log
48# You DO NOT want to change this.
49#----------------------------------------------------------------------
50
51[ -w config.log ] && mv config.log config.log.old52[ -w config.h ] && mv config.h config.h.old53
54exec 3> config.log55echo "config.log: writing..."56
57# GNU submake prints different output if invoked recursively, which
58# messes up CC and CFLAGS detection. Pass --no-print-directory if
59# we have a MAKELEVEL (GNU and FreeBSD make) and the argument is
60# allowed.
61
62MAKE_FLAGS=""63
64if [ -n "${MAKELEVEL}" ]; then65if [ "${MAKELEVEL}" -gt 0 ] ; then66MAKE_FLAGS="--no-print-directory"67echo "all:" | make ${MAKE_FLAGS} -sf - 2>/dev/null || MAKE_FLAGS=""68fi69fi
70
71if [ -n "$MAKE_FLAGS" ]; then72echo "GNU submake detected: using --no-print-directory" 1>&273echo "GNU submake detected: using --no-print-directory" 1>&374fi
75
76#----------------------------------------------------------------------
77# Initialise all variables here such that nothing can leak in from the
78# environment except for AR, CC and CFLAGS, which we might have passed
79# in.
80#----------------------------------------------------------------------
81
82AR=`printf "all:\\n\\t@echo \\\$(AR)\\n" | make ${MAKE_FLAGS} -sf -`83CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | make ${MAKE_FLAGS} -sf -`84CFLAGS=`printf "all:\\n\\t@echo \\\$(CFLAGS)\\n" | make ${MAKE_FLAGS} -sf -`85CFLAGS="${CFLAGS} -g -W -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes"86CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter"87LDLIBS=88LDADD=89LDADD_B64_NTOP=90LDADD_CRYPT=91LDADD_MD5=92LDADD_SHA2=93LDADD_LIB_SOCKET=94LDADD_SCAN_SCALED=95LDADD_STATIC=96CPPFLAGS=97LDFLAGS=98LINKER_SONAME=99DESTDIR=100PREFIX="/usr/local"101BINDIR=102SBINDIR=103INCLUDEDIR=104LIBDIR=105MANDIR=106SHAREDIR=107INSTALL="install"108INSTALL_PROGRAM=109INSTALL_LIB=110INSTALL_MAN=111INSTALL_DATA=112
113# SunOS sets "cc", but this doesn't exist.
114# It does have gcc, so try that instead.
115# Prefer clang, though.
116
117command -v ${CC} 2>/dev/null 1>&2 || {118echo "${CC} not found: trying clang" 1>&2119echo "${CC} not found: trying clang" 1>&3120CC=clang121command -v ${CC} 2>/dev/null 1>&2 || {122echo "${CC} not found: trying gcc" 1>&2123echo "${CC} not found: trying gcc" 1>&3124CC=gcc125command -v ${CC} 2>/dev/null 1>&2 || {126echo "gcc not found: giving up" 1>&2127echo "gcc not found: giving up" 1>&3128exit 1129}130}131}
132
133#----------------------------------------------------------------------
134# Allow certain variables to be overriden on the command line.
135#----------------------------------------------------------------------
136
137for keyvals in "$@"138do
139key=`echo $keyvals | cut -s -d '=' -f 1`140if [ -z "$key" ]141then142echo "$0: invalid key-value: $keyvals" 1>&2143exit 1144fi145val=`echo $keyvals | cut -d '=' -f 2-`146case "$key" in147LDADD)148LDADD="$val" ;;149LDLIBS)150LDLIBS="$val" ;;151LDFLAGS)152LDFLAGS="$val" ;;153LINKER_SONAME)154LINKER_SONAME="$val" ;;155CPPFLAGS)156CPPFLAGS="$val" ;;157DESTDIR)158DESTDIR="$val" ;;159PREFIX)160PREFIX="$val" ;;161MANDIR)162MANDIR="$val" ;;163LIBDIR)164LIBDIR="$val" ;;165BINDIR)166BINDIR="$val" ;;167SHAREDIR)168SHAREDIR="$val" ;;169SBINDIR)170SBINDIR="$val" ;;171INCLUDEDIR)172INCLUDEDIR="$val" ;;173*)174echo "$0: invalid key: $key" 1>&2175exit 1176esac177done
178
179#----------------------------------------------------------------------
180# If the user doesn't specify whether we want "-soname" or
181# "-install_name" for the linker option to generate shared libraries,
182# try to figure it out here. If we can't figure it out, just set it to
183# -soname and let the user figure it out.
184
185if [ -z "$LINKER_SONAME" ]186then
187test_soname="`mktemp`" || {188echo "mktemp: failed" 1>&2189echo "mktemp: failed" 1>&3190exit 1191}192echo "int foo(void) { return 1; }" > "${test_soname}.c"193${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c || {194echo "${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c: failed" 1>&2195echo "${CC} -fPIC -o ${test_soname}.o -c ${test_soname}.c: failed" 1>&3196}197LINKER_SONAME="-soname"198echo "LINKER_SONAME: testing -soname" 1>&3199${CC} -shared -o ${test_soname}.so.0 ${test_soname}.o -Wl,${LINKER_SONAME},${test_soname}.so.0 || {200LINKER_SONAME="-install_name"201echo "LINKER_SONAME: testing -install_name" 1>&3202${CC} -shared -o ${test_soname}.so.0 ${test_soname}.o -Wl,-install_name,${test_soname}.so.0 || {203echo "LINKER_SONAME: cannot determine: default to -soname" 1>&2204echo "LINKER_SONAME: cannot determine: default to -soname" 1>&3205LINKER_SONAME="-soname"206}207}208echo "LINKER_SONAME: $LINKER_SONAME" 1>&3209rm -f "$test_soname" "${test_soname}.*"210fi
211
212#----------------------------------------------------------------------
213# These are the values that will be pushed into config.h after we test
214# for whether they're supported or not.
215# Each of these must have a runtest(), below.
216# Please sort by alpha, for clarity.
217# You WANT to change this.
218#----------------------------------------------------------------------
219
220HAVE_ARC4RANDOM=221HAVE_B64_NTOP=222HAVE_CAPSICUM=223HAVE_CRYPT=224HAVE_CRYPT_NEWHASH=225HAVE_ENDIAN_H=226HAVE_ERR=227HAVE_EXPLICIT_BZERO=228HAVE_FTS=229HAVE_GETEXECNAME=230HAVE_GETPROGNAME=231HAVE_INFTIM=232HAVE_LANDLOCK=233HAVE_MD5=234HAVE_MEMMEM=235HAVE_MEMRCHR=236HAVE_MEMSET_S=237HAVE_MKFIFOAT=238HAVE_MKNODAT=239HAVE_OSBYTEORDER_H=240HAVE_PATH_MAX=241HAVE_PLEDGE=242HAVE_PROGRAM_INVOCATION_SHORT_NAME=243HAVE_READPASSPHRASE=244HAVE_REALLOCARRAY=245HAVE_RECALLOCARRAY=246HAVE_SANDBOX_INIT=247HAVE_SCAN_SCALED=248HAVE_SECCOMP_FILTER=249HAVE_SETRESGID=250HAVE_SETRESUID=251HAVE_SOCK_NONBLOCK=252HAVE_SHA2=253HAVE_SHA2_H=254HAVE_STRLCAT=255HAVE_STRLCPY=256HAVE_STRNDUP=257HAVE_STRNLEN=258HAVE_STRTONUM=259HAVE_SYS_BYTEORDER_H=260HAVE_SYS_ENDIAN_H=261HAVE_SYS_MKDEV_H=262HAVE_SYS_QUEUE=263HAVE_SYS_SYSMACROS=264HAVE_SYS_TREE=265HAVE_SYSTRACE=0266HAVE_TERMIOS=267HAVE_UNVEIL=268HAVE_WAIT_ANY=269HAVE___PROGNAME=270
271#----------------------------------------------------------------------
272# Allow configure.local to override all variables, default settings,
273# command-line arguments, and tested features, above.
274# You PROBABLY DO NOT want to change this.
275#----------------------------------------------------------------------
276
277if [ -r ./configure.local ]; then278echo "configure.local: reading..." 1>&2279echo "configure.local: reading..." 1>&3280cat ./configure.local 1>&3281. ./configure.local282else
283echo "configure.local: no (fully automatic configuration)" 1>&2284echo "configure.local: no (fully automatic configuration)" 1>&3285fi
286
287echo 1>&3288
289#----------------------------------------------------------------------
290# Infrastructure for running tests.
291# These consists of a series of functions that will attempt to run the
292# given test file and record its exit into a HAVE_xxx variable.
293# You DO NOT want to change this.
294#----------------------------------------------------------------------
295
296COMP="${CC} ${CFLAGS} ${CPPFLAGS} -Wno-unused -Werror"297
298# Check whether this HAVE_ setting is manually overridden.
299# If yes, use the override, if no, do not decide anything yet.
300# Arguments: lower-case test name, manual value
301
302ismanual() {303[ -z "${3}" ] && return 1304echo "${1}: manual (HAVE_${2}=${3})" 1>&2305echo "${1}: manual (HAVE_${2}=${3})" 1>&3306echo 1>&3307return 0308}
309
310# Run a single autoconfiguration test.
311# In case of success, enable the feature.
312# In case of failure, do not decide anything yet.
313# Arguments: lower-case test name, upper-case test name, additional
314# CFLAGS, additional LIBS.
315
316singletest() {317extralib=""318cat 1>&3 << __HEREDOC__319${1}: testing...320${COMP} -DTEST_${2} ${3} -o test-${1} tests.c ${LDFLAGS} ${4}321__HEREDOC__
322if ${COMP} -DTEST_${2} ${3} -o "test-${1}" tests.c ${LDFLAGS} ${4} 1>&3 2>&3; then323echo "${1}: ${CC} succeeded" 1>&3324else325if [ -n "${5}" ] ; then326echo "${1}: ${CC} failed with $? (retrying)" 1>&3327cat 1>&3 << __HEREDOC__328${1}: testing...329${COMP} -DTEST_${2} ${3} -o test-${1} tests.c ${LDFLAGS} ${5}330__HEREDOC__
331if ${COMP} -DTEST_${2} ${3} -o "test-${1}" tests.c ${LDFLAGS} ${5} 1>&3 2>&3; then332echo "${1}: ${CC} succeeded" 1>&3333extralib="(with ${5})"334else335echo "${1}: ${CC} failed with $?" 1>&3336echo 1>&3337return 1338fi339else340echo "${1}: ${CC} failed with $?" 1>&3341echo 1>&3342return 1343fi344fi345
346if [ -n "${extralib}" ]347then348eval "LDADD_${2}=\"${5}\""349elif [ -n "${4}" ]350then351eval "LDADD_${2}=\"${4}\""352fi353
354echo "${1}: yes ${extralib}" 1>&2355echo "${1}: yes ${extralib}" 1>&3356echo 1>&3357eval HAVE_${2}=1358rm "test-${1}"359return 0360}
361
362# Run a complete autoconfiguration test, including the check for
363# a manual override and disabling the feature on failure.
364# Arguments: lower case name, upper case name, additional CFLAGS,
365# additional LDADD, alternative LDADD.
366
367runtest() {368eval _manual=\${HAVE_${2}}369ismanual "${1}" "${2}" "${_manual}" && return 0370singletest "${1}" "${2}" "${3}" "${4}" "${5}" && return 0371echo "${1}: no" 1>&2372eval HAVE_${2}=0373return 1374}
375
376#----------------------------------------------------------------------
377# Begin running the tests themselves.
378# All of your tests must be defined here.
379# Please sort as the HAVE_xxxx values were defined.
380# You WANT to change this.
381# It consists of the following columns:
382# runtest
383# (1) test file
384# (2) macro to set
385# (3) argument to cc *before* -o
386# (4) argument to cc *after*
387# (5) alternative argument to cc *after*
388#----------------------------------------------------------------------
389
390runtest arc4random ARC4RANDOM || true391runtest b64_ntop B64_NTOP "" "" "-lresolv" || true392runtest capsicum CAPSICUM || true393runtest crypt CRYPT "" "" "-lcrypt" || true394runtest crypt_newhash CRYPT_NEWHASH || true395runtest endian_h ENDIAN_H || true396runtest err ERR || true397runtest explicit_bzero EXPLICIT_BZERO || true398runtest fts FTS || true399runtest getexecname GETEXECNAME || true400runtest getprogname GETPROGNAME || true401runtest INFTIM INFTIM || true402runtest landlock LANDLOCK || true403runtest lib_socket LIB_SOCKET "" "" "-lsocket -lnsl" || true404runtest md5 MD5 "" "" "-lmd" || true405runtest memmem MEMMEM || true406runtest memrchr MEMRCHR || true407runtest memset_s MEMSET_S || true408runtest mkfifoat MKFIFOAT || true409runtest mknodat MKNODAT || true410runtest osbyteorder_h OSBYTEORDER_H || true411runtest PATH_MAX PATH_MAX || true412runtest pledge PLEDGE || true413runtest program_invocation_short_name PROGRAM_INVOCATION_SHORT_NAME || true414runtest readpassphrase READPASSPHRASE || true415runtest reallocarray REALLOCARRAY || true416runtest recallocarray RECALLOCARRAY || true417runtest sandbox_init SANDBOX_INIT "-Wno-deprecated" || true418runtest scan_scaled SCAN_SCALED "" "" "-lutil" || true419runtest seccomp-filter SECCOMP_FILTER || true420runtest setresgid SETRESGID || true421runtest setresuid SETRESUID || true422runtest sha2 SHA2 "" "" "-lmd" || true423runtest SOCK_NONBLOCK SOCK_NONBLOCK || true424runtest static STATIC "" "-static" || true425runtest strlcat STRLCAT || true426runtest strlcpy STRLCPY || true427runtest strndup STRNDUP || true428runtest strnlen STRNLEN || true429runtest strtonum STRTONUM || true430runtest sys_byteorder_h SYS_BYTEORDER_H || true431runtest sys_endian_h SYS_ENDIAN_H || true432runtest sys_mkdev_h SYS_MKDEV_H || true433runtest sys_sysmacros_h SYS_SYSMACROS_H || true434runtest sys_queue SYS_QUEUE || true435runtest sys_tree SYS_TREE || true436runtest termios TERMIOS || true437runtest unveil UNVEIL || true438runtest WAIT_ANY WAIT_ANY || true439runtest __progname __PROGNAME || true440
441#----------------------------------------------------------------------
442# Output writing: generate the config.h file.
443# This file contains all of the HAVE_xxxx variables necessary for
444# compiling your source.
445# You must include "config.h" BEFORE any other variables.
446# You WANT to change this.
447#----------------------------------------------------------------------
448
449exec > config.h450
451# Start with prologue.
452
453cat << __HEREDOC__454#ifndef OCONFIGURE_CONFIG_H
455#define OCONFIGURE_CONFIG_H
456
457#ifdef __cplusplus
458# error "Do not use C++: this is a C application."
459#endif
460#if !defined(__GNUC__) || (__GNUC__ < 4)
461# define __attribute__(x)
462#endif
463#if defined(__linux__) || defined(__MINT__) || defined(__wasi__)
464# define _GNU_SOURCE /* memmem, memrchr, setresuid... */
465# define _DEFAULT_SOURCE /* le32toh, crypt, ... */
466#endif
467#if defined(__NetBSD__)
468# define _OPENBSD_SOURCE /* reallocarray, etc. */
469#endif
470#if defined(__sun)
471# ifndef _XOPEN_SOURCE /* SunOS already defines */
472# define _XOPEN_SOURCE /* XPGx */
473# endif
474# define _XOPEN_SOURCE_EXTENDED 1 /* XPG4v2 */
475# ifndef __EXTENSIONS__ /* SunOS already defines */
476# define __EXTENSIONS__ /* reallocarray, etc. */
477# endif
478#endif
479#if !defined(__BEGIN_DECLS)
480# define __BEGIN_DECLS
481#endif
482#if !defined(__END_DECLS)
483# define __END_DECLS
484#endif
485
486__HEREDOC__
487
488# This is just for size_t, mode_t, and dev_t.
489# Most of these functions, in the real world, pull in <string.h> or
490# someting that pulls in support for size_t.
491# Our function declarations are standalone, so specify them here.
492
493if [ ${HAVE_FTS} -eq 0 -o \494${HAVE_MD5} -eq 0 -o \495${HAVE_MEMMEM} -eq 0 -o \496${HAVE_MEMRCHR} -eq 0 -o \497${HAVE_MKFIFOAT} -eq 0 -o \498${HAVE_MKNODAT} -eq 0 -o \499${HAVE_READPASSPHRASE} -eq 0 -o \500${HAVE_REALLOCARRAY} -eq 0 -o \501${HAVE_RECALLOCARRAY} -eq 0 -o \502${HAVE_SETRESGID} -eq 0 -o \503${HAVE_SETRESUID} -eq 0 -o \504${HAVE_SHA2} -eq 0 -o \505${HAVE_STRLCAT} -eq 0 -o \506${HAVE_STRLCPY} -eq 0 -o \507${HAVE_STRNDUP} -eq 0 -o \508${HAVE_STRNLEN} -eq 0 ]509then
510echo "#include <sys/types.h> /* size_t, mode_t, dev_t */ "511echo512fi
513
514if [ ${HAVE_MD5} -eq 0 -o \515${HAVE_SHA2} -eq 0 ]516then
517echo "#include <stdint.h> /* C99 [u]int[nn]_t types */"518echo519fi
520
521if [ ${HAVE_ERR} -eq 0 ]522then
523echo "#include <stdarg.h> /* err(3) */"524echo525fi
526
527# Now we handle our HAVE_xxxx values.
528# Most will just be defined as 0 or 1.
529
530if [ ${HAVE_PATH_MAX} -eq 0 ]531then
532echo "#define PATH_MAX 4096"533echo534fi
535
536if [ ${HAVE_WAIT_ANY} -eq 0 ]537then
538echo "#define WAIT_ANY (-1) /* sys/wait.h */"539echo "#define WAIT_MYPGRP 0"540echo541fi
542
543
544if [ ${HAVE_INFTIM} -eq 0 ]545then
546echo "#define INFTIM (-1) /* poll.h */"547echo548fi
549
550cat << __HEREDOC__551/*
552* Results of configuration feature-testing.
553*/
554#define HAVE_ARC4RANDOM ${HAVE_ARC4RANDOM}555#define HAVE_B64_NTOP ${HAVE_B64_NTOP}556#define HAVE_CAPSICUM ${HAVE_CAPSICUM}557#define HAVE_CRYPT ${HAVE_CRYPT}558#define HAVE_CRYPT_NEWHASH ${HAVE_CRYPT_NEWHASH}559#define HAVE_ENDIAN_H ${HAVE_ENDIAN_H}560#define HAVE_ERR ${HAVE_ERR}561#define HAVE_EXPLICIT_BZERO ${HAVE_EXPLICIT_BZERO}562#define HAVE_FTS ${HAVE_FTS}563#define HAVE_GETEXECNAME ${HAVE_GETEXECNAME}564#define HAVE_GETPROGNAME ${HAVE_GETPROGNAME}565#define HAVE_INFTIM ${HAVE_INFTIM}566#define HAVE_LANDLOCK ${HAVE_LANDLOCK}567#define HAVE_MD5 ${HAVE_MD5}568#define HAVE_MEMMEM ${HAVE_MEMMEM}569#define HAVE_MEMRCHR ${HAVE_MEMRCHR}570#define HAVE_MEMSET_S ${HAVE_MEMSET_S}571#define HAVE_MKFIFOAT ${HAVE_MKFIFOAT}572#define HAVE_MKNODAT ${HAVE_MKNODAT}573#define HAVE_OSBYTEORDER_H ${HAVE_OSBYTEORDER_H}574#define HAVE_PATH_MAX ${HAVE_PATH_MAX}575#define HAVE_PLEDGE ${HAVE_PLEDGE}576#define HAVE_PROGRAM_INVOCATION_SHORT_NAME ${HAVE_PROGRAM_INVOCATION_SHORT_NAME}577#define HAVE_READPASSPHRASE ${HAVE_READPASSPHRASE}578#define HAVE_REALLOCARRAY ${HAVE_REALLOCARRAY}579#define HAVE_RECALLOCARRAY ${HAVE_RECALLOCARRAY}580#define HAVE_SANDBOX_INIT ${HAVE_SANDBOX_INIT}581#define HAVE_SCAN_SCALED ${HAVE_SCAN_SCALED}582#define HAVE_SECCOMP_HEADER ${HAVE_SECCOMP_FILTER}583#define HAVE_SETRESGID ${HAVE_SETRESGID}584#define HAVE_SETRESUID ${HAVE_SETRESUID}585#define HAVE_SHA2 ${HAVE_SHA2}586#define HAVE_SHA2_H ${HAVE_SHA2}587#define HAVE_SOCK_NONBLOCK ${HAVE_SOCK_NONBLOCK}588#define HAVE_STRLCAT ${HAVE_STRLCAT}589#define HAVE_STRLCPY ${HAVE_STRLCPY}590#define HAVE_STRNDUP ${HAVE_STRNDUP}591#define HAVE_STRNLEN ${HAVE_STRNLEN}592#define HAVE_STRTONUM ${HAVE_STRTONUM}593#define HAVE_SYS_BYTEORDER_H ${HAVE_SYS_BYTEORDER_H}594#define HAVE_SYS_ENDIAN_H ${HAVE_SYS_ENDIAN_H}595#define HAVE_SYS_MKDEV_H ${HAVE_SYS_MKDEV_H}596#define HAVE_SYS_QUEUE ${HAVE_SYS_QUEUE}597#define HAVE_SYS_SYSMACROS_H ${HAVE_SYS_SYSMACROS_H}598#define HAVE_SYS_TREE ${HAVE_SYS_TREE}599#define HAVE_SYSTRACE ${HAVE_SYSTRACE}600#define HAVE_UNVEIL ${HAVE_UNVEIL}601#define HAVE_TERMIOS ${HAVE_TERMIOS}602#define HAVE_WAIT_ANY ${HAVE_WAIT_ANY}603#define HAVE___PROGNAME ${HAVE___PROGNAME}604
605__HEREDOC__
606
607# Compat for libkern/OSByteOrder.h in place of endian.h.
608
609[ ${HAVE_OSBYTEORDER_H} -eq 1 -a \610${HAVE_ENDIAN_H} -eq 0 -a \611${HAVE_SYS_BYTEORDER_H} -eq 0 -a \612${HAVE_SYS_ENDIAN_H} -eq 0 ] \613&& cat << __HEREDOC__614/*
615* endian.h compatibility with libkern/OSByteOrder.h.
616*/
617#define htobe16(x) OSSwapHostToBigInt16(x)
618#define htole16(x) OSSwapHostToLittleInt16(x)
619#define be16toh(x) OSSwapBigToHostInt16(x)
620#define le16toh(x) OSSwapLittleToHostInt16(x)
621#define htobe32(x) OSSwapHostToBigInt32(x)
622#define htole32(x) OSSwapHostToLittleInt32(x)
623#define be32toh(x) OSSwapBigToHostInt32(x)
624#define le32toh(x) OSSwapLittleToHostInt32(x)
625#define htobe64(x) OSSwapHostToBigInt64(x)
626#define htole64(x) OSSwapHostToLittleInt64(x)
627#define be64toh(x) OSSwapBigToHostInt64(x)
628#define le64toh(x) OSSwapLittleToHostInt64(x)
629
630__HEREDOC__
631
632[ ${HAVE_SYS_BYTEORDER_H} -eq 1 -a \633${HAVE_ENDIAN_H} -eq 0 -a \634${HAVE_OSBYTEORDER_H} -eq 0 -a \635${HAVE_SYS_ENDIAN_H} -eq 0 ] \636&& cat << __HEREDOC__637/*
638* endian.h compatibility with sys/byteorder.h.
639*/
640#define htobe16(x) BE_16(x)
641#define htole16(x) LE_16(x)
642#define be16toh(x) BE_16(x)
643#define le16toh(x) LE_16(x)
644#define htobe32(x) BE_32(x)
645#define htole32(x) LE_32(x)
646#define be32toh(x) BE_32(x)
647#define le32toh(x) LE_32(x)
648#define htobe64(x) BE_64(x)
649#define htole64(x) LE_64(x)
650#define be64toh(x) BE_64(x)
651#define le64toh(x) LE_64(x)
652
653__HEREDOC__
654
655# Make minor()/major()/makedev() easier to use.
656
657cat << __HEREDOC__658/*
659* Handle the various major()/minor() header files.
660* Use sys/mkdev.h before sys/sysmacros.h because SunOS
661* has both, where only the former works properly.
662*/
663#if HAVE_SYS_MKDEV_H
664# define COMPAT_MAJOR_MINOR_H <sys/mkdev.h>
665#elif HAVE_SYS_SYSMACROS_H
666# define COMPAT_MAJOR_MINOR_H <sys/sysmacros.h>
667#else
668# define COMPAT_MAJOR_MINOR_H <sys/types.h>
669#endif
670
671__HEREDOC__
672
673# Make endian.h easier by providing a COMPAT_ENDIAN_H.
674
675cat << __HEREDOC__676/*
677* Make it easier to include endian.h forms.
678*/
679#if HAVE_ENDIAN_H
680# define COMPAT_ENDIAN_H <endian.h>
681#elif HAVE_SYS_ENDIAN_H
682# define COMPAT_ENDIAN_H <sys/endian.h>
683#elif HAVE_OSBYTEORDER_H
684# define COMPAT_ENDIAN_H <libkern/OSByteOrder.h>
685#elif HAVE_SYS_BYTEORDER_H
686# define COMPAT_ENDIAN_H <sys/byteorder.h>
687#else
688# warning No suitable endian.h could be found.
689# warning Please e-mail the maintainers with your OS.
690# define COMPAT_ENDIAN_H <endian.h>
691#endif
692
693__HEREDOC__
694
695# Now we do our function declarations for missing functions.
696
697[ ${HAVE_ERR} -eq 0 ] && \698cat << __HEREDOC__699/*
700* Compatibility functions for err(3).
701*/
702extern void err(int, const char *, ...) __attribute__((noreturn));703extern void errc(int, int, const char *, ...) __attribute__((noreturn));704extern void errx(int, const char *, ...) __attribute__((noreturn));705extern void verr(int, const char *, va_list) __attribute__((noreturn));706extern void verrc(int, int, const char *, va_list) __attribute__((noreturn));707extern void verrx(int, const char *, va_list) __attribute__((noreturn));708extern void warn(const char *, ...);
709extern void warnx(const char *, ...);
710extern void warnc(int, const char *, ...);
711extern void vwarn(const char *, va_list);
712extern void vwarnc(int, const char *, va_list);
713extern void vwarnx(const char *, va_list);
714
715__HEREDOC__
716
717[ ${HAVE_MD5} -eq 0 ] && \718cat << __HEREDOC__719/*
720* Compatibility for md4(3).
721*/
722#define MD5_BLOCK_LENGTH 64
723#define MD5_DIGEST_LENGTH 16
724#define MD5_DIGEST_STRING_LENGTH (MD5_DIGEST_LENGTH * 2 + 1)
725
726typedef struct MD5Context {
727uint32_t state[4];
728uint64_t count;
729uint8_t buffer[MD5_BLOCK_LENGTH];
730} MD5_CTX;
731
732extern void MD5Init(MD5_CTX *);
733extern void MD5Update(MD5_CTX *, const uint8_t *, size_t);
734extern void MD5Pad(MD5_CTX *);
735extern void MD5Transform(uint32_t [4], const uint8_t [MD5_BLOCK_LENGTH]);
736extern char *MD5End(MD5_CTX *, char *);
737extern void MD5Final(uint8_t [MD5_DIGEST_LENGTH], MD5_CTX *);
738
739__HEREDOC__
740
741[ ${HAVE_SHA2} -eq 0 ] && \742cat << __HEREDOC__743/*
744* Compatibility for sha2(3).
745*/
746
747/*** SHA-256/384/512 Various Length Definitions ***********************/
748#define SHA256_BLOCK_LENGTH 64
749#define SHA256_DIGEST_LENGTH 32
750#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1)
751#define SHA384_BLOCK_LENGTH 128
752#define SHA384_DIGEST_LENGTH 48
753#define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1)
754#define SHA512_BLOCK_LENGTH 128
755#define SHA512_DIGEST_LENGTH 64
756#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
757#define SHA512_256_BLOCK_LENGTH 128
758#define SHA512_256_DIGEST_LENGTH 32
759#define SHA512_256_DIGEST_STRING_LENGTH (SHA512_256_DIGEST_LENGTH * 2 + 1)
760
761/*** SHA-224/256/384/512 Context Structure *******************************/
762typedef struct _SHA2_CTX {
763union {
764uint32_t st32[8];
765uint64_t st64[8];
766} state;
767uint64_t bitcount[2];
768uint8_t buffer[SHA512_BLOCK_LENGTH];
769} SHA2_CTX;
770
771void SHA256Init(SHA2_CTX *);
772void SHA256Transform(uint32_t state[8], const uint8_t [SHA256_BLOCK_LENGTH]);
773void SHA256Update(SHA2_CTX *, const uint8_t *, size_t);
774void SHA256Pad(SHA2_CTX *);
775void SHA256Final(uint8_t [SHA256_DIGEST_LENGTH], SHA2_CTX *);
776char *SHA256End(SHA2_CTX *, char *);
777char *SHA256File(const char *, char *);
778char *SHA256FileChunk(const char *, char *, off_t, off_t);
779char *SHA256Data(const uint8_t *, size_t, char *);
780
781void SHA384Init(SHA2_CTX *);
782void SHA384Transform(uint64_t state[8], const uint8_t [SHA384_BLOCK_LENGTH]);
783void SHA384Update(SHA2_CTX *, const uint8_t *, size_t);
784void SHA384Pad(SHA2_CTX *);
785void SHA384Final(uint8_t [SHA384_DIGEST_LENGTH], SHA2_CTX *);
786char *SHA384End(SHA2_CTX *, char *);
787char *SHA384File(const char *, char *);
788char *SHA384FileChunk(const char *, char *, off_t, off_t);
789char *SHA384Data(const uint8_t *, size_t, char *);
790
791void SHA512Init(SHA2_CTX *);
792void SHA512Transform(uint64_t state[8], const uint8_t [SHA512_BLOCK_LENGTH]);
793void SHA512Update(SHA2_CTX *, const uint8_t *, size_t);
794void SHA512Pad(SHA2_CTX *);
795void SHA512Final(uint8_t [SHA512_DIGEST_LENGTH], SHA2_CTX *);
796char *SHA512End(SHA2_CTX *, char *);
797char *SHA512File(const char *, char *);
798char *SHA512FileChunk(const char *, char *, off_t, off_t);
799char *SHA512Data(const uint8_t *, size_t, char *);
800
801__HEREDOC__
802
803if [ ${HAVE_SECCOMP_FILTER} -eq 1 ]; then804seccomp_audit_arch=805arch=$(uname -m 2>/dev/null || echo unknown)806case "$arch" in807x86_64)808seccomp_audit_arch=AUDIT_ARCH_X86_64809;;810i*86)811seccomp_audit_arch=AUDIT_ARCH_I386812;;813arm*)814seccomp_audit_arch=AUDIT_ARCH_ARM815;;816aarch64*)817seccomp_audit_arch=AUDIT_ARCH_AARCH64818;;819s390x)820seccomp_audit_arch=AUDIT_ARCH_S390X821;;822s390)823seccomp_audit_arch=AUDIT_ARCH_S390824;;825ppc)826seccomp_audit_arch=AUDIT_ARCH_PPC827;;828ppc64)829seccomp_audit_arch=AUDIT_ARCH_PPC64830;;831ppc64le)832seccomp_audit_arch=AUDIT_ARCH_PPC64LE833;;834mips)835seccomp_audit_arch=AUDIT_ARCH_MIPS836;;837mipsel)838seccomp_audit_arch=AUDIT_ARCH_MIPSEL839;;840riscv64)841seccomp_audit_arch=AUDIT_ARCH_RISCV64842;;843esac844if [ -n "$seccomp_audit_arch" ]845then846echo "seccomp-arch: $seccomp_audit_arch" 1>&2847cat << __HEREDOC__848/*
849* Seccomp is both available and has a recognised architecture.
850*/
851#define HAVE_SECCOMP_FILTER 1
852#define SECCOMP_AUDIT_ARCH $seccomp_audit_arch853
854__HEREDOC__
855else856echo "seccomp-arch: disabling (unknown: `uname -m`)" 1>&2857cat << __HEREDOC__858/**
859* Seccomp is available, but not with a recognised architecture.
860* Please submit your architecture (via uname -m) to the oconfigure
861* maintainers.
862*/
863#define HAVE_SECCOMP_FILTER 0
864
865__HEREDOC__
866fi867else
868cat << __HEREDOC__869#define HAVE_SECCOMP_FILTER 0
870
871__HEREDOC__
872fi
873
874[ ${HAVE_B64_NTOP} -eq 0 ] && \875cat << __HEREDOC__876/*
877* Compatibility for b64_ntop(3).
878*/
879extern int b64_ntop(unsigned char const *, size_t, char *, size_t);
880extern int b64_pton(char const *, unsigned char *, size_t);
881
882__HEREDOC__
883
884[ ${HAVE_SCAN_SCALED} -eq 0 ] && \885cat << __HEREDOC__886#define FMT_SCALED_STRSIZE 7 /* minus sign, 4 digits, suffix, null byte */
887int fmt_scaled(long long, char *);
888int scan_scaled(char *, long long *);
889__HEREDOC__
890
891[ ${HAVE_EXPLICIT_BZERO} -eq 0 ] && \892cat << __HEREDOC__893/*
894* Compatibility for explicit_bzero(3).
895*/
896extern void explicit_bzero(void *, size_t);
897
898__HEREDOC__
899
900[ ${HAVE_MEMMEM} -eq 0 ] && \901cat << __HEREDOC__902/*
903* Compatibility for memmem(3).
904*/
905void *memmem(const void *, size_t, const void *, size_t);
906
907__HEREDOC__
908
909[ ${HAVE_MEMRCHR} -eq 0 ] && \910cat << __HEREDOC__911/*
912* Compatibility for memrchr(3).
913*/
914void *memrchr(const void *b, int, size_t);
915
916__HEREDOC__
917
918[ ${HAVE_GETPROGNAME} -eq 0 ] && \919cat << __HEREDOC__920/*
921* Compatibility for getprogname(3).
922*/
923extern const char *getprogname(void);
924
925__HEREDOC__
926
927[ ${HAVE_READPASSPHRASE} -eq 0 ] && \928cat << __HEREDOC__929/*
930* Macros and function required for readpassphrase(3).
931*/
932#define RPP_ECHO_OFF 0x00
933#define RPP_ECHO_ON 0x01
934#define RPP_REQUIRE_TTY 0x02
935#define RPP_FORCELOWER 0x04
936#define RPP_FORCEUPPER 0x08
937#define RPP_SEVENBIT 0x10
938#define RPP_STDIN 0x20
939char *readpassphrase(const char *, char *, size_t, int);
940
941__HEREDOC__
942
943[ ${HAVE_REALLOCARRAY} -eq 0 ] && \944cat << __HEREDOC__945/*
946* Compatibility for reallocarray(3).
947*/
948extern void *reallocarray(void *, size_t, size_t);
949
950__HEREDOC__
951
952[ ${HAVE_RECALLOCARRAY} -eq 0 ] && \953cat << __HEREDOC__954/*
955* Compatibility for recallocarray(3).
956*/
957extern void *recallocarray(void *, size_t, size_t, size_t);
958
959__HEREDOC__
960
961[ ${HAVE_STRLCAT} -eq 0 ] && \962cat << __HEREDOC__963/*
964* Compatibility for strlcat(3).
965*/
966extern size_t strlcat(char *, const char *, size_t);
967
968__HEREDOC__
969
970[ ${HAVE_STRLCPY} -eq 0 ] && \971cat << __HEREDOC__972/*
973* Compatibility for strlcpy(3).
974*/
975extern size_t strlcpy(char *, const char *, size_t);
976
977__HEREDOC__
978
979[ ${HAVE_STRNDUP} -eq 0 ] && \980cat << __HEREDOC__981/*
982* Compatibility for strndup(3).
983*/
984extern char *strndup(const char *, size_t);
985
986__HEREDOC__
987
988[ ${HAVE_STRNLEN} -eq 0 ] && \989cat << __HEREDOC__990/*
991* Compatibility for strnlen(3).
992*/
993extern size_t strnlen(const char *, size_t);
994
995__HEREDOC__
996
997[ ${HAVE_STRTONUM} -eq 0 ] && \998cat << __HEREDOC__999/*
1000* Compatibility for strotnum(3).
1001*/
1002extern long long strtonum(const char *, long long, long long, const char **);
1003
1004__HEREDOC__
1005
1006[ ${HAVE_MKFIFOAT} -eq 0 ] && \1007cat << __HEREDOC__1008/*
1009* Compatibility for mkfifoat(2).
1010*/
1011int mkfifoat(int, const char *, mode_t);
1012
1013__HEREDOC__
1014
1015[ ${HAVE_MKNODAT} -eq 0 ] && \1016cat << __HEREDOC__1017/*
1018* Compatibility for mknodat(2).
1019*/
1020int mknodat(int, const char *, mode_t, dev_t);
1021
1022__HEREDOC__
1023
1024[ ${HAVE_SETRESGID} -eq 0 ] && \1025cat << __HEREDOC__1026/*
1027* Compatibility for setresgid(2).
1028*/
1029int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
1030
1031__HEREDOC__
1032
1033[ ${HAVE_SETRESUID} -eq 0 ] && \1034cat << __HEREDOC__1035/*
1036* Compatibility for setresuid(2).
1037*/
1038int setresuid(uid_t ruid, uid_t euid, uid_t suid);
1039
1040__HEREDOC__
1041
1042if [ ${HAVE_SYS_QUEUE} -eq 0 ]; then1043cat << __HEREDOC__1044/*
1045* A compatible version of OpenBSD <sys/queue.h>.
1046*/
1047/*
1048* Copyright (c) 1991, 1993
1049* The Regents of the University of California. All rights reserved.
1050*
1051* Redistribution and use in source and binary forms, with or without
1052* modification, are permitted provided that the following conditions
1053* are met:
1054* 1. Redistributions of source code must retain the above copyright
1055* notice, this list of conditions and the following disclaimer.
1056* 2. Redistributions in binary form must reproduce the above copyright
1057* notice, this list of conditions and the following disclaimer in the
1058* documentation and/or other materials provided with the distribution.
1059* 3. Neither the name of the University nor the names of its contributors
1060* may be used to endorse or promote products derived from this software
1061* without specific prior written permission.
1062*
1063* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND
1064* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1065* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1066* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1067* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1068* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1069* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1070* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1071* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1072* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1073* SUCH DAMAGE.
1074*
1075* @(#)queue.h 8.5 (Berkeley) 8/20/94
1076*/
1077
1078/* OPENBSD ORIGINAL: sys/sys/queue.h */
1079
1080/*
1081* Require for OS/X and other platforms that have old/broken/incomplete
1082* <sys/queue.h>.
1083*/
1084
1085#undef LIST_EMPTY
1086#undef LIST_END
1087#undef LIST_ENTRY
1088#undef LIST_FIRST
1089#undef LIST_FOREACH
1090#undef LIST_FOREACH_SAFE
1091#undef LIST_HEAD
1092#undef LIST_HEAD_INITIALIZER
1093#undef LIST_INIT
1094#undef LIST_INSERT_AFTER
1095#undef LIST_INSERT_BEFORE
1096#undef LIST_INSERT_HEAD
1097#undef LIST_NEXT
1098#undef LIST_REMOVE
1099#undef LIST_REPLACE
1100#undef SIMPLEQ_CONCAT
1101#undef SIMPLEQ_EMPTY
1102#undef SIMPLEQ_END
1103#undef SIMPLEQ_ENTRY
1104#undef SIMPLEQ_FIRST
1105#undef SIMPLEQ_FOREACH
1106#undef SIMPLEQ_FOREACH_SAFE
1107#undef SIMPLEQ_HEAD
1108#undef SIMPLEQ_HEAD_INITIALIZER
1109#undef SIMPLEQ_INIT
1110#undef SIMPLEQ_INSERT_AFTER
1111#undef SIMPLEQ_INSERT_HEAD
1112#undef SIMPLEQ_INSERT_TAIL
1113#undef SIMPLEQ_NEXT
1114#undef SIMPLEQ_REMOVE_AFTER
1115#undef SIMPLEQ_REMOVE_HEAD
1116#undef SLIST_EMPTY
1117#undef SLIST_END
1118#undef SLIST_ENTRY
1119#undef SLIST_FIRST
1120#undef SLIST_FOREACH
1121#undef SLIST_FOREACH_SAFE
1122#undef SLIST_HEAD
1123#undef SLIST_HEAD_INITIALIZER
1124#undef SLIST_INIT
1125#undef SLIST_INSERT_AFTER
1126#undef SLIST_INSERT_HEAD
1127#undef SLIST_NEXT
1128#undef SLIST_REMOVE
1129#undef SLIST_REMOVE_AFTER
1130#undef SLIST_REMOVE_HEAD
1131#undef TAILQ_CONCAT
1132#undef TAILQ_EMPTY
1133#undef TAILQ_END
1134#undef TAILQ_ENTRY
1135#undef TAILQ_FIRST
1136#undef TAILQ_FOREACH
1137#undef TAILQ_FOREACH_REVERSE
1138#undef TAILQ_FOREACH_REVERSE_SAFE
1139#undef TAILQ_FOREACH_SAFE
1140#undef TAILQ_HEAD
1141#undef TAILQ_HEAD_INITIALIZER
1142#undef TAILQ_INIT
1143#undef TAILQ_INSERT_AFTER
1144#undef TAILQ_INSERT_BEFORE
1145#undef TAILQ_INSERT_HEAD
1146#undef TAILQ_INSERT_TAIL
1147#undef TAILQ_LAST
1148#undef TAILQ_NEXT
1149#undef TAILQ_PREV
1150#undef TAILQ_REMOVE
1151#undef TAILQ_REPLACE
1152#undef XSIMPLEQ_EMPTY
1153#undef XSIMPLEQ_END
1154#undef XSIMPLEQ_ENTRY
1155#undef XSIMPLEQ_FIRST
1156#undef XSIMPLEQ_FOREACH
1157#undef XSIMPLEQ_FOREACH_SAFE
1158#undef XSIMPLEQ_HEAD
1159#undef XSIMPLEQ_INIT
1160#undef XSIMPLEQ_INSERT_AFTER
1161#undef XSIMPLEQ_INSERT_HEAD
1162#undef XSIMPLEQ_INSERT_TAIL
1163#undef XSIMPLEQ_NEXT
1164#undef XSIMPLEQ_REMOVE_AFTER
1165#undef XSIMPLEQ_REMOVE_HEAD
1166#undef XSIMPLEQ_XOR
1167
1168/*
1169* This file defines five types of data structures: singly-linked lists,
1170* lists, simple queues, tail queues and XOR simple queues.
1171*
1172*
1173* A singly-linked list is headed by a single forward pointer. The elements
1174* are singly linked for minimum space and pointer manipulation overhead at
1175* the expense of O(n) removal for arbitrary elements. New elements can be
1176* added to the list after an existing element or at the head of the list.
1177* Elements being removed from the head of the list should use the explicit
1178* macro for this purpose for optimum efficiency. A singly-linked list may
1179* only be traversed in the forward direction. Singly-linked lists are ideal
1180* for applications with large datasets and few or no removals or for
1181* implementing a LIFO queue.
1182*
1183* A list is headed by a single forward pointer (or an array of forward
1184* pointers for a hash table header). The elements are doubly linked
1185* so that an arbitrary element can be removed without a need to
1186* traverse the list. New elements can be added to the list before
1187* or after an existing element or at the head of the list. A list
1188* may only be traversed in the forward direction.
1189*
1190* A simple queue is headed by a pair of pointers, one to the head of the
1191* list and the other to the tail of the list. The elements are singly
1192* linked to save space, so elements can only be removed from the
1193* head of the list. New elements can be added to the list before or after
1194* an existing element, at the head of the list, or at the end of the
1195* list. A simple queue may only be traversed in the forward direction.
1196*
1197* A tail queue is headed by a pair of pointers, one to the head of the
1198* list and the other to the tail of the list. The elements are doubly
1199* linked so that an arbitrary element can be removed without a need to
1200* traverse the list. New elements can be added to the list before or
1201* after an existing element, at the head of the list, or at the end of
1202* the list. A tail queue may be traversed in either direction.
1203*
1204* An XOR simple queue is used in the same way as a regular simple queue.
1205* The difference is that the head structure also includes a "cookie" that
1206* is XOR'd with the queue pointer (first, last or next) to generate the
1207* real pointer value.
1208*
1209* For details on the use of these macros, see the queue(3) manual page.
1210*/
1211
1212#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
1213#define _Q_INVALID ((void *)-1)1214#define _Q_INVALIDATE(a) (a) = _Q_INVALID1215#else
1216#define _Q_INVALIDATE(a)1217#endif
1218
1219/*1220* Singly-linked List definitions.1221*/1222#define SLIST_HEAD(name, type) \\1223struct name { \\
1224struct type *slh_first; /* first element */ \\1225}
1226
1227#define SLIST_HEAD_INITIALIZER(head) \\1228{ NULL }
1229
1230#define SLIST_ENTRY(type) \\1231struct { \\
1232struct type *sle_next; /* next element */ \\1233}
1234
1235/*1236* Singly-linked List access methods.1237*/1238#define SLIST_FIRST(head) ((head)->slh_first)1239#define SLIST_END(head) NULL1240#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))1241#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)1242
1243#define SLIST_FOREACH(var, head, field) \\1244for((var) = SLIST_FIRST(head); \\1245(var) != SLIST_END(head); \\1246(var) = SLIST_NEXT(var, field))1247
1248#define SLIST_FOREACH_SAFE(var, head, field, tvar) \\1249for ((var) = SLIST_FIRST(head); \\1250(var) && ((tvar) = SLIST_NEXT(var, field), 1); \\1251(var) = (tvar))1252
1253/*
1254* Singly-linked List functions.
1255*/
1256#define SLIST_INIT(head) { \\1257SLIST_FIRST(head) = SLIST_END(head); \\1258}
1259
1260#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \\1261(elm)->field.sle_next = (slistelm)->field.sle_next; \\1262(slistelm)->field.sle_next = (elm); \\1263} while (0)
1264
1265#define SLIST_INSERT_HEAD(head, elm, field) do { \\1266(elm)->field.sle_next = (head)->slh_first; \\1267(head)->slh_first = (elm); \\1268} while (0)
1269
1270#define SLIST_REMOVE_AFTER(elm, field) do { \\1271(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \\1272} while (0)
1273
1274#define SLIST_REMOVE_HEAD(head, field) do { \\1275(head)->slh_first = (head)->slh_first->field.sle_next; \\1276} while (0)
1277
1278#define SLIST_REMOVE(head, elm, type, field) do { \\1279if ((head)->slh_first == (elm)) { \\1280SLIST_REMOVE_HEAD((head), field); \\1281} else { \\
1282struct type *curelm = (head)->slh_first; \\1283\\
1284while (curelm->field.sle_next != (elm)) \\1285curelm = curelm->field.sle_next; \\1286curelm->field.sle_next = \\1287curelm->field.sle_next->field.sle_next; \\1288} \\1289_Q_INVALIDATE((elm)->field.sle_next); \\1290} while (0)1291
1292/*1293* List definitions.1294*/1295#define LIST_HEAD(name, type) \\1296struct name { \\
1297struct type *lh_first; /* first element */ \\1298}
1299
1300#define LIST_HEAD_INITIALIZER(head) \\1301{ NULL }
1302
1303#define LIST_ENTRY(type) \\1304struct { \\
1305struct type *le_next; /* next element */ \\1306struct type **le_prev; /* address of previous next element */ \\1307}
1308
1309/*1310* List access methods.1311*/1312#define LIST_FIRST(head) ((head)->lh_first)1313#define LIST_END(head) NULL1314#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))1315#define LIST_NEXT(elm, field) ((elm)->field.le_next)1316
1317#define LIST_FOREACH(var, head, field) \\1318for((var) = LIST_FIRST(head); \\1319(var)!= LIST_END(head); \\1320(var) = LIST_NEXT(var, field))1321
1322#define LIST_FOREACH_SAFE(var, head, field, tvar) \\1323for ((var) = LIST_FIRST(head); \\1324(var) && ((tvar) = LIST_NEXT(var, field), 1); \\1325(var) = (tvar))1326
1327/*
1328* List functions.
1329*/
1330#define LIST_INIT(head) do { \\1331LIST_FIRST(head) = LIST_END(head); \\1332} while (0)
1333
1334#define LIST_INSERT_AFTER(listelm, elm, field) do { \\1335if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \\1336(listelm)->field.le_next->field.le_prev = \\1337&(elm)->field.le_next; \\1338(listelm)->field.le_next = (elm); \\1339(elm)->field.le_prev = &(listelm)->field.le_next; \\1340} while (0)1341
1342#define LIST_INSERT_BEFORE(listelm, elm, field) do { \\1343(elm)->field.le_prev = (listelm)->field.le_prev; \\1344(elm)->field.le_next = (listelm); \\1345*(listelm)->field.le_prev = (elm); \\1346(listelm)->field.le_prev = &(elm)->field.le_next; \\1347} while (0)1348
1349#define LIST_INSERT_HEAD(head, elm, field) do { \\1350if (((elm)->field.le_next = (head)->lh_first) != NULL) \\1351(head)->lh_first->field.le_prev = &(elm)->field.le_next;\\1352(head)->lh_first = (elm); \\1353(elm)->field.le_prev = &(head)->lh_first; \\1354} while (0)1355
1356#define LIST_REMOVE(elm, field) do { \\1357if ((elm)->field.le_next != NULL) \\1358(elm)->field.le_next->field.le_prev = \\1359(elm)->field.le_prev; \\1360*(elm)->field.le_prev = (elm)->field.le_next; \\1361_Q_INVALIDATE((elm)->field.le_prev); \\1362_Q_INVALIDATE((elm)->field.le_next); \\1363} while (0)1364
1365#define LIST_REPLACE(elm, elm2, field) do { \\1366if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \\1367(elm2)->field.le_next->field.le_prev = \\1368&(elm2)->field.le_next; \\1369(elm2)->field.le_prev = (elm)->field.le_prev; \\1370*(elm2)->field.le_prev = (elm2); \\1371_Q_INVALIDATE((elm)->field.le_prev); \\1372_Q_INVALIDATE((elm)->field.le_next); \\1373} while (0)1374
1375/*1376* Simple queue definitions.1377*/1378#define SIMPLEQ_HEAD(name, type) \\1379struct name { \\
1380struct type *sqh_first; /* first element */ \\1381struct type **sqh_last; /* addr of last next element */ \\1382}
1383
1384#define SIMPLEQ_HEAD_INITIALIZER(head) \\1385{ NULL, &(head).sqh_first }1386
1387#define SIMPLEQ_ENTRY(type) \\1388struct { \\
1389struct type *sqe_next; /* next element */ \\1390}
1391
1392/*1393* Simple queue access methods.1394*/1395#define SIMPLEQ_FIRST(head) ((head)->sqh_first)1396#define SIMPLEQ_END(head) NULL1397#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))1398#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)1399
1400#define SIMPLEQ_FOREACH(var, head, field) \\1401for((var) = SIMPLEQ_FIRST(head); \\1402(var) != SIMPLEQ_END(head); \\1403(var) = SIMPLEQ_NEXT(var, field))1404
1405#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \\1406for ((var) = SIMPLEQ_FIRST(head); \\1407(var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \\1408(var) = (tvar))1409
1410/*
1411* Simple queue functions.
1412*/
1413#define SIMPLEQ_INIT(head) do { \\1414(head)->sqh_first = NULL; \\1415(head)->sqh_last = &(head)->sqh_first; \\1416} while (0)
1417
1418#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \\1419if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \\1420(head)->sqh_last = &(elm)->field.sqe_next; \\1421(head)->sqh_first = (elm); \\1422} while (0)1423
1424#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \\1425(elm)->field.sqe_next = NULL; \\1426*(head)->sqh_last = (elm); \\1427(head)->sqh_last = &(elm)->field.sqe_next; \\1428} while (0)1429
1430#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \\1431if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\\1432(head)->sqh_last = &(elm)->field.sqe_next; \\1433(listelm)->field.sqe_next = (elm); \\1434} while (0)1435
1436#define SIMPLEQ_REMOVE_HEAD(head, field) do { \\1437if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \\1438(head)->sqh_last = &(head)->sqh_first; \\1439} while (0)1440
1441#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \\1442if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \\1443== NULL) \\1444(head)->sqh_last = &(elm)->field.sqe_next; \\1445} while (0)1446
1447#define SIMPLEQ_CONCAT(head1, head2) do { \\1448if (!SIMPLEQ_EMPTY((head2))) { \\1449*(head1)->sqh_last = (head2)->sqh_first; \\1450(head1)->sqh_last = (head2)->sqh_last; \\1451SIMPLEQ_INIT((head2)); \\1452} \\1453} while (0)
1454
1455/*
1456* XOR Simple queue definitions.
1457*/
1458#define XSIMPLEQ_HEAD(name, type) \\1459struct name { \\1460struct type *sqx_first; /* first element */ \\1461struct type **sqx_last; /* addr of last next element */ \\1462unsigned long sqx_cookie; \\1463}
1464
1465#define XSIMPLEQ_ENTRY(type) \\1466struct { \\1467struct type *sqx_next; /* next element */ \\1468}
1469
1470/*
1471* XOR Simple queue access methods.
1472*/
1473#define XSIMPLEQ_XOR(head, ptr) ((__typeof(ptr))((head)->sqx_cookie ^ \\1474(unsigned long)(ptr)))1475#define XSIMPLEQ_FIRST(head) XSIMPLEQ_XOR(head, ((head)->sqx_first))1476#define XSIMPLEQ_END(head) NULL
1477#define XSIMPLEQ_EMPTY(head) (XSIMPLEQ_FIRST(head) == XSIMPLEQ_END(head))
1478#define XSIMPLEQ_NEXT(head, elm, field) XSIMPLEQ_XOR(head, ((elm)->field.sqx_next))1479
1480
1481#define XSIMPLEQ_FOREACH(var, head, field) \\1482for ((var) = XSIMPLEQ_FIRST(head); \\1483(var) != XSIMPLEQ_END(head); \\1484(var) = XSIMPLEQ_NEXT(head, var, field))1485
1486#define XSIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \\1487for ((var) = XSIMPLEQ_FIRST(head); \\1488(var) && ((tvar) = XSIMPLEQ_NEXT(head, var, field), 1); \\1489(var) = (tvar))1490
1491/*
1492* XOR Simple queue functions.
1493*/
1494#define XSIMPLEQ_INIT(head) do { \\1495arc4random_buf(&(head)->sqx_cookie, sizeof((head)->sqx_cookie)); \\1496(head)->sqx_first = XSIMPLEQ_XOR(head, NULL); \\1497(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \\1498} while (0)
1499
1500#define XSIMPLEQ_INSERT_HEAD(head, elm, field) do { \\1501if (((elm)->field.sqx_next = (head)->sqx_first) == \\1502XSIMPLEQ_XOR(head, NULL)) \\1503(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\1504(head)->sqx_first = XSIMPLEQ_XOR(head, (elm)); \\1505} while (0)
1506
1507#define XSIMPLEQ_INSERT_TAIL(head, elm, field) do { \\1508(elm)->field.sqx_next = XSIMPLEQ_XOR(head, NULL); \\1509*(XSIMPLEQ_XOR(head, (head)->sqx_last)) = XSIMPLEQ_XOR(head, (elm)); \\1510(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\1511} while (0)
1512
1513#define XSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \\1514if (((elm)->field.sqx_next = (listelm)->field.sqx_next) == \\1515XSIMPLEQ_XOR(head, NULL)) \\1516(head)->sqx_last = XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\1517(listelm)->field.sqx_next = XSIMPLEQ_XOR(head, (elm)); \\1518} while (0)
1519
1520#define XSIMPLEQ_REMOVE_HEAD(head, field) do { \\1521if (((head)->sqx_first = XSIMPLEQ_XOR(head, \\1522(head)->sqx_first)->field.sqx_next) == XSIMPLEQ_XOR(head, NULL)) \\1523(head)->sqx_last = XSIMPLEQ_XOR(head, &(head)->sqx_first); \\1524} while (0)
1525
1526#define XSIMPLEQ_REMOVE_AFTER(head, elm, field) do { \\1527if (((elm)->field.sqx_next = XSIMPLEQ_XOR(head, \\1528(elm)->field.sqx_next)->field.sqx_next) \\1529== XSIMPLEQ_XOR(head, NULL)) \\1530(head)->sqx_last = \\1531XSIMPLEQ_XOR(head, &(elm)->field.sqx_next); \\1532} while (0)
1533
1534
1535/*
1536* Tail queue definitions.
1537*/
1538#define TAILQ_HEAD(name, type) \\1539struct name { \\1540struct type *tqh_first; /* first element */ \\1541struct type **tqh_last; /* addr of last next element */ \\1542}
1543
1544#define TAILQ_HEAD_INITIALIZER(head) \\1545{ NULL, &(head).tqh_first }
1546
1547#define TAILQ_ENTRY(type) \\1548struct { \\1549struct type *tqe_next; /* next element */ \\1550struct type **tqe_prev; /* address of previous next element */ \\1551}
1552
1553/*
1554* Tail queue access methods.
1555*/
1556#define TAILQ_FIRST(head) ((head)->tqh_first)1557#define TAILQ_END(head) NULL1558#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)1559#define TAILQ_LAST(head, headname) \\1560(*(((struct headname *)((head)->tqh_last))->tqh_last))1561/* XXX */
1562#define TAILQ_PREV(elm, headname, field) \\1563(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))1564#define TAILQ_EMPTY(head) \\1565(TAILQ_FIRST(head) == TAILQ_END(head))
1566
1567#define TAILQ_FOREACH(var, head, field) \\1568for((var) = TAILQ_FIRST(head); \\1569(var) != TAILQ_END(head); \\1570(var) = TAILQ_NEXT(var, field))1571
1572#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \\1573for ((var) = TAILQ_FIRST(head); \\1574(var) != TAILQ_END(head) && \\1575((tvar) = TAILQ_NEXT(var, field), 1); \\1576(var) = (tvar))1577
1578
1579#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \\1580for((var) = TAILQ_LAST(head, headname); \\1581(var) != TAILQ_END(head); \\1582(var) = TAILQ_PREV(var, headname, field))1583
1584#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \\1585for ((var) = TAILQ_LAST(head, headname); \\1586(var) != TAILQ_END(head) && \\1587((tvar) = TAILQ_PREV(var, headname, field), 1); \\1588(var) = (tvar))1589
1590/*
1591* Tail queue functions.
1592*/
1593#define TAILQ_INIT(head) do { \\1594(head)->tqh_first = NULL; \\1595(head)->tqh_last = &(head)->tqh_first; \\1596} while (0)
1597
1598#define TAILQ_INSERT_HEAD(head, elm, field) do { \\1599if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \\1600(head)->tqh_first->field.tqe_prev = \\1601&(elm)->field.tqe_next; \\1602else \\
1603(head)->tqh_last = &(elm)->field.tqe_next; \\1604(head)->tqh_first = (elm); \\1605(elm)->field.tqe_prev = &(head)->tqh_first; \\1606} while (0)1607
1608#define TAILQ_INSERT_TAIL(head, elm, field) do { \\1609(elm)->field.tqe_next = NULL; \\1610(elm)->field.tqe_prev = (head)->tqh_last; \\1611*(head)->tqh_last = (elm); \\1612(head)->tqh_last = &(elm)->field.tqe_next; \\1613} while (0)1614
1615#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \\1616if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\\1617(elm)->field.tqe_next->field.tqe_prev = \\1618&(elm)->field.tqe_next; \\1619else \\
1620(head)->tqh_last = &(elm)->field.tqe_next; \\1621(listelm)->field.tqe_next = (elm); \\1622(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \\1623} while (0)1624
1625#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \\1626(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \\1627(elm)->field.tqe_next = (listelm); \\1628*(listelm)->field.tqe_prev = (elm); \\1629(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \\1630} while (0)1631
1632#define TAILQ_REMOVE(head, elm, field) do { \\1633if (((elm)->field.tqe_next) != NULL) \\1634(elm)->field.tqe_next->field.tqe_prev = \\1635(elm)->field.tqe_prev; \\1636else \\
1637(head)->tqh_last = (elm)->field.tqe_prev; \\1638*(elm)->field.tqe_prev = (elm)->field.tqe_next; \\1639_Q_INVALIDATE((elm)->field.tqe_prev); \\1640_Q_INVALIDATE((elm)->field.tqe_next); \\1641} while (0)1642
1643#define TAILQ_REPLACE(head, elm, elm2, field) do { \\1644if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \\1645(elm2)->field.tqe_next->field.tqe_prev = \\1646&(elm2)->field.tqe_next; \\1647else \\
1648(head)->tqh_last = &(elm2)->field.tqe_next; \\1649(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \\1650*(elm2)->field.tqe_prev = (elm2); \\1651_Q_INVALIDATE((elm)->field.tqe_prev); \\1652_Q_INVALIDATE((elm)->field.tqe_next); \\1653} while (0)1654
1655#define TAILQ_CONCAT(head1, head2, field) do { \\1656if (!TAILQ_EMPTY(head2)) { \\1657*(head1)->tqh_last = (head2)->tqh_first; \\1658(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \\1659(head1)->tqh_last = (head2)->tqh_last; \\1660TAILQ_INIT((head2)); \\1661} \\1662} while (0)
1663
1664__HEREDOC__
1665fi
1666
1667if [ ${HAVE_SYS_TREE} -eq 0 ]; then1668cat << __HEREDOC__1669/*
1670* A compatible version of OpenBSD <sys/tree.h>.
1671*/
1672/*
1673* Copyright 2002 Niels Provos <provos@citi.umich.edu>
1674* All rights reserved.
1675*
1676* Redistribution and use in source and binary forms, with or without
1677* modification, are permitted provided that the following conditions
1678* are met:
1679* 1. Redistributions of source code must retain the above copyright
1680* notice, this list of conditions and the following disclaimer.
1681* 2. Redistributions in binary form must reproduce the above copyright
1682* notice, this list of conditions and the following disclaimer in the
1683* documentation and/or other materials provided with the distribution.
1684*
1685* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
1686* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1687* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1688* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1689* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1690* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1691* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1692* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1693* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1694* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1695*/
1696
1697/* OPENBSD ORIGINAL: sys/sys/tree.h */
1698
1699/*
1700* This file defines data structures for different types of trees:
1701* splay trees and red-black trees.
1702*
1703* A splay tree is a self-organizing data structure. Every operation
1704* on the tree causes a splay to happen. The splay moves the requested
1705* node to the root of the tree and partly rebalances it.
1706*
1707* This has the benefit that request locality causes faster lookups as
1708* the requested nodes move to the top of the tree. On the other hand,
1709* every lookup causes memory writes.
1710*
1711* The Balance Theorem bounds the total access time for m operations
1712* and n inserts on an initially empty tree as O((m + n)lg n). The1713* amortized cost for a sequence of m accesses to a splay tree is O(lg n);1714*1715* A red-black tree is a binary search tree with the node color as an1716* extra attribute. It fulfills a set of conditions:1717* - every search path from the root to a leaf consists of the1718* same number of black nodes,1719* - each red node (except for the root) has a black parent,1720* - each leaf node is black.1721*1722* Every operation on a red-black tree is bounded as O(lg n).1723* The maximum height of a red-black tree is 2lg (n+1).1724*/1725
1726#define SPLAY_HEAD(name, type) \\1727struct name { \\
1728struct type *sph_root; /* root of the tree */ \\1729}
1730
1731#define SPLAY_INITIALIZER(root) \\1732{ NULL }
1733
1734#define SPLAY_INIT(root) do { \\1735(root)->sph_root = NULL; \\1736} while (0)1737
1738#define SPLAY_ENTRY(type) \\1739struct { \\
1740struct type *spe_left; /* left element */ \\1741struct type *spe_right; /* right element */ \\1742}
1743
1744#define SPLAY_LEFT(elm, field) (elm)->field.spe_left1745#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right1746#define SPLAY_ROOT(head) (head)->sph_root1747#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)1748
1749/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */1750#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \\1751SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \\1752SPLAY_RIGHT(tmp, field) = (head)->sph_root; \\1753(head)->sph_root = tmp; \\1754} while (0)1755
1756#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \\1757SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \\1758SPLAY_LEFT(tmp, field) = (head)->sph_root; \\1759(head)->sph_root = tmp; \\1760} while (0)1761
1762#define SPLAY_LINKLEFT(head, tmp, field) do { \\1763SPLAY_LEFT(tmp, field) = (head)->sph_root; \\1764tmp = (head)->sph_root; \\1765(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \\1766} while (0)1767
1768#define SPLAY_LINKRIGHT(head, tmp, field) do { \\1769SPLAY_RIGHT(tmp, field) = (head)->sph_root; \\1770tmp = (head)->sph_root; \\1771(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \\1772} while (0)1773
1774#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \\1775SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \\1776SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\\1777SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \\1778SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \\1779} while (0)1780
1781/* Generates prototypes and inline functions */1782
1783#define SPLAY_PROTOTYPE(name, type, field, cmp) \\1784void name##_SPLAY(struct name *, struct type *); \\1785void name##_SPLAY_MINMAX(struct name *, int); \\1786struct type *name##_SPLAY_INSERT(struct name *, struct type *); \\1787struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \\1788\\
1789/* Finds the node with the same key as elm */ \\1790static __inline struct type * \\1791name##_SPLAY_FIND(struct name *head, struct type *elm) \\1792{ \\
1793if (SPLAY_EMPTY(head)) \\1794return(NULL); \\1795name##_SPLAY(head, elm); \\1796if ((cmp)(elm, (head)->sph_root) == 0) \\1797return (head->sph_root); \\1798return (NULL); \\1799} \\
1800\\
1801static __inline struct type * \\1802name##_SPLAY_NEXT(struct name *head, struct type *elm) \\1803{ \\
1804name##_SPLAY(head, elm); \\1805if (SPLAY_RIGHT(elm, field) != NULL) { \\1806elm = SPLAY_RIGHT(elm, field); \\1807while (SPLAY_LEFT(elm, field) != NULL) { \\1808elm = SPLAY_LEFT(elm, field); \\1809} \\
1810} else \\
1811elm = NULL; \\1812return (elm); \\1813} \\
1814\\
1815static __inline struct type * \\1816name##_SPLAY_MIN_MAX(struct name *head, int val) \\1817{ \\
1818name##_SPLAY_MINMAX(head, val); \\1819return (SPLAY_ROOT(head)); \\1820}
1821
1822/* Main splay operation.
1823* Moves node close to the key of elm to top
1824*/
1825#define SPLAY_GENERATE(name, type, field, cmp) \\1826struct type * \\1827name##_SPLAY_INSERT(struct name *head, struct type *elm) \\1828{ \\1829if (SPLAY_EMPTY(head)) { \\1830SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \\1831} else { \\1832int __comp; \\1833name##_SPLAY(head, elm); \\1834__comp = (cmp)(elm, (head)->sph_root); \\1835if(__comp < 0) { \\1836SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\\1837SPLAY_RIGHT(elm, field) = (head)->sph_root; \\1838SPLAY_LEFT((head)->sph_root, field) = NULL; \\1839} else if (__comp > 0) { \\1840SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\\1841SPLAY_LEFT(elm, field) = (head)->sph_root; \\1842SPLAY_RIGHT((head)->sph_root, field) = NULL; \\1843} else \\
1844return ((head)->sph_root); \\1845} \\
1846(head)->sph_root = (elm); \\1847return (NULL); \\1848} \\
1849\\
1850struct type * \\1851name##_SPLAY_REMOVE(struct name *head, struct type *elm) \\1852{ \\
1853struct type *__tmp; \\1854if (SPLAY_EMPTY(head)) \\1855return (NULL); \\1856name##_SPLAY(head, elm); \\1857if ((cmp)(elm, (head)->sph_root) == 0) { \\1858if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \\1859(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\\1860} else { \\
1861__tmp = SPLAY_RIGHT((head)->sph_root, field); \\1862(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\\1863name##_SPLAY(head, elm); \\1864SPLAY_RIGHT((head)->sph_root, field) = __tmp; \\1865} \\
1866return (elm); \\1867} \\
1868return (NULL); \\1869} \\
1870\\
1871void \\
1872name##_SPLAY(struct name *head, struct type *elm) \\1873{ \\
1874struct type __node, *__left, *__right, *__tmp; \\1875int __comp; \\1876\\
1877SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\1878__left = __right = &__node; \\1879\\
1880while ((__comp = (cmp)(elm, (head)->sph_root))) { \\1881if (__comp < 0) { \\1882__tmp = SPLAY_LEFT((head)->sph_root, field); \\1883if (__tmp == NULL) \\1884break; \\1885if ((cmp)(elm, __tmp) < 0){ \\1886SPLAY_ROTATE_RIGHT(head, __tmp, field); \\1887if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\1888break; \\1889} \\
1890SPLAY_LINKLEFT(head, __right, field); \\1891} else if (__comp > 0) { \\1892__tmp = SPLAY_RIGHT((head)->sph_root, field); \\1893if (__tmp == NULL) \\1894break; \\1895if ((cmp)(elm, __tmp) > 0){ \\1896SPLAY_ROTATE_LEFT(head, __tmp, field); \\1897if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\1898break; \\1899} \\
1900SPLAY_LINKRIGHT(head, __left, field); \\1901} \\
1902} \\
1903SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \\1904} \\
1905\\
1906/* Splay with either the minimum or the maximum element \\1907* Used to find minimum or maximum element in tree. \\1908*/ \\1909void name##_SPLAY_MINMAX(struct name *head, int __comp) \\1910{ \\
1911struct type __node, *__left, *__right, *__tmp; \\1912\\
1913SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\\1914__left = __right = &__node; \\1915\\
1916while (1) { \\1917if (__comp < 0) { \\1918__tmp = SPLAY_LEFT((head)->sph_root, field); \\1919if (__tmp == NULL) \\1920break; \\1921if (__comp < 0){ \\1922SPLAY_ROTATE_RIGHT(head, __tmp, field); \\1923if (SPLAY_LEFT((head)->sph_root, field) == NULL)\\1924break; \\1925} \\
1926SPLAY_LINKLEFT(head, __right, field); \\1927} else if (__comp > 0) { \\1928__tmp = SPLAY_RIGHT((head)->sph_root, field); \\1929if (__tmp == NULL) \\1930break; \\1931if (__comp > 0) { \\1932SPLAY_ROTATE_LEFT(head, __tmp, field); \\1933if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\\1934break; \\1935} \\
1936SPLAY_LINKRIGHT(head, __left, field); \\1937} \\
1938} \\
1939SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \\1940}
1941
1942#define SPLAY_NEGINF -11943#define SPLAY_INF 11944
1945#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)1946#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)1947#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)1948#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)1949#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \\1950: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))1951#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \\1952: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
1953
1954#define SPLAY_FOREACH(x, name, head) \\1955for ((x) = SPLAY_MIN(name, head); \\1956(x) != NULL; \\1957(x) = SPLAY_NEXT(name, head, x))1958
1959/* Macros that define a red-black tree */
1960#define RB_HEAD(name, type) \\1961struct name { \\1962struct type *rbh_root; /* root of the tree */ \\1963}
1964
1965#define RB_INITIALIZER(root) \\1966{ NULL }
1967
1968#define RB_INIT(root) do { \\1969(root)->rbh_root = NULL; \\1970} while (0)
1971
1972#define RB_BLACK 0
1973#define RB_RED 1
1974#define RB_ENTRY(type) \\1975struct { \\1976struct type *rbe_left; /* left element */ \\1977struct type *rbe_right; /* right element */ \\1978struct type *rbe_parent; /* parent element */ \\1979int rbe_color; /* node color */ \\1980}
1981
1982#define RB_LEFT(elm, field) (elm)->field.rbe_left
1983#define RB_RIGHT(elm, field) (elm)->field.rbe_right
1984#define RB_PARENT(elm, field) (elm)->field.rbe_parent
1985#define RB_COLOR(elm, field) (elm)->field.rbe_color
1986#define RB_ROOT(head) (head)->rbh_root
1987#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
1988
1989#define RB_SET(elm, parent, field) do { \\1990RB_PARENT(elm, field) = parent; \\1991RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \\1992RB_COLOR(elm, field) = RB_RED; \\1993} while (0)
1994
1995#define RB_SET_BLACKRED(black, red, field) do { \\1996RB_COLOR(black, field) = RB_BLACK; \\1997RB_COLOR(red, field) = RB_RED; \\1998} while (0)
1999
2000#ifndef RB_AUGMENT
2001#define RB_AUGMENT(x) do {} while (0)
2002#endif
2003
2004#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \\2005(tmp) = RB_RIGHT(elm, field); \\2006if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \\2007RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \\2008} \\2009RB_AUGMENT(elm); \\2010if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \\2011if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\2012RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \\2013else \\2014RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\2015} else \\2016(head)->rbh_root = (tmp); \\2017RB_LEFT(tmp, field) = (elm); \\2018RB_PARENT(elm, field) = (tmp); \\2019RB_AUGMENT(tmp); \\2020if ((RB_PARENT(tmp, field))) \\2021RB_AUGMENT(RB_PARENT(tmp, field)); \\2022} while (0)
2023
2024#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \\2025(tmp) = RB_LEFT(elm, field); \\2026if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \\2027RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \\2028} \\2029RB_AUGMENT(elm); \\2030if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \\2031if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \\2032RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \\2033else \\2034RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \\2035} else \\2036(head)->rbh_root = (tmp); \\2037RB_RIGHT(tmp, field) = (elm); \\2038RB_PARENT(elm, field) = (tmp); \\2039RB_AUGMENT(tmp); \\2040if ((RB_PARENT(tmp, field))) \\2041RB_AUGMENT(RB_PARENT(tmp, field)); \\2042} while (0)
2043
2044/* Generates prototypes and inline functions */
2045#define RB_PROTOTYPE(name, type, field, cmp) \\2046RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
2047#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \\2048RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)2049#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \\2050attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \\2051attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\\2052attr struct type *name##_RB_REMOVE(struct name *, struct type *); \\2053attr struct type *name##_RB_INSERT(struct name *, struct type *); \\2054attr struct type *name##_RB_FIND(struct name *, struct type *); \\2055attr struct type *name##_RB_NFIND(struct name *, struct type *); \\2056attr struct type *name##_RB_NEXT(struct type *); \\2057attr struct type *name##_RB_PREV(struct type *); \\2058attr struct type *name##_RB_MINMAX(struct name *, int); \\2059\\2060
2061/* Main rb operation.
2062* Moves node close to the key of elm to top
2063*/
2064#define RB_GENERATE(name, type, field, cmp) \\2065RB_GENERATE_INTERNAL(name, type, field, cmp,)
2066#define RB_GENERATE_STATIC(name, type, field, cmp) \\2067RB_GENERATE_INTERNAL(name, type, field, cmp, __attribute__((__unused__)) static)2068#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \\2069attr void \\2070name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \\2071{ \\2072struct type *parent, *gparent, *tmp; \\2073while ((parent = RB_PARENT(elm, field)) && \\2074RB_COLOR(parent, field) == RB_RED) { \\2075gparent = RB_PARENT(parent, field); \\2076if (parent == RB_LEFT(gparent, field)) { \\2077tmp = RB_RIGHT(gparent, field); \\2078if (tmp && RB_COLOR(tmp, field) == RB_RED) { \\2079RB_COLOR(tmp, field) = RB_BLACK; \\2080RB_SET_BLACKRED(parent, gparent, field);\\2081elm = gparent; \\2082continue; \\2083} \\2084if (RB_RIGHT(parent, field) == elm) { \\2085RB_ROTATE_LEFT(head, parent, tmp, field);\\2086tmp = parent; \\2087parent = elm; \\2088elm = tmp; \\2089} \\2090RB_SET_BLACKRED(parent, gparent, field); \\2091RB_ROTATE_RIGHT(head, gparent, tmp, field); \\2092} else { \\2093tmp = RB_LEFT(gparent, field); \\2094if (tmp && RB_COLOR(tmp, field) == RB_RED) { \\2095RB_COLOR(tmp, field) = RB_BLACK; \\2096RB_SET_BLACKRED(parent, gparent, field);\\2097elm = gparent; \\2098continue; \\2099} \\2100if (RB_LEFT(parent, field) == elm) { \\2101RB_ROTATE_RIGHT(head, parent, tmp, field);\\2102tmp = parent; \\2103parent = elm; \\2104elm = tmp; \\2105} \\2106RB_SET_BLACKRED(parent, gparent, field); \\2107RB_ROTATE_LEFT(head, gparent, tmp, field); \\2108} \\2109} \\2110RB_COLOR(head->rbh_root, field) = RB_BLACK; \\2111} \\2112\\2113attr void \\2114name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \\2115{ \\2116struct type *tmp; \\2117while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \\2118elm != RB_ROOT(head)) { \\2119if (RB_LEFT(parent, field) == elm) { \\2120tmp = RB_RIGHT(parent, field); \\2121if (RB_COLOR(tmp, field) == RB_RED) { \\2122RB_SET_BLACKRED(tmp, parent, field); \\2123RB_ROTATE_LEFT(head, parent, tmp, field);\\2124tmp = RB_RIGHT(parent, field); \\2125} \\2126if ((RB_LEFT(tmp, field) == NULL || \\2127RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\2128(RB_RIGHT(tmp, field) == NULL || \\2129RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\2130RB_COLOR(tmp, field) = RB_RED; \\2131elm = parent; \\2132parent = RB_PARENT(elm, field); \\2133} else { \\2134if (RB_RIGHT(tmp, field) == NULL || \\2135RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\\2136struct type *oleft; \\2137if ((oleft = RB_LEFT(tmp, field)))\\2138RB_COLOR(oleft, field) = RB_BLACK;\\2139RB_COLOR(tmp, field) = RB_RED; \\2140RB_ROTATE_RIGHT(head, tmp, oleft, field);\\2141tmp = RB_RIGHT(parent, field); \\2142} \\2143RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\2144RB_COLOR(parent, field) = RB_BLACK; \\2145if (RB_RIGHT(tmp, field)) \\2146RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\\2147RB_ROTATE_LEFT(head, parent, tmp, field);\\2148elm = RB_ROOT(head); \\2149break; \\2150} \\2151} else { \\2152tmp = RB_LEFT(parent, field); \\2153if (RB_COLOR(tmp, field) == RB_RED) { \\2154RB_SET_BLACKRED(tmp, parent, field); \\2155RB_ROTATE_RIGHT(head, parent, tmp, field);\\2156tmp = RB_LEFT(parent, field); \\2157} \\2158if ((RB_LEFT(tmp, field) == NULL || \\2159RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\\2160(RB_RIGHT(tmp, field) == NULL || \\2161RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\\2162RB_COLOR(tmp, field) = RB_RED; \\2163elm = parent; \\2164parent = RB_PARENT(elm, field); \\2165} else { \\2166if (RB_LEFT(tmp, field) == NULL || \\2167RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\\2168struct type *oright; \\2169if ((oright = RB_RIGHT(tmp, field)))\\2170RB_COLOR(oright, field) = RB_BLACK;\\2171RB_COLOR(tmp, field) = RB_RED; \\2172RB_ROTATE_LEFT(head, tmp, oright, field);\\2173tmp = RB_LEFT(parent, field); \\2174} \\2175RB_COLOR(tmp, field) = RB_COLOR(parent, field);\\2176RB_COLOR(parent, field) = RB_BLACK; \\2177if (RB_LEFT(tmp, field)) \\2178RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\\2179RB_ROTATE_RIGHT(head, parent, tmp, field);\\2180elm = RB_ROOT(head); \\2181break; \\2182} \\2183} \\2184} \\2185if (elm) \\2186RB_COLOR(elm, field) = RB_BLACK; \\2187} \\2188\\2189attr struct type * \\2190name##_RB_REMOVE(struct name *head, struct type *elm) \\2191{ \\2192struct type *child, *parent, *old = elm; \\2193int color; \\2194if (RB_LEFT(elm, field) == NULL) \\2195child = RB_RIGHT(elm, field); \\2196else if (RB_RIGHT(elm, field) == NULL) \\2197child = RB_LEFT(elm, field); \\2198else { \\2199struct type *left; \\2200elm = RB_RIGHT(elm, field); \\2201while ((left = RB_LEFT(elm, field))) \\2202elm = left; \\2203child = RB_RIGHT(elm, field); \\2204parent = RB_PARENT(elm, field); \\2205color = RB_COLOR(elm, field); \\2206if (child) \\2207RB_PARENT(child, field) = parent; \\2208if (parent) { \\2209if (RB_LEFT(parent, field) == elm) \\2210RB_LEFT(parent, field) = child; \\2211else \\2212RB_RIGHT(parent, field) = child; \\2213RB_AUGMENT(parent); \\2214} else \\2215RB_ROOT(head) = child; \\2216if (RB_PARENT(elm, field) == old) \\2217parent = elm; \\2218(elm)->field = (old)->field; \\2219if (RB_PARENT(old, field)) { \\2220if (RB_LEFT(RB_PARENT(old, field), field) == old)\\2221RB_LEFT(RB_PARENT(old, field), field) = elm;\\2222else \\2223RB_RIGHT(RB_PARENT(old, field), field) = elm;\\2224RB_AUGMENT(RB_PARENT(old, field)); \\2225} else \\2226RB_ROOT(head) = elm; \\2227RB_PARENT(RB_LEFT(old, field), field) = elm; \\2228if (RB_RIGHT(old, field)) \\2229RB_PARENT(RB_RIGHT(old, field), field) = elm; \\2230if (parent) { \\2231left = parent; \\2232do { \\2233RB_AUGMENT(left); \\2234} while ((left = RB_PARENT(left, field))); \\2235} \\2236goto color; \\2237} \\2238parent = RB_PARENT(elm, field); \\2239color = RB_COLOR(elm, field); \\2240if (child) \\2241RB_PARENT(child, field) = parent; \\2242if (parent) { \\2243if (RB_LEFT(parent, field) == elm) \\2244RB_LEFT(parent, field) = child; \\2245else \\2246RB_RIGHT(parent, field) = child; \\2247RB_AUGMENT(parent); \\2248} else \\2249RB_ROOT(head) = child; \\2250color: \\2251if (color == RB_BLACK) \\2252name##_RB_REMOVE_COLOR(head, parent, child); \\2253return (old); \\2254} \\2255\\2256/* Inserts a node into the RB tree */ \\2257attr struct type * \\2258name##_RB_INSERT(struct name *head, struct type *elm) \\2259{ \\2260struct type *tmp; \\2261struct type *parent = NULL; \\2262int comp = 0; \\2263tmp = RB_ROOT(head); \\2264while (tmp) { \\2265parent = tmp; \\2266comp = (cmp)(elm, parent); \\2267if (comp < 0) \\2268tmp = RB_LEFT(tmp, field); \\2269else if (comp > 0) \\2270tmp = RB_RIGHT(tmp, field); \\2271else \\2272return (tmp); \\2273} \\2274RB_SET(elm, parent, field); \\2275if (parent != NULL) { \\2276if (comp < 0) \\2277RB_LEFT(parent, field) = elm; \\2278else \\2279RB_RIGHT(parent, field) = elm; \\2280RB_AUGMENT(parent); \\2281} else \\2282RB_ROOT(head) = elm; \\2283name##_RB_INSERT_COLOR(head, elm); \\2284return (NULL); \\2285} \\2286\\2287/* Finds the node with the same key as elm */ \\2288attr struct type * \\2289name##_RB_FIND(struct name *head, struct type *elm) \\2290{ \\2291struct type *tmp = RB_ROOT(head); \\2292int comp; \\2293while (tmp) { \\2294comp = cmp(elm, tmp); \\2295if (comp < 0) \\2296tmp = RB_LEFT(tmp, field); \\2297else if (comp > 0) \\2298tmp = RB_RIGHT(tmp, field); \\2299else \\2300return (tmp); \\2301} \\2302return (NULL); \\2303} \\2304\\2305/* Finds the first node greater than or equal to the search key */ \\2306attr struct type * \\2307name##_RB_NFIND(struct name *head, struct type *elm) \\2308{ \\2309struct type *tmp = RB_ROOT(head); \\2310struct type *res = NULL; \\2311int comp; \\2312while (tmp) { \\2313comp = cmp(elm, tmp); \\2314if (comp < 0) { \\2315res = tmp; \\2316tmp = RB_LEFT(tmp, field); \\2317} \\2318else if (comp > 0) \\2319tmp = RB_RIGHT(tmp, field); \\2320else \\2321return (tmp); \\2322} \\2323return (res); \\2324} \\2325\\2326/* ARGSUSED */ \\2327attr struct type * \\2328name##_RB_NEXT(struct type *elm) \\2329{ \\2330if (RB_RIGHT(elm, field)) { \\2331elm = RB_RIGHT(elm, field); \\2332while (RB_LEFT(elm, field)) \\2333elm = RB_LEFT(elm, field); \\2334} else { \\2335if (RB_PARENT(elm, field) && \\2336(elm == RB_LEFT(RB_PARENT(elm, field), field))) \\2337elm = RB_PARENT(elm, field); \\2338else { \\2339while (RB_PARENT(elm, field) && \\2340(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\\2341elm = RB_PARENT(elm, field); \\2342elm = RB_PARENT(elm, field); \\2343} \\2344} \\2345return (elm); \\2346} \\2347\\2348/* ARGSUSED */ \\2349attr struct type * \\2350name##_RB_PREV(struct type *elm) \\2351{ \\2352if (RB_LEFT(elm, field)) { \\2353elm = RB_LEFT(elm, field); \\2354while (RB_RIGHT(elm, field)) \\2355elm = RB_RIGHT(elm, field); \\2356} else { \\2357if (RB_PARENT(elm, field) && \\2358(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \\2359elm = RB_PARENT(elm, field); \\2360else { \\2361while (RB_PARENT(elm, field) && \\2362(elm == RB_LEFT(RB_PARENT(elm, field), field)))\\2363elm = RB_PARENT(elm, field); \\2364elm = RB_PARENT(elm, field); \\2365} \\2366} \\2367return (elm); \\2368} \\2369\\2370attr struct type * \\2371name##_RB_MINMAX(struct name *head, int val) \\2372{ \\2373struct type *tmp = RB_ROOT(head); \\2374struct type *parent = NULL; \\2375while (tmp) { \\2376parent = tmp; \\2377if (val < 0) \\2378tmp = RB_LEFT(tmp, field); \\2379else \\2380tmp = RB_RIGHT(tmp, field); \\2381} \\2382return (parent); \\2383}
2384
2385#define RB_NEGINF -1
2386#define RB_INF 1
2387
2388#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
2389#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
2390#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
2391#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
2392#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
2393#define RB_PREV(name, x, y) name##_RB_PREV(y)
2394#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
2395#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
2396
2397#define RB_FOREACH(x, name, head) \\2398for ((x) = RB_MIN(name, head); \\2399(x) != NULL; \\2400(x) = name##_RB_NEXT(x))2401
2402#define RB_FOREACH_SAFE(x, name, head, y) \\2403for ((x) = RB_MIN(name, head); \\2404((x) != NULL) && ((y) = name##_RB_NEXT(x), 1); \\2405(x) = (y))2406
2407#define RB_FOREACH_REVERSE(x, name, head) \\2408for ((x) = RB_MAX(name, head); \\2409(x) != NULL; \\2410(x) = name##_RB_PREV(x))2411
2412#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \\2413for ((x) = RB_MAX(name, head); \\2414((x) != NULL) && ((y) = name##_RB_PREV(x), 1); \\2415(x) = (y))2416
2417__HEREDOC__
2418fi
2419
2420if [ ${HAVE_FTS} -eq 0 ]; then2421cat << __HEREDOC__2422/*
2423* Compatibility for fts(3) functions.
2424*/
2425typedef struct {
2426struct _ftsent *fts_cur; /* current node */
2427struct _ftsent *fts_child; /* linked list of children */
2428struct _ftsent **fts_array; /* sort array */
2429dev_t fts_dev; /* starting device # */
2430char *fts_path; /* path for this descent */
2431int fts_rfd; /* fd for root */
2432size_t fts_pathlen; /* sizeof(path) */
2433int fts_nitems; /* elements in the sort array */
2434int (*fts_compar)(const struct _ftsent **, const struct _ftsent **); /* compare function */
2435#define FTS_COMFOLLOW 0x0001 /* follow command line symlinks */
2436#define FTS_LOGICAL 0x0002 /* logical walk */
2437#define FTS_NOCHDIR 0x0004 /* don't change directories */
2438#define FTS_NOSTAT 0x0008 /* don't get stat info */
2439#define FTS_PHYSICAL 0x0010 /* physical walk */
2440#define FTS_SEEDOT 0x0020 /* return dot and dot-dot */
2441#define FTS_XDEV 0x0040 /* don't cross devices */
2442#define FTS_OPTIONMASK 0x00ff /* valid user option mask */
2443#define FTS_NAMEONLY 0x1000 /* (private) child names only */
2444#define FTS_STOP 0x2000 /* (private) unrecoverable error */
2445int fts_options; /* fts_open options, global flags */
2446} FTS;
2447
2448typedef struct _ftsent {
2449struct _ftsent *fts_cycle; /* cycle node */
2450struct _ftsent *fts_parent; /* parent directory */
2451struct _ftsent *fts_link; /* next file in directory */
2452long fts_number; /* local numeric value */
2453void *fts_pointer; /* local address value */
2454char *fts_accpath; /* access path */
2455char *fts_path; /* root path */
2456int fts_errno; /* errno for this node */
2457int fts_symfd; /* fd for symlink */
2458size_t fts_pathlen; /* strlen(fts_path) */
2459size_t fts_namelen; /* strlen(fts_name) */
2460ino_t fts_ino; /* inode */
2461dev_t fts_dev; /* device */
2462nlink_t fts_nlink; /* link count */
2463#define FTS_ROOTPARENTLEVEL -1
2464#define FTS_ROOTLEVEL 0
2465#define FTS_MAXLEVEL 0x7fffffff
2466int fts_level; /* depth (-1 to N) */
2467#define FTS_D 1 /* preorder directory */
2468#define FTS_DC 2 /* directory that causes cycles */
2469#define FTS_DEFAULT 3 /* none of the above */
2470#define FTS_DNR 4 /* unreadable directory */
2471#define FTS_DOT 5 /* dot or dot-dot */
2472#define FTS_DP 6 /* postorder directory */
2473#define FTS_ERR 7 /* error; errno is set */
2474#define FTS_F 8 /* regular file */
2475#define FTS_INIT 9 /* initialized only */
2476#define FTS_NS 10 /* stat(2) failed */
2477#define FTS_NSOK 11 /* no stat(2) requested */
2478#define FTS_SL 12 /* symbolic link */
2479#define FTS_SLNONE 13 /* symbolic link without target */
2480unsigned short fts_info; /* user flags for FTSENT structure */
2481#define FTS_DONTCHDIR 0x01 /* don't chdir .. to the parent */
2482#define FTS_SYMFOLLOW 0x02 /* followed a symlink to get here */
2483unsigned short fts_flags; /* private flags for FTSENT structure */
2484#define FTS_AGAIN 1 /* read node again */
2485#define FTS_FOLLOW 2 /* follow symbolic link */
2486#define FTS_NOINSTR 3 /* no instructions */
2487#define FTS_SKIP 4 /* discard node */
2488unsigned short fts_instr; /* fts_set() instructions */
2489unsigned short fts_spare; /* unused */
2490struct stat *fts_statp; /* stat(2) information */
2491char fts_name[1]; /* file name */
2492} FTSENT;
2493
2494FTSENT *fts_children(FTS *, int);
2495int fts_close(FTS *);
2496FTS *fts_open(char * const *, int,
2497int (*)(const FTSENT **, const FTSENT **));
2498FTSENT *fts_read(FTS *);
2499int fts_set(FTS *, FTSENT *, int);
2500
2501__HEREDOC__
2502fi
2503
2504cat << __HEREDOC__2505#endif /*!OCONFIGURE_CONFIG_H*/
2506__HEREDOC__
2507
2508echo "config.h: written" 1>&22509echo "config.h: written" 1>&32510
2511#----------------------------------------------------------------------
2512# Now we go to generate our Makefile.configure.
2513# This file is simply a bunch of Makefile variables.
2514# They'll work in both GNUmakefile and BSDmakefile.
2515# You MIGHT want to change this.
2516#----------------------------------------------------------------------
2517
2518exec > Makefile.configure2519
2520[ -z "${BINDIR}" ] && BINDIR="${PREFIX}/bin"2521[ -z "${SBINDIR}" ] && SBINDIR="${PREFIX}/sbin"2522[ -z "${INCLUDEDIR}" ] && INCLUDEDIR="${PREFIX}/include"2523[ -z "${LIBDIR}" ] && LIBDIR="${PREFIX}/lib"2524[ -z "${MANDIR}" ] && MANDIR="${PREFIX}/man"2525[ -z "${SHAREDIR}" ] && SHAREDIR="${PREFIX}/share"2526
2527[ -z "${INSTALL_PROGRAM}" ] && INSTALL_PROGRAM="${INSTALL} -m 0555"2528[ -z "${INSTALL_LIB}" ] && INSTALL_LIB="${INSTALL} -m 0444"2529[ -z "${INSTALL_MAN}" ] && INSTALL_MAN="${INSTALL} -m 0444"2530[ -z "${INSTALL_DATA}" ] && INSTALL_DATA="${INSTALL} -m 0444"2531
2532cat << __HEREDOC__2533AR = ${AR}2534CC = ${CC}2535CFLAGS = ${CFLAGS}2536CPPFLAGS = ${CPPFLAGS}2537LDLIBS = ${LDLIBS}2538LDADD = ${LDADD}2539LDADD_B64_NTOP = ${LDADD_B64_NTOP}2540LDADD_CRYPT = ${LDADD_CRYPT}2541LDADD_LIB_SOCKET = ${LDADD_LIB_SOCKET}2542LDADD_MD5 = ${LDADD_MD5}2543LDADD_SHA2 = ${LDADD_SHA2}2544LDADD_SCAN_SCALED= ${LDADD_SCAN_SCALED}2545LDADD_STATIC = ${LDADD_STATIC}2546LDFLAGS = ${LDFLAGS}2547LINKER_SONAME = ${LINKER_SONAME}2548STATIC = ${STATIC}2549PREFIX = ${PREFIX}2550BINDIR = ${BINDIR}2551SHAREDIR = ${SHAREDIR}2552SBINDIR = ${SBINDIR}2553INCLUDEDIR = ${INCLUDEDIR}2554LIBDIR = ${LIBDIR}2555MANDIR = ${MANDIR}2556INSTALL = ${INSTALL}2557INSTALL_PROGRAM = ${INSTALL_PROGRAM}2558INSTALL_LIB = ${INSTALL_LIB}2559INSTALL_MAN = ${INSTALL_MAN}2560INSTALL_DATA = ${INSTALL_DATA}2561__HEREDOC__
2562
2563echo "Makefile.configure: written" 1>&22564echo "Makefile.configure: written" 1>&32565
2566exit 02567