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