- Timestamp:
- Mar 13, 2014, 10:41:30 AM (11 years ago)
- Location:
- trunk/src/PacpusLib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/PacpusLib/ComponentBase.cpp
r263 r270 244 244 } 245 245 246 void ComponentBase::parseParameters(const XmlComponentConfig & cfg) 246 class DomElementParser 247 { 248 public: 249 DomElementParser(QDomElement const& args); 250 251 /** Sets options descriptions to use. */ 252 DomElementParser& options(const boost::program_options::options_description& desc); 253 254 /** Parses the options and returns the result of parsing. 255 Throws on error. 256 */ 257 boost::program_options::basic_parsed_options<char> run(); 258 259 /** Specifies that unregistered options are allowed and should 260 be passed though. For each command like token that looks 261 like an option but does not contain a recognized name, an 262 instance of basic_option<charT> will be added to result, 263 with 'unrecognized' field set to 'true'. It's possible to 264 collect all unrecognized options with the 'collect_unrecognized' 265 funciton. 266 */ 267 DomElementParser& allow_unregistered(); 268 269 private: 270 boost::program_options::basic_parsed_options<char> parseDomElement( 271 const QDomElement& dom_element, 272 const boost::program_options::options_description& desc, 273 bool allow_unregistered = false); 274 275 private: 276 const boost::program_options::options_description* m_desc; 277 const QDomElement& m_dom_element; 278 bool m_allow_unregistered; 279 }; 280 281 DomElementParser::DomElementParser(const QDomElement& dom_element) 282 : m_dom_element(dom_element) 283 , m_allow_unregistered(false) 284 { 285 } 286 287 DomElementParser& DomElementParser::options(const boost::program_options::options_description& desc) 288 { 289 m_desc = &desc; 290 return *this; 291 } 292 293 DomElementParser& DomElementParser::allow_unregistered() 294 { 295 m_allow_unregistered = true; 296 return *this; 297 } 298 299 #include <boost/iterator/iterator_facade.hpp> 300 #include <boost/program_options/errors.hpp> 301 302 namespace detail 303 { 304 template <typename charT> 305 class basic_dom_element_iterator 306 : public boost::iterator_facade< 307 basic_dom_element_iterator<charT> 308 , const boost::program_options::option 309 , boost::random_access_traversal_tag 310 > 311 { 312 public: 313 typedef boost::program_options::option ValueType; 314 315 basic_dom_element_iterator<charT>() 316 : m_dom_element(NULL) 317 , m_at_eof(true) 318 { 319 } 320 321 basic_dom_element_iterator<charT>(const QDomElement& dom_element, 322 const std::set<std::string>& allowed_options, 323 bool allow_unregistered = false) 324 : m_dom_element(&dom_element) 325 , m_allowed_options(allowed_options) 326 , m_allow_unregistered(false) 327 , m_i(0) 328 { 329 m_attrs = m_dom_element->attributes(); 330 m_at_eof = !(m_i < m_attrs.size()); 331 if (!m_at_eof) { 332 get(); 333 } 334 } 335 336 //private: 337 friend class iterator_core_access; 338 339 bool equal(const basic_dom_element_iterator<charT>& other) const 340 { 341 if (m_at_eof && other.m_at_eof) { 342 return true; 343 } 344 return false; 345 } 346 347 void increment() 348 { 349 ++m_i; 350 m_at_eof = !(m_i < m_attrs.size()); 351 if (!m_at_eof) { 352 get(); 353 } 354 } 355 356 const ValueType& dereference() const 357 { 358 return m_value; 359 } 360 361 difference_type distance_to(const basic_dom_element_iterator<charT>& other) const 362 { 363 return other.m_i - this->m_i; 364 } 365 366 private: 367 ValueType& value() 368 { 369 return m_value; 370 } 371 372 void get() 373 { 374 using namespace boost::program_options; 375 376 QDomNode node = m_attrs.item(m_i); 377 QDomAttr attr = node.toAttr(); 378 379 string name = attr.name().toStdString(); 380 string value = attr.value().toStdString(); 381 382 bool registered = allowed_option(name); 383 if (!registered && !m_allow_unregistered) { 384 boost::throw_exception(unknown_option(name)); 385 } 386 387 this->value().string_key = name; 388 this->value().value.clear(); 389 this->value().value.push_back(value); 390 this->value().unregistered = !registered; 391 this->value().original_tokens.push_back(name); 392 this->value().original_tokens.push_back(value); 393 } 394 395 bool allowed_option(const std::string& s) const 396 { 397 set<string>::const_iterator i = m_allowed_options.find(s); 398 if (i != m_allowed_options.end()) { 399 return true; 400 } 401 return false; 402 } 403 404 private: 405 const QDomElement* m_dom_element; 406 std::set<std::string> m_allowed_options; 407 bool m_allow_unregistered; 408 409 QDomNamedNodeMap m_attrs; 410 int m_i; 411 bool m_at_eof; 412 ValueType m_value; 413 }; 414 415 typedef basic_dom_element_iterator<char> dom_element_iterator; 416 typedef basic_dom_element_iterator<wchar_t> wdom_element_iterator; 417 418 } 419 420 boost::program_options::basic_parsed_options<char> DomElementParser::run() 421 { 422 assert(m_desc); 423 return parseDomElement(m_dom_element, *m_desc, m_allow_unregistered); 424 } 425 426 boost::program_options::basic_parsed_options<char> DomElementParser::parseDomElement( 427 const QDomElement& dom_element, 428 const boost::program_options::options_description& desc, 429 bool allow_unregistered) 430 { 431 typedef char charT; 432 433 using boost::program_options::error; 434 using boost::shared_ptr; 435 using namespace boost::program_options; 436 using ::detail::basic_dom_element_iterator; 437 438 set<string> allowed_options; 439 440 const vector<shared_ptr<option_description> >& options = desc.options(); 441 for (unsigned i = 0; i < options.size(); ++i) { 442 const option_description& d = *options[i]; 443 444 if (d.long_name().empty()) { 445 boost::throw_exception( 446 error("abbreviated option names are not permitted when parsing DOM elements")); 447 } 448 449 allowed_options.insert(d.long_name()); 450 } 451 452 // Parser returns char strings 453 parsed_options result(&desc); 454 copy(basic_dom_element_iterator<charT>(dom_element, allowed_options, allow_unregistered), 455 basic_dom_element_iterator<charT>(), 456 back_inserter(result.options)); 457 458 // Convert char strings into desired type. 459 return basic_parsed_options<charT>(result); 460 } 461 462 DomElementParser parseDomElement(); 463 464 /** Creates instance of 'command_line_parser', passes parameters to it, 465 and returns the result of calling the 'run' method. 466 */ 467 boost::program_options::basic_parsed_options<char> 468 parseDomElement(QDomElement const& domElement, const boost::program_options::options_description&); 469 470 boost::program_options::basic_parsed_options<char> 471 parseDomElement(QDomElement const& domElement, const boost::program_options::options_description& desc) 472 { 473 return DomElementParser(domElement) 474 .options(desc) 475 .run(); 476 } 477 478 void ComponentBase::parseParameters(XmlComponentConfig const& cfg) 247 479 { 248 480 LOG_INFO("Parsing parameters..."); … … 254 486 try { 255 487 po::store( 256 po::command_line_parser(xargs) 488 DomElementParser(cfg.getDomElement()) 489 //po::command_line_parser(xargs) 257 490 .options(mOptionsDescription) 258 491 .allow_unregistered() // FIXME: temporary only, at term all the components specify all parameters … … 260 493 , vm); 261 494 po::notify(vm); 262 } catch (po::error 495 } catch (po::error& e) { 263 496 LOG_WARN(e.what()); 264 497 throw PacpusException(e.what()); -
trunk/src/PacpusLib/ComponentManager.cpp
r232 r270 340 340 } 341 341 342 component->param.localCopy(cfg. qDomElement());342 component->param.localCopy(cfg.getDomElement()); 343 343 try { 344 344 component->parseParameters(cfg); … … 373 373 374 374 // copy locally the config parameters of the component 375 component->param.localCopy(cfg. qDomElement());375 component->param.localCopy(cfg.getDomElement()); 376 376 component->setConfigurationState(component->configureComponent(cfg)); 377 377 } -
trunk/src/PacpusLib/XmlComponentConfig.cpp
r176 r270 126 126 } 127 127 128 QDomElement XmlComponentConfig::qDomElement() const128 QDomElement const& XmlComponentConfig::getDomElement() const 129 129 { 130 130 return component_;
Note:
See TracChangeset
for help on using the changeset viewer.