xref: /titanic_52/usr/src/tools/scripts/validate_flg.pl (revision f136dc05547d5c8bf0829a1439b3e4caadef85a0)
17c478bd9Sstevel@tonic-gate#!/usr/bin/perl
27c478bd9Sstevel@tonic-gate#
37c478bd9Sstevel@tonic-gate# CDDL HEADER START
47c478bd9Sstevel@tonic-gate#
57c478bd9Sstevel@tonic-gate# The contents of this file are subject to the terms of the
6*f136dc05Scarlsonj# Common Development and Distribution License (the "License").
7*f136dc05Scarlsonj# You may not use this file except in compliance with the License.
87c478bd9Sstevel@tonic-gate#
97c478bd9Sstevel@tonic-gate# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate# or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate# See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate# and limitations under the License.
137c478bd9Sstevel@tonic-gate#
147c478bd9Sstevel@tonic-gate# When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate# If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate# fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate# information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate#
207c478bd9Sstevel@tonic-gate# CDDL HEADER END
217c478bd9Sstevel@tonic-gate#
227c478bd9Sstevel@tonic-gate
23*f136dc05Scarlsonj# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate# Use is subject to license terms.
257c478bd9Sstevel@tonic-gate#
267c478bd9Sstevel@tonic-gate#ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gateuse strict;
297c478bd9Sstevel@tonic-gateuse File::Find ();
307c478bd9Sstevel@tonic-gaterequire v5.6.1;
317c478bd9Sstevel@tonic-gate
32*f136dc05Scarlsonjuse vars qw/$f_flg *name *dir @execlist $basedir @opt_e @exclude/;
337c478bd9Sstevel@tonic-gate*name   = *File::Find::name;
347c478bd9Sstevel@tonic-gate*dir    = *File::Find::dir;
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate# Use the same mechanism as def.dir.flp to determine if there are any
377c478bd9Sstevel@tonic-gate# SCCS files matching the pattern supplied for a "find_files"
387c478bd9Sstevel@tonic-gate# statement.
397c478bd9Sstevel@tonic-gatesub sccs_empty {
407c478bd9Sstevel@tonic-gate    my ($pat, $dir) = @_;
417c478bd9Sstevel@tonic-gate    return 0 if $f_flg;
427c478bd9Sstevel@tonic-gate    my $foo = `find $dir -name "$pat" -print | grep /SCCS/s.`;
437c478bd9Sstevel@tonic-gate    $foo eq "";
447c478bd9Sstevel@tonic-gate}
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate# Not pretty, but simple enough to work for the known cases.
477c478bd9Sstevel@tonic-gate# Does not bother with curly braces or fancy substitutions.
48*f136dc05Scarlsonj# Returns undef if this pattern is excluded.
497c478bd9Sstevel@tonic-gatesub expand {
507c478bd9Sstevel@tonic-gate    my ($str) = @_;
517c478bd9Sstevel@tonic-gate    while ($str =~ /\$(\w+)/) {
527c478bd9Sstevel@tonic-gate	my $newstr = $ENV{$1};
537c478bd9Sstevel@tonic-gate	$str =~ s/\$$1/$newstr/g;
547c478bd9Sstevel@tonic-gate    }
55*f136dc05Scarlsonj    foreach my $pat (@exclude) {
56*f136dc05Scarlsonj	return undef if $str =~ /$pat/;
57*f136dc05Scarlsonj    }
587c478bd9Sstevel@tonic-gate    $str;
597c478bd9Sstevel@tonic-gate}
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate# Process a single inc.flg or req.flg file.
627c478bd9Sstevel@tonic-gatesub process_file {
637c478bd9Sstevel@tonic-gate    my ($fname, $incpath) = @_;
647c478bd9Sstevel@tonic-gate    my ($dname, $isincflg);
657c478bd9Sstevel@tonic-gate    my ($expfile, $newpath, $line, $cont, $firstline, $text);
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate    $dname = $fname;
687c478bd9Sstevel@tonic-gate    $dname =~ s+/[^/]*$++;
697c478bd9Sstevel@tonic-gate
707c478bd9Sstevel@tonic-gate    $isincflg = $fname =~ /inc.flg$/;
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate    if (defined $incpath) {
737c478bd9Sstevel@tonic-gate	$newpath = "$incpath, from $fname:";
747c478bd9Sstevel@tonic-gate    } else {
757c478bd9Sstevel@tonic-gate	$newpath = "from $fname:";
767c478bd9Sstevel@tonic-gate    }
777c478bd9Sstevel@tonic-gate
787c478bd9Sstevel@tonic-gate    if (open INC, "<$fname") {
797c478bd9Sstevel@tonic-gate	$line = 0;
807c478bd9Sstevel@tonic-gate	$cont = 0;
817c478bd9Sstevel@tonic-gate	while (<INC>) {
827c478bd9Sstevel@tonic-gate	    chomp;
837c478bd9Sstevel@tonic-gate	    $line++;
847c478bd9Sstevel@tonic-gate	    ( $cont = 0, next ) if /^\s*#/ || /^\s*$/;
857c478bd9Sstevel@tonic-gate	    if ($cont) {
867c478bd9Sstevel@tonic-gate		$text = $text . $_;
877c478bd9Sstevel@tonic-gate	    } else {
887c478bd9Sstevel@tonic-gate		$firstline = $line;
897c478bd9Sstevel@tonic-gate		$text = $_;
907c478bd9Sstevel@tonic-gate	    }
917c478bd9Sstevel@tonic-gate	    if (/\\$/) {
927c478bd9Sstevel@tonic-gate		$cont = 1;
937c478bd9Sstevel@tonic-gate		$text =~ s/\\$//;
947c478bd9Sstevel@tonic-gate		next;
957c478bd9Sstevel@tonic-gate	    }
967c478bd9Sstevel@tonic-gate	    $cont = 0;
977c478bd9Sstevel@tonic-gate	    if ($text =~ /\s*echo_file\s+(\S+)/) {
98*f136dc05Scarlsonj		next if !defined($expfile = expand($1));
997c478bd9Sstevel@tonic-gate		warn "$fname:$firstline: $1 isn't a file\n" if ! -f $expfile;
1007c478bd9Sstevel@tonic-gate	    } elsif ($text =~ /\s*find_files\s+['"]([^'"]+)['"]\s+(.*)/) {
1017c478bd9Sstevel@tonic-gate		foreach my $dir (split(/\s+/, "$2")) {
102*f136dc05Scarlsonj		    next if !defined($expfile = expand($dir));
1037c478bd9Sstevel@tonic-gate		    if (! -d $expfile) {
1047c478bd9Sstevel@tonic-gate			warn "$fname:$firstline: $dir isn't a directory\n";
1057c478bd9Sstevel@tonic-gate		    } elsif ($isincflg && $expfile eq $dname) {
1067c478bd9Sstevel@tonic-gate			warn "$fname:$firstline: $dir is unnecessary\n";
1077c478bd9Sstevel@tonic-gate		    } elsif (sccs_empty($1, $expfile)) {
1087c478bd9Sstevel@tonic-gate			warn "$fname:$firstline: $dir has no SCCS objects ",
1097c478bd9Sstevel@tonic-gate				"with '$1'\n";
1107c478bd9Sstevel@tonic-gate		    }
1117c478bd9Sstevel@tonic-gate		}
1127c478bd9Sstevel@tonic-gate	    } elsif ($text =~ /\s*exec_file\s+(\S+)/) {
113*f136dc05Scarlsonj		next if !defined($expfile = expand($1));
1147c478bd9Sstevel@tonic-gate		if (-f $expfile) {
1157c478bd9Sstevel@tonic-gate		    push @execlist, $expfile, "$newpath:$firstline";
1167c478bd9Sstevel@tonic-gate		} else {
1177c478bd9Sstevel@tonic-gate		    warn "$fname:$firstline: $1 isn't a file\n";
1187c478bd9Sstevel@tonic-gate		    warn "included $incpath\n" if defined $incpath;
1197c478bd9Sstevel@tonic-gate		}
1207c478bd9Sstevel@tonic-gate	    } else {
1217c478bd9Sstevel@tonic-gate		warn "$0: $fname:$firstline: unknown entry: $text\n";
1227c478bd9Sstevel@tonic-gate		warn "included $incpath\n" if defined $incpath;
1237c478bd9Sstevel@tonic-gate	    }
1247c478bd9Sstevel@tonic-gate	}
1257c478bd9Sstevel@tonic-gate	close INC;
1267c478bd9Sstevel@tonic-gate    } else {
1277c478bd9Sstevel@tonic-gate	warn "$0: $fname: $!\n";
1287c478bd9Sstevel@tonic-gate    }
1297c478bd9Sstevel@tonic-gate}
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gatesub wanted {
1327c478bd9Sstevel@tonic-gate    process_file($_, undef) if /\/(inc|req)\.flg$/ && -f $_;
1337c478bd9Sstevel@tonic-gate}
1347c478bd9Sstevel@tonic-gate
135*f136dc05Scarlsonjsub next_arg {
136*f136dc05Scarlsonj    my ($arg) = @_;
137*f136dc05Scarlsonj    if ($arg eq "") {
138*f136dc05Scarlsonj	die "$0: missing argument for $_\n" if $#ARGV == -1;
139*f136dc05Scarlsonj	$arg = shift @ARGV;
140*f136dc05Scarlsonj    }
141*f136dc05Scarlsonj    $arg;
142*f136dc05Scarlsonj}
143*f136dc05Scarlsonj
144*f136dc05Scarlsonj# I'd like to use Perl's getopts here, but it doesn't handle repeated
145*f136dc05Scarlsonj# options, and using comma separators is just too ugly.
146*f136dc05Scarlsonj# This doesn't handle combined options (as in '-rm'), but I don't care.
147*f136dc05Scarlsonjmy $arg;
148*f136dc05Scarlsonjwhile ($#ARGV >= 0) {
149*f136dc05Scarlsonj    $_ = $ARGV[0];
150*f136dc05Scarlsonj    last if /^[^-]/;
151*f136dc05Scarlsonj    shift @ARGV;
152*f136dc05Scarlsonj    last if /^--$/;
153*f136dc05Scarlsonj    SWITCH: {
154*f136dc05Scarlsonj	  /^-f/ && do { $f_flg = 1; last SWITCH; };
155*f136dc05Scarlsonj	  if (/^-e(.*)$/) {
156*f136dc05Scarlsonj	      $arg = next_arg($1);
157*f136dc05Scarlsonj	      push @opt_e, $arg;
158*f136dc05Scarlsonj	      last SWITCH;
159*f136dc05Scarlsonj	  }
160*f136dc05Scarlsonj	  print "$0: unknown option $_\n";
161*f136dc05Scarlsonj	  usage();
162*f136dc05Scarlsonj    }
163*f136dc05Scarlsonj}
164*f136dc05Scarlsonj
165*f136dc05Scarlsonj# compile the 'exclude' regexps
166*f136dc05Scarlsonj@exclude = map qr/$_/x, @opt_e;
1677c478bd9Sstevel@tonic-gate
168fb9f9b97Skupfer$basedir = "usr";
1697c478bd9Sstevel@tonic-gateif ($#ARGV == 0) {
1707c478bd9Sstevel@tonic-gate    $basedir = shift @ARGV;
1717c478bd9Sstevel@tonic-gate} elsif ($#ARGV > 0) {
1727c478bd9Sstevel@tonic-gate    die "$0: unexpected arguments\n";
1737c478bd9Sstevel@tonic-gate}
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gatedie "$0: \$CODEMGR_WS must be set\n" if $ENV{CODEMGR_WS} eq "";
1767c478bd9Sstevel@tonic-gatechdir $ENV{CODEMGR_WS} or die "$0: chdir $ENV{CODEMGR_WS}: $!\n";
1777c478bd9Sstevel@tonic-gate
1787c478bd9Sstevel@tonic-gateFile::Find::find({wanted => \&wanted, no_chdir => 1}, $basedir);
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate# After passing through the tree, process all of the included files.
1817c478bd9Sstevel@tonic-gate# There aren't many of these, so don't bother trying to optimize the
1827c478bd9Sstevel@tonic-gate# traversal.  Just do them all.
1837c478bd9Sstevel@tonic-gatewhile (@execlist) {
1847c478bd9Sstevel@tonic-gate    my $file = shift @execlist;
1857c478bd9Sstevel@tonic-gate    my $incpath = shift @execlist;
1867c478bd9Sstevel@tonic-gate    process_file($file, $incpath);
1877c478bd9Sstevel@tonic-gate}
1887c478bd9Sstevel@tonic-gate
1897c478bd9Sstevel@tonic-gateexit 0;
190