#!/bin/sh

# This configure script written by Brian Callahan <bcallah@openbsd.org>
# and released into the Public Domain.

Makefile() {
  if [ $strip -ne 0 ] ; then
    stripopt="-s"
  fi

  if [ -z "$cc" ] ; then
    cc=$CC
  fi
cat << EOF > Makefile
# This Makefile automatically generated by configure.

CC =		$cc
CFLAGS =	$cflags
EOF

if [ ! -z "$ldflags" ] ; then
cat << EOF >> Makefile
LDFLAGS =	$ldflags
EOF
fi

cat << EOF >> Makefile

PREFIX =	$prefix
BINDIR =	$bindir
MANDIR =	$mandir

PROG =	$instprog
OBJS =	alloc.o asprintf.o c_ksh.o c_sh.o c_test.o c_ulimit.o edit.o \\
	emacs.o eval.o exec.o expr.o history.o io.o jobs.o lex.o mail.o \\
	main.o misc.o path.o shf.o syn.o table.o trap.o tree.o tty.o var.o \\
	version.o vi.o confstr.o reallocarray.o siglist.o signame.o \\
	strlcat.o strlcpy.o strtonum.o unvis.o vis.o issetugid.o

all: \${PROG}

\${PROG}: \${OBJS}
EOF

if [ $compileonly -eq 0 ] ; then
cat << EOF >> Makefile
	\${CC} \${LDFLAGS} -o \${PROG} \${OBJS} $libs \${LIBS}
EOF
fi

cat << EOF >> Makefile

install:
	install -d \${DESTDIR}\${BINDIR}
	install -d \${DESTDIR}\${MANDIR}/man1
	install -c $stripopt -m 755 \${PROG} \${DESTDIR}\${BINDIR}
	install -c -m 644 \${PROG}.1 \${DESTDIR}\${MANDIR}/man1
EOF

if [ $instsh -ne 0 ] ; then
cat << EOF >> Makefile
	install -d \${DESTDIR}\${BINDIR}
	install -d \${DESTDIR}\${MANDIR}/man1
	install -c $stripopt -m 755 \${PROG} \${DESTDIR}\${BINDIR}/sh
	install -c -m 644 sh.1 \${DESTDIR}\${MANDIR}/man1
EOF
fi

cat << EOF >> Makefile
	@echo "Please add $bindir/$instprog to /etc/shells"
EOF

if [ $instsh -ne 0 ] ; then
cat << EOF >> Makefile
	@echo "Please add $bindir/sh to /etc/shells"
EOF
fi

cat << EOF >> Makefile

uninstall:
	rm -f \${DESTDIR}\${BINDIR}/\${PROG}
	rm -f \${DESTDIR}\${MANDIR}/man1/\${PROG}.1
EOF

if [ $instsh -ne 0 ] ; then
cat << EOF >> Makefile
	rm -f \${DESTDIR}\${BINDIR}/sh
	rm -f \${DESTDIR}\${MANDIR}/man1/sh.1
EOF
fi

cat << EOF >> Makefile

test:
	echo "No tests"

clean:
	rm -f \${PROG} \${OBJS}

distclean: clean
	rm -f Makefile pconfig.h *.core
EOF
}

