Line data Source code
1 : /*
2 : * File:
3 : * advgetopt/options.h -- a replacement to the Unix getopt() implementation
4 : *
5 : * License:
6 : * Copyright (c) 2006-2019 Made to Order Software Corp. All Rights Reserved
7 : *
8 : * https://snapwebsites.org/
9 : * contact@m2osw.com
10 : *
11 : * This program is free software; you can redistribute it and/or modify
12 : * it under the terms of the GNU General Public License as published by
13 : * the Free Software Foundation; either version 2 of the License, or
14 : * (at your option) any later version.
15 : *
16 : * This program is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU General Public License for more details.
20 : *
21 : * You should have received a copy of the GNU General Public License along
22 : * with this program; if not, write to the Free Software Foundation, Inc.,
23 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 : *
25 : * Authors:
26 : * Alexis Wilke alexis@m2osw.com
27 : * Doug Barbieri doug@m2osw.com
28 : */
29 : #pragma once
30 :
31 : /** \file
32 : * \brief Definitions of the options class a initialization functions.
33 : *
34 : * The advgetopt library offers an advanced way to manage your command
35 : * line tools options on the command line, in environment variables, and
36 : * in configuration files.
37 : */
38 :
39 : //// advgetopt lib
40 : ////
41 : //#include "advgetopt/option_info.h"
42 :
43 : // C++ lib
44 : //
45 : #include <cstdint>
46 :
47 :
48 :
49 : namespace advgetopt
50 : {
51 :
52 :
53 :
54 : typedef std::uint32_t flag_t;
55 :
56 : static constexpr flag_t GETOPT_FLAG_NONE = static_cast<flag_t>(0x00000000);
57 :
58 : static constexpr flag_t GETOPT_FLAG_COMMAND_LINE = static_cast<flag_t>(0x00000001); // acceptable on the command line
59 : static constexpr flag_t GETOPT_FLAG_ENVIRONMENT_VARIABLE = static_cast<flag_t>(0x00000002); // acceptable in environment variable
60 : static constexpr flag_t GETOPT_FLAG_CONFIGURATION_FILE = static_cast<flag_t>(0x00000004); // acceptable in configuration files
61 :
62 : static constexpr flag_t GETOPT_FLAG_ALIAS = static_cast<flag_t>(0x00000010); // alias, result in another option defined in "help" string
63 : static constexpr flag_t GETOPT_FLAG_FLAG = static_cast<flag_t>(0x00000020); // no parameter allowed (--help)
64 : static constexpr flag_t GETOPT_FLAG_REQUIRED = static_cast<flag_t>(0x00000040); // required (--host 127.0.0.1)
65 : static constexpr flag_t GETOPT_FLAG_MULTIPLE = static_cast<flag_t>(0x00000080); // any number of parameter is allowed (--files a b c d ...)
66 : static constexpr flag_t GETOPT_FLAG_DEFAULT_OPTION = static_cast<flag_t>(0x00000100); // where entries go by default (a.k.a. after "--")
67 : static constexpr flag_t GETOPT_FLAG_HAS_DEFAULT = static_cast<flag_t>(0x00000200); // default value is defined
68 :
69 : static constexpr flag_t GETOPT_FLAG_SHOW_MOST = static_cast<flag_t>(0x00000000); // show in usage() when not in GROUP1 or GROUP2
70 : static constexpr flag_t GETOPT_FLAG_SHOW_USAGE_ON_ERROR = static_cast<flag_t>(0x00001000); // show in usage() when an error occurs
71 : static constexpr flag_t GETOPT_FLAG_SHOW_ALL = static_cast<flag_t>(0x00002000); // show in usage() when --long-help is used
72 : static constexpr flag_t GETOPT_FLAG_SHOW_GROUP1 = static_cast<flag_t>(0x00004000); // show in usage() when --<group1>-help is used (app dependent)
73 : static constexpr flag_t GETOPT_FLAG_SHOW_GROUP2 = static_cast<flag_t>(0x00008000); // show in usage() when --<group2>-help is used (app dependent)
74 :
75 : static constexpr flag_t GETOPT_FLAG_GROUP_MASK = static_cast<flag_t>(0x00700000);
76 : static constexpr flag_t GETOPT_FLAG_GROUP_MINIMUM = static_cast<flag_t>(0);
77 : static constexpr flag_t GETOPT_FLAG_GROUP_MAXIMUM = static_cast<flag_t>(7);
78 : static constexpr flag_t GETOPT_FLAG_GROUP_SHIFT = static_cast<flag_t>(20);
79 : static constexpr flag_t GETOPT_FLAG_GROUP_NONE = static_cast<flag_t>(0x00000000); // not in a group
80 : static constexpr flag_t GETOPT_FLAG_GROUP_COMMANDS = static_cast<flag_t>(0x00100000); // in command group (group 1)
81 : static constexpr flag_t GETOPT_FLAG_GROUP_OPTIONS = static_cast<flag_t>(0x00200000); // in option group (group 2)
82 : static constexpr flag_t GETOPT_FLAG_GROUP_THREE = static_cast<flag_t>(0x00300000); // in group 3
83 : static constexpr flag_t GETOPT_FLAG_GROUP_FOUR = static_cast<flag_t>(0x00400000); // in group 4
84 : static constexpr flag_t GETOPT_FLAG_GROUP_FIVE = static_cast<flag_t>(0x00500000); // in group 5
85 : static constexpr flag_t GETOPT_FLAG_GROUP_SIX = static_cast<flag_t>(0x00600000); // in group 6
86 : static constexpr flag_t GETOPT_FLAG_GROUP_SEVEN = static_cast<flag_t>(0x00700000); // in group 7
87 :
88 : static constexpr flag_t GETOPT_FLAG_DYNAMIC = static_cast<flag_t>(0x20000000); // this value was found in a configuration file and dynamic parameters are allowed (i.e. no definition for this option was found)
89 : static constexpr flag_t GETOPT_FLAG_LOCK = static_cast<flag_t>(0x40000000); // this value is currently locked (can't be modified)
90 :
91 : static constexpr flag_t GETOPT_FLAG_END = static_cast<flag_t>(0x80000000); // mark the end of the list
92 :
93 :
94 :
95 : template<class none = void>
96 : constexpr flag_t option_flags_merge()
97 : {
98 : return GETOPT_FLAG_NONE;
99 : }
100 :
101 :
102 : template<flag_t flag, flag_t ...args>
103 : constexpr flag_t option_flags_merge()
104 : {
105 : static_assert((flag & GETOPT_FLAG_GROUP_MASK) == 0
106 : || (option_flags_merge<args...>() & GETOPT_FLAG_GROUP_MASK) == 0
107 : , "more than one GETOPT_FLAG_GROUP_... is not allowed within one set of flags.");
108 :
109 : return flag | option_flags_merge<args...>();
110 : }
111 :
112 :
113 : template<flag_t flag, flag_t ...args>
114 : constexpr flag_t combine_option_flags()
115 : {
116 : constexpr flag_t result(option_flags_merge<flag, args...>());
117 :
118 : static_assert(static_cast<int>((result & GETOPT_FLAG_FLAG) != 0)
119 : + static_cast<int>((result & (GETOPT_FLAG_REQUIRED | GETOPT_FLAG_MULTIPLE | GETOPT_FLAG_DEFAULT_OPTION)) != 0)
120 : + static_cast<int>((result & GETOPT_FLAG_END) != 0)
121 : <= 1
122 : , "flag GETOPT_FLAG_FLAG is not compatible with any of GETOPT_FLAG_REQUIRED | GETOPT_FLAG_MULTIPLE | GETOPT_FLAG_DEFAULT_OPTION or none of these flags were specified.");
123 :
124 : static_assert(((result & (GETOPT_FLAG_COMMAND_LINE | GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE)) != 0)
125 : ^ ((result & GETOPT_FLAG_END) != 0)
126 : , "flags must include at least one of GETOPT_FLAG_COMMAND_LINE | GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE or be set to GETOPT_FLAG_END");
127 :
128 : return result;
129 : }
130 :
131 :
132 : constexpr flag_t end_flags()
133 : {
134 : return combine_option_flags<GETOPT_FLAG_END>();
135 : }
136 :
137 :
138 : template<flag_t ...args>
139 : constexpr flag_t any_flags()
140 : {
141 : constexpr flag_t result(combine_option_flags<args...>());
142 :
143 : static_assert((result & GETOPT_FLAG_END) == 0
144 : , "an option_flag() cannot include GETOPT_FLAG_END");
145 :
146 : return result;
147 : }
148 :
149 :
150 : template<flag_t ...args>
151 : constexpr flag_t option_flags()
152 : {
153 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_FLAG, args...>());
154 :
155 : //static_assert((result & (GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE)) == 0
156 : // , "an option_flag() cannot include GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE");
157 :
158 : return result;
159 : }
160 :
161 :
162 : template<flag_t ...args>
163 5 : constexpr flag_t all_flags()
164 : {
165 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_COMMAND_LINE
166 : , GETOPT_FLAG_ENVIRONMENT_VARIABLE
167 : , GETOPT_FLAG_CONFIGURATION_FILE
168 5 : , args...>());
169 :
170 5 : return result;
171 : }
172 :
173 :
174 : template<flag_t ...args>
175 : constexpr flag_t standalone_all_flags()
176 : {
177 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_COMMAND_LINE
178 : , GETOPT_FLAG_ENVIRONMENT_VARIABLE
179 : , GETOPT_FLAG_CONFIGURATION_FILE
180 : , GETOPT_FLAG_FLAG
181 : , args...>());
182 :
183 : return result;
184 : }
185 :
186 :
187 : template<flag_t ...args>
188 : constexpr flag_t standalone_command_flags()
189 : {
190 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_COMMAND_LINE, GETOPT_FLAG_FLAG, args...>());
191 :
192 : static_assert((result & (GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE)) == 0
193 : , "an option_flag() cannot include GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE");
194 :
195 : return result;
196 : }
197 :
198 :
199 : template<flag_t ...args>
200 13 : constexpr flag_t command_flags()
201 : {
202 13 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_COMMAND_LINE, args...>());
203 :
204 : static_assert((result & (GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE)) == 0
205 : , "an option_flag() cannot include GETOPT_FLAG_ENVIRONMENT_VARIABLE | GETOPT_FLAG_CONFIGURATION_FILE");
206 :
207 13 : return result;
208 : }
209 :
210 :
211 : template<flag_t ...args>
212 : constexpr flag_t var_flags()
213 : {
214 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_ENVIRONMENT_VARIABLE, args...>());
215 :
216 : static_assert((result & (GETOPT_FLAG_COMMAND_LINE | GETOPT_FLAG_CONFIGURATION_FILE)) == 0
217 : , "a config_flag() cannot include GETOPT_FLAG_COMMAND_LINE | GETOPT_FLAG_CONFIGURATION_FILE");
218 :
219 : return result;
220 : }
221 :
222 :
223 : template<flag_t ...args>
224 : constexpr flag_t config_flags()
225 : {
226 : constexpr flag_t result(combine_option_flags<GETOPT_FLAG_CONFIGURATION_FILE, GETOPT_FLAG_FLAG, args...>());
227 :
228 : static_assert((result & (GETOPT_FLAG_COMMAND_LINE | GETOPT_FLAG_ENVIRONMENT_VARIABLE)) == 0
229 : , "a config_flag() cannot include GETOPT_FLAG_COMMAND_LINE | GETOPT_FLAG_ENVIRONMENT_VARIABLE");
230 :
231 : return result;
232 : }
233 :
234 :
235 :
236 :
237 :
238 :
239 : } // namespace advgetopt
240 : // vim: ts=4 sw=4 et
|