Geant4-11
G4tgrFileIn.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// G4tgrFileIn implementation
27//
28// Author: P.Arce, CIEMAT (November 2007)
29// --------------------------------------------------------------------
30
31#include "globals.hh"
32
33#include <iostream>
34#include <fstream>
35#include <sstream>
36
37#include "G4tgrFileIn.hh"
38#include "G4tgrMessenger.hh"
39#include "G4tgrUtils.hh"
40#include "G4UIcommand.hh"
41
42G4ThreadLocal std::vector<G4tgrFileIn*>* G4tgrFileIn::theInstances = nullptr;
43
44// --------------------------------------------------------------------
46{
47 if(theInstances == nullptr)
48 {
49 theInstances = new std::vector<G4tgrFileIn*>;
50 }
51}
52
53// --------------------------------------------------------------------
55{
56 delete theInstances;
57 theInstances = nullptr;
58 /*
59 for( auto vfcite = theInstances->cbegin();
60 vfcite != theInstances->cend(); ++vfcite)
61 {
62 delete *vfcite;
63 }
64 */
65}
66
67// --------------------------------------------------------------------
69{
70 if(theInstances == nullptr)
71 {
72 theInstances = new std::vector<G4tgrFileIn*>;
73 }
74
75 std::vector<G4tgrFileIn*>::const_iterator vfcite;
76 for(vfcite = theInstances->cbegin(); vfcite != theInstances->cend(); ++vfcite)
77 {
78 if((*vfcite)->GetName() == filename)
79 {
80 return *(*vfcite);
81 }
82 }
83
84 G4tgrFileIn* instance = nullptr;
85 if(vfcite == theInstances->cend())
86 {
87 instance = new G4tgrFileIn(filename);
88
89 instance->theCurrentFile = -1;
90 instance->OpenNewFile(filename.c_str());
91
92 theInstances->push_back(instance);
93 }
94
95 return *instance;
96}
97
98// --------------------------------------------------------------------
99void G4tgrFileIn::OpenNewFile(const char* filename)
100{
102 std::ifstream* fin = new std::ifstream(filename);
103 theFiles.push_back(fin);
104
105 theLineNo.push_back(0);
106
107 theNames.push_back(filename);
108
109#ifndef OS_SUN_4_2
110 if(!fin->is_open())
111 {
112 G4String ErrMessage = "Input file does not exist: " + G4String(filename);
113 G4Exception("G4tgrFileIn::OpenNewFile()", "InvalidInput", FatalException,
114 ErrMessage);
115 }
116#endif
117}
118
119// --------------------------------------------------------------------
121{
122 G4tgrFileIn& filein = G4tgrFileIn::GetInstance(filename);
123 if(filein.GetName() != filename)
124 {
125 G4String ErrMessage = "File not opened yet: " + filename;
126 G4Exception("G4tgrFileIn::GetInstanceOpened()", "InvalidInput",
127 FatalException, ErrMessage);
128 }
129 else
130 {
131 return filein;
132 }
133 return filein; // to avoid compilation warnings
134}
135
136// --------------------------------------------------------------------
137G4int G4tgrFileIn::GetWordsInLine(std::vector<G4String>& wordlist)
138{
139 G4int isok = 1;
140
141 //---------- Read a line of file:
142 // NOTE: cannot be read with a istream_iterator,
143 // because it uses G4cout, and then doesn't read '\n'
144 //----- Clear wordlist
145 G4int wsiz = wordlist.size();
146 G4int ii;
147 for(ii = 0; ii < wsiz; ++ii)
148 {
149 wordlist.pop_back();
150 }
151
152 //---------- Loop lines while there is an ending '\' or line is blank
153 const G4int NMAXLIN = 1000;
154 char ltemp[NMAXLIN]; // there won't be lines longer than NMAXLIN characters
155 for(;;)
156 {
158 for(ii = 0; ii < NMAXLIN; ++ii)
159 {
160 ltemp[ii] = ' ';
161 }
162 theFiles[theCurrentFile]->getline(ltemp, NMAXLIN);
163
164 //---------- Check for lines longer than NMAXLIN character
165 for(ii = 0; ii < NMAXLIN; ++ii)
166 {
167 if(ltemp[ii] == '\0')
168 {
169 break;
170 }
171 }
172 if(ii == NMAXLIN - 1)
173 {
174 ErrorInLine();
175 G4String ErrMessage = "Too long line. Please split it " +
176 G4String("putting a '\\' at the end!");
177 G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput",
178 FatalException, ErrMessage);
179 }
180
181 //---------- End of file
182 if(EndOfFile())
183 {
184 return 0;
185 }
186
187 //---------- Convert line read to istrstream to split it in words
188 std::istringstream istr_line(ltemp);
189
190 //--------- Count how many words are there in ltemp
191 // this shouln't be needed, but SUN compiler has problems...
192 G4int NoWords = 0;
193 char* tt = ltemp;
194
195 G4String stemp(ltemp);
196 do
197 {
198 if(*tt != ' ' && *(tt) != '\0')
199 {
200 if(tt == ltemp)
201 {
202 ++NoWords;
203#ifdef G4VERBOSE
205 {
206 G4cout << "G4tgrFileIn::GetWordsInLine() - NoWords" << NoWords
207 << ltemp << G4endl;
208 }
209#endif
210 }
211 else if(*(tt - 1) == ' ' || *(tt - 1) == '\015' || *(tt - 1) == '\t')
212 {
213 ++NoWords;
214#ifdef G4VERBOSE
216 {
217 G4cout << "G4tgrFileIn::GetWordsInLine() - NoWords" << NoWords
218 << ltemp << G4endl;
219 }
220#endif
221 }
222 }
223 ++tt;
224 } while((*tt != '\0') && (stemp.length() != 0));
225
226 if(stemp.length() == 0)
227 {
228 NoWords = 0;
229 }
230
231 //--------- Read words from istr_line and write them into wordlist
232 for(ii = 0; ii < NoWords; ++ii)
233 {
234 stemp = "";
235 istr_line >> stemp;
236 if(stemp.length() == 0)
237 {
238 break;
239 }
240 G4int comment = stemp.find(G4String("//"));
241#ifdef G4VERBOSE
243 {
244 G4cout << "!!!COMMENT" << comment << stemp.c_str() << G4endl;
245 }
246#endif
247 if(comment == 0)
248 {
249 break;
250 }
251 else if(comment > 0)
252 {
253 stemp = stemp.substr(0, comment);
254 wordlist.push_back(stemp);
255 break;
256 }
257 wordlist.push_back(stemp);
258 }
259
260 // These two algorithms should be the more STL-like way, but they don't
261 // work for files whose lines end without '\015'=TAB (STL problem: doesn't
262 // find end of string??):
263 // istream_iterator<G4String, ptrdiff_t> G4String_iter(istr_line);
264 // istream_iterator<G4String, ptrdiff_t> eosl;
265 // copy(G4String_iter, eosl, back_inserter(wordlist));
266 // typedef istream_iterator<G4String, ptrdiff_t> G4String_iter;
267 // copy(G4String_iter(istr_line), G4String_iter(), back_inserter(wordlist));
268
269 if(wordlist.size() != 0)
270 {
271 if((*(wordlist.end() - 1)).compare("\\") == 0) // use '\' to mark
272 { // continuing line
273 wordlist.pop_back();
274 }
275 else
276 {
277 break;
278 }
279 }
280 }
281
282 //--------- A pair of double quotes delimits a word, therefore, look for the
283 // case where there is more than one word between two double quotes
284 std::vector<G4String> wordlist2;
285 G4String wordq = "";
286 unsigned int imerge = 0;
287 for(std::size_t jj = 0; jj < wordlist.size(); ++jj)
288 {
289 if(wordlist[jj].substr(0, 1) == "\"")
290 {
291 imerge = 1;
292 }
293 if(wordlist[jj][wordlist[jj].size() - 1] == '\"')
294 {
295 if(imerge != 1)
296 {
297 G4String err1 = " word with trailing '\"' while there is no";
298 G4String err2 = " previous word with leading '\"' in line ";
299 G4String err = err1 + err2;
300 DumpException(err);
301 }
302 imerge = 2;
303 }
304 if(imerge == 0)
305 {
306 wordlist2.push_back(wordlist[jj]);
307 }
308 else if(imerge == 1)
309 {
310 if(wordq == "")
311 {
312 wordq.append(wordlist[jj].substr(1, wordlist[jj].size()));
313 }
314 else
315 {
316 wordq.append(wordlist[jj].substr(0, wordlist[jj].size()));
317 }
318 wordq.append(" ");
319 }
320 else if(imerge == 2)
321 {
322 if(wordq == "")
323 {
324 wordq.append(wordlist[jj].substr(1, wordlist[jj].size() - 2));
325 }
326 else
327 {
328 wordq.append(wordlist[jj].substr(0, wordlist[jj].size() - 1));
329 }
330 wordlist2.push_back(wordq);
331 wordq = "";
332 imerge = 0;
333 }
334 }
335 if(imerge == 1)
336 {
337 G4String err1 = " word with leading '\"' in line while there is no";
338 G4String err2 = " later word with trailing '\"' in line ";
339 G4String err = err1 + err2;
340 DumpException(err);
341 }
342
343 wordlist = wordlist2;
344
345 // Or why not like this (?):
346 // typedef std::istream_iterator<G4String, ptrdiff_t> string_iter;
347 // std::copy(string_iter(istr_line), string_iter(), back_inserter(wordlist));
348
349 // check if including a new file
350 if(wordlist[0] == "#include")
351 {
352 if(wordlist.size() != 2)
353 {
354 ErrorInLine();
355 G4String ErrMessage =
356 "'#include' should have as second argument, the filename !";
357 G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput",
358 FatalException, ErrMessage);
359 }
360
361#ifdef G4VERBOSE
363 {
364 G4cout << " G4tgrFileIn::GetWordsInLine() - Include found !" << G4endl;
365 }
366#endif
367 OpenNewFile(wordlist[1].c_str());
368 isok = GetWordsInLine(wordlist);
369 }
370
371 return isok;
372}
373
374// --------------------------------------------------------------------
376{
377 G4cerr << "!! EXITING: ERROR IN LINE No " << theLineNo[theCurrentFile]
378 << " file: " << theNames[theCurrentFile] << " : ";
379}
380
381// --------------------------------------------------------------------
383{
384 G4bool isok = theFiles[theCurrentFile]->eof();
385 if(isok)
386 {
387#ifdef G4VERBOSE
389 {
390 G4cout << " G4tgrFileIn::EndOfFile() - EOF: " << theCurrentFile << G4endl;
391 }
392#endif
394 if(theCurrentFile != -1) // Last file will be closed by the user
395 {
396 Close();
397 }
398 }
399
400 // Only real closing if all files are closed
401#ifdef G4VERBOSE
403 {
404 G4cout << " G4tgrFileIn::EndOfFile() - EOF: " << isok << " "
406 }
407#endif
408 if(theCurrentFile != -1)
409 {
410 return false;
411 }
412 else
413 {
414 return isok;
415 }
416}
417
418// --------------------------------------------------------------------
420{
421#ifdef G4VERBOSE
423 {
424 G4cout << "G4tgrFileIn::Close() - " << theCurrentFile << ", size "
425 << theFiles.size() << G4endl;
426 }
427#endif
428
429 theFiles[theCurrentFile + 1]->close();
430 theFiles.pop_back();
431}
432
433// --------------------------------------------------------------------
435{
436 G4String Err1 = sent + " in file " + theName;
437 G4String Err2 =
439 G4String ErrMessage = Err1;
440 G4Exception("G4tgrFileIn::DumpException()", "FileError", FatalException,
441 ErrMessage);
442}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static G4String ConvertToString(G4bool boolVal)
Definition: G4UIcommand.cc:445
void OpenNewFile(const char *filename)
Definition: G4tgrFileIn.cc:99
void Close()
Definition: G4tgrFileIn.cc:419
G4int theCurrentFile
Definition: G4tgrFileIn.hh:84
void ErrorInLine()
Definition: G4tgrFileIn.cc:375
std::vector< G4int > theLineNo
Definition: G4tgrFileIn.hh:79
const G4String & GetName()
Definition: G4tgrFileIn.hh:64
G4String theName
Definition: G4tgrFileIn.hh:90
G4bool EndOfFile()
Definition: G4tgrFileIn.cc:382
static G4ThreadLocal std::vector< G4tgrFileIn * > * theInstances
Definition: G4tgrFileIn.hh:87
G4int GetWordsInLine(std::vector< G4String > &wl)
Definition: G4tgrFileIn.cc:137
static G4tgrFileIn & GetInstanceOpened(const G4String &name)
Definition: G4tgrFileIn.cc:120
static G4tgrFileIn & GetInstance(const G4String &name)
Definition: G4tgrFileIn.cc:68
std::vector< G4String > theNames
Definition: G4tgrFileIn.hh:82
void DumpException(const G4String &sent)
Definition: G4tgrFileIn.cc:434
std::vector< std::ifstream * > theFiles
Definition: G4tgrFileIn.hh:77
static G4int GetVerboseLevel()
#define G4ThreadLocal
Definition: tls.hh:77