open-story-teller/story-editor-legacy/ost_convert/command_line.h
2023-12-13 13:44:23 +01:00

81 lines
3 KiB
C++

#ifndef COMMAND_LINE_HPP
#define COMMAND_LINE_HPP
#include <iostream>
#include <string>
#include <variant>
#include <vector>
// License: Public Domain
// original author: Simon Schneegans https://schneegans.github.io/tutorials/2019/08/06/commandline
// This class is a simple and effective class to parse command line arguments.
// For each possible argument it stores a pointer to a variable. When the
// corresponding argument is set on the command line (given to the parse()
// method) the variable is set to the given value. If the option is not set,
// the variable is not touched. Hence it should be initialized to a default
// state.
// For each argument, several names (aliases) can be defined. Thus, the same
// boolean could be set via '--help' or '-h'. While not required, it is a good
// practice to precede the argument names with either '--' or '-'. Except for
// booleans, a value is expected to be given. Booleans are set to 'true' if no
// value is provided (that means they can be used as simple flags as in the
// '--help' case). Values can be given in two ways: Either the option name and
// the value should be separated by a space or by a '='. Here are some valid
// examples:
// --string="Foo Bar"
// --string "Foo Bar"
// --help
// --help=false
// --help true
class CommandLine {
public:
// These are the possible variables the options may point to. Bool and
// std::string are handled in a special way, all other values are parsed
// with a std::stringstream. This std::variant can be easily extended if
// the stream operator>> is overloaded. If not, you have to add a special
// case to the parse() method.
typedef std::variant<int32_t*,
uint32_t*,
double*,
float*,
bool*,
std::string*> Value;
// The description is printed as part of the help message.
explicit CommandLine(std::string description);
// Adds a possible option. A typical call would be like this:
// bool printHelp = false;
// cmd.addArgument({"--help", "-h"}, &printHelp, "Print this help message");
// Then, after parse() has been called, printHelp will be true if the user
// provided the flag.
void addArgument(std::vector<std::string> const& flags,
Value const& value, std::string const& help);
// Prints the description given to the constructor and the help
// for each option.
void printHelp(std::ostream& os = std::cout) const;
// The command line arguments are traversed from start to end. That means,
// if an option is set multiple times, the last will be the one which is
// finally used. This call will throw a std::runtime_error if a value is
// missing for a given option. Unknown flags will cause a warning on
// std::cerr.
void parse(int argc, char* argv[]) const;
private:
struct Argument {
std::vector<std::string> mFlags;
Value mValue;
std::string mHelp;
};
std::string mDescription;
std::vector<Argument> mArguments;
};
#endif // COMMAND_LINE_HPP