The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

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