monotone

monotone Mtn Source Tree

Root/cmd.hh

1#ifndef __CMD_HH__
2#define __CMD_HH__
3
4#include <boost/shared_ptr.hpp>
5
6// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
7//
8// This program is made available under the GNU GPL version 2.0 or
9// greater. See the accompanying file COPYING for details.
10//
11// This program is distributed WITHOUT ANY WARRANTY; without even the
12// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13// PURPOSE.
14
15#include "app_state.hh"
16#include "commands.hh"
17#include "constants.hh"
18#include "options.hh"
19#include "sanity.hh"
20
21
22namespace commands
23{
24 std::string const & hidden_group();
25 using boost::shared_ptr;
26
27
28 struct command
29 {
30 // NB: these strings are stored _un_translated, because we cannot
31 // translate them until after main starts, by which time the
32 // command objects have all been constructed.
33 std::string name;
34 std::string cmdgroup;
35 std::string params_;
36 std::string desc_;
37 bool use_workspace_options;
38 options::options_type opts;
39 command(std::string const & n,
40 std::string const & g,
41 std::string const & p,
42 std::string const & d,
43 bool u,
44 options::options_type const & o);
45 virtual ~command();
46 virtual std::string params();
47 virtual std::string desc();
48 virtual options::options_type get_options(std::vector<utf8> const & args);
49 virtual void exec(app_state & app,
50 std::vector<utf8> const & args) = 0;
51 };
52};
53
54inline std::vector<file_path>
55args_to_paths(std::vector<utf8> const & args)
56{
57 std::vector<file_path> paths;
58 for (std::vector<utf8>::const_iterator i = args.begin(); i != args.end(); ++i)
59 {
60 if (bookkeeping_path::external_string_is_bookkeeping_path(*i))
61 W(F("ignored bookkeeping path '%s'") % *i);
62 else
63 paths.push_back(file_path_external(*i));
64 }
65 // "it should not be the case that args were passed, but our paths set
66 // ended up empty". This test is because some commands have default
67 // behavior for empty path sets -- in particular, it is the same as having
68 // no restriction at all. "mtn revert _MTN" turning into "mtn revert"
69 // would be bad. (Or substitute diff, etc.)
70 N(!(!args.empty() && paths.empty()),
71 F("all arguments given were bookkeeping paths; aborting"));
72 return paths;
73}
74
75std::string
76describe_revision(app_state & app,
77 revision_id const & id);
78
79void
80complete(app_state & app,
81 std::string const & str,
82 revision_id & completion,
83 bool must_exist=true);
84
85void
86complete(app_state & app,
87 std::string const & str,
88 std::set<revision_id> & completion,
89 bool must_exist=true);
90
91template<typename ID>
92static void
93complete(app_state & app,
94 std::string const & str,
95 ID & completion)
96{
97 N(str.find_first_not_of(constants::legal_id_bytes) == std::string::npos,
98 F("non-hex digits in id"));
99 if (str.size() == constants::idlen)
100 {
101 completion = ID(str);
102 return;
103 }
104 std::set<ID> completions;
105 app.db.complete(str, completions);
106 N(completions.size() != 0,
107 F("partial id '%s' does not have an expansion") % str);
108 if (completions.size() > 1)
109 {
110 std::string err =
111 (F("partial id '%s' has multiple ambiguous expansions:")
112 % str).str();
113 for (typename std::set<ID>::const_iterator i = completions.begin();
114 i != completions.end(); ++i)
115 err += (i->inner()() + "\n");
116 N(completions.size() == 1, i18n_format(err));
117 }
118 completion = *(completions.begin());
119 P(F("expanded partial id '%s' to '%s'")
120 % str % completion);
121}
122
123void
124notify_if_multiple_heads(app_state & app);
125
126void
127process_commit_message_args(bool & given,
128 utf8 & log_message,
129 app_state & app,
130 utf8 message_prefix = utf8(""));
131
132void
133get_content_paths(roster_t const & roster,
134 std::map<file_id,
135 file_path> & paths);
136
137#define CMD(C, group, params, desc, opts) \
138namespace commands { \
139 struct cmd_ ## C : public command \
140 { \
141 cmd_ ## C() : command(#C, group, params, desc, true, \
142 options::options_type() | opts) \
143 {} \
144 virtual void exec(app_state & app, \
145 std::vector<utf8> const & args); \
146 }; \
147 static cmd_ ## C C ## _cmd; \
148} \
149void commands::cmd_ ## C::exec(app_state & app, \
150 std::vector<utf8> const & args)
151
152// Use this for commands that want to define a params() function
153// instead of having a static description. (Good for "automate"
154// and possibly "list".)
155#define CMD_WITH_SUBCMDS(C, group, desc, opts) \
156namespace commands { \
157 struct cmd_ ## C : public command \
158 { \
159 cmd_ ## C() : command(#C, group, "", desc, true, \
160 options::options_type() | opts) \
161 {} \
162 virtual void exec(app_state & app, \
163 std::vector<utf8> const & args); \
164 std::string params(); \
165 options::options_type get_options(vector<utf8> const & args); \
166 }; \
167 static cmd_ ## C C ## _cmd; \
168} \
169void commands::cmd_ ## C::exec(app_state & app, \
170 std::vector<utf8> const & args)
171
172// Use this for commands that should specifically _not_ look for an
173// _MTN dir and load options from it.
174
175#define CMD_NO_WORKSPACE(C, group, params, desc, opts) \
176namespace commands { \
177 struct cmd_ ## C : public command \
178 { \
179 cmd_ ## C() : command(#C, group, params, desc, false, \
180 options::options_type() | opts) \
181 {} \
182 virtual void exec(app_state & app, \
183 std::vector<utf8> const & args); \
184 }; \
185 static cmd_ ## C C ## _cmd; \
186} \
187void commands::cmd_ ## C::exec(app_state & app, \
188 std::vector<utf8> const & args) \
189
190#define ALIAS(C, realcommand) \
191namespace commands { \
192 struct cmd_ ## C : public command \
193 { \
194 cmd_ ## C() : command(#C, realcommand##_cmd.cmdgroup, \
195 realcommand##_cmd.params_, \
196 realcommand##_cmd.desc_, true, \
197 realcommand##_cmd.opts) \
198 {} \
199 virtual std::string desc(); \
200 virtual void exec(app_state & app, \
201 std::vector<utf8> const & args); \
202 }; \
203 static cmd_ ## C C ## _cmd; \
204} \
205std::string commands::cmd_ ## C::desc() \
206{ \
207 std::string result = _(desc_.c_str()); \
208 result += "\n"; \
209 result += (F("Alias for %s") % #realcommand).str(); \
210 return result; \
211} \
212void commands::cmd_ ## C::exec(app_state & app, \
213 std::vector<utf8> const & args) \
214{ \
215 process(app, std::string(#realcommand), args); \
216}
217
218namespace automation {
219 struct automate
220 {
221 std::string name;
222 std::string params;
223 options::options_type opts;
224 automate(std::string const & n, std::string const & p,
225 options::options_type const & o);
226 virtual void run(std::vector<utf8> args,
227 std::string const & help_name,
228 app_state & app,
229 std::ostream & output) const = 0;
230 virtual ~automate();
231 };
232}
233
234#define AUTOMATE(NAME, PARAMS, OPTIONS) \
235namespace automation { \
236 struct auto_ ## NAME : public automate \
237 { \
238 auto_ ## NAME () \
239 : automate(#NAME, PARAMS, options::options_type() | OPTIONS) \
240 {} \
241 void run(std::vector<utf8> args, std::string const & help_name, \
242 app_state & app, std::ostream & output) const; \
243 virtual ~auto_ ## NAME() {} \
244 }; \
245 static auto_ ## NAME NAME ## _auto; \
246} \
247void automation::auto_ ## NAME :: run(std::vector<utf8> args, \
248 std::string const & help_name,\
249 app_state & app, \
250 std::ostream & output) const
251
252
253
254
255// Local Variables:
256// mode: C++
257// fill-column: 76
258// c-file-style: "gnu"
259// indent-tabs-mode: nil
260// End:
261// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
262
263#endif

Archive Download this file

Branches

Tags

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