Several additions and bug fixes.
[wine.git] / tools / winapi_check / modules.pm
blob25f109e5f95f4f558a9368f6c14dcd0cecbfa6bd
1 package modules;
3 use strict;
5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
6 require Exporter;
8 @ISA = qw(Exporter);
9 @EXPORT = qw();
10 @EXPORT_OK = qw($modules);
12 use vars qw($modules);
14 sub new {
15 my $proto = shift;
16 my $class = ref($proto) || $proto;
17 my $self = {};
18 bless ($self, $class);
20 my $options = \${$self->{OPTIONS}};
21 my $output = \${$self->{OUTPUT}};
22 my $spec_files = \%{$self->{SPEC_FILES}};
23 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
25 $$options = shift;
26 $$output = shift;
27 my $wine_dir = shift;
28 my $current_dir = shift;
29 my $file_type = shift;
30 my $module_file = shift;
32 $module_file =~ s/^\.\///;
34 my @all_spec_files = map {
35 s/^.\/(.*)$/$1/;
36 if(&$file_type($_) eq "winelib") {
37 $_;
38 } else {
39 ();
41 } split(/\n/, `find $wine_dir -name \\*.spec`);
43 my %all_spec_files;
44 foreach my $file (@all_spec_files) {
45 $all_spec_files{$file}++ ;
48 if($$options->progress) {
49 $$output->progress("modules.dat");
52 my $allowed_dir;
53 my $spec_file;
55 open(IN, "< $module_file");
56 local $/ = "\n";
57 while(<IN>) {
58 s/^\s*?(.*?)\s*$/$1/; # remove whitespace at begining and end of line
59 s/^(.*?)\s*#.*$/$1/; # remove comments
60 /^$/ && next; # skip empty lines
62 if(/^%\s+(.*?)$/) {
63 $spec_file = $1;
65 if(!-f "$wine_dir/$spec_file") {
66 $$output->write("modules.dat: $spec_file: file ($spec_file) doesn't exist or is no file\n");
69 if($wine_dir eq ".") {
70 $all_spec_files{$spec_file}--;
71 } else {
72 $all_spec_files{"$wine_dir/$spec_file"}--;
74 $$spec_files{""}{$spec_file}++; # FIXME: Kludge
75 next;
76 } else {
77 $allowed_dir = $1;
79 $$spec_files{$allowed_dir}{$spec_file}++;
81 if(!-d "$wine_dir/$allowed_dir") {
82 $$output->write("modules.dat: $spec_file: directory ($allowed_dir) doesn't exist or is no directory\n");
85 close(IN);
87 foreach my $spec_file (sort(keys(%all_spec_files))) {
88 if($all_spec_files{$spec_file} > 0) {
89 $$output->write("modules.dat: $spec_file: exists but is not specified\n");
93 $modules = $self;
95 return $self;
98 sub spec_file_module {
99 my $self = shift;
101 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
102 my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
104 my $spec_file = shift;
105 $spec_file =~ s/^\.\///;
107 my $module = shift;
109 $$spec_file2module{$spec_file}{$module}++;
110 $$module2spec_file{$module}{$spec_file}++;
113 sub is_allowed_module_in_file {
114 my $self = shift;
116 my $spec_files = \%{$self->{SPEC_FILES}};
117 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
119 my $module = shift;
120 my $file = shift;
121 $file =~ s/^\.\///;
123 my $dir = $file;
124 $dir =~ s/\/[^\/]*$//;
126 foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
127 if($$spec_file2module{$spec_file}{$module}) {
128 return 1;
132 return 0;
135 sub allowed_modules_in_file {
136 my $self = shift;
138 my $spec_files = \%{$self->{SPEC_FILES}};
139 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
141 my $file = shift;
142 $file =~ s/^\.\///;
144 my $dir = $file;
145 $dir =~ s/\/[^\/]*$//;
147 my %allowed_modules = ();
148 foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
149 foreach my $module (sort(keys(%{$$spec_file2module{$spec_file}}))) {
150 $allowed_modules{$module}++;
154 return join(" & ", sort(keys(%allowed_modules)));
157 sub allowed_spec_files {
158 my $self = shift;
160 my $options = \${$self->{OPTIONS}};
161 my $output = \${$self->{OUTPUT}};
162 my $spec_files = \%{$self->{SPEC_FILES}};
164 my $wine_dir = shift;
165 my $current_dir = shift;
167 my @dirs = map {
168 s/^\.\/(.*)$/$1/;
169 if(/^\.$/) {
170 $current_dir;
171 } else {
172 if($current_dir ne ".") {
173 "$current_dir/$_";
174 } else {
178 } split(/\n/, `find . -type d ! -name CVS`);
180 my %allowed_spec_files = ();
181 foreach my $dir (sort(@dirs)) {
182 foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
183 $allowed_spec_files{$spec_file}++;
187 return sort(keys(%allowed_spec_files));
190 sub found_module_in_dir {
191 my $self = shift;
193 my $module = shift;
194 my $dir = shift;
196 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
198 $$used_module_dirs{$module}{$dir}++;
201 sub global_report {
202 my $self = shift;
204 my $output = \${$self->{OUTPUT}};
205 my $spec_files = \%{$self->{SPEC_FILES}};
206 my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
207 my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
209 my @messages;
210 foreach my $dir (sort(keys(%$spec_files))) {
211 if($dir eq "") { next; }
212 foreach my $spec_file (sort(keys(%{$$spec_files{$dir}}))) {
213 foreach my $module (sort(keys(%{$$spec_file2module{$spec_file}}))) {
214 if(!$$used_module_dirs{$module}{$dir}) {
215 push @messages, "modules.dat: $spec_file: directory ($dir) is not used\n";
221 foreach my $message (sort(@messages)) {
222 $$output->write($message);