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