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 :
20 :
21 : /** \file
22 : * \brief Advanced getopt version functions.
23 : *
24 : * The advgetopt environment is versioned. The functions available here
25 : * give you access to the version, in case you wanted to make sure you
26 : * had a minimum version or had some special case options when you
27 : * want to be able to support various versions.
28 : */
29 :
30 : // self
31 : //
32 : #include "advgetopt/validator.h"
33 :
34 :
35 : // advgetopt lib
36 : //
37 : #include "advgetopt/exception.h"
38 :
39 :
40 : // cppthread lib
41 : //
42 : #include <cppthread/log.h>
43 :
44 :
45 : // snapdev lib
46 : //
47 : #include <snapdev/not_used.h>
48 :
49 :
50 : // boost lib
51 : //
52 : #include <boost/algorithm/string/trim.hpp>
53 :
54 :
55 : // C++ lib
56 : //
57 : #include <map>
58 :
59 :
60 : // last include
61 : //
62 : #include <snapdev/poison.h>
63 :
64 :
65 :
66 :
67 : namespace advgetopt
68 : {
69 :
70 :
71 :
72 : namespace
73 : {
74 :
75 :
76 2 : std::map<std::string, validator_factory const *> g_validator_factories;
77 :
78 :
79 : } // no name namespace
80 :
81 :
82 :
83 : /** \brief The destructor to ease derived classes.
84 : *
85 : * At this point this destructor does nothing more than help with the
86 : * virtual table.
87 : */
88 11 : validator_factory::~validator_factory()
89 : {
90 11 : }
91 :
92 :
93 :
94 :
95 :
96 :
97 : /** \brief The validator destructor to support virtuals.
98 : *
99 : * This destructor is defined so virtual functions work as expected including
100 : * the deleter.
101 : */
102 113 : validator::~validator()
103 : {
104 113 : }
105 :
106 :
107 : /** \fn std::string const & validator::name() const;
108 : * \brief Return the name of the validator.
109 : *
110 : * The name() function is used to get the name of the validator.
111 : * Validators are recognized by name and added to your options
112 : * using their name.
113 : *
114 : * Note that when an option specifies a validator which it can't find,
115 : * then an error occurs.
116 : *
117 : * \return The name of the validator.
118 : */
119 :
120 :
121 : /** \fn bool validator::validate(std::string const & value) const;
122 : * \brief Return true if \p value validates agains this validator.
123 : *
124 : * The function parses the \p value parameter and if it matches the
125 : * allowed parameters, then it returns true.
126 : *
127 : * \param[in] value The value to validate.
128 : *
129 : * \return true if the value validates.
130 : */
131 :
132 :
133 11 : void validator::register_validator(validator_factory const & factory)
134 : {
135 11 : auto it(g_validator_factories.find(factory.get_name()));
136 11 : if(it != g_validator_factories.end())
137 : {
138 : throw getopt_logic_error(
139 : "you have two or more validator factories named \""
140 2 : + factory.get_name()
141 3 : + "\".");
142 : }
143 10 : g_validator_factories[factory.get_name()] = &factory;
144 10 : }
145 :
146 :
147 114 : validator::pointer_t validator::create(std::string const & name, string_list_t const & data)
148 : {
149 114 : auto it(g_validator_factories.find(name));
150 114 : if(it == g_validator_factories.end())
151 : {
152 1 : return validator::pointer_t();
153 : }
154 :
155 113 : return it->second->create(data);
156 : }
157 :
158 :
159 : /** \brief Set the validator for this option.
160 : *
161 : * This function parses the specified name and optional parameters and
162 : * create a corresponding validator for this option.
163 : *
164 : * The \p name_and_params string can be defined as:
165 : *
166 : * \code
167 : * <validator-name>(<param1>, <param2>, ...)
168 : * \endcode
169 : *
170 : * The list of parameters is optional. There may be an empty, just one,
171 : * or any number of parameters. How the parameters are parsed is left
172 : * to the validator to decide.
173 : *
174 : * If the input string is empty, the current validator, if one is
175 : * installed, gets removed.
176 : *
177 : * \param[in] name_and_params The validator name and parameters.
178 : */
179 34 : validator::pointer_t validator::create(std::string const & name_and_params)
180 : {
181 34 : if(name_and_params.empty())
182 : {
183 15 : return validator::pointer_t();
184 : }
185 :
186 38 : if(name_and_params.length() >= 2
187 19 : && name_and_params[0] == '/')
188 : {
189 : // for the regex we have a special case
190 : //
191 14 : string_list_t data{name_and_params};
192 7 : return create("regex", data);
193 : }
194 : else
195 : {
196 12 : std::string::size_type const params(name_and_params.find('('));
197 24 : std::string name(name_and_params);
198 24 : string_list_t data;
199 12 : if(params != std::string::npos)
200 : {
201 10 : if(name_and_params.back() != ')')
202 : {
203 : throw getopt_logic_error(
204 : "invalid validator parameter definition: \""
205 8 : + name_and_params
206 12 : + "\", the ')' is missing.");
207 : }
208 6 : name = name_and_params.substr(0, params);
209 12 : split_string(name_and_params.substr(params + 1, name_and_params.length() - params - 2)
210 : , data
211 6 : , {","});
212 : }
213 8 : return create(name, data);
214 : }
215 : }
216 :
217 :
218 :
219 6 : } // namespace advgetopt
220 : // vim: ts=4 sw=4 et
|