diff options
author | meem <Peter.Memishian@Sun.COM> | 2009-08-14 17:11:26 -0400 |
---|---|---|
committer | meem <Peter.Memishian@Sun.COM> | 2009-08-14 17:11:26 -0400 |
commit | 9730304d175c7545fecc3f6fc8731d57d3875f47 (patch) | |
tree | 47fe0dae32abea9ae49ebe9746be71fc8704b08b /usr/src/tools/findunref | |
parent | 79c0745d20b12387e468deefd44f647aa2451fa8 (diff) | |
download | illumos-gate-9730304d175c7545fecc3f6fc8731d57d3875f47.tar.gz |
6869889 findunref needs to grok mercurial
6870670 findunref should have a manpage
6870810 xref manpage is stale
Diffstat (limited to 'usr/src/tools/findunref')
-rw-r--r-- | usr/src/tools/findunref/Makefile | 11 | ||||
-rw-r--r-- | usr/src/tools/findunref/exception_list.closed | 16 | ||||
-rw-r--r-- | usr/src/tools/findunref/exception_list.open | 240 | ||||
-rw-r--r-- | usr/src/tools/findunref/findunref.1 | 94 | ||||
-rw-r--r-- | usr/src/tools/findunref/findunref.c | 254 |
5 files changed, 451 insertions, 164 deletions
diff --git a/usr/src/tools/findunref/Makefile b/usr/src/tools/findunref/Makefile index f1b0f07768..ab76673378 100644 --- a/usr/src/tools/findunref/Makefile +++ b/usr/src/tools/findunref/Makefile @@ -20,18 +20,19 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# -PROG = findunref +PROG = findunref +MAN1FILES = findunref.1 CFLAGS += $(CCVERBOSE) LINTFLAGS += -ux include ../Makefile.tools +$(ROOTONBLDMAN1FILES) := FILEMODE= 644 + EXCEPTION_SRC= $(SCM_TYPE:none=) common open $(CLOSED_BUILD)EXCEPTION_SRC += closed EXCEPTION_LISTS= $(EXCEPTION_SRC:%=exception_list.%) @@ -42,7 +43,7 @@ CLOBBERFILES += exception_list all: $(PROG) exception_list -install: all .WAIT $(ROOTONBLDMACHPROG) +install: all .WAIT $(ROOTONBLDMACHPROG) $(ROOTONBLDMAN1FILES) lint: lint_PROG diff --git a/usr/src/tools/findunref/exception_list.closed b/usr/src/tools/findunref/exception_list.closed index df70b10427..c2cc06a1c5 100644 --- a/usr/src/tools/findunref/exception_list.closed +++ b/usr/src/tools/findunref/exception_list.closed @@ -20,11 +20,9 @@ # # -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # # closed-tree exception list @@ -36,19 +34,19 @@ # Ignore internal packages, scripts, and tools that are intentionally not # built or used during a nightly. # -./closed/cmd/zic/makefile.tzpkg -./closed/cmd/zic/tzpkg.awk +./usr/closed/cmd/zic/makefile.tzpkg +./usr/closed/cmd/zic/tzpkg.awk # # Ignore files that get used during a EXPORT_SRC or CRYPT_SRC build only. # -./closed/uts/sun4v/io/n2cp/Makefile -./closed/uts/sun4v/io/ncp/Makefile +./usr/closed/uts/sun4v/io/n2cp/Makefile +./usr/closed/uts/sun4v/io/ncp/Makefile # # Ignore files that are only used for warlock # -./closed/uts/sparc/marvell88sx/Makefile +./usr/closed/uts/sparc/marvell88sx/Makefile # # An unfortunate artifact of the bridged, split gate is that closed-source @@ -59,4 +57,4 @@ # won't exist, so we need the ISUSED directive here. # # ISUSED - let checkpaths know that the next entry is good. -./closed/deleted_files +./usr/closed/deleted_files diff --git a/usr/src/tools/findunref/exception_list.open b/usr/src/tools/findunref/exception_list.open index 1d0c7a43b5..8be6623efe 100644 --- a/usr/src/tools/findunref/exception_list.open +++ b/usr/src/tools/findunref/exception_list.open @@ -34,87 +34,87 @@ # Ignore oddly-named text files scattered about -- someday these should be # suffixed with .txt so we don't have to list them. # -./src/cmd/oawk/EXPLAIN -./src/cmd/rpcsvc/nis/rpc.nisd/resolv_server/DNS_FWD -./src/cmd/vi/port/ex.news -./src/cmd/ssh/doc +./usr/src/cmd/oawk/EXPLAIN +./usr/src/cmd/rpcsvc/nis/rpc.nisd/resolv_server/DNS_FWD +./usr/src/cmd/vi/port/ex.news +./usr/src/cmd/ssh/doc # # Ignore everything under trees that may be resynched from outside ON. # -./src/cmd/perl -./src/cmd/sqlite -./src/lib/libsqlite -./src/cmd/tcpd -./src/common/openssl -./src/grub -./src/uts/intel/sys/acpi +./usr/src/cmd/perl +./usr/src/cmd/sqlite +./usr/src/lib/libsqlite +./usr/src/cmd/tcpd +./usr/src/common/openssl +./usr/src/grub +./usr/src/uts/intel/sys/acpi # # Ignore ksh93/ast-related files that are only used to resync our build # configuration with upstream. # -./src/lib/libast/*/src/lib/libast/FEATURE -./src/lib/libast/common/comp/conf.* -./src/lib/libast/common/features -./src/lib/libast/common/include/ast_windows.h -./src/lib/libast/common/port/lc.tab -./src/lib/libast/common/port/lcgen.c -./src/lib/libcmd/*/src/lib/libcmd/FEATURE -./src/lib/libcmd/common/features -./src/lib/libdll/*/src/lib/libdll/FEATURE -./src/lib/libdll/common/features -./src/lib/libpp/*/pp.* -./src/lib/libpp/common/gentab.sh -./src/lib/libpp/common/ppsym.c -./src/lib/libpp/i386/ppdebug.h -./src/lib/libpp/sparc/ppdebug.h -./src/lib/libshell/*/src/cmd/ksh93/FEATURE -./src/lib/libshell/common/data/math.tab -./src/lib/libshell/common/features -./src/lib/libshell/misc/buildksh93.sh -./src/lib/libshell/misc/buildksh93.readme +./usr/src/lib/libast/*/src/lib/libast/FEATURE +./usr/src/lib/libast/common/comp/conf.* +./usr/src/lib/libast/common/features +./usr/src/lib/libast/common/include/ast_windows.h +./usr/src/lib/libast/common/port/lc.tab +./usr/src/lib/libast/common/port/lcgen.c +./usr/src/lib/libcmd/*/src/lib/libcmd/FEATURE +./usr/src/lib/libcmd/common/features +./usr/src/lib/libdll/*/src/lib/libdll/FEATURE +./usr/src/lib/libdll/common/features +./usr/src/lib/libpp/*/pp.* +./usr/src/lib/libpp/common/gentab.sh +./usr/src/lib/libpp/common/ppsym.c +./usr/src/lib/libpp/i386/ppdebug.h +./usr/src/lib/libpp/sparc/ppdebug.h +./usr/src/lib/libshell/*/src/cmd/ksh93/FEATURE +./usr/src/lib/libshell/common/data/math.tab +./usr/src/lib/libshell/common/features +./usr/src/lib/libshell/misc/buildksh93.sh +./usr/src/lib/libshell/misc/buildksh93.readme # # Ignore ksh93/ast-related "iffe" (if feature enabled) probe # -./src/lib/libsum/common/features/sum +./usr/src/lib/libsum/common/features/sum # # Ignore ksh93/ast-related upstream source, currently superseded by # a per-platform version of sum.h, since we use libmd.so.1 for some # ciphers. # -./src/lib/libsum/common/sum.h +./usr/src/lib/libsum/common/sum.h # # Ignore ksh93/ast-related test programs. # -./src/cmd/ast/msgcc/msgcc.tst -./src/lib/libast/common/port/astmath.c +./usr/src/cmd/ast/msgcc/msgcc.tst +./usr/src/lib/libast/common/port/astmath.c # # Ignore ksh93/ast-related source components that are not currently # used but may be useful later. # -./src/lib/libcmd/common/cksum.c -./src/lib/libcmd/common/md5sum.c -./src/lib/libcmd/common/sum.c -./src/lib/libshell/common/bltins/mkservice.c -./src/lib/libshell/common/data/bash_pre_rc.sh -./src/lib/libshell/common/include/env.h -./src/lib/libshell/common/sh/bash.c -./src/lib/libshell/common/sh/env.c -./src/lib/libshell/common/sh/shcomp.c -./src/lib/libshell/common/sh/suid_exec.c +./usr/src/lib/libcmd/common/cksum.c +./usr/src/lib/libcmd/common/md5sum.c +./usr/src/lib/libcmd/common/sum.c +./usr/src/lib/libshell/common/bltins/mkservice.c +./usr/src/lib/libshell/common/data/bash_pre_rc.sh +./usr/src/lib/libshell/common/include/env.h +./usr/src/lib/libshell/common/sh/bash.c +./usr/src/lib/libshell/common/sh/env.c +./usr/src/lib/libshell/common/sh/shcomp.c +./usr/src/lib/libshell/common/sh/suid_exec.c # # Ignore any files built as part of the nightly program itself. # # ISUSED - let checkpaths know that the next entry is good. -./src/*.out +./usr/src/*.out # ISUSED - let checkpaths know that the next entry is good. -./src/*.ref +./usr/src/*.ref # # Ignore internal test directories and test programs. @@ -123,145 +123,145 @@ */test *Test.java *_test.[ch] -./src/cmd/ldap/common/*test.c -./src/cmd/logadm/tester -./src/cmd/print/printmgr/com/sun/admin/pm/client/helptools/extract -./src/cmd/print/printmgr/com/sun/admin/pm/server/pmtest -./src/cmd/sendmail/libsm/t-*.c -./src/cmd/sort/common/convert.c -./src/cmd/sort/common/invoke.c -./src/lib/crypt_modules/sha256/test.c -./src/lib/efcode/fcode_test -./src/lib/libkvm/common/test.c +./usr/src/cmd/ldap/common/*test.c +./usr/src/cmd/logadm/tester +./usr/src/cmd/print/printmgr/com/sun/admin/pm/client/helptools/extract +./usr/src/cmd/print/printmgr/com/sun/admin/pm/server/pmtest +./usr/src/cmd/sendmail/libsm/t-*.c +./usr/src/cmd/sort/common/convert.c +./usr/src/cmd/sort/common/invoke.c +./usr/src/lib/crypt_modules/sha256/test.c +./usr/src/lib/efcode/fcode_test +./usr/src/lib/libkvm/common/test.c # # Ignore debugging code. # -./src/cmd/fs.d/pcfs/fsck/inject.c -./src/cmd/sort/common/statistics.c +./usr/src/cmd/fs.d/pcfs/fsck/inject.c +./usr/src/cmd/sort/common/statistics.c # # Ignore internal packages, scripts, and tools that are intentionally not # built or used during a nightly. # -./src/cmd/mdb/packages -./src/cmd/sgs/packages -./src/cmd/sgs/rtld.4.x -./src/prototypes -./src/cmd/pools/poold/com/sun/solaris/*/*/package.html -./src/uts/intel/io/acpica/cmp_ca.sh +./usr/src/cmd/mdb/packages +./usr/src/cmd/sgs/packages +./usr/src/cmd/sgs/rtld.4.x +./usr/src/prototypes +./usr/src/cmd/pools/poold/com/sun/solaris/*/*/package.html +./usr/src/uts/intel/io/acpica/cmp_ca.sh # # Ignore files that are only used by internal packages. # -./src/cmd/sgs/*/*/*chk.msg +./usr/src/cmd/sgs/*/*/*chk.msg # # Ignore files that get used during a EXPORT_SRC or CRYPT_SRC build only. # -./src/common/crypto/aes/Makefile -./src/common/crypto/arcfour/Makefile -./src/common/crypto/blowfish/Makefile -./src/common/crypto/des/Makefile -./src/common/crypto/rsa/Makefile -./src/lib/gss_mechs/mech_dh/backend/mapfile-vers -./src/lib/gss_mechs/mech_dh/dh1024/mapfile-vers -./src/lib/gss_mechs/mech_dh/dh192/mapfile-vers -./src/lib/gss_mechs/mech_dh/dh640/mapfile-vers -./src/lib/gss_mechs/mech_krb5/mapfile-vers-clean -./src/lib/gss_mechs/mech_spnego/mapfile-vers-clean -./src/lib/pkcs11/pkcs11_softtoken/common/Makefile -./src/uts/common/Makefile -./src/uts/common/crypto/io/Makefile -./src/uts/common/gssapi/include/Makefile -./src/uts/common/gssapi/mechs/dummy/Makefile -./src/uts/common/gssapi/mechs/krb5/Makefile -./src/xmod +./usr/src/common/crypto/aes/Makefile +./usr/src/common/crypto/arcfour/Makefile +./usr/src/common/crypto/blowfish/Makefile +./usr/src/common/crypto/des/Makefile +./usr/src/common/crypto/rsa/Makefile +./usr/src/lib/gss_mechs/mech_dh/backend/mapfile-vers +./usr/src/lib/gss_mechs/mech_dh/dh1024/mapfile-vers +./usr/src/lib/gss_mechs/mech_dh/dh192/mapfile-vers +./usr/src/lib/gss_mechs/mech_dh/dh640/mapfile-vers +./usr/src/lib/gss_mechs/mech_krb5/mapfile-vers-clean +./usr/src/lib/gss_mechs/mech_spnego/mapfile-vers-clean +./usr/src/lib/pkcs11/pkcs11_softtoken/common/Makefile +./usr/src/uts/common/Makefile +./usr/src/uts/common/crypto/io/Makefile +./usr/src/uts/common/gssapi/include/Makefile +./usr/src/uts/common/gssapi/mechs/dummy/Makefile +./usr/src/uts/common/gssapi/mechs/krb5/Makefile +./usr/src/xmod # # Ignore Makefiles which are used by developers but not used by nightly # itself. This is a questionable practice, since they tend to rot. # -./src/cmd/syslogd/sparcv9/Makefile -./src/uts/sparc/uhci/Makefile -./src/lib/pam_modules/smb/amd64/Makefile -./src/lib/pam_modules/smb/sparcv9/Makefile -./src/cmd/isns/isnsd/xml_def/isnsmgmtSchema.xsd +./usr/src/cmd/syslogd/sparcv9/Makefile +./usr/src/uts/sparc/uhci/Makefile +./usr/src/lib/pam_modules/smb/amd64/Makefile +./usr/src/lib/pam_modules/smb/sparcv9/Makefile +./usr/src/cmd/isns/isnsd/xml_def/isnsmgmtSchema.xsd # # Ignore dtrace scripts only used by developers # -./src/cmd/vscan/vscand/vscan.d +./usr/src/cmd/vscan/vscand/vscan.d # # Ignore sample source code. # -./src/cmd/sendmail/libmilter/example.c -./src/lib/libdhcpsvc/modules/templates +./usr/src/cmd/sendmail/libmilter/example.c +./usr/src/lib/libdhcpsvc/modules/templates # # Ignore .xcl files that aren't used because the program is statically linked. # -./src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.xcl +./usr/src/cmd/cmd-inet/sbin/dhcpagent/dhcpagent.xcl # # Ignore sendmail files included for completeness' sake, but which won't # be used until certain _FFR (for future release) #define's go live. # -./src/cmd/sendmail/src/statusd_shm.h +./usr/src/cmd/sendmail/src/statusd_shm.h # # Ignore files originally supplied by ISC (Internet Software Consortium) # as part of a BIND release. # -./src/lib/libresolv2/common/cylink/bn68000.c -./src/lib/libresolv2/common/cylink/bn8086.c -./src/lib/libresolv2/common/cylink/lbn68000.c -./src/lib/libresolv2/common/cylink/lbn68000.h -./src/lib/libresolv2/common/cylink/lbn68020.c -./src/lib/libresolv2/common/cylink/lbn68020.h -./src/lib/libresolv2/common/cylink/lbn80386.h -./src/lib/libresolv2/common/cylink/lbn8086.h -./src/lib/libresolv2/common/cylink/lbnppc.c -./src/lib/libresolv2/common/cylink/lbnppc.h -./src/lib/libresolv2/common/cylink/ppcasm.h -./src/lib/libresolv2/common/cylink/sizetest.c -./src/lib/libresolv2/common/irs/getaddrinfo.c -./src/lib/libresolv2/common/irs/nis_p.h -./src/lib/libresolv2/common/resolv/res_mkupdate.h -./src/lib/libresolv2/include/err.h +./usr/src/lib/libresolv2/common/cylink/bn68000.c +./usr/src/lib/libresolv2/common/cylink/bn8086.c +./usr/src/lib/libresolv2/common/cylink/lbn68000.c +./usr/src/lib/libresolv2/common/cylink/lbn68000.h +./usr/src/lib/libresolv2/common/cylink/lbn68020.c +./usr/src/lib/libresolv2/common/cylink/lbn68020.h +./usr/src/lib/libresolv2/common/cylink/lbn80386.h +./usr/src/lib/libresolv2/common/cylink/lbn8086.h +./usr/src/lib/libresolv2/common/cylink/lbnppc.c +./usr/src/lib/libresolv2/common/cylink/lbnppc.h +./usr/src/lib/libresolv2/common/cylink/ppcasm.h +./usr/src/lib/libresolv2/common/cylink/sizetest.c +./usr/src/lib/libresolv2/common/irs/getaddrinfo.c +./usr/src/lib/libresolv2/common/irs/nis_p.h +./usr/src/lib/libresolv2/common/resolv/res_mkupdate.h +./usr/src/lib/libresolv2/include/err.h # # Ignore mont_mulf.c. It is used as a starting point for some hand optimized # assembly files. We keep it around for future reference. # -./src/common/bignum/mont_mulf.c +./usr/src/common/bignum/mont_mulf.c # # Ignore the sparc Makefiles for x86-only drivers; # they're used to build warlock only. # -./src/uts/sparc/sata/Makefile -./src/uts/sparc/si3124/Makefile -./src/uts/sparc/nv_sata/Makefile -./src/uts/sparc/ahci/Makefile +./usr/src/uts/sparc/sata/Makefile +./usr/src/uts/sparc/si3124/Makefile +./usr/src/uts/sparc/nv_sata/Makefile +./usr/src/uts/sparc/ahci/Makefile # # Ignore uttrack.c. It is provided as part of the standard # ACPI CA source code but provides optional resource tracking # functionality which is not used. # -./src/uts/intel/io/acpica/utilities/uttrack.c +./usr/src/uts/intel/io/acpica/utilities/uttrack.c # # Ignore any files that get used during a gcc build only. # -./src/cmd/sgs/rtld/common/mapfile-order-gcc +./usr/src/cmd/sgs/rtld/common/mapfile-order-gcc # # Ignore compiler dependent header files for fpscrubber # and sparc prototype files # -./src/cmd/fps/fptest/singdoub* -./src/pkgdefs/SUNWfsu/prototype_gcc_sparc -./src/pkgdefs/SUNWfsu/prototype_cc_sparc +./usr/src/cmd/fps/fptest/singdoub* +./usr/src/pkgdefs/SUNWfsu/prototype_gcc_sparc +./usr/src/pkgdefs/SUNWfsu/prototype_cc_sparc diff --git a/usr/src/tools/findunref/findunref.1 b/usr/src/tools/findunref/findunref.1 new file mode 100644 index 0000000000..00e19c5712 --- /dev/null +++ b/usr/src/tools/findunref/findunref.1 @@ -0,0 +1,94 @@ +.\" " CDDL HEADER START +.\" " +.\" " The contents of this file are subject to the terms of the +.\" " Common Development and Distribution License (the "License"). +.\" " You may not use this file except in compliance with the License. +.\" " +.\" " You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +.\" " or http://www.opensolaris.org/os/licensing. +.\" " See the License for the specific language governing permissions +.\" " and limitations under the License. +.\" " +.\" " When distributing Covered Code, include this CDDL HEADER in each +.\" " file and include the License file at usr/src/OPENSOLARIS.LICENSE. +.\" " If applicable, add the following below this CDDL HEADER, with the +.\" " fields enclosed by brackets "[]" replaced with your own identifying +.\" " information: Portions Copyright [yyyy] [name of copyright owner] +.\" " +.\" " CDDL HEADER END +.\" " +.\" "Copyright 2009 Sun Microsystems, Inc. All rights reserved. +.\" "Use is subject to license terms. +.TH findunref 1 "11 Aug 2009" +.I findunref +\- find unused files in a source tree +.SH SYNOPSIS +findunref [\fB-s\fP \fIsubtree\fP] [\fB-t\fP \fItstampfile\fP] +[\fB-S\fP \fBhg\fP|\fBtw\fP] \fIsrcroot\fP \fIexceptfile\fP +.LP +.SH DESCRIPTION +.IX "OS-Net build tools" "findunref" "" "\fBfindunref\fP" +.LP +The findunref utility lists the files in a source tree which have not been +accessed more recently than a particular timestamp file. Although +findunref may be used on its own, it is usually invoked by +\fBnightly\fP(1) to find files that are never referenced during a given +build (see \fB-f\fP in \fBnightly\fP(1)). +.LP +The root of the source tree to examine is specified by \fIsrcroot\fP. To +simplify comparing findunref output from different source trees, findunref +outputs all filenames relative to \fIsrcroot\fP. +.LP +Some files in a source tree may be intentionally unreferenced (e.g., +documentation) or only referenced during specialized types of builds. +Accordingly, \fIexceptfile\fP names a file containing a list of pathname +globs that will be ignored by findunref. Within \fIexceptfile\fP, any +lines consisting solely of whitespace or starting with \fB#\fP will be +ignored. Directory globs may also be specified, which will cause any +matching directories to be skipped entirely. If no exceptions are +desired, \fIexceptfile\fP can be \fB/dev/null\fP. +.LP +Depending on how findunref is invoked, it can either check all files, or +limit its checks to files under control of a specific source code +management (SCM) system. To limit checks to files managed by Mercurial, +the \fBhg\fP(1) utility must be present in \fB/usr/bin\fP and any relevant +repositories must be located at or under \fBsrcroot\fP. Nested Mercurial +repositories are supported. +.SH OPTIONS +.TP 10 +.B -s \fIsubtree\fP +Only look under \fIsubtree\fP for unreferenced files. By default, all +directories under \fIsrcroot\fP are examined. +.TP 10 +.B -t \fItstampfile\fP +Consider files older than \fItstampfile\fP to be unreferenced. +By default, \fIsrcroot\fB/.build.tstamp\fR is used. +.TP 10 +.B -S \fBhg\fP|\fBtw\fP +Only check files that are managed by the specified SCM. To simplify +interaction with \fBwhich_scm\fP(1), the SCM names "mercurial" and +"teamware" may also be specified. By default, all files are checked. +.SH SEE ALSO +.LP +\fBhg\fP(1), +\fBnightly\fP(1), +\fBwhich_scm\fP(1) +.SH NOTES +Since many files are only used when building for a particular ISA (e.g., +Makefiles that are specified to i386 or sparc), builds must be done on all +applicable ISAs and the results merged. For instance, if nightly builds +(with \fB-f\fP) are done on both SPARC and x86, \fBusr/src\fP will be +populated with a corresponding \fBunref-\fIisa\fB.out\fR file, which can +be merged with \fBcomm\fP(1): +.LP +.nf +comm -12 /path/to/unref-i386.out + /path/to/unref-sparc.out > unref.out +.fi +.LP +This merged file can then be compared against the gate's latest +unreferenced file list (e.g. \fB/ws/onnv-gate/usr/src/unrefmaster.out\fP). +.LP +Different gates have different unreferenced file policies. Any changes to +\fIexceptfile\fP that would define new unreferenced file policies for a +given gate must be cleared with the appropriate gatekeepers. diff --git a/usr/src/tools/findunref/findunref.c b/usr/src/tools/findunref/findunref.c index f40690fa75..11764c4963 100644 --- a/usr/src/tools/findunref/findunref.c +++ b/usr/src/tools/findunref/findunref.c @@ -17,13 +17,10 @@ * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" /* * Finds all unreferenced files in a source tree that do not match a list of @@ -55,18 +52,54 @@ typedef struct { unsigned int maxpaths; } pnset_t; +/* + * Data associated with the current Mercurial manifest. + */ +typedef struct hgdata { + pnset_t *manifest; + char hgpath[MAXPATHLEN]; + char root[MAXPATHLEN]; + unsigned int rootlen; + boolean_t rootwarn; +} hgdata_t; + +/* + * Hooks used to check if a given unreferenced file is known to an SCM + * (currently Mercurial and TeamWare). + */ +typedef int checkscm_func_t(const char *, const struct FTW *); +typedef void chdirscm_func_t(const char *); + +typedef struct { + const char *name; + checkscm_func_t *checkfunc; + chdirscm_func_t *chdirfunc; +} scm_t; + +static checkscm_func_t check_tw, check_hg; +static chdirscm_func_t chdir_hg; static int pnset_add(pnset_t *, const char *); static int pnset_check(const pnset_t *, const char *); static void pnset_empty(pnset_t *); +static void pnset_free(pnset_t *); static int checkpath(const char *, const struct stat *, int, struct FTW *); static pnset_t *make_exset(const char *); static void warn(const char *, ...); static void die(const char *, ...); +static const scm_t scms[] = { + { "tw", check_tw, NULL }, + { "teamware", check_tw, NULL }, + { "hg", check_hg, chdir_hg }, + { "mercurial", check_hg, chdir_hg }, + { NULL, NULL, NULL } +}; + +static const scm_t *scm; +static hgdata_t hgdata; static time_t tstamp; /* timestamp to compare files to */ static pnset_t *exsetp; /* pathname globs to ignore */ static const char *progname; -static boolean_t allfiles = B_FALSE; int main(int argc, char *argv[]) @@ -83,10 +116,10 @@ main(int argc, char *argv[]) else progname++; - while ((c = getopt(argc, argv, "as:t:")) != EOF) { + while ((c = getopt(argc, argv, "as:t:S:")) != EOF) { switch (c) { case 'a': - allfiles = B_TRUE; + /* for compatibility; now the default */ break; case 's': @@ -97,6 +130,15 @@ main(int argc, char *argv[]) tstampfile = optarg; break; + case 'S': + for (scm = scms; scm->name != NULL; scm++) { + if (strcmp(scm->name, optarg) == 0) + break; + } + if (scm->name == NULL) + die("unsupported SCM `%s'\n", optarg); + break; + default: case '?': goto usage; @@ -107,8 +149,9 @@ main(int argc, char *argv[]) argv += optind; if (argc != 2) { -usage: (void) fprintf(stderr, "usage: %s [-a] [-s subtree] " - "[-t tstampfile] srcroot exceptfile\n", progname); +usage: (void) fprintf(stderr, "usage: %s [-s <subtree>] " + "[-t <tstampfile>] [-S hg|tw] <srcroot> <exceptfile>\n", + progname); return (EXIT_FAILURE); } @@ -134,7 +177,9 @@ usage: (void) fprintf(stderr, "usage: %s [-a] [-s subtree] " /* * Walk the specified subtree of the tree rooted at argv[0]. */ - (void) chdir(argv[0]); + if (chdir(argv[0]) == -1) + die("cannot change directory to \"%s\"", argv[0]); + if (nftw(subtree, checkpath, 100, FTW_PHYS) != 0) die("cannot walk tree rooted at \"%s\"\n", argv[0]); @@ -143,6 +188,143 @@ usage: (void) fprintf(stderr, "usage: %s [-a] [-s subtree] " } /* + * Load and return a pnset for the manifest for the Mercurial repo at `hgroot'. + */ +static pnset_t * +load_manifest(const char *hgroot) +{ + FILE *fp = NULL; + char *hgcmd = NULL; + char *newline; + pnset_t *pnsetp; + char path[MAXPATHLEN]; + + pnsetp = calloc(sizeof (pnset_t), 1); + if (pnsetp == NULL || + asprintf(&hgcmd, "/usr/bin/hg manifest -R %s", hgroot) == -1) + goto fail; + + fp = popen(hgcmd, "r"); + if (fp == NULL) + goto fail; + + while (fgets(path, sizeof (path), fp) != NULL) { + newline = strrchr(path, '\n'); + if (newline != NULL) + *newline = '\0'; + + if (pnset_add(pnsetp, path) == 0) + goto fail; + } + + (void) pclose(fp); + free(hgcmd); + return (pnsetp); +fail: + warn("cannot load hg manifest at %s", hgroot); + if (fp != NULL) + (void) pclose(fp); + free(hgcmd); + pnset_free(pnsetp); + return (NULL); +} + +/* + * If necessary, change our active manifest to be appropriate for `path'. + */ +static void +chdir_hg(const char *path) +{ + char hgpath[MAXPATHLEN]; + char basepath[MAXPATHLEN]; + char *slash; + + (void) snprintf(hgpath, MAXPATHLEN, "%s/.hg", path); + + /* + * Change our active manifest if any one of the following is true: + * + * 1. No manifest is loaded. Find the nearest hgroot to load from. + * + * 2. A manifest is loaded, but we've moved into a directory with + * its own hgroot (e.g., usr/closed). Load from its hgroot. + * + * 3. A manifest is loaded, but no longer applies (e.g., the manifest + * under usr/closed is loaded, but we've moved to usr/src). + */ + if (hgdata.manifest == NULL || + strcmp(hgpath, hgdata.hgpath) != 0 && access(hgpath, X_OK) == 0 || + strncmp(path, hgdata.root, hgdata.rootlen - 1) != 0) { + pnset_free(hgdata.manifest); + hgdata.manifest = NULL; + + (void) strlcpy(basepath, path, MAXPATHLEN); + + /* + * Walk up the directory tree looking for .hg subdirectories. + */ + while (access(hgpath, X_OK) == -1) { + slash = strrchr(basepath, '/'); + if (slash == NULL) { + if (!hgdata.rootwarn) { + warn("no hg root for \"%s\"\n", path); + hgdata.rootwarn = B_TRUE; + } + return; + } + *slash = '\0'; + (void) snprintf(hgpath, MAXPATHLEN, "%s/.hg", basepath); + } + + /* + * We found a directory with an .hg subdirectory; record it + * and load its manifest. + */ + (void) strlcpy(hgdata.hgpath, hgpath, MAXPATHLEN); + (void) strlcpy(hgdata.root, basepath, MAXPATHLEN); + hgdata.manifest = load_manifest(hgdata.root); + + /* + * The logic in check_hg() depends on hgdata.root having a + * single trailing slash, so only add it if it's missing. + */ + if (hgdata.root[strlen(hgdata.root) - 1] != '/') + (void) strlcat(hgdata.root, "/", MAXPATHLEN); + hgdata.rootlen = strlen(hgdata.root); + } +} + +/* + * Check if a file is under Mercurial control by checking against the manifest. + */ +/* ARGSUSED */ +static int +check_hg(const char *path, const struct FTW *ftwp) +{ + /* + * The manifest paths are relative to the manifest root; skip past it. + */ + path += hgdata.rootlen; + + return (hgdata.manifest != NULL && pnset_check(hgdata.manifest, path)); +} + +/* + * Check if a file is under TeamWare control by checking for its corresponding + * SCCS "s-dot" file. + */ +static int +check_tw(const char *path, const struct FTW *ftwp) +{ + char sccspath[MAXPATHLEN]; + + (void) snprintf(sccspath, MAXPATHLEN, "%.*s/SCCS/s.%s", ftwp->base, + path, path + ftwp->base); + + return (access(sccspath, F_OK) == 0); +} + +/* * Using `exceptfile' and a built-in list of exceptions, build and return a * pnset_t consisting of all of the pathnames globs which are allowed to be * unreferenced in the source tree. @@ -189,8 +371,7 @@ make_exset(const char *exceptfile) (void) fclose(fp); return (pnsetp); fail: - pnset_empty(pnsetp); - free(pnsetp); + pnset_free(pnsetp); return (NULL); } @@ -201,8 +382,6 @@ static int checkpath(const char *path, const struct stat *statp, int type, struct FTW *ftwp) { - char sccspath[MAXPATHLEN]; - switch (type) { case FTW_F: /* @@ -212,26 +391,28 @@ checkpath(const char *path, const struct stat *statp, int type, return (0); /* - * If not explicitly checking all files, restrict ourselves - * to unreferenced files under SCCS control. + * If requested, restrict ourselves to unreferenced files + * under SCM control. */ - if (!allfiles) { - (void) snprintf(sccspath, MAXPATHLEN, "%.*s/SCCS/s.%s", - ftwp->base, path, path + ftwp->base); - - if (access(sccspath, F_OK) == -1) - return (0); - } - - (void) puts(path); + if (scm == NULL || scm->checkfunc(path, ftwp)) + (void) puts(path); return (0); case FTW_D: /* * Prune any directories in the exception list. */ - if (pnset_check(exsetp, path)) + if (pnset_check(exsetp, path)) { ftwp->quit = FTW_PRUNE; + return (0); + } + + /* + * If necessary, advise the SCM logic of our new directory. + */ + if (scm != NULL && scm->chdirfunc != NULL) + scm->chdirfunc(path); + return (0); case FTW_DNR: @@ -256,14 +437,15 @@ static int pnset_add(pnset_t *pnsetp, const char *path) { char **newpaths; + unsigned int maxpaths; if (pnsetp->npath == pnsetp->maxpaths) { - newpaths = realloc(pnsetp->paths, sizeof (const char *) * - (pnsetp->maxpaths + 15)); + maxpaths = (pnsetp->maxpaths == 0) ? 512 : pnsetp->maxpaths * 2; + newpaths = realloc(pnsetp->paths, sizeof (char *) * maxpaths); if (newpaths == NULL) return (0); pnsetp->paths = newpaths; - pnsetp->maxpaths += 15; + pnsetp->maxpaths = maxpaths; } pnsetp->paths[pnsetp->npath] = strdup(path); @@ -302,6 +484,18 @@ pnset_empty(pnset_t *pnsetp) pnsetp->maxpaths = 0; } +/* + * Free the pnset_t pointed to by `pnsetp'. + */ +static void +pnset_free(pnset_t *pnsetp) +{ + if (pnsetp != NULL) { + pnset_empty(pnsetp); + free(pnsetp); + } +} + /* PRINTFLIKE1 */ static void warn(const char *format, ...) |