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