#! /bin/bash
#
# This script is only for the CVS repository to bootstrap the checked
# out module. It will be deleted before making the distribution.
#

#set -x

# Helper functions

bt_usage ()
{

    echo "Usage: $__bt_script $__bt_usage"

}


bt_message ()
{

    echo "$1"

}


bt_info ()
{

    if test $__bt_level -eq 0; then
        echo "$__bt_script: $1"
    else
        echo "$__bt_script[$__bt_level]: $1"
    fi

}


bt_warning ()
{

    if test $__bt_level -eq 0; then
        echo "$__bt_script: Warning: $1"
    else
        echo "$__bt_script[$__bt_level]: Warning: $1"
    fi

}


bt_error ()
{

    if test $__bt_level -eq 0; then
        echo "$__bt_script: Error: $1"
    else
        echo "$__bt_script[$__bt_level]: Error: $1"
    fi

}


bt_init ()
{
    __bt_script=`basename $0`
    readonly __bt_script

    __bt_usage="[-hlcCD] [-L level] [-d helpers-dir] [-s subdirs-file]"
    bt_options="hlcCDL:d:s:"
    readonly __bt_usage bt_options

    # Recursion level
    __bt_level=0

    # Default helpers directory
    bt_auxdir="admin"

    # Default subdirs file
    bt_subdirs_file="bootdirs"

    # Disable check for maintainer tools
    bt_check_tools=1

    # Distribution mode (default is to run in maintainer mode)
    bt_dist_mode=no

    # Local flag (default is to work recursive)
    bt_run_local=0

    # Copy files flag
    bt_copy_files="--copy"

    # Process command line
    set -- `getopt $bt_options $*`

    if test $? != 0; then
	bt_usage
	exit 1
    fi

    for opt in $*; do
	case $opt in
	-h) bt_usage
	    exit 0
	    ;;

	-l) bt_run_local=1
	    shift
	    ;;

	-c) bt_copy_files=""
	    shift
	    ;;

	-C) bt_check_tools=0
	    shift
	    ;;

	-D) bt_dist_mode=yes
	    shift
	    ;;

	-L) __bt_level=$2
	    shift 2
	    ;;

	-d) bt_auxdir=$2
	    shift 2
	    ;;

	-s) bt_subdirs_file=$2
	    shift 2
	    ;;

	--) shift
	    break
	    ;;
	esac
    done


    # Check existance of the helpers directory
    if test ! -d $bt_auxdir; then
	mkdir -p $bt_auxdir
    fi


    # Force local mode if subdirs file is missing
    if test ! -r $bt_subdirs_file; then
	bt_run_local=1
    fi

    return 0

}


bt_check_autoconf_template ()
{
    for f in configure.ac configure.in; do
	if test -r $f; then
	    bt_configure=$f
	    break
	fi
    done

    if test -z "$bt_configure"; then
	bt_error "No GNU autoconf configure template found!"
	return 1
    fi

    return 0
}


bt_needs_automake ()
{
    bt_use_am=no

    if egrep "^AM_INIT_AUTOMAKE" $bt_configure >/dev/null 2>&1; then
	if test ! -r Makefile.am; then
	    bt_error "No GNU automake Makefile template found!"
	    return 1
	fi

        bt_use_am=yes
    fi

    return 0
}


bt_needs_libtool ()
{
    bt_use_lt=no

    if egrep "^AC_PROG_LIBTOOL" $bt_configure >/dev/null 2>&1; then
        bt_use_lt=yes
    fi

    return 0
}


