lbm_reference
ConfParser.cpp
Go to the documentation of this file.
1 //! \file ConfParser.cpp
2 //! Implementation of the ConfParser class
3 
4 //! \date Jan 17, 2009
5 //! \author Florian Rathgeber
6 
7 #include <iostream>
8 #include <fstream>
9 #include <boost/algorithm/string_regex.hpp>
10 
11 #include "ConfParser.h"
12 #include "ConfBlock.h"
13 
14 using namespace std;
15 using namespace boost;
16 
17 namespace confparser {
18 
19 ConfBlock& ConfParser::parse( string configFileName ) throw( BadSyntax ) {
20 
21  // Open configuration file
22  ifstream configFile( configFileName.c_str(), ios::out );
23  if ( !configFile ) throw BadSyntax( configFileName, 0,
24  "Specified configuration file does not exist" );
25 
26 #ifdef DEBUG
27  cout << "Parsing configuration file " << configFileName << endl;
28 #endif
29 
30  parse_rec( &outermost_, 0, 0, configFile, configFileName );
31 
32  return outermost_;
33 
34 }
35 
36 int ConfParser::parse_rec( ConfBlock* currBlock,
37  int level,
38  int nLine,
39  ifstream& configFile,
40  const string& configFileName ) {
41 
42  // Read in config file linewise
43  string l;
44  while ( getline( configFile, l ) ) {
45 
46  ++nLine;
47 
48  // Remove leading and trailing whitespace
49  trim( l );
50  // If the line contained only whitspace we can skip it
51  if ( l.empty() ) continue;
52 
53  // Ignore lines beginning with # or // as comments
54  if ( starts_with( l, "#") || starts_with( l, "//" ) ) continue;
55 
56  // Check whether it is the end of a block
57  if ( l.length() == 1 && l[0] == '}' ) {
58 
59  // Syntax error if we are at level 0
60  if ( level == 0 ) {
61  throw BadSyntax( configFileName, nLine,
62  "Found closing block at outermost level" );
63  }
64 
65  return nLine;
66  }
67 
68  cmatch m;
69  regex blockBegin( "^(\\w+)\\s*\\{$" );
70  regex keyVal( "^(\\w+)\\s+(.*);" );
71 
72  // Check whether it is the beginning of a new block
73  if ( regex_match( l.c_str(), m, blockBegin ) ) {
74 
75 #ifdef DEBUG
76  cout << "Adding Block " << m[1] << " at level " << level << " (line " << nLine << ")" << endl;
77 #endif
78 
79  nLine = parse_rec( &currBlock->addChild( m[1] ), level + 1, nLine, configFile, configFileName );
80 
81  // Check whether it is a key / value pair
82  } else if ( regex_match( l.c_str(), m, keyVal ) ) {
83 
84  currBlock->addParam( m[1], m[2] );
85 
86  // Else we have a malformed expression and throw an exception
87  } else {
88 
89  throw BadSyntax( configFileName, nLine, "Malformed expression" );
90 
91  }
92 
93  }
94 
95  // check if we are at outermost level again at the end
96  if ( level != 0 )
97  throw BadSyntax( configFileName, nLine, "Unexpected end of configuration file" );
98 
99  return nLine;
100 }
101 
102 } // namespace