#!/bin/sh
#ident	"@(#)sc:hier/bin/hier	3.5"
###############################################################################
#
# C++ Standard Components, Release 3.0.
#
# Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc.
# Copyright (c) 1988, 1989, 1990 AT&T.  All Rights Reserved.
#
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System
# Laboratories, Inc.  The copyright notice above does not evidence
# any actual or intended publication of such source code.
#
###############################################################################

# Your C++ translator.
CC=${CC-CC}

# Set this to where you installed the library files.
HIER2=${HIER2-`dirname $0`/../lib/hier2}

# Set these to the locations of these tools on your machine.  
# If you don't have one, then just set it to the empty string, 
# eg, TPIC=
DAG=${DAG-/tools/DAG/bin/dag}	# dag graph drawing tool
TPIC=${TPIC-/usr/tools/ctex/bin/tpic}	# pic to tex converter
TEX=${TEX-/usr/tools/ctex/bin/tex}	# Knuth's TeX

# Set these to whatever number of inches you like.  It's the 
# default size of the inheritance graph.  If you change it 
# from 8.5x10, remember to change the manpage.
DEFAULTWIDTH=8.5
DEFAULTHEIGHT=10

###############################################################
# You shouldn't have to change anything below this line.
###############################################################
badargs=0
set -- `getopt Aakintvcsumxb:D:U:I:Rh:w:L:o: $*`
if [ $? -ne 0 ]
then	badargs=1
fi

cppopts=
boxname=graph
width=$DEFAULTWIDTH
height=$DEFAULTHEIGHT
base=hierout
parseopts=
vertical=0
wantps=0
wantdvi=0
wanttex=0
wantpic=0
wantdag=0
countlangs=
lang=

# parse the options
#
for i in $*
do	case $i in
	-x)	set -x
		shift;;
	-b)	case $2 in
			-*)	echo "hier: missing box name"; badargs=1; break;;
			*)	boxname=$2; shift; shift;;
		esac;;
	-L)	countlangs=x$countlangs
		lang=$2
		case $lang in
			ps)	wantps=1;;
			dvi)	wantdvi=1;;
			tex)	wanttex=1;;
			pic)	wantpic=1;;
			dag)	wantdag=1;;
			*)	echo "hier: unrecognized language -- $2"; badargs=1;;
		esac; shift; shift;;
	-h)	case $2 in 
			[0-9]*)	height=$2; shift; shift;;	# rudimentary error checking.  
								# should really check that $2 is a number.
			-*)	echo "hier: missing height"; badargs=1; break;;
			*)	echo "hier: bad height ($2)"; badargs=1; shift; shift;;
		esac;;
	-w)	case $2 in 
			[0-9]*)	width=$2; shift; shift;;
			-*)	echo "hier: missing width"; badargs=1; break;;
			*)	echo "hier: bad width ($2)"; badargs=1; shift; shift;;
		esac;;
	-o)	case $2 in
			-*)	echo "hier: missing base file name"; badargs=1; break;;
			*)	base=`echo $2 | sed 's/\.[^\.]*$//'`	# strip any extension.  
									# i will provide the appropriate extension(s).
		esac; shift; shift;;
	-[Aaikntscum])
		parseopts="$parseopts $i"; shift;;
	-v)	vertical=1; shift;;
	-I)	cppopts="$cppopts -I$2"; shift; shift;;
	-D)	cppopts="$cppopts -D$2"; shift; shift;;
	-U)	cppopts="$cppopts -U$2"; shift; shift;;
	-R)	cppopts="$cppopts -R"; shift;;
	--)	shift; break;;
	-*)	#echo "hier: illegal option $i (ignored)"; 
		shift;;
	esac
done

# -A is implicit if no languages are specified
if [ -z "$countlangs" ]
then	parseopts="$parseopts -A";
fi

if [ $badargs -eq 1 ]
then
cat <<'End of cat'

usage: hier [-Aacikmnstuv] [-L language] [-b boxname] [-o outputbase] [-w width] [-h height] [cpp options] file ...

-A = produce ascii output in addition to output(s) specified by -L
-a = differentiate node types
-c, -s, -u = show classes, structs, unions (defaults to -c)
-i = do not differentiate inheritance types
-k = draw inheritance edges from derived class to base class
-m = show file and line numbers where inheritance occurred
-n = display isolated nodes
-t = do not show information for included files
-v = orient graph vertically
language can be any of {ps, tex, dvi, pic, dag}
multiple -L options are allowed
any extension on outputbase is ignored
height and width should be dimensionless inches (eg, -h5.2)

End of cat
exit 2
fi
	
# Check to see whether we have the basic tools.

if [ ! -x $CC ]
then	if [ -z "`type CC`" ]
	then	echo "hier: Cannot find CC."
		exit 2
	fi
fi
if [ ! -x $HIER2 ]
then	echo "hier: Cannot find hier2 executable."
	exit 2
fi

# Check to see whether we have the tools necessary
# to produce output in the desired languages.
#

