The R Project SVN R

Rev

Rev 37487 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 37487 Rev 37725
1
#! @PERL@
1
#! @PERL@
2
#-*- perl -*-
2
#-*- perl -*-
3
 
3
 
4
## Copyright (C) 2000-2006 R Development Core Team
4
## Copyright (C) 2000-2006 R Development Core Team
5
##
5
##
6
## This program is free software; you can redistribute it and/or modify
6
## This program is free software; you can redistribute it and/or modify
7
## it under the terms of the GNU General Public License as published by
7
## it under the terms of the GNU General Public License as published by
8
## the Free Software Foundation; either version 2, or (at your option)
8
## the Free Software Foundation; either version 2, or (at your option)
9
## any later version.
9
## any later version.
10
##
10
##
11
## This program is distributed in the hope that it will be useful, but
11
## This program is distributed in the hope that it will be useful, but
12
## WITHOUT ANY WARRANTY; without even the implied warranty of
12
## WITHOUT ANY WARRANTY; without even the implied warranty of
13
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
13
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
14
## General Public License for more details.
14
## General Public License for more details.
15
##
15
##
16
## A copy of the GNU General Public License is available via WWW at
16
## A copy of the GNU General Public License is available via WWW at
17
## http://www.gnu.org/copyleft/gpl.html.  You can also obtain it by
17
## http://www.gnu.org/copyleft/gpl.html.  You can also obtain it by
18
## writing to the Free Software Foundation, Inc., 51 Franklin Street,
18
## writing to the Free Software Foundation, Inc., 51 Franklin Street,
19
## Fifth Floor, Boston, MA 02110-1301  USA.
19
## Fifth Floor, Boston, MA 02110-1301  USA.
20
 
20
 
21
## Send any bug reports to r-bugs@r-project.org
21
## Send any bug reports to r-bugs@r-project.org
22
 
22
 
23
use Cwd;
23
use Cwd;
24
use File::Basename;
24
use File::Basename;
25
use File::Copy;
25
use File::Copy;
26
use File::Find;
26
use File::Find;
27
use File::Path;
27
use File::Path;
28
use Getopt::Long;
28
use Getopt::Long;
29
use IO::File;
29
use IO::File;
30
use R::Dcf;
30
use R::Dcf;
31
use R::Logfile;
31
use R::Logfile;
32
use R::Rdtools;
32
use R::Rdtools;
33
use R::Utils;
33
use R::Utils;
34
use R::Vars;
34
use R::Vars;
35
use Text::Wrap;
35
use Text::Wrap;
36
 
36
 
37
## Don't buffer output.
37
## Don't buffer output.
38
$| = 1;
38
$| = 1;
39
 
39
 
40
my $revision = ' $Rev: 37487 $ ';
40
my $revision = ' $Rev: 37725 $ ';
41
my $version;
41
my $version;
42
my $name;
42
my $name;
43
$revision =~ / ([\d\.]*) /;
43
$revision =~ / ([\d\.]*) /;
44
$version = $1;
44
$version = $1;
45
($name = $0) =~ s|.*/||;
45
($name = $0) =~ s|.*/||;
46
 
46
 
47
### Options
47
### Options
48
my $opt_clean = 1;
48
my $opt_clean = 1;
49
my $opt_examples = 1;
49
my $opt_examples = 1;
50
my $opt_tests = 1;
50
my $opt_tests = 1;
51
my $opt_latex = 1;
51
my $opt_latex = 1;
52
my $opt_use_gct = 0;
52
my $opt_use_gct = 0;
53
my $opt_codoc = 1;
53
my $opt_codoc = 1;
54
my $opt_install = 1;
54
my $opt_install = 1;
55
my $opt_vignettes = 1;
55
my $opt_vignettes = 1;
56
my $opt_use_valgrind = 0;
56
my $opt_use_valgrind = 0;
57
my $opt_rcfile = "";		# Only set this if $ENV{"HOME"} is set.
57
my $opt_rcfile = "";		# Only set this if $ENV{"HOME"} is set.
58
$opt_rcfile = &file_path($ENV{"HOME"}, ".R", "check.conf")
58
$opt_rcfile = &file_path($ENV{"HOME"}, ".R", "check.conf")
59
    if defined($ENV{"HOME"});
59
    if defined($ENV{"HOME"});
60
my $opt_subdirs;
60
my $opt_subdirs;
61
 
61
 
62
my $WINDOWS = ($R::Vars::OSTYPE eq "windows");
62
my $WINDOWS = ($R::Vars::OSTYPE eq "windows");
63
 
63
 
64
R::Vars::error("R_HOME", "R_EXE");
64
R::Vars::error("R_HOME", "R_EXE");
65
 
65
 
66
my @known_options = ("help|h", "version|v", "outdir|o:s", "library|l:s",
66
my @known_options = ("help|h", "version|v", "outdir|o:s", "library|l:s",
67
		     "no-clean", "no-examples", "no-tests", "no-latex",
67
		     "no-clean", "no-examples", "no-tests", "no-latex",
68
		     "use-gct" => \$opt_use_gct, "no-codoc",
68
		     "use-gct" => \$opt_use_gct, "no-codoc",
69
		     "install=s" => \$opt_install, "no-install",
69
		     "install=s" => \$opt_install, "no-install",
70
		     "no-vignettes", "use-valgrind" => \$opt_use_valgrind,
70
		     "no-vignettes", "use-valgrind" => \$opt_use_valgrind,
71
		     "rcfile=s" => \$opt_rcfile,
71
		     "rcfile=s" => \$opt_rcfile,
72
		     "check-subdirs=s" => \$opt_subdirs);
72
		     "check-subdirs=s" => \$opt_subdirs);
73
GetOptions(@known_options) or usage();
73
GetOptions(@known_options) or usage();
74
 
74
 
75
R_version("R add-on package checker", $version) if $opt_version;
75
R_version("R add-on package checker", $version) if $opt_version;
76
usage() if $opt_help;
76
usage() if $opt_help;
77
 
77
 
78
$opt_clean = 0 if $opt_no_clean;
78
$opt_clean = 0 if $opt_no_clean;
79
$opt_examples = 0 if $opt_no_examples;
79
$opt_examples = 0 if $opt_no_examples;
80
$opt_tests = 0 if $opt_no_tests;
80
$opt_tests = 0 if $opt_no_tests;
81
$opt_latex = 0 if $opt_no_latex;
81
$opt_latex = 0 if $opt_no_latex;
82
$opt_codoc = 0 if $opt_no_codoc;
82
$opt_codoc = 0 if $opt_no_codoc;
83
$opt_install = 0 if $opt_no_install;
83
$opt_install = 0 if $opt_no_install;
84
$opt_vignettes = 0 if $opt_no_vignettes;
84
$opt_vignettes = 0 if $opt_no_vignettes;
85
 
85
 
86
if($opt_install eq "fake") {
86
if($opt_install eq "fake") {
87
    ## If we fake installation, then we cannot *run* any code.
87
    ## If we fake installation, then we cannot *run* any code.
88
    $opt_examples = $opt_tests = $opt_vignettes = 0;
88
    $opt_examples = $opt_tests = $opt_vignettes = 0;
89
}
89
}
90
$opt_install = 0 if($opt_install eq "no");
90
$opt_install = 0 if($opt_install eq "no");
91
 
91
 
92
my $opt_ff_calls = 1;
92
my $opt_ff_calls = 1;
93
## The neverending story ...
93
## The neverending story ...
94
## For the time being, allow to turn this off by setting the environment
94
## For the time being, allow to turn this off by setting the environment
95
## variable _R_CHECK_FF_CALLS_ to a Perl 'null' value.
95
## variable _R_CHECK_FF_CALLS_ to a Perl 'null' value.
96
if(defined($ENV{"_R_CHECK_FF_CALLS_"})) {
96
if(defined($ENV{"_R_CHECK_FF_CALLS_"})) {
97
    $opt_ff_calls = $ENV{"_R_CHECK_FF_CALLS_"};
97
    $opt_ff_calls = $ENV{"_R_CHECK_FF_CALLS_"};
98
}
98
}
99
 
99
 
100
## Use system default unless explicitly specified otherwise.
100
## Use system default unless explicitly specified otherwise.
101
$ENV{"R_DEFAULT_PACKAGES"} = "";
101
$ENV{"R_DEFAULT_PACKAGES"} = "";
102
 
102
 
103
### Configurable variables
103
### Configurable variables
104
my $R_check_use_install_log =
104
my $R_check_use_install_log =
105
    &R_getenv("_R_CHECK_USE_INSTALL_LOG_", "TRUE");
105
    &R_getenv("_R_CHECK_USE_INSTALL_LOG_", "TRUE");
106
my $R_check_subdirs_nocase =
106
my $R_check_subdirs_nocase =
107
    &R_getenv("_R_CHECK_SUBDIRS_NOCASE_", "FALSE");
107
    &R_getenv("_R_CHECK_SUBDIRS_NOCASE_", "FALSE");
108
my $R_check_all_non_ISO_C =
108
my $R_check_all_non_ISO_C =
109
    &R_getenv("_R_CHECK_ALL_NON_ISO_C_", "FALSE");
109
    &R_getenv("_R_CHECK_ALL_NON_ISO_C_", "FALSE");
110
my $R_check_weave_vignettes =
110
my $R_check_weave_vignettes =
111
    &R_getenv("_R_CHECK_WEAVE_VIGNETTES_", "TRUE");
111
    &R_getenv("_R_CHECK_WEAVE_VIGNETTES_", "TRUE");
112
my $R_check_subdirs_strict =
112
my $R_check_subdirs_strict =
113
    &R_getenv("_R_CHECK_SUBDIRS_STRICT_", "default");
113
    &R_getenv("_R_CHECK_SUBDIRS_STRICT_", "default");
114
 
114
 
115
## Maybe move basic configuration (and documentation) to
115
## Maybe move basic configuration (and documentation) to
116
##   &file_path($R::Vars::R_HOME, "etc", "check.conf")
116
##   &file_path($R::Vars::R_HOME, "etc", "check.conf")
117
## eventually ...
117
## eventually ...
118
for my $file ($opt_rcfile) {
118
for my $file ($opt_rcfile) {
119
    if(-r $file) {
119
    if(-r $file) {
120
	open(FILE, "< $file")
120
	open(FILE, "< $file")
121
	    or die "Error: cannot open file '$file' for reading\n";
121
	    or die "Error: cannot open file '$file' for reading\n";
122
	my @lines = <FILE>;
122
	my @lines = <FILE>;
123
	close(FILE);
123
	close(FILE);
124
	eval("@lines");
124
	eval("@lines");
125
	die "Error: failed to eval config file '$file'\n$@\n" if ($@);
125
	die "Error: failed to eval config file '$file'\n$@\n" if ($@);
126
	## <NOTE>
126
	## <NOTE>
127
	## We prefer the above to the usual recommendation
127
	## We prefer the above to the usual recommendation
128
	## 	unless ($return = do($file)) {
128
	## 	unless ($return = do($file)) {
129
	## 	    warn "couldn't parse $file: $@" if $@;
129
	## 	    warn "couldn't parse $file: $@" if $@;
130
	## 	    warn "couldn't do $file: $!"    unless defined $return;
130
	## 	    warn "couldn't do $file: $!"    unless defined $return;
131
	## 	    warn "couldn't run $file"       unless $return;
131
	## 	    warn "couldn't run $file"       unless $return;
132
	##  }
132
	##  }
133
	## as do(FILE) cannot see lexicals in the enclosing scope.
133
	## as do(FILE) cannot see lexicals in the enclosing scope.
134
	## </NOTE>
134
	## </NOTE>
135
    }
135
    }
136
}
136
}
137
 
137
 
138
$R_check_use_install_log =
138
$R_check_use_install_log =
139
    &config_val_to_logical($R_check_use_install_log);
139
    &config_val_to_logical($R_check_use_install_log);
140
$R_check_subdirs_nocase =
140
$R_check_subdirs_nocase =
141
    &config_val_to_logical($R_check_subdirs_nocase);
141
    &config_val_to_logical($R_check_subdirs_nocase);
142
$R_check_all_non_ISO_C =
142
$R_check_all_non_ISO_C =
143
    &config_val_to_logical($R_check_all_non_ISO_C);
143
    &config_val_to_logical($R_check_all_non_ISO_C);
144
$R_check_weave_vignettes =
144
$R_check_weave_vignettes =
145
    &config_val_to_logical($R_check_weave_vignettes);
145
    &config_val_to_logical($R_check_weave_vignettes);
146
 
146
 
147
$opt_subdirs = $R_check_subdirs_strict if $opt_subdirs eq "";
147
$opt_subdirs = $R_check_subdirs_strict if $opt_subdirs eq "";
148
 
148
 
149
my $startdir = R_cwd();
149
my $startdir = R_cwd();
150
$opt_outdir = $startdir unless $opt_outdir;
150
$opt_outdir = $startdir unless $opt_outdir;
151
chdir($opt_outdir)
151
chdir($opt_outdir)
152
    or die "Error: cannot change to directory '$opt_outdir'\n";
152
    or die "Error: cannot change to directory '$opt_outdir'\n";
153
my $outdir = R_cwd();
153
my $outdir = R_cwd();
154
chdir($startdir);
154
chdir($startdir);
155
 
155
 
156
my $R_LIBS = $ENV{'R_LIBS'};
156
my $R_LIBS = $ENV{'R_LIBS'};
157
my $library;
157
my $library;
158
if($opt_library) {
158
if($opt_library) {
159
    chdir($opt_library)
159
    chdir($opt_library)
160
	or die "Error: cannot change to directory '$opt_library'\n";
160
	or die "Error: cannot change to directory '$opt_library'\n";
161
    $library = R_cwd();
161
    $library = R_cwd();
162
    $ENV{'R_LIBS'} = env_path($library, $R_LIBS);
162
    $ENV{'R_LIBS'} = env_path($library, $R_LIBS);
163
 
163
 
164
    chdir($startdir);
164
    chdir($startdir);
165
}
165
}
166
 
166
 
167
my $tar = R_getenv("TAR", "tar");
167
my $tar = R_getenv("TAR", "tar");
168
my $gzip = R_getenv("R_GZIPCMD", "gzip");
168
my $gzip = R_getenv("R_GZIPCMD", "gzip");
169
 
169
 
170
my $R_opts = "--vanilla";
170
my $R_opts = "--vanilla";
171
 
171
 
172
if($opt_latex) {
172
if($opt_latex) {
173
    my $log = new R::Logfile();
173
    my $log = new R::Logfile();
174
    $log->checking("for working latex");
174
    $log->checking("for working latex");
175
    open(TEXFILE,
175
    open(TEXFILE,
176
	 "> " . &file_path(${R::Vars::TMPDIR}, "Rtextest$$.tex"))
176
	 "> " . &file_path(${R::Vars::TMPDIR}, "Rtextest$$.tex"))
177
      or die "Error: cannot open file 'Rtextest$$.tex' for writing\n";
177
      or die "Error: cannot open file 'Rtextest$$.tex' for writing\n";
178
    print TEXFILE "\\documentclass\{article\}\\begin\{document\}" .
178
    print TEXFILE "\\documentclass\{article\}\\begin\{document\}" .
179
	"test\\end\{document\}\n";
179
	"test\\end\{document\}\n";
180
    close(TEXFILE);
180
    close(TEXFILE);
181
    chdir($R::Vars::TMPDIR);
181
    chdir($R::Vars::TMPDIR);
182
    if(R_system("${R::Vars::LATEX} Rtextest$$ > Rtextest$$.out")) {
182
    if(R_system("${R::Vars::LATEX} Rtextest$$ > Rtextest$$.out")) {
183
	$log->result("NO");
183
	$log->result("NO");
184
	$HAVE_LATEX = 0;
184
	$HAVE_LATEX = 0;
185
    } else {
185
    } else {
186
	$log->result("OK");
186
	$log->result("OK");
187
	$HAVE_LATEX = 1;
187
	$HAVE_LATEX = 1;
188
    }
188
    }
189
    unlink(<Rtextest$$.*>);
189
    unlink(<Rtextest$$.*>);
190
    chdir($startdir);
190
    chdir($startdir);
191
    $log->close();
191
    $log->close();
192
}
192
}
193
 
193
 
