Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 69803 2013-05-15 15:24:50Z 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 std::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 //-----------------------------------------------------------------------
98 void 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 //-----------------------------------------------------------------------
139 G4int 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