It is more reuable there.
Signed-off-by: Sage Weil <sage@redhat.com>
{
assert(lock.is_locked());
- std::string val = raw_val;
-
- int r = opt.pre_validate(&val, error_message);
- if (r != 0) {
- return r;
- }
-
Option::value_t new_value;
- if (opt.type == Option::TYPE_INT) {
- int64_t f = strict_si_cast<int64_t>(val.c_str(), error_message);
- if (!error_message->empty()) {
- return -EINVAL;
- }
- new_value = f;
- } else if (opt.type == Option::TYPE_UINT) {
- uint64_t f = strict_si_cast<uint64_t>(val.c_str(), error_message);
- if (!error_message->empty()) {
- return -EINVAL;
- }
- new_value = f;
- } else if (opt.type == Option::TYPE_STR) {
- new_value = val;
- } else if (opt.type == Option::TYPE_FLOAT) {
- double f = strict_strtod(val.c_str(), error_message);
- if (!error_message->empty()) {
- return -EINVAL;
- } else {
- new_value = f;
- }
- } else if (opt.type == Option::TYPE_BOOL) {
- if (strcasecmp(val.c_str(), "false") == 0) {
- new_value = false;
- } else if (strcasecmp(val.c_str(), "true") == 0) {
- new_value = true;
- } else {
- int b = strict_strtol(val.c_str(), 10, error_message);
- if (!error_message->empty()) {
- return -EINVAL;
- }
- new_value = !!b;
- }
- } else if (opt.type == Option::TYPE_ADDR) {
- entity_addr_t addr;
- if (!addr.parse(val.c_str())){
- return -EINVAL;
- }
- new_value = addr;
- } else if (opt.type == Option::TYPE_UUID) {
- uuid_d uuid;
- if (!uuid.parse(val.c_str())) {
- return -EINVAL;
- }
- new_value = uuid;
- } else {
- ceph_abort();
- }
-
- r = opt.validate(new_value, error_message);
- if (r != 0) {
+ int r = opt.parse_value(raw_val, &new_value, error_message);
+ if (r < 0) {
return r;
}
-
// Apply the value to its entry in the `values` map
values[opt.name] = new_value;
return 0;
}
+int Option::parse_value(
+ const std::string& raw_val,
+ value_t *out,
+ std::string *error_message) const
+{
+ std::string val = raw_val;
+
+ int r = pre_validate(&val, error_message);
+ if (r != 0) {
+ return r;
+ }
+
+ if (type == Option::TYPE_INT) {
+ int64_t f = strict_si_cast<int64_t>(val.c_str(), error_message);
+ if (!error_message->empty()) {
+ return -EINVAL;
+ }
+ *out = f;
+ } else if (type == Option::TYPE_UINT) {
+ uint64_t f = strict_si_cast<uint64_t>(val.c_str(), error_message);
+ if (!error_message->empty()) {
+ return -EINVAL;
+ }
+ *out = f;
+ } else if (type == Option::TYPE_STR) {
+ *out = val;
+ } else if (type == Option::TYPE_FLOAT) {
+ double f = strict_strtod(val.c_str(), error_message);
+ if (!error_message->empty()) {
+ return -EINVAL;
+ } else {
+ *out = f;
+ }
+ } else if (type == Option::TYPE_BOOL) {
+ if (strcasecmp(val.c_str(), "false") == 0) {
+ *out = false;
+ } else if (strcasecmp(val.c_str(), "true") == 0) {
+ *out = true;
+ } else {
+ int b = strict_strtol(val.c_str(), 10, error_message);
+ if (!error_message->empty()) {
+ return -EINVAL;
+ }
+ *out = !!b;
+ }
+ } else if (type == Option::TYPE_ADDR) {
+ entity_addr_t addr;
+ if (!addr.parse(val.c_str())){
+ return -EINVAL;
+ }
+ *out = addr;
+ } else if (type == Option::TYPE_UUID) {
+ uuid_d uuid;
+ if (!uuid.parse(val.c_str())) {
+ return -EINVAL;
+ }
+ *out = uuid;
+ } else {
+ ceph_abort();
+ }
+
+ r = validate(*out, error_message);
+ if (r != 0) {
+ return r;
+ }
+
+ return 0;
+}
+
void Option::dump(Formatter *f) const
{
f->open_object_section("option");
return *this;
}
+ /// parse and validate a string input
+ int parse_value(
+ const std::string& raw_val,
+ value_t *out,
+ std::string *error_message) const;
+
template<typename T>
Option& set_default(const T& v) {
return set_value(value, v);