예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
/**
 * 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;
}
예제 #6
0
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;
}
예제 #7
0
/**
 * 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();
}
예제 #8
0
/**
 * 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();
}