MRPT  1.9.9
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-2019, 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 /** Checks if a given section exists (name is case insensitive) */
206 bool CConfigFileBase::sectionExists(const std::string& section_name) const
207 {
208  std::vector<std::string> sects;
209  getAllSections(sects);
210  for (auto& sect : sects)
211  if (!mrpt::system::os::_strcmpi(section_name.c_str(), sect.c_str()))
212  return true;
213  return false;
214 }
215 
216 void CConfigFileBase::setContentFromYAML(const std::string& yaml_block)
217 {
218  MRPT_START
219 #if MRPT_HAS_YAMLCPP
220  this->clear();
221 
222  YAML::Node root = YAML::Load(yaml_block);
223 
224  // Prepare all data here, then insert into the actual INI file at the end,
225  // to ensure that unscoped variables get first.
226  using key_values_t = std::map<std::string, std::string>;
227  key_values_t unscoped;
228  std::map<std::string, key_values_t> sections;
229 
230  for (const auto& sect : root)
231  {
232  const auto sectName = sect.first.as<std::string>();
233  // YAML Type: sect.first.Type()
234 
235  if (sect.second.size() >= 1)
236  {
237  // A section:
238  for (const auto& kv : sect.second)
239  {
240  const auto key = kv.first.as<std::string>();
241  const auto val = kv.second.as<std::string>();
242  sections[sectName].emplace(key, val);
243  }
244  }
245  else
246  {
247  // an unscoped key-value:
248  const auto key = sect.first.as<std::string>();
249  const auto val = sect.second.as<std::string>();
250  unscoped.emplace(key, val);
251  }
252  }
253 
254  // 1st: unscoped:
255  for (const auto& kv : unscoped) this->write("", kv.first, kv.second);
256 
257  for (const auto& sect : sections)
258  for (const auto& kv : sect.second)
259  this->write(sect.first, kv.first, kv.second);
260 
261 #else
263  "This method requires building MRPT with yaml-cpp support.");
264 #endif
265  MRPT_END
266 }
267 
268 std::string CConfigFileBase::getContentAsYAML() const
269 {
270  MRPT_START
271 #if MRPT_HAS_YAMLCPP
272  YAML::Node n;
273 
274  // Sections:
275  std::vector<std::string> lstSects;
276  getAllSections(lstSects);
277 
278  // Unscoped: "" empty section name:
279  lstSects.insert(lstSects.begin(), std::string());
280 
281  // Go thru values:
282  for (const auto& sect : lstSects)
283  {
284  std::vector<std::string> keys;
285  getAllKeys(sect, keys);
286  for (const auto& k : keys)
287  {
288  const auto val = this->readString(sect, k, "");
289  if (sect.empty())
290  n[k] = val;
291  else
292  n[sect][k] = val;
293  }
294  }
295 
296  // Convert to string:
297  std::stringstream ss;
298  ss << n;
299  return ss.str();
300 #else
302  "This method requires building MRPT with yaml-cpp support.");
303 #endif
304  MRPT_END
305 }
#define MRPT_START
Definition: exceptions.h:241
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
int MRPT_SAVE_NAME_PADDING()
Default padding sizes for macros MRPT_SAVE_CONFIG_VAR_COMMENT(), etc.
GLenum GLsizei n
Definition: glext.h:5136
STL namespace.
GLdouble s
Definition: glext.h:3682
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)
static int MRPT_SAVE_VALUE_PADDING
GLsizei const GLchar ** string
Definition: glext.h:4116
unsigned __int64 uint64_t
Definition: rptypes.h:53
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
#define MRPT_END
Definition: exceptions.h:245
GLuint const GLchar * name
Definition: glext.h:4068
uint64_t _strtoull(const char *nptr, char **endptr, int base)
An OS-independent version of strtoull.
Definition: os.cpp:468
std::string trim(const std::string &str)
Removes leading and trailing spaces.
static int MRPT_SAVE_NAME_PADDING
GLenum GLsizei GLenum format
Definition: glext.h:3535
GLsizei const GLfloat * value
Definition: glext.h:4134
void clear()
Clear the contents of this container.
Definition: ts_hash_map.h:182
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.
Definition: os.cpp:322



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 8fe78517f Sun Jul 14 19:43:28 2019 +0200 at lun oct 28 02:10:00 CET 2019