try {
switch(command.builtin()) {
- case ParseCommandInfo::NoBuiltin :
- traverseCommand(command.commandPath())(output, command);
+ case ParseCommandInfo::NoBuiltin : {
+ GenericNode & node ( traverseCommand(command.commandPath()) );
+ DirectoryNode * dir ( dynamic_cast<DirectoryNode*>(&node) );
+ if ( dir ) {
+ oldCwd_ = cwd_;
+ cwd_ = dir->thisptr();
+ } else {
+ dynamic_cast<CommandNode &>(node)(output, command);
+ }
break;
+ }
case ParseCommandInfo::BuiltinCD :
if ( command.arguments() ) {
}
}
-prefix_ senf::console::DirectoryNode &
-senf::console::Executor::traverseDirectory(ParseCommandInfo::argument_value_type const & path)
+prefix_ senf::console::GenericNode &
+senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path)
{
try {
- return dynamic_cast<DirectoryNode&>( traverseNode(path) );
+ return cwd().traverse(path);
}
catch (std::bad_cast &) {
- throw InvalidDirectoryException();
+ throw InvalidPathException();
}
- catch (InvalidPathException &) {
- throw InvalidDirectoryException();
+ catch (UnknownNodeNameException &) {
+ throw InvalidPathException();
}
}
-prefix_ senf::console::CommandNode &
-senf::console::Executor::traverseCommand(ParseCommandInfo::CommandPathRange const & path)
+prefix_ senf::console::DirectoryNode &
+senf::console::Executor::traverseDirectory(ParseCommandInfo::argument_value_type const & path)
{
try {
- return dynamic_cast<CommandNode &>( cwd().traverse(path) );
+ return dynamic_cast<DirectoryNode&>( traverseNode(path) );
}
catch (std::bad_cast &) {
- throw InvalidCommandException();
+ throw InvalidDirectoryException();
+ }
+ catch (InvalidPathException &) {
+ throw InvalidDirectoryException();
}
- catch (UnknownNodeNameException &) {
- throw InvalidCommandException();
- }
}
-
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_
//#include "Executor.mpp"
private:
GenericNode & traverseNode(ParseCommandInfo::argument_value_type const & path);
+ GenericNode & traverseCommand(ParseCommandInfo::CommandPathRange const & path);
DirectoryNode & traverseDirectory(ParseCommandInfo::argument_value_type const & path);
- CommandNode & traverseCommand(ParseCommandInfo::CommandPathRange const & path);
struct InvalidPathException {};
struct InvalidDirectoryException {};
// senf::console::SyntaxErrorException
prefix_ senf::console::SyntaxErrorException::SyntaxErrorException(std::string const & msg)
- : Exception(msg)
+ : message_(msg)
{}
+prefix_ senf::console::SyntaxErrorException::~SyntaxErrorException()
+ throw()
+{}
+
+prefix_ std::string const & senf::console::SyntaxErrorException::message()
+ const
+{
+ return message_;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::console::CommandNode
All errors while parsing the arguments of a command must be signaled by throwing an instance
of SyntaxErrorException. This is important, so command overloading works.
*/
- struct SyntaxErrorException : public senf::Exception
+ struct SyntaxErrorException : public std::exception
{
explicit SyntaxErrorException(std::string const & msg = "");
+ virtual ~SyntaxErrorException() throw();
virtual char const * what() const throw();
+ std::string const & message() const;
+
+ private:
+ std::string message_;
};
/** \brief Config/console tree command node
///////////////////////////////////////////////////////////////////////////
// senf::console::detail::ReadlineClientReader
-extern int readline_echoing_p;
-extern int _rl_bell_preference;
+extern "C" {
+ extern int readline_echoing_p;
+ extern int _rl_bell_preference;
+
+ void _rl_erase_entire_line();
+}
+
namespace {
}
prefix_ void senf::console::detail::ReadlineClientReader::v_disablePrompt()
-{}
+{
+ _rl_erase_entire_line();
+}
prefix_ void senf::console::detail::ReadlineClientReader::v_enablePrompt()
-{}
+{
+ rl_forced_update_display();
+}
prefix_ void senf::console::detail::ReadlineClientReader::v_translate(std::string & data)
{
char promptBuffer_[1024];
SchedulerBinding schedBinding_;
bool terminate_;
+
+ char * savedLineBuffer_;
+ int savedPoint_;
+ int savedEnd_;
+ int savedMark_;
};
/** \brief Internal: Safe GNU readline based ClientReader implementation
: client_ (client)
{}
+prefix_ senf::console::Client & senf::console::detail::NonblockingSocketSink::client()
+ const
+{
+ return client_;
+}
+
///////////////////////////////////////////////////////////////////////////
// senf::console::Server
return name_ + ":" + executor_.cwd().path() + "$ ";
}
+prefix_ senf::console::Client & senf::console::Client::get(std::ostream & os)
+{
+ return dynamic_cast<detail::NonblockingSocketOStream&>(os)->client();
+}
+
prefix_ senf::console::Client::ClientHandle senf::console::Client::handle()
const
{
std::ostream & stream();
std::string promptString() const;
+ static Client & get(std::ostream & os);
+
protected:
private:
NonblockingSocketSink(Client & client);
std::streamsize write(const char * s, std::streamsize n);
+
+ Client & client() const;
private:
Client & client_;
throw senf::console::Executor::ExitException();
}
+void enableLogging(std::ostream & os)
+{
+ senf::console::Client::get(os).route<senf::SenfLog,senf::log::NOTICE>();
+}
+
int main(int, char **)
{
::signal(SIGPIPE, SIG_IGN);
senf::console::root()
.doc("This is the console test application");
senf::console::root()
+ .mkdir("console")
+ .doc("Console settings");
+ senf::console::root()
.mkdir("test")
- .doc("Network related settings");
+ .doc("Test functions");
senf::console::root()
.mkdir("server");
+
+ senf::console::root()["console"]
+ .add("showlog", &enableLogging)
+ .doc("Enable display of log messages on the current console");
senf::console::root()["server"]
.add("shutdown", &shutdownServer)
.doc("Terminate server application");
.doc("Example of a function utilizing manual argument parsing");
TestObject test;
- senf::console::root()
+ senf::console::root()["test"]
.add("testob", test.dir)
.doc("Example of an instance directory");