Belle II Software development
ConfigFile.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include "daq/slc/base/ConfigFile.h"
9
10#include "daq/slc/base/StringUtil.h"
11
12#include <cstdlib>
13#include <cstring>
14#include <fstream>
15#include <iostream>
16#include <sstream>
17
18using namespace Belle2;
19
20const std::string ConfigFile::getFilePath(const std::string& filename_in)
21{
22 std::string filename = filename_in;
23 if (filename == "slowcontrol") {
24 /*
25 char* hostname = getenv("HOSTNAME");
26 if (hostname != NULL && std::string(hostname).find("hlt") != std::string::npos) {
27 filename = "slowcontrol.hlt";
28 }
29 */
30 char* slcfile = getenv("BELLE2_SLC_FILE");
31 if (slcfile != NULL && strlen(slcfile) > 0) {
32 filename = slcfile;
33 }
34 }
35 std::string file_path;
36 if (filename.size() > std::string(".conf").size() + 1 &&
37 StringUtil::find(filename, ".conf")) {
38 return filename;
39 }
40 if (filename.at(0) != '/') {
41 char* path = getenv("BELLE2_DAQ_SLC");
42 if (path == NULL) {
43 path = getenv("BELLE2_LOCAL_DIR");
44 if (path == NULL) {
45 exit(1);
46 }
47 file_path = path;
48 file_path += "/daq/slc/";
49 } else {
50 file_path = path;
51 }
52 if (filename.find("/") == std::string::npos) {
53 file_path += "/data/config/" + filename + ".conf";
54 } else {
55 file_path += "/data/" + filename + ".conf";
56 }
57 } else {
58 file_path = filename;
59 }
60 return file_path;
61}
62
63void ConfigFile::read(const std::string& filename, bool overload)
64{
65 if (filename.size() == 0) return;
66 std::ifstream fin(getFilePath(filename).c_str());
67 read(fin, overload);
68 fin.close();
69}
70
71void ConfigFile::read(std::istream& is, bool overload)
72{
73 std::string s;
74 std::string dir = "";
75 while (is && getline(is, s)) {
76 if (s.size() == 0 || s.at(0) == '#') continue;
77 std::vector<std::string> str_v = StringUtil::split(s, ':');
78 if (str_v.size() >= 2) {
79 std::string label = StringUtil::replace(StringUtil::replace(str_v[0],
80 " ", ""), "\t", "");
81 if (label.find("[]") != std::string::npos) {
82 if (m_count.find(label) == m_count.end()) {
83 m_count.insert(std::pair<std::string, int>(label, 0));
84 }
85 std::string l = label;
86 label = StringUtil::replace(label, "[]", StringUtil::form("[%d]", m_count[l]));
87 m_count[l] = m_count[l] + 1;
88 }
89 if (str_v.size() > 2) {
90 for (size_t i = 2; i < str_v.size(); i++) {
91 str_v[1].append(":");
92 str_v[1].append(str_v[i]);
93 }
94 }
95 std::string value = "";
96 size_t i = 0;
97 std::stringstream ss;
98 for (; i < str_v[1].size(); i++) {
99 if (str_v[1].at(i) == '#' || str_v[1].at(i) == '\n') break;
100 if (str_v[1].at(i) == ' ' || str_v[1].at(i) == '\t') continue;
101 if (str_v[1].at(i) == '"') {
102 for (i++ ; i < str_v[1].size(); i++) {
103 if (str_v[1].at(i) == '"') break;
104 ss << str_v[1].at(i);
105 }
106 break;
107 }
108 if (str_v[1].at(i) == '$') {
109 i++;
110 if (str_v[1].at(i) == '{') {
111 for (i++ ; i < str_v[1].size(); i++) {
112 if (str_v[1].at(i) == '}') break;
113 ss << str_v[1].at(i);
114 }
115 }
116 std::string tmp = ss.str();
117 const char* env = getenv(tmp.c_str());
118 ss.str("");
119 if (env != NULL) {
120 ss << env;
121 } else if (m_value_m.find(tmp) != m_value_m.end()) {
122 ss << m_value_m[tmp];
123 }
124 continue;
125 }
126 ss << str_v[1].at(i);
127 }
128 add(label, ss.str(), overload);
129 }
130 }
131}
132
133void ConfigFile::clear()
134{
135 m_value_m.clear();
136}
137
138const std::string ConfigFile::get(const std::string& label)
139{
140 if (m_value_m.find(label) != m_value_m.end()) {
141 return m_value_m[label];
142 }
143 return "";
144}
145
146int ConfigFile::getInt(const std::string& label)
147{
148 std::string value = get(label);
149 if (value.size() > 0) return atoi(value.c_str());
150 else return 0;
151}
152
153bool ConfigFile::getBool(const std::string& label)
154{
155 std::string value = get(label);
156 if (value.size() > 0) return StringUtil::tolower(value) == "true";
157 else return false;
158}
159
160double ConfigFile::getFloat(const std::string& label)
161{
162 std::string value = get(label);
163 if (value.size() > 0) return atof(value.c_str());
164 else return 0;
165}
166
167void ConfigFile::add(const std::string& label,
168 const std::string& value, bool overload)
169{
170 if (m_value_m.find(label) == m_value_m.end()) {
171 m_value_m.insert(ValueList::value_type(label, value));
172 m_label_v.push_back(label);
173 } else if (overload) {
174 m_value_m[label] = value;
175 }
176}
177
178void ConfigFile::write(const std::string& path)
179{
180 std::stringstream ss;
181 ss << "#" << std::endl
182 << "#" << std::endl
183 << "#" << std::endl
184 << "" << std::endl;
185 for (std::vector<std::string>::iterator it = m_label_v.begin();
186 it != m_label_v.end(); ++it) {
187 std::string& label(*it);
188 std::string& value(m_value_m[label]);
189 ss << label << " : " << value << std::endl;
190 }
191 ss << "" << std::endl
192 << "#" << std::endl
193 << "#" << std::endl
194 << "#" << std::endl;
195 std::ofstream fout(getFilePath(path).c_str());
196 fout << ss.str();
197}
198
199void ConfigFile::print()
200{
201 std::cout << "#" << std::endl
202 << "#" << std::endl
203 << "#" << std::endl
204 << "" << std::endl;
205 for (std::vector<std::string>::iterator it = m_label_v.begin();
206 it != m_label_v.end(); ++it) {
207 std::string& label(*it);
208 std::string& value(m_value_m[label]);
209 std::cout << label << " : " << value << std::endl;
210 }
211 std::cout << "" << std::endl
212 << "#" << std::endl
213 << "#" << std::endl
214 << "#" << std::endl;
215}
Abstract base class for different kinds of events.