#!/bin/sh


##################################################################

### subroutines for listing help texts

list_options_dim()
{
	echo "         problem dimension";
	echo "             2 (two-dimensional problem)";
	echo "             3 (three-dimensional problem)";
}

list_options_arch()
{
	echo "         hardware & compiler (in alphabetical order)";
	echo "             AIX (set ARCH = AIX)";
	echo "             AIXGCC (set ARCH = AIXGCC)";
	echo "             AMD64 (set ARCH = AMD64)";
	echo "             YDL64 (set ARCH = YDL64)";
	echo "             C90 (set ARCH = C90)";
	echo "             CC (set ARCH = CC)";
	echo "             CYGWIN (set ARCH = CYGWIN)";
	echo "             DEC (set ARCH = DEC)";
	echo "             SGI (set ARCH = DEC)";
	echo "             SGI10 (set ARCH = SGI10)";
	echo "             HP (set ARCH = HP)";
	echo "             HP20 (set ARCH = HP20)";
	echo "             HPUX9 (set ARCH = HPUX9)";
	echo "             LINUXAXP (set ARCH = LINUXAXP)";
	echo "             LINUXIA64 (set ARCH = LINUXIA64)";
	echo "             LINUXPPC (set ARCH = LINUXPPC)";	
	echo "             MACOSX (set ARCH = MACOSX)";
	echo "             MACOSX64 (set ARCH = MACOSX64)";
	echo "             MACCLUSTER (set ARCH = MACCLUSTER)";
	echo "             MACOSXSERVER (set ARCH = MACOSXSERVER)";
	echo "             MKLINUX (set ARCH = MKLINUX)";
	echo "             NECSX4 (set ARCH = NECSX4)";
	echo "             ORIGIN (set ARCH = ORIGIN)";
	echo "             PARAGON (set ARCH = PARAGON)";
	echo "             PC (set ARCH = PC)";
	echo "             PCGCOV (set ARCH = PCGCOV)";
	echo "             PCCPP (set ARCH = PCCPP)";
	echo "             PCI (set ARCH = PCI)";
	echo "             PCICPP (set ARCH = PCICPP)";
	echo "             PCCLUSTER (set ARCH = PCCLUSTER)";
	echo "             PCICLUSTER (set ARCH = PCICLUSTER)";
	echo "             POWERGC (set ARCH = POWERGC)";
	echo "             SOLARIS (set ARCH = SOLARIS)";
	echo "             SOLARISGCC (set ARCH = SOLARISGCC)";
	echo "             SP2 (set ARCH = SP2)";
	echo "             SR2201 (set ARCH = SR2201)";
	echo "             SUN4GCC (set ARCH = SUN4GCC)";
	echo "             T3D (set ARCH = T3D)";
	echo "             T3E (set ARCH = T3E)";
	echo "             YMP (set ARCH = YMP)";
}

list_options_ui()
{
	echo "         user interface";
	echo "             SIF (set IF=S, REMOTE_IF = OFF)";
	echo "             MIF (set IF=M, REMOTE_IF = OFF)";
	echo "             XIF (set IF=X, REMOTE_IF = OFF)";
	echo "             RIF (set IF=R, REMOTE_IF = ON)";
	echo "             XRIF (set IF=X, REMOTE_IF = ON)";
	echo "             NORIF (set REMOTE_IF = OFF)";
	echo "             GUI (set GUI = ON)";
	echo "             NOGUI (set GUI = OFF)";
}

list_options_model()
{
	echo "         sequential version or parallel model";
	echo "             SEQ      (sequential version)";
	echo "             MPI      (Message Passing Interface, the standard)";
	echo "             NX       (Intel's message passing)";
	echo "             NXLIB    (NX simulation for workstation clusters)";
	echo "             PARIX    (Parsytec's message passing)";
	echo "             PVM      (Parallel Virtual Machine, ancestor of MPI)";
	echo "             SHMEM    (Cray T3E's shared-memory model)";
	echo "             SHMEMT3D (Cray T3D's shared-memory model)";

}


##################################################################

if test "$1" = "-progname"
then
	PROGNAME=$2;
	shift;
	shift;
