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