You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.3 KiB
138 lines
4.3 KiB
/*****************************************************************************
|
|
*
|
|
* demo program - part of CLIPP (command line interfaces for modern C++)
|
|
*
|
|
* released under MIT license
|
|
*
|
|
* (c) 2017-2018 André Müller; foss@andremueller-online.de
|
|
*
|
|
*
|
|
* This command line interface example was taken from http://docopt.org/.
|
|
*
|
|
* EXAMPLE
|
|
* We want to model this command line interface:
|
|
*
|
|
* Naval Fate.
|
|
*
|
|
* Usage:
|
|
* naval_fate ship new <name>...
|
|
* naval_fate ship <name> move <x> <y> [--speed=<kn>]
|
|
* naval_fate ship shoot <x> <y>
|
|
* naval_fate mine (set|remove) <x> <y> [--moored|--drifting]
|
|
* naval_fate -h | --help
|
|
* naval_fate --version
|
|
*
|
|
* Options:
|
|
* -h --help Show this screen.
|
|
* --version Show version.
|
|
* --speed=<kn> Speed in knots [default: 10].
|
|
* --moored Moored (anchored) mine.
|
|
* --drifting Drifting mine.
|
|
*
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <clipp.h>
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
using namespace clipp;
|
|
using std::string;
|
|
using std::vector;
|
|
using std::cout;
|
|
|
|
int x = 0, y = 0;
|
|
float speed = 10.0f;
|
|
bool drift = true;
|
|
vector<string> names;
|
|
|
|
enum class mode { none, help, shipnew, shipmove, shipshoot, mineset, minerem};
|
|
mode selected = mode::none;
|
|
|
|
auto coordinates = ( value("x", x), value("y", y) );
|
|
|
|
auto shipnew = ( command("new").set(selected,mode::shipnew),
|
|
values("name", names) );
|
|
|
|
auto shipmove = (
|
|
value("name", names),
|
|
command("move").set(selected,mode::shipmove), coordinates,
|
|
(option("--speed=") & value("kn",speed)) % "Speed in knots [default: 10]");
|
|
|
|
auto shipshoot = ( command("shoot").set(selected,mode::shipshoot),
|
|
coordinates );
|
|
|
|
auto mines = (
|
|
command("mine"),
|
|
(command("set" ).set(selected,mode::mineset) |
|
|
command("remove").set(selected,mode::minerem) ),
|
|
coordinates,
|
|
(option("--moored" ).set(drift,false) % "Moored (anchored) mine." |
|
|
option("--drifting").set(drift,true) % "Drifting mine." )
|
|
);
|
|
|
|
auto navalcli = (
|
|
( command("ship"), ( shipnew | shipmove | shipshoot ) )
|
|
| mines
|
|
| command("-h", "--help").set(selected,mode::help) % "Show this screen."
|
|
| command("--version")([]{ cout << "version 1.0\n"; }) % "Show version."
|
|
);
|
|
|
|
auto fmt = doc_formatting{}
|
|
.first_column(2)
|
|
.doc_column(20)
|
|
.max_flags_per_param_in_usage(8);
|
|
|
|
if(parse(argc, argv, navalcli)) {
|
|
switch(selected) {
|
|
default:
|
|
case mode::none:
|
|
break;
|
|
case mode::help: {
|
|
cout << "Naval Fate.\n\nUsage:\n"
|
|
<< usage_lines(navalcli, "naval_fate", fmt)
|
|
<< "\n\nOptions:\n"
|
|
<< documentation(navalcli, fmt) << '\n';
|
|
}
|
|
break;
|
|
case mode::shipnew:
|
|
if(names.empty()) {
|
|
cout << "No new ships were made\n";
|
|
} else {
|
|
cout << "Made new ship" << (names.size() > 1 ? "s " : " ");
|
|
for(const auto& n : names) cout << n << ' ';
|
|
cout << "\n";
|
|
}
|
|
break;
|
|
case mode::shipmove:
|
|
if(names.empty()) {
|
|
cout << "No ship was moved.\n";
|
|
} else {
|
|
cout << "Moving ship " << names.front()
|
|
<< " to x=" << x << " y=" << y << ".\n";
|
|
}
|
|
break;
|
|
case mode::shipshoot:
|
|
cout << "Ship fired shot aimed at x=" << x << " y=" << y << ".\n";
|
|
break;
|
|
case mode::mineset:
|
|
cout << "Laid " << (drift ? "drifting" : "& moored")
|
|
<< " mine at x=" << x << " y=" << y << ".\n";
|
|
break;
|
|
case mode::minerem:
|
|
cout << "Removed mine at x=" << x << " y=" << y << ".\n";
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
std::cerr << "Wrong command line arguments.\nUsage:"
|
|
<< usage_lines(navalcli, "naval_fate", fmt) << '\n';
|
|
}
|
|
|
|
}
|