else
	PROGNAME=$0;
fi


if test "$1" = "-help"
then
	echo "usage: $PROGNAME [-o] [<conf>]";
	echo "purpose: modify config file $UGROOT/ug.conf";
	echo "Options are";
	echo " -o:     use object database. trade time against diskspace.";
	echo " -v:     print settings in any case.";
	echo " <conf>:";

	list_options_dim;
	list_options_arch;
	list_options_ui;
	list_options_model;

	echo "         domain representation library";
	echo "             STD_DOMAIN (set DOM_MODUL = STD_DOMAIN)";
	echo "             LGM_DOMAIN (set DOM_MODUL = LGM_DOMAIN)";
	echo "             GEN_DOMAIN (set DOM_MODUL = GEN_DOMAIN)";

	echo "         grid generation in 3D";
	echo "             NETGEN (set NETGEN = ON)";
	echo "             NONETGEN (set NETGEN = OFF)";

	echo "         load balancing tool (for parallel version)";
	echo "             CHACO (set CHACO = ON)";
	echo "             NOCHACO (set CHACO = OFF)";

	echo "         interfaces to postprocessing tools";
	echo "             GRAPE (set GRAPE = ON)";
	echo "             NOGRAPE (set GRAPE = OFF)";
	echo "             COVISE (set COVISE = ON)";
	echo "             NOCOVISE (set COVISE = OFF)";
	echo "             PV3 (set PV3 = ON)"
	echo "             NOPV3 (set PV3 = OFF)"

	echo "         interface to CAD";
	echo "             CAD (set CAD = ON)";
	echo "             NOCAD (set CAD = OFF)";

	echo "         debug flag";
	echo "             DEBUG (set DEBUG_MODE = ON)";
	echo "             NODEBUG (set DEBUG_MODE = OFF)";

	echo "         optimization flag";
	echo "             OPTIM (set OPTIM_MODE = ON)";
	echo "             NOOPTIM (set OPTIM_MODE = OFF)";
	exit 1;
fi

if test "x$UGROOT" = "x"
then
	echo "$PROGNAME: to use $PROGNAME set shell environment variable UGROOT!";
	exit 1;
fi


##################################################################

# internal option '-list <what>' in order to show portions of help 
if test "$1" = "-list"
then
	case $2 in
	dim)
		list_options_dim;
		;;
	arch)
		list_options_arch;
		;;
	ui)
		list_options_ui;
		;;
	model)
		list_options_model;
		;;
	esac;
	exit 1;
fi


##################################################################

# switch AWK depending on unix version
if test -x /bin/uname
then
    case `/bin/uname` in
	    HP-UX | Linux)
		    AWK=awk
		    ;;
	    *)
		    AWK=nawk
		    ;;
    esac;
else
AWK=awk
fi

# compression/decompression

#PACKER=gzip
#UNPACKER=gunzip --stdout
#PACKSUFFIX=gz

PACKER=compress
UNPACKER=zcat
PACKSUFFIX=Z


##################################################################
# subroutines
##################################################################

### subroutines for configuration

grep_valid_entries()
{
	egrep '^[ ]*ARCH|^[ ]*MODEL |^[ ]*DIM|^[ ]*GRAPE |^[ ]*COVISE|^[ ]*PV3|^[ ]*NETGEN|^[ ]*REMOTE_IF|^[ ]*IF|^[ ]*DOM_MODULE|^[ ]*DEBUG_MODE|^[ ]*OPTIM_MODE|^[ ]*CHACO|^[ ]*CAD|^[ ]*GUI' $1;
}


### subroutines for obj-database

build_objdb_name()
{
	grep_valid_entries $1 | $AWK '{printf("%s.",$3);} END { print "obj"}' -
}


objdb_show_contents()
{
	OBJDIR=$UGROOT/obj

	# test whether object database exists
	if test ! -d $OBJDIR
	then
		echo "no object database."
	else
		cd $OBJDIR
		echo "contents of your ug object database (size in blocks):"
		du 
	fi
}


