Skip to content

Commit

Permalink
[llvm-cov] Use relative paths to the stylesheet (for html reports)
Browse files Browse the repository at this point in the history
This makes it easy to swap out the default stylesheet for a custom one.
It also shaves ~6.62 MB out of the report directory for a full coverage
build of llvm+clang.

While we're at it, prune the CSS and add tests for it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@276359 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
vedantk committed Jul 21, 2016
1 parent 0eeda09 commit 6aa68be
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 58 deletions.
22 changes: 22 additions & 0 deletions test/tools/llvm-cov/style.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -filename-equivalence %S/showTemplateInstantiations.cpp -format html -o %t.dir

RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -filename-equivalence -name=_Z4funcIbEiT_ %S/showTemplateInstantiations.cpp -format html -o %t.dir

RUN: FileCheck %s -input-file=%t.dir/style.css -check-prefix=STYLE
RUN: FileCheck %s -input-file=%t.dir/functions.html -check-prefix=FUNCTIONS
RUN: FileCheck %s -input-file=%t.dir/coverage/tmp/showTemplateInstantiations.cpp.html -check-prefix=FILEVIEW

STYLE-DAG: .red
STYLE-DAG: .cyan
STYLE-DAG: .source-name-title
STYLE-DAG: .centered
STYLE-DAG: .expansion-view
STYLE-DAG: .line-number
STYLE-DAG: .covered-line
STYLE-DAG: .uncovered-line
STYLE-DAG: .tooltip
STYLE-DAG: .tooltip span.tooltip-content

FUNCTIONS: <link rel='stylesheet' type='text/css' href='style.css'>

