Raw source file available here .
// Written by retoor@molodetz.nl
// This code provides a console utility for performing code coverage analysis on a specified C source file using lcov and genhtml. It checks
// for lcov installation, compiles the source file with coverage options, runs it, and generates an HTML report.
// The code uses lcov and genhtml for coverage analysis and viewing, google-chrome for displaying the HTML report, and it requires gcc for
// compilation.
// MIT License
#ifndef RCOV_H
#define RCOV_H
#include "rtypes.h"
#include "rtemp.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "rbench.h"
bool check_lcov() {
char buffer[1024 * 64];
FILE *fp = popen("lcov --help", "r");
if (fp == NULL) {
return false;
}
if (fgets(buffer, sizeof(buffer), fp) == NULL) {
return false;
}
pclose(fp);
return strstr(buffer, "lcov: not found") ? false : true;
}
int rcov_main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: [source.c]\n");
return 1;
}
char argstr[4096] = {0};
for (int i = 2; i < argc; i++) {
strcat(argstr, argv[i]);
strcat(argstr, " ");
}
if (!check_lcov()) {
printf("lcov is not installed. Please execute `sudo apt install lcov`.\n");
return 1;
}
char *source_file = argv[1];
char *commands[] = {"rm -f *.gcda 2>/dev/null",
"rm -f *.gcno 2>/dev/null",
"rm -f %s.coverage.info 2>/dev/null",
"gcc -pg -fprofile-arcs -ftest-coverage -g -o %s_coverage.o %s",
"./%s_coverage.o",
"lcov --capture --directory . --output-file %s.coverage.info",
"genhtml %s.coverage.info --output-directory /tmp/%s.coverage",
"rm -f *.gcda 2>/dev/null",
"rm -f *.gcno 2>/dev/null",
"rm -f %s.coverage.info 2>/dev/null",
"gprof %s_coverage.o gmon.out > output.rcov_analysis",
"rm -f gmon.out",
"cat output.rcov_analysis",
"rm output.rcov_analysis",
"rm -f %s_coverage.o",
"google-chrome /tmp/%s.coverage/index.html"};
uint command_count = sizeof(commands) / sizeof(commands[0]);
RBENCH(1, {
for (uint i = 0; i < command_count; i++) {
char *formatted_command = sbuf("");
sprintf(formatted_command, commands[i], source_file, source_file);
if (formatted_command[0] == '.' && formatted_command[1] == '/') {
strcat(formatted_command, " ");
strcat(formatted_command, argstr);
}
if (system(formatted_command)) {
printf("`%s` returned non-zero code.\n", formatted_command);
}
}
});
return 0;
}
#endif