objdb_save_current()
{
	OBJDIR=$UGROOT/obj

	# create object database, if none
	if test ! -d $OBJDIR
	then
		echo "creating ug object database " $OBJDIR
		mkdir $OBJDIR
	fi

	echo "saving current objects into object database"

	# test whether objdb for old ug.conf already exists
	if test -d $OBJDIR/`build_objdb_name $UGROOT/ug.conf`
	then
		echo "  removing old object tree " `build_objdb_name $UGROOT/ug.conf`
		cat $OBJDIR/`build_objdb_name $UGROOT/ug.conf`/date
		rm -r $OBJDIR/`build_objdb_name $UGROOT/ug.conf`
	fi

	# save object tree
	cd $UGROOT

	# create list of all objects
	find . -name "*.o" -print >$OBJDIR/obj_list

	# create directory in database and copy current ug.conf there
	mkdir $OBJDIR/`build_objdb_name $UGROOT/ug.conf`
	cp ug.conf $OBJDIR/`build_objdb_name $UGROOT/ug.conf`
	echo "   (version from " `date` ")" \
		> $OBJDIR/`build_objdb_name $UGROOT/ug.conf`/date

	# collect objects into compressed tar file.
	echo "  this may take a while ..."
	tar cf - `cat $OBJDIR/obj_list` | \
		$PACKER >$OBJDIR/`build_objdb_name $UGROOT/ug.conf`/obj.tar.$PACKSUFFIX
	echo "  stored " `build_objdb_name $UGROOT/ug.conf` " in object database."
}


objdb_restore_new()
{
	OBJDIR=$UGROOT/obj

	# test if there is a database for new ug.conf
	if test -d $OBJDIR/`build_objdb_name $UGROOT/ug.conf`
	then
		echo "restoring old object tree from object database"

		# remove all existing obj-files
		cd $UGROOT
		find . -name '*.o' -exec rm {} \;

		# restore object tree
		cd $UGROOT
		$UNPACKER $OBJDIR/`build_objdb_name $UGROOT/ug.conf`/obj.tar.$PACKSUFFIX  | \
			tar xf -
		echo "  restored object tree " `build_objdb_name $UGROOT/ug.conf`
		cat $OBJDIR/`build_objdb_name $UGROOT/ug.conf`/date

	else
		echo "database contains no object tree " `build_objdb_name $UGROOT/ug.conf`
		echo "  no restore this time, so we keep old object files."
		echo "  use ugbcheck to check integrity of your executable."
	fi
}



# edit_ugconf (ug.conf-filename, cmdline-argument)

