execute(output, command);
}
+prefix_ senf::console::GenericNode &
+senf::console::detail::RestrictedExecutor::getNode(ParseCommandInfo const & command)
+{
+ return executor_.getNode(command);
+}
+
prefix_ bool senf::console::detail::RestrictedExecutor::parsed(GenericNode & node)
const
{
/**< Output will be written to \a output.
Same as execute(). */
+ GenericNode & getNode(ParseCommandInfo const & command);
+
bool complete() const; ///< \c true, if all nodes have been parsed
bool parsed(GenericNode & node) const; ///< \c true. if \a node has been parsed
void reset(); ///< Reset node parse info state
catch (IgnoreCommandException &) {}
}
+prefix_ senf::console::GenericNode &
+senf::console::Executor::getNode(ParseCommandInfo const & command)
+{
+ return traverseNode(command.commandPath());
+}
+
prefix_ void senf::console::Executor::exec(std::ostream & output,
ParseCommandInfo const & command)
{
///< Execute command
/**< Output will be written to \a output.
Same as execute(). */
+ GenericNode & getNode(ParseCommandInfo const & command);
DirectoryNode & cwd() const; ///< Current working directory
std::string cwdPath() const; ///< Return pathname of current directory
bool skipping() const; ///< \c true, if currently skipping a directory group
- overloads_.begin() + 1;
}
+prefix_ senf::console::OverloadedCommandNode::OverloadsRange
+senf::console::OverloadedCommandNode::overloads()
+ const
+{
+ return boost::make_iterator_range(overloads_.begin(), overloads_.end());
+}
+
prefix_ senf::console::OverloadedCommandNode::OverloadedCommandNode()
{}
// Custom includes
#include "Node.hh"
#include <boost/intrusive_ptr.hpp>
+#include <boost/range/iterator_range.hpp>
#include "../../Utils/intrusive_refcount.hh"
//#include "OverloadedCommand.mpp"
std::string type; ///< Argument type (string representation)
std::string defaultValue; ///< Default value (string representation) or empty string
std::string doc; ///< Documentation for this argument
+ bool singleToken; ///< \c true, if argument is parsed from single token
};
/** \brief Base class for command overload of OverloadedCommandNode
class OverloadedCommandNode
: public CommandNode
{
+ typedef std::vector<CommandOverload::ptr> Overloads;
+
public:
///////////////////////////////////////////////////////////////////////////
// Types
typedef OverloadedCommandNode node_type;
typedef OverloadedCommandNode & return_type;
+ typedef boost::iterator_range<Overloads::const_iterator> OverloadsRange;
+
///////////////////////////////////////////////////////////////////////////
///\name Structors and default members
///@{
/**< overloadIndex returns the index of \a overload in the
internal list of overloads. */
+ OverloadsRange overloads() const; ///< Get all overloads
+
ptr thisptr();
cptr thisptr() const;
virtual void v_execute(boost::any & rv, std::ostream & os, ParseCommandInfo const & command)
const;
- typedef std::vector<CommandOverload::ptr> Overloads;
-
Overloads overloads_;
std::string doc_;
std::string shortdoc_;
doc.defaultValue = "(empty)";
}
doc.doc = arg.doc;
+ doc.singleToken = arg.singleToken;
}
prefix_ std::string senf::console::ParsedCommandOverloadBase::v_doc()
///////////////////////////////////////////////////////////////////////////
// senf::console::detail::ArgumentInfoBase
-prefix_ senf::console::detail::ArgumentInfoBase::ArgumentInfoBase(std::string const & type_)
- : type (type_), name (), hasDefault (false)
+prefix_ senf::console::detail::ArgumentInfoBase::ArgumentInfoBase(std::string const & type_,
+ bool singleToken_)
+ : type (type_), name (), hasDefault (false), singleToken (singleToken_)
{}
///////////////////////////////////////////////////////////////////////////
template <class ParameterType>
prefix_ senf::console::detail::ArgumentInfo<ParameterType>::ArgumentInfo()
- : ArgumentInfoBase ( ArgumentTraits<ParameterType>::description() ),
+ : ArgumentInfoBase ( ArgumentTraits<ParameterType>::description(),
+ ArgumentTraits<ParameterType>::singleToken ),
defaultValue ()
{}
std::string defaultDoc;
bool hasDefault;
std::string doc;
+ bool singleToken;
- ArgumentInfoBase(std::string const & type);
+ explicit ArgumentInfoBase(std::string const & type, bool singleToken=false);
virtual ~ArgumentInfoBase();
virtual std::string defaultValueStr() const = 0;
#include <boost/algorithm/string/predicate.hpp>
#include <boost/format.hpp>
#include "../../Utils/range.hh"
+#include "OverloadedCommand.hh"
//#include "ProgramOptions.mpp"
#define prefix_
}
cmd.command(path);
- parser_.parseArguments(value, cmd);
- executor(executor.stream(), cmd);
+ // Here we check, whether the command
+ // - is an overloaded/parsed command
+ // - with a single overload
+ // - taking only a single argument
+ // - which consists of a single token
+ // If all these conditions are met, we pass the parameter value as a single WordToken
+ // otherwise we parse it using the config parser
+ try {
+ GenericNode const & node (executor.getNode(cmd));
+ OverloadedCommandNode const * cmdnode (dynamic_cast<OverloadedCommandNode const *>(&node));
+ if (cmdnode && cmdnode->overloads().size() == 1) {
+ CommandOverload const & overload (**cmdnode->overloads().begin());
+ if (overload.numArguments() == 1) {
+ ArgumentDoc argdoc;
+ argdoc.singleToken = false;
+ overload.argumentDoc(0, argdoc);
+ if (argdoc.singleToken) {
+ cmd.addToken(WordToken(value));
+ goto execute;
+ }
+ }
+ } /* else */ {
+ parser_.parseArguments(value, cmd);
+ }
+ execute:
+ executor(executor.stream(), cmd);
+ }
+ catch (Executor::IgnoreCommandException &)
+ {}
}
prefix_ void
struct SequenceArgumentTraits
{
typedef Sequence type;
+ static bool const singleToken = false;
static void parse(ParseCommandInfo::TokensRange const & tokens, type & out);
static std::string description();
///////////////////////////////ct.p////////////////////////////////////////
template <class Type>
-prefix_ void
+prefix_ bool
senf::console::senf_console_parse_argument(ParseCommandInfo::TokensRange const & tokens,
Type & out)
{
catch (std::bad_cast & ex) {
throw SyntaxErrorException("parameter syntax error");
}
+ return false;
}
///////////////////////////////////////////////////////////////////////////
// Custom includes
#include <iostream>
#include <boost/intrusive_ptr.hpp>
+#include <boost/type_traits/is_same.hpp>
#include "../../Utils/intrusive_refcount.hh"
#include "Parse.hh"
#include "Node.hh"
{
typedef Type type;
+ static bool const singleToken =
+ boost::is_same< typeof(senf_console_parse_argument(
+ *static_cast<ParseCommandInfo::TokensRange const *>(0),
+ *static_cast<Type*>(0))),
+ bool >::value;
+
static void parse(ParseCommandInfo::TokensRange const & tokens, Type & out);
///< Parse token range into value
/**< This function needs to parse \a tokens and write the
\related ArgumentTraits
*/
template <class Type>
- void senf_console_parse_argument(ParseCommandInfo::TokensRange const & tokens, Type & out);
+ bool senf_console_parse_argument(ParseCommandInfo::TokensRange const & tokens, Type & out);
/** \brief Parse token range
struct ArgumentTraits<bool>
{
typedef bool type;
+ static bool const singleToken = true;
static void parse(ParseCommandInfo::TokensRange const & tokens, bool & out);
static std::string description();
struct ArgumentTraits< FlagCollection<Enum> >
{
typedef FlagCollection<Enum> 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);
BOOST_CHECK_EQUAL( ss.str(), "()\n" );
}
+BOOST_AUTO_UNIT_TEST(singleToken)
+{
+ BOOST_CHECK( senf::console::ArgumentTraits<std::string>::singleToken );
+ BOOST_CHECK( senf::console::ArgumentTraits<int>::singleToken );
+ BOOST_CHECK( ! senf::console::ArgumentTraits<
+ senf::console::FlagCollection<TestEnum> >::singleToken );
+}
+
///////////////////////////////cc.e////////////////////////////////////////
#undef prefix_