diff options
Diffstat (limited to 'tinycc/lib/tcov.c')
| -rw-r--r-- | tinycc/lib/tcov.c | 428 |
1 files changed, 0 insertions, 428 deletions
diff --git a/tinycc/lib/tcov.c b/tinycc/lib/tcov.c deleted file mode 100644 index 32b7d18..0000000 --- a/tinycc/lib/tcov.c +++ /dev/null @@ -1,428 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <fcntl.h> -#ifndef _WIN32 -#include <unistd.h> -#include <errno.h> -#else -#include <windows.h> -#include <io.h> -#endif - -/* section layout (all little endian): - 32bit offset to executable/so file name - filename \0 - function name \0 - align to 64 bits - 64bit function start line - 64bits end_line(28bits) / start_line(28bits) / flag=0xff(8bits) - 64bits counter - \0 - \0 - \0 - executable/so file name \0 - */ - -typedef struct tcov_line { - unsigned int fline; - unsigned int lline; - unsigned long long count; -} tcov_line; - -typedef struct tcov_function { - char *function; - unsigned int first_line; - unsigned int n_line; - unsigned int m_line; - tcov_line *line; -} tcov_function; - -typedef struct tcov_file { - char *filename; - unsigned int n_func; - unsigned int m_func; - tcov_function *func; - struct tcov_file *next; -} tcov_file; - -static FILE *open_tcov_file (char *cov_filename) -{ - int fd; -#ifndef _WIN32 - struct flock lock; - - lock.l_type = F_WRLCK; - lock.l_whence = SEEK_SET; - lock.l_start = 0; - lock.l_len = 0; /* Until EOF. */ - lock.l_pid = getpid (); -#endif - fd = open (cov_filename, O_RDWR | O_CREAT, 0666); - if (fd < 0) - return NULL; - -#ifndef _WIN32 - while (fcntl (fd, F_SETLKW, &lock) && errno == EINTR) - continue; -#else - { - OVERLAPPED overlapped = { 0 }; - LockFileEx((HANDLE)_get_osfhandle(fd), LOCKFILE_EXCLUSIVE_LOCK, - 0, 1, 0, &overlapped); - } -#endif - - return fdopen (fd, "r+"); -} - -static unsigned long long get_value(unsigned char *p, int size) -{ - unsigned long long value = 0; - - p += size; - while (size--) - value = (value << 8) | *--p; - return value; -} - -static int sort_func (const void *p, const void *q) -{ - const tcov_function *pp = (const tcov_function *) p; - const tcov_function *pq = (const tcov_function *) q; - - return pp->first_line > pq->first_line ? 1 : - pp->first_line < pq->first_line ? -1 : 0; -} - -static int sort_line (const void *p, const void *q) -{ - const tcov_line *pp = (const tcov_line *) p; - const tcov_line *pq = (const tcov_line *) q; - - return pp->fline > pq->fline ? 1 : - pp->fline < pq->fline ? -1 : - pp->count < pq->count ? 1 : - pp->count > pq->count ? -1 : 0; -} - -/* sort to let inline functions work */ -static tcov_file *sort_test_coverage (unsigned char *p) -{ - int i, j, k; - unsigned char *start = p; - tcov_file *file = NULL; - tcov_file *nfile; - - p += 4; - while (*p) { - char *filename = (char *)p; - size_t len = strlen (filename); - - nfile = file; - while (nfile) { - if (strcmp (nfile->filename, filename) == 0) - break; - nfile = nfile->next; - } - if (nfile == NULL) { - nfile = malloc (sizeof(tcov_file)); - if (nfile == NULL) { - fprintf (stderr, "Malloc error test_coverage\n"); - return file; - } - nfile->filename = filename; - nfile->n_func = 0; - nfile->m_func = 0; - nfile->func = NULL; - nfile->next = NULL; - if (file == NULL) - file = nfile; - else { - tcov_file *lfile = file; - - while (lfile->next) - lfile = lfile->next; - lfile->next = nfile; - } - } - p += len + 1; - while (*p) { - int i; - char *function = (char *)p; - tcov_function *func; - - p += strlen (function) + 1; - p += -(p - start) & 7; - for (i = 0; i < nfile->n_func; i++) { - func = &nfile->func[i]; - if (strcmp (func->function, function) == 0) - break; - } - if (i == nfile->n_func) { - if (nfile->n_func >= nfile->m_func) { - nfile->m_func = nfile->m_func == 0 ? 4 : nfile->m_func * 2; - nfile->func = realloc (nfile->func, - nfile->m_func * - sizeof (tcov_function)); - if (nfile->func == NULL) { - fprintf (stderr, "Realloc error test_coverage\n"); - return file; - } - } - func = &nfile->func[nfile->n_func++]; - func->function = function; - func->first_line = get_value (p, 8); - func->n_line = 0; - func->m_line = 0; - func->line = NULL; - } - p += 8; - while (*p) { - tcov_line *line; - unsigned long long val; - - if (func->n_line >= func->m_line) { - func->m_line = func->m_line == 0 ? 4 : func->m_line * 2; - func->line = realloc (func->line, - func->m_line * sizeof (tcov_line)); - if (func->line == NULL) { - fprintf (stderr, "Realloc error test_coverage\n"); - return file; - } - } - line = &func->line[func->n_line++]; - val = get_value (p, 8); - line->fline = (val >> 8) & 0xfffffffULL; - line->lline = val >> 36; - line->count = get_value (p + 8, 8); - p += 16; - } - p++; - } - p++; - } - nfile = file; - while (nfile) { - qsort (nfile->func, nfile->n_func, sizeof (tcov_function), sort_func); - for (i = 0; i < nfile->n_func; i++) { - tcov_function *func = &nfile->func[i]; - qsort (func->line, func->n_line, sizeof (tcov_line), sort_line); - } - nfile = nfile->next; - } - return file; -} - -/* merge with previous tcov file */ -static void merge_test_coverage (tcov_file *file, FILE *fp, - unsigned int *pruns) -{ - unsigned int runs; - char *p; - char str[10000]; - - *pruns = 1; - if (fp == NULL) - return; - if (fgets(str, sizeof(str), fp) && - (p = strrchr (str, ':')) && - (sscanf (p + 1, "%u", &runs) == 1)) - *pruns = runs + 1; - while (file) { - int i; - size_t len = strlen (file->filename); - - while (fgets(str, sizeof(str), fp) && - (p = strstr(str, "0:File:")) == NULL) {} - if ((p = strstr(str, "0:File:")) == NULL || - strncmp (p + strlen("0:File:"), file->filename, len) != 0 || - p[strlen("0:File:") + len] != ' ') - break; - for (i = 0; i < file->n_func; i++) { - int j; - tcov_function *func = &file->func[i]; - unsigned int next_zero = 0; - unsigned int curline = 0; - - for (j = 0; j < func->n_line; j++) { - tcov_line *line = &func->line[j]; - unsigned int fline = line->fline; - unsigned long long count; - unsigned int tmp; - char c; - - while (curline < fline && - fgets(str, sizeof(str), fp)) - if ((p = strchr(str, ':')) && - sscanf (p + 1, "%u", &tmp) == 1) - curline = tmp; - if (sscanf (str, "%llu%c\n", &count, &c) == 2) { - if (next_zero == 0) - line->count += count; - next_zero = c == '*'; - } - } - } - file = file->next; - } -} - -/* store tcov data in file */ -void __store_test_coverage (unsigned char * p) -{ - int i, j; - unsigned int files; - unsigned int funcs; - unsigned int blocks; - unsigned int blocks_run; - unsigned int runs; - char *cov_filename = (char *)p + get_value (p, 4); - FILE *fp; - char *q; - tcov_file *file; - tcov_file *nfile; - tcov_function *func; - - fp = open_tcov_file (cov_filename); - if (fp == NULL) { - fprintf (stderr, "Cannot create coverage file: %s\n", cov_filename); - return; - } - file = sort_test_coverage (p); - merge_test_coverage (file, fp, &runs); - fseek (fp, 0, SEEK_SET); - fprintf (fp, " -: 0:Runs:%u\n", runs); - files = 0; - funcs = 0; - blocks = 0; - blocks_run = 0; - nfile = file; - while (nfile) { - files++; - for (i = 0; i < nfile->n_func; i++) { - func = &nfile->func[i]; - funcs++; - for (j = 0; j < func->n_line; j++) { - blocks++; - blocks_run += func->line[j].count != 0; - } - } - nfile = nfile->next; - } - if (blocks == 0) - blocks = 1; - fprintf (fp, " -: 0:All:%s Files:%u Functions:%u %.02f%%\n", - cov_filename, files, funcs, 100.0 * (double) blocks_run / blocks); - nfile = file; - while (nfile) { - FILE *src = fopen (nfile->filename, "r"); - unsigned int curline = 1; - char str[10000]; - - if (src == NULL) - goto next; - funcs = 0; - blocks = 0; - blocks_run = 0; - for (i = 0; i < nfile->n_func; i++) { - func = &nfile->func[i]; - funcs++; - for (j = 0; j < func->n_line; j++) { - blocks++; - blocks_run += func->line[j].count != 0; - } - } - if (blocks == 0) - blocks = 1; - fprintf (fp, " -: 0:File:%s Functions:%u %.02f%%\n", - nfile->filename, funcs, 100.0 * (double) blocks_run / blocks); - for (i = 0; i < nfile->n_func; i++) { - func = &nfile->func[i]; - - while (curline < func->first_line) - if (fgets(str, sizeof(str), src)) - fprintf (fp, " -:%5u:%s", curline++, str); - blocks = 0; - blocks_run = 0; - for (j = 0; j < func->n_line; j++) { - blocks++; - blocks_run += func->line[j].count != 0; - } - if (blocks == 0) - blocks = 1; - fprintf (fp, " -: 0:Function:%s %.02f%%\n", - func->function, 100.0 * (double) blocks_run / blocks); -#if 0 - for (j = 0; j < func->n_line; j++) { - unsigned int fline = func->line[j].fline; - unsigned int lline = func->line[j].lline; - unsigned long long count = func->line[j].count; - - fprintf (fp, "%u %u %llu\n", fline, lline, count); - } -#endif - for (j = 0; j < func->n_line;) { - unsigned int fline = func->line[j].fline; - unsigned int lline = func->line[j].lline; - unsigned long long count = func->line[j].count; - unsigned int has_zero = 0; - unsigned int same_line = fline == lline; - - j++; - while (j < func->n_line) { - unsigned int nfline = func->line[j].fline; - unsigned int nlline = func->line[j].lline; - unsigned long long ncount = func->line[j].count; - - if (fline == nfline) { - if (ncount == 0) - has_zero = 1; - else if (ncount > count) - count = ncount; - same_line = nfline == nlline; - lline = nlline; - j++; - } - else - break; - } - if (same_line) - lline++; - - while (curline < fline) - if (fgets(str, sizeof(str), src)) - fprintf (fp, " -:%5u:%s", curline++, str); - while (curline < lline && - fgets(str, sizeof(str), src)) { - if (count == 0) - fprintf (fp, " #####:%5u:%s", - curline, str); - else if (has_zero) - fprintf (fp, "%8llu*:%5u:%s", - count, curline, str); - else - fprintf (fp, "%9llu:%5u:%s", - count, curline, str); - curline++; - } - } - } - while (fgets(str, sizeof(str), src)) - fprintf (fp, " -:%5u:%s", curline++, str); - fclose (src); -next: - nfile = nfile->next; - } - while (file) { - for (i = 0; i < file->n_func; i++) { - func = &file->func[i]; - free (func->line); - } - free (file->func); - nfile = file; - file = file->next; - free (nfile); - } - fclose (fp); -} |
