#!/bin/sh
#
# XML Catalog Manager (xmlcatmgr)
# $Id: configure.sh,v 1.29 2004/05/02 09:36:27 jmmv Exp $
#
# Copyright (c) 2003, 2004 Julio M. Merino Vidal.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with the
#    distribution.
# 3. Neither the name of the author nor the names of contributors may
#    be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#

progname=`basename $0`

PKGNAME=xmlcatmgr
PKGVERSION=2.1

# -------------------------------------------------------------------------
# check_developer
# -------------------------------------------------------------------------

check_developer() {
    case ${CC_NAME} in
        gnu)
            flags="-Wall -Wstrict-prototypes -Wmissing-prototypes \
                   -Wpointer-arith -Wmissing-declarations -Wcast-qual \
                   -Wnested-externs -Wreturn-type -Wswitch -Wshadow
                   -Wredundant-decls -Wwrite-strings -g"
            ;;
        sunpro)
            flags="-g"
            ;;
        *)
            flags=
            ;;
    esac

    cat > ${WORKDIR}/tmp.c <<EOF
#include <stdio.h>
int main(void) { return 0; }
EOF

    for f in ${flags}; do
        printf "checking for C compiler flag ${f}: "
        ${CC} ${CPPFLAGS} ${CFLAGS} ${f} -o ${WORKDIR}/tmp ${LDFLAGS} \
            ${WORKDIR}/tmp.c ${LIBS} >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            CFLAGS="${CFLAGS} ${f}"
            echo "yes"
        else
            echo "no"
        fi
        rm -f ${WORKDIR}/tmp
    done

    rm -f ${WORKDIR}/tmp.c
}

# -------------------------------------------------------------------------
# check_func
# -------------------------------------------------------------------------

check_func() {
    var="$1"
    name="$2"

    printf "checking for function ${name}: "

    rm -f ${WORKDIR}/tmp.c
    touch ${WORKDIR}/tmp.c

    for h in ${HEADERS}; do
        echo "#include <${h}>" >> ${WORKDIR}/tmp.c
    done
    echo "int main(void) { printf(\"%p\", ${name}); }" >> ${WORKDIR}/tmp.c

    ${CC} ${CPPFLAGS} ${CFLAGS} -o ${WORKDIR}/tmp ${LDFLAGS} \
        ${WORKDIR}/tmp.c ${LIBS} >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "yes"
        CPPFLAGS="${CPPFLAGS} -D${var}"
    else
        echo "no"
    fi
    rm -f ${WORKDIR}/tmp.c ${WORKDIR}/tmp
}

# -------------------------------------------------------------------------
# check_hdr
# -------------------------------------------------------------------------

check_hdr() {
    var="$1"
    name="$2"

    printf "checking for header ${name}: "

    rm -f ${WORKDIR}/tmp.c
    touch ${WORKDIR}/tmp.c

    for h in ${HEADERS}; do
        echo "#include <${h}>" >> ${WORKDIR}/tmp.c
    done
    echo "#include <${name}>" >> ${WORKDIR}/tmp.c
    echo "int main(void) { return 0; }" >> ${WORKDIR}/tmp.c

    ${CC} ${CPPFLAGS} ${CFLAGS} -o ${WORKDIR}/tmp ${LDFLAGS} \
        ${WORKDIR}/tmp.c ${LIBS} >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        echo "yes"
        CPPFLAGS="${CPPFLAGS} -D${var}"
        HEADERS="${HEADERS} ${name}"
    else
        echo "no"
    fi
    rm -f ${WORKDIR}/tmp.c ${WORKDIR}/tmp
}

# -------------------------------------------------------------------------
# check_prog
# -------------------------------------------------------------------------

check_prog() {
    var="$1"
    names="$2"
    dirs=`echo ${PATH} | tr ':' ' '`

    eval tmp=\"\${${var}}\"
    if [ -n "${tmp}" ]; then
        echo "using preset value of ${var}: ${tmp}"
        return 0
    fi

    for n in ${names}; do
        printf "checking for program ${n}: "
        for d in ${dirs}; do
            if [ -x ${d}/${n} ]; then
                eval ${var}="${d}/${n}"
                echo ${d}/${n}
                return 0
            fi
        done
        echo "not found"
    done

    return 1
}

