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 return convert_string(value, f_flags, result);
184}
185#pragma GCC diagnostic pop
186
187
242#pragma GCC diagnostic push
243#pragma GCC diagnostic ignored "-Wpedantic"
245 std::string const & value
246 , flag_t flags
247 , __int128 & result)
248{
249 using namespace snapdev::literals;
250
251 // determine the factor by checking the suffix
252 //
254 std::string::size_type pos(value.length());
255 for(; pos > 0; --pos)
256 {
257 char c(value[pos - 1]);
258 if(c >= '0'
259 && c <= '9'
260 || c == '.')
261 {
262 break;
263 }
264 }
265 if(pos == 0)
266 {
267 return false;
268 }
269 __int128 const base(
271 ? 1024_int128
272 : 1000_int128);
273 std::string const number(value.substr(0, pos));
274 for(; pos < value.length() && isspace(value[pos]); ++pos);
275 if(pos < value.length())
276 {
277 // copy and force lowercase (although the case is important
278 // when writing such a measurement, it does not matter when
279 // testing here)
280 //
281 std::string suffix;
282 for(; pos < value.length(); ++pos)
283 {
284 if(value[pos] >= 'A'
285 && value[pos] <= 'Z')
286 {
287 suffix += value[pos] + 0x20;
288 }
289 else
290 {
291 suffix += value[pos];
292 }
293 }
294
295 switch(suffix[0])
296 {
297 case 'b':
298 if(suffix != "b")
299 {
300 return false;
301 }
302 break;
303
304 case 'e':
305 if(suffix == "eb")
306 {
307 factor = snapdev::pow(base, 6);
308 }
309 else if(suffix == "eib")
310 {
311 factor = snapdev::pow(1024_int128, 6);
312 }
313 else
314 {
315 return false;
316 }
317 break;
318
319 case 'g':
320 if(suffix == "gb")
321 {
322 factor = snapdev::pow(base, 3);
323 }
324 else if(suffix == "gib")
325 {
326 factor = snapdev::pow(1024_int128, 3);
327 }
328 else
329 {
330 return false;
331 }
332 break;
333
334 case 'k':
335 if(suffix == "kb")
336 {
337 factor = base;
338 }
339 else if(suffix == "kib")
340 {
341 factor = 1024_int128;
342 }
343 else
344 {
345 return false;
346 }
347 break;
348
349 case 'm':
350 if(suffix == "mb")
351 {
352 factor = snapdev::pow(base, 2);
353 }
354 else if(suffix == "mib")
355 {
356 factor = snapdev::pow(1024_int128, 2);
357 }
358 else
359 {
360 return false;
361 }
362 break;
363
364 case 'p':
365 if(suffix == "pb")
366 {
367 factor = snapdev::pow(base, 5);
368 }
369 else if(suffix == "pib")
370 {
371 factor = snapdev::pow(1024_int128, 5);
372 }
373 else
374 {
375 return false;
376 }
377 break;
378
379 case 'q':
380 if(suffix == "qb")
381 {
382 factor = snapdev::pow(base, 10);
383 }
384 else if(suffix == "qib")
385 {
386 factor = snapdev::pow(1024_int128, 10);
387 }
388 else
389 {
390 return false;
391 }
392 break;
393
394 case 'r':
395 if(suffix == "rb")
396 {
397 factor = snapdev::pow(base, 9);
398 }
399 else if(suffix == "rib")
400 {
401 factor = snapdev::pow(1024_int128, 9);
402 }
403 else
404 {
405 return false;
406 }
407 break;
408
409 case 't':
410 if(suffix == "tb")
411 {
412 factor = snapdev::pow(base, 4);
413 }
414 else if(suffix == "tib")
415 {
416 factor = snapdev::pow(1024_int128, 4);
417 }
418 else
419 {
420 return false;
421 }
422 break;
423
424 case 'y':
425 if(suffix == "yb")
426 {
427 factor = snapdev::pow(base, 8);
428 }
429 else if(suffix == "yib")
430 {
431 factor = snapdev::pow(1024_int128, 8);
432 }
433 else
434 {
435 return false;
436 }
437 break;
438
439 case 'z':
440 if(suffix == "zb")
441 {
442 factor = snapdev::pow(base, 7);
443 }
444 else if(suffix == "zib")
445 {
446 factor = snapdev::pow(1024_int128, 7);
447 }
448 else
449 {
450 return false;
451 }
452 break;
453
454 default:
455 return false;
456
457 }
458 }
459
460 double base_number(0.0);
462 {
463 return false;
464 }
465
466 // TODO: I think that even with the long double this will lose bits
467 result = static_cast<long double>(base_number) * factor;
468
469 return true;
470}
471#pragma GCC diagnostic pop
472
473
474
475} // namespace advgetopt
476// 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.
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.