// $Id$
//
-// Copyright (C) 2008
+// Copyright (C) 2008
// Fraunhofer Institute for Open Communication Systems (FOKUS)
-// Competence Center NETwork research (NET), St. Augustin, GERMANY
-// Stefan Bund <g0dil@berlios.de>
//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 2 of the License, or
-// (at your option) any later version.
+// The contents of this file are subject to the Fraunhofer FOKUS Public License
+// Version 1.0 (the "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+// http://senf.berlios.de/license.html
//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// The Fraunhofer FOKUS Public License Version 1.0 is based on,
+// but modifies the Mozilla Public License Version 1.1.
+// See the full license text for the amendments.
//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the
-// Free Software Foundation, Inc.,
-// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// Software distributed under the License is distributed on an "AS IS" basis,
+// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+// for the specific language governing rights and limitations under the License.
+//
+// The Original Code is Fraunhofer FOKUS code.
+//
+// The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
+// (registered association), Hansastraße 27 c, 80686 Munich, Germany.
+// All Rights Reserved.
+//
+// Contributor(s):
+// Stefan Bund <g0dil@berlios.de>
/** \file
\brief Parse public header */
configuration file
\code
# My someserver configuration file
-
+
/server/port 1234;
-
+
/logger/targets {
console {
accept senf::log::Debug IMPORTANT;
These are characters, which have a special meaning. Some are used internally, others are just
returned as punctuation tokens
-
+
<table class="senf">
<tr><td>#</td><td>Comments are marked with '#' and continue to the end of the line</td></tr>
<tr><td>/</td><td>path component separator</td></tr>
"\"foo\nbar\""
"\x04test"
</pre>
-
+
A <b>hex-string literal</b> is used to represent binary data. It looks like a string which has
only hexadecimal bytes or whitespace as contents (comments and newlines are Ok when not read
from the interactive console)
</pre>
\subsection console_statements Statements
-
+
There are several types of statements:
\li The bulk of all statements are \e path statements
\li There are some \e built-in statements which are mostly useful at the interactive console
is completely up to the command.
A <b>built-in</b> statement is one of
-
+
<table class="senf">
<tr><td>\c cd \e path</td><td>Change current directory</td></tr>
<tr><td>\c ls [ \e path ]</td><td>List contents of \e path or current directory</td></tr>
#include <senf/Utils/Exception.hh>
//#include "Parse.mpp"
-///////////////////////////////hh.p////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
namespace senf {
namespace console {
/** \brief Single argument token
All command arguments are split into tokens by the parser. Each token is returned as an
- Token instance.
+ Token instance.
\ingroup console_parser
*/
class Token
{
public:
- enum TokenType {
+ enum TokenType {
None = 0,
PathSeparator = 0x0001, // '/'
ArgumentGroupOpen = 0x0002, // '('
};
enum TokenGroup {
- ArgumentGrouper = ArgumentGroupOpen
+ ArgumentGrouper = ArgumentGroupOpen
| ArgumentGroupClose,
- DirectoryGrouper = DirectoryGroupOpen
+ DirectoryGrouper = DirectoryGroupOpen
| DirectoryGroupClose,
- Punctuation = DirectoryGroupOpen
- | DirectoryGroupClose
- | PathSeparator
- | CommandTerminator
+ Punctuation = DirectoryGroupOpen
+ | DirectoryGroupClose
+ | PathSeparator
+ | CommandTerminator
| OtherPunctuation,
- String = BasicString
+ String = BasicString
| HexString,
- SimpleArgument = Word
- | BasicString
+ SimpleArgument = Word
+ | BasicString
| HexString
};
-
+
Token(); ///< Create empty token
- Token(TokenType type, std::string token);
+ Token(TokenType type, std::string token);
///< Create token with given type and value
- Token(TokenType type, std::string token, detail::FilePositionWithIndex const & pos);
+ Token(TokenType type, std::string token, detail::FilePositionWithIndex const & pos);
///< Create token with given type and value
Every command parsed is returned in a ParseCommandInfo instance. This information is purely
taken from the parser, no semantic information is attached at this point, the config/console
node tree is not involved in any way. ParseCommandInfo consist of
-
+
\li the type of command: built-in or normal command represented by a possibly relative path
into the command tree.
\li the command
typedef std::vector<std::string> CommandPath;
public:
- class ArgumentIterator;
+ class ArgumentIterator;
typedef CommandPath::const_iterator path_iterator;
typedef Tokens::const_iterator token_iterator;
typedef boost::iterator_range<argument_iterator> ArgumentsRange;
typedef boost::iterator_range<token_iterator> TokensRange;
- enum BuiltinCommand { NoBuiltin,
- BuiltinCD,
- BuiltinLS,
+ enum BuiltinCommand { NoBuiltin,
+ BuiltinCD,
+ BuiltinLS,
BuiltinLL,
BuiltinLR,
- BuiltinPUSHD,
+ BuiltinPUSHD,
BuiltinPOPD,
BuiltinEXIT,
BuiltinHELP };
void clear(); ///< Clear all data members
bool empty(); ///< \c true, if the data is empty
- void builtin(BuiltinCommand builtin); ///< Assign builtin command
+ void builtin(BuiltinCommand builtin); ///< Assign builtin command
void command(std::vector<Token> & commandPath); ///< Assign non-builtin command
void addToken(Token const & token); ///< Add argument token
This iterator is a bidirectional iterator \e not a random access iterator.
*/
class ParseCommandInfo::ArgumentIterator
- : public boost::iterator_facade< ParseCommandInfo::ArgumentIterator,
+ : public boost::iterator_facade< ParseCommandInfo::ArgumentIterator,
ParseCommandInfo::TokensRange,
boost::bidirectional_traversal_tag,
ParseCommandInfo::TokensRange >
of SyntaxErrorException. This is important, so command overloading works.
*/
struct SyntaxErrorException : public senf::Exception
- { explicit SyntaxErrorException(std::string const & msg = "syntax error")
+ { explicit SyntaxErrorException(std::string const & msg = "syntax error")
: senf::Exception(msg) {} };
/** \brief Wrapper checking argument iterator access for validity
-
+
CheckedArgumentIteratorWrapper is a wrapper around a range of arguments parsed using the
ParseCommandInfo::ArgumentIterator. It is used to parse arguments either in a command
(registered with manual argument parsing) or when defining a custom parser.
{
std:;string arg1;
unsigned arg2 (0);
-
+
{
senf::console::CheckedArgumentIteratorWrapper arg (command.arguments());
senf::console::parse( *(arg++), arg1 );
\li You increment the iterator \e past all arguments you parse. The iterator must point to
the end of the range when parsing is complete.
\li The iterator wrapper is destroyed after parsing but before executing the command itself
- begins.
+ begins.
Accessing a non-existent argument or failing to parse all arguments will raise a
senf::console::SyntaxErrorException.
- \see \link console_args_custom Example customer parser \endlink
+ \see \ref console_args_custom "Example customer parser"
*/
class CheckedArgumentIteratorWrapper
: boost::noncopyable,
std::string const & msg = "invalid number of arguments");
///< Make wrapper from ArgumentsRange
/**< This constructs a wrapper from a
- ParseCommandInfo::ArgumentsRange.
+ ParseCommandInfo::ArgumentsRange.
\param[in] range Range of arguments to parse
\param[in] msg Error message */
explicit CheckedArgumentIteratorWrapper(
SyntaxErrorException, if not all arguments are parsed
and when no other exception is in progress. */
- operator ParseCommandInfo::ArgumentIterator();
+ operator ParseCommandInfo::ArgumentIterator();
///< Use wrapper as ParseCommandInfo::ArgumentIterator
bool boolean_test() const; ///< \c true, if more arguments are available
///< Compare wrapper against ArgumentIterator
bool operator!=(ParseCommandInfo::ArgumentIterator const & other) const;
///< Compare wrapper against ArgumentIterator
-
+
using IteratorFacade::operator++;
ParseCommandInfo::ArgumentIterator operator++(int);
: boost::noncopyable
{
public:
- ///////////////////////////////////////////////////////////////////////////
+ //-////////////////////////////////////////////////////////////////////////
// Types
typedef boost::function<void (ParseCommandInfo const &)> Callback;
- ///////////////////////////////////////////////////////////////////////////
+ //-////////////////////////////////////////////////////////////////////////
///\name Structors and default members
- ///@{
+ //\{
CommandParser();
~CommandParser();
- ///@}
- ///////////////////////////////////////////////////////////////////////////
+ //\}
+ //-////////////////////////////////////////////////////////////////////////
void parse(std::string const & command, Callback cb); ///< Parse string
void parseFile(std::string const & filename, Callback cb); ///< Parse file
/**< An incremental parse will parse all complete statements
in \a commands. parseIncremental() will return the
number of characters successfully parsed from \a
- commands.
-
+ commands.
+
\note The incremental parser \e requires all statements
to be terminated explicitly. This means, that the
last ';' is \e not optional in this case. */
}}
-///////////////////////////////hh.e////////////////////////////////////////
+//-/////////////////////////////////////////////////////////////////////////////////////////////////
#include "Parse.cci"
//#include "Parse.ct"
//#include "Parse.cti"