1
2//
3// This source file is part of appleseed.
4// Visit http://appleseedhq.net/ for additional information and resources.
5//
6// This software is released under the MIT license.
7//
8// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
9// Copyright (c) 2014-2017 Francois Beaune, The appleseedhq Organization
10//
11// Permission is hereby granted, free of charge, to any person obtaining a copy
12// of this software and associated documentation files (the "Software"), to deal
13// in the Software without restriction, including without limitation the rights
14// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15// copies of the Software, and to permit persons to whom the Software is
16// furnished to do so, subject to the following conditions:
17//
18// The above copyright notice and this permission notice shall be included in
19// all copies or substantial portions of the Software.
20//
21// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27// THE SOFTWARE.
28//
29
30#ifndef APPLESEED_FOUNDATION_UTILITY_COMMANDLINEPARSER_OPTIONHANDLER_H
31#define APPLESEED_FOUNDATION_UTILITY_COMMANDLINEPARSER_OPTIONHANDLER_H
32
33// appleseed.foundation headers.
34#include "foundation/core/concepts/noncopyable.h"
35#include "foundation/utility/foreach.h"
36
37// Standard headers.
38#include <cstddef>
39#include <string>
40#include <vector>
41
42// Forward declarations.
43namespace foundation { class ParseResults; }
44
45namespace foundation
46{
47
48//
49// A vector of strings.
50//
51
52typedef std::vector<std::string> StringVector;
53
54
55//
56// Base class for option handlers.
57//
58
59class OptionHandler
60 : public NonCopyable
61{
62 public:
63 // Flags.
64 enum Flags
65 {
66 None = 0, // none of the flags below are set
67 Required = 1 << 0, // this option is required and must appear on the command line
68 Hidden = 1 << 1, // don't list this option in program usage
69 Repeatable = 1 << 2 // this option can appear multiple times on a command line
70 };
71
72 // Constructor.
73 OptionHandler();
74
75 // Add a name for this option.
76 OptionHandler& add_name(const std::string& name);
77
78 // Set a description of this option.
79 OptionHandler& set_description(const std::string& description);
80
81 // Set the syntax for this option.
82 OptionHandler& set_syntax(const std::string& syntax);
83
84 // Set the flags for this option.
85 OptionHandler& set_flags(const Flags flags);
86
87 // Return true if this option is set.
88 virtual bool is_set() const;
89
90 protected:
91 friend class CommandLineParser;
92
93 StringVector m_names;
94 std::string m_description;
95 std::string m_syntax;
96 Flags m_flags;
97 size_t m_occurrence_count;
98
99 // Return a description of this option.
100 // The returned value may be different than what was set with set_description().
101 virtual std::string get_description() const;
102
103 // Return the maximum number of values this option can handle.
104 virtual size_t get_max_value_count() const = 0;
105
106 // Parse a vector of values.
107 virtual void parse(
108 const std::string& name,
109 const StringVector& values,
110 ParseResults& results) = 0;
111
112 // Print this option to a string.
113 virtual void print(std::string& s) const = 0;
114
115 // Return true if an argument matches any of the name of this option.
116 bool match_name(const std::string& arg) const;
117};
118
119
120//
121// OptionHandler class implementation.
122//
123
124inline OptionHandler::OptionHandler()
125 : m_flags(None)
126 , m_occurrence_count(0)
127{
128}
129
130inline OptionHandler& OptionHandler::add_name(const std::string& name)
131{
132 m_names.push_back(name);
133 return *this;
134}
135
136inline OptionHandler& OptionHandler::set_description(const std::string& description)
137{
138 m_description = description;
139 return *this;
140}
141
142inline OptionHandler& OptionHandler::set_syntax(const std::string& syntax)
143{
144 m_syntax = syntax;
145 return *this;
146}
147
148inline OptionHandler& OptionHandler::set_flags(const Flags flags)
149{
150 m_flags = flags;
151 return *this;
152}
153
154inline bool OptionHandler::is_set() const
155{
156 return m_occurrence_count > 0;
157}
158
159inline std::string OptionHandler::get_description() const
160{
161 return m_description;
162}
163
164inline bool OptionHandler::match_name(const std::string& arg) const
165{
166 for (const_each<StringVector> i = m_names; i; ++i)
167 {
168 if (arg == *i)
169 return true;
170 }
171
172 return false;
173}
174
175} // namespace foundation
176
177#endif // !APPLESEED_FOUNDATION_UTILITY_COMMANDLINEPARSER_OPTIONHANDLER_H
178