int Config::initialize(int argc, char* argv[]) { Config* c = Config::getInstance(); std::vector< std::string > nodes; std::vector< std::string > hostnames; std::vector< std::string > box_strings; std::string configfile; std::string keystore_file; std::string private_key_file; // parsing program options using boost::program_options namespace po = boost::program_options; po::options_description cmdline_options("Generic options"); cmdline_options.add_options() ("help,h", "Produce this help message") ("config,c", po::value<std::string>(&configfile), "Use supplied config file instead of default one") ("keystore", po::value<std::string>(&keystore_file), "Use supplied keystore file instead of default one") ("privatekey", po::value<std::string>(&private_key_file), "Use supplied privatekey file instead of default one") ("create-private-key", "Create new keypair for hostnames") ; po::options_description generic_options("Allowed options"); generic_options.add_options() ("node,n", po::value<std::vector< std::string >>(&nodes), "Add node location to listen to (multiple arguments allowed)") ("box,b", po::value<std::vector <std::string> >(&box_strings), "Add path of a directory to watch (multiple arguments allowed)") ("hostname,p", po::value<std::vector <std::string> >(&hostnames), "Add a name for this machine under which other nodes can reach it (multiple arguments allowed)") ; po::options_description options; options.add(cmdline_options).add(generic_options); // BUG we cannot ADD nodes/boxes through the cli, // it takes either the config file or the command line... // parse command line arguments po::store(po::parse_command_line( argc, argv, options ), c->vm_); po::notify(c->vm_); // parse config file, if any wordexp_t expanded_config_file_path; if (configfile.empty()) { wordexp( F_CONFIG_FILE, &expanded_config_file_path, 0 ); } else { wordexp( configfile.c_str(), &expanded_config_file_path, 0 ); } std::ifstream ifs( expanded_config_file_path.we_wordv[0] ); wordfree(&expanded_config_file_path); if ( !ifs ) { if (F_MSG_DEBUG) printf("config: no config file found\n"); } else { po::store(po::parse_config_file(ifs, generic_options), c->vm_); po::notify(c->vm_); ifs.close(); } // parse keystore file wordexp_t expanded_keystore_file_path; if (keystore_file.empty()) { wordexp( F_KEYSTORE_FILE, &expanded_keystore_file_path, 0 ); } else { wordexp( keystore_file.c_str(), &expanded_keystore_file_path, 0 ); } keystore_file = expanded_keystore_file_path.we_wordv[0]; wordfree(&expanded_keystore_file_path); // parse privatekey file wordexp_t expanded_privatekey_file_path; if (private_key_file.empty()) { wordexp( F_PRIVATEKEY_FILE, &expanded_privatekey_file_path, 0 ); } else { wordexp( private_key_file.c_str(), &expanded_privatekey_file_path, 0 ); } private_key_file = expanded_privatekey_file_path.we_wordv[0]; wordfree(&expanded_privatekey_file_path); int return_val; return_val = c->doSanityCheck( &options, &nodes, &hostnames, &box_strings ); if ( return_val != 0 ) return return_val; return_val = c->synchronizeKeystore( &keystore_file, &private_key_file ); return return_val; }
return_code ExtractorOptions::ParseArguments(int argc, char *argv[], ExtractorConfig &extractor_config) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( "config,c", boost::program_options::value<boost::filesystem::path>( &extractor_config.config_file_path)->default_value("extractor.ini"), "Path to a configuration file."); // declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description config_options("Configuration"); config_options.add_options()("profile,p", boost::program_options::value<boost::filesystem::path>( &extractor_config.profile_path)->default_value("profile.lua"), "Path to LUA routing profile")( "threads,t", boost::program_options::value<unsigned int>(&extractor_config.requested_num_threads) ->default_value(tbb::task_scheduler_init::default_num_threads()), "Number of threads to use"); // hidden options, will be allowed both on command line and in config file, but will not be // shown to the user boost::program_options::options_description hidden_options("Hidden options"); hidden_options.add_options()("input,i", boost::program_options::value<boost::filesystem::path>( &extractor_config.input_path), "Input file in .osm, .osm.bz2 or .osm.pbf format"); // positional option boost::program_options::positional_options_description positional_options; positional_options.add("input", 1); // combine above options for parsing boost::program_options::options_description cmdline_options; cmdline_options.add(generic_options).add(config_options).add(hidden_options); boost::program_options::options_description config_file_options; config_file_options.add(config_options).add(hidden_options); boost::program_options::options_description visible_options( boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [options]"); visible_options.add(generic_options).add(config_options); // parse command line options try { boost::program_options::variables_map option_variables; boost::program_options::store(boost::program_options::command_line_parser(argc, argv) .options(cmdline_options) .positional(positional_options) .run(), option_variables); if (option_variables.count("version")) { SimpleLogger().Write() << g_GIT_DESCRIPTION; return return_code::exit; } if (option_variables.count("help")) { SimpleLogger().Write() << visible_options; return return_code::exit; } boost::program_options::notify(option_variables); // parse config file if (boost::filesystem::is_regular_file(extractor_config.config_file_path)) { SimpleLogger().Write() << "Reading options from: " << extractor_config.config_file_path.string(); std::string ini_file_contents = read_file_lower_content(extractor_config.config_file_path); std::stringstream config_stream(ini_file_contents); boost::program_options::store(parse_config_file(config_stream, config_file_options), option_variables); boost::program_options::notify(option_variables); } if (!option_variables.count("input")) { SimpleLogger().Write() << visible_options; return return_code::exit; } } catch (std::exception &e) { SimpleLogger().Write(logWARNING) << e.what(); return return_code::fail; } return return_code::ok; }
bool Config::init_with_args(int ac, char** av, const std::vector<std::string>& customized, WorkerInfo* worker_info) { namespace po = boost::program_options; po::options_description generic_options("Generic options"); generic_options.add_options()("help,H", "print help message"); std::string config_file_path; po::options_description config_file_options("Configuration File"); config_file_options.add_options()("conf,C", po::value<std::string>(&config_file_path), "Configure file Path"); std::string master_host; int master_port; int comm_port; std::string log_dir; po::options_description required_options("Required options"); required_options.add_options()("master_host", po::value<std::string>(&master_host), "Master hostname")( "master_port", po::value<int>(&master_port), "Master port")( "comm_port", po::value<int>(&comm_port), "Communication port")("log_dir", po::value<std::string>(&log_dir), "Log directory"); po::options_description worker_info_options("Worker Info options"); worker_info_options.add_options()("worker.info", po::value<std::vector<std::string>>()->multitoken(), "Worker information.\nFormat is '%worker_hostname:%thread_number'.\nUse " "colon ':' as separator."); po::options_description worker_info_config("Worker Info from config"); worker_info_config.add_options()("worker.info", po::value<std::vector<std::string>>()->multitoken(), "Worker information.\nFormat is '%worker_hostname:%thread_number'.\nUse " "colon ':' as separator."); po::options_description customized_options("Customized options"); if (!customized.empty()) for (auto& arg : customized) customized_options.add_options()(arg.c_str(), po::value<std::string>(), ""); po::options_description cmdline_options; cmdline_options.add(generic_options).add(config_file_options).add(required_options).add(worker_info_options); po::options_description config_options; config_options.add(required_options).add(worker_info_config); if (!customized_options.options().empty()) { cmdline_options.add(customized_options); config_options.add(customized_options); } po::variables_map vm; po::store(po::command_line_parser(ac, av).options(cmdline_options).run(), vm); po::notify(vm); if (ac == 1 || vm.count("help")) { std::cout << "Usage:" << std::endl; std::cout << cmdline_options << std::endl; return false; } if (vm.count("conf")) { std::ifstream config_file(config_file_path.c_str()); if (!config_file) { LOG_E << "Can not open config file: " << config_file_path; return false; } // The configure in config_file would be overwritten by cmdline as parsing order. // For details, the interface is: // parse_config_file(const char * filename, const options_description &, // bool allow_unregistered = false) auto parsed_config_options = po::parse_config_file(config_file, config_options, true); po::store(parsed_config_options, vm); po::notify(vm); // Store what is not registered in customized_options. for (const auto& o : parsed_config_options.options) if (vm.find(o.string_key) == vm.end()) set_param(o.string_key, o.value.front()); // Only accept `key=value`. } int setup_all = 0; if (vm.count("master_host")) { set_master_host(master_host); setup_all += 1; } else { LOG_E << "arg master_host is needed"; } if (vm.count("master_port")) { set_master_port(master_port); setup_all += 1; } else { LOG_E << "arg master_port is needed"; } if (vm.count("comm_port")) { set_comm_port(comm_port); setup_all += 1; } else { LOG_E << "arg comm_port is needed"; } if (vm.count("log_dir")) set_log_dir(log_dir); if (vm.count("worker.info")) { std::string hostname = get_hostname(); int proc_id = -1; int num_workers = 0; int num_local_threads = 0; int num_global_threads = 0; std::vector<std::string> workers_info = vm["worker.info"].as<std::vector<std::string>>(); for (auto& w : workers_info) { std::size_t colon_pos = w.find(':'); if (colon_pos == std::string::npos || colon_pos == w.size() - 1) { // Cannot find colon ':' or lack number of threads. LOG_E << "arg worker.info '" + w + "' not match the format"; return false; } std::string worker_hostname = w.substr(0, colon_pos); machines_.insert(worker_hostname); int num_threads = std::stoi(w.substr(colon_pos + 1, w.size() - colon_pos - 1)); if (is_local(worker_hostname)) { num_local_threads = num_threads; proc_id = num_workers; } if (worker_info != nullptr) worker_info->set_hostname(num_workers, worker_hostname); for (int i = 0; i < num_threads; i++) { if (worker_info != nullptr) worker_info->add_worker(num_workers, num_global_threads, i); ++num_global_threads; } num_workers += 1; } if (worker_info != nullptr) worker_info->set_process_id(proc_id); set_param("hostname", hostname); setup_all += 1; } else { LOG_E << "arg worker.info is needed"; } if (!customized.empty()) { for (auto& arg : customized) if (vm.count(arg.c_str())) { set_param(arg, vm[arg.c_str()].as<std::string>()); setup_all += 1; } else { LOG_E << "arg " << arg << " is needed"; } } if (setup_all != customized.size() + 4) { LOG_E << "Please provide all necessary args!"; return false; } return true; }
return_code ContractorOptions::ParseArguments(int argc, char *argv[], ContractorConfig &contractor_config) { // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( "config,c", boost::program_options::value<boost::filesystem::path>(&contractor_config.config_file_path) ->default_value("contractor.ini"), "Path to a configuration file."); // declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description config_options("Configuration"); config_options.add_options()( "restrictions,r", boost::program_options::value<boost::filesystem::path>(&contractor_config.restrictions_path), "Restrictions file in .osrm.restrictions format")( "profile,p", boost::program_options::value<boost::filesystem::path>(&contractor_config.profile_path) ->default_value("profile.lua"), "Path to LUA routing profile")( "threads,t", boost::program_options::value<unsigned int>(&contractor_config.requested_num_threads) ->default_value(tbb::task_scheduler_init::default_num_threads()), "Number of threads to use"); // hidden options, will be allowed both on command line and in config file, but will not be // shown to the user boost::program_options::options_description hidden_options("Hidden options"); hidden_options.add_options()( "input,i", boost::program_options::value<boost::filesystem::path>(&contractor_config.osrm_input_path), "Input file in .osm, .osm.bz2 or .osm.pbf format"); // positional option boost::program_options::positional_options_description positional_options; positional_options.add("input", 1); // combine above options for parsing boost::program_options::options_description cmdline_options; cmdline_options.add(generic_options).add(config_options).add(hidden_options); boost::program_options::options_description config_file_options; config_file_options.add(config_options).add(hidden_options); boost::program_options::options_description visible_options( "Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]"); visible_options.add(generic_options).add(config_options); // parse command line options boost::program_options::variables_map option_variables; boost::program_options::store(boost::program_options::command_line_parser(argc, argv) .options(cmdline_options) .positional(positional_options) .run(), option_variables); const auto &temp_config_path = option_variables["config"].as<boost::filesystem::path>(); if (boost::filesystem::is_regular_file(temp_config_path)) { boost::program_options::store(boost::program_options::parse_config_file<char>( temp_config_path.string().c_str(), cmdline_options, true), option_variables); } if (option_variables.count("version")) { SimpleLogger().Write() << g_GIT_DESCRIPTION; return return_code::exit; } if (option_variables.count("help")) { SimpleLogger().Write() << "\n" << visible_options; return return_code::exit; } boost::program_options::notify(option_variables); if (!option_variables.count("restrictions")) { contractor_config.restrictions_path = contractor_config.osrm_input_path.string() + ".restrictions"; } if (!option_variables.count("input")) { SimpleLogger().Write() << "\n" << visible_options; return return_code::fail; } return return_code::ok; }
bool parse_options(fscp::logger& logger, int argc, char** argv, cli_configuration& configuration) { namespace po = boost::program_options; po::options_description visible_options; po::options_description all_options; po::options_description generic_options("Generic options"); generic_options.add_options() ("help,h", "Produce help message.") ("version,v", "Get the program version.") ("debug,d", "Enables debug output.") ("threads,t", po::value<unsigned int>(&configuration.thread_count)->default_value(0), "The number of threads to use.") ("configuration_file,c", po::value<std::string>(), "The configuration file to use.") ; visible_options.add(generic_options); all_options.add(generic_options); po::options_description configuration_options("Configuration"); configuration_options.add(get_server_options()); configuration_options.add(get_client_options()); configuration_options.add(get_fscp_options()); configuration_options.add(get_security_options()); configuration_options.add(get_tap_adapter_options()); configuration_options.add(get_switch_options()); configuration_options.add(get_router_options()); visible_options.add(configuration_options); all_options.add(configuration_options); #ifdef WINDOWS po::options_description service_options("Service"); service_options.add_options() ("install", "Install the service.") ("uninstall", "Uninstall the service.") ("reinstall", "Reinstall the service.") ; visible_options.add(service_options); all_options.add(service_options); #else po::options_description daemon_options("Daemon"); daemon_options.add_options() ("foreground,f", "Do not run as a daemon.") ("pid_file,p", po::value<std::string>(), "A pid file to use.") ; visible_options.add(daemon_options); all_options.add(daemon_options); po::options_description misc_options("Miscellaneous"); misc_options.add_options() ("nocolor", "Disable color output.") ; visible_options.add(misc_options); all_options.add(misc_options); #endif po::variables_map vm; po::store(po::parse_command_line(argc, argv, all_options), vm); make_paths_absolute(vm, fs::current_path()); if (vm.count("help")) { std::cout << visible_options << std::endl; return false; } if (vm.count("version")) { std::cout << FREELAN_NAME << " " << FREELAN_VERSION_STRING << " " << FREELAN_DATE << std::endl; return false; } #ifdef WINDOWS if (vm.count("install")) { if (vm.count("uninstall")) { throw std::runtime_error("Cannot specify both --install and --uninstall options. Use --reinstall instead."); } else { if (windows::install_service()) { logger(fscp::log_level::important) << "Service installed."; } else { logger(fscp::log_level::error) << "The service was already installed."; } return false; } } else if (vm.count("uninstall")) { if (windows::uninstall_service()) { logger(fscp::log_level::important) << "Service uninstalled."; } else { logger(fscp::log_level::error) << "The service has already been deleted."; } return false; } else if (vm.count("reinstall")) { if (windows::uninstall_service()) { logger(fscp::log_level::important) << "Service uninstalled."; } else { logger(fscp::log_level::error) << "The service has already been deleted."; } if (windows::install_service()) { logger(fscp::log_level::important) << "Service installed."; } else { logger(fscp::log_level::error) << "The service was already installed."; } return false; } #else configuration.foreground = (vm.count("foreground") > 0); if (vm.count("nocolor") > 0) { // This is a global variable. Not really nice but does its job in this case. DISABLE_COLOR = true; } if (vm.count("pid_file")) { configuration.pid_file = fs::absolute(vm["pid_file"].as<std::string>()); } else { char* val = getenv("FREELAN_PID_FILE"); if (val) { configuration.pid_file = fs::absolute(std::string(val)); } } #endif fs::path configuration_file; if (vm.count("configuration_file")) { configuration_file = fs::absolute(vm["configuration_file"].as<std::string>()); } else { #ifdef _MSC_VER #ifdef UNICODE std::wstring value(4096, L'\0'); const DWORD value_size = GetEnvironmentVariable(L"FREELAN_CONFIGURATION_FILE", &value[0], static_cast<DWORD>(value.size())); #else std::string value(4096, '\0'); const DWORD value_size = GetEnvironmentVariable("FREELAN_CONFIGURATION_FILE", &value[0], static_cast<DWORD>(value.size())); #endif if (value_size > 0) { value.resize(value_size); configuration_file = fs::absolute(value); } #else const char* val = getenv("FREELAN_CONFIGURATION_FILE"); if (val) { configuration_file = fs::absolute(std::string(val)); } #endif } if (!configuration_file.empty()) { logger(fscp::log_level::information) << "Reading configuration file at: " << configuration_file; fs::basic_ifstream<char> ifs(configuration_file); if (!ifs) { throw po::reading_file(configuration_file.string().c_str()); } po::store(po::parse_config_file(ifs, configuration_options, true), vm); } else { bool configuration_read = false; const std::vector<fs::path> configuration_files = get_configuration_files(); BOOST_FOREACH(const fs::path& conf, configuration_files) { fs::basic_ifstream<char> ifs(conf); if (ifs) { logger(fscp::log_level::information) << "Reading configuration file at: " << conf << std::endl; po::store(po::parse_config_file(ifs, configuration_options, true), vm); configuration_file = fs::absolute(conf); configuration_read = true; break; } } if (!configuration_read) { logger(fscp::log_level::warning) << "Warning ! No configuration file specified and none found in the environment."; logger(fscp::log_level::warning) << "Looked up locations were:"; for (auto&& conf : configuration_files) { logger(fscp::log_level::warning) << "- " << conf; } } }
int main (int argc, char *argv[]) { try { LogPolicy::GetInstance().Unmute(); double startup_time = get_timestamp(); boost::filesystem::path config_file_path, input_path, profile_path; int requested_num_threads; // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); generic_options.add_options() ("version,v", "Show version") ("help,h", "Show this help message") ("config,c", boost::program_options::value<boost::filesystem::path>(&config_file_path)->default_value("extractor.ini"), "Path to a configuration file."); // declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description config_options("Configuration"); config_options.add_options() ("profile,p", boost::program_options::value<boost::filesystem::path>(&profile_path)->default_value("profile.lua"), "Path to LUA routing profile") ("threads,t", boost::program_options::value<int>(&requested_num_threads)->default_value(8), "Number of threads to use"); // hidden options, will be allowed both on command line and in config file, but will not be shown to the user boost::program_options::options_description hidden_options("Hidden options"); hidden_options.add_options() ("input,i", boost::program_options::value<boost::filesystem::path>(&input_path), "Input file in .osm, .osm.bz2 or .osm.pbf format"); // positional option boost::program_options::positional_options_description positional_options; positional_options.add("input", 1); // combine above options for parsing boost::program_options::options_description cmdline_options; cmdline_options.add(generic_options).add(config_options).add(hidden_options); boost::program_options::options_description config_file_options; config_file_options.add(config_options).add(hidden_options); boost::program_options::options_description visible_options(boost::filesystem::basename(argv[0]) + " <input.osm/.osm.bz2/.osm.pbf> [options]"); visible_options.add(generic_options).add(config_options); // parse command line options boost::program_options::variables_map option_variables; boost::program_options::store(boost::program_options::command_line_parser(argc, argv). options(cmdline_options).positional(positional_options).run(), option_variables); if(option_variables.count("version")) { SimpleLogger().Write() << g_GIT_DESCRIPTION; return 0; } if(option_variables.count("help")) { SimpleLogger().Write() << visible_options; return 0; } boost::program_options::notify(option_variables); // parse config file if(boost::filesystem::is_regular_file(config_file_path)) { SimpleLogger().Write() << "Reading options from: " << config_file_path.c_str(); std::string config_str; PrepareConfigFile( config_file_path.c_str(), config_str ); std::stringstream config_stream( config_str ); boost::program_options::store(parse_config_file(config_stream, config_file_options), option_variables); boost::program_options::notify(option_variables); } if(!option_variables.count("input")) { SimpleLogger().Write(logWARNING) << "No input file specified"; SimpleLogger().Write() << visible_options; return -1; } if(1 > requested_num_threads) { SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger"; return -1; } SimpleLogger().Write() << "Input file: " << input_path.filename().string(); SimpleLogger().Write() << "Profile: " << profile_path.filename().string(); SimpleLogger().Write() << "Threads: " << requested_num_threads; /*** Setup Scripting Environment ***/ ScriptingEnvironment scriptingEnvironment(profile_path.c_str()); omp_set_num_threads( std::min( omp_get_num_procs(), requested_num_threads) ); bool file_has_pbf_format(false); std::string output_file_name(input_path.c_str()); std::string restrictionsFileName(input_path.c_str()); std::string::size_type pos = output_file_name.find(".osm.bz2"); if(pos==std::string::npos) { pos = output_file_name.find(".osm.pbf"); if(pos!=std::string::npos) { file_has_pbf_format = true; } } if(pos==std::string::npos) { pos = output_file_name.find(".pbf"); if(pos!=std::string::npos) { file_has_pbf_format = true; } } if(pos!=std::string::npos) { output_file_name.replace(pos, 8, ".osrm"); restrictionsFileName.replace(pos, 8, ".osrm.restrictions"); } else { pos=output_file_name.find(".osm"); if(pos!=std::string::npos) { output_file_name.replace(pos, 5, ".osrm"); restrictionsFileName.replace(pos, 5, ".osrm.restrictions"); } else { output_file_name.append(".osrm"); restrictionsFileName.append(".osrm.restrictions"); } } StringMap stringMap; ExtractionContainers externalMemory; stringMap[""] = 0; extractCallBacks = new ExtractorCallbacks(&externalMemory, &stringMap); BaseParser* parser; if(file_has_pbf_format) { parser = new PBFParser(input_path.c_str(), extractCallBacks, scriptingEnvironment); } else { parser = new XMLParser(input_path.c_str(), extractCallBacks, scriptingEnvironment); } if(!parser->ReadHeader()) { throw OSRMException("Parser not initialized!"); } SimpleLogger().Write() << "Parsing in progress.."; double parsing_start_time = get_timestamp(); parser->Parse(); SimpleLogger().Write() << "Parsing finished after " << (get_timestamp() - parsing_start_time) << " seconds"; if( externalMemory.all_edges_list.empty() ) { SimpleLogger().Write(logWARNING) << "The input data is empty, exiting."; return -1; } externalMemory.PrepareData(output_file_name, restrictionsFileName); delete parser; delete extractCallBacks; SimpleLogger().Write() << "extraction finished after " << get_timestamp() - startup_time << "s"; SimpleLogger().Write() << "To prepare the data for routing, run: " << "./osrm-prepare " << output_file_name << std::endl; } catch(boost::program_options::too_many_positional_options_error& e) { SimpleLogger().Write(logWARNING) << "Only one input file can be specified"; return -1; } catch(boost::program_options::error& e) { SimpleLogger().Write(logWARNING) << e.what(); return -1; } catch(std::exception & e) { SimpleLogger().Write(logWARNING) << "Unhandled exception: " << e.what(); return -1; } return 0; }
bool parse_options(int argc, char** argv, cli_configuration& configuration) { namespace po = boost::program_options; po::options_description visible_options; po::options_description all_options; po::options_description generic_options("Generic options"); generic_options.add_options() ("help,h", "Produce help message.") ("debug,d", "Enables debug output.") ("configuration_file,c", po::value<std::string>(), "The configuration file to use") ; visible_options.add(generic_options); all_options.add(generic_options); po::options_description configuration_options("Configuration"); configuration_options.add(get_server_options()); configuration_options.add(get_fscp_options()); configuration_options.add(get_security_options()); configuration_options.add(get_tap_adapter_options()); configuration_options.add(get_switch_options()); visible_options.add(configuration_options); all_options.add(configuration_options); #ifdef WINDOWS po::options_description service_options("Service"); service_options.add_options() ("install", "Install the service.") ("uninstall", "Uninstall the service.") ("reinstall", "Reinstall the service.") ; visible_options.add(service_options); all_options.add(service_options); #else po::options_description daemon_options("Daemon"); daemon_options.add_options() ("foreground,f", "Do not run as a daemon.") ("pid_file,p", po::value<std::string>(), "A pid file to use.") ; visible_options.add(daemon_options); all_options.add(daemon_options); #endif po::variables_map vm; po::store(po::parse_command_line(argc, argv, all_options), vm); if (vm.count("help")) { std::cout << visible_options << std::endl; return false; } #ifdef WINDOWS if (vm.count("install")) { if (vm.count("uninstall")) { throw std::runtime_error("Cannot specify both --install and --uninstall options. Use --reinstall instead."); } else { if (win32::install_service()) { std::cout << "Service installed." << std::endl; } else { std::cerr << "The service was already installed." << std::endl; } return false; } } else if (vm.count("uninstall")) { if (win32::uninstall_service()) { std::cout << "Service uninstalled." << std::endl; } else { std::cerr << "The service has already been deleted." << std::endl; } return false; } else if (vm.count("reinstall")) { if (win32::uninstall_service()) { std::cout << "Service uninstalled." << std::endl; } else { std::cerr << "The service has already been deleted." << std::endl; } if (win32::install_service()) { std::cout << "Service installed." << std::endl; } else { std::cerr << "The service was already installed." << std::endl; } return false; } #else configuration.foreground = (vm.count("foreground") > 0); if (vm.count("pid_file")) { configuration.pid_file = fs::absolute(vm["pid_file"].as<std::string>()); } else { char* val = getenv("FREELAN_PID_FILE"); if (val) { configuration.pid_file = fs::absolute(std::string(val)); } } #endif fs::path configuration_file; if (vm.count("configuration_file")) { configuration_file = fs::absolute(vm["configuration_file"].as<std::string>()); } else { char* val = getenv("FREELAN_CONFIGURATION_FILE"); if (val) { configuration_file = fs::absolute(std::string(val)); } } if (!configuration_file.empty()) { std::cout << "Reading configuration file at: " << configuration_file << std::endl; fs::basic_ifstream<char> ifs(configuration_file); if (!ifs) { throw po::reading_file(configuration_file.string().c_str()); } po::store(po::parse_config_file(ifs, configuration_options, true), vm); } else { bool configuration_read = false; const std::vector<fs::path> configuration_files = get_configuration_files(); BOOST_FOREACH(const fs::path& conf, configuration_files) { fs::basic_ifstream<char> ifs(conf); if (ifs) { std::cout << "Reading configuration file at: " << conf << std::endl; po::store(po::parse_config_file(ifs, configuration_options, true), vm); configuration_file = fs::absolute(conf); break; } } if (!configuration_read) { std::cerr << "Warning ! No configuration file specified and none found in the environment." << std::endl; std::cerr << "Looked up locations were:" << std::endl; BOOST_FOREACH(const fs::path& conf, configuration_files) { std::cerr << "- " << conf << std::endl; }
int main(int argc, char *argv[]) { try { LogPolicy::GetInstance().Unmute(); std::chrono::time_point<std::chrono::steady_clock> startup_time = std::chrono::steady_clock::now(); boost::filesystem::path config_file_path, input_path, restrictions_path, profile_path; int requested_num_threads; // declare a group of options that will be allowed only on command line boost::program_options::options_description generic_options("Options"); generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")( "config,c", boost::program_options::value<boost::filesystem::path>(&config_file_path) ->default_value("contractor.ini"), "Path to a configuration file."); // declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description config_options("Configuration"); config_options.add_options()( "restrictions,r", boost::program_options::value<boost::filesystem::path>(&restrictions_path), "Restrictions file in .osrm.restrictions format")( "profile,p", boost::program_options::value<boost::filesystem::path>(&profile_path) ->default_value("profile.lua"), "Path to LUA routing profile")( "threads,t", boost::program_options::value<int>(&requested_num_threads)->default_value(8), "Number of threads to use"); // hidden options, will be allowed both on command line and in config file, but will not be // shown to the user boost::program_options::options_description hidden_options("Hidden options"); hidden_options.add_options()( "input,i", boost::program_options::value<boost::filesystem::path>(&input_path), "Input file in .osm, .osm.bz2 or .osm.pbf format"); // positional option boost::program_options::positional_options_description positional_options; positional_options.add("input", 1); // combine above options for parsing boost::program_options::options_description cmdline_options; cmdline_options.add(generic_options).add(config_options).add(hidden_options); boost::program_options::options_description config_file_options; config_file_options.add(config_options).add(hidden_options); boost::program_options::options_description visible_options( "Usage: " + boost::filesystem::basename(argv[0]) + " <input.osrm> [options]"); visible_options.add(generic_options).add(config_options); // parse command line options boost::program_options::variables_map option_variables; boost::program_options::store(boost::program_options::command_line_parser(argc, argv) .options(cmdline_options) .positional(positional_options) .run(), option_variables); if (option_variables.count("version")) { SimpleLogger().Write() << g_GIT_DESCRIPTION; return 0; } if (option_variables.count("help")) { SimpleLogger().Write() << "\n" << visible_options; return 0; } boost::program_options::notify(option_variables); if (!option_variables.count("restrictions")) { restrictions_path = std::string(input_path.string() + ".restrictions"); } if (!option_variables.count("input")) { SimpleLogger().Write() << "\n" << visible_options; return 0; } if (!boost::filesystem::is_regular_file(input_path)) { SimpleLogger().Write(logWARNING) << "Input file " << input_path.string() << " not found!"; return 1; } if (!boost::filesystem::is_regular_file(profile_path)) { SimpleLogger().Write(logWARNING) << "Profile " << profile_path.string() << " not found!"; return 1; } if (1 > requested_num_threads) { SimpleLogger().Write(logWARNING) << "Number of threads must be 1 or larger"; return 1; } int real_num_threads = std::min(omp_get_num_procs(), requested_num_threads); SimpleLogger().Write() << "Input file: " << input_path.filename().string(); SimpleLogger().Write() << "Restrictions file: " << restrictions_path.filename().string(); SimpleLogger().Write() << "Profile: " << profile_path.filename().string(); SimpleLogger().Write() << "Threads: " << real_num_threads << " (requested " << requested_num_threads << ")"; omp_set_num_threads(real_num_threads); LogPolicy::GetInstance().Unmute(); boost::filesystem::ifstream restriction_stream(restrictions_path, std::ios::binary); TurnRestriction restriction; UUID uuid_loaded, uuid_orig; unsigned number_of_usable_restrictions = 0; restriction_stream.read((char *)&uuid_loaded, sizeof(UUID)); if (!uuid_loaded.TestPrepare(uuid_orig)) { SimpleLogger().Write(logWARNING) << ".restrictions was prepared with different build.\n" "Reprocess to get rid of this warning."; } restriction_stream.read((char *)&number_of_usable_restrictions, sizeof(unsigned)); restriction_list.resize(number_of_usable_restrictions); restriction_stream.read((char *)&(restriction_list[0]), number_of_usable_restrictions * sizeof(TurnRestriction)); restriction_stream.close(); boost::filesystem::ifstream in; in.open(input_path, std::ios::in | std::ios::binary); const std::string node_filename = input_path.string() + ".nodes"; const std::string edge_out = input_path.string() + ".edges"; const std::string geometry_filename = input_path.string() + ".geometry"; const std::string graphOut = input_path.string() + ".hsgr"; const std::string rtree_nodes_path = input_path.string() + ".ramIndex"; const std::string rtree_leafs_path = input_path.string() + ".fileIndex"; /*** Setup Scripting Environment ***/ // Create a new lua state lua_State *lua_state = luaL_newstate(); // Connect LuaBind to this lua state luabind::open(lua_state); // open utility libraries string library; luaL_openlibs(lua_state); // adjust lua load path luaAddScriptFolderToLoadPath(lua_state, profile_path.c_str()); // Now call our function in a lua script if (0 != luaL_dofile(lua_state, profile_path.c_str())) { std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl; return 1; } EdgeBasedGraphFactory::SpeedProfileProperties speed_profile; if (0 != luaL_dostring(lua_state, "return traffic_signal_penalty\n")) { std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl; return 1; } speed_profile.trafficSignalPenalty = 10 * lua_tointeger(lua_state, -1); SimpleLogger().Write(logDEBUG) << "traffic_signal_penalty: " << speed_profile.trafficSignalPenalty; if (0 != luaL_dostring(lua_state, "return u_turn_penalty\n")) { std::cerr << lua_tostring(lua_state, -1) << " occured in scripting block" << std::endl; return 1; } speed_profile.uTurnPenalty = 10 * lua_tointeger(lua_state, -1); speed_profile.has_turn_penalty_function = lua_function_exists(lua_state, "turn_function"); std::vector<ImportEdge> edge_list; NodeID number_of_node_based_nodes = readBinaryOSRMGraphFromStream(in, edge_list, barrier_node_list, traffic_light_list, &internal_to_external_node_map, restriction_list); in.close(); if (edge_list.empty()) { SimpleLogger().Write(logWARNING) << "The input data is empty, exiting."; return 1; } SimpleLogger().Write() << restriction_list.size() << " restrictions, " << barrier_node_list.size() << " bollard nodes, " << traffic_light_list.size() << " traffic lights"; /*** * Building an edge-expanded graph from node-based input and turn restrictions */ SimpleLogger().Write() << "Generating edge-expanded graph representation"; std::shared_ptr<NodeBasedDynamicGraph> node_based_graph = NodeBasedDynamicGraphFromImportEdges(number_of_node_based_nodes, edge_list); std::unique_ptr<RestrictionMap> restriction_map = std::unique_ptr<RestrictionMap>(new RestrictionMap(node_based_graph, restriction_list)); EdgeBasedGraphFactory *edge_based_graph_factor = new EdgeBasedGraphFactory(node_based_graph, std::move(restriction_map), barrier_node_list, traffic_light_list, internal_to_external_node_map, speed_profile); edge_list.clear(); edge_list.shrink_to_fit(); edge_based_graph_factor->Run(edge_out, geometry_filename, lua_state); restriction_list.clear(); restriction_list.shrink_to_fit(); barrier_node_list.clear(); barrier_node_list.shrink_to_fit(); traffic_light_list.clear(); traffic_light_list.shrink_to_fit(); unsigned number_of_edge_based_nodes = edge_based_graph_factor->GetNumberOfEdgeBasedNodes(); BOOST_ASSERT(number_of_edge_based_nodes != std::numeric_limits<unsigned>::max()); DeallocatingVector<EdgeBasedEdge> edgeBasedEdgeList; edge_based_graph_factor->GetEdgeBasedEdges(edgeBasedEdgeList); std::vector<EdgeBasedNode> node_based_edge_list; edge_based_graph_factor->GetEdgeBasedNodes(node_based_edge_list); delete edge_based_graph_factor; // TODO actually use scoping: Split this up in subfunctions node_based_graph.reset(); std::chrono::duration<double> end_of_expansion_time = std::chrono::steady_clock::now() - startup_time; // Building grid-like nearest-neighbor data structure SimpleLogger().Write() << "building r-tree ..."; StaticRTree<EdgeBasedNode> *rtree = new StaticRTree<EdgeBasedNode>(node_based_edge_list, rtree_nodes_path.c_str(), rtree_leafs_path.c_str(), internal_to_external_node_map); delete rtree; IteratorbasedCRC32<std::vector<EdgeBasedNode>> crc32; unsigned node_based_edge_list_CRC32 = crc32(node_based_edge_list.begin(), node_based_edge_list.end()); node_based_edge_list.clear(); node_based_edge_list.shrink_to_fit(); SimpleLogger().Write() << "CRC32: " << node_based_edge_list_CRC32; /*** * Writing info on original (node-based) nodes */ SimpleLogger().Write() << "writing node map ..."; boost::filesystem::ofstream node_stream(node_filename, std::ios::binary); const unsigned size_of_mapping = internal_to_external_node_map.size(); node_stream.write((char *)&size_of_mapping, sizeof(unsigned)); node_stream.write((char *)&(internal_to_external_node_map[0]), size_of_mapping * sizeof(NodeInfo)); node_stream.close(); internal_to_external_node_map.clear(); internal_to_external_node_map.shrink_to_fit(); /*** * Contracting the edge-expanded graph */ SimpleLogger().Write() << "initializing contractor"; Contractor *contractor = new Contractor(number_of_edge_based_nodes, edgeBasedEdgeList); std::chrono::time_point<std::chrono::steady_clock> contraction_start_timestamp = std::chrono::steady_clock::now(); contractor->Run(); std::chrono::duration<double> contraction_duration = std::chrono::steady_clock::now() - contraction_start_timestamp; SimpleLogger().Write() << "Contraction took " << contraction_duration.count() << " sec"; DeallocatingVector<QueryEdge> contracted_edge_list; contractor->GetEdges(contracted_edge_list); delete contractor; /*** * Sorting contracted edges in a way that the static query graph can read some in in-place. */ std::sort(contracted_edge_list.begin(), contracted_edge_list.end()); unsigned max_used_node_id = 0; unsigned contracted_edge_count = contracted_edge_list.size(); SimpleLogger().Write() << "Serializing compacted graph of " << contracted_edge_count << " edges"; boost::filesystem::ofstream hsgr_output_stream(graphOut, std::ios::binary); hsgr_output_stream.write((char *)&uuid_orig, sizeof(UUID)); for (const QueryEdge &edge : contracted_edge_list) { BOOST_ASSERT(UINT_MAX != edge.source); BOOST_ASSERT(UINT_MAX != edge.target); max_used_node_id = std::max(max_used_node_id, edge.source); max_used_node_id = std::max(max_used_node_id, edge.target); } SimpleLogger().Write(logDEBUG) << "input graph has " << number_of_edge_based_nodes << " nodes"; SimpleLogger().Write(logDEBUG) << "contracted graph has " << max_used_node_id << " nodes"; max_used_node_id += 1; std::vector<StaticGraph<EdgeData>::NodeArrayEntry> node_array; node_array.resize(number_of_edge_based_nodes + 1); SimpleLogger().Write() << "Building node array"; StaticGraph<EdgeData>::EdgeIterator edge = 0; StaticGraph<EdgeData>::EdgeIterator position = 0; StaticGraph<EdgeData>::EdgeIterator lastEdge = edge; for (StaticGraph<EdgeData>::NodeIterator node = 0; node < max_used_node_id; ++node) { lastEdge = edge; while ((edge < contracted_edge_count) && (contracted_edge_list[edge].source == node)) { ++edge; } node_array[node].firstEdge = position; //=edge position += edge - lastEdge; // remove } for (unsigned sentinel_counter = max_used_node_id; sentinel_counter != node_array.size(); ++sentinel_counter) { // sentinel element, guarded against underflow node_array[sentinel_counter].firstEdge = contracted_edge_count; } unsigned node_array_size = node_array.size(); // serialize crc32, aka checksum hsgr_output_stream.write((char *)&node_based_edge_list_CRC32, sizeof(unsigned)); // serialize number of nodes hsgr_output_stream.write((char *)&node_array_size, sizeof(unsigned)); // serialize number of edges hsgr_output_stream.write((char *)&contracted_edge_count, sizeof(unsigned)); // serialize all nodes hsgr_output_stream.write((char *)&node_array[0], sizeof(StaticGraph<EdgeData>::NodeArrayEntry) * node_array_size); // serialize all edges SimpleLogger().Write() << "Building edge array"; edge = 0; int number_of_used_edges = 0; StaticGraph<EdgeData>::EdgeArrayEntry current_edge; for (unsigned edge = 0; edge < contracted_edge_list.size(); ++edge) { // no eigen loops BOOST_ASSERT(contracted_edge_list[edge].source != contracted_edge_list[edge].target); current_edge.target = contracted_edge_list[edge].target; current_edge.data = contracted_edge_list[edge].data; // every target needs to be valid BOOST_ASSERT(current_edge.target < max_used_node_id); if (current_edge.data.distance <= 0) { SimpleLogger().Write(logWARNING) << "Edge: " << edge << ",source: " << contracted_edge_list[edge].source << ", target: " << contracted_edge_list[edge].target << ", dist: " << current_edge.data.distance; SimpleLogger().Write(logWARNING) << "Failed at adjacency list of node " << contracted_edge_list[edge].source << "/" << node_array.size() - 1; return 1; } hsgr_output_stream.write((char *)¤t_edge, sizeof(StaticGraph<EdgeData>::EdgeArrayEntry)); ++number_of_used_edges; } hsgr_output_stream.close(); std::chrono::duration<double> entire_duration = std::chrono::steady_clock::now() - startup_time; SimpleLogger().Write() << "Preprocessing : " << entire_duration.count() << " seconds"; SimpleLogger().Write() << "Expansion : " << (number_of_node_based_nodes / end_of_expansion_time.count()) << " nodes/sec and " << (number_of_edge_based_nodes / end_of_expansion_time.count()) << " edges/sec"; SimpleLogger().Write() << "Contraction: " << (number_of_edge_based_nodes / contraction_duration.count()) << " nodes/sec and " << number_of_used_edges / contraction_duration.count() << " edges/sec"; node_array.clear(); SimpleLogger().Write() << "finished preprocessing"; } catch (boost::program_options::too_many_positional_options_error &) { SimpleLogger().Write(logWARNING) << "Only one file can be specified"; return 1; } catch (boost::program_options::error &e) { SimpleLogger().Write(logWARNING) << e.what(); return 1; } catch (const std::exception &e) { SimpleLogger().Write(logWARNING) << "Exception occured: " << e.what() << std::endl; return 1; } return 0; }
static int main(int argc, char *argv[]) { const string DEFAULT_TITLE = "Sequence Coverage Plot"; const string DEFAULT_X_LABEL = "X"; const string DEFAULT_Y_LABEL = "Y"; const int32_t DEFAULT_X_MAX = 1000; const int32_t DEFAULT_Y_MAX = 1000; const uint32_t DEFAULT_FASTA_INDEX = 0; path sect_file; string output_type; path output; string title; string x_label; string y_label; uint16_t width; uint16_t height; uint32_t x_max; uint32_t y_max; bool y_logscale; uint32_t fasta_index; string fasta_header; bool verbose; bool help; // Declare the supported options. po::options_description generic_options(PlotProfile::helpMessage(), 100); generic_options.add_options() ("output_type,p", po::value<string>(&output_type)->default_value("png"), "The plot file type to create: png, ps, pdf. Warning... if pdf is selected please ensure your gnuplot installation can export pdf files.") ("output,o", po::value<path>(&output), "The path to the output file") ("title,t", po::value<string>(&title)->default_value(DEFAULT_TITLE), "Title for plot") ("x_label,a", po::value<string>(&x_label)->default_value(DEFAULT_X_LABEL), "Label for the x-axis (value taken from matrix metadata if present)") ("y_label,b", po::value<string>(&y_label)->default_value(DEFAULT_Y_LABEL), "Label for the y-axis (value taken from matrix metadata if present)") ("x_max,x", po::value<uint32_t>(&x_max)->default_value(DEFAULT_X_MAX), "Maximum value for the x-axis (value taken from matrix metadata if present)") ("y_max,y", po::value<uint32_t>(&y_max)->default_value(DEFAULT_Y_MAX), "Maximum value for the y-axis (value taken from matrix metadata if present)") ("width,w", po::value<uint16_t>(&width)->default_value(1024), "Width of canvas") ("height,h", po::value<uint16_t>(&height)->default_value(1024), "Height of canvas") ("index,n", po::value<uint32_t>(&fasta_index)->default_value(DEFAULT_FASTA_INDEX), "Index of fasta entry to plot. First entry is 1.") ("header,d", po::value<string>(&fasta_header), "Fasta header of fasta entry to plot. NOTE: \'--header\' has priority over index") ("y_logscale,m", po::bool_switch(&y_logscale)->default_value(false), "Y-axis is logscale. This overrides the y_min and y_max limits.") ("verbose,v", po::bool_switch(&verbose)->default_value(false), "Print extra information.") ("help", po::bool_switch(&help)->default_value(false), "Produce help message.") ; // Hidden options, will be allowed both on command line and // in config file, but will not be shown to the user. po::options_description hidden_options("Hidden options"); hidden_options.add_options() ("sect_file,s", po::value<path>(§_file), "Path to the sect profile file to plot.") ; // Positional option for the input bam file po::positional_options_description p; p.add("sect_file", 1); // Combine non-positional options po::options_description cmdline_options; cmdline_options.add(generic_options).add(hidden_options); // Parse command line po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(cmdline_options).positional(p).run(), vm); po::notify(vm); // Output help information the exit if requested if (help || argc <= 1) { cout << generic_options << endl; return 1; } // Check input file exists if (!bfs::exists(sect_file) && !bfs::symbolic_link_exists(sect_file)) { cerr << endl << "Could not find matrix file at: " << sect_file << "; please check the path and try again." << endl << endl; return 1; } string header; string coverages; if (!fasta_header.empty()) { header.assign(fasta_header); getEntryFromFasta(sect_file, header, coverages); } else if (fasta_index > 0) { getEntryFromFasta(sect_file, fasta_index, header, coverages); } if (coverages.length() == 0) { cerr << "Could not find requested fasta header in sect coverages fasta file" << endl; } else { if (verbose) cerr << "Found requested sequence : " << header << endl << coverages << endl << endl; // Split coverages vector<uint32_t> cvs = kat::splitUInt32(coverages, ' '); uint32_t maxCvgVal = y_max != DEFAULT_Y_MAX ? y_max : (*(std::max_element(cvs.begin(), cvs.end())) + 1); string t = autoTitle(title, header); if (verbose) cerr << "Acquired K-mer counts" << endl; // Initialise gnuplot Gnuplot profile_plot = Gnuplot("lines"); profile_plot.configurePlot(output_type, output.string(), width, height); profile_plot.set_title(t); profile_plot.set_xlabel(x_label); profile_plot.set_ylabel(y_label); profile_plot.set_xrange(0, cvs.size()); profile_plot.set_yrange(0, maxCvgVal); profile_plot.cmd("set style data linespoints"); std::ostringstream data_str; for(uint32_t i = 0; i < cvs.size(); i++) { uint32_t index = i+1; double val = y_logscale ? (double)std::log(cvs[i]) : (double)cvs[i]; data_str << index << " " << val << "\n"; } std::ostringstream plot_str; plot_str << "plot '-'\n" << data_str.str() << "e\n"; profile_plot.cmd(plot_str.str()); if (verbose) cerr << "Plotted data: " << plot_str.str() << endl; } return 0; }