?RCS: $Id: Options.U 1 2006-08-24 12:32:52Z rmanfredi $
?RCS:
?RCS: Copyright (c) 1991-1997, 2004-2006, Raphael Manfredi
?RCS:
?RCS: You may redistribute only under the terms of the Artistic License,
?RCS: as specified in the README file that comes with the distribution.
?RCS: You may reuse parts of this distribution only within the terms of
?RCS: that same Artistic License; a copy of which may be found at the root
?RCS: of the source tree for dist 4.0.
?RCS:
?RCS: $Log: Options.U,v $
?RCS: Revision 3.0.1.7  1997/02/28  15:08:15  ram
?RCS: patch61: optdef.sh now starts with a "startsh"
?RCS: patch61: moved some code from Head.U
?RCS:
?RCS: Revision 3.0.1.6  1995/09/25  09:14:46  ram
?RCS: patch59: protected option parsing code against 'echo -*' option failure
?RCS:
?RCS: Revision 3.0.1.5  1995/05/12  12:04:52  ram
?RCS: patch54: added -K option for experts
?RCS:
?RCS: Revision 3.0.1.4  1995/01/30  14:27:52  ram
?RCS: patch49: this unit now exports file optdef.sh, not a variable
?RCS:
?RCS: Revision 3.0.1.3  1995/01/11  15:19:00  ram
?RCS: patch45: new -O option allowing -D and -U to override config.sh settings
?RCS: patch45: file optdef.sh is no longer removed after sourcing
?RCS:
?RCS: Revision 3.0.1.2  1994/10/29  15:58:06  ram
?RCS: patch36: ensure option definition file is removed before appending
?RCS: patch36: protect variable definitions with spaces in them
?RCS:
?RCS: Revision 3.0.1.1  1994/06/20  06:55:44  ram
?RCS: patch30: now uses new me symbol to tag error messages
?RCS: patch30: new -D and -U options to define/undef symbols (JHI)
?RCS:
?RCS: Revision 3.0  1993/08/18  12:05:14  ram
?RCS: Baseline for dist 3.0 netwide release.
?RCS:
?X:
?X: Command line parsing. It is really important that the variables used here
?X:	be not listed in the MAKE line, or they will be saved in config.sh and
?X: loading this file to fetch default answers would clobber the values set
?X:	herein.
?X:
?MAKE:Options: startsh
?MAKE:	-pick wipe $@ %<
?V:reuseval alldone error realsilent silent extractsh fastread \
	knowitall: config_sh
?T:arg argn symbol config_arg0 config_args config_argc xxx yyy zzz uuu
?T:args_exp args_sep arg_exp ccflags
?F:!Configure
?F:./optdef.sh ./cmdline.opt ./posthint.sh ./cmdl.opt
: Save command line options in file UU/cmdline.opt for later use in
: generating config.sh.
?X: This temporary file will be read by Oldsym.U.  I used a temporary
?X: file to preserve all sorts of potential command line quotes and
?X: also because we don't know in advance how many variables we'll
?X: need, so I can't actually declare them on the MAKE line.
?X: The config_args variable won't be quite correct if Configure is
?X: fed something like    ./Configure -Dcc="gcc -B/usr/ccs/bin/"
?X: since the quotes are gone by the time we see them.  You'd have to
?X: reconstruct the command line from the config_arg? lines, but since
?X: I don't imagine anyone actually having to do that, I'm not going
?X: to worry too much.
cat > cmdline.opt <<EOSH
: Configure command line arguments.
config_arg0='$0'
config_args='$*'
config_argc=$#
EOSH
argn=1
args_exp=''
args_sep=''
for arg in "$@"; do
	cat >>cmdline.opt <<EOSH
config_arg$argn='$arg'
EOSH
?X: Extreme backslashitis: replace each ' by '"'"'
	cat <<EOC | sed -e "s/'/'"'"'"'"'"'"'/g" > cmdl.opt
$arg
EOC
	arg_exp=`cat cmdl.opt`
	args_exp="$args_exp$args_sep'$arg_exp'"
	argn=`expr $argn + 1`
	args_sep=' '
done
?X: args_exp is good for restarting self: eval "set X $args_exp"; shift; $0 "$@"
?X: used by hints/os2.sh in Perl, for instance
rm -f cmdl.opt

