// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- // vim: ts=8 sw=2 smarttab #include "acconfig.h" #include "options.h" #include "common/Formatter.h" // Helpers for validators #include "include/stringify.h" #include #include #include // Definitions for enums #include "common/perf_counters.h" void Option::dump_value(const char *field_name, const Option::value_t &v, Formatter *f) const { if (boost::get(&v)) { // This should be nil but Formatter doesn't allow it. f->dump_string(field_name, ""); } else if (type == TYPE_UINT) { f->dump_unsigned(field_name, boost::get(v)); } else if (type == TYPE_INT) { f->dump_int(field_name, boost::get(v)); } else if (type == TYPE_STR) { f->dump_string(field_name, boost::get(v)); } else if (type == TYPE_FLOAT) { f->dump_float(field_name, boost::get(v)); } else if (type == TYPE_BOOL) { f->dump_bool(field_name, boost::get(v)); } else { f->dump_stream(field_name) << v; } } int Option::pre_validate(std::string *new_value, std::string *err) const { if (validator) { return validator(new_value, err); } else { return 0; } } int Option::validate(const Option::value_t &new_value, std::string *err) const { // Generic validation: min if (!boost::get(&(min))) { if (new_value < min) { std::ostringstream oss; oss << "Value '" << new_value << "' is below minimum " << min; *err = oss.str(); return -EINVAL; } } // Generic validation: max if (!boost::get(&(max))) { if (new_value > max) { std::ostringstream oss; oss << "Value '" << new_value << "' exceeds maximum " << max; *err = oss.str(); return -EINVAL; } } // Generic validation: enum if (!enum_allowed.empty() && type == Option::TYPE_STR) { auto found = std::find(enum_allowed.begin(), enum_allowed.end(), boost::get(new_value)); if (found == enum_allowed.end()) { std::ostringstream oss; oss << "'" << new_value << "' is not one of the permitted " "values: " << joinify(enum_allowed.begin(), enum_allowed.end(), std::string(", ")); *err = oss.str(); return -EINVAL; } } return 0; } void Option::dump(Formatter *f) const { f->open_object_section("option"); f->dump_string("name", name); f->dump_string("type", type_to_str(type)); f->dump_string("level", level_to_str(level)); f->dump_string("desc", desc); f->dump_string("long_desc", long_desc); dump_value("default", value, f); dump_value("daemon_default", daemon_value, f); f->open_array_section("tags"); for (const auto t : tags) { f->dump_string("tag", t); } f->close_section(); f->open_array_section("services"); for (const auto s : services) { f->dump_string("service", s); } f->close_section(); f->open_array_section("see_also"); for (const auto sa : see_also) { f->dump_string("see_also", sa); } f->close_section(); if (type == TYPE_STR) { f->open_array_section("enum_values"); for (const auto &ea : enum_allowed) { f->dump_string("enum_value", ea); } f->close_section(); } dump_value("min", min, f); dump_value("max", max, f); f->close_section(); } std::vector