advgetopt 2.0.47
Parse complex command line arguments and configuration files in C++.
advgetopt_data.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//
29#include "advgetopt/advgetopt.h"
30
31#include "advgetopt/conf_file.h"
32#include "advgetopt/exception.h"
35#include "advgetopt/version.h"
36
37
38// cppthread
39//
40#include <cppthread/log.h>
41
42
43// C
44//
45#include <string.h>
46
47
48// last include
49//
50#include <snapdev/poison.h>
51
52
53
54
55namespace advgetopt
56{
57
58
59
60
61
96bool getopt::is_defined(std::string const & name) const
97{
98 is_parsed();
99
101 if(opt != nullptr)
102 {
103 return opt->is_defined();
104 }
105
106 return false;
107}
108
109
125size_t getopt::size(std::string const & name) const
126{
127 is_parsed();
128
130 if(opt != nullptr)
131 {
132 return opt->size();
133 }
134 return 0;
135}
136
137
156bool getopt::has_default(std::string const & name) const
157{
159 if(opt != nullptr)
160 {
161 return opt->has_default();
162 }
163
164 return false;
165}
166
167
191std::string getopt::get_default(std::string const & name) const
192{
194 if(opt != nullptr)
195 {
196 return opt->get_default();
197 }
198
199 return std::string();
200}
201
202
246long getopt::get_long(std::string const & name, int idx, long min, long max) const
247{
248 is_parsed();
249
251 if(opt == nullptr)
252 {
253 throw getopt_logic_error(
254 "there is no --"
255 + name
256 + " option defined.");
257 }
258
259 long result(0.0);
260 if(!opt->is_defined())
261 {
262 std::string const d(opt->get_default());
263 if(d.empty())
264 {
265 throw getopt_logic_error(
266 "the --"
267 + name
268 + " option was not defined on the command line and it has no or an empty default.");
269 }
271 {
272 // here we throw because this default value is defined in the
273 // options of the tool and not by the user
274 //
275 throw getopt_logic_error(
276 "invalid default number \""
277 + d
278 + "\" for option --"
279 + name);
280 }
281 }
282 else
283 {
284 result = opt->get_long(idx);
285 }
286
287 // TODO: replace with validators
288 //
289 if(result < min || result > max)
290 {
291 cppthread::log << cppthread::log_level_t::error
292 << result
293 << " is out of bounds ("
294 << min
295 << ".."
296 << max
297 << " inclusive) in parameter --"
298 << name
299 << "."
300 << cppthread::end;
301 result = -1;
302 }
303
304 return result;
305}
306
307
354double getopt::get_double(std::string const & name, int idx, double min, double max) const
355{
356 is_parsed();
357
359 if(opt == nullptr)
360 {
361 throw getopt_logic_error(
362 "there is no --"
363 + name
364 + " option defined.");
365 }
366
367 double result(0);
368 if(!opt->is_defined())
369 {
370 std::string const d(opt->get_default());
371 if(d.empty())
372 {
373 throw getopt_logic_error(
374 "the --"
375 + name
376 + " option was not defined on the command line and it has no or an empty default.");
377 }
379 {
380 // here we throw because this default value is defined in the
381 // options of the tool and not by the user
382 //
383 throw getopt_logic_error(
384 "invalid default number \""
385 + d
386 + "\" for option --"
387 + name
388 + ".");
389 }
390 }
391 else
392 {
393 result = opt->get_double(idx);
394 }
395
396 // TODO: replace with validators
397 //
398 if(result < min || result > max)
399 {
400 cppthread::log << cppthread::log_level_t::error
401 << result
402 << " is out of bounds ("
403 << min
404 << ".."
405 << max
406 << " inclusive) in parameter --"
407 << name
408 << "."
409 << cppthread::end;
410 result = -1.0;
411 }
412
413 return result;
414}
415
416
443 std::string const & name
444 , int idx
445 , bool raw) const
446{
447 is_parsed();
448
450 if(opt == nullptr)
451 {
452 throw getopt_logic_error(
453 "there is no --"
454 + name
455 + " option defined.");
456 }
457
458 if(!opt->is_defined())
459 {
460 if(opt->has_default())
461 {
462 return opt->get_default();
463 }
464 throw getopt_logic_error(
465 "the --"
466 + name
467 + " option was not defined on the command line and it has no default.");
468 }
469
470 // it was defined, but if REQUIRED is not set and the value is empty
471 // then we want to return the default if it has such defined
472 //
473 std::string const value(opt->get_value(idx, raw));
474 if(value.empty()
475 && opt->has_default()
476 && !opt->has_flag(GETOPT_FLAG_REQUIRED))
477 {
478 return opt->get_default();
479 }
480
481 return value;
482}
483
484
499std::string getopt::operator [] (std::string const & name) const
500{
501 is_parsed();
502
503 if(name.empty())
504 {
505 throw getopt_logic_error("argument name cannot be empty.");
506 }
507
509 if(opt == nullptr)
510 {
511 return std::string();
512 }
513
514 if(!opt->is_defined())
515 {
516 if(opt->has_default())
517 {
518 return opt->get_default();
519 }
520 return std::string();
521 }
522
523 return opt->get_value(0);
524}
525
526
577option_info_ref getopt::operator [] (std::string const & name)
578{
579 is_parsed();
580
581 if(name.empty())
582 {
583 throw getopt_logic_error("argument name cannot be empty.");
584 }
585
587 if(opt == nullptr)
588 {
589 if(name.length() == 1)
590 {
591 throw getopt_logic_error("argument name cannot be one letter if it does not exist in operator [].");
592 }
593
594 // The option doesn't exist yet, create it
595 //
596 opt = std::make_shared<option_info>(name);
597 opt->set_variables(f_variables);
599 f_options_by_name[name] = opt;
600 }
601
602 return option_info_ref(opt);
603}
604
605
640flag_t getopt::process_system_options(std::basic_ostream<char> & out)
641{
643
644 // --version
645 if(is_defined("version"))
646 {
647 if(f_options_environment.f_version == nullptr)
648 {
649 out << "warning: no version found." << std::endl;
650 }
651 else
652 {
653 out << f_options_environment.f_version << std::endl;
654 }
655 result |= SYSTEM_OPTION_VERSION;
656 }
657
658 // --has-sanitizer
659 if(is_defined("has-sanitizer"))
660 {
661 out << sanitizer_details() << std::flush;
662 result |= SYSTEM_OPTION_HELP;
663 }
664
665 // --compiler-version
666 if(is_defined("compiler-version"))
667 {
668 out << LIBADVGETOPT_COMPILER_VERSION << std::endl;
669 result |= SYSTEM_OPTION_HELP;
670 }
671
672 // --help
673 if(is_defined("help"))
674 {
675 less(out, usage());
676 result |= SYSTEM_OPTION_HELP;
677 }
678
679 // --long-help
680 if(is_defined("long-help"))
681 {
683 result |= SYSTEM_OPTION_HELP;
684 }
685
686 // --<group-name>-help
687 //
688 if(f_options_environment.f_groups != nullptr)
689 {
691 ; grp->f_group != GETOPT_FLAG_GROUP_NONE
692 ; ++grp)
693 {
694 // the name is not mandatory, without it you do not get the command
695 // line option but still get the group description
696 //
697 if(grp->f_name != nullptr
698 && *grp->f_name != '\0')
699 {
700 std::string const name(grp->f_name);
701 std::string const option_name(name + "-help");
702 if(is_defined(option_name))
703 {
704 less(out, usage(grp->f_group));
705 result |= SYSTEM_OPTION_HELP;
706 }
707 }
708 }
709 }
710
711 // --system-help
712 if(is_defined("system-help"))
713 {
715 result |= SYSTEM_OPTION_HELP;
716 }
717
718 // --copyright
719 if(is_defined("copyright"))
720 {
722 {
723 out << "warning: no copyright notice found." << std::endl;
724 }
725 else
726 {
728 }
729 result |= SYSTEM_OPTION_COPYRIGHT;
730 }
731
732 // --license
733 if(is_defined("license"))
734 {
735 if(f_options_environment.f_license == nullptr)
736 {
737 out << "warning: no license found." << std::endl;
738 }
739 else
740 {
742 }
743 result |= SYSTEM_OPTION_LICENSE;
744 }
745
746 // --build-date
747 if(is_defined("build-date"))
748 {
749 out << "Built on "
751 ? "<no-build-date>"
753 << " at "
755 ? "<no-build-time>"
757 << std::endl;
758 result |= SYSTEM_OPTION_BUILD_DATE;
759 }
760
761 // --environment-variable-name
762 if(is_defined("environment-variable-name"))
763 {
766 {
768 << " does not support an environment variable."
769 << std::endl;
770 }
771 else
772 {
774 }
776 }
777
778 // --configuration-filenames
779 if(is_defined("configuration-filenames"))
780 {
781 string_list_t list(get_configuration_filenames(false, false));
782 if(list.empty())
783 {
785 << " does not support configuration files."
786 << std::endl;
787 }
788 else
789 {
790 out << "Configuration filenames:" << std::endl;
791 for(auto n : list)
792 {
793 out << " . " << n << std::endl;
794 }
795 }
797 }
798
799 // --path-to-option-definitions
800 if(is_defined("path-to-option-definitions"))
801 {
804 {
805 out << "/usr/share/advgetopt/options/" << std::endl;
806 }
807 else
808 {
811 {
812 out << '/';
813 }
814 out << std::endl;
815 }
817 }
818
819 // --config-dir
820 if(is_defined("config-dir"))
821 {
822 // these are automatically used in the get_configuration_filenames()
823 // function, there is nothing for us to do here
824 //
825 result |= SYSTEM_OPTION_CONFIG_DIR;
826 }
827
828 // --show-option-sources
829 if(is_defined("show-option-sources"))
830 {
833 }
834
835 // --print-option
836 if(is_defined("print-option"))
837 {
838 std::string const name(get_string("print-option"));
839 if(is_defined(name))
840 {
841 out << get_string(name) << std::endl;
842 }
843 else if(has_default(name))
844 {
845 out << get_default(name) << std::endl;
846 }
848 }
849
850 return result;
851}
852
853
854
855
856
857} // namespace advgetopt
858// vim: ts=4 sw=4 et
Definitions of the advanced getopt class.
std::string get_string(std::string const &name, int idx=0, bool raw=false) const
Get the content of an option as a string.
string_list_t get_configuration_filenames(bool exists, bool writable, int argc=0, char *argv[]=nullptr) const
Generate a list of configuration filenames.
std::size_t size(std::string const &name) const
Retrieve the number of arguments.
options_environment f_options_environment
Definition advgetopt.h:224
option_info::map_by_name_t f_options_by_name
Definition advgetopt.h:225
bool is_defined(std::string const &name) const
Check whether a parameter is defined.
option_info::pointer_t get_option(std::string const &name, bool exact_option=false) const
Retrieve an option by name.
std::string usage(flag_t show=GETOPT_FLAG_SHOW_MOST) const
Create a string of the command line arguments.
double get_double(std::string const &name, int idx=0, double min=std::numeric_limits< double >::min(), double max=std::numeric_limits< double >::max()) const
This function retrieves an argument as a double value.
std::string operator[](std::string const &name) const
Retrieve the value of an argument.
std::string get_default(std::string const &name) const
Get the default value for this option.
bool has_default(std::string const &name) const
Check whether an option has a default value.
void is_parsed() const
Verify that the parser is done.
flag_t process_system_options(std::basic_ostream< char > &out)
Process the system options.
long get_long(std::string const &name, int idx=0, long min=std::numeric_limits< long >::min(), long max=std::numeric_limits< long >::max()) const
This function retrieves an argument as a long value.
void show_option_sources(std::basic_ostream< char > &out)
Output the source of each option.
variables::pointer_t f_variables
Definition advgetopt.h:229
std::shared_ptr< option_info > pointer_t
Definition option_info.h:78
static bool convert_string(std::string const &number, double &result)
Convert a string to a double value.
static bool convert_string(std::string const &number, std::int64_t &result)
Convert a string to an std::int64_t value.
Declaration of the conf_file class used to read a configuration file.
Definitions of the advanced getopt exceptions.
The advgetopt environment to parse command line options.
static constexpr flag_t GETOPT_FLAG_SHOW_SYSTEM
Definition flags.h:64
constexpr flag_t SYSTEM_OPTION_HELP
Definition advgetopt.h:57
static constexpr flag_t GETOPT_FLAG_DYNAMIC_CONFIGURATION
Definition flags.h:48
void less(std::basic_ostream< char > &out, std::string const &data)
Print out a string to the console or use less.
Definition utils.cpp:1069
constexpr flag_t SYSTEM_OPTION_BUILD_DATE
Definition advgetopt.h:61
std::uint32_t flag_t
Definition flags.h:41
static constexpr flag_t GETOPT_FLAG_GROUP_NONE
Definition flags.h:70
constexpr flag_t SYSTEM_OPTION_SHOW_OPTION_VALUE
Definition advgetopt.h:66
constexpr flag_t SYSTEM_OPTION_NONE
Definition advgetopt.h:54
constexpr flag_t SYSTEM_OPTION_VERSION
Definition advgetopt.h:58
constexpr flag_t SYSTEM_OPTION_PATH_TO_OPTION_DEFINITIONS
Definition advgetopt.h:64
constexpr flag_t SYSTEM_OPTION_LICENSE
Definition advgetopt.h:60
constexpr flag_t SYSTEM_OPTION_CONFIGURATION_FILENAMES
Definition advgetopt.h:63
constexpr flag_t SYSTEM_OPTION_CONFIG_DIR
Definition advgetopt.h:69
std::string sanitizer_details()
Generate a string describing whether we're using the sanitizer.
Definition utils.cpp:1005
static constexpr flag_t GETOPT_FLAG_REQUIRED
Definition flags.h:52
constexpr flag_t SYSTEM_OPTION_COPYRIGHT
Definition advgetopt.h:59
constexpr flag_t SYSTEM_OPTION_ENVIRONMENT_VARIABLE_NAME
Definition advgetopt.h:62
std::vector< std::string > string_list_t
Definition utils.h:41
static constexpr flag_t GETOPT_FLAG_SHOW_ALL
Definition flags.h:61
constexpr flag_t SYSTEM_OPTION_SHOW_OPTION_SOURCES
Definition advgetopt.h:65
char const * f_options_files_directory
Definition options.h:445
char const * f_environment_variable_name
Definition options.h:446
group_description const * f_groups
Definition options.h:460
Declaration of validators which can be used to verify the parameters.
Declaration of validators which can be used to verify the parameters.
#define LIBADVGETOPT_COMPILER_VERSION
Definition version.h.in:34

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.