edit_ugconf()
{
	case $2 in
	2)
		sed 's/^DIM.*$/DIM = 2/' $1 > $1.tmp
		;;
	3)
		sed 's/^DIM.*$/DIM = 3/' $1 > $1.tmp
		;;

	NETGEN)
		sed 's/^NETGEN.*$/NETGEN = ON/' $1 > $1.tmp
		mv $1.tmp $1
		sed 's/^DIM.*$/DIM = 3/' $1 > $1.tmp
		;;
	NONETGEN)
		sed 's/^NETGEN.*$/NETGEN = OFF/' $1 > $1.tmp
		;;

	GRAPE)
		sed 's/^GRAPE.*$/GRAPE = ON/' $1 > $1.tmp
		;;
	NOGRAPE)
		sed 's/^GRAPE.*$/GRAPE = OFF/' $1 > $1.tmp
		;;
	COVISE)
		sed 's/^COVISE.*$/COVISE = ON/' $1 > $1.tmp
		;;
	NOCOVISE)
		sed 's/^COVISE.*$/COVISE = OFF/' $1 > $1.tmp
		;;
	PV3)
		sed 's/^PV3.*$/PV3 = ON/' $1 > $1.tmp
		;;
	NOPV3)
		sed 's/^PV3.*$/PV3 = OFF/' $1 > $1.tmp
		;;

	RIF)
		sed 's/^IF.*$/IF = R/' $1 > $1.tmp
		mv $1.tmp $1
		sed 's/^REMOTE_IF.*$/REMOTE_IF = ON/' $1 > $1.tmp
		;;
	SIF)
		sed 's/^IF.*$/IF = S/' $1 > $1.tmp
		mv $1.tmp $1
		sed 's/^REMOTE_IF.*$/REMOTE_IF = OFF/' $1 > $1.tmp
	    touch $UGROOT/lib/libdevS.a	    
		;;
        MIF)
                sed 's/^IF.*$/IF = M/' $1 > $1.tmp
	        mv $1.tmp $1
	        sed 's/^REMOTE_IF.*$/REMOTE_IF = OFF/' $1 > $1.tmp
	        touch $UGROOT/lib/libdevM.a
	        ;;
	XIF)
		sed 's/^IF.*$/IF = X/' $1 > $1.tmp
		mv $1.tmp $1
		sed 's/^REMOTE_IF.*$/REMOTE_IF = OFF/' $1 > $1.tmp
	    touch $UGROOT/lib/libdevX.a	    
		;;
	XRIF)
		sed 's/^IF.*$/IF = X/' $1 > $1.tmp
		mv $1.tmp $1
		sed 's/^REMOTE_IF.*$/REMOTE_IF = ON/' $1 > $1.tmp
		;;
	NORIF)
		sed 's/^REMOTE_IF.*$/REMOTE_IF = OFF/' $1 > $1.tmp
		;;
	GUI)
		sed 's/^GUI[ ].*$/GUI = ON/' $1 > $1.tmp
		;;
	NOGUI)
		sed 's/^GUI[ ].*$/GUI = OFF/' $1 > $1.tmp
		;;

	HP)
		sed 's/^ARCH.*$/ARCH = HP/' $1 > $1.tmp
		;;
	HP20)
		sed 's/^ARCH.*$/ARCH = HP20/' $1 > $1.tmp
		;;
	HPUX9)
		sed 's/^ARCH.*$/ARCH = HPUX9/' $1 > $1.tmp
		;;
	DEC)
		sed 's/^ARCH.*$/ARCH = DEC/' $1 > $1.tmp
		;;
	SGI)
		sed 's/^ARCH.*$/ARCH = SGI/' $1 > $1.tmp
		;;
	SGI10)
		sed 's/^ARCH.*$/ARCH = SGI10/' $1 > $1.tmp
		;;
	AIX)
		sed 's/^ARCH.*$/ARCH = AIX/' $1 > $1.tmp
		;;
	SP2)
		sed 's/^ARCH.*$/ARCH = SP2/' $1 > $1.tmp
		;;
	AIXGCC)
		sed 's/^ARCH.*$/ARCH = AIXGCC/' $1 > $1.tmp
		;;
	PARAGON)
		sed 's/^ARCH.*$/ARCH = PARAGON/' $1 > $1.tmp
		;;
	PC)
		sed 's/^ARCH.*$/ARCH = PC/' $1 > $1.tmp
		;;
	PCGCOV)
		sed 's/^ARCH.*$/ARCH = PCGCOV/' $1 > $1.tmp
		;;
	PCCPP)
                sed 's/^ARCH.*$/ARCH = PCCPP/' $1 > $1.tmp
                ;;
	PCI)
		sed 's/^ARCH.*$/ARCH = PCI/' $1 > $1.tmp
		;;
        PCICPP)
                sed 's/^ARCH.*$/ARCH = PCICPP/' $1 > $1.tmp
                ;;
	PCCLUSTER)
		sed 's/^ARCH.*$/ARCH = PCCLUSTER/' $1 > $1.tmp
		mv $1.tmp $1
                sed 's/^MODEL[ \t].*$/MODEL = MPI/' $1 >$1.tmp
		;;
	PCICLUSTER)
		sed 's/^ARCH.*$/ARCH = PCICLUSTER/' $1 > $1.tmp
		mv $1.tmp $1
                sed 's/^MODEL[ \t].*$/MODEL = MPI/' $1 >$1.tmp
		;;
	MKLINUX)
		sed 's/^ARCH.*$/ARCH = MKLINUX/' $1 > $1.tmp
		;;
	LINUXPPC)
		sed 's/^ARCH.*$/ARCH = LINUXPPC/' $1 > $1.tmp
		;;
	LINUXAXP)
		sed 's/^ARCH.*$/ARCH = LINUXAXP/' $1 > $1.tmp
		;;
	LINUXIA64)
		sed 's/^ARCH.*$/ARCH = LINUXIA64/' $1 > $1.tmp
		;;
	CYGWIN)
	        sed 's/^ARCH.*$/ARCH = CYGWIN/' $1 > $1.tmp
		;;
	POWERGC)
		sed 's/^ARCH.*$/ARCH = POWERGC/' $1 > $1.tmp
		;;
	CC)
		sed 's/^ARCH.*$/ARCH = CC/' $1 > $1.tmp
		;;
	C90)
		sed 's/^ARCH.*$/ARCH = C90/' $1 > $1.tmp
		;;
	YMP)
		sed 's/^ARCH.*$/ARCH = YMP/' $1 > $1.tmp
		;;
	SOLARIS)
		sed 's/^ARCH.*$/ARCH = SOLARIS/' $1 > $1.tmp
		;;
	SOLARISGCC)
		sed 's/^ARCH.*$/ARCH = SOLARISGCC/' $1 > $1.tmp
		;;
	SUN4GCC)
		sed 's/^ARCH.*$/ARCH = SUN4GCC/' $1 > $1.tmp
		;;
	SR2201)
		sed 's/^ARCH.*$/ARCH = SR2201/' $1 > $1.tmp
		;;
	T3D)
		sed 's/^ARCH.*$/ARCH = T3D/' $1 > $1.tmp
		;;
	T3E)
		sed 's/^ARCH.*$/ARCH = T3E/' $1 > $1.tmp
		;;
	NECSX4)
		sed 's/^ARCH.*$/ARCH = NECSX4/' $1 > $1.tmp
		;;
	MACOSX)
		sed 's/^ARCH.*$/ARCH = MACOSX/' $1 > $1.tmp
		;;
	MACOSX64)
		sed 's/^ARCH.*$/ARCH = MACOSX64/' $1 > $1.tmp
		;;
	MACCLUSTER)
		sed 's/^ARCH.*$/ARCH = MACCLUSTER/' $1 > $1.tmp
		mv $1.tmp $1
                sed 's/^MODEL[ \t].*$/MODEL = MPI/' $1 >$1.tmp
		;;
	MACOSXSERVER)
		sed 's/^ARCH.*$/ARCH = MACOSXSERVER/' $1 > $1.tmp
		;;
	ORIGIN)
		sed 's/^ARCH.*$/ARCH = ORIGIN/' $1 > $1.tmp
		;;
	AMD64)
		sed 's/^ARCH.*$/ARCH = AMD64/' $1 > $1.tmp
		;;
	YDL64)
		sed 's/^ARCH.*$/ARCH = YDL64/' $1 > $1.tmp
		;;
	SEQ)
		sed 's/^MODEL[ \t].*$/MODEL = SEQ/' $1 > $1.tmp
		;;
	MPI)
		sed 's/^MODEL[ \t].*$/MODEL = MPI/' $1 > $1.tmp
		;;
	NX)
		sed 's/^MODEL[ \t].*$/MODEL = NX/' $1 > $1.tmp
		;;
	NXLIB)
		sed 's/^MODEL[ \t].*$/MODEL = NXLIB/' $1 > $1.tmp
		;;
	PARIX)
		sed 's/^MODEL[ \t].*$/MODEL = PARIX/' $1 > $1.tmp
		;;
	PVM)
		sed 's/^MODEL[ \t].*$/MODEL = PVM/' $1 > $1.tmp
		;;
	SHMEM)
		sed 's/^MODEL[ \t].*$/MODEL = SHMEM/' $1 > $1.tmp
		;;
	SHMEMT3D)
		sed 's/^MODEL[ \t].*$/MODEL = SHMEMT3D/' $1 > $1.tmp
		;;

	STD_DOMAIN)
		sed 's/^DOM_MODULE.*$/DOM_MODULE = STD_DOMAIN/' $1 > $1.tmp
		;;
	LGM_DOMAIN)
		sed 's/^DOM_MODULE.*$/DOM_MODULE = LGM_DOMAIN/' $1 > $1.tmp
		;;
	GEN_DOMAIN)
		sed 's/^DOM_MODULE.*$/DOM_MODULE = GEN_DOMAIN/' $1 > $1.tmp
		;;

	DEBUG)
		sed 's/^DEBUG_MODE.*$/DEBUG_MODE = ON/' $1 > $1.tmp
		;;
	NODEBUG)
		sed 's/^DEBUG_MODE.*$/DEBUG_MODE = OFF/' $1 > $1.tmp
		;;

	OPTIM)
		sed 's/^OPTIM_MODE.*$/OPTIM_MODE = ON/' $1 > $1.tmp
		;;
	NOOPTIM)
		sed 's/^OPTIM_MODE.*$/OPTIM_MODE = OFF/' $1 > $1.tmp
		;;

	CHACO)
		sed 's/^CHACO.*$/CHACO = ON/' $1 > $1.tmp
		;;
	NOCHACO)
		sed 's/^CHACO.*$/CHACO = OFF/' $1 > $1.tmp
		;;

	CAD)
		sed 's/^CAD.*$/CAD = ON/' $1 > $1.tmp
		;;
	NOCAD)
		sed 's/^CAD.*$/CAD = OFF/' $1 > $1.tmp
		;;

	*)
		echo "error: unrecognized option '" $2 "'. use '$PROGNAME -help' for help.";
		cp $1 $1.tmp
	esac;

	mv $1.tmp $1
}


