Initfile.cc 6.26 KB
Newer Older
Praetorius, Simon's avatar
Praetorius, Simon committed
1
2
3
4
5
6
7
8
#include "Initfile.h"

#include <string>
#include <stdexcept>
#include <iostream>
#include <sstream>
using namespace std;

9
10
namespace AMDiS {

11
12
  /// the small parser for the initfile. see description of 
  /// read(Initfile&,istream&)
13
14
15
16
  struct Parser {
    Parser(const string& line) 
    {
      size_t pos = line.find(':');
17
      if (pos == string::npos) {
18
19
	throw runtime_error("cannot find the delimiter ':' in line "
			    "'" + line + "'");
20
      }
21
22
23
24
25
26
      name = line.substr(0, pos);
      value = line.substr(pos + 1, line.length() - (pos + 1));

      // remove everything after the %
      pos = value.find('%');
      if (pos != string::npos)
27
        value = value.substr(0, pos);      
28
29
30
31
32
    }
    string name;
    string value;
  };

33

34
  Initfile* Initfile::singlett = NULL;
35
36
37
38
39
40
41
42
43
44
45
  std::set<std::string> Initfile::fn_include_list;


  /// initialize singleton object an global parameters
  void Initfile::init(std::string in)
  {
    initIntern();
    singlett->clear();
    fn_include_list.clear();
    singlett->read(in);	
    singlett->getInternalParameters();
46

47
48
    // initialize global strcutures using parameters
    Global::init();
49
  }
50
51
52


  /// Fill an initfile from a file with filename fn
53
  void Initfile::read(std::string fn, bool force)
54
55
  {
    // read file if its not parsed already
56
    if (fn_include_list.find(fn) == fn_include_list.end() || force) {
57
58
59
      std::ifstream inputFile;
      inputFile.open(fn.c_str(), std::ios::in);
      if (!inputFile.is_open())
60
	throw runtime_error("init-file '" + fn + "' cannot be opened for reading");
61

62
63
64
      fn_include_list.insert(fn);
      read(inputFile);
    }
65
  }
66
67
68
69
70


  /// Fill an initfile from an input stream
  void Initfile::read(istream& in) 
  {
71
    unsigned line_length = 512;
72
73
    char swap[line_length];
    in.getline(swap, line_length);
74
    while (in.good() || in.gcount() > 0) {
75
      std::string whitespaces = " \t\r\f\n";
76
77
      std::string sw(swap);
      size_t pos0 = sw.find_first_not_of(whitespaces);
78

79
80
81
82
      if (pos0 != std::string::npos
          && sw[pos0] != '%' 
          && sw[pos0] != '#'
          && sw[pos0] != 0) {
83
84
        // parse line and extract map: tag->value
        Parser parser(sw);
85
        
86
        // add parameter to map after variable replacement
87
88
89
        std::string paramName = variableReplacement(InitfileInternal::trim(parser.name));
        std::string paramValue = variableReplacement(InitfileInternal::trim(parser.value));
        operator[](paramName) = paramValue;
90
#ifndef DEBUG
91
92
93
        int info = 0;
        get("parameter information", info, 0);
        if (info >= 2)
94
#endif
Praetorius, Simon's avatar
Praetorius, Simon committed
95
        {
96
          std::cout << "read [" << paramName << " => " << paramValue << "]" << std::endl;
Praetorius, Simon's avatar
Praetorius, Simon committed
97
        }
98
99
100
      } else if (pos0 != std::string::npos &&
		 sw[pos0] == '#'  &&
		 static_cast<size_t>(sw.find("#include")) == pos0) {
101
        // include file by '#include "filename"' or '#include <filename>'
102
103
104
105
106
107
        bool forceRead = false;
        int posAdd = 1;
        if (sw[pos0 + std::string("#include").size()] == '!') {
          forceRead = true;
          posAdd++;
        }
108
        size_t pos = sw.find_first_not_of(whitespaces, 
109
          pos0 + std::string("#include").size() + posAdd);
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
        size_t epos = 0;
        std::string fn =  "";
        std::stringstream errorMsg;
        switch (char c= swap[pos++]) {
          case '<':
            c= '>';
          case '\"':
            whitespaces += c;
            epos = sw.find_first_of(whitespaces, pos);
            fn = sw.substr(pos, epos - pos);

            if (sw[epos]!=c) {
              errorMsg << "filename in #include not terminated by " << c;
              throw std::runtime_error(errorMsg.str());
            }
            break;
          default:
            throw std::runtime_error("no filename given for #include");
        }
129
        read(fn, forceRead);
130
      }
131

132
133
      in.getline(swap, line_length);
    }
134
  }
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153


