aboutsummaryrefslogtreecommitdiff
path: root/tinycc/lib/tcov.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinycc/lib/tcov.c')
-rw-r--r--tinycc/lib/tcov.c428
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);
-}