# -------------------------------------------------------------------------
# check_prog_cc
# -------------------------------------------------------------------------

check_prog_cc() {
    check_prog CC "gcc cc"
    if [ -z "${CC}" ]; then
        echo "ERROR: C compiler not found." 1>&2
        exit 1
    fi

    printf "checking for the C compiler name: "

    cat > ${WORKDIR}/tmp.c <<EOF
#include <stdio.h>
int main(void) {
#if defined(__GNUC__)
printf("gnu");
#elif defined(__SUNPRO_C)
printf("sunpro");
#else
printf("unknown");
#endif
}
EOF
    ${CC} ${CPPFLAGS} ${CFLAGS} -o ${WORKDIR}/tmp ${LDFLAGS} \
        ${WORKDIR}/tmp.c ${LIBS} >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        rm -f ${WORKDIR}/tmp.c ${WORKDIR}/tmp
        echo "failed"
        echo "ERROR: C compiler cannot build binaries." 1>&2
        exit 1
    fi
    CC_NAME=`${WORKDIR}/tmp`
    echo ${CC_NAME}
    rm -f ${WORKDIR}/tmp.c ${WORKDIR}/tmp
}

# -------------------------------------------------------------------------
# gen_deps
# -------------------------------------------------------------------------

gen_deps() {
    src=$1
    obj=$2

    if [ -n "${CPP}" ]; then
        ${CPP} -M ${src} 2>/dev/null
        [ $? -gt 0 ] && echo "`basename ${obj}`: ${src}"
    else
        echo "`basename ${obj}`: ${src}"
    fi
}

# -------------------------------------------------------------------------
# install_data
# -------------------------------------------------------------------------

install_data() {
    if [ -n "${INSTALL_DATA}" ]; then
        echo "	${INSTALL_DATA} $1 \${DESTDIR}$2"
    else
        echo "	cp $1 \${DESTDIR}$2"
        echo "	chmod ${DATAMODE:-0644} \${DESTDIR}$2"
    fi
}

# -------------------------------------------------------------------------
# install_dir
# -------------------------------------------------------------------------

install_dir() {
    echo "	${INSTALL_DIR:-mkdir -p} \${DESTDIR}$1"
}

# -------------------------------------------------------------------------
# install_program
# -------------------------------------------------------------------------

install_program() {
    if [ -n "${INSTALL_PROGRAM}" ]; then
        echo "	${INSTALL_PROGRAM} $1 \${DESTDIR}$2"
    else
        echo "	cp $1 \${DESTDIR}$2"
        echo "	chmod ${BINMODE:-0755} \${DESTDIR}$2"
    fi
}

# -------------------------------------------------------------------------
# set_prefix
# -------------------------------------------------------------------------

set_prefix() {
    PREFIX=$1
    DEFAULT_CATALOG_SGML=${PREFIX}/etc/sgml/catalog
    DEFAULT_CATALOG_XML=${PREFIX}/etc/xml/catalog
    DIR_DOC=${PREFIX}/share/doc/${PKGNAME}
    DIR_EXEC=${PREFIX}/bin
    DIR_MAN=${PREFIX}/man
}

# -------------------------------------------------------------------------
# usage
# -------------------------------------------------------------------------

