?RCS: $Id$
?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: libc.U,v $
?RCS: Revision 3.0.1.10  1997/02/28  15:56:48  ram
?RCS: patch61: replaced .a with $_a all over the place
?RCS: patch61: added support for HPUX-10 nm output
?RCS:
?RCS: Revision 3.0.1.9  1995/07/25  14:11:56  ram
?RCS: patch56: now knows about OS/2 platforms
?RCS:
?RCS: Revision 3.0.1.8  1995/05/12  12:20:47  ram
?RCS: patch54: made sure only most recent version of shared lib is picked
?RCS: patch54: final "nm -p" check now uses xscan and xrun like everybody
?RCS: patch54: can now grok linux nm output with lead __IO (ADO)
?RCS: patch54: added support for linux ELF output, using 'W' for alias (ADO)
?RCS:
?RCS: Revision 3.0.1.7  1994/10/29  16:23:40  ram
?RCS: patch36: now looks for shared libraries before anything else (ADO)
?RCS: patch36: added new nm output format (ADO)
?RCS:
?RCS: Revision 3.0.1.6  1994/08/29  16:28:10  ram
?RCS: patch32: added I-type symbols for nm output parsing on Linux
?RCS:
?RCS: Revision 3.0.1.5  1994/06/20  07:03:24  ram
?RCS: patch30: checks are now presented by succession of if/elif
?RCS: patch30: uniformized checks for shared objects with new so symbol
?RCS:
?RCS: Revision 3.0.1.4  1994/05/06  15:06:33  ram
?RCS: patch23: added shared library knowledge (ADO and WED)
?RCS:
?RCS: Revision 3.0.1.3  1994/01/24  14:12:17  ram
?RCS: patch16: can now export nm_extract as an internal-use only variable
?RCS:
?RCS: Revision 3.0.1.2  1993/09/13  16:09:03  ram
?RCS: patch10: added special handling for Apollo systems (WAD)
?RCS:
?RCS: Revision 3.0.1.1  1993/08/27  14:40:03  ram
?RCS: patch7: added entry for /usr/shlib/libc.so (OSF/1 machines)
?RCS:
?RCS: Revision 3.0  1993/08/18  12:08:57  ram
?RCS: Baseline for dist 3.0 netwide release.
?RCS:
?MAKE:libc libnames +nm_extract: echo n c rm test grep Getfile Myread \
	Oldconfig Loc sed libs incpath libpth ar runnm nm nm_opt nm_so_opt \
	contains xlibpth so osname trnl tr sort uniq _o _a
?MAKE:	-pick add $@ %<
?S:libc:
?S:	This variable contains the location of the C library.
?S:.
?S:libnames:
?S:	The constructed list of library names.  Normally empty, but hint files
?S:	may set this for later perusal by Configure.
?S:.
?S:nm_extract:
?S:	This variable holds the name of the extraction command used to process
?S:	the output of nm and yield the list of defined symbols. It is used
?S:	internally by Configure.
?S:.
?T:thislib try libnames xxx xscan xrun thisname com tans file
?F:!libnames !libc.tmp !tmp.imp
?LINT:change nm_opt runnm
?INIT:libnames=''
: Figure out where the libc is located
case "$runnm" in
true)
?X: indentation is wrong on purpose--RAM
: get list of predefined functions in a handy place
echo " "
case "$libc" in
'') libc=unknown
	case "$libs" in
	*-lc_s*) libc=`./loc libc_s$_a $libc $libpth`
	esac
	;;
esac
case "$libs" in
'') ;;
*)  for thislib in $libs; do
	case "$thislib" in
	-lc|-lc_s)
		: Handle C library specially below.
		;;
	-l*)
		thislib=`echo $thislib | $sed -e 's/^-l//'`
		if try=`./loc lib$thislib.$so.'*' X $libpth`; $test -f "$try"; then
			:
		elif try=`./loc lib$thislib.$so X $libpth`; $test -f "$try"; then
			:
		elif try=`./loc lib$thislib$_a X $libpth`; $test -f "$try"; then
			:
		elif try=`./loc $thislib$_a X $libpth`; $test -f "$try"; then
			:
		elif try=`./loc lib$thislib X $libpth`; $test -f "$try"; then
			:
		elif try=`./loc $thislib X $libpth`; $test -f "$try"; then
			:
		elif try=`./loc Slib$thislib$_a X $xlibpth`; $test -f "$try"; then
			:
		else
			try=''
		fi
		libnames="$libnames $try"
		;;
	*) libnames="$libnames $thislib" ;;
	esac
	done
	;;
