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