|  |  | @ -19,11 +19,12 @@ namespace bpo = boost::program_options; | 
			
		
	
		
			
				
					|  |  |  | /*
 | 
			
		
	
		
			
				
					|  |  |  |  * static initializers | 
			
		
	
		
			
				
					|  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  | std::unique_ptr<bpo::options_description> mrmc::settings::Settings::cli; | 
			
		
	
		
			
				
					|  |  |  | std::unique_ptr<bpo::options_description> mrmc::settings::Settings::conf = nullptr; | 
			
		
	
		
			
				
					|  |  |  | std::unique_ptr<bpo::options_description> mrmc::settings::Settings::desc = nullptr; | 
			
		
	
		
			
				
					|  |  |  | std::string mrmc::settings::Settings::binaryName = ""; | 
			
		
	
		
			
				
					|  |  |  | mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | std::map< std::pair<std::string, std::string>, bpo::options_description* > mrmc::settings::Settings::modules; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*!
 | 
			
		
	
		
			
				
					|  |  |  |  *	The constructor fills the option descriptions, parses the | 
			
		
	
		
			
				
					|  |  |  |  *	command line and the config file and puts the option values to | 
			
		
	
	
		
			
				
					|  |  | @ -38,7 +39,6 @@ mrmc::settings::Settings* mrmc::settings::Settings::inst = nullptr; | 
			
		
	
		
			
				
					|  |  |  |  *	@param filename	either nullptr or name of config file | 
			
		
	
		
			
				
					|  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  | Settings::Settings(const int argc, const char* argv[], const char* filename) | 
			
		
	
		
			
				
					|  |  |  | 	: configfile("Config Options"), generic("Generic Options"), commandline("Commandline Options") | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	Settings::binaryName = std::string(argv[0]); | 
			
		
	
		
			
				
					|  |  |  | 	try | 
			
		
	
	
		
			
				
					|  |  | @ -49,22 +49,33 @@ Settings::Settings(const int argc, const char* argv[], const char* filename) | 
			
		
	
		
			
				
					|  |  |  | 		//! Take care of positional arguments
 | 
			
		
	
		
			
				
					|  |  |  | 		Settings::positional.add("trafile", 1); | 
			
		
	
		
			
				
					|  |  |  | 		Settings::positional.add("labfile", 1); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 		//! Check module triggers
 | 
			
		
	
		
			
				
					|  |  |  | 		for (auto it : Settings::modules) | 
			
		
	
		
			
				
					|  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  | 			std::pair< std::string, std::string > trigger = it.first; | 
			
		
	
		
			
				
					|  |  |  | 			Settings::desc->add_options() | 
			
		
	
		
			
				
					|  |  |  | 				(trigger.first.c_str(), bpo::value<std::string>(), trigger.second.c_str()) | 
			
		
	
		
			
				
					|  |  |  | 			; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		//! Create and fill collecting options descriptions
 | 
			
		
	
		
			
				
					|  |  |  | 		Settings::cli = std::unique_ptr<bpo::options_description>(new bpo::options_description()); | 
			
		
	
		
			
				
					|  |  |  | 		Settings::cli->add(Settings::commandline).add(generic); | 
			
		
	
		
			
				
					|  |  |  | 		Settings::conf = std::unique_ptr<bpo::options_description>(new bpo::options_description()); | 
			
		
	
		
			
				
					|  |  |  | 		Settings::conf->add(Settings::configfile).add(generic); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		//! Perform first parse run and call intermediate callbacks
 | 
			
		
	
		
			
				
					|  |  |  | 		//! Perform first parse run
 | 
			
		
	
		
			
				
					|  |  |  | 		this->firstRun(argc, argv, filename); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		//! Rebuild collecting options descriptions
 | 
			
		
	
		
			
				
					|  |  |  | 		Settings::cli = std::unique_ptr<bpo::options_description>(new bpo::options_description()); | 
			
		
	
		
			
				
					|  |  |  | 		Settings::cli->add(Settings::commandline).add(generic); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 		Settings::conf = std::unique_ptr<bpo::options_description>(new bpo::options_description()); | 
			
		
	
		
			
				
					|  |  |  | 		Settings::conf->add(Settings::configfile).add(generic); | 
			
		
	
		
			
				
					|  |  |  | 		//! Check module triggers
 | 
			
		
	
		
			
				
					|  |  |  | 		for (auto it : Settings::modules) | 
			
		
	
		
			
				
					|  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  | 			std::pair< std::string, std::string > trigger = it.first; | 
			
		
	
		
			
				
					|  |  |  | 			if (this->vm.count(trigger.first)) | 
			
		
	
		
			
				
					|  |  |  | 			{ | 
			
		
	
		
			
				
					|  |  |  | 				if (this->vm[trigger.first].as<std::string>().compare(trigger.second) == 0) | 
			
		
	
		
			
				
					|  |  |  | 				{ | 
			
		
	
		
			
				
					|  |  |  | 					Settings::desc->add(*it.second); | 
			
		
	
		
			
				
					|  |  |  | 					Settings::modules.erase(trigger); | 
			
		
	
		
			
				
					|  |  |  | 				} | 
			
		
	
		
			
				
					|  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  | 			 | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		//! Stop if help is set
 | 
			
		
	
		
			
				
					|  |  |  | 		if ((this->vm.count("help") > 0) || (this->vm.count("help-config") > 0)) | 
			
		
	
	
		
			
				
					|  |  | @ -77,7 +88,6 @@ Settings::Settings(const int argc, const char* argv[], const char* filename) | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		//! Finalize parsed options, check for specified requirements
 | 
			
		
	
		
			
				
					|  |  |  | 		bpo::notify(this->vm); | 
			
		
	
		
			
				
					|  |  |  | 		mrmc::settings::Callbacks::instance()->disabled = true; | 
			
		
	
		
			
				
					|  |  |  | 		LOG4CPLUS_DEBUG(logger, "Finished loading config."); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 	catch (bpo::reading_file e) | 
			
		
	
	
		
			
				
					|  |  | @ -118,43 +128,16 @@ Settings::Settings(const int argc, const char* argv[], const char* filename) | 
			
		
	
		
			
				
					|  |  |  | void Settings::initDescriptions() | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	LOG4CPLUS_DEBUG(logger, "Initializing descriptions."); | 
			
		
	
		
			
				
					|  |  |  | 	this->commandline.add_options() | 
			
		
	
		
			
				
					|  |  |  | 	Settings::desc = std::unique_ptr<bpo::options_description>(new bpo::options_description("Generic Options")); | 
			
		
	
		
			
				
					|  |  |  | 	Settings::desc->add_options() | 
			
		
	
		
			
				
					|  |  |  | 		("help,h", "produce help message") | 
			
		
	
		
			
				
					|  |  |  | 		("verbose,v", "be verbose") | 
			
		
	
		
			
				
					|  |  |  | 		("help-config", "produce help message about config file") | 
			
		
	
		
			
				
					|  |  |  | 		("configfile,c", bpo::value<std::string>(), "name of config file") | 
			
		
	
		
			
				
					|  |  |  | 		("test-prctl", bpo::value<std::string>(), "name of prctl file") | 
			
		
	
		
			
				
					|  |  |  | 	; | 
			
		
	
		
			
				
					|  |  |  | 	this->generic.add_options() | 
			
		
	
		
			
				
					|  |  |  | 		("trafile", bpo::value<std::string>()->required(), "name of the .tra file") | 
			
		
	
		
			
				
					|  |  |  | 		("labfile", bpo::value<std::string>()->required(), "name of the .lab file") | 
			
		
	
		
			
				
					|  |  |  | 	; | 
			
		
	
		
			
				
					|  |  |  | 	this->configfile.add_options() | 
			
		
	
		
			
				
					|  |  |  | 	; | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	/*
 | 
			
		
	
		
			
				
					|  |  |  | 	 *	Get Callbacks object, then iterate over and call all register callbacks. | 
			
		
	
		
			
				
					|  |  |  | 	 */ | 
			
		
	
		
			
				
					|  |  |  | 	Callbacks* cb = mrmc::settings::Callbacks::instance(); | 
			
		
	
		
			
				
					|  |  |  | 	while (cb->registerList.size() > 0) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		CallbackType type = cb->registerList.front().first; | 
			
		
	
		
			
				
					|  |  |  | 		RegisterCallback fptr = cb->registerList.front().second; | 
			
		
	
		
			
				
					|  |  |  | 		cb->registerList.pop_front(); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		switch (type) | 
			
		
	
		
			
				
					|  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  | 			case CB_CONFIG: | 
			
		
	
		
			
				
					|  |  |  | 				(*fptr)(this->configfile); | 
			
		
	
		
			
				
					|  |  |  | 				break; | 
			
		
	
		
			
				
					|  |  |  | 			case CB_CLI: | 
			
		
	
		
			
				
					|  |  |  | 				(*fptr)(this->commandline); | 
			
		
	
		
			
				
					|  |  |  | 				break; | 
			
		
	
		
			
				
					|  |  |  | 			case CB_GENERIC: | 
			
		
	
		
			
				
					|  |  |  | 				(*fptr)(this->generic); | 
			
		
	
		
			
				
					|  |  |  | 				break; | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | /*!
 | 
			
		
	
	
		
			
				
					|  |  | @ -168,50 +151,18 @@ void Settings::firstRun(const int argc, const char* argv[], const char* filename | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	LOG4CPLUS_DEBUG(logger, "Performing first run."); | 
			
		
	
		
			
				
					|  |  |  | 	//! parse command line
 | 
			
		
	
		
			
				
					|  |  |  | 	bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::cli)).allow_unregistered().run(), this->vm); | 
			
		
	
		
			
				
					|  |  |  | 	bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::desc)).allow_unregistered().run(), this->vm); | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  | 	/*
 | 
			
		
	
		
			
				
					|  |  |  | 	 *	load config file if specified | 
			
		
	
		
			
				
					|  |  |  | 	 */ | 
			
		
	
		
			
				
					|  |  |  | 	if (this->vm.count("configfile")) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::conf)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::desc)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 	else if (filename != NULL) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(filename, *(Settings::conf)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  | 	/*
 | 
			
		
	
		
			
				
					|  |  |  | 	 *	Call intermediate callbacks. | 
			
		
	
		
			
				
					|  |  |  | 	 */ | 
			
		
	
		
			
				
					|  |  |  | 	Callbacks* cb = mrmc::settings::Callbacks::instance(); | 
			
		
	
		
			
				
					|  |  |  | 	while (cb->intermediateList.size() > 0) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		CallbackType type = cb->intermediateList.front().first; | 
			
		
	
		
			
				
					|  |  |  | 		IntermediateCallback fptr = cb->intermediateList.front().second; | 
			
		
	
		
			
				
					|  |  |  | 		cb->intermediateList.pop_front(); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		try | 
			
		
	
		
			
				
					|  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  | 			switch (type) | 
			
		
	
		
			
				
					|  |  |  | 			{ | 
			
		
	
		
			
				
					|  |  |  | 				case CB_CONFIG: | 
			
		
	
		
			
				
					|  |  |  | 					(*fptr)(&this->configfile, this->vm); | 
			
		
	
		
			
				
					|  |  |  | 					break; | 
			
		
	
		
			
				
					|  |  |  | 				case CB_CLI: | 
			
		
	
		
			
				
					|  |  |  | 					(*fptr)(&this->commandline, this->vm); | 
			
		
	
		
			
				
					|  |  |  | 					break; | 
			
		
	
		
			
				
					|  |  |  | 				case CB_GENERIC: | 
			
		
	
		
			
				
					|  |  |  | 					(*fptr)(&this->generic, this->vm); | 
			
		
	
		
			
				
					|  |  |  | 					break; | 
			
		
	
		
			
				
					|  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		catch (boost::bad_any_cast e) | 
			
		
	
		
			
				
					|  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  | 			std::cerr << "An intermediate callback failed." << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 			LOG4CPLUS_ERROR(logger, "An intermediate callback failed.\n" << e.what()); | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(filename, *(Settings::desc)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -226,35 +177,17 @@ void Settings::secondRun(const int argc, const char* argv[], const char* filenam | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	LOG4CPLUS_DEBUG(logger, "Performing second run."); | 
			
		
	
		
			
				
					|  |  |  | 	//! Parse command line
 | 
			
		
	
		
			
				
					|  |  |  | 	bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::cli)).positional(this->positional).run(), this->vm); | 
			
		
	
		
			
				
					|  |  |  | 	bpo::store(bpo::command_line_parser(argc, argv).options(*(Settings::desc)).positional(this->positional).run(), this->vm); | 
			
		
	
		
			
				
					|  |  |  | 	/*
 | 
			
		
	
		
			
				
					|  |  |  | 	 *	load config file if specified | 
			
		
	
		
			
				
					|  |  |  | 	 */ | 
			
		
	
		
			
				
					|  |  |  | 	if (this->vm.count("configfile")) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::conf)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(this->vm["configfile"].as<std::string>().c_str(), *(Settings::desc)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 	else if (filename != NULL) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(filename, *(Settings::conf)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  | 	 | 
			
		
	
		
			
				
					|  |  |  | 	/*
 | 
			
		
	
		
			
				
					|  |  |  | 	 *	Call checker callbacks. | 
			
		
	
		
			
				
					|  |  |  | 	 */ | 
			
		
	
		
			
				
					|  |  |  | 	Callbacks* cb = mrmc::settings::Callbacks::instance(); | 
			
		
	
		
			
				
					|  |  |  | 	while (cb->checkerList.size() > 0) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		CheckerCallback fptr = cb->checkerList.front(); | 
			
		
	
		
			
				
					|  |  |  | 		cb->checkerList.pop_front(); | 
			
		
	
		
			
				
					|  |  |  | 		 | 
			
		
	
		
			
				
					|  |  |  | 		if (! (*fptr)(this->vm)) | 
			
		
	
		
			
				
					|  |  |  | 		{ | 
			
		
	
		
			
				
					|  |  |  | 			std::cerr << "Custom option checker failed." << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 			LOG4CPLUS_ERROR(logger, "A checker callback returned false."); | 
			
		
	
		
			
				
					|  |  |  | 			throw mrmc::exceptions::InvalidSettings(); | 
			
		
	
		
			
				
					|  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  | 		bpo::store(bpo::parse_config_file<char>(filename, *(Settings::desc)), this->vm, true); | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -269,7 +202,13 @@ void Settings::secondRun(const int argc, const char* argv[], const char* filenam | 
			
		
	
		
			
				
					|  |  |  | std::ostream& help(std::ostream& os) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	os << "Usage: " << mrmc::settings::Settings::binaryName << " [options] <transition file> <label file>" << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 	os << *(mrmc::settings::Settings::cli) << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 	os << *(mrmc::settings::Settings::desc) << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 	for (auto it : Settings::modules) | 
			
		
	
		
			
				
					|  |  |  | 	{ | 
			
		
	
		
			
				
					|  |  |  | 		std::pair< std::string, std::string > trigger = it.first; | 
			
		
	
		
			
				
					|  |  |  | 		os << "If --" << trigger.first << " = " << trigger.second << ":" << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 		os << *(it.second) << std::endl; | 
			
		
	
		
			
				
					|  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  | 	return os; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | @ -281,7 +220,7 @@ std::ostream& help(std::ostream& os) | 
			
		
	
		
			
				
					|  |  |  |  */ | 
			
		
	
		
			
				
					|  |  |  | std::ostream& helpConfigfile(std::ostream& os) | 
			
		
	
		
			
				
					|  |  |  | { | 
			
		
	
		
			
				
					|  |  |  | 	os << *(mrmc::settings::Settings::conf) << std::endl;; | 
			
		
	
		
			
				
					|  |  |  | 	os << *(mrmc::settings::Settings::desc) << std::endl;; | 
			
		
	
		
			
				
					|  |  |  | 	return os; | 
			
		
	
		
			
				
					|  |  |  | } | 
			
		
	
		
			
				
					|  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  | 
 |