From 2d1039210a0ea016d45a348cf1736cdf26596908 Mon Sep 17 00:00:00 2001
From: Simon Schwitanski <schwitanski@itc.rwth-aachen.de>
Date: Fri, 26 Apr 2024 19:27:22 +0200
Subject: [PATCH] Add patch for relative output paths in HTML report

---
 Dockerfile                   |   1 +
 patches/relative-paths.patch | 226 +++++++++++++++++++++++++++++++++++
 2 files changed, 227 insertions(+)
 create mode 100644 patches/relative-paths.patch

diff --git a/Dockerfile b/Dockerfile
index 1f792d1..0bc70d5 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -114,6 +114,7 @@ RUN cd MUST-v${MUST_VERSION} && \
     patch utility/mustrun2.sh < /patches/mustrun-env.patch && \
     patch externals/typeart/scripts/typeart-wrapper.in < /patches/typeart-fpic.patch && \
     patch modules/MpiTypeArt/MpiTypeArt.cpp < /patches/typeart-output.patch && \
+    patch -p1 < /patches/relative-paths.patch && \
     cd build && \
     CC=clang CXX=clang++ MPICH_CC=clang MPICH_CXX=clang++ OMPI_CC=clang OMPI_CXX=clang \
       cmake .. -DCMAKE_INSTALL_PREFIX=/opt/must -DUSE_BACKWARD=ON -DENABLE_TESTS=ON -DENABLE_FORTRAN=ON -DLLVM_FILECHECK_PATH=$(which FileCheck) -DCMAKE_BUILD_TYPE=Release && \
