Blame maint/clmake

Packit 0848f5
#! /usr/bin/env perl
Packit 0848f5
# -*- Mode: perl; -*-
Packit 0848f5
#
Packit 0848f5
# Set Defaults
Packit 0848f5
$debug = 0;
Packit 0848f5
$debugDir = 0;
Packit 0848f5
$gDebugOther = 0;
Packit 0848f5
Packit 0848f5
$summaryOutput = 0;
Packit 0848f5
$terseOutput = 1;
Packit 0848f5
$rootSrcDir = "";
Packit 0848f5
# Define the known commands, along with known make noise (results of
Packit 0848f5
# echo)
Packit 0848f5
# We include /bin/rm and /bin/mv because some Makefile authors prefer
Packit 0848f5
# to get the full path for these routines
Packit 0848f5
@commands = ( "cc", "pgcc", "gcc", "icc", "acc", 
Packit 0848f5
              "rm", "mv", "cp", "ar", "ranlib", "perl", "for", 
Packit 0848f5
	      "/bin/rm", "/bin/mv", "/bin/cp", "/bin/chmod",
Packit 0848f5
	      "rm", "mv", "cp", "chmod",
Packit 0848f5
	      "if", "make", "gnumake", 
Packit 0848f5
	      "[A-Za-z0-9_\/\.-]*\/mpicc",
Packit 0848f5
	      "[A-Za-z0-9_\/\.-]*\/mpifort",
Packit 0848f5
	      "[A-Za-z0-9_\/\.-]*\/mpicxx",
Packit 0848f5
	      "cleaning", "sleep", "date", "g77", "f77", "f90", "f95", "pgCC",
Packit 0848f5
	      "pgf77", "pgf90", "CC", "g95", "g\\+\\+", "c\\+\\+",
Packit 0848f5
	      "acc\\+\\+", "xlc", "xlf", "xlC", "xlf90", "gfortran", 
Packit 0848f5
	      "ifort", "ifc", "test",
Packit 0848f5
	      "true", "false", "/[A-Za-z0-9_\/\.-]*createshlib", 
Packit 0848f5
	      "/bin/sh\\s+[A-Za-z0-9_\/\.-]*libtool\\s+\(--tag=\\w+\)*\\s+--mode=\\w+",
Packit 0848f5
	      "/bin/bash\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--mode=\\w+",
Packit 0848f5
	      "/bin/sh\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--finish",
Packit 0848f5
	      "/bin/bash\\s+[A-Za-z0-9_\/\.-]*libtool\\s+--finish",
Packit 0848f5
	      "libtool:\\s+compile:",
Packit 0848f5
	      "libtool:\\s+link:",
Packit 0848f5
	      "libtool:\\s+install:",
Packit 0848f5
	      "libtool:\\s+finish:",
Packit 0848f5
	      "[A-Za-z0-9_\/-]*\/icc",
Packit 0848f5
	      "[A-Za-z0-9_\/-]*\/install-sh",
Packit 0848f5
	      "/usr/bin/ar", "mkdir",
Packit 0848f5
              "/bin/mkdir",
Packit 0848f5
              "/.*bin/mkdir",
Packit 0848f5
	      "/usr/ucb/ld",
Packit 0848f5
	      "mpicc", "mpicxx",
Packit 0848f5
	      "compiling ROMIO in", 
Packit 0848f5
	      "Make completed",
Packit 0848f5
	      "echo", "cat",
Packit 0848f5
	      "CC", "CCLD", "AR", "RANLIB", "LIBTOOL", "MV", 
Packit 0848f5
              "MOD", "GEN", "F77", "FC", "CXXLD", "CXX", "FCLD",
Packit 0848f5
	      "CP", # "terse" make versions
Packit 0848f5
	      "\\(?cd",
Packit 0848f5
	      "\\(\\s*cd",
Packit 0848f5
	      "creating\s+lib.*",
Packit 0848f5
	      "cd\\s+\&\&\\s+make",
Packit 0848f5
	      "sed -e",
Packit 0848f5
	      "PATH=\"\\\$PATH.*\\sldconfig\\s",
Packit 0848f5
	      "building profiling interface in directory",
Packit 0848f5
	      "/usr/bin/install",
Packit 0848f5
              "/.*bin/install",
Packit 0848f5
              ".*confdb/install-sh",
Packit 0848f5
	      "Copying Upshot",
Packit 0848f5
	      "Cleaning directory",
Packit 0848f5
	      "[*][*][*][*] Making .*\.\.\.\.",
Packit 0848f5
	      "Making .* in .*",
Packit 0848f5
	      "Making upshot", "\\s*\$",
Packit 0848f5
              "ld: warning: directory not found for option '-L\\S*src/mpl'",
Packit 0848f5
              "ld: warning: directory not found for option '-L\\S*src/openpa/src'",
Packit 0848f5
);
Packit 0848f5
Packit 0848f5
# OtherNoise is an array of patterns that describe blocks of
Packit 0848f5
# text that we'd like to skip.  The initial use it to handle 
Packit 0848f5
# libtool install output.
Packit 0848f5
# The PG entries are work-arounds for bugs in the PG header files that have
Packit 0848f5
# small incompatibilities with the system header file /usr/include/unistd.h
Packit 0848f5
#
Packit 0848f5
@OtherNoise = ( 'Libraries have been installed in:<SEP>more information, such as the ld\(1\) and ld.so\(8\) manual pages.<SEP>20',
Packit 0848f5
		'^\s*-+\s*$<SEP><SEP>1', 
Packit 0848f5
		'^In directory:<SEP><SEP>1',
Packit 0848f5
		'^creating\s<SEP><SEP>1', 
Packit 0848f5
#		'^PGC-W-0114-More than one type.*/usr/include/unistd.h: 189<SEP>^PGC-W-0143-Useless typedef.*/usr/include/unistd.h: 189<SEP>2',
Packit 0848f5
#		'^PGC-W-0114-More than one type.*/usr/include/unistd.h: 243<SEP>^PGC-W-0143-Useless typedef.*/usr/include/unistd.h: 243<SEP>2',
Packit 0848f5
		'^PGC.*: compilation completed with warnings<SEP><SEP>1',
Packit 0848f5
# This next is a general version to handle all of these mistakes
Packit 0848f5
		'^PGC-W-0114-More than one type specified.*/usr/include<SEP>^PGC-W-0143-Useless typedef declaration \(no declarators present\).*/usr/include<SEP>2',
Packit 0848f5
		'copying python',
Packit 0848f5
		'LOOP WAS VECTORIZED',
Packit 0848f5
		'Using variables ',
Packit 0848f5
		);
