From 99ba78f9f992f613defaf66bbb43b999dc15aaff Mon Sep 17 00:00:00 2001 From: Quentin Sabah Date: Tue, 27 Dec 2022 13:15:06 +0100 Subject: [PATCH 1/2] fixes for the debug report - update `highlightjs` and `diff2html` - fix: display graphs as images instead of text - fix: display diffs correctly - fix: highlight souffle and RAM diffs correctly --- src/TranslationUnitBase.h | 7 ++- src/ast/TranslationUnit.cpp | 5 +- src/ast/analysis/PrecedenceGraph.cpp | 1 + src/ast/analysis/PrecedenceGraph.h | 2 +- src/include/souffle/utility/StringUtil.h | 23 +++++++ src/reports/DebugReport.cpp | 78 +++++++++++------------- 6 files changed, 69 insertions(+), 47 deletions(-) diff --git a/src/TranslationUnitBase.h b/src/TranslationUnitBase.h index 42f80de5e2c..98e0e03228c 100644 --- a/src/TranslationUnitBase.h +++ b/src/TranslationUnitBase.h @@ -49,9 +49,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; }; diff --git a/src/ast/TranslationUnit.cpp b/src/ast/TranslationUnit.cpp index c1be8f6aa7e..77a3c5f2fda 100644 --- a/src/ast/TranslationUnit.cpp +++ b/src/ast/TranslationUnit.cpp @@ -22,10 +22,9 @@ void TranslationUnit::logAnalysis(Analysis& analysis) const { std::string name = analysis.getName(); if (as(analysis) || as(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)); } } diff --git a/src/ast/analysis/PrecedenceGraph.cpp b/src/ast/analysis/PrecedenceGraph.cpp index 5c783cb29f4..01968404240 100644 --- a/src/ast/analysis/PrecedenceGraph.cpp +++ b/src/ast/analysis/PrecedenceGraph.cpp @@ -27,6 +27,7 @@ #include "ast/Relation.h" #include "ast/TranslationUnit.h" #include "ast/utility/Visitor.h" +#include "souffle/utility/StringUtil.h" #include #include #include diff --git a/src/ast/analysis/PrecedenceGraph.h b/src/ast/analysis/PrecedenceGraph.h index abeb366b67d..12e036e6815 100644 --- a/src/ast/analysis/PrecedenceGraph.h +++ b/src/ast/analysis/PrecedenceGraph.h @@ -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& graph() const { diff --git a/src/include/souffle/utility/StringUtil.h b/src/include/souffle/utility/StringUtil.h index 0c1483b0562..7e87d447825 100644 --- a/src/include/souffle/utility/StringUtil.h +++ b/src/include/souffle/utility/StringUtil.h @@ -247,6 +247,15 @@ template struct is_printable() << std::declval()), void>::type> : public std::true_type {}; + +template +struct is_html_printable : public std::false_type {}; + +template +struct is_html_printable().printHTML(std::declval())), + void>::type> : public std::true_type {}; + } // namespace detail /** @@ -277,6 +286,20 @@ typename std::enable_if::value, std::string>::type toSt return ss.str(); } +template +auto toHtml(const T& obj) -> typename std::enable_if::value, std::string>::type { + std::stringstream out; + obj.printHTML(out); + return out.str(); +} + +/** Fallback to `toString` */ +template +auto toHtml(const T& obj) -> + typename std::enable_if::value, std::string>::type { + return toString(obj); +} + // ------------------------------------------------------------------------------- // String Utils // ------------------------------------------------------------------------------- diff --git a/src/reports/DebugReport.cpp b/src/reports/DebugReport.cpp index d2a2aba7bf0..b54d6a8804c 100644 --- a/src/reports/DebugReport.cpp +++ b/src/reports/DebugReport.cpp @@ -135,13 +135,16 @@ void DebugReport::addSection(DebugReportSection section) { buf.emplace_back(std::move(section)); } -static std::string CDATA(const std::string_view code) { - return "", "]]]]>") + "]]>"; +static std::string codeToHtml(const std::string_view code) { + return replaceAll( + replaceAll(replaceAll(replaceAll(replaceAll(code, "&", " "), "<", "<"), ">", ">"), + "\"", """), + "'", "&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("
%s
", CDATA(code)))); + addSection(DebugReportSection( + std::move(id), std::move(title), tfm::format("
%s
", codeToHtml(code)))); } void DebugReport::addCodeSection(std::string id, std::string title, std::string_view language, @@ -149,10 +152,10 @@ void DebugReport::addCodeSection(std::string id, std::string title, std::string_ const std::string diff = (prev.empty() ? std::string(curr) : generateDiff(prev, curr)); auto divId = nextUniqueId++; auto html = R"( -
%s>
+
%s
)"; 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) { @@ -165,12 +168,10 @@ void DebugReport::endSection(std::string currentSectionName, std::string current void DebugReport::print(std::ostream& out) const { out << R"--html--( - - - + + + - Souffle Debug Report ()--html--"; out << *programName << R"--html--() + "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/styles/default.min.css"> + "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/highlight.min.js"> - + "https://cdn.jsdelivr.net/npm/diff2html@3.4.22/bundles/css/diff2html.min.css" /> + "https://cdn.jsdelivr.net/npm/diff2html@3.4.22/bundles/js/diff2html-ui-base.min.js"> + "https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.8.0/build/highlight.min.js"> + "https://cdn.jsdelivr.net/npm/diff2html@3.4.34/bundles/css/diff2html.min.css" /> + "https://cdn.jsdelivr.net/npm/diff2html@3.4.34/bundles/js/diff2html-ui-base.min.js">