dnl
dnl Configure script for readline library
dnl
dnl report bugs to chet@po.cwru.edu
dnl
dnl Process this file with autoconf to produce a configure script.

# Copyright (C) 1987-2009 Free Software Foundation, Inc.

#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or
#   (at your option) any later version.

#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.

#   You should have received a copy of the GNU General Public License
#   along with this program.  If not, see <http://www.gnu.org/licenses/>.

AC_REVISION([for Readline 6.2, version 2.67])

m4_include([../config/override.m4])

AC_INIT(readline, 6.2, bug-readline@gnu.org)

dnl make sure we are using a recent autoconf version
AC_PREREQ(2.50)

AC_CONFIG_SRCDIR(readline.h)
dnl GDB LOCAL
dnl AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_AUX_DIR(`cd $srcdir;pwd`/..)
AC_CONFIG_HEADERS(config.h)

dnl update the value of RL_READLINE_VERSION in readline.h when this changes
LIBVERSION=6.2

AC_CANONICAL_HOST
AC_CANONICAL_BUILD

dnl configure defaults
opt_curses=no
opt_purify=no

dnl arguments to configure
AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval)

if test "$opt_curses" = "yes"; then
	prefer_curses=yes
fi

if test "$opt_purify" = yes; then
	PURIFY="purify"
else
	PURIFY=
fi

dnl option parsing for optional features
opt_multibyte=yes
opt_static_libs=yes
opt_shared_libs=no

AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval)
dnl AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval)
AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval)

if test $opt_multibyte = no; then
AC_DEFINE(NO_MULTIBYTE_SUPPORT)
fi

dnl load up the cross-building cache file -- add more cases and cache
dnl files as necessary

dnl Note that host and target machine are the same, and different than the
dnl build machine.

CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
    case "${host}" in
    *-cygwin*)
        cross_cache=${srcdir}/cross-build/cygwin.cache
        ;;
    *-mingw*)
        cross_cache=${srcdir}/cross-build/mingw.cache
        ;;
    i[[3456]]86-*-beos*)
        cross_cache=${srcdir}/cross-build/x86-beos.cache
        ;;
    *)  echo "configure: cross-compiling for $host is not supported" >&2
        ;;
    esac
    if test -n "${cross_cache}" && test -r "${cross_cache}"; then
        echo "loading cross-build cache file ${cross_cache}"
        . ${cross_cache}
    fi
    unset cross_cache
    CROSS_COMPILE='-DCROSS_COMPILING'
    AC_SUBST(CROSS_COMPILE)
fi

echo ""
echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}"
echo ""

# We want these before the checks, so the checks can modify their values.
test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1

AC_PROG_MAKE_SET
AC_PROG_CC
dnl AC_AIX
AC_MINIX

# If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS.
test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O"

AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL
AC_CHECK_PROG(AR, ar, , ar)
dnl Set default for ARFLAGS, since autoconf does not have a macro for it.
dnl This allows people to set it when running configure or make
test -n "$ARFLAGS" || ARFLAGS="cr"
AC_PROG_RANLIB

MAKE_SHELL=/bin/sh
AC_SUBST(MAKE_SHELL)

AC_C_CONST
AC_C_PROTOTYPES
AC_C_CHAR_UNSIGNED
AC_C_VOLATILE

AC_TYPE_SIGNAL

AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)

AC_HEADER_STDC

AC_HEADER_STAT
AC_HEADER_DIRENT

AC_CHECK_FUNCS(fcntl kill lstat)
AC_CHECK_FUNCS(memmove putenv select setenv setlocale \
		strcasecmp strpbrk tcgetattr vsnprintf)
AC_CHECK_FUNCS(isascii isxdigit)
AC_CHECK_FUNCS(getpwent getpwnam getpwuid)

AC_FUNC_STRCOLL

AC_CHECK_HEADERS(fcntl.h unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \
		limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h)
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h)

AC_CHECK_HEADERS(sys/ptem.h,,,
[[
#if HAVE_SYS_STREAM_H
#  include <sys/stream.h>
#endif
]])

AC_SYS_LARGEFILE

BASH_SYS_SIGNAL_VINTAGE
BASH_SYS_REINSTALL_SIGHANDLERS

BASH_FUNC_POSIX_SETJMP
BASH_FUNC_LSTAT
BASH_FUNC_STRCOLL
BASH_FUNC_CTYPE_NONASCII

BASH_CHECK_GETPW_FUNCS

AC_HEADER_TIOCGWINSZ

