From 9ef1d60596517791cc9822f295e256f3675244da Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Tue, 30 Jul 2024 17:43:38 +0200 Subject: [PATCH 1/9] G4tgrFileIn: added some preprocessor-like conditionals --- .../persistency/ascii/include/G4tgrFileIn.hh | 6 + source/persistency/ascii/src/G4tgrFileIn.cc | 124 ++++++++++++++++++ 2 files changed, 130 insertions(+) diff --git a/source/persistency/ascii/include/G4tgrFileIn.hh b/source/persistency/ascii/include/G4tgrFileIn.hh index 84dcb82de02..3ef100b7827 100644 --- a/source/persistency/ascii/include/G4tgrFileIn.hh +++ b/source/persistency/ascii/include/G4tgrFileIn.hh @@ -35,6 +35,7 @@ #define G4tgrFileIn_hh 1 #include +#include #include "globals.hh" @@ -60,6 +61,7 @@ class G4tgrFileIn // Access data members G4int Nline() { return theLineNo[theCurrentFile]; } + G4bool IgnoreLine() const { return ignoreLine; } const G4String& GetName() { return theName; } @@ -81,6 +83,10 @@ class G4tgrFileIn std::vector theNames; + std::map theMacros; + + G4bool ignoreLine = false; + G4int theCurrentFile = -1; // Index of file being read in theFiles diff --git a/source/persistency/ascii/src/G4tgrFileIn.cc b/source/persistency/ascii/src/G4tgrFileIn.cc index 1b655583c61..2d87c65fb2c 100644 --- a/source/persistency/ascii/src/G4tgrFileIn.cc +++ b/source/persistency/ascii/src/G4tgrFileIn.cc @@ -367,6 +367,130 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) OpenNewFile(wordlist[1].c_str()); isok = GetWordsInLine(wordlist); } + // check for 'define' + else if(wordlist[0] == "#define") + { + if(wordlist.size() != 2 && wordlist.size() != 3) + { + ErrorInLine(); + G4String ErrMessage = + "'#define' should have one or two arguments (macro name, [macro body])!"; + G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput", + FatalException, ErrMessage); + } + +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - Define found !" << G4endl; + } +#endif + G4String macroBody; + if(wordlist.size() == 3) + { + macroBody = wordlist[2]; + wordlist.pop_back(); + } + theMacros[wordlist[1]] = macroBody; + wordlist.pop_back(); + wordlist.pop_back(); + } + // check for 'undef' + else if(wordlist[0] == "#undef") + { + if(wordlist.size() != 2) + { + ErrorInLine(); + G4String ErrMessage = + "'#undef' should have as second argument, the macro name !"; + G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput", + FatalException, ErrMessage); + } + +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - Undef found !" << G4endl; + } +#endif + theMacros.erase(wordlist[1]); + wordlist.pop_back(); + wordlist.pop_back(); + } + // check for 'ifdef' + else if(wordlist[0] == "#ifdef") + { + if(wordlist.size() != 2) + { + ErrorInLine(); + G4String ErrMessage = + "'#ifdef' should have as second argument, the macro name!"; + G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput", + FatalException, ErrMessage); + } + +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - Ifdef found !" << G4endl; + } +#endif + if (theMacros.find(wordlist[1]) == theMacros.end()) + ignoreLine = true; + else + ignoreLine = false; + wordlist.pop_back(); + wordlist.pop_back(); + } + // check for 'ifndef' + else if(wordlist[0] == "#ifndef") + { + if(wordlist.size() != 2) + { + ErrorInLine(); + G4String ErrMessage = + "'#ifndef' should have as second argument, the macro name!"; + G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput", + FatalException, ErrMessage); + } + +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - Ifndef found !" << G4endl; + } +#endif + if (theMacros.find(wordlist[1]) == theMacros.end()) + ignoreLine = false; + else + ignoreLine = true; + wordlist.pop_back(); + wordlist.pop_back(); + } + // check for 'else' + else if(wordlist[0] == "#else") + { +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - else found !" << G4endl; + } +#endif + ignoreLine = !ignoreLine; + wordlist.pop_back(); + } + // check for 'endif' + else if(wordlist[0] == "#endif") + { +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - endif found !" << G4endl; + } +#endif + ignoreLine = false; + wordlist.pop_back(); + } return isok; } From 8713aa3b8649ca5fb163cc03663812a100016790 Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Tue, 30 Jul 2024 17:44:37 +0200 Subject: [PATCH 2/9] G4tgrFileIn: added replacement of macro-expressions --- source/persistency/ascii/src/G4tgrFileIn.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/persistency/ascii/src/G4tgrFileIn.cc b/source/persistency/ascii/src/G4tgrFileIn.cc index 2d87c65fb2c..be56f11c3a2 100644 --- a/source/persistency/ascii/src/G4tgrFileIn.cc +++ b/source/persistency/ascii/src/G4tgrFileIn.cc @@ -342,6 +342,22 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) wordlist = wordlist2; + // check for macros + for (auto& w : wordlist) + { + auto it = theMacros.find(w); + if (it != theMacros.end()) + { +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - Replacing '" << w << "' by '" << (*it).second << "'" << G4endl; + } +#endif + w = (*it).second; + } + } + // Or why not like this (?): // typedef std::istream_iterator string_iter; // std::copy(string_iter(istr_line), string_iter(), back_inserter(wordlist)); From bbf930e57724b8659b176526679fb16c029340dd Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Tue, 30 Jul 2024 17:45:01 +0200 Subject: [PATCH 3/9] G4tgrFileReader: added skipping of ignored lines --- source/persistency/ascii/src/G4tgrFileReader.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/persistency/ascii/src/G4tgrFileReader.cc b/source/persistency/ascii/src/G4tgrFileReader.cc index 92982547dca..94783feac47 100644 --- a/source/persistency/ascii/src/G4tgrFileReader.cc +++ b/source/persistency/ascii/src/G4tgrFileReader.cc @@ -107,6 +107,8 @@ G4bool G4tgrFileReader::ReadFiles() { break; } + if (fin.IgnoreLine()) + continue; // Check if it is continuation line or first line if(wlnew[0].c_str()[0] != ':') { From 64a6424e52c8179b9a61ae55c0bec05b04b05af6 Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Wed, 31 Jul 2024 17:55:34 +0200 Subject: [PATCH 4/9] G4tgrLineProcessor: fixed crash by catching empty word lists --- source/persistency/ascii/src/G4tgrLineProcessor.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/persistency/ascii/src/G4tgrLineProcessor.cc b/source/persistency/ascii/src/G4tgrLineProcessor.cc index e3d34a7f6e3..c68f8e42337 100644 --- a/source/persistency/ascii/src/G4tgrLineProcessor.cc +++ b/source/persistency/ascii/src/G4tgrLineProcessor.cc @@ -67,6 +67,10 @@ G4bool G4tgrLineProcessor::ProcessLine(const std::vector& wl) } #endif + // ignore empty word list + if(!wl.size()) + return true; + G4String wl0 = wl[0]; for(G4int ii = 0; ii < (G4int)wl0.length(); ++ii) { From e41605a79bd09b92f87f3b9caf9de2cf0a7bf0a6 Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Wed, 31 Jul 2024 17:58:48 +0200 Subject: [PATCH 5/9] G4tgrFileIn: no macro replacements for empty macros and preproc-directives --- source/persistency/ascii/src/G4tgrFileIn.cc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/persistency/ascii/src/G4tgrFileIn.cc b/source/persistency/ascii/src/G4tgrFileIn.cc index be56f11c3a2..01fd8bfde25 100644 --- a/source/persistency/ascii/src/G4tgrFileIn.cc +++ b/source/persistency/ascii/src/G4tgrFileIn.cc @@ -342,19 +342,22 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) wordlist = wordlist2; - // check for macros - for (auto& w : wordlist) + // check for macro replacements (exclude # directives) + if (wordlist[0][0] != '#') { - auto it = theMacros.find(w); - if (it != theMacros.end()) + for (auto& w : wordlist) { -#ifdef G4VERBOSE - if(G4tgrMessenger::GetVerboseLevel() >= 3) + auto it = theMacros.find(w); + if (it != theMacros.end() && (*it).second != "") { - G4cout << " G4tgrFileIn::GetWordsInLine() - Replacing '" << w << "' by '" << (*it).second << "'" << G4endl; - } +#ifdef G4VERBOSE + if(G4tgrMessenger::GetVerboseLevel() >= 3) + { + G4cout << " G4tgrFileIn::GetWordsInLine() - Replacing '" << w << "' by '" << (*it).second << "'" << G4endl; + } #endif - w = (*it).second; + w = (*it).second; + } } } From e403048ce99b2f227445e5def882c1e0bd35b117 Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Wed, 31 Jul 2024 18:00:54 +0200 Subject: [PATCH 6/9] G4tgrFileIn: support for checking parameters in #ifdef and #ifndef --- source/persistency/ascii/src/G4tgrFileIn.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/source/persistency/ascii/src/G4tgrFileIn.cc b/source/persistency/ascii/src/G4tgrFileIn.cc index 01fd8bfde25..41fbf9b4d20 100644 --- a/source/persistency/ascii/src/G4tgrFileIn.cc +++ b/source/persistency/ascii/src/G4tgrFileIn.cc @@ -37,6 +37,7 @@ #include "G4tgrFileIn.hh" #include "G4tgrMessenger.hh" #include "G4tgrUtils.hh" +#include "G4tgrParameterMgr.hh" #include "G4UIcommand.hh" G4ThreadLocal std::vector* G4tgrFileIn::theInstances = nullptr; @@ -454,7 +455,12 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) G4cout << " G4tgrFileIn::GetWordsInLine() - Ifdef found !" << G4endl; } #endif - if (theMacros.find(wordlist[1]) == theMacros.end()) + G4bool macroFound = theMacros.find(wordlist[1]) != theMacros.end(); + G4bool paramFound = false; + if(wordlist[1][0] == '$') + paramFound = G4tgrParameterMgr::GetInstance()->FindParameter( + wordlist[1].substr(1, wordlist[1].size()), false) != ""; + if(!macroFound && !paramFound) ignoreLine = true; else ignoreLine = false; @@ -479,7 +485,12 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) G4cout << " G4tgrFileIn::GetWordsInLine() - Ifndef found !" << G4endl; } #endif - if (theMacros.find(wordlist[1]) == theMacros.end()) + G4bool macroFound = theMacros.find(wordlist[1]) != theMacros.end(); + G4bool paramFound = false; + if(wordlist[1][0] == '$') + paramFound = G4tgrParameterMgr::GetInstance()->FindParameter( + wordlist[1].substr(1, wordlist[1].size()), false) != ""; + if(!macroFound && !paramFound) ignoreLine = false; else ignoreLine = true; From ae06874e39aa1f18653c0c865c4e50520c7f94e4 Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Wed, 31 Jul 2024 18:03:49 +0200 Subject: [PATCH 7/9] G4tgrFileReader: code cosmetics --- source/persistency/ascii/src/G4tgrFileReader.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/persistency/ascii/src/G4tgrFileReader.cc b/source/persistency/ascii/src/G4tgrFileReader.cc index 94783feac47..7bf6ed91dae 100644 --- a/source/persistency/ascii/src/G4tgrFileReader.cc +++ b/source/persistency/ascii/src/G4tgrFileReader.cc @@ -107,7 +107,7 @@ G4bool G4tgrFileReader::ReadFiles() { break; } - if (fin.IgnoreLine()) + if(fin.IgnoreLine()) continue; // Check if it is continuation line or first line if(wlnew[0].c_str()[0] != ':') From c15ae121fc26d704ac304ab5bf89a4102ba51354 Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Wed, 7 Aug 2024 19:01:31 +0200 Subject: [PATCH 8/9] G4tgrFileIn: fixed bugs in original file --- source/persistency/ascii/src/G4tgrFileIn.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/persistency/ascii/src/G4tgrFileIn.cc b/source/persistency/ascii/src/G4tgrFileIn.cc index 41fbf9b4d20..912bf2dbd25 100644 --- a/source/persistency/ascii/src/G4tgrFileIn.cc +++ b/source/persistency/ascii/src/G4tgrFileIn.cc @@ -545,10 +545,7 @@ G4bool G4tgrFileIn::EndOfFile() } #endif --theCurrentFile; - if(theCurrentFile != -1) // Last file will be closed by the user - { - Close(); - } + Close(); } // Only real closing if all files are closed @@ -582,6 +579,7 @@ void G4tgrFileIn::Close() theFiles[theCurrentFile + 1]->close(); theFiles.pop_back(); + theNames.pop_back(); } // -------------------------------------------------------------------- From 6bf4b550898da12b90b47f1ba0f95063bc95285a Mon Sep 17 00:00:00 2001 From: Dominik Werthmueller Date: Wed, 7 Aug 2024 19:03:44 +0200 Subject: [PATCH 9/9] G4tgrFileIn: support for nested #if and block checking --- .../persistency/ascii/include/G4tgrFileIn.hh | 4 +- source/persistency/ascii/src/G4tgrFileIn.cc | 50 ++++++++++++++++--- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/source/persistency/ascii/include/G4tgrFileIn.hh b/source/persistency/ascii/include/G4tgrFileIn.hh index 3ef100b7827..825d9e91b01 100644 --- a/source/persistency/ascii/include/G4tgrFileIn.hh +++ b/source/persistency/ascii/include/G4tgrFileIn.hh @@ -61,7 +61,7 @@ class G4tgrFileIn // Access data members G4int Nline() { return theLineNo[theCurrentFile]; } - G4bool IgnoreLine() const { return ignoreLine; } + G4bool IgnoreLine() const; const G4String& GetName() { return theName; } @@ -85,7 +85,7 @@ class G4tgrFileIn std::map theMacros; - G4bool ignoreLine = false; + std::vector> ignoreLines; G4int theCurrentFile = -1; // Index of file being read in theFiles diff --git a/source/persistency/ascii/src/G4tgrFileIn.cc b/source/persistency/ascii/src/G4tgrFileIn.cc index 912bf2dbd25..292ec597dcc 100644 --- a/source/persistency/ascii/src/G4tgrFileIn.cc +++ b/source/persistency/ascii/src/G4tgrFileIn.cc @@ -107,6 +107,8 @@ void G4tgrFileIn::OpenNewFile(const char* filename) theNames.push_back(filename); + ignoreLines.push_back({}); + #ifndef OS_SUN_4_2 if(!fin->is_open()) { @@ -384,8 +386,16 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) G4cout << " G4tgrFileIn::GetWordsInLine() - Include found !" << G4endl; } #endif - OpenNewFile(wordlist[1].c_str()); - isok = GetWordsInLine(wordlist); + if(IgnoreLine()) + { + wordlist.pop_back(); + wordlist.pop_back(); + } + else + { + OpenNewFile(wordlist[1].c_str()); + isok = GetWordsInLine(wordlist); + } } // check for 'define' else if(wordlist[0] == "#define") @@ -461,9 +471,9 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) paramFound = G4tgrParameterMgr::GetInstance()->FindParameter( wordlist[1].substr(1, wordlist[1].size()), false) != ""; if(!macroFound && !paramFound) - ignoreLine = true; + ignoreLines.back().push_back(true); else - ignoreLine = false; + ignoreLines.back().push_back(false); wordlist.pop_back(); wordlist.pop_back(); } @@ -491,9 +501,9 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) paramFound = G4tgrParameterMgr::GetInstance()->FindParameter( wordlist[1].substr(1, wordlist[1].size()), false) != ""; if(!macroFound && !paramFound) - ignoreLine = false; + ignoreLines.back().push_back(false); else - ignoreLine = true; + ignoreLines.back().push_back(true); wordlist.pop_back(); wordlist.pop_back(); } @@ -506,7 +516,7 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) G4cout << " G4tgrFileIn::GetWordsInLine() - else found !" << G4endl; } #endif - ignoreLine = !ignoreLine; + ignoreLines.back().back() = !ignoreLines.back().back(); wordlist.pop_back(); } // check for 'endif' @@ -518,7 +528,13 @@ G4int G4tgrFileIn::GetWordsInLine(std::vector& wordlist) G4cout << " G4tgrFileIn::GetWordsInLine() - endif found !" << G4endl; } #endif - ignoreLine = false; + if(!ignoreLines.back().size()) + { + G4String ErrMessage = "#endif without if in file " + theNames[theCurrentFile]; + G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput", FatalException, + ErrMessage); + } + ignoreLines.back().pop_back(); wordlist.pop_back(); } @@ -532,6 +548,16 @@ void G4tgrFileIn::ErrorInLine() << " file: " << theNames[theCurrentFile] << " : "; } +// -------------------------------------------------------------------- +G4bool G4tgrFileIn::IgnoreLine() const +{ + if(std::find(ignoreLines.back().begin(), ignoreLines.back().end(), true) + != ignoreLines.back().end()) + return true; + else + return false; +} + // -------------------------------------------------------------------- G4bool G4tgrFileIn::EndOfFile() { @@ -577,6 +603,14 @@ void G4tgrFileIn::Close() } #endif + if(ignoreLines.back().size()) + { + G4String ErrMessage = "Missing #endif in file " + theNames[theCurrentFile + 1]; + G4Exception("G4tgrFileIn::Close()", "InvalidInput", FatalException, + ErrMessage); + } + ignoreLines.pop_back(); + theFiles[theCurrentFile + 1]->close(); theFiles.pop_back(); theNames.pop_back();