#include #include #include #include #include #include #include #include #include #include #include #include #include "CoverageFactory.h" #include "CoverageMap.h" /* * Variables to control global behavior */ Coverage::CoverageReaderBase* coverageReader = NULL; Coverage::CoverageWriterBase* coverageWriter = NULL; uint32_t highAddress = 0xffffffff; Coverage::CoverageFormats_t inputFormat; uint32_t lowAddress = 0xffffffff; char* progname; /* * Global variables for the program */ Coverage::CoverageMapBase *CoverageMap = NULL; /* * Convert string to int with status out */ bool stringToUint32( const char* s, int base, uint32_t* n ) { long long result; if (!n) return false; errno = 0; *n = 0; result = strtoll( s, NULL, base ); if ((result == 0) && errno) return false; if ((result == LLONG_MAX) && (errno == ERANGE)) return false; if ((result == LLONG_MIN) && (errno == ERANGE)) return false; *n = (uint32_t)result; return true; } /* * Print program usage message */ void usage() { fprintf( stderr, "Usage: %s [-v] -l ADDRESS -h ADDRESS coverage_in coverage_out\n" "\n" " -l low address - low address of range to merge\n" " -l high address - high address of range to merge\n" " -f format - coverage files are in (Qemu)\n" " -v - verbose at initialization\n" "\n", progname ); } #define PrintableString(_s) \ ((!(_s)) ? "NOT SET" : (_s)) int main( int argc, char** argv ) { char* format = NULL; const char* coverageFile; const char* coverageIn; int opt; // // Process command line options. // progname = argv[0]; while ((opt = getopt(argc, argv, "f:h:l:v")) != -1) { switch (opt) { case 'v': Verbose = 1; break; case 'f': inputFormat = Coverage::CoverageFormatToEnum(optarg); format = optarg; break; case 'l': if (!stringToUint32( optarg, 16, &lowAddress )) { fprintf( stderr, "ERROR: Low address is not a hexadecimal number\n" ); usage(); exit(-1); } break; case 'h': if (!stringToUint32( optarg, 16, &highAddress )) { fprintf( stderr, "ERROR: High address is not a hexadecimal number\n" ); usage(); exit(-1); } break; default: /* '?' */ usage(); exit( -1 ); } } if ((argc - optind) != 2) { fprintf( stderr, "ERROR: Must provide input and output files\n" ); exit(1); } coverageIn = argv[optind]; coverageFile = argv[optind + 1]; if (Verbose) { fprintf( stderr, "Verbose : %d\n", Verbose ); fprintf( stderr, "Input Format : %s\n", format ); fprintf( stderr, "Input File : %s\n", coverageIn ); fprintf( stderr, "Output Format : %s\n", "RTEMS" ); fprintf( stderr, "Output File : %s\n", coverageFile ); fprintf( stderr, "low address : 0x%08x\n", lowAddress ); fprintf( stderr, "high address : 0x%08x\n", highAddress ); fprintf( stderr, "\n" ); } // // Validate inputs. // // Validate format. if (!format) { fprintf( stderr, "ERROR: input format must be given.\n\n" ); usage(); exit(-1); } // Validate address range if (lowAddress == 0xffffffff) { fprintf( stderr, "ERROR: Low address not specified.\n\n" ); usage(); exit(-1); } if (highAddress == 0xffffffff) { fprintf( stderr, "ERROR: High address not specified.\n\n" ); usage(); exit(-1); } if (lowAddress >= highAddress) { fprintf( stderr, "ERROR: Low address >= high address.\n\n" ); usage(); exit(-1); } // // Create data to support conversion. // // Create coverage map. CoverageMap = new Coverage::CoverageMap( lowAddress, highAddress ); if (!CoverageMap) { fprintf( stderr, "ERROR: Unable to create coverage map.\n\n" ); exit(-1); } // Create coverage writer. coverageWriter = Coverage::CreateCoverageWriter(Coverage::COVERAGE_FORMAT_RTEMS); if (!coverageWriter) { fprintf( stderr, "ERROR: Unable to create coverage file writer.\n\n" ); exit(-1); } // Create coverage reader. coverageReader = CreateCoverageReader( inputFormat ); if (!coverageReader) { fprintf( stderr, "ERROR: Unable to create input file reader.\n\n" ); exit(-1); } // Now get to some real work. if (Verbose) fprintf( stderr, "Processing %s\n", coverageIn ); coverageReader->processFile( coverageIn, CoverageMap ); if (Verbose) fprintf( stderr, "Writing coverage file (%s)\n", coverageFile ); coverageWriter->writeFile( coverageFile, CoverageMap, lowAddress, highAddress ); return 0; }