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
23 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
28 @EXPORT_OK = qw($modules);
30 use vars qw($modules);
35 get_c_files get_spec_files
36 $current_dir $wine_dir
38 use options qw($options);
39 use output qw($output);
42 $Exporter::ExportLevel++;
44 $Exporter::ExportLevel--;
46 if (defined($modules)) {
50 $modules = 'modules'->new;
53 sub get_spec_file_type($) {
60 $module =~ s%^.*?([^/]+)\.spec$%$1%;
62 open(IN, "< $file") || die "$file: $!\n";
66 while($lookahead || defined($_ = <IN>)) {
73 if(/^(?:\d+|@)/) { $header = 0; $lookahead = 1; }
77 if(/^(\d+|@)\s+pascal(?:16)?/) {
88 return ($type, $module);
91 sub find_spec_files($) {
94 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
95 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
97 $output->progress("modules");
99 my $spec_file_found = {};
103 my @spec_files = <{dlls/*/*.spec,dlls/*/*/*.spec}>;
105 foreach $spec_file (@spec_files) {
106 $spec_file =~ /(.*)\/.*\.spec/;
110 $$spec_file_found{$spec_file}++;
111 $$spec_file2dir{$spec_file}{$allowed_dir}++;
112 $$dir2spec_file{$allowed_dir}{$spec_file}++;
115 return $spec_file_found;
118 sub read_spec_files($$) {
121 my $spec_file_found = shift;
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}};
130 if($wine_dir eq ".") {
131 @spec_files = get_spec_files("winelib");
134 foreach my $dir ($options->directories) {
135 $dir = "$current_dir/$dir";
137 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
138 $spec_files{$spec_file}++;
141 @spec_files = sort(keys(%spec_files));
146 foreach my $spec_file (@spec_files) {
147 (my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");
149 $$spec_file2module{$spec_file} = $module;
150 $$module2spec_file{$module} = $spec_file;
152 if($type eq "win16") {
153 push @$spec_files16, $spec_file;
154 } elsif($type eq "win32") {
155 push @$spec_files32, $spec_file;
157 $output->write("$spec_file: unknown type '$type'\n");
161 foreach my $spec_file (@spec_files) {
162 if(!$$spec_file_found{$spec_file} && $spec_file !~ m%tests/[^/]+$%) {
163 $output->write("modules: $spec_file: exists but is not specified\n");
170 my $class = ref($proto) || $proto;
172 bless ($self, $class);
174 my $spec_file_found = $self->find_spec_files();
175 $self->read_spec_files($spec_file_found);
183 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
185 return sort(keys(%$module2spec_file));
188 sub is_allowed_module($$) {
191 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
195 return defined($$module2spec_file{$module});
198 sub is_allowed_module_in_file($$$) {
201 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
202 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
209 $dir =~ s/\/[^\/]*$//;
211 if($dir =~ m%^include%) {
215 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
216 if($$spec_file2module{$spec_file} eq $module) {
224 sub allowed_modules_in_file($$) {
227 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
228 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
234 $dir =~ s/\/[^\/]*$//;
236 my %allowed_modules = ();
237 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
238 my $module = $$spec_file2module{$spec_file};
239 $allowed_modules{$module}++;
242 my $module = join(" & ", sort(keys(%allowed_modules)));
247 sub allowed_dirs_for_module($$) {
250 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
251 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
255 my $spec_file = $$module2spec_file{$module};
257 return sort(keys(%{$$spec_file2dir{$spec_file}}));
260 sub allowed_spec_files16($) {
263 my $spec_files16 = \@{$self->{SPEC_FILES16}};
265 return @$spec_files16;
268 sub allowed_spec_files32($) {
271 my $spec_files32 = \@{$self->{SPEC_FILES32}};
273 return @$spec_files32;
276 sub found_module_in_dir($$$) {
282 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
284 $dir = "$current_dir/$dir";
287 $$used_module_dirs{$module}{$dir}++;
290 sub complete_modules($$) {
297 foreach my $file (@$c_files) {
298 my $dir = file_directory("$current_dir/$file");
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})) {
311 my @complete_modules = ();
312 foreach my $module ($self->all_modules) {
314 my @dirs = $self->allowed_dirs_for_module($module);
315 foreach my $dir (@dirs) {
316 if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
320 if($index == $#dirs) {
321 push @complete_modules, $module;
325 return @complete_modules;
328 sub global_report($) {
331 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
332 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
335 foreach my $dir ($options->directories) {
336 $dir = "$current_dir/$dir";
338 foreach my $module ($self->all_modules) {
339 if(!$$used_module_dirs{$module}{$dir}) {
340 my $spec_file = $$module2spec_file{$module};
341 push @messages, "modules: $spec_file: directory ($dir) is not used\n";
346 foreach my $message (sort(@messages)) {
347 $output->write($message);