From 08e65445760a453a95f9039f9ea6ab626789a12d Mon Sep 17 00:00:00 2001 From: schodet Date: Wed, 19 Apr 2006 18:49:31 +0000 Subject: Ajout de la gestion de l'aide dans l'interpreteur. --- i/marvin/src/interpreter/interpreter.cc | 36 ++++++++++++++++++++++++---- i/marvin/src/interpreter/interpreter.hh | 13 +++++++++- i/marvin/src/interpreter/test_interpreter.cc | 21 ++++++++++++---- 3 files changed, 60 insertions(+), 10 deletions(-) (limited to 'i') diff --git a/i/marvin/src/interpreter/interpreter.cc b/i/marvin/src/interpreter/interpreter.cc index bdc918a..0c067cf 100644 --- a/i/marvin/src/interpreter/interpreter.cc +++ b/i/marvin/src/interpreter/interpreter.cc @@ -30,15 +30,15 @@ Interpreter::~Interpreter (void) { for (Funcs::iterator i = funcs_.begin (); i != funcs_.end (); ++i) { - delete i->second; + delete i->second.func; } } /// Add a function, Interpreter owns f. void -Interpreter::add (const std::string &s, Func *f) +Interpreter::add (const std::string &s, Func *f, const std::string &desc) { - if (!funcs_.insert (Funcs::value_type (s, f)).second) + if (!funcs_.insert (Funcs::value_type (s, FuncDesc (f, desc))).second) { // Interpreter owns f, therefore, f must be deleted. delete f; @@ -47,6 +47,13 @@ Interpreter::add (const std::string &s, Func *f) } } +/// Add a function without description, Interpreter owns f. +void +Interpreter::add (const std::string &s, Func *f) +{ + add (s, f, ""); +} + /// Call a function by name. void Interpreter::call (const std::string &s, const Args &a, @@ -58,7 +65,7 @@ Interpreter::call (const std::string &s, const Args &a, throw std::runtime_error ("function \'" + s + "\' does not exist"); try { - (*i->second) (a, dryrun); + (*i->second.func) (a, dryrun); } catch (const std::exception &e) { @@ -83,3 +90,24 @@ Interpreter::interpretFile (const std::string &file, bool dryrun/*false*/) p.parseFile (file); } +/// Return an help string. +std::string +Interpreter::help (void) const +{ + std::string ret; + for (Funcs::const_iterator i = funcs_.begin (); i != funcs_.end (); ++i) + { + // Well, if you really want to implement this better, please do... + for (std::string::const_iterator j = i->second.desc.begin (); + j != i->second.desc.end (); j++) + { + if (*j == '\n') + ret += "\n "; + else + ret += *j; + } + ret += '\n'; + } + return ret; +} + diff --git a/i/marvin/src/interpreter/interpreter.hh b/i/marvin/src/interpreter/interpreter.hh index 4164c28..1f6e688 100644 --- a/i/marvin/src/interpreter/interpreter.hh +++ b/i/marvin/src/interpreter/interpreter.hh @@ -51,14 +51,23 @@ class Interpreter template class MemFunc; private: + struct FuncDesc + { + Func *func; + std::string desc; + FuncDesc (Func *func_, const std::string &desc_) + : func (func_), desc (desc_) { } + }; /// Type of the private function map. - typedef std::map Funcs; + typedef std::map Funcs; /// The function map itself. Funcs funcs_; public: /// Destructor. ~Interpreter (void); /// Add a function, Interpreter owns f. + void add (const std::string &s, Func *f, const std::string &desc); + /// Add a function without description, Interpreter owns f. void add (const std::string &s, Func *f); /// Call a function by name. void call (const std::string &s, const Args &a, @@ -67,6 +76,8 @@ class Interpreter void interpretString (const std::string &s, bool dryrun = false); /// Interpret a file. void interpretFile (const std::string &file, bool dryrun = false); + /// Return an help string. + std::string help (void) const; /// Take all the template sophistications out of the programmer hands. template static Func *memFunc (T &i, F f); diff --git a/i/marvin/src/interpreter/test_interpreter.cc b/i/marvin/src/interpreter/test_interpreter.cc index d51357d..631d10d 100644 --- a/i/marvin/src/interpreter/test_interpreter.cc +++ b/i/marvin/src/interpreter/test_interpreter.cc @@ -86,11 +86,20 @@ class TestInterpreter int main (void) { // Add functions. - t.add ("a", Interpreter::memFunc (*this, &TestInterpreter::funcA)); - t.add ("b", Interpreter::memFunc (*this, &TestInterpreter::funcB)); - t.add ("c", Interpreter::memFunc (*this, &TestInterpreter::funcC)); - t.add ("d", Interpreter::memFunc (*this, &TestInterpreter::funcD)); - t.add ("e", Interpreter::memFunc (*this, &TestInterpreter::funcE)); + t.add ("a", Interpreter::memFunc (*this, &TestInterpreter::funcA), + "a ARGS...\n" + "the wonderful `a' function taking any number of any arguments"); + t.add ("b", Interpreter::memFunc (*this, &TestInterpreter::funcB), + "b\ntakes no argument"); + t.add ("c", Interpreter::memFunc (*this, &TestInterpreter::funcC), + "c THE_MIGHTY_NUMBER\n" + "takes one integer"); + t.add ("d", Interpreter::memFunc (*this, &TestInterpreter::funcD), + "d THE_STRING\n" + "takes one string"); + t.add ("e", Interpreter::memFunc (*this, &TestInterpreter::funcE), + "e INT STRING DOUBLE\n" + "takes one integer, one string and one double"); // Make argument lists. Interpreter::Args a[4]; a[1].push_back (71117); @@ -98,6 +107,8 @@ class TestInterpreter a[3].push_back (42); a[3].push_back (std::string ("merguez")); a[3].push_back (51.1664); + // Need help? + std::cout << t.help () << std::endl; // Call all those wonderful functions. call ("unknown", a[0]); for (unsigned int i = 0; i < sizeof (a) / sizeof (a[0]); ++i) -- cgit v1.2.3