8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / tools / scripts / validate_paths.pl
blob49f9ef7e692d416c9698ef6daab9bf031e0fad0e
1 #!/usr/bin/perl
3 # CDDL HEADER START
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.
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.
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]
20 # CDDL HEADER END
24 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
29 # Given either a list of files containing paths on the command line or
30 # a set of paths on standard input, validate that the paths actually
31 # exist, and complain if they do not. This is invoked by nightly to
32 # verify the contents of various control files used by the ON build
33 # process.
35 # Command line options:
37 # -m Show the matches (for debug).
39 # -r Allow shell globs in the paths. Unless otherwise
40 # flagged by a keyword (see -k) or exclusion (see -e),
41 # it is an error if no files match the expression at
42 # all.
44 # -s/from/to/
45 # Perform a substitution on all of the paths in the
46 # file. This substitution is performed after stripping
47 # any in-line comments but before any exclusion matching
48 # is done. The option may include any legal Perl
49 # substitution expression and may be repeated to give
50 # multiple expressions.
52 # -e <pattern>
53 # Exclude paths matching the given pattern from the
54 # "must exist" rule. These paths will not be checked.
55 # Option may include any legal Perl regular expression,
56 # and may be repeated to give multiple patterns.
58 # -k <keyword>
59 # Exclude paths if there is either an in-line comment
60 # containing the given keyword, or the preceding line
61 # consists of only a comment containing that keyword.
62 # Option may be repeated to provide multiple keywords.
64 # -b <base>
65 # Base directory for relative paths tested.
67 # -n <name>
68 # String to use in place of file name when using stdin
70 use strict;
72 my ($opt_r, $opt_m, @opt_s, @opt_e, @opt_k, $opt_b, $opt_n);
73 my ($keywords, @exclude);
75 sub usage {
76 die "usage: $0 [-r] [-m]\n",
77 "\t[-s/from/to/] [-e <pattern>] [-k <keyword>] [-b <base>]\n",
78 "\t[-n <name> ] [files...]\n";
81 # process the path list in a given file
82 sub process_paths {
83 my ($FILE, $name) = @_;
84 my ($ignore, $file, $line);
85 $ignore = 0;
86 $line = 0;
87 while (<$FILE>) {
88 chomp;
89 $line++;
90 # Ignore comment lines
91 if (/^\s*#(.*)$/) {
92 $ignore = ($1 =~ /$keywords/) if defined $keywords;
93 next;
95 # Extract path as $1 from line
96 if (/^\s*([^#]+)#(.*)$/) {
97 ($ignore = 0, next) if $ignore;
98 $ignore = ($2 =~ /$keywords/) if defined $keywords;
99 ($ignore = 0, next) if $ignore;
100 } elsif (/^\s*([^#]+)$/) {
101 ($ignore = 0, next) if $ignore;
102 } else {
103 # Ignore blank lines
104 $ignore = 0;
105 next;
107 # remove any trailing spaces from path
108 ($file = $1) =~ s/[ ]*$//;
109 # perform user-supplied substitutions
110 foreach my $pat (@opt_s) {
111 eval '$file =~ s' . $pat;
113 # check if the given path is on the 'exclude' list
114 $ignore = 0;
115 foreach my $pat (@exclude) {
116 ($ignore = 1, last) if $file =~ /$pat/;
118 if ($ignore == 0) {
119 # construct the actual path to the file
120 my $path = $opt_b . $file;
121 # Expand any shell globs, if that feature is on. Since
122 # Perl's glob() is stateful, we use an array assignment
123 # to get the first match and discard the others.
124 ($path) = glob($path) if $opt_r;
125 print "$name:$line: $file\n" unless !$opt_m && -e $path;
126 print " $path\n" if $opt_m;
128 $ignore = 0;
132 sub next_arg {
133 my ($arg) = @_;
134 if ($arg eq "") {
135 die "$0: missing argument for $_\n" if $#ARGV == -1;
136 $arg = shift @ARGV;
138 $arg;
141 # I'd like to use Perl's getopts here, but it doesn't handle repeated
142 # options, and using comma separators is just too ugly.
143 # This doesn't handle combined options (as in '-rm'), but I don't care.
144 my $arg, $opt_r, $opt_m, @opt_s, @opt_e, @opt_k, $opt_b, $opt_n;
145 while ($#ARGV >= 0) {
146 $_ = $ARGV[0];
147 last if /^[^-]/;
148 shift @ARGV;
149 $opt_n = "standard input";
150 last if /^--$/;
151 SWITCH: {
152 /^-r/ && do { $opt_r = 1; last SWITCH; };
153 /^-m/ && do { $opt_m = 1; last SWITCH; };
154 if (/^-s(.*)$/) {
155 $arg = next_arg($1);
156 push @opt_s, $arg;
157 last SWITCH;
159 if (/^-e(.*)$/) {
160 $arg = next_arg($1);
161 push @opt_e, $arg;
162 last SWITCH;
164 if (/^-k(.*)$/) {
165 $arg = next_arg($1);
166 push @opt_k, $arg;
167 last SWITCH;
169 if (/^-b(.*)$/) {
170 $opt_b = next_arg($1);
171 last SWITCH;
173 if (/^-n(.*)$/) {
174 $opt_n = next_arg($1);
175 last SWITCH;
177 print "$0: unknown option $_\n";
178 usage();
182 # compile the 'exclude' regexps
183 @exclude = map qr/$_/x, @opt_e;
184 # if no keywords are given, then leave $keywords undefined
185 if (@opt_k) {
186 # construct a regexp that matches the keywords specified
187 my $opt_k = join("|", @opt_k);
188 $keywords = qr/($opt_k)/xo;
190 $opt_b .= "/" if $opt_b =~ /[^\/]$/;
192 my $file;
194 if ($#ARGV < 0) {
195 process_paths(\*STDIN, $opt_n);
196 } else {
197 foreach $file (@ARGV) {
198 if (! -e $file) {
199 warn "$0: $file doesn't exist\n";
200 } elsif (! -f $file) {
201 warn "$0: $file isn't a regular file\n";
202 } elsif (! -T $file) {
203 warn "$0: $file isn't a text file\n";
204 } elsif (open FILE, "<$file") {
205 process_paths(\*FILE, $file);
206 } else {
207 warn "$0: $file: $!\n";
212 exit 0