1 package winapi_options
;
5 sub parser_comma_list
{
8 if(defined($prefix) && $prefix eq "no") {
9 return { active
=> 0, filter
=> 0, hash
=> {} };
10 } elsif(defined($value)) {
12 for my $name (split /,/, $value) {
15 return { active
=> 1, filter
=> 1, hash
=> \
%names };
17 return { active
=> 1, filter
=> 0, hash
=> {} };
22 "debug" => { default => 0, description
=> "debug mode" },
23 "help" => { default => 0, description
=> "help mode" },
24 "verbose" => { default => 0, description
=> "verbose mode" },
26 "progress" => { default => 1, description
=> "show progress" },
28 "win16" => { default => 1, description
=> "Win16 checking" },
29 "win32" => { default => 1, description
=> "Win32 checking" },
31 "shared" => { default => 0, description
=> "show shared functions between Win16 and Win32" },
32 "shared-segmented" => { default => 0, description
=> "segmented shared functions between Win16 and Win32 checking" },
34 "config" => { default => 1, parent
=> "local", description
=> "check configuration include consistancy" },
35 "config-unnessary" => { default => 0, parent
=> "config", description
=> "check for unnessary #include \"config.h\"" },
37 "spec-mismatch" => { default => 0, description
=> "spec file mismatch checking" },
39 "local" => { default => 1, description
=> "local checking" },
41 default => { active
=> 1, filter
=> 0, hash
=> {} },
43 parser
=> \
&parser_comma_list
,
44 description
=> "module filter"
47 "argument" => { default => 1, parent
=> "local", description
=> "argument checking" },
48 "argument-count" => { default => 1, parent
=> "argument", description
=> "argument count checking" },
49 "argument-forbidden" => {
50 default => { active
=> 1, filter
=> 0, hash
=> {} },
52 parser
=> \
&parser_comma_list
,
53 description
=> "argument forbidden checking"
56 default => { active
=> 1, filter
=> 1, hash
=> { double
=> 1 } },
58 parser
=> \
&parser_comma_list
,
59 description
=> "argument kind checking"
61 "calling-convention" => { default => 1, parent
=> "local", description
=> "calling convention checking" },
62 "calling-convention-win16" => { default => 0, parent
=> "calling-convention", description
=> "calling convention checking (Win16)" },
63 "calling-convention-win32" => { default => 1, parent
=> "calling-convention", description
=> "calling convention checking (Win32)" },
64 "misplaced" => { default => 1, parent
=> "local", description
=> "check for misplaced functions" },
65 "statements" => { default => 0, parent
=> "local", description
=> "check for statements inconsistances" },
66 "cross-call" => { default => 0, parent
=> "statements", description
=> "check for cross calling functions" },
67 "cross-call-win32-win16" => {
68 default => 0, parent
=> "cross-call", description
=> "check for cross calls between win32 and win16"
70 "cross-call-unicode-ascii" => {
71 default => 0, parent
=> "cross-call", description
=> "check for cross calls between Unicode and ASCII"
73 "debug-messages" => { default => 0, parent
=> "statements", description
=> "check for debug messages inconsistances" },
78 description
=> "check for documentation inconsistances"
80 "documentation-pedantic" => {
82 parent
=> "documentation",
83 description
=> "be pendantic when checking for documentation inconsistances"
86 "documentation-arguments" => {
88 parent
=> "documentation",
89 description
=> "check for arguments documentation inconsistances\n"
91 "documentation-comment-indent" => {
93 parent
=> "documentation", description
=> "check for documentation comment indent inconsistances"
95 "documentation-comment-width" => {
97 parent
=> "documentation", description
=> "check for documentation comment width inconsistances"
99 "documentation-name" => {
101 parent
=> "documentation",
102 description
=> "check for documentation name inconsistances\n"
104 "documentation-ordinal" => {
106 parent
=> "documentation",
107 description
=> "check for documentation ordinal inconsistances\n"
109 "documentation-wrong" => {
111 parent
=> "documentation",
112 description
=> "check for wrong documentation\n"
115 "prototype" => {default => 0, parent
=> ["local", "headers"], description
=> "prototype checking" },
116 "global" => { default => 1, description
=> "global checking" },
117 "declared" => { default => 1, parent
=> "global", description
=> "declared checking" },
118 "implemented" => { default => 0, parent
=> "local", description
=> "implemented checking" },
119 "implemented-win32" => { default => 0, parent
=> "implemented", description
=> "implemented as win32 checking" },
120 "include" => { default => 1, parent
=> "global", description
=> "include checking" },
122 "headers" => { default => 0, description
=> "headers checking" },
123 "headers-duplicated" => { default => 0, parent
=> "headers", description
=> "duplicated function declarations checking" },
124 "headers-misplaced" => { default => 0, parent
=> "headers", description
=> "misplaced function declarations checking" },
125 "headers-needed" => { default => 1, parent
=> "headers", description
=> "headers needed checking" },
126 "headers-unused" => { default => 0, parent
=> "headers", description
=> "headers unused checking" },
129 my %short_options = (
137 my $class = ref($proto) || $proto;
139 bless ($self, $class);
141 my $output = \
${$self->{OUTPUT
}};
144 my $refarguments = shift;
145 my $wine_dir = shift;
147 $self->options_set("default");
149 my $c_files = \@
{$self->{C_FILES
}};
150 my $h_files = \@
{$self->{H_FILES
}};
151 my $module = \
${$self->{MODULE
}};
152 my $global = \
${$self->{GLOBAL
}};
153 my $headers = \
${$self->{HEADERS
}};
157 if($wine_dir eq ".") {
163 while(defined($_ = shift @
$refarguments)) {
164 if(/^--(all|none)$/) {
165 $self->options_set("$1");
167 } elsif(/^-([^=]*)(=(.*))?$/) {
177 if($name =~ /^([^-].*)$/) {
178 $name = $short_options{$1};
180 $name =~ s/^-(.*)$/$1/;
184 if(defined($name) && $name =~ /^no-(.*)$/) {
187 if(defined($value)) {
188 $$output->write("options with prefix 'no' can't take parameters\n");
196 $option = $options{$name};
199 if(defined($option)) {
200 my $key = $$option{key
};
201 my $parser = $$option{parser
};
202 my $refvalue = \
${$self->{$key}};
205 if(defined($$option{parent
})) {
206 if(ref($$option{parent
}) eq "ARRAY") {
207 @parents = @
{$$option{parent
}};
209 @parents = $$option{parent
};
213 if(defined($parser)) {
214 $$refvalue = &$parser($prefix,$value);
216 if(defined($value)) {
218 } elsif(!defined($prefix)) {
225 if((ref($$refvalue) eq "HASH" && $$refvalue->{active
}) || $$refvalue) {
226 while($#parents >= 0) {
227 my @old_parents = @parents;
229 foreach my $parent (@old_parents) {
230 my $parentkey = $options{$parent}{key
};
231 my $refparentvalue = \
${$self->{$parentkey}};
233 $$refparentvalue = 1;
235 if(defined($options{$parent}{parent
})) {
236 if(ref($options{$parent}{parent
}) eq "ARRAY") {
237 push @parents, @
{$options{$parent}{parent
}};
239 push @parents, $options{$parent}{parent
};
249 if(/^--module-dlls$/) {
250 my @dirs = `cd dlls && find . -type d ! -name CVS`;
252 for my $dir (@dirs) {
254 $dir =~ s/^\.\/(.*)$/$1/;
258 $$module = { active
=> 1, filter
=> 1, hash
=> \
%names };
261 $$output->write("unknown option: $_\n");
266 $$output->write("$_: no such file or directory\n");
282 foreach my $file (@files) {
283 if($file =~ /\.c$/) {
284 push @c_files, $file;
285 } elsif($file =~ /\.h$/) {
286 push @h_files, $file;
296 if($#c_files == -1 && $#h_files == -1 &&
297 ($#paths == -1 || ($#paths == 0 && $paths[0] eq $wine_dir)))
304 if($#paths != -1 || $#c_files != -1) {
305 my $c_command = "find " . join(" ", @paths, @c_files) . " -name \\*.c";
307 @
$c_files = sort(map {
309 if(defined($found{$_}) || /glue\.c|spec\.c$/) {
315 } split(/\n/, `$c_command`));
318 if($#paths != -1 || $#h_files != -1) {
319 my $h_command = "find " . join(" ", @paths, @h_files) . " -name \\*.h";
322 @
$h_files = sort(map {
324 if(defined($found{$_})) {
330 } split(/\n/, `$h_command`));
342 for my $name (sort(keys(%options))) {
343 my $option = $options{$name};
346 $$option{key
} = $key;
347 my $refvalue = \
${$self->{$key}};
350 $$refvalue = $$option{default};
352 if($name !~ /^help|debug|verbose|module$/) {
353 if(ref($$refvalue) ne "HASH") {
356 $$refvalue = { active
=> 1, filter
=> 0, hash
=> {} };
360 if($name !~ /^help|debug|verbose|module$/) {
361 if(ref($$refvalue) ne "HASH") {
364 $$refvalue = { active
=> 0, filter
=> 0, hash
=> {} };
375 for my $name (sort(keys(%options))) {
376 if(length($name) > $maxname) {
377 $maxname = length($name);
381 print "usage: winapi-check [--help] [<files>]\n";
383 for my $name (sort(keys(%options))) {
384 my $option = $options{$name};
385 my $description = $$option{description
};
386 my $default = $$option{default};
387 my $current = ${$self->{$$option{key
}}};
389 my $value = $current;
392 if(ref($value) ne "HASH") {
394 $output = "--no-$name";
399 if($value->{active
}) {
400 $output = "--[no-]$name\[=<value>]";
402 $output = "--$name\[=<value>]";
407 for (0..(($maxname - length($name) + 17) - (length($output) - length($name) + 1))) { print " "; }
408 if(ref($value) ne "HASH") {
415 if($value->{active
}) {
421 if($default == $current) {
422 print "$description (default)\n";
424 print "$description\n";
432 my $name = $winapi_options::AUTOLOAD
;
433 $name =~ s/^.*::(.[^:]*)$/\U$1/;
435 my $refvalue = $self->{$name};
436 if(!defined($refvalue)) {
437 die "<internal>: winapi_options.pm: member $name does not exists\n";
440 if(ref($$refvalue) ne "HASH") {
443 return $$refvalue->{active
};
447 sub c_files
{ my $self = shift; return @
{$self->{C_FILES
}}; }
449 sub h_files
{ my $self = shift; return @
{$self->{H_FILES
}}; }
453 my $refvalue = $self->{MODULE
};
458 return $$refvalue->{active
} && (!$$refvalue->{filter
} || $$refvalue->{hash
}->{$name});
464 sub report_argument_forbidden
{
466 my $refargument_forbidden = $self->{ARGUMENT_FORBIDDEN
};
470 return $$refargument_forbidden->{active
} && (!$$refargument_forbidden->{filter
} || $$refargument_forbidden->{hash
}->{$type});
473 sub report_argument_kind
{
475 my $refargument_kind = $self->{ARGUMENT_KIND
};
479 return $$refargument_kind->{active
} && (!$$refargument_kind->{filter
} || $$refargument_kind->{hash
}->{$kind});