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