#!/bin/sh

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

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

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

    $compiler $cflags $ldflags -o conftest conftest.c > /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
	rm -f conftest conftest.o conftest.c
	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
}

cflagscheck() {
  cat << EOF > conftest.c
int main(void){return 0;}
EOF
  $cc $cflags $1 -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
}

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 -Wl,-O3 -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
}

pledgecheck() {
  cat << EOF > conftest.c
#include <unistd.h>
int main(void){pledge(NULL,NULL);return 0;}
EOF
  $cc $cflags $ldflags -o conftest 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
}

reallocarraycheck() {
  cat << EOF > conftest.c
#include <stdlib.h>
int main(void){reallocarray(NULL, 0, 0);return 0;}
EOF
  $cc $cflags $ldflags -o conftest 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
}

strlcatcheck() {
  cat << EOF > conftest.c
#include <string.h>
int main(void){strlcat(NULL,NULL,0);return 0;}
EOF
  $cc $cflags $ldflags -o conftest 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
}

strlcpycheck() {
  cat << EOF > conftest.c
#include <string.h>
int main(void){strlcpy(NULL,NULL,0);return 0;}
EOF
  $cc $cflags $ldflags -o conftest 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
}

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

if [ ! -x "$(command -v ed)" ] ; then
  prog="ed"
else
  prog="oed"
fi

cflags=""

lto=0
static=0
setmandir=0

# Options
for opt
do
  case "$opt" in
    --prefix=*)
	prefix=`echo $opt | cut -d '=' -f 2`
	;;
    --mandir=*)
	mandir=`echo $opt | cut -d '=' -f 2`
	setmandir=1
	;;
    --cc=*)
	CC=${opt#*=}
	;;
    --cflags=*)
	CFLAGS=${opt#*=}
	;;
    --ldflags=*)
	LDFLAGS=${opt#*=}
	;;
    --disable-lto|--enable-lto)
	if [ "x$opt" = "x--enable-lto" ] ; then
	  lto=1
	else
	  lto=0
	fi
	;;
    --disable-static|--enable-static)
	if [ "x$opt" = "x--enable-static" ] ; then
	  static=1
	else
	  static=0
	fi
	;;
    --program-name=*)
	prog=`echo $opt | cut -d '=' -f 2`
	;;
    --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 "  --mandir=MANDIR         "
	echo "Manual pages are installed to MANDIR [$prefix/man]"
	printf "  --cc=CC                 "
	echo "Use specified C compiler [default=cc]"
	printf "  --cflags=CFLAGS         "
	echo "Use specified CFLAGS [default=\"-g -O2 -pipe -w\"]"
	printf "  --ldflags=LDFLAGS       "
	echo "Use specified LDFLAGS"
	printf "  --program-name=NAME     "
	echo "Install executable as NAME [default=$prog]"
	printf "  --enable-lto            "
	echo "Enable link-time optimization [default=no]"
	printf "  --enable-static         "
	echo "Statically link executables [default=no]"
	exit 1
	;;
    *)
	;;
  esac
done

if [ $setmandir -eq 0 ] ; then
  mandir="$prefix/man"
fi

if [ ! -z "$CFLAGS" ] ; then
  flags="$CFLAGS"
else
  flags=""
fi

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

if [ $static -ne 0 ] ; then
  ldflags="$ldflags -static"
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$flags" = "x" ] ; then
  flags="-g -O2 -pipe -w -I$(pwd)"
else
  flags="$flags -I$(pwd)"
fi

for flag in $flags ; do
  printf "checking whether %s accepts %s... " $cc $flag
  cflagscheck $flag
  if [ $? -eq 0 ] ; then
    echo "no"
  else
    cflags="$cflags $flag"
    echo "yes"
  fi
done

if [ $lto -eq 1 ] ; then
  printf "checking for -flto compiler flag... "
  ltoflagcheck
  if [ $? -eq 0 ] ; then
    echo "no"
  else
    cflags="$cflags -flto"
    ldflags="$ldflags -flto -Wl,-O3"
    echo "yes"
  fi
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"
    ;;
esac

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

EOF

needreallocarray=0
needstrlcat=0
needstrlcpy=0

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

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

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

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

echo "" >> config.h

if [ $needreallocarray -eq 1 ] ; then
  echo "extern void *reallocarray(void *, size_t, size_t);" >> config.h
fi

if [ $needstrlcat -eq 1 ] ; then
  echo "extern size_t strlcat(char *, const char *, size_t);" >> config.h
fi

if [ $needstrlcpy -eq 1 ] ; then
  echo "extern size_t strlcpy(char *, const char *, size_t);" >> config.h
fi

if [ ! -z "$cflags" ] ; then
  cflags="${cflags## }"
fi

if [ ! -z "$ldflags" ] ; then
  ldflags="${ldflags## }"
fi

printf "creating Makefile... "
cat << EOF > Makefile
# This Makefile automatically generated by configure.

CC =		$cc
EOF

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

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

cat << EOF >> Makefile

PREFIX =	$prefix
MANDIR =	$mandir

PROG =	$prog
OBJS =	buf.o glbl.o io.o main.o re.o sub.o undo.o \\
	regcomp.o regerror.o regexec.o regfree.o \\
	reallocarray.o strlcat.o strlcpy.o

all: \${PROG}

\${PROG}: \${OBJS}
	\${CC} \${LDFLAGS} -o \${PROG} \${OBJS}

install:
	install -d \${DESTDIR}\${PREFIX}/bin
	install -d \${DESTDIR}\${MANDIR}/man1
	install -c -s -m 755 \${PROG} \${DESTDIR}\${PREFIX}/bin
	install -c -m 644 ed.1 \${DESTDIR}\${MANDIR}/man1/\${PROG}.1

test:
	@echo "No tests"

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

distclean: clean
	rm -f Makefile config.h
EOF
echo "done"
