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