[Positioning] Add Configuration and UserInterface
- Add class Configuration, a stock for the configuration structure. - Add class UserInterface, that handles the configuration input. - Update owlps-positioning.cc (delete old stuff like configuration) and delete owlps-positioning.hh: we now have a compilable executable.
This commit is contained in:
parent
12d14b805f
commit
9cf4daca3b
|
@ -1,3 +1,4 @@
|
|||
*~
|
||||
*.o
|
||||
*.swp
|
||||
*.orig
|
||||
|
|
|
@ -2,3 +2,4 @@ doc
|
|||
csv/*.csv
|
||||
tests/*.cc
|
||||
tests/tests
|
||||
owlps-positioning
|
||||
|
|
|
@ -17,7 +17,7 @@ RM_RECURSIVE = \rm -fr
|
|||
CP = cp -v
|
||||
|
||||
# Autres outils
|
||||
STYLE = astyle --style=gnu
|
||||
STYLE = astyle --style=gnu --formatted
|
||||
CPPCHECK = cppcheck --enable=all
|
||||
DOXYGEN = doxygen
|
||||
|
||||
|
@ -26,20 +26,20 @@ GXX = g++-4.4
|
|||
TESTSGXXFLAGS = -I$(TEST_DIR) -I.
|
||||
GXXFLAGS = $(DEBUG) -Wall -Wextra $(STLPORTGXXFLAGS)
|
||||
LD = $(GXX)
|
||||
LDFLAGS = -lm -lrt
|
||||
LIBS = -lpq -lboost_program_options-mt
|
||||
LDFLAGS = -lm -lrt -lboost_program_options
|
||||
#LIBS = -lpq
|
||||
|
||||
TARGET = owlps-positioning
|
||||
#HEADER = owlps-positioning.hh
|
||||
OBJ = posutil.o stock.o timestamp.o point3d.o referencepoint.o \
|
||||
waypoint.o building.o area.o wifidevice.o accesspoint.o \
|
||||
mobile.o measurement.o calibrationmeasurement.o request.o \
|
||||
inputcsv.o
|
||||
inputcsv.o configuration.o userinterface.o
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
%: %.o
|
||||
$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(LD) $(LDFLAGS) -o $@ $^
|
||||
|
||||
%.o: %.cc $(HEADER)
|
||||
$(GXX) $(GXXFLAGS) -c $<
|
||||
|
@ -49,6 +49,8 @@ $(TEST_DIR)/%_test.o: %.o
|
|||
|
||||
posutil.o: posutil.hh
|
||||
stock.o: stock.hh
|
||||
configuration.o: configuration.hh
|
||||
userinterface.o: userinterface.hh configuration.o
|
||||
timestamp.o: timestamp.hh
|
||||
point3d.o: point3d.hh
|
||||
referencepoint.o : referencepoint.hh point3d.o
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
utilisant les champs de direction.
|
||||
° Lire la direction en tant qu'entier plutôt que float ?
|
||||
|
||||
- Tests unitaires
|
||||
Écrire une classe utilitaire pour les tests contenant par exemple
|
||||
une fonction pour écrire un fichier de test à partir d'un
|
||||
vector<string>.
|
||||
|
||||
- Réorganisation du dépôt ?
|
||||
owlps-positioning/src
|
||||
owlps-positioning/include
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#include "configuration.hh"
|
||||
|
||||
namespace po = boost::program_options ;
|
||||
|
||||
|
||||
|
||||
/* *** Attribute definitions *** */
|
||||
|
||||
po::variables_map Configuration::configuration ;
|
||||
|
||||
|
||||
|
||||
/* *** Read accessors *** */
|
||||
|
||||
|
||||
po::variables_map& Configuration::getw_configuration()
|
||||
{
|
||||
return configuration ;
|
||||
}
|
||||
|
||||
|
||||
bool Configuration::is_configured(const std::string &key)
|
||||
{
|
||||
if (configuration.count(key))
|
||||
return true ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
|
||||
const std::string&
|
||||
Configuration::get_string_value(const std::string &key)
|
||||
{
|
||||
return configuration[key].as<std::string>() ;
|
||||
}
|
||||
|
||||
|
||||
int Configuration::get_int_value(const std::string &key)
|
||||
{
|
||||
return configuration[key].as<int>() ;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef _OWLPS_POSITIONING_CONFIGURATION_HH_
|
||||
#define _OWLPS_POSITIONING_CONFIGURATION_HH_
|
||||
|
||||
#include <string>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
|
||||
/// Stocks the configuration of the program
|
||||
class Configuration
|
||||
{
|
||||
private:
|
||||
/// Configuration structure
|
||||
static boost::program_options::variables_map configuration ;
|
||||
|
||||
|
||||
public:
|
||||
/// Get a reference to the configuration structure
|
||||
static boost::program_options::variables_map& getw_configuration(void) ;
|
||||
/// Checks if the key exists in the configuration
|
||||
static bool is_configured(const std::string &key) ;
|
||||
/// Get the string value corresponding to \em key
|
||||
static const std::string& get_string_value(const std::string &key) ;
|
||||
/// Get the int value corresponding to \em key
|
||||
static int get_int_value(const std::string &key) ;
|
||||
} ;
|
||||
|
||||
#endif // _OWLPS_POSITIONING_CONFIGURATION_HH_
|
|
@ -1,64 +1,10 @@
|
|||
#include "owlps-positioning.hh"
|
||||
#include "userinterface.hh"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
string config_filename = DEFAULT_CONFIG_FILE;
|
||||
int port, mport;
|
||||
UserInterface *ui = new UserInterface(argc, argv) ;
|
||||
delete ui ; // We don't need it any more
|
||||
|
||||
|
||||
/* Options spécifiques à la ligne de commandes */
|
||||
po::options_description generic("Options générales ");
|
||||
generic.add_options()
|
||||
("help,h", "Affichage de l'aide")
|
||||
("config-file,f", po::value<string>(), "Fichier de configuration")
|
||||
("input-topo,T", po::value<string>(), "Input file topology")
|
||||
("input-waypoint,W", po::value<string>(), "Input file waypoint")
|
||||
("input-refpoint,R", po::value<string>(), "Input file reference point")
|
||||
("input-ap,A", po::value<string>(), "Input file accesspoint")
|
||||
;
|
||||
|
||||
/* Options ligne de commandes & fichier de configuration */
|
||||
po::options_description config("Paramètres ");
|
||||
config.add_options()
|
||||
("server.port,l", po::value<int>(&port) -> default_value(9902), "Port d'écoute du serveur")
|
||||
("server.mobile-port,p", po::value<int>(&mport) -> default_value(9903), "Port d'envoi vers le mobile")
|
||||
("db.name,D", po::value<string>(), "Nom de la base de données à utiliser")
|
||||
("db.host,H", po::value<string>(), "Adresse de l'hôte hébergeant la base de données")
|
||||
("db.user,U", po::value<string>(), "Nom de l'utilisateur pour la connexion à la base de données")
|
||||
("db.passwd,P", po::value<string>(), "Mot de passe pour la connexion à la base de données")
|
||||
;
|
||||
|
||||
/* Total des options acceptées en ligne de commandes */
|
||||
po::options_description cmd_line_options("Options acceptées ") ;
|
||||
cmd_line_options.add(generic).add(config) ;
|
||||
|
||||
/* Parcours de la ligne de commandes */
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(argc, argv, cmd_line_options), vm) ;
|
||||
|
||||
if (vm.count("help")) // L'utilisateur a demandé l'aide
|
||||
{
|
||||
cout << cmd_line_options << endl ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
if (vm.count("config-file")) // L'utilisateur a spécifié un fichier de config
|
||||
config_filename = vm["config-file"].as<string>() ;
|
||||
|
||||
ifstream ifs(config_filename.c_str());
|
||||
if (!ifs.is_open())
|
||||
cerr << "Attention ! Erreur lors de l'ouverture du fichier de configuration « " << config_filename << " » : le fichier n'existe pas ou ne peut être lu.\nUtilisation des valeurs par défaut..." << endl ;
|
||||
else // Parcours du fichier de config
|
||||
po::store(po::parse_config_file(ifs, config), vm) ;
|
||||
|
||||
po::notify(vm);
|
||||
|
||||
Server server(port, mport);
|
||||
|
||||
if (server.init(vm))
|
||||
return 1 ;
|
||||
|
||||
server.start();
|
||||
|
||||
return 0;
|
||||
return 0 ;
|
||||
}
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef _OWLPS_HH_
|
||||
#define _OWLPS_HH_
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include "server.hh"
|
||||
|
||||
//using namespace std ;
|
||||
//namespace po = boost::program_options ;
|
||||
|
||||
#endif // _OWLPS_HH_
|
|
@ -7,13 +7,11 @@ using std::tr1::unordered_map ;
|
|||
|
||||
|
||||
|
||||
/* *** Attribute definition *** */
|
||||
/* *** Attribute definitions *** */
|
||||
|
||||
unordered_map<string, Mobile> Stock::mobiles =
|
||||
unordered_map<string, Mobile>() ;
|
||||
unordered_map<string, Mobile> Stock::mobiles ;
|
||||
|
||||
unordered_map<string, AccessPoint> Stock::aps =
|
||||
unordered_map<string, AccessPoint>() ;
|
||||
unordered_map<string, AccessPoint> Stock::aps ;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "configuration.hh"
|
||||
|
||||
class Configuration_test: public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
|
||||
void test_accessors(void)
|
||||
{
|
||||
// Non-configured values
|
||||
TS_ASSERT(! Configuration::is_configured("miaou")) ;
|
||||
TS_ASSERT(! Configuration::is_configured("ouaf")) ;
|
||||
|
||||
/*
|
||||
* Due to the lack of direct variables_map manipulators, it is
|
||||
* hard to manually add values in order to test them.
|
||||
* Some other tests are done in userinterface_test.hh.
|
||||
*/
|
||||
}
|
||||
|
||||
} ;
|
|
@ -0,0 +1,88 @@
|
|||
#include <cxxtest/TestSuite.h>
|
||||
|
||||
#include "userinterface.hh"
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
class UserInterface_test: public CxxTest::TestSuite
|
||||
{
|
||||
private:
|
||||
std::string config_file_name ;
|
||||
std::vector<std::string> config_lines ; // Test config file contents
|
||||
|
||||
public:
|
||||
|
||||
UserInterface_test(void)
|
||||
{
|
||||
// If we cannot open the file, we want to stop the test
|
||||
CxxTest::setAbortTestOnFail(true) ;
|
||||
|
||||
// Filling name and contents of the config test file
|
||||
config_file_name = "/tmp/UserInterface_test_config_file.csv" ;
|
||||
config_lines.push_back("\n") ;
|
||||
config_lines.push_back("[server]\n") ;
|
||||
config_lines.push_back("\n") ;
|
||||
config_lines.push_back("port = 42\n") ;
|
||||
config_lines.push_back("\n") ;
|
||||
|
||||
// Opening the file
|
||||
std::ofstream config_file ;
|
||||
config_file.open(config_file_name.c_str()) ;
|
||||
if (! config_file)
|
||||
TS_FAIL("Cannot open test config file for creation!") ;
|
||||
|
||||
// Writing contents to the file
|
||||
for (std::vector<std::string>::const_iterator i = config_lines.begin() ;
|
||||
i != config_lines.end() ; ++i)
|
||||
config_file << *i ;
|
||||
|
||||
config_file.close() ;
|
||||
|
||||
// Back to the normal behaviour (i.e. do not abort on fail)
|
||||
CxxTest::setAbortTestOnFail(false) ;
|
||||
}
|
||||
|
||||
|
||||
~UserInterface_test(void)
|
||||
{
|
||||
// Deleting the test config file
|
||||
if (remove(config_file_name.c_str()) == -1)
|
||||
TS_WARN("Cannot remove test config file!") ;
|
||||
}
|
||||
|
||||
|
||||
static UserInterface_test* createSuite(void)
|
||||
{
|
||||
return new UserInterface_test() ;
|
||||
}
|
||||
|
||||
|
||||
static void destroySuite(UserInterface_test *suite)
|
||||
{
|
||||
delete suite ;
|
||||
}
|
||||
|
||||
|
||||
void test_constructors(void)
|
||||
{
|
||||
// Note: as --help makes the program exit, we cannot test it.
|
||||
const char *argv[] =
|
||||
{
|
||||
"owlps-positioning", // program name
|
||||
"--config-file",
|
||||
config_file_name.c_str()
|
||||
} ;
|
||||
int argc = 3 ;
|
||||
|
||||
UserInterface ui(argc, const_cast<char**>(argv)) ;
|
||||
|
||||
TS_ASSERT(Configuration::is_configured("server.port")) ;
|
||||
TS_ASSERT(Configuration::is_configured("config-file")) ;
|
||||
|
||||
TS_ASSERT_EQUALS(Configuration::get_int_value("server.port"), 42) ;
|
||||
TS_ASSERT_EQUALS(Configuration::get_string_value("config-file"),
|
||||
config_file_name) ;
|
||||
}
|
||||
|
||||
} ;
|
|
@ -0,0 +1,128 @@
|
|||
#include "userinterface.hh"
|
||||
#include "configuration.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
using namespace std ;
|
||||
namespace po = boost::program_options ;
|
||||
|
||||
|
||||
|
||||
/* *** Default value definitions *** */
|
||||
|
||||
#define DEFAULT_CONFIG_FILE_NAME "cfg/owlps-positioning.cfg"
|
||||
#define DEFAULT_LISTENING_PORT 9902
|
||||
|
||||
|
||||
|
||||
/* *** Constructors *** */
|
||||
|
||||
|
||||
UserInterface::UserInterface(const int argc, char **argv)
|
||||
{
|
||||
cli_argument_count = argc ;
|
||||
cli_argument_values = argv ;
|
||||
config_file_name = DEFAULT_CONFIG_FILE_NAME ;
|
||||
|
||||
cli_options = new po::options_description("General options") ;
|
||||
file_options = new po::options_description("Parameters") ;
|
||||
fill_options() ;
|
||||
|
||||
parse_options() ;
|
||||
}
|
||||
|
||||
|
||||
UserInterface::~UserInterface()
|
||||
{
|
||||
delete cli_options ;
|
||||
delete file_options ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* *** Operations *** */
|
||||
|
||||
|
||||
void UserInterface::fill_options()
|
||||
{
|
||||
fill_cli_options() ;
|
||||
fill_file_options() ;
|
||||
|
||||
// File options are also accepted on the command line
|
||||
cli_options->add(*file_options) ;
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::fill_cli_options()
|
||||
{
|
||||
cli_options->add_options()
|
||||
("help,h", "Print help")
|
||||
("config-file,f", po::value<string>(),
|
||||
"Alternative configuration file")
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::fill_file_options()
|
||||
{
|
||||
file_options->add_options()
|
||||
("server.port,l", po::value<int>()
|
||||
->default_value(DEFAULT_LISTENING_PORT),
|
||||
"Server listening port")
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::parse_options()
|
||||
{
|
||||
parse_command_line() ;
|
||||
print_usage_and_exit_if_requested() ;
|
||||
|
||||
// Was the config file name specified on the command line?
|
||||
if (Configuration::is_configured("config-file"))
|
||||
config_file_name = Configuration::get_string_value("config-file") ;
|
||||
|
||||
parse_file() ;
|
||||
|
||||
po::notify(Configuration::getw_configuration()) ;
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::parse_command_line() const
|
||||
{
|
||||
po::store(po::parse_command_line(cli_argument_count,
|
||||
cli_argument_values,
|
||||
*cli_options),
|
||||
Configuration::getw_configuration()) ;
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::print_usage_and_exit_if_requested() const
|
||||
{
|
||||
if (Configuration::is_configured("help"))
|
||||
{
|
||||
cout << *cli_options ;
|
||||
exit(0) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UserInterface::parse_file() const
|
||||
{
|
||||
ifstream config_file(config_file_name.c_str()) ;
|
||||
|
||||
if (! config_file)
|
||||
{
|
||||
cerr
|
||||
<< "Warning! Error opening input configuration file « "
|
||||
<< config_file_name
|
||||
<< " »! Using command line and default values…"
|
||||
<< endl ;
|
||||
return ;
|
||||
}
|
||||
|
||||
po::store(po::parse_config_file(config_file, *file_options),
|
||||
Configuration::getw_configuration()) ;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef _OWLPS_POSITIONING_USERINTERFACE_HH_
|
||||
#define _OWLPS_POSITIONING_USERINTERFACE_HH_
|
||||
|
||||
#include <string>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
|
||||
/// Handles configuration inputs from user
|
||||
class UserInterface
|
||||
{
|
||||
protected:
|
||||
std::string config_file_name ;
|
||||
int cli_argument_count ;
|
||||
char **cli_argument_values ;
|
||||
boost::program_options::options_description *cli_options ;
|
||||
boost::program_options::options_description *file_options ;
|
||||
|
||||
/** @name Operations */
|
||||
//@{
|
||||
/// Fill in all the options
|
||||
void fill_options(void) ;
|
||||
/// Fill in the options accepted on the command line
|
||||
void fill_cli_options(void) ;
|
||||
/// \brief Fill in the options accepted on the command line and in
|
||||
/// the configuration file
|
||||
void fill_file_options(void) ;
|
||||
/// Parse all the configuration inputs and updates Configuration
|
||||
void parse_options(void) ;
|
||||
void parse_command_line(void) const ;
|
||||
void parse_file(void) const ;
|
||||
/// If help was requested by user, displays accepted options and exit
|
||||
void print_usage_and_exit_if_requested(void) const ;
|
||||
//@}
|
||||
|
||||
public:
|
||||
UserInterface(const int argc, char **argv) ;
|
||||
|
||||
~UserInterface(void) ;
|
||||
} ;
|
||||
|
||||
#endif // _OWLPS_POSITIONING_USERINTERFACE_HH_
|
Loading…
Reference in New Issue