# Copyright (C) 1998-2002 Joe Orton <joe@manyfish.co.uk>
#
# This file is free software; you may copy and/or distribute it with
# or without modifications, as long as this notice is preserved.
# This software is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.

# The above license applies to THIS FILE ONLY, the neon library code
# itself may be copied and distributed under the terms of the GNU
# LGPL, see COPYING.LIB for more details

# This file is part of the neon HTTP/WebDAV client library.
# See http://www.webdav.org/neon/ for the latest version. 
# Please send any feedback to <neon@webdav.org>

#
# Usage:
#
#      NEON_LIBRARY
# or   NEON_BUNDLED(srcdir, [ACTIONS-IF-BUNDLED], [ACTIONS-IF-NOT_BUNDLED]) 
# or   NEON_VPATH_BUNDLED(srcdir, builddir, 
#			  [ACTIONS-IF-BUNDLED], [ACTIONS-IF-NOT-BUNDLED])
#
#   where srcdir is the location of bundled neon 'src' directory.
#   If using a VPATH-enabled build, builddir is the location of the
#   build directory corresponding to srcdir.
#
#   If a bundled build *is* being used, ACTIONS-IF-BUNDLED will be
#   evaluated. These actions should ensure that 'make' is run
#   in srcdir, and that one of NEON_NORMAL_BUILD or NEON_LIBTOOL_BUILD 
#   is called.
#
# After calling one of the above macros, if the NEON_NEED_XML_PARSER
# variable is set to "yes", then you must configure an XML parser
# too. You can do this your own way, or do it easily using the
# NEON_XML_PARSER() macro. Example usage for where we have bundled the
# neon sources in a directory called libneon, and bundled expat
# sources in a directory called 'expat'.
#
#   NEON_BUNDLED(libneon, [
#	NEON_XML_PARSER(expat)
#	NEON_NORMAL_BUILD
#   ])
#
# Alternatively, for a simple standalone app with neon as a
# dependancy, use just:
#
#   NEON_LIBRARY
# 
# and rely on the user installing neon correctly.
#
# You are free to configure an XML parser any other way you like,
# but the end result must be, either expat or libxml will get linked
# in, and HAVE_EXPAT or HAVE_LIBXML is defined appropriately.
#
# To set up the bundled build environment, call 
#
#    NEON_NORMAL_BUILD
# or
#    NEON_LIBTOOL_BUILD
# 
# depending on whether you are using libtool to build, or not.
# Both these macros take an optional argument specifying the set
# of object files you wish to build: if the argument is not given,
# all of neon will be built.

AC_DEFUN([NEON_BUNDLED],[

neon_bundled_srcdir=$1
neon_bundled_builddir=$1

NEON_COMMON_BUNDLED([$2], [$3])

])

AC_DEFUN([NEON_VPATH_BUNDLED],[

neon_bundled_srcdir=$1
neon_bundled_builddir=$2
NEON_COMMON_BUNDLED([$3], [$4])

])

AC_DEFUN([NEON_COMMON_BUNDLED],[

AC_PREREQ(2.50)

AC_ARG_WITH(included-neon,
AC_HELP_STRING([--with-included-neon], [force use of included neon library]),
[neon_force_included="$withval"],
[neon_force_included="no"])

NEON_COMMON

# The colons are here so there is something to evaluate
# in case the argument was not passed.
if test "$neon_force_included" = "yes"; then
	:
	$1
else
	:
	$2
fi

])

dnl Not got any bundled sources:
AC_DEFUN([NEON_LIBRARY],[

AC_PREREQ(2.50)
neon_force_included=no
neon_bundled_srcdir=
neon_bundled_builddir=

NEON_COMMON

])

AC_DEFUN([NEON_VERSIONS], [

# Define the current versions.
NEON_VERSION_MAJOR=0
NEON_VERSION_MINOR=19
NEON_VERSION_RELEASE=0
NEON_VERSION_TAG=

NEON_VERSION="${NEON_VERSION_MAJOR}.${NEON_VERSION_MINOR}.${NEON_VERSION_RELEASE}${NEON_VERSION_TAG}"

# The libtool interface version is "current:revision:age".  This 
# is what the libtool manual says about how to update it:
#
# if new release is forwards&backwards compatible with previous:
#    revision++
# if new release is not backwards compatible with old:
#    current++, revision=age=0
# if new release is backwards but not forwards compatible with old:
#    current++, age++, revision=0

NEON_INTERFACE_VERSION="19:0:0"

AC_DEFINE_UNQUOTED(NEON_VERSION, "${NEON_VERSION}", 
	[Define to be the neon version string])
AC_DEFINE_UNQUOTED(NEON_VERSION_MAJOR, [(${NEON_VERSION_MAJOR})],
	[Define to be major number of neon version])
AC_DEFINE_UNQUOTED(NEON_VERSION_MINOR, [(${NEON_VERSION_MINOR})],
	[Define to be minor number of neon version])

])

