~ubuntu-branches/ubuntu/trusty/ticcutils/trusty-proposed

« back to all changes in this revision

Viewing changes to src/Configuration.cxx

  • Committer: Package Import Robot
  • Author(s): Ko van der Sloot
  • Date: 2013-04-18 15:14:58 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130418151458-o3zeb8f0676003y3
Tags: 0.4-3
debian/control: also added Replaces: libticcutils1-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  $Id: Configuration.cxx 15564 2013-01-07 14:25:32Z sloot $
 
3
  $URL: https://ilk.uvt.nl/svn/sources/libticcutils/trunk/src/Configuration.cxx $
 
4
  Copyright (c) 2006 - 2013
 
5
  Tilburg University
 
6
 
 
7
  This file is part of ticcutils.
 
8
 
 
9
  ticcutils is free software; you can redistribute it and/or modify
 
10
  it under the terms of the GNU General Public License as published by
 
11
  the Free Software Foundation; either version 3 of the License, or
 
12
  (at your option) any later version.
 
13
 
 
14
  ticcutils is distributed in the hope that it will be useful,
 
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
 
17
  GNU General Public License for more details.
 
18
 
 
19
  You should have received a copy of the GNU General Public License
 
20
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
 
 
22
  For questions and suggestions, see:
 
23
      http://ilk.uvt.nl/software.html
 
24
  or send mail to:
 
25
      timbl@uvt.nl
 
26
*/
 
27
 
 
28
#include <string>
 
29
#include <map>
 
30
#include <set>
 
31
#include <fstream>
 
32
#include <stdexcept>
 
33
#include <iostream>
 
34
#include "ticcutils/StringOps.h"
 
35
#include "ticcutils/Configuration.h"
 
36
 
 
37
using namespace std;
 
