blob: 07fc8245de40ab7489fe836a9ffeaad46b8ebe53 [file] [log] [blame]
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00001#
2# Copyright 1999, 2000, 2001 Patrik Stridvall
3#
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.
8#
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.
13#
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
17#
18
Patrik Stridvall1932d402000-04-15 20:39:55 +000019package modules;
20
21use strict;
22
Patrik Stridvallb59a9c72001-07-12 22:22:05 +000023use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
24require Exporter;
25
26@ISA = qw(Exporter);
27@EXPORT = qw();
28@EXPORT_OK = qw($modules);
29
30use vars qw($modules);
31
Patrik Stridvall67f0a702001-07-26 21:42:12 +000032use config qw(
Francois Gouget493d60f2004-10-07 18:53:56 +000033 file_type files_skip
34 file_directory
35 get_c_files get_spec_files
Patrik Stridvall67f0a702001-07-26 21:42:12 +000036 $current_dir $wine_dir
Patrik Stridvall67f0a702001-07-26 21:42:12 +000037);
38use options qw($options);
39use output qw($output);
40
Francois Gouget493d60f2004-10-07 18:53:56 +000041sub import(@) {
Patrik Stridvalla40a4f72002-10-01 18:10:54 +000042 $Exporter::ExportLevel++;
Francois Gouget493d60f2004-10-07 18:53:56 +000043 Exporter::import(@_);
Patrik Stridvalla40a4f72002-10-01 18:10:54 +000044 $Exporter::ExportLevel--;
45
Patrik Stridvallf2c2eaf2002-11-27 20:11:10 +000046 if (defined($modules)) {
47 return;
48 }
49
Patrik Stridvalla40a4f72002-10-01 18:10:54 +000050 $modules = 'modules'->new;
51}
Patrik Stridvall67f0a702001-07-26 21:42:12 +000052
Francois Gouget493d60f2004-10-07 18:53:56 +000053sub get_spec_file_type($) {
Patrik Stridvallcec294e2001-07-30 18:49:10 +000054 my $file = shift;
55
56 my $module;
57 my $type;
58
Patrik Stridvall5379c792002-07-23 01:59:09 +000059 $module = $file;
60 $module =~ s%^.*?([^/]+)\.spec$%$1%;
61
Patrik Stridvallcec294e2001-07-30 18:49:10 +000062 open(IN, "< $file") || die "$file: $!\n";
63 local $/ = "\n";
Patrik Stridvall0704650f2002-07-19 00:31:05 +000064 my $header = 1;
65 my $lookahead = 0;
66 while($lookahead || defined($_ = <IN>)) {
67 $lookahead = 0;
Patrik Stridvallcec294e2001-07-30 18:49:10 +000068 s/^\s*(.*?)\s*$/$1/;
69 s/^(.*?)\s*#.*$/$1/;
70 /^$/ && next;
71
Patrik Stridvall0704650f2002-07-19 00:31:05 +000072 if($header) {
Francois Gougetb4df2412004-10-22 19:55:42 +000073 if(/^(?:\d+|@)/) { $header = 0; $lookahead = 1; }
Patrik Stridvall0704650f2002-07-19 00:31:05 +000074 next;
75 }
Patrik Stridvallcec294e2001-07-30 18:49:10 +000076
Patrik Stridvall0704650f2002-07-19 00:31:05 +000077 if(/^(\d+|@)\s+pascal(?:16)?/) {
78 $type = "win16";
79 last;
80 }
Patrik Stridvallcec294e2001-07-30 18:49:10 +000081 }
82 close(IN);
83
Patrik Stridvallcec294e2001-07-30 18:49:10 +000084 if(!defined($type)) {
Patrik Stridvall0704650f2002-07-19 00:31:05 +000085 $type = "win32";
Patrik Stridvallcec294e2001-07-30 18:49:10 +000086 }
87
88 return ($type, $module);
89}
90
Francois Gouget493d60f2004-10-07 18:53:56 +000091sub find_spec_files($) {
Patrik Stridvalla40a4f72002-10-01 18:10:54 +000092 my $self = shift;
93
Patrik Stridvallbda50742001-07-14 00:48:41 +000094 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
95 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
Patrik Stridvall1932d402000-04-15 20:39:55 +000096
Hans Leidekkerb2fa4202004-01-18 22:09:39 +000097 $output->progress("modules");
Patrik Stridvall1932d402000-04-15 20:39:55 +000098
Patrik Stridvalla40a4f72002-10-01 18:10:54 +000099 my $spec_file_found = {};
Patrik Stridvall1932d402000-04-15 20:39:55 +0000100 my $allowed_dir;
101 my $spec_file;
102
Hans Leidekkerb2fa4202004-01-18 22:09:39 +0000103 my @spec_files = <{dlls/*/*.spec,dlls/*/*/*.spec}>;
Patrik Stridvall1932d402000-04-15 20:39:55 +0000104
Hans Leidekkerb2fa4202004-01-18 22:09:39 +0000105 foreach $spec_file (@spec_files) {
106 $spec_file =~ /(.*)\/.*\.spec/;
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000107
Hans Leidekkerb2fa4202004-01-18 22:09:39 +0000108 $allowed_dir = $1;
Patrik Stridvall0d974812000-05-23 23:37:51 +0000109
Hans Leidekkerb2fa4202004-01-18 22:09:39 +0000110 $$spec_file_found{$spec_file}++;
111 $$spec_file2dir{$spec_file}{$allowed_dir}++;
112 $$dir2spec_file{$allowed_dir}{$spec_file}++;
Patrik Stridvall1932d402000-04-15 20:39:55 +0000113 }
Patrik Stridvall1932d402000-04-15 20:39:55 +0000114
Patrik Stridvalla40a4f72002-10-01 18:10:54 +0000115 return $spec_file_found;
116}
117
Francois Gouget493d60f2004-10-07 18:53:56 +0000118sub read_spec_files($$) {
Patrik Stridvalla40a4f72002-10-01 18:10:54 +0000119 my $self = shift;
Francois Gouget493d60f2004-10-07 18:53:56 +0000120
Patrik Stridvalla40a4f72002-10-01 18:10:54 +0000121 my $spec_file_found = shift;
122
123 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
124 my $spec_files16 = \@{$self->{SPEC_FILES16}};
125 my $spec_files32 = \@{$self->{SPEC_FILES32}};
126 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
127 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
128
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000129 my @spec_files;
130 if($wine_dir eq ".") {
131 @spec_files = get_spec_files("winelib");
132 } else {
133 my %spec_files = ();
134 foreach my $dir ($options->directories) {
135 $dir = "$current_dir/$dir";
136 $dir =~ s%/\.$%%;
137 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
138 $spec_files{$spec_file}++;
139 }
140 }
141 @spec_files = sort(keys(%spec_files));
142 }
143
144 @$spec_files16 = ();
145 @$spec_files32 = ();
146 foreach my $spec_file (@spec_files) {
147 (my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");
148
149 $$spec_file2module{$spec_file} = $module;
150 $$module2spec_file{$module} = $spec_file;
151
152 if($type eq "win16") {
153 push @$spec_files16, $spec_file;
154 } elsif($type eq "win32") {
155 push @$spec_files32, $spec_file;
156 } else {
157 $output->write("$spec_file: unknown type '$type'\n");
158 }
159 }
160
161 foreach my $spec_file (@spec_files) {
Patrik Stridvalla40a4f72002-10-01 18:10:54 +0000162 if(!$$spec_file_found{$spec_file} && $spec_file !~ m%tests/[^/]+$%) {
Hans Leidekkerb2fa4202004-01-18 22:09:39 +0000163 $output->write("modules: $spec_file: exists but is not specified\n");
Patrik Stridvallaceeaa92000-05-07 18:28:18 +0000164 }
165 }
Patrik Stridvall1932d402000-04-15 20:39:55 +0000166}
167
Francois Gouget493d60f2004-10-07 18:53:56 +0000168sub new($) {
169 my $proto = shift;
170 my $class = ref($proto) || $proto;
171 my $self = {};
172 bless ($self, $class);
173
174 my $spec_file_found = $self->find_spec_files();
175 $self->read_spec_files($spec_file_found);
176
177 return $self;
178}
179
180sub all_modules($) {
Patrik Stridvallbda50742001-07-14 00:48:41 +0000181 my $self = shift;
182
183 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
184
185 return sort(keys(%$module2spec_file));
186}
187
Francois Gouget493d60f2004-10-07 18:53:56 +0000188sub is_allowed_module($$) {
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000189 my $self = shift;
190
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000191 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000192
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000193 my $module = shift;
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000194
195 return defined($$module2spec_file{$module});
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000196}
197
Francois Gouget493d60f2004-10-07 18:53:56 +0000198sub is_allowed_module_in_file($$$) {
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000199 my $self = shift;
200
Patrik Stridvallbda50742001-07-14 00:48:41 +0000201 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000202 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000203
204 my $module = shift;
205 my $file = shift;
206 $file =~ s/^\.\///;
207
208 my $dir = $file;
209 $dir =~ s/\/[^\/]*$//;
210
Patrik Stridvalld07a6462001-07-18 20:09:12 +0000211 if($dir =~ m%^include%) {
212 return 1;
213 }
214
Patrik Stridvallbda50742001-07-14 00:48:41 +0000215 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
216 if($$spec_file2module{$spec_file} eq $module) {
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000217 return 1;
218 }
219 }
220
221 return 0;
222}
223
Francois Gouget493d60f2004-10-07 18:53:56 +0000224sub allowed_modules_in_file($$) {
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000225 my $self = shift;
226
Patrik Stridvallbda50742001-07-14 00:48:41 +0000227 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000228 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000229
230 my $file = shift;
231 $file =~ s/^\.\///;
232
233 my $dir = $file;
234 $dir =~ s/\/[^\/]*$//;
235
236 my %allowed_modules = ();
Patrik Stridvallbda50742001-07-14 00:48:41 +0000237 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
238 my $module = $$spec_file2module{$spec_file};
239 $allowed_modules{$module}++;
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000240 }
241
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000242 my $module = join(" & ", sort(keys(%allowed_modules)));
243
244 return $module;
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000245}
246
Francois Gouget493d60f2004-10-07 18:53:56 +0000247sub allowed_dirs_for_module($$) {
Patrik Stridvallbda50742001-07-14 00:48:41 +0000248 my $self = shift;
249
250 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
Alexandre Julliard7cae5582002-06-01 02:55:48 +0000251 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
Patrik Stridvallbda50742001-07-14 00:48:41 +0000252
253 my $module = shift;
254
255 my $spec_file = $$module2spec_file{$module};
256
257 return sort(keys(%{$$spec_file2dir{$spec_file}}));
258}
259
Francois Gouget493d60f2004-10-07 18:53:56 +0000260sub allowed_spec_files16($) {
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000261 my $self = shift;
262
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000263 my $spec_files16 = \@{$self->{SPEC_FILES16}};
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000264
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000265 return @$spec_files16;
266}
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000267
Francois Gouget493d60f2004-10-07 18:53:56 +0000268sub allowed_spec_files32($) {
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000269 my $self = shift;
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000270
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000271 my $spec_files32 = \@{$self->{SPEC_FILES32}};
272
273 return @$spec_files32;
Patrik Stridvall14bb7f12000-04-24 18:02:32 +0000274}
275
Francois Gouget493d60f2004-10-07 18:53:56 +0000276sub found_module_in_dir($$$) {
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000277 my $self = shift;
278
279 my $module = shift;
280 my $dir = shift;
281
282 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
283
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000284 $dir = "$current_dir/$dir";
285 $dir =~ s%/\.$%%;
286
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000287 $$used_module_dirs{$module}{$dir}++;
288}
289
Francois Gougetbebac0a2004-10-30 02:11:19 +0000290sub complete_modules($$) {
291 my $self = shift;
292
293 my $c_files = shift;
294
295 my %dirs;
296
297 foreach my $file (@$c_files) {
298 my $dir = file_directory("$current_dir/$file");
299 $dirs{$dir}++;
300 }
301
302 my @c_files = get_c_files("winelib");
303 @c_files = files_skip(@c_files);
304 foreach my $file (@c_files) {
305 my $dir = file_directory($file);
306 if(exists($dirs{$dir})) {
307 $dirs{$dir}--;
308 }
309 }
310
311 my @complete_modules = ();
312 foreach my $module ($self->all_modules) {
313 my $index = -1;
314 my @dirs = $self->allowed_dirs_for_module($module);
315 foreach my $dir (@dirs) {
316 if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
317 $index++;
318 }
319 }
320 if($index == $#dirs) {
321 push @complete_modules, $module;
322 }
323 }
324
325 return @complete_modules;
326}
327
Francois Gouget493d60f2004-10-07 18:53:56 +0000328sub global_report($) {
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000329 my $self = shift;
330
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000331 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000332 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
333
334 my @messages;
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000335 foreach my $dir ($options->directories) {
336 $dir = "$current_dir/$dir";
337 $dir =~ s%/\.$%%;
338 foreach my $module ($self->all_modules) {
Patrik Stridvallbda50742001-07-14 00:48:41 +0000339 if(!$$used_module_dirs{$module}{$dir}) {
Patrik Stridvallcec294e2001-07-30 18:49:10 +0000340 my $spec_file = $$module2spec_file{$module};
Hans Leidekkerb2fa4202004-01-18 22:09:39 +0000341 push @messages, "modules: $spec_file: directory ($dir) is not used\n";
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000342 }
343 }
344 }
345
346 foreach my $message (sort(@messages)) {
Patrik Stridvall67f0a702001-07-26 21:42:12 +0000347 $output->write($message);
Patrik Stridvallc1d5dc42000-08-04 21:08:47 +0000348 }
349}
350
Patrik Stridvall1932d402000-04-15 20:39:55 +00003511;