1 #
2 # Copyright 1999, 2000, 2001 Patrik Stridvall
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 #
18
19 package options;
20
21 use strict;
22
23 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
24 require Exporter;
25
26 @ISA = qw(Exporter);
27 @EXPORT = qw();
28 @EXPORT_OK = qw($options parse_comma_list parse_value);
29
30 use vars qw($options);
31
32 use output qw($output);
33
34 sub parse_comma_list($$) {
35 my $prefix = shift;
36 my $value = shift;
37
38 if(defined($prefix) && $prefix eq "no") {
39 return { active => 0, filter => 0, hash => {} };
40 } elsif(defined($value)) {
41 my %names;
42 for my $name (split /,/, $value) {
43 $names{$name} = 1;
44 }
45 return { active => 1, filter => 1, hash => \%names };
46 } else {
47 return { active => 1, filter => 0, hash => {} };
48 }
49 }
50
51 sub parse_value($$) {
52 my $prefix = shift;
53 my $value = shift;
54
55 return $value;
56 }
57
58 package _options;
59
60 use strict;
61
62 use output qw($output);
63
64 sub options_set($$);
65
66 sub new($$$$) {
67 my $proto = shift;
68 my $class = ref($proto) || $proto;
69 my $self = {};
70 bless ($self, $class);
71
72 my $options_long = \%{$self->{_OPTIONS_LONG}};
73 my $options_short = \%{$self->{_OPTIONS_SHORT}};
74 my $options_usage = \${$self->{_OPTIONS_USAGE}};
75
76 my $refoptions_long = shift;
77 my $refoptions_short = shift;
78 $$options_usage = shift;
79
80 %$options_long = %{$refoptions_long};
81 %$options_short = %{$refoptions_short};
82
83 $self->options_set("default");
84
85 my $arguments = \@{$self->{_ARGUMENTS}};
86 @$arguments = ();
87
88 my $end_of_options = 0;
89 while(defined($_ = shift @ARGV)) {
90 if(/^--$/) {
91 $end_of_options = 1;
92 next;
93 } elsif($end_of_options) {
94 # Nothing
95 } elsif(/^--(all|none)$/) {
96 $self->options_set("$1");
97 next;
98 } elsif(/^-([^=]*)(=(.*))?$/) {
99 my $name;
100 my $value;
101 if(defined($2)) {
102 $name = $1;
103 $value = $3;
104 } else {
105 $name = $1;
106 }
107
108 if($name =~ /^([^-].*)$/) {
109 $name = $$options_short{$1};
110 } else {
111 $name =~ s/^-(.*)$/$1/;
112 }
113
114 my $prefix;
115 if(defined($name) && $name =~ /^no-(.*)$/) {
116 $name = $1;
117 $prefix = "no";
118 if(defined($value)) {
119 $output->write("options with prefix 'no' can't take parameters\n");
120
121 return undef;
122 }
123 }
124
125 my $option;
126 if(defined($name)) {
127 $option = $$options_long{$name};
128 }
129
130 if(defined($option)) {
131 my $key = $$option{key};
132 my $parser = $$option{parser};
133 my $refvalue = \${$self->{$key}};
134 my @parents = ();
135
136 if(defined($$option{parent})) {
137 if(ref($$option{parent}) eq "ARRAY") {
138 @parents = @{$$option{parent}};
139 } else {
140 @parents = $$option{parent};
141 }
142 }
143
144 if(defined($parser)) {
145 if(!defined($value)) {
146 $value = shift @ARGV;
147 }
148 $$refvalue = &$parser($prefix,$value);
149 } else {
150 if(defined($value)) {
151 $$refvalue = $value;
152 } elsif(!defined($prefix)) {
153 $$refvalue = 1;
154 } else {
155 $$refvalue = 0;
156 }
157 }
158
159 if((ref($$refvalue) eq "HASH" && $$refvalue->{active}) || $$refvalue) {
160 while($#parents >= 0) {
161 my @old_parents = @parents;
162 @parents = ();
163 foreach my $parent (@old_parents) {
164 my $parentkey = $$options_long{$parent}{key};
165 my $refparentvalue = \${$self->{$parentkey}};
166
167 $$refparentvalue = 1;
168
169 if(defined($$options_long{$parent}{parent})) {
170 if(ref($$options_long{$parent}{parent}) eq "ARRAY") {
171 push @parents, @{$$options_long{$parent}{parent}};
172 } else {
173 push @parents, $$options_long{$parent}{parent};
174 }
175 }
176 }
177 }
178 }
179 next;
180 }
181 }
182
183 if(!$end_of_options && /^-(.*)$/) {
184 $output->write("unknown option: $_\n");
185 $output->write($$options_usage);
186 exit 1;
187 } else {
188 push @$arguments, $_;
189 }
190 }
191
192 if($self->help) {
193 $output->write($$options_usage);
194 $self->show_help;
195 exit 0;
196 }
197
198 return $self;
199 }
200
201 sub DESTROY {
202 }
203
204 sub parse_files($) {
205 my $self = shift;
206
207 my $arguments = \@{$self->{_ARGUMENTS}};
208 my $directories = \@{$self->{_DIRECTORIES}};
209 my $c_files = \@{$self->{_C_FILES}};
210 my $h_files = \@{$self->{_H_FILES}};
211
212 my $error = 0;
213 my @files = ();
214 foreach (@$arguments) {
215 if(!-e $_) {
216 $output->write("$_: no such file or directory\n");
217 $error = 1;
218 } else {
219 push @files, $_;
220 }
221 }
222 if($error) {
223 exit 1;
224 }
225
226 my @paths = ();
227 my @c_files = ();
228 my @h_files = ();
229 foreach my $file (@files) {
230 if($file =~ /\.c$/) {
231 push @c_files, $file;
232 } elsif($file =~ /\.h$/) {
233 push @h_files, $file;
234 } else {
235 push @paths, $file;
236 }
237 }
238
239 if($#c_files == -1 && $#h_files == -1 && $#paths == -1)
240 {
241 @paths = ".";
242 }
243
244 if($#paths != -1 || $#c_files != -1) {
245 my $c_command = "find " . join(" ", @paths, @c_files) . " -name \\*.c";
246 my %found;
247 @$c_files = sort(map {
248 s/^\.\/(.*)$/$1/;
249 if(defined($found{$_})) {
250 ();
251 } else {
252 $found{$_}++;
253 $_;
254 }
255 } split(/\n/, `$c_command`));
256 }
257
258 if($#paths != -1 || $#h_files != -1) {
259 my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
260 my %found;
261
262 @$h_files = sort(map {
263 s/^\.\/(.*)$/$1/;
264 if(defined($found{$_})) {
265 ();
266 } else {
267 $found{$_}++;
268 $_;
269 }
270 } split(/\n/, `$h_command`));
271 }
272
273 my %dirs;
274 foreach my $file (@$c_files, @$h_files) {
275 my $dir = $file;
276 $dir =~ s%/?[^/]+$%%;
277 if(!$dir) { $dir = "."; }
278 $dirs{$dir}++
279 }
280
281 @$directories = sort(keys(%dirs));
282 }
283
284 sub options_set($$) {
285 my $self = shift;
286
287 my $options_long = \%{$self->{_OPTIONS_LONG}};
288 my $options_short = \%{$self->{_OPTIONS_SHORT}};
289
290 local $_ = shift;
291 for my $name (sort(keys(%$options_long))) {
292 my $option = $$options_long{$name};
293 my $key = uc($name);
294 $key =~ tr/-/_/;
295 $$option{key} = $key;
296 my $refvalue = \${$self->{$key}};
297
298 if(/^default$/) {
299 $$refvalue = $$option{default};
300 } elsif(/^all$/) {
301 if($name !~ /^(?:help|debug|verbose|module)$/) {
302 if(ref($$refvalue) ne "HASH") {
303 $$refvalue = 1;
304 } else {
305 $$refvalue = { active => 1, filter => 0, hash => {} };
306 }
307 }
308 } elsif(/^none$/) {
309 if($name !~ /^(?:help|debug|verbose|module)$/) {
310 if(ref($$refvalue) ne "HASH") {
311 $$refvalue = 0;
312 } else {
313 $$refvalue = { active => 0, filter => 0, hash => {} };
314 }
315 }
316 }
317 }
318 }
319
320 sub show_help($) {
321 my $self = shift;
322
323 my $options_long = \%{$self->{_OPTIONS_LONG}};
324 my $options_short = \%{$self->{_OPTIONS_SHORT}};
325
326 my $maxname = 0;
327 for my $name (sort(keys(%$options_long))) {
328 if(length($name) > $maxname) {
329 $maxname = length($name);
330 }
331 }
332
333 for my $name (sort(keys(%$options_long))) {
334 my $option = $$options_long{$name};
335 my $description = $$option{description};
336 my $parser = $$option{parser};
337 my $current = ${$self->{$$option{key}}};
338
339 my $value = $current;
340
341 my $command;
342 if(!defined $parser) {
343 if($value) {
344 $command = "--no-$name";
345 } else {
346 $command = "--$name";
347 }
348 } else {
349 if(ref($value) eq "HASH" && $value->{active}) {
350 $command = "--[no-]$name\[=<value>]";
351 } else {
352 $command = "--$name\[=<value>]";
353 }
354 }
355
356 $output->write($command);
357 $output->write(" " x (($maxname - length($name) + 17) - (length($command) - length($name) + 1)));
358 if(!defined $parser) {
359 if($value) {
360 $output->write("Disable ");
361 } else {
362 $output->write("Enable ");
363 }
364 } else {
365 if(ref($value) eq "HASH")
366 {
367 if ($value->{active}) {
368 $output->write("(Disable) ");
369 } else {
370 $output->write("Enable ");
371 }
372 }
373 }
374 $output->write("$description\n");
375 }
376 }
377
378 sub AUTOLOAD {
379 my $self = shift;
380
381 my $name = $_options::AUTOLOAD;
382 $name =~ s/^.*::(.[^:]*)$/\U$1/;
383
384 my $refvalue = $self->{$name};
385 if(!defined($refvalue)) {
386 die "<internal>: options.pm: member $name does not exist\n";
387 }
388
389 if(ref($$refvalue) ne "HASH") {
390 return $$refvalue;
391 } else {
392 return $$refvalue->{active};
393 }
394 }
395
396 sub arguments($) {
397 my $self = shift;
398
399 my $arguments = \@{$self->{_ARGUMENTS}};
400
401 return @$arguments;
402 }
403
404 sub c_files($) {
405 my $self = shift;
406
407 my $c_files = \@{$self->{_C_FILES}};
408
409 if(!defined(@$c_files)) {
410 $self->parse_files;
411 }
412
413 return @$c_files;
414 }
415
416 sub h_files($) {
417 my $self = shift;
418
419 my $h_files = \@{$self->{_H_FILES}};
420
421 if(!defined(@$h_files)) {
422 $self->parse_files;
423 }
424
425 return @$h_files;
426 }
427
428 sub directories($) {
429 my $self = shift;
430
431 my $directories = \@{$self->{_DIRECTORIES}};
432
433 if(!defined(@$directories)) {
434 $self->parse_files;
435 }
436
437 return @$directories;
438 }
439
440 1;
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.