194
## This is the main loop over all packages to be checked.
194
## This is the main loop over all packages to be checked.
195
(scalar(@ARGV) > 0) or die "Error: no packages were specified\n";
195
(scalar(@ARGV) > 0) or die "Error: no packages were specified\n";
196
foreach my $pkg (@ARGV) {
196
foreach my $pkg (@ARGV) {
197
    ## $pkg should be the path to the package (bundle) root source
197
    ## $pkg should be the path to the package (bundle) root source
198
    ## directory, either absolute or relative to $startdir.
198
    ## directory, either absolute or relative to $startdir.
199
    ## As from 2.1.0 it can also be a tarball
199
    ## As from 2.1.0 it can also be a tarball
200
 
200
 
201
    ## $pkgdir is the corresponding absolute path.
201
    ## $pkgdir is the corresponding absolute path.
202
    ## $pkgname is the name of the package (bundle).
202
    ## $pkgname is the name of the package (bundle).
203
    chdir($startdir);
203
    chdir($startdir);
204
    $pkg =~ s+/$++;  # strip any trailing '/'
204
    $pkg =~ s+/$++;  # strip any trailing '/'
205
    my $pkgname = basename($pkg);
205
    my $pkgname = basename($pkg);
206
 
206
 
207
    my $thispkg_subdirs = $opt_subdirs;
207
    my $thispkg_subdirs = $opt_subdirs;
208
    ## is this a tar archive?
208
    ## is this a tar archive?
209
    my $istar = 0;
209
    my $istar = 0;
210
    if($pkgname =~ /\.tar\.gz$/ || $pkgname =~ /\.tgz$/) {
210
    if($pkgname =~ /\.tar\.gz$/ || $pkgname =~ /\.tgz$/) {
211
	$pkgname =~ s/\.tar\.gz$//;
211
	$pkgname =~ s/\.tar\.gz$//;
212
	$pkgname =~ s/\.tgz$//;
212
	$pkgname =~ s/\.tgz$//;
213
	$pkgname =~ s/_[0-9\.-]*$//;
213
	$pkgname =~ s/_[0-9\.-]*$//;
214
	$istar = 1;
214
	$istar = 1;
215
	$thispkg_subdirs = "yes-maybe" if $thispkg_subdirs eq "default";
215
	$thispkg_subdirs = "yes-maybe" if $thispkg_subdirs eq "default";
216
    } else {
216
    } else {
217
	$thispkg_subdirs = "no" if $thispkg_subdirs eq "default";
217
	$thispkg_subdirs = "no" if $thispkg_subdirs eq "default";
218
    }
218
    }
219
 
219
 
220
    my $pkgoutdir = &file_path($outdir, "$pkgname.Rcheck");
220
    my $pkgoutdir = &file_path($outdir, "$pkgname.Rcheck");
221
    rmtree($pkgoutdir) if ($opt_clean && (-d $pkgoutdir)) ;
221
    rmtree($pkgoutdir) if ($opt_clean && (-d $pkgoutdir)) ;
222
    if(!(-d $pkgoutdir)) {
222
    if(!(-d $pkgoutdir)) {
223
	mkdir($pkgoutdir, 0755)
223
	mkdir($pkgoutdir, 0755)
224
	  or die("Error: cannot create directory '$pkgoutdir'\n");
224
	  or die("Error: cannot create directory '$pkgoutdir'\n");
225
    }
225
    }
226
 
226
 
227
    if($istar) {
227
    if($istar) {
228
	my $dir = &file_path("$pkgoutdir", "00_pkg_src");
228
	my $dir = &file_path("$pkgoutdir", "00_pkg_src");
229
	mkdir($dir, 0755)
229
	mkdir($dir, 0755)
230
	  or die("Error: cannot create directory '$dir'\n");
230
	  or die("Error: cannot create directory '$dir'\n");
231
	if($WINDOWS) {
231
	if($WINDOWS) {
232
	    ## workaround for paths in Cygwin tar
232
	    ## workaround for paths in Cygwin tar
233
	    $pkg =~ s+^([A-Za-z]):+/cygdrive/\1+;
233
	    $pkg =~ s+^([A-Za-z]):+/cygdrive/\1+;
234
	}
234
	}
235
	## this requires GNU tar: ATT 'tar x' does not support -C.
235
	## this requires GNU tar: ATT 'tar x' does not support -C.
236
	if(R_system("$gzip -dc '$pkg' | $tar -xf - -C $dir")) {
236
	if(R_system("$gzip -dc '$pkg' | $tar -xf - -C $dir")) {
237
	    die "Error: cannot untar $pkg\n";}
237
	    die "Error: cannot untar $pkg\n";}
238
	$pkg = &file_path($dir, $pkgname);
238
	$pkg = &file_path($dir, $pkgname);
239
    }
239
    }
240
 
240
 
241
    $pkg =~ s/\/$//;
241
    $pkg =~ s/\/$//;
242
    (-d $pkg) or die "Error: package dir '$pkg' does not exist\n";
242
    (-d $pkg) or die "Error: package dir '$pkg' does not exist\n";
243
    chdir($pkg)
243
    chdir($pkg)
244
	or die "Error: cannot change to directory '$pkg'\n";
244
	or die "Error: cannot change to directory '$pkg'\n";
245
    my $pkgdir = R_cwd();
245
    my $pkgdir = R_cwd();
246
    ## my $pkgname = basename($pkgdir);
246
    ## my $pkgname = basename($pkgdir);
247
    my $thispkg_src_subdir = $thispkg_subdirs;
247
    my $thispkg_src_subdir = $thispkg_subdirs;
248
    if($thispkg_src_subdir eq "yes-maybe") {
248
    if($thispkg_src_subdir eq "yes-maybe") {
249
	## now see if there is a 'configure' file
249
	## now see if there is a 'configure' file
250
	## configure files are only used if executable, but
250
	## configure files are only used if executable, but
251
	## -x is always false on Windows.
251
	## -x is always false on Windows.
252
	if($WINDOWS) {
252
	if($WINDOWS) {
253
	    $thispkg_src_subdir = "no" if (-f "configure");
253
	    $thispkg_src_subdir = "no" if (-f "configure");
254
	} else {
254
	} else {
255
	    $thispkg_src_subdir = "no" if (-x "configure");
255
	    $thispkg_src_subdir = "no" if (-x "configure");
256
	}
256
	}
257
    }
257
    }
258
    chdir($startdir);
258
    chdir($startdir);
259
 
259
 
260
    $log = new R::Logfile(&file_path($pkgoutdir, "00check.log"));
260
    $log = new R::Logfile(&file_path($pkgoutdir, "00check.log"));
261
    $log->message("using log directory '$pkgoutdir'");
261
    $log->message("using log directory '$pkgoutdir'");
262
    my @out = R_runR("cat(R.version.string, '\n', sep='')",
262
    my @out = R_runR("cat(R.version.string, '\n', sep='')",
263
		     "--slave --vanilla");
263
		     "--slave --vanilla");
264
    $log->message("using @out");
264
    $log->message("using @out");
265
 
265
 
266
    if(!$opt_library) {
266
    if(!$opt_library) {
267
	$library = $pkgoutdir;
267
	$library = $pkgoutdir;
268
	$ENV{'R_LIBS'} = env_path($library, $R_LIBS);
268
	$ENV{'R_LIBS'} = env_path($library, $R_LIBS);
269
    }
269
    }
270
    if($WINDOWS) { ## need to avoid spaces in $library
270
    if($WINDOWS) { ## need to avoid spaces in $library
271
	$library = Win32::GetShortPathName($library) if $library =~ / /;
271
	$library = Win32::GetShortPathName($library) if $library =~ / /;
272
    }
272
    }
273
 
273
 
274
    my $description;
274
    my $description;
275
    my $is_base_pkg = 0;
275
    my $is_base_pkg = 0;
276
    my $is_bundle = 0;
276
    my $is_bundle = 0;
277
    my $package_or_bundle = "package";
277
    my $package_or_bundle = "package";
278
    my $package_or_bundle_name;
278
    my $package_or_bundle_name;
279
    ## Package sources from the R distribution are special.  They have a
279
    ## Package sources from the R distribution are special.  They have a
280
    ## 'DESCRIPTION.in' file (instead of 'DESCRIPTION'), with Version
280
    ## 'DESCRIPTION.in' file (instead of 'DESCRIPTION'), with Version
281
    ## field containing '@VERSION@' for substitution by configure.  We
281
    ## field containing '@VERSION@' for substitution by configure.  We
282
    ## test for such packages by looking for 'DESCRIPTION.in' with
282
    ## test for such packages by looking for 'DESCRIPTION.in' with
283
    ## Priority 'base', and skip the installation test for such
283
    ## Priority 'base', and skip the installation test for such
284
    ## packages.
284
    ## packages.
285
    if(-r &file_path($pkgdir, "DESCRIPTION.in")) {
285
    if(-r &file_path($pkgdir, "DESCRIPTION.in")) {
286
	$description =
286
	$description =
287
	  new R::Dcf(&file_path($pkgdir, "DESCRIPTION.in"));
287
	  new R::Dcf(&file_path($pkgdir, "DESCRIPTION.in"));
288
	if($description->{"Priority"} eq "base") {
288
	if($description->{"Priority"} eq "base") {
289
	    $log->message("looks like '${pkgname}' is a base package");
289
	    $log->message("looks like '${pkgname}' is a base package");
290
	    $log->message("skipping installation test");
290
	    $log->message("skipping installation test");
291
	    $is_base_pkg = 1;
291
	    $is_base_pkg = 1;
292
	}
292
	}
293
    }
293
    }
294
 
294
 
295
    if(!$is_base_pkg) {
295
    if(!$is_base_pkg) {
296
	$log->checking(join("",
296
	$log->checking(join("",
297
			    ("for file '",
297
			    ("for file '",
298
			     &file_path($pkgname, "DESCRIPTION"),
298
			     &file_path($pkgname, "DESCRIPTION"),
299
			     "'")));
299
			     "'")));
300
	if(-r &file_path($pkgdir, "DESCRIPTION")) {
300
	if(-r &file_path($pkgdir, "DESCRIPTION")) {
301
	    $description =
301
	    $description =
302
	      new R::Dcf(&file_path($pkgdir, "DESCRIPTION"));
302
	      new R::Dcf(&file_path($pkgdir, "DESCRIPTION"));
303
	    $log->result("OK");
303
	    $log->result("OK");
304
	}
304
	}
305
	else {
305
	else {
306
	    $log->result("NO");
306
	    $log->result("NO");
307
	    exit(1);
307
	    exit(1);
308
	}
308
	}
309
	if($description->{"Type"}) { # standard packages do not have this
309
	if($description->{"Type"}) { # standard packages do not have this
310
	    $log->checking("extension type");
310
	    $log->checking("extension type");
311
	    $log->result($description->{"Type"});
311
	    $log->result($description->{"Type"});
312
	    if($description->{"Type"} ne "Package") {
312
	    if($description->{"Type"} ne "Package") {
313
		$log->print("Only Type = Package extensions can be checked.\n");
313
		$log->print("Only Type = Package extensions can be checked.\n");
314
		exit(0);
314
		exit(0);
315
	    }
315
	    }
316
	}
316
	}
317
 
317
 
318
	if($description->{"Bundle"}) {
318
	if($description->{"Bundle"}) {
319
	    $is_bundle = 1;
319
	    $is_bundle = 1;
320
	    $log->message("looks like '${pkgname}' is a package bundle");
320
	    $log->message("looks like '${pkgname}' is a package bundle");
321
	    $package_or_bundle = "bundle";
321
	    $package_or_bundle = "bundle";
322
	    $package_or_bundle_name = $description->{"Bundle"};
322
	    $package_or_bundle_name = $description->{"Bundle"};
323
	}
323
	}
324
	else {
324
	else {
325
	    $package_or_bundle_name = $description->{"Package"};
325
	    $package_or_bundle_name = $description->{"Package"};
326
	}
326
	}
327
	$log->message("this is $package_or_bundle " .
327
	$log->message("this is $package_or_bundle " .
328
		      "'$package_or_bundle_name' " .
328
		      "'$package_or_bundle_name' " .
329
		      "version '$description->{\"Version\"}'");
329
		      "version '$description->{\"Version\"}'");
330
 
330
 
331
	## Check package dependencies.
331
	## Check package dependencies.
332
 
332
 
333
	## <NOTE>
333
	## <NOTE>
334
	## We want to check for dependencies early, since missing
334
	## We want to check for dependencies early, since missing
335
	## dependencies may make installation fail, and in any case we
335
	## dependencies may make installation fail, and in any case we
336
	## give up if they are missing.  But we don't check them if
336
	## give up if they are missing.  But we don't check them if
337
	## we are not going to install and hence not run any code.
337
	## we are not going to install and hence not run any code.
338
	## </NOTE>
338
	## </NOTE>
339
 
339
 
340
	if($opt_install) { 
340
	if($opt_install) { 
341
	    ## Try figuring out whether the package dependencies can be 
341
	    ## Try figuring out whether the package dependencies can be 
342
	    ## resolved at run time.  
342
	    ## resolved at run time.  
343
	    ## Ideally, the installation mechanism would do this,
343
	    ## Ideally, the installation mechanism would do this,
344
	    ## and we also do not check versions ... also see whether vignette
344
	    ## and we also do not check versions ... also see whether vignette
345
	    ## and namespace package dependencies are recorded in DESCRIPTION.
345
	    ## and namespace package dependencies are recorded in DESCRIPTION.
346
	    
346
	    
347
	    ## <NOTE>
347
	    ## <NOTE>
348
	    ## We are not checking base packages here, so all packages do 
348
	    ## We are not checking base packages here, so all packages do 
349
	    ## have a description file.  Bundles should have dependencies 
349
	    ## have a description file.  Bundles should have dependencies 
350
	    ## only at the top level to be usable by install.packages and 
350
	    ## only at the top level to be usable by install.packages and 
351
	    ## friends, and `Writing R Extensions' requires this.
351
	    ## friends, and `Writing R Extensions' requires this.
352
	    ## </NOTE>
352
	    ## </NOTE>
353
 
353
 
354
	    $log->checking("package dependencies");
354
	    $log->checking("package dependencies");
355
	    ## Everything listed in Depends or Suggests or Imports
355
	    ## Everything listed in Depends or Suggests or Imports
356
	    ## should be available for successfully running R CMD check.
356
	    ## should be available for successfully running R CMD check.
357
	    ## \VignetteDepends{} entries not "required" by the package code
357
	    ## \VignetteDepends{} entries not "required" by the package code
358
	    ## must be in Suggests.  Note also that some of us think that a
358
	    ## must be in Suggests.  Note also that some of us think that a
359
	    ## package vignette must require its own package, which OTOH is
359
	    ## package vignette must require its own package, which OTOH is
360
	    ## not required in the package DESCRIPTION file.
360
	    ## not required in the package DESCRIPTION file.
361
	    ## Namespace imports must really be in Depends.
361
	    ## Namespace imports must really be in Depends.
362
	    my $Rcmd = "tools:::.check_package_depends(\"${pkgdir}\")\n";
362
	    my $Rcmd = "tools:::.check_package_depends(\"${pkgdir}\")\n";
363
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
363
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
364
			     "R_DEFAULT_PACKAGES=NULL");
364
			     "R_DEFAULT_PACKAGES=NULL");
365
	    @out = grep(!/^\>/, @out);
365
	    @out = grep(!/^\>/, @out);
366
	    if(scalar(@out) > 0) {
366
	    if(scalar(@out) > 0) {
367
		$log->error();
367
		$log->error();
368
		$log->print(join("\n", @out) . "\n");
368
		$log->print(join("\n", @out) . "\n");
369
		$log->print(wrap("", "", @msg_DESCRIPTION));
369
		$log->print(wrap("", "", @msg_DESCRIPTION));
370
		exit(1);
370
		exit(1);
371
	    } else {
371
	    } else {
372
		$log->result("OK");
372
		$log->result("OK");
373
	    }
373
	    }
374
	}
374
	}
375
 
375
 
376
	## <NOTE>
376
	## <NOTE>
377
	## This check should be adequate, but would not catch a manually
377
	## This check should be adequate, but would not catch a manually
378
	## installed package, nor one installed prior to 1.4.0.
378
	## installed package, nor one installed prior to 1.4.0.
379
	## </NOTE>
379
	## </NOTE>
380
	$log->checking("if this is a source $package_or_bundle");
380
	$log->checking("if this is a source $package_or_bundle");
381
	if(defined($description->{"Built"})) {
381
	if(defined($description->{"Built"})) {
382
	    $log->error();
382
	    $log->error();
383
	    $log->print("Only *source* packages can be checked.\n");
383
	    $log->print("Only *source* packages can be checked.\n");
384
	    exit(1);
384
	    exit(1);
385
	}
385
	}
386
	elsif($opt_install !~ /^check/) {
386
	elsif($opt_install !~ /^check/) {
387
	    ## Check for package/bundle 'src' subdirectories with object
387
	    ## Check for package/bundle 'src' subdirectories with object
388
	    ## files (but not if installation was already performed).
388
	    ## files (but not if installation was already performed).
389
	    my $any;
389
	    my $any;
390
	    my $pat = "(a|o|[ls][ao]|sl|obj)"; # Object file extensions.
390
	    my $pat = "(a|o|[ls][ao]|sl|obj)"; # Object file extensions.
391
	    my @dirs;
391
	    my @dirs;
392
	    if($is_bundle) {
392
	    if($is_bundle) {
393
		foreach my $ppkg (split(/\s+/,
393
		foreach my $ppkg (split(/\s+/,
394
					$description->{"Contains"})) {
394
					$description->{"Contains"})) {
395
		    push(@dirs, &file_path($ppkg, "src"));
395
		    push(@dirs, &file_path($ppkg, "src"));
396
		}
396
		}
397
	    }
397
	    }
398
	    else {
398
	    else {
399
		@dirs = ("src");
399
		@dirs = ("src");
400
	    }
400
	    }
401
	    foreach my $dir (@dirs) {
401
	    foreach my $dir (@dirs) {
402
		if((-d &file_path($pkgdir, $dir))
402
		if((-d &file_path($pkgdir, $dir))
403
		   && &list_files_with_exts(&file_path($pkgdir, $dir),
403
		   && &list_files_with_exts(&file_path($pkgdir, $dir),
404
					    $pat)) {
404
					    $pat)) {
405
		    $log->warning() unless $any;
405
		    $log->warning() unless $any;
406
		    $any++;
406
		    $any++;
407
		    $dir = &file_path($pkgname, $dir);
407
		    $dir = &file_path($pkgname, $dir);
408
		    $log->print("Subdirectory '$dir' " .
408
		    $log->print("Subdirectory '$dir' " .
409
				"contains object files.\n");
409
				"contains object files.\n");
410
		}
410
		}
411
	    }
411
	    }
412
 
412
 
413
	    if($thispkg_src_subdir ne "no") {
413
	    if($thispkg_src_subdir ne "no") {
414
		foreach my $dir (@dirs) {
414
		foreach my $dir (@dirs) {
415
		    if((-d &file_path($pkgdir, $dir))) {
415
		    if((-d &file_path($pkgdir, $dir))) {
416
			chdir(&file_path($pkgdir, $dir));
416
			chdir(&file_path($pkgdir, $dir));
417
			if(!(-f "Makefile") && !(-f "Makefile.win")) {
417
			if(!(-f "Makefile") && !(-f "Makefile.win")) {
418
			    opendir(DIR, ".") or die "cannot opendir $dir: $!";
418
			    opendir(DIR, ".") or die "cannot opendir $dir: $!";
419
			    @srcfiles = grep { 
419
			    @srcfiles = grep { 
420
				!(/\.([Ccfh]|cc|cpp|f90|f95)$/
420
				!(/\.([Ccfh]|cc|cpp|f90|f95)$/
421
				  || /^Makevars/ || /-win\.def$/ )
421
				  || /^Makevars/ || /-win\.def$/ )
422
				    && -f "$_" } readdir(DIR);
422
				    && -f "$_" } readdir(DIR);
423
			    closedir(DIR);
423
			    closedir(DIR);
424
			    if(@srcfiles) {
424
			    if(@srcfiles) {
425
				$log->warning() unless $any;
425
				$log->warning() unless $any;
426
				$any++;
426
				$any++;
427
				$log->print("Subdirectory '$dir' contains:\n");
427
				$log->print("Subdirectory '$dir' contains:\n");
428
				$log->print(wrap("  ", "  ",
428
				$log->print(wrap("  ", "  ",
429
						 join(" ", sort @srcfiles) . "\n"));
429
						 join(" ", sort @srcfiles) . "\n"));
430
				$log->print(wrap("", "",
430
				$log->print(wrap("", "",
431
						 ("These are unlikely file names",
431
						 ("These are unlikely file names",
432
						  "for src files.\n")));
432
						  "for src files.\n")));
433
			    }
433
			    }
434
			}
434
			}
435
			chdir($startdir);
435
			chdir($startdir);
436
		    }
436
		    }
437
		}
437
		}
438
	    }
438
	    }
439
	    $log->result("OK") unless $any;
439
	    $log->result("OK") unless $any;
440
	}
440
	}
441
	else {
441
	else {
442
	    $log->result("OK");
442
	    $log->result("OK");
443
	}
443
	}
444
 
444
 
445
	## Option '--no-install' turns off installation and the tests
445
	## Option '--no-install' turns off installation and the tests
446
	## which require the package to be installed.  When testing
446
	## which require the package to be installed.  When testing
447
	## recommended packages bundled with R we can skip installation,
447
	## recommended packages bundled with R we can skip installation,
448
	## and do so if '--install=skip' was given.  If command line
448
	## and do so if '--install=skip' was given.  If command line
449
	## option '--install' is of the form 'check:FILE', it is assumed
449
	## option '--install' is of the form 'check:FILE', it is assumed
450
	## that installation was already performed with stdout/stderr to
450
	## that installation was already performed with stdout/stderr to
451
	## FILE, the contents of which need to be checked (without
451
	## FILE, the contents of which need to be checked (without
452
	## repeating the installation).
452
	## repeating the installation).
453
	## <NOTE>
453
	## <NOTE>
454
	## In this case, one also needs to specify *where* the package
454
	## In this case, one also needs to specify *where* the package
455
	## was installed to using command line option '--library'.
455
	## was installed to using command line option '--library'.
456
	## Perhaps we should check for that, although '--install=check'
456
	## Perhaps we should check for that, although '--install=check'
457
	## is really only meant for repository maintainers.
457
	## is really only meant for repository maintainers.
458
	## </NOTE>
458
	## </NOTE>
459
	if($opt_install) {
459
	if($opt_install) {
460
	    if($opt_install eq "skip") {
460
	    if($opt_install eq "skip") {
461
		$log->message("skipping installation test");
461
		$log->message("skipping installation test");
462
	    }
462
	    }
463
	    else {
463
	    else {
464
		my $use_install_log =
464
		my $use_install_log =
465
		    (($opt_install =~ /^check/) ||
465
		    (($opt_install =~ /^check/) ||
466
		     $R_check_use_install_log ||
466
		     $R_check_use_install_log ||
467
		     !(-t STDIN && -t STDOUT));
467
		     !(-t STDIN && -t STDOUT));
468
		my $INSTALL_opts = "";
468
		my $INSTALL_opts = "";
469
		$INSTALL_opts = "--fake" if($opt_install eq "fake");
469
		$INSTALL_opts = "--fake" if($opt_install eq "fake");
470
		my $cmd;
470
		my $cmd;
471
		if($WINDOWS) {
471
		if($WINDOWS) {
472
		    $cmd = join(" ",
472
		    $cmd = join(" ",
473
				("Rcmd.exe INSTALL -l",
473
				("Rcmd.exe INSTALL -l",
474
				 &shell_quote_file_path($library),
474
				 &shell_quote_file_path($library),
475
				 "$INSTALL_opts",
475
				 "$INSTALL_opts",
476
				 &shell_quote_file_path($pkgdir)));
476
				 &shell_quote_file_path($pkgdir)));
477
		} else {
477
		} else {
478
		    $cmd = join(" ",
478
		    $cmd = join(" ",
479
				(&shell_quote_file_path(${R::Vars::R_EXE}),
479
				(&shell_quote_file_path(${R::Vars::R_EXE}),
480
				 "CMD INSTALL -l",
480
				 "CMD INSTALL -l",
481
				 &shell_quote_file_path($library),
481
				 &shell_quote_file_path($library),
482
				 "$INSTALL_opts",
482
				 "$INSTALL_opts",
483
				 &shell_quote_file_path($pkgdir)));
483
				 &shell_quote_file_path($pkgdir)));
484
		}
484
		}
485
		if(!$use_install_log) {
485
		if(!$use_install_log) {
486
		    ## Case A: No redirection of stdout/stderr from
486
		    ## Case A: No redirection of stdout/stderr from
487
		    ## installation.
487
		    ## installation.
488
		    print("\n");
488
		    print("\n");
489
		    if(R_system($cmd)) {
489
		    if(R_system($cmd)) {
490
			$log->error();
490
			$log->error();
491
			$log->print("Installation failed.\n");
491
			$log->print("Installation failed.\n");
492
			exit(1);
492
			exit(1);
493
		    }
493
		    }
494
		    print("\n");
494
		    print("\n");
495
		}
495
		}
496
		else {
496
		else {
497
		    ## Case B. All output from installation redirected,
497
		    ## Case B. All output from installation redirected,
498
		    ## or already available in the log file.
498
		    ## or already available in the log file.
499
		    $log->checking("whether $package_or_bundle " .
499
		    $log->checking("whether $package_or_bundle " .
500
				   "'$package_or_bundle_name' " .
500
				   "'$package_or_bundle_name' " .
501
				   "can be installed");
501
				   "can be installed");
502
		    my $out = &file_path($pkgoutdir, "00install.out");
502
		    my $out = &file_path($pkgoutdir, "00install.out");
503
		    my $install_error;
503
		    my $install_error;
504
		    my @lines;
504
		    my @lines;
505
		    if($opt_install =~ /^check/) {
505
		    if($opt_install =~ /^check/) {
506
			copy(substr($opt_install, 6), $out);
506
			copy(substr($opt_install, 6), $out);
507
			$opt_install = "check";
507
			$opt_install = "check";
508
			@lines = &read_lines($out);
508
			@lines = &read_lines($out);
509
			## <NOTE>
509
			## <NOTE>
510
			## We used to have
510
			## We used to have
511
			## $install_error =
511
			## $install_error =
512
			##    ($lines[$#lines] !~ /^\* DONE/);
512
			##    ($lines[$#lines] !~ /^\* DONE/);
513
			## but what if there is output from do_cleanup
513
			## but what if there is output from do_cleanup
514
			## in (Unix) R CMD INSTALL?
514
			## in (Unix) R CMD INSTALL?
515
			$install_error =
515
			$install_error =
516
			    (scalar(grep(/^\* DONE/, @lines)) == 0);
516
			    (scalar(grep(/^\* DONE/, @lines)) == 0);
517
		    }
517
		    }
518
		    else {
518
		    else {
519
			$cmd .= " >" .
519
			$cmd .= " >" .
520
			    &shell_quote_file_path($out) .
520
			    &shell_quote_file_path($out) .
521
			    " 2>&1";
521
			    " 2>&1";
522
			$install_error = &R_system($cmd);
522
			$install_error = &R_system($cmd);
523
			if($WINDOWS) {
523
			if($WINDOWS) {
524
			    ## MS Html Help Compiler gives lines terminated
524
			    ## MS Html Help Compiler gives lines terminated
525
			    ## by CRCRLF, so we clean up the log file.
525
			    ## by CRCRLF, so we clean up the log file.
526
			    my $line;
526
			    my $line;
527
			    ## read_lines does chomp.
527
			    ## read_lines does chomp.
528
			    @lines = &read_lines($out);
528
			    @lines = &read_lines($out);
529
			    open(FILE, "> $out")
529
			    open(FILE, "> $out")
530
				or die "Error: cannot open file '$out' for re-writing\n";
530
				or die "Error: cannot open file '$out' for re-writing\n";
531
			    foreach $line (@lines) {
531
			    foreach $line (@lines) {
532
				$line =~ s/\r$//;
532
				$line =~ s/\r$//;
533
				print FILE $line, "\n";
533
				print FILE $line, "\n";
534
			    }
534
			    }
535
			    close(FILE);
535
			    close(FILE);
536
			}
536
			}
537
		    }
537
		    }
538
		    if($install_error) {
538
		    if($install_error) {
539
			$log->error();
539
			$log->error();
540
			$log->print("Installation failed.\n");
540
			$log->print("Installation failed.\n");
541
			$log->print("See '$out' for details.\n");
541
			$log->print("See '$out' for details.\n");
542
			exit(1);
542
			exit(1);
543
		    }
543
		    }
544
		    ## There could still be some important warnings that
544
		    ## There could still be some important warnings that
545
		    ## we'd like to report.  For the time being, start
545
		    ## we'd like to report.  For the time being, start
546
		    ## with compiler warnings about non ISO C code (Or
546
		    ## with compiler warnings about non ISO C code (Or
547
		    ## at least, what looks like it.)  In theory, we
547
		    ## at least, what looks like it.)  In theory, we
548
		    ## should only do this when using GCC ...
548
		    ## should only do this when using GCC ...
549
		    @lines = &read_lines($out)
549
		    @lines = &read_lines($out)
550
			unless($opt_install eq "check");
550
			unless($opt_install eq "check");
551
		    my $warn_re =
551
		    my $warn_re =
552
			"(" . join("|", ("^WARNING:",
552
			"(" . join("|", ("^WARNING:",
553
					 "^Warning:",
553
					 "^Warning:",
554
					 ": warning: .*ISO C",
554
					 ": warning: .*ISO C",
555
					 "missing link\\(s\\):")) . ")";
555
					 "missing link\\(s\\):")) . ")";
556
		    @lines = grep(/$warn_re/, @lines);
556
		    @lines = grep(/$warn_re/, @lines);
557
 
557
 
558
		    ## Ignore install time readLines() warnings about
558
		    ## Ignore install time readLines() warnings about
559
		    ## files with incomplete final lines.  Most of these
559
		    ## files with incomplete final lines.  Most of these
560
		    ## come from .install_package_indices(), and should be
560
		    ## come from .install_package_indices(), and should be
561
		    ## safe to ignore ...
561
		    ## safe to ignore ...
562
		    $warn_re = "Warning: incomplete final line " .
562
		    $warn_re = "Warning: incomplete final line " .
563
			"found by readLines";
563
			"found by readLines";
564
		    @lines = grep(!/$warn_re/, @lines);
564
		    @lines = grep(!/$warn_re/, @lines);
565
 
565
 
566
		    ## Package writers cannot really do anything about
566
		    ## Package writers cannot really do anything about
567
		    ## non ISO C code in *system* headers.  Also, GCC
567
		    ## non ISO C code in *system* headers.  Also, GCC
568
		    ## 3.4 or better warns about function pointers
568
		    ## 3.4 or better warns about function pointers
569
		    ## casts which are "needed" for dlsym(), but it
569
		    ## casts which are "needed" for dlsym(), but it
570
		    ## seems that all systems which have dlsym() also
570
		    ## seems that all systems which have dlsym() also
571
		    ## support the cast.  Hence, try to ignore these by
571
		    ## support the cast.  Hence, try to ignore these by
572
		    ## default, but make it possible to get all ISO C
572
		    ## default, but make it possible to get all ISO C
573
		    ## warnings via an environment variable.
573
		    ## warnings via an environment variable.
574
		    if(!$R_check_all_non_ISO_C) {
574
		    if(!$R_check_all_non_ISO_C) {
575
			@lines = grep(!/^ *\/.*: warning: .*ISO C/,
575
			@lines = grep(!/^ *\/.*: warning: .*ISO C/,
576
				      @lines);
576
				      @lines);
577
			$warn_re = "warning: *ISO C forbids.*" .
577
			$warn_re = "warning: *ISO C forbids.*" .
578
			    "function pointer";
578
			    "function pointer";
579
			@lines = grep(!/$warn_re/, @lines);
579
			@lines = grep(!/$warn_re/, @lines);
580
		    }
580
		    }
581
 
581
 
582
		    ## Warnings spotted by gfortran 4.0 or better with
582
		    ## Warnings spotted by gfortran 4.0 or better with
583
		    ## -Wall.  Justified in principle, it seems.  Let's
583
		    ## -Wall.  Justified in principle, it seems.  Let's
584
		    ## filter them for the time being, and maybe revert
584
		    ## filter them for the time being, and maybe revert
585
		    ## this lateron ... but make it possible to suppress
585
		    ## this lateron ... but make it possible to suppress
586
		    ## filtering out by setting the internal environment
586
		    ## filtering out by setting the internal environment
587
		    ## variable _R_CHECK_WALL_FORTRAN_ to something
587
		    ## variable _R_CHECK_WALL_FORTRAN_ to something
588
		    ## "true".
588
		    ## "true".
589
		    my $R_check_Wall_FORTRAN =
589
		    my $R_check_Wall_FORTRAN =
590
			&R_getenv("_R_CHECK_WALL_FORTRAN_", "FALSE");
590
			&R_getenv("_R_CHECK_WALL_FORTRAN_", "FALSE");
591
		    $R_check_Wall_FORTRAN =
591
		    $R_check_Wall_FORTRAN =
592
			&config_val_to_logical($R_check_Wall_FORTRAN);
592
			&config_val_to_logical($R_check_Wall_FORTRAN);
593
		    if(!$R_check_Wall_FORTRAN) {
593
		    if(!$R_check_Wall_FORTRAN) {
594
			my $warn_re =
594
			my $warn_re =
595
			    "(" .
595
			    "(" .
596
			    join("|",
596
			    join("|",
597
				 ("Label .* at \\(1\\) defined but not used",
597
				 ("Label .* at \\(1\\) defined but not used",
598
				  "Line truncated at \\(1\\)",
598
				  "Line truncated at \\(1\\)",
599
				  "ASSIGN statement at \\(1\\)",
599
				  "ASSIGN statement at \\(1\\)",
600
				  "Assigned GOTO statement at \\(1\\)",
600
				  "Assigned GOTO statement at \\(1\\)",
601
				  "arithmetic IF statement at \\(1\\)")) .
601
				  "arithmetic IF statement at \\(1\\)")) .
602
			    ")";
602
			    ")";
603
			@lines = grep(!/$warn_re/, @lines);
603
			@lines = grep(!/$warn_re/, @lines);
604
		    }
604
		    }
605
 
605
 
606
		    if(scalar(@lines) > 0) {
606
		    if(scalar(@lines) > 0) {
607
			$log->warning();
607
			$log->warning();
608
			$log->print("Found the following " .
608
			$log->print("Found the following " .
609
				    "significant warnings:\n");
609
				    "significant warnings:\n");
610
			$log->print("  " . join("\n  ", @lines) . "\n");
610
			$log->print("  " . join("\n  ", @lines) . "\n");
611
		    }
611
		    }
612
		    else {
612
		    else {
613
			$log->result("OK");
613
			$log->result("OK");
614
		    }
614
		    }
615
		}
615
		}
616
	    }
616
	    }
617
	}
617
	}
618
 
618
 
619
    }
619
    }