esac
?X:
?X: Some systems (e.g. DG/UX) use "environmental" links, which make the test
?X: -f fail. Ditto for symbolic links. So in order to reliably check the
?X: existence of a file, we use test -r. It will still fail with DG/UX links
?X: though, but at least it will detect symbolic links. At some strategic
?X: points, we make use of (test -h), using a sub-shell in case builtin test
?X: does not implement the -h check for symbolic links. This makes it
?X: possible to preset libc in a hint file for instance and have it show up
?X: as-is in the question.
?X:
xxx=normal
case "$libc" in
unknown)
?X:
?X: The sed below transforms .so.9 .so.12 into something like .so.0009 .so.0012,
?X: then sorts on it to allow keeping .so.12 instead of .so.9 as the latest
?X: up-to-date library. The initial filename (before sed munging, saved in hold
?X: space via 'h') is appended via 'G' before sorting, then the leading munged
?X: part is removed after sorting. Nice efficient work from Tye McQueen.
?X: The initial blurfl is here to prevent the trailing pipe from producing an
?X: empty string, causing Configure to output all its set variables!
?X:
	set /lib/libc.$so
	for xxx in $libpth; do
		$test -r $1 || set $xxx/libc.$so
		: The messy sed command sorts on library version numbers.
		$test -r $1 || \
			set `echo blurfl; echo $xxx/libc.$so.[0-9]* | \
			tr ' ' $trnl | egrep -v '\.[A-Za-z]*$' | $sed -e '
				h
				s/[0-9][0-9]*/0000&/g
				s/0*\([0-9][0-9][0-9][0-9][0-9]\)/\1/g
				G
				s/\n/ /' | \
			 $sort | $sed -e 's/^.* //'`
		eval set \$$#
	done
	$test -r $1 || set /usr/ccs/lib/libc.$so
	$test -r $1 || set /lib/libsys_s$_a
	;;
*)
?X: ensure the test below for the (shared) C library will fail
	set blurfl
	;;
esac
if $test -r "$1"; then
	echo "Your (shared) C library seems to be in $1."
	libc="$1"
elif $test -r /lib/libc && $test -r /lib/clib; then
?X:
?X: Apollo has its C library in /lib/clib AND /lib/libc
?X: not to mention its math library in /lib/syslib...
?X:
	echo "Your C library seems to be in both /lib/clib and /lib/libc."
	xxx=apollo
	libc='/lib/clib /lib/libc'
	if $test -r /lib/syslib; then
		echo "(Your math library is in /lib/syslib.)"
?X: Put syslib in libc -- not quite right, but won't hurt
		libc="$libc /lib/syslib"
	fi
elif $test -r "$libc" || (test -h "$libc") >/dev/null 2>&1; then
	echo "Your C library seems to be in $libc, as you said before."
?X: For mips, and...
elif $test -r $incpath/usr/lib/libc$_a; then
	libc=$incpath/usr/lib/libc$_a;
	echo "Your C library seems to be in $libc.  That's fine."
elif $test -r /lib/libc$_a; then
	libc=/lib/libc$_a;
	echo "Your C library seems to be in $libc.  You're normal."
else
	if tans=`./loc libc$_a blurfl/dyick $libpth`; $test -r "$tans"; then
		:
	elif tans=`./loc libc blurfl/dyick $libpth`; $test -r "$tans"; then
		libnames="$libnames "`./loc clib blurfl/dyick $libpth`
	elif tans=`./loc clib blurfl/dyick $libpth`; $test -r "$tans"; then
		:
	elif tans=`./loc Slibc$_a blurfl/dyick $xlibpth`; $test -r "$tans"; then
		:
	elif tans=`./loc Mlibc$_a blurfl/dyick $xlibpth`; $test -r "$tans"; then
		:
	else
		tans=`./loc Llibc$_a blurfl/dyick $xlibpth`
	fi
	if $test -r "$tans"; then
		echo "Your C library seems to be in $tans, of all places."
		libc=$tans
	else
		libc='blurfl'
	fi
fi
if $test $xxx = apollo -o -r "$libc" || (test -h "$libc") >/dev/null 2>&1; then
	dflt="$libc"
	cat <<EOM

If the guess above is wrong (which it might be if you're using a strange
compiler, or your machine supports multiple models), you can override it here.

EOM
else
	dflt=''
	echo $libpth | $tr ' ' $trnl | $sort | $uniq > libpath
	cat >&4 <<EOM
I can't seem to find your C library.  I've looked in the following places:

EOM
	$sed 's/^/	/' libpath
	cat <<EOM

None of these seems to contain your C library. I need to get its name...

EOM
fi
fn=f
rp='Where is your C library?'
. ./getfile
libc="$ans"

echo " "
echo $libc $libnames | $tr ' ' $trnl | $sort | $uniq > libnames
set X `cat libnames`
shift
xxx=files
case $# in 1) xxx=file; esac
echo "Extracting names from the following $xxx for later perusal:" >&4
echo " "
$sed 's/^/	/' libnames >&4
echo " "
$echo $n "This may take a while...$c" >&4

?X:
?X: Linux may need the special Dynamic option to nm for shared libraries.
?X: In general, this is stored in the nm_so_opt variable.
?X: Unfortunately, that option may be fatal on non-shared libraries.
?X:
for file in $*; do
	case $file in
	*$so*) $nm $nm_so_opt $nm_opt $file 2>/dev/null;;
	*) $nm $nm_opt $file 2>/dev/null;;
	esac
done >libc.tmp

