51#include <system_error>
53G4bool G4UImanager::doublePrecisionStr =
false;
54G4int G4UImanager::igThreadID = -1;
64G4bool& G4UImanager::fUImanagerHasBeenKilled()
80 if (fUImanager() ==
nullptr) {
81 if (!fUImanagerHasBeenKilled()) {
83 fUImanager()->CreateMessenger();
92 return fMasterUImanager();
101 commandStack =
new std::vector<G4String>;
105void G4UImanager::CreateMessenger()
115 if (bridges !=
nullptr) {
116 for (
auto bridge : *bridges) {
126 delete CoutMessenger;
127 delete UnitsMessenger;
131 fUImanagerHasBeenKilled() =
true;
132 fUImanager() =
nullptr;
133 if (commandStack !=
nullptr) {
134 commandStack->clear();
147 doublePrecisionStr = val;
153 return doublePrecisionStr;
160 savedCommand = treeTop->FindPath(theCommand);
161 if (savedCommand ==
nullptr) {
165 return savedCommand->GetCurrentValue();
172 if (reGet || savedCommand ==
nullptr) {
177 for (
G4int i_thParameter = 0; i_thParameter < parameterNumber; ++i_thParameter) {
178 token = savedToken();
182 if (token[(
size_t)0] ==
'"') {
184 token.append(savedToken(
"\""));
194 if (reGet || savedCommand ==
nullptr) {
197 for (
G4int i = 0; i < (
G4int)savedCommand->GetParameterEntries(); ++i) {
198 if (aParameterName == savedCommand->GetParameter(i)->GetParameterName()) {
211 const char* t = targetParameter;
212 std::istringstream is(t);
222 const char* t = targetParameter;
223 std::istringstream is(t);
234 const char* t = targetParameter;
235 std::istringstream is(t);
246 const char* t = targetParameter;
247 std::istringstream is(t);
255 treeTop->AddNewCommand(newCommand);
257 fMasterUImanager()->AddWorkerCommand(newCommand);
262void G4UImanager::AddWorkerCommand(
G4UIcommand* newCommand)
270 treeTop->RemoveCommand(aCommand);
272 fMasterUImanager()->RemoveWorkerCommand(aCommand);
277void G4UImanager::RemoveWorkerCommand(
G4UIcommand* aCommand)
286 session = batchSession;
291 session = previousSession;
303 c1 += parameterToken();
305 c1 += parameterToken();
307 std::istringstream is(t1);
311 is >> d1 >> d2 >> d3;
312 Loop(mf, vn, d1, d2, d3);
321 for (
G4double d = initialValue; d <= finalValue; d += stepSize) {
322 std::ostringstream os;
329 for (
G4double d = initialValue; d >= finalValue; d += stepSize) {
330 std::ostringstream os;
336 Foreach(macroFile, variableName, cd);
344 const G4String& mf = parameterToken();
345 const G4String& vn = parameterToken();
348 while (!((ca = parameterToken()).empty())) {
353 G4String aliasValue = std::move(c1);
354 if (aliasValue[0] ==
'"') {
356 if (aliasValue.back() ==
'"') {
357 strippedValue = aliasValue.substr(1, aliasValue.length() - 2);
360 strippedValue = aliasValue.substr(1, aliasValue.length() - 1);
362 aliasValue = std::move(strippedValue);
372 G4String candidatesString = candidates;
375 while (!((cd = parameterToken()).empty())) {
383 ed <<
"Loop aborted due to a command execution error - "
384 <<
"error code " << lastRC;
395 std::size_t ia = aCommand.find(
'{');
396 std::size_t iz = aCommand.find(
'#');
397 while ((ia != std::string::npos) && ((iz == std::string::npos) || (ia < iz))) {
400 std::size_t ib = aCommand.find(
'}');
401 if (ib == std::string::npos) {
403 for (std::size_t i = 0; i < ia; ++i) {
407 G4cerr <<
"Unmatched alias parenthesis -- command ignored" <<
G4endl;
411 G4String ps = aCommand.substr(ia + 1, aCommand.length() - (ia + 1));
412 std::size_t ic = ps.find(
'{');
413 std::size_t
id = ps.find(
'}');
414 if (ic != std::string::npos && ic <
id) {
425 subs = aCommand.substr(0, ia);
427 G4String alis = aCommand.substr(ia + 1, ibx - ia - 1);
428 G4String rems = aCommand.substr(ibx + 1, aCommand.length() - ibx);
429 const G4String* alVal = aliasList->FindAlias(alis);
430 if (alVal ==
nullptr) {
431 G4cerr <<
"Alias <" << alis <<
"> not found -- command ignored" <<
G4endl;
435 aCommand = subs + (*alVal) + rems;
436 ia = aCommand.find(
'{');
455 if (aCommand.empty()) {
459 if (verboseLevel != 0) {
461 fLastCommandOutputTreated =
false;
468 std::size_t iAt = aCommand.find(
'@');
469 if (iAt != std::string::npos) {
470 G4String commandStr1 = aCommand.substr(0,iAt);
471 G4String commandStr2 = aCommand.substr(iAt+1,aCommand.length() - (iAt + 1));
472 std::size_t iAt2 = commandStr2.find(
'@');
475 if (iAt2 != std::string::npos) {
478 tmpFileName =
"tmptmp_";
480 tmpFileName +=
".tmpmac";
483 tmpFileName = commandStr2.substr(0,iAt2);
488 G4String commandStr3 = commandStr2.substr(iAt2+1,commandStr2.length()-(iAt2+1));
489 G4String revisedCommand = commandStr1;
490 revisedCommand +=
" ";
491 revisedCommand += tmpFileName;
492 revisedCommand +=
" ";
493 revisedCommand += commandStr3;
498 std::size_t i = aCommand.find(
' ');
499 if (i != std::string::npos) {
500 commandString = aCommand.substr(0, i);
501 commandParameter = aCommand.substr(i + 1, aCommand.length() - (i + 1));
504 commandString = aCommand;
508 std::size_t len = commandString.length();
512 while (ll < len - 1) {
513 if (commandString.substr(ll, 2) ==
"//") {
516 commandString.erase(ll, 1);
519 a1 = commandString.substr(0, ll);
520 a2 = commandString.substr(ll + 1, len - ll - 1);
521 commandString = a1 + a2;
530 if (isMaster && bridges !=
nullptr) {
531 for (
auto bridge : *bridges) {
532 G4int leng = bridge->DirLength();
533 if (commandString.substr(0, leng) == bridge->DirName()) {
534 return bridge->LocalUI()->ApplyCommand(commandString +
" " + commandParameter);
539 G4UIcommand* targetCommand = treeTop->FindPath(commandString);
540 if (targetCommand ==
nullptr) {
541 if (ignoreCmdNotFound) {
542 if (stackCommandsForBroadcast) {
543 commandStack->push_back(commandString +
" " + commandParameter);
552 commandStack->push_back(commandString +
" " + commandParameter);
560 historyFile << aCommand <<
G4endl;
562 if (
G4int(histVec.size()) >= maxHistSize) {
563 histVec.erase(histVec.begin());
565 histVec.push_back(aCommand);
567 if(fRecordDepth>=0) {
568 if(aCommand ==
"/control/endRecord") {
571 }
else if(commandString !=
"/control/recordToMacro") {
578 G4int commandFailureCode = targetCommand->
DoIt(commandParameter);
579 if (commandFailureCode == 0) {
581 if (additionalFailureCode > 0) {
584 <<
"Error code : " << additionalFailureCode;
586 commandFailureCode += additionalFailureCode;
589 return commandFailureCode;
602 if (aCommand.empty()) {
608 std::size_t i = aCommand.find(
' ');
609 if (i != std::string::npos) {
610 commandString = aCommand.substr(0, i);
613 commandString = aCommand;
616 return treeTop->FindPath(commandString);
632 historyFile.open((
char*)fileName);
639 saveHistory = historySwitch;
643void G4UImanager::PauseSession(
const char* msg)
646 session->PauseSessionStart(msg);
654 if (comTree !=
nullptr) {
667 if (targetDir.back() !=
'/') {
670 G4UIcommandTree* comTree = treeTop;
671 if (targetDir ==
"/") {
675 while (idx < targetDir.length() - 1) {
676 std::size_t i = targetDir.find(
'/', idx);
677 G4String targetDirString = targetDir.substr(0, i + 1);
678 comTree = comTree->
GetTree(targetDirString);
679 if (comTree ==
nullptr) {
690 if (pauseAtBeginOfEvent) {
694 PauseSession(
"BeginOfEvent");
697 if (pauseAtEndOfEvent) {
701 PauseSession(
"EndOfEvent");
717 std::size_t i = aLine.find(
' ');
718 const G4String& aliasName = aLine.substr(0, i);
719 G4String aliasValue = aLine.substr(i + 1, aLine.length() - (i + 1));
720 if (aliasValue[0] ==
'"') {
722 if (aliasValue.back() ==
'"') {
723 strippedValue = aliasValue.substr(1, aliasValue.length() - 2);
726 strippedValue = aliasValue.substr(1, aliasValue.length() - 1);
728 aliasValue = std::move(strippedValue);
731 aliasList->ChangeAlias(aliasName, aliasValue);
739 aliasList->RemoveAlias(targetAlias);
756 G4cerr <<
"Directory <" << dir <<
"> is not found." <<
G4endl;
765 std::size_t idxfirst = 0;
766 std::size_t idxend = 0;
768 while ((idxend = searchPath.find(
':', idxfirst)) != G4String::npos) {
769 pathstring = searchPath.substr(idxfirst, idxend - idxfirst);
770 if (!pathstring.empty()) {
771 searchDirs.push_back(pathstring);
773 idxfirst = idxend + 1;
776 pathstring = searchPath.substr(idxfirst, searchPath.size() - idxfirst);
777 if (!pathstring.empty()) {
778 searchDirs.push_back(std::move(pathstring));
787 fs.open(fname.c_str(), std::ios::in);
800 for (
const auto& searchDir : searchDirs) {
801 const G4String& fullpath = searchDir +
"/" + fname;
802 if (FileFound(fullpath)) {
803 macrofile = fullpath;
813 std::vector<G4String>* returnValue = commandStack;
814 commandStack =
new std::vector<G4String>;
823 "G4UIBridge cannot bridge between same object.");
826 bridges->push_back(brg);
836 threadCout->SetIgnoreCout(igThreadID);
846 threadCout->SetPrefixString(pref);
847 threadCout->SetIgnoreCout(igThreadID);
858 if (fileN ==
"**Screen**") {
859 threadCout->SetCoutFileName(fileN, ifAppend);
862 std::stringstream fn;
863 fn <<
"G4W_" << threadID <<
"_" << fileN;
864 threadCout->SetCoutFileName(fn.str(), ifAppend);
876 if (fileN ==
"**Screen**") {
877 threadCout->SetCerrFileName(fileN, ifAppend);
880 std::stringstream fn;
881 fn <<
"G4W_" << threadID <<
"_" << fileN;
882 threadCout->SetCerrFileName(fn.str(), ifAppend);
893 threadCout->SetPrefixString(s);
903 threadCout->EnableBuffering(flg);
914 threadCout->SetIgnoreCout(tid);
924 threadCout->SetIgnoreInit(flg);
934 while (
auto aBatchSession =
dynamic_cast<G4UIbatch*
>(baseSession)) {
935 auto previousSession = aBatchSession->GetPreviousSession();
936 if (previousSession ==
nullptr) {
938 baseSession = aBatchSession;
943 baseSession = previousSession;
952 fRecordFileName.push_back(std::pair<G4String,G4bool>(fn,ifTemp));
953 fAccosiatedCommand.push_back(assocCmd);
954 G4cout <<
"G4UImanager::StartRecording [" << fRecordDepth <<
"] " << fn <<
G4endl;
955 auto mode = std::ios_base::out;
956 if(ifAppend) mode = std::ios_base::app;
957 auto rf =
new std::ofstream;
959 fRecordFile.push_back(rf);
965 *(fRecordFile[fRecordDepth]) << aCommand <<
G4endl;
972 fRecordFile[fRecordDepth]->close();
973 delete fRecordFile[fRecordDepth];
974 fRecordFile.pop_back();
975 G4String assocCmd = fAccosiatedCommand[fRecordDepth];
976 fAccosiatedCommand.pop_back();
977 G4cout <<
"G4UImanager::EndRecording [" << fRecordDepth <<
"] "
978 << fRecordFileName[fRecordDepth].first <<
G4endl;
980 if(assocCmd!=
"**NOCMD**") {
984 while(fRecordFileName.size()>0) {
985 G4String fn = fRecordFileName.back().first;
986 G4bool ifTemp = fRecordFileName.back().second;
987 fRecordFileName.pop_back();
990 G4bool res = G4fs::remove(fn.c_str(), ec);
993 ed <<
"Error removing temporary macro file " << fn <<
" : "
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
@ fIllegalApplicationState
G4GLOB_DLL std::ostream G4cerr
void G4iosSetDestination(G4coutDestination *sink)
G4GLOB_DLL std::ostream G4cout
void G4iosInitialization()
static G4StateManager * GetStateManager()
G4UImanager * LocalUI() const
G4UIcommandTree * GetTree(G4int i)
void AddNewCommand(G4UIcommand *newCommand, G4bool workerThreadOnly=false)
void CreateHTML(const G4String &="")
void RemoveCommand(G4UIcommand *aCommand, G4bool workerThreadOnly=false)
G4bool ToBeBroadcasted() const
virtual G4int DoIt(const G4String ¶meterList)
static G4String ConvertToString(G4bool boolVal)
const G4String & GetFailureDescription()
static G4bool DoublePrecisionStr()
void SetCerrFileName(const G4String &fileN="G4cerr.txt", G4bool ifAppend=true)
void SetCoutDestination(G4UIsession *const value)
static void UseDoublePrecisionStr(G4bool val)
void ForeachS(const char *valueList)
void SetUpForAThread(G4int tId)
std::vector< G4String > * GetCommandStack()
void Foreach(const char *macroFile, const char *variableName, const char *candidates)
G4int ApplyCommand(const char *aCommand)
void SetThreadIgnoreInit(G4bool flg=true)
void CreateHTML(const char *dir="/")
void Loop(const char *macroFile, const char *variableName, G4double initialValue, G4double finalValue, G4double stepSize=1.0)
G4int GetCurrentIntValue(const char *aCommand, G4int parameterNumber=1, G4bool reGet=true)
void SetThreadPrefixString(const G4String &prefix="W")
void LoopS(const char *valueList)
void StoreHistory(const char *fileName="G4history.macro")
void ListCommands(const char *direc)
G4double GetCurrentDoubleValue(const char *aCommand, G4int parameterNumber=1, G4bool reGet=true)
void ExecuteMacroFile(const char *fileName)
void SetCoutFileName(const G4String &fileN="G4cout.txt", G4bool ifAppend=true)
static G4UImanager * GetMasterUIpointer()
G4String GetCurrentStringValue(const char *aCommand, G4int parameterNumber=1, G4bool reGet=true)
void SetUpForSpecialThread(const G4String &aPrefix)
void AddNewCommand(G4UIcommand *newCommand)
G4String GetCurrentValues(const char *aCommand)
void SetThreadIgnore(G4int tid=0)
void SetAlias(const char *aliasLine)
G4String FindMacroPath(const G4String &fname) const
void RemoveAlias(const char *aliasName)
G4bool Notify(G4ApplicationState requestedState) override
G4String SolveAlias(const char *aCmd)
void RemoveCommand(G4UIcommand *aCommand)
G4UIcommand * FindCommand(const char *aCommand)
void ParseMacroSearchPath()
static G4UImanager * GetUIpointer()
void StartRecording(G4String fn, G4bool ifAppend, G4bool ifTemp=false, G4String assocCmd="**NOCMD**")
void RegisterBridge(G4UIbridge *brg)
G4UImanager(const G4UImanager &)=delete
G4UIsession * GetBaseSession() const
void SetThreadUseBuffer(G4bool flg=true)
void RecordCommand(const G4String &aCommand)
virtual G4UIsession * SessionStart()
G4int GetLastReturnCode() const
G4VStateDependent(G4bool bottom=false)
G4String strip_copy(G4String str, char ch=' ')
Return copy of string with leading and trailing characters removed.
void G4SetThreadId(G4int aNewValue)
#define G4ThreadLocalStatic