From: g0dil Date: Wed, 3 Jun 2009 22:20:28 +0000 (+0000) Subject: Utils/Termlib: Add width() member to AbstractTerminal X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=7108fb56be5e093ca088b583712d08f9dafc0790;p=senf.git Utils/Termlib: Add width() member to AbstractTerminal Utils/Console: Add 'lr' command git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1221 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index e3f0921..10d45df 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -35,6 +35,7 @@ #include "../../Utils/Range.hh" #include "../../Utils/String.hh" #include "../../Utils/range.hh" +#include "Server.hh" //#include "Executor.mpp" #define prefix_ @@ -112,6 +113,13 @@ prefix_ void senf::console::Executor::execute(std::ostream & output, ls( output, command.commandPath() ); break; + case ParseCommandInfo::BuiltinLR : + if (skipping()) + break; + // The parser ensures, we have either one or no argument + lr( output, command.commandPath() ); + break; + case ParseCommandInfo::BuiltinPUSHD : // The parser ensures, we have exactly one argument if (skipping()) @@ -218,12 +226,21 @@ prefix_ void senf::console::Executor::cd(ParseCommandInfo::TokensRange dir) prefix_ void senf::console::Executor::ls(std::ostream & output, ParseCommandInfo::TokensRange path) { + unsigned width (80); + try { + width = senf::console::Client::get(output).width(); + } + catch (std::bad_cast &) + {} + if (width<60) + width = 80; + width -= 28+1; Path dir (cwd_); traverseDirectory(path, dir); DirectoryNode & node (*dir.back().lock()); DirectoryNode::child_iterator i (node.children().begin()); DirectoryNode::child_iterator const i_end (node.children().end()); - boost::format fmt ("%s%s %|20t|%.59s\n"); + boost::format fmt ("%s%s %|28t|%s\n"); for (; i != i_end; ++i) output << fmt % i->first @@ -232,7 +249,66 @@ prefix_ void senf::console::Executor::ls(std::ostream & output, : i->second->isLink() ? "@" : "" ) - % i->second->shorthelp(); + % i->second->shorthelp().substr(0,width); +} + +namespace { + + typedef std::map NodesMap; + + void dolr(std::ostream & output, unsigned width, NodesMap & nodes, std::string const & base, + unsigned level, senf::console::DirectoryNode & node) + { + boost::format fmt ("%s%s%s %|40t|%s\n"); + std::string pad (2*level, ' '); + senf::console::DirectoryNode::child_iterator i (node.children().begin()); + senf::console::DirectoryNode::child_iterator const i_end (node.children().end()); + for (; i != i_end; ++i) { + output << fmt + % pad + % i->first + % ( i->second->isDirectory() + ? "/" + : i->second->isLink() + ? "@" + : "" ) + % i->second->shorthelp().substr(0,width); + if (i->second->followLink().isDirectory()) { + senf::console::DirectoryNode & subnode ( + static_cast(i->second->followLink())); + NodesMap::iterator j (nodes.find(&subnode)); + if (j == nodes.end()) { + std::string subbase (base); + if (! subbase.empty()) + subbase += "/"; + subbase += i->first; + nodes.insert(std::make_pair(&subnode, subbase)); + dolr(output, width, nodes, subbase, level+1, subnode); + } else + output << pad << " -> " << j->second << "\n"; + } + } + } + +} + +prefix_ void senf::console::Executor::lr(std::ostream & output, + ParseCommandInfo::TokensRange path) +{ + unsigned width (80); + try { + width = senf::console::Client::get(output).width(); + } + catch (std::bad_cast &) + {} + if (width<60) + width = 80; + width -= 40+1; + Path dir (cwd_); + traverseDirectory(path, dir); + DirectoryNode & node (*dir.back().lock()); + NodesMap nodes; + dolr(output, width, nodes, "", 0, node); } prefix_ void senf::console::Executor::pushd(ParseCommandInfo::TokensRange dir) diff --git a/Utils/Console/Executor.hh b/Utils/Console/Executor.hh index 9341ded..2fc9c06 100644 --- a/Utils/Console/Executor.hh +++ b/Utils/Console/Executor.hh @@ -138,6 +138,7 @@ namespace console { void cd(ParseCommandInfo::TokensRange dir); void ls(std::ostream & output, ParseCommandInfo::TokensRange dir); + void lr(std::ostream & output, ParseCommandInfo::TokensRange dir); void pushd(ParseCommandInfo::TokensRange dir); void popd(); void exit(); diff --git a/Utils/Console/Executor.test.cc b/Utils/Console/Executor.test.cc index f02943b..d4df850 100644 --- a/Utils/Console/Executor.test.cc +++ b/Utils/Console/Executor.test.cc @@ -100,9 +100,9 @@ BOOST_AUTO_UNIT_TEST(executor) executor(os, commands.back()); BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::BuiltinLS ); BOOST_CHECK_EQUAL( os.str(), - "dir1/ \n" - "dir2/ Helptext\n" - "sys/ \n" ); + "dir1/ \n" + "dir2/ Helptext\n" + "sys/ \n" ); } { @@ -110,7 +110,7 @@ BOOST_AUTO_UNIT_TEST(executor) parser.parse("ls dir1", &setCommand); executor(os, commands.back()); BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::BuiltinLS ); - BOOST_CHECK_EQUAL( os.str(), "dir3/ \n" ); + BOOST_CHECK_EQUAL( os.str(), "dir3/ \n" ); } { @@ -123,6 +123,19 @@ BOOST_AUTO_UNIT_TEST(executor) { std::stringstream os; + parser.parse("lr", &setCommand); + executor(os, commands.back()); + BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::BuiltinLR ); + BOOST_CHECK_EQUAL( os.str().substr(0,213), + "dir1/ \n" + " dir3/ \n" + "dir2/ Helptext\n" + " test \n" + "sys/ \n" ); + } + + { + std::stringstream os; parser.parse("dir1/dir3 { }", &setCommand); executor(os, commands.rbegin()[1]); BOOST_CHECK_EQUAL( commands.rbegin()[1].builtin(), senf::console::ParseCommandInfo::BuiltinPUSHD ); @@ -216,7 +229,7 @@ BOOST_AUTO_UNIT_TEST(executorPolicy) parser.parse("ls dir1", &setCommand); executor(os, commands.back()); BOOST_CHECK_EQUAL( commands.back().builtin(), senf::console::ParseCommandInfo::BuiltinLS ); - BOOST_CHECK_EQUAL( os.str(), "dir3/ \n" ); + BOOST_CHECK_EQUAL( os.str(), "dir3/ \n" ); } { diff --git a/Utils/Console/LineEditor.cc b/Utils/Console/LineEditor.cc index 31df1f7..df9d065 100644 --- a/Utils/Console/LineEditor.cc +++ b/Utils/Console/LineEditor.cc @@ -65,6 +65,12 @@ prefix_ void senf::console::detail::LineEditorSwitcher::v_write(std::string cons reader_->write(data); } +prefix_ unsigned senf::console::detail::LineEditorSwitcher::v_width() + const +{ + return reader_->width(); +} + /////////////////////////////////////////////////////////////////////////// // senf::console::detail::LineEditorClientReader @@ -109,6 +115,12 @@ prefix_ void senf::console::detail::LineEditorClientReader::v_write(std::string BaseTelnetProtocol::write(data); } +prefix_ unsigned senf::console::detail::LineEditorClientReader::v_width() + const +{ + return editor_.width(); +} + prefix_ void senf::console::detail::LineEditorClientReader::executeLine(std::string const & text) { diff --git a/Utils/Console/LineEditor.hh b/Utils/Console/LineEditor.hh index 2a94a7e..6fe3ea3 100644 --- a/Utils/Console/LineEditor.hh +++ b/Utils/Console/LineEditor.hh @@ -60,6 +60,7 @@ namespace detail { virtual void v_disablePrompt(); virtual void v_enablePrompt(); virtual void v_write(std::string const & data); + virtual unsigned v_width() const; boost::scoped_ptr reader_; }; @@ -83,6 +84,7 @@ namespace detail { virtual void v_disablePrompt(); virtual void v_enablePrompt(); virtual void v_write(std::string const & data); + virtual unsigned v_width() const; // Editor callbacks void executeLine(std::string const & text); diff --git a/Utils/Console/Parse.cc b/Utils/Console/Parse.cc index 28fa61a..5281be5 100644 --- a/Utils/Console/Parse.cc +++ b/Utils/Console/Parse.cc @@ -76,6 +76,11 @@ namespace detail { info_->builtin(ParseCommandInfo::BuiltinLS); setBuiltinPathArg(path); } + void builtin_lr(std::vector & path) + { info_->clear(); + info_->builtin(ParseCommandInfo::BuiltinLR); + 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) @@ -169,7 +174,7 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & stream, } } else { - char const * builtins[] = { 0, "cd", "ls", "pushd", "popd", "exit", "help" }; + char const * builtins[] = { 0, "cd", "ls", "lr", "pushd", "popd", "exit", "help" }; stream << "builtin-" << builtins[info.builtin()]; } diff --git a/Utils/Console/Parse.hh b/Utils/Console/Parse.hh index 4303fc2..e7712e0 100644 --- a/Utils/Console/Parse.hh +++ b/Utils/Console/Parse.hh @@ -366,6 +366,7 @@ namespace console { enum BuiltinCommand { NoBuiltin, BuiltinCD, BuiltinLS, + BuiltinLR, BuiltinPUSHD, BuiltinPOPD, BuiltinEXIT, diff --git a/Utils/Console/Parse.ih b/Utils/Console/Parse.ih index d99e168..00745cc 100644 --- a/Utils/Console/Parse.ih +++ b/Utils/Console/Parse.ih @@ -220,6 +220,9 @@ namespace detail { | self.keyword_p("ls") >> ! path >> eps_p [ bind(&PD::builtin_ls)(d_, path_) ] + | self.keyword_p("lr") + >> ! path + >> eps_p [ bind(&PD::builtin_lr)(d_, path_) ] | self.keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ] | self.keyword_p("help") >> ! path diff --git a/Utils/Console/Parse.test.cc b/Utils/Console/Parse.test.cc index 5d625e3..bbc2c68 100644 --- a/Utils/Console/Parse.test.cc +++ b/Utils/Console/Parse.test.cc @@ -66,6 +66,8 @@ namespace { os_ << "builtin_cd( " << senf::stringJoin(path, "/") << " )\n"; } void builtin_ls(std::vector const & path) { os_ << "builtin_ls( " << senf::stringJoin(path, "/") << " )\n"; } + void builtin_lr(std::vector const & path) + { os_ << "builtin_lr( " << senf::stringJoin(path, "/") << " )\n"; } void builtin_exit() { os_ << "builtin_exit()\n"; } void builtin_help(std::vector const & path) @@ -133,6 +135,15 @@ BOOST_AUTO_UNIT_TEST(commandGrammar) { ss.str(""); BOOST_CHECK( boost::spirit::parse( + "lr /foo/bar;", + grammar.use_parser(), + grammar.use_parser() ) . full ); + BOOST_CHECK_EQUAL( ss.str(), "builtin_lr( None('')/Word('foo')/Word('bar') )\n" ); + } + + { + ss.str(""); + BOOST_CHECK( boost::spirit::parse( "cd /foo/bar;", grammar.use_parser(), grammar.use_parser() ) . full ); diff --git a/Utils/Console/ParsedCommand.test.cc b/Utils/Console/ParsedCommand.test.cc index 5953658..b9c095a 100644 --- a/Utils/Console/ParsedCommand.test.cc +++ b/Utils/Console/ParsedCommand.test.cc @@ -303,7 +303,9 @@ BOOST_AUTO_UNIT_TEST(directoryReturn) SENF_CHECK_NO_THROW( parser.parse("test/test { ls; }", boost::bind( boost::ref(executor), boost::ref(ss), _1 )) ); - BOOST_CHECK_EQUAL( ss.str(), "\ncb1 \n" ); + BOOST_CHECK_EQUAL( ss.str(), + "\n" + "cb1 \n" ); } } diff --git a/Utils/Console/Server.cc b/Utils/Console/Server.cc index 41475c2..afcf922 100644 --- a/Utils/Console/Server.cc +++ b/Utils/Console/Server.cc @@ -180,6 +180,12 @@ prefix_ void senf::console::detail::DumbClientReader::v_write(std::string const handle().write(data); } +prefix_ unsigned senf::console::detail::DumbClientReader::v_width() + const +{ + return 80; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::detail::NoninteractiveClientReader @@ -202,6 +208,12 @@ prefix_ void senf::console::detail::NoninteractiveClientReader::v_write(std::str handle().write(data); } +prefix_ unsigned senf::console::detail::NoninteractiveClientReader::v_width() + const +{ + return 80; +} + prefix_ void senf::console::detail::NoninteractiveClientReader::newData(int event) { diff --git a/Utils/Console/Server.cci b/Utils/Console/Server.cci index 62e6fad..488fb3a 100644 --- a/Utils/Console/Server.cci +++ b/Utils/Console/Server.cci @@ -163,6 +163,12 @@ prefix_ std::string const & senf::console::Client::backtrace() return backtrace_; } +prefix_ unsigned senf::console::Client::width() + const +{ + return reader_->width(); +} + prefix_ senf::console::Client & senf::console::Client::get(std::ostream & os) { return dynamic_cast(os)->client(); @@ -236,6 +242,12 @@ prefix_ void senf::console::detail::ClientReader::write(std::string const & data v_write(data); } +prefix_ unsigned senf::console::detail::ClientReader::width() + const +{ + return v_width(); +} + prefix_ senf::console::detail::ClientReader::ClientReader(Client & client) : client_ (client) {} diff --git a/Utils/Console/Server.hh b/Utils/Console/Server.hh index 7d0a10d..4c5e66f 100644 --- a/Utils/Console/Server.hh +++ b/Utils/Console/Server.hh @@ -177,6 +177,7 @@ namespace console { Server::Mode mode() const; void write(std::string const & data) const; std::string const & backtrace() const; + unsigned width() const; static Client & get(std::ostream & os); diff --git a/Utils/Console/Server.ih b/Utils/Console/Server.ih index d97c1c9..aa77d74 100644 --- a/Utils/Console/Server.ih +++ b/Utils/Console/Server.ih @@ -114,6 +114,7 @@ namespace detail { void disablePrompt(); void enablePrompt(); void write(std::string const & data); + unsigned width() const; protected: ClientReader(Client & client); @@ -122,6 +123,7 @@ namespace detail { virtual void v_disablePrompt() = 0; virtual void v_enablePrompt() = 0; virtual void v_write(std::string const & data) = 0; + virtual unsigned v_width() const = 0; Client & client_; }; @@ -141,6 +143,7 @@ namespace detail { virtual void v_disablePrompt(); virtual void v_enablePrompt(); virtual void v_write(std::string const & data); + virtual unsigned v_width() const; void clientData(senf::ReadHelper::ptr helper); void showPrompt(); @@ -165,6 +168,7 @@ namespace detail { virtual void v_disablePrompt(); virtual void v_enablePrompt(); virtual void v_write(std::string const & data); + virtual unsigned v_width() const; void newData(int event); diff --git a/Utils/Termlib/AbstractTerminal.hh b/Utils/Termlib/AbstractTerminal.hh index b3f396d..95408f6 100644 --- a/Utils/Termlib/AbstractTerminal.hh +++ b/Utils/Termlib/AbstractTerminal.hh @@ -69,8 +69,8 @@ namespace term { virtual void setCallbacks(Callbacks & cb) = 0; ///< Register terminal callbacks virtual std::string terminalType() = 0; ///< Get the terminal type - virtual unsigned width() = 0; ///< Get current terminal window width - virtual unsigned height() = 0; ///< Get current terminal window height + virtual unsigned width() const = 0; ///< Get current terminal window width + virtual unsigned height() const = 0; ///< Get current terminal window height virtual void write(char ch) = 0; ///< Write character to terminal }; diff --git a/Utils/Termlib/Editor.cc b/Utils/Termlib/Editor.cc index ce6a3fb..0122904 100644 --- a/Utils/Termlib/Editor.cc +++ b/Utils/Termlib/Editor.cc @@ -253,11 +253,13 @@ prefix_ void senf::term::BaseEditor::processKeys() } prefix_ unsigned senf::term::BaseEditor::width() + const { return terminal_->width(); } prefix_ unsigned senf::term::BaseEditor::height() + const { return terminal_->height(); } diff --git a/Utils/Termlib/Editor.hh b/Utils/Termlib/Editor.hh index bacfeff..952291f 100644 --- a/Utils/Termlib/Editor.hh +++ b/Utils/Termlib/Editor.hh @@ -81,8 +81,8 @@ namespace term { unsigned currentColumn() const; ///< Return number of current column unsigned currentLine() const; ///< Return number of current relative line - unsigned width(); ///< Return current screen width - unsigned height(); ///< Return current screen height + unsigned width() const; ///< Return current screen width + unsigned height() const; ///< Return current screen height protected: virtual bool cb_init(); ///< Called when terminal is initialized diff --git a/Utils/Termlib/TelnetTerminal.cc b/Utils/Termlib/TelnetTerminal.cc index 3445d5c..758a360 100644 --- a/Utils/Termlib/TelnetTerminal.cc +++ b/Utils/Termlib/TelnetTerminal.cc @@ -51,11 +51,13 @@ prefix_ std::string senf::term::TelnetTerminal::terminalType() } prefix_ unsigned senf::term::TelnetTerminal::width() + const { return telnethandler::NAWS::width(); } prefix_ unsigned senf::term::TelnetTerminal::height() + const { return telnethandler::NAWS::height(); } diff --git a/Utils/Termlib/TelnetTerminal.hh b/Utils/Termlib/TelnetTerminal.hh index 650ce1f..09aea80 100644 --- a/Utils/Termlib/TelnetTerminal.hh +++ b/Utils/Termlib/TelnetTerminal.hh @@ -62,8 +62,8 @@ namespace term { ///\{ virtual void setCallbacks(AbstractTerminal::Callbacks & cb); virtual std::string terminalType(); - virtual unsigned width(); - virtual unsigned height(); + virtual unsigned width() const; + virtual unsigned height() const; virtual void write(char ch); ///\}