22 #include <boost/algorithm/string.hpp> 48 void parse(
const std::string& str)
63 if (n <
args.size()) {
73 if (n <
args.size()) {
92 std::size_t first_space =
str_.find_first_of(
' ',
args.back());
93 std::size_t next_arg_begin =
str_.find_first_not_of(
' ', first_space);
94 if (next_arg_begin != std::string::npos) {
95 args.push_back(next_arg_begin);
103 mutable std::vector<std::size_t>
args;
120 template <
class Worker>
124 typedef void (Worker::*command_handler)();
131 explicit command(command_handler
h,
const std::string& help =
"",
132 const std::string& usage =
"",
const std::string& flags =
"")
133 : handler(h), help(help), usage(usage), flags(flags)
138 return flags.find(f) != flags.npos;
157 return command_map_.empty();
168 for (
int i = 0;
i < 100; ++
i) {
170 std::string actual_cmd = get_actual_cmd(
get_cmd());
175 cmd = actual_cmd + (data.empty() ?
"" :
" ") + data;
182 if (
const command*
c = get_command(
get_cmd())) {
183 if (is_enabled(*
c)) {
184 (
static_cast<Worker*
>(
this)->*(
c->handler))();
187 print(
get_cmd(),
_(
"This command is currently unavailable."));
190 else if (help_on_unknown_) {
192 symbols[
"command"] =
get_cmd();
193 symbols[
"help_command"] = cmd_prefix_ +
"help";
194 print(
"help",
VGETTEXT(
"Unknown command '$command', try $help_command " 195 "for a list of available commands.", symbols));
201 std::vector<std::string> res;
202 for (
typename command_map::value_type
i : command_map_) {
203 res.push_back(
i.first);
216 _(
"Available commands list and command-specific help. " 217 "Use \"help all\" to include currently unavailable commands."),
221 _(
"[all|<command>]\n“all” = overview of all commands, <command> = name of a specific command (provides more detail)"));
224 virtual void init_map() = 0;
226 virtual void print(
const std::string& title,
const std::string& message) = 0;
246 cap_.parse(cmd_string);
249 virtual std::string
get_arg(
unsigned argn)
const 251 return cap_.get_arg(argn);
254 virtual std::string
get_data(
unsigned argn = 1)
const 256 return cap_.get_data(argn);
260 return cap_.get_cmd();
265 symbols[
"arg_id"] = std::to_string(argn);
266 command_failed(
VGETTEXT(
"Missing argument $arg_id", symbols));
275 command_alias_map::const_iterator
i = command_alias_map_.find(cmd);
276 return i != command_alias_map_.end() ? i->second : cmd;
280 typename command_map::const_iterator
i = command_map_.find(cmd);
281 return i != command_map_.end() ? &i->second : 0;
286 return i != command_map_.end() ? &i->second : 0;
291 if (help_command(
get_arg(1))) {
294 std::stringstream ss;
295 bool show_unavail = show_unavailable_ ||
get_arg(1) ==
"all";
296 for (
typename command_map::value_type
i : command_map_) {
297 if (show_unavail || is_enabled(
i.second)) {
304 if (!
i.second.flags.empty()) {
305 ss <<
" (" <<
i.second.flags <<
") ";
311 symbols[
"flags_description"] = get_flags_description();
312 symbols[
"list_of_commands"] = ss.str();
313 symbols[
"help_command"] = cmd_prefix_ +
"help";
314 print(
_(
"help"),
VGETTEXT(
"Available commands $flags_description:\n$list_of_commands", symbols));
315 print(
_(
"help"),
VGETTEXT(
"Type $help_command <command> for more info.", symbols));
320 std::string cmd = get_actual_cmd(acmd);
321 const command*
c = get_command(cmd);
323 std::stringstream ss;
324 ss << cmd_prefix_ << cmd;
325 if (c->help.empty() && c->usage.empty()) {
326 ss <<
_(
" No help available.");
329 ss <<
" - " << c->help <<
"\n";
331 if (!c->usage.empty()) {
332 ss <<
_(
"Usage:") <<
" " << cmd_prefix_ << cmd <<
" " << c->usage <<
"\n";
334 const auto flags_description = get_command_flags_description(*c);
335 if (!flags_description.empty()) {
337 ss <<
_(
"Notes:") <<
" " << get_command_flags_description(*c) <<
"\n";
339 const std::vector<std::string> l = get_aliases(cmd);
343 ss <<
_n(
"command^Alias:",
"Aliases:", l.size()) <<
" " <<
utils::join(l,
" ") <<
"\n";
345 print(
_(
"help"), ss.str());
354 help_on_unknown_ = value;
362 command_handler
h,
const std::string&
help =
"",
363 const std::string& usage =
"",
const std::string& flags =
"")
365 command
c = command(h,
help, usage, flags);
366 std::pair<typename command_map::iterator, bool> r;
367 r = command_map_.insert(
typename command_map::value_type(cmd, c));
374 const std::string& cmd)
376 command_alias_map_[cmd] = to_cmd;
380 static const std::vector<std::string>
get_aliases(
const std::string& cmd)
382 std::vector<std::string> aliases;
383 typedef command_alias_map::value_type
p;
384 for (p
i : command_alias_map_) {
385 if (
i.second == cmd) {
386 aliases.push_back(
i.first);
400 template <
class Worker>
403 template <
class Worker>
406 template <
class Worker>
409 template <
class Worker>
412 template <
class Worker>
void command_failed(const std::string &message, bool=false)
std::string get_arg(unsigned n) const
static bool help_on_unknown_
void parse(const std::string &str)
static std::string _n(const char *str1, const char *str2, int n)
std::map< std::string, t_string > string_map
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
virtual std::string get_data(unsigned argn=1) const
std::vector< std::string > get_commands_list() const
static bool show_unavailable_
cmd_arg_parser & operator=(const cmd_arg_parser &)
static void set_cmd_prefix(const std::string &value)
std::string get_data(unsigned n) const
virtual std::string get_cmd() const
static command_map command_map_
virtual std::string get_arg(unsigned argn) const
static std::string _(const char *str)
Definitions for the interface to Wesnoth Markup Language (WML).
const std::string & get_str() const
cmd_arg_parser(const std::string &str)
void dispatch(std::string cmd)
void advance_to_arg(unsigned n) const
virtual void register_alias(const std::string &to_cmd, const std::string &cmd)
virtual bool is_enabled(const command &) const
const command * get_command(const std::string &cmd) const
virtual std::string get_flags_description() const
std::vector< std::size_t > args
virtual std::string get_command_flags_description(const command &) const
command & add_flag(const char f)
static std::string cmd_prefix_
std::map< std::string, std::string > command_alias_map
static void print(std::stringstream &sstr, const std::string &queue, const std::string &id)
std::map< std::string, command > command_map
command * get_command(const std::string &cmd)
static const std::vector< std::string > get_aliases(const std::string &cmd)
Handling of system events.
static void set_help_on_unknown(bool value)
bool has_flag(const char f) const
void trim(std::string_view &s)
static command_alias_map command_alias_map_
bool help_command(const std::string &acmd)
virtual void parse_cmd(const std::string &cmd_string)
virtual void register_command(const std::string &cmd, command_handler h, const std::string &help="", const std::string &usage="", const std::string &flags="")
std::string get_cmd() const
static map_location::DIRECTION n
std::string::const_iterator iterator
virtual ~map_command_handler()
std::string get_actual_cmd(const std::string &cmd) const
command(command_handler h, const std::string &help="", const std::string &usage="", const std::string &flags="")
void command_failed_need_arg(int argn)