: produce awk script to parse command line options
cat >options.awk <<'EOF'
BEGIN {
	optstr = "A:dD:eEf:hKOrsSU:V";	# getopt-style specification

	len = length(optstr);
	for (i = 1; i <= len; i++) {
		c = substr(optstr, i, 1);
?X: some older awk's do not have the C ?: construct
		if (i < len) a = substr(optstr, i + 1, 1); else a = "";
		if (a == ":") {
			arg[c] = 1;
			i++;
		}
		opt[c] = 1;
	}
}
{
	expect = 0;
	str = $0;
	if (substr(str, 1, 1) != "-") {
		printf("'%s'\n", str);
		next;
	}
	len = length($0);
	for (i = 2; i <= len; i++) {
		c = substr(str, i, 1);
		if (!opt[c]) {
			printf("-%s\n", substr(str, i));
			next;
		}
		printf("-%s\n", c);
		if (arg[c]) {
			if (i < len)
				printf("'%s'\n", substr(str, i + 1));
			else
				expect = 1;
			next;
		}
	}
}
END {
	if (expect)
		print "?";
}
EOF

: process the command line options
?X: Use "$@" to keep arguments with spaces in them from being split apart.
?X: For the same reason, awk will output quoted arguments and the final eval
?X: removes them and sets a proper $* array. An 'X' is prepended to each
?X: argument before being fed to echo to guard against 'echo -x', where -x
?X: would be understood as an echo option! It is removed before feeding awk.
set X `for arg in "$@"; do echo "X$arg"; done |
	sed -e s/X// | awk -f options.awk`
eval "set $*"
shift
rm -f options.awk

: set up default values
fastread=''
reuseval=false
config_sh=''
alldone=''
error=''
silent=''
extractsh=''
knowitall=''
rm -f optdef.sh posthint.sh
cat >optdef.sh <<EOS
$startsh
EOS

?X:
?X: Given that we now have the possibility to execute Configure remotely
?X: thanks to the new src.U support, we have to face the possibility
?X: of having to ask where the source lie, which means we need the Myread.U
?X: stuff and possibly other things that might echo something on the
?X: screen...
?X:
?X: That's not pretty, and might be confusing in 99% of the time. So...
?X: We introduce a new realsilent variable which is set when -s is given,
?X: and we force silent=true if -S is supplied. The Extractall.U unit
?X: will then undo the >&4 redirection based on the value of the
?X: realsilent variable... -- RAM, 18/93/96
?X:

: option parsing
while test $# -gt 0; do
	case "$1" in
	-d) shift; fastread=yes;;
	-e) shift; alldone=cont;;
	-f)
		shift
		cd ..
		if test -r "$1"; then
			config_sh="$1"
		else
			echo "$me: cannot read config file $1." >&2
			error=true
		fi
		cd UU
		shift;;
	--help|\
	-h) shift; error=true;;
	-r) shift; reuseval=true;;
	-s) shift; silent=true; realsilent=true;;
	-E) shift; alldone=exit;;
	-K) shift; knowitall=true;;
	-O) shift;;
	-S) shift; silent=true; extractsh=true;;
	-D)
		shift
		case "$1" in
		*=)
			echo "$me: use '-U symbol=', not '-D symbol='." >&2
			echo "$me: ignoring -D $1" >&2
			;;
		*=*) echo "$1" | \
				sed -e "s/'/'\"'\"'/g" -e "s/=\(.*\)/='\1'/" >> optdef.sh;;
		*) echo "$1='define'" >> optdef.sh;;
		esac
		shift
		;;
	-U)
		shift
		case "$1" in
		*=) echo "$1" >> optdef.sh;;
		*=*)
			echo "$me: use '-D symbol=val', not '-U symbol=val'." >&2
			echo "$me: ignoring -U $1" >&2
			;;
		*) echo "$1='undef'" >> optdef.sh;;
		esac
		shift
		;;
	-A)
	    shift
	    xxx=''
	    yyy="$1"
	    zzz=''
	    uuu=undef
	    case "$yyy" in
            *=*) zzz=`echo "$yyy"|sed 's!=.*!!'`
                 case "$zzz" in
                 *:*) zzz='' ;;
                 *)   xxx=append
                      zzz=" "`echo "$yyy"|sed 's!^[^=]*=!!'`
                      yyy=`echo "$yyy"|sed 's!=.*!!'` ;;
                 esac
                 ;;
            esac
            case "$xxx" in
            '')  case "$yyy" in
                 *:*) xxx=`echo "$yyy"|sed 's!:.*!!'`
                      yyy=`echo "$yyy"|sed 's!^[^:]*:!!'`
                      zzz=`echo "$yyy"|sed 's!^[^=]*=!!'`
                      yyy=`echo "$yyy"|sed 's!=.*!!'` ;;
                 *)   xxx=`echo "$yyy"|sed 's!:.*!!'`
                      yyy=`echo "$yyy"|sed 's!^[^:]*:!!'` ;;
                 esac
                 ;;
            esac
	    case "$xxx" in
	    append)
		echo "$yyy=\"\${$yyy}$zzz\""	>> posthint.sh ;;
	    clear)
		echo "$yyy=''"			>> posthint.sh ;;
	    define)
	        case "$zzz" in
		'') zzz=define ;;
		esac
		echo "$yyy='$zzz'"		>> posthint.sh ;;
	    eval)
		echo "eval \"$yyy=$zzz\""	>> posthint.sh ;;
	    prepend)
		echo "$yyy=\"$zzz\${$yyy}\""	>> posthint.sh ;;
	    undef)
	        case "$zzz" in
		'') zzz="$uuu" ;;
		esac
		echo "$yyy=$zzz"		>> posthint.sh ;;
            *)  echo "$me: unknown -A command '$xxx', ignoring -A $1" >&2 ;;
	    esac
	    shift
	    ;;
	-V) echo "$me generated by metaconfig <VERSION> PL<PATCHLEVEL>." >&2
	    exit 0;;
	--) break;;
	-*) echo "$me: unknown option $1" >&2; shift; error=true;;
	*) break;;
	esac
