Skip to content

Commit

Permalink
fixes for the debug report (#2433)
Browse files Browse the repository at this point in the history
- update `highlightjs` and `diff2html`
- fix: display graphs as images instead of text
- fix: display diffs correctly
- fix: highlight souffle and RAM diffs correctly
  • Loading branch information
quentin authored Oct 24, 2023
1 parent da9e3c2 commit ab6c00d
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 49 deletions.
7 changes: 6 additions & 1 deletion src/TranslationUnitBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,14 @@ class AnalysisBase {
return name_as_cstr_literal;
}

/** @brief Print the analysis result in HTML format */
/** @brief Print the analysis result in textual format */
virtual void print(std::ostream& /* os */) const {}

/** @brief Print the analysis result in HTML format (or fallback to textual format) */
virtual void printHTML(std::ostream& os) const {
print(os);
}

private:
char const* const name_as_cstr_literal;
};
Expand Down
5 changes: 2 additions & 3 deletions src/ast/TranslationUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@ void TranslationUnit::logAnalysis(Analysis& analysis) const {

std::string name = analysis.getName();
if (as<analysis::PrecedenceGraphAnalysis>(analysis) || as<analysis::SCCGraphAnalysis>(analysis)) {
debugReport.addSection(
DebugReportSection(name, "Ast Analysis [" + name + "]", {}, toString(analysis)));
debugReport.addSection(DebugReportSection(name, "Ast Analysis [" + name + "]", {}, toHtml(analysis)));
} else {
debugReport.addSection(name, "Ast Analysis [" + name + "]", toString(analysis));
debugReport.addSection(name, "Ast Analysis [" + name + "]", toHtml(analysis));
}
}

Expand Down
1 change: 1 addition & 0 deletions src/ast/analysis/PrecedenceGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "ast/Relation.h"
#include "ast/TranslationUnit.h"
#include "ast/utility/Visitor.h"
#include "souffle/utility/StringUtil.h"
#include <set>
#include <string>
#include <vector>
Expand Down
2 changes: 1 addition & 1 deletion src/ast/analysis/PrecedenceGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class PrecedenceGraphAnalysis : public Analysis {
/** Output precedence graph in text format to a given stream */
void print(std::ostream& os) const override;

/** Output precedence graph in graphviz format to a given stream */
/** Output precedence graph in image format to a given stream */
void printHTML(std::ostream& os) const;

const Graph<const Relation*, NameComparison>& graph() const {
Expand Down
23 changes: 23 additions & 0 deletions src/include/souffle/utility/StringUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ template <typename T>
struct is_printable<T, typename std::conditional<false,
decltype(std::declval<std::ostream&>() << std::declval<T>()), void>::type>
: public std::true_type {};

template <typename T, typename filter = void>
struct is_html_printable : public std::false_type {};

template <typename T>
struct is_html_printable<T,
typename std::conditional<false, decltype(std::declval<T>().printHTML(std::declval<std::ostream&>())),
void>::type> : public std::true_type {};

} // namespace detail

/**
Expand Down Expand Up @@ -277,6 +286,20 @@ typename std::enable_if<!detail::is_printable<T>::value, std::string>::type toSt
return ss.str();
}

template <typename T>
auto toHtml(const T& obj) -> typename std::enable_if<detail::is_html_printable<T>::value, std::string>::type {
std::stringstream out;
obj.printHTML(out);
return out.str();
}

/** Fallback to `toString` */
template <typename T>
auto toHtml(const T& obj) ->
typename std::enable_if<not detail::is_html_printable<T>::value, std::string>::type {
return toString(obj);
}

// -------------------------------------------------------------------------------
// String Utils
// -------------------------------------------------------------------------------
Expand Down
82 changes: 38 additions & 44 deletions src/reports/DebugReport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,24 +135,27 @@ void DebugReport::addSection(DebugReportSection section) {
buf.emplace_back(std::move(section));
}

static std::string CDATA(const std::string_view code) {
return "<![CDATA[" + replaceAll(code, "]]>", "]]]]><![CDATA[>") + "]]>";
static std::string codeToHtml(const std::string_view code) {
return replaceAll(
replaceAll(replaceAll(replaceAll(replaceAll(code, "&", "&nbsp;"), "<", "&lt;"), ">", "&gt;"),
"\"", "&ldquo;"),
"'", "&lsquo");
}

void DebugReport::addSection(std::string id, std::string title, const std::string_view code) {
addSection(
DebugReportSection(std::move(id), std::move(title), tfm::format("<pre>%s</pre>", CDATA(code))));
addSection(DebugReportSection(
std::move(id), std::move(title), tfm::format("<pre>%s</pre>", codeToHtml(code))));
}

void DebugReport::addCodeSection(std::string id, std::string title, std::string_view language,
std::string_view prev, std::string_view curr) {
void DebugReport::addCodeSection(std::string id, std::string title,
[[maybe_unused]] std::string_view language, std::string_view prev, std::string_view curr) {
const std::string diff = (prev.empty() ? std::string(curr) : generateDiff(prev, curr));
auto divId = nextUniqueId++;
auto html = R"(
<div id="code-id-%d" class="diff-%s">%s></div>
<div id="code-id-%d" class="diff-%s">%s</div>
)";
addSection(DebugReportSection(
std::move(id), std::move(title), tfm::format(html, divId, language, CDATA(diff))));
std::move(id), std::move(title), tfm::format(html, divId, language, codeToHtml(diff))));
}