dnl Define the minimum required version
AC_DEFUN([NEON_REQUIRE], [
neon_require_major=$1
neon_require_minor=$2
])

dnl Check that the external library found in a given location
dnl matches the min. required version (if any).  Requires that
dnl NEON_CONFIG be set the the full path of a valid neon-config
dnl script
dnl
dnl Usage:
dnl    NEON_CHECK_VERSION([ACTIONS-IF-OKAY[, ACTIONS-IF-FAILURE]])
dnl
AC_DEFUN([NEON_CHECK_VERSION], [

if test "x$neon_require_major" = "x"; then
    # Nothing to check.
    : 
    $1
else
    # Check whether the library is of required version
    oLIBS="$LIBS"
    oCFLAGS="$CFLAGS"
    CFLAGS="$CFLAGS `$NEON_CONFIG --cflags`"
    LIBS="$LIBS `$NEON_CONFIG --libs`"
    neon_ver=`$NEON_CONFIG --version | sed -e "s/neon //g"`
    AC_MSG_CHECKING([linking against neon])
    AC_TRY_LINK([#include <ne_utils.h>], [int i = ne_version_minimum(0,0)], [
    AC_MSG_RESULT([okay])
    AC_MSG_CHECKING(for neon library version)

    AC_TRY_RUN([
#include <ne_utils.h>
    
int main(void) {
return ne_version_minimum($neon_require_major, $neon_require_minor);
}
], [
    AC_MSG_RESULT([okay (found neon $neon_ver)])
    LIBS="$oLIBS"
    CFLAGS="$oCFLAGS"
    $1
], [
    AC_MSG_RESULT([failed, found $neon_ver wanted >=$neon_require_major.$neon_require_minor])
    LIBS="$oLIBS"
    CFLAGS="$oCFLAGS"
    $2
])
], [
    AC_MSG_RESULT([failed (see config.log for details)])
    AC_MSG_NOTICE([may be an incompatible version: neon $neon_require_major.$neon_require_minor is required, found $neon_ver.])
    LIBS="$oLIBS"
    CFLAGS="$oCFLAGS"
    $2
])

fi

])

dnl NEON_CHECK_SUPPORT(feature, var)
AC_DEFUN([NEON_CHECK_SUPPORT], [
if $NEON_CONFIG --support $1 >/dev/null; then
   neon_$1_message="supported by neon"
   $2=yes
else
   neon_$1_message="not supported by neon"
   $2=no
fi
])

AC_DEFUN([NEON_USE_EXTERNAL], [
# Configure to use an external neon, given a neon-config script
# found at $NEON_CONFIG.
neon_prefix=`$NEON_CONFIG --prefix`
NEON_CHECK_VERSION([
    CFLAGS="$CFLAGS `$NEON_CONFIG --cflags`"
    NEON_LIBS="$NEON_LIBS `$NEON_CONFIG --libs`"
    neon_library_message="library in ${neon_prefix} (`$NEON_CONFIG --version`)"
    neon_xml_parser_message="using whatever neon uses"
    NEON_CHECK_SUPPORT([ssl], [NEON_SUPPORTS_SSL])
    NEON_CHECK_SUPPORT([zlib], [NEON_SUPPORTS_ZLIB])
    neon_got_library=yes
], [neon_got_library=no])
])

AC_DEFUN([NEON_COMMON],[

AC_REQUIRE([NEON_COMMON_CHECKS])

NEON_VERSIONS

AC_ARG_WITH(neon,
[  --with-neon[[=DIR]]       specify location of neon library],
[case $withval in
yes|no) neon_force_external=$withval; neon_ext_path= ;;
*) neon_force_external=yes; neon_ext_path=$withval ;;
esac;], [
neon_force_external=no
neon_ext_path=
])

