common/config: move parse_value() into Option

It is more reuable there.

Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
Sage Weil 2017-11-13 09:25:07 -06:00
parent 02e57753e5
commit 4161e804d7
3 changed files with 77 additions and 59 deletions

View File

@ -1061,69 +1061,12 @@ int md_config_t::set_val_impl(const std::string &raw_val, const Option &opt,
{
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;

View File

@ -88,6 +88,75 @@ int Option::validate(const Option::value_t &new_value, std::string *err) const
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");

View File

@ -182,6 +182,12 @@ struct 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);