MRPT  2.0.1
CConfigFileBase.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "config-precomp.h" // Precompiled headers
11 
13 #include <mrpt/core/exceptions.h>
14 #include <mrpt/core/format.h>
15 #include <mrpt/system/os.h>
17 #include <cmath> // abs()
18 
19 #include <mrpt/config.h>
20 #if MRPT_HAS_YAMLCPP
21 #include <yaml-cpp/yaml.h>
22 #endif
23 
24 using namespace std;
25 using namespace mrpt::config;
26 using namespace mrpt::system;
27 using mrpt::format;
28 
29 static int MRPT_SAVE_NAME_PADDING = 50;
30 static int MRPT_SAVE_VALUE_PADDING = 20;
33 {
35 }
36 
37 CConfigFileBase::~CConfigFileBase() = default;
38 void CConfigFileBase::write(
39  const std::string& section, const std::string& name, double value,
40  const int name_padding_width, const int value_padding_width,
41  const std::string& comment)
42 {
43  writeString(
44  section, name,
45  format(
46  ((std::abs(value) > 1e-4 && std::abs(value) < 1e4) || value == .0)
47  ? "%f"
48  : "%e",
49  value),
50  name_padding_width, value_padding_width, comment);
51 }
52 void CConfigFileBase::write(
53  const std::string& section, const std::string& name, float value,
54  const int name_padding_width, const int value_padding_width,
55  const std::string& comment)
56 {
57  writeString(
58  section, name,
59  format(
60  ((std::abs(value) > 1e-4f && std::abs(value) < 1e4f) ||
61  value == .0f)
62  ? "%f"
63  : "%e",
64  value),
65  name_padding_width, value_padding_width, comment);
66 }
67 
68 /** Write a generic string with optional padding and a comment field ("// ...")
69  * at the end of the line. */
70 void CConfigFileBase::writeString(
71  const std::string& section, const std::string& name, const std::string& str,
72  const int name_padding_width, const int value_padding_width,
73  const std::string& comment)
74 {
75  if (name_padding_width < 1 && value_padding_width < 1 && comment.empty())
76  this->writeString(section, name, str); // Default (old) behavior.
77 
78  std::string name_pad;
79  if (name_padding_width >= 1)
80  name_pad = mrpt::format(
81  "%*s", -name_padding_width,
82  name.c_str()); // negative width: printf right padding
83  else
84  name_pad = name;
85 
86  std::string value_pad;
87  if (value_padding_width >= 1)
88  value_pad = mrpt::format(
89  " %*s", -value_padding_width,
90  str.c_str()); // negative width: printf right padding
91  else
92  value_pad = str;
93 
94  if (!comment.empty())
95  {
96  value_pad += std::string(" // ");
97  value_pad += comment;
98  }
99 
100  this->writeString(section, name_pad, value_pad);
101 }
102 
103 /*---------------------------------------------------------------
104  read_double
105  ---------------------------------------------------------------*/
106 double CConfigFileBase::read_double(
107  const std::string& section, const std::string& name, double defaultValue,
108  bool failIfNotFound) const
109 {
110  return atof(
111  readString(section, name, format("%.16e", defaultValue), failIfNotFound)
112  .c_str());
113 }
114 
115 /*---------------------------------------------------------------
116  read_float
117  ---------------------------------------------------------------*/
118 float CConfigFileBase::read_float(
119  const std::string& section, const std::string& name, float defaultValue,
120  bool failIfNotFound) const
121 {
122  return (float)atof(
123  readString(section, name, format("%.10e", defaultValue), failIfNotFound)
124  .c_str());
125 }
126 
127 /*---------------------------------------------------------------
128  read_int
129  ---------------------------------------------------------------*/
130 int CConfigFileBase::read_int(
131  const std::string& section, const std::string& name, int defaultValue,
132  bool failIfNotFound) const
133 {
134  return atoi(
135  readString(section, name, format("%i", defaultValue), failIfNotFound)
136  .c_str());
137 }
138 
139 /*---------------------------------------------------------------
140  read_uint64_t
141  ---------------------------------------------------------------*/
142 uint64_t CConfigFileBase::read_uint64_t(
143  const std::string& section, const std::string& name, uint64_t defaultValue,
144  bool failIfNotFound) const
145 {
146  string s = readString(
147  section, name, format("%lu", (long unsigned int)defaultValue),
148  failIfNotFound);
149  return mrpt::system::os::_strtoull(s.c_str(), nullptr, 0);
150 }
151 
152 /*---------------------------------------------------------------
153  read_bool
154  ---------------------------------------------------------------*/
155 bool CConfigFileBase::read_bool(
156  const std::string& section, const std::string& name, bool defaultValue,
157  bool failIfNotFound) const
158 {
159  const string s = mrpt::system::lowerCase(trim(readString(
160  section, name, string(defaultValue ? "1" : "0"), failIfNotFound)));
161  if (s == "true") return true;
162  if (s == "false") return false;
163  if (s == "yes") return true;
164  if (s == "no") return false;
165  return (0 != atoi(s.c_str()));
166 }
167 
168 /*---------------------------------------------------------------
169  read_string
170  ---------------------------------------------------------------*/
171 std::string CConfigFileBase::read_string(
172  const std::string& section, const std::string& name,
173  const std::string& defaultValue, bool failIfNotFound) const
174 {
175  return mrpt::system::trim(
176  readString(section, name, defaultValue, failIfNotFound));
177 }
178 
179 /*---------------------------------------------------------------
180  read_string_first_word
181  ---------------------------------------------------------------*/
182 std::string CConfigFileBase::read_string_first_word(
183  const std::string& section, const std::string& name,
184  const std::string& defaultValue, bool failIfNotFound) const
185 {
186  string s = readString(section, name, defaultValue, failIfNotFound);
187  std::vector<std::string> auxStrs;
188  mrpt::system::tokenize(s, "[], \t", auxStrs);
189  if (auxStrs.empty())
190  {
191  if (failIfNotFound)
192  {
194  "Value '%s' seems to be present in section '%s' but, are "
195  "all whitespaces??",
196  name.c_str(), section.c_str()));
197  }
198  else
199  return "";
200  }
201  else
202  return auxStrs[0];
203 }
204 
205 bool CConfigFileBase::sectionExists(const std::string& section_name) const
206 {
207  std::vector<std::string> sects;
208  getAllSections(sects);
209  for (auto& sect : sects)
210  if (!mrpt::system::os::_strcmpi(section_name.c_str(), sect.c_str()))
211  return true;
212  return false;
213 }
214 
215 bool CConfigFileBase::keyExists(
216  const std::string& section, const std::string& key) const
217 {
218  std::vector<std::string> keys;
219  getAllKeys(section, keys);
220  for (auto& k : keys)
221  if (!mrpt::system::os::_strcmpi(key.c_str(), k.c_str())) return true;
222  return false;
223 }
224 
225 void CConfigFileBase::setContentFromYAML(const std::string& yaml_block)
226 {
227  MRPT_START
228 #if MRPT_HAS_YAMLCPP
229  this->clear();
230 
231  YAML::Node root = YAML::Load(yaml_block);
232 
233  // Prepare all data here, then insert into the actual INI file at the end,
234  // to ensure that unscoped variables get first.
235  using key_values_t = std::map<std::string, std::string>;
236  key_values_t unscoped;
237  std::map<std::string, key_values_t> sections;
238 
239  for (const auto& sect : root)
240  {
241  const auto sectName = sect.first.as<std::string>();
242  // YAML Type: sect.first.Type()
243 
244  if (sect.second.size() >= 1)
245  {
246  // A section:
247  for (const auto& kv : sect.second)
248  {
249  const auto key = kv.first.as<std::string>();
250  const auto val = kv.second.as<std::string>();
251  sections[sectName].emplace(key, val);
252  }
253  }
254  else
255  {
256  // an unscoped key-value:
257  const auto key = sect.first.as<std::string>();
258  const auto val = sect.second.as<std::string>();
259  unscoped.emplace(key, val);
260  }
261  }
262 
263  // 1st: unscoped:
264  for (const auto& kv : unscoped) this->write("", kv.first, kv.second);
265 
266  for (const auto& sect : sections)
267  for (const auto& kv : sect.second)
268  this->write(sect.first, kv.first, kv.second);
269 
270 #else
272  "This method requires building MRPT with yaml-cpp support.");
273 #endif
274  MRPT_END
275 }
276 
277 std::string CConfigFileBase::getContentAsYAML() const
278 {
279  MRPT_START
280 #if MRPT_HAS_YAMLCPP
281  YAML::Node n;
282 
283  // Sections:
284  std::vector<std::string> lstSects;
285  getAllSections(lstSects);
286 
287  // Unscoped: "" empty section name:
288  lstSects.insert(lstSects.begin(), std::string());
289 
290  // Go thru values:
291  for (const auto& sect : lstSects)
292  {
293  std::vector<std::string> keys;
294  getAllKeys(sect, keys);
295  for (const auto& k : keys)
296  {
297  const auto val = this->readString(sect, k, "");
298  if (sect.empty())
299  n[k] = val;
300  else
301  n[sect][k] = val;
302  }
303  }
304 
305  // Convert to string:
306  std::stringstream ss;
307  ss << n;
308  return ss.str();
309 #else
311  "This method requires building MRPT with yaml-cpp support.");
312 #endif
313  MRPT_END
314 }
#define MRPT_START
Definition: exceptions.h:241
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
int MRPT_SAVE_NAME_PADDING()
Default padding sizes for macros MRPT_SAVE_CONFIG_VAR_COMMENT(), etc.
STL namespace.
void tokenize(const std::string &inString, const std::string &inDelimiters, OUT_CONTAINER &outTokens, bool skipBlankTokens=true) noexcept
Tokenizes a string according to a set of delimiting characters.
std::string lowerCase(const std::string &str)
Returns an lower-case version of a string.
int val
Definition: mrpt_jpeglib.h:957
int MRPT_SAVE_VALUE_PADDING()
static std::string & trim(std::string &s)
constexpr auto sect
static int MRPT_SAVE_VALUE_PADDING
#define MRPT_END
Definition: exceptions.h:245
uint64_t _strtoull(const char *nptr, char **endptr, int base)
An OS-independent version of strtoull.
Definition: os.cpp:466
std::string trim(const std::string &str)
Removes leading and trailing spaces.
static int MRPT_SAVE_NAME_PADDING
void clear()
Clear the contents of this container.
Definition: ts_hash_map.h:183
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.
Definition: os.cpp:320



Page generated by Doxygen 1.8.14 for MRPT 2.0.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020