Utils: Document new utilities
[senf.git] / Console / Executor.hh
1 // $Id$
2 //
3 // Copyright (C) 2008 
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Executor public header */
25
26 #ifndef HH_Executor_
27 #define HH_Executor_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include "Parse.hh"
32 #include "../Utils/Logger/SenfLog.hh"
33 #include "Node.hh"
34
35 //#include "Executor.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
37
38 namespace senf {
39 namespace console {
40
41     /** \brief Execute config/console commands
42
43         The Executor interprets parsed config/console commands and executes them. It manages the
44         current execution context (current directory, directory stack and so on).
45
46         The executor is normally called directly by the parser callback for each command.
47
48         Executing the built-in 'exit' command will throw Executor::ExitException. This exception
49         (which is not derived from std::exception since it's not a real exception) must be handled
50         by the caller.
51
52         All directories are managed using weak pointers. If any of the directories expires (current
53         directory, directory stack, last directory) it will be replaced with the root
54         directory. Directories expire when they are destructed or when they are detached from the
55         config tree root node.
56       */
57     class Executor
58         : boost::noncopyable
59     {
60         SENF_LOG_CLASS_AREA();
61         SENF_LOG_DEFAULT_LEVEL( senf::log::VERBOSE );
62     public:
63         ///////////////////////////////////////////////////////////////////////////
64         // Types
65
66         /// Thrown by built-in 'exit' command
67         struct ExitException {};        
68
69         /// Executor policy function
70         typedef boost::function<void (DirectoryNode &,std::string const &)> SecurityPolicy;
71
72         /// Thrown by the SecurityPolicy to silently ignore a command
73         struct IgnoreCommandException {};
74
75         ///////////////////////////////////////////////////////////////////////////
76         //\/name Structors and default members
77         ///\{
78         
79         Executor();
80
81         ///\}
82         ///////////////////////////////////////////////////////////////////////////
83
84         void execute(std::ostream & output, ParseCommandInfo const & command);
85                                         ///< Execute command
86                                         /**< Output will be written to \a output. 
87                                              Same as operator()(). */
88
89         void operator()(std::ostream & output, ParseCommandInfo const & command);
90                                         ///< Execute command
91                                         /**< Output will be written to \a output. 
92                                              Same as execute(). */
93         DirectoryNode & cwd() const;    ///< Current working directory
94         std::string cwdPath() const;    ///< Return pathname of current directory
95         bool skipping() const;          ///< \c true, if currently skipping a directory group
96
97         bool autocd() const;            ///< Get current autocd status
98                                         /**< if autocd is enabled, specifying a directory name as
99                                              command will cd to that directory. Disabled by
100                                              default (but enabled automatically by the interactive
101                                              console). */
102         Executor & autocd(bool v);      ///< Set autocd status
103                                         /**< \see autocd() */
104
105         bool autocomplete() const;      ///< Get current autocomplete status
106                                         /**< if autocomplete is enabled, path components which can
107                                              be uniquely completed will be completed
108                                              automatically. Disabled by default (but enabled
109                                              automatically by the interactive console) void
110                                              autocomplete(bool v). */
111
112         Executor & autocomplete(bool v); ///< Set autocomplete status
113                                         /**< \see autocomplete() */
114
115         DirectoryNode & chroot() const; ///< Get root node
116                                         /**< The root node defaults to senf::console::root(). If
117                                              changed, all path references are relative to this node
118                                              and objects outside that tree cannot be accessed. */ 
119         Executor & chroot(DirectoryNode & node); ///< chroot into given directory
120                                         /**< After this call, all path's are interpreted relative to
121                                              \a node and only nodes in the tree rooted at \a node
122                                              are accessible via the executor. This value defaults to
123                                              senf::console::root(). */
124
125         Executor & policy(SecurityPolicy policy = SecurityPolicy()); ///< Set security policy
126                                         /**< The security policy is called before traversing a node
127                                              to validate that access. */
128
129     protected:
130
131     private:
132         typedef std::vector<DirectoryNode::weak_ptr> Path;
133
134         void exec(std::ostream & output, ParseCommandInfo const & command);
135
136         void cd(ParseCommandInfo::TokensRange dir);
137         void ls(std::ostream & output, ParseCommandInfo::TokensRange dir);
138         void pushd(ParseCommandInfo::TokensRange dir);
139         void popd();
140         void exit();
141         void help(std::ostream & output, ParseCommandInfo::TokensRange path);
142
143         GenericNode & traverseNode(ParseCommandInfo::TokensRange const & path);
144         void traverseDirectory(ParseCommandInfo::TokensRange const & path,
145                                Path & dir);
146
147         struct InvalidPathException {};
148         struct InvalidDirectoryException {};
149         struct InvalidCommandException {};
150         
151         DirectoryNode::ptr root_;
152         SecurityPolicy policy_;
153         mutable Path cwd_;
154         Path oldCwd_;
155
156         typedef std::vector<Path> DirStack;
157         DirStack dirstack_;
158
159         bool autocd_;
160         bool autocomplete_;
161     };
162
163 }}
164
165 ///////////////////////////////hh.e////////////////////////////////////////
166 #include "Executor.cci"
167 //#include "Executor.ct"
168 //#include "Executor.cti"
169 #endif
170
171 \f
172 // Local Variables:
173 // mode: c++
174 // fill-column: 100
175 // comment-column: 40
176 // c-file-style: "senf"
177 // indent-tabs-mode: nil
178 // ispell-local-dictionary: "american"
179 // compile-command: "scons -u test"
180 // End: