begin of config file parsing
Stefan Schuermans

Stefan Schuermans commited on 2017-06-08 19:55:08
Showing 3 changed files, with 264 additions and 2 deletions.

... ...
@@ -0,0 +1,183 @@
1
+/*
2
+ * EtherPix simulator
3
+ *
4
+ * Copyright 2017 Stefan Schuermans <stefan schuermans info>
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, version 3 of the License.
9
+ *
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public License
17
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+#include <algorithm>
21
+#include <cctype>
22
+#include <functional>
23
+#include <fstream>
24
+#include <stdexcept>
25
+#include <sstream>
26
+#include <string>
27
+
28
+#include "config.h"
29
+
30
+/**
31
+ * @brief constructor
32
+ * @param[in] configFile name of config file
33
+ */
34
+Config::Config(std::string const &configFile)
35
+{
36
+  readFile(configFile);
37
+}
38
+
39
+/**
40
+ * @brief remove whitespace at beging and end of string
41
+ * @param[in,out] str string to process
42
+ */
43
+void Config::trim(std::string &str)
44
+{
45
+  // remove leading whitespace
46
+  str.erase(str.begin(),
47
+            std::find_if(str.begin(), str.end(),
48
+                         std::not1(std::ptr_fun<int, int>(std::isspace))));
49
+
50
+  // remove trailing whitespace
51
+  str.erase(std::find_if(str.rbegin(), str.rend(),
52
+                         std::not1(std::ptr_fun<int, int>(std::isspace))).base(),
53
+            str.end());
54
+}
55
+
56
+/**
57
+ * @brief split string at sequences of whitespace
58
+ * @param[in] str string to split
59
+ * @param[out] fields fields of string
60
+ */
61
+void Config::split(std::string const &str, std::vector<std::string> &fields)
62
+{
63
+  std::stringstream strm(str);
64
+  fields.clear();
65
+  while (! strm.eof()) {
66
+    std::string field;
67
+    strm >> field;
68
+    if (! field.empty()) {
69
+      fields.push_back(field);
70
+    }
71
+  }
72
+}
73
+
74
+/**
75
+ * @brief read config file
76
+ * @param[in] configFile name of config file
77
+ * @throws std::exception in case of error
78
+ */
79
+void Config::readFile(std::string const &configFile)
80
+{
81
+  // open file
82
+  std::ifstream cf(configFile.c_str(), std::ios::in);
83
+  if (! cf.is_open()) {
84
+    std::stringstream msg;
85
+    msg << "cannot open config file \"" << configFile <<  "\" for reading";
86
+    throw std::runtime_error(msg.str());
87
+  }
88
+
89
+  // read lines and process them
90
+  std::string line;
91
+  size_t no;
92
+  for (no = 1; std::getline(cf, line); ++no) {
93
+    // process line
94
+    try {
95
+      procLine(line);
96
+    } catch (std::exception &ex) {
97
+      std::stringstream msg;
98
+      msg << "error in line " << no << " of config file \"" << configFile
99
+          << "\": " << ex.what();
100
+      throw std::runtime_error(msg.str());
101
+    }
102
+  }
103
+
104
+  // close file
105
+  cf.close();
106
+}
107
+
108
+/**
109
+ * @brief process line from config file
110
+ * @param[in] line line to process
111
+ * @throws std::exception in case of error
112
+ */
113
+void Config::procLine(std::string line)
114
+{
115
+  // remove comment ("# ...")
116
+  size_t commentStart = line.find("#");
117
+  if (commentStart != std::string::npos) {
118
+    line.erase(commentStart);
119
+  }
120
+
121
+  trim(line);
122
+
123
+  // ignore empty lines
124
+  if (line.empty()) {
125
+    return;
126
+  }
127
+
128
+  // split line at equal sign
129
+  size_t equalSign = line.find("=");
130
+  if (equalSign == std::string::npos) {
131
+    std::stringstream msg;
132
+    msg << "no equal sign found in \"" << line << "\"";
133
+    throw std::runtime_error(msg.str());
134
+  }
135
+  std::string setting = line.substr(0, equalSign);
136
+  std::string value = line.substr(equalSign + 1);
137
+  trim(setting);
138
+  trim(value);
139
+
140
+  procSetting(setting, value);
141
+}
142
+
143
+/**
144
+ * @brief process setting from config file
145
+ * @param[in] setting name of the setting
146
+ * @param[in] value value for setting
147
+ * @throws std::exception in case of error
148
+ */
149
+void Config::procSetting(std::string const &setting, std::string const &value)
150
+{
151
+  std::vector<std::string> setFields, valFields;
152
+  split(setting, setFields);
153
+  split(value, valFields);
154
+
155
+  // empty setting
156
+  if (setFields.size() < 1) {
157
+    throw std::runtime_error("empty setting name");
158
+  }
159
+
160
+  // distributor
161
+  if (setFields[0] == "distributor") {
162
+    // TODO
163
+  }
164
+  // distributor address
165
+  else if (setFields[0] == "distributorAddr") {
166
+    // TODO
167
+  }
168
+  // mapping
169
+  else if (setFields[0] == "mapping") {
170
+    // TODO
171
+  }
172
+  // output
173
+  else if (setFields[0] == "output") {
174
+    // TODO
175
+  }
176
+  // unknown setting
177
+  else {
178
+    std::stringstream msg;
179
+    msg << "unknown setting \"" << setting << "\"";
180
+    throw std::runtime_error(msg.str());
181
+  }
182
+}
183
+
... ...
@@ -0,0 +1,75 @@
1
+/*
2
+ * EtherPix simulator
3
+ *
4
+ * Copyright 2017 Stefan Schuermans <stefan schuermans info>
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation, version 3 of the License.
9
+ *
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public License
17
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ */
19
+
20
+#ifndef CONFIG_H
21
+#define CONFIG_H
22
+
23
+#include <string>
24
+#include <vector>
25
+
26
+/// config file
27
+class Config
28
+{
29
+public:
30
+  /**
31
+   * @brief constructor
32
+   * @param[in] configFile name of config file
33
+   */
34
+  Config(std::string const &configFile);
35
+
36
+protected:
37
+  /**
38
+   * @brief remove whitespace at beging and end of string
39
+   * @param[in,out] str string to process
40
+   */
41
+  static void trim(std::string &str);
42
+
43
+  /**
44
+   * @brief split string at sequences of whitespace
45
+   * @param[in] str string to split
46
+   * @param[out] fields fields of string
47
+   */
48
+  static void split(std::string const &str, std::vector<std::string> &fields);
49
+
50
+  /**
51
+   * @brief read config file
52
+   * @param[in] configFile name of config file
53
+   * @throws std::exception in case of error
54
+   */
55
+  void readFile(std::string const &configFile);
56
+
57
+  /**
58
+   * @brief process line from config file
59
+   * @param[in] line line to process
60
+   * @throws std::exception in case of error
61
+   */
62
+  void procLine(std::string line);
63
+
64
+  /**
65
+   * @brief process setting from config file
66
+   * @param[in] setting name of the setting
67
+   * @param[in] value value for setting
68
+   * @throws std::exception in case of error
69
+   */
70
+  void procSetting(std::string const &setting, std::string const &value);
71
+
72
+};
73
+
74
+#endif // #ifndef CONFIG_H
75
+
... ...
@@ -21,6 +21,7 @@
21 21
 #include <iostream>
22 22
 #include <string.h>
23 23
 
24
+#include "config.h"
24 25
 #include "etherpix_sim.glade.h"
25 26
 #include "main_window.h"
26 27
 
... ...
@@ -34,10 +35,13 @@ int main(int argc, char *argv[])
34 35
     std::cerr << "usage: " << argv[0] << " <sim_config.etps>" << std::endl;
35 36
     return 2;
36 37
   }
37
-  char *config_file_name = argv[1];
38
+  char *configFile = argv[1];
38 39
 
39 40
   try {
40 41
 
42
+    // parse config file
43
+    Config config(configFile);
44
+
41 45
     // create window
42 46
     Glib::RefPtr<Gtk::Builder> builder =
43 47
       Gtk::Builder::create_from_string(widgets_etherpix_sim);
... ...
@@ -47,7 +51,7 @@ int main(int argc, char *argv[])
47 51
     builder->get_widget_derived("MainWindow", mainWindow);
48 52
 
49 53
     // append config file name to window title
50
-    mainWindow->set_title(mainWindow->get_title() + " - " + config_file_name);
54
+    mainWindow->set_title(mainWindow->get_title() + " - " + configFile);
51 55
 
52 56
     // run GTK main loop
53 57
     Gtk::Main::run();
54 58