summaryrefslogtreecommitdiff
path: root/i
diff options
context:
space:
mode:
authordufourj2006-03-21 21:15:17 +0000
committerdufourj2006-03-21 21:15:17 +0000
commit7fcaa8a15fd9b6de7da0f183b96d765a9ed3cb99 (patch)
tree6e8538738d81c872d28f9d5987d73ca080a6644c /i
parente0ac51b1a486a5bc1889c7ba0e5c8b81c1221dec (diff)
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.
Diffstat (limited to 'i')
-rw-r--r--i/marvin/src/tester/Makefile.defs2
-rw-r--r--i/marvin/src/tester/test_tester.cc27
-rw-r--r--i/marvin/src/tester/tester.cc147
-rw-r--r--i/marvin/src/tester/tester.hh22
4 files changed, 192 insertions, 6 deletions
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 <unistd.h>
+#include <iostream>
+#include <exception>
+#include <sstream>
+
+/// 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 <commands list>]" <<
+ 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 <map>
+#include <string>
class Tester
{
@@ -55,16 +57,36 @@ class Tester
typedef std::map<std::string, Func *> 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<class T, typename F>
static Func *memFunc (T &i, F f);
+ /// Run commands.
+ void run (void);
};
#include "tester.tcc"