if test "$neon_force_included" = "no"; then
    # There is no included neon source directory, or --with-included-neon
    # wasn't given (so we're not forced to use it).

    # Default to no external neon.
    neon_got_library=no
    if test "x$neon_ext_path" = "x"; then
	AC_PATH_PROG([NEON_CONFIG], neon-config, none)
	if test "x${NEON_CONFIG}" = "xnone"; then
	    AC_MSG_NOTICE([no external neon library found])
	elif test -x "${NEON_CONFIG}"; then
	    NEON_USE_EXTERNAL
	else
	    AC_MSG_NOTICE([ignoring non-executable ${NEON_CONFIG}])
	fi
    else
	AC_MSG_CHECKING([for neon library in $neon_ext_path])
	NEON_CONFIG="$neon_ext_path/bin/neon-config"
	if test -x ${NEON_CONFIG}; then
	    AC_MSG_RESULT([found])
	    NEON_USE_EXTERNAL
	else
	    AC_MSG_RESULT([not found])
	    # ...will fail since force_external=yes
	fi
    fi

    if test "$neon_got_library" = "no"; then 
	if test $neon_force_external = yes; then
	    AC_MSG_ERROR([could not use external neon library])
	elif test -n "$neon_bundled_srcdir"; then
	    # Couldn't find external neon, forced to use bundled sources
	    neon_force_included="yes"
	else
	    # Couldn't find neon, and don't have bundled sources
	    AC_MSG_ERROR(could not find neon)
	fi
    fi
fi

# This isn't a simple 'else' branch, since neon_force_included
# is set to yes if the search fails.

if test "$neon_force_included" = "yes"; then
    AC_MSG_NOTICE([using bundled neon ($NEON_VERSION)])
    NEON_BUILD_BUNDLED="yes"
    LIBNEON_SOURCE_CHECKS
    CFLAGS="$CFLAGS -I$neon_bundled_srcdir"
    NEON_LIBS="-L$neon_bundled_builddir -lneon $NEON_LIBS"
    NEON_NEED_XML_PARSER=yes
    neon_library_message="included libneon (${NEON_VERSION})"
else
    # Don't need to configure an XML parser
    NEON_NEED_XML_PARSER=no
    NEON_BUILD_BUNDLED="yes"
fi

AC_SUBST(NEON_BUILD_BUNDLED)

])

dnl Replacement for AC_SEARCH_LIBS, adds to NEON_LIBS instead.
AC_DEFUN([NE_SEARCH_LIBS], [
AC_MSG_CHECKING([for library containing $1])

AC_TRY_LINK_FUNC($1, [AC_MSG_RESULT(none needed)], [
ne_save_LIBS=$LIBS
LIBS="$LIBS $NEON_LIBS"
ne_found=0
for l in $2; do
    LIBS="$LIBS -l$l"
    AC_TRY_LINK_FUNC($1, [AC_MSG_RESULT([-l$l])
    NEON_LIBS="$NEON_LIBS -l$l"
    ne_found=1
    break])
done
if test $ne_found = 0; then
   AC_MSG_RESULT(not found)
   AC_MSG_ERROR([could not find library for $1])
fi
LIBS=$ne_save_LIBS
])
])

AC_DEFUN([NEON_ZLIB], [

AC_ARG_WITH(zlib, AC_HELP_STRING([--without-zlib], [disable zlib support]),
ne_use_zlib=$withval, ne_use_zlib=yes)

NEON_SUPPORTS_ZLIB=no
if test "$ne_use_zlib" = "yes"; then
    AC_CHECK_HEADER(zlib.h, [
  	AC_CHECK_LIB(z, inflate, [ 
	    NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_compress"
	    NEON_LIBS="$NEON_LIBS -lz"
	    NEON_CFLAGS="$NEON_CFLAGS -DNEON_ZLIB"
	    neon_zlib_message="found zlib in -lz"
	    NEON_SUPPORTS_ZLIB=yes	
	], [neon_zlib_message="zlib not found"])
    ], [neon_zlib_message="zlib not found"])
else
    neon_zlib_message="zlib disabled"
fi

AC_SUBST(NEON_SUPPORTS_ZLIB)

])

AC_DEFUN([NE_MACOSX], [

# Check for Mac OS X 10.1 which needs extra cpp and linker flags.

AC_MSG_CHECKING([for Mac OS X 10.1])
case `uname -s 2>/dev/null`:`uname -r 2>/dev/null` in
Darwin:5.*)
  AC_MSG_RESULT([yes])
  CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
  LDFLAGS="$LDFLAGS -flat_namespace"
;;
*) AC_MSG_RESULT([no]) ;;
esac

])

