|
Packit |
0848f5 |
//-*- Mode: C++; c-basic-offset:4 ; -*- */
|
|
Packit |
0848f5 |
//
|
|
Packit |
0848f5 |
// Copyright (C) 2004 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
// See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
//
|
|
Packit |
0848f5 |
// This is a *very* simple tool for basic coverage analysis.
|
|
Packit |
0848f5 |
// This is intended as a stop-gap until gcov works with the C++ files
|
|
Packit |
0848f5 |
// used in the MPICH binding of C++ (as of 2/23/2004, gcov aborts when
|
|
Packit |
0848f5 |
// processing the coverage files produced by g++ for the MPICH C++
|
|
Packit |
0848f5 |
// binding).
|
|
Packit |
0848f5 |
//
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include <iostream.h>
|
|
Packit |
0848f5 |
#include <fstream.h>
|
|
Packit |
0848f5 |
#include <string.h>
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#include "mpicovsimple.h"
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* For remove */
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Find the matching entry or insert and initialize a new one
|
|
Packit |
0848f5 |
covinfo * MPIX_Coverage::findOrInsert( const char name[], int argcount )
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
covinfo *p = head, *newp;
|
|
Packit |
0848f5 |
int cmp;
|
|
Packit |
0848f5 |
static covinfo *lastp = 0; // We use lastp to start where we
|
|
Packit |
0848f5 |
// left off if we can; this speeds
|
|
Packit |
0848f5 |
// sorted inserts
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// See if we can skip ahead...
|
|
Packit |
0848f5 |
if (lastp) {
|
|
Packit |
0848f5 |
cmp = strcmp( lastp->name, name );
|
|
Packit |
0848f5 |
if (cmp < 0 || (cmp == 0 && lastp->argcount <= argcount )) p = lastp;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
while (p) {
|
|
Packit |
0848f5 |
cmp = strcmp( p->name, name );
|
|
Packit |
0848f5 |
if (cmp == 0) {
|
|
Packit |
0848f5 |
cmp = p->argcount - argcount;
|
|
Packit |
0848f5 |
if (cmp == 0) {
|
|
Packit |
0848f5 |
// If still 0, we've found our match.
|
|
Packit |
0848f5 |
lastp = p;
|
|
Packit |
0848f5 |
return p;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (cmp > 0) {
|
|
Packit |
0848f5 |
// If we got here, backup and exit to perform the insert
|
|
Packit |
0848f5 |
p = p->bLink;
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
// If we're at the end of the list, this p is the last element,
|
|
Packit |
0848f5 |
// so we exit now
|
|
Packit |
0848f5 |
if (!p->fLink) break;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
p = p->fLink;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// If we got here, we need to insert after p
|
|
Packit |
0848f5 |
newp = new covinfo;
|
|
Packit |
0848f5 |
newp->name = new char [strlen(name)+1];
|
|
Packit |
0848f5 |
strcpy( newp->name, name );
|
|
Packit |
0848f5 |
newp->argcount = argcount;
|
|
Packit |
0848f5 |
newp->count = 0;
|
|
Packit |
0848f5 |
newp->sourceFile = 0;
|
|
Packit |
0848f5 |
newp->firstLine = -1;
|
|
Packit |
0848f5 |
newp->lastLine = -1;
|
|
Packit |
0848f5 |
newp->bLink = p;
|
|
Packit |
0848f5 |
if (p) {
|
|
Packit |
0848f5 |
// insert after p
|
|
Packit |
0848f5 |
newp->fLink = p->fLink;
|
|
Packit |
0848f5 |
p->fLink = newp;
|
|
Packit |
0848f5 |
if (newp->fLink) {
|
|
Packit |
0848f5 |
newp->fLink->bLink = newp;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else {
|
|
Packit |
0848f5 |
// insert at the head of the list
|
|
Packit |
0848f5 |
newp->fLink = head;
|
|
Packit |
0848f5 |
if (head) {
|
|
Packit |
0848f5 |
head->bLink = newp;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
head = newp;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
lastp = newp;
|
|
Packit |
0848f5 |
return newp;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Add an item to the coverage list, including the first line
|
|
Packit |
0848f5 |
void MPIX_Coverage::Add( const char name[], int argcnt,
|
|
Packit |
0848f5 |
const char file[], int line )
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
covinfo *p = findOrInsert( name, argcnt );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
p->count ++;
|
|
Packit |
0848f5 |
if (!p->sourceFile) {
|
|
Packit |
0848f5 |
p->sourceFile = new char [strlen(file)+1];
|
|
Packit |
0848f5 |
strcpy( p->sourceFile, file );
|
|
Packit |
0848f5 |
p->firstLine = line;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Add the last line value to an item in the coverage list
|
|
Packit |
0848f5 |
void MPIX_Coverage::AddEnd( const char name[], int argcnt,
|
|
Packit |
0848f5 |
const char file[], int line )
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
covinfo *p = findOrInsert( name, argcnt );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (p->lastLine < 0)
|
|
Packit |
0848f5 |
p->lastLine = line;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
//
|
|
Packit |
0848f5 |
// Merge the coverage data with the data in the file
|
|
Packit |
0848f5 |
// The directory for the coverage file is defined by the
|
|
Packit |
0848f5 |
// cpp value COVERAGE_DIR
|
|
Packit |
0848f5 |
int MPIX_Coverage::FileMerge( const char filename[] )
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
ifstream infile;
|
|
Packit |
0848f5 |
ofstream outfile;
|
|
Packit |
0848f5 |
covinfo *p;
|
|
Packit |
0848f5 |
covinfo fp;
|
|
Packit |
0848f5 |
char *infilename, *tmpfilename;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Try to open the input file.
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
#ifdef COVERAGE_DIR
|
|
Packit |
0848f5 |
infilename = new char [strlen(filename) + strlen(COVERAGE_DIR) + 2 ];
|
|
Packit |
0848f5 |
strcpy( infilename, COVERAGE_DIR );
|
|
Packit |
0848f5 |
strcat( infilename, "/" );
|
|
Packit |
0848f5 |
strcat( infilename, filename );
|
|
Packit |
0848f5 |
#else
|
|
Packit |
0848f5 |
infilename = (char *)filename;
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
infile.open( infilename );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Create a place in which to read the data
|
|
Packit |
0848f5 |
fp.name = new char [1024];
|
|
Packit |
0848f5 |
fp.sourceFile = new char [1024];
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Add the contents of the file to the internal list
|
|
Packit |
0848f5 |
// This is easy but not the most memory efficient.
|
|
Packit |
0848f5 |
// If this becomes a problem, we can merge the two
|
|
Packit |
0848f5 |
// into a single output
|
|
Packit |
0848f5 |
while (infile) {
|
|
Packit |
0848f5 |
fp.count = -1; // Set a sentinal on eof in infile
|
|
Packit |
0848f5 |
infile >> fp.name >> fp.argcount >> fp.count >> fp.sourceFile >>
|
|
Packit |
0848f5 |
fp.firstLine >> fp.lastLine;
|
|
Packit |
0848f5 |
if (fp.count == -1) break;
|
|
Packit |
0848f5 |
p = findOrInsert( fp.name, fp.argcount );
|
|
Packit |
0848f5 |
if (!p->sourceFile) {
|
|
Packit |
0848f5 |
p->sourceFile = strdup( fp.sourceFile );
|
|
Packit |
0848f5 |
p->firstLine = fp.firstLine;
|
|
Packit |
0848f5 |
p->lastLine = fp.lastLine;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
p->count += fp.count;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
infile.close();
|
|
Packit |
0848f5 |
// Recover new storage
|
|
Packit |
0848f5 |
delete fp.name;
|
|
Packit |
0848f5 |
delete fp.sourceFile;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Try to open the output file
|
|
Packit |
0848f5 |
#ifdef COVERAGE_DIR
|
|
Packit |
0848f5 |
tmpfilename = new char [strlen(".covtmp") + strlen(COVERAGE_DIR) + 2 ];
|
|
Packit |
0848f5 |
strcpy( tmpfilename, COVERAGE_DIR );
|
|
Packit |
0848f5 |
strcat( tmpfilename, "/" );
|
|
Packit |
0848f5 |
strcat( tmpfilename, ".covtmp" );
|
|
Packit |
0848f5 |
#else
|
|
Packit |
0848f5 |
tmpfilename = ".covtmp";
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
outfile.open( tmpfilename );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
p = head;
|
|
Packit |
0848f5 |
while (p) {
|
|
Packit |
0848f5 |
outfile << p->name << '\t' << p->argcount << '\t' <<
|
|
Packit |
0848f5 |
p->count << '\t' << p->sourceFile << '\t' <<
|
|
Packit |
0848f5 |
p->firstLine << '\t' << p->lastLine << '\n';
|
|
Packit |
0848f5 |
p = p->fLink;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
outfile.close();
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
// Now, remove the old file and move the new file over it
|
|
Packit |
0848f5 |
remove( infilename );
|
|
Packit |
0848f5 |
rename( tmpfilename, infilename );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#if 0
|
|
Packit |
0848f5 |
// This is partial and incomplete code for an alternative version of
|
|
Packit |
0848f5 |
// FileMerge that avoids reading the entire file into memory
|
|
Packit |
0848f5 |
// This was a early version that was lost in a terrible keyboarding
|
|
Packit |
0848f5 |
// accident just after it was debugged :)
|
|
Packit |
0848f5 |
// This predates the current form of the coverage file and contains
|
|
Packit |
0848f5 |
// a number of bugs, but it would be a reasonable starting point
|
|
Packit |
0848f5 |
// if it is desired to avoid reading the entire file into memory.
|
|
Packit |
0848f5 |
int MPIX_Ooverage::FileMerge( const char filename[] )
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
covinfo *p, *fp=0;
|
|
Packit |
0848f5 |
ifstream infile;
|
|
Packit |
0848f5 |
ofstream outfile;
|
|
Packit |
0848f5 |
char *tmpfile;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
infile.open( filename, ios::in );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
tmpfile = new char [ strlen(filename) + 5 ];
|
|
Packit |
0848f5 |
strcpy( tmpfile, filename );
|
|
Packit |
0848f5 |
strcat( tmpfile, ".tmp" );
|
|
Packit |
0848f5 |
outfile.open( tmpfile );
|
|
Packit |
0848f5 |
if (!outfile) {
|
|
Packit |
0848f5 |
cerr << "Unable to open " << tmpfile << "\n";
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
p = head;
|
|
Packit |
0848f5 |
if (infile) {
|
|
Packit |
0848f5 |
fp = new covinfo;
|
|
Packit |
0848f5 |
fp->name = new char [1024];
|
|
Packit |
0848f5 |
infile >> fp->name >> fp->argcount >> fp->count;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
while (p) {
|
|
Packit |
0848f5 |
int cmp = 0;
|
|
Packit |
0848f5 |
if (fp) {
|
|
Packit |
0848f5 |
cmp = strcmp( fp->name, p->name );
|
|
Packit |
0848f5 |
if (cmp == 0) {
|
|
Packit |
0848f5 |
cmp = fp->argcount - p->argcount;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (cmp < 0) {
|
|
Packit |
0848f5 |
// output the file entry
|
|
Packit |
0848f5 |
outfile << fp->name << '\t' << fp->argcount << '\t' <<
|
|
Packit |
0848f5 |
fp->count << '\n';
|
|
Packit |
0848f5 |
infile >> fp->name >> fp->argcount >> fp->count;
|
|
Packit |
0848f5 |
if (infile.eof()) break;
|
|
Packit |
0848f5 |
continue;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (cmp == 0) {
|
|
Packit |
0848f5 |
// Increment the p entry
|
|
Packit |
0848f5 |
p->count += fp->count;
|
|
Packit |
0848f5 |
infile >> fp->name >> fp->argcount >> fp->count;
|
|
Packit |
0848f5 |
if (infile.eof()) break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
// else keep this entry
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
outfile << p->name << '\t' << p->argcount << '\t' << p->count << '\n';
|
|
Packit |
0848f5 |
p = p->fLink;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
// Read the rest of the file, if any
|
|
Packit |
0848f5 |
while (infile && !infile.eof()) {
|
|
Packit |
0848f5 |
infile >> fp->name >> fp->argcount fp->count;
|
|
Packit |
0848f5 |
outfile << fp->name << '\t' << fp->argcount << '\t' <<
|
|
Packit |
0848f5 |
fp->count << '\n';
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
// Output the rest of the list
|
|
Packit |
0848f5 |
while (p) {
|
|
Packit |
0848f5 |
outfile << p->name << '\t' << p->argcount << '\t' << p->count << '\n';
|
|
Packit |
0848f5 |
p = p->fLink;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
// Close the input file if we opened it...
|
|
Packit |
0848f5 |
if (fp) {
|
|
Packit |
0848f5 |
infile.close();
|
|
Packit |
0848f5 |
... remove code as above
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPIX_Coverage MPIR_Cov;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
//#define TEST_PROGRAM
|
|
Packit |
0848f5 |
#ifdef TEST_PROGRAM
|
|
Packit |
0848f5 |
int main( int argc, char **argv )
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPIR_Cov.Add( "foo", 2, __FILE__, __LINE__ );
|
|
Packit |
0848f5 |
MPIR_Cov.Add( "foo", 1, __FILE__, __LINE__ );
|
|
Packit |
0848f5 |
MPIR_Cov.Add( "bar", 2, __FILE__, __LINE__ );
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPIR_Cov.FileMerge( "covtest.dat" );
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|