mirror of
https://github.com/dlang/phobos.git
synced 2025-04-28 22:21:09 +03:00
185 lines
4.2 KiB
D
185 lines
4.2 KiB
D
// Written in the D programming language
|
|
|
|
/*
|
|
* Copyright (C) 2005-2007 by Digital Mars, www.digitalmars.com
|
|
* Written by Walter Bright
|
|
*
|
|
* This software is provided 'as-is', without any express or implied
|
|
* warranty. In no event will the authors be held liable for any damages
|
|
* arising from the use of this software.
|
|
*
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
* including commercial applications, and to alter it and redistribute it
|
|
* freely, in both source and binary form, subject to the following
|
|
* restrictions:
|
|
*
|
|
* o The origin of this software must not be misrepresented; you must not
|
|
* claim that you wrote the original software. If you use this software
|
|
* in a product, an acknowledgment in the product documentation would be
|
|
* appreciated but is not required.
|
|
* o Altered source versions must be plainly marked as such, and must not
|
|
* be misrepresented as being the original software.
|
|
* o This notice may not be removed or altered from any source
|
|
* distribution.
|
|
*/
|
|
|
|
/**
|
|
* Code coverage analyzer.
|
|
* Bugs:
|
|
* $(UL
|
|
* $(LI the execution counters are 32 bits in size, and can overflow)
|
|
* $(LI inline asm statements are not counted)
|
|
* )
|
|
* Macros:
|
|
* WIKI = Phobos/StdCover
|
|
*/
|
|
|
|
module std.cover;
|
|
|
|
private import std.stdio;
|
|
private import std.file;
|
|
private import std.bitmanip;
|
|
|
|
private
|
|
{
|
|
struct Cover
|
|
{
|
|
string filename;
|
|
BitArray valid;
|
|
uint[] data;
|
|
}
|
|
|
|
Cover[] gdata;
|
|
string srcpath;
|
|
string dstpath;
|
|
bool merge;
|
|
}
|
|
|
|
/***********************************
|
|
* Set path to where source files are located.
|
|
*/
|
|
|
|
void setSourceDir(string pathname)
|
|
{
|
|
srcpath = pathname;
|
|
}
|
|
|
|
/***********************************
|
|
* Set path to where listing files are to be written.
|
|
*/
|
|
|
|
void setDestDir(string pathname)
|
|
{
|
|
srcpath = pathname;
|
|
}
|
|
|
|
/***********************************
|
|
* Set merge mode.
|
|
* Params:
|
|
* flag = true means new data is summed with existing data in the
|
|
* listing file; false means a new listing file is always
|
|
* created.
|
|
*/
|
|
|
|
void setMerge(bool flag)
|
|
{
|
|
merge = flag;
|
|
}
|
|
|
|
extern (C) void _d_cover_register(string filename, BitArray valid, uint[] data)
|
|
{
|
|
//printf("_d_cover_register()\n");
|
|
//printf("\tfilename = '%.*s'\n", filename);
|
|
|
|
Cover c;
|
|
c.filename = filename;
|
|
c.valid = valid;
|
|
c.data = data;
|
|
|
|
gdata ~= c;
|
|
}
|
|
|
|
static ~this()
|
|
{
|
|
//printf("cover.~this()\n");
|
|
|
|
foreach (Cover c; gdata)
|
|
{
|
|
//printf("filename = '%.*s'\n", c.filename);
|
|
|
|
// Generate source file name
|
|
string srcfilename = std.path.join(srcpath, c.filename);
|
|
|
|
string buf = cast(string)std.file.read(srcfilename);
|
|
string[] lines = std.string.splitlines(buf);
|
|
|
|
// Generate listing file name
|
|
string lstfilename = std.path.addExt(std.path.getBaseName(c.filename), "lst");
|
|
|
|
if (merge && exists(lstfilename) && isfile(lstfilename))
|
|
{
|
|
string lst = cast(string)std.file.read(lstfilename);
|
|
string[] lstlines = std.string.splitlines(lst);
|
|
|
|
for (size_t i = 0; i < lstlines.length; i++)
|
|
{
|
|
if (i >= c.data.length)
|
|
break;
|
|
int count = 0;
|
|
foreach (char c2; lstlines[i])
|
|
{
|
|
switch (c2)
|
|
{ case ' ':
|
|
continue;
|
|
case '0': case '1': case '2': case '3': case '4':
|
|
case '5': case '6': case '7': case '8': case '9':
|
|
count = count * 10 + c2 - '0';
|
|
continue;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
//printf("[%d] %d\n", i, count);
|
|
c.data[i] += count;
|
|
}
|
|
}
|
|
|
|
FILE *flst = std.c.stdio.fopen(lstfilename.ptr, "wb");
|
|
if (!flst)
|
|
throw new std.file.FileException(lstfilename, "cannot open for write");
|
|
|
|
uint nno;
|
|
uint nyes;
|
|
|
|
for (int i = 0; i < c.data.length; i++)
|
|
{
|
|
//printf("[%2d] = %u\n", i, c.data[i]);
|
|
if (i < lines.length)
|
|
{
|
|
uint n = c.data[i];
|
|
string line = lines[i];
|
|
line = std.string.expandtabs(line);
|
|
if (n == 0)
|
|
{
|
|
if (c.valid[i])
|
|
{ nno++;
|
|
fwritefln(flst, "0000000|%s", line);
|
|
}
|
|
else
|
|
fwritefln(flst, " |%s", line);
|
|
}
|
|
else
|
|
{ nyes++;
|
|
fwritefln(flst, "%7s|%s", n, line);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nyes + nno) // no divide by 0 bugs
|
|
fwritefln(flst, "%s is %s%% covered", c.filename, (nyes * 100) / (nyes + nno));
|
|
|
|
std.c.stdio.fclose(flst);
|
|
}
|
|
}
|
|
|