AC_DEFUN([NEON_COMMON_CHECKS], [

# These checks are done whether or not the bundled neon build
# is used.

AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_CC_STDC])
AC_REQUIRE([AC_LANG_C])
AC_REQUIRE([AC_ISC_POSIX])
AC_REQUIRE([AC_C_INLINE])
AC_REQUIRE([AC_C_CONST])

AC_REQUIRE([NE_MACOSX])

AC_REQUIRE([AC_PROG_MAKE_SET])

AC_REQUIRE([AC_HEADER_STDC])

AC_CHECK_HEADERS([errno.h stdarg.h string.h stdlib.h])

NEON_FORMAT(size_t)
NEON_FORMAT(off_t)

])

AC_DEFUN([NEON_FORMAT_PREP], [
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
])

dnl NEON_FORMAT(type[, HEADERS]) checks how to print integer
dnl type; which may be defined in HEADERS if given.
AC_DEFUN([NEON_FORMAT], [

AC_REQUIRE([NEON_FORMAT_PREP])

AC_CHECK_SIZEOF($1, [$2])

AC_CACHE_CHECK([how to print $1], [ne_cv_fmt_$1], [
ne_cv_fmt_$1=none
if test "$GCC" = yes; then
  oflags="$CPPFLAGS"
  # Consider format string mismatches as errors
  CPPFLAGS="$CPPFLAGS -Wformat -Werror"
  for str in d ld qd; do
    AC_TRY_COMPILE([#include <sys/types.h>
$2
#include <stdio.h>], [$1 i = 1; printf("%$str", i);], 
	[ne_cv_fmt_$1=$str; break])
  done
  CPPFLAGS=$oflags
else
  # Best guess. Don't have to be too precise since we probably won't
  # get a warning message anyway.
  case $ac_cv_sizeof_$1 in
  $ac_cv_sizeof_int) ne_cv_fmt_$1="d" ;;
  $ac_cv_sizeof_long) ne_cv_fmt_$1="ld" ;;
  # Maybe lld is a better guess for non-gcc
  $ac_cv_sizeof_long_long) ne_cv_fmt_$1="lld" ;;
  esac
fi
])

if test "x$ne_cv_fmt_$1" = "xnone"; then
  AC_MSG_ERROR([format string for $1 not found])
fi

AC_DEFINE_UNQUOTED([NE_FMT_]translit($1, a-z, A-Z), "$ne_cv_fmt_$1", 
	[Define to be printf format string for $1])
])

dnl Call these checks when compiling the libneon source package.

AC_DEFUN([LIBNEON_SOURCE_CHECKS],[

dnl Run all the normal C language/compiler tests
AC_REQUIRE([NEON_COMMON_CHECKS])

dnl Needed for building the MD5 code.
AC_REQUIRE([AC_C_BIGENDIAN])

AC_CHECK_HEADERS([strings.h sys/time.h limits.h sys/select.h arpa/inet.h \
	signal.h sys/socket.h netinet/in.h])

AC_REPLACE_FUNCS(strcasecmp)

AC_CHECK_FUNCS(signal setvbuf setsockopt)

dnl Unixware 7 can only link gethostbyname with -lnsl -lsocket
dnl So, pick up -lsocket first, then the gethostbyname check
dnl will work.
NE_SEARCH_LIBS(socket, socket inet)

NE_SEARCH_LIBS(gethostbyname, nsl)

AC_MSG_CHECKING([for SIGPIPE in signal.h])
AC_CACHE_VAL(ac_cv_sigpipe_in_signal_h, [
AC_EGREP_CPP(sigpipe_yes,
  [#include <signal.h>
  #ifdef SIGPIPE
       sigpipe_yes
   #endif
  ], ac_cv_sigpipe_in_signal_h=yes, ac_cv_sigpipe_in_signal_h=no)])
AC_MSG_RESULT($ac_cv_sigpipe_in_signal_h)

if test "$ac_cv_sigpipe_in_signal_h" = "yes" ; then
  AC_DEFINE(HAVE_SIGPIPE, 1, [Defined if signal.h defines SIGPIPE.])
fi

dnl timezone
AC_MSG_CHECKING(for tm_gmtoff in struct tm)
AC_TRY_COMPILE([#include <time.h>], [
struct tm t;
t.tm_gmtoff = 1;
], [AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_TM_GMTOFF], 1, [Defined if struct tm has a tm_gmtoff field])
], 
[AC_MSG_RESULT(no)
AC_MSG_WARN([timezone handling may be broken on this platform])])

