xref: /titanic_51/usr/src/tools/scripts/xref.sh (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate#! /bin/ksh -p
2*7c478bd9Sstevel@tonic-gate#
3*7c478bd9Sstevel@tonic-gate# CDDL HEADER START
4*7c478bd9Sstevel@tonic-gate#
5*7c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*7c478bd9Sstevel@tonic-gate# Common Development and Distribution License, Version 1.0 only
7*7c478bd9Sstevel@tonic-gate# (the "License").  You may not use this file except in compliance
8*7c478bd9Sstevel@tonic-gate# with the License.
9*7c478bd9Sstevel@tonic-gate#
10*7c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*7c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
12*7c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
13*7c478bd9Sstevel@tonic-gate# and limitations under the License.
14*7c478bd9Sstevel@tonic-gate#
15*7c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
16*7c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*7c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
18*7c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
19*7c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
20*7c478bd9Sstevel@tonic-gate#
21*7c478bd9Sstevel@tonic-gate# CDDL HEADER END
22*7c478bd9Sstevel@tonic-gate#
23*7c478bd9Sstevel@tonic-gate#
24*7c478bd9Sstevel@tonic-gate# Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
25*7c478bd9Sstevel@tonic-gate# Use is subject to license terms.
26*7c478bd9Sstevel@tonic-gate#
27*7c478bd9Sstevel@tonic-gate# ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate#
29*7c478bd9Sstevel@tonic-gate# xref: build and maintain source cross-reference databases.
30*7c478bd9Sstevel@tonic-gate#
31*7c478bd9Sstevel@tonic-gate
32*7c478bd9Sstevel@tonic-gatePATH=/usr/bin:/usr/ccs/bin:${BUILD_TOOLS:-/opt}/teamware/bin export PATH
33*7c478bd9Sstevel@tonic-gatePROG=`basename $0`
34*7c478bd9Sstevel@tonic-gateXREFMK=`dirname $0`/xref.mk
35*7c478bd9Sstevel@tonic-gateXRMAKEFILE=Makefile export XRMAKEFILE
36*7c478bd9Sstevel@tonic-gate
37*7c478bd9Sstevel@tonic-gate#
38*7c478bd9Sstevel@tonic-gate# The CSCOPEOPTIONS variable can cause problems if it's set in the environment
39*7c478bd9Sstevel@tonic-gate# when using cscope; remove it.
40*7c478bd9Sstevel@tonic-gate#
41*7c478bd9Sstevel@tonic-gateunset CSCOPEOPTIONS
42*7c478bd9Sstevel@tonic-gate
43*7c478bd9Sstevel@tonic-gate#
44*7c478bd9Sstevel@tonic-gate# The CDPATH variable causes ksh's `cd' builtin to emit messages to stdout
45*7c478bd9Sstevel@tonic-gate# under certain circumstances, which can really screw things up; unset it.
46*7c478bd9Sstevel@tonic-gate#
47*7c478bd9Sstevel@tonic-gateunset CDPATH
48*7c478bd9Sstevel@tonic-gate
49*7c478bd9Sstevel@tonic-gate#
50*7c478bd9Sstevel@tonic-gate# Print the provided failure message and exit with an error.
51*7c478bd9Sstevel@tonic-gate#
52*7c478bd9Sstevel@tonic-gatefail()
53*7c478bd9Sstevel@tonic-gate{
54*7c478bd9Sstevel@tonic-gate        echo $PROG: $@ > /dev/stderr
55*7c478bd9Sstevel@tonic-gate        exit 1
56*7c478bd9Sstevel@tonic-gate}
57*7c478bd9Sstevel@tonic-gate
58*7c478bd9Sstevel@tonic-gate#
59*7c478bd9Sstevel@tonic-gate# Print the provided warning message.
60*7c478bd9Sstevel@tonic-gate#
61*7c478bd9Sstevel@tonic-gatewarn()
62*7c478bd9Sstevel@tonic-gate{
63*7c478bd9Sstevel@tonic-gate        echo $PROG: warning: $@ > /dev/stderr
64*7c478bd9Sstevel@tonic-gate}
65*7c478bd9Sstevel@tonic-gate
66*7c478bd9Sstevel@tonic-gate#
67*7c478bd9Sstevel@tonic-gate# Print the provided informational message.
68*7c478bd9Sstevel@tonic-gate#
69*7c478bd9Sstevel@tonic-gateinfo()
70*7c478bd9Sstevel@tonic-gate{
71*7c478bd9Sstevel@tonic-gate        echo $PROG: $@
72*7c478bd9Sstevel@tonic-gate}
73*7c478bd9Sstevel@tonic-gate
74*7c478bd9Sstevel@tonic-gate#
75*7c478bd9Sstevel@tonic-gate# Print the provided informational message, and the current value of $SECONDS
76*7c478bd9Sstevel@tonic-gate# in a user-friendly format.
77*7c478bd9Sstevel@tonic-gate#
78*7c478bd9Sstevel@tonic-gatetimeinfo()
79*7c478bd9Sstevel@tonic-gate{
80*7c478bd9Sstevel@tonic-gate	typeset -Z2 sec
81*7c478bd9Sstevel@tonic-gate	typeset min seconds
82*7c478bd9Sstevel@tonic-gate
83*7c478bd9Sstevel@tonic-gate	((seconds = SECONDS))
84*7c478bd9Sstevel@tonic-gate	((min = seconds / 60))
85*7c478bd9Sstevel@tonic-gate	((sec = seconds % 60))
86*7c478bd9Sstevel@tonic-gate
87*7c478bd9Sstevel@tonic-gate	info "$1 in ${min}m${sec}s"
88*7c478bd9Sstevel@tonic-gate}
89*7c478bd9Sstevel@tonic-gate
90*7c478bd9Sstevel@tonic-gate#
91*7c478bd9Sstevel@tonic-gate# If $CODEMGR_WS isn't set, then attempt to glean it from the workspace
92*7c478bd9Sstevel@tonic-gate# command before giving up.
93*7c478bd9Sstevel@tonic-gate#
94*7c478bd9Sstevel@tonic-gateif [ -z "$CODEMGR_WS" ]; then
95*7c478bd9Sstevel@tonic-gate	if whence workspace > /dev/null; then
96*7c478bd9Sstevel@tonic-gate		#
97*7c478bd9Sstevel@tonic-gate		# Since ws(1) hasn't been run, set up SRC and MACH too.
98*7c478bd9Sstevel@tonic-gate		# Note that other environment variables, such as
99*7c478bd9Sstevel@tonic-gate		# ENVCPPFLAGS*, can also affect the resulting
100*7c478bd9Sstevel@tonic-gate		# cross-reference, but we assume that if the developer
101*7c478bd9Sstevel@tonic-gate		# really cared, he would've ws'd first.
102*7c478bd9Sstevel@tonic-gate		#
103*7c478bd9Sstevel@tonic-gate		CODEMGR_WS=`workspace name` export CODEMGR_WS
104*7c478bd9Sstevel@tonic-gate		SRC=$CODEMGR_WS/usr/src export SRC
105*7c478bd9Sstevel@tonic-gate		MACH=`uname -p` export MACH
106*7c478bd9Sstevel@tonic-gate	else
107*7c478bd9Sstevel@tonic-gate		fail "No active workspace; run \"ws <workspace_name>\""
108*7c478bd9Sstevel@tonic-gate	fi
109*7c478bd9Sstevel@tonic-gatefi
110*7c478bd9Sstevel@tonic-gate
111*7c478bd9Sstevel@tonic-gate[ -d "$CODEMGR_WS" ] || fail "\$CODEMGR_WS ($CODEMGR_WS) is not a directory"
112*7c478bd9Sstevel@tonic-gate[ -f $XREFMK ] || fail "cannot locate xref.mk"
113*7c478bd9Sstevel@tonic-gate
114*7c478bd9Sstevel@tonic-gateclobber=
115*7c478bd9Sstevel@tonic-gatenoflg=
116*7c478bd9Sstevel@tonic-gatexrefs=
117*7c478bd9Sstevel@tonic-gate
118*7c478bd9Sstevel@tonic-gatewhile getopts cfm:px: flag; do
119*7c478bd9Sstevel@tonic-gate	case $flag in
120*7c478bd9Sstevel@tonic-gate	c)
121*7c478bd9Sstevel@tonic-gate		clobber=y
122*7c478bd9Sstevel@tonic-gate		;;
123*7c478bd9Sstevel@tonic-gate	f)
124*7c478bd9Sstevel@tonic-gate		noflg=y
125*7c478bd9Sstevel@tonic-gate		;;
126*7c478bd9Sstevel@tonic-gate	m)
127*7c478bd9Sstevel@tonic-gate		XRMAKEFILE=$OPTARG
128*7c478bd9Sstevel@tonic-gate		;;
129*7c478bd9Sstevel@tonic-gate	p)
130*7c478bd9Sstevel@tonic-gate		#
131*7c478bd9Sstevel@tonic-gate		# The ENVCPPFLAGS* environment variables contain the include
132*7c478bd9Sstevel@tonic-gate		# paths to our proto areas; clear 'em so that they don't end
133*7c478bd9Sstevel@tonic-gate		# up in CPPFLAGS, and thus don't end up in XRINCS in xref.mk.
134*7c478bd9Sstevel@tonic-gate		#
135*7c478bd9Sstevel@tonic-gate		ENVCPPFLAGS1=
136*7c478bd9Sstevel@tonic-gate		ENVCPPFLAGS2=
137*7c478bd9Sstevel@tonic-gate		ENVCPPFLAGS3=
138*7c478bd9Sstevel@tonic-gate		ENVCPPFLAGS4=
139*7c478bd9Sstevel@tonic-gate		;;
140*7c478bd9Sstevel@tonic-gate 	x)
141*7c478bd9Sstevel@tonic-gate		xrefs=$OPTARG
142*7c478bd9Sstevel@tonic-gate		;;
143*7c478bd9Sstevel@tonic-gate	\?)
144*7c478bd9Sstevel@tonic-gate		echo "usage: $PROG [-cfp] [-m <makefile>]"\
145*7c478bd9Sstevel@tonic-gate		     "[-x cscope|ctags|etags[,...]] [<subtree> ...]"\
146*7c478bd9Sstevel@tonic-gate		      > /dev/stderr
147*7c478bd9Sstevel@tonic-gate		exit 1
148*7c478bd9Sstevel@tonic-gate		;;
149*7c478bd9Sstevel@tonic-gate	esac
150*7c478bd9Sstevel@tonic-gatedone
151*7c478bd9Sstevel@tonic-gate
152*7c478bd9Sstevel@tonic-gateshift $((OPTIND - 1))
153*7c478bd9Sstevel@tonic-gate
154*7c478bd9Sstevel@tonic-gate#
155*7c478bd9Sstevel@tonic-gate# Get the list of directories before we reset $@.
156*7c478bd9Sstevel@tonic-gate#
157*7c478bd9Sstevel@tonic-gatedirs=$@
158*7c478bd9Sstevel@tonic-gate[ -z "$dirs" ] && dirs=.
159*7c478bd9Sstevel@tonic-gate
160*7c478bd9Sstevel@tonic-gate#
161*7c478bd9Sstevel@tonic-gate# Get the canonical path to the workspace.  This allows xref to work
162*7c478bd9Sstevel@tonic-gate# even in the presence of lofs(7FS).
163*7c478bd9Sstevel@tonic-gate#
164*7c478bd9Sstevel@tonic-gatecd $CODEMGR_WS
165*7c478bd9Sstevel@tonic-gateCODEMGR_WS=`/bin/pwd`
166*7c478bd9Sstevel@tonic-gatecd - > /dev/null
167*7c478bd9Sstevel@tonic-gate
168*7c478bd9Sstevel@tonic-gate#
169*7c478bd9Sstevel@tonic-gate# Process the xref format list.  For convenience, support common synonyms
170*7c478bd9Sstevel@tonic-gate# for the xref formats.
171*7c478bd9Sstevel@tonic-gate#
172*7c478bd9Sstevel@tonic-gateif [ -z "$xrefs" ]; then
173*7c478bd9Sstevel@tonic-gate	#
174*7c478bd9Sstevel@tonic-gate	# Disable etags if we can't find it.
175*7c478bd9Sstevel@tonic-gate	#
176*7c478bd9Sstevel@tonic-gate	xrefs="cscope ctags"
177*7c478bd9Sstevel@tonic-gate	make -e -f $XREFMK xref.etags.check 2>/dev/null 1>&2 && \
178*7c478bd9Sstevel@tonic-gate	    xrefs="$xrefs etags"
179*7c478bd9Sstevel@tonic-gateelse
180*7c478bd9Sstevel@tonic-gate	oldifs=$IFS
181*7c478bd9Sstevel@tonic-gate	IFS=,
182*7c478bd9Sstevel@tonic-gate	set -- $xrefs
183*7c478bd9Sstevel@tonic-gate	IFS=$oldifs
184*7c478bd9Sstevel@tonic-gate
185*7c478bd9Sstevel@tonic-gate	xrefs=
186*7c478bd9Sstevel@tonic-gate	for xref; do
187*7c478bd9Sstevel@tonic-gate		case $xref in
188*7c478bd9Sstevel@tonic-gate		cscope|cscope.out)
189*7c478bd9Sstevel@tonic-gate			xrefs="$xrefs cscope"
190*7c478bd9Sstevel@tonic-gate			;;
191*7c478bd9Sstevel@tonic-gate		ctags|tags)
192*7c478bd9Sstevel@tonic-gate			xrefs="$xrefs ctags"
193*7c478bd9Sstevel@tonic-gate			;;
194*7c478bd9Sstevel@tonic-gate		etags|TAGS)
195*7c478bd9Sstevel@tonic-gate			xrefs="$xrefs etags"
196*7c478bd9Sstevel@tonic-gate			;;
197*7c478bd9Sstevel@tonic-gate		*)
198*7c478bd9Sstevel@tonic-gate			warn "ignoring unknown cross-reference \"$xref\""
199*7c478bd9Sstevel@tonic-gate			;;
200*7c478bd9Sstevel@tonic-gate 		esac
201*7c478bd9Sstevel@tonic-gate 	done
202*7c478bd9Sstevel@tonic-gate
203*7c478bd9Sstevel@tonic-gate	[ -z "$xrefs" ] && fail "no known cross-reference formats specified"
204*7c478bd9Sstevel@tonic-gatefi
205*7c478bd9Sstevel@tonic-gate
206*7c478bd9Sstevel@tonic-gate#
207*7c478bd9Sstevel@tonic-gate# Process the requested list of directories.
208*7c478bd9Sstevel@tonic-gate#
209*7c478bd9Sstevel@tonic-gatefor dir in $dirs; do
210*7c478bd9Sstevel@tonic-gate	if [ ! -d $dir ]; then
211*7c478bd9Sstevel@tonic-gate		warn "directory \"$dir\" does not exist; skipping"
212*7c478bd9Sstevel@tonic-gate		continue
213*7c478bd9Sstevel@tonic-gate	fi
214*7c478bd9Sstevel@tonic-gate
215*7c478bd9Sstevel@tonic-gate	#
216*7c478bd9Sstevel@tonic-gate	# NOTE: we cannot use $PWD because it will mislead in the presence
217*7c478bd9Sstevel@tonic-gate	# of lofs(7FS).
218*7c478bd9Sstevel@tonic-gate	#
219*7c478bd9Sstevel@tonic-gate	cd $dir || fail "cannot change to directory $dir"
220*7c478bd9Sstevel@tonic-gate	pwd=`/bin/pwd`
221*7c478bd9Sstevel@tonic-gate	reldir=${pwd##${CODEMGR_WS}/}
222*7c478bd9Sstevel@tonic-gate	if [ "$reldir" = "$pwd" ]; then
223*7c478bd9Sstevel@tonic-gate		warn "directory \"$pwd\" is not beneath \$CODEMGR_WS; skipping"
224*7c478bd9Sstevel@tonic-gate		cd - > /dev/null
225*7c478bd9Sstevel@tonic-gate		continue
226*7c478bd9Sstevel@tonic-gate	fi
227*7c478bd9Sstevel@tonic-gate
228*7c478bd9Sstevel@tonic-gate	#
229*7c478bd9Sstevel@tonic-gate	# If we're building cross-references, then run `xref.clean' first
230*7c478bd9Sstevel@tonic-gate	# to purge any crud that may be lying around from previous aborted runs.
231*7c478bd9Sstevel@tonic-gate	#
232*7c478bd9Sstevel@tonic-gate	if [ -z "$clobber" ]; then
233*7c478bd9Sstevel@tonic-gate		make -e -f $XREFMK xref.clean > /dev/null
234*7c478bd9Sstevel@tonic-gate	fi
235*7c478bd9Sstevel@tonic-gate
236*7c478bd9Sstevel@tonic-gate	#
237*7c478bd9Sstevel@tonic-gate	# Find flg-related source files, if requested.
238*7c478bd9Sstevel@tonic-gate	#
239*7c478bd9Sstevel@tonic-gate	if [ -z "$noflg" -a -z "$clobber" ]; then
240*7c478bd9Sstevel@tonic-gate		SECONDS=0
241*7c478bd9Sstevel@tonic-gate    		info "$reldir: finding flg-related source files"
242*7c478bd9Sstevel@tonic-gate		make -e -f $XREFMK xref.flg > /dev/null
243*7c478bd9Sstevel@tonic-gate		if [ $? -ne 0 ]; then
244*7c478bd9Sstevel@tonic-gate			warn "$reldir: unable to find flg-related source files"
245*7c478bd9Sstevel@tonic-gate		else
246*7c478bd9Sstevel@tonic-gate			nfiles=`wc -l < xref.flg`
247*7c478bd9Sstevel@tonic-gate			if [ "$nfiles" -eq 1 ]; then
248*7c478bd9Sstevel@tonic-gate				msg="found 1 flg-related source file"
249*7c478bd9Sstevel@tonic-gate			else
250*7c478bd9Sstevel@tonic-gate				msg="found $nfiles flg-related source files"
251*7c478bd9Sstevel@tonic-gate			fi
252*7c478bd9Sstevel@tonic-gate			timeinfo "$reldir: $msg"
253*7c478bd9Sstevel@tonic-gate		fi
254*7c478bd9Sstevel@tonic-gate	fi
255*7c478bd9Sstevel@tonic-gate
256*7c478bd9Sstevel@tonic-gate	#
257*7c478bd9Sstevel@tonic-gate	# Build or clobber all of the requested cross-references.
258*7c478bd9Sstevel@tonic-gate	#
259*7c478bd9Sstevel@tonic-gate	for xref in $xrefs; do
260*7c478bd9Sstevel@tonic-gate		if [ -n "$clobber" ]; then
261*7c478bd9Sstevel@tonic-gate			info "$reldir: clobbering $xref cross-reference"
262*7c478bd9Sstevel@tonic-gate			make -e -f $XREFMK xref.${xref}.clobber > /dev/null ||
263*7c478bd9Sstevel@tonic-gate 			    warn "$reldir: cannot clobber $xref cross-reference"
264*7c478bd9Sstevel@tonic-gate			continue
265*7c478bd9Sstevel@tonic-gate		fi
266*7c478bd9Sstevel@tonic-gate
267*7c478bd9Sstevel@tonic-gate		SECONDS=0
268*7c478bd9Sstevel@tonic-gate		info "$reldir: building $xref cross-reference"
269*7c478bd9Sstevel@tonic-gate		make -e -f $XREFMK xref.${xref} > /dev/null ||
270*7c478bd9Sstevel@tonic-gate		    fail "$reldir: cannot build $xref cross-reference"
271*7c478bd9Sstevel@tonic-gate		timeinfo "$reldir: built $xref cross-reference"
272*7c478bd9Sstevel@tonic-gate 	done
273*7c478bd9Sstevel@tonic-gate
274*7c478bd9Sstevel@tonic-gate	make -e -f $XREFMK xref.clean > /dev/null ||
275*7c478bd9Sstevel@tonic-gate	    warn "$reldir: cannot clean up temporary files"
276*7c478bd9Sstevel@tonic-gate	cd - > /dev/null
277*7c478bd9Sstevel@tonic-gatedone
278*7c478bd9Sstevel@tonic-gateexit 0
279