38
 
 
39
namespace TiCC {
 
40
  Configuration::Configuration(){
 
41
    myMap["global"] = ssMap();
 
42
  }
 
43
 
 
44
  string dirname( const string& f ){
 
45
    string::size_type pos = f.find_last_of("/");
 
46
    if ( pos != string::npos ){
 
47
      return f.substr( 0, pos+1 );
 
48
    }
 
49
    else 
 
50
    return ".";
 
51
  }
 
52
  
 
53
  string fixControl( const string& s, char c ){
 
54
    string sString;
 
55
    string rString;
 
56
    switch ( c ){
 
57
    case 't':
 
58
      sString = "\\t";
 
59
      rString = "\t";
 
60
      break;
 
61
    case 'r': 
 
62
      sString = "\\r";
 
63
      rString = "\r";
 
64
      break;
 
65
    case 'n': 
 
66
      sString = "\\n";
 
67
      rString = "\n";
 
68
      break;
 
69
    default:
 
70
      throw logic_error("invalid char for fixControl" );
 
71
    }
 
72
    string::size_type pos1 = s.find( sString );
 
73
    if ( pos1 == string::npos ){
 
74
      return s;
 
75
    }
 
76
    else {
 
77
      string result = s.substr( 0, pos1 );
 
78
      result += rString;
 
79
      string::size_type pos2 = s.find( sString, pos1+1 );
 
80
      while ( pos2 != string::npos ){
 
81
        result += s.substr( pos1+2, pos2-pos1-2 );
 
82
        result += rString;
 
83
        pos1 = pos2;
 
84
        pos2 = s.find( sString, pos1+1 );
 
85
      }
 
86
      result += s.substr( pos1+2 );
 
87
      return result;
 
88
    }
 
89
  }
 
90
  
 
91
  string fixControls( const string& s ){
 
92
    string result = s;
 
93
    result = fixControl( result, 'n' );
 
94
    result = fixControl( result, 'r' );
 
95
    result = fixControl( result, 't' );
 
96
    return result;
 
97
  }
 
98
  
 
99
  bool Configuration::fill( const string& fileName ){
 
100
    cdir = dirname( fileName );
 
101
    //  cerr << "dirname= " << cdir << endl;
 
102
    ifstream is( fileName.c_str() );
 
103
    if ( !is ){
 
104
      cerr << "unable to read configuration from " << fileName << endl;
 
105
      return false;
 
106
    }
 
107
    string inLine;
 
108
    string section = "global";
 
109
    while ( getline( is, inLine ) ){
 
110
      string line = TiCC::trim(inLine);
 
111
      if ( line.empty() )
 
112
        continue;
 
113
      if ( line[0] == '#' )
 
114
        continue;
 
115
      if ( line.find( "[[") == 0  ) 
 
116
        if ( line[line.length()-1] == ']' &&
 
117
             line[line.length()-2] == ']' ){
 
118
          section = line.substr(2,line.length()-4);
 
119
          //    cerr << "GOT section = " << section << endl;
 
120
        }
 
121
        else {
 
122
          cerr << "invalid section: in line '" << line << "'" << endl;
 
123
          return false;
 
124
        }
 
125
      else {
 
126
        vector<string> parts;
 
127
        int num = TiCC::split_at( line, parts, "=" );
 
128
        if ( num == 2 ){
 
129
          string val = parts[1];
 
130
          if ( val[0] == '"' && val[val.length()-1] == '"' )
 
131
            val = val.substr(1, val.length()-2);
 
132
          val = fixControls( val );
 
133
          myMap[section][parts[0]] = val;
 
134
          if ( section == "global" 
 
135
               && parts[0] == "configDir" )
 
136
            cdir = val;
 
137
        }
 
138
        else {
 
139
          cerr << "invalid attribute value pair in line '" << line << "'" << endl;
 
140
          return false;
 
141
        }
 
142
      }
 
143
    }
 
144
    return true;
 
145
  }
 
146
  
 
147
  bool Configuration::fill( const string& fileName, const string& section ){
 
148
    ifstream is( fileName.c_str() );
 
149
    if ( !is ){
 
150
      cerr << "unable to read configuration from " << fileName << endl;
 
151
      return false;
 
152
    }
 
153
    bool found = false;
 
154
    string inLine;
 
155
    string localsection;
 
156
    //  cerr << "looking for section = " << section << endl;
 
157
    while ( getline( is, inLine ) ){
 
158
      string line = TiCC::trim(inLine);
 
159
      if ( line.empty() )
 
160
        continue;
 
161
      if ( line[0] == '#' )
 
162
        continue;
 
163
      if ( line.find( "[[") == 0  ) 
 
164
        if ( line[line.length()-1] == ']' &&
 
165
             line[line.length()-2] == ']' ){
 
166
          localsection = line.substr(2,line.length()-4);
 
167
          //    cerr << "GOT section = " << localsection << endl;
 
168
        }
 
169
        else {
 
170
          cerr << "invalid section: in line '" << line << "'" << endl;
 
171
          return false;
 
172
        }
 
173
      else if ( localsection == section ){
 
174
        found = true;
 
175
        vector<string> parts;
 
176
        int num = TiCC::split_at( line, parts, "=" );
 
177
        if ( num == 2 ){
 
178
          string val = parts[1];
 
179
          if ( val[0] == '"' && val[val.length()-1] == '"' )
 
180
            val = val.substr(1, val.length()-2);
 
181
          myMap[section][parts[0]] = val;
 
182
        }
 
183
        else {
 
184
          cerr << "invalid attribute value pair in line '" << line << "'" << endl;
 
185
          return false;
 
186
        }
 
187
      }
 
188
    }
 
189
    if ( !found ){
 
190
      cerr << "unable to find a section [[" << section << "]] in file: "
 
191
           << fileName << endl;
 
192
      return false;
 
193
    }
 
194
    return true;
 
195
  }
 
196
  
 
197
  void Configuration::dump( ostream& os ) const {
 
198
    sssMap::const_iterator it1 = myMap.find("global");
 
199
    if ( it1 == myMap.end() ){
 
200
      os << "empty" << endl;
 
201
      return;
 
202
    }
 
203
    os << "[global]" << endl;
 
204
    os << "configDir=" << cdir << endl;
 
205
    ssMap::const_iterator it2 = it1->second.begin();
 
206
    while ( it2 != it1->second.end() ){
 
207
      os << it2->first << "=" << it2->second << endl;
 
208
      ++it2;
 
209
    }
 
210
    it1 = myMap.begin();
 
211
    while ( it1 != myMap.end() ){
 
212
      if ( it1->first != "global" ){
 
213
        os << "[" << it1->first << "]" << endl;
 
214
        it2 = it1->second.begin();
 
215
        while ( it2 != it1->second.end() ){
 
216
          os << it2->first << "=" << it2->second << endl;
 
217
          ++it2;
 
218
        }
 
219
      }
 
220
      ++it1;
 
221
    }
 
222
  }
 
223
  
 
224
  string Configuration::setatt( const string& att, 
 
225
                                const string& val,
 
226
                                const string& sect ){
 
227
    string oldVal;
 
228
    string section = sect;
 
229
    if ( section.empty() )
 
230
      section = "global";
 
231
    sssMap::iterator it1 = myMap.find( section );
 
232
    if ( it1 != myMap.end() ){
 
233
      ssMap::iterator it2 = it1->second.find( att );
 
234
      if ( it2 != it1->second.end() ){
 
235
        oldVal = it2->second;
 
236
      }
 
237
      it1->second[att] = val;
 
238
    }
 
239
    return oldVal;
 
240
  }
 
241
  
 
242
  string Configuration::lookUp( const string& att, const string& section ) const {
 
243
    sssMap::const_iterator it1;
 
244
    if ( section.empty() )
 
245
      it1 = myMap.find( "global" );
 
246
    else
 
247
      it1 = myMap.find( section );
 
248
    if ( it1 == myMap.end() ){
 
249
      return "";
 
250
    }
 
251
    else {
 
252
      ssMap::const_iterator it2 = it1->second.find( att );
 
253
      if ( it2 == it1->second.end() ){
 
254
        if ( section.empty() || section == "global" )
 
255
          return "";
 
256
        else
 
257
          return lookUp( att, "global" );
 
258
      }
 
259
      else
 
260
        return it2->second;
 
261
    }
 
262
  }
 
263
 
 
264
  map<string,string> Configuration::lookUpAll( const string& section ) const {
 
265
    map<string,string> result;
 
266
    sssMap::const_iterator it1;
 
267
    if ( section.empty() )
 
268
      it1 = myMap.find( "global" );
 
269
    else
 
270
      it1 = myMap.find( section );
 
271
    if ( it1 != myMap.end() ){
 
272
      ssMap::const_iterator it2 = it1->second.begin();
 
273
      while ( it2 != it1->second.end() ){
 
274
        result[it2->first] = it2->second;
 
275
        ++it2;
 
276
      }
 
277
    }
 
278
    return result;
 
279
  }
 
280
  
 
281
  set<string> Configuration::lookUpSections() const {
 
282
    set<string> result;
 
283
    result.insert("global");
 
284
    sssMap::const_iterator it = myMap.begin();
 
285
    while ( it != myMap.end() ){
 
286
      result.insert( it->first );
 
287
      ++it;
 
288
    }
 
289
    return result;
 
290
  }
 
291
  
 
292
  bool Configuration::hasSection( const string& section ) const {
 
293
    if ( !section.empty() ){
 
294
      sssMap::const_iterator it1 = myMap.find( section );
 
295
      if ( it1 != myMap.end() )
 
296
        return true;
 
297
    }
 
298
    return false;
 
299
  }
 
300
  
 
301
}