Packit 0848f5
# In the past, we also needed
Packit 0848f5
# WARNING 84.*not used for resolving any symbol
Packit 0848f5
# Info: File not optimized
Packit 0848f5
Packit 0848f5
Packit 0848f5
$trimCompileLine = 1;
Packit 0848f5
Packit 0848f5
# Create the variables that keep track of state
Packit 0848f5
# dirstack keeps the directory name that gnumake and similar make
Packit 0848f5
# implementations echo as a directory is entered or exited (this can generate
Packit 0848f5
# a great deal of output noise that can obscure important data.  However, when
Packit 0848f5
# a problem *does* occur, this directory information is valuable.
Packit 0848f5
# dirprinted is a parallel array that indicates whether the corresponding
Packit 0848f5
# directory entry has been printed.
Packit 0848f5
@dirstack = ();
Packit 0848f5
@dirprinted = ();
Packit 0848f5
Packit 0848f5
# Process arguments to select options
Packit 0848f5
foreach $_ (@ARGV) {
Packit 0848f5
    if (/^--?debug/) { $debug = 1; }
Packit 0848f5
    elsif (/^--?showdir/) { $debugDir = 1; }
Packit 0848f5
    elsif (/^--?summary/) { $summaryOutput = 1; }
Packit 0848f5
    elsif (/^--?notrimcompileline/) { $trimCompileLine = 0; }
Packit 0848f5
    elsif (/^-/) {
Packit 0848f5
	print STDERR "Unrecognized argument $_\n";
Packit 0848f5
	print STDERR "clmake [ -debug ] [ -showdir ] [ -summary ]\n";
Packit 0848f5
	exit(1);
Packit 0848f5
    }
Packit 0848f5
    else { last; }
Packit 0848f5
    shift @ARGV;
Packit 0848f5
}
Packit 0848f5
# Read lines.  Categorize lines as commands and output.  This
Packit 0848f5
# script suppresses commands that generate no extra output.
Packit 0848f5
# The approach is to read a line and then read the next line.
Packit 0848f5
# While the line is a command and the next line is not, output the
Packit 0848f5
# line.
Packit 0848f5
#
Packit 0848f5
# We use eof() (see man perlfun) so that we can accept filenames on the
Packit 0848f5
# commandline.
Packit 0848f5
#
Packit 0848f5
$cmdline = "";
Packit 0848f5
T:
Packit 0848f5
while ($line = <>) {
Packit 0848f5
    if (eof()) { next; }
Packit 0848f5
Packit 0848f5
    $line =~ s/\r//;    # remove returns from line (de DOSify)
Packit 0848f5
Packit 0848f5
    # Read the next line, including handling any continuation lines
Packit 0848f5
    while ($line =~ /\\$/) {
Packit 0848f5
	print "Read continuation line (cmd) ... \n" if $debug;
Packit 0848f5
	$line .= <>;
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    # Check for noise
Packit 0848f5
    foreach my $pat (@OtherNoise) {
Packit 0848f5
	# maxlines is the maximum number of lines to match
Packit 0848f5
	my ($beginpat,$endpat,$maxlines) = split( '<SEP>', $pat );
Packit 0848f5
	print "Trying to match $beginpat\n" if $gDebugOther;
Packit 0848f5
	if ($line =~ /$beginpat/) {
Packit 0848f5
	    $maxlines --;
Packit 0848f5
	    print "Found match to $beginpat\n" if $gDebugOther;
Packit 0848f5
	    # Found the beginning.  Look for the end (if one requested)
Packit 0848f5
	    if ($endpat =~ /\S/) {
Packit 0848f5
		print "Trying to match endpat $endpat\n" if $gDebugOther;
Packit 0848f5
		while ($line = <>) {
Packit 0848f5
		    if (eof()) { last; }
Packit 0848f5
		    print "Trying to match to $line" if $gDebugOther;
Packit 0848f5
		    if ($line =~ /$endpat/) { last; }
Packit 0848f5
		    if ($maxlines-- <= 0) { 
Packit 0848f5
			print STDOUT "Failed to match $endpat; last line was $line";
Packit 0848f5
			last; 
Packit 0848f5
		    }
Packit 0848f5
		}
Packit 0848f5
	    }
Packit 0848f5
	    next T;
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
    
Packit 0848f5
    # Is the line a command (including a directory change?)
Packit 0848f5
    # Check first for a directory change
Packit 0848f5
    if ($line =~ /^\s*make.* Entering directory \`([^\']*)\'/) {
Packit 0848f5
	my $dirname = $1;
Packit 0848f5
	$dirstack[$#dirstack+1] = $dirname;
Packit 0848f5
	$dirprinted[$#dirprinted+1] = 0;
Packit 0848f5
	print ">>entering $dirname\n" if $debugDir;
Packit 0848f5
	$cmdline = "";
Packit 0848f5
	next;
Packit 0848f5
    }
Packit 0848f5
    elsif ($line =~ /^\s*make.* Leaving directory \`([^\']*)\'/) {
Packit 0848f5
	# We should check that the directory names match
Packit 0848f5
	my $dirname = $1;
Packit 0848f5
	print ">>leaving $dirname\n" if $debugDir;
Packit 0848f5
	if ($dirname ne $dirstack[$#dirstack]) {
Packit 0848f5
	    print STDERR "Warning: leaving directory $dirname but expected to leave directory " . $dirstack[$#dirstack] . "\n";
Packit 0848f5
	}
Packit 0848f5
	$#dirstack--;
Packit 0848f5
	$#dirprinted--;
Packit 0848f5
	$cmdline = "";
Packit 0848f5
	next;
Packit 0848f5
    }
Packit 0848f5
    else {
Packit 0848f5
	$is_command = 0;
Packit 0848f5
	foreach $cmdname (@commands) {
Packit 0848f5
	    if ($line =~ /^\s*$cmdname\W/) {
Packit 0848f5
		$is_command = 1;
Packit 0848f5
		$cmdline = $line;
Packit 0848f5
		last;
Packit 0848f5
	    }
Packit 0848f5
	}
Packit 0848f5
	if ($is_command) { 
Packit 0848f5
	    if ($summaryOutput) {
Packit 0848f5
		# FIXME: Summarize the command
Packit 0848f5
		if ($terseOutput) {
Packit 0848f5
		    if ($rootSrcDir eq "") {
Packit 0848f5
			if ($line =~ /\s(\/\S+\/src\/)/) {
Packit 0848f5
			    $rootSrcDir = $1;
Packit 0848f5
			    print "rootSrcDir = $rootSrcDir\n";
Packit 0848f5
			}
Packit 0848f5
		    }
Packit 0848f5
		    else {
Packit 0848f5
			$line =~ s/$rootSrcDir//g;
Packit 0848f5
		    }
Packit 0848f5
		    # Compiler options to remove
Packit 0848f5
		    $line =~ s/-I\S+\s+//g;
Packit 0848f5
		    $line =~ s/-W\S+\s+//g;
Packit 0848f5
		    $line =~ s/-D\S+\s+//g;
Packit 0848f5
		}
Packit 0848f5
		print $line;
Packit 0848f5
	    }
Packit 0848f5
	    next; 
Packit 0848f5
	}
Packit 0848f5
    }
Packit 0848f5
Packit 0848f5
    # If we got to this point, the line was not a recognized command or
Packit 0848f5
    # ignorable output.  Output the line, including the command if this 
Packit 0848f5
    # is the first time.  We can then forget the command 
Packit 0848f5
    if ($#dirstack >= 0 && $dirprinted[$#dirstack] == 0) {
Packit 0848f5
	print "In directory: ". $dirstack[$#dirstack] . "\n";
Packit 0848f5
	$dirprinted[$#dirstack] = 1;
Packit 0848f5
    }
Packit 0848f5
    if ($cmdline ne "") { 
Packit 0848f5
	if ($trimCompileLine) {
Packit 0848f5
	    # Simplify the command line before printing
Packit 0848f5
	    $cmdline =~ s/-I\S*\s+//g;
Packit 0848f5
	    $cmdline =~ s/-ansi//g;
Packit 0848f5
	    $cmdline =~ s/-W\S*\s+//g;
Packit 0848f5
	    $cmdline =~ s/-DHAVE_CONFIG_H//g;
Packit 0848f5
	    $cmdline =~ s/-DGCC_WALL//g;
Packit 0848f5
	}
Packit 0848f5
	# We could print a newline here to separate commands
Packit 0848f5
	print $cmdline;
Packit 0848f5
	$cmdline = "";
Packit 0848f5
    }
Packit 0848f5
    print $line;
Packit 0848f5
}
Packit 0848f5
Packit 0848f5
#
Packit 0848f5
# ToDo:
Packit 0848f5
# Handle lines containing just ----, e.g., patterns of the form
Packit 0848f5
# -*