usage() {
    cat 1>&2 << EOF
usage: ./${progname} [-Dh] [-p prefix] [-demw dir] [-n feat] [-Cc catalog_file]

    -D         enable developer mode
    -C file    set default SGML catalog file (PREFIX/etc/sgml/catalog)
    -c file    set default XML catalog file (PREFIX/etc/xml/catalog)
    -d dir     set documentation directory (PREFIX/share/doc/${PKGNAME}-${PKGVERSION})
    -e dir     set exec directory (PREFIX/bin)
    -h         show this help message
    -m dir     set man directory (PREFIX/man)
    -n feat    disable feature \`feat'; allowed values: \`doc'
    -w dir     set work directory (${WORKDIR})

The prefix should be modified before any other directory.

Environment variables that can be used to override checks:
    CC CFLAGS CPP CPPFLAGS LDFLAGS LIBS
    INSTALL_DATA INSTALL_DIR INSTALL_PROGRAM
EOF
}

# -------------------------------------------------------------------------
# Main program
# -------------------------------------------------------------------------

TOPDIR=`pwd`
WORKDIR=`pwd`/work
WORKDIR_ARG=
DEVELOPER=no
DOC=yes
DOC_COND=

SUBSTS="PKGNAME PKGVERSION DEFAULT_CATALOG_SGML DEFAULT_CATALOG_XML"
SUBSTS="${SUBSTS} DIR_DOC DOC_COND"

set_prefix /usr/local

while [ $# -gt 0 ]; do
    echo -- $1 | grep '^-- -' >/dev/null || break

    case $1 in
        -C)
            DEFAULT_CATALOG_SGML=$2
            shift
            ;;
        -c)
            DEFAULT_CATALOG_XML=$2
            shift
            ;;
        -D)
            DEVELOPER=yes
            ;;
        -d)
            DIR_DOC=$2
            shift
            ;;
        -e)
            DIR_EXEC=$2
            shift
            ;;
        -h)
            usage
            exit 0
            ;;
        -m)
            DIR_MAN=$2
            shift
            ;;
        -n)
            case $2 in
                doc)
                    DOC=no
                    DOC_COND='.\\" '
                    ;;
                *)
                    echo "${progname}: unknown feature \`$2'" 1>&2
                    ;;
            esac
            shift
            ;;
        -p)
            set_prefix $2
            shift
            ;;
        -w)
            WORKDIR=$2
            WORKDIR_ARG=" -w ${WORKDIR}"
            shift
            ;;
        *)
            echo "${progname}: unknown option \`$1'" 1>&2
            echo "type \`./${progname} -h' for more information" 1>&2
            exit 1
            ;;
    esac

    shift
done

if [ ! -d ${WORKDIR} ]; then
    mkdir -p ${WORKDIR}
fi

echo "configuring for ${PKGNAME}-${PKGVERSION}"

# Gather system information.

check_prog CPP "cpp"
check_prog_cc
check_prog MAKE "bmake gmake make"
check_prog SED "gsed sed"
if [ "${DEVELOPER}" = "yes" ]; then
    check_developer
else
    CPPFLAGS="${CPPFLAGS} -DNDEBUG"
fi

HEADERS=
check_hdr HAVE_SYS_CDEFS_H sys/cdefs.h
check_hdr HAVE_ASSERT_H assert.h
check_hdr HAVE_CTYPE_H ctype.h
check_hdr HAVE_ERR_H err.h
check_hdr HAVE_FCNTL_H fcntl.h
check_hdr HAVE_STDARG_H stdarg.h
check_hdr HAVE_STDBOOL_H stdbool.h
check_hdr HAVE_STDIO_H stdio.h
check_hdr HAVE_STDLIB_H stdlib.h
check_hdr HAVE_STRING_H string.h
check_hdr HAVE_UNISTD_H unistd.h
if [ -z "`echo ${HEADERS} | grep stdarg.h`" ]; then
    check_hdr HAVE_VARARGS_H varargs.h
    if [ -z "`echo ${HEADERS} | grep varargs.h`" ]; then
        check_hdr HAVE_SYS_VARARGS_H sys/varargs.h
    fi
fi

check_func HAVE_LOCKF lockf
check_func HAVE_GETPROGNAME getprogname
check_func HAVE_SETPROGNAME setprogname
check_func HAVE_WARN warn
check_func HAVE_WARNX warnx

# Generate environment for make.sh.

echo "PKGNAME=${PKGNAME}" > ${WORKDIR}/pkgvars
echo "PKGVERSION=${PKGVERSION}" >> ${WORKDIR}/pkgvars
echo "MAKE=${MAKE}" >> ${WORKDIR}/pkgvars

# Generate output Makefile.

mkfile=${WORKDIR}/Makefile
srcdir=${TOPDIR}/bin

echo "generating makefile: ${mkfile}"

cat > ${mkfile} <<EOF
# ${PKGNAME}-${PKGVERSION} Makefile
# Generated on `date`
#

EOF

CPPFLAGS="${CPPFLAGS} -I${srcdir}"
CPPFLAGS="${CPPFLAGS} -DPKGNAME=\\\"${PKGNAME}\\\""
CPPFLAGS="${CPPFLAGS} -DPKGVERSION=\\\"${PKGVERSION}\\\""
CPPFLAGS="${CPPFLAGS} -DDEFAULT_CATALOG_SGML=\\\"${DEFAULT_CATALOG_SGML}\\\""
CPPFLAGS="${CPPFLAGS} -DDEFAULT_CATALOG_XML=\\\"${DEFAULT_CATALOG_XML}\\\""

sed_substs=""
for s in ${SUBSTS}; do
    eval tmp=\"\${${s}}\"
    sed_substs="${sed_substs} -e 's|@${s}@|${tmp}|g'"
done

cat >> ${mkfile} <<EOF
.PHONY: all
all: xmlcatmgr xmlcatmgr.1

##################
# .c -> .o rules #
##################

EOF

objs=""
for s in `cd ${srcdir} && ls *.c`; do
    obj=`echo ${s} | sed -e 's|c$|o|g'`
    objs="${objs} ${obj}"
    gen_deps ${srcdir}/${s} ${obj} >> ${mkfile}
    echo "	${CC} ${CPPFLAGS} ${CFLAGS} -o ${obj} -c ${srcdir}/${s}" \
        >> ${mkfile}
    echo "" >> ${mkfile}
done

cat >> ${mkfile} <<EOF
###########
# Targets #
###########

xmlcatmgr: ${objs}
	${CC} ${CFLAGS} -o xmlcatmgr ${LDFLAGS} ${objs} ${LIBS}

xmlcatmgr.1: ${srcdir}/xmlcatmgr.1.in
	${SED} ${sed_substs} < ${srcdir}/xmlcatmgr.1.in > xmlcatmgr.1

.PHONY: clean
clean:
	rm -f ${objs}
	rm -f ${WORKDIR}/xmlcatmgr
	rm -f ${WORKDIR}/xmlcatmgr.1

.PHONY: install
install: all
EOF

install_dir ${DIR_EXEC} >> ${mkfile}
install_dir ${DIR_MAN}/man1 >> ${mkfile}
install_program xmlcatmgr ${DIR_EXEC}/xmlcatmgr >> ${mkfile}
install_data xmlcatmgr.1 ${DIR_MAN}/man1/xmlcatmgr.1 >> ${mkfile}
if [ "${DOC}" = "yes" ]; then
    install_dir ${DIR_DOC} >> ${mkfile}
    install_data ${TOPDIR}/CHANGES ${DIR_DOC}/CHANGES >> ${mkfile}
    install_data ${TOPDIR}/COPYING ${DIR_DOC}/COPYING >> ${mkfile}
    install_data ${TOPDIR}/PEOPLE ${DIR_DOC}/PEOPLE >> ${mkfile}
    install_data ${TOPDIR}/README ${DIR_DOC}/README >> ${mkfile}
    install_data ${TOPDIR}/TODO ${DIR_DOC}/TODO >> ${mkfile}
fi

echo "# End of generated Makefile." >> ${mkfile}

cat <<EOF

===========================================================================
${PKGNAME}-${PKGVERSION} configuration summary:

    Default SGML catalog: ${DEFAULT_CATALOG_SGML}
    Default XML catalog: ${DEFAULT_CATALOG_XML}
    Installation prefix: ${PREFIX}
    Work directory: ${WORKDIR}

    Type \`./make.sh${WORKDIR_ARG}' to start the build.
    Type \`./make.sh${WORKDIR_ARG} install' to install.

===========================================================================

EOF

exit 0

# Local Variables: ***
# mode: shell-script ***
# End: ***
# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
