vconfig::child_list vconfig::get_children(const std::string& key) const { vconfig::child_list res; BOOST_FOREACH(const config::any_child &child, cfg_->all_children_range()) { if (child.key == key) { res.push_back(vconfig(child.cfg, cache_)); } else if (child.key == "insert_tag") { vconfig insert_cfg(child.cfg); if(insert_cfg["name"] == key) { variable_info vinfo(insert_cfg["variable"], false, variable_info::TYPE_CONTAINER); if(!vinfo.is_valid) { //push back an empty tag res.push_back(empty_vconfig()); } else if(vinfo.explicit_index) { res.push_back(vconfig(vinfo.as_container(), true)); } else { variable_info::array_range range = vinfo.as_array(); if(range.first == range.second) { //push back an empty tag res.push_back(empty_vconfig()); } while(range.first != range.second) { res.push_back(vconfig(*range.first++, true)); } } } } } return res; }
size_t vconfig::count_children(const std::string& key) const { size_t n = 0; for (const config::any_child &child : cfg_->all_children_range()) { if (child.key == key) { n++; } else if (child.key == "insert_tag") { vconfig insert_cfg(child.cfg); if(insert_cfg["name"] == key) { try { config::const_child_itors range = as_nonempty_range(insert_cfg["variable"]); n += range.second - range.first; } catch(const invalid_variablename_exception&) { n++; } } } } return n; }
vconfig::child_list vconfig::get_children(const std::string& key) const { vconfig::child_list res; for (const config::any_child &child : cfg_->all_children_range()) { if (child.key == key) { res.push_back(vconfig(child.cfg, cache_)); } else if (child.key == "insert_tag") { vconfig insert_cfg(child.cfg); if(insert_cfg["name"] == key) { try { config::const_child_itors range = as_nonempty_range(insert_cfg["variable"]); for (const config& child : range) { res.push_back(vconfig(child, true)); } } catch(const invalid_variablename_exception&) { res.push_back(empty_vconfig()); } } } } return res; }
config vconfig::get_parsed_config() const { // Keeps track of insert_tag variables. static std::set<std::string> vconfig_recursion; config res; BOOST_FOREACH(const config::attribute &i, cfg_->attribute_range()) { res[i.first] = expand(i.first); } BOOST_FOREACH(const config::any_child &child, cfg_->all_children_range()) { if (child.key == "insert_tag") { vconfig insert_cfg(child.cfg); const t_string& name = insert_cfg["name"]; const t_string& vname = insert_cfg["variable"]; if(!vconfig_recursion.insert(vname).second) { throw recursion_error("vconfig::get_parsed_config() infinite recursion detected, aborting"); } try { variable_info vinfo(vname, false, variable_info::TYPE_CONTAINER); if(!vinfo.is_valid) { res.add_child(name); //add empty tag } else if(vinfo.explicit_index) { res.add_child(name, vconfig(vinfo.as_container()).get_parsed_config()); } else { variable_info::array_range range = vinfo.as_array(); if(range.first == range.second) { res.add_child(name); //add empty tag } while(range.first != range.second) { res.add_child(name, vconfig(*range.first++).get_parsed_config()); } } vconfig_recursion.erase(vname); } catch(recursion_error &err) { vconfig_recursion.erase(vname); WRN_NG << err.message << std::endl; if(vconfig_recursion.empty()) { res.add_child("insert_tag", insert_cfg.get_config()); } else { // throw to the top [insert_tag] which started the recursion throw; } } } else { res.add_child(child.key, vconfig(child.cfg).get_parsed_config()); } } return res; }
/** * Returns whether or not *this has a child whose key is @a key. */ bool vconfig::has_child(const std::string& key) const { if (cfg_->child(key)) { return true; } BOOST_FOREACH(const config &ins, cfg_->child_range("insert_tag")) { vconfig insert_cfg(ins); if(insert_cfg["name"] == key) { return true; } } return false; }
config vconfig::get_parsed_config() const { // Keeps track of insert_tag variables. static std::set<std::string> vconfig_recursion; config res; for (const config::attribute &i : cfg_->attribute_range()) { res[i.first] = expand(i.first); } for (const config::any_child &child : cfg_->all_children_range()) { if (child.key == "insert_tag") { vconfig insert_cfg(child.cfg); const t_string& name = insert_cfg["name"]; const t_string& vname = insert_cfg["variable"]; if(!vconfig_recursion.insert(vname).second) { throw recursion_error("vconfig::get_parsed_config() infinite recursion detected, aborting"); } try { config::const_child_itors range = as_nonempty_range(vname); for (const config& child : range) { res.add_child(name, vconfig(child).get_parsed_config()); } } catch(const invalid_variablename_exception&) { res.add_child(name); } catch(recursion_error &err) { vconfig_recursion.erase(vname); WRN_NG << err.message << std::endl; if(vconfig_recursion.empty()) { res.add_child("insert_tag", insert_cfg.get_config()); } else { // throw to the top [insert_tag] which started the recursion throw; } } vconfig_recursion.erase(vname); } else { res.add_child(child.key, vconfig(child.cfg).get_parsed_config()); } } return res; }
/** * Returns a child of *this whose key is @a key. * If no such child exists, returns an unconstructed vconfig (use null() to test * for this). */ vconfig vconfig::child(const std::string& key) const { if (const config &natural = cfg_->child(key)) { return vconfig(natural, cache_); } BOOST_FOREACH(const config &ins, cfg_->child_range("insert_tag")) { vconfig insert_cfg(ins); if(insert_cfg["name"] == key) { variable_info vinfo(insert_cfg["variable"], false, variable_info::TYPE_CONTAINER); if(!vinfo.is_valid) { return empty_vconfig(); } return vconfig(vinfo.as_container(), true); } } return unconstructed_vconfig(); }
/** * Returns a child of *this whose key is @a key. * If no such child exists, returns an unconstructed vconfig (use null() to test * for this). */ vconfig vconfig::child(const std::string& key) const { if (const config &natural = cfg_->child(key)) { return vconfig(natural, cache_); } for (const config &ins : cfg_->child_range("insert_tag")) { vconfig insert_cfg(ins); if(insert_cfg["name"] == key) { try { config::const_child_itors range = as_nonempty_range(insert_cfg["variable"]); return vconfig(*range.first, true); } catch(const invalid_variablename_exception&) { return empty_vconfig(); } } } return unconstructed_vconfig(); }