asprintfcheck() {
  cat << EOF > conftest.c
#include <stdio.h>
int main(void){asprintf(NULL,NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

c99check() {
  cat << EOF > conftest.c
#include <stdio.h>
int main(void){long long l;for (int i=0;i<1;i++)printf("%s",__func__);return 0;}
EOF
  $cc $cflags -std=c99 -o conftest.o -c conftest.c > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

cccheck() {
  if [ ! -z "$CC" ] ; then
cat << EOF > conftest.c
int main(void){return 0;}
EOF
    $CC $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
    $CC $ldflags -o conftest conftest.o > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
      ./conftest
      if [ $? -eq 0 ] ; then
	rm -f conftest conftest.o conftest.c
	cc="$CC"
	return 0
      else
	echo "could not build working executables"
	echo "Please ensure your C compiler is a native compiler"
	exit 1
      fi
    else
      rm -f conftest conftest.o conftest.c
    fi
  fi

  for compiler in cc clang pcc tcc lacc cparser ccomp xlc gcc ; do
cat << EOF > conftest.c
int main(void){return 0;}
EOF

    $compiler $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
    $compiler $ldflags -o conftest conftest.o > /dev/null 2>&1

    if [ $? -eq 0 ] ; then
      ./conftest
      if [ $? -eq 0 ] ; then
	rm -f conftest conftest.o conftest.c
	cc="$compiler"
	return 0
      else
	echo "could not build working executables"
	echo "Please ensure your C compiler is a native compiler"
	exit 1
      fi
    else
      rm -f conftest conftest.o conftest.c
    fi
  done
  return 1
}

clockgettimecheck() {
  cat << EOF > conftest.c
#include <stdio.h>
#include <time.h>
int main(void){clock_gettime(0,NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

clockgettimertcheck() {
  cat << EOF > conftest.c
#include <stdio.h>
#include <time.h>
int main(void){clock_gettime(0,NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o -lrt > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

confstrcheck() {
  cat << EOF > conftest.c
#include <unistd.h>
int main(void){confstr(0,NULL,0);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

cursescheck() {
  cat << EOF > conftest.c
#include <term.h>
#include <curses.h>
int main(void){setupterm(NULL, 0, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o -lcurses > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

deadcheck() {
  cat << EOF > conftest.c
#include <stdlib.h>
__dead usage(void){exit(1);}int main(void){usage();return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

dead2check() {
  cat << EOF > conftest.c
#include <stdlib.h>
__dead2 usage(void){exit(1);}int main(void){usage();return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

defaultcflagscheck() {
  cat << EOF > conftest.c
int main(void){return 0;}
EOF
  $cc $cflags -g -O2 -o conftest.o -c conftest.c > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 1
  else
    rm -f conftest conftest.o conftest.c
    return 0
  fi
}

getauxvalcheck() {
  cat << EOF > conftest.c
#include <sys/auxv.h>
int main(void){getauxval(AT_SECURE);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

gnu99check() {
  cat << EOF > conftest.c
#include <stdio.h>
int main(void){long long l;for (int i=0;i<1;i++)printf("%s",__func__);return 0;}
EOF
  $cc $cflags -std=gnu99 -o conftest.o -c conftest.c > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

issetugidcheck() {
  cat << EOF > conftest.c
#include <unistd.h>
int main(void){issetugid();return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

ltoflagcheck() {
  cat << EOF > conftest.c
int main(void){return 0;}
EOF
  $cc $cflags -flto -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -flto -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 1
  else
    rm -f conftest conftest.o conftest.c
    return 0
  fi
}

ncursescheck() {
  cat << EOF > conftest.c
#include <term.h>
#include <ncurses.h>
int main(void){setupterm(NULL, 0, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c -lncurses > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o -lncurses > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

ncursesncursescheck() {
  cat << EOF > conftest.c
#include <ncurses/term.h>
#include <ncurses/ncurses.h>
int main(void){setupterm(NULL, 0, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c -lncurses > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o -lncurses > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

noc99check() {
  cat << EOF > conftest.c
#include <stdio.h>
int main(void){long long l;for (int i=0;i<1;i++)printf("%s",__func__);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

noreturncheck() {
  cat << EOF > conftest.c
#include <stdlib.h>
__attribute__((__noreturn__)) usage(void){exit(1);}int main(void){usage();return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

pledgecheck() {
  cat << EOF > conftest.c
#include <unistd.h>
int main(void){pledge(NULL,NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

# Intentionally fail on Android.
# Avoids header/library mismatches as found on
#   (at least) Termux. Doesn't hurt to use the
#   portable reallocarray in this repo.
reallocarraycheck() {
  cat << EOF > conftest.c
#include <stdlib.h>
#ifdef __ANDROID__
00ThisWillDefinitelyFail00
#endif
int main(void){reallocarray(NULL, 0, 0);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

setresgidcheck() {
  cat << EOF > conftest.c
#include <sys/types.h>
#include <unistd.h>
int main(void){setresgid(NULL, NULL, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

setresuidcheck() {
  cat << EOF > conftest.c
#include <sys/types.h>
#include <unistd.h>
int main(void){setresuid(NULL, NULL, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

siglistcheck() {
  cat << EOF > conftest.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
int main(void){printf("%s",sys_siglist[0]);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

signamecheck() {
  cat << EOF > conftest.c
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
int main(void){printf("%s",sys_signame[0]);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

sig_tcheck() {
  cat << EOF > conftest.c
#include <signal.h>
int main(void){sig_t s;return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

sranddeterministiccheck() {
  cat << EOF > conftest.c
#include <stdlib.h>
int main(void){srand_deterministic(0);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

st_mtimcheck() {
  cat << EOF > conftest.c
#include <sys/stat.h>
int main(void){struct stat s;s.st_mtim.tv_sec=0;return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

st_mtimespeccheck() {
  cat << EOF > conftest.c
#include <sys/stat.h>
int main(void){struct stat s;s.st_mtimespec.tv_sec=0;return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

stravischeck() {
  cat << EOF > conftest.c
#include <stdlib.h>
#include <vis.h>
int main(void){stravis(NULL, NULL, 0);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

strlcatcheck() {
  cat << EOF > conftest.c
#include <string.h>
int main(void){strlcat(NULL,NULL,0);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

strlcpycheck() {
  cat << EOF > conftest.c
#include <string.h>
int main(void){strlcpy(NULL,NULL,0);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

strtonumcheck() {
  cat << EOF > conftest.c
#include <stdlib.h>
int main(void){strtonum(NULL, 0, 0, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

strunvischeck() {
  cat << EOF > conftest.c
#include <stdlib.h>
#include <vis.h>
int main(void){strunvis(NULL, NULL);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

timeraddcheck() {
  cat << EOF > conftest.c
#include <sys/time.h>
int main(void){struct timeval a, b, res;timeradd(&a, &b, &res);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

timerclearcheck() {
  cat << EOF > conftest.c
#include <sys/time.h>
int main(void){struct timeval a;timerclear(&a);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

timersubcheck() {
  cat << EOF > conftest.c
#include <sys/time.h>
int main(void){struct timeval a, b, res;timersub(&a, &b, &res);return 0;}
EOF
  $cc $cflags -o conftest.o -c conftest.c > /dev/null 2>&1
  $cc $ldflags -o conftest conftest.o > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 0
  else
    rm -f conftest conftest.o conftest.c
    return 1
  fi
}

wflagcheck() {
  cat << EOF > conftest.c
int main(void){return 0;}
EOF
  $cc $cflags -w -o conftest.o -c conftest.c > /dev/null 2>&1
  if [ $? -eq 0 ] ; then
    rm -f conftest conftest.o conftest.c
    return 1
  else
    rm -f conftest conftest.o conftest.c
    return 0
  fi
}

# Option variables
if [ ! -z "$PREFIX" ] ; then
  prefix="$PREFIX"
else
  prefix="/usr/local"
fi

doconfigure=1
compileonly=0
bindirset=0
mandirset=0
bindir="$prefix/bin"
mandir="$prefix/share/man"

instprog="oksh"
libs=""
curses=1
instsh=0
static=0
lto=0
strip=1

# Options
for opt
do
  case "$opt" in
    --prefix=*)
	prefix=${opt#*=}
	if [ $bindirset -eq 0 ] ; then
	  bindir="$prefix/bin"
	fi
	if [ $mandirset -eq 0 ] ; then
	  mandir="$prefix/share/man"
	fi
	;;
    --bindir=*)
	bindir=${opt#*=}
	bindirset=1
	;;
    --mandir=*)
	mandir=${opt#*=}
	mandirset=1
	;;
    --disable-curses|--enable-curses)
	if [ "x$opt" = "x--disable-curses" ] ; then
	  curses=0
	else
	  curses=1
	fi
	;;
    --disable-ksh|--enable-ksh)
	if [ "x$opt" = "x--enable-ksh" ] ; then
	  instprog="ksh"
	else
	  instprog="oksh"
	fi
	;;
    --disable-sh|--enable-sh)
	if [ "x$opt" = "x--enable-sh" ] ; then
	  instsh=1
	else
	  instsh=0
	fi
	;;
    --disable-static|--enable-static)
	if [ "x$opt" = "x--enable-static" ] ; then
	  static=1
	else
	  static=0
	fi
	;;
    --disable-lto|--enable-lto)
	if [ "x$opt" = "x--enable-lto" ] ; then
	  lto=1
	else
	  lto=0
	fi
	;;
    --no-thanks)
	doconfigure=0
	;;
    --no-link)
	compileonly=1
	;;
    --no-strip)
	strip=0
	;;
    --help|-h)
	echo "Usage: configure [options]"
	echo ""
	echo "Options:"
	printf "  --help or -h            "
	echo "Display this help message"
	printf "  --prefix=PREFIX         "
	echo "Top level install directory is PREFIX [$prefix]"
	printf "  --bindir=BINDIR         "
	echo "Install executable to BINDIR [$bindir]"
	printf "  --mandir=MANDIR         "
	echo "Install manual pages to MANDIR [$mandir]"
	printf "  --enable-curses         "
	echo "Use curses library for screen clear [default=yes]"
	printf "  --enable-ksh            "
	echo "Install executable as ksh [default=no]"
	printf "  --enable-lto            "
	echo "Enable link-time optimization [default=no]"
	printf "  --enable-sh             "
	echo "Install additional sh executable [default=no]"
	printf "  --enable-static         "
	echo "Statically link executables [default=no]"
	printf "  --no-thanks             "
	echo "Skip all configure checks"
	printf "  --no-link               "
	echo "Compile only, do not link (requires --no-thanks)"
	printf "  --no-strip              "
	echo "Do not strip executables at install [default=strip]"
	exit 1
	;;
    *)
	;;
  esac
done

if [ ! -z "$CFLAGS" ] ; then
  cflags="$CFLAGS -DEMACS -DVI"
else
  cflags="-DEMACS -DVI"
fi

if [ ! -z "$LDFLAGS" ] ; then
  ldflags="$LDFLAGS "
else
  ldflags=""
fi

if [ $static -ne 0 ] ; then
  ldflags="${ldflags}-static"
fi

if [ $compileonly -eq 1 ] ; then
  if [ $doconfigure -eq 1 ] ; then
    echo "ERROR: --no-link requires --no-thanks"
    exit 1
  fi
fi

if [ $doconfigure -eq 0 ] ; then
  if [ -z "$CC" ] ; then
    CC=gcc
  fi
  cflags="$cflags -std=gnu99"
  echo "OK, I trust you."
  echo "I'll assume you have gcc/clang and little else."
  echo "Edit Makefile and pconfig.h if needed."
  echo "Good luck!"
  cat << EOF > pconfig.h
/* This file automatically generated by configure.  */

#ifndef __dead
#define __dead __attribute__((__noreturn__))
#endif

/* #define __attribute__(x) */

/* #define HAVE_ASPRINTF */
/* #define HAVE_CONFSTR */
#define NO_CURSES
/* #define HAVE_ISSETUGID */
/* #define HAVE_GETAUXVAL */
/* #define HAVE_PLEDGE */
/* #define HAVE_REALLOCARRAY */
/* #define HAVE_SETRESGID */
/* #define HAVE_SETRESUID */
/* #define HAVE_SIG_T */
/* #define HAVE_SRAND_DETERMINISTIC */
#define HAVE_ST_MTIM
/* #define HAVE_ST_MTIMESPEC */
/* #define HAVE_STRAVIS */
/* #define HAVE_STRLCAT */
/* #define HAVE_STRLCPY */
/* #define HAVE_STRTONUM */
/* #define HAVE_STRUNVIS */
/* #define HAVE_SIGLIST */
/* #define HAVE_SIGNAME */
/* #define HAVE_TIMERADD */
/* #define HAVE_TIMERCLEAR */
/* #define HAVE_TIMERSUB */
EOF
  Makefile

  exit 0
fi

printf "checking for C compiler... "
cccheck
if [ $? -ne 0 ] ; then
  echo "not found"
  echo "Please install a C compiler and re-run configure."
  exit 1
else
  echo "$cc"
fi

if [ "x$cflags" = "x-DEMACS -DVI" ] ; then
  printf "checking if the compiler accepts -g -O2... "
  defaultcflagscheck
  if [ $? -eq 0 ] ; then
    echo "no"
  else
    cflags="-g -O2 $cflags"
    echo "yes"
  fi
fi

printf "checking if the compiler can compile C99 without -std=c99... "
noc99check
if [ $? -ne 0 ] ; then
  echo "no"
  printf "checking if the compiler can compile C99 with -std=c99... "
  cflags="$cflags"
  c99check
  if [ $? -ne 0 ] ; then
    echo "no"
    printf "checking if the compiler can compile C99 with -std=gnu99... "
    gnu99check
    if [ $? -ne 0 ] ; then
      echo "no"
      echo "You must have a C99 compiler to build oksh!"
      exit 1
    else
      cflags="$cflags -std=gnu99"
      echo "yes"
    fi
  else
    cflags="$cflags -std=c99"
    echo "yes"
  fi
else
  echo "yes"
fi

printf "checking for -w compiler flag... "
wflagcheck
if [ $? -eq 0 ] ; then
  echo "no"
else
  cflags="$cflags -w"
  echo "yes"
fi

printf "checking for OS... "
os=`uname -s`
echo "$os"

case "x$os" in
  "xLinux"|"xCYGWIN"*)
    cflags="$cflags -D_GNU_SOURCE"
    ;;
  "xNetBSD")
    cflags="$cflags -D_OPENBSD_SOURCE"
    ;;
  "xOpenBSD")
    case "x$cc" in
      "xccomp")
	cflags="$cflags -D_ANSI_LIBRARY"
	ldflags="$ldflags -Wl,-nopie"
	;;
      "xnwcc")
	ldflags="$ldflags -Wl,-nopie"
	;;
    esac
    ;;
  "xAIX"|"xOS400")
    cflags="$cflags -D_ALL_SOURCE"
    ldflags="-lbsd"
    ;;
esac

printf "checking for -flto compiler flag... "
if [ $lto -eq 0 ] ; then
  echo "not enabled"
else
  ltoflagcheck
  if [ $lto -eq 0 ] ; then
    echo "no"
  else
    cflags="$cflags -flto"
    ldflags="$ldflags -flto -Wl,-O3"
    echo "yes"
  fi
fi

cat << EOF > pconfig.h
/* This file automatically generated by configure.  */

EOF

printf "checking for __dead... "
deadcheck
if [ $? -eq 0 ] ; then
  echo "yes"
else
  echo "no"
  printf "checking for __dead2... "
  dead2check
  if [ $? -eq 0 ] ; then
    echo "#define __dead __dead2" >> pconfig.h
    echo "yes"
  else
    echo "no"
    printf "checking for __attribute__((__noreturn__))... "
    noreturncheck
    if [ $? -eq 0 ] ; then
      echo "#define __dead __attribute__((__noreturn__))" >> pconfig.h
      echo "yes"
    else
      echo "#define __dead" >> pconfig.h
      echo "#define __attribute__(x)" >> pconfig.h
      echo "no"
    fi
  fi
fi

printf "checking for asprintf... "
asprintfcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_ASPRINTF" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for clock_gettime in libc... "
clockgettimecheck
if [ $? -eq 0 ] ; then
  echo "yes"
else
  echo "no"
  printf "checking for clock_gettime in librt... "
  clockgettimertcheck
  if [ $? -eq 0 ] ; then
    libs="$libs -lrt"
    echo "yes"
  else
    echo "no"
    echo "Error: oksh requires clock_gettime()"
    exit 1
  fi
fi

printf "checking for confstr... "
confstrcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_CONFSTR" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for curses library... "
if [ $curses -eq 1 ] ; then
  cursescheck
  if [ $? -eq 0 ] ; then
    libs="$libs -lcurses"
    echo "#define HAVE_CURSES" >> pconfig.h
    echo "curses.h"
  else
    ncursescheck
    if [ $? -eq 0 ] ; then
      libs="$libs -lncurses"
      echo "#define HAVE_NCURSES" >> pconfig.h
      echo "ncurses.h"
    else
      ncursesncursescheck
      if [ $? -eq 0 ] ; then
	libs="$libs -lncurses"
	echo "#define HAVE_NCURSESNCURSES" >> pconfig.h
	echo "ncurses/ncurses.h"
      else
	echo "#define NO_CURSES" >> pconfig.h
	echo "not found"
	echo "oksh will be built without screen clearing support"
      fi
    fi
  fi
else
  echo "#define NO_CURSES" >> pconfig.h
  echo "disabled by user"
  echo "oksh will be built without screen clearing support"
fi

printf "checking for issetugid... "
issetugidcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_ISSETUGID" >> pconfig.h
  echo "yes"
else
  echo "no"
  printf "checking for getauxval(AT_SECURE)... "
  getauxvalcheck
  if [ $? -eq 0 ] ; then
    echo "#define HAVE_GETAUXVAL" >> pconfig.h
    echo "yes"
  else
    echo "no"
  fi
fi

printf "checking for pledge... "
pledgecheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_PLEDGE" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for reallocarray... "
reallocarraycheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_REALLOCARRAY" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for setresgid... "
setresgidcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_SETRESGID" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for setresuid... "
setresuidcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_SETRESUID" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for sig_t... "
sig_tcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_SIG_T" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for srand_deterministic... "
sranddeterministiccheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_SRAND_DETERMINISTIC" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for st_mtim... "
st_mtimcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_ST_MTIM" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for st_mtimespec... "
st_mtimespeccheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_ST_MTIMESPEC" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for stravis... "
stravischeck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_STRAVIS" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for strlcat... "
strlcatcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_STRLCAT" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for strlcpy... "
strlcpycheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_STRLCPY" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for strtonum... "
strtonumcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_STRTONUM" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for strunvis... "
strunvischeck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_STRUNVIS" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for sys_siglist... "
siglistcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_SIGLIST" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for sys_signame... "
signamecheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_SIGNAME" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for timeradd... "
timeraddcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_TIMERADD" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for timerclear... "
timerclearcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_TIMERCLEAR" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "checking for timersub... "
timersubcheck
if [ $? -eq 0 ] ; then
  echo "#define HAVE_TIMERSUB" >> pconfig.h
  echo "yes"
else
  echo "no"
fi

printf "creating Makefile... "
Makefile
echo "done"
