advgetopt 2.0.47
Parse complex command line arguments and configuration files in C++.
validator_double.cpp
Go to the documentation of this file.
1// Copyright (c) 2006-2024 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
27// self
28//
30
31
32// cppthread
33//
34#include <cppthread/log.h>
35
36
37// snapdev
38//
39#include <snapdev/not_used.h>
40#include <snapdev/trim_string.h>
41
42
43// last include
44//
45#include <snapdev/poison.h>
46
47
48
49
50namespace advgetopt
51{
52
53
54
55namespace
56{
57
58
60 : public validator_factory
61{
62public:
64 {
65 validator::register_validator(*this);
66 }
67
68 virtual std::string get_name() const override
69 {
70 return std::string("double");
71 }
72
73 virtual std::shared_ptr<validator> create(string_list_t const & data) const override
74 {
75 snapdev::NOT_USED(data); // ignore `data`
76 return std::make_shared<validator_double>(data);
77 }
78};
79
81
82
83} // no name namespace
84
85
86
87
134{
136 for(auto r : range_list)
137 {
138 std::string::size_type const pos(r.find("..."));
139 if(pos == std::string::npos)
140 {
141 if(!convert_string(r, range.f_minimum))
142 {
143 cppthread::log << cppthread::log_level_t::error
144 << r
145 << " is not a valid standalone value;"
146 " it must be a valid floating point,"
147 " optionally preceeded by a sign (+ or -)."
148 << cppthread::end;
149 continue;
150 }
151 range.f_maximum = range.f_minimum;
152 }
153 else
154 {
155 std::string const min_value(snapdev::trim_string(r.substr(0, pos)));
156 if(!min_value.empty())
157 {
158 if(!convert_string(min_value, range.f_minimum))
159 {
160 cppthread::log << cppthread::log_level_t::error
161 << min_value
162 << " is not a valid value for your range's start;"
163 " it must be a valid floating point,"
164 " optionally preceeded by a sign (+ or -)."
165 << cppthread::end;
166 continue;
167 }
168 }
169
170 std::string const max_value(snapdev::trim_string(r.substr(pos + 3)));
171 if(!max_value.empty())
172 {
173 if(!convert_string(max_value, range.f_maximum))
174 {
175 cppthread::log << cppthread::log_level_t::error
176 << max_value
177 << " is not a valid value for your range's end;"
178 " it must be a valid floating point,"
179 " optionally preceeded by a sign (+ or -)."
180 << cppthread::end;
181 continue;
182 }
183 }
184
185 if(range.f_minimum > range.f_maximum)
186 {
187 cppthread::log << cppthread::log_level_t::error
188 << min_value
189 << " has to be smaller or equal to "
190 << max_value
191 << "; you have an invalid range."
192 << cppthread::end;
193 continue;
194 }
195 }
196 f_allowed_values.push_back(range);
197 }
198}
199
200
207std::string validator_double::name() const
208{
209 return std::string("double");
210}
211
212
230bool validator_double::validate(std::string const & value) const
231{
232 double result(0.0);
233 if(convert_string(value, result))
234 {
235 if(f_allowed_values.empty())
236 {
237 return true;
238 }
239
240 for(auto f : f_allowed_values)
241 {
242 if(result >= f.f_minimum
243 && result <= f.f_maximum)
244 {
245 return true;
246 }
247 }
248 return false;
249 }
250
251 return false;
252}
253
254
273bool validator_double::convert_string(std::string const & value, double & result)
274{
275 char const * start(value.c_str());
276
277 // do not allow spaces before the number
278 //
279 if(start[0] != '+'
280 && start[0] != '-'
281 && (start[0] < '0' || start[0] > '9'))
282 {
283 return false;
284 }
285
286 char * end(nullptr);
287 errno = 0;
288 result = std::strtod(start, &end);
289
290 // do not allow anything after the last digit
291 // also return false on an overflow
292 //
293 return end == start + value.length()
294 && errno != ERANGE;
295}
296
297
298
299} // namespace advgetopt
300// vim: ts=4 sw=4 et
virtual std::shared_ptr< validator > create(string_list_t const &data) const override
virtual bool validate(std::string const &value) const override
Determine whether value is a double.
virtual std::string name() const override
Return the name of this validator.
range_t::vector_t f_allowed_values
static bool convert_string(std::string const &number, double &result)
Convert a string to a double value.
validator_double(string_list_t const &data)
Initialize the double validator.
The advgetopt environment to parse command line options.
constexpr flag_t option_flags_merge()
Definition flags.h:87
std::vector< std::string > string_list_t
Definition utils.h:41
Declaration of validators which can be used to verify the parameters.

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.