Commit c519aa88 authored by Thomas Markwalder's avatar Thomas Markwalder

[2355] Minor changes in response to review comments.

parent f18722f2
...@@ -41,10 +41,6 @@ using namespace isc::asiolink; ...@@ -41,10 +41,6 @@ using namespace isc::asiolink;
namespace { namespace {
/// @brief Create the global parser context which stores global
/// parameters, options, and option definitions.
ParserContextPtr global_context_ptr(new ParserContext(Option::V4));
/// @brief Parser for DHCP4 option data value. /// @brief Parser for DHCP4 option data value.
/// ///
/// This parser parses configuration entries that specify value of /// This parser parses configuration entries that specify value of
...@@ -66,7 +62,7 @@ public: ...@@ -66,7 +62,7 @@ public:
/// @brief static factory method for instantiating Dhcp4OptionDataParsers /// @brief static factory method for instantiating Dhcp4OptionDataParsers
/// ///
/// @param param_name name fo the parameter to be parsed. /// @param param_name name of the parameter to be parsed.
/// @param options storage where the parameter value is to be stored. /// @param options storage where the parameter value is to be stored.
/// @param global_context is a pointer to the global context which /// @param global_context is a pointer to the global context which
/// stores global scope parameters, options, option defintions. /// stores global scope parameters, options, option defintions.
...@@ -130,10 +126,10 @@ protected: ...@@ -130,10 +126,10 @@ protected:
/// ///
/// @param addr is the IPv4 prefix of the pool. /// @param addr is the IPv4 prefix of the pool.
/// @param len is the prefix length. /// @param len is the prefix length.
/// @param ignored dummy parameter to provide symmetry between /// @param ignored dummy parameter to provide symmetry between the
/// PoolParser derivations. The V6 derivation requires a third value.
/// @return returns a PoolPtr to the new Pool4 object. /// @return returns a PoolPtr to the new Pool4 object.
PoolPtr poolMaker (IOAddress &addr, uint32_t len, int32_t) PoolPtr poolMaker (IOAddress &addr, uint32_t len, int32_t) {
{
return (PoolPtr(new Pool4(addr, len))); return (PoolPtr(new Pool4(addr, len)));
} }
...@@ -144,8 +140,7 @@ protected: ...@@ -144,8 +140,7 @@ protected:
/// @param ignored dummy parameter to provide symmetry between the /// @param ignored dummy parameter to provide symmetry between the
/// PoolParser derivations. The V6 derivation requires a third value. /// PoolParser derivations. The V6 derivation requires a third value.
/// @return returns a PoolPtr to the new Pool4 object. /// @return returns a PoolPtr to the new Pool4 object.
PoolPtr poolMaker (IOAddress &min, IOAddress &max, int32_t) PoolPtr poolMaker (IOAddress &min, IOAddress &max, int32_t) {
{
return (PoolPtr(new Pool4(min, max))); return (PoolPtr(new Pool4(min, max)));
} }
}; };
...@@ -162,15 +157,22 @@ public: ...@@ -162,15 +157,22 @@ public:
/// @param ignored first parameter /// @param ignored first parameter
/// @param global_context is a pointer to the global context which /// @param global_context is a pointer to the global context which
/// stores global scope parameters, options, option defintions. /// stores global scope parameters, options, option defintions.
Subnet4ConfigParser(const std::string&, ParserContextPtr global_context) Subnet4ConfigParser(const std::string&)
:SubnetConfigParser("", global_context) { :SubnetConfigParser("", globalContext()) {
} }
/// @brief Adds the created subnet to a server's configuration. /// @brief Adds the created subnet to a server's configuration.
/// @throw throws Unexpected if dynamic cast fails.
void commit() { void commit() {
if (subnet_) { if (subnet_) {
Subnet4Ptr bs = boost::dynamic_pointer_cast<Subnet4>(subnet_); Subnet4Ptr sub4ptr = boost::dynamic_pointer_cast<Subnet4>(subnet_);
isc::dhcp::CfgMgr::instance().addSubnet4(bs); if (!sub4ptr) {
// If we hit this, it is a programming error.
isc_throw(Unexpected,
"Invalid cast in Subnet4ConfigParser::commit");
}
isc::dhcp::CfgMgr::instance().addSubnet4(sub4ptr);
} }
} }
...@@ -191,14 +193,14 @@ protected: ...@@ -191,14 +193,14 @@ protected:
(config_id.compare("rebind-timer") == 0)) { (config_id.compare("rebind-timer") == 0)) {
parser = new Uint32Parser(config_id, uint32_values_); parser = new Uint32Parser(config_id, uint32_values_);
} else if ((config_id.compare("subnet") == 0) || } else if ((config_id.compare("subnet") == 0) ||
(config_id.compare("interface") == 0)) { (config_id.compare("interface") == 0)) {
parser = new StringParser(config_id, string_values_); parser = new StringParser(config_id, string_values_);
} else if (config_id.compare("pool") == 0) { } else if (config_id.compare("pool") == 0) {
parser = new Pool4Parser(config_id, pools_); parser = new Pool4Parser(config_id, pools_);
} else if (config_id.compare("option-data") == 0) { } else if (config_id.compare("option-data") == 0) {
parser = new OptionDataListParser(config_id, options_, parser = new OptionDataListParser(config_id, options_,
global_context_, global_context_,
Dhcp4OptionDataParser::factory); Dhcp4OptionDataParser::factory);
} else { } else {
isc_throw(NotImplemented, isc_throw(NotImplemented,
"parser error: Subnet4 parameter not supported: " << config_id); "parser error: Subnet4 parameter not supported: " << config_id);
...@@ -277,7 +279,7 @@ public: ...@@ -277,7 +279,7 @@ public:
/// @brief constructor /// @brief constructor
/// ///
/// @param dummy first argument, always ingored. All parsers accept a /// @param dummy first argument, always ignored. All parsers accept a
/// string parameter "name" as their first argument. /// string parameter "name" as their first argument.
Subnets4ListConfigParser(const std::string&) { Subnets4ListConfigParser(const std::string&) {
} }
...@@ -290,8 +292,7 @@ public: ...@@ -290,8 +292,7 @@ public:
/// @param subnets_list pointer to a list of IPv4 subnets /// @param subnets_list pointer to a list of IPv4 subnets
void build(ConstElementPtr subnets_list) { void build(ConstElementPtr subnets_list) {
BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) { BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
ParserPtr parser(new Subnet4ConfigParser("subnet", ParserPtr parser(new Subnet4ConfigParser("subnet"));
global_context_ptr));
parser->build(subnet); parser->build(subnet);
subnets_.push_back(parser); subnets_.push_back(parser);
} }
...@@ -346,22 +347,22 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) { ...@@ -346,22 +347,22 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
(config_id.compare("renew-timer") == 0) || (config_id.compare("renew-timer") == 0) ||
(config_id.compare("rebind-timer") == 0)) { (config_id.compare("rebind-timer") == 0)) {
parser = new Uint32Parser(config_id, parser = new Uint32Parser(config_id,
global_context_ptr->uint32_values_); globalContext()->uint32_values_);
} else if (config_id.compare("interface") == 0) { } else if (config_id.compare("interface") == 0) {
parser = new InterfaceListConfigParser(config_id); parser = new InterfaceListConfigParser(config_id);
} else if (config_id.compare("subnet4") == 0) { } else if (config_id.compare("subnet4") == 0) {
parser = new Subnets4ListConfigParser(config_id); parser = new Subnets4ListConfigParser(config_id);
} else if (config_id.compare("option-data") == 0) { } else if (config_id.compare("option-data") == 0) {
parser = new OptionDataListParser(config_id, parser = new OptionDataListParser(config_id,
global_context_ptr->options_, globalContext()->options_,
global_context_ptr, globalContext(),
Dhcp4OptionDataParser::factory); Dhcp4OptionDataParser::factory);
} else if (config_id.compare("option-def") == 0) { } else if (config_id.compare("option-def") == 0) {
parser = new OptionDefListParser(config_id, parser = new OptionDefListParser(config_id,
global_context_ptr->option_defs_); globalContext()->option_defs_);
} else if (config_id.compare("version") == 0) { } else if (config_id.compare("version") == 0) {
parser = new StringParser(config_id, parser = new StringParser(config_id,
global_context_ptr->string_values_); globalContext()->string_values_);
} else if (config_id.compare("lease-database") == 0) { } else if (config_id.compare("lease-database") == 0) {
parser = new DbAccessParser(config_id); parser = new DbAccessParser(config_id);
} else { } else {
...@@ -405,7 +406,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -405,7 +406,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
// parsing operation fails after the global storage has been // parsing operation fails after the global storage has been
// modified. We need to preserve the original global data here // modified. We need to preserve the original global data here
// so as we can rollback changes when an error occurs. // so as we can rollback changes when an error occurs.
ParserContext original_context(*global_context_ptr); ParserContext original_context(*globalContext());
// Answer will hold the result. // Answer will hold the result.
ConstElementPtr answer; ConstElementPtr answer;
...@@ -500,7 +501,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -500,7 +501,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
// Rollback changes as the configuration parsing failed. // Rollback changes as the configuration parsing failed.
if (rollback) { if (rollback) {
global_context_ptr.reset(new ParserContext(original_context)); globalContext().reset(new ParserContext(original_context));
return (answer); return (answer);
} }
...@@ -511,11 +512,13 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -511,11 +512,13 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
return (answer); return (answer);
} }
// Makes global context accessible for unit tests. ParserContextPtr globalContext() {
const ParserContext& getGlobalParserContext() { static ParserContextPtr global_context_ptr(new ParserContext(Option::V4));
return (*global_context_ptr); return (global_context_ptr);
} }
}; // end of isc::dhcp namespace }; // end of isc::dhcp namespace
}; // end of isc namespace }; // end of isc namespace
...@@ -63,11 +63,8 @@ configureDhcp4Server(Dhcpv4Srv&, ...@@ -63,11 +63,8 @@ configureDhcp4Server(Dhcpv4Srv&,
/// @brief Returns the global context /// @brief Returns the global context
/// ///
/// This function must be only used by unit tests that need /// @return a const reference to the global context
/// to access global context. ParserContextPtr globalContext();
///
/// @returns a const reference to the global context
const ParserContext& getGlobalParserContext();
}; // end of isc::dhcp namespace }; // end of isc::dhcp namespace
}; // end of isc namespace }; // end of isc namespace
......
...@@ -53,7 +53,11 @@ public: ...@@ -53,7 +53,11 @@ public:
// Checks if global parameter of name have expected_value // Checks if global parameter of name have expected_value
void checkGlobalUint32(string name, uint32_t expected_value) { void checkGlobalUint32(string name, uint32_t expected_value) {
const Uint32StoragePtr uint32_defaults = const Uint32StoragePtr uint32_defaults =
#if 0
getGlobalParserContext().uint32_values_; getGlobalParserContext().uint32_values_;
#else
globalContext()->uint32_values_;
#endif
try { try {
uint32_t actual_value = uint32_defaults->getParam(name); uint32_t actual_value = uint32_defaults->getParam(name);
EXPECT_EQ(expected_value, actual_value); EXPECT_EQ(expected_value, actual_value);
......
...@@ -55,9 +55,6 @@ typedef boost::shared_ptr<BooleanParser> BooleanParserPtr; ...@@ -55,9 +55,6 @@ typedef boost::shared_ptr<BooleanParser> BooleanParserPtr;
typedef boost::shared_ptr<StringParser> StringParserPtr; typedef boost::shared_ptr<StringParser> StringParserPtr;
typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr; typedef boost::shared_ptr<Uint32Parser> Uint32ParserPtr;
// TKM - declare a global parser context
ParserContextPtr global_context_ptr(new ParserContext(Option::V6));
/// @brief Parser for DHCP6 option data value. /// @brief Parser for DHCP6 option data value.
/// ///
/// This parser parses configuration entries that specify value of /// This parser parses configuration entries that specify value of
...@@ -182,15 +179,21 @@ public: ...@@ -182,15 +179,21 @@ public:
/// @param ignored first parameter /// @param ignored first parameter
/// @param global_context is a pointer to the global context which /// @param global_context is a pointer to the global context which
/// stores global scope parameters, options, option defintions. /// stores global scope parameters, options, option defintions.
Subnet6ConfigParser(const std::string&, ParserContextPtr global_context) Subnet6ConfigParser(const std::string&)
:SubnetConfigParser("", global_context) { :SubnetConfigParser("", globalContext()) {
} }
/// @brief Adds the created subnet to a server's configuration. /// @brief Adds the created subnet to a server's configuration.
/// @throw throws Unexpected if dynamic cast fails.
void commit() { void commit() {
if (subnet_) { if (subnet_) {
Subnet6Ptr bs = boost::dynamic_pointer_cast<Subnet6>(subnet_); Subnet6Ptr sub6ptr = boost::dynamic_pointer_cast<Subnet6>(subnet_);
isc::dhcp::CfgMgr::instance().addSubnet6(bs); if (!sub6ptr) {
// If we hit this, it is a programming error.
isc_throw(Unexpected,
"Invalid cast in Subnet4ConfigParser::commit");
}
isc::dhcp::CfgMgr::instance().addSubnet6(sub6ptr);
} }
} }
...@@ -212,7 +215,7 @@ protected: ...@@ -212,7 +215,7 @@ protected:
(config_id.compare("rebind-timer") == 0)) { (config_id.compare("rebind-timer") == 0)) {
parser = new Uint32Parser(config_id, uint32_values_); parser = new Uint32Parser(config_id, uint32_values_);
} else if ((config_id.compare("subnet") == 0) || } else if ((config_id.compare("subnet") == 0) ||
(config_id.compare("interface") == 0)) { (config_id.compare("interface") == 0)) {
parser = new StringParser(config_id, string_values_); parser = new StringParser(config_id, string_values_);
} else if (config_id.compare("pool") == 0) { } else if (config_id.compare("pool") == 0) {
parser = new Pool6Parser(config_id, pools_); parser = new Pool6Parser(config_id, pools_);
...@@ -303,7 +306,7 @@ public: ...@@ -303,7 +306,7 @@ public:
/// @brief constructor /// @brief constructor
/// ///
/// @param dummy first argument, always ingored. All parsers accept a /// @param dummy first argument, always ignored. All parsers accept a
/// string parameter "name" as their first argument. /// string parameter "name" as their first argument.
Subnets6ListConfigParser(const std::string&) { Subnets6ListConfigParser(const std::string&) {
} }
...@@ -316,8 +319,7 @@ public: ...@@ -316,8 +319,7 @@ public:
/// @param subnets_list pointer to a list of IPv6 subnets /// @param subnets_list pointer to a list of IPv6 subnets
void build(ConstElementPtr subnets_list) { void build(ConstElementPtr subnets_list) {
BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) { BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
ParserPtr parser(new Subnet6ConfigParser("subnet", ParserPtr parser(new Subnet6ConfigParser("subnet" ));
global_context_ptr));
parser->build(subnet); parser->build(subnet);
subnets_.push_back(parser); subnets_.push_back(parser);
} }
...@@ -373,22 +375,22 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) { ...@@ -373,22 +375,22 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
(config_id.compare("renew-timer") == 0) || (config_id.compare("renew-timer") == 0) ||
(config_id.compare("rebind-timer") == 0)) { (config_id.compare("rebind-timer") == 0)) {
parser = new Uint32Parser(config_id, parser = new Uint32Parser(config_id,
global_context_ptr->uint32_values_); globalContext()->uint32_values_);
} else if (config_id.compare("interface") == 0) { } else if (config_id.compare("interface") == 0) {
parser = new InterfaceListConfigParser(config_id); parser = new InterfaceListConfigParser(config_id);
} else if (config_id.compare("subnet6") == 0) { } else if (config_id.compare("subnet6") == 0) {
parser = new Subnets6ListConfigParser(config_id); parser = new Subnets6ListConfigParser(config_id);
} else if (config_id.compare("option-data") == 0) { } else if (config_id.compare("option-data") == 0) {
parser = new OptionDataListParser(config_id, parser = new OptionDataListParser(config_id,
global_context_ptr->options_, globalContext()->options_,
global_context_ptr, globalContext(),
Dhcp6OptionDataParser::factory); Dhcp6OptionDataParser::factory);
} else if (config_id.compare("option-def") == 0) { } else if (config_id.compare("option-def") == 0) {
parser = new OptionDefListParser(config_id, parser = new OptionDefListParser(config_id,
global_context_ptr->option_defs_); globalContext()->option_defs_);
} else if (config_id.compare("version") == 0) { } else if (config_id.compare("version") == 0) {
parser = new StringParser(config_id, parser = new StringParser(config_id,
global_context_ptr->string_values_); globalContext()->string_values_);
} else if (config_id.compare("lease-database") == 0) { } else if (config_id.compare("lease-database") == 0) {
parser = new DbAccessParser(config_id); parser = new DbAccessParser(config_id);
} else { } else {
...@@ -432,7 +434,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) { ...@@ -432,7 +434,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
// parsing operation fails after the global storage has been // parsing operation fails after the global storage has been
// modified. We need to preserve the original global data here // modified. We need to preserve the original global data here
// so as we can rollback changes when an error occurs. // so as we can rollback changes when an error occurs.
ParserContext original_context(*global_context_ptr); ParserContext original_context(*globalContext());
// answer will hold the result. // answer will hold the result.
ConstElementPtr answer; ConstElementPtr answer;
...@@ -528,7 +530,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) { ...@@ -528,7 +530,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
// Rollback changes as the configuration parsing failed. // Rollback changes as the configuration parsing failed.
if (rollback) { if (rollback) {
global_context_ptr.reset(new ParserContext(original_context)); globalContext().reset(new ParserContext(original_context));
return (answer); return (answer);
} }
...@@ -539,9 +541,9 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) { ...@@ -539,9 +541,9 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
return (answer); return (answer);
} }
// Makes global context accessible for unit tests. ParserContextPtr globalContext() {
const ParserContext& getGlobalParserContext() { static ParserContextPtr global_context_ptr(new ParserContext(Option::V6));
return (*global_context_ptr); return (global_context_ptr);
} }
}; // end of isc::dhcp namespace }; // end of isc::dhcp namespace
......
...@@ -51,11 +51,8 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set); ...@@ -51,11 +51,8 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set);
/// @brief Returns the global context /// @brief Returns the global context
/// ///
/// This function must be only used by unit tests that need
/// to access global context.
///
/// @returns a const reference to the global context /// @returns a const reference to the global context
const ParserContext& getGlobalParserContext(); ParserContextPtr globalContext();
}; // end of isc::dhcp namespace }; // end of isc::dhcp namespace
}; // end of isc namespace }; // end of isc namespace
......
...@@ -130,82 +130,6 @@ public: ...@@ -130,82 +130,6 @@ public:
virtual void commit() = 0; virtual void commit() = 0;
}; };
/// @brief A template class that stores named elements of a given data type.
///
/// This template class is provides data value storage for configuration parameters
/// of a given data type. The values are stored by parameter name and as instances
/// of type "ValueType".
///
/// @param ValueType is the data type of the elements to store.
template<typename ValueType>
class ValueStorage {
public:
/// @brief Stores the the parameter and its value in the store.
///
/// If the parameter does not exist in the store, then it will be added,
/// otherwise its data value will be updated with the given value.
///
/// @param name is the name of the paramater to store.
/// @param value is the data value to store.
void setParam(const std::string& name, const ValueType& value) {
values_[name] = value;
}
/// @brief Returns the data value for the given parameter.
///
/// Finds and returns the data value for the given parameter.
/// @param name is the name of the parameter for which the data
/// value is desired.
///
/// @return The paramater's data value of type <ValueType>.
/// @throw DhcpConfigError if the parameter is not found.
ValueType getParam(const std::string& name) const {
typename std::map<std::string, ValueType>::const_iterator param
= values_.find(name);
if (param == values_.end()) {
isc_throw(DhcpConfigError, "Missing parameter '"
<< name << "'");
}
return (param->second);
}
/// @brief Remove the parameter from the store.
///
/// Deletes the entry for the given parameter from the store if it
/// exists.
///
/// @param name is the name of the paramater to delete.
void delParam(const std::string& name) {
values_.erase(name);
}
/// @brief Deletes all of the entries from the store.
///
void clear() {
values_.clear();
}
private:
/// @brief An std::map of the data values, keyed by parameter names.
std::map<std::string, ValueType> values_;
};
/// @brief a collection of elements that store uint32 values (e.g. renew-timer = 900)
typedef ValueStorage<uint32_t> Uint32Storage;
typedef boost::shared_ptr<Uint32Storage> Uint32StoragePtr;
/// @brief a collection of elements that store string values
typedef ValueStorage<std::string> StringStorage;
typedef boost::shared_ptr<StringStorage> StringStoragePtr;
/// @brief Storage for parsed boolean values.
typedef ValueStorage<bool> BooleanStorage;
typedef boost::shared_ptr<BooleanStorage> BooleanStoragePtr;
}; // end of isc::dhcp namespace }; // end of isc::dhcp namespace
}; // end of isc namespace }; // end of isc namespace
......
...@@ -44,7 +44,7 @@ ParserContext::ParserContext(Option::Universe universe): ...@@ -44,7 +44,7 @@ ParserContext::ParserContext(Option::Universe universe):
universe_(universe) { universe_(universe) {
} }
ParserContext::ParserContext(ParserContext& rhs): ParserContext::ParserContext(const ParserContext& rhs):
boolean_values_(new BooleanStorage(*(rhs.boolean_values_))), boolean_values_(new BooleanStorage(*(rhs.boolean_values_))),
uint32_values_(new Uint32Storage(*(rhs.uint32_values_))), uint32_values_(new Uint32Storage(*(rhs.uint32_values_))),
string_values_(new StringStorage(*(rhs.string_values_))), string_values_(new StringStorage(*(rhs.string_values_))),
...@@ -53,19 +53,38 @@ ParserContext::ParserContext(ParserContext& rhs): ...@@ -53,19 +53,38 @@ ParserContext::ParserContext(ParserContext& rhs):
universe_(rhs.universe_) { universe_(rhs.universe_) {
} }
ParserContext&
ParserContext::operator=(const ParserContext& rhs) {
ParserContext tmp(rhs);
boolean_values_ =
BooleanStoragePtr(new BooleanStorage(*(rhs.boolean_values_)));
uint32_values_ =
Uint32StoragePtr(new Uint32Storage(*(tmp.uint32_values_)));
string_values_ =
StringStoragePtr(new StringStorage(*(tmp.string_values_)));
options_ = OptionStoragePtr(new OptionStorage(*(tmp.options_)));
option_defs_ =
OptionDefStoragePtr(new OptionDefStorage(*(tmp.option_defs_)));
universe_ = rhs.universe_;
return (*this);
}
// **************************** DebugParser ************************* // **************************** DebugParser *************************
DebugParser::DebugParser(const std::string& param_name) DebugParser::DebugParser(const std::string& param_name)
:param_name_(param_name) { :param_name_(param_name) {
} }
void DebugParser::build(ConstElementPtr new_config) { void
DebugParser::build(ConstElementPtr new_config) {
std::cout << "Build for token: [" << param_name_ <<