/** * Look for sections set up to inherit from a base section * and copy the missing parameters * * [sub/seciton] * inherit = base/section */ void config::copy_inherited() { for (auto&& section : m_sections) { for (auto&& param : section.second) { if (param.first.find("inherit") == 0) { // Get name of base section auto inherit = param.second; if ((inherit = dereference<string>(section.first, param.first, inherit, inherit)).empty()) { throw value_error("Invalid section \"\" defined for \"" + section.first + ".inherit\""); } // Find and validate base section auto base_section = m_sections.find(inherit); if (base_section == m_sections.end()) { throw value_error("Invalid section \"" + inherit + "\" defined for \"" + section.first + ".inherit\""); } m_log.trace("config: Copying missing params (sub=\"%s\", base=\"%s\")", section.first, inherit); // Iterate the base and copy the parameters // that hasn't been defined for the sub-section for (auto&& base_param : base_section->second) { section.second.insert(make_pair(base_param.first, base_param.second)); } } } } }
value value_tail(value op) { if (op.type == VALUE_ARY) { size_t length = value_length(op); if (length == 0) { value_error(1, "Error: cannot find tail() of an empty array."); return value_init_error(); } value array[length - 1]; size_t i; for (i = 0; i < length-1; ++i) array[i] = op.core.u_a.a[i+1]; value res = value_set_ary(array, length-1); return res; } else if (op.type == VALUE_LST) { return value_set(op.core.u_l[1]); } else if (op.type == VALUE_PAR) { return value_set(op.core.u_p->tail); } else { value_error(1, "Type Error: tail() is undefined where op is %ts (array or list expected).", op); return value_init_error(); } }
value value_cons(value op1, value op2) { value res = value_init_nil(); if (op2.type == VALUE_NIL) { res = value_init(VALUE_PAR); res.core.u_p->head = value_set(op1); } else if (op2.type == VALUE_ARY) { size_t length = value_length(op2) + 1; value array[length]; array[0] = op1; size_t i; for (i = 1; i < length; ++i) array[i] = op2.core.u_a.a[i-1]; res = value_set_ary(array, length); } else if (op2.type == VALUE_LST) { res = value_init(VALUE_LST); res.core.u_l[0] = value_set(op1); res.core.u_l[1] = value_set(op2); } else if (op2.type == VALUE_PAR) { res = value_init(VALUE_PAR); res.core.u_l[0] = value_set(op1); res.core.u_l[1] = value_set(op2); } else { value_error(1, "Type Error: cons() is undefined where op2 is %ts (nil, array or list expected).", op2); res = value_init_error(); } return res; }
/** * @brief Deserialize the integer value from the specified input stream. * @param __s Reference to the input stream. */ void load(std::basic_istream<CharT, Traits> &__s) { // We must ensure that subsequent actions will be performed // for very likely integer value, otherwise and exception // should be raised. if (__s.peek() != basic_value_type::integer_token) { throw type_error( "bencode::integer::load the specified stream does " "not contain interpretable bencode integer value\n"); } // Read the leading "i" symbol from the provided stream. __s.get(); // Define the integer symbol representation placeholder. std::basic_stringstream<CharT, Traits> __i; // Define the input stream iterator of the provided stream to // be able to read the integer value symbol by symbol. auto __si = std::istream_iterator<CharT, CharT, Traits>(__s); // Define the output stream to as a buffer for the integer // value, which will be later converted. auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i); // Copy the values from the input stream into the integer // placeholder string stream. auto __result = copy_until(__si, __ival, [&__s](const CharT& __ch) { // Additionally, check that we did not exceed the // length of the stream to prevent hangs. return !__s.eof() && __ch != basic_value_type::end_token; }, basic_value_type::integer_length); // Covert the value from the string into the integer. __i >> _M_value; // The "e" symbol should be already extracted at this moment, // so validate that the iterator pointing right to it. if (*__result != basic_value_type::end_token) { std::ostringstream __error; __error << "bencode::integer::load the end of the integer " "`e` expected, but `" << CharT(*__result) << "` found\n"; throw encoding_error(__error.str()); } // Validate that decoded value is an actual integer. if (!_M_value && __i.str() != std::basic_string< CharT, Traits>(1, CharT('0'))) { std::ostringstream __error; __error << "bencode::integer::load the specified " "value is not a number\n"; throw value_error(__error.str()); } }
value value_head(value op) { if (op.type == VALUE_ARY) { if (value_length(op) == 0) { value_error(1, "Error: cannot find head() of an empty array."); return value_init_error(); } return value_set(op.core.u_a.a[0]); } else if (op.type == VALUE_LST) { return value_set(op.core.u_l[0]); } else if (op.type == VALUE_PAR) { return value_set(op.core.u_p->head); } else { value_error(1, "Type Error: head() is undefined where op is %ts (array or list expected).", op); return value_init_error(); } }
Dict::Dict( xmmsv_t* val ) : value_( 0 ) { if( xmmsv_is_error( val ) ) { const char *buf; xmmsv_get_error( val, &buf ); throw value_error( buf ); } else if( xmmsv_get_type( val ) != XMMSV_TYPE_DICT ) { throw not_dict_error( "Value is not a dict" ); } setValue( val ); }
value value_tail_now(value *op) { if (op->type == VALUE_NIL) { value_error(1, "Error: cannot find tail!() of an empty list."); return value_init_error(); } else if (op->type == VALUE_ARY) { size_t i, length = value_length(*op); if (length == 0) { value_error(1, "Error: cannot find tail!() of an empty array."); return value_init_error(); } value_clear(&op->core.u_a.a[0]); for (i = 0; i < length-1; ++i) op->core.u_a.a[i] = op->core.u_a.a[i+1]; --op->core.u_a.length; } else if (op->type == VALUE_LST) { if (value_empty_p(*op)) { value_error(1, "Error: cannot find tail!() of an empty list."); return value_init_error(); } else { value_clear(&op->core.u_l[0]); value_free(op->core.u_l); *op = op->core.u_l[1]; } } else if (op->type == VALUE_PAR) { value tmp = op->core.u_p->tail; value_clear(&op->core.u_p->head); value_free(op->core.u_p); *op = tmp; } else { value_error(1, "Type Error: tail!() is undefined where op is %ts (array or list expected).", *op); return value_init_error(); } return value_init_nil(); }
output_formatter *formatter_factory::output(const string &name) { if(name == "simple") return new simple_output_formatter(); else if(name == "csv") return new csv_output_formatter(); else if(name == "keyvalue") return new key_value_output_formatter(); else if(name == "xml") return new xml_output_formatter(); else throw value_error(EXCEPTION_RECORD, "Unknown output formatter ["+name+"]!"); }
/* ** Store the string on top of the stack on the attributes structure. ** Increment the bvals counter. */ static BerValue *A_setbval (lua_State *L, attrs_data *a, const char *n) { BerValue *ret = &(a->bvals[a->bi]); if (a->bi >= LUALDAP_MAX_VALUES) { luaL_error (L, LUALDAP_PREFIX"too many values"); return NULL; } else if (!lua_isstring (L, -1)) { value_error (L, n); return NULL; } a->bvals[a->bi].bv_len = lua_strlen (L, -1); a->bvals[a->bi].bv_val = (char *)lua_tostring (L, -1); a->bi++; return ret; }
void command_line_parser::parse_parameters(void) { for (const auto& parameter : m_params) { const char* token = m_command_line.read(); if (!token) { if (parameter.is_required()) throw value_error(parameter.name()); else return; } parameter.read(token); } }
/// Sets the value of a leaf addressed by its key from a string value. /// /// This respects the native types of all the nodes that have been predefined. /// For new nodes under a dynamic subtree, this has no mechanism of determining /// what type they need to have, so they are created as plain string nodes. /// /// \param dotted_key The key to be registered in dotted representation. /// \param raw_value The string representation of the value to set the node to. /// /// \throw invalid_key_error If the provided key has an invalid format. /// \throw unknown_key_error If the provided key is unknown. /// \throw value_error If the value mismatches the node type. void config::tree::set_string(const std::string& dotted_key, const std::string& raw_value) { const detail::tree_key key = detail::parse_key(dotted_key); detail::base_node* raw_node = _root->lookup_rw( key, 0, detail::new_node< string_node >); try { leaf_node& child = dynamic_cast< leaf_node& >(*raw_node); child.set_string(raw_value); } catch (const std::bad_cast& unused_error) { throw value_error(F("Invalid value for key '%s'") % detail::flatten_key(key)); } }
value value_cons_now2(value *op1, value *op2) { if (op2->type == VALUE_NIL) { op2->type = VALUE_PAR; value_malloc(op2, 2); if (op2->type == VALUE_ERROR) return; op2->core.u_p->head = *op1; op2->core.u_p->tail = value_init_nil(); } else if (op2->type == VALUE_ARY) { value res; res.type = VALUE_ARY; size_t i, length = value_length(*op2); if (resize_p(length+1)) { value_realloc(op1, next_size(length+1) + 1); if (op1->type == VALUE_ERROR) return value_init_error(); } for (i = 1; i < length; ++i) res.core.u_a.a[i+1] = op2->core.u_a.a[i]; res.core.u_a.a[0] = *op1; res.core.u_a.length = op2->core.u_a.length + 1; *op2 = res; } else if (op2->type == VALUE_LST) { value res; res.type = VALUE_LST; value_malloc(&res, 2); if (res.type == VALUE_ERROR) { return value_init_error(); } res.core.u_l[0] = *op1; res.core.u_l[1] = *op2; *op2 = res; } else if (op2->type == VALUE_PAR) { value res; res.type = VALUE_PAR; value_malloc(&res, 2); return_if_error(res); res.core.u_l[0] = *op1; res.core.u_l[1] = *op2; *op2 = res; } else { value_error(1, "Type Error: cons() is undefined where op2 is %ts (nil, array or list expected).", *op2); return value_init_error(); } return value_init_nil(); }
value value_drop(value op, value n) { if (op.type == VALUE_NIL) { return value_init_nil(); } else if (op.type == VALUE_ARY) { if (n.type == VALUE_MPZ) { value length = value_set_long(op.core.u_a.length); value res = value_range(op, n, length); value_clear(&length); return res; } } else if (op.type == VALUE_LST) { if (n.type == VALUE_MPZ) { if (value_lt(n, value_zero)) { value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n); return value_init_error(); } else if (value_gt(n, value_int_max)) { value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max); return value_init_error(); } size_t i, max = value_get_long(n); value ptr = op; for (i = 0; i < max && ptr.type == VALUE_LST; ++i) { ptr = ptr.core.u_l[1]; } return value_set(ptr); } } else if (op.type == VALUE_PAR) { if (n.type == VALUE_MPZ) { if (value_lt(n, value_zero)) { value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n); return value_init_error(); } else if (value_gt(n, value_int_max)) { value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max); return value_init_error(); } size_t i, max = value_get_long(n); value ptr = op; for (i = 0; i < max && ptr.type == VALUE_PAR; ++i) { ptr = ptr.core.u_p->tail; } return value_set(ptr); } } else { value_error(1, "Type Error: drop() is undefined where op1 is %ts (array or list expected).", op); if (n.type == VALUE_MPZ) return value_init_error(); } value_error(1, "Type Error: drop() is undefined where op2 is %ts (integer expected).", n); return value_init_error(); }
/// Converts the tree to a collection of key/value string pairs. /// /// \param dotted_key Subtree from which to start the export. /// \param strip_key If true, remove the dotted_key prefix from the resulting /// properties. /// /// \return A map of keys to values in their textual representation. /// /// \throw invalid_key_error If the provided key has an invalid format. /// \throw unknown_key_error If the provided key is unknown. /// \throw value_error If the provided key points to a leaf. config::properties_map config::tree::all_properties(const std::string& dotted_key, const bool strip_key) const { PRE(!strip_key || !dotted_key.empty()); properties_map properties; detail::tree_key key; const detail::base_node* raw_node; if (dotted_key.empty()) { raw_node = _root.get(); } else { key = detail::parse_key(dotted_key); raw_node = _root->lookup_ro(key, 0); } try { const detail::inner_node& child = dynamic_cast< const detail::inner_node& >(*raw_node); child.all_properties(properties, key); } catch (const std::bad_cast& unused_error) { INV(!dotted_key.empty()); throw value_error(F("Cannot export properties from a leaf node; " "'%s' given") % dotted_key); } if (strip_key) { properties_map stripped; for (properties_map::const_iterator iter = properties.begin(); iter != properties.end(); ++iter) { stripped[(*iter).first.substr(dotted_key.length() + 1)] = (*iter).second; } properties = stripped; } return properties; }
/** * @brief Deserialize the string value from the specified input stream. * @param __s Reference to the input stream. */ void load(std::basic_istream<CharT, Traits>& __s) { // Define the integer symbol representation placeholder. std::basic_stringstream<CharT, Traits> __i; // Define the input stream iterator of the provided stream to // be able to read the string length value symbol by symbol. auto __si = std::istream_iterator<CharT, CharT, Traits>(__s); // Define the output stream to as a buffer for the integer // value, which will be later converted. auto __ival = std::ostream_iterator<CharT, CharT, Traits>(__i); // Copy the symbols from the input stream to the integer // placeholder until the ":" delimiter value. auto __result = copy_until(__si, __ival, [&__s](const CharT& __ch) { // Additionally, check that we did not exceed the // length of the stream to prevent hangs. return !__s.eof() && __ch != basic_value_type::delimiter_token; }, basic_value_type::integer_length); if (*__result != basic_value_type::delimiter_token) { std::ostringstream __error; __error << "bencode::string::load the delimiter `:` " "expected, but `" << CharT(*__result) << "` found\n"; throw encoding_error(__error.str()); } // Save the length of the string. int64_t __count; __i >> __count; if (!__count && __i.str() != std::basic_string< CharT, Traits>(1, CharT('0'))) { std::ostringstream __error; __error << "bencode::string::load the specified string " "length is not a number\n"; throw value_error(__error.str()); } // Ensure that the string length is a non-negative value. if (__count < 0) { std::ostringstream __error; __error << "bencode::string::load the length of the string " "value must be a positive integer: `" << __count << "`\n"; throw value_error(__error.str()); } // Allocate the list of symbols of the specified string length. std::unique_ptr<CharT[]> __str(new CharT[__count+1]); // Read the string value into the symbol list. __s.get(__str.get(), std::streamsize(__count+1)); auto __strval = string_type(__str.get()); // Ensure that valid count of the symbols was extracted from // the provided input stream. if (int64_t(__strval.length()) != __count) { std::ostringstream __error; __error << "bencode::string::load the specified string " "decoded length is not equal to the real one: `" << __count << "` != `" << __strval.length() << "`\n"; throw value_error(__error.str()); } // Initialize the internal value with a new string. _M_value = __strval; }
static bool handle_configitem(const char keyword[], const char *value) { const struct option keyopt = { keyword, 0, 0, 0, 0 }; const struct option *const opt = bsearch(&keyopt, options, sizeof(options)/sizeof(*options), sizeof(*options), optcmp); if (!opt) return value_error(keyword, "unknown configuration item"); long long numarg = 0; size_t arglen = 0; if (value) arglen = strlen(value); const char *err = NULL; if (value) switch (opt->argtype) { case at_none: err = "does not take an argument"; break; case at_num: if (!*value) err = "requires a numeric argument"; else { char *endptr; numarg = strtoll(value, &endptr, 0); if (*endptr) switch (tolower(*endptr++)) { case 'k': numarg *= KILO; break; case 'm': numarg *= MEGA; break; case 'g': numarg *= GIGA; break; case 't': numarg *= TERA; break; default: err = "invalid unit letter"; } if (*endptr) err = "invalid numeric argument"; else if (numarg < opt->min) switch (opt->min) { case 0: err = "argument may not be negative"; break; case 1: err = "argument must be greater than zero"; break; default: err = "given value too small"; break; } else if (numarg > opt->max) err = "given value too large"; } break; case at_str: if (arglen > opt->max) err = "string too long"; break; } else if (opt->argtype == at_num || (opt->argtype == at_str && opt->min)) { err = "requires an argument"; } if (err) return value_error(keyword, err); char *const strdest = opt->setter(numarg); if (strdest && value) strcpy(strdest, value); return true; }
/** * Parse key/value pairs from the configuration file */ void config::parse_file() { vector<pair<int, string>> lines; vector<string> files{m_file}; std::function<void(int, string&&)> pushline = [&](int lineno, string&& line) { // Ignore empty lines and comments if (line.empty() || line[0] == ';' || line[0] == '#') { return; } string key, value; string::size_type pos; // Filter lines by: // - key/value pairs // - section headers if ((pos = line.find('=')) != string::npos) { key = forward<string>(string_util::trim(forward<string>(line.substr(0, pos)))); value = forward<string>(string_util::trim(line.substr(pos + 1))); } else if (line[0] != '[' || line[line.length() - 1] != ']') { return; } if (key == "include-file") { auto file_path = file_util::expand(value); if (file_path.empty() || !file_util::exists(file_path)) { throw value_error("Invalid include file \"" + file_path + "\" defined on line " + to_string(lineno)); } if (std::find(files.begin(), files.end(), file_path) != files.end()) { throw value_error("Recursive include file \"" + file_path + "\""); } files.push_back(file_util::expand(file_path)); m_log.trace("config: Including file \"%s\"", file_path); for (auto&& l : string_util::split(file_util::contents(file_path), '\n')) { pushline(lineno, forward<string>(l)); } files.pop_back(); } else { lines.emplace_back(make_pair(lineno, line)); } }; int lineno{0}; string line; std::ifstream in(m_file); while (std::getline(in, line)) { pushline(++lineno, string_util::replace_all(line, "\t", "")); } string section; for (auto&& l : lines) { auto& lineno = l.first; auto& line = l.second; // New section if (line[0] == '[' && line[line.length() - 1] == ']') { section = line.substr(1, line.length() - 2); continue; } else if (section.empty()) { continue; } size_t equal_pos; // Check for key-value pair equal sign if ((equal_pos = line.find('=')) == string::npos) { continue; } string key{forward<string>(string_util::trim(forward<string>(line.substr(0, equal_pos))))}; string value; auto it = m_sections[section].find(key); if (it != m_sections[section].end()) { throw key_error("Duplicate key name \"" + key + "\" defined on line " + to_string(lineno)); } if (equal_pos + 1 < line.size()) { value = forward<string>(string_util::trim(line.substr(equal_pos + 1))); size_t len{value.size()}; if (len > 2 && value[0] == '"' && value[len - 1] == '"') { value.erase(len - 1, 1).erase(0, 1); } } #if WITH_XRM // Initialize the xresource manage if there are any xrdb refs // present in the configuration if (!m_xrm && value.find("${xrdb") != string::npos) { m_xrm.reset(new xresource_manager{connection::make()}); } #endif m_sections[section].emplace_hint(it, move(key), move(value)); } }
void assert_check() const { if (pos_ == end_) throw value_error("Attempt to read past end of value list."); }
void finish() const { if (pos_ != end_) throw value_error("Not all values handled."); }
void assert_check(value::tag_type t) const { assert_check(); if (t != pos_->get_tag()) throw value_error("Incorrect value tag."); }
value value_take(value op, value n) { if (op.type == VALUE_NIL) { return value_init_nil(); } else if (op.type == VALUE_ARY) { if (n.type == VALUE_MPZ) { value start = value_set_long(0); value res = value_range(op, start, n); value_clear(&start); return res; } } else if (op.type == VALUE_LST) { if (n.type == VALUE_MPZ) { if (value_lt(n, value_zero)) { value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n); return value_init_error(); } else if (value_gt(n, value_int_max)) { value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max); return value_init_error(); } value res = value_init_nil(); size_t i, max = value_get_long(n); value ptr = op; for (i = 0; i < max && ptr.type == VALUE_LST; ++i) { value_cons_now(ptr.core.u_l[0], &res); ptr = ptr.core.u_l[1]; } value_reverse_now(&res); return res; } } else if (op.type == VALUE_PAR) { if (n.type == VALUE_MPZ) { if (value_lt(n, value_zero)) { value_error(1, "Domain Error: drop() is undefined where n is %s (>= 0 expected).", n); return value_init_error(); } else if (value_gt(n, value_int_max)) { value_error(1, "Domain Error: drop() is undefined where n is %s (<= %s expected).", n, value_int_max); return value_init_error(); } value res = value_init_nil(); size_t i, max = value_get_long(n); value ptr = op; for (i = 0; i < max && ptr.type == VALUE_PAR; ++i) { value_cons_now(ptr.core.u_p->tail, &res); ptr = ptr.core.u_p->tail; } value_reverse_now(&res); return res; } } else { value_error(1, "Type Error: take() is undefined where op is %ts (array or list expected).", op); if (n.type == VALUE_MPZ) return value_init_error(); } value_error(1, "Type Error: drop() is undefined where n is %ts (integer expected).", n); return value_init_error(); }
void command_line_parser::parse_options(void) { while(const char* token = m_command_line.peek()) { if (*token != '-') break; std::string param(m_command_line.read()); logger().trace(corecpp::concat<std::string>({"parsing ", param}), __FILE__, __LINE__); if (param.substr(0,2) == "--") { std::string value = ""; auto pos = param.find('='); if(pos == std::string::npos) { //param with no value => value is let to an empty string param = param.substr(2); } else { value = param.substr(pos); param = param.substr(2, param.length() - 2 - pos); } auto option = get_option(param); if (option == m_options.end()) throw std::invalid_argument(param); if (option->require_value() && (pos == std::string::npos)) throw value_error(param); option->read(value); } else if (param[0] == '-') { param = param.substr(1); const char* value = m_command_line.peek(); if(value && *value == '-') //another option value = nullptr; //for loop because we can have multiple params for(auto iter = param.begin(); iter != param.end(); ) { char shortname = *iter; auto option = get_option(shortname); if(option == m_options.end()) throw std::invalid_argument(std::string(1, shortname)); if (++iter == param.end())//last option => must give the value to it { if (!value && option->require_value()) throw value_error(param); if (option->require_value()) { value = m_command_line.read(); //consume the parameter option->read(value); } else option->read(""); } else //not the last parameter => should not need a value { if (option->require_value()) throw value_error(param); option->read(""); } } } } }
Value pow(Value & v1,Value & v2) { Value val; if ((v1.code == ISERROR) || (v2.code == ISERROR)) return val; switch(v1.code) { case ISINT: { switch(v2.code) { case ISINT: val.code = ISINT; if (((v1.i < 0)&&(v2.i <= 0)) || ((v1.i < 0)&&(v2.IsInt()))) { return value_error(" illegal exponentiation"); } else { val.i = (int)pow((double)v1.i,v2.i); return val; } default: val.code = ISFLOAT; if (((v1.i < 0)&&(v2.f <= 0)) || ((v1.i < 0)&&(v2.IsInt()))) { return value_error(" illegal exponentiation"); } else { val.f = pow((double)(v1.i),v2.f); return val; } } } default: switch(v2.code) { case ISINT: val.code = ISFLOAT; if (((v1.f < 0)&&(v2.i <= 0)) || ((v1.f < 0)&&(v2.IsInt()))) { return value_error(" illegal exponentiation"); } else { val.f = pow(v1.f,(double)(v2.i)); return val; } default: val.code = ISFLOAT; if (((v1.f < 0)&&(v2.f <= 0)) || ((v1.f < 0)&&(v2.IsInt()))) { return value_error(" illegal exponentiation"); } else { val.f = pow(v1.f,v2.f); return val; } } } }
Value operator/(Value & v1,Value & v2) { Value val; if ((v1.code == ISERROR) || (v2.code == ISERROR)) return val; switch(v1.code) { case ISINT: { switch(v2.code) { case ISINT: val.code = ISINT; if (v2.i == 0) { value_error(" divide by 0"); val.i = 0; } else { val.i = (v1.i) / (v2.i); } return val; default: val.code = ISFLOAT; if (v2.f == 0) { value_error(" divide by 0"); val.f = 0; } else { val.f = (double)(v1.i) / (v2.f); } return val; } } default: { switch(v2.code) { case ISINT: val.code = ISFLOAT; if (v2.i == 0) { value_error(" divide by 0"); val.f = 0; } else { val.f = (v1.f) / (double)(v2.i); } return val; default: val.code = ISFLOAT; if (v2.f == 0) { value_error(" divide by 0"); val.f = 0; } else { val.f = (v1.f) / (v2.f); } return val; } } } }