Use a better icon. Comment out the binary resource.
[wine.git] / tools / winapi_check / modules.pm
blobdaa91ae3807469fd479892f72ff1ae0515e06c07
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 modules;
21 use strict;
23 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
24 require Exporter;
26 @ISA = qw(Exporter);
27 @EXPORT = qw();
28 @EXPORT_OK = qw($modules);
30 use vars qw($modules);
32 use config qw(
33 &file_type &files_skip
34 &file_directory
35 &get_c_files &get_spec_files
36 $current_dir $wine_dir
37 $winapi_check_dir
39 use options qw($options);
40 use output qw($output);
42 sub import {
43 $Exporter::ExportLevel++;
44 &Exporter::import(@_);
45 $Exporter::ExportLevel--;
47 if (defined($modules)) {
48 return;
51 $modules = 'modules'->new;
54 sub get_spec_file_type {
55 my $file = shift;
57 my $module;
58 my $type;
60 $module = $file;
61 $module =~ s%^.*?([^/]+)\.spec$%$1%;
63 open(IN, "< $file") || die "$file: $!\n";
64 local $/ = "\n";
65 my $header = 1;
66 my $lookahead = 0;
67 while($lookahead || defined($_ = <IN>)) {
68 $lookahead = 0;
69 s/^\s*(.*?)\s*$/$1/;
70 s/^(.*?)\s*#.*$/$1/;
71 /^$/ && next;
73 if($header) {
74 if(/^\d+|@/) { $header = 0; $lookahead = 1; }
75 next;
78 if(/^(\d+|@)\s+pascal(?:16)?/) {
79 $type = "win16";
80 last;
83 close(IN);
85 if(!defined($type)) {
86 $type = "win32";
89 return ($type, $module);
92 sub new {
93 my $proto = shift;
94 my $class = ref($proto) || $proto;
95 my $self = {};
96 bless ($self, $class);
98 my $spec_file_found = $self->read_module_file();
99 $self->read_spec_files($spec_file_found);
101 return $self;
104 sub read_module_file {
105 my $self = shift;
107 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
108 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
110 my $module_file = "$winapi_check_dir/modules.dat";
112 $output->progress("modules.dat");
114 my $spec_file_found = {};
115 my $allowed_dir;
116 my $spec_file;
118 open(IN, "< $module_file");
119 local $/ = "\n";
120 while(<IN>) {
121 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begining and end of line
122 s/^(.*?)\s*#.*$/$1/; # remove comments
123 /^$/ && next; # skip empty lines
125 if(/^%\s+(.*?)$/) {
126 $spec_file = $1;
128 if(!-f "$wine_dir/$spec_file") {
129 $output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
132 $$spec_file_found{$spec_file}++;
133 $$spec_file2dir{$spec_file} = {};
134 next;
135 } else {
136 $allowed_dir = $1;
137 $$spec_file2dir{$spec_file}{$allowed_dir}++;
139 $$dir2spec_file{$allowed_dir}{$spec_file}++;
141 if(!-d "$wine_dir/$allowed_dir") {
142 $output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
145 close(IN);
147 return $spec_file_found;
150 sub read_spec_files {
151 my $self = shift;
153 my $spec_file_found = shift;
155 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
156 my $spec_files16 = \@{$self->{SPEC_FILES16}};
157 my $spec_files32 = \@{$self->{SPEC_FILES32}};
158 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
159 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
161 my @spec_files;
162 if($wine_dir eq ".") {
163 @spec_files = get_spec_files("winelib");
164 } else {
165 my %spec_files = ();
166 foreach my $dir ($options->directories) {
167 $dir = "$current_dir/$dir";
168 $dir =~ s%/\.$%%;
169 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
170 $spec_files{$spec_file}++;
173 @spec_files = sort(keys(%spec_files));
176 @$spec_files16 = ();
177 @$spec_files32 = ();
178 foreach my $spec_file (@spec_files) {
179 (my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");
181 $$spec_file2module{$spec_file} = $module;
182 $$module2spec_file{$module} = $spec_file;
184 if($type eq "win16") {
185 push @$spec_files16, $spec_file;
186 } elsif($type eq "win32") {
187 push @$spec_files32, $spec_file;
188 } else {
189 $output->write("$spec_file: unknown type '$type'\n");
193 foreach my $spec_file (@spec_files) {
194 if(!$$spec_file_found{$spec_file} && $spec_file !~ m%tests/[^/]+$%) {
195 $output->write("modules.dat: $spec_file: exists but is not specified\n");
200 sub all_modules {
201 my $self = shift;
203 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
205 return sort(keys(%$module2spec_file));
208 sub complete_modules {
209 my $self = shift;
211 my $c_files = shift;
213 my %dirs;
215 foreach my $file (@$c_files) {
216 my $dir = file_directory("$current_dir/$file");
217 $dirs{$dir}++;
220 my @c_files = get_c_files("winelib");
221 @c_files = files_skip(@c_files);
222 foreach my $file (@c_files) {
223 my $dir = file_directory($file);
224 if(exists($dirs{$dir})) {
225 $dirs{$dir}--;
229 my @complete_modules = ();
230 foreach my $module ($self->all_modules) {
231 my $index = -1;
232 my @dirs = $self->allowed_dirs_for_module($module);
233 foreach my $dir (@dirs) {
234 if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
235 $index++;
238 if($index == $#dirs) {
239 push @complete_modules, $module;
243 return @complete_modules;
246 sub is_allowed_module {
247 my $self = shift;
249 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
251 my $module = shift;
253 return defined($$module2spec_file{$module});
256 sub is_allowed_module_in_file {
257 my $self = shift;
259 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
260 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
262 my $module = shift;
263 my $file = shift;
264 $file =~ s/^\.\///;
266 my $dir = $file;
267 $dir =~ s/\/[^\/]*$//;
269 if($dir =~ m%^include%) {
270 return 1;
273 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
274 if($$spec_file2module{$spec_file} eq $module) {
275 return 1;
279 return 0;
282 sub allowed_modules_in_file {
283 my $self = shift;
285 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
286 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
288 my $file = shift;
289 $file =~ s/^\.\///;
291 my $dir = $file;
292 $dir =~ s/\/[^\/]*$//;
294 my %allowed_modules = ();
295 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
296 my $module = $$spec_file2module{$spec_file};
297 $allowed_modules{$module}++;
300 my $module = join(" & ", sort(keys(%allowed_modules)));
302 return $module;
305 sub allowed_dirs_for_module {
306 my $self = shift;
308 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
309 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
311 my $module = shift;
313 my $spec_file = $$module2spec_file{$module};
315 return sort(keys(%{$$spec_file2dir{$spec_file}}));
318 sub allowed_spec_files16 {
319 my $self = shift;
321 my $spec_files16 = \@{$self->{SPEC_FILES16}};
323 return @$spec_files16;
326 sub allowed_spec_files32 {
327 my $self = shift;
329 my $spec_files32 = \@{$self->{SPEC_FILES32}};
331 return @$spec_files32;
334 sub found_module_in_dir {
335 my $self = shift;
337 my $module = shift;
338 my $dir = shift;
340 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
342 $dir = "$current_dir/$dir";
343 $dir =~ s%/\.$%%;
345 $$used_module_dirs{$module}{$dir}++;
348 sub global_report {
349 my $self = shift;
351 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
352 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
353 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
355 my @messages;
356 foreach my $dir ($options->directories) {
357 $dir = "$current_dir/$dir";
358 $dir =~ s%/\.$%%;
359 foreach my $module ($self->all_modules) {
360 if(!$$used_module_dirs{$module}{$dir}) {
361 my $spec_file = $$module2spec_file{$module};
362 push @messages, "modules.dat: $spec_file: directory ($dir) is not used\n";
367 foreach my $message (sort(@messages)) {
368 $output->write($message);