-
Notifications
You must be signed in to change notification settings - Fork 1
/
config_magr2.cpp
157 lines (122 loc) · 3.75 KB
/
config_magr2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <fstream>
#include <iostream>
#include "config_magr2.hpp"
config_mgr2::config_mgr2(std::string const& extension)
{
//! save file extension;
file_extension = extension;
//! open the configuration file
std::string configFile =extension;
std::ifstream file(configFile.c_str());
if (!file.good())
{
std::string msg = "configuration file <" + configFile + "> not opened";
error(class_name(),"scan", msg, 1);
}
//! clear the vector of tags
tags.clear();
std::string line;
std::string input_line;
std::string name;
std::string value;
std::string current_section;
std::string section_end;
int posEqual;
while (std::getline(file,input_line))
{
//! clear the line from leading and trailing spaces
line=trim(input_line);
//! does not consider empty lines
if (!line.length()) continue;
//! does not consider comments
if (line[0] == '#') continue;
if (line[0] == ';') continue;
//! check for the start/end of a section
if (input_line[0] == '<')
{
//! check if is an end
if (input_line[1]=='/')
{
//! end of a section
section_end=trim(line.substr(2,line.find('>')-2));
//cout << "*** " << current_section << endl;
//cout << "*** " << section_end << endl;
if (section_end!=current_section)
{
std::string msg = "section <"+current_section+"> ends with </"+section_end+">";
error(class_name(),"constructor", msg, 1);
} else {
//! clear current section
current_section = "";
}
} else {
//! start of a new section
if (current_section!="")
{
error(class_name(),"constructor", "nested section in <"+current_section+">", 1);
}
//! begin of a section
current_section=trim(line.substr(1,line.find('>')-1));
tags.push_back(current_section);
//! check for '/' symbols in tags
if (current_section.find('/')!=std::string::npos)
{
std::string msg = "symbol '/' not allowed in tag " + section_end;
error(class_name(),"constructor", msg, 1);
}
}
continue;
}
posEqual=line.find('=');
if (posEqual==std::string::npos)
{
std::string msg = "configuration entry <" + line + "> not a comment, not a tag, not an assignment";
error(class_name(),"constructor", msg, 1);
}
name = trim(line.substr(0,posEqual));
value = trim(line.substr(posEqual+1));
content_[current_section+'/'+name]=generic(value);
}
}
void config_mgr2::save(std::ostream &output) const
{
for(auto tag = tags.begin(); tag!=tags.end(); tag++)
{
std::string current_tag = *tag;
output << "<" << current_tag << ">" << std::endl;
for(auto i=content_.begin();i!=content_.end();i++)
{
std::string s = i->first;
std::string t = s.substr(0,s.find('/')); //! tag in list
std::string p = s.substr(s.find('/')+1); //! associated generic
generic v = i->second; //! associated value
if (current_tag == t)
{
output << "\t" << p << " = " << v << std::endl;
}
}
output << "</" << current_tag << ">" << std::endl;
}
}
generic const& config_mgr2::Value(std::string const& section, std::string const& entry) const
{
auto ci = content_.find(section + '/' + entry);
if (ci == content_.end()) throw std::string(entry).c_str();
return ci->second;
}
generic const& config_mgr2::Value(std::string const& section, std::string const& entry, double value)
{
try {
return Value(section, entry);
} catch(const char*) {
return content_.insert(std::make_pair(section+'/'+entry, generic(value))).first->second;
}
}
generic const& config_mgr2::Value(std::string const& section, std::string const& entry, std::string const& value)
{
try {
return Value(section, entry);
} catch(const char*) {
return content_.insert(std::make_pair(section+'/'+entry, generic(value))).first->second;
}
}