620
 
620
 
621
    if($is_bundle) {
621
    if($is_bundle) {
622
	my @bundlepkgs = split(/\s+/, $description->{"Contains"});
622
	my @bundlepkgs = split(/\s+/, $description->{"Contains"});
623
	foreach my $ppkg (@bundlepkgs) {
623
	foreach my $ppkg (@bundlepkgs) {
624
	    $log->message("checking '$ppkg' in bundle '$pkgname'");
624
	    $log->message("checking '$ppkg' in bundle '$pkgname'");
625
	    $log->setstars("**");
625
	    $log->setstars("**");
626
	    chdir($startdir);
626
	    chdir($startdir);
627
	    check_pkg(&file_path($pkgdir, $ppkg), $pkgoutdir, $startdir,
627
	    check_pkg(&file_path($pkgdir, $ppkg), $pkgoutdir, $startdir,
628
		      $library, $is_bundle, $description, $log,
628
		      $library, $is_bundle, $description, $log,
629
		      $is_base_pkg);
629
		      $is_base_pkg);
630
	    $log->setstars("*");
630
	    $log->setstars("*");
631
	}
631
	}
632
    }
632
    }
633
    else {
633
    else {
634
	chdir($startdir);
634
	chdir($startdir);
635
	check_pkg($pkgdir, $pkgoutdir, $startdir, $library,
635
	check_pkg($pkgdir, $pkgoutdir, $startdir, $library,
636
		  $is_bundle, $description, $log, $is_base_pkg, 
636
		  $is_bundle, $description, $log, $is_base_pkg, 
637
		  $thispkg_subdirs);
637
		  $thispkg_subdirs);
638
    }
638
    }
639
 
639
 
640
    if($log->{"warnings"}) {
640
    if($log->{"warnings"}) {
641
	print("\n") ;
641
	print("\n") ;
642
	$log->summary();
642
	$log->summary();
643
    }
643
    }
644
    $log->close();
644
    $log->close();
645
    print("\n");
645
    print("\n");
646
}
646
}
647
 
647
 
648

648