diff --git a/patches/relative-paths.patch b/patches/relative-paths.patch
new file mode 100644
index 0000000..9cbac6a
--- /dev/null
+++ b/patches/relative-paths.patch
@@ -0,0 +1,226 @@
+diff --git a/modules/Common/MustOutputdir.cpp b/modules/Common/MustOutputdir.cpp
+index 98d5729c..1bde2b22 100644
+--- a/modules/Common/MustOutputdir.cpp
++++ b/modules/Common/MustOutputdir.cpp
+@@ -15,16 +15,16 @@ std::string const& get_base_output_dir()
+     return path;
+ }
+ 
+-std::string must_output_dir_with_file(char const* file_name)
++std::string must_output_reldir_with_file(char const* file_name)
+ {
+-    std::string result = get_base_output_dir() + "/MUST_Output-files/" + file_name;
++    std::string result = std::string("MUST_Output-files/") + file_name;
+ 
+     return result;
+ }
+ 
+ std::ofstream must_output_open_file(char const* file_name)
+ {
+-    std::string const path = must_output_dir_with_file(file_name);
++    std::string const path = get_base_output_dir() + "/MUST_Output-files/" + file_name;
+ 
+     return std::ofstream(path);
+ }
+diff --git a/modules/Common/MustOutputdir.h b/modules/Common/MustOutputdir.h
+index 23e71f03..81efc6a5 100644
+--- a/modules/Common/MustOutputdir.h
++++ b/modules/Common/MustOutputdir.h
+@@ -22,8 +22,9 @@
+ 
+ // Replacement for getBaseOutputDir()
+ std::string const& get_base_output_dir();
+-// Replacement for MUST_OUTPUT_DIR macro (no more invoking UB by calling .c_str() on a temporary)
+-std::string must_output_dir_with_file(char const* file_name);
++// Returns relative output path from directory where MUST_Output.html is placed.
++// This is required to format paths correctly in MUST reports.
++std::string must_output_reldir_with_file(char const* file_name);
+ 
+ // Opens a file `file_name` in the MUST_Output directory
+ // USE THIS IF YOU WANT TO OPEN A FILE IN THE OUTPUT DIRECTORY,
+diff --git a/modules/DeadlockDetection/BlockingState/BlockingState.cpp b/modules/DeadlockDetection/BlockingState/BlockingState.cpp
+index 68087347..31bd8d5b 100644
+--- a/modules/DeadlockDetection/BlockingState/BlockingState.cpp
++++ b/modules/DeadlockDetection/BlockingState/BlockingState.cpp
+@@ -1111,7 +1111,7 @@ void BlockingState::printHistoryAsDot(void)
+     out.close();
+ 
+     must::cout << "BlockingState: Printed block history into a file named \""
+-               << must_output_dir_with_file("must_block_history.dot")
++               << must_output_reldir_with_file("must_block_history.dot")
+                << "\" use DOT to visualize it." << std::endl;
+ }
+ #endif
+@@ -1493,9 +1493,9 @@ bool BlockingState::detectDeadlock(void)
+     stream
+         << "The application issued a set of MPI calls that can cause a deadlock!"
+         << " A graphical representation of this situation is available in a"
+-        << " <a href=\"" << must_output_dir_with_file("MUST_Deadlock.html")
++        << " <a href=\"" << must_output_reldir_with_file("MUST_Deadlock.html")
+         << "\" title=\"detailed deadlock view\"> detailed deadlock view ("
+-        << must_output_dir_with_file("MUST_Deadlock.html") << ")</a>."
++        << must_output_reldir_with_file("MUST_Deadlock.html") << ")</a>."
+         << " References 1-" << refs.size()
+         << " list the involved calls (limited to the first 5 calls, further calls may be involved)."
+         << " The application still runs, if the deadlock manifested (e.g. caused a hang on this "
+@@ -1505,13 +1505,13 @@ bool BlockingState::detectDeadlock(void)
+     stream
+         << "The application issued a set of MPI calls that can cause a deadlock!"
+         << " A graphical representation of this situation is available in the file named \""
+-        << must_output_dir_with_file("MUST_Deadlock.dot") << "\"."
++        << must_output_reldir_with_file("MUST_Deadlock.dot") << "\"."
+         << " Use the dot tool of the graphviz package to visualize it, e.g. issue \"dot -Tps "
+-        << must_output_dir_with_file("MUST_Deadlock.dot") << " -o deadlock.ps\"."
++        << must_output_reldir_with_file("MUST_Deadlock.dot") << " -o deadlock.ps\"."
+         << " The graph shows the nodes that form the root cause of the deadlock, any other active "
+            "MPI calls have been removed."
+         << " A legend is available in the dot format in the file named \""
+-        << must_output_dir_with_file("MUST_DeadlockLegend.dot")
++        << must_output_reldir_with_file("MUST_DeadlockLegend.dot")
+         << "\", further information on these graphs is available in the "
+            "MUST manual."
+         << " References 1-" << refs.size()
+diff --git a/modules/DeadlockDetection/DWaitState/DWaitStateWfgMgr.cpp b/modules/DeadlockDetection/DWaitState/DWaitStateWfgMgr.cpp
+index 17eb945e..d31bf12a 100644
+--- a/modules/DeadlockDetection/DWaitState/DWaitStateWfgMgr.cpp
++++ b/modules/DeadlockDetection/DWaitState/DWaitStateWfgMgr.cpp
+@@ -976,9 +976,9 @@ void DWaitStateWfgMgr::reportDeadlock(std::list<int> nodes, bool abort)
+     stream
+         << "The application issued a set of MPI calls that can cause a deadlock!"
+         << " A graphical representation of this situation is available in a"
+-        << " <a href=\"" << must_output_dir_with_file("MUST_Deadlock.html")
++        << " <a href=\"" << must_output_reldir_with_file("MUST_Deadlock.html")
+         << "\" title=\"detailed deadlock view\"> detailed deadlock view ("
+-        << must_output_dir_with_file("MUST_Deadlock.html") << ")</a>."
++        << must_output_reldir_with_file("MUST_Deadlock.html") << ")</a>."
+         << " References 1-" << refs.size()
+         << " list the involved calls (limited to the first 5 calls, further calls may be involved)."
+         << " The application still runs, if the deadlock manifested (e.g. caused a hang on this "
+@@ -988,13 +988,13 @@ void DWaitStateWfgMgr::reportDeadlock(std::list<int> nodes, bool abort)
+     stream
+         << "The application issued a set of MPI calls that can cause a deadlock!"
+         << " A graphical representation of this situation is available in the file named \""
+-        << must_output_dir_with_file("MUST_Deadlock.dot") << "\"."
++        << must_output_reldir_with_file("MUST_Deadlock.dot") << "\"."
+         << " Use the dot tool of the graphviz package to visualize it, e.g. issue \"dot -Tps "
+-        << must_output_dir_with_file("MUST_Deadlock.dot") << " -o deadlock.ps\"."
++        << must_output_reldir_with_file("MUST_Deadlock.dot") << " -o deadlock.ps\"."
+         << " The graph shows the nodes that form the root cause of the deadlock, any other active "
+            "MPI calls have been removed."
+         << " A legend is available in the dot format in the file named \""
+-        << must_output_dir_with_file("MUST_DeadlockLegend.dot")
++        << must_output_reldir_with_file("MUST_DeadlockLegend.dot")
+         << "\", further information on these graphs is available in the "
+            "MUST manual."
+         << " References 1-" << refs.size()
+diff --git a/modules/DeadlockDetection/P2PMatch/DP2POp.cpp b/modules/DeadlockDetection/P2PMatch/DP2POp.cpp
+index 33dba199..29a850be 100644
+--- a/modules/DeadlockDetection/P2PMatch/DP2POp.cpp
++++ b/modules/DeadlockDetection/P2PMatch/DP2POp.cpp
+@@ -334,9 +334,9 @@ bool DP2POp::matchTypes(DP2POp* other)
+             ss << "MUST_Typemismatch_" << myPId;
+             std::string base_file_name_without_ext = ss.str();
+             std::string htmlFile =
+-                must_output_dir_with_file((base_file_name_without_ext + ".html").c_str());
++                must_output_reldir_with_file((base_file_name_without_ext + ".html").c_str());
+             std::string dotFile =
+-                must_output_dir_with_file((base_file_name_without_ext + ".dot").c_str());
++                must_output_reldir_with_file((base_file_name_without_ext + ".dot").c_str());
+ 
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_file_name_without_ext + ".dot").c_str());
+diff --git a/modules/DeadlockDetection/P2PMatch/P2POp.cpp b/modules/DeadlockDetection/P2PMatch/P2POp.cpp
+index bc8a5e2d..7da9d0a4 100644
+--- a/modules/DeadlockDetection/P2PMatch/P2POp.cpp
++++ b/modules/DeadlockDetection/P2PMatch/P2POp.cpp
+@@ -370,9 +370,9 @@ bool P2POp::matchTypes(P2POp* other)
+             ss << "MUST_Typemismatch_" << myPId;
+             std::string base_file_name_without_ext = ss.str();
+             std::string htmlFile =
+-                must_output_dir_with_file((base_file_name_without_ext + ".html").c_str());
++                must_output_reldir_with_file((base_file_name_without_ext + ".html").c_str());
+             std::string dotFile =
+-                must_output_dir_with_file((base_file_name_without_ext + ".dot").c_str());
++                must_output_reldir_with_file((base_file_name_without_ext + ".dot").c_str());
+ 
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_file_name_without_ext + ".dot").c_str());
+diff --git a/modules/OverlapChecks/OverlapChecks.cpp b/modules/OverlapChecks/OverlapChecks.cpp
+index 27751fa7..3d71e731 100644
+--- a/modules/OverlapChecks/OverlapChecks.cpp
++++ b/modules/OverlapChecks/OverlapChecks.cpp
+@@ -412,9 +412,8 @@ GTI_ANALYSIS_RETURN OverlapChecks::isSendRecvOverlappedN(
+         if (doDotOutput) { // generate dotfile
+             doDotOutput = false;
+             std::string base_name = graphFileName(pId);
+-            std::string htmlFile = must_output_dir_with_file((base_name + ".html").c_str());
+-            std::string imageFile = must_output_dir_with_file((base_name + ".png").c_str());
+-            std::string dotFile = must_output_dir_with_file((base_name + ".dot").c_str());
++            std::string htmlFile = must_output_reldir_with_file((base_name + ".html").c_str());
++            std::string dotFile = must_output_reldir_with_file((base_name + ".dot").c_str());
+             std::ofstream out;
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_name + ".dot").c_str());
+@@ -676,9 +675,8 @@ GTI_ANALYSIS_RETURN OverlapChecks::sendOverlapcheckCounts(
+         if (doDotOutput) { // generate dotfile
+             doDotOutput = false;
+             std::string base_name = graphFileName(pId);
+-            std::string htmlFile = must_output_dir_with_file((base_name + ".html").c_str());
+-            std::string imageFile = must_output_dir_with_file((base_name + ".png").c_str());
+-            std::string dotFile = must_output_dir_with_file((base_name + ".dot").c_str());
++            std::string htmlFile = must_output_reldir_with_file((base_name + ".html").c_str());
++            std::string dotFile = must_output_reldir_with_file((base_name + ".dot").c_str());
+             std::ofstream out;
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_name + ".dot").c_str());
+@@ -790,9 +788,8 @@ GTI_ANALYSIS_RETURN OverlapChecks::recvOverlapcheckCounts(
+         if (doDotOutput) { // generate dotfile
+             doDotOutput = false;
+             std::string base_name = graphFileName(pId);
+-            std::string htmlFile = must_output_dir_with_file((base_name + ".html").c_str());
+-            std::string imageFile = must_output_dir_with_file((base_name + ".png").c_str());
+-            std::string dotFile = must_output_dir_with_file((base_name + ".dot").c_str());
++            std::string htmlFile = must_output_reldir_with_file((base_name + ".html").c_str());
++            std::string dotFile = must_output_reldir_with_file((base_name + ".dot").c_str());
+             std::ofstream out;
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_name + ".dot").c_str());
+@@ -907,9 +904,8 @@ GTI_ANALYSIS_RETURN OverlapChecks::sendOverlapcheckTypes(
+         if (doDotOutput) { // generate dotfile
+             doDotOutput = false;
+             std::string base_name = graphFileName(pId);
+-            std::string htmlFile = must_output_dir_with_file((base_name + ".html").c_str());
+-            std::string imageFile = must_output_dir_with_file((base_name + ".png").c_str());
+-            std::string dotFile = must_output_dir_with_file((base_name + ".dot").c_str());
++            std::string htmlFile = must_output_reldir_with_file((base_name + ".html").c_str());
++            std::string dotFile = must_output_reldir_with_file((base_name + ".dot").c_str());
+             std::ofstream out;
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_name + ".dot").c_str());
+@@ -1026,9 +1022,8 @@ GTI_ANALYSIS_RETURN OverlapChecks::recvOverlapcheckTypes(
+         if (doDotOutput) { // generate dotfile
+             doDotOutput = false;
+             std::string base_name = graphFileName(pId);
+-            std::string htmlFile = must_output_dir_with_file((base_name + ".html").c_str());
+-            std::string imageFile = must_output_dir_with_file((base_name + ".png").c_str());
+-            std::string dotFile = must_output_dir_with_file((base_name + ".dot").c_str());
++            std::string htmlFile = must_output_reldir_with_file((base_name + ".html").c_str());
++            std::string dotFile = must_output_reldir_with_file((base_name + ".dot").c_str());
+             std::ofstream out;
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_name + ".dot").c_str());
+@@ -1267,9 +1262,8 @@ GTI_ANALYSIS_RETURN OverlapChecks::checkOverlapsRequests(
+         if (doDotOutput) { // generate dotfile
+             doDotOutput = false;
+             std::string base_name = graphFileName(pId);
+-            std::string htmlFile = must_output_dir_with_file((base_name + ".html").c_str());
+-            std::string imageFile = must_output_dir_with_file((base_name + ".png").c_str());
+-            std::string dotFile = must_output_dir_with_file((base_name + ".dot").c_str());
++            std::string htmlFile = must_output_reldir_with_file((base_name + ".html").c_str());
++            std::string dotFile = must_output_reldir_with_file((base_name + ".dot").c_str());
+             std::ofstream out;
+             must_ensure_output_dir_exists();
+             out = must_output_open_file((base_name + ".dot").c_str());
+-- 
+2.39.1
+
-- 
GitLab