FILEVIEW: <link rel='stylesheet' type='text/css' href='..{{.*}}..{{.*}}style.css'>
4 changes: 2 additions & 2 deletions tools/llvm-cov/SourceCoverageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,6 @@ struct LineCoverageStats {

/// \brief A file manager that handles format-aware file creation.
class CoveragePrinter {
const CoverageViewOptions &Opts;

public:
struct StreamDestructor {
void operator()(raw_ostream *OS) const;
Expand All @@ -109,6 +107,8 @@ class CoveragePrinter {
using OwnedStream = std::unique_ptr<raw_ostream, StreamDestructor>;

protected:
const CoverageViewOptions &Opts;

CoveragePrinter(const CoverageViewOptions &Opts) : Opts(Opts) {}

/// \brief Return `OutputDir/ToplevelDir/Path.Extension`. If \p InToplevel is
Expand Down
127 changes: 71 additions & 56 deletions tools/llvm-cov/SourceCoverageViewHTML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,51 @@ using namespace llvm;

namespace {

// Return a string with the special characters in \p Str escaped.
std::string escape(StringRef Str) {
std::string Result;
for (char C : Str) {
if (C == '&')
Result += "&amp;";
else if (C == '<')
Result += "&lt;";
else if (C == '>')
Result += "&gt;";
else if (C == '\"')
Result += "&quot;";
else
Result += C;
}
return Result;
}

// Create a \p Name tag around \p Str, and optionally set its \p ClassName.
std::string tag(const std::string &Name, const std::string &Str,
const std::string &ClassName = "") {
std::string Tag = "<" + Name;
if (ClassName != "")
Tag += " class='" + ClassName + "'";
return Tag + ">" + Str + "</" + Name + ">";
}

// Create an anchor to \p Link with the label \p Str.
std::string a(const std::string &Link, const std::string &Str,
const std::string &TargetType = "href") {
return "<a " + TargetType + "='" + Link + "'>" + Str + "</a>";
}

const char *BeginHeader =
"<head>"
"<meta name='viewport' content='width=device-width,initial-scale=1'>"
"<meta charset='UTF-8'>";

const char *CSSForCoverage =
"<style>"
R"(
.red {
R"(.red {
background-color: #FFD0D0;
}
.cyan {
background-color: cyan;
}
.black {
background-color: black;
color: white;
}
.green {
background-color: #98FFA6;
color: white;
}
.magenta {
background-color: #F998FF;
color: white;
}
body {
font-family: -apple-system, sans-serif;
}
Expand Down Expand Up @@ -140,9 +158,7 @@ td:first-child {
td:last-child {
border-right: none;
}
)"
"</style>";
)";

const char *EndHeader = "</head>";

Expand Down Expand Up @@ -170,51 +186,35 @@ const char *BeginTable = "<table>";

const char *EndTable = "</table>";

void emitPrelude(raw_ostream &OS) {
std::string getPathToStyle(StringRef ViewPath) {
std::string PathToStyle = "";
std::string PathSep = sys::path::get_separator();
unsigned NumSeps = ViewPath.count(PathSep);
for (unsigned I = 0, E = NumSeps; I < E; ++I)
PathToStyle += ".." + PathSep;
return PathToStyle + "style.css";
}

void emitPrelude(raw_ostream &OS, const std::string &PathToStyle = "") {
OS << "<!doctype html>"
"<html>"
<< BeginHeader << CSSForCoverage << EndHeader << "<body>"
<< BeginCenteredDiv;
<< BeginHeader;

// Link to a stylesheet if one is available. Otherwise, use the default style.
if (PathToStyle.empty())
OS << "<style>" << CSSForCoverage << "</style>";
else
OS << "<link rel='stylesheet' type='text/css' href='" << escape(PathToStyle)
<< "'>";

OS << EndHeader << "<body>" << BeginCenteredDiv;
}

void emitEpilog(raw_ostream &OS) {
OS << EndCenteredDiv << "</body>"
"</html>";
}

// Return a string with the special characters in \p Str escaped.
std::string escape(StringRef Str) {
std::string Result;
for (char C : Str) {
if (C == '&')
Result += "&amp;";
else if (C == '<')
Result += "&lt;";
else if (C == '>')
Result += "&gt;";
else if (C == '\"')
Result += "&quot;";
else
Result += C;
}
return Result;
}

// Create a \p Name tag around \p Str, and optionally set its \p ClassName.
std::string tag(const std::string &Name, const std::string &Str,
const std::string &ClassName = "") {
std::string Tag = "<" + Name;
if (ClassName != "")
Tag += " class='" + ClassName + "'";
return Tag + ">" + Str + "</" + Name + ">";
}

// Create an anchor to \p Link with the label \p Str.
std::string a(const std::string &Link, const std::string &Str,
const std::string &TargetType = "href") {
return "<a " + TargetType + "='" + Link + "'>" + Str + "</a>";
}

} // anonymous namespace

Expected<CoveragePrinter::OwnedStream>
Expand All @@ -224,7 +224,14 @@ CoveragePrinterHTML::createViewFile(StringRef Path, bool InToplevel) {
return OSOrErr;

OwnedStream OS = std::move(OSOrErr.get());
emitPrelude(*OS.get());

if (!Opts.hasOutputDirectory()) {
emitPrelude(*OS.get());
} else {
std::string ViewPath = getOutputPath(Path, "html", InToplevel);
emitPrelude(*OS.get(), getPathToStyle(ViewPath));
}

return std::move(OS);
}

Expand Down Expand Up @@ -252,6 +259,14 @@ Error CoveragePrinterHTML::createIndexFile(ArrayRef<StringRef> SourceFiles) {
OSRef << EndTable;
emitEpilog(OSRef);

// Emit the default stylesheet.
auto CSSOrErr = createOutputStream("style", "css", /*InToplevel=*/true);
if (Error E = CSSOrErr.takeError())
return E;

OwnedStream CSS = std::move(CSSOrErr.get());
CSS->operator<<(CSSForCoverage);

return Error::success();
}

Expand Down

0 comments on commit 6aa68be

Please sign in to comment.