if [ ! -x $DAG ]
then	if [ $wantdvi -eq 1 -o $wanttex -eq 1 -o $wantps -eq 1 -o $wantpic -eq 1 ]
	then	echo "hier: Your system does not have dag."
		echo "hier: cannot process -Lps, -Lpic, -Ltex, and -Ldvi."
		exit 2  # prefer termination to previous ignoring & continuing
	fi
fi
if [ ! -x $TPIC ]
then	if [ $wantdvi -eq 1 -o $wanttex -eq 1 ]
	then	echo "hier: Your system does not have tpic."
		if [ $wantdvi -eq 1 -a $wanttex -eq 1 ]
		then	echo "hier: cannot process -Ltex and -Ldvi switches."
		elif [ $wantdvi -eq 1 ] 
		then	echo "hier: cannot process -Ldvi switch."
		else	echo "hier: cannot process -Ltex switch."
		fi
		exit 2
	fi
fi
if [ ! -x $TEX -a $wantdvi -eq 1 ]
then	echo "hier: Your system does not have TeX."
	echo "hier: cannot process -Ldvi switch."
	exit 2
fi

# keeps track of the files that should be removed before exiting.
#
deleteEm=$base.tmp
trap 'rm -f $deleteEm; exit' 1 2 3 15

							# create the dag source no matter what (everyone needs it).
if [ $wantdag -eq 0 ]
then	deleteEm="$deleteEm $base.dag"
fi
rm -f $base.dag
echo >$base.dag

# analyze all the input files.
#
if [ -z "$*" ]
then	# notice that it doesn't preprocess stdin.
	$HIER2 $parseopts -d $base.dag
else	for file in $*
	do	case $file in 
		#
		# $file should be the same file name as appears in the first #line
		# directive in the preprocessed file, but I don't trust CC to do
		# this correctly on every machine.  thus, i use $file for reporting
		# error messages, and the file name appearing in the first #line
		# directive for guiding the -t option.  
		# 
		*.[cCh]|*.cpp|*.CPP|*.cxx|*.CXX|*.cc|*.CC|*.c++|*.C++)	$CC -E $cppopts $file | $HIER2 $parseopts -f $file -d $base.dag;; 
										# C++ source gets expanded, then parsed.
		*.i)	$HIER2 $parseopts -d $base.dag $file;;			# Already expanded, just parse it.
		*.dag)	sed '/^\.G[SRE].*$/d' $file >>$base.dag;;		# Append it after stripping out . directives.
		*) echo "hier: file with unrecognized suffix: $file (ignored)";;
		esac
	done
fi

if [ $vertical -eq 1 ]
then	if [ -z "$width" ]
	then	echo ".GS" >$base.tmp
	else	echo ".GS $width $height" >$base.tmp
	fi
else	if [ -z "$width" ]
	then	echo ".GR" >$base.tmp
	else	echo ".GR $width $height" >$base.tmp
	fi
fi
sort $base.dag | uniq >>$base.tmp	# remove duplicate edges
mv $base.tmp $base.dag
echo ".GE" >>$base.dag			# this is the final version of the .dag output

deleteEm="$deleteEm $$.dag"
sed 's/#.*//' $base.dag >$$.dag					# create a dag-able dag source

if [ $wantps -eq 1 ]						# then create the postscript source
then	$DAG -Tps $$.dag >$base.ps
fi

if [ $wantpic -eq 1 -o $wanttex -eq 1 -o $wantdvi -eq 1 ]	# then create the pic source
then	if [ $wantpic -eq 0 ]
	then	deleteEm="$deleteEm $base.pic"
	fi
	$DAG $$.dag >$base.pic					
fi

# rm -f $$.dag

if [ $wanttex -eq 1 -o $wantdvi -eq 1 ]				# then create the tex source
then	if [ $wanttex -eq 0 ]
	then	deleteEm="$deleteEm $base.tex"
	fi
	sed -e '/^\.lf.*/d' -e '/^\.ps$/d' <$base.pic >$base.tmp	# pic suitable for tpic
	$TPIC $base.tmp	 						# tex but with free underscores in identifier names,
									# and box name = "graph"
	mv $base.tmp.tex $base.tmp
	sed -e "s/\\\csname graph/\\\csname $boxname/"		\
		-e "s/\\\insc@unt\\\graph/\\\insc@unt\\\\$boxname/" 	\
		-e "s/\\\setbox\\\graph/\\\setbox\\\\$boxname/" 	\
		-e 's/_/\\_/g' <$base.tmp >$base.tex			# tex
	rm -f $base.tmp
fi


if [ $wantdvi -eq 1 ]						# then create the dvi source
then	if [ $wantdvi -eq 0 ]
	then	deleteEm="$deleteEm $base.dvi $base.log"
	fi
	cp $base.tex $base.tmp
	echo "\centerline{\box\\$boxname}" >>$base.tex
	echo "\end" >>$base.tex
	$TEX $base
	mv $base.tmp $base.tex
	rm -f $base.log
fi

# Delete unwanted files.
#
# if [ ! -z "$deleteEm" ]
# then	rm -f $deleteEm
# fi
