Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/persistency/ascii/src/G4tgrFileIn.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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