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