void DebugReport::endSection(std::string currentSectionName, std::string currentSectionTitle) {
Expand All @@ -165,12 +168,10 @@ void DebugReport::endSection(std::string currentSectionName, std::string current

void DebugReport::print(std::ostream& out) const {
out << R"--html--(
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-AU">
<!DOCTYPE html>
<html lang="en">
<meta charset="utf8">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
<title>Souffle Debug Report ()--html--";
out << *programName << R"--html--()</title>
<style>
Expand All @@ -188,15 +189,14 @@ void DebugReport::print(std::ostream& out) const {
</style>
<link rel="stylesheet" href=
"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.5.1/build/styles/default.min.css">
"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.8.0/build/styles/default.min.css">
<script src=
"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.5.1/build/highlight.min.js"></script>
"https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.8.0/build/highlight.min.js"></script>
<!-- must use 3.4.10 until https://github.com/rtfpessoa/diff2html/issues/437 is resolved -->
<link rel="stylesheet" type="text/css" href=
"https://cdn.jsdelivr.net/npm/[email protected].10/bundles/css/diff2html.min.css" />
"https://cdn.jsdelivr.net/npm/[email protected].34/bundles/css/diff2html.min.css" />
<script type="text/javascript" src=
"https://cdn.jsdelivr.net/npm/[email protected].10/bundles/js/diff2html-ui-base.min.js"></script>
"https://cdn.jsdelivr.net/npm/[email protected].34/bundles/js/diff2html-ui-base.min.js"></script>
<script>
function toggleVisibility(id) {
Expand All @@ -216,15 +216,15 @@ void DebugReport::print(std::ostream& out) const {
]
let KEYWORDS = {
$pattern: '\\.?\\w+',
$pattern: /\.?\w+/,
literal: 'true false',
keyword: '.pragma .functor .component .decl .input .output .type ' +
'ord strlen strsub range matches land lor lxor lnot bwand bwor bwxor bwnot bshl bshr bshru',
keyword: '.pragma .functor .comp .init .override .decl .input .output .type .plan .include .once ' +
'ord strlen strsub range matches land lor lxor lnot bwand bwor bwxor bwnot bshl bshr bshru inline btree btree_delete override unsigned number float symbol',
}
let STRING = hljs.QUOTE_STRING_MODE
let NUMBERS = {
className: 'number', relevance: 0, variants: [
scope: 'number', relevance: 0, variants: [
{ begin: /\b0b[01]+/ },
{ begin: /\b\d+\.\d+/ }, // float
{ begin: /\b\d+\.\d+.\d+.\d+/ }, // IPv4 literal
Expand All @@ -234,42 +234,33 @@ void DebugReport::print(std::ostream& out) const {
}
let PREPROCESSOR = {
className: 'meta',
scope: 'meta',
begin: /#\s*[a-z]+\b/,
end: /$/,
keyword: {
'meta-keyword': 'if else elif endif define undef warning error line pragma ifdef ifndef include'
},
contains: [
{ begin: /\\\n/, relevance: 0 },
hljs.inherit(STRING, { className: 'meta-string' }),
hljs.inherit(STRING, { scope: 'meta-string' }),
].concat(COMMENT_MODES)
};
let ATOM = { begin: /[a-z][A-Za-z0-9_]*/, relevance: 0 }
let VAR = {
className: 'symbol', relevance: 0, variants: [
{ begin: /[A-Z][a-zA-Z0-9_]*/ },
{ begin: /_[A-Za-z0-9_]*/ },
]
}
let PARENTED = { begin: /\(/, end: /\)/, relevance: 0 }
let LIST = { begin: /\[/, end: /\]/ }
let PRED_OP = { begin: /:\-/ } // relevance booster
let PRED_OP = { begin: /:\-/, scope: 'keyword' } // relevance booster
let RELATION_DISPATCH = {
scope: 'title.function',
relevance: 0,
begin: hljs.regex.concat(hljs.IDENT_RE, hljs.regex.lookahead(/\s*\(/))
};
let INNER = [
ATOM,
VAR,
PARENTED,
RELATION_DISPATCH,
PRED_OP,
LIST,
STRING,
NUMBERS,
].concat(COMMENT_MODES)
PARENTED.contains = INNER;
LIST.contains = INNER;
return {
name: 'souffle',
keywords: KEYWORDS,
Expand Down Expand Up @@ -326,7 +317,7 @@ void DebugReport::print(std::ostream& out) const {
const STRING = hljs.QUOTE_STRING_MODE;
const INDEX = {
className: 'variable',
scope: 'variable',
begin: /\bt\d+(\.\d+)?/
}
Expand Down Expand Up @@ -360,6 +351,9 @@ void DebugReport::print(std::ostream& out) const {
+++ ${ram_file}
@@ -1 +1 @@
`
let extLang = new Map();
extLang.set('souffle', 'souffle');
extLang.set('ram', 'ram');
document.addEventListener('DOMContentLoaded', function() {
var els = document.getElementsByClassName("diff-souffle");
Expand All @@ -370,7 +364,7 @@ void DebugReport::print(std::ostream& out) const {
matching: 'none',
outputFormat: 'side-by-side',
synchronisedScroll: true,
highlightLanguage: 'souffle'
highlightLanguages: extLang
}, hljs);
diff2htmlUi.draw();
});
Expand All @@ -382,7 +376,7 @@ void DebugReport::print(std::ostream& out) const {
matching: 'none',
outputFormat: 'side-by-side',
synchronisedScroll: true,
highlightLanguage: 'ram'
highlightLanguages: extLang
}, hljs);
diff2htmlUi.draw();
});
Expand Down

0 comments on commit ab6c00d

Please sign in to comment.