  std::string Initfile::variableReplacement(const std::string& input) const
  {
    std::string whitespaces = " \t\r\f";
    std::string inputSwap = input; 
    size_t posVar = inputSwap.find_first_of('$');
    while (posVar != string::npos) {
      size_t posVarBegin, posVarEnd;
      if(inputSwap[posVar+1] == '{') {
        posVarEnd = inputSwap.find_first_of('}',posVar + 2);
        posVarBegin = posVar + 1;
      } else {
        posVarEnd = inputSwap.find_first_of(whitespaces, posVar + 1);
        posVarBegin = posVar;
      }
      std::string varName = inputSwap.substr(posVarBegin + 1 , posVarEnd - posVarBegin - 1);
      std::string varParam = checkedGet(varName);
      // if varname is found in parameter list then replace variable by value
154
      // otherwise throw tagNotFound exception
155
156
157
158
159
160
161
      std::string replaceName = inputSwap.substr(posVar , posVarEnd - posVar + (posVarBegin - posVar));
      inputSwap.replace(inputSwap.find(replaceName), replaceName.length(), varParam);

      posVar = inputSwap.find_first_of('$');
    }

    return inputSwap;
162
  }
163

164
165
166
167
168

  void Initfile::readArgv(int argc, char **argv)
  {
    for (int i = 0; i < argc; i++) {
      if (strcmp("-rs", argv[i]) == 0) {
169
170
        std::string input(argv[i + 1]);
        add("argv->rs", input, 0);
171
172
173
174
175
176
177
178
179
180
181
      }
    }
  }


  /// read standard values for output and information of parameter-values
  void Initfile::getInternalParameters() 
  {
    int val = 0;
    get("level of information", val, 0);
    msgInfo = val;
182

183
184
185
    val = 1;
    get("WAIT", val, 0);
    msgWait = val;
186

187
188
189
    val = 1;
    get("parameter information", val, 0);
    paramInfo = val;
190

191
192
193
194
195
196
    val = 0;
    get("break on missing tag", val, 0);
    breakOnMissingTag = val;

    if (msgInfo == 0)
      paramInfo = 0;
197
  }
198
199
200
201
202
203
204


  /// print all parameters to std::cout
  void Initfile::printParameters() 
  {
    initIntern();
    for (Initfile::iterator it = singlett->begin(); it != singlett->end(); it++)
205
      std::cout << (*it).first << " => " << (*it).second << std::endl;
206
  }
207
208
209
210
211
212


  /// Write data-map to initfile
  void Initfile::write(ostream& out)
  {
    for (Initfile::iterator it = begin() ; it!=end(); it++)
213
      out << (*it).first << ": " << (*it).second << std::endl;	
214
215
216
217
218
219
220
221
222
223
  }


  /// Write data-map to initfile
  void Initfile::write(std::string fn) 
  {
    std::ofstream outFile;
    outFile.open(fn.c_str(), std::ios::out);
    if (!outFile.is_open())
      throw runtime_error("init-file cannot be opened for writing");
224

225
226
    write(outFile);
  }
227
} // end namespace AMDiS