From 7fcaa8a15fd9b6de7da0f183b96d765a9ed3cb99 Mon Sep 17 00:00:00 2001 From: dufourj Date: Tue, 21 Mar 2006 21:15:17 +0000 Subject: Tester : - ajout du parsage de la ligne de commandes (à la main) ; - création de Config dans le constructeur. TODO - gérer le type des arguments des commandes. --- i/marvin/src/tester/Makefile.defs | 2 +- i/marvin/src/tester/test_tester.cc | 27 +++++-- i/marvin/src/tester/tester.cc | 147 +++++++++++++++++++++++++++++++++++++ i/marvin/src/tester/tester.hh | 22 ++++++ 4 files changed, 192 insertions(+), 6 deletions(-) (limited to 'i') diff --git a/i/marvin/src/tester/Makefile.defs b/i/marvin/src/tester/Makefile.defs index d0e6b73..6c1b60d 100644 --- a/i/marvin/src/tester/Makefile.defs +++ b/i/marvin/src/tester/Makefile.defs @@ -1,5 +1,5 @@ PROGRAMS += test_tester -tester_OBJECTS = tester.o +tester_OBJECTS = tester.o $(config_OBJECTS) test_tester_OBJECTS = test_tester.o $(tester_OBJECTS) $(utils_OBJECTS) diff --git a/i/marvin/src/tester/test_tester.cc b/i/marvin/src/tester/test_tester.cc index 57973f6..6e1c208 100644 --- a/i/marvin/src/tester/test_tester.cc +++ b/i/marvin/src/tester/test_tester.cc @@ -32,6 +32,9 @@ class TestTester { Tester t; public: + // Constructor + TestTester (int argc, char ** argv) + : t (argc, argv) { } bool funcA (const Tester::Args &a) { std::cout << " a " << a << std::endl; @@ -70,7 +73,13 @@ class TestTester std::cout << ' ' << e.what () << std::endl; } } - int main (void) + int run (void) + { + t.add ("m", Tester::memFunc (*this, &TestTester::main)); + t.run (); + return 0; + } + bool main (void) { Tester::Args a[4]; // Add functions. @@ -95,12 +104,20 @@ class TestTester call ("d", a[i]); call ("e", a[i]); } - return 0; + return true; } }; -int main (void) +int +main (int argc, char **argv) { - TestTester tt; - return tt.main (); + TestTester tt (argc, argv); + try + { + return tt.run (); + } + catch (const std::exception &e) + { + std::cerr << e.what () << std::endl; + } } diff --git a/i/marvin/src/tester/tester.cc b/i/marvin/src/tester/tester.cc index ba4ff40..3251fbb 100644 --- a/i/marvin/src/tester/tester.cc +++ b/i/marvin/src/tester/tester.cc @@ -24,6 +24,19 @@ // }}} #include "tester.hh" +#include +#include +#include +#include + +/// Constructor. +Tester::Tester (int argc, char **argv) + : config_ (argc, argv), program_(argv[0]), commands_ ("") +{ + // Parse command line + getOpt (argc, argv); +} + /// Destructor. Tester::~Tester (void) { @@ -33,6 +46,121 @@ Tester::~Tester (void) } } +/// Getopt command line. +/// Supported arguemnts : +/// - -c "commands list" +void +Tester::getOpt (int argc, char **argv) +{ + char *optstring = "c:"; + int option; + + // Check number of args + if (argc < 2) + { + std::cerr << "Argument missing." << std::endl; + usage (); + exit (1); + } + + // Automatic error message + opterr = 1; + + while ((option = getopt (argc, argv, optstring)) != EOF) + { + switch (option) + { + case 'c': + commands_ = optarg; + break; + case '?': + default: + usage (); + exit (2); + break; + } + } +} + +/// Print usage to stdout. +void +Tester::usage (void) +{ + std::cout << "Usage: " << program_ << " [-c ]" << + std::endl; +} + +/// Run command list. +/// If check is true, the command list will be checked, otherwise, it +/// will be executed. If check failed, it throw an exception. +void +Tester::parse (const std::string &commands, bool check) +{ + Args argList; + std::istringstream list_commands (commands); + std::string commandargs, command, args; + std::string::size_type pos; + + // Cut it by ; + while (std::getline (list_commands, commandargs, ';')) + { + argList.clear (); + // Remove space at begining + pos = commandargs.find_first_not_of (' '); + // For empty command... + if (pos != std::string::npos) + { + commandargs = commandargs.substr + (commandargs.find_first_not_of (' ')); + // Remove space at end + commandargs = commandargs.substr + (0, commandargs.find_last_not_of (' ') + 1); + // Get the command + pos = commandargs.find_first_of (' '); + command = commandargs.substr (0, pos); + // Args ? + if (pos != std::string::npos) + { + args = commandargs.substr (pos); + pos = 0; + do + { + // Next + args = args.substr (pos); + // Remove space at begining + args = args.substr (args.find_first_not_of (' ')); + // Get the end position of the first arg + pos = args.find_first_of (' '); + // Add args + // TODO type ? + argList.push_back (args.substr (0, pos)); + } + while (pos != std::string::npos); + } + if (check) + { + // TODO Check args + if (!exist (command)) + throw std::runtime_error ("Unknow command : " + command); + } + else + call (command, argList); + } + } +} + +/// Check function exists. +bool +Tester::exist (const std::string &s) +{ + Funcs::const_iterator i; + i = funcs_.find (s); + if (i == funcs_.end ()) + return false; + else + return true; +} + /// Add a test function, Tester owns f. void Tester::add (const std::string &s, Func *f) @@ -65,3 +193,22 @@ Tester::call (const std::string &s, const Args &a) const } } +void +Tester::run (void) +{ + if (commands_.size () < 1) + throw std::runtime_error ("Nothing to do"); + // Check commands + try + { + parse (commands_, true); + } + catch (const std::exception &e) + { + std::cerr << "Error : " << e.what () << std::endl; + usage (); + exit (3); + } + parse (commands_, false); +} + diff --git a/i/marvin/src/tester/tester.hh b/i/marvin/src/tester/tester.hh index 15ad9dc..e38967d 100644 --- a/i/marvin/src/tester/tester.hh +++ b/i/marvin/src/tester/tester.hh @@ -25,8 +25,10 @@ // // }}} #include "utils/any.hh" +#include "config/config.hh" #include +#include class Tester { @@ -55,16 +57,36 @@ class Tester typedef std::map Funcs; /// The function map itself. Funcs funcs_; + /// The config. + Config config_; + /// Program name. + std::string program_; + /// Commands to parse. + std::string commands_; + /// Getopt command line. + void getOpt (int argc, char **argv); + /// Run command list. + /// If check is true, the command list will be checked, otherwise, it + /// will be executed. If check failed, it throw an exception. + void parse (const std::string &command, bool check); + /// Print usage to stdout. + void usage (void); public: + /// Constructor. + Tester (int argc, char ** argv); /// Destructor. ~Tester (void); /// Add a test function, Tester owns f. void add (const std::string &s, Func *f); /// Call a test function by name. bool call (const std::string &s, const Args &a) const; + /// Check function exists. + bool exist (const std::string &s); /// Take all the template sophistications out of the programmer hands. template static Func *memFunc (T &i, F f); + /// Run commands. + void run (void); }; #include "tester.tcc" -- cgit v1.2.3