1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-15 07:41:09 -08:00
emacs/mps/qa/test/script/clib
Richard Tucker 0bfe35bba0 New unit
new unit

Copied from Perforce
 Change: 20775
 ServerID: perforce.ravenbrook.com
1999-05-04 15:30:51 +01:00

299 lines
6.7 KiB
Perl

#!/usr/local/perl
# $HopeName: $
#
# subroutines to compile test libraries, and check whether they
# need to be compiled
#
1;
sub clib {
local ($success) = (1);
&objpurge();
&scrutinize();
&logcomment("Compiling test libraries.");
open(MANIFEST, "$testlib_dir/manifest");
while ($tlfile = <MANIFEST>) {
unless ($tlfile =~ /^%/) {
chop($tlfile);
$tlfile = $testlib_dir."/".$tlfile;
$tlobj = $tlfile;
$tlobj =~ s/\.c/$obj_suffix/;
$tlobj =~ s/$testlib_dir/$obj_dir/;
if (&compile($tlfile, $tlobj)) {
} else {
$success = 0;
&logcomment(" failed on %tlfile.");
}
}
}
close(MANIFEST);
&record_clib;
$success;
}
#
# delete everything in the object directory
#
sub objpurge {
unless (opendir(DIR, $obj_dir)) {
die "Failed to open object directory $obj_dir.\n";
}
&logcomment("Cleaning out old object files.");
foreach (readdir(DIR)) {
unless ($_ eq "." || $_ eq ".." || unlink $obj_dir."/".$_) {
&logcomment(" ... but failed to delete $_.");
}
}
closedir(DIR);
}
#
# record information about environment so that when running tests
# we can check the libraries are still applicable
#
# specifically:
# - MMQA_harness version
# - values of MPS_INCLUDE_DIR and MPS_LINK_OBJ
# - latest modification time of a mpsXXX.h files in MPS_INCLUDE_DIR,
# - or an object in MPS_LINK_OBJ
# - C-compiler version??
sub record_clib {
unless (open(REC, ">$obj_dir/record")) {
die "Unable to write clib record.";
}
print REC "HARNESS_VERSION $HARNESS_VERSION\n";
print REC "INCLUDE_DIR $MPS_INCLUDE_DIR\n";
print REC "LINK_OBJ $MPS_LINK_OBJ\n";
# &headertimes and &linkobjtimes have already been called, by &scrutinize
foreach (sort keys %mps_headers) {
print REC "HEADER $_ $mps_headers{$_}\n";
}
foreach (sort keys %mps_linkobjs) {
print REC "LINK $_ $mps_linkobjs{$_}\n";
}
close(REC);
}
#
# check whether the test libraries correspond to the current
# settings
#
sub test_clib {
local $err = 0;
if (!open(REC, "$obj_dir/record")) {
$err = "no test library description found";
} elsif (<REC> ne "HARNESS_VERSION $HARNESS_VERSION\n") {
$err = "libraries were compiled with a different harness version";
} elsif (<REC> ne "INCLUDE_DIR $MPS_INCLUDE_DIR\n") {
$err = "MPS_INCLUDE_DIR has changed";
} elsif (<REC> ne "LINK_OBJ $MPS_LINK_OBJ\n") {
$err = "MPS_LINK_OBJ has changed";
} else {
&headertimes();
&linkobjtimes();
while (<REC>) {
if (/^HEADER\s+(\S+)\s+(\S+)/) {
if (!exists $mps_headers{$1}) {
$err = "header file $1 disappeared";
} elsif ($mps_headers{$1} != $2) {
$err = "I think $1 may have changed";
} else {
delete $mps_headers{$1};
}
} elsif (/^LINK\s+(\S+)\s+(\S+)/) {
if (!exists $mps_linkobjs{$1}) {
$err = "link object $1 disappeared";
} elsif ($mps_linkobjs{$1} != $2) {
$err = "I think $1 may have changed";
} else {
delete $mps_linkobjs{$1};
}
} else {
$err = "test library description not understood";
}
if ($err) {
last;
}
}
unless ($err) {
if (scalar (keys %mps_headers)) {
($err) = keys %mps_headers;
$err = "new header file $err";
} elsif (scalar (keys %mps_linkobjs)) {
($err) = keys %mps_linkobjs;
$err = "new link object $err";
}
}
}
return $err;
}
sub headertimes {
%mps_headers = ();
unless (opendir(DIR, $MPS_INCLUDE_DIR)) {
die "Failed to open directory $MPS_INCLUDE_DIR.\n";
}
foreach (readdir(DIR)) {
if (/^mps.*\.h$/) {
$mps_headers{$_} = &mod_time("$MPS_INCLUDE_DIR/$_");
}
}
closedir(DIR);
}
sub linkobjtimes {
%mps_linkobjs = ();
$_ = $MPS_LINK_OBJ;
foreach (split) {
$mps_linkobjs{$_} = &mod_time($_);
}
closedir(DIR);
}
sub mod_time {
local ($file, $modtime) = @_;
unless (open(STAT, $file)) {
die "Couldn't find $file.\n";
}
(undef,undef,undef,undef,undef,
undef,undef,undef,undef,$modtime) = stat STAT;
close(STAT);
return $modtime;
}
#
# root around in MPS_INCLUDE_DIR and find useful-looking header files
#
sub scrutinize {
%mps_symbols = ();
%mps_linkable = ();
&logcomment("Checking settings.");
&headertimes();
&linkobjtimes();
&logcomment("Scrutinizing MPS header files.");
foreach (keys %mps_headers) {
&scrutfile($_);
}
# add a dummy symbol to allow us to check that non-defined
# symbols are correctly filtered out
$mps_symbols{"MPS_MMQA_DUMMY_SYMBOL"} = 1;
unless (open(SYM, ">$obj_dir/symtest.c")) {
die "Failed to write symbol test file.\n";
}
print SYM "/* THIS FILE IS AUTOMATICALLY GENERATED */\n\n";
foreach (sort keys %mps_symbols) {
print SYM "void $_(void);\n";
}
print SYM "\n\nint main(void) {\n";
foreach (sort keys %mps_symbols) {
print SYM " $_();\n";
}
print SYM "\n return 1;\n}\n\n";
close(SYM);
$command = "$obj_dir/symtest.c";
if ($cc_objandexe) {
$comobj = "$cc_obj$obj_dir/symtest$obj_suffix";
} else {
$comobj = "";
}
$command = &convdirseps(
"$cc_command $cc_opts $comobj $cc_exe$obj_dir/symtest".
" $obj_dir/symtest.c $MPS_LINK_OBJ $cc_link_opts $stderr_merge |");
&debug("OPEN >>$command<<");
unless (open(LINKTEST, $command)) {
die "Failed link test.";
}
%mps_linkable = %mps_symbols;
while (<LINKTEST>) {
while (s/((mps|MPS)_\w+)/ /) {
delete $mps_linkable{$1};
&debug("Filtering out $1.");
}
}
close(LINKTEST);
if (exists $mps_linkable{"MPS_MMQA_DUMMY_SYMBOL"}) {
print "Failed to determine symbols defined in MPS libraries -- exiting.\n";
die "[Complain to rit about this.]\n";
} elsif ((scalar(keys %mps_symbols)) == 0) {
print "Couldn't determine which symbols are defined in MPS libraries -- exiting.\n";
die "[Complain to rit about this.]\n";
}
delete $mps_symbols{"MPS_MMQA_DUMMY_SYMBOL"};
unless (open(SYM, ">$obj_dir/mmqasym.h")) {
die "Failed to write mmqa symbol file.\n";
}
print SYM "/* THIS FILE IS AUTOMATICALLY GENERATED */\n\n";
print SYM "/* mps header files */\n\n";
foreach (sort keys %mps_headers) {
s/\.h$//;
print SYM "#define MMQA_HEADER_$_\n";
}
print SYM "\n\n/* symbols in header files */\n\n";
foreach (sort keys %mps_symbols) {
print SYM "#define MMQA_SYMBOL_$_\n";
}
print SYM "\n\n/* symbols defined in library */\n\n";
foreach (sort keys %mps_linkable) {
print SYM "#define MMQA_DEFINED_$_\n";
}
print SYM "\n/* end */\n";
close(SYM);
}
sub scrutfile {
local ($infile) = @_;
unless(open(IN, "$MPS_INCLUDE_DIR/$infile")) {
die "Whoops! Failed to read $infile.\n";
}
while (<IN>) {
chomp;
while (s/\$//) { $_ = $_.<IN>; chomp; }
if (/^\s*#\s*define\s*((mps|MPS)_\w+)/) {
$mps_symbols{$1} = 1;
}
}
close(IN);
$cmd = &convdirseps("$preprocommand $MPS_INCLUDE_DIR/$infile |");
&debug("OPEN >>$cmd<<");
unless(open(IN, $cmd)) {
die "Failed to preprocess $infile.\n";
}
while (<IN>) {
while (s/((mps|MPS)_\w+)/ /) {
$mps_symbols{$1} = 1;
}
}
close(IN);
}