Scheduler: Implement Timer helper
[senf.git] / Console / Parse.cci
index 1a72abf..322fc44 100644 (file)
 ///////////////////////////////cci.p///////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////
-// senf::console::ArgumentToken
+// senf::console::Token
 
-prefix_ std::string const & senf::console::ArgumentToken::value()
+prefix_ std::string const & senf::console::Token::value()
     const
 {
     return token_;
 }
 
-prefix_ senf::console::ArgumentToken::ArgumentToken(std::string token)
-    : token_ (token)
+prefix_ senf::console::Token::TokenType senf::console::Token::type()
+    const
+{
+    return type_;
+}
+
+prefix_ bool senf::console::Token::is(unsigned tokens)
+    const
+{
+    return tokens & type_;
+}
+
+prefix_ bool senf::console::Token::operator==(Token const & other)
+    const
+{
+    return type() == other.type() && value() == other.value();
+}
+
+prefix_ bool senf::console::Token::operator!=(Token const & other)
+    const
+{
+    return ! operator==(other);
+}
+
+prefix_ senf::console::Token::Token()
+    : type_(None), token_()
+{}
+
+prefix_ senf::console::Token::Token(TokenType type, std::string token)
+    : type_(type), token_ (token)
 {}
 
+prefix_ senf::console::Token senf::console::NoneToken()
+{
+    return Token(Token::None,"");
+}
+
+prefix_ senf::console::Token senf::console::PathSeparatorToken()
+{
+    return Token(Token::PathSeparator,"/");
+}
+
+prefix_ senf::console::Token senf::console::ArgumentGroupOpenToken()
+{
+    return Token(Token::ArgumentGroupOpen,"(");
+}
+
+prefix_ senf::console::Token senf::console::ArgumentGroupCloseToken()
+{
+    return Token(Token::ArgumentGroupClose,")");
+}
+
+prefix_ senf::console::Token senf::console::DirectoryGroupOpenToken()
+{
+    return Token(Token::DirectoryGroupOpen,"{");
+}
+
+prefix_ senf::console::Token senf::console::DirectoryGroupCloseToken()
+{
+    return Token(Token::DirectoryGroupClose,"}");
+}
+
+prefix_ senf::console::Token senf::console::CommandTerminatorToken()
+{
+    return Token(Token::CommandTerminator,";");
+}
+
+prefix_ senf::console::Token senf::console::OtherPunctuationToken(std::string const & value)
+{
+    return Token(Token::OtherPunctuation, value);
+}
+
+prefix_ senf::console::Token senf::console::BasicStringToken(std::string const & value)
+{
+    return Token(Token::BasicString, value);
+}
+
+prefix_ senf::console::Token senf::console::HexStringToken(std::string const & value)
+{
+    return Token(Token::HexString, value);
+}
+
+prefix_ senf::console::Token senf::console::WordToken(std::string const & value)
+{
+    return Token(Token::Word, value);
+}
+
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::ParseCommandInfo
 
-prefix_ std::string const & senf::console::ParseCommandInfo::commandPath()
+prefix_ senf::console::ParseCommandInfo::ParseCommandInfo()
+    : builtin_ (NoBuiltin)
+{}
+
+prefix_ senf::console::ParseCommandInfo::BuiltinCommand
+senf::console::ParseCommandInfo::builtin()
+    const
+{
+    return builtin_;
+}
+
+prefix_ senf::console::ParseCommandInfo::TokensRange
+senf::console::ParseCommandInfo::commandPath()
     const
 {
-    return commandPath_;
+    return boost::make_iterator_range(commandPath_.begin(), commandPath_.end());
 }
 
-prefix_ senf::console::ParseCommandInfo::size_type senf::console::ParseCommandInfo::arguments()
+prefix_ senf::console::ParseCommandInfo::ArgumentsRange
+senf::console::ParseCommandInfo::arguments()
     const
 {
-    return arguments_.size();
+    return boost::make_iterator_range( ArgumentIterator(tokens_.begin()),
+                                       ArgumentIterator(tokens_.end()) );
+}
+
+prefix_ senf::console::ParseCommandInfo::TokensRange senf::console::ParseCommandInfo::tokens()
+    const
+{
+    return boost::make_iterator_range(tokens_.begin(), tokens_.end());
+}
+
+prefix_ void senf::console::ParseCommandInfo::clear()
+{
+    builtin_ = NoBuiltin;
+    commandPath_.clear();
+    tokens_.clear();
+}
+
+prefix_ bool senf::console::ParseCommandInfo::empty()
+{
+    return builtin_ == NoBuiltin && commandPath_.empty();
+}
+
+prefix_ void senf::console::ParseCommandInfo::builtin(BuiltinCommand builtin)
+{
+    builtin_ = builtin;
+    commandPath_.clear();
+}
+
+prefix_ void
+senf::console::ParseCommandInfo::command(std::vector<Token> & commandPath)
+{
+    commandPath_.clear();
+    commandPath_.swap(commandPath);
+    builtin_ = NoBuiltin;
+}
+
+prefix_ void senf::console::ParseCommandInfo::addToken(Token const & token)
+{
+    tokens_.push_back(token);
 }
 
