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

Last change on this file since 1351 was 1347, checked in by garnier, 15 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.