Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4UIbatch.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4UIbatch
27//
28// Author: M.Asai, 2000
29// --------------------------------------------------------------------
30
31#include "G4UIbatch.hh"
32
33#include "G4UImanager.hh"
34
35#include <string>
36#include <vector>
37
38// --------------------------------------------------------------------
39static void Tokenize(const G4String& str, std::vector<G4String>& tokens)
40{
41 const char* delimiter = " ";
42
43 G4String::size_type pos0 = str.find_first_not_of(delimiter);
44 G4String::size_type pos = str.find_first_of(delimiter, pos0);
45
46 while (pos != G4String::npos || pos0 != G4String::npos) {
47 if (str[(G4int)pos0] == '\"') {
48 pos = str.find_first_of('\"', pos0 + 1);
49 if (pos != G4String::npos) {
50 pos++;
51 }
52 }
53 if (str[(G4int)pos0] == '\'') {
54 pos = str.find_first_of('\'', pos0 + 1);
55 if (pos != G4String::npos) {
56 pos++;
57 }
58 }
59
60 tokens.emplace_back(str.substr(pos0, pos - pos0));
61 pos0 = str.find_first_not_of(delimiter, pos);
62 pos = str.find_first_of(delimiter, pos0);
63 }
64}
65
66// --------------------------------------------------------------------
67G4UIbatch::G4UIbatch(const char* fileName, G4UIsession* prevSession)
68 : G4UIsession(1), previousSession(prevSession)
69{
70 macroStream.open(fileName, std::ios::in);
71 if (macroStream.fail()) {
72 G4cerr << "ERROR: Can not open a macro file <" << fileName
73 << ">. Set macro path with \"/control/macroPath\" if needed." << G4endl;
74 lastRC = fParameterUnreadable;
75 }
76 else {
77 isOpened = true;
78 }
79
80 G4UImanager::GetUIpointer()->SetSession(this);
81}
82
83// --------------------------------------------------------------------
85{
86 if (isOpened) {
87 macroStream.close();
88 }
89}
90
91// --------------------------------------------------------------------
92G4String G4UIbatch::ReadCommand()
93{
94 enum
95 {
96 BUFSIZE = 4096
97 };
98 static G4ThreadLocal char* linebuf = nullptr;
99 if (linebuf == nullptr) {
100 linebuf = new char[BUFSIZE];
101 }
102 const char ctrM = 0x0d;
103
104 G4String cmdtotal = "";
105 G4bool qcontinued = false;
106 while (macroStream.good()) {
107 macroStream.getline(linebuf, BUFSIZE);
108
109 G4String cmdline(linebuf);
110
111 // TAB-> ' ' conversion
112 G4String::size_type nb = 0;
113 while ((nb = cmdline.find('\t', nb)) != G4String::npos) {
114 cmdline.replace(nb, 1, " ");
115 }
116
117 // strip
118 G4StrUtil::strip(cmdline);
119 G4StrUtil::rstrip(cmdline, ctrM);
120
121 // skip null line if single line
122 if (!qcontinued && cmdline.empty()) {
123 continue;
124 }
125
126 // '#' is treated as echoing something
127 if (cmdline[(std::size_t)0] == '#') {
128 return cmdline;
129 }
130
131 // tokenize...
132 std::vector<G4String> tokens;
133 Tokenize(cmdline, tokens);
134 qcontinued = false;
135 for (G4int i = 0; i < G4int(tokens.size()); ++i) {
136 // string after '#" is ignored
137 if (tokens[i][(std::size_t)0] == '#') {
138 break;
139 }
140 // '\' or '_' is treated as continued line.
141 if (tokens[i] == "\\" || tokens[i] == "_") {
142 qcontinued = true;
143 // check nothing after line continuation character
144 if (i != G4int(tokens.size()) - 1) {
145 G4Exception("G4UIbatch::ReadCommand", "UI0003", JustWarning,
146 "unexpected character after line continuation character");
147 }
148 break; // stop parsing
149 }
150 cmdtotal += tokens[i];
151 cmdtotal += " ";
152 }
153
154 if (qcontinued) {
155 continue; // read the next line
156 }
157
158 if (!cmdtotal.empty()) {
159 break;
160 }
161 if (macroStream.eof()) {
162 break;
163 }
164 }
165
166 // strip again
167 G4StrUtil::strip(cmdtotal);
168
169 // finally,
170 if (macroStream.eof() && cmdtotal.empty()) {
171 return "exit";
172 }
173
174 return cmdtotal;
175}
176
177// --------------------------------------------------------------------
178G4int G4UIbatch::ExecCommand(const G4String& command)
179{
180 G4UImanager* UI = G4UImanager::GetUIpointer();
181 G4int rc = UI->ApplyCommand(command);
182
183 switch (rc) {
185 break;
186 case fCommandNotFound:
187 G4cerr << "***** COMMAND NOT FOUND <" << command << "> *****" << G4endl;
188 break;
190 G4cerr << "***** Illegal application state <" << command << "> *****" << G4endl;
191 break;
192 default:
193 G4int pn = rc % 100;
194 G4cerr << "***** Illegal parameter (" << pn << ") <" << command << "> *****" << G4endl;
195 }
196
197 return rc;
198}
199
200// --------------------------------------------------------------------
202{
203 if (!isOpened) {
204 return previousSession;
205 }
206
207 while (true) {
208 G4String newCommand = ReadCommand();
209
210 if (newCommand == "exit") {
211 break;
212 }
213
214 // just echo something
215 if (newCommand[(std::size_t)0] == '#') {
216 if (G4UImanager::GetUIpointer()->GetVerboseLevel() == 2) {
217 G4cout << newCommand << G4endl;
218 }
219 continue;
220 }
221
222 // execute command
223 G4int rc = ExecCommand(newCommand);
224 if (rc != fCommandSucceeded) {
225 G4cerr << G4endl << "***** Batch is interrupted!! *****" << G4endl;
226 lastRC = rc;
227 break;
228 }
229 }
230
231 return previousSession;
232}
233
234// --------------------------------------------------------------------
236{
237 G4cout << "Pause session <" << Prompt << "> start." << G4endl;
238
239 SessionStart();
240
241 G4cout << "Pause session <" << Prompt << "> Terminate." << G4endl;
242}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
@ fCommandNotFound
@ fIllegalApplicationState
@ fCommandSucceeded
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
void PauseSessionStart(const G4String &Prompt) override
Definition G4UIbatch.cc:235
~G4UIbatch() override
Definition G4UIbatch.cc:84
G4UIsession * SessionStart() override
Definition G4UIbatch.cc:201
G4UIbatch(const char *fileName, G4UIsession *prevSession=nullptr)
Definition G4UIbatch.cc:67
G4int ApplyCommand(const char *aCommand)
static G4UImanager * GetUIpointer()
void Tokenize(const G4String &line, std::vector< G4String > &tokens)
#define G4ThreadLocal
Definition tls.hh:77