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
16namespace base {
17
18 class InvalidProgramOption : public std::runtime_error {
19 public:
20 InvalidProgramOption(const std::string& msg)
21 : std::runtime_error(msg) { }
22 };
23
24 class InvalidProgramOptionsCombination : public std::runtime_error {
25 public:
26 InvalidProgramOptionsCombination(const std::string& msg)
27 : std::runtime_error(msg) { }
28 };
29
30 class ProgramOptionNeedsValue : public std::runtime_error {
31 public:
32 ProgramOptionNeedsValue(const std::string& msg)
33 : std::runtime_error(msg) { }
34 };
35
36 class ProgramOptions {
37 public:
38 class Option {
39 public:
40 Option(const std::string& name)
41 : m_name(name)
42 , m_mnemonic(0) {
43 }
44 // Getters
45 const std::string& name() const { return m_name; }
46 const std::string& alias() const { return m_alias; }
47 const std::string& description() const { return m_description; }
48 const std::string& getValueName() const { return m_valueName; }
49 char mnemonic() const { return m_mnemonic; }
50 bool doesRequireValue() const { return !m_valueName.empty(); }
51 // Setters
52 Option& alias(const std::string& alias) { m_alias = alias; return *this; }
53 Option& description(const std::string& desc) { m_description = desc; return *this; }
54 Option& mnemonic(char mnemonic) { m_mnemonic = mnemonic; return *this; }
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:
71 Value(Option* option, const std::string& value)
72 : m_option(option)
73 , m_value(value) {
74 }
75 const Option* option() const { return m_option; }
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.
103 const OptionList& options() const { return m_options; }
104
105 // List of specified options/values in the command line.
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.
120std::ostream& operator<<(std::ostream& os, const base::ProgramOptions& po);
121
122#endif
123