]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/common/cmdparse.cc
update sources to v12.2.3
[ceph.git] / ceph / src / common / cmdparse.cc
index 3fdf94c73676600d72b084a39acd36fb490ede5d..a93e92c3e88dcc22a309ed41cf1d10477536ac39 100644 (file)
  *
  */
 
-#include <cxxabi.h>
-#include "common/cmdparse.h"
-#include "common/Formatter.h"
-#include "include/str_list.h"
 #include "json_spirit/json_spirit.h"
 #include "common/debug.h"
 
@@ -59,12 +55,10 @@ dump_cmd_to_json(Formatter *f, const string& cmd)
   // elements are: "name", meaning "the typeless name that means a literal"
   // an object {} with key:value pairs representing an argument
 
-  int argnum = 0;
   stringstream ss(cmd);
   std::string word;
 
   while (std::getline(ss, word, ' ')) {
-    argnum++;
     // if no , or =, must be a plain word to put out
     if (word.find_first_of(",=") == string::npos) {
       f->dump_string("arg", word);
@@ -189,6 +183,15 @@ void cmdmap_dump(const cmdmap_t &cmdmap, Formatter *f)
       }
       f->close_section();
     }
+
+    void operator()(const std::vector<double> &operand) const
+    {
+      f->open_array_section(key.c_str());
+      for (const auto i : operand) {
+        f->dump_float("item", i);
+      }
+      f->close_section();
+    }
   };
 
   //f->open_object_section("cmdmap");
@@ -244,7 +247,7 @@ cmdmap_from_json(vector<string> cmd, map<string, cmd_vartype> *mapp, stringstrea
       case json_spirit::array_type:
        {
          // array is a vector of values.  Unpack it to a vector
-         // of strings or int64_t, the only types we handle.
+         // of strings, doubles, or int64_t, the only types we handle.
          const vector<json_spirit::mValue>& spvals = it->second.get_array();
          if (spvals.empty()) {
            // if an empty array is acceptable, the caller should always check for
@@ -269,9 +272,18 @@ cmdmap_from_json(vector<string> cmd, map<string, cmd_vartype> *mapp, stringstrea
              outv.push_back(sv.get_int64());
            }
            (*mapp)[it->first] = std::move(outv);
+         } else if (spvals.front().type() == json_spirit::real_type) {
+           vector<double> outv;
+           for (const auto& sv : spvals) {
+             if (spvals.front().type() != json_spirit::real_type) {
+               throw(runtime_error("Can't handle arrays of multiple types"));
+             }
+             outv.push_back(sv.get_real());
+           }
+           (*mapp)[it->first] = std::move(outv);
          } else {
            throw(runtime_error("Can't handle arrays of types other than "
-                               "int or string"));
+                               "int, string, or double"));
          }
        }
        break;
@@ -319,7 +331,7 @@ cmd_vartype_stringify(const cmd_vartype &v)
 
 
 void
-handle_bad_get(CephContext *cct, string k, const char *tname)
+handle_bad_get(CephContext *cct, const string& k, const char *tname)
 {
   ostringstream errstr;
   int status;
@@ -331,7 +343,52 @@ handle_bad_get(CephContext *cct, string k, const char *tname)
 
   ostringstream oss;
   oss << BackTrace(1);
-  lderr(cct) << oss.rdbuf() << dendl;
+  lderr(cct) << oss.str() << dendl;
+
   if (status == 0)
     free((char *)typestr);
 }
+
+long parse_pos_long(const char *s, std::ostream *pss)
+{
+  if (*s == '-' || *s == '+') {
+    if (pss)
+      *pss << "expected numerical value, got: " << s;
+    return -EINVAL;
+  }
+
+  string err;
+  long r = strict_strtol(s, 10, &err);
+  if ((r == 0) && !err.empty()) {
+    if (pss)
+      *pss << err;
+    return -1;
+  }
+  if (r < 0) {
+    if (pss)
+      *pss << "unable to parse positive integer '" << s << "'";
+    return -1;
+  }
+  return r;
+}
+
+int parse_osd_id(const char *s, std::ostream *pss)
+{
+  // osd.NNN?
+  if (strncmp(s, "osd.", 4) == 0) {
+    s += 4;
+  }
+
+  // NNN?
+  ostringstream ss;
+  long id = parse_pos_long(s, &ss);
+  if (id < 0) {
+    *pss << ss.str();
+    return id;
+  }
+  if (id > 0xffff) {
+    *pss << "osd id " << id << " is too large";
+    return -ERANGE;
+  }
+  return id;
+}