dllhost: Add stub implementation.
[wine.git] / tools / winapi / options.pm
blob2254852d55bcb24e6aa933c18a750156f286038c
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
19 package options;
21 use strict;
22 use warnings 'all';
24 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
25 require Exporter;
27 @ISA = qw(Exporter);
28 @EXPORT = qw();
29 @EXPORT_OK = qw($options parse_comma_list parse_value);
31 use vars qw($options);
33 use output qw($output);
35 sub parse_comma_list($$) {
36 my $prefix = shift;
37 my $value = shift;
39 if(defined($prefix) && $prefix eq "no") {
40 return { active => 0, filter => 0, hash => {} };
41 } elsif(defined($value)) {
42 my %names;
43 for my $name (split /,/, $value) {
44 $names{$name} = 1;
46 return { active => 1, filter => 1, hash => \%names };
47 } else {
48 return { active => 1, filter => 0, hash => {} };
52 sub parse_value($$) {
53 my $prefix = shift;
54 my $value = shift;
56 return $value;
59 package _options;
61 use strict;
62 use warnings 'all';
64 use output qw($output);
66 sub options_set($$);
68 sub new($$$$) {
69 my $proto = shift;
70 my $class = ref($proto) || $proto;
71 my $self = {};
72 bless ($self, $class);
74 my $options_long = \%{$self->{_OPTIONS_LONG}};
75 my $options_short = \%{$self->{_OPTIONS_SHORT}};
76 my $options_usage = \${$self->{_OPTIONS_USAGE}};
78 my $refoptions_long = shift;
79 my $refoptions_short = shift;
80 $$options_usage = shift;
82 %$options_long = %{$refoptions_long};
83 %$options_short = %{$refoptions_short};
85 $self->options_set("default");
87 my $arguments = \@{$self->{_ARGUMENTS}};
88 @$arguments = ();
90 my $end_of_options = 0;
91 while(defined($_ = shift @ARGV)) {
92 if(/^--$/) {
93 $end_of_options = 1;
94 next;
95 } elsif($end_of_options) {
96 # Nothing
97 } elsif(/^--(all|none)$/) {
98 $self->options_set("$1");
99 next;
100 } elsif(/^-([^=]*)(=(.*))?$/) {
101 my $name;
102 my $value;
103 if(defined($2)) {
104 $name = $1;
105 $value = $3;
106 } else {
107 $name = $1;
110 if($name =~ /^([^-].*)$/) {
111 $name = $$options_short{$1};
112 } else {
113 $name =~ s/^-(.*)$/$1/;
116 my $prefix;
117 if(defined($name) && $name =~ /^no-(.*)$/) {
118 $name = $1;
119 $prefix = "no";
120 if(defined($value)) {
121 $output->write("options with prefix 'no' can't take parameters\n");
123 return undef;
127 my $option;
128 if(defined($name)) {
129 $option = $$options_long{$name};
132 if(defined($option)) {
133 my $key = $$option{key};
134 my $parser = $$option{parser};
135 my $refvalue = \${$self->{$key}};
136 my @parents = ();
138 if(defined($$option{parent})) {
139 if(ref($$option{parent}) eq "ARRAY") {
140 @parents = @{$$option{parent}};
141 } else {
142 @parents = $$option{parent};
146 if(defined($parser)) {
147 if(!defined($value)) {
148 $value = shift @ARGV;
150 $$refvalue = &$parser($prefix,$value);
151 } else {
152 if(defined($value)) {
153 $$refvalue = $value;
154 } elsif(!defined($prefix)) {
155 $$refvalue = 1;
156 } else {
157 $$refvalue = 0;
161 if((ref($$refvalue) eq "HASH" && $$refvalue->{active}) || $$refvalue) {
162 while($#parents >= 0) {
163 my @old_parents = @parents;
164 @parents = ();
165 foreach my $parent (@old_parents) {
166 my $parentkey = $$options_long{$parent}{key};
167 my $refparentvalue = \${$self->{$parentkey}};
169 $$refparentvalue = 1;
171 if(defined($$options_long{$parent}{parent})) {
172 if(ref($$options_long{$parent}{parent}) eq "ARRAY") {
173 push @parents, @{$$options_long{$parent}{parent}};
174 } else {
175 push @parents, $$options_long{$parent}{parent};
181 next;
185 if(!$end_of_options && /^-(.*)$/) {
186 $output->write("unknown option: $_\n");
187 $output->write($$options_usage);
188 exit 1;
189 } else {
190 push @$arguments, $_;
194 if($self->help) {
195 $output->write($$options_usage);
196 $self->show_help;
197 exit 0;
200 return $self;
203 sub DESTROY {
206 sub parse_files($) {
207 my $self = shift;
209 my $arguments = \@{$self->{_ARGUMENTS}};
210 my $directories = \@{$self->{_DIRECTORIES}};
211 my $c_files = \@{$self->{_C_FILES}};
212 my $h_files = \@{$self->{_H_FILES}};
214 my $error = 0;
215 my @files = ();
216 foreach (@$arguments) {
217 if(!-e $_) {
218 $output->write("$_: no such file or directory\n");
219 $error = 1;
220 } else {
221 push @files, $_;
224 if($error) {
225 exit 1;
228 my @paths = ();
229 my @c_files = ();
230 my @h_files = ();
231 foreach my $file (@files) {
232 if($file =~ /\.c$/) {
233 push @c_files, $file;
234 } elsif($file =~ /\.h$/) {
235 push @h_files, $file;
236 } else {
237 push @paths, $file;
241 if($#c_files == -1 && $#h_files == -1 && $#paths == -1 && -d ".git")
243 @$c_files = sort split /\0/, `git ls-files -z \\*.c`;
244 @$h_files = sort split /\0/, `git ls-files -z \\*.h`;
246 else
248 if($#c_files == -1 && $#h_files == -1 && $#paths == -1)
250 @paths = ".";
253 if($#paths != -1 || $#c_files != -1) {
254 my $c_command = "find " . join(" ", @paths, @c_files) . " -name \\*.c";
255 my %found;
256 @$c_files = sort(map {
257 s/^\.\/(.*)$/$1/;
258 if(defined($found{$_})) {
260 } else {
261 $found{$_}++;
264 } split(/\n/, `$c_command`));
267 if($#paths != -1 || $#h_files != -1) {
268 my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
269 my %found;
271 @$h_files = sort(map {
272 s/^\.\/(.*)$/$1/;
273 if(defined($found{$_})) {
275 } else {
276 $found{$_}++;
279 } split(/\n/, `$h_command`));
283 my %dirs;
284 foreach my $file (@$c_files, @$h_files) {
285 my $dir = $file;
286 $dir =~ s%/?[^/]+$%%;
287 if(!$dir) { $dir = "."; }
288 $dirs{$dir}++
291 @$directories = sort(keys(%dirs));
294 sub options_set($$) {
295 my $self = shift;
297 my $options_long = \%{$self->{_OPTIONS_LONG}};
298 my $options_short = \%{$self->{_OPTIONS_SHORT}};
300 local $_ = shift;
301 for my $name (sort(keys(%$options_long))) {
302 my $option = $$options_long{$name};
303 my $key = uc($name);
304 $key =~ tr/-/_/;
305 $$option{key} = $key;
306 my $refvalue = \${$self->{$key}};
308 if(/^default$/) {
309 $$refvalue = $$option{default};
310 } elsif(/^all$/) {
311 if($name !~ /^(?:help|debug|verbose|module)$/) {
312 if(ref($$refvalue) ne "HASH") {
313 $$refvalue = 1;
314 } else {
315 $$refvalue = { active => 1, filter => 0, hash => {} };
318 } elsif(/^none$/) {
319 if($name !~ /^(?:help|debug|verbose|module)$/) {
320 if(ref($$refvalue) ne "HASH") {
321 $$refvalue = 0;
322 } else {
323 $$refvalue = { active => 0, filter => 0, hash => {} };
330 sub show_help($) {
331 my $self = shift;
333 my $options_long = \%{$self->{_OPTIONS_LONG}};
334 my $options_short = \%{$self->{_OPTIONS_SHORT}};
336 my $maxname = 0;
337 for my $name (sort(keys(%$options_long))) {
338 if(length($name) > $maxname) {
339 $maxname = length($name);
343 for my $name (sort(keys(%$options_long))) {
344 my $option = $$options_long{$name};
345 my $description = $$option{description};
346 my $parser = $$option{parser};
347 my $current = ${$self->{$$option{key}}};
349 my $value = $current;
351 my $command;
352 if(!defined $parser) {
353 if($value) {
354 $command = "--no-$name";
355 } else {
356 $command = "--$name";
358 } else {
359 if(ref($value) eq "HASH" && $value->{active}) {
360 $command = "--[no-]$name\[=<value>]";
361 } else {
362 $command = "--$name\[=<value>]";
366 $output->write($command);
367 $output->write(" " x (($maxname - length($name) + 17) - (length($command) - length($name) + 1)));
368 if(!defined $parser) {
369 if($value) {
370 $output->write("Disable ");
371 } else {
372 $output->write("Enable ");
374 } else {
375 if(ref($value) eq "HASH")
377 if ($value->{active}) {
378 $output->write("(Disable) ");
379 } else {
380 $output->write("Enable ");
384 $output->write("$description\n");
388 sub AUTOLOAD {
389 my $self = shift;
391 my $name = $_options::AUTOLOAD;
392 $name =~ s/^.*::(.[^:]*)$/\U$1/;
394 my $refvalue = $self->{$name};
395 if(!defined($refvalue)) {
396 die "<internal>: options.pm: member $name does not exist\n";
399 if(ref($$refvalue) ne "HASH") {
400 return $$refvalue;
401 } else {
402 return $$refvalue->{active};
406 sub arguments($) {
407 my $self = shift;
409 my $arguments = \@{$self->{_ARGUMENTS}};
411 return @$arguments;
414 sub c_files($) {
415 my $self = shift;
417 my $c_files = \@{$self->{_C_FILES}};
419 if(!@$c_files) {
420 $self->parse_files;
423 return @$c_files;
426 sub h_files($) {
427 my $self = shift;
429 my $h_files = \@{$self->{_H_FILES}};
431 if(!@$h_files) {
432 $self->parse_files;
435 return @$h_files;
438 sub directories($) {
439 my $self = shift;
441 my $directories = \@{$self->{_DIRECTORIES}};
443 if(!@$directories) {
444 $self->parse_files;
447 return @$directories;