bt_check_build_tools ()
{

    bt_info "Checking for maintainer tools..."

    # Temporarily remove the current working directory from PATH
    save_PATH="$PATH"
    PATH="`echo $PATH | sed -e 's/^\.://' -e 's/:\.:/:/g' -e 's/:\.$//'`"

    # Autoconf 2.59 or newer
    bt_autoconf=`which autoconf 2>/dev/null | grep '^/' | head -1`
    bt_ac_version=`$bt_autoconf --version 2>/dev/null | head -1 \
    	      | sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`
    
    if test -z "$bt_ac_version"; then
        bt_error "GNU autoconf not found in your PATH!"
        bt_error "You need autoconf 2.59 or newer installed."
    
        return 1
    else
        save_IFS="$IFS"
        IFS=.
        set $bt_ac_version
        IFS="$save_IFS"
    
        if test "$1" -lt 2 || test x"$1" = x2 && test "$2" -lt 59; then
            bt_error "Installed GNU autoconf $bt_ac_version is too old!"
            bt_error "You need autoconf 2.59 or newer installed."
    
            return 1
        else
            bt_info "GNU autoconf $bt_ac_version found."
            bt_ac_path=`dirname $bt_autoconf`
            bt_use_ac=yes
        fi
    fi


    # Automake 1.8 or newer
    if test x"$bt_use_am" = xyes; then

	bt_automake=`which automake 2>/dev/null | grep '^/' | head -1`
	bt_am_version=`$bt_automake --version 2>/dev/null | head -1 \
		      | sed -e 's/^[^0-9]*//' -e 's/[a-z]* *$//'`

	if test -z "$bt_am_version"; then
	    bt_error "GNU automake not found in your PATH!"
	    bt_error "You need automake 1.8 or newer installed."

	    return 1
	else
	    save_IFS="$IFS"
	    IFS=.
	    set $bt_am_version
	    IFS="$save_IFS"

	    if test "$1" -lt 1 || test x"$1" = x1 && test "$2" -lt 8; then
		bt_error "Installed GNU automake $bt_am_version is too old!"
		bt_error "You need automake 1.8 or newer installed."

		return 1
	    else
		bt_info "GNU automake $bt_am_version found."
		bt_am_path=`dirname $bt_automake`
	    fi
	fi
    fi


    # Libtool 1.5 or newer (optional)
    if test x"$bt_use_lt" = xyes; then

        for f in glibtool libtool; do
            bt_libtool=`which $f 2>/dev/null | grep '^/' | head -1`
            test -n "$bt_libtool" && break
        done

	bt_lt_version=`$bt_libtool --version 2>/dev/null | head -1 \
		       | sed -e 's/^[^0-9]*//' -e 's/[- ].*//'`

	if test -z "$bt_lt_version"; then
	    bt_error "GNU libtool not found in your PATH!"
	    bt_error "You need libtool 1.5 or newer installed."

	    return 1
	else
	    save_IFS="$IFS"
	    IFS=.
	    set $bt_lt_version
	    IFS="$save_IFS"

	    if test "$1" -lt 1 || test x"$1" = x1 && test "$2" -lt 5; then
		bt_error "Installed GNU libtool $bt_lt_version is too old!"
		bt_error "You need libtool 1.5 or newer installed."

		return 1
	    else
		bt_info "GNU libtool $bt_lt_version found."
		bt_lt_path=`dirname $bt_libtool`
	    fi
	fi
    fi

    PATH="$save_PATH"

    return 0

}


bt_setup_libtool ()
{

    for f in glibtoolize libtoolize; do
        bt_libtoolize=`which $f 2>/dev/null | grep '^/' | head -1`
        test -n "$bt_libtoolize" && break
    done

    if test x"$bt_libtoolize" = x; then
	bt_error "GNU libtoolize not found in your PATH!"
    	return 1
    else
	bt_lt_path=`dirname $bt_libtoolize`
    fi


    save_cwd=`pwd`
    cd $bt_auxdir

    bt_lt_files="config.guess config.sub ltmain.sh"

    for f in $bt_lt_files; do
	if test ! -f $f; then
	    bt_run_libtoolize=yes
	    break
	fi
    done

    cd $save_cwd


    bt_install_ltdl=" "

    if egrep "^AC_LIBLTDL_CONVENIENCE" $bt_configure >/dev/null 2>&1; then
	bt_install_ltdl="--ltdl"
    fi

    if test x"$bt_run_libtoolize" = xyes; then
	bt_info "Copying libtool files."
	bt_warning "Do not forget to put these files under version control!"

	$bt_libtoolize --automake $bt_copy_files $bt_install_ltdl
    fi

    # Setup libltdl if the directory exists
    if test -d libltdl; then
	bt_info "Setting up libltdl convenience library ..."

	(cd libltdl; $bt_libtoolize --automake $bt_copy_files; \
         aclocal && autoheader \
                 && automake --gnits --add-missing $bt_copy_files \
                 && autoconf) || return 1
    fi

    return 0

}


bt_create_macro_file ()
{

    # Sanity check
    if test x"$bt_check_tools" = x1 && test ! -x $bt_am_path/aclocal; then
        bt_error "Cannot run aclocal. Check your automake installation!"
        return 1
    fi

    # Remove aclocal.m4 if it exists
    test -f ./aclocal.m4 && rm -f ./aclocal.m4


    # Recreate aclocal.m4
    if test -f ./acinclude.m4 || test x"$bt_use_lt" = xyes; then
	bt_message "Creating aclocal.m4"
        bt_aclocal_flags=`egrep "^\ *ACLOCAL_AMFLAGS" Makefile.am | \
                          sed -e 's/^.*=[ ]*//'`
        if test -n "bt_aclocal_flags"; then
            aclocal $bt_aclocal_flags || return 1
        else
            aclocal || return 1
        fi
    fi

    return 0

}


bt_create_configure ()
{

    # Save existing configure
    test -f ./configure && cp ./configure ./configure.$$.tmp

    # Create the configure script
    bt_message "Creating configure"
    autoconf || return 1

    if test -f ./config.cache && test -f ./configure.$$.tmp; then
	if cmp ./configure ./configure.$$.tmp; then
	    bt_warning "configure has changed. Removing file config.cache."
	    rm -f ./config.cache
	fi
    fi

    test -f ./configure.$$.tmp && rm -f ./configure.$$.tmp

    return 0

}


bt_create_config_header ()
{

    # Sanity check
    if test x"$bt_check_tools" = x1 && test ! -x $bt_ac_path/autoheader; then 
        bt_error "Cannot run autoheader. Check your autoconf installation!"
        return 1
    fi

    if egrep "^AM_CONFIG_HEADER" $bt_configure >/dev/null 2>&1; then
	bt_message "Creating config.h template"
	autoheader || return 1
    fi

    return 0

}


bt_create_makefile_templates ()
{

    bt_message "Creating Makefile templates"

    if test x"$1" != xyes; then
	automake --foreign --add-missing $bt_copy_files
    else
	automake --foreign --include-deps
    fi

    return 0

}


bt_bootstrap_packages ()
{

    if test -r $bt_subdirs_file; then
	for bt_dir in `cat $bt_subdirs_file`; do
	    if test ! -d $bt_dir; then
		bt_warning "Skipping $bt_dir. Directory does not exist!"
	    else
		if test ! -x $bt_dir/bootstrap; then
		    bt_error "Cannot execute $bt_dir/bootstrap."
		    return 1
		else
                    __bt_level=$(($__bt_level + 1))
		    bt_info "Entering directory \`$PWD/$bt_dir'"
		    (cd $bt_dir && ./bootstrap -C -L $__bt_level) || return 1
		    bt_info "Leaving directory \`$PWD/$bt_dir'"
                    __bt_level=$(($__bt_level - 1))
		fi
	    fi
	done
    fi
		    
    return 0

}


bt_main ()
{

    # Initialize some variables and process the command line
    bt_init $* || return 1

    # Sanity check
    bt_check_autoconf_template || return 1


    # Check whether optional tools should be used
    bt_needs_automake
    bt_needs_libtool

    # Check maintainer tools
    if test x$bt_check_tools = x1; then
	bt_check_build_tools || return 1
    fi


    # Setup maintainer tools
    if test x"$bt_use_lt" = xyes; then
	bt_setup_libtool || return 1
    fi


    # Bootstrap local build environment
    if test x"$__bt_level" = x0; then
        bt_info "Bootstrapping build tree in \`$PWD' ..."
    fi

    bt_create_macro_file || return 1

    bt_create_configure || return 1

    bt_create_config_header || return 1

    bt_create_makefile_templates $bt_dist_mode || return 1

    
    # Bootstrap 3rd party packages
    bt_bootstrap_packages || return 1

    if test $__bt_level -eq 0; then
        bt_message ""
        bt_message "Don't forget to run ./configure"
        bt_message "If you haven't done so in a while, run ./configure --help"
        bt_message ""
    fi

    return 0

}


# Call main here
bt_main $* || exit 1
