Utils/Console: Implement command node return value support
g0dil [Tue, 10 Feb 2009 02:12:06 +0000 (02:12 +0000)]
Utils/Console: Implement directory return value support in Executor
Utils/Logger: Make file-target return the new directory node

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1111 270642c3-0616-0410-b53a-bc976706d245

17 files changed:
Utils/Console/Executor.cc
Utils/Console/Executor.hh
Utils/Console/Node.cc
Utils/Console/Node.cci
Utils/Console/Node.hh
Utils/Console/OverloadedCommand.cc
Utils/Console/OverloadedCommand.cci
Utils/Console/OverloadedCommand.hh
Utils/Console/Parse.cc
Utils/Console/Parse.cci
Utils/Console/Parse.ih
Utils/Console/Parse.test.cc
Utils/Console/ParsedCommand.mpp
Utils/Console/ParsedCommand.test.cc
Utils/Logger/FileTarget.cc
Utils/Logger/FileTarget.hh
Utils/Logger/Target.hh

index a228c33..7733e07 100644 (file)
@@ -96,7 +96,7 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
                 break;
             try {
                 // The parser ensures, we have exactly one argument
-                cd(*command.arguments().begin());
+                cd(command.commandPath());
             }
             catch (IgnoreCommandException &) {
                 throw SyntaxErrorException(
@@ -108,13 +108,15 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
             if (skipping())
                 break;
             // The parser ensures, we have either one or no argument
-            ls( output,
-                command.tokens().empty() ? command.tokens() : *command.arguments().begin() );
+            ls( output, command.commandPath() );
             break;
 
         case ParseCommandInfo::BuiltinPUSHD :
             // The parser ensures, we have exactly one argument
-            pushd( *command.arguments().begin() );
+            if (skipping())
+                pushd(command.commandPath());
+            else
+                exec(output, command);
             break;
             
         case ParseCommandInfo::BuiltinPOPD :
@@ -133,8 +135,7 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
             if (skipping())
                 break;
             // The parser ensures, we have either one or no arguments
-            help( output,
-                  command.tokens().empty() ? command.tokens() : *command.arguments().begin() );
+            help( output, command.commandPath() );
             break;
 
         }
@@ -154,17 +155,45 @@ prefix_ void senf::console::Executor::execute(std::ostream & output,
 prefix_ void senf::console::Executor::exec(std::ostream & output,
                                            ParseCommandInfo const & command)
 {
-    GenericNode & node ( traverseNode(command.commandPath()) );
-    DirectoryNode * dir ( dynamic_cast<DirectoryNode*>(&node) );
-    if ( dir ) {
-        if (autocd_ && command.tokens().empty()) {
-            cd( boost::make_iterator_range(
-                    command.commandPath().begin(),
-                    command.commandPath().end()) );
-        } else
-            throw InvalidCommandException();
-    } else {
-        dynamic_cast<CommandNode &>(node)(output, command);
+    try {
+        GenericNode & node ( traverseNode(command.commandPath()) );
+        DirectoryNode * dir ( dynamic_cast<DirectoryNode*>(&node) );
+        if ( dir ) {
+            if (! command.tokens().empty())
+                throw InvalidCommandException();
+            if (command.builtin() == ParseCommandInfo::BuiltinPUSHD)
+                pushd( command.commandPath() );
+            else if (autocd_) {
+                cd(command.commandPath());
+            }
+            else
+                throw InvalidCommandException();
+        } else {
+            boost::any rv;
+            dynamic_cast<CommandNode &>(node)(rv, output, command);
+            if (command.builtin() == ParseCommandInfo::BuiltinPUSHD) {
+                DirectoryNode::ptr rvdir;
+                try {
+                    rvdir = boost::any_cast<DirectoryNode::ptr>(rv);
+                }
+                catch (boost::bad_any_cast &) {
+                    throw InvalidCommandException();
+                }
+                Path newDir (cwd_);
+                newDir.push_back(rvdir);
+                dirstack_.push_back(Path());
+                dirstack_.back().swap(cwd_);
+                cwd_.swap(newDir);
+            }
+        }
+    }
+    catch (IgnoreCommandException &) {
+        if (command.builtin() == ParseCommandInfo::BuiltinPUSHD) {
+            dirstack_.push_back(Path());
+            dirstack_.back().swap(cwd_);
+        }
+        else
+            throw;
     }
 }
 
@@ -320,6 +349,15 @@ prefix_ std::string senf::console::Executor::complete(DirectoryNode & dir,
     return name;
 }
 
+prefix_ void senf::console::senf_console_format_value(DirectoryNode::ptr value,
+                                                      std::ostream & os)
+{
+    if (value)
+        os << "<Directory at '" << value->path() << "'>";
+    else
+        os << "<Null Directory>";
+}
+
 ///////////////////////////////cc.e////////////////////////////////////////
 #undef prefix_
 //#include "Executor.mpp"
index 7538eff..540472d 100644 (file)
@@ -163,6 +163,8 @@ namespace console {
         bool autocomplete_;
     };
 
+    void senf_console_format_value(DirectoryNode::ptr value, std::ostream & os);
+
 }}
 
 ///////////////////////////////hh.e////////////////////////////////////////
index 39c2685..5096ba8 100644 (file)
@@ -209,11 +209,11 @@ prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output)
     output << doc_ << "\n";
 }
 
