advgetopt 2.0.49
Parse complex command line arguments and configuration files in C++.
validator_size.cpp
Go to the documentation of this file.
1// Copyright (c) 2006-2025 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
40// self
41//
43
45
46
47// cppthread
48//
49#include <cppthread/log.h>
50
51
52// snapdev
53//
54#include <snapdev/int128_literal.h>
55#include <snapdev/math.h>
56
57
58// last include
59//
60#include <snapdev/poison.h>
61
62
63
64
65namespace advgetopt
66{
67
68
69
70namespace
71{
72
73
74
76 : public validator_factory
77{
78public:
80 {
81 validator::register_validator(*this);
82 }
83
84 virtual std::string get_name() const override
85 {
86 return std::string("size");
87 }
88
89 virtual std::shared_ptr<validator> create(string_list_t const & data) const override
90 {
91 return std::make_shared<validator_size>(data);
92 }
93};
94
96
97
98
99} // no name namespace
100
101
102
103
104
130{
131 for(auto r : flag_list)
132 {
133 if(r == "si")
134 {
136 }
137 else if(r == "legacy")
138 {
140 }
141 else
142 {
143 cppthread::log << cppthread::log_level_t::error
144 << r
145 << " is not a valid flag for the size validator."
146 << cppthread::end;
147 continue;
148 }
149 }
150}
151
152
159std::string validator_size::name() const
160{
161 return std::string("size");
162}
163
164
177#pragma GCC diagnostic push
178#pragma GCC diagnostic ignored "-Wpedantic"
179bool validator_size::validate(std::string const & value) const
180{
181 using namespace snapdev::literals;
183 if(convert_string(value, f_flags, result))
184 {
185 return true;
186 }
187
188 set_error("invalid size suffix or number.");
189 return false;
190}
191#pragma GCC diagnostic pop
192
193
248#pragma GCC diagnostic push
249#pragma GCC diagnostic ignored "-Wpedantic"
251 std::string const & value
252 , flag_t flags
253 , __int128 & result)
254{
255 using namespace snapdev::literals;
256
257 // determine the factor by checking the suffix
258 //
260 std::string::size_type pos(value.length());
261 for(; pos > 0; --pos)
262 {
263 char c(value[pos - 1]);
264 if(c >= '0'
265 && c <= '9'
266 || c == '.')
267 {
268 break;
269 }
270 }
271 if(pos == 0)
272 {
273 return false;
274 }
275 __int128 const base(
277 ? 1024_int128
278 : 1000_int128);
279 std::string const number(value.substr(0, pos));
280 for(; pos < value.length() && isspace(value[pos]); ++pos);
281 if(pos < value.length())
282 {
283 // copy and force lowercase (although the case is important
284 // when writing such a measurement, it does not matter when
285 // testing here)
286 //
287 std::string suffix;
288 for(; pos < value.length(); ++pos)
289 {
290 if(value[pos] >= 'A'
291 && value[pos] <= 'Z')
292 {
293 suffix += value[pos] + 0x20;
294 }
295 else
296 {
297 suffix += value[pos];
298 }
299 }
300
301 switch(suffix[0])
302 {
303 case 'b':
304 if(suffix != "b")
305 {
306 return false;
307 }
308 break;
309
310 case 'e':
311 if(suffix == "eb")
312 {
313 factor = snapdev::pow(base, 6);
314 }
315 else if(suffix == "eib")
316 {
317 factor = snapdev::pow(1024_int128, 6);
318 }
319 else
320 {
321 return false;
322 }
323 break;
324
325 case 'g':
326 if(suffix == "gb")
327 {
328 factor = snapdev::pow(base, 3);
329 }
330 else if(suffix == "gib")
331 {
332 factor = snapdev::pow(1024_int128, 3);
333 }
334 else
335 {
336 return false;
337 }
338 break;
339
340 case 'k':
341 if(suffix == "kb")
342 {
343 factor = base;
344 }
345 else if(suffix == "kib")
346 {
347 factor = 1024_int128;
348 }
349 else
350 {
351 return false;
352 }
353 break;
354
355 case 'm':
356 if(suffix == "mb")
357 {
358 factor = snapdev::pow(base, 2);
359 }
360 else if(suffix == "mib")
361 {
362 factor = snapdev::pow(1024_int128, 2);
363 }
364 else
365 {
366 return false;
367 }
368 break;
369
370 case 'p':
371 if(suffix == "pb")
372 {
373 factor = snapdev::pow(base, 5);
374 }
375 else if(suffix == "pib")
376 {
377 factor = snapdev::pow(1024_int128, 5);
378 }
379 else
380 {
381 return false;
382 }
383 break;
384
385 case 'q':
386 if(suffix == "qb")
387 {
388 factor = snapdev::pow(base, 10);
389 }
390 else if(suffix == "qib")
391 {
392 factor = snapdev::pow(1024_int128, 10);
393 }
394 else
395 {
396 return false;
397 }
398 break;
399
400 case 'r':
401 if(suffix == "rb")
402 {
403 factor = snapdev::pow(base, 9);
404 }
405 else if(suffix == "rib")
406 {
407 factor = snapdev::pow(1024_int128, 9);
408 }
409 else
410 {
411 return false;
412 }
413 break;
414
415 case 't':
416 if(suffix == "tb")
417 {
418 factor = snapdev::pow(base, 4);
419 }
420 else if(suffix == "tib")
421 {
422 factor = snapdev::pow(1024_int128, 4);
423 }
424 else
425 {
426 return false;
427 }
428 break;
429
430 case 'y':
431 if(suffix == "yb")
432 {
433 factor = snapdev::pow(base, 8);
434 }
435 else if(suffix == "yib")
436 {
437 factor = snapdev::pow(1024_int128, 8);
438 }
439 else
440 {
441 return false;
442 }
443 break;
444
445 case 'z':
446 if(suffix == "zb")
447 {
448 factor = snapdev::pow(base, 7);
449 }
450 else if(suffix == "zib")
451 {
452 factor = snapdev::pow(1024_int128, 7);
453 }
454 else
455 {
456 return false;
457 }
458 break;
459
460 default:
461 return false;
462
463 }
464 }
465
466 double base_number(0.0);
468 {
469 return false;
470 }
471
472 // TODO: I think that even with the long double this will lose bits
473 result = static_cast<long double>(base_number) * factor;
474
475 return true;
476}
477#pragma GCC diagnostic pop
478
479
480
481} // namespace advgetopt
482// vim: ts=4 sw=4 et
virtual std::shared_ptr< validator > create(string_list_t const &data) const override
static bool convert_string(std::string const &number, double &result)
Convert a string to a double value.
static constexpr flag_t VALIDATOR_SIZE_POWER_OF_TWO
static bool convert_string(std::string const &size, flag_t flags, __int128 &result)
Convert a string to a large integer (128 bits) value representing a size.
virtual std::string name() const override
Return the name of this validator.
validator_size(string_list_t const &data)
Initialize the size validator.
virtual bool validate(std::string const &value) const override
Determine whether value is a valid size.
void set_error(std::string const &msg) const
The advgetopt environment to parse command line options.
Definition version.h:37
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.
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.