#! /bin/sh
#
# Update all of the derived files
# For best performance, execute this in the top-level directory.
# There are some experimental features to allow it to be executed in
# subdirectories
#
# Eventually, we want to allow this script to be executed anywhere in the
# mpich tree.  This is not yet implemented.
at_top=no
if [ -d maint -a -s maint/simplemake.in ] ; then
    at_top=yes
fi
#
# Default choices
do_codingcheck=yes
codecheck_args=""
do_geterrmsgs=yes
do_bindings=yes
#
# Extract the arguments intended for updatefiles.  Any others are
# given to simplemake.  
temp_args=""
for arg in "$@" ; do
    case $arg in 
    -with-codecheck=*|--with-codecheck=*)
    do_codingcheck=yes
    codecheck_args=`echo "A$arg" | sed -e 's/.*=//'`
    ;;
    -with-codecheck|--with-codecheck)
    do_codingcheck=yes
    ;;
    -without-codecheck|--without-codecheck)
    do_codingcheck=no
    ;;
    -without-errmsgs|--without-errmsgs)
    do_geterrmsgs=no
    ;;
    -with-bindings|--with-bindings)
    do_bindings=yes
    ;;
    -without-bindings|--without-bindings)
    do_bindings=no
    ;;

    -help|--help|-usage|--usage)
    cat <<EOF
    updatefiles [ --with-codecheck | --without-codecheck ] 
                [ args for simplemake ] 
    Update the files in the MPICH2 build tree.  This file builds the 
    configure files, creates the Makefile.in files (using the simplemake
    program), extracts the error messages, and performs basic coding checks.
    Coding checks may be suppressed with --without-codecheck .
EOF
    exit
    ;;
    *)
    temp_args="$temp_args $arg"
    esac
done
# Reset the arguments.  Note that this doesn't handle arguments that contain
# blanks.  I hope that we don't need those.
set -- $temp_args
#
# Get the Autoconf macro files
if [ $at_top = "yes" -a ! -d confdb ] ; then
    # setup to allow CVSROOT instead of an absolute directory path
    if [ -n "$CVSROOT" -a -d "$CVSROOT/fpmpi" ] ; then
        if [ ! -d CVS ] ; then
            cvs -q export -D now confdb
	else
            cvs -q checkout confdb
	fi
    elif [ -d /home/gropp/cvsMaster_z ] ; then 
        # export if doing a distribution build
        if [ ! -d CVS ] ; then
            cvs -q -d /home/gropp/cvsMaster_z export -D now confdb
	else
            cvs -q -d /home/gropp/cvsMaster_z checkout confdb
	fi
    else
        echo "Checkout confdb from /home/gropp/cvsMaster_z and rerun"
	exit 1
    fi
fi
#
if [ $at_top = "no" ] ; then
    echo "Must execute at top level directory for now"
    exit 1
fi
#
# Create the bindings if necessary 
if [ $do_bindings = "yes" ] ; then
    if [ ! -s src/binding/f77/abortf.c ] ; then 
	build_f77=yes
    elif find -name 'src/binding/f77/buildiface' -newer 'src/binding/f77/abortf.c' ; then
	build_f77=yes
    else
	build_f77=no
    fi

    if [ $build_f77 = "yes" ] ; then
	echo "Building Fortran 77 interface"
	(cd src/binding/f77 ; ./buildiface )
    fi
    if [ ! -s src/binding/cxx/mpicxx.h ] ; then 
	build_cxx=yes
    elif find -name 'src/binding/cxx/buildiface' -newer 'src/binding/cxx/mpicxx.h' ; then
	build_cxx=yes
    else
	build_cxx=no
    fi
    if [ $build_cxx = "yes" ] ; then
	echo "Building C++ interface"
    #    File code still needs work
    #    if [ ! -d src/mpi/romio ] ; then
	    otherarg="-noromio"
    #    fi
	(cd src/binding/cxx ; ./buildiface -nosep $otherarg )
    fi
fi
#
# Capture the error messages
if [ ! -x maint/extracterrmsgs -a -s maint/extracterrmsgs ] ; then
    # grrr.  CVS doesn't maintain permissions correctly across Windows/Unix
    chmod a+x maint/extracterrmsgs
