#!/bin/bash

# find where a symbol is defined
# argument 1: "has" == what object provides a given symbol?
#	      "needs" == what object requires a given symbol?
#	      "requiredby" == what symbols are required by an object
#                             providing a given symbol?
# argument 2: the symbol to search for
# argument 3: directory to search in ("." if omitted)


printresult() {
# printresult: arg1 = file, arg2 = search pattern
	local NM=nm
	[ -n "`echo "$1" | egrep '\.so(\.|$)'`" ] && NM="nm -D"
	local results="`$NM "$1" 2> /dev/null | egrep "$2"`"
	[ -n "$results" ] && echo "$results" | sed "s,^,$1: ,g"
}

dir=.
[ -n "$3" ] && dir="$3"
files="find '$dir' -type f -a \
	\( -name \*.o -o -name \*.a -o -name \*.so -o -name \*.so.\* \)"

find_has() {
	search='[^U]'" $1"'$'
	for x in `eval $files` ; do printresult "$x" "$search" ; done
}

find_needs() {
	antisearch='[^U]'" $1"'$'
	search=U" $1"'$'
	for x in `eval $files` ; do
		[ -z "`printresult "$x" "$antisearch"`" ] && \
		printresult "$x" "$search"
	done
}

if [ "$1" = "has" ] ; then
	find_has "$2"
elif [ "$1" = "needs" ] ; then
	find_needs "$2"
elif [ "$1" = "requiredby" ] ; then
	objects="$(echo "$(find_has "$2")" | awk '{print $1}' | tr -d ':')"
	for file in $objects ; do
		printresult "$file" "U "
	done
else
	echo "Usage: findsym {has|needs|requiredby} <symbol>"
	exit 1
fi

exit 0

