]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/common/ConfUtils.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / common / ConfUtils.cc
index 70367c0931536b19acd95b8743d7b7776e717f22..d1ed75cea51974066fa1f6a161a9b0f09aec1529 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <algorithm>
 #include <cctype>
+#include <experimental/iterator>
 #include <fstream>
 #include <iostream>
 #include <iterator>
@@ -133,9 +134,9 @@ int ConfFile::parse_file(const std::string &fname,
     }
   }
   std::ifstream ifs{fname};
-  const std::string buffer{std::istreambuf_iterator<char>(ifs),
-                          std::istreambuf_iterator<char>()};
-  if (load_from_buffer(buffer, warnings)) {
+  std::string buffer{std::istreambuf_iterator<char>(ifs),
+                                      std::istreambuf_iterator<char>()};
+  if (parse_buffer(buffer, warnings)) {
     return 0;
   } else {
     return -EINVAL;
@@ -246,19 +247,27 @@ struct IniGrammer : qi::grammar<Iterator, ConfFile(), Skipper>
 };
 }
 
-bool ConfFile::load_from_buffer(std::string_view buf, std::ostream* err)
+bool ConfFile::parse_buffer(std::string_view buf, std::ostream* err)
 {
-  if (int err_pos = check_utf8(buf.data(), buf.size()); err_pos > 0) {
+  assert(err);
+#ifdef _WIN32
+  // We'll need to ensure that there's a new line at the end of the buffer,
+  // otherwise the config parsing will fail.
+  std::string _buf = std::string(buf) + "\n";
+#else
+  std::string_view _buf = buf;
+#endif
+  if (int err_pos = check_utf8(_buf.data(), _buf.size()); err_pos > 0) {
     *err << "parse error: invalid UTF-8 found at line "
-        << std::count(buf.begin(), std::next(buf.begin(), err_pos), '\n') + 1;
+        << std::count(_buf.begin(), std::next(_buf.begin(), err_pos), '\n') + 1;
     return false;
   }
-  using iter_t = boost::spirit::line_pos_iterator<decltype(buf.begin())>;
-  iter_t first{buf.begin()};
+  using iter_t = boost::spirit::line_pos_iterator<decltype(_buf.begin())>;
+  iter_t first{_buf.begin()};
   using skipper_t = qi::rule<iter_t>;
   IniGrammer<iter_t, skipper_t> grammar{first, *err};
   skipper_t skipper = grammar.continue_marker | grammar.comment;
-  return qi::phrase_parse(first, iter_t{buf.end()},
+  return qi::phrase_parse(first, iter_t{_buf.end()},
                          grammar, skipper, *this);
 }
 
@@ -270,10 +279,10 @@ int ConfFile::parse_bufferlist(ceph::bufferlist *bl,
   if (!warnings) {
     warnings = &oss;
   }
-  return load_from_buffer({bl->c_str(), bl->length()}, warnings) ? 0 : -EINVAL;
+  return parse_buffer({bl->c_str(), bl->length()}, warnings) ? 0 : -EINVAL;
 }
 
-int ConfFile::read(const std::string& section_name,
+int ConfFile::read(std::string_view section_name,
                   std::string_view key,
                   std::string &val) const
 {
@@ -303,6 +312,27 @@ std::string ConfFile::normalize_key_name(std::string_view key)
   return k;
 }
 
+void ConfFile::check_old_style_section_names(const std::vector<std::string>& prefixes,
+                                            std::ostream& os)
+{
+  // Warn about section names that look like old-style section names
+  std::vector<std::string> old_style_section_names;
+  for (auto& [name, section] : *this) {
+    for (auto& prefix : prefixes) {
+      if (name.find(prefix) == 0 && name.size() > 3 && name[3] != '.') {
+       old_style_section_names.push_back(name);
+      }
+    }
+  }
+  if (!old_style_section_names.empty()) {
+    os << "ERROR! old-style section name(s) found: ";
+    std::copy(std::begin(old_style_section_names),
+              std::end(old_style_section_names),
+              std::experimental::make_ostream_joiner(os, ", "));
+    os << ". Please use the new style section names that include a period.";
+  }
+}
+
 std::ostream &operator<<(std::ostream &oss, const ConfFile &cf)
 {
   for (auto& [name, section] : cf) {