diff --git a/Util/BoostFileSystemFix.h b/Util/BoostFileSystemFix.h index c8a2744a1..1cf21223d 100644 --- a/Util/BoostFileSystemFix.h +++ b/Util/BoostFileSystemFix.h @@ -28,7 +28,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef BOOST_FILE_SYSTEM_FIX_H #define BOOST_FILE_SYSTEM_FIX_H +#include "OSRMException.h" + +#include #include +#include //This is one big workaround for latest boost renaming woes. @@ -41,6 +45,28 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace boost { namespace filesystem { +// Validator for boost::filesystem::path, that verifies that the file +// exists. The validate() function must be defined in the same namespace +// as the target type, (boost::filesystem::path in this case), otherwise +// it is not called +inline void validate( + boost::any & v, + const std::vector & values, + boost::filesystem::path *, + int +) { + boost::program_options::validators::check_first_occurrence(v); + const std::string & input_string = + boost::program_options::validators::get_single_string(values); + // SimpleLogger().Write() << "validator called for " << input_string; + // SimpleLogger().Write() << "validator called for " << input_string; + if(boost::filesystem::is_regular_file(input_string)) { + v = boost::any(boost::filesystem::path(input_string)); + } else { + throw OSRMException(input_string + " not found"); + } +} + // adapted from: http://stackoverflow.com/questions/1746136/how-do-i-normalize-a-pathname-using-boostfilesystem inline boost::filesystem::path portable_canonical( const boost::filesystem::path & relative_path, diff --git a/Util/DataStoreOptions.h b/Util/DataStoreOptions.h new file mode 100644 index 000000000..ce7448b41 --- /dev/null +++ b/Util/DataStoreOptions.h @@ -0,0 +1,289 @@ +/* + +Copyright (c) 2013, Project OSRM, Dennis Luxen, others +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or +other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifndef DATA_STORE_OPTIONS_H +#define DATA_STORE_OPTIONS_H + +#include "BoostFileSystemFix.h" +#include "GitDescription.h" +#include "OSRMException.h" +#include "SimpleLogger.h" + +#include + +#include +#include +#include +#include +#include +#include + +#include + + +// support old capitalized option names by down-casing them with a regex replace +inline void PrepareConfigFile( + const boost::filesystem::path& path, + std::string& output +) { + boost::filesystem::fstream config_stream( path ); + std::string input_str( + (std::istreambuf_iterator(config_stream)), + std::istreambuf_iterator() + ); + boost::regex regex( "^([^=]*)" ); //match from start of line to '=' + std::string format( "\\L$1\\E" ); //replace with downcased substring + output = boost::regex_replace( input_str, regex, format ); +} + + +// generate boost::program_options object for the routing part +inline bool GenerateDataStoreOptions( + const int argc, + const char * argv[], + ServerPaths & paths +) { + + // 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( + &paths["config"] + )->default_value("server.ini"), + "Path to a configuration file" + ); + + // declare a group of options that will be allowed both on command line + // as well as in a config file + boost::program_options::options_description config_options("Configuration"); + config_options.add_options() + ( + "hsgrdata", + boost::program_options::value(&paths["hsgrdata"]), + ".hsgr file" + ) + ( + "nodesdata", + boost::program_options::value(&paths["nodesdata"]), + ".nodes file" + ) + ( + "edgesdata", + boost::program_options::value(&paths["edgesdata"]), + ".edges file" + ) + ( + "geometry", + boost::program_options::value(&paths["geometries"]), + ".geometry file" + ) + ( + "ramindex", + boost::program_options::value(&paths["ramindex"]), + ".ramIndex file" + ) + ( + "fileindex", + boost::program_options::value(&paths["fileindex"]), + "File index file" + ) + ( + "namesdata", + boost::program_options::value(&paths["namesdata"]), + ".names file" + ) + ( + "timestamp", + boost::program_options::value(&paths["timestamp"]), + ".timestamp file" + ); + + // 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() + ( + "base,b", + boost::program_options::value(&paths["base"]), + "base path to .osrm file" + ); + + // positional option + boost::program_options::positional_options_description positional_options; + positional_options.add("base", 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]) + " []" + ); + 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 false; + } + + if(option_variables.count("help")) { + SimpleLogger().Write() << visible_options; + return false; + } + + boost::program_options::notify(option_variables); + + // parse config file + ServerPaths::iterator path_iterator = paths.find("config"); + if( + path_iterator != paths.end() && + boost::filesystem::is_regular_file(path_iterator->second) && + !option_variables.count("base") + ) { + SimpleLogger().Write() << + "Reading options from: " << path_iterator->second.string(); + std::string config_str; + PrepareConfigFile( path_iterator->second, 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("base") ) { + path_iterator = paths.find("base"); + BOOST_ASSERT( paths.end() != path_iterator ); + std::string base_string = path_iterator->second.string(); + + path_iterator = paths.find("hsgrdata"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".hsgr"; + } else { + throw OSRMException(base_string + ".hsgr not found"); + } + + path_iterator = paths.find("nodesdata"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".nodes"; + } else { + throw OSRMException(base_string + ".nodes not found"); + } + + + path_iterator = paths.find("edgesdata"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".edges"; + } else { + throw OSRMException(base_string + ".edges not found"); + } + + + path_iterator = paths.find("geometries"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".geometry"; + } else { + throw OSRMException(base_string + ".geometry not found"); + } + + + path_iterator = paths.find("ramindex"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".ramIndex"; + } else { + throw OSRMException(base_string + ".ramIndex not found"); + } + + + path_iterator = paths.find("fileindex"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".fileIndex"; + } else { + throw OSRMException(base_string + ".fileIndex not found"); + } + + + path_iterator = paths.find("namesdata"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".names"; + } else { + throw OSRMException(base_string + ".namesIndex not found"); + } + + path_iterator = paths.find("timestamp"); + if( + path_iterator != paths.end() && + !boost::filesystem::is_regular_file(path_iterator->second) + ) { + path_iterator->second = base_string + ".timestamp"; + } + + return true; + } + + SimpleLogger().Write() << visible_options; + + return false; +} + +#endif /* DATA_STORE_OPTIONS_H */ diff --git a/Util/ProgramOptions.h b/Util/ProgramOptions.h index 30a8c373f..0f6a2b358 100644 --- a/Util/ProgramOptions.h +++ b/Util/ProgramOptions.h @@ -42,33 +42,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include - - -namespace boost { - namespace filesystem { - // Validator for boost::filesystem::path, that verifies that the file - // exists. The validate() function must be defined in the same namespace - // as the target type, (boost::filesystem::path in this case), otherwise - // it is not called - inline void validate( - boost::any & v, - const std::vector & values, - boost::filesystem::path *, - int - ) { - boost::program_options::validators::check_first_occurrence(v); - const std::string & input_string = - boost::program_options::validators::get_single_string(values); - SimpleLogger().Write() << "validator called for " << input_string; - if(boost::filesystem::is_regular_file(input_string)) { - v = boost::any(boost::filesystem::path(input_string)); - } else { - throw OSRMException(input_string + " not found"); - } - } - } -} // support old capitalized option names by down-casing them with a regex replace inline void PrepareConfigFile( @@ -85,7 +58,6 @@ inline void PrepareConfigFile( output = boost::regex_replace( input_str, regex, format ); } - // generate boost::program_options object for the routing part inline bool GenerateServerProgramOptions( const int argc, diff --git a/datastore.cpp b/datastore.cpp index 6d2753f05..8eefc0fba 100644 --- a/datastore.cpp +++ b/datastore.cpp @@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Server/DataStructures/SharedDataType.h" #include "Server/DataStructures/SharedBarriers.h" #include "Util/BoostFileSystemFix.h" -#include "Util/ProgramOptions.h" +#include "Util/DataStoreOptions.h" #include "Util/SimpleLogger.h" #include "Util/UUID.h" #include "typedefs.h" @@ -55,12 +55,6 @@ int main( const int argc, const char * argv[] ) { LogPolicy::GetInstance().Unmute(); SharedBarriers barrier; - if (argc < 2) - { - SimpleLogger().Write(logWARNING) << "no parameters given. try\n\t" << argv[0] << " --help"; - return -1; - } - #ifdef __linux__ if( -1 == mlockall(MCL_CURRENT | MCL_FUTURE) ) { SimpleLogger().Write(logWARNING) << @@ -84,20 +78,12 @@ int main( const int argc, const char * argv[] ) { try { SimpleLogger().Write(logDEBUG) << "Checking input parameters"; - bool use_shared_memory = false; - std::string ip_address; - int ip_port, requested_num_threads; - ServerPaths server_paths; if( - !GenerateServerProgramOptions( + !GenerateDataStoreOptions( argc, argv, - server_paths, - ip_address, - ip_port, - requested_num_threads, - use_shared_memory + server_paths ) ) { return 0;