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 : /** \file
21 : * \brief Implementation of the regular expression validator.
22 : *
23 : * The regular expression validator allows us to check pretty much any type
24 : * of value.
25 : *
26 : * This validator does not offer a convertor since a regular expression
27 : * does not really offer such a feature.
28 : */
29 :
30 : // self
31 : //
32 : #include "advgetopt/validator_regex.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 : // last include
56 : //
57 : #include <snapdev/poison.h>
58 :
59 :
60 :
61 :
62 : namespace advgetopt
63 : {
64 :
65 :
66 :
67 : namespace
68 : {
69 :
70 :
71 :
72 2 : class validator_regex_factory
73 : : public validator_factory
74 : {
75 : public:
76 2 : validator_regex_factory()
77 2 : {
78 2 : validator::register_validator(*this);
79 2 : }
80 :
81 4 : virtual std::string get_name() const override
82 : {
83 4 : return std::string("regex");
84 : }
85 :
86 18 : virtual std::shared_ptr<validator> create(string_list_t const & data) const override
87 : {
88 18 : return std::make_shared<validator_regex>(data);
89 : }
90 : };
91 :
92 2 : validator_regex_factory g_validator_regex_factory;
93 :
94 :
95 :
96 : } // no name namespace
97 :
98 :
99 :
100 :
101 :
102 18 : validator_regex::validator_regex(string_list_t const & regex_list)
103 : {
104 18 : if(regex_list.size() > 1)
105 : {
106 8 : cppthread::log << cppthread::log_level_t::error
107 4 : << "validator_regex() only supports one parameter; "
108 8 : << regex_list.size()
109 4 : << " were supplied; single or double quotation may be required?"
110 12 : << cppthread::end;
111 4 : return;
112 : }
113 :
114 28 : std::string regex;
115 14 : if(!regex_list.empty())
116 : {
117 14 : regex = regex_list[0];
118 : }
119 14 : std::regex::flag_type flags = std::regex_constants::extended;
120 28 : if(regex.length() >= 2
121 14 : && regex[0] == '/')
122 : {
123 11 : auto it(regex.end());
124 30 : for(--it; it != regex.begin(); --it)
125 : {
126 29 : if(*it == '/')
127 : {
128 10 : break;
129 : }
130 19 : switch(*it)
131 : {
132 4 : case 'i':
133 4 : flags |= std::regex_constants::icase;
134 4 : break;
135 :
136 15 : default:
137 30 : cppthread::log << cppthread::log_level_t::error
138 15 : << "unsupported regex flag "
139 15 : << *it
140 15 : << " in regular expression \""
141 15 : << regex
142 15 : << "\"."
143 30 : << cppthread::end;
144 15 : break;
145 :
146 : }
147 : }
148 11 : if(it == regex.begin())
149 : {
150 2 : cppthread::log << cppthread::log_level_t::error
151 1 : << "invalid regex definition, ending / is missing in \""
152 1 : << regex
153 1 : << "\"."
154 2 : << cppthread::end;
155 :
156 1 : f_regex = std::regex(std::string(regex.begin() + 1, regex.end()), flags);
157 : }
158 : else
159 : {
160 10 : f_regex = std::regex(std::string(regex.begin() + 1, it), flags);
161 : }
162 : }
163 : else
164 : {
165 3 : f_regex = std::regex(regex, flags);
166 : }
167 : }
168 :
169 :
170 : /** \brief Return the name of this validator.
171 : *
172 : * This function returns "regex".
173 : *
174 : * \return "regex".
175 : */
176 7 : std::string const validator_regex::name() const
177 : {
178 7 : return std::string("regex");
179 : }
180 :
181 :
182 : /** \brief Check the value against a regular expression.
183 : *
184 : * This function is used to match the value of an argument against a
185 : * regular expression. It returns true when it does match.
186 : *
187 : * \param[in] value The value to be validated.
188 : *
189 : * \return true on a match.
190 : */
191 72 : bool validator_regex::validate(std::string const & value) const
192 : {
193 144 : std::smatch info;
194 144 : return std::regex_match(value, info, f_regex);
195 : }
196 :
197 :
198 :
199 6 : } // namespace advgetopt
200 : // vim: ts=4 sw=4 et
|