diff options
author | Chris Johns <chrisj@rtems.org> | 2014-05-09 21:50:37 +1000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2014-06-18 16:48:08 +1200 |
commit | 100f517ab37265acdf067e36b6860020ec8b2184 (patch) | |
tree | 2316c8b888e11dcbcfbfc66a0c1e31991ea20656 /tester/covoar/coverage_converter.cc | |
parent | 4.11: Add ntp patch. (diff) | |
download | rtems-tools-100f517ab37265acdf067e36b6860020ec8b2184.tar.bz2 |
covoar: Merger the covoar source from rtems-testing.git.
Use waf to build covoar.
Diffstat (limited to 'tester/covoar/coverage_converter.cc')
-rw-r--r-- | tester/covoar/coverage_converter.cc | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/tester/covoar/coverage_converter.cc b/tester/covoar/coverage_converter.cc new file mode 100644 index 0000000..8144d93 --- /dev/null +++ b/tester/covoar/coverage_converter.cc @@ -0,0 +1,220 @@ +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <netdb.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "app_common.h" +#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 <format> (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; +} |