]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/guards
Add a patch to fix Intel E100 wake-on-lan problems.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / guards
1 #!/usr/bin/perl -w
2
3 #
4 # Guards:
5 #
6 # +xxx include if xxx is defined
7 # -xxx exclude if xxx is defined
8 # +!xxx include if xxx is not defined
9 # -!xxx exclude if xxx is not defined
10 #
11
12 use FileHandle;
13 use Getopt::Long;
14 use strict;
15
16 # Prototypes
17 sub files_in($$);
18 sub parse($$);
19 sub help();
20
21 #sub strip_ext($) {
22 # local ($_) = @_;
23 # s/\.(diff?|patch)$//;
24 #}
25
26 #sub try_ext($) {
27 # my ($path) = @_;
28 # for my $p in (($path, "$path.diff", "$path.dif", "$path.patch")) {
29 # return $p
30 # if (-f $p);
31 # }
32 # return undef;
33 #}
34
35 sub slashme($) {
36 my ($dir) = @_;
37 $dir =~ s#([^/])$#$&/#; # append a slash if necessary
38 if ($dir eq './') {
39 return '';
40 } else {
41 return $dir;
42 }
43 }
44
45 # Generate a list of files in a directory
46 #
47 sub files_in($$) {
48 my ($dir, $path) = @_;
49 my $dh = new FileHandle;
50 my (@files, $file);
51
52
53 opendir $dh, length("$dir$path") ? "$dir$path" : '.'
54 or die "$dir$path: $!\n";
55 while ($file = readdir($dh)) {
56 next if $file =~ /^(\.|\.\.|\.#.*|CVS|.*~)$/;
57 if (-d "$dir$path$file") {
58 @files = (@files, files_in($dir, "$path$file/"));
59 } else {
60 #print "[$path$file]\n";
61 push @files, "$path$file";
62 }
63 }
64 closedir $dh;
65 return @files;
66 }
67
68 # Parse a configuration file
69 # Callback called with ($patch, @guards) arguments
70 #
71 sub parse($$) {
72 my ($fh, $callback) = @_;
73
74 my $line = "";
75
76 while (<$fh>) {
77 chomp;
78 s/(^|\s+)#.*//;
79 if (s/\\$/ /) {
80 $line .= $_;
81 next;
82 }
83 $line .= $_;
84 my @guards = ();
85 foreach my $token (split /[\s\t\n]+/, $line) {
86 next if $token eq "";
87 if ($token =~ /^[-+]/) {
88 push @guards, $token;
89 } else {
90 #print "[" . join(",", @guards) . "] $token\n";
91 &$callback($token, @guards);
92 }
93 }
94 $line = "";
95 }
96 }
97
98 # Command line options
99 #
100 my ($dir, $config, $default, $check, $list, $invert_match, $with_guards) =
101 ( '', '-', 1, 0, 0, 0, 0);
102 my @path;
103
104 # Help text
105 #
106 sub help() {
107 print "$0 - select from a list of files guarded by conditions\n";
108 print "SYNOPSIS: $0 [--prefix=dir] [--path=dir1:dir2:...]\n" .
109 " [--default=0|1] [--check|--list] [--invert-match]\n" .
110 " [--with-guards] [--config=file] symbol ...\n\n" .
111 " (Default values: --path='" . join(':', @path) . "', " .
112 "--default=$default)\n";
113 exit 0;
114 }
115
116 # Parse command line options
117 #
118 Getopt::Long::Configure ("bundling");
119 eval {
120 unless (GetOptions (
121 'd|prefix=s' => \$dir,
122 'c|config=s' => \$config,
123 'C|check' => \$check,
124 'l|list' => \$list,
125 'w|with-guards' => \$with_guards,
126 'p|path=s' => \@path,
127 'D|default=i' => \$default,
128 'v|invert-match' => \$invert_match,
129 'h|help' => sub { help(); exit 0; })) {
130 help();
131 exit 1;
132 }
133 };
134 if ($@) {
135 print "$@";
136 help();
137 exit 1;
138 }
139
140 @path = ('.')
141 unless (@path);
142 @path = split(/:/, join(':', @path));
143
144 my $fh = ($config eq '-') ? \*STDIN : new FileHandle($config)
145 or die "$config: $!\n";
146
147 $dir = slashme($dir);
148
149 if ($check) {
150 # Check for duplicate files, or for files that are not referenced by
151 # the specification.
152
153 my $problems = 0;
154 my @files;
155
156 foreach (@path) {
157 @files = (@files, files_in($dir, slashme($_)));
158 }
159 my %files = map { $_ => 0 } @files;
160
161 parse($fh, sub {
162 my ($patch, @guards) = @_;
163 if (exists $files{$patch}) {
164 $files{$patch}++;
165 } else {
166 print "Not found: $dir$patch\n";
167 $problems++;
168 }});
169
170 $fh->close();
171
172 my ($file, $ref);
173 while (($file, $ref) = each %files) {
174 next if $ref == 1;
175
176 if ($ref == 0) {
177 print "Unused: $file\n" if $ref == 0;
178 $problems++;
179 }
180 if ($ref > 1) {
181 print "Warning: multiple uses: $file\n" if $ref > 1;
182 # This is not an error if the entries are mutually exclusive...
183 }
184 }
185 exit $problems ? 1 : 0;
186
187 } elsif ($list) {
188 parse($fh, sub {
189 my ($patch, @guards) = @_;
190 print join(' ', @guards), ' '
191 if (@guards && $with_guards);
192 print "$dir$patch\n";
193 });
194 } else {
195 # Generate a list of patches to apply.
196
197 my %symbols = map { $_ => 1 } @ARGV;
198
199 parse($fh, sub {
200 my ($patch, @guards) = @_;
201
202 my $selected;
203 if (@guards) {
204 # If the first guard is -xxx, the patch is included by default;
205 # if it is +xxx, the patch is excluded by default.
206 $selected = ($guards[0] =~ /^-/);
207
208 foreach (@guards) {
209 /^([-+])(!?)(.*)?/
210 or die "Bad guard '$_'\n";
211
212 # Check if the guard matches
213 if (($2 eq '!' && !exists $symbols{$3}) ||
214 ($2 eq '' && ( $3 eq '' || exists $symbols{$3}))) {
215 # Include or exclude
216 $selected = ($1 eq '+');
217 }
218 }
219 } else {
220 # If there are no guards, use the specified default result.
221 $selected = $default;
222 }
223
224 print "$dir$patch\n"
225 if $selected ^ $invert_match;
226 });
227
228 $fh->close();
229
230 exit 0;
231 }
232
233 __END__
234
235 =head1 NAME
236
237 guards - select from a list of files guarded by conditions
238
239 =head1 SYNOPSIS
240
241 F<guards> [--prefix=F<dir>] [--path=F<dir1:dir2:...>] [--default=<0|1>]
242 [--check|--list] [--invert-match] [--with-guards] [--config=<file>]
243 I<symbol> ...
244
245
246 =head1 DESCRIPTION
247
248 The script reads a configuration file that may contain so-called guards, file
249 names, and comments, and writes those file names that satisfy all guards to
250 standard output. The script takes a list of symbols as its arguments. Each line
251 in the configuration file is processed separately. Lines may start with a
252 number of guards. The following guards are defined:
253
254 =over
255
256 +I<xxx> Include the file(s) on this line if the symbol I<xxx> is defined.
257
258 -I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is defined.
259
260 +!I<xxx> Include the file(s) on this line if the symbol I<xxx> is not defined.
261
262 -!I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is not defined.
263
264 - Exclude this file. Used to avoid spurious I<--check> messages.
265
266 =back
267
268 The guards are processed left to right. The last guard that matches determines
269 if the file is included. If no guard is specified, the I<--default>
270 setting determines if the file is included.
271
272 If no configuration file is specified, the script reads from standard input.
273
274 The I<--check> option is used to compare the specification file against the
275 file system. If files are referenced in the specification that do not exist, or
276 if files are not enlisted in the specification file warnings are printed. The
277 I<--path> option can be used to specify which directory or directories to scan.
278 Multiple directories are eparated by a colon (C<:>) character. The
279 I<--prefix> option specifies the location of the files.
280
281 Use I<--list> to list all files independend of any rules. Use I<--invert-match>
282 to list only the excluded patches. Use I<--with-guards> to also include all
283 inclusion and exclusion rules.
284
285 =head1 AUTHOR
286
287 Andreas Gruenbacher <agruen@suse.de>, SUSE Labs