From: g0dil Date: Tue, 16 Jun 2009 11:29:12 +0000 (+0000) Subject: Utils/Console: Move link target in lr output one line up X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=1e4e4f0d4cdba4ba8b3f7f73849b7e0dc52e2d46;p=senf.git Utils/Console: Move link target in lr output one line up Utils/Console: Add documentation to Client members Utils/Console: Add support for std::pair parsing/formatting Utils/Console: Some more documentation git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1233 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index 141565a..692af69 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include "../../Utils/senfassert.hh" #include "../../Utils/Range.hh" #include "../../Utils/String.hh" @@ -232,21 +233,15 @@ 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; +# define HELP_COLUMN 28 + + unsigned width (senf::console::Client::getWidth(output, 80u, 60u)-(HELP_COLUMN+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 %|28t|%s\n"); + boost::format fmt ("%s%s %|" BOOST_PP_STRINGIZE(HELP_COLUMN) "t|%s\n"); for (; i != i_end; ++i) output << fmt % i->first @@ -256,8 +251,12 @@ prefix_ void senf::console::Executor::ls(std::ostream & output, ? "@" : "" ) % i->second->shorthelp().substr(0,width); + +# undef HELP_COLUMN } +# define HELP_COLUMN 40 + namespace { typedef std::map NodesMap; @@ -265,25 +264,20 @@ namespace { 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"); + boost::format fmt ("%s%s%s %|" BOOST_PP_STRINGIZE(HELP_COLUMN) "t|%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()) { + output << fmt + % pad % i->first + % ( i->second->isDirectory() ? "/" : i->second->isLink() ? "@" : "" ) + % i->second->shorthelp().substr(0,width); std::string subbase (base); if (! subbase.empty()) subbase += "/"; @@ -291,7 +285,14 @@ namespace { nodes.insert(std::make_pair(&subnode, subbase)); dolr(output, width, nodes, subbase, level+1, subnode); } else - output << pad << " -> " << j->second << "\n"; + output << pad << i->first + << ( i->second->isDirectory() ? "/" : i->second->isLink() ? "@" : "" ) + << " -> " << j->second << "\n"; + } else { + output << fmt + % pad % i->first + % ( i->second->isDirectory() ? "/" : i->second->isLink() ? "@" : "" ) + % i->second->shorthelp().substr(0,width); } } } @@ -301,22 +302,16 @@ namespace { 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); + dolr(output, senf::console::Client::getWidth(output, 80u, 60u)-(HELP_COLUMN+1), + nodes, "", 0, node); } +#undef HELP_COLUMN + prefix_ void senf::console::Executor::pushd(ParseCommandInfo::TokensRange dir) { Path newDir (cwd_); diff --git a/Utils/Console/Node.hh b/Utils/Console/Node.hh index 4cd15d1..b8702be 100644 --- a/Utils/Console/Node.hh +++ b/Utils/Console/Node.hh @@ -223,7 +223,17 @@ namespace console { class DirectoryNode; class CommandNode; + /** \brief Get console root node */ DirectoryNode & root(); + + /** \brief Dump console directory structure + + Recursively dumps the console directory structure starting at \a dir. By default, dumps the + complete tree beginning at the root node. + + In contrast to the console 'lr' command, links are dumped by showing the \e absolute path + to the target node. + */ void dump(std::ostream & os, DirectoryNode & dir=root()); /** \brief Config/console node tree base-class diff --git a/Utils/Console/STLSupport.ct b/Utils/Console/STLSupport.ct index ca7f599..18af3dc 100644 --- a/Utils/Console/STLSupport.ct +++ b/Utils/Console/STLSupport.ct @@ -26,6 +26,7 @@ //#include "VectorSupport.ih" // Custom includes +#include #define prefix_ ///////////////////////////////ct.p//////////////////////////////////////// @@ -82,6 +83,42 @@ prefix_ void senf::console::SequenceReturnValueTraits::format(type con os << ")"; } +template +prefix_ void senf::console::ArgumentTraits< std::pair >:: +parse(ParseCommandInfo::TokensRange const & tokens, type & out) +{ + CheckedArgumentIteratorWrapper arg (tokens); + senf::console::parse( *(arg++), out.first ); + senf::console::parse( *(arg++), out.second ); +} + +template +prefix_ std::string senf::console::ArgumentTraits< std::pair >::description() +{ + return (boost::format("pair<%s,%s>") + % ArgumentTraits::description() + % ArgumentTraits::description()).str(); +} + +template +prefix_ std::string senf::console::ArgumentTraits< std::pair >::str(type const & value) +{ + std::stringstream ss; + senf::console::format(value, ss); + return ss.str(); +} + +template +prefix_ void senf::console::ReturnValueTraits< std::pair >::format(type const & value, + std::ostream & os) +{ + os << "("; + senf::console::format(value.first, os); + os << " "; + senf::console::format(value.second, os); + os << ")"; +} + #endif ///////////////////////////////ct.e//////////////////////////////////////// diff --git a/Utils/Console/STLSupport.hh b/Utils/Console/STLSupport.hh index 69a6e14..d459488 100644 --- a/Utils/Console/STLSupport.hh +++ b/Utils/Console/STLSupport.hh @@ -78,6 +78,25 @@ namespace console { : public SequenceReturnValueTraits< std::list > {}; + template + struct ArgumentTraits< std::pair > + { + typedef std::pair type; + static bool const singleToken = false; + + static void parse(ParseCommandInfo::TokensRange const & tokens, type & out); + static std::string description(); + static std::string str(type const & value); + }; + + template + struct ReturnValueTraits< std::pair > + { + typedef std::pair type; + + static void format(type const & value, std::ostream & os); + }; + #endif }} diff --git a/Utils/Console/Server.cc b/Utils/Console/Server.cc index 58a3dcc..913a271 100644 --- a/Utils/Console/Server.cc +++ b/Utils/Console/Server.cc @@ -336,6 +336,17 @@ prefix_ void senf::console::Client::v_write(senf::log::time_type timestamp, reader_->enablePrompt(); } +prefix_ unsigned senf::console::Client::getWidth(std::ostream & os, unsigned defaultWidth, + unsigned minWidth) +{ + unsigned rv (defaultWidth); + try { + rv = get(os).width(); + } + catch (std::bad_cast &) {} + return rv < minWidth ? defaultWidth : rv; +} + /////////////////////////////////////////////////////////////////////////// // senf::console::Client::SysBacktrace diff --git a/Utils/Console/Server.hh b/Utils/Console/Server.hh index 4c5e66f..9e9471a 100644 --- a/Utils/Console/Server.hh +++ b/Utils/Console/Server.hh @@ -168,18 +168,51 @@ namespace console { void stop(); ///< Stop the client /**< This will close the client socket. */ - std::string const & name() const; - ClientHandle handle() const; - std::ostream & stream(); - std::string promptString() const; - DirectoryNode & root() const; - DirectoryNode & cwd() const; - Server::Mode mode() const; + std::string const & name() const; ///< Get name of the client instance + /**< This name is used in the prompt string and is set by + the server. */ + ClientHandle handle() const; ///< Get the client's network socket handle + std::ostream & stream(); ///< Get client's output stream + /**< Data sent to this stream is sent out over the network + via the client's socket handle. Write operation is + non-blocking and data may be dropped. Data is written + using Client::write(). */ + std::string promptString() const; ///< Get the prompt string + DirectoryNode & root() const; ///< Get configured root node + DirectoryNode & cwd() const; ///< Get current directory + /**< This is the directory, the console currently is changed + into by the user of the console. */ + Server::Mode mode() const; ///< Get operation mode + /**< \see Server::mode() */ void write(std::string const & data) const; - std::string const & backtrace() const; - unsigned width() const; + ///< Write data to network socket + /**< The data is automatically filtered depending on the + type of connection (e.g. on a telnet connection, + specific bytes are quoted). */ + std::string const & backtrace() const; ///< Get backtrace of last console error, if any + unsigned width() const; ///< Get console width + /**< If possible, this will be the width of the connected + terminal, otherwise a default value (normally 80) is + returned. */ static Client & get(std::ostream & os); + ///< Access client instance + /**< Allows to access the client instance from console + command implementations. The first argument to a + console command is a stream object. \e If this stream + object belongs to a network console client, this call + will return the associated Client instance reference. + \throws std::bad_cast if \a os is not associated with a + Client instance. */ + static unsigned getWidth(std::ostream & os, unsigned defaultWidth = 0, + unsigned minWidth = 0); + ///< Get width of client console if possible + /**< If possible, the width of the client console attached + to the stream \a os is returned. If this is not + possible, the \a defaultValue will be used. + + If the width obtained this way is smaller than \a + minWidth, \a defaultValue will be returned instead. */ protected: