1 // LAF Base Library
2 // Copyright (c) 2001-2016 David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6 
7 #ifndef BASE_PROGRAM_OPTIONS_H_INCLUDED
8 #define BASE_PROGRAM_OPTIONS_H_INCLUDED
9 #pragma once
10 
11 #include <string>
12 #include <vector>
13 #include <iosfwd>
14 #include <stdexcept>
15 
16 namespace base {
17 
18   class InvalidProgramOption : public std::runtime_error {
19   public:
InvalidProgramOption(const std::string & msg)20     InvalidProgramOption(const std::string& msg)
21       : std::runtime_error(msg) { }
22   };
23 
24   class InvalidProgramOptionsCombination : public std::runtime_error {
25   public:
InvalidProgramOptionsCombination(const std::string & msg)26     InvalidProgramOptionsCombination(const std::string& msg)
27       : std::runtime_error(msg) { }
28   };
29 
30   class ProgramOptionNeedsValue : public std::runtime_error {
31   public:
ProgramOptionNeedsValue(const std::string & msg)32     ProgramOptionNeedsValue(const std::string& msg)
33       : std::runtime_error(msg) { }
34   };
35 
36   class ProgramOptions {
37   public:
38     class Option {
39     public:
Option(const std::string & name)40       Option(const std::string& name)
41         : m_name(name)
42         , m_mnemonic(0) {
43       }
44       // Getters
name()45       const std::string& name() const { return m_name; }
alias()46       const std::string& alias() const { return m_alias; }
description()47       const std::string& description() const { return m_description; }
getValueName()48       const std::string& getValueName() const { return m_valueName; }
mnemonic()49       char mnemonic() const { return m_mnemonic; }
doesRequireValue()50       bool doesRequireValue() const { return !m_valueName.empty(); }
51       // Setters
alias(const std::string & alias)52       Option& alias(const std::string& alias) { m_alias = alias; return *this; }
description(const std::string & desc)53       Option& description(const std::string& desc) { m_description = desc; return *this; }
mnemonic(char mnemonic)54       Option& mnemonic(char mnemonic) { m_mnemonic = mnemonic; return *this; }
requiresValue(const std::string & valueName)55       Option& requiresValue(const std::string& valueName) {
56         m_valueName = valueName;
57         return *this;
58       }
59     private:
60       std::string m_name;        // Name of the option (e.g. "help" for "--help")
61       std::string m_alias;
62       std::string m_description; // Description of the option (this can be used when the help is printed).
63       std::string m_valueName;   // Empty if this option doesn't require a value, or the name of the expected value.
64       char m_mnemonic;           // One character that can be used in the command line to use this option.
65 
66       friend class ProgramOptions;
67     };
68 
69     class Value {
70     public:
Value(Option * option,const std::string & value)71       Value(Option* option, const std::string& value)
72         : m_option(option)
73         , m_value(value) {
74       }
option()75       const Option* option() const { return m_option; }
value()76       const std::string& value() const { return m_value; }
77     private:
78       Option* m_option;
79       std::string m_value;
80     };
81 
82     typedef std::vector<Option*> OptionList;
83     typedef std::vector<Value> ValueList;
84 
85     ProgramOptions();
86 
87     // After destructing the ProgramOptions, you cannot continue using
88     // references to "Option" instances obtained through add() function.
89     ~ProgramOptions();
90 
91     // Adds a option for the program. The options must be specified
92     // before calling parse(). The returned reference must be used in
93     // the ProgramOptions lifetime.
94     Option& add(const std::string& name);
95 
96     // Detects which options where specified in the command line.
97     void parse(int argc, const char* argv[]);
98 
99     // Reset all option values/flags.
100     void reset();
101 
102     // Returns the list of available options for the user.
options()103     const OptionList& options() const { return m_options; }
104 
105     // List of specified options/values in the command line.
values()106     const ValueList& values() const { return m_values; }
107 
108     bool enabled(const Option& option) const;
109     std::string value_of(const Option& option) const;
110 
111   private:
112     OptionList m_options;
113     ValueList m_values;
114   };
115 
116 } // namespace base
117 
118 // Prints the program options correctly formatted to be read by
119 // the user. E.g. This can be used in a --help option.
120 std::ostream& operator<<(std::ostream& os, const base::ProgramOptions& po);
121 
122 #endif
123