123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- #include "blitz.h"
- #ifdef BMX_COVERAGE
- BBString * bbCoverageOutputFileName = &bbEmptyString;
- Hashmap* BBCoverageLineExecInfoTable;
- static int hashmapStringHash(intptr_t key) {
- const char* str = (const char*)key;
- int64_t hash = 0;
- while (*str) {
- hash = (31 * hash + *str++) % 0x7FFFFFFF;
- }
- return (int)(hash % 0x7FFFFFFF);
- }
- static int hashmapStringEquals(intptr_t keyA, intptr_t keyB) {
- const char* strA = (const char*)keyA;
- const char* strB = (const char*)keyB;
- return strcmp(strA, strB) == 0;
- }
- void bbCoverageStartup() {
- BBCoverageLineExecInfoTable = hashmapCreate(64, hashmapStringHash, hashmapStringEquals);
- }
- void bbCoverageRegisterFile(BBCoverageFileInfo * coverage_files) {
- for (int i = 0; coverage_files[i].filename != NULL; i++) {
- BBCoverageFileInfo * coverage_file = &coverage_files[i];
-
- if (coverage_file->line_map == NULL) {
- coverage_file->line_map = hashmapCreate(64, hashmapIntHash, hashmapIntEquals);
- hashmapPut(BBCoverageLineExecInfoTable, (void*)coverage_file->filename, coverage_file);
- }
-
- if (coverage_file->func_map == NULL) {
- coverage_file->func_map = hashmapCreate(64, hashmapIntHash, hashmapIntEquals);
- }
-
- for (int j = 0; j < coverage_file->coverage_lines_count; j++) {
- BBCoverageLineExecInfo* info = (BBCoverageLineExecInfo*) malloc(sizeof(BBCoverageLineExecInfo));
- info->file = coverage_file->filename;
- info->line = coverage_file->coverage_lines[j];
- info->count = 0;
- hashmapPut(coverage_file->line_map, (void*)(intptr_t)info->line, info);
- }
- for (int j = 0; j < coverage_file->coverage_functions_count; j++) {
- BBCoverageFuncExecInfo* info = (BBCoverageFuncExecInfo*) malloc(sizeof(BBCoverageFuncExecInfo));
- info->func = coverage_file->coverage_functions[j].func;
- info->line = coverage_file->coverage_functions[j].line;
- info->count = 0;
- hashmapPut(coverage_file->func_map, (void*)(intptr_t)info->line, info);
- }
- }
- }
- void bbCoverageUpdateLineInfo(const char* file, int line) {
- BBCoverageFileInfo * coverage_file = (Hashmap*) hashmapGet(BBCoverageLineExecInfoTable, (void*)file);
-
- if (!coverage_file) {
- // error
- return;
- }
- BBCoverageLineExecInfo* info = (BBCoverageLineExecInfo*) hashmapGet(coverage_file->line_map, (void*)(intptr_t)line);
-
- if (!info) {
- info = (BBCoverageLineExecInfo*) malloc(sizeof(BBCoverageLineExecInfo));
- info->file = file;
- info->line = line;
- info->count = 0;
- hashmapPut(coverage_file->line_map, (void*)(intptr_t)line, info);
- }
- info->count++;
- }
- void bbCoverageUpdateFunctionLineInfo(const char* file, const char* func, int line) {
- BBCoverageFileInfo * coverage_file = (Hashmap*) hashmapGet(BBCoverageLineExecInfoTable, (void*)file);
-
- if (!coverage_file) {
- // error
- return;
- }
- BBCoverageFuncExecInfo* info = (BBCoverageFuncExecInfo*) hashmapGet(coverage_file->func_map, (void*)(intptr_t)line);
-
- if (!info) {
- info = (BBCoverageFuncExecInfo*) malloc(sizeof(BBCoverageFuncExecInfo));
- info->file = file;
- info->func = func;
- info->line = line;
- info->count = 0;
- hashmapPut(coverage_file->line_map, (void*)(intptr_t)line, info);
- }
- info->count++;
- }
- static int write_line_exec_info(intptr_t key, void* value, void* context) {
- BBCoverageLineExecInfo* info = (BBCoverageLineExecInfo*)value;
- FILE* lcov_file = (FILE*)context;
- fprintf(lcov_file, "DA:%d,%d\n", info->line, info->count);
- return 1;
- }
- static int write_file_exec_info(intptr_t key, void* value, void* context) {
- const char* file = (const char*)key;
- BBCoverageFileInfo* coverage_file = (BBCoverageFileInfo*)value;
- FILE* lcov_file = (FILE*)context;
- fprintf(lcov_file, "SF:%s\n", file);
- int lines_hit = 0;
- for (int i=0; i < coverage_file->coverage_lines_count; i++) {
- BBCoverageLineExecInfo* info = (BBCoverageLineExecInfo*) hashmapGet(coverage_file->line_map, (void*)(intptr_t)coverage_file->coverage_lines[i]);
- if (info) {
- if (info->count > 0) {
- lines_hit++;
- }
- fprintf(lcov_file, "DA:%d,%d\n", info->line, info->count);
- }
- }
- fprintf(lcov_file, "LF:%d\n", coverage_file->coverage_lines_count);
- fprintf(lcov_file, "LH:%d\n", lines_hit);
- int functions_hit = 0;
- for (int i=0; i < coverage_file->coverage_functions_count; i++) {
- BBCoverageFuncExecInfo* info = (BBCoverageFuncExecInfo*) hashmapGet(coverage_file->func_map, (void*)(intptr_t)coverage_file->coverage_functions[i].line);
- if (info) {
- if (info->count > 0) {
- functions_hit++;
- }
- fprintf(lcov_file, "FN:%d,%s\n", info->line, info->func);
- fprintf(lcov_file, "FNDA:%d,%d\n", info->count, info->line);
- }
- }
- fprintf(lcov_file, "FNF:%d\n", coverage_file->coverage_functions_count);
- fprintf(lcov_file, "FNH:%d\n", functions_hit);
- // Write the end of record marker
- fprintf(lcov_file, "end_of_record\n");
- return 1;
- }
- void bbCoverageGenerateOutput() {
- const char* output_file_name;
- if ( bbCoverageOutputFileName == &bbEmptyString ) {
- output_file_name = "lcov.info";
- } else {
- output_file_name = bbStringToUTF8String(bbCoverageOutputFileName);
- }
-
- FILE* lcov_file = fopen(output_file_name, "w");
- if (!lcov_file) {
- printf("Error: Unable to open output file: %s\n", output_file_name);
- return;
- }
- // Iterate through the global hash table (BBCoverageLineExecInfoTable) and write file coverage data
- hashmapForEach(BBCoverageLineExecInfoTable, write_file_exec_info, lcov_file);
- fclose(lcov_file);
- }
- #endif // BMX_COVERAGE
|