ifdef([neon_no_zlib], [
    neon_zlib_message="zlib disabled"
    NEON_SUPPORTS_ZLIB=no
], [
    NEON_ZLIB()
])

# Conditionally enable ACL support
AC_MSG_CHECKING([whether to enable ACL support in neon])
if test "x$neon_no_acl" = "xyes"; then
    AC_MSG_RESULT(no)
else
    AC_MSG_RESULT(yes)
    NEON_EXTRAOBJS="$NEON_EXTRAOBJS ne_acl"
fi

NEON_SSL()
NEON_SOCKS()

AC_SUBST(NEON_CFLAGS)
AC_SUBST(NEON_LIBS)

])

dnl Call to put lib/snprintf.o in LIBOBJ and define HAVE_SNPRINTF_H
dnl if snprintf isn't in libc.

AC_DEFUN([NEON_REPLACE_SNPRINTF], [

dnl Check for snprintf
AC_CHECK_FUNC(snprintf,,
	AC_DEFINE(HAVE_SNPRINTF_H, 1, [Define if need to include snprintf.h])
	LIBOBJ="$LIBOBJ lib/snprintf.o" )

])

dnl turn off webdav, boo hoo.
AC_DEFUN([NEON_WITHOUT_WEBDAV], [
neon_no_webdav=yes
neon_no_acl=yes
NEON_NEED_XML_PARSER=no
neon_xml_parser_message="none needed"
])

dnl Turn off zlib support
AC_DEFUN([NEON_WITHOUT_ZLIB], [
define(neon_no_zlib, yes)
])

AC_DEFUN([NEON_WITHOUT_ACL], [
# Turn off ACL support
neon_no_acl=yes
])

dnl Common macro to NEON_LIBTOOL_BUILD and NEON_NORMAL_BUILD
dnl Sets NEONOBJS appropriately if it has not already been set.
dnl 
dnl NOT FOR EXTERNAL USE: use LIBTOOL_BUILD or NORMAL_BUILD.
dnl

AC_DEFUN([NEON_COMMON_BUILD], [

# Using the default set of object files to build.
# Add the extension to EXTRAOBJS
ne="$NEON_EXTRAOBJS"
NEON_EXTRAOBJS=
for o in $ne; do
	NEON_EXTRAOBJS="$NEON_EXTRAOBJS $o.$NEON_OBJEXT"
done	

AC_MSG_CHECKING(whether to enable WebDAV support in neon)

dnl Did they want DAV support?
if test "x$neon_no_webdav" = "xyes"; then
  # No WebDAV support
  AC_MSG_RESULT(no)
  NEONOBJS="$NEONOBJS \$(NEON_BASEOBJS)"
  NEON_CFLAGS="$NEON_CFLAGS -DNEON_NODAV"
  NEON_SUPPORTS_DAV=no
  AC_DEFINE(NEON_NODAV, 1, [Enable if built without WebDAV support])
else
  # WebDAV support
  NEON_SUPPORTS_DAV=yes
  NEONOBJS="$NEONOBJS \$(NEON_DAVOBJS)"
  # Turn on DAV locking please then.
  AC_DEFINE(USE_DAV_LOCKS, 1, [Support WebDAV locking through the library])

  AC_MSG_RESULT(yes)

fi

AC_SUBST(NEON_TARGET)
AC_SUBST(NEON_OBJEXT)
AC_SUBST(NEONOBJS)
AC_SUBST(NEON_EXTRAOBJS)
AC_SUBST(NEON_LINK_FLAGS)
AC_SUBST(NEON_SUPPORTS_DAV)

])

# The libtoolized build case:
AC_DEFUN([NEON_LIBTOOL_BUILD], [

NEON_TARGET=libneon.la
NEON_OBJEXT=lo

NEON_COMMON_BUILD($#, $*)

])

# The non-libtool build case:
AC_DEFUN([NEON_NORMAL_BUILD], [

NEON_TARGET=libneon.a
NEON_OBJEXT=o

AC_CHECK_TOOL(AR, ar, :)
AC_CHECK_TOOL(RANLIB, ranlib, :)

NEON_COMMON_BUILD($#, $*)

])
