123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- #
- # Copyright 1999, 2000, 2001 Patrik Stridvall
- #
- # This library is free software; you can redistribute it and/or
- # modify it under the terms of the GNU Lesser General Public
- # License as published by the Free Software Foundation; either
- # version 2.1 of the License, or (at your option) any later version.
- #
- # This library is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # Lesser General Public License for more details.
- #
- # You should have received a copy of the GNU Lesser General Public
- # License along with this library; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- #
- package modules;
- use strict;
- use warnings 'all';
- use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
- require Exporter;
- @ISA = qw(Exporter);
- @EXPORT = qw();
- @EXPORT_OK = qw($modules);
- use vars qw($modules);
- use config qw(
- file_type files_skip
- file_directory
- get_c_files get_spec_files
- $current_dir $wine_dir
- );
- use options qw($options);
- use output qw($output);
- sub import(@) {
- $Exporter::ExportLevel++;
- Exporter::import(@_);
- $Exporter::ExportLevel--;
- if (defined($modules)) {
- return;
- }
- $modules = 'modules'->new;
- }
- sub get_spec_file_type($) {
- my $file = shift;
- my $module;
- my $type;
- $module = $file;
- $module =~ s%^.*?([^/]+)\.spec$%$1%;
- open(IN, "< $file") || die "$file: $!\n";
- local $/ = "\n";
- my $header = 1;
- my $lookahead = 0;
- while($lookahead || defined($_ = <IN>)) {
- $lookahead = 0;
- s/^\s*(.*?)\s*$/$1/;
- s/^(.*?)\s*#.*$/$1/;
- /^$/ && next;
- if($header) {
- if(/^(?:\d+|@)/) { $header = 0; $lookahead = 1; }
- next;
- }
- if(/^(\d+|@)\s+pascal(?:16)?/) {
- $type = "win16";
- last;
- }
- }
- close(IN);
- if(!defined($type)) {
- $type = "win32";
- }
- return ($type, $module);
- }
- sub find_spec_files($) {
- my $self = shift;
- my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
- my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
- $output->progress("modules");
- my $spec_file_found = {};
- my $allowed_dir;
- my $spec_file;
- my @spec_files = <{dlls/*/*.spec}>;
- foreach $spec_file (@spec_files) {
- $spec_file =~ /(.*)\/.*\.spec/;
- $allowed_dir = $1;
- $$spec_file_found{$spec_file}++;
- $$spec_file2dir{$spec_file}{$allowed_dir}++;
- $$dir2spec_file{$allowed_dir}{$spec_file}++;
- # gdi32.dll and gdi.exe have some extra sources in subdirectories
- if ($spec_file =~ m!/gdi32\.spec$!)
- {
- $$spec_file2dir{$spec_file}{"$allowed_dir/enhmfdrv"}++;
- $$dir2spec_file{"$allowed_dir/enhmfdrv"}{$spec_file}++;
- }
- if ($spec_file =~ m!/gdi(?:32|\.exe)\.spec$!)
- {
- $$spec_file2dir{$spec_file}{"$allowed_dir/mfdrv"}++;
- $$dir2spec_file{"$allowed_dir/mfdrv"}{$spec_file}++;
- }
- }
- return $spec_file_found;
- }
- sub read_spec_files($$) {
- my $self = shift;
- my $spec_file_found = shift;
- my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
- my $spec_files16 = \@{$self->{SPEC_FILES16}};
- my $spec_files32 = \@{$self->{SPEC_FILES32}};
- my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
- my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
- my @spec_files;
- if($wine_dir eq ".") {
- @spec_files = get_spec_files("winelib");
- } else {
- my %spec_files = ();
- foreach my $dir ($options->directories) {
- $dir = "$current_dir/$dir";
- $dir =~ s%/\.$%%;
- foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
- $spec_files{$spec_file}++;
- }
- }
- @spec_files = sort(keys(%spec_files));
- }
- @$spec_files16 = ();
- @$spec_files32 = ();
- foreach my $spec_file (@spec_files) {
- (my $type, my $module) = get_spec_file_type("$wine_dir/$spec_file");
- $$spec_file2module{$spec_file} = $module;
- $$module2spec_file{$module} = $spec_file;
- if($type eq "win16") {
- push @$spec_files16, $spec_file;
- } elsif($type eq "win32") {
- push @$spec_files32, $spec_file;
- } else {
- $output->write("$spec_file: unknown type '$type'\n");
- }
- }
- foreach my $spec_file (@spec_files) {
- if(!$$spec_file_found{$spec_file} && $spec_file !~ m%tests/[^/]+$%) {
- $output->write("modules: $spec_file: exists but is not specified\n");
- }
- }
- }
- sub new($) {
- my $proto = shift;
- my $class = ref($proto) || $proto;
- my $self = {};
- bless ($self, $class);
- my $spec_file_found = $self->find_spec_files();
- $self->read_spec_files($spec_file_found);
- return $self;
- }
- sub all_modules($) {
- my $self = shift;
- my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
- return sort(keys(%$module2spec_file));
- }
- sub is_allowed_module($$) {
- my $self = shift;
- my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
- my $module = shift;
- return defined($$module2spec_file{$module});
- }
- sub is_allowed_module_in_file($$$) {
- my $self = shift;
- my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
- my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
- my $module = shift;
- my $file = shift;
- $file =~ s/^\.\///;
- my $dir = $file;
- $dir =~ s/\/[^\/]*$//;
- if($dir =~ m%^include%) {
- return 1;
- }
- foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
- if($$spec_file2module{$spec_file} eq $module) {
- return 1;
- }
- }
- return 0;
- }
- sub allowed_modules_in_file($$) {
- my $self = shift;
- my $dir2spec_file = \%{$self->{DIR2SPEC_FILE}};
- my $spec_file2module = \%{$self->{SPEC_FILE2MODULE}};
- my $file = shift;
- $file =~ s/^\.\///;
- my $dir = $file;
- $dir =~ s/\/[^\/]*$//;
- my %allowed_modules = ();
- foreach my $spec_file (sort(keys(%{$$dir2spec_file{$dir}}))) {
- my $module = $$spec_file2module{$spec_file};
- $allowed_modules{$module}++;
- }
- my $module = join(" & ", sort(keys(%allowed_modules)));
- return $module;
- }
- sub allowed_dirs_for_module($$) {
- my $self = shift;
- my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
- my $spec_file2dir = \%{$self->{SPEC_FILE2DIR}};
- my $module = shift;
- my $spec_file = $$module2spec_file{$module};
- return sort(keys(%{$$spec_file2dir{$spec_file}}));
- }
- sub allowed_spec_files16($) {
- my $self = shift;
- my $spec_files16 = \@{$self->{SPEC_FILES16}};
- return @$spec_files16;
- }
- sub allowed_spec_files32($) {
- my $self = shift;
- my $spec_files32 = \@{$self->{SPEC_FILES32}};
- return @$spec_files32;
- }
- sub found_module_in_dir($$$) {
- my $self = shift;
- my $module = shift;
- my $dir = shift;
- my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
- $dir = "$current_dir/$dir";
- $dir =~ s%/\.$%%;
- $$used_module_dirs{$module}{$dir}++;
- }
- sub complete_modules($$) {
- my $self = shift;
- my $c_files = shift;
- my %dirs;
- foreach my $file (@$c_files) {
- my $dir = file_directory("$current_dir/$file");
- $dirs{$dir}++;
- }
- my @c_files = get_c_files("winelib");
- @c_files = files_skip(@c_files);
- foreach my $file (@c_files) {
- my $dir = file_directory($file);
- if(exists($dirs{$dir})) {
- $dirs{$dir}--;
- }
- }
- my @complete_modules = ();
- foreach my $module ($self->all_modules) {
- my $index = -1;
- my @dirs = $self->allowed_dirs_for_module($module);
- foreach my $dir (@dirs) {
- if(exists($dirs{$dir}) && $dirs{$dir} == 0) {
- $index++;
- }
- }
- if($index == $#dirs) {
- push @complete_modules, $module;
- }
- }
- return @complete_modules;
- }
- sub global_report($) {
- my $self = shift;
- my $module2spec_file = \%{$self->{MODULE2SPEC_FILE}};
- my $used_module_dirs = \%{$self->{USED_MODULE_DIRS}};
- my @messages;
- foreach my $dir ($options->directories) {
- $dir = "$current_dir/$dir";
- $dir =~ s%/\.$%%;
- foreach my $module ($self->all_modules) {
- if(!$$used_module_dirs{$module}{$dir}) {
- my $spec_file = $$module2spec_file{$module};
- push @messages, "modules: $spec_file: directory ($dir) is not used\n";
- }
- }
- }
- foreach my $message (sort(@messages)) {
- $output->write($message);
- }
- }
- 1;
|