BASH_TYPE_SIG_ATOMIC_T
BASH_TYPE_SIGHANDLER

BASH_HAVE_TIOCSTAT
BASH_HAVE_FIONREAD
BASH_CHECK_SPEED_T
BASH_STRUCT_WINSIZE
BASH_STRUCT_DIRENT_D_INO
BASH_STRUCT_DIRENT_D_FILENO

dnl yuck
case "$host_os" in
aix*)   prefer_curses=yes ;;
esac
BASH_CHECK_LIB_TERMCAP
if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then
	if test "$prefer_curses" = yes; then
		TERMCAP_LIB=-lcurses
	else
		TERMCAP_LIB=-ltermcap	#default
	fi
fi

BASH_CHECK_MULTIBYTE

case "$host_cpu" in
*cray*)	LOCAL_CFLAGS=-DCRAY ;;
*s390*) LOCAL_CFLAGS=-fsigned-char ;;
esac

case "$host_os" in
isc*)	LOCAL_CFLAGS=-Disc386 ;;
esac

# shared library configuration section
#
# Shared object configuration section.  These values are generated by
# ${srcdir}/support/shobj-conf
#
if test -f ${srcdir}/support/shobj-conf; then
        AC_MSG_CHECKING(configuration for building shared libraries)
        eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`

#	case "$SHLIB_LIBS" in
#	*curses*|*termcap*|*termlib*)	;;
#	*)			SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;;
#	esac
	
        AC_SUBST(SHOBJ_CC)
        AC_SUBST(SHOBJ_CFLAGS)
        AC_SUBST(SHOBJ_LD)
        AC_SUBST(SHOBJ_LDFLAGS)
	AC_SUBST(SHOBJ_XLDFLAGS)
        AC_SUBST(SHOBJ_LIBS)
        AC_SUBST(SHOBJ_STATUS)
	AC_SUBST(SHLIB_STATUS)
	AC_SUBST(SHLIB_XLDFLAGS)
	AC_SUBST(SHLIB_DOT)
	AC_SUBST(SHLIB_LIBPREF)
	AC_SUBST(SHLIB_LIBSUFF)
	AC_SUBST(SHLIB_LIBVERSION)
	AC_SUBST(SHLIB_DLLVERSION)
	AC_SUBST(SHLIB_LIBS)
        AC_MSG_RESULT($SHLIB_STATUS)

	# SHLIB_STATUS is either `supported' or `unsupported'.  If it's
	# `unsupported', turn off any default shared library building
	if test "$SHLIB_STATUS" = 'unsupported'; then
		opt_shared_libs=no
	fi

	# shared library versioning
	# quoted for m4 so I can use character classes
	SHLIB_MAJOR=[`expr "$LIBVERSION" : '\([0-9]\)\..*'`]
	SHLIB_MINOR=[`expr "$LIBVERSION" : '[0-9]\.\([0-9]\).*'`]
	AC_SUBST(SHLIB_MAJOR)
	AC_SUBST(SHLIB_MINOR)
fi

if test "$opt_static_libs" = "yes"; then
	STATIC_TARGET=static
	STATIC_INSTALL_TARGET=install-static
fi
if test "$opt_shared_libs" = "yes"; then
	SHARED_TARGET=shared
	SHARED_INSTALL_TARGET=install-shared
fi

AC_SUBST(STATIC_TARGET)
AC_SUBST(SHARED_TARGET)
AC_SUBST(STATIC_INSTALL_TARGET)
AC_SUBST(SHARED_INSTALL_TARGET)

case "$build_os" in
msdosdjgpp*)	BUILD_DIR=`pwd.exe` ;;	# to prevent //d/path/file
*)		BUILD_DIR=`pwd` ;;
esac

case "$BUILD_DIR" in
*\ *)	BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;;
*)	;;
esac

AC_SUBST(PURIFY)
AC_SUBST(BUILD_DIR)

AC_SUBST(CFLAGS)
AC_SUBST(LOCAL_CFLAGS)
AC_SUBST(LOCAL_LDFLAGS)
AC_SUBST(LOCAL_DEFS)

AC_SUBST(AR)
AC_SUBST(ARFLAGS)

AC_SUBST(host_cpu)
AC_SUBST(host_os)

AC_SUBST(LIBVERSION)

AC_SUBST(TERMCAP_LIB)

AC_OUTPUT([Makefile doc/Makefile examples/Makefile shlib/Makefile],
[
# Makefile uses this timestamp file to record whether config.h is up to date.
echo > stamp-h
])