-prefix_ senf::console::ParseCommandInfo::argument_iterator
-senf::console::ParseCommandInfo::begin_arguments()
+///////////////////////////////////////////////////////////////////////////
+// senf::console::ParseCommandInfo::ArgumentIterator
+
+prefix_ senf::console::ParseCommandInfo::ArgumentIterator::ArgumentIterator()
+{}
+
+prefix_ senf::console::ParseCommandInfo::ArgumentIterator::
+ArgumentIterator(ParseCommandInfo::TokensRange::iterator i)
+    : b_(i), e_(i)
+{}
+
+prefix_ senf::console::ParseCommandInfo::ArgumentIterator::reference
+senf::console::ParseCommandInfo::ArgumentIterator::dereference()
     const
 {
-    return arguments_.begin();
+    if (b_ == e_) setRange();
+    return b_->is(Token::ArgumentGroupOpen) 
+        ? boost::make_iterator_range(boost::next(b_), boost::prior(e_))
+        : boost::make_iterator_range(b_, e_);
 }
 
-prefix_ senf::console::ParseCommandInfo::argument_iterator
-senf::console::ParseCommandInfo::end_arguments()
+prefix_ bool
+senf::console::ParseCommandInfo::ArgumentIterator::equal(ArgumentIterator const & other)
     const
 {
-    return arguments_.end();
+    return b_ == other.b_;
 }
 
-prefix_ senf::console::ParseCommandInfo::size_type senf::console::ParseCommandInfo::tokens()
+prefix_ void senf::console::ParseCommandInfo::ArgumentIterator::increment()
+{
+    if (b_ == e_) setRange();
+    b_ = e_;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// senf::console::SyntaxErrorException
+
+prefix_ senf::console::SyntaxErrorException::SyntaxErrorException(std::string const & msg)
+    : message_(msg)
+{}
+
+prefix_ senf::console::SyntaxErrorException::~SyntaxErrorException()
+    throw()
+{}
+
+prefix_ std::string const & senf::console::SyntaxErrorException::message()
     const
 {
-    return tokens_.size();
+    return message_;
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+prefix_ senf::console::CheckedArgumentIteratorWrapper::
+CheckedArgumentIteratorWrapper(ParseCommandInfo::ArgumentsRange const & range,
+                               std::string const & msg)
+    : i_ (range.begin()), e_ (range.end()), msg_ (msg)
+{}
+
+prefix_ senf::console::CheckedArgumentIteratorWrapper::
+CheckedArgumentIteratorWrapper(ParseCommandInfo::TokensRange const & range,
+                               std::string const & msg)
+    : i_ (range.begin()), e_ (range.end()), msg_ (msg)
+{}
+
+prefix_ senf::console::CheckedArgumentIteratorWrapper::~CheckedArgumentIteratorWrapper()
+{
+    if (i_ != e_ && ! std::uncaught_exception())
+        throw SyntaxErrorException(msg_);
+}
+
+prefix_ senf::console::CheckedArgumentIteratorWrapper::operator ParseCommandInfo::ArgumentIterator()
+{
+    return i_;
 }
 
-prefix_ senf::console::ParseCommandInfo::token_iterator
-senf::console::ParseCommandInfo::begin_tokens()
+prefix_ bool senf::console::CheckedArgumentIteratorWrapper::boolean_test()
     const
 {
-    return tokens_.begin();
+    return i_ != e_;
 }
 
-prefix_ senf::console::ParseCommandInfo::token_iterator
-senf::console::ParseCommandInfo::end_tokens()
+prefix_ bool senf::console::CheckedArgumentIteratorWrapper::done()
     const
 {
-    return tokens_.end();
+    return i_ == e_;
 }
 
-////////////////////////////////////////
-// private members
+prefix_ void senf::console::CheckedArgumentIteratorWrapper::clear()
+{
+    i_ = e_;
+}
 
-prefix_ void senf::console::ParseCommandInfo::init()
+prefix_ senf::console::CheckedArgumentIteratorWrapper::reference
+senf::console::CheckedArgumentIteratorWrapper::dereference()
+    const
 {
-    commandPath_ = "";
-    tokens_.clear();
-    arguments_.clear();
-    tempArguments_.clear();
+    if (i_ == e_)
+        throw SyntaxErrorException(msg_);
+    return *i_;
 }
 
-prefix_ void senf::console::ParseCommandInfo::setCommand(std::string const & commandPath)
+prefix_ void senf::console::CheckedArgumentIteratorWrapper::increment()
 {
-    commandPath_ = commandPath;
+    if (i_ == e_)
+        throw SyntaxErrorException(msg_);
+    ++ i_;
 }
 
-prefix_ void senf::console::ParseCommandInfo::startArgument()
+prefix_ bool senf::console::CheckedArgumentIteratorWrapper::
+operator==(ParseCommandInfo::ArgumentIterator const & other)
+    const
 {
-    tempArguments_.push_back( TempArgumentRange( tokens_.size(), tokens_.size() ) );
+    return i_ == other;
 }
 
-prefix_ void senf::console::ParseCommandInfo::endArgument()
+prefix_ bool senf::console::CheckedArgumentIteratorWrapper::
+operator!=(ParseCommandInfo::ArgumentIterator const & other)
+    const
 {
-    tempArguments_.back().second = tokens_.size();
+    return i_ != other;
 }
 
-prefix_ void senf::console::ParseCommandInfo::addToken(ArgumentToken const & token)
+prefix_ senf::console::ParseCommandInfo::ArgumentIterator
+senf::console::CheckedArgumentIteratorWrapper::operator++(int)
 {
-    tokens_.push_back(token);
+    ParseCommandInfo::ArgumentIterator i (i_);
+    increment();
+    return i;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // senf::console::SingleCommandParser
 
-prefix_ senf::console::SingleCommandParser::Impl & senf::console::SingleCommandParser::impl()
+prefix_ senf::console::CommandParser::Impl & senf::console::CommandParser::impl()
 {
     SENF_ASSERT(impl_);
     return *impl_;