2 # Copyright 1999, 2000, 2001 Patrik Stridvall
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.
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.
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
23 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
28 @EXPORT_OK = qw($options parse_comma_list parse_value);
30 use vars qw($options);
32 use output qw($output);
34 sub parse_comma_list($$) {
38 if(defined($prefix) && $prefix eq "no") {
39 return { active => 0, filter => 0, hash => {} };
40 } elsif(defined($value)) {
42 for my $name (split /,/, $value) {
45 return { active => 1, filter => 1, hash => \%names };
47 return { active => 1, filter => 0, hash => {} };
62 use output qw($output);
68 my $class = ref($proto) || $proto;
70 bless ($self, $class);
72 my $options_long = \%{$self->{_OPTIONS_LONG}};
73 my $options_short = \%{$self->{_OPTIONS_SHORT}};
74 my $options_usage = \${$self->{_OPTIONS_USAGE}};
76 my $refoptions_long = shift;
77 my $refoptions_short = shift;
78 $$options_usage = shift;
80 %$options_long = %{$refoptions_long};
81 %$options_short = %{$refoptions_short};
83 $self->options_set("default");
85 my $arguments = \@{$self->{_ARGUMENTS}};
88 my $end_of_options = 0;
89 while(defined($_ = shift @ARGV)) {
93 } elsif($end_of_options) {
95 } elsif(/^--(all|none)$/) {
96 $self->options_set("$1");
98 } elsif(/^-([^=]*)(=(.*))?$/) {
108 if($name =~ /^([^-].*)$/) {
109 $name = $$options_short{$1};
111 $name =~ s/^-(.*)$/$1/;
115 if(defined($name) && $name =~ /^no-(.*)$/) {
118 if(defined($value)) {
119 $output->write("options with prefix 'no' can't take parameters\n");
127 $option = $$options_long{$name};
130 if(defined($option)) {
131 my $key = $$option{key};
132 my $parser = $$option{parser};
133 my $refvalue = \${$self->{$key}};
136 if(defined($$option{parent})) {
137 if(ref($$option{parent}) eq "ARRAY") {
138 @parents = @{$$option{parent}};
140 @parents = $$option{parent};
144 if(defined($parser)) {
145 if(!defined($value)) {
146 $value = shift @ARGV;
148 $$refvalue = &$parser($prefix,$value);
150 if(defined($value)) {
152 } elsif(!defined($prefix)) {
159 if((ref($$refvalue) eq "HASH" && $$refvalue->{active}) || $$refvalue) {
160 while($#parents >= 0) {
161 my @old_parents = @parents;
163 foreach my $parent (@old_parents) {
164 my $parentkey = $$options_long{$parent}{key};
165 my $refparentvalue = \${$self->{$parentkey}};
167 $$refparentvalue = 1;
169 if(defined($$options_long{$parent}{parent})) {
170 if(ref($$options_long{$parent}{parent}) eq "ARRAY") {
171 push @parents, @{$$options_long{$parent}{parent}};
173 push @parents, $$options_long{$parent}{parent};
183 if(!$end_of_options && /^-(.*)$/) {
184 $output->write("unknown option: $_\n");
185 $output->write($$options_usage);
188 push @$arguments, $_;
193 $output->write($$options_usage);
207 my $arguments = \@{$self->{_ARGUMENTS}};
208 my $directories = \@{$self->{_DIRECTORIES}};
209 my $c_files = \@{$self->{_C_FILES}};
210 my $h_files = \@{$self->{_H_FILES}};
214 foreach (@$arguments) {
216 $output->write("$_: no such file or directory\n");
229 foreach my $file (@files) {
230 if($file =~ /\.c$/) {
231 push @c_files, $file;
232 } elsif($file =~ /\.h$/) {
233 push @h_files, $file;
239 if($#c_files == -1 && $#h_files == -1 && $#paths == -1 && -d ".git")
241 @$c_files = sort split /\0/, `git ls-files -z \\*.c`;
242 @$h_files = sort split /\0/, `git ls-files -z \\*.h`;
246 if($#c_files == -1 && $#h_files == -1 && $#paths == -1)
251 if($#paths != -1 || $#c_files != -1) {
252 my $c_command = "find " . join(" ", @paths, @c_files) . " -name \\*.c";
254 @$c_files = sort(map {
256 if(defined($found{$_})) {
262 } split(/\n/, `$c_command`));
265 if($#paths != -1 || $#h_files != -1) {
266 my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
269 @$h_files = sort(map {
271 if(defined($found{$_})) {
277 } split(/\n/, `$h_command`));
282 foreach my $file (@$c_files, @$h_files) {
284 $dir =~ s%/?[^/]+$%%;
285 if(!$dir) { $dir = "."; }
289 @$directories = sort(keys(%dirs));
292 sub options_set($$) {
295 my $options_long = \%{$self->{_OPTIONS_LONG}};
296 my $options_short = \%{$self->{_OPTIONS_SHORT}};
299 for my $name (sort(keys(%$options_long))) {
300 my $option = $$options_long{$name};
303 $$option{key} = $key;
304 my $refvalue = \${$self->{$key}};
307 $$refvalue = $$option{default};
309 if($name !~ /^(?:help|debug|verbose|module)$/) {
310 if(ref($$refvalue) ne "HASH") {
313 $$refvalue = { active => 1, filter => 0, hash => {} };
317 if($name !~ /^(?:help|debug|verbose|module)$/) {
318 if(ref($$refvalue) ne "HASH") {
321 $$refvalue = { active => 0, filter => 0, hash => {} };
331 my $options_long = \%{$self->{_OPTIONS_LONG}};
332 my $options_short = \%{$self->{_OPTIONS_SHORT}};
335 for my $name (sort(keys(%$options_long))) {
336 if(length($name) > $maxname) {
337 $maxname = length($name);
341 for my $name (sort(keys(%$options_long))) {
342 my $option = $$options_long{$name};
343 my $description = $$option{description};
344 my $parser = $$option{parser};
345 my $current = ${$self->{$$option{key}}};
347 my $value = $current;
350 if(!defined $parser) {
352 $command = "--no-$name";
354 $command = "--$name";
357 if(ref($value) eq "HASH" && $value->{active}) {
358 $command = "--[no-]$name\[=<value>]";
360 $command = "--$name\[=<value>]";
364 $output->write($command);
365 $output->write(" " x (($maxname - length($name) + 17) - (length($command) - length($name) + 1)));
366 if(!defined $parser) {
368 $output->write("Disable ");
370 $output->write("Enable ");
373 if(ref($value) eq "HASH")
375 if ($value->{active}) {
376 $output->write("(Disable) ");
378 $output->write("Enable ");
382 $output->write("$description\n");
389 my $name = $_options::AUTOLOAD;
390 $name =~ s/^.*::(.[^:]*)$/\U$1/;
392 my $refvalue = $self->{$name};
393 if(!defined($refvalue)) {
394 die "<internal>: options.pm: member $name does not exist\n";
397 if(ref($$refvalue) ne "HASH") {
400 return $$refvalue->{active};
407 my $arguments = \@{$self->{_ARGUMENTS}};
415 my $c_files = \@{$self->{_C_FILES}};
417 if(!defined(@$c_files)) {
427 my $h_files = \@{$self->{_H_FILES}};
429 if(!defined(@$h_files)) {
439 my $directories = \@{$self->{_DIRECTORIES}};
441 if(!defined(@$directories)) {
445 return @$directories;