/** \file \brief Declares the CommandLine class. \author \kpr */ #ifndef MUTILS_COMMANDLINE_H #define MUTILS_COMMANDLINE_H #include #include "mutils/util.h" namespace mutils { // Forward reference. class Options; /** \headerfile CommandLine.h \brief Command line options and arguments. This class manages command line options and arguments for an application. Its functionality is similar to the POSIX `getopt()` routine, but the API is structured to allow command line options to be retrieved in independent segments controlled by different callers. The command line interface accepts [POSIX command line syntax]( http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html), including support for GNU-style long options (e.g., `--help`), with the extension that short (single-character) options---like long options---may attach their value using an equals sign; e.g., `-f FILE` and `-f=FILE` are interchangeable, as are `--file FILE` and `--file=FILE`. The complete command line is parsed into options (with or without values) and trailing arguments which are stored for later access. Callers then query for individual options in whatever order they find convenient; this allows queries to be divided among modules as appropriate. %Options can have both short and long names and take a value, as indicated by the caller. It is permitted for the same option to be supplied multiple times on the command line; when queried, the option count and all values, if applicable, are returned. \who \kpr */ class CommandLine { public: /// Command line arguments type. typedef std::vector Arguments; /** \headerfile CommandLine.h \brief Command line option specification. Defines the dynamic command line interface for a single option. Each option has a corresponding Options file keyword, allowing automated processing of arbitrary command line arguments. Users of this structure should note the following special values: - If \a shortName is `'\0'`, there is no single-character option name. - If \a longName is empty, there is no long option name. - If \a valueName is empty, the option does not take a value. - If \a keyName is empty, then keyword() should be used. - If \a keyName is #nullStr, the option is private to the command line. */ struct Option { char shortName; ///< Short option name. std::string longName; ///< Long option name. std::string valueName; ///< Value name (for \--help). std::string scopeName; ///< Associated Options scope name. std::string sectName; ///< Associated Options section name. std::string keyName; ///< Associated Options keyword name. std::string helpText; ///< %Option description (for \--help). /** \brief Standard Options keyword name for this option. Returns \a keyName if not empty, else the default keyword name. The default keyword name is \a longName with hyphens removed and each term capitalized; e.g., `log-file` becomes `LogFile`. If \a longName is also empty, the single-character \a shortName (converted to uppercase) is used. \return Keyword string. */ std::string keyword() const { std::string shortStr(1, shortName); std::string key = (!keyName.empty() ? keyName : longName.empty() ? shortStr : longName); if (keyName == nullStr || keyName.empty()) { std::string::size_type pos = 0; while (pos < key.size()) { key[pos] = toupper(key[pos]); pos = key.find_first_of('-', pos); if (pos != npos) { key.erase(pos, 1); } } } return key; } /// Command line option source information (for Options::MetaValues). std::string source() const { std::string src = "CommandLine["; if (! longName.empty()) { src += "--"; src += longName; } else { src += '-'; src += toupper(shortName); } src += ']'; return src; } }; /// Default constructor. CommandLine() : validOpts_(nullptr) { } /// Destructor. ~CommandLine() { } /// Initializes new command line input. void init(int argc, char *argv[], const std::vector