source: trunk/source/persistency/ascii/src/G4tgrFileIn.cc @ 1202

Last change on this file since 1202 was 1035, checked in by garnier, 15 years ago

dossiers oublies

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