From 618e96fb00ee4c3a0d407cbc5ce74cca4ffeb760 Mon Sep 17 00:00:00 2001 From: Andreas Suter Date: Wed, 29 Jul 2026 19:44:50 +0200 Subject: [PATCH] fix musrview ctest failures on macOS: RGB order and path buffers Three unrelated issues made the musrview_check tests fail on macOS while passing on Linux. 1. Unspecified argument evaluation order TColor::GetColor(rand.Integer(255), rand.Integer(255), rand.Integer(255)) evaluates its (side-effecting) arguments in an unspecified order: clang goes left-to-right, gcc right-to-left, so the same seed yielded RGB on one platform and BGR on the other. Visible whenever more runs are plotted than the startup xml colour list provides, e.g. test-histo-HAL9500.msr with 16 runs against 10 colours. The rgb values are now drawn into separate variables first. This keeps the clang result and changes gcc to match, hence the regenerated reference PNG for musrview-histo-HAL9500 (99.94% of the differing pixels were exact R<->B swaps). Fixed in PMusrCanvas, PFourierCanvas and both mupp PMuppCanvas copies. 2. Fixed size path buffers char fileName[128] plus strncpy(dst, src, sizeof(dst)) truncates *and* leaves the buffer unterminated once the path reaches the buffer size. musrview then failed on a 132 character msr-path in doc/examples/ViewOpts. musrFT and musrt0 were worse: an unbounded strcpy of the startup file path into char startup_path_name[128], i.e. a stack buffer overflow. All path/filename buffers in the drivers are now std::string: musrview, musrFT, musrt0, musrfit, any2many, addRun, dump_header. PMusrCanvas::SaveGraphicsAndQuit() takes const Char_t* accordingly. Along the way in the same files: - msr2msr_replace() wrote a 256 byte line into char temp[128] - msr2msr assembled "cp"/"rm" shell commands from paths in a 256 byte buffer; replaced by std::filesystem - msr2msr and addRun read lines with getline(buf, N), which silently abandons the rest of the file on the first over-long line - addRun: bound the unbounded sscanf "%s" to "%255s" - dropped scratch buffers that only held a string literal, in favour of TString::ReplaceAll(const char*, const char*) 3. musrview_check.py left its PNGs behind on failure The two early error returns skipped the cleanup, and since generated PNGs were identified by "not in the pre-run snapshot", one leftover file permanently masked the real output of that test: musrview overwrites the stale PNG, so it was there, just filtered out. One failure thus poisoned every later run (30 of the 37 observed failures) after a 15 s poll each. Cleanup now runs in a finally block on every exit path, and generated PNGs are detected by mtime instead, which sees rewritten leftovers while staying safe for a sibling test running concurrently under ctest -j. Also dropped the MUSRVIEW_PNG_DIR env var and its tmp-dir fallback: it is read nowhere in src/, so the fallback was dead code that guaranteed the full 15 s poll before every "no PNGs found" failure. Co-Authored-By: Claude Opus 5 --- src/addRun.cpp | 22 +++-- src/any2many.cpp | 8 +- src/classes/PFourierCanvas.cpp | 16 +++- src/classes/PMusrCanvas.cpp | 34 ++++++-- src/dump_header.cpp | 15 ++-- src/include/PMusrCanvas.h | 2 +- src/msr2msr.cpp | 76 +++++++++--------- src/musrFT.cpp | 6 +- src/musredit_qt5/mupp/plotter/PMuppCanvas.cpp | 8 +- src/musredit_qt6/mupp/plotter/PMuppCanvas.cpp | 8 +- src/musrfit.cpp | 51 +++++------- src/musrt0.cpp | 29 +++---- src/musrview.cpp | 27 +++---- tests/musrview_check/musrview_check.py | 62 ++++++++------ .../test-histo-HAL9500_0.png | Bin 35457 -> 36130 bytes 15 files changed, 204 insertions(+), 160 deletions(-) diff --git a/src/addRun.cpp b/src/addRun.cpp index 9e361615..5c5ada53 100644 --- a/src/addRun.cpp +++ b/src/addRun.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -162,24 +163,22 @@ bool addRun_checkFormat(std::string &format) { bool addRun_readInputFiles(const std::string fileName, std::vector &infoVec) { PAddRunInfo info; - char buf[256], str[256]; + char str[256]; std::ifstream fin(fileName.c_str(), std::ifstream::in); std::string line; char *tok{nullptr}; int status, ival; bool lastWasFile{false}; - memset(buf, '\0', sizeof(buf)); memset(str, '\0', sizeof(str)); - while (fin.good()) { - fin.getline(buf, 256); - line = buf; + // read into a std::string: a fixed size line buffer silently drops the rest of + // the input file as soon as one line (e.g. a long data-file path) exceeds it. + while (std::getline(fin, line)) { boost::trim_left(line); if (line.empty()) continue; if (line[0] == '%') continue; - strncpy(buf, line.c_str(), sizeof(buf)); - tok = strtok(buf, " "); + tok = strtok(line.data(), " "); // strtok tokenises in place, line stays the owner if (!strcmp(tok, "file")) { if (lastWasFile) { infoVec.push_back(info); @@ -198,7 +197,7 @@ bool addRun_readInputFiles(const std::string fileName, std::vector lastWasFile = true; } else if (!strcmp(tok, "t0")) { while ((tok = strtok(NULL, ",")) != NULL) { - status = sscanf(tok, "%d%s", &ival, str); + status = sscanf(tok, "%d%255s", &ival, str); if (status != 1) { std::cerr << std::endl; std::cerr << "**ERROR** found t0 argument '" << tok << "' which is not a number." << std::endl; @@ -541,20 +540,19 @@ int main(int argc, char *argv[]) } // read startup file - char startup_path_name[128]; - memset(startup_path_name, '\0', sizeof(startup_path_name)); + std::string startup_path_name{}; std::unique_ptr saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(); if (!startupHandler->StartupFileFound()) { std::cerr << std::endl << ">> addRun **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - strncpy(startup_path_name, startupHandler->GetStartupFilePath().Data(), sizeof(startup_path_name)); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - status = parseXmlFile(saxParser.get(), startup_path_name); + status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> addRun **WARNING** Reading/parsing musrfit_startup.xml failed."; diff --git a/src/any2many.cpp b/src/any2many.cpp index 67121939..f3f78dfd 100644 --- a/src/any2many.cpp +++ b/src/any2many.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -498,20 +499,19 @@ int main(int argc, char *argv[]) } // read startup file - char startup_path_name[128]; - memset(startup_path_name, '\0', sizeof(startup_path_name)); + std::string startup_path_name{}; std::unique_ptr saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(); if (!startupHandler->StartupFileFound()) { std::cerr << std::endl << ">> any2many **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - strncpy(startup_path_name, startupHandler->GetStartupFilePath().Data(), sizeof(startup_path_name)); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - status = parseXmlFile(saxParser.get(), startup_path_name); + status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> any2many **WARNING** Reading/parsing musrfit_startup.xml failed."; diff --git a/src/classes/PFourierCanvas.cpp b/src/classes/PFourierCanvas.cpp index 20276d2c..f45c4bf3 100644 --- a/src/classes/PFourierCanvas.cpp +++ b/src/classes/PFourierCanvas.cpp @@ -146,7 +146,13 @@ PFourierCanvas::PFourierCanvas(std::vector &fourier, PIntVector dataS rand.SetSeed(i); style = 20+static_cast(rand.Integer(10)); fMarkerList.push_back(style); - color = TColor::GetColor(static_cast(rand.Integer(255)), static_cast(rand.Integer(255)), static_cast(rand.Integer(255))); + // the rgb values need to be drawn into separate variables first: the evaluation order of + // function arguments is unspecified in C++, hence calling rand.Integer() three times within + // the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = static_cast(rand.Integer(255)); + Int_t g = static_cast(rand.Integer(255)); + Int_t b = static_cast(rand.Integer(255)); + color = TColor::GetColor(r, g, b); fColorList.push_back(color); } @@ -226,7 +232,13 @@ PFourierCanvas::PFourierCanvas(std::vector &fourier, PIntVector dataS } for (UInt_t i=static_cast(fColorList.size()); i(rand.Integer(255)), static_cast(rand.Integer(255)), static_cast(rand.Integer(255))); + // the rgb values need to be drawn into separate variables first: the evaluation order of + // function arguments is unspecified in C++, hence calling rand.Integer() three times within + // the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = static_cast(rand.Integer(255)); + Int_t g = static_cast(rand.Integer(255)); + Int_t b = static_cast(rand.Integer(255)); + color = TColor::GetColor(r, g, b); fColorList.push_back(color); } diff --git a/src/classes/PMusrCanvas.cpp b/src/classes/PMusrCanvas.cpp index 58a6ab1d..acf5a357 100644 --- a/src/classes/PMusrCanvas.cpp +++ b/src/classes/PMusrCanvas.cpp @@ -1527,7 +1527,7 @@ void PMusrCanvas::WindowClosed() * \param fileName file name under which the canvas shall be saved. * \param graphicsFormat One of the supported graphics formats. */ -void PMusrCanvas::SaveGraphicsAndQuit(Char_t *fileName, Char_t *graphicsFormat) +void PMusrCanvas::SaveGraphicsAndQuit(const Char_t *fileName, const Char_t *graphicsFormat) { std::cout << std::endl << ">> SaveGraphicsAndQuit: will dump the canvas into a graphics output file (" << graphicsFormat << ") ..."<< std::endl; @@ -2925,7 +2925,13 @@ void PMusrCanvas::HandleDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data) dataHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); - Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); + // the rgb values need to be drawn into separate variables first: the evaluation order of + // function arguments is unspecified in C++, hence calling rand.Integer() three times within + // the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = (Int_t)rand.Integer(255); + Int_t g = (Int_t)rand.Integer(255); + Int_t b = (Int_t)rand.Integer(255); + Int_t color = TColor::GetColor(r, g, b); dataHisto->SetMarkerColor(color); dataHisto->SetLineColor(color); } @@ -3058,7 +3064,13 @@ void PMusrCanvas::HandleDataSet(UInt_t plotNo, UInt_t runNo, PRunData *data) theoHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); - Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); + // the rgb values need to be drawn into separate variables first: the evaluation order of + // function arguments is unspecified in C++, hence calling rand.Integer() three times within + // the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = (Int_t)rand.Integer(255); + Int_t g = (Int_t)rand.Integer(255); + Int_t b = (Int_t)rand.Integer(255); + Int_t color = TColor::GetColor(r, g, b); theoHisto->SetLineColor(color); } @@ -3108,7 +3120,13 @@ void PMusrCanvas::HandleNonMusrDataSet(UInt_t plotNo, UInt_t runNo, PRunData *da dataHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); - Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); + // the rgb values need to be drawn into separate variables first: the evaluation order of + // function arguments is unspecified in C++, hence calling rand.Integer() three times within + // the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = (Int_t)rand.Integer(255); + Int_t g = (Int_t)rand.Integer(255); + Int_t b = (Int_t)rand.Integer(255); + Int_t color = TColor::GetColor(r, g, b); dataHisto->SetMarkerColor(color); dataHisto->SetLineColor(color); } @@ -3138,7 +3156,13 @@ void PMusrCanvas::HandleNonMusrDataSet(UInt_t plotNo, UInt_t runNo, PRunData *da theoHisto->SetLineColor(fColorList[plotNo]); } else { TRandom rand(plotNo); - Int_t color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); + // the rgb values need to be drawn into separate variables first: the evaluation order of + // function arguments is unspecified in C++, hence calling rand.Integer() three times within + // the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = (Int_t)rand.Integer(255); + Int_t g = (Int_t)rand.Integer(255); + Int_t b = (Int_t)rand.Integer(255); + Int_t color = TColor::GetColor(r, g, b); theoHisto->SetLineColor(color); } diff --git a/src/dump_header.cpp b/src/dump_header.cpp index 7561ca75..1897c33d 100644 --- a/src/dump_header.cpp +++ b/src/dump_header.cpp @@ -611,10 +611,10 @@ int dump_header_mud(const std::string fileName, const bool counts) char str[1024]; int success; - char fln[256]; - memset(fln, '\0', sizeof(fln)); - strncpy(fln, fileName.c_str(), sizeof(fln)); - fh = MUD_openRead(fln, &type); + // MUD_openRead() takes a non-const char*, hence the mutable copy. It must not + // be a fixed size buffer: paths longer than its size would silently truncate. + std::string fln(fileName); + fh = MUD_openRead(fln.data(), &type); if (fh == -1) { std::cerr << std::endl << "**ERROR** Couldn't open mud-file " << fileName << ", sorry." << std::endl; return 1; @@ -1019,20 +1019,19 @@ int main(int argc, char *argv[]) // invoke the startup handler in order to get the default search paths to the data files // read startup file - char startup_path_name[128]; - memset(startup_path_name, '\0', sizeof(startup_path_name)); + std::string startup_path_name{}; std::unique_ptr saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(); if (!startupHandler->StartupFileFound()) { std::cerr << std::endl << ">> musrfit **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - strncpy(startup_path_name, startupHandler->GetStartupFilePath().Data(), sizeof(startup_path_name)); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - int status = parseXmlFile(saxParser.get(), startup_path_name); + int status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> musrfit **WARNING** Reading/parsing musrfit_startup.xml failed."; diff --git a/src/include/PMusrCanvas.h b/src/include/PMusrCanvas.h index 497d5ea2..78a31db2 100644 --- a/src/include/PMusrCanvas.h +++ b/src/include/PMusrCanvas.h @@ -350,7 +350,7 @@ class PMusrCanvas : public TObject, public TQObject virtual void WindowClosed(); // SLOT /// Saves canvas to graphics file and emits Done signal - virtual void SaveGraphicsAndQuit(Char_t *fileName, Char_t *graphicsFormat); + virtual void SaveGraphicsAndQuit(const Char_t *fileName, const Char_t *graphicsFormat); /// Exports displayed data to ASCII file virtual void ExportData(const Char_t *fileName); diff --git a/src/msr2msr.cpp b/src/msr2msr.cpp index 6852485c..30b8eca9 100644 --- a/src/msr2msr.cpp +++ b/src/msr2msr.cpp @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include @@ -388,7 +390,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) * * \param str msr-file line */ -bool msr2msr_is_comment(char *str) +bool msr2msr_is_comment(const char *str) { bool isComment = false; @@ -417,7 +419,7 @@ bool msr2msr_is_comment(char *str) * * \param str msr-file line */ -bool msr2msr_is_whitespace(char *str) +bool msr2msr_is_whitespace(const char *str) { bool isWhitespace = true; @@ -440,29 +442,25 @@ bool msr2msr_is_whitespace(char *str) * \param str msr-file line * \param paramNo parameter number */ -void msr2msr_replace(char *str, int paramNo) +void msr2msr_replace(std::string &str, int paramNo) { - char temp[128]; - char no[16]; + const std::string no{std::to_string(paramNo)}; - memset(temp, 0, sizeof(temp)); + // build the result in a std::string: the previous fixed size scratch buffer + // overflowed for msr-lines longer than its size. + std::string temp; + temp.reserve(str.length()); - snprintf(no, sizeof(no), "%d", paramNo); - - int j=0; - for (unsigned int i=0; i parameter number + temp += no; i += 2; } } - strcpy(str, temp); + str = temp; } //-------------------------------------------------------------------------- @@ -494,25 +492,23 @@ bool msr2msr_finalize_theory(char *fln, int theoryTag, int noOfAddionalParams) return 0; } - char str[256]; + std::string str; int tag = -1; bool success = true; int param = 0; int count = 0; - while (!fin.eof() && success) { - fin.getline(str, sizeof(str)); - - if (strstr(str, "FITPARAMETER")) { + while (std::getline(fin, str) && success) { + if (str.find("FITPARAMETER") != std::string::npos) { tag = MSR_TAG_FITPARAMETER; - } else if (strstr(str, "THEORY")) { + } else if (str.find("THEORY") != std::string::npos) { tag = MSR_TAG_THEORY; } - if ((tag == MSR_TAG_FITPARAMETER) && !strstr(str, "FITPARAMETER")) { + if ((tag == MSR_TAG_FITPARAMETER) && (str.find("FITPARAMETER") == std::string::npos)) { if ((theoryTag == MSR_THEORY_INTERN_FLD) || (theoryTag == MSR_THEORY_INTERN_BESSEL)) { - if (!msr2msr_is_comment(str)) { + if (!msr2msr_is_comment(str.c_str())) { param++; - if (msr2msr_is_whitespace(str)) { + if (msr2msr_is_whitespace(str.c_str())) { // add needed parameters for (int i=0; i " << fln << ": " << ec.message() << std::endl; return false; } - // rm __temp.msr - strcpy(str, "rm __temp.msr"); - if (system(str) == -1) { - std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl; + std::filesystem::remove(std::filesystem::path("__temp.msr"), ec); + if (ec) { + std::cerr << "**ERROR** couldn't remove __temp.msr: " << ec.message() << std::endl; return false; } @@ -677,9 +676,10 @@ int main(int argc, char *argv[]) // check if conversion seems to be OK if (!success) { - snprintf(str, sizeof(str), "rm -rf %s", argv[2]); - if (system(str) == -1) { - std::cerr << "**ERROR** cmd: " << str << " failed." << std::endl; + std::error_code ec; + std::filesystem::remove_all(std::filesystem::path(argv[2]), ec); + if (ec) { + std::cerr << "**ERROR** couldn't remove " << argv[2] << ": " << ec.message() << std::endl; return 0; } } diff --git a/src/musrFT.cpp b/src/musrFT.cpp index ae8f9e5f..6482110a 100644 --- a/src/musrFT.cpp +++ b/src/musrFT.cpp @@ -1020,7 +1020,7 @@ Int_t main(Int_t argc, Char_t *argv[]) } // read startup file - Char_t startup_path_name[128]; + std::string startup_path_name{}; PStartupOptions startup_options; startup_options.writeExpectedChisq = false; startup_options.estimateN0 = true; @@ -1030,12 +1030,12 @@ Int_t main(Int_t argc, Char_t *argv[]) std::cerr << std::endl << ">> musrFT **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - strcpy(startup_path_name, startupHandler->GetStartupFilePath().Data()); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - status = parseXmlFile(saxParser.get(), startup_path_name); + status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> musrFT **WARNING** Reading/parsing musrfit_startup.xml failed."; diff --git a/src/musredit_qt5/mupp/plotter/PMuppCanvas.cpp b/src/musredit_qt5/mupp/plotter/PMuppCanvas.cpp index 4c685fd7..51121707 100644 --- a/src/musredit_qt5/mupp/plotter/PMuppCanvas.cpp +++ b/src/musredit_qt5/mupp/plotter/PMuppCanvas.cpp @@ -537,7 +537,13 @@ void PMuppCanvas::UpdateGraphs() gg->SetFillColor(kWhite); } else { // random choise of the color TRandom rand(i+j+k); - color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); + // the rgb values need to be drawn into separate variables first: the evaluation order + // of function arguments is unspecified in C++, hence calling rand.Integer() three times + // within the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = (Int_t)rand.Integer(255); + Int_t g = (Int_t)rand.Integer(255); + Int_t b = (Int_t)rand.Integer(255); + color = TColor::GetColor(r, g, b); gg->SetMarkerColor(color); gg->SetLineColor(color); gg->SetFillColor(kWhite); diff --git a/src/musredit_qt6/mupp/plotter/PMuppCanvas.cpp b/src/musredit_qt6/mupp/plotter/PMuppCanvas.cpp index 16aff557..91e06a12 100644 --- a/src/musredit_qt6/mupp/plotter/PMuppCanvas.cpp +++ b/src/musredit_qt6/mupp/plotter/PMuppCanvas.cpp @@ -591,7 +591,13 @@ void PMuppCanvas::UpdateGraphs() gg->SetFillColor(kWhite); } else { // random choise of the color TRandom rand(i+j+k); - color = TColor::GetColor((Int_t)rand.Integer(255), (Int_t)rand.Integer(255), (Int_t)rand.Integer(255)); + // the rgb values need to be drawn into separate variables first: the evaluation order + // of function arguments is unspecified in C++, hence calling rand.Integer() three times + // within the argument list would yield compiler dependent (r,g,b) permutations. + Int_t r = (Int_t)rand.Integer(255); + Int_t g = (Int_t)rand.Integer(255); + Int_t b = (Int_t)rand.Integer(255); + color = TColor::GetColor(r, g, b); gg->SetMarkerColor(color); gg->SetLineColor(color); gg->SetFillColor(kWhite); diff --git a/src/musrfit.cpp b/src/musrfit.cpp index ceaf781a..61185d49 100644 --- a/src/musrfit.cpp +++ b/src/musrfit.cpp @@ -37,7 +37,7 @@ #include #include -//#include +#include #include #include #include @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -188,7 +189,7 @@ void musrfit_write_ascii(TString fln, PRunData *data, int runCounter) * \param fileName file name * \param runList run list collection handler */ -void musrfit_dump_ascii(char *fileName, PRunListCollection *runList) +void musrfit_dump_ascii(const char *fileName, PRunListCollection *runList) { TString fln(fileName); fln.ReplaceAll(".msr", ".dat"); @@ -331,7 +332,7 @@ void musrfit_write_root(TFile &f, TString fln, PRunData *data, int runCounter) * \param fileName file name * \param runList run list connection handler */ -void musrfit_dump_root(char *fileName, PRunListCollection *runList) +void musrfit_dump_root(const char *fileName, PRunListCollection *runList) { TString fln(fileName); fln.ReplaceAll(".msr", ".root"); @@ -508,7 +509,7 @@ int main(int argc, char *argv[]) #endif TString dump(""); - char filename[1024]; + std::string filename{}; // add default shared library path /usr/local/lib if not already persent const char *dsp = gSystem->GetDynamicPath(); @@ -524,11 +525,9 @@ int main(int argc, char *argv[]) } } - memset(filename, '\0', sizeof(filename)); - strcpy(filename, ""); for (int i=1; i> musrfit **ERROR** no msr-file present!" << std::endl; } @@ -643,7 +642,7 @@ int main(int argc, char *argv[]) } // read startup file - char startup_path_name[128]; + std::string startup_path_name{}; std::unique_ptr saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(reset_startup_file); if (reset_startup_file) // only rewrite musrfit_startup.xml has been requested @@ -652,13 +651,12 @@ int main(int argc, char *argv[]) std::cerr << std::endl << ">> musrfit **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - memset(startup_path_name, '\0', sizeof(startup_path_name)); - strncpy(startup_path_name, startupHandler->GetStartupFilePath().Data(), sizeof(startup_path_name)); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - status = parseXmlFile(saxParser.get(), startup_path_name); + status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> musrfit **WARNING** Reading/parsing musrfit_startup.xml failed."; @@ -674,9 +672,9 @@ int main(int argc, char *argv[]) // read msr-file std::unique_ptr msrHandler; if (startupHandler) - msrHandler = std::make_unique(filename, &startup_options); + msrHandler = std::make_unique(filename.c_str(), &startup_options); else - msrHandler = std::make_unique(filename); + msrHandler = std::make_unique(filename.c_str()); status = msrHandler->ReadMsrFile(); if (status != PMUSR_SUCCESS) { switch (status) { @@ -796,9 +794,9 @@ int main(int argc, char *argv[]) std::cout << std::endl << "will write dump file ..." << std::endl; dump.ToLower(); if (dump.Contains("ascii")) - musrfit_dump_ascii(filename, runListCollection.get()); + musrfit_dump_ascii(filename.c_str(), runListCollection.get()); else if (dump.Contains("root")) - musrfit_dump_root(filename, runListCollection.get()); + musrfit_dump_root(filename.c_str(), runListCollection.get()); else std::cout << std::endl << "do not know format " << dump.Data() << ", sorry :-| " << std::endl; } @@ -807,16 +805,13 @@ int main(int argc, char *argv[]) if (success) { if (keep_mn2_output && !chisq_only && !fitter->IsScanOnly()) { // 1st rename MINUIT2.OUTPUT - TString fln = TString(filename); - char ext[32]; - strcpy(ext, "-mn2.output"); - fln.ReplaceAll(".msr", 4, ext, strlen(ext)); + TString fln = TString(filename.c_str()); + fln.ReplaceAll(".msr", "-mn2.output"); gSystem->CopyFile("MINUIT2.OUTPUT", fln.Data(), kTRUE); // 2nd rename MINUIT2.ROOT - fln = TString(filename); - strcpy(ext, "-mn2.root"); - fln.ReplaceAll(".msr", 4, ext, strlen(ext)); + fln = TString(filename.c_str()); + fln.ReplaceAll(".msr", "-mn2.root"); gSystem->CopyFile("MINUIT2.root", fln.Data(), kTRUE); } } @@ -826,13 +821,11 @@ int main(int argc, char *argv[]) // swap msr- and mlog-file std::cout << std::endl << ">> swapping msr-, mlog-file ..." << std::endl; // copy msr-file -> __temp.msr - gSystem->CopyFile(filename, "__temp.msr", kTRUE); + gSystem->CopyFile(filename.c_str(), "__temp.msr", kTRUE); // copy mlog-file -> msr-file - TString fln = TString(filename); - char ext[32]; - strcpy(ext, ".mlog"); - fln.ReplaceAll(".msr", 4, ext, strlen(ext)); - gSystem->CopyFile(fln.Data(), filename, kTRUE); + TString fln = TString(filename.c_str()); + fln.ReplaceAll(".msr", ".mlog"); + gSystem->CopyFile(fln.Data(), filename.c_str(), kTRUE); // copy __temp.msr -> mlog-file gSystem->CopyFile("__temp.msr", fln.Data(), kTRUE); // delete __temp.msr diff --git a/src/musrt0.cpp b/src/musrt0.cpp index f75bb55a..0f6a8909 100644 --- a/src/musrt0.cpp +++ b/src/musrt0.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -181,7 +182,7 @@ Int_t main(Int_t argc, Char_t *argv[]) Bool_t show_syntax = false; Int_t status; Bool_t success = true; - Char_t filename[1024]; + std::string filename{}; Bool_t getT0FromPromptPeak = false; Bool_t firstGoodBinOffsetPresent = false; Int_t firstGoodBinOffset = 0; @@ -198,7 +199,6 @@ Int_t main(Int_t argc, Char_t *argv[]) if (strstr(dsp, "/usr/local/lib") == nullptr) gSystem->AddDynamicPath("/usr/local/lib"); - memset(filename, '\0', sizeof(filename)); for (int i=1; iGetDynamicPath() << "'" << std::endl << std::endl; return PMUSR_SUCCESS; } else if (strstr(argv[i], ".msr")) { // check for filename - if (strlen(filename) == 0) { - strncpy(filename, argv[i], sizeof(filename)); + if (filename.empty()) { + filename = argv[i]; } else { std::cout << std::endl << "**ERROR** only one file name allowed." << std::endl; show_syntax = true; @@ -262,7 +262,7 @@ Int_t main(Int_t argc, Char_t *argv[]) } } - if (strlen(filename) == 0) { + if (filename.empty()) { std::cout << std::endl << "**ERROR** msr-file missing!" << std::endl; show_syntax = true; } @@ -273,19 +273,19 @@ Int_t main(Int_t argc, Char_t *argv[]) } // read startup file - Char_t startup_path_name[128]; + std::string startup_path_name{}; std::unique_ptr saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(); if (!startupHandler->StartupFileFound()) { std::cerr << std::endl << ">> musrt0 **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - strcpy(startup_path_name, startupHandler->GetStartupFilePath().Data()); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - status = parseXmlFile(saxParser.get(), startup_path_name); + status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> musrt0 **WARNING** Reading/parsing musrfit_startup.xml failed."; @@ -294,7 +294,7 @@ Int_t main(Int_t argc, Char_t *argv[]) } // read msr-file - std::unique_ptr msrHandler = std::make_unique(filename); + std::unique_ptr msrHandler = std::make_unique(filename.c_str()); status = msrHandler->ReadMsrFile(); if (status != PMUSR_SUCCESS) { switch (status) { @@ -1165,14 +1165,11 @@ Int_t main(Int_t argc, Char_t *argv[]) // swap msr- and mlog-file // copy msr-file -> __temp.msr - gSystem->CopyFile(filename, "__temp.msr", kTRUE); + gSystem->CopyFile(filename.c_str(), "__temp.msr", kTRUE); // copy mlog-file -> msr-file - TString fln = TString(filename); - Char_t ext[32]; - memset(ext, '\0', sizeof(ext)); - strncpy(ext, ".mlog", sizeof(ext)); - fln.ReplaceAll(".msr", 4, ext, strlen(ext)); - gSystem->CopyFile(fln.Data(), filename, kTRUE); + TString fln = TString(filename.c_str()); + fln.ReplaceAll(".msr", ".mlog"); + gSystem->CopyFile(fln.Data(), filename.c_str(), kTRUE); // copy __temp.msr -> mlog-file gSystem->CopyFile("__temp.msr", fln.Data(), kTRUE); // delete __temp.msr diff --git a/src/musrview.cpp b/src/musrview.cpp index 18a60151..2f629414 100644 --- a/src/musrview.cpp +++ b/src/musrview.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -123,20 +124,17 @@ int main(int argc, char *argv[]) bool show_syntax{false}; int status; bool success{true}; - char fileName[128]; + std::string fileName{}; bool fourier{false}; bool avg{false}; bool theoAtData{false}; // theory points only at data points bool graphicsOutput{false}; bool asciiOutput{false}; - char graphicsExtension[128]; + std::string graphicsExtension{}; int timeout{0}; bool show_errMsgBox{false}; std::stringstream errMsg; - memset(fileName, '\0', sizeof(fileName)); - memset(graphicsExtension, '\0', sizeof(graphicsExtension)); - // add default shared library path /usr/local/lib if not already persent const char *dsp = gSystem->GetDynamicPath(); if (strstr(dsp, "/usr/local/lib") == nullptr) @@ -149,8 +147,8 @@ int main(int argc, char *argv[]) } for (int i=1; i saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(); if (!startupHandler->StartupFileFound()) { std::cerr << std::endl << ">> musrview **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { - strncpy(startup_path_name, startupHandler->GetStartupFilePath().Data(), sizeof(startup_path_name)); + startup_path_name = startupHandler->GetStartupFilePath().Data(); saxParser->ConnectToHandler("PStartupHandler", startupHandler.get()); //status = saxParser->ParseFile(startup_path_name); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition) - status = parseXmlFile(saxParser.get(), startup_path_name); + status = parseXmlFile(saxParser.get(), startup_path_name.c_str()); // check for parse errors if (status) { // error std::cerr << std::endl << ">> musrview **WARNING** Reading/parsing musrfit_startup.xml failed."; @@ -245,7 +242,7 @@ int main(int argc, char *argv[]) } // read msr-file - std::unique_ptr msrHandler = std::make_unique(fileName); + std::unique_ptr msrHandler = std::make_unique(fileName.c_str()); status = msrHandler->ReadMsrFile(); if (status != PMUSR_SUCCESS) { errMsg << msrHandler->GetLastErrorMsg(); @@ -402,12 +399,12 @@ int main(int argc, char *argv[]) musrCanvas->Connect("Done(Int_t)", "TApplication", &app, "Terminate(Int_t)"); if (graphicsOutput) { - musrCanvas->SaveGraphicsAndQuit(fileName, graphicsExtension); + musrCanvas->SaveGraphicsAndQuit(fileName.c_str(), graphicsExtension.c_str()); } if (asciiOutput) { // generate export data file name - TString str(fileName); + TString str(fileName.c_str()); str.Remove(str.Last('.')); str += ".dat"; // save data in batch mode diff --git a/tests/musrview_check/musrview_check.py b/tests/musrview_check/musrview_check.py index d09c0d3a..bde71bed 100644 --- a/tests/musrview_check/musrview_check.py +++ b/tests/musrview_check/musrview_check.py @@ -21,7 +21,6 @@ import os import shutil import subprocess import sys -import tempfile import time @@ -76,36 +75,56 @@ def main(): msr_basename = os.path.splitext(os.path.basename(args.msr_file))[0] ref_subdir = os.path.join(args.ref_dir, args.test_name) - # ---- run musrview in a temporary directory ------------------------------- + # ---- run musrview -------------------------------------------------------- + # musrview always writes its PNGs next to the msr-file, so the test has to + # run there and clean up after itself. work_dir = os.path.dirname(os.path.abspath(args.msr_file)) - with tempfile.TemporaryDirectory() as tmp_dir: - # snapshot existing PNGs so we only pick up newly created ones - pre_existing = set(glob.glob(os.path.join(work_dir, f"{msr_basename}_*.png"))) + png_glob = os.path.join(work_dir, f"{msr_basename}_*.png") + # Snapshot the PNGs that are already there together with their mtimes. A PNG + # counts as produced by this run if it is either new, or pre-existing but + # rewritten (a leftover from an earlier aborted run -- musrview simply + # overwrites it). Matching on mtime rather than mere existence keeps stale + # leftovers from masking the real output, while still ignoring the PNGs of a + # sibling test running concurrently on the same msr-file. + pre_existing = {p: os.stat(p).st_mtime_ns for p in glob.glob(png_glob)} + + generated = [] + + def collect(): + """Return the PNGs in work_dir that this musrview run created/rewrote.""" + found = [] + for p in glob.glob(png_glob): + if pre_existing.get(p) != os.stat(p).st_mtime_ns: + found.append(p) + return sorted(found) + + def cleanup(): + """Remove everything this run produced -- must happen on every exit path, + otherwise the leftovers pile up in doc/examples.""" + for png in generated: + try: + os.remove(png) + except OSError: + pass + + try: cmd = [args.musrview, args.msr_file, "--png"] + musrview_opts print(f"running: {' '.join(cmd)}") - result = subprocess.run(cmd, capture_output=True, text=True, - cwd=work_dir, - env={**os.environ, "MUSRVIEW_PNG_DIR": tmp_dir}) + result = subprocess.run(cmd, capture_output=True, text=True, cwd=work_dir) if result.returncode != 0: + generated = collect() print(f"**ERROR** musrview returned exit code {result.returncode}") print(result.stdout + result.stderr) return 1 - # collect only newly created PNGs (exclude pre-existing ones). # musrview has already exited by the time subprocess.run() returns, but on # some systems the PNG file's directory entry becomes visible to this # process only after a further delay (observed running under ctest, up to # several seconds) -- poll for a while instead of failing on the first # empty glob. - generated = [] for _ in range(150): - generated = sorted( - p for p in glob.glob(os.path.join(work_dir, f"{msr_basename}_*.png")) - if p not in pre_existing - ) - if not generated: - generated = sorted(glob.glob(os.path.join(tmp_dir, f"{msr_basename}_*.png"))) + generated = collect() if generated: break time.sleep(0.1) @@ -123,10 +142,6 @@ def main(): dst = os.path.join(ref_subdir, os.path.basename(png)) shutil.copy2(png, dst) print(f" saved reference: {dst}") - # clean up generated PNGs from work_dir - for png in generated: - if os.path.dirname(os.path.abspath(png)) == os.path.abspath(work_dir): - os.remove(png) print(f"GENERATE: {len(generated)} reference PNG(s) written to {ref_subdir}") return 0 @@ -153,11 +168,6 @@ def main(): else: print(f"PASS: {name} diff={diff:.6f} <= tol={args.tol:.6f}") - # clean up generated PNGs from work_dir - for png in generated: - if os.path.dirname(os.path.abspath(png)) == os.path.abspath(work_dir): - os.remove(png) - if compared == 0: print("**ERROR** no PNGs were compared") return 1 @@ -168,6 +178,8 @@ def main(): print(f"\nAll {compared} PNG(s) PASSED (tol={args.tol})") return 0 + finally: + cleanup() if __name__ == "__main__": diff --git a/tests/musrview_check/ref/musrview-histo-HAL9500/test-histo-HAL9500_0.png b/tests/musrview_check/ref/musrview-histo-HAL9500/test-histo-HAL9500_0.png index 7b1627be9287d9e79f9a024d7a11ef20c1375c2d..74d94c8c62b45c40d3145f9fa14177cb83688648 100644 GIT binary patch literal 36130 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