monotone

monotone Mtn Source Tree

Root/cmd.hh

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

Archive Download this file

Branches

Tags

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