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);
33 &file_type &files_skip
35 &get_c_files &get_spec_files
36 $current_dir $wine_dir
39 use options qw($options);
40 use output qw($output);
42 $modules = 'modules'->new;
44 sub get_spec_file_type {
50 open(IN, "< $file") || die "$file: $!\n";
57 if(/^name\s*(\S*)/) { $module = $1; }
58 if(/^type\s*(\w+)/) { $type = $1; }
60 if(defined($module) && defined($type)) { last; }
64 if(!defined($module)) {
66 $module =~ s%^.*?([^/]+)\.spec|%$1%;
73 return ($type, $module);
78 my $class = ref($proto) || $proto;
80 bless ($self, $class);
82 my $spec_files16 = \@{$self->{SPEC_FILES16}};
83 my $spec_files32 = \@{$self->{SPEC_FILES32}};
84 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
85 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
86 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
87 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
89 my $module_file = "$winapi_check_dir/modules.dat";
91 $output->progress("modules.dat");
97 open(IN, "< $module_file");
100 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begining and end of line
101 s/^(.*?)\s*#.*$/$1/; # remove comments
102 /^$/ && next; # skip empty lines
107 if(!-f "$wine_dir/$spec_file") {
108 $output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
111 $spec_file_found{$spec_file}++;
112 $$spec_file2dir{$spec_file} = {};
116 $$spec_file2dir{$spec_file}{$allowed_dir}++;
118 $$dir2spec_file{$allowed_dir}{$spec_file}++;
120 if(!-d "$wine_dir/$allowed_dir") {
121 $output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
127 if($wine_dir eq ".") {
128 @spec_files = get_spec_files("winelib");
131 foreach my $dir ($options->directories) {
132 $dir = "$current_dir/$dir";
134 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
135 $spec_files{$spec_file}++;
138 @spec_files = sort(keys(%spec_files));
143 foreach my $spec_file (@spec_files) {
144 (my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");
146 if(!$type) { $type = "win32"; }
148 $$spec_file2module{$spec_file} = $module;
149 $$module2spec_file{$module} = $spec_file;
151 if($type eq "win16") {
152 push @$spec_files16, $spec_file;
153 } elsif($type eq "win32") {
154 push @$spec_files32, $spec_file;
156 $output->write("$spec_file: unknown type '$type'\n");
160 foreach my $spec_file (@spec_files) {
161 if(!$spec_file_found{$spec_file} && $spec_file !~ m%tests/[^/]+$%) {
162 $output->write("modules.dat: $spec_file: exists but is not specified\n");
174 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
176 return sort(keys(%$module2spec_file));
179 sub complete_modules {
186 foreach my $file (@$c_files) {
187 my $dir = file_directory("$current_dir/$file");
191 my @c_files = get_c_files("winelib");
192 @c_files = files_skip(@c_files);
193 foreach my $file (@c_files) {
194 my $dir = file_directory($file);
195 if(exists($dirs{$dir})) {
200 my @complete_modules = ();
201 foreach my $module ($self->all_modules) {
203 my @dirs = $self->allowed_dirs_for_module($module);
204 foreach my $dir (@dirs) {
205 if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
209 if($index == $#dirs) {
210 push @complete_modules, $module;
214 return @complete_modules;
217 sub is_allowed_module {
220 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
224 return defined($$module2spec_file{$module});
227 sub is_allowed_module_in_file {
230 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
231 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
238 $dir =~ s/\/[^\/]*$//;
240 if($dir =~ m%^include%) {
244 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
245 if($$spec_file2module{$spec_file} eq $module) {
253 sub allowed_modules_in_file {
256 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
257 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
263 $dir =~ s/\/[^\/]*$//;
265 my %allowed_modules = ();
266 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
267 my $module = $$spec_file2module{$spec_file};
268 $allowed_modules{$module}++;
271 my $module = join(" & ", sort(keys(%allowed_modules)));
276 sub allowed_dirs_for_module {
279 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
280 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
284 my $spec_file = $$module2spec_file{$module};
286 return sort(keys(%{$$spec_file2dir{$spec_file}}));
289 sub allowed_spec_files16 {
292 my $spec_files16 = \@{$self->{SPEC_FILES16}};
294 return @$spec_files16;
297 sub allowed_spec_files32 {
300 my $spec_files32 = \@{$self->{SPEC_FILES32}};
302 return @$spec_files32;
305 sub found_module_in_dir {
311 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
313 $dir = "$current_dir/$dir";
316 $$used_module_dirs{$module}{$dir}++;
322 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
323 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
324 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
327 foreach my $dir ($options->directories) {
328 $dir = "$current_dir/$dir";
330 foreach my $module ($self->all_modules) {
331 if(!$$used_module_dirs{$module}{$dir}) {
332 my $spec_file = $$module2spec_file{$module};
333 push @messages, "modules.dat: $spec_file: directory ($dir) is not used\n";
338 foreach my $message (sort(@messages)) {
339 $output->write($message);