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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 package winapi_options;
23 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
27 @EXPORT = qw(&parse_comma_list);
28 @EXPORT_OK = qw($options);
30 use vars qw($options);
32 use config qw($current_dir $wine_dir);
33 use output qw($output);
35 sub parser_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 => {} };
52 "debug" => { default => 0, description => "debug mode" },
53 "help" => { default => 0, description => "help mode" },
54 "verbose" => { default => 0, description => "verbose mode" },
56 "progress" => { default => 1, description => "show progress" },
58 "win16" => { default => 1, description => "Win16 checking" },
59 "win32" => { default => 1, description => "Win32 checking" },
61 "shared" => { default => 0, description => "show shared functions between Win16 and Win32" },
62 "shared-segmented" => { default => 0, description => "segmented shared functions between Win16 and Win32 checking" },
64 "config" => { default => 1, parent => "local", description => "check configuration include consistancy" },
65 "config-unnessary" => { default => 0, parent => "config", description => "check for unnessary #include \"config.h\"" },
67 "spec-mismatch" => { default => 0, description => "spec file mismatch checking" },
69 "local" => { default => 1, description => "local checking" },
71 default => { active => 1, filter => 0, hash => {} },
73 parser => \&parser_comma_list,
74 description => "module filter"
77 "argument" => { default => 1, parent => "local", description => "argument checking" },
78 "argument-count" => { default => 1, parent => "argument", description => "argument count checking" },
79 "argument-forbidden" => {
80 default => { active => 1, filter => 0, hash => {} },
82 parser => \&parser_comma_list,
83 description => "argument forbidden checking"
86 default => { active => 1, filter => 1, hash => { double => 1 } },
88 parser => \&parser_comma_list,
89 description => "argument kind checking"
91 "calling-convention" => { default => 1, parent => "local", description => "calling convention checking" },
92 "calling-convention-win16" => { default => 0, parent => "calling-convention", description => "calling convention checking (Win16)" },
93 "calling-convention-win32" => { default => 1, parent => "calling-convention", description => "calling convention checking (Win32)" },
94 "misplaced" => { default => 1, parent => "local", description => "check for misplaced functions" },
95 "statements" => { default => 0, parent => "local", description => "check for statements inconsistances" },
96 "cross-call" => { default => 0, parent => "statements", description => "check for cross calling functions" },
97 "cross-call-win32-win16" => {
98 default => 0, parent => "cross-call", description => "check for cross calls between win32 and win16"
100 "cross-call-unicode-ascii" => {
101 default => 0, parent => "cross-call", description => "check for cross calls between Unicode and ASCII"
103 "debug-messages" => { default => 0, parent => "statements", description => "check for debug messages inconsistances" },
108 description => "check for documentation inconsistances"
110 "documentation-pedantic" => {
112 parent => "documentation",
113 description => "be pendantic when checking for documentation inconsistances"
116 "documentation-arguments" => {
118 parent => "documentation",
119 description => "check for arguments documentation inconsistances\n"
121 "documentation-comment-indent" => {
123 parent => "documentation", description => "check for documentation comment indent inconsistances"
125 "documentation-comment-width" => {
127 parent => "documentation", description => "check for documentation comment width inconsistances"
129 "documentation-name" => {
131 parent => "documentation",
132 description => "check for documentation name inconsistances\n"
134 "documentation-ordinal" => {
136 parent => "documentation",
137 description => "check for documentation ordinal inconsistances\n"
139 "documentation-wrong" => {
141 parent => "documentation",
142 description => "check for wrong documentation\n"
145 "prototype" => {default => 0, parent => ["local", "headers"], description => "prototype checking" },
146 "global" => { default => 1, description => "global checking" },
147 "declared" => { default => 1, parent => "global", description => "declared checking" },
148 "implemented" => { default => 0, parent => "local", description => "implemented checking" },
149 "implemented-win32" => { default => 0, parent => "implemented", description => "implemented as win32 checking" },
150 "include" => { default => 1, parent => "global", description => "include checking" },
152 "headers" => { default => 0, description => "headers checking" },
153 "headers-duplicated" => { default => 0, parent => "headers", description => "duplicated function declarations checking" },
154 "headers-misplaced" => { default => 0, parent => "headers", description => "misplaced function declarations checking" },
155 "headers-needed" => { default => 1, parent => "headers", description => "headers needed checking" },
156 "headers-unused" => { default => 0, parent => "headers", description => "headers unused checking" },
159 my %short_options = (
167 my $class = ref($proto) || $proto;
169 bless ($self, $class);
171 $self->options_set("default");
173 my $c_files = \@{$self->{C_FILES}};
174 my $h_files = \@{$self->{H_FILES}};
175 my $module = \${$self->{MODULE}};
176 my $global = \${$self->{GLOBAL}};
177 my $headers = \${$self->{HEADERS}};
181 if($wine_dir eq ".") {
187 while(defined($_ = shift @ARGV)) {
188 if(/^--(all|none)$/) {
189 $self->options_set("$1");
191 } elsif(/^-([^=]*)(=(.*))?$/) {
201 if($name =~ /^([^-].*)$/) {
202 $name = $short_options{$1};
204 $name =~ s/^-(.*)$/$1/;
208 if(defined($name) && $name =~ /^no-(.*)$/) {
211 if(defined($value)) {
212 $output->write("options with prefix 'no' can't take parameters\n");
220 $option = $options{$name};
223 if(defined($option)) {
224 my $key = $$option{key};
225 my $parser = $$option{parser};
226 my $refvalue = \${$self->{$key}};
229 if(defined($$option{parent})) {
230 if(ref($$option{parent}) eq "ARRAY") {
231 @parents = @{$$option{parent}};
233 @parents = $$option{parent};
237 if(defined($parser)) {
238 $$refvalue = &$parser($prefix,$value);
240 if(defined($value)) {
242 } elsif(!defined($prefix)) {
249 if((ref($$refvalue) eq "HASH" && $$refvalue->{active}) || $$refvalue) {
250 while($#parents >= 0) {
251 my @old_parents = @parents;
253 foreach my $parent (@old_parents) {
254 my $parentkey = $options{$parent}{key};
255 my $refparentvalue = \${$self->{$parentkey}};
257 $$refparentvalue = 1;
259 if(defined($options{$parent}{parent})) {
260 if(ref($options{$parent}{parent}) eq "ARRAY") {
261 push @parents, @{$options{$parent}{parent}};
263 push @parents, $options{$parent}{parent};
273 if(/^--module-dlls$/) {
274 my @dirs = `cd dlls && find . -type d ! -name CVS`;
276 for my $dir (@dirs) {
278 $dir =~ s/^\.\/(.*)$/$1/;
282 $$module = { active => 1, filter => 1, hash => \%names };
285 $output->write("unknown option: $_\n");
290 $output->write("$_: no such file or directory\n");
306 foreach my $file (@files) {
307 if($file =~ /\.c$/) {
308 push @c_files, $file;
309 } elsif($file =~ /\.h$/) {
310 push @h_files, $file;
320 if($#c_files == -1 && $#h_files == -1 &&
321 ($#paths == -1 || ($#paths == 0 && $paths[0] eq $wine_dir)))
328 if($#paths != -1 || $#c_files != -1) {
329 my $c_command = "find " . join(" ", @paths, @c_files) . " -name \\*.c";
331 @$c_files = sort(map {
333 if(defined($found{$_}) || /glue\.c|spec\.c$/) {
339 } split(/\n/, `$c_command`));
342 if($#paths != -1 || $#h_files != -1) {
343 my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
346 @$h_files = sort(map {
348 if(defined($found{$_})) {
354 } split(/\n/, `$h_command`));
369 for my $name (sort(keys(%options))) {
370 my $option = $options{$name};
373 $$option{key} = $key;
374 my $refvalue = \${$self->{$key}};
377 $$refvalue = $$option{default};
379 if($name !~ /^help|debug|verbose|module$/) {
380 if(ref($$refvalue) ne "HASH") {
383 $$refvalue = { active => 1, filter => 0, hash => {} };
387 if($name !~ /^help|debug|verbose|module$/) {
388 if(ref($$refvalue) ne "HASH") {
391 $$refvalue = { active => 0, filter => 0, hash => {} };
402 for my $name (sort(keys(%options))) {
403 if(length($name) > $maxname) {
404 $maxname = length($name);
408 print "usage: winapi-check [--help] [<files>]\n";
410 for my $name (sort(keys(%options))) {
411 my $option = $options{$name};
412 my $description = $$option{description};
413 my $default = $$option{default};
414 my $current = ${$self->{$$option{key}}};
416 my $value = $current;
419 if(ref($value) ne "HASH") {
421 $output = "--no-$name";
426 if($value->{active}) {
427 $output = "--[no-]$name\[=<value>]";
429 $output = "--$name\[=<value>]";
434 for (0..(($maxname - length($name) + 17) - (length($output) - length($name) + 1))) { print " "; }
435 if(ref($value) ne "HASH") {
442 if($value->{active}) {
448 if($default == $current) {
449 print "$description (default)\n";
451 print "$description\n";
459 my $name = $winapi_options::AUTOLOAD;
460 $name =~ s/^.*::(.[^:]*)$/\U$1/;
462 my $refvalue = $self->{$name};
463 if(!defined($refvalue)) {
464 die "<internal>: winapi_options.pm: member $name does not exists\n";
467 if(ref($$refvalue) ne "HASH") {
470 return $$refvalue->{active};
474 sub c_files { my $self = shift; return @{$self->{C_FILES}}; }
476 sub h_files { my $self = shift; return @{$self->{H_FILES}}; }
480 my $refvalue = $self->{MODULE};
485 return $$refvalue->{active} && (!$$refvalue->{filter} || $$refvalue->{hash}->{$name});
491 sub report_argument_forbidden {
493 my $refargument_forbidden = $self->{ARGUMENT_FORBIDDEN};
497 return $$refargument_forbidden->{active} && (!$$refargument_forbidden->{filter} || $$refargument_forbidden->{hash}->{$type});
500 sub report_argument_kind {
502 my $refargument_kind = $self->{ARGUMENT_KIND};
506 return $$refargument_kind->{active} && (!$$refargument_kind->{filter} || $$refargument_kind->{hash}->{$kind});