done

case "$error" in
true)
	cat >&2 <<EOM
Usage: $me [-dehrsEKOSV] [-f config.sh] [-D symbol] [-D symbol=value]
                 [-U symbol] [-U symbol=] [-A command:symbol...]
  -d : use defaults for all answers.
  -e : go on without questioning past the production of config.sh.
  -f : specify an alternate default configuration file.
  -h : print this help message and exit (with an error status).
  -r : reuse C symbols value if possible (skips costly nm extraction).
  -s : silent mode, only echoes questions and essential information.
  -D : define symbol to have some value:
         -D symbol                symbol gets the value 'define'
         -D symbol='some value'   symbol is set to 'some value'
       common used examples (see INSTALL for more info):
         -Duse64bitint            use 64bit integers
         -Duse64bitall            use 64bit integers and pointers
         -Dusethreads             use thread support
         -Dinc_version_list=none  do not include older perl trees in @INC
         -DEBUGGING=none          DEBUGGING options
         -Dcc=gcc                 choose your compiler
         -Dprefix=/opt/perl5      choose your destination
  -E : stop at the end of questions, after having produced config.sh.
  -K : do not use unless you know what you are doing.
  -O : ignored for backward compatibility
  -S : perform variable substitutions on all .SH files (can mix with -f)
  -U : undefine symbol:
         -U symbol    symbol gets the value 'undef'
         -U symbol=   symbol gets completely empty
       e.g.:  -Uversiononly
  -A : manipulate symbol after the platform specific hints have been applied:
         -A append:symbol=value   append value to symbol
         -A symbol=value          like append:, but with a separating space
         -A define:symbol=value   define symbol to have value
         -A clear:symbol          define symbol to be ''
         -A define:symbol         define symbol to be 'define'
         -A eval:symbol=value     define symbol to be eval of value
         -A prepend:symbol=value  prepend value to symbol
         -A undef:symbol          define symbol to be 'undef'
         -A undef:symbol=         define symbol to be ''
       e.g.:  -A prepend:libswanted='cl pthread '
              -A ccflags=-DSOME_MACRO
  -V : print version number and exit (with a zero status).
EOM
	exit 1
	;;
esac

?X:
?X: Unless they specified either -S or both -d and -e/E, make sure we're
?X: running interactively, i.e. attached to a terminal. Moved from Head.U to
?X: be able to handle batch configurations...
?X:
?X: We have to hardwire the Configure name and cannot use $me, since if they
?X: said 'sh <Configure', then $me is 'sh'...
?X:
: Sanity checks
case "$fastread$alldone" in
yescont|yesexit) ;;
*)
	case "$extractsh" in
	true) ;;
	*)
		if test ! -t 0; then
			echo "Say 'sh Configure', not 'sh <Configure'"
			exit 1
		fi
		;;
	esac
	;;
esac

?X: In silent mode, the standard output is closed. Questions are asked by
?X: outputing on file descriptor #4, which is the original stdout descriptor.
?X: This filters out all the "junk", since all the needed information is written
?X: on #4. Note that ksh will not let us redirect output if the file descriptor
?X: has not be defined yet, unlike sh, hence the following line...--RAM.
exec 4>&1
case "$silent" in
true) exec 1>/dev/null;;
esac

: run the defines and the undefines, if any, but leave the file out there...
touch optdef.sh
?X: -q is POSIX
?X: It does not work in SysV (solaris) or old BSD greps.
grep '\\' optdef.sh >/dev/null 2>&1
if test $? = 0; then
    echo "Configure does not support \\ in -D arguments"
    exit 1
fi
. ./optdef.sh
: create the posthint manipulation script and leave the file out there...
?X: this file will be perused by Oldconfig.U
touch posthint.sh

