summaryrefslogtreecommitdiffstats
path: root/tester/covoar/coverage_converter.cc
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2014-05-09 21:50:37 +1000
committerChris Johns <chrisj@rtems.org>2014-06-18 16:48:08 +1200
commit100f517ab37265acdf067e36b6860020ec8b2184 (patch)
tree2316c8b888e11dcbcfbfc66a0c1e31991ea20656 /tester/covoar/coverage_converter.cc
parent4.11: Add ntp patch. (diff)
downloadrtems-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.cc220
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;
+}