649
sub check_pkg {
649
sub check_pkg {
650
 
650
 
651
    my ($pkg, $pkgoutdir, $startdir, $library,
651
    my ($pkg, $pkgoutdir, $startdir, $library,
652
	$in_bundle, $description, $log, $is_base_pkg, $subdirs) = @_;
652
	$in_bundle, $description, $log, $is_base_pkg, $subdirs) = @_;
653
    my ($pkgdir, $pkgname);
653
    my ($pkgdir, $pkgname);
654
 
654
 
655
    ## $pkg is the argument we received from the main loop.
655
    ## $pkg is the argument we received from the main loop.
656
    ## $pkgdir is the corresponding absolute path,
656
    ## $pkgdir is the corresponding absolute path,
657
    ## $pkgname the name of the package.
657
    ## $pkgname the name of the package.
658
    ## Note that we need to repeat the checking from the main loop in
658
    ## Note that we need to repeat the checking from the main loop in
659
    ## the case of package bundles (and we could check for this).
659
    ## the case of package bundles (and we could check for this).
660
 
660
 
661
    $log->checking("package directory");
661
    $log->checking("package directory");
662
    chdir($startdir);
662
    chdir($startdir);
663
    $pkg =~ s/\/$//;
663
    $pkg =~ s/\/$//;
664
    if(-d $pkg) {
664
    if(-d $pkg) {
665
	chdir($pkg)
665
	chdir($pkg)
666
	  or die "Error: cannot change to directory '$pkg'\n";
666
	  or die "Error: cannot change to directory '$pkg'\n";
667
	$pkgdir = R_cwd();
667
	$pkgdir = R_cwd();
668
	if($in_bundle) {
668
	if($in_bundle) {
669
	    $pkgname = basename($pkgdir);
669
	    $pkgname = basename($pkgdir);
670
	} else {
670
	} else {
671
	    $pkgname = $description->{"Package"};
671
	    $pkgname = $description->{"Package"};
672
	}
672
	}
673
    }
673
    }
674
    else {
674
    else {
675
	$log->error();
675
	$log->error();
676
	$log->print("Package directory '$pkg' does not exist.\n");
676
	$log->print("Package directory '$pkg' does not exist.\n");
677
	exit(1);
677
	exit(1);
678
    }
678
    }
679
    $log->result("OK");
679
    $log->result("OK");
680
 
680
 
681
    chdir($pkgdir);
681
    chdir($pkgdir);
682
 
682
 
683
    ## Build list of exclude patterns.
683
    ## Build list of exclude patterns.
684
 
684
 
685
    my @exclude_patterns = R::Utils::get_exclude_patterns();
685
    my @exclude_patterns = R::Utils::get_exclude_patterns();
686
    my $exclude_file = ".Rbuildignore";
686
    my $exclude_file = ".Rbuildignore";
687
    ## This is a bit tricky for bundles where the build ignore pattern
687
    ## This is a bit tricky for bundles where the build ignore pattern
688
    ## file is in the top-level bundle dir.
688
    ## file is in the top-level bundle dir.
689
    $exclude_file = &file_path(dirname($pkgdir), $exclude_file);
689
    $exclude_file = &file_path(dirname($pkgdir), $exclude_file);
690
    if(-f $exclude_file) {
690
    if(-f $exclude_file) {
691
	open(RBUILDIGNORE, "< $exclude_file");
691
	open(RBUILDIGNORE, "< $exclude_file");
692
	while(<RBUILDIGNORE>) {
692
	while(<RBUILDIGNORE>) {
693
	    chop;
693
	    chop;
694
	    push(@exclude_patterns, $_) if $_;
694
	    push(@exclude_patterns, $_) if $_;
695
	}
695
	}
696
	close(RBUILDIGNORE);
696
	close(RBUILDIGNORE);
697
    }
697
    }
698
 
698
 
699
    ## Check for portable file names.
699
    ## Check for portable file names.
700
 
700
 
701
    ## Ensure that the names of the files in the package are valid for
701
    ## Ensure that the names of the files in the package are valid for
702
    ## at least the supported OS types.  Under Unix, we definitely
702
    ## at least the supported OS types.  Under Unix, we definitely
703
    ## cannot have '/'; under Windows, the control characters as well as
703
    ## cannot have '/'; under Windows, the control characters as well as
704
    ##   " * : < > ? \ |
704
    ##   " * : < > ? \ |
705
    ## (i.e., ASCII characters 1 to 31 and 34, 36, 58, 60, 62, 63, 92,
705
    ## (i.e., ASCII characters 1 to 31 and 34, 36, 58, 60, 62, 63, 92,
706
    ## and 124) are or can be invalid.  (In addition, one cannot have
706
    ## and 124) are or can be invalid.  (In addition, one cannot have
707
    ## one-character file names consisting of just ' ', '.', or '~'.)
707
    ## one-character file names consisting of just ' ', '.', or '~'.)
708
    ## Based on information by Uwe Ligges, Duncan Murdoch, and Brian
708
    ## Based on information by Uwe Ligges, Duncan Murdoch, and Brian
709
    ## Ripley.
709
    ## Ripley.
710
 
710
 
711
    ## Furthermore, Uwe Ligges says that Windows still does not allow
711
    ## Furthermore, Uwe Ligges says that Windows still does not allow
712
    ## the following DOS device names (by themselves or with possible
712
    ## the following DOS device names (by themselves or with possible
713
    ## extensions):
713
    ## extensions):
714
    ##
714
    ##
715
    ## Name    Function
715
    ## Name    Function
716
    ## ----    --------
716
    ## ----    --------
717
    ## CON     Keyboard and display
717
    ## CON     Keyboard and display
718
    ## PRN     System list device, usually a parallel port
718
    ## PRN     System list device, usually a parallel port
719
    ## AUX     Auxiliary device, usually a serial port
719
    ## AUX     Auxiliary device, usually a serial port
720
    ## CLOCK$  System real-time clock
720
    ## CLOCK$  System real-time clock
721
    ## NUL     Bit-bucket device
721
    ## NUL     Bit-bucket device
722
    ## COM1    First serial communications port
722
    ## COM1    First serial communications port
723
    ## COM2    Second serial communications port
723
    ## COM2    Second serial communications port
724
    ## COM3    Third serial communications port
724
    ## COM3    Third serial communications port
725
    ## COM4    Fourth serial communications port
725
    ## COM4    Fourth serial communications port
726
    ## LPT1    First parallel printer port
726
    ## LPT1    First parallel printer port
727
    ## LPT2    Second parallel printer port
727
    ## LPT2    Second parallel printer port
728
    ## LPT3    Third parallel printer port
728
    ## LPT3    Third parallel printer port
729
 
729
 
730
    ## In addition, the names of help files get converted to HTML
730
    ## In addition, the names of help files get converted to HTML
731
    ## file names and so should be valid in URLs.  We check that they are
731
    ## file names and so should be valid in URLs.  We check that they are
732
    ## ASCII and do not contain %, which is what is known to cause troubles.
732
    ## ASCII and do not contain %, which is what is known to cause troubles.
733
 
733
 
734
    $log->checking("for portable file names");
734
    $log->checking("for portable file names");
735
    my @bad_files = ();
735
    my @bad_files = ();
736
    sub find_wrong_names {
736
    sub find_wrong_names {
737
	my $file_path = $File::Find::name;
737
	my $file_path = $File::Find::name;
738
	$file_path =~ s/^\.[^\/]*\///;
738
	$file_path =~ s/^\.[^\/]*\///;
739
	foreach my $p (@exclude_patterns) {
739
	foreach my $p (@exclude_patterns) {
740
	    if($WINDOWS) {
740
	    if($WINDOWS) {
741
		## Argh: Windows is case-honoring but not
741
		## Argh: Windows is case-honoring but not
742
		## case-insensitive ...
742
		## case-insensitive ...
743
		return 0 if($file_path =~ /$p/i);
743
		return 0 if($file_path =~ /$p/i);
744
	    }
744
	    }
745
	    else {
745
	    else {
746
		return 0 if($file_path =~ /$p/);
746
		return 0 if($file_path =~ /$p/);
747
	    }
747
	    }
748
	}
748
	}
749
	my $file_name = basename($file_path);
749
	my $file_name = basename($file_path);
750
	if(grep(/[[:cntrl:]\"\*\/\:\<\>\?\\\|]/, $file_name)) {
750
	if(grep(/[[:cntrl:]\"\*\/\:\<\>\?\\\|]/, $file_name)) {
751
	    push(@bad_files, $file_path);
751
	    push(@bad_files, $file_path);
752
	} elsif(dirname($file_path) =~ /man$/) {
752
	} elsif(dirname($file_path) =~ /man$/) {
753
	    my $ch;
753
	    my $ch;
754
	    foreach $ch (split //, $file_name) {
754
	    foreach $ch (split //, $file_name) {
755
		## collation is ASCII as uselocale is not in effect.
755
		## collation is ASCII as uselocale is not in effect.
756
		if ($ch eq "%" || $ch lt " " || $ch gt "~")  {
756
		if ($ch eq "%" || $ch lt " " || $ch gt "~")  {
757
		    push(@bad_files, $file_path);
757
		    push(@bad_files, $file_path);
758
		    last;
758
		    last;
759
		}
759
		}
760
	    }
760
	    }
761
	} else {
761
	} else {
762
	    $file_name =~ tr/A-Z/a-z/;
762
	    $file_name =~ tr/A-Z/a-z/;
763
	    $file_name =~ s/\..*//;
763
	    $file_name =~ s/\..*//;
764
	    push(@bad_files, $file_path)
764
	    push(@bad_files, $file_path)
765
	      if(grep(/^(con|prn|aux|clock\$|nul|lpt[1-3]|com[1-4])$/,
765
	      if(grep(/^(con|prn|aux|clock\$|nul|lpt[1-3]|com[1-4])$/,
766
		     $file_name));
766
		     $file_name));
767
	}
767
	}
768
    }
768
    }
769
    if($in_bundle) {
769
    if($in_bundle) {
770
	chdir(dirname($pkgdir)); # more portable than '..'?
770
	chdir(dirname($pkgdir)); # more portable than '..'?
771
	find(\&find_wrong_names, $pkgname);
771
	find(\&find_wrong_names, $pkgname);
772
	chdir($pkgname);
772
	chdir($pkgname);
773
    }
773
    }
774
    else {
774
    else {
775
	find(\&find_wrong_names, ".");
775
	find(\&find_wrong_names, ".");
776
    }
776
    }
777
    if(scalar(@bad_files) > 0) {
777
    if(scalar(@bad_files) > 0) {
778
	$log->error();
778
	$log->error();
779
	$log->print("Found the following file(s) with " .
779
	$log->print("Found the following file(s) with " .
780
		    "non-portable file names:\n");
780
		    "non-portable file names:\n");
781
	$log->print("  " . join("\n  ", @bad_files) . "\n");
781
	$log->print("  " . join("\n  ", @bad_files) . "\n");
782
	$log->print(wrap("", "",
782
	$log->print(wrap("", "",
783
			 ("These are not valid file names",
783
			 ("These are not valid file names",
784
			  "on all R platforms.\n",
784
			  "on all R platforms.\n",
785
			  "Please rename the files and try again.\n",
785
			  "Please rename the files and try again.\n",
786
			  "See section 'Package structure'",
786
			  "See section 'Package structure'",
787
			  "in manual 'Writing R Extensions'.\n")));
787
			  "in manual 'Writing R Extensions'.\n")));
788
	exit(1);
788
	exit(1);
789
    }
789
    }
790
 
790
 
791
    ## next check for name clashes on case-insensitive file systems
791
    ## next check for name clashes on case-insensitive file systems
792
    ## (that is on Windows).
792
    ## (that is on Windows).
793
    %seen = ();
793
    %seen = ();
794
    my @duplicated = ();
794
    my @duplicated = ();
795
    sub check_case_names {
795
    sub check_case_names {
796
	my $file_path = lc($File::Find::name);
796
	my $file_path = lc($File::Find::name);
797
	if($seen{$file_path}) {push(@duplicated, $file_path);}
797
	if($seen{$file_path}) {push(@duplicated, $file_path);}
798
	$seen{$file_path}  = 1;
798
	$seen{$file_path}  = 1;
799
    }
799
    }
800
    if($in_bundle) {
800
    if($in_bundle) {
801
	chdir(dirname($pkgdir)); # more portable than '..'?
801
	chdir(dirname($pkgdir)); # more portable than '..'?
802
	find(\&check_case_names, $pkgname);
802
	find(\&check_case_names, $pkgname);
803
	chdir($pkgname);
803
	chdir($pkgname);
804
    }
804
    }
805
    else {
805
    else {
806
	find(\&check_case_names, ".");
806
	find(\&check_case_names, ".");
807
    }
807
    }
808
    if(scalar(@duplicated) > 0) {
808
    if(scalar(@duplicated) > 0) {
809
	$log->error();
809
	$log->error();
810
	$log->print("Found the following file(s) with " .
810
	$log->print("Found the following file(s) with " .
811
		    "duplicate lower-cased file names:\n");
811
		    "duplicate lower-cased file names:\n");
812
	$log->print("  " . join("\n  ", @duplicated) . "\n");
812
	$log->print("  " . join("\n  ", @duplicated) . "\n");
813
	$log->print(wrap("", "",
813
	$log->print(wrap("", "",
814
			 ("File names must not differ just by case",
814
			 ("File names must not differ just by case",
815
			  "to be usable on all R platforms.\n",
815
			  "to be usable on all R platforms.\n",
816
			  "Please rename the files and try again.\n",
816
			  "Please rename the files and try again.\n",
817
			  "See section 'Package structure'",
817
			  "See section 'Package structure'",
818
			  "in manual 'Writing R Extensions'.\n")));
818
			  "in manual 'Writing R Extensions'.\n")));
819
	exit(1);
819
	exit(1);
820
    }
820
    }
821
 
821
 
822
    $log->result("OK");
822
    $log->result("OK");
823
 
823
 
824
    ## Check for sufficient file permissions (Unix only).
824
    ## Check for sufficient file permissions (Unix only).
825
 
825
 
826
    ## This used to be much more 'aggressive', requiring that dirs and
826
    ## This used to be much more 'aggressive', requiring that dirs and
827
    ## files have mode >= 00755 and 00644, respectively (with an error
827
    ## files have mode >= 00755 and 00644, respectively (with an error
828
    ## if not), and that files know to be 'text' have mode 00644 (with a
828
    ## if not), and that files know to be 'text' have mode 00644 (with a
829
    ## warning if not).  We now only require that dirs and files have
829
    ## warning if not).  We now only require that dirs and files have
830
    ## mode >= 00700 and 00400, respectively, and try to fix
830
    ## mode >= 00700 and 00400, respectively, and try to fix
831
    ## insufficient permission in the INSTALL code (Unix only).
831
    ## insufficient permission in the INSTALL code (Unix only).
832
    ##
832
    ##
833
    ## In addition, we check whether files 'configure' and 'cleanup'
833
    ## In addition, we check whether files 'configure' and 'cleanup'
834
    ## exists in the top-level directory but are not executable, which
834
    ## exists in the top-level directory but are not executable, which
835
    ## is most likely not what was intended.
835
    ## is most likely not what was intended.
836
 
836
 
837
    if($R::Vars::OSTYPE eq "unix") {
837
    if($R::Vars::OSTYPE eq "unix") {
838
	$log->checking("for sufficient/correct file permissions");
838
	$log->checking("for sufficient/correct file permissions");
839
	my @bad_files = ();
839
	my @bad_files = ();
840
 
840
 
841
	## Phase A.  Directories at least 700, files at least 400.
841
	## Phase A.  Directories at least 700, files at least 400.
842
	sub find_wrong_perms_A {
842
	sub find_wrong_perms_A {
843
	    my $filename = $File::Find::name;
843
	    my $filename = $File::Find::name;
844
	    $filename =~ s/^\.[^\/]*\///;
844
	    $filename =~ s/^\.[^\/]*\///;
845
	    foreach my $p (@exclude_patterns) {
845
	    foreach my $p (@exclude_patterns) {
846
		## Unix only, so no special casing for Windows.
846
		## Unix only, so no special casing for Windows.
847
		return 0 if($filename =~ /$p/);
847
		return 0 if($filename =~ /$p/);
848
	    }
848
	    }
849
	    if(-d $_ && (((stat $_)[2] & 00700) < oct("700"))) {
849
	    if(-d $_ && (((stat $_)[2] & 00700) < oct("700"))) {
850
		push(@bad_files, $filename);
850
		push(@bad_files, $filename);
851
	    }
851
	    }
852
	    if(-f $_ && (((stat $_)[2] & 00400) < oct("400"))) {
852
	    if(-f $_ && (((stat $_)[2] & 00400) < oct("400"))) {
853
		push(@bad_files, $filename);
853
		push(@bad_files, $filename);
854
	    }
854
	    }
855
	}
855
	}
856
	if($in_bundle) {
856
	if($in_bundle) {
857
	    chdir(dirname($pkgdir)); # more portable than '..'?
857
	    chdir(dirname($pkgdir)); # more portable than '..'?
858
	    find(\&find_wrong_perms_A, $pkgname);
858
	    find(\&find_wrong_perms_A, $pkgname);
859
	    chdir($pkgname);
859
	    chdir($pkgname);
860
	}
860
	}
861
	else {
861
	else {
862
	    find(\&find_wrong_perms_A, ".");
862
	    find(\&find_wrong_perms_A, ".");
863
	}
863
	}
864
        if(scalar(@bad_files) > 0) {
864
        if(scalar(@bad_files) > 0) {
865
	    $log->error();
865
	    $log->error();
866
	    $log->print("Found the following files with " .
866
	    $log->print("Found the following files with " .
867
			"insufficient permissions:\n");
867
			"insufficient permissions:\n");
868
	    $log->print("  " . join("\n  ", @bad_files) . "\n");
868
	    $log->print("  " . join("\n  ", @bad_files) . "\n");
869
	    $log->print(wrap("", "",
869
	    $log->print(wrap("", "",
870
			     ("Permissions should be at least 700",
870
			     ("Permissions should be at least 700",
871
			      "for directories and 400 for files.\n",
871
			      "for directories and 400 for files.\n",
872
			      "Please fix permissions",
872
			      "Please fix permissions",
873
			      "and try again.\n")));
873
			      "and try again.\n")));
874
	    exit(1);
874
	    exit(1);
875
	}
875
	}
876
 
876
 
877
	## Phase B.  Top-level scripts 'configure' and 'cleanup' should
877
	## Phase B.  Top-level scripts 'configure' and 'cleanup' should
878
	## really be mode at least 500, or they will not be necessarily
878
	## really be mode at least 500, or they will not be necessarily
879
	## be used (or should we rather change *that*?)
879
	## be used (or should we rather change *that*?)
880
	@bad_files = ();
880
	@bad_files = ();
881
	foreach my $filename ("configure", "cleanup") {
881
	foreach my $filename ("configure", "cleanup") {
882
	    ## This is a bit silly ...
882
	    ## This is a bit silly ...
883
	    my $ignore = 0;
883
	    my $ignore = 0;
884
	    foreach my $p (@exclude_patterns) {
884
	    foreach my $p (@exclude_patterns) {
885
		if($filename =~ /$p/) {
885
		if($filename =~ /$p/) {
886
		    $ignore = 1;
886
		    $ignore = 1;
887
		    last;
887
		    last;
888
		}
888
		}
889
	    }
889
	    }
890
	    if(!$ignore
890
	    if(!$ignore
891
	       && (-f $filename)
891
	       && (-f $filename)
892
	       && (((stat $filename)[2] & 00500) < oct("500"))) {
892
	       && (((stat $filename)[2] & 00500) < oct("500"))) {
893
		push(@bad_files, $filename);
893
		push(@bad_files, $filename);
894
	    }
894
	    }
895
	}
895
	}
896
	if(scalar(@bad_files) > 0) {
896
	if(scalar(@bad_files) > 0) {
897
	    $log->warning();
897
	    $log->warning();
898
	    $log->print(wrap("", "",
898
	    $log->print(wrap("", "",
899
			     "The following files should most likely",
899
			     "The following files should most likely",
900
			     "be executable (for the owner):\n"));
900
			     "be executable (for the owner):\n"));
901
	    $log->print("  " . join("\n  ", @bad_files) . "\n");
901
	    $log->print("  " . join("\n  ", @bad_files) . "\n");
902
	    $log->print(wrap("", "",
902
	    $log->print(wrap("", "",
903
			     "Please fix permissions.\n"));
903
			     "Please fix permissions.\n"));
904
	}
904
	}
905
	else {
905
	else {
906
	    $log->result("OK");
906
	    $log->result("OK");
907
	}
907
	}
908
    }
908
    }
909
 
909
 
910
    ## Check DESCRIPTION meta-information.
910
    ## Check DESCRIPTION meta-information.
911
 
911
 
912
    ## If we just installed the package (via R CMD INSTALL), we already
912
    ## If we just installed the package (via R CMD INSTALL), we already
913
    ## validated most of the package DESCRIPTION metadata.  Otherwise,
913
    ## validated most of the package DESCRIPTION metadata.  Otherwise,
914
    ## let us be defensive about this ...
914
    ## let us be defensive about this ...
915
 
915
 
916
    my $full =
916
    my $full =
917
	!$opt_install || ($opt_install eq "skip") || $is_base_pkg;
917
	!$opt_install || ($opt_install eq "skip") || $is_base_pkg;
918
    &R::Utils::check_package_description($pkgdir, $pkgname, $log,
918
    &R::Utils::check_package_description($pkgdir, $pkgname, $log,
919
					 $in_bundle, $is_base_pkg,
919
					 $in_bundle, $is_base_pkg,
920
					 $full);
920
					 $full);
921
 
921
 
922
    $log->checking("top-level files");
922
    $log->checking("top-level files");
923
    opendir(DIR, ".") or die "cannot opendir package: $!";
923
    opendir(DIR, ".") or die "cannot opendir package: $!";
924
    my @topfiles = grep { /^install.R$/ || /^R_PROFILE.R/
924
    my @topfiles = grep { /^install.R$/ || /^R_PROFILE.R/
925
			      && -f "$_" } readdir(DIR);
925
			      && -f "$_" } readdir(DIR);
926
    closedir(DIR);
926
    closedir(DIR);
927
    if(@topfiles) {
927
    if(@topfiles) {
928
	$log->warning();
928
	$log->warning();
929
	    $log->print(join(" ", @topfiles) . "\n");
929
	    $log->print(join(" ", @topfiles) . "\n");
930
	    $log->print(wrap("", "",
930
	    $log->print(wrap("", "",
931
			     ("These files are deprecated.",
931
			     ("These files are deprecated.",
932
			      "See manual 'Writing R Extensions'.\n")));
932
			      "See manual 'Writing R Extensions'.\n")));
933
    } else {
933
    } else {
934
	$log->result("OK");
934
	$log->result("OK");
935
    }
935
    }
936
 
936
 
937
    ## Check index information.
937
    ## Check index information.
938
 
938
 
939
    $log->checking("index information");
939
    $log->checking("index information");
940
    my @msg_index = ("See the information on INDEX files and package",
940
    my @msg_index = ("See the information on INDEX files and package",
941
		     "subdirectories in section 'Creating R packages'",
941
		     "subdirectories in section 'Creating R packages'",
942
		     "of the 'Writing R Extensions' manual.\n");
942
		     "of the 'Writing R Extensions' manual.\n");
943
    my $any = 0;
943
    my $any = 0;
944
    if(-z "INDEX") {
944
    if(-z "INDEX") {
945
	## If there is an empty INDEX file, we get no information about
945
	## If there is an empty INDEX file, we get no information about
946
	## the package contents ...
946
	## the package contents ...
947
	$any++;
947
	$any++;
948
	$log->warning();
948
	$log->warning();
949
	$log->print("Empty file 'INDEX'.\n");
949
	$log->print("Empty file 'INDEX'.\n");
950
    }
950
    }
951
    if((-d "demo")
951
    if((-d "demo")
952
       && &list_files_with_type("demo", "demo")) {
952
       && &list_files_with_type("demo", "demo")) {
953
	my $index = &file_path("demo", "00Index");
953
	my $index = &file_path("demo", "00Index");
954
	if(!(-s $index)) {
954
	if(!(-s $index)) {
955
	    $log->warning() unless($any);
955
	    $log->warning() unless($any);
956
	    $any++;
956
	    $any++;
957
	    $log->print("Empty or missing file '$index'.\n");
957
	    $log->print("Empty or missing file '$index'.\n");
958
	}
958
	}
959
	else {
959
	else {
960
	    my $dir = "demo";
960
	    my $dir = "demo";
961
	    my $Rcmd = "options(warn=1)\ntools:::.check_demo_index(\"$dir\")\n";
961
	    my $Rcmd = "options(warn=1)\ntools:::.check_demo_index(\"$dir\")\n";
962
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
962
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
963
			     "R_DEFAULT_PACKAGES=NULL");
963
			     "R_DEFAULT_PACKAGES=NULL");
964
	    @out = grep(!/^\>/, @out);
964
	    @out = grep(!/^\>/, @out);
965
	    if(scalar(@out) > 0) {
965
	    if(scalar(@out) > 0) {
966
		$log->warning() unless($any);
966
		$log->warning() unless($any);
967
		$any++;
967
		$any++;
968
		$log->print(join("\n", @out) . "\n");
968
		$log->print(join("\n", @out) . "\n");
969
	    }
969
	    }
970
	}
970
	}
971
    }
971
    }
972
    if((-d &file_path("inst", "doc"))
972
    if((-d &file_path("inst", "doc"))
973
       && &list_files_with_type(&file_path("inst", "doc"),
973
       && &list_files_with_type(&file_path("inst", "doc"),
974
				"vignette")) {
974
				"vignette")) {
975
	my $dir = &file_path("inst", "doc");
975
	my $dir = &file_path("inst", "doc");
976
	my $Rcmd = "options(warn=1)\ntools:::.check_vignette_index(\"$dir\")\n";
976
	my $Rcmd = "options(warn=1)\ntools:::.check_vignette_index(\"$dir\")\n";
977
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
977
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
978
			 "R_DEFAULT_PACKAGES=NULL");
978
			 "R_DEFAULT_PACKAGES=NULL");
979
	@out = grep(!/^\>/, @out);
979
	@out = grep(!/^\>/, @out);
980
	if(scalar(@out) > 0) {
980
	if(scalar(@out) > 0) {
981
	    $log->warning() unless($any);
981
	    $log->warning() unless($any);
982
	    $any++;
982
	    $any++;
983
	    $log->print(join("\n", @out) . "\n");
983
	    $log->print(join("\n", @out) . "\n");
984
	}
984
	}
985
    }
985
    }
986
    if($any) {
986
    if($any) {
987
	$log->print(wrap("", "", @msg_index));
987
	$log->print(wrap("", "", @msg_index));
988
    }
988
    }
989
    else {
989
    else {
990
	$log->result("OK");
990
	$log->result("OK");
991
    }
991
    }
992
 
992
 
993
    ## Check package subdirectories.
993
    ## Check package subdirectories.
994
 
994
 
995
    $log->checking("package subdirectories");
995
    $log->checking("package subdirectories");
996
    my $any;
996
    my $any;
997
    if($R_check_subdirs_nocase) {
997
    if($R_check_subdirs_nocase) {
998
	## Argh.  We often get submissions where 'R' comes out as 'r',
998
	## Argh.  We often get submissions where 'R' comes out as 'r',
999
	## or 'man' comes out as 'MAN'.  Maybe we should warn about this
999
	## or 'man' comes out as 'MAN'.  Maybe we should warn about this
1000
	## unconditionally ...
1000
	## unconditionally ...
1001
	if((-d "r")) {
1001
	if((-d "r")) {
1002
	    $log->warning() unless $any;
1002
	    $log->warning() unless $any;
1003
	    $any++;
1003
	    $any++;
1004
	    $log->print("Found subdirectory 'r'.\n");
1004
	    $log->print("Found subdirectory 'r'.\n");
1005
	    $log->print("Most likely, this should be 'R'.\n")
1005
	    $log->print("Most likely, this should be 'R'.\n")
1006
	}
1006
	}
1007
	if((-d "MAN")) {
1007
	if((-d "MAN")) {
1008
	    $log->warning() unless $any;
1008
	    $log->warning() unless $any;
1009
	    $any++;
1009
	    $any++;
1010
	    $log->print("Found subdirectory 'MAN'.\n");
1010
	    $log->print("Found subdirectory 'MAN'.\n");
1011
	    $log->print("Most likely, this should be 'man'.\n")
1011
	    $log->print("Most likely, this should be 'man'.\n")
1012
	}
1012
	}
1013
    }
1013
    }
1014
    sub check_subdirs {
1014
    sub check_subdirs {
1015
	my ($dpath) = @_;
1015
	my ($dpath) = @_;
1016
	my $Rcmd = "tools:::.check_package_subdirs(\"$dpath\")\n";
1016
	my $Rcmd = "tools:::.check_package_subdirs(\"$dpath\")\n";
1017
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1017
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1018
			 "R_DEFAULT_PACKAGES=NULL");
1018
			 "R_DEFAULT_PACKAGES=NULL");
1019
	@out = grep(!/^\>/, @out);
1019
	@out = grep(!/^\>/, @out);
1020
	if(scalar(@out) > 0) {
1020
	if(scalar(@out) > 0) {
1021
	    $log->warning() unless($any);
1021
	    $log->warning() unless($any);
1022
	    $any++;
1022
	    $any++;
1023
	    $log->print(join("\n", @out) . "\n");
1023
	    $log->print(join("\n", @out) . "\n");
1024
	    $log->print(wrap("", "",
1024
	    $log->print(wrap("", "",
1025
			     ("Please remove or rename the files.\n",
1025
			     ("Please remove or rename the files.\n",
1026
			      "See section 'Package subdirectories'",
1026
			      "See section 'Package subdirectories'",
1027
			      "in manual 'Writing R Extensions'.\n")));
1027
			      "in manual 'Writing R Extensions'.\n")));
1028
	}
1028
	}
1029
    }
1029
    }
1030
    &check_subdirs(".") unless ($subdirs eq "no");
1030
    &check_subdirs(".") unless ($subdirs eq "no");
1031
    ## Subdirectory 'data' without data sets?