-prefix_ void senf::console::SimpleCommandNode::v_execute(std::ostream & output,
+prefix_ void senf::console::SimpleCommandNode::v_execute(boost::any & rv, std::ostream & os,
                                                          ParseCommandInfo const & command)
     const
 {
-    fn_(output, command);
+    fn_(os, command);
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index 1c130cb..3c21bc9 100644 (file)
@@ -282,7 +282,16 @@ prefix_ void senf::console::CommandNode::execute(std::ostream & output,
                                                  ParseCommandInfo const & command)
     const
 {
-    v_execute(output, command);
+    boost::any rv;
+    execute(rv, output, command);
+}
+
+prefix_ void senf::console::CommandNode::execute(boost::any & rv, std::ostream & output,
+                                                 ParseCommandInfo const & command)
+    const
+{
+    rv = boost::any();
+    v_execute(rv, output, command);
 }
 
 prefix_ void senf::console::CommandNode::operator()(std::ostream & output,
@@ -292,6 +301,13 @@ prefix_ void senf::console::CommandNode::operator()(std::ostream & output,
     execute(output, command);
 }
 
+prefix_ void senf::console::CommandNode::operator()(boost::any & rv, std::ostream & output,
+                                                    ParseCommandInfo const & command)
+    const
+{
+    execute(rv, output, command);
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::SimpleCommandNode
 
index 6caef96..0367f5a 100644 (file)
 #include <boost/range/iterator_range.hpp>
 #include <boost/typeof/typeof.hpp>
 #include <boost/type_traits/remove_reference.hpp>
+#include <boost/any.hpp>
 #include "../../Utils/Exception.hh"
 #include "../../Utils/mpl.hh"
 #include "../../Utils/Logger/SenfLog.hh"
@@ -606,7 +607,15 @@ namespace console {
 
         void execute(std::ostream & output, ParseCommandInfo const & command) const;
                                         ///< Execute the command
-                                        /**< Same as operator()()
+                                        /**< \param[in] output stream where result messages may be
+                                                 written to
+                                             \param[in] arguments command arguments. This is a
+                                                 range of ranges of Token instances. */
+
+        void execute(boost::any & rv, std::ostream & output, ParseCommandInfo const & command) 
+            const;
+                                        ///< Execute the command
+                                        /**< \param[out] rv command return value
                                              \param[in] output stream where result messages may be
                                                  written to
                                              \param[in] arguments command arguments. This is a
@@ -619,6 +628,8 @@ namespace console {
                                                  written to
                                              \param[in] arguments command arguments. This is a
                                                  range of ranges of Token instances. */
+        void operator()(boost::any & rv, std::ostream & output, ParseCommandInfo const & command)
+            const;
 
         ptr thisptr();
         cptr thisptr() const;
@@ -629,10 +640,10 @@ namespace console {
 #ifndef DOXYGEN
     private:
 #endif
-        virtual void v_execute(std::ostream & output, ParseCommandInfo const & command) const = 0;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const = 0;
                                         ///< Called to execute the command
-                                        /**< \param[in] output stream where result messages may be
-                                                 written to
+                                        /**< \param[out] rv return value holder
                                              \param[in] arguments command arguments. This is a
                                                  range of ranges of Token instances. */
 
@@ -686,7 +697,8 @@ namespace console {
 
     private:
         virtual void v_help(std::ostream & output) const;
-        virtual void v_execute(std::ostream & output, ParseCommandInfo const & command) const;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const;
 
 
         Function fn_;
index ecc5c44..abae95e 100644 (file)
@@ -155,7 +155,8 @@ prefix_ void senf::console::OverloadedCommandNode::v_help(std::ostream & os)
     }
 }
 
-prefix_ void senf::console::OverloadedCommandNode::v_execute(std::ostream & output,
+prefix_ void senf::console::OverloadedCommandNode::v_execute(boost::any & rv,
+                                                             std::ostream & os,
                                                              ParseCommandInfo const & command)
     const
 {
@@ -164,7 +165,7 @@ prefix_ void senf::console::OverloadedCommandNode::v_execute(std::ostream & outp
     SyntaxErrorException err;
     for (; i != i_end; ++i) {
         try {
-            (**i)(output, command);
+            (**i)(rv, os, command);
             return;
         }
         catch (SyntaxErrorException & ex) {
@@ -193,7 +194,8 @@ prefix_ std::string senf::console::SimpleCommandOverload::v_doc()
     return doc_;
 }
 
-prefix_ void senf::console::SimpleCommandOverload::v_execute(std::ostream & os,
+prefix_ void senf::console::SimpleCommandOverload::v_execute(boost::any & rv,
+                                                             std::ostream & os,
                                                              ParseCommandInfo const & command)
     const
 {
index d48d9d6..c2fbdc6 100644 (file)
@@ -72,16 +72,16 @@ prefix_ senf::console::OverloadedCommandNode::OverloadedCommandNode()
 prefix_ senf::console::CommandOverload::~CommandOverload()
 {}
 
-prefix_ void senf::console::CommandOverload::execute(std::ostream & os,
+prefix_ void senf::console::CommandOverload::execute(boost::any & rv, std::ostream & os,
                                                      ParseCommandInfo const & command)
 {
-    v_execute(os, command);
+    v_execute(rv, os, command);
 }
 
-prefix_ void senf::console::CommandOverload::operator()(std::ostream & os,
+prefix_ void senf::console::CommandOverload::operator()(boost::any & rv, std::ostream & os,
                                                         ParseCommandInfo const & command)
 {
-    execute(os, command);
+    execute(rv, os, command);
 }
 
 prefix_ unsigned senf::console::CommandOverload::numArguments()
index ee9bde9..bb80f23 100644 (file)
@@ -69,13 +69,13 @@ namespace console {
 
         virtual ~CommandOverload();
 
-        void execute(std::ostream & os, ParseCommandInfo const & command);
+        void execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
                                         ///< Call the overload
                                         /**< If the \a arguments are not acceptable for this
                                              overload, a SyntaxErrorException must be thrown. 
                                              Same as operator()() */
 
-        void operator()(std::ostream & os, ParseCommandInfo const & command);
+        void operator()(boost::any & rv, std::ostream & os, ParseCommandInfo const & command);
                                         ///< Call the overload
                                         /**< If the \a arguments are not acceptable for this
                                              overload, a SyntaxErrorException must be thrown. 
@@ -120,7 +120,8 @@ namespace console {
                                         /**< This member must be implemented in the derived class to
                                              return the overloads documentation string. */
 
-        virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const = 0;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const = 0;
                                         ///< Execute the overload
                                         /**< This member must be implemented in the derived class
                                              o execute the overload. */
@@ -196,7 +197,8 @@ namespace console {
         OverloadedCommandNode();
 
         virtual void v_help(std::ostream & output) const;
-        virtual void v_execute(std::ostream & output, ParseCommandInfo const & command) const;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const;
 
         typedef std::vector<CommandOverload::ptr> Overloads;
 
@@ -240,7 +242,8 @@ namespace console {
         virtual unsigned v_numArguments() const;
         virtual void v_argumentDoc(unsigned index, ArgumentDoc & doc) const;
         virtual std::string v_doc() const;
-        virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
+        virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
+            const;
 
         Function fn_;
         std::string doc_;
index e4e1e66..dece5df 100644 (file)
@@ -76,10 +76,10 @@ namespace detail {
               info_->builtin(ParseCommandInfo::BuiltinLS);
               setBuiltinPathArg(path); }
 
-        void pushDirectory(std::vector<Token> & path)
-            { info_->clear();
-              info_->builtin(ParseCommandInfo::BuiltinPUSHD);
-              setBuiltinPathArg(path); }
+        void pushDirectory()
+            { // Do NOT call clear since pushDirectory is set in ADDITION
+              // to an ordinary command (which may be only a directory name)
+              info_->builtin(ParseCommandInfo::BuiltinPUSHD); }
 
         void popDirectory()
             { info_->clear();
@@ -96,11 +96,12 @@ namespace detail {
 
         void setBuiltinPathArg(std::vector<Token> & path)
             {
-                pushToken(ArgumentGroupOpenToken());
-                for (std::vector<Token>::const_iterator i (path.begin());
-                     i != path.end(); ++i)
-                    pushToken(*i);
-                pushToken(ArgumentGroupCloseToken());
+                info_->command(path);
+//                 pushToken(ArgumentGroupOpenToken());
+//                 for (std::vector<Token>::const_iterator i (path.begin());
+//                      i != path.end(); ++i)
+//                     pushToken(*i);
+//                 pushToken(ArgumentGroupCloseToken());
             }
     };
 
@@ -249,7 +250,6 @@ namespace {
     void throwParserError(Error const & err) 
     {
         static char const * msg [] = { "end of statement expected",
-                                       "'{' or arguments expected",
                                        "path expected",
                                        "')' expected",
                                        "'\"' expected" };
index 563cd6f..374d366 100644 (file)
@@ -178,7 +178,6 @@ prefix_ bool senf::console::ParseCommandInfo::empty()
 prefix_ void senf::console::ParseCommandInfo::builtin(BuiltinCommand builtin)
 {
     builtin_ = builtin;
-    commandPath_.clear();
 }
 
 prefix_ void
@@ -186,7 +185,6 @@ senf::console::ParseCommandInfo::command(std::vector<Token> & commandPath)
 {
     commandPath_.clear();
     commandPath_.swap(commandPath);
-    builtin_ = NoBuiltin;
 }
 
 prefix_ void senf::console::ParseCommandInfo::addToken(Token const & token)
index 8d3d35d..38b9fc9 100644 (file)
@@ -83,7 +83,6 @@ namespace detail {
 
         enum Errors {
             EndOfStatementExpected,
-            GroupOrArgumentsExpected,
             PathExpected,
             ClosingParenExpected,
             QuoteExpected
@@ -145,7 +144,6 @@ namespace detail {
                 actor< variable< ParseDispatcher > >    d_     (self.dispatcher);
 
                 assertion<Errors> end_of_statement_expected   (EndOfStatementExpected);
-                assertion<Errors> group_or_arguments_expected (GroupOrArgumentsExpected);
                 assertion<Errors> path_expected               (PathExpected);
                 assertion<Errors> closing_paren_expected      (ClosingParenExpected);
                 assertion<Errors> quote_expected              (QuoteExpected);
@@ -192,8 +190,16 @@ namespace detail {
                     =    builtin >> end_of_statement_expected(statement_end)
                     |    group_close
                     |    ch_p(';') // Ignore empty commands
-                    |    path_expected(path) 
-                      >> group_or_arguments_expected( group_start | statement )
+                    |    statement
+                    ;
+
+                statement
+                    =    path_expected(path)      [ bind(&PD::beginCommand)(d_, path_) ]
+                      >> arguments
+                      >> end_of_statement_expected( 
+                           ( group_start | statement_end )
+                                                  [ bind(&PD::endCommand)(d_) ]
+                         )
                     ;
 
                 builtin
@@ -210,20 +216,13 @@ namespace detail {
                     ;
 
                 group_start
-                    =    ch_p('{')                [ bind(&PD::pushDirectory)(d_, path_) ]
+                    =    ch_p('{')                [ bind(&PD::pushDirectory)(d_) ]
                     ;
 
                 group_close
                     =    ch_p('}')                [ bind(&PD::popDirectory)(d_) ]
                     ;
 
-                statement
-                    =    eps_p                    [ bind(&PD::beginCommand)(d_, path_) ]
-                      >> arguments
-                      >> end_of_statement_expected(statement_end)
-                                                  [ bind(&PD::endCommand)(d_) ]
-                    ;
-
                 arguments
                     =    * argument
                     ;
index 4570fb0..7b9e7be 100644 (file)
@@ -49,8 +49,8 @@ namespace
 
         std::ostream & os_;
 
-        void pushDirectory(std::vector<senf::console::Token> const & path)
-            { os_ << "pushDirectory( " << senf::stringJoin(path, "/") << " )\n"; }
+        void pushDirectory()
+            { os_ << "pushDirectory()\n"; }
         void popDirectory()
             { os_ << "popDirectory()\n"; }
 
@@ -154,7 +154,10 @@ BOOST_AUTO_UNIT_TEST(commandGrammar)
                          "foo/bar/ {", 
                          grammar.use_parser<Grammar::CommandParser>(), 
                          grammar.use_parser<Grammar::SkipParser>() ) . full );
-        BOOST_CHECK_EQUAL( ss.str(), "pushDirectory( Word('foo')/Word('bar')/None('') )\n" );
+        BOOST_CHECK_EQUAL( ss.str(), 
+                           "beginCommand( Word('foo')/Word('bar')/None('') )\n"
+                           "pushDirectory()\n"
+                           "endCommand()\n" );
     }
 
     {
@@ -330,7 +333,7 @@ BOOST_AUTO_UNIT_TEST(parseExceptions)
         try { parser.parse(c, &setInfo); }                                                        \
         catch (std::exception & ex) { msg = parseErrorMessage(ex.what()); }                       \
         BOOST_CHECK_EQUAL( msg, e )
-
+    
     CheckParseEx( "/foo/bar;\n  ()", "path expected\nat <unknown>:2:3" );
     CheckParseEx( "cd /foo/bar foo/bar", "end of statement expected\nat <unknown>:1:13" );
     CheckParseEx( "/foo/bar foo /", "end of statement expected\nat <unknown>:1:14" );
index a8598fa..340e073 100644 (file)
@@ -102,7 +102,8 @@ protected:
 private:
     ParsedCommandOverload(Function fn);
 
-    virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
+    virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command) 
+        const;
 
     Function function_;
     Formatter formatter_;
@@ -140,7 +141,8 @@ protected:
 private:
     ParsedCommandOverload(Function fn);
 
-    virtual void v_execute(std::ostream & os, ParseCommandInfo const & command) const;
+    virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command) 
+        const;
 
     Function function_;
 };
@@ -249,7 +251,7 @@ ParsedCommandOverload(Function fn)
 
 template <class FunctionTraits, class ReturnValue>
 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, ReturnValue, BOOST_PP_ITERATION() >::
-v_execute(std::ostream & os, ParseCommandInfo const & command)
+v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
     const
 {
     // We NEED to know the number of arguments beforehand so we can assign default values
@@ -280,16 +282,18 @@ v_execute(std::ostream & os, ParseCommandInfo const & command)
 #   undef mpp_l
 #   undef mpp_l_
 
+    ReturnValue rvv (function_(os mpp_TrailingArgs()));
+    rv = rvv;
     if (formatter_)
-        formatter_( function_(os mpp_TrailingArgs()), os );
+        formatter_(rvv, os);
     else
-        ReturnValueTraits<result_type>::format( function_(os mpp_TrailingArgs()), os );
+        ReturnValueTraits<result_type>::format(rvv, os);
     os << "\n";
 }
 
 template <class FunctionTraits>
 prefix_ void senf::console::ParsedCommandOverload<FunctionTraits, void, BOOST_PP_ITERATION() >::
-v_execute(std::ostream & os, ParseCommandInfo const & command)
+v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
     const
 {
     // We NEED to know the number of arguments beforehand so we can assign default values
index 0ad7fc6..42a5097 100644 (file)
@@ -273,6 +273,36 @@ BOOST_AUTO_UNIT_TEST(memberParsedCommand)
     }
 }
 
+namespace {
+
+    senf::console::DirectoryNode::ptr dircb() 
+    {
+        senf::console::DirectoryNode & dir (
+            senf::console::root()["test"].mkdir("dircb"));
+        dir.add("cb1", &cb1);
+        return dir.thisptr();
+    }
+
+}
+
+BOOST_AUTO_UNIT_TEST(directoryReturn)
+{
+    senf::console::Executor executor;
+    senf::console::CommandParser parser;
+    senf::console::ScopedDirectory<> dir;
+    senf::console::root().add("test", dir);
+    dir.add("test", &dircb);
+
+    {
+        std::stringstream ss;
+        SENF_CHECK_NO_THROW(
+            parser.parse("test/test { ls; }",
+                         boost::bind<void>( boost::ref(executor), boost::ref(ss), _1 )) );
+        BOOST_CHECK_EQUAL( ss.str(), "<Directory at '/test/dircb'>\ncb1\n" );
+    }
+    
+}
+
 #ifdef COMPILE_CHECK
 
 COMPILE_FAIL(argParser)
index 7cc2ad0..52ebaf8 100644 (file)
@@ -71,10 +71,13 @@ prefix_ senf::log::FileTarget::RegisterConsole::RegisterConsole()
         .doc("Create new file target.");
 }
 
-prefix_ void senf::log::FileTarget::RegisterConsole::create(std::string const & filename)
+prefix_ boost::shared_ptr<senf::console::DirectoryNode>
+senf::log::FileTarget::RegisterConsole::create(std::string const & filename)
 {
-    detail::TargetRegistry::instance().dynamicTarget(
-        std::auto_ptr<Target>(new FileTarget(filename)));
+    std::auto_ptr<Target> tp (new FileTarget(filename));
+    Target & target (*tp.get());
+    detail::TargetRegistry::instance().dynamicTarget(tp);
+    return target.consoleDir().node().thisptr();
 }
 
 ///////////////////////////////cc.e////////////////////////////////////////
index ccd78fc..11543d7 100644 (file)
@@ -28,6 +28,7 @@
 
 // Custom includes
 #include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
 #include <fstream>
 #include "IOStreamTarget.hh"
 
@@ -35,6 +36,9 @@
 ///////////////////////////////hh.p////////////////////////////////////////
 
 namespace senf {
+
+    namespace console { class DirectoryNode; }
+
 namespace log {
 
     /** \brief Log target writing to a %log file.
@@ -79,7 +83,8 @@ namespace log {
 
         struct RegisterConsole {
             RegisterConsole();
-            static void create(std::string const & filename);
+            static boost::shared_ptr<senf::console::DirectoryNode> create(
+                std::string const & filename);
             static RegisterConsole instance;
         };
     };
index e371443..6f26ddd 100644 (file)
@@ -342,7 +342,6 @@ namespace log {
 
         void flush();                   ///< Clear routing table
 
-    protected:
         senf::console::ScopedDirectory<> & consoleDir(); ///< Get console/config directory
 
     private: