5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
10 @EXPORT_OK = qw($modules);
12 use vars qw($modules);
15 &file_type &files_skip
17 &get_c_files &get_spec_files
18 $current_dir $wine_dir
21 use options qw($options);
22 use output qw($output);
24 $modules = 'modules'->new;
26 sub get_spec_file_type {
32 open(IN, "< $file") || die "$file: $!\n";
39 if(/^name\s*(\S*)/) { $module = $1; }
40 if(/^type\s*(\w+)/) { $type = $1; }
42 if(defined($module) && defined($type)) { last; }
46 if(!defined($module)) {
48 $module =~ s%^.*?([^/]+)\.spec|%$1%;
55 return ($type, $module);
60 my $class = ref($proto) || $proto;
62 bless ($self, $class);
64 my $spec_files16 = \@{$self->{SPEC_FILES16}};
65 my $spec_files32 = \@{$self->{SPEC_FILES32}};
66 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
67 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
68 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
69 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
71 my $module_file = "$winapi_check_dir/modules.dat";
73 if($options->progress) {
74 $output->progress("modules.dat");
81 open(IN, "< $module_file");
84 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begining and end of line
85 s/^(.*?)\s*#.*$/$1/; # remove comments
86 /^$/ && next; # skip empty lines
91 if(!-f "$wine_dir/$spec_file") {
92 $output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
95 $spec_file_found{$spec_file}++;
96 $$spec_file2dir{$spec_file} = {};
100 $$spec_file2dir{$spec_file}{$allowed_dir}++;
102 $$dir2spec_file{$allowed_dir}{$spec_file}++;
104 if(!-d "$wine_dir/$allowed_dir") {
105 $output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
111 if($wine_dir eq ".") {
112 @spec_files = get_spec_files("winelib");
115 foreach my $dir ($options->directories) {
116 $dir = "$current_dir/$dir";
118 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
119 $spec_files{$spec_file}++;
122 @spec_files = sort(keys(%spec_files));
127 foreach my $spec_file (@spec_files) {
128 (my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");
130 $$spec_file2module{$spec_file} = $module;
131 $$module2spec_file{$module} = $spec_file;
133 if($type eq "win16") {
134 push @$spec_files16, $spec_file;
135 } elsif($type eq "win32") {
136 push @$spec_files32, $spec_file;
138 $output->write("$spec_file: unknown type '$type'\n");
142 foreach my $spec_file (@spec_files) {
143 if(!$spec_file_found{$spec_file}) {
144 $output->write("modules.dat: $spec_file: exists but is not specified\n");
156 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
158 return sort(keys(%$module2spec_file));
161 sub complete_modules {
168 foreach my $file (@$c_files) {
169 my $dir = file_directory("$current_dir/$file");
173 my @c_files = get_c_files("winelib");
174 @c_files = files_skip(@c_files);
175 foreach my $file (@c_files) {
176 my $dir = file_directory($file);
177 if(exists($dirs{$dir})) {
182 my @complete_modules = ();
183 foreach my $module ($self->all_modules) {
185 my @dirs = $self->allowed_dirs_for_module($module);
186 foreach my $dir (@dirs) {
187 if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
191 if($index == $#dirs) {
192 push @complete_modules, $module;
196 return @complete_modules;
199 sub is_allowed_module {
202 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
206 return defined($$module2spec_file{$module});
209 sub is_allowed_module_in_file {
212 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
213 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
220 $dir =~ s/\/[^\/]*$//;
222 if($dir =~ m%^include%) {
226 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
227 if($$spec_file2module{$spec_file} eq $module) {
235 sub allowed_modules_in_file {
238 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
239 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
245 $dir =~ s/\/[^\/]*$//;
247 my %allowed_modules = ();
248 foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
249 my $module = $$spec_file2module{$spec_file};
250 $allowed_modules{$module}++;
253 my $module = join(" & ", sort(keys(%allowed_modules)));
258 sub allowed_dirs_for_module {
261 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
262 my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
266 my $spec_file = $$module2spec_file{$module};
268 return sort(keys(%{$$spec_file2dir{$spec_file}}));
271 sub allowed_spec_files16 {
274 my $spec_files16 = \@{$self->{SPEC_FILES16}};
276 return @$spec_files16;
279 sub allowed_spec_files32 {
282 my $spec_files32 = \@{$self->{SPEC_FILES32}};
284 return @$spec_files32;
287 sub found_module_in_dir {
293 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
295 $dir = "$current_dir/$dir";
298 $$used_module_dirs{$module}{$dir}++;
304 my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
305 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
306 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
309 foreach my $dir ($options->directories) {
310 $dir = "$current_dir/$dir";
312 foreach my $module ($self->all_modules) {
313 if(!$$used_module_dirs{$module}{$dir}) {
314 my $spec_file = $$module2spec_file{$module};
315 push @messages, "modules.dat: $spec_file: directory ($dir) is not used\n";
320 foreach my $message (sort(@messages)) {
321 $output->write($message);