Elaboradar 0.1
Caricamento in corso...
Ricerca in corso...
Nessun risultato
config.cpp
1#include "config.h"
2#include <unordered_set>
3#include <fstream>
4#include <sstream>
5#include <cstdlib>
6#include <cctype>
7
8using namespace std;
9
10namespace elaboradar {
11
12namespace {
13
14struct ConfigValue
15{
16 const char* key; // Config key
17 const char* env; // Environment variable name
18 const char* def; // Default value
19
20 ConfigValue(const char* key, const char* env, const char* def=0)
21 : key(key), env(env), def(def) {}
22
23};
24
25ConfigValue config_layout[] = {
26 { "file/first_level", "FIRST_LEVEL_FILE" },
27 { "file/vpr_heating", "VPR_HEATING" },
28};
29
31std::string trim(const std::string s)
32{
33 if (s.empty()) return s;
34
35 size_t start = 0;
36 size_t end = s.size() - 1;
37 while (start < end && isspace(s[start]))
38 ++start;
39 while (end > start && isspace(s[end]))
40 --end;
41
42 if (start == end) return string();
43 if (start == 0 && end == s.size() - 1) return s;
44 return s.substr(start, end - start);
45}
46
48bool is_empty(const std::string& line)
49{
50 for (auto i : line)
51 {
52 if (isspace(i)) continue;
53 if (i == '#') return true;
54 return false;
55 }
56 return true;
57}
58
59}
60
61void Config::set_defaults()
62{
63 for (auto v : config_layout)
64 {
65 if (!v.def) continue;
66 values[v.key] = v.def;
67 }
68}
69
70void Config::read_env()
71{
72 for (auto v : config_layout)
73 {
74 if (!v.env) continue;
75 const char* val = getenv(v.env);
76 if (val == NULL) continue;
77 values[v.key] = val;
78 }
79}
80
81void Config::read_file(const std::string& fname)
82{
83 ifstream in(fname);
84 string line;
85 unsigned lineno = 0;
86
87 // Whitelist of valid keys
88 unordered_set<string> valid_keys;
89 for (auto v : config_layout)
90 valid_keys.insert(v.key);
91
92 while (getline(in, line))
93 {
94 ++lineno;
95 if (is_empty(line)) continue;
96
97 size_t pos = line.find('=');
98 if (pos == string::npos)
99 {
100 stringstream s;
101 s << fname << ":" << lineno << ": unparsed line (not empty, a comment or key = value)";
102 throw runtime_error(s.str());
103 }
104 string key = trim(line.substr(0, pos));
105 string val = trim(line.substr(pos+1));
106 if (valid_keys.find(key) == valid_keys.end())
107 {
108 stringstream s;
109 s << fname << ":" << lineno << ": unsupported key '" << key << "'";
110 throw runtime_error(s.str());
111 }
112 values[key] = val;
113 }
114}
115
116bool Config::has(const std::string& key) const
117{
118 return values.find(key) != values.end();
119}
120
121std::string Config::get(const std::string& key) const
122{
123 auto res = values.find(key);
124 if (res == values.end()) throw std::runtime_error("configuration key " + key + " not found");
125 return res->second;
126}
127
128std::string Config::get(const std::string& key, const std::string& deflt) const
129{
130 auto res = values.find(key);
131 if (res == values.end()) return deflt;
132 return res->second;
133}
134
135int Config::get_int(const std::string& key) const
136{
137 auto res = values.find(key);
138 if (res == values.end()) throw std::runtime_error("configuration key " + key + " not found");
139 return stoi(res->second);
140}
141
142int Config::get_int(const std::string& key, int deflt) const
143{
144 auto res = values.find(key);
145 if (res == values.end()) return deflt;
146 return stoi(res->second);
147}
148
149double Config::get_double(const std::string& key) const
150{
151 auto res = values.find(key);
152 if (res == values.end()) throw std::runtime_error("configuration key " + key + " not found");
153 return stod(res->second);
154}
155
156double Config::get_double(const std::string& key, double deflt) const
157{
158 auto res = values.find(key);
159 if (res == values.end()) return deflt;
160 return stod(res->second);
161}
162
163}
name space generale del programma
Definition assets.h:28