1031
    ## Subdirectory 'data' without data sets?
1032
    if((-d "data") && !&list_files_with_type("data", "data")) {
1032
    if((-d "data") && !&list_files_with_type("data", "data")) {
1033
	$log->warning() unless $any;
1033
	$log->warning() unless $any;
1034
	$any++;
1034
	$any++;
1035
	$log->print("Subdirectory 'data' contains no data sets.\n");
1035
	$log->print("Subdirectory 'data' contains no data sets.\n");
1036
    }
1036
    }
1037
    ## Subdirectory 'demo' without demos?
1037
    ## Subdirectory 'demo' without demos?
1038
    if((-d "demo") && !&list_files_with_type("demo", "demo")) {
1038
    if((-d "demo") && !&list_files_with_type("demo", "demo")) {
1039
	$log->warning() unless $any;
1039
	$log->warning() unless $any;
1040
	$any++;
1040
	$any++;
1041
	$log->print("Subdirectory 'demo' contains no demos.\n");
1041
	$log->print("Subdirectory 'demo' contains no demos.\n");
1042
    }
1042
    }
1043
    ## Subdirectory 'src' without sources?
1043
    ## Subdirectory 'src' without sources?
1044
    ## <NOTE>
1044
    ## <NOTE>
1045
    ## If there is a Makefile (or a Makefile.win), we cannot assume
1045
    ## If there is a Makefile (or a Makefile.win), we cannot assume
1046
    ## that source files have the predefined extensions.
1046
    ## that source files have the predefined extensions.
1047
    ## </NOTE>
1047
    ## </NOTE>
1048
    if( (-d "src") && !( (-f &file_path("src", "Makefile"))
1048
    if( (-d "src") && !( (-f &file_path("src", "Makefile"))
1049
			 || (-f &file_path("src", "Makefile.win")) )) {
1049
			 || (-f &file_path("src", "Makefile.win")) )) {
1050
	if( !(&list_files_with_exts("src", "([Ccf]|cc|cpp|f90|f95)"))) {
1050
	if( !(&list_files_with_exts("src", "([Ccf]|cc|cpp|f90|f95)"))) {
1051
	    $log->warning() unless $any;
1051
	    $log->warning() unless $any;
1052
	    $any++;
1052
	    $any++;
1053
	    $log->print("Subdirectory 'src' contains no source files.\n");
1053
	    $log->print("Subdirectory 'src' contains no source files.\n");
1054
	}
1054
	}
1055
    }
1055
    }
1056
    ## Do subdirectories of 'inst' interfere with R package system
1056
    ## Do subdirectories of 'inst' interfere with R package system
1057
    ## subdirectories?
1057
    ## subdirectories?
1058
    if((-d "inst")) {
1058
    if((-d "inst")) {
1059
	my @R_system_subdirs =
1059
	my @R_system_subdirs =
1060
	    ("Meta", "R", "data", "demo", "exec", "libs",
1060
	    ("Meta", "R", "data", "demo", "exec", "libs",
1061
	     "man", "help", "html", "latex", "R-ex");
1061
	     "man", "help", "html", "latex", "R-ex");
1062
	my @bad_dirs = ();
1062
	my @bad_dirs = ();
1063
	foreach my $dir (@R_system_subdirs) {
1063
	foreach my $dir (@R_system_subdirs) {
1064
	    push(@bad_dirs, $dir)
1064
	    push(@bad_dirs, $dir)
1065
		if((-d &file_path("inst", $dir))
1065
		if((-d &file_path("inst", $dir))
1066
		   && &list_files(file_path("inst", $dir)));
1066
		   && &list_files(file_path("inst", $dir)));
1067
	}
1067
	}
1068
	if(scalar(@bad_dirs) > 0) {
1068
	if(scalar(@bad_dirs) > 0) {
1069
	    $log->warning() unless $any;
1069
	    $log->warning() unless $any;
1070
	    $any++;
1070
	    $any++;
1071
	    $log->print(wrap("", "",
1071
	    $log->print(wrap("", "",
1072
			     ("Found the following non-empty",
1072
			     ("Found the following non-empty",
1073
			      "subdirectories of 'inst' also",
1073
			      "subdirectories of 'inst' also",
1074
			      "used by R:\n")));
1074
			      "used by R:\n")));
1075
	    $log->print("  " . join(" ", @bad_dirs) . "\n");
1075
	    $log->print("  " . join(" ", @bad_dirs) . "\n");
1076
	    $log->print(wrap("", "",
1076
	    $log->print(wrap("", "",
1077
			     ("It is recommended not to interfere",
1077
			     ("It is recommended not to interfere",
1078
			      "with package subdirectories",
1078
			      "with package subdirectories",
1079
			      "used by R.\n")));
1079
			      "used by R.\n")));
1080
	}
1080
	}
1081
    }
1081
    }
1082
    $log->result("OK") unless $any;
1082
    $log->result("OK") unless $any;
1083
 
1083
 
1084
    ## Check R code for syntax errors.
1084
    ## Check R code for syntax errors.
1085
 
1085
 
1086
    if(!$is_base_pkg && (-d "R")) {
1086
    if(!$is_base_pkg && (-d "R")) {
1087
	$log->checking("R files for syntax errors");
1087
	$log->checking("R files for syntax errors");
1088
	## <NOTE>
1088
	## <NOTE>
1089
	## We could/should really check *all* OS specific subdirs here.
1089
	## We could/should really check *all* OS specific subdirs here.
1090
	my @R_files = &list_files_with_type("R", "code");
1090
	my @R_files = &list_files_with_type("R", "code");
1091
	## </NOTE>
1091
	## </NOTE>
1092
	my $Rcmd = "RFiles <- c(\"";
1092
	my $Rcmd = "RFiles <- c(\"";
1093
	$Rcmd .= join("\",\n\"", @R_files) . "\")\n";
1093
	$Rcmd .= join("\",\n\"", @R_files) . "\")\n";
1094
	$Rcmd .= "for(f in RFiles)\n";
1094
	$Rcmd .= "for(f in RFiles)\n";
1095
	$Rcmd .= "if(inherits(try(parse(f)), \"try-error\")) stop(f)\n";
1095
	$Rcmd .= "if(inherits(try(parse(f)), \"try-error\")) stop(f)\n";
1096
        my @out = R_runR($Rcmd, "${R_opts} --quiet");
1096
        my @out = R_runR($Rcmd, "${R_opts} --quiet");
1097
	@out = grep(/^Error:/, @out);
1097
	@out = grep(/^Error:/, @out);
1098
	if(scalar(@out) > 0) {
1098
	if(scalar(@out) > 0) {
1099
	    my $Rfile = $out[0];
1099
	    my $Rfile = $out[0];
1100
	    $Rfile =~ s/^Error: *//;
1100
	    $Rfile =~ s/^Error: *//;
1101
	    $log->error();
1101
	    $log->error();
1102
	    $log->print("Syntax error in file '$Rfile'\n");
1102
	    $log->print("Syntax error in file '$Rfile'\n");
1103
	    exit(1);
1103
	    exit(1);
1104
	}
1104
	}
1105
	else {
1105
	else {
1106
	    $log->result("OK");
1106
	    $log->result("OK");
1107
	}
1107
	}
1108
    }
1108
    }
1109
 
1109
 
1110
    ## Check usage of library.dynam (if any).
1110
    ## Check usage of library.dynam (if any).
1111
 
1111
 
1112
    if(!$is_base_pkg && (-d "R")) {
1112
    if(!$is_base_pkg && (-d "R")) {
1113
	$log->checking("R files for library.dynam");
1113
	$log->checking("R files for library.dynam");
1114
	my @R_files;
1114
	my @R_files;
1115
	if($opt_install) {
1115
	if($opt_install) {
1116
	    ## Only need to check the installed file (if installed).
1116
	    ## Only need to check the installed file (if installed).
1117
	    @R_files = (&file_path($library, $pkgname, "R", $pkgname));
1117
	    @R_files = (&file_path($library, $pkgname, "R", $pkgname));
1118
	}
1118
	}
1119
	else {
1119
	else {
1120
	    ## Otherwise (if the package was not installed), we need to
1120
	    ## Otherwise (if the package was not installed), we need to
1121
	    ## check all R code files.
1121
	    ## check all R code files.
1122
	    ## <NOTE>
1122
	    ## <NOTE>
1123
	    ## We could/should really check all OS specific subdirs here.
1123
	    ## We could/should really check all OS specific subdirs here.
1124
	    @R_files = &list_files_with_type("R", "code");
1124
	    @R_files = &list_files_with_type("R", "code");
1125
	    ## </NOTE>
1125
	    ## </NOTE>
1126
	}
1126
	}
1127
	my $any = 0;
1127
	my $any = 0;
1128
	my $ext;
1128
	my $ext;
1129
	foreach my $file (@R_files) {
1129
	foreach my $file (@R_files) {
1130
	    last if $any;
1130
	    last if $any;
1131
	    open(FILE, "< $file")
1131
	    open(FILE, "< $file")
1132
	      or die "Error: cannot open file '$file' for reading\n";
1132
	      or die "Error: cannot open file '$file' for reading\n";
1133
	    while(<FILE>) {
1133
	    while(<FILE>) {
1134
		if(/library.dynam\(\"(.*?)\"/o) {
1134
		if(/library.dynam\(\"(.*?)\"/o) {
1135
		    my $arg = $1;
1135
		    my $arg = $1;
1136
		    if($arg =~ /\.(so|sl|dll)$/) {
1136
		    if($arg =~ /\.(so|sl|dll)$/) {
1137
			$ext = $1;
1137
			$ext = $1;
1138
			$any++;
1138
			$any++;
1139
			last;
1139
			last;
1140
		    }
1140
		    }
1141
		}
1141
		}
1142
	    }
1142
	    }
1143
	    close(FILE);
1143
	    close(FILE);
1144
	}
1144
	}
1145
	if($any == 0) {
1145
	if($any == 0) {
1146
	    $log->result("OK");
1146
	    $log->result("OK");
1147
	}
1147
	}
1148
	else {
1148
	else {
1149
	    $log->error();
1149
	    $log->error();
1150
	    $log->print("library.dynam() used with extension '.$ext'.\n");
1150
	    $log->print("library.dynam() used with extension '.$ext'.\n");
1151
	    $log->print(wrap("", "",
1151
	    $log->print(wrap("", "",
1152
			     ("The system-specific extension for",
1152
			     ("The system-specific extension for",
1153
			      "shared libraries should not be added.\n",
1153
			      "shared libraries should not be added.\n",
1154
			      "See ?library.dynam\n")));
1154
			      "See ?library.dynam\n")));
1155
	    exit(1);
1155
	    exit(1);
1156
	}
1156
	}
1157
    }
1157
    }
1158
 
1158
 
1159
    ## Check whether methods have all arguments of the corresponding
1159
    ## Check whether methods have all arguments of the corresponding
1160
    ## generic.
1160
    ## generic.
1161
 
1161
 
1162
    if(-d "R") {
1162
    if(-d "R") {
1163
	$log->checking("S3 generic/method consistency");
1163
	$log->checking("S3 generic/method consistency");
1164
 
1164
 
1165
	my @msg_S3_methods =
1165
	my @msg_S3_methods =
1166
	  ("See section 'Generic functions and methods'",
1166
	  ("See section 'Generic functions and methods'",
1167
	   "of the 'Writing R Extensions' manual.\n");
1167
	   "of the 'Writing R Extensions' manual.\n");
1168
 
1168
 
1169
	my $Rcmd = "options(warn=1)\n";
1169
	my $Rcmd = "options(warn=1)\n";
1170
	$Rcmd .= "options(expressions=1000)\n";
1170
	$Rcmd .= "options(expressions=1000)\n";
1171
	if($opt_install) {
1171
	if($opt_install) {
1172
	    $Rcmd .= "tools::checkS3methods(package = \"${pkgname}\")\n";
1172
	    $Rcmd .= "tools::checkS3methods(package = \"${pkgname}\")\n";
1173
	}
1173
	}
1174
        else {
1174
        else {
1175
	    $Rcmd .= "tools::checkS3methods(dir = \"${pkgdir}\")\n";
1175
	    $Rcmd .= "tools::checkS3methods(dir = \"${pkgdir}\")\n";
1176
	}
1176
	}
1177
 
1177
 
1178
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1178
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1179
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1179
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1180
	@out = grep(!/^\>/, @out);
1180
	@out = grep(!/^\>/, @out);
1181
	if(scalar(@out) > 0) {
1181
	if(scalar(@out) > 0) {
1182
	    $log->warning();
1182
	    $log->warning();
1183
	    $log->print(join("\n", @out) . "\n");
1183
	    $log->print(join("\n", @out) . "\n");
1184
	    $log->print(wrap("", "", @msg_S3_methods));
1184
	    $log->print(wrap("", "", @msg_S3_methods));
1185
	}
1185
	}
1186
	else {
1186
	else {
1187
	    $log->result("OK");
1187
	    $log->result("OK");
1188
	}
1188
	}
1189
    }
1189
    }
1190
 
1190
 
1191
    ## Check whether replacement functions have their final argument
1191
    ## Check whether replacement functions have their final argument
1192
    ## named 'value'.
1192
    ## named 'value'.
1193
 
1193
 
1194
    if(-d "R") {
1194
    if(-d "R") {
1195
	$log->checking("replacement functions");
1195
	$log->checking("replacement functions");
1196
 
1196
 
1197
	my @msg_replace_funs =
1197
	my @msg_replace_funs =
1198
	  ("In R, the argument of a replacement function",
1198
	  ("In R, the argument of a replacement function",
1199
	   "which corresponds to the right hand side",
1199
	   "which corresponds to the right hand side",
1200
	   "must be named 'value'.\n");
1200
	   "must be named 'value'.\n");
1201
 
1201
 
1202
	my $Rcmd = "options(warn=1)\n";
1202
	my $Rcmd = "options(warn=1)\n";
1203
	if($opt_install) {
1203
	if($opt_install) {
1204
	    $Rcmd .= "tools::checkReplaceFuns(package = \"${pkgname}\")\n";
1204
	    $Rcmd .= "tools::checkReplaceFuns(package = \"${pkgname}\")\n";
1205
	}
1205
	}
1206
	else {
1206
	else {
1207
	    $Rcmd .= "tools::checkReplaceFuns(dir = \"${pkgdir}\")\n";
1207
	    $Rcmd .= "tools::checkReplaceFuns(dir = \"${pkgdir}\")\n";
1208
	}
1208
	}
1209
 
1209
 
1210
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1210
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1211
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1211
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1212
        @out = grep(!/^\>/, @out);
1212
        @out = grep(!/^\>/, @out);
1213
	if(scalar(@out) > 0) {
1213
	if(scalar(@out) > 0) {
1214
	    ## <NOTE>
1214
	    ## <NOTE>
1215
	    ## We really want to stop if we find offending replacement
1215
	    ## We really want to stop if we find offending replacement
1216
	    ## functions.  But we cannot use error() because output may
1216
	    ## functions.  But we cannot use error() because output may
1217
	    ## contain warnings ...
1217
	    ## contain warnings ...
1218
	    $log->warning();
1218
	    $log->warning();
1219
	    ## </NOTE>
1219
	    ## </NOTE>
1220
	    $log->print(join("\n", @out) . "\n");
1220
	    $log->print(join("\n", @out) . "\n");
1221
	    $log->print(wrap("", "", @msg_replace_funs));
1221
	    $log->print(wrap("", "", @msg_replace_funs));
1222
	}
1222
	}
1223
	else {
1223
	else {
1224
	    $log->result("OK");
1224
	    $log->result("OK");
1225
	}
1225
	}
1226
    }
1226
    }
1227
 
1227
 
1228
    ## Check foreign function calls.
1228
    ## Check foreign function calls.
1229
 
1229
 
1230
    if($opt_ff_calls && (-d "R")) {
1230
    if($opt_ff_calls && (-d "R")) {
1231
	$log->checking("foreign function calls");
1231
	$log->checking("foreign function calls");
1232
 
1232
 
1233
	my @msg_ff_calls =
1233
	my @msg_ff_calls =
1234
	  ("See section 'System and foreign language interfaces'",
1234
	  ("See section 'System and foreign language interfaces'",
1235
	   "of the 'Writing R Extensions' manual.\n");
1235
	   "of the 'Writing R Extensions' manual.\n");
1236
 
1236
 
1237
	my $Rcmd = "options(warn=1)\n";
1237
	my $Rcmd = "options(warn=1)\n";
1238
	if($opt_install) {
1238
	if($opt_install) {
1239
	    $Rcmd .= "tools::checkFF(package = \"${pkgname}\")\n";
1239
	    $Rcmd .= "tools::checkFF(package = \"${pkgname}\")\n";
1240
	}
1240
	}
1241
        else {
1241
        else {
1242
	    $Rcmd .= "tools::checkFF(dir = \"${pkgdir}\")\n";
1242
	    $Rcmd .= "tools::checkFF(dir = \"${pkgdir}\")\n";
1243
	}
1243
	}
1244
 
1244
 
1245
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1245
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1246
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1246
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1247
	@out = grep(!/^\>/, @out);
1247
	@out = grep(!/^\>/, @out);
1248
	if(scalar(@out) > 0) {
1248
	if(scalar(@out) > 0) {
1249
	    $log->warning();
1249
	    $log->warning();
1250
	    $log->print(join("\n", @out) . "\n");
1250
	    $log->print(join("\n", @out) . "\n");
1251
	    $log->print(wrap("", "", @msg_ff_calls));
1251
	    $log->print(wrap("", "", @msg_ff_calls));
1252
	}
1252
	}
1253
	else {
1253
	else {
1254
	    $log->result("OK");
1254
	    $log->result("OK");
1255
	}
1255
	}
1256
    }
1256
    }
1257
 
1257
 
1258
    ## Check R code for possible problems using LT's codetools package
1258
    ## Check R code for possible problems using LT's codetools package
1259
    ## available from http://www.stat.uiowa.edu/~luke/R/codetools, and
1259
    ## available from http://www.stat.uiowa.edu/~luke/R/codetools, and
1260
    ## scheduled for integration into base R eventually).
1260
    ## scheduled for integration into base R eventually).
1261
 
1261
 
1262
    ## Activated only via setting the internal environment variable
1262
    ## Activated only via setting the internal environment variable
1263
    ## _R_CHECK_USE_CODETOOLS_ to something "true".
1263
    ## _R_CHECK_USE_CODETOOLS_ to something "true".
1264
 
1264
 
1265
    my $R_check_use_codetools =
1265
    my $R_check_use_codetools =
1266
	&R_getenv("_R_CHECK_USE_CODETOOLS_", "FALSE");
1266
	&R_getenv("_R_CHECK_USE_CODETOOLS_", "FALSE");
1267
    $R_check_use_codetools =
1267
    $R_check_use_codetools =
1268
	&config_val_to_logical($R_check_use_codetools);
1268
	&config_val_to_logical($R_check_use_codetools);
1269
 
1269
 
1270
    if($R_check_use_codetools && $opt_install && (-d "R")) {
1270
    if($R_check_use_codetools && $opt_install && (-d "R")) {
1271
	$log->checking("R code for possible problems");
1271
	$log->checking("R code for possible problems");
1272
 
1272
 
1273
	my $Rcmd = "options(warn=1)\n";
1273
	my $Rcmd = "options(warn=1)\n";
1274
	$Rcmd .= "tools:::.check_code_usage_in_package(package = \"${pkgname}\")\n";
1274
	$Rcmd .= "tools:::.check_code_usage_in_package(package = \"${pkgname}\")\n";
1275
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1275
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1276
                         "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1276
                         "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1277
	@out = grep(!/^\>/, @out);
1277
	@out = grep(!/^\>/, @out);
1278
	## <FIXME>
-
 
1279
	## Temporarily work around R 2.3.0 NULL environment changes.
-
 
1280
        @out = grep(!/^Warning: use of NULL environment is deprecated/,
-
 
1281
		    @out);
-
 
1282
	## </FIXME>
-
 
1283
	if(scalar(@out) > 0) {
1278
	if(scalar(@out) > 0) {
1284
	    $log->warning();
1279
	    $log->warning();
1285
	    $log->print(join("\n", @out) . "\n");
1280
	    $log->print(join("\n", @out) . "\n");
1286
	}
1281
	}
1287
	else {
1282
	else {
1288
	    $log->result("OK");
1283
	    $log->result("OK");
1289
	}
1284
	}
1290
    }
1285
    }
1291
 
1286
 
1292
    ## Check R documentation files.
1287
    ## Check R documentation files.
1293
 
1288
 
1294
    my @msg_writing_Rd
1289
    my @msg_writing_Rd
1295
      = ("See chapter 'Writing R documentation files'",
1290
      = ("See chapter 'Writing R documentation files'",
1296
	 "in manual 'Writing R Extensions'.\n");
1291
	 "in manual 'Writing R Extensions'.\n");
1297
 
1292
 
1298
    if(-d "man") {
1293
    if(-d "man") {
1299
	$log->checking("Rd files");
1294
	$log->checking("Rd files");
1300
 
1295
 
1301
	my $Rcmd = "options(warn=1)\ntools:::check_Rd_files_in_man_dir(\"man\")\n";
1296
	my $Rcmd = "options(warn=1)\ntools:::check_Rd_files_in_man_dir(\"man\")\n";
1302
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1297
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1303
			 "R_DEFAULT_PACKAGES=NULL");
1298
			 "R_DEFAULT_PACKAGES=NULL");
1304
	@out = grep(!/^\>/, @out);
1299
	@out = grep(!/^\>/, @out);
1305
	if(scalar(@out) > 0) {
1300
	if(scalar(@out) > 0) {
1306
	    ## Output may indicate warnings or errors ...
1301
	    ## Output may indicate warnings or errors ...
1307
	    if(grep(/^Rd files with (syntax errors|missing or empty)/,
1302
	    if(grep(/^Rd files with (syntax errors|missing or empty)/,
1308
		    @out)) {
1303
		    @out)) {
1309
		$log->error();
1304
		$log->error();
1310
		$log->print(join("\n", @out) . "\n");
1305
		$log->print(join("\n", @out) . "\n");
1311
		$log->print(wrap("", "", @msg_writing_Rd));
1306
		$log->print(wrap("", "", @msg_writing_Rd));
1312
		exit(1);
1307
		exit(1);
1313
	    }
1308
	    }
1314
	    else {
1309
	    else {
1315
		$log->warning();
1310
		$log->warning();
1316
		$log->print(join("\n", @out) . "\n");
1311
		$log->print(join("\n", @out) . "\n");
1317
		$log->print(wrap("", "", @msg_writing_Rd));
1312
		$log->print(wrap("", "", @msg_writing_Rd));
1318
	    }
1313
	    }
1319
	}
1314
	}
1320
	else {
1315
	else {
1321
	    $log->result("OK");
1316
	    $log->result("OK");
1322
	}
1317
	}
1323
    }
1318
    }
