monotone

monotone Mtn Source Tree

Root/src/cmd.hh

1// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10#ifndef __CMD_HH__
11#define __CMD_HH__
12
13#include <map>
14#include <set>
15
16#include "commands.hh"
17#include "selectors.hh"
18#include "options.hh"
19
20class app_state;
21
22class automate_stdio_helpers;
23
24namespace commands
25{
26 class command
27 {
28 public:
29 typedef std::set< utf8 > names_set;
30 typedef std::set< command * > children_set;
31
32 private:
33 // NB: these strings are stored _un_translated, because we cannot
34 // translate them until after main starts, by which time the
35 // command objects have all been constructed.
36 utf8 m_primary_name;
37 names_set m_names;
38 command * m_parent;
39 bool m_is_group;
40 bool m_hidden;
41 utf8 m_params;
42 utf8 m_abstract;
43 utf8 m_desc;
44 bool m_use_workspace_options;
45 options::options_type m_opts;
46 children_set m_children;
47 bool m_allow_completion;
48
49 std::map< command_id, command * >
50 find_completions(utf8 const & prefix, command_id const & completed,
51 bool completion_ok = true) const;
52 command * find_child_by_name(utf8 const & name) const;
53
54 bool allow_completion() const;
55 public:
56 command(std::string const & primary_name,
57 std::string const & other_names,
58 command * parent,
59 bool is_group,
60 bool hidden,
61 std::string const & params,
62 std::string const & abstract,
63 std::string const & desc,
64 bool use_workspace_options,
65 options::options_type const & opts,
66 bool allow_completion);
67
68 virtual ~command(void);
69
70 command_id ident(void) const;
71
72 utf8 const & primary_name(void) const;
73 names_set const & names(void) const;
74 void add_alias(const utf8 &new_name);
75 command * parent(void) const;
76 bool is_group(void) const;
77 bool hidden(void) const;
78 virtual std::string params(void) const;
79 virtual std::string abstract(void) const;
80 virtual std::string desc(void) const;
81 virtual names_set subcommands(bool hidden) const;
82
83 options::options_type const & opts(void) const;
84 bool use_workspace_options(void) const;
85 void preset_options(options & opts) const;
86
87 children_set & children(void);
88 children_set const & children(void) const;
89 bool is_leaf(void) const;
90
91 bool operator<(command const & cmd) const;
92
93 virtual void exec(app_state & app,
94 command_id const & execid,
95 args_vector const & args) const = 0;
96
97 bool has_name(utf8 const & name) const;
98 command const * find_command(command_id const & id) const;
99 command * find_command(command_id const & id);
100 std::set< command_id >
101 complete_command(command_id const & id,
102 command_id completed = command_id(),
103 bool completion_ok = true) const;
104 };
105
106 class cmdpreset
107 {
108 public:
109 void register_for(command const * cmd);
110 virtual void preset(options & opts) const = 0;
111 virtual ~cmdpreset();
112 };
113
114 class automate : public command
115 {
116 bool stdio_ok;
117 // This function is supposed to be called only after the requirements
118 // for "automate" commands have been fulfilled. This is done by the
119 // "exec" function defined below, which implements code shared among
120 // all automation commands. Also, this is also needed by the "stdio"
121 // automation, as it executes multiple of these commands sharing the
122 // same initialization, hence the friend declaration.
123 virtual void exec_from_automate(app_state & app,
124 command_id const & execid,
125 args_vector const & args,
126 std::ostream & output) const = 0;
127 friend class ::automate_stdio_helpers;
128
129 public:
130 automate(std::string const & name,
131 bool stdio_ok,
132 bool hidden,
133 std::string const & params,
134 std::string const & abstract,
135 std::string const & desc,
136 options::options_type const & opts);
137
138 void exec(app_state & app,
139 command_id const & execid,
140 args_vector const & args,
141 std::ostream & output) const;
142
143 void exec(app_state & app,
144 command_id const & execid,
145 args_vector const & args) const;
146
147 bool can_run_from_stdio() const;
148 };
149
150 void get_stdio_headers(std::vector<std::pair<std::string, std::string> > & headers);
151}
152
153inline std::vector<file_path>
154args_to_paths(args_vector const & args)
155{
156 std::vector<file_path> paths;
157 for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i)
158 {
159 if (bookkeeping_path::external_string_is_bookkeeping_path(*i))
160 W(F("ignored bookkeeping path '%s'") % *i);
161 else
162 paths.push_back(file_path_external(*i));
163 }
164 // "it should not be the case that args were passed, but our paths set
165 // ended up empty". This test is because some commands have default
166 // behavior for empty path sets -- in particular, it is the same as having
167 // no restriction at all. "mtn revert _MTN" turning into "mtn revert"
168 // would be bad. (Or substitute diff, etc.)
169 E(!(!args.empty() && paths.empty()), origin::user,
170 F("all arguments given were bookkeeping paths; aborting"));
171 return paths;
172}
173
174void
175process_commit_message_args(options const & opts,
176 bool & given,
177 utf8 & log_message,
178 utf8 const & message_prefix = utf8());
179
180#define CMD_FWD_DECL(C) \
181namespace commands { \
182 class cmd_ ## C; \
183 extern cmd_ ## C C ## _cmd; \
184}
185
186#define CMD_REF(C) ((commands::command *)&(commands::C ## _cmd))
187
188#define CMD_PRESET_OPTIONS(C) \
189 CMD_FWD_DECL(C) \
190 namespace commands{ \
191 class cmdpreset_ ## C : public cmdpreset \
192 { \
193 public: \
194 cmdpreset_ ## C () { register_for(CMD_REF(C)); } \
195 virtual void preset(options & opts) const; \
196 }; \
197 cmdpreset_ ## C C ## _cmdpreset; \
198 } \
199 void commands::cmdpreset_ ## C ::preset(options & opts) const
200
201
202#define _CMD2(C, name, aliases, parent, hidden, params, abstract, desc, opts) \
203namespace commands { \
204 class cmd_ ## C : public command \
205 { \
206 public: \
207 cmd_ ## C() : command(name, aliases, parent, false, hidden, \
208 params, abstract, desc, true, \
209 options::options_type() | opts, true) \
210 {} \
211 virtual void exec(app_state & app, \
212 command_id const & execid, \
213 args_vector const & args) const; \
214 }; \
215 cmd_ ## C C ## _cmd; \
216} \
217void commands::cmd_ ## C::exec(app_state & app, \
218 command_id const & execid, \
219 args_vector const & args) const
220
221#define CMD(C, name, aliases, parent, params, abstract, desc, opts) \
222 _CMD2(C, name, aliases, parent, false, params, abstract, desc, opts)
223
224#define CMD_HIDDEN(C, name, aliases, parent, params, abstract, desc, opts) \
225 _CMD2(C, name, aliases, parent, true, params, abstract, desc, opts)
226
227#define _CMD_GROUP2(C, name, aliases, parent, abstract, desc, cmpl) \
228 namespace commands { \
229 class cmd_ ## C : public command \
230 { \
231 public: \
232 cmd_ ## C() : command(name, aliases, parent, true, false, "", \
233 abstract, desc, true, \
234 options::options_type(), cmpl) \
235 {} \
236 virtual void exec(app_state & app, \
237 command_id const & execid, \
238 args_vector const & args) const; \
239 }; \
240 cmd_ ## C C ## _cmd; \
241} \
242void commands::cmd_ ## C::exec(app_state & app, \
243 command_id const & execid, \
244 args_vector const & args) const \
245{ \
246 I(false); \
247}
248
249#define CMD_GROUP(C, name, aliases, parent, abstract, desc) \
250 _CMD_GROUP2(C, name, aliases, parent, abstract, desc, true)
251
252#define CMD_GROUP_NO_COMPLETE(C, name, aliases, parent, abstract, desc) \
253 _CMD_GROUP2(C, name, aliases, parent, abstract, desc, false)
254
255// Use this for commands that should specifically _not_ look for an
256// _MTN dir and load options from it.
257
258#define CMD_NO_WORKSPACE(C, name, aliases, parent, params, abstract, \
259 desc, opts) \
260namespace commands { \
261 class cmd_ ## C : public command \
262 { \
263 public: \
264 cmd_ ## C() : command(name, aliases, parent, false, false, \
265 params, abstract, desc, false, \
266 options::options_type() | opts, true) \
267 {} \
268 virtual void exec(app_state & app, \
269 command_id const & execid, \
270 args_vector const & args) const; \
271 }; \
272 cmd_ ## C C ## _cmd; \
273} \
274void commands::cmd_ ## C::exec(app_state & app, \
275 command_id const & execid, \
276 args_vector const & args) const
277
278// TODO: 'abstract' and 'desc' should be refactored so that the
279// command definition allows the description of input/output format,
280// error conditions, version when added, etc. 'desc' can later be
281// automatically built from these.
282#define _CMD_AUTOMATE2(C, stdio_ok, hidden, params, abstract, desc, opts) \
283namespace commands { \
284 class automate_ ## C : public automate \
285 { \
286 void exec_from_automate(app_state & app, \
287 command_id const & execid, \
288 args_vector const & args, \
289 std::ostream & output) const; \
290 public: \
291 automate_ ## C() : automate(#C, stdio_ok, hidden, params, \
292 abstract, desc, \
293 options::options_type() | opts) \
294 {} \
295 }; \
296 automate_ ## C C ## _automate; \
297} \
298void commands::automate_ ## C :: exec_from_automate \
299 (app_state & app, \
300 command_id const & execid, \
301 args_vector const & args, \
302 std::ostream & output) const
303
304#define CMD_AUTOMATE(C, params, abstract, desc, opts) \
305 _CMD_AUTOMATE2(C, true, false, params, abstract, desc, opts)
306
307#define CMD_AUTOMATE_NO_STDIO(C, params, abstract, desc, opts) \
308 _CMD_AUTOMATE2(C, false, false, params, abstract, desc, opts)
309
310#define CMD_AUTOMATE_HIDDEN(C, params, abstract, desc, opts) \
311 _CMD_AUTOMATE2(C, true, true, params, abstract, desc, opts)
312
313CMD_FWD_DECL(__root__);
314CMD_FWD_DECL(automation);
315CMD_FWD_DECL(conflicts);
316CMD_FWD_DECL(database);
317CMD_FWD_DECL(debug);
318CMD_FWD_DECL(informative);
319CMD_FWD_DECL(key_and_cert);
320CMD_FWD_DECL(network);
321CMD_FWD_DECL(packet_io);
322CMD_FWD_DECL(vcs);
323CMD_FWD_DECL(review);
324CMD_FWD_DECL(tree);
325CMD_FWD_DECL(variables);
326CMD_FWD_DECL(workspace);
327CMD_FWD_DECL(user);
328
329#endif
330
331// Local Variables:
332// mode: C++
333// fill-column: 76
334// c-file-style: "gnu"
335// indent-tabs-mode: nil
336// End:
337// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status