#! /bin/bash
#  -*- Mode: Shell-script -*-
#
# bootstrap --- maintainer's bootstrap script
#
##  This file is part of AutoGen.
##  AutoGen Copyright (C) 1992-2020 by Bruce Korb - all rights reserved
##
##  AutoGen 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.
##
##  AutoGen 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/>.

# This script is designed to find any directories which contain a
# configure.ac in script, and to run the autotools programs from each
# of those directories to make sure they are in a state ready to
# 'configure; make; make install'
#
# Often this process involves more than `libtoolize; automake; autoconf',
# so supplementary actions can be placed in a bootstrap.local script
# in the same directory as this script, and anywhere in the source tree
# in bootstrap.dir files.  The bootstrap.local script will be sourced
# twice; first with 'pre' before the main part is run, and then
# again with 'post' after the main part has finished.  This makes
# it possible to set up any links or temporary files required for this
# script to work before it has executed, and then remove them when it
# has finished.  The bootstrap.dir files are also sourced, in a random
# order, as they are found in the tree just before the post
# phase.  This allows a developer to put any peculiar bootstrap actions
# required by individual directories where they can be seen (and not
# forgotten!).
#
# In an ideal world, running this bootstrap script (including any extra
# scripts it executes) should leave a freshly checked out repository tree
# in the same state as a freshly unrolled tarball.  In this way, one
# no longer has to maintain generated files under source control, they
# can be generated after checkout using this bootstrap procedure.

PS4='+BS=${FUNCNAME:-=}-$LINENO> '

top_srcdir=$(
    cd $(dirname $0)/.. >/dev/null || kill -9 $$
    pwd )
top_builddir=${top_srcdir}

PS4='+shlib=${FUNCNAME:-=}-$LINENO> ' \
  source config/bootstrap.shlib

