Home | History | Annotate | Download | only in scripts
      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 
     31 ONBLDDIR=$(dirname $(whence $0))
     32 
     33 PATH=/usr/bin:/usr/ccs/bin:${BUILD_TOOLS:-/opt}/teamware/bin:$ONBLDDIR
     34 export PATH
     35 PROG=`basename $0`
     36 XREFMK=`dirname $0`/xref.mk
     37 XRMAKEFILE=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 #
     43 unset 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 #
     49 unset CDPATH
     50 
     51 #
     52 # Print the provided failure message and exit with an error.
     53 #
     54 fail()
     55 {
     56         echo $PROG: $@ > /dev/stderr
     57         exit 1
     58 }
     59 
     60 #
     61 # Print the provided warning message.
     62 #
     63 warn()
     64 {
     65         echo $PROG: warning: $@ > /dev/stderr
     66 }
     67 
     68 #
     69 # Print the provided informational message.
     70 #
     71 info()
     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 #
     80 timeinfo()
     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 
     92 which_scm | read SCM_MODE CODEMGR_WS || exit 1
     93 
     94 if [[ $SCM_MODE == "unknown" ]];then
     95 	print -u2 "Unable to determine SCM type currently in use."
     96 	exit 1
     97 fi
     98 
     99 export CODEMGR_WS
    100 SRC=$CODEMGR_WS/usr/src export SRC
    101 MACH=`uname -p` export MACH
    102 
    103 [ -f $XREFMK ] || fail "cannot locate xref.mk"
    104 
    105 clobber=
    106 noflg=
    107 xrefs=
    108 
    109 while 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
    141 done
    142 
    143 shift $((OPTIND - 1))
    144 
    145 #
    146 # Get the list of directories before we reset $@.
    147 #
    148 dirs=$@
    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 #
    155 cd $CODEMGR_WS
    156 CODEMGR_WS=`/bin/pwd`
    157 cd - > /dev/null
    158 
    159 #
    160 # Process the xref format list.  For convenience, support common synonyms
    161 # for the xref formats.
    162 #
    163 if [ -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"
    170 else
    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"
    195 fi
    196 
    197 #
    198 # Process the requested list of directories.
    199 #
    200 for 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
    268 done
    269 exit 0
    270