1324
 
1319
 
1325
    ## Check cross-references in R documentation files.
1320
    ## Check cross-references in R documentation files.
1326
 
1321
 
1327
    ## <NOTE>
1322
    ## <NOTE>
1328
    ## Installing a package warns about missing links (and hence R CMD
1323
    ## Installing a package warns about missing links (and hence R CMD
1329
    ## check knows about this too provided an install log is used).
1324
    ## check knows about this too provided an install log is used).
1330
    ## However, under Windows the install-time check verifies the links
1325
    ## However, under Windows the install-time check verifies the links
1331
    ## against what is available in the default library, which might be
1326
    ## against what is available in the default library, which might be
1332
    ## considerably more than what can be assumed to be available.
1327
    ## considerably more than what can be assumed to be available.
1333
    ##
1328
    ##
1334
    ## The formulations in section "Cross-references" of R-exts are not
1329
    ## The formulations in section "Cross-references" of R-exts are not
1335
    ## quite clear about this, but CRAN policy has for a long time
1330
    ## quite clear about this, but CRAN policy has for a long time
1336
    ## enforced anchoring links to targets (aliases) from non-base
1331
    ## enforced anchoring links to targets (aliases) from non-base
1337
    ## packages.
1332
    ## packages.
1338
    ##
1333
    ##
1339
    ## For the time being, if the package is installed only run the test
1334
    ## For the time being, if the package is installed only run the test
1340
    ## if the internal environment variable _R_CHECK_RD_XREFS_ is set to
1335
    ## if the internal environment variable _R_CHECK_RD_XREFS_ is set to
1341
    ## something "true".  Most likely one should always run the check if
1336
    ## something "true".  Most likely one should always run the check if
1342
    ## no install log is used.
1337
    ## no install log is used.
1343
 
1338
 
1344
    if(-d "man") {
1339
    if(-d "man") {
1345
	my $R_check_Rd_xrefs = &R_getenv("_R_CHECK_RD_XREFS_", "FALSE");
1340
	my $R_check_Rd_xrefs = &R_getenv("_R_CHECK_RD_XREFS_", "FALSE");
1346
	$R_check_Rd_xrefs = &config_val_to_logical($R_check_Rd_xrefs);
1341
	$R_check_Rd_xrefs = &config_val_to_logical($R_check_Rd_xrefs);
1347
 
1342
 
1348
	if(($opt_install && $R_check_Rd_xrefs) || !$opt_install) {
1343
	if(($opt_install && $R_check_Rd_xrefs) || !$opt_install) {
1349
 
1344
 
1350
	    $log->checking("Rd cross-references");
1345
	    $log->checking("Rd cross-references");
1351
 
1346
 
1352
	    my $Rcmd = "options(warn=1)\n";
1347
	    my $Rcmd = "options(warn=1)\n";
1353
	    if($opt_install) {
1348
	    if($opt_install) {
1354
		$Rcmd .= "tools:::.check_Rd_xrefs(package = \"${pkgname}\")\n";
1349
		$Rcmd .= "tools:::.check_Rd_xrefs(package = \"${pkgname}\")\n";
1355
	    }
1350
	    }
1356
	    else {
1351
	    else {
1357
		$Rcmd .= "tools:::.check_Rd_xrefs(dir = \"${pkgdir}\")\n";
1352
		$Rcmd .= "tools:::.check_Rd_xrefs(dir = \"${pkgdir}\")\n";
1358
	    }
1353
	    }
1359
 
1354
 
1360
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1355
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1361
			     "R_DEFAULT_PACKAGES=NULL");
1356
			     "R_DEFAULT_PACKAGES=NULL");
1362
	    @out = grep(!/^\>/, @out);
1357
	    @out = grep(!/^\>/, @out);
1363
	    if(scalar(@out) > 0) {
1358
	    if(scalar(@out) > 0) {
1364
		$log->warning();
1359
		$log->warning();
1365
		$log->print(join("\n", @out) . "\n");
1360
		$log->print(join("\n", @out) . "\n");
1366
	    }
1361
	    }
1367
	    else {
1362
	    else {
1368
		$log->result("OK");
1363
		$log->result("OK");
1369
	    }
1364
	    }
1370
	}
1365
	}
1371
    }
1366
    }
1372
 
1367
 
1373
    ## Check for missing documentation entries.
1368
    ## Check for missing documentation entries.
1374
 
1369
 
1375
    if(((-d "R") || (-d "data"))) {
1370
    if(((-d "R") || (-d "data"))) {
1376
	$log->checking("for missing documentation entries");
1371
	$log->checking("for missing documentation entries");
1377
 
1372
 
1378
	my $Rcmd= "options(warn=1)\n";
1373
	my $Rcmd= "options(warn=1)\n";
1379
	if($opt_install) {
1374
	if($opt_install) {
1380
	    $Rcmd .= "tools::undoc(package = \"${pkgname}\")\n";
1375
	    $Rcmd .= "tools::undoc(package = \"${pkgname}\")\n";
1381
	}
1376
	}
1382
	else {
1377
	else {
1383
	    $Rcmd .= "tools::undoc(dir = \"${pkgdir}\")\n";
1378
	    $Rcmd .= "tools::undoc(dir = \"${pkgdir}\")\n";
1384
	}
1379
	}
1385
 
1380
 
1386
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1381
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1387
                         "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1382
                         "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1388
	my @err = grep(/^Error/, @out);
1383
	my @err = grep(/^Error/, @out);
1389
	@out = grep(!/^\>/, @out);
1384
	@out = grep(!/^\>/, @out);
1390
	if(scalar(@err) > 0) {
1385
	if(scalar(@err) > 0) {
1391
	    $log->error();
1386
	    $log->error();
1392
	    $log->print(join("\n", @err) . "\n");
1387
	    $log->print(join("\n", @err) . "\n");
1393
	    exit(1);
1388
	    exit(1);
1394
	}
1389
	}
1395
	elsif(scalar(@out) > 0) {
1390
	elsif(scalar(@out) > 0) {
1396
	    $log->warning();
1391
	    $log->warning();
1397
	    $log->print(join("\n", @out) . "\n");
1392
	    $log->print(join("\n", @out) . "\n");
1398
	    my $details;
1393
	    my $details;
1399
	    $details = " (including S4 classes and methods)"
1394
	    $details = " (including S4 classes and methods)"
1400
	      if(grep(/^Undocumented S4/, @out));
1395
	      if(grep(/^Undocumented S4/, @out));
1401
	    $log->print(wrap("", "",
1396
	    $log->print(wrap("", "",
1402
			     ("All user-level objects",
1397
			     ("All user-level objects",
1403
			      "in a package${details} should",
1398
			      "in a package${details} should",
1404
			      "have documentation entries.\n")));
1399
			      "have documentation entries.\n")));
1405
	    $log->print(wrap("", "", @msg_writing_Rd));
1400
	    $log->print(wrap("", "", @msg_writing_Rd));
1406
	}
1401
	}
1407
	else {
1402
	else {
1408
	    $log->result("OK");
1403
	    $log->result("OK");
1409
	}
1404
	}
1410
    }
1405
    }
1411
 
1406
 
1412
    ## Check for code/documentation mismatches.
1407
    ## Check for code/documentation mismatches.
1413
 
1408
 
1414
    if($opt_codoc && (-d "man")) {
1409
    if($opt_codoc && (-d "man")) {
1415
	$log->checking("for code/documentation mismatches");
1410
	$log->checking("for code/documentation mismatches");
1416
 
1411
 
1417
	my $any = 0;
1412
	my $any = 0;
1418
 
1413
 
1419
	## Check for code/documentation mismatches in functions.
1414
	## Check for code/documentation mismatches in functions.
1420
	if(-d "R") {
1415
	if(-d "R") {
1421
	    my $Rcmd = "options(warn=1)\n";
1416
	    my $Rcmd = "options(warn=1)\n";
1422
	    if($opt_install) {
1417
	    if($opt_install) {
1423
		$Rcmd .= "tools::codoc(package = \"${pkgname}\")\n";
1418
		$Rcmd .= "tools::codoc(package = \"${pkgname}\")\n";
1424
	    }
1419
	    }
1425
	    else {
1420
	    else {
1426
		$Rcmd .= "tools::codoc(dir = \"${pkgdir}\")\n";
1421
		$Rcmd .= "tools::codoc(dir = \"${pkgdir}\")\n";
1427
	    }
1422
	    }
1428
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1423
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1429
			     "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1424
			     "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1430
 
1425
 
1431
	    @out = grep(!/^\>/, @out);
1426
	    @out = grep(!/^\>/, @out);
1432
	    if(scalar(@out) > 0) {
1427
	    if(scalar(@out) > 0) {
1433
		$any++;
1428
		$any++;
1434
		$log->warning();
1429
		$log->warning();
1435
		$log->print(join("\n", @out) . "\n");
1430
		$log->print(join("\n", @out) . "\n");
1436
	    }
1431
	    }
1437
	}
1432
	}
1438
 
1433
 
1439
	## Check for code/documentation mismatches in data sets.
1434
	## Check for code/documentation mismatches in data sets.
1440
	if($opt_install) {
1435
	if($opt_install) {
1441
	    my $Rcmd = "options(warn=1)\ntools::codocData(package = \"${pkgname}\")\n";
1436
	    my $Rcmd = "options(warn=1)\ntools::codocData(package = \"${pkgname}\")\n";
1442
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1437
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1443
			     "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1438
			     "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1444
	    @out = grep(!/^\>/, @out);
1439
	    @out = grep(!/^\>/, @out);
1445
	    if(scalar(@out) > 0) {
1440
	    if(scalar(@out) > 0) {
1446
		$log->warning() unless($any);
1441
		$log->warning() unless($any);
1447
		$any++;
1442
		$any++;
1448
		$log->print(join("\n", @out) . "\n");
1443
		$log->print(join("\n", @out) . "\n");
1449
	    }
1444
	    }
1450
	}
1445
	}
1451
 
1446
 
1452
	## Check for code/documentation mismatches in S4 classes.
1447
	## Check for code/documentation mismatches in S4 classes.
1453
	if($opt_install && (-d "R")) {
1448
	if($opt_install && (-d "R")) {
1454
	    my $Rcmd = "options(warn=1)\ntools::codocClasses(package = \"${pkgname}\")\n";
1449
	    my $Rcmd = "options(warn=1)\ntools::codocClasses(package = \"${pkgname}\")\n";
1455
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1450
	    my @out = R_runR($Rcmd, "${R_opts} --quiet",
1456
			     "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1451
			     "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1457
	    @out = grep(!/^\>/, @out);
1452
	    @out = grep(!/^\>/, @out);
1458
	    if(scalar(@out) > 0) {
1453
	    if(scalar(@out) > 0) {
1459
		$log->warning() unless($any);
1454
		$log->warning() unless($any);
1460
		$any++;
1455
		$any++;
1461
		$log->print(join("\n", @out) . "\n");
1456
		$log->print(join("\n", @out) . "\n");
1462
	    }
1457
	    }
1463
	}
1458
	}
1464
 
1459
 
1465
	$log->result("OK") unless($any);
1460
	$log->result("OK") unless($any);
1466
 
1461
 
1467
    }
1462
    }
1468
 
1463
 
1469
    ## Check Rd files, for consistency of \usage with \arguments (are
1464
    ## Check Rd files, for consistency of \usage with \arguments (are
1470
    ## all arguments shown in \usage documented in \arguments?) and
1465
    ## all arguments shown in \usage documented in \arguments?) and
1471
    ## aliases (do all functions shown in \usage have an alias?)
1466
    ## aliases (do all functions shown in \usage have an alias?)
1472
 
1467
 
1473
    if(-d "man") {
1468
    if(-d "man") {
1474
	$log->checking("Rd \\usage sections");
1469
	$log->checking("Rd \\usage sections");
1475
 
1470
 
1476
	my @msg_doc_files =
1471
	my @msg_doc_files =
1477
	  ("Functions with \\usage entries",
1472
	  ("Functions with \\usage entries",
1478
	   "need to have the appropriate \\alias entries,",
1473
	   "need to have the appropriate \\alias entries,",
1479
	   "and all their arguments documented.\n",
1474
	   "and all their arguments documented.\n",
1480
	   "The \\usage entries must correspond to syntactically",
1475
	   "The \\usage entries must correspond to syntactically",
1481
	   "valid R code.\n");
1476
	   "valid R code.\n");
1482
 
1477
 
1483
	my $Rcmd = "options(warn=1)\n";
1478
	my $Rcmd = "options(warn=1)\n";
1484
	if($opt_install) {
1479
	if($opt_install) {
1485
	    $Rcmd .= "tools::checkDocFiles(package = \"${pkgname}\")\n";
1480
	    $Rcmd .= "tools::checkDocFiles(package = \"${pkgname}\")\n";
1486
	}
1481
	}
1487
	else {
1482
	else {
1488
	    $Rcmd .= "tools::checkDocFiles(dir = \"${pkgdir}\")\n";
1483
	    $Rcmd .= "tools::checkDocFiles(dir = \"${pkgdir}\")\n";
1489
	}
1484
	}
1490
 
1485
 
1491
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1486
        my @out = R_runR($Rcmd, "${R_opts} --quiet",
1492
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1487
			 "R_DEFAULT_PACKAGES='utils,grDevices,graphics,stats'");
1493
	@out = grep(!/^\>/, @out);
1488
	@out = grep(!/^\>/, @out);
1494
	if(scalar(@out) > 0) {
1489
	if(scalar(@out) > 0) {
1495
	    $log->warning();
1490
	    $log->warning();
1496
	    $log->print(join("\n", @out) . "\n");
1491
	    $log->print(join("\n", @out) . "\n");
1497
	    $log->print(wrap("", "", @msg_doc_files));
1492
	    $log->print(wrap("", "", @msg_doc_files));
1498
	    $log->print(wrap("", "", @msg_writing_Rd));
1493
	    $log->print(wrap("", "", @msg_writing_Rd));
1499
	}
1494
	}
1500
	else {
1495
	else {
1501
	    $log->result("OK");
1496
	    $log->result("OK");
1502
	}
1497
	}
1503
    }
1498
    }
1504
 
1499
 
1505
    ## Check C/C++/Fortran sources/headers for CRLF line endings.
1500
    ## Check C/C++/Fortran sources/headers for CRLF line endings.
1506
 
1501
 
1507
    ## <FIXME>
1502
    ## <FIXME>
1508
    ## Does ISO C really require LF line endings?  (Reference?)
1503
    ## Does ISO C really require LF line endings?  (Reference?)
1509
    ## We definitely know that some versions of Solaris cc and f77
1504
    ## We definitely know that some versions of Solaris cc and f77
1510
    ## will not accept CRLF or CR line endings.
1505
    ## will not accept CRLF or CR line endings.
1511
    ## Note that we currently only check the CRLF part.
1506
    ## Note that we currently only check the CRLF part.
1512
    ## </FIXME>
1507
    ## </FIXME>
1513
 
1508
 
1514
    if(!$is_base_pkg && (-d "src")) {
1509
    if(!$is_base_pkg && (-d "src")) {
1515
	$log->checking("for CRLF line endings in C/C++/Fortran sources/headers");
1510
	$log->checking("for CRLF line endings in C/C++/Fortran sources/headers");
1516
	my @src_files = &list_files_with_exts("src", "(c|h|f|cc|cpp)");
1511
	my @src_files = &list_files_with_exts("src", "(c|h|f|cc|cpp)");
1517
	my @bad_files = ();
1512
	my @bad_files = ();
1518
	foreach my $file (@src_files) {
1513
	foreach my $file (@src_files) {
1519
	    open(FILE, "< $file")
1514
	    open(FILE, "< $file")
1520
	      or die "Error: cannot open '$file' for reading\n";
1515
	      or die "Error: cannot open '$file' for reading\n";
1521
            binmode(FILE);	# for Windows
1516
            binmode(FILE);	# for Windows
1522
	    while(<FILE>) {
1517
	    while(<FILE>) {
1523
		chop;
1518
		chop;
1524
		if($_ =~ /\r$/) {
1519
		if($_ =~ /\r$/) {
1525
		    push(@bad_files, $file);
1520
		    push(@bad_files, $file);
1526
		    last;
1521
		    last;
1527
		}
1522
		}
1528
	    }
1523
	    }
1529
	    close(FILE);
1524
	    close(FILE);
1530
	}
1525
	}
1531
	if(scalar(@bad_files) > 0) {
1526
	if(scalar(@bad_files) > 0) {
1532
	    $log->warning();
1527
	    $log->warning();
1533
	    $log->print("Found the following sources/headers with " .
1528
	    $log->print("Found the following sources/headers with " .
1534
			"CRLF line endings:\n");
1529
			"CRLF line endings:\n");
1535
	    $log->print("  " . join("\n  ", @bad_files) . "\n");
1530
	    $log->print("  " . join("\n  ", @bad_files) . "\n");
1536
	    $log->print("Some Unix compilers require LF line endings.\n");
1531
	    $log->print("Some Unix compilers require LF line endings.\n");
1537
	}
1532
	}
1538
	else {
1533
	else {
1539
	    $log->result("OK");
1534
	    $log->result("OK");
1540
	}
1535
	}
1541
    }
1536
    }
1542
 
1537
 
1543
    ## Check src/Makevars[.in] for portable compilation flags.
1538
    ## Check src/Makevars[.in] for portable compilation flags.
1544
 
1539
 
1545
    if((-f &file_path("src", "Makevars.in"))
1540
    if((-f &file_path("src", "Makevars.in"))
1546
       || (-f &file_path("src", "Makevars"))) {
1541
       || (-f &file_path("src", "Makevars"))) {
1547
	$log->checking("for portable compilation flags in Makevars");
1542
	$log->checking("for portable compilation flags in Makevars");
1548
	my $Rcmd = "tools:::.check_make_vars(\"src\")\n";
1543
	my $Rcmd = "tools:::.check_make_vars(\"src\")\n";
1549
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1544
	my @out = R_runR($Rcmd, "${R_opts} --quiet",
1550
			 "R_DEFAULT_PACKAGES=NULL");
1545
			 "R_DEFAULT_PACKAGES=NULL");
1551
	@out = grep(!/^\>/, @out);
1546
	@out = grep(!/^\>/, @out);
1552
	if(scalar(@out) > 0) {
1547
	if(scalar(@out) > 0) {
1553
	    $log->warning();
1548
	    $log->warning();
1554
	    $log->print(join("\n", @out) . "\n");
1549
	    $log->print(join("\n", @out) . "\n");
1555
	}
1550
	}
1556
	else {
1551
	else {
1557
	    $log->result("OK");
1552
	    $log->result("OK");
1558
	}
1553
	}
1559
    }
1554
    }
1560
 
1555
 
1561
 
1556
 
1562
    chdir($pkgoutdir);
1557
    chdir($pkgoutdir);
1563
 
1558
 
1564
    ## Run the examples.
1559
    ## Run the examples.
1565
    ## This setting applies to vignettes below too.
1560
    ## This setting applies to vignettes below too.
1566
    ${R_opts} = ${R_opts}." -d valgrind" if $opt_use_valgrind;
