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