##################################################################


# test whether object database should be used
if test "$1" = "-o"
then
	USE_OBJDB="true"
	shift
else
	USE_OBJDB="false"
fi




# test whether ugconf should print the settings 
if test "$USE_OBJDB" = "false"
then
	if test "$1" = "-v"
	then
		VERBOSE="true"
		shift
	else
	        VERBOSE="false"
        fi
else
	if test "$2" = "-v"
        then
                VERBOSE="true"
		shift
        else
                VERBOSE="false"
        fi
fi




if test $# -eq 0
then 
	echo "current ug configuration is:";
	echo "UGROOT = $UGROOT";
	grep_valid_entries $UGROOT/ug.conf;
	if test "$USE_OBJDB" = "true"
	then
		echo
		objdb_show_contents;
	fi
	
	exit 0;
fi




# process arguments and edit ug.conf.new
cp $UGROOT/ug.conf $UGROOT/ug.conf.new

FLAG_QUIET="false";
while [ $# -gt 0 ]; do
	if test "$1" = "-q"
	then
		FLAG_QUIET="true";
	else
		( edit_ugconf $UGROOT/ug.conf.new $1; )
	fi

	shift;
done


# decide whether ug.conf has really been changed
grep_valid_entries $UGROOT/ug.conf > $UGROOT/ug.conf.old.1
grep_valid_entries $UGROOT/ug.conf.new > $UGROOT/ug.conf.new.1
if test $HOSTTYPE != "macintosh"
then
if `diff $UGROOT/ug.conf.old.1 $UGROOT/ug.conf.new.1 >/dev/null `
then
	if test $FLAG_QUIET = "false"
	then
		echo "nothing changed by these parameters.";
	fi
	rm $UGROOT/ug.conf.old.1 $UGROOT/ug.conf.new.1
	rm $UGROOT/ug.conf.new
	if test "$VERBOSE" = "true"
        then
		grep_valid_entries $UGROOT/ug.conf;
		if test "$USE_OBJDB" = "true"
		then
			echo
			objdb_show_contents;
		fi
	fi
	exit 0;
fi
fi
rm $UGROOT/ug.conf.old.1 $UGROOT/ug.conf.new.1






if test "$USE_OBJDB" = "true"
then
	objdb_save_current;
fi

mv $UGROOT/ug.conf.new $UGROOT/ug.conf

if test "$USE_OBJDB" = "true"
then
	objdb_restore_new;
fi




if test "$VERBOSE" = "true"
then
	grep_valid_entries $UGROOT/ug.conf;
        if test "$USE_OBJDB" = "true"
        then
                echo
                objdb_show_contents;
        fi
fi







