G4tgrFileIn.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id: G4tgrFileIn.cc 69803 2013-05-15 15:24:50Z gcosmo $
00028 //
00029 //
00030 // class G4tgrFileIn
00031 
00032 // History:
00033 // - Created.                                 P.Arce, CIEMAT (November 2007)
00034 // -------------------------------------------------------------------------
00035 
00036 #include "globals.hh"
00037 
00038 #include <iostream>
00039 #include <fstream>
00040 #include <sstream>
00041 
00042 #include "G4tgrFileIn.hh"
00043 #include "G4tgrMessenger.hh"
00044 #include "G4tgrUtils.hh"
00045 #include "G4UIcommand.hh"
00046 
00047 std::vector<G4tgrFileIn*> G4tgrFileIn::theInstances;
00048 
00049 
00050 //-----------------------------------------------------------------------
00051 G4tgrFileIn::G4tgrFileIn()
00052   : theCurrentFile(-1), theName("")
00053 {
00054 }
00055 
00056 
00057 //-----------------------------------------------------------------------
00058 G4tgrFileIn::~G4tgrFileIn()
00059 {
00060 /*
00061   std::vector<G4tgrFileIn*>::const_iterator vfcite;
00062   for( vfcite = theInstances.begin(); vfcite != theInstances.end(); vfcite++)
00063   {
00064     delete *vfcite;
00065   }
00066 */
00067 }
00068 
00069 
00070 //-----------------------------------------------------------------------
00071 G4tgrFileIn& G4tgrFileIn::GetInstance( const G4String& filename )
00072 {
00073   std::vector<G4tgrFileIn*>::const_iterator vfcite;
00074   for( vfcite = theInstances.begin(); vfcite != theInstances.end(); vfcite++)
00075   {
00076     if( (*vfcite)->GetName() == filename)
00077     {
00078       return *(*vfcite);
00079     }
00080   }
00081 
00082   G4tgrFileIn* instance = 0;
00083   if( vfcite == theInstances.end() )
00084   {
00085     instance = new G4tgrFileIn( filename );
00086     
00087     instance->theCurrentFile = -1;
00088     instance->OpenNewFile( filename.c_str() );
00089 
00090     theInstances.push_back( instance );
00091   }
00092 
00093   return *instance;
00094 }
00095 
00096 
00097 //-----------------------------------------------------------------------
00098 void G4tgrFileIn::OpenNewFile( const char* filename )
00099 { 
00100   theCurrentFile++;
00101   std::ifstream* fin = new std::ifstream(filename);
00102   theFiles.push_back(fin);
00103 
00104   theLineNo.push_back( 0 );
00105 
00106   theNames.push_back( filename );
00107 
00108 #ifndef OS_SUN_4_2
00109   if( !fin->is_open() )
00110   {
00111     G4String ErrMessage = "Input file does not exist: " + G4String(filename);
00112     G4Exception("G4tgrFileIn::OpenNewFile()",
00113                 "InvalidInput", FatalException, ErrMessage);
00114   }
00115 #endif
00116 }
00117 
00118 
00119 //-----------------------------------------------------------------------
00120 G4tgrFileIn& G4tgrFileIn::GetInstanceOpened( const G4String& filename )
00121 {
00122 
00123   G4tgrFileIn& filein = G4tgrFileIn::GetInstance(filename);
00124   if (filein.GetName() != filename )
00125   {
00126     G4String ErrMessage = "File not opened yet: " + filename;
00127     G4Exception("G4tgrFileIn::GetInstanceOpened()",
00128                 "InvalidInput", FatalException, ErrMessage);
00129   }
00130   else
00131   {
00132     return filein;
00133   }
00134   return filein; // to avoid compilation warnings
00135 }
00136 
00137 
00138 //----------------------------------------------------------------------- 
00139 G4int G4tgrFileIn::GetWordsInLine( std::vector<G4String>& wordlist)
00140 {
00141   G4int isok = 1;
00142 
00143   //---------- Read a line of file:
00144   //           NOTE: cannot be read with a istream_iterator,
00145   //           because it uses G4cout, and then doesn't read '\n'
00146   //----- Clear wordlist
00147   G4int wsiz = wordlist.size();
00148   G4int ii;
00149   for (ii = 0; ii < wsiz; ii++)
00150   {
00151     wordlist.pop_back();
00152   } 
00153 
00154   //---------- Loop lines while there is an ending '\' or line is blank   
00155   const G4int NMAXLIN = 1000;
00156   char ltemp[NMAXLIN]; // there won't be lines longer than NMAXLIN characters
00157   for (;;)
00158   {
00159     (theLineNo[theCurrentFile])++;
00160     for ( ii = 0; ii < NMAXLIN; ii++)  { ltemp[ii] = ' '; }
00161     theFiles[theCurrentFile]->getline( ltemp, NMAXLIN ); 
00162 
00163     //---------- Check for lines longer than NMAXLIN character
00164     for ( ii=0; ii < NMAXLIN; ii++)
00165     {
00166       if ( ltemp[ii] == '\0' )  { break; }
00167     }
00168     if ( ii == NMAXLIN-1 )
00169     {
00170       ErrorInLine();
00171       G4String ErrMessage = "Too long line. Please split it "
00172                           + G4String("putting a '\\' at the end!");
00173       G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput",
00174                   FatalException, ErrMessage);
00175     }
00176     
00177     //---------- End of file
00178     if ( EndOfFile() )
00179     {
00180       return 0;
00181     }
00182     
00183     //---------- Convert line read to istrstream to split it in words 
00184     std::istringstream istr_line(ltemp);
00185      
00186     //--------- Count how many words are there in ltemp
00187     //          this shouln't be needed, but SUN compiler has problems...
00188     G4int NoWords = 0;
00189     char* tt = ltemp;
00190 
00191     G4String stemp(ltemp);
00192     do
00193     {
00194       if( *tt != ' ' && *(tt) != '\0' )
00195       {
00196         if( tt == ltemp)
00197         {
00198           NoWords++;
00199 #ifdef G4VERBOSE
00200           if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00201           {
00202             G4cout << "G4tgrFileIn::GetWordsInLine() - NoWords"
00203                    << NoWords << ltemp << G4endl;
00204           }
00205 #endif
00206         }
00207         else if( *(tt-1) == ' ' ||  *(tt-1) == '\015' ||  *(tt-1) == '\t')
00208         {
00209           NoWords++; 
00210 #ifdef G4VERBOSE
00211           if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00212           {
00213             G4cout << "G4tgrFileIn::GetWordsInLine() - NoWords"
00214                    << NoWords << ltemp << G4endl;
00215           }
00216 #endif
00217         }
00218       }
00219       tt++;
00220     } while((*tt != '\0') && (stemp.length()!=0));
00221 
00222     if(stemp.length() == 0)  { NoWords = 0; }
00223 
00224     //--------- Read words from istr_line and write them into wordlist
00225     for( ii=0; ii < NoWords; ii++)
00226     {
00227       stemp = "";
00228       istr_line >> stemp;
00229       if ( stemp.length() == 0 )  { break; }
00230       G4int comment = stemp.find(G4String("//") );
00231 #ifdef G4VERBOSE
00232       if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00233       {
00234         G4cout << "!!!COMMENT" << comment << stemp.c_str() << G4endl;
00235       }
00236 #endif
00237       if ( comment == 0 )
00238       {
00239         break; 
00240       }
00241       else if ( comment > 0 )
00242       {
00243         stemp = stemp.substr( 0, comment );
00244         wordlist.push_back(stemp);
00245         break;
00246       } 
00247       wordlist.push_back(stemp);
00248     }
00249     
00250     // These two algorithms should be the more STL-like way, but they don't
00251     // work for files whose lines end without '\015'=TAB (STL problem: doesn't
00252     // find end of string??):
00253     // istream_iterator<G4String, ptrdiff_t> G4String_iter(istr_line);
00254     // istream_iterator<G4String, ptrdiff_t> eosl;
00255     // copy(G4String_iter, eosl, back_inserter(wordlist));
00256     // typedef istream_iterator<G4String, ptrdiff_t> G4String_iter;
00257     // copy(G4String_iter(istr_line), G4String_iter(), back_inserter(wordlist));
00258     
00259     if ( wordlist.size() != 0 )
00260     {
00261       if( (*(wordlist.end()-1)).compare("\\") == 0 )   // use '\' to mark
00262       {                                                // continuing line
00263         wordlist.pop_back();
00264       }
00265       else
00266       {
00267         break;
00268       }
00269     }
00270   }
00271   
00272   //--------- A pair of double quotes delimits a word, therefore, look for the
00273   //          case where there is more than one word between two double quotes
00274   std::vector<G4String> wordlist2;
00275   G4String wordq = "";
00276   unsigned int imerge = 0;
00277   for( size_t jj = 0; jj < wordlist.size(); jj++)
00278   {
00279     if( wordlist[jj].substr(0,1) == "\"" )
00280     {
00281       imerge = 1;
00282     } 
00283     if( wordlist[jj][ wordlist[jj].size()-1 ] == '\"' )
00284     {
00285       if( imerge != 1 )
00286       {
00287         G4String err1 = " word with trailing '\"' while there is no";
00288         G4String err2 = " previous word with leading '\"' in line ";
00289         G4String err = err1 + err2;
00290         DumpException(err);
00291       }
00292       imerge = 2;
00293     }
00294     if( imerge == 0 )
00295     {
00296       wordlist2.push_back( wordlist[jj] );
00297     }
00298     else if( imerge == 1 )
00299     {
00300       if( wordq == "" )
00301       {
00302         wordq.append( wordlist[jj].substr(1,wordlist[jj].size()) );
00303       }
00304       else
00305       {
00306         wordq.append( wordlist[jj].substr(0,wordlist[jj].size()) );
00307       }
00308       wordq.append(" ");
00309     }
00310     else if( imerge == 2 )
00311     {
00312       if( wordq == "" )
00313       {
00314         wordq.append( wordlist[jj].substr(1,wordlist[jj].size()-2));
00315       }
00316       else
00317       {
00318         wordq.append( wordlist[jj].substr(0,wordlist[jj].size()-1) );
00319       } 
00320       wordlist2.push_back( wordq );
00321       wordq = "";
00322       imerge = 0;
00323     }
00324   }
00325   if( imerge == 1 )
00326   {
00327     G4String err1 = " word with leading '\"' in line while there is no";
00328     G4String err2 = " later word with trailing '\"' in line ";
00329     G4String err = err1 + err2;
00330     DumpException(err);
00331   }
00332 
00333   wordlist = wordlist2;
00334 
00335   // Or why not like this (?):
00336   // typedef std::istream_iterator<G4String, ptrdiff_t> string_iter;
00337   // std::copy(string_iter(istr_line), string_iter(), back_inserter(wordlist));
00338   
00339   // check if including a new file
00340   if( wordlist[0] == "#include" )
00341   {
00342     if( wordlist.size() != 2 )
00343     {
00344       ErrorInLine();
00345       G4String ErrMessage
00346                = "'#include' should have as second argument, the filename !";
00347       G4Exception("G4tgrFileIn::GetWordsInLine()", "InvalidInput",
00348                   FatalException, ErrMessage);
00349     }
00350 
00351 #ifdef G4VERBOSE
00352     if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00353     {
00354       G4cout << " G4tgrFileIn::GetWordsInLine() - Include found !" << G4endl;
00355     }
00356 #endif
00357     OpenNewFile( wordlist[1].c_str() );
00358     isok = GetWordsInLine( wordlist);
00359   }
00360 
00361   return isok;
00362 }
00363 
00364 
00365 //-----------------------------------------------------------------------
00366 void G4tgrFileIn::ErrorInLine()
00367 {
00368   G4cerr << "!! EXITING: ERROR IN LINE No "
00369          << theLineNo[theCurrentFile] << " file: "
00370          << theNames[theCurrentFile] << " : ";
00371 }
00372 
00373 
00374 //-----------------------------------------------------------------------
00375 G4bool G4tgrFileIn::EndOfFile()
00376 {
00377   G4bool isok = theFiles[theCurrentFile]->eof();
00378   if( isok )
00379   {
00380 #ifdef G4VERBOSE
00381     if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00382     {
00383       G4cout << " G4tgrFileIn::EndOfFile() - EOF: "
00384              << theCurrentFile << G4endl;
00385     }
00386 #endif
00387     theCurrentFile--;
00388     if( theCurrentFile != -1 )   // Last file will be closed by the user
00389     {
00390       Close();
00391     }
00392   }
00393 
00394   // Only real closing if all files are closed
00395 #ifdef G4VERBOSE
00396   if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00397   {
00398     G4cout << " G4tgrFileIn::EndOfFile() - EOF: "
00399            << isok << " " << theCurrentFile << G4endl;
00400   }
00401 #endif
00402   if( theCurrentFile != -1 )
00403   { 
00404     return 0;
00405   }
00406   else
00407   {
00408     return isok;
00409   }
00410 }
00411 
00412 
00413 //-----------------------------------------------------------------------
00414 void G4tgrFileIn::Close()
00415 {
00416 #ifdef G4VERBOSE
00417   if( G4tgrMessenger::GetVerboseLevel() >= 3 )
00418   {
00419     G4cout << "G4tgrFileIn::Close() - "
00420            << theCurrentFile << ", size " << theFiles.size() << G4endl;
00421   }
00422 #endif
00423 
00424   theFiles[theCurrentFile+1]->close();
00425   theFiles.pop_back();
00426 }
00427 
00428 
00429 //-----------------------------------------------------------------------
00430 void G4tgrFileIn::DumpException( const G4String& sent )
00431 {
00432   G4String Err1 = sent + " in file " + theName;
00433   G4String Err2 = " line No: "
00434                 + G4UIcommand::ConvertToString(theLineNo[theCurrentFile]);
00435   G4String ErrMessage = Err1;
00436   G4Exception("G4tgrFileIn::DumpException()", "FileError",
00437               FatalException, ErrMessage);  
00438 }
00439 

Generated on Mon May 27 17:49:58 2013 for Geant4 by  doxygen 1.4.7