fi
if [ -x maint/extracterrmsgs -a $do_geterrmsgs = "yes" ] ; then
    echo "Extracting the error messages..."
    rm -rf .tmp
    maint/extracterrmsgs `find src/mpi -name '*.c' -print` `find src/nameserv -name '*.c' -print` \
        `find src/util -name '*.c' -print` `find src/binding -name '*.c' -print` src/include/*.h \
	`find src/mpid -name '*.[ch]' -print` > .tmp 2>.err
    # (error here is ok)
    update_errdefs=yes
    if [ -s .err ] ; then 
       cat .err
       rm -f .err2
       grep -v "Warning:" .err > .err2
       if [ -s .err2 ] ; then
           echo "Because of errors in extracting error messages, the file"
           echo "src/mpi/errhan/defmsg.h was not updated."
           update_errdefs=no
       fi
       rm -f .tmp .err .err2
    else
       # Incase it exists but has zero size
       rm -f .err
    fi
    if [ -s .tmp -a "$update_errdefs" = "yes" ] ; then
        mv .tmp src/mpi/errhan/defmsg.h
    fi
    if [ ! -s src/mpi/errhan/defmsg.h ] ; then
        echo "Creating a dummy defmsg.h file"
	cat > src/mpi/errhan/defmsg.h <<EOF
typedef struct { const char *short_name, *long_name; } msgpair;
static const int generic_msgs_len = 0;
static msgpair generic_err_msgs[] { {0, "no error catalog"}, };
static const int specific_msgs_len = 0;
static msgpair specific_err_msgs[] {  {0,0}, };
static int class_to_index[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 }
EOF
    fi
fi
#
# Build scripts such as simplemake if necessary
made_simplemake=no
run_configure=no
if [ ! -x maint/configure ] ; then
    (cd maint && autoconf )
elif find -name 'maint/configure.in' -newer 'maint/configure' ; then
    # The above relies on the Unix find command
    (cd maint && autoconf)
fi
if [ ! -x maint/simplemake -o ! -x maint/getstates ] ; then
    run_configure=yes
fi
#
# The following relies on the Unix find command
if find -name 'maint/simplemake.in' -newer 'maint/simplemake' ; then
    run_configure=yes
fi
if find -name 'maint/getstates.in' -newer 'maint/getstates' ; then
    run_configure=yes
fi

if [ "$run_configure" = "yes" ] ; then
    (cd maint && ./configure)
    made_simplemake=yes
fi

# Run some of the simple codes
if [ -x maint/getstates ] ; then
    maint/getstates -outfile=src/util/logging/lwlog/lwstates.c \
                    -namefile=src/util/logging/lwlog/lwnames.h src
fi

#
if [ ! -x maint/simplemake ] ; then
    echo "Could not create simplemake"
    echo "You can copy simplemake.in to simplemake, replacing @PERL@ with the"
    echo "path to Perl (version5).  Make sure the resulting file has"
    echo "execute permissions set."
    exit 1
fi
#
if [ $made_simplemake != "no" ] ; then
    # Check that only the first line was changed:
    rm -f .t1 .t2
    sed -e 1d maint/simplemake.in > .t1
    sed -e 1d maint/simplemake > .t2
    if diff .t1 .t2 >/dev/null 2>&1 ; then
        :
    else
        echo "Something is wrong with simplemake; configure may have"
        echo "replaced variables that it should not have."
        diff .t1 .t2
        exit 1
    fi
    rm -f .t1 .t2
fi
#
# Create the Makefile.in files
# Make sure that these files exist so that the gcc dependency creation
# can work
rm_prepost=no
if [ ! -s src/include/mpidpre.h ] ; then
    rm_prepost=yes
fi
otherargs="$@"
# If there is no mpi.h file (and other files, but testing on mpi.h should
# be enough), don't generate the dependency information in the Makefiles
# Currently, the dependency generation relies on using gcc, so we may 
# want to test on that as well.
if [ ! -s src/include/mpi.h ] ; then 
    otherargs="$otherargs -nodepend"
else
    # The next two files may be needed to build the dependency lists
    touch src/include/mpidpre.h src/include/mpidpost.h
fi
if maint/simplemake -common=maint/makedefs \
    -docnamedefs='${master_top_srcdir}/maint/docnotes' \
    -autoconf="-l ROOTDIR/confdb" \
    -libdir='${MPILIBNAME}'=ROOTDIR/lib $otherargs \
    Makefile.sm ; then
    :
else
    echo "Simplemake step failed!"
    exit 1
fi
#
# Create the configure files and run autoheader
# Eventually, make this a test for find available.  Perhaps
# find . -name configure.in > /dev/null 2>&1
# The problem is that even though cygnus has find, the DOS find
# is identified first.  We probably need a test for this case
find . -name 'configure.in' >/dev/null 2>&1
if [ $? = 0 ] ; then has_unix_find=yes ; else has_unix_find=no ; fi
# if [ $? = 0 ] ; then .. code with find
if [ "$has_unix_find" = "yes" ] ; then
    for dir in `find . -name 'configure.in' -print` ; do
        dir=`dirname $dir`
	#echo $dir
	if [ -s $dir/Makefile.in ] ; then 
            #echo "Found $dir/configure.in"
	    #
	    # Check for known problems
	    if [ $dir = "./src/binding/f77" -a \
		! -x "/home/gropp/bin/linux/autoconf" ] ; then
		# We need a *patched*, version 2.13 form of autoconf
		# Version 2.62 breaks the Fortran 90 extensions
		# to TRY_COMPILE, and stock 2.13 generates bogus 
		# code for language FORTRAN.

		# See if autoconf works
		rm -rf .ctmp
		mkdir .ctmp
		cd .ctmp
		cat >>configure.in <<EOF
AC_INIT(configure.in)
AC_LANG_FORTRAN77
AC_TRY_COMPILE(,[integer a],a=1,a=0)
EOF
		autoconf
		# The bug is that the EOF doesn't go onto the next line
		if grep endEOF configure 2>&1 >/dev/null ; then
		    echo "The available version of configure has a bug"
		    echo "in handling Fortran programs and cannot be used"
		    echo "This bug is an improper placement of the EOF"
		    echo "token used to implement AC_TRY_COMPILE for Fortran."
		    cd ..
		    rm -rf .ctmp
		    continue
		else
		    rm -rf .ctmp
		    cd ..
		fi
	    fi
	    if [ -s "$dir/configure2.in" ] ; then
	        # There is a version 1 and version 2 configure in this
	        # directory.  
	        if [ $dir = "./src/mpi/romio" ] ; then
		    echo $dir
		    (cd $dir ; \
		     autoheader -l ../../../confdb configure2.in > adio/include/romioconf.h.in ; \
		     autoconf -l ../../../confdb configure2.in > configure )
		fi
	        continue
	    fi
	    # The make -q checks whether the target is upto date first;
	    # if it isn't, we remake it.
            (cd $dir ; rm -f mf.tmp ; \
	    sed -e 's%^SHELL[ 	]*=.*%SHELL = /bin/sh%' \
		-e "s%@srcdir@%.%g" \
		-e '/@SET_MAKE@/d' Makefile.in > mf.tmp ;\
		if make -q -f mf.tmp configure 2>&1 >/dev/null ; then \
            : ; else \
	    echo "Found $dir/configure.in" ; \
	    make -f mf.tmp configure ; fi ; rm -f mf.tmp  \
	    )
	    #
            # Under cygwin, sometimes (?) configure ends up containing \^M
	    # (that <ctrl>-M).  We may need to add this sed step
	    # sed -e '/"\
"/d' -e 's/\
//g'
	    # (the first removes case statements on \^M, the second
	    # removes the \^M from the ac_config_files statement
	    if [ ! -s $dir/configure ] ; then 
		echo "PANIC: Could not make configure from configure.in"
		echo "In directory $dir"
		exit 1
	    elif grep 'src/Makefile \\ src' $dir/configure 2>&1 >/dev/null ; then 
		rm -f c.tmp 
		sed -e '/"\\
/d' -e 's/\\
//g' $dir/configure > c.tmp
		rm -f $dir/configure
		mv c.tmp $dir/configure
	    elif grep 'attr/Makefile \\ util' $dir/configure 2>&1 >/dev/null ; then 
		rm -f c.tmp 
		sed -e '/"\\
/d' -e 's/\\
//g' $dir/configure > c.tmp
		rm -f $dir/configure
		mv c.tmp $dir/configure
            fi
        fi
    done
else
    echo "You need to install find (in findutils)"
    exit 1
fi
if [ $rm_prepost = yes ] ; then
    rm -f src/include/mpidpre.h src/include/mpidpost.h
fi
#
if [ ! -x maint/codingcheck -a -s maint/codingcheck ] ; then
    # Fix CVS limitation with file modes (updates from Windows loses x bit)
    chmod +x maint/codingcheck
fi
if [ -x maint/codingcheck -a $do_codingcheck = "yes" ] ; then
    echo ""
    echo "Running coding check"
    echo ""
    # codingcheck now understands directories.
    # skip *only* files provided by an outside source
    # vipl.h is probably ok, even though copyrighted.  Question:
    # Should there be three versions or just one?
    maint/codingcheck -skipfile=./src/pmi/winmpd/crypt.c \
		      -skipfile=./src/pmi/winmpd/crypt.h \
		      -skipfile=./src/pm/winmpd/crypt.h \
		      -skipfile=./src/pmi/winmpd/des.c \
		      -skipfile=./src/pmi/winmpd/des.h \
		      -skipfile=./src/pm/mpd/proxy.c \
		      -skipfile=./src/pm/mpd/sigcatcher.c \
		      -skipfile=./src/pm/mpd/sleeploop.c \
		      -skipfile=./src/pm/mpd/infloop.c \
		      -skipfile=./src/mpid/mm/include/vipl.h \
		      -skipfile=./src/mpid/mm/src/via/vipl.h \
		      -skipfile=./src/mpid/mm/src/viardma/vipl.h \
		      -skipfile=./src/mpi/romio/adio/sgi/mpi3.1/mpi.h \
		      -skipfile=./src/mpi/romio/adio/sgi/mpi3.1/mpif.h \
	 	      -skipfile=./src/mpi/romio/adio/include/mpisgi2.h \
			$codecheck_args src 
fi