config_tools()
{
    shopt -qo xtrace && VERBOSE=true || VERBOSE=${VERBOSE:-false}

    if test -d "$TEMP_DIR"
    then
        TMPDIR="$TEMP_DIR"
        must_remove_temp_dir=false

    else
        TMPDIR=${TMPDIR:-/tmp}/ag-bs-????????.tdir
        rm -rf $TMPDIR
        TMPDIR=$(mktemp -d ${TMPDIR//\?/X})
        touch  ${TMPDIR}/bs-log.txt || \
            die ${TMPDIR}/bs-log.txt is untouchable
        exec 2> ${TMPDIR}/bs-log.txt
        $VERBOSE && must_remove_temp_dir=false || must_remove_temp_dir=true
        TEMP_DIR=$TMPDIR
    fi
    export TMPDIR TEMP_DIR VERBOSE

    conf_dir=${top_srcdir}/config
    test -f "${top_srcdir}/configure.ac.pre" || \
        die "configure.ac.pre not in ${top_srcdir}"

    # ORDERED LIST. "pre" goes in this order, "post" in reverse so,
    # bootstrap.local pre is first and bootstrap.local post is last.
    #
    bootstrap_list='
        config/bootstrap.local
        autoopts/bootstrap.dir
        agen5/bootstrap.dir
        columns/bootstrap.dir
        compat/bootstrap.dir
        getdefs/bootstrap.dir
        snprintfv/bootstrap.dir'

    export top_srcdir top_builddir bootstrap_list
    readonly bootstrap_list

    # ------------------------------------------------------------------
    # Make sure all of the maintainer tools required for bootstrap are
    # available on the host machine.
    # ------------------------------------------------------------------
    #
    tools="autoconf autoheader aclocal automake libtoolize"
    for f in $tools
    do
        tool=$(command -v ${f}) > /dev/null || die "No $f found"
        eval ${f}_reqver=$(
            set -- $(${tool} --version | sed 1q)
            eval echo \${$#})
        eval $(echo $f | tr '[a-z]' '[A-Z]')=${tool}
    done

    char_mapper=$(command -v char-mapper) 2>/dev/null
    test -x "${char_mapper}" || {
        char_mapper=$(
            cd add-on/char-mapper >&2
            make char-mapper >&2 || die "cannot make char-mapper"
            echo ${PWD}/char-mapper)
    }
    export char_mapper

    echo bootstrapping in ${PWD}

    set +e
}

# Source any local scripts which add to the bootstrap procedure.  The
# bootstrap.local script should test the value of the argument to see
# whether it should run the sections to be called before the main
# script, or afterwards.
#
source_bs() {
    local file=${1##*/}
    local _PS4=${PWD##*/}
    _PS4=+BS${_PS4:0:4}-$2='${FUNCNAME:-=}-$LINENO> '

    test -f "$file" || die "cannot locate $file in $PWD"
    : IN $PWD sourcing "$file"
    PS4="$_PS4" source "$PWD/${file}" ${2} || \
        die "$PWD/${file} failed"
}

sub_bootstrap()
{
    local list= start_dir=$PWD

    if test X$1 = Xpost
    then list=$(tac <<<"$bootstrap_list")
    else list="$bootstrap_list"
    fi

    for f in ${list}
    do
        printf "START %-4s %-24s %s\n" $1 "$f" "$(date '+%M:%S.%N')" > /dev/tty
        cd $(dirname "$f")
        source_bs "$f" $1
        cd "$start_dir"
        printf "DONE  %-4s %-24s %s\n" $1 "$f" "$(date '+%M:%S.%N')" > /dev/tty
    done
}

filter_chaff() {
    if test -f configure
    then
        sedcmd='/configure.ac:.*no .* detected/,/configure.ac:.*top level/d'
        sed "$sedcmd" "${tool_out_file}"
    else
        cat "${tool_out_file}"
    fi 1>&2
    rm -f "${tool_out_file}"
}

fix_do_not_make_me() {
    local fix_list=$(
        grep -l FIX-DO-NOT-MAKE-ME \
             $(find * -type f -name 'Makefile.am'))
    local sedcmd= vlist= f= v=

    for f in $fix_list
    do
        sedcmd=$'/##FIX-DO-NOT-MAKE-ME/ {\ns/.*//\n'
        vlist=$(sed -n '/do_not_make_me/s/ *[+=].*//p' $f | \
                    sort -u)
        if test ${#vlist} -gt 1
        then
            sedcmd+=$'i\\\n'
            for v in $vlist
            do
                sedcmd+="$(printf '%-32s=' $v)"
                sedcmd+=$'\\\n'
            done
            sedcmd+=$'\n'
        fi
        sedcmd+='}'

        sed "$sedcmd" $f > $f.XX
        mv -f $f.XX $f
    done
}

run_autotools()
{
    cd ${top_builddir}
    # remove any stale config.cache
    doit rm -f config.cache
    :

    test -n "$auxdir" || auxdir=${top_srcdir}
    test -d $auxdir   || auxdir=.

    fix_do_not_make_me

    doit $LIBTOOLIZE    --force
    doit $ACLOCAL       -I config
    doit $AUTOHEADER
    doit $AUTOMAKE      --gnu --add-missing
    test -f libtool || cp -fp $(command -v libtool) .
    doit $AUTOCONF
    sedcmd='s/^PS4=/## PS4=/'
    shopt -qo xtrace && {
        sedcmd+=$';/SHELL.*CONFIG_STATUS/{\n'
        sedcmd+='s/^/   PS4="+csts=\\${FUNCNAME:-=}-\\$LINENO> " /'
        sedcmd+=$'\ns/SHELL /SHELL -x /\n}'
    }
    sed -i "$sedcmd" configure
}

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
#    M A I N
#
{
    config_tools
    sub_bootstrap pre
    tool_out_file=${TEMP_DIR:-${TMPDIR:-/tmp}}/autotool-out.txt
    run_autotools 1> ${tool_out_file} 2>&1
    filter_chaff ${tool_out_file}
    sub_bootstrap post

    trap '' 0
    echo 'bootstrap complete' $(date)
    ${must_remove_temp_dir} && rm_temp_dir
    exit 0
}
# Local Variables:
# mode:shell-script
# sh-indentation:4
# sh-basic-offset:4
# indent-tabs-mode: nil
# End:

# bootstrap ends here
