#!/usr/bin/perl # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (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 2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" use strict; use File::Find (); require v5.6.1; use vars qw/$f_flg *name *dir @execlist $basedir/; *name = *File::Find::name; *dir = *File::Find::dir; # Use the same mechanism as def.dir.flp to determine if there are any # SCCS files matching the pattern supplied for a "find_files" # statement. sub sccs_empty { my ($pat, $dir) = @_; return 0 if $f_flg; my $foo = `find $dir -name "$pat" -print | grep /SCCS/s.`; $foo eq ""; } # Not pretty, but simple enough to work for the known cases. # Does not bother with curly braces or fancy substitutions. sub expand { my ($str) = @_; while ($str =~ /\$(\w+)/) { my $newstr = $ENV{$1}; $str =~ s/\$$1/$newstr/g; } $str; } # Process a single inc.flg or req.flg file. sub process_file { my ($fname, $incpath) = @_; my ($dname, $isincflg); my ($expfile, $newpath, $line, $cont, $firstline, $text); $dname = $fname; $dname =~ s+/[^/]*$++; $isincflg = $fname =~ /inc.flg$/; if (defined $incpath) { $newpath = "$incpath, from $fname:"; } else { $newpath = "from $fname:"; } if (open INC, "<$fname") { $line = 0; $cont = 0; while () { chomp; $line++; ( $cont = 0, next ) if /^\s*#/ || /^\s*$/; if ($cont) { $text = $text . $_; } else { $firstline = $line; $text = $_; } if (/\\$/) { $cont = 1; $text =~ s/\\$//; next; } $cont = 0; if ($text =~ /\s*echo_file\s+(\S+)/) { $expfile = expand($1); warn "$fname:$firstline: $1 isn't a file\n" if ! -f $expfile; } elsif ($text =~ /\s*find_files\s+['"]([^'"]+)['"]\s+(.*)/) { foreach my $dir (split(/\s+/, "$2")) { $expfile = expand($dir); if (! -d $expfile) { warn "$fname:$firstline: $dir isn't a directory\n"; } elsif ($isincflg && $expfile eq $dname) { warn "$fname:$firstline: $dir is unnecessary\n"; } elsif (sccs_empty($1, $expfile)) { warn "$fname:$firstline: $dir has no SCCS objects ", "with '$1'\n"; } } } elsif ($text =~ /\s*exec_file\s+(\S+)/) { $expfile = expand($1); if (-f $expfile) { push @execlist, $expfile, "$newpath:$firstline"; } else { warn "$fname:$firstline: $1 isn't a file\n"; warn "included $incpath\n" if defined $incpath; } } else { warn "$0: $fname:$firstline: unknown entry: $text\n"; warn "included $incpath\n" if defined $incpath; } } close INC; } else { warn "$0: $fname: $!\n"; } } sub wanted { process_file($_, undef) if /\/(inc|req)\.flg$/ && -f $_; } $f_flg = $ARGV[0] eq "-f"; shift @ARGV if $f_flg; $basedir = "usr/src"; if ($#ARGV == 0) { $basedir = shift @ARGV; } elsif ($#ARGV > 0) { die "$0: unexpected arguments\n"; } die "$0: \$CODEMGR_WS must be set\n" if $ENV{CODEMGR_WS} eq ""; chdir $ENV{CODEMGR_WS} or die "$0: chdir $ENV{CODEMGR_WS}: $!\n"; File::Find::find({wanted => \&wanted, no_chdir => 1}, $basedir); # After passing through the tree, process all of the included files. # There aren't many of these, so don't bother trying to optimize the # traversal. Just do them all. while (@execlist) { my $file = shift @execlist; my $incpath = shift @execlist; process_file($file, $incpath); } exit 0;