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