1561
    ${R_opts} = ${R_opts}." -d valgrind" if $opt_use_valgrind;
1567
 
1562
 
1568
    if($opt_examples && (-d &file_path($library, $pkgname, "R-ex"))) {
1563
    if($opt_examples && (-d &file_path($library, $pkgname, "R-ex"))) {
1569
	$log->creating("${pkgname}-Ex.R");
1564
	$log->creating("${pkgname}-Ex.R");
1570
	my $Rexdir = &file_path($library, $pkgname, "R-ex");
1565
	my $Rexdir = &file_path($library, $pkgname, "R-ex");
1571
        ## $Rexdir might contain spaces (not on Windows)
1566
        ## $Rexdir might contain spaces (not on Windows)
1572
        my $is_zipped = 0;
1567
        my $is_zipped = 0;
1573
	my $cmd;
1568
	my $cmd;
1574
 
1569
 
1575
        if(-e &file_path($Rexdir, "Rex.zip")) {
1570
        if(-e &file_path($Rexdir, "Rex.zip")) {
1576
            $is_zipped = 1;
1571
            $is_zipped = 1;
1577
	    my $UNZIP = &R_getenv("R_UNZIPCMD", "unzip");
1572
	    my $UNZIP = &R_getenv("R_UNZIPCMD", "unzip");
1578
            my $Rexfile = &file_path($Rexdir, "Rex.zip");
1573
            my $Rexfile = &file_path($Rexdir, "Rex.zip");
1579
	    $cmd = join(" ",
1574
	    $cmd = join(" ",
1580
			("$UNZIP", "-q",
1575
			("$UNZIP", "-q",
1581
			 &shell_quote_file_path($Rexfile),
1576
			 &shell_quote_file_path($Rexfile),
1582
			 "-d",
1577
			 "-d",
1583
			 &shell_quote_file_path($Rexdir)));
1578
			 &shell_quote_file_path($Rexdir)));
1584
	    if(R_system($cmd)) {
1579
	    if(R_system($cmd)) {
1585
		$log->error();
1580
		$log->error();
1586
		$log->print("Cannot extract examples from ZIP archive.\n");
1581
		$log->print("Cannot extract examples from ZIP archive.\n");
1587
		exit(1);
1582
		exit(1);
1588
	    }
1583
	    }
1589
        }
1584
        }
1590
        if($WINDOWS) {
1585
        if($WINDOWS) {
1591
            ## avoid Rcmd as line may be too long after expansion.
1586
            ## avoid Rcmd as line may be too long after expansion.
1592
            ## We've forced R_HOME and Rexdir to have no spaces already.
1587
            ## We've forced R_HOME and Rexdir to have no spaces already.
1593
            $cmd = "perl ${R::Vars::R_HOME}/bin/massage-Examples ".
1588
            $cmd = "perl ${R::Vars::R_HOME}/bin/massage-Examples ".
1594
  		     "${pkgname} ${Rexdir} ".
1589
  		     "${pkgname} ${Rexdir} ".
1595
  		     "> ${pkgname}-Ex.R";
1590
  		     "> ${pkgname}-Ex.R";
1596
        } else {
1591
        } else {
1597
	    $cmd =
1592
	    $cmd =
1598
		join(" ",
1593
		join(" ",
1599
		     (&shell_quote_file_path(${R::Vars::R_EXE}),
1594
		     (&shell_quote_file_path(${R::Vars::R_EXE}),
1600
		      "CMD perl",
1595
		      "CMD perl",
1601
		      &shell_quote_file_path(&file_path(${R::Vars::R_SHARE_DIR},
1596
		      &shell_quote_file_path(&file_path(${R::Vars::R_SHARE_DIR},
1602
							"perl",
1597
							"perl",
1603
							"massage-Examples.pl")),
1598
							"massage-Examples.pl")),
1604
		      "${pkgname}",
1599
		      "${pkgname}",
1605
		      &shell_quote_file_path(${Rexdir}),
1600
		      &shell_quote_file_path(${Rexdir}),
1606
		      "> ${pkgname}-Ex.R"));
1601
		      "> ${pkgname}-Ex.R"));
1607
        }
1602
        }
1608
 
1603
 
1609
 	if(R_system($cmd)) {
1604
 	if(R_system($cmd)) {
1610
  	    $log->error();
1605
  	    $log->error();
1611
	    $log->print("Running massage-Examples to create " .
1606
	    $log->print("Running massage-Examples to create " .
1612
			"${pkgname}-Ex.R failed.\n");
1607
			"${pkgname}-Ex.R failed.\n");
1613
  	    exit(1);
1608
  	    exit(1);
1614
        }
1609
        }
1615
        if($is_zipped) {
1610
        if($is_zipped) {
1616
            unlink(&list_files_with_exts($Rexdir, "R"));
1611
            unlink(&list_files_with_exts($Rexdir, "R"));
1617
        }
1612
        }
1618
 
1613
 
1619
	$log->result("OK");
1614
	$log->result("OK");
1620
	$log->checking("examples");
1615
	$log->checking("examples");
1621
 
1616
 
1622
	if($opt_use_gct) {
1617
	if($opt_use_gct) {
1623
            $cmd = join(" ",
1618
            $cmd = join(" ",
1624
			("(echo 'gctorture(TRUE)';",
1619
			("(echo 'gctorture(TRUE)';",
1625
			 "cat ${pkgname}-Ex.R) |",
1620
			 "cat ${pkgname}-Ex.R) |",
1626
			 &shell_quote_file_path(${R::Vars::R_EXE}),
1621
			 &shell_quote_file_path(${R::Vars::R_EXE}),
1627
			 "${R_opts}",
1622
			 "${R_opts}",
1628
			 "> ${pkgname}-Ex.Rout 2>&1"));
1623
			 "> ${pkgname}-Ex.Rout 2>&1"));
1629
	} else {
1624
	} else {
1630
	    $cmd = join(" ",
1625
	    $cmd = join(" ",
1631
			(&shell_quote_file_path(${R::Vars::R_EXE}),
1626
			(&shell_quote_file_path(${R::Vars::R_EXE}),
1632
			 "${R_opts}",
1627
			 "${R_opts}",
1633
			 "< ${pkgname}-Ex.R",
1628
			 "< ${pkgname}-Ex.R",
1634
			 "> ${pkgname}-Ex.Rout 2>&1"));
1629
			 "> ${pkgname}-Ex.Rout 2>&1"));
1635
	}
1630
	}
1636
	if(R_system($cmd)) {
1631
	if(R_system($cmd)) {
1637
	    $log->error();
1632
	    $log->error();
1638
	    $log->print("Running examples in ${pkgname}-Ex.R failed.\n");
1633
	    $log->print("Running examples in ${pkgname}-Ex.R failed.\n");
1639
	    ## Try to spot the offending example right away.
1634
	    ## Try to spot the offending example right away.
1640
	    my $txt = join("\n", &read_lines("${pkgname}-Ex.Rout"));
1635
	    my $txt = join("\n", &read_lines("${pkgname}-Ex.Rout"));
1641
	    ## Look for the header section anchored by a subsequent call
1636
	    ## Look for the header section anchored by a subsequent call
1642
	    ## to flush(): needs to be kept in sync with the code in
1637
	    ## to flush(): needs to be kept in sync with the code in
1643
	    ## massage-Examples.pl.  Should perhaps also be more
1638
	    ## massage-Examples.pl.  Should perhaps also be more
1644
	    ## defensive about the prompt ...
1639
	    ## defensive about the prompt ...
1645
	    my @chunks = split(/(> \#\#\# \* [^\n]+\n> \n> flush)/, $txt);
1640
	    my @chunks = split(/(> \#\#\# \* [^\n]+\n> \n> flush)/, $txt);
1646
	    if(scalar(@chunks) > 2) {
1641
	    if(scalar(@chunks) > 2) {
1647
		$log->print("The error most likely occurred in:\n\n");
1642
		$log->print("The error most likely occurred in:\n\n");
1648
		$log->print($chunks[$#chunks - 1]);
1643
		$log->print($chunks[$#chunks - 1]);
1649
		$log->print($chunks[$#chunks] . "\n");
1644
		$log->print($chunks[$#chunks] . "\n");
1650
	    }
1645
	    }
1651
	    exit(1);
1646
	    exit(1);
1652
	}
1647
	}
1653
	## Look at the output from running the examples.  For the time
1648
	## Look at the output from running the examples.  For the time
1654
	## being, report warnings about use of deprecated functions, as
1649
	## being, report warnings about use of deprecated functions, as
1655
	## the next release will make them defunct and hence using them
1650
	## the next release will make them defunct and hence using them
1656
	## an error.  Also warn about loading defunct base package stubs,
1651
	## an error.  Also warn about loading defunct base package stubs,
1657
	## as load special-casing for these will be removed eventually.
1652
	## as load special-casing for these will be removed eventually.
1658
	my @lines = &read_lines("${pkgname}-Ex.Rout");
1653
	my @lines = &read_lines("${pkgname}-Ex.Rout");
1659
	my $any;
1654
	my $any;
1660
	my @bad_lines;
1655
	my @bad_lines;
1661
	@bad_lines = grep(/^Warning: .*is deprecated.$/, @lines);
1656
	@bad_lines = grep(/^Warning: .*is deprecated.$/, @lines);
1662
	if(scalar(@bad_lines) > 0) {
1657
	if(scalar(@bad_lines) > 0) {
1663
	    $log->warning();
1658
	    $log->warning();
1664
	    $any++;
1659
	    $any++;
1665
	    $log->print("Found the following significant warnings:\n");
1660
	    $log->print("Found the following significant warnings:\n");
1666
	    $log->print("  " . join("\n  ", @bad_lines) . "\n");
1661
	    $log->print("  " . join("\n  ", @bad_lines) . "\n");
1667
	    $log->print(wrap("", "",
1662
	    $log->print(wrap("", "",
1668
			     ("Deprecated functions may be defunct as",
1663
			     ("Deprecated functions may be defunct as",
1669
			      "soon as of the next release of R.\n",
1664
			      "soon as of the next release of R.\n",
1670
			      "See ?Deprecated.\n")));
1665
			      "See ?Deprecated.\n")));
1671
	}
1666
	}
1672
	@bad_lines = grep(/^Warning: package '.*' has been merged into/,
1667
	@bad_lines = grep(/^Warning: package '.*' has been merged into/,
1673
			  @lines);
1668
			  @lines);
1674
	## Could make this more precise by looking for an exact match
1669
	## Could make this more precise by looking for an exact match
1675
	## for one of the defunct stubs, but we currently do not get
1670
	## for one of the defunct stubs, but we currently do not get
1676
	## R_PKGS_STUBS from 'share/make/vars.mk'.
1671
	## R_PKGS_STUBS from 'share/make/vars.mk'.
1677
	if(scalar(@bad_lines) > 0) {
1672
	if(scalar(@bad_lines) > 0) {
1678
	    if($any) {
1673
	    if($any) {
1679
		$log->print("\nAdditional significant warnings:\n");
1674
		$log->print("\nAdditional significant warnings:\n");
1680
	    }
1675
	    }
1681
	    else {
1676
	    else {
1682
		$log->warning();
1677
		$log->warning();
1683
		$any++;
1678
		$any++;
1684
		$log->print("Found the following significant " .
1679
		$log->print("Found the following significant " .
1685
			    "warnings:\n");
1680
			    "warnings:\n");
1686
	    }
1681
	    }
1687
	    $log->print("  " . join("\n  ", @bad_lines) . "\n");
1682
	    $log->print("  " . join("\n  ", @bad_lines) . "\n");
1688
	    $log->print(wrap("", "",
1683
	    $log->print(wrap("", "",
1689
			     ("Support for loading defunct former base",
1684
			     ("Support for loading defunct former base",
1690
			      "packages may be removed as soon as of",
1685
			      "packages may be removed as soon as of",
1691
			      "the next release of R.\n")));
1686
			      "the next release of R.\n")));
1692
	}
1687
	}
1693
	$log->result("OK") unless($any);
1688
	$log->result("OK") unless($any);
1694
    }
1689
    }
1695
 
1690
 
1696
    ## Run the package-specific tests.
1691
    ## Run the package-specific tests.
1697
 
1692
 
1698
    if($opt_install && $opt_tests && (-d &file_path($pkgdir, "tests"))) {
1693
    if($opt_install && $opt_tests && (-d &file_path($pkgdir, "tests"))) {
1699
        $log->checking("tests");
1694
        $log->checking("tests");
1700
        my $testsrcdir = &file_path($pkgdir, "tests");
1695
        my $testsrcdir = &file_path($pkgdir, "tests");
1701
        my $testdir = &file_path($pkgoutdir, "tests");
1696
        my $testdir = &file_path($pkgoutdir, "tests");
1702
        if(!(-d $testdir)) {
1697
        if(!(-d $testdir)) {
1703
            mkdir($testdir, 0755)
1698
            mkdir($testdir, 0755)
1704
	      or die "Error: cannot create directory '$testdir'\n";
1699
	      or die "Error: cannot create directory '$testdir'\n";
1705
        }
1700
        }
1706
        chdir($testdir);
1701
        chdir($testdir);
1707
	foreach my $file (&list_files($testsrcdir)) {
1702
	foreach my $file (&list_files($testsrcdir)) {
1708
	    copy($file, basename($file));
1703
	    copy($file, basename($file));
1709
	}
1704
	}
1710
        my $makefiles = "-f " .
1705
        my $makefiles = "-f " .
1711
	    &shell_quote_file_path(&file_path(${R::Vars::R_SHARE_DIR},
1706
	    &shell_quote_file_path(&file_path(${R::Vars::R_SHARE_DIR},
1712
					      "make", "tests.mk"));
1707
					      "make", "tests.mk"));
1713
        if($WINDOWS) {
1708
        if($WINDOWS) {
1714
            $makefiles = "-f ${R::Vars::R_SHARE_DIR}/make/wintests.mk";}
1709
            $makefiles = "-f ${R::Vars::R_SHARE_DIR}/make/wintests.mk";}
1715
        my $makevars = "";
1710
        my $makevars = "";
1716
        if($WINDOWS && (-r "$testsrcdir/Makefile.win")) {
1711
        if($WINDOWS && (-r "$testsrcdir/Makefile.win")) {
1717
            $makefiles .= " -f $testsrcdir/Makefile.win";
1712
            $makefiles .= " -f $testsrcdir/Makefile.win";
1718
        }
1713
        }
1719
        elsif(-r &file_path($testsrcdir, "Makefile")) {
1714
        elsif(-r &file_path($testsrcdir, "Makefile")) {
1720
            $makefiles .= " -f " . &file_path($testsrcdir, "Makefile");
1715
            $makefiles .= " -f " . &file_path($testsrcdir, "Makefile");
1721
        }
1716
        }
1722
        if($WINDOWS && (-r "$testsrcdir/Makevars.win")) {
1717
        if($WINDOWS && (-r "$testsrcdir/Makevars.win")) {
1723
            $makevars = " -f $testsrcdir/Makevars.win";
1718
            $makevars = " -f $testsrcdir/Makevars.win";
1724
        }
1719
        }
1725
        elsif(-r &file_path($testsrcdir, "Makevars")) {
1720
        elsif(-r &file_path($testsrcdir, "Makevars")) {
1726
            $makevars = " -f " . &file_path($testsrcdir, "Makevars");
1721
            $makevars = " -f " . &file_path($testsrcdir, "Makevars");
1727
        }
1722
        }
1728
        else {
1723
        else {
1729
            open(MAKEVARS, "> Makevars");
1724
            open(MAKEVARS, "> Makevars");
1730
            print MAKEVARS "makevars = -f Makevars\n";
1725
            print MAKEVARS "makevars = -f Makevars\n";
1731
            print MAKEVARS "srcdir = $testsrcdir\n";
1726
            print MAKEVARS "srcdir = $testsrcdir\n";
1732
            ## at least windows does not pass env correctly to make
1727
            ## at least windows does not pass env correctly to make
1733
            print MAKEVARS "R_LIBS = $ENV{'R_LIBS'}\n";
1728
            print MAKEVARS "R_LIBS = $ENV{'R_LIBS'}\n";
1734
            print MAKEVARS "VPATH = \$(srcdir)\n\n";
1729
            print MAKEVARS "VPATH = \$(srcdir)\n\n";
1735
            print MAKEVARS "test-src-1 =";
1730
            print MAKEVARS "test-src-1 =";
1736
	    foreach my $file (sort &list_files_with_exts($testdir, "R")) {
1731
	    foreach my $file (sort &list_files_with_exts($testdir, "R")) {
1737
                print MAKEVARS "\\\n " . basename($file);
1732
                print MAKEVARS "\\\n " . basename($file);
1738
            }
1733
            }
1739
            print MAKEVARS "\n";
1734
            print MAKEVARS "\n";
1740
            print MAKEVARS "test-src-auto =";
1735
            print MAKEVARS "test-src-auto =";
1741
	    foreach my $file (sort &list_files_with_exts($testdir, "Rin")) {
1736
	    foreach my $file (sort &list_files_with_exts($testdir, "Rin")) {
1742
                $file =~ s/Rin$/R/;
1737
                $file =~ s/Rin$/R/;
1743
                print MAKEVARS "\\\n " . basename($file);
1738
                print MAKEVARS "\\\n " . basename($file);
1744
            }
1739
            }
1745
            print MAKEVARS "\n";
1740
            print MAKEVARS "\n";
1746
	    print MAKEVARS "USE_GCT = $opt_use_gct\n";
1741
	    print MAKEVARS "USE_GCT = $opt_use_gct\n";
1747
	    print MAKEVARS "R_OPTS = -d valgrind\n" if $opt_use_valgrind;
1742
	    print MAKEVARS "R_OPTS = -d valgrind\n" if $opt_use_valgrind;
1748
            close(MAKEVARS);
1743
            close(MAKEVARS);
1749
            $makevars = " -f Makevars";
1744
            $makevars = " -f Makevars";
1750
        }
1745
        }
1751
        print "\n";
1746
        print "\n";
1752
        if(R_system("${R::Vars::MAKE} $makefiles $makevars")) {
1747
        if(R_system("${R::Vars::MAKE} $makefiles $makevars")) {
1753
            $log->error();
1748
            $log->error();
1754
            exit(1);
1749
            exit(1);
1755
        }
1750
        }
1756
        chdir($pkgoutdir);
1751
        chdir($pkgoutdir);
1757
        $log->result("OK");
1752
        $log->result("OK");
1758
    }
1753
    }
1759
 
1754
 
1760
    ## Check package vignettes.
1755
    ## Check package vignettes.
1761
 
1756
 
1762
    chdir($pkgoutdir);
1757
    chdir($pkgoutdir);
1763
 
1758
 
1764
    my $vignette_dir = &file_path($pkgdir, "inst", "doc");
1759
    my $vignette_dir = &file_path($pkgdir, "inst", "doc");
1765
    if((-d $vignette_dir)
1760
    if((-d $vignette_dir)
1766
       && &list_files_with_type($vignette_dir, "vignette")) {
1761
       && &list_files_with_type($vignette_dir, "vignette")) {
1767
	$log->checking(join(" ",
1762
	$log->checking(join(" ",
1768
			    ("package vignettes in",
1763
			    ("package vignettes in",
1769
			     &sQuote(&file_path("inst", "doc")))));
1764
			     &sQuote(&file_path("inst", "doc")))));
1770
	my $any = 0;
1765
	my $any = 0;
1771
 
1766
 
1772
	## Do PDFs exist for all package vignettes?
1767
	## Do PDFs exist for all package vignettes?
1773
	my @vignette_files =
1768
	my @vignette_files =
1774
	  &list_files_with_type($vignette_dir, "vignette");
1769
	  &list_files_with_type($vignette_dir, "vignette");
1775
	my @bad_vignettes = ();
1770
	my @bad_vignettes = ();
1776
	foreach my $file (@vignette_files) {
1771
	foreach my $file (@vignette_files) {
1777
	    my $pdf_file = $file;
1772
	    my $pdf_file = $file;
1778
	    $pdf_file =~ s/\.[[:alpha:]]+$/.pdf/;
1773
	    $pdf_file =~ s/\.[[:alpha:]]+$/.pdf/;
1779
	    push(@bad_vignettes, $file) unless(-f $pdf_file);
1774
	    push(@bad_vignettes, $file) unless(-f $pdf_file);
1780
	}
1775
	}
1781
        ## A base package may not have PDFs to avoid blowing out the
1776
        ## A base package may not have PDFs to avoid blowing out the
1782
	## distribution size.  *Note* that it is assumed that base
1777
	## distribution size.  *Note* that it is assumed that base
1783
	## packages can be woven (i.e., that they only contain
1778
	## packages can be woven (i.e., that they only contain
1784
	## "standard" LaTeX).
1779
	## "standard" LaTeX).
1785
	if(!$is_base_pkg && scalar(@bad_vignettes) > 0) {
1780
	if(!$is_base_pkg && scalar(@bad_vignettes) > 0) {
1786
	    $log->warning();
1781
	    $log->warning();
1787
	    $any++;
1782
	    $any++;
1788
	    $log->print("Package vignettes without corresponding PDF:\n");
1783
	    $log->print("Package vignettes without corresponding PDF:\n");
1789
	    $log->print("  " . join("\n  ", @bad_vignettes) . "\n");
1784
	    $log->print("  " . join("\n  ", @bad_vignettes) . "\n");
1790
	}
1785
	}
1791
 
1786
 
1792
	## Can we run the code in the vignettes?
1787
	## Can we run the code in the vignettes?
1793
	if($opt_install && $opt_vignettes) {
1788
	if($opt_install && $opt_vignettes) {
1794
	    ## Should checking the vignettes assume the system default
1789
	    ## Should checking the vignettes assume the system default
1795
	    ## packages, or just base?
1790
	    ## packages, or just base?
1796
	    my $Rcmd = "options(warn=1)\nlibrary(tools)\n";
1791
	    my $Rcmd = "options(warn=1)\nlibrary(tools)\n";
1797
            ## A base package does not get installed during check.
1792
            ## A base package does not get installed during check.
1798
	    if(!$is_base_pkg && $opt_install) {
1793
	    if(!$is_base_pkg && $opt_install) {
1799
		$Rcmd .= "checkVignettes(package = \"${pkgname}\", " .
1794
		$Rcmd .= "checkVignettes(package = \"${pkgname}\", " .
1800
		         "lib.loc = \"${library}\", " .
1795
		         "lib.loc = \"${library}\", " .
1801
		         "workdir = \"src\"";
1796
		         "workdir = \"src\"";
1802
	    }
1797
	    }
1803
	    else {
1798
	    else {
1804
		$Rcmd .= "checkVignettes(dir = \"${pkgdir}\"";
1799
		$Rcmd .= "checkVignettes(dir = \"${pkgdir}\"";
1805
	    }
1800
	    }
1806
	    $Rcmd .= ", weave = FALSE" if(!$R_check_weave_vignettes);
1801
	    $Rcmd .= ", weave = FALSE" if(!$R_check_weave_vignettes);
1807
	    $Rcmd .= ")\n";
1802
	    $Rcmd .= ")\n";
1808
	    my @out = R_runR($Rcmd, "${R_opts} --quiet");
1803
	    my @out = R_runR($Rcmd, "${R_opts} --quiet");
1809
	    ## Vignette could redefine the prompt, e.g. to 'R>' ...
1804
	    ## Vignette could redefine the prompt, e.g. to 'R>' ...
1810
	    @out = grep(!/^[[:alnum:]]*\>/, @out);
1805
	    @out = grep(!/^[[:alnum:]]*\>/, @out);
1811
	    ## Or to "empty".  As empty lines in the output will most
1806
	    ## Or to "empty".  As empty lines in the output will most
1812
	    ## likely not indicate a problem ...
1807
	    ## likely not indicate a problem ...
1813
	    @out = grep(!/^[[:space:]]*$/, @out);
1808
	    @out = grep(!/^[[:space:]]*$/, @out);
1814
	    if(scalar(@out) > 0) {
1809
	    if(scalar(@out) > 0) {
1815
		$log->warning() unless($any);
1810
		$log->warning() unless($any);
1816
		$any++;
1811
		$any++;
1817
		$log->print(join("\n", @out) . "\n");
1812
		$log->print(join("\n", @out) . "\n");
1818
	    }
1813
	    }
1819
	}
1814
	}
1820
 
1815
 
1821
	$log->result("OK") unless($any);
1816
	$log->result("OK") unless($any);
1822
    }
1817
    }
1823
 
1818
 
1824
    ## Run LaTeX on the manual.
1819
    ## Run LaTeX on the manual.
1825
 
1820
 
1826
    if($opt_latex) {
1821
    if($opt_latex) {
1827
        my $latex_dir = &file_path($library, $pkgname, "latex");
1822
        my $latex_dir = &file_path($library, $pkgname, "latex");
1828
	if(-d $latex_dir) {
1823
	if(-d $latex_dir) {
1829
	    $ENV{'TEXINPUTS'} =
1824
	    $ENV{'TEXINPUTS'} =
1830
	      env_path(&file_path($R::Vars::R_SHARE_DIR, "texmf"),
1825
	      env_path(&file_path($R::Vars::R_SHARE_DIR, "texmf"),
1831
		       $ENV{'TEXINPUTS'});
1826
		       $ENV{'TEXINPUTS'});
1832
            my $is_zipped = 0;
1827
            my $is_zipped = 0;
1833
            # latex files might have been zipped
1828
            # latex files might have been zipped
1834
            if(-f &file_path($latex_dir, "Rhelp.zip")) {
1829
            if(-f &file_path($latex_dir, "Rhelp.zip")) {
1835
                $is_zipped = 1;
1830
                $is_zipped = 1;
1836
		my $UNZIP = &R_getenv("R_UNZIPCMD", "unzip");
1831
		my $UNZIP = &R_getenv("R_UNZIPCMD", "unzip");
1837
		my $latex_file = &file_path($latex_dir, "Rhelp.zip");
1832
		my $latex_file = &file_path($latex_dir, "Rhelp.zip");
1838
		$cmd = join(" ",
1833
		$cmd = join(" ",
1839
			    ("$UNZIP", "-q",
1834
			    ("$UNZIP", "-q",
1840
			     &shell_quote_file_path($latex_file),
1835
			     &shell_quote_file_path($latex_file),
1841
			     "-d",
1836
			     "-d",
1842
			     &shell_quote_file_path($latex_dir)));
1837
			     &shell_quote_file_path($latex_dir)));
1843
                if(R_system($cmd)) {
1838
                if(R_system($cmd)) {
1844
		    $log->error();
1839
		    $log->error();
1845
		    $log->print("Unzipping latex files failed.\n");
1840
		    $log->print("Unzipping latex files failed.\n");
1846
		    exit(1);
1841
		    exit(1);
1847
                }
1842
                }
1848
            }
1843
            }
1849
	    $log->creating("${pkgname}-manual.tex");
1844
	    $log->creating("${pkgname}-manual.tex");
1850
	    my @tex_files = &list_files_with_exts($latex_dir, "tex");
1845
	    my @tex_files = &list_files_with_exts($latex_dir, "tex");
1851
	    my %encodings;
1846
	    my %encodings;
1852
	    foreach my $file (@tex_files) {
1847
	    foreach my $file (@tex_files) {
1853
		open(FILE, "< $file")
1848
		open(FILE, "< $file")
1854
		  or die("Error: cannot open file '$file' for reading\n");
1849
		  or die("Error: cannot open file '$file' for reading\n");
1855
		while(<FILE>) {
1850
		while(<FILE>) {
1856
		    if (/^\\inputencoding/) {
1851
		    if (/^\\inputencoding/) {
1857
			$enc = $_;
1852
			$enc = $_;
1858
			chomp $enc;
1853
			chomp $enc;
1859
			$enc =~ s/^\\inputencoding{(.*)}/\1/;
1854
			$enc =~ s/^\\inputencoding{(.*)}/\1/;
1860
			$encodings{$enc} = $enc;
1855
			$encodings{$enc} = $enc;
1861
		    }
1856
		    }
1862
		}
1857
		}
1863
		close(FILE);
1858
		close(FILE);
1864
	    }
1859
	    }
1865
	    my $encs = "";
1860
	    my $encs = "";
1866
	    if (scalar(%encodings)) {
1861
	    if (scalar(%encodings)) {
1867
		$encs = "\\usepackage[" . join(",", values %encodings) .
1862
		$encs = "\\usepackage[" . join(",", values %encodings) .
1868
		    "]{inputenc}";
1863
		    "]{inputenc}";
1869
	    }
1864
	    }
1870
	    open(MANUAL, "> ${pkgname}-manual.tex")
1865
	    open(MANUAL, "> ${pkgname}-manual.tex")
1871
	      or die("Error: cannot open file '${pkgname}-manual.tex'" .
1866
	      or die("Error: cannot open file '${pkgname}-manual.tex'" .
1872
		     "for writing\n");
1867
		     "for writing\n");
1873
	    print MANUAL "\\documentclass\{article\}\n" . $encs .
1868
	    print MANUAL "\\documentclass\{article\}\n" . $encs .
1874
		"\\usepackage[ae,hyper]\{Rd\}\n\\begin\{document\}\n";
1869
		"\\usepackage[ae,hyper]\{Rd\}\n\\begin\{document\}\n";
1875
	    foreach my $file (@tex_files) {
1870
	    foreach my $file (@tex_files) {
1876
		open(FILE, "< $file")
1871
		open(FILE, "< $file")
1877
		  or die("Error: cannot open file '$file' for reading\n");
1872
		  or die("Error: cannot open file '$file' for reading\n");
1878
		while(<FILE>) {
1873
		while(<FILE>) {
1879
		    print MANUAL $_;
1874
		    print MANUAL $_;
1880
		}
1875
		}
1881
		close(FILE);
1876
		close(FILE);
1882
	    }
1877
	    }
1883
	    print MANUAL "\\end\{document\}\n";
1878
	    print MANUAL "\\end\{document\}\n";
1884
	    close(MANUAL);
1879
	    close(MANUAL);
1885
            if($is_zipped) {
1880
            if($is_zipped) {
1886
		unlink(&list_files_with_exts($latex_dir, "tex"));
1881
		unlink(&list_files_with_exts($latex_dir, "tex"));
1887
            }
1882
            }
1888
	    $log->result("OK");
1883
	    $log->result("OK");
1889
	    if($HAVE_LATEX) {
1884
	    if($HAVE_LATEX) {
1890
		$log->checking("${pkgname}-manual.tex");
1885
		$log->checking("${pkgname}-manual.tex");
1891
		## <NOTE>
1886
		## <NOTE>
1892
		## We use \nonstopmode{} so that LaTeX really gives an
1887
		## We use \nonstopmode{} so that LaTeX really gives an
1893
	        ## error (and returns) if something is wrong, and all
1888
	        ## error (and returns) if something is wrong, and all
1894
	        ## info goes to ${pkgname}-manual.log.
1889
	        ## info goes to ${pkgname}-manual.log.
1895
		## We also suppress all output from running LaTeX.
1890
		## We also suppress all output from running LaTeX.
1896
                ## We could also write stdout to a tempfile and replay
1891
                ## We could also write stdout to a tempfile and replay
1897
                ## this in case of problems.  But does this really help?
1892
                ## this in case of problems.  But does this really help?
1898
		my $cmd = "${R::Vars::LATEX}";
1893
		my $cmd = "${R::Vars::LATEX}";
1899
		if($WINDOWS) {
1894
		if($WINDOWS) {
1900
		    ## check if we have MiKTeX and call latex accordingly
1895
		    ## check if we have MiKTeX and call latex accordingly
1901
		    ## (can't do this in R::Vars::LATEX as we need R::Utils.)
1896
		    ## (can't do this in R::Vars::LATEX as we need R::Utils.)
1902
		    my $Rout = R_tempfile("Rlatex");
1897
		    my $Rout = R_tempfile("Rlatex");
1903
		    my $cmd2 = "$cmd --version > ${Rout}";
1898
		    my $cmd2 = "$cmd --version > ${Rout}";
1904
		    R_system($cmd2);
1899
		    R_system($cmd2);
1905
		    my $is_miktex = 0;
1900
		    my $is_miktex = 0;
1906
		    open ROUT, "< $Rout";
1901
		    open ROUT, "< $Rout";
1907
		    while (<ROUT>) {
1902
		    while (<ROUT>) {
1908
			chomp;
1903
			chomp;
1909
			$is_miktex = 1 if /^MiKTeX/;
1904
			$is_miktex = 1 if /^MiKTeX/;
1910
		    }
1905
		    }
1911
		    close ROUT;
1906
		    close ROUT;
1912
		    unlink($Rout);
1907
		    unlink($Rout);
1913
		    $out =~ s/\w//;
1908
		    $out =~ s/\w//;
1914
		    if($is_miktex) {
1909
		    if($is_miktex) {
1915
			my $R_HOME = $ENV{"R_HOME"};
1910
			my $R_HOME = $ENV{"R_HOME"};
1916
			$cmd .= " --include-directory=$R_HOME/share/texmf";
1911
			$cmd .= " --include-directory=$R_HOME/share/texmf";
1917
		    }
1912
		    }
1918
		}
1913
		}
1919
		$cmd .= " '\\nonstopmode{}\\input{${pkgname}-manual.tex}'";
1914
		$cmd .= " '\\nonstopmode{}\\input{${pkgname}-manual.tex}'";
1920
		$cmd .= " >/dev/null 2>&1";
1915
		$cmd .= " >/dev/null 2>&1";
1921
		## </NOTE>
1916
		## </NOTE>
1922
		if(R_system($cmd)) {
1917
		if(R_system($cmd)) {
1923
		    $log->error();
1918
		    $log->error();
1924
		    $log->print("LaTeX errors when creating DVI version.\n");
1919
		    $log->print("LaTeX errors when creating DVI version.\n");
1925
		    $log->print("This typically indicates Rd problems.\n");
1920
		    $log->print("This typically indicates Rd problems.\n");
1926
		    ## If possible, indicate the problems found.
1921
		    ## If possible, indicate the problems found.
1927
		    ## GNU grep rather usefully has a '-A' option for
1922
		    ## GNU grep rather usefully has a '-A' option for
1928
		    ## controlling the number of lines of trailing
1923
		    ## controlling the number of lines of trailing
1929
		    ## context after matching lines (not POSIX; maybe
1924
		    ## context after matching lines (not POSIX; maybe
1930
		    ## sed could do this?).  Not sure how to do this in
1925
		    ## sed could do this?).  Not sure how to do this in
1931
		    ## Perl.  For the time being, try 'grep -A', and
1926
		    ## Perl.  For the time being, try 'grep -A', and
1932
		    ## give no additional info if this fails.
1927
		    ## give no additional info if this fails.
1933
		    my $out = R_tempfile("gout");
1928
		    my $out = R_tempfile("gout");
1934
		    my $cmd = "grep -A4 '^!' ${pkgname}-manual.log";
1929
		    my $cmd = "grep -A4 '^!' ${pkgname}-manual.log";
1935
		    $cmd .= " > ${out} 2>/dev/null";
1930
		    $cmd .= " > ${out} 2>/dev/null";
1936
		    if(!R_system($cmd)) {
1931
		    if(!R_system($cmd)) {
1937
			$log->print("LaTeX errors found:\n\n");
1932
			$log->print("LaTeX errors found:\n\n");
1938
			$log->print(join("\n", &read_lines("${out}")) .
1933
			$log->print(join("\n", &read_lines("${out}")) .
1939
				    "\n");
1934
				    "\n");
1940
		    }
1935
		    }
1941
		    unlink($out);
1936
		    unlink($out);
1942
		    exit(1);
1937
		    exit(1);
1943
		}
1938
		}
1944
		$log->result("OK");
1939
		$log->result("OK");
1945
	    }
1940
	    }
1946
	}
1941
	}
1947
	else {
1942
	else {
1948
	    if($HAVE_LATEX) {
1943
	    if($HAVE_LATEX) {
1949
		$log->checking("DVI version of manual");
1944
		$log->checking("DVI version of manual");
1950
		my $cmd;
1945
		my $cmd;
1951
		if($WINDOWS) {
1946
		if($WINDOWS) {
1952
		    $cmd = join(" ",
1947
		    $cmd = join(" ",
1953
				("Rcmd.exe Rd2dvi --batch --no-preview",
1948
				("Rcmd.exe Rd2dvi --batch --no-preview",
1954
				 "-o ${pkgname}-manual.dvi >/dev/null 2>&1",
1949
				 "-o ${pkgname}-manual.dvi >/dev/null 2>&1",
1955
				 "$pkgdir"));
1950
				 "$pkgdir"));
1956
		} else {
1951
		} else {
1957
		    $cmd = join(" ",
1952
		    $cmd = join(" ",
1958
				(&shell_quote_file_path("${R::Vars::R_EXE}"),
1953
				(&shell_quote_file_path("${R::Vars::R_EXE}"),
1959
				 "CMD Rd2dvi --batch --no-preview",
1954
				 "CMD Rd2dvi --batch --no-preview",
1960
				 "-o ${pkgname}-manual.dvi >/dev/null 2>&1",
1955
				 "-o ${pkgname}-manual.dvi >/dev/null 2>&1",
1961
				 "$pkgdir"));
1956
				 "$pkgdir"));
1962
		}
1957
		}
1963
		if(R_system($cmd)) {
1958
		if(R_system($cmd)) {
1964
		    $log->error();
1959
		    $log->error();
1965
		    $log->print("LaTeX errors when creating DVI version.\n");
1960
		    $log->print("LaTeX errors when creating DVI version.\n");
1966
		    $log->print("This typically indicates Rd problems.\n");
1961
		    $log->print("This typically indicates Rd problems.\n");
1967
		    exit(1);
1962
		    exit(1);
1968
		}
1963
		}
1969
		$log->result("OK");
1964
		$log->result("OK");
1970
	    }
1965
	    }
1971
	}
1966
	}
1972
    }
1967
    }
1973
}
1968
}
1974
 
1969
 
1975

1970

1976
sub usage {
1971
sub usage {
1977
    print STDERR <<END;
1972
    print STDERR <<END;
1978
Usage: R CMD $name [options] pkgs
1973
Usage: R CMD $name [options] pkgs
1979
 
1974
 
1980
Check R packages from package sources, which can be directories or
1975
Check R packages from package sources, which can be directories or
1981
gzipped package 'tar' archives with extension '.tar.gz' or '.tgz'.
1976
gzipped package 'tar' archives with extension '.tar.gz' or '.tgz'.
1982
 
1977
 
1983
A variety of diagnostic checks on directory structure, index and
1978
A variety of diagnostic checks on directory structure, index and
1984
control files are performed.  The package is installed into the log
1979
control files are performed.  The package is installed into the log
1985
directory (which includes the translation of all Rd files into several
1980
directory (which includes the translation of all Rd files into several
1986
formats), and the Rd files are tested by LaTeX (if available).  All
1981
formats), and the Rd files are tested by LaTeX (if available).  All
1987
examples and tests provided by the package are tested to see if they
1982
examples and tests provided by the package are tested to see if they
1988
run successfully.
1983
run successfully.
1989
 
1984
 
1990
Options:
1985
Options:
1991
  -h, --help            print short help message and exit
1986
  -h, --help            print short help message and exit
1992
  -v, --version         print 'check' version info and exit
1987
  -v, --version         print 'check' version info and exit
1993
  -l, --library=LIB     library directory used for test installation
1988
  -l, --library=LIB     library directory used for test installation
1994
                        of packages (default is outdir)
1989
                        of packages (default is outdir)
1995
  -o, --outdir=DIR      directory used for logfiles, R output, etc.
1990
  -o, --outdir=DIR      directory used for logfiles, R output, etc.
1996
                        (default is 'pkg.Rcheck' in current directory,
1991
                        (default is 'pkg.Rcheck' in current directory,
1997
			where 'pkg' is the name of the package checked)
1992
			where 'pkg' is the name of the package checked)
1998
      --no-clean        do not clean outdir before using it
1993
      --no-clean        do not clean outdir before using it
1999
      --no-codoc        do not check for code/documentation mismatches
1994
      --no-codoc        do not check for code/documentation mismatches
2000
      --no-examples     do not run the examples in the Rd files
1995
      --no-examples     do not run the examples in the Rd files
2001
      --no-install      skip installation and associated tests
1996
      --no-install      skip installation and associated tests
2002
      --no-tests        do not run code in tests subdirectory
1997
      --no-tests        do not run code in tests subdirectory
2003
      --no-vignettes    do not check vignettes in Sweave format
1998
      --no-vignettes    do not check vignettes in Sweave format
2004
      --no-latex        do not run LaTeX on help files
1999
      --no-latex        do not run LaTeX on help files
2005
      --use-gct         use 'gctorture(TRUE)' when running examples/tests
2000
      --use-gct         use 'gctorture(TRUE)' when running examples/tests
2006
      --use-valgrind    use 'valgrind' when running examples/tests/vignettes
2001
      --use-valgrind    use 'valgrind' when running examples/tests/vignettes
2007
      --check-subdirs=default|yes|no
2002
      --check-subdirs=default|yes|no
2008
                        run checks on the package subdirectories
2003
                        run checks on the package subdirectories
2009
			(default is yes for a tarball, no otherwise)
2004
			(default is yes for a tarball, no otherwise)
2010
      --rcfile=FILE     read configuration values from FILE
2005
      --rcfile=FILE     read configuration values from FILE
2011
 
2006
 
2012
By default, all test sections are turned on.
2007
By default, all test sections are turned on.
2013
 
2008
 
2014
Email bug reports to <r-bugs\@r-project.org>.
2009
Email bug reports to <r-bugs\@r-project.org>.
2015
END
2010
END
2016
    exit 0;
2011
    exit 0;
2017
}
2012
}