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

Last change on this file since 1347 was 1347, checked in by garnier, 13 years ago

geant4 tag 9.4

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.13 2010/12/15 11:29:54 arce Exp $
28// GEANT4 tag $Name: geant4-09-04-ref-00 $
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#include <sstream>
42
43#include "G4tgrFileIn.hh"
44#include "G4tgrMessenger.hh"
45#include "G4tgrUtils.hh"
46#include "G4UIcommand.hh"
47
48std::vector<G4tgrFileIn*> G4tgrFileIn::theInstances;
49
50
51//-----------------------------------------------------------------------
52G4tgrFileIn::G4tgrFileIn()
53  : theCurrentFile(-1), theName("")
54{
55}
56
57
58//-----------------------------------------------------------------------
59G4tgrFileIn::~G4tgrFileIn()
60{
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//-----------------------------------------------------------------------
72G4tgrFileIn& G4tgrFileIn::GetInstance( const G4String& filename )
73{
74  std::vector<G4tgrFileIn*>::const_iterator vfcite;
75  for( vfcite = theInstances.begin(); vfcite != theInstances.end(); vfcite++)
76  {
77    if( (*vfcite)->GetName() == filename)
78    {
79      return *(*vfcite);
80    }
81  }
82
83  G4tgrFileIn* instance = 0;
84  if( vfcite == theInstances.end() )
85  {
86    instance = new G4tgrFileIn( filename );
87   
88    instance->theCurrentFile = -1;
89    instance->OpenNewFile( filename.c_str() );
90
91    theInstances.push_back( instance );
92  }
93
94  return *instance;
95}
96
97
98//-----------------------------------------------------------------------
99void G4tgrFileIn::OpenNewFile( const char* filename )
100{ 
101  theCurrentFile++;
102  std::ifstream* fin = new std::ifstream(filename);
103  theFiles.push_back(fin);
104
105  theLineNo.push_back( 0 );
106
107  theNames.push_back( filename );
108
109#ifndef OS_SUN_4_2
110  if( !fin->is_open() )
111  {
112    G4String ErrMessage = "Input file does not exist: " + G4String(filename);
113    G4Exception("G4tgrFileIn::OpenNewFile()",
114                "InvalidInput", FatalException, ErrMessage);
115  }
116#endif
117}
118
119
120//-----------------------------------------------------------------------
121G4tgrFileIn& G4tgrFileIn::GetInstanceOpened( const G4String& filename )
122{
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//-----------------------------------------------------------------------
140G4int 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  {
160    (theLineNo[theCurrentFile])++;
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
201          if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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
212          if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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    G4String stempt (ltemp);
224    if(stempt.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      G4String stemp = "";
230      istr_line >> stemp;
231      if ( stemp.length() == 0 )  { break; }
232      G4int comment = stemp.find(G4String("//") );
233#ifdef G4VERBOSE
234      if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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 ii = 0; ii < wordlist.size(); ii++)
280  {
281    if( wordlist[ii].substr(0,1) == "\"" )
282    {
283      imerge = 1;
284    } 
285    if( wordlist[ii][ wordlist[ii].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[ii] );
299    }
300    else if( imerge == 1 )
301    {
302      if( wordq == "" )
303      {
304        wordq.append( wordlist[ii].substr(1,wordlist[ii].size()) );
305      }
306      else
307      {
308        wordq.append( wordlist[ii].substr(0,wordlist[ii].size()) );
309      }
310      wordq.append(" ");
311    }
312    else if( imerge == 2 )
313    {
314      if( wordq == "" )
315      {
316        wordq.append( wordlist[ii].substr(1,wordlist[ii].size()-2));
317      }
318      else
319      {
320        wordq.append( wordlist[ii].substr(0,wordlist[ii].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
354    if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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//-----------------------------------------------------------------------
368void G4tgrFileIn::ErrorInLine()
369{
370  G4cerr << "!! EXITING: ERROR IN LINE No "
371         << theLineNo[theCurrentFile] << " file: "
372         << theNames[theCurrentFile] << " : ";
373}
374
375
376//-----------------------------------------------------------------------
377G4bool G4tgrFileIn::EndOfFile()
378{
379  G4bool isok = theFiles[theCurrentFile]->eof();
380  if( isok )
381  {
382#ifdef G4VERBOSE
383    if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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
398  if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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//-----------------------------------------------------------------------
416void G4tgrFileIn::Close()
417{
418#ifdef G4VERBOSE
419  if( G4tgrMessenger::GetVerboseLevel() >= 3 )
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//-----------------------------------------------------------------------
432void G4tgrFileIn::DumpException( const G4String& sent )
433{
434  G4String Err1 = sent + " in file " + theName;
435  G4String Err2 = " line No: "
436                + G4UIcommand::ConvertToString(theLineNo[theCurrentFile]);
437  G4String ErrMessage = Err1;
438  G4Exception("G4tgrFileIn::DumpException()", "FileError",
439              FatalException, ErrMessage); 
440}
441
Note: See TracBrowser for help on using the repository browser.