$echo $n ".$c"
?X:
?X: To accelerate processing, we look at the correct 'sed' command
?X:	by using a small subset of libc.tmp, i.e. fprintf function.
?X: When we know which sed command to use, do the name extraction
?X:
$grep fprintf libc.tmp > libc.ptf
?X:
?X: In order to enhance readability and save some space, we define
?X:	some variables that will be "eval"ed.
?X:
xscan='eval "<libc.ptf $com >libc.list"; $echo $n ".$c" >&4'
xrun='eval "<libc.tmp $com >libc.list"; echo "done." >&4'
?X: BSD-like output, I and W types added for Linux
?X: Some versions of Linux include a leading __IO in the symbol name.
?X: HPUX10 reportedly has trailing spaces, though I'm surprised it has
?X: BSD-like output.  (AD).
xxx='[ADTSIW]'
if com="$sed -n -e 's/__IO//' -e 's/^.* $xxx  *_[_.]*//p' -e 's/^.* $xxx  *//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
?X: SYSV-like output
elif com="$sed -n -e 's/^__*//' -e 's/^\([a-zA-Z_0-9$]*\).*xtern.*/\1/p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e '/|UNDEF/d' -e '/FUNC..GL/s/^.*|__*//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e 's/^.* D __*//p' -e 's/^.* D //p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e 's/^_//' -e 's/^\([a-zA-Z_0-9]*\).*xtern.*text.*/\1/p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e 's/^.*|FUNC |GLOB .*|//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$grep '|' | $sed -n -e '/|COMMON/d' -e '/|DATA/d' \
				-e '/ file/d' -e 's/^\([^ 	]*\).*/\1/p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e 's/^.*|FUNC |GLOB .*|//p' -e 's/^.*|FUNC |WEAK .*|//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
?X: mips nm output (sysV)
elif com="$sed -n -e 's/^__//' -e '/|Undef/d' -e '/|Proc/s/ .*//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e 's/^.*|Proc .*|Text *| *//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e '/Def. Text/s/.* \([^ ]*\)\$/\1/p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
?X: OS/2 nm output
elif com="$sed -n -e 's/^[-0-9a-f ]*_\(.*\)=.*/\1/p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
elif com="$sed -n -e 's/.*\.text n\ \ \ \.//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
?X: AIX nm output
elif com="sed -n -e 's/^__.*//' -e 's/[       ]*D[    ]*[0-9]*.*//p'";\
	eval $xscan;\
	$contains '^fprintf$' libc.list >/dev/null 2>&1; then
		eval $xrun
else
	$nm -p $* 2>/dev/null >libc.tmp
	$grep fprintf libc.tmp > libc.ptf
	if com="$sed -n -e 's/^.* [ADTSIW]  *_[_.]*//p' -e 's/^.* [ADTSIW] //p'";\
		eval $xscan; $contains '^fprintf$' libc.list >/dev/null 2>&1
	then
		nm_opt='-p'
		eval $xrun
	else
		echo " "
		echo "$nm didn't seem to work right. Trying $ar instead..." >&4
		com=''
		if $ar t $libc > libc.tmp && \
			$contains '^fprintf$' libc.tmp >/dev/null 2>&1
		then
			for thisname in $libnames $libc; do
				$ar t $thisname >>libc.tmp
			done
			$sed -e "s/\\$_o\$//" < libc.tmp > libc.list
			echo "Ok." >&4
		elif test "X$osname" = "Xos2" && $ar tv $libc > libc.tmp; then
?X: Repeat libc to extract forwarders to DLL entries too
			for thisname in $libnames $libc; do
				$ar tv $thisname >>libc.tmp
?X: Revision 50 of EMX has bug in ar: it will not extract forwarders
?X: to DLL entries.  Use emximp which will extract exactly them.
				emximp -o tmp.imp $thisname \
				    2>/dev/null && \
				    $sed -e 's/^\([_a-zA-Z0-9]*\) .*$/\1/p' \
				    < tmp.imp >>libc.tmp
				$rm -f tmp.imp
			done
			$sed -e "s/\\$_o\$//" -e 's/^ \+//' < libc.tmp > libc.list
			echo "Ok." >&4
		else
			echo "$ar didn't seem to work right." >&4
			echo "Maybe this is a Cray...trying bld instead..." >&4
			if
				bld t $libc | \
					$sed -e 's/.*\///' -e "s/\\$_o:.*\$//" > libc.list &&
				$test -s libc.list
			then
				for thisname in $libnames; do
					bld t $libnames | \
					$sed -e 's/.*\///' -e "s/\\$_o:.*\$//" >>libc.list
					$ar t $thisname >>libc.tmp
				done
				echo "Ok." >&4
			else
				echo "That didn't work either." >&4
				echo "No problem, I'll be compiling test programs then..." >&4
				runnm=false
			fi
		fi
	fi
fi
nm_extract="$com"
if $test -f /lib/syscalls.exp; then
	echo " "
	echo "Also extracting names from /lib/syscalls.exp for good ole AIX..." >&4
	$sed -n 's/^\([^ 	]*\)[ 	]*syscall[0-9]*[ 	]*$/\1/p' \
		/lib/syscalls.exp >>libc.list
fi
?X: remember, indentation is wrong on purpose--RAM
;;
esac
$rm -f libnames libpath

