advgetopt 2.0.50
Parse complex command line arguments and configuration files in C++.
advgetopt_data.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
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 if(result < min || result > max)
397 {
398 cppthread::log << cppthread::log_level_t::error
399 << result
400 << " is out of bounds ("
401 << min
402 << ".."
403 << max
404 << " inclusive) in parameter --"
405 << name
406 << "."
407 << cppthread::end;
408 result = -1.0;
409 }
410
411 return result;
412}
413
414
441 std::string const & name
442 , int idx
443 , bool raw) const
444{
445 is_parsed();
446
448 if(opt == nullptr)
449 {
450 throw getopt_logic_error(
451 "there is no --"
452 + name
453 + " option defined.");
454 }
455
456 if(!opt->is_defined())
457 {
458 if(opt->has_default())
459 {
460 return opt->get_default();
461 }
462 throw getopt_logic_error(
463 "the --"
464 + name
465 + " option was not defined on the command line and it has no default.");
466 }
467
468 // it was defined, but if REQUIRED is not set and the value is empty
469 // then we want to return the default if it has such defined
470 //
471 std::string const value(opt->get_value(idx, raw));
472 if(value.empty()
473 && opt->has_default()
474 && !opt->has_flag(GETOPT_FLAG_REQUIRED))
475 {
476 return opt->get_default();
477 }
478
479 return value;
480}
481
482
497std::string getopt::operator [] (std::string const & name) const
498{
499 is_parsed();
500
501 if(name.empty())
502 {
503 throw getopt_logic_error("argument name cannot be empty.");
504 }
505
507 if(opt == nullptr)
508 {
509 return std::string();
510 }
511
512 if(!opt->is_defined())
513 {
514 if(opt->has_default())
515 {
516 return opt->get_default();
517 }
518 return std::string();
519 }
520
521 return opt->get_value(0);
522}
523
524
575option_info_ref getopt::operator [] (std::string const & name)
576{
577 is_parsed();
578
579 if(name.empty())
580 {
581 throw getopt_logic_error("argument name cannot be empty.");
582 }
583
585 if(opt == nullptr)
586 {
587 if(name.length() == 1)
588 {
589 throw getopt_logic_error("argument name cannot be one letter if it does not exist in operator [].");
590 }
591
592 // The option doesn't exist yet, create it
593 //
594 opt = std::make_shared<option_info>(name);
595 opt->set_variables(f_variables);
597 f_options_by_name[name] = opt;
598 }
599
600 return option_info_ref(opt);
601}
602
603
638flag_t getopt::process_system_options(std::basic_ostream<char> & out)
639{
641
642 // --version
643 if(is_defined("version"))
644 {
645 if(f_options_environment.f_version == nullptr)
646 {
647 out << "warning: no version found." << std::endl;
648 }
649 else
650 {
651 out << f_options_environment.f_version << std::endl;
652 }
653 result |= SYSTEM_OPTION_VERSION;
654 }
655
656 // --has-sanitizer
657 if(is_defined("has-sanitizer"))
658 {
659 out << sanitizer_details() << std::flush;
660 result |= SYSTEM_OPTION_HELP;
661 }
662
663 // --compiler-version
664 if(is_defined("compiler-version"))
665 {
666 out << LIBADVGETOPT_COMPILER_VERSION << std::endl;
667 result |= SYSTEM_OPTION_HELP;
668 }
669
670 // --help
671 if(is_defined("help"))
672 {
673 less(out, usage());
674 result |= SYSTEM_OPTION_HELP;
675 }
676
677 // --long-help
678 if(is_defined("long-help"))
679 {
681 result |= SYSTEM_OPTION_HELP;
682 }
683
684 // --<group-name>-help
685 //
686 if(f_options_environment.f_groups != nullptr)
687 {
689 ; grp->f_group != GETOPT_FLAG_GROUP_NONE
690 ; ++grp)
691 {
692 // the name is not mandatory, without it you do not get the command
693 // line option but still get the group description
694 //
695 if(grp->f_name != nullptr
696 && *grp->f_name != '\0')
697 {
698 std::string const name(grp->f_name);
699 std::string const option_name(name + "-help");
700 if(is_defined(option_name))
701 {
702 less(out, usage(grp->f_group));
703 result |= SYSTEM_OPTION_HELP;
704 }
705 }
706 }
707 }
708
709 // --system-help
710 if(is_defined("system-help"))
711 {
713 result |= SYSTEM_OPTION_HELP;
714 }
715
716 // --copyright
717 if(is_defined("copyright"))
718 {
720 {
721 out << "warning: no copyright notice found." << std::endl;
722 }
723 else
724 {
726 }
727 result |= SYSTEM_OPTION_COPYRIGHT;
728 }
729
730 // --license
731 if(is_defined("license"))
732 {
733 if(f_options_environment.f_license == nullptr)
734 {
735 out << "warning: no license found." << std::endl;
736 }
737 else
738 {
740 }
741 result |= SYSTEM_OPTION_LICENSE;
742 }
743
744 // --build-date
745 if(is_defined("build-date"))
746 {
747 out << "Built on "
749 ? "<no-build-date>"
751 << " at "
753 ? "<no-build-time>"
755 << std::endl;
756 result |= SYSTEM_OPTION_BUILD_DATE;
757 }
758
759 // --environment-variable-name
760 if(is_defined("environment-variable-name"))
761 {
764 {
766 << " does not support an environment variable."
767 << std::endl;
768 }
769 else
770 {
772 }
774 }
775
776 // --configuration-filenames
777 if(is_defined("configuration-filenames"))
778 {
779 string_list_t list(get_configuration_filenames(false, false));
780 if(list.empty())
781 {
783 << " does not support configuration files."
784 << std::endl;
785 }
786 else
787 {
788 out << "Configuration filenames:" << std::endl;
789 for(auto n : list)
790 {
791 out << " . " << n << std::endl;
792 }
793 }
795 }
796
797 // --path-to-option-definitions
798 if(is_defined("path-to-option-definitions"))
799 {
800 out << get_path_to_option_files() << std::endl;
802 }
803
804 // --filenames-of-option-definitions
805 if(is_defined("filenames-of-option-definitions"))
806 {
808 for(auto const & l : list)
809 {
810 out << l << std::endl;
811 }
813 }
814
815 // --config-dir
816 if(is_defined("config-dir"))
817 {
818 // these are automatically used in the get_configuration_filenames()
819 // function, there is nothing for us to do here
820 //
821 result |= SYSTEM_OPTION_CONFIG_DIR;
822 }
823
824 // --show-option-sources
825 if(is_defined("show-option-sources"))
826 {
829 }
830
831 // --print-option
832 if(is_defined("print-option"))
833 {
834 std::string const name(get_string("print-option"));
835 if(is_defined(name))
836 {
837 out << get_string(name) << std::endl;
838 }
839 else if(has_default(name))
840 {
841 out << get_default(name) << std::endl;
842 }
844 }
845
846 return result;
847}
848
849
850
851
852
853} // namespace advgetopt
854// 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:226
option_info::map_by_name_t f_options_by_name
Definition advgetopt.h:227
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.
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 get_path_to_option_files() const
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.
string_list_t get_filenames_of_option_definitions() const
Get the path and filename to options.
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:231
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.
void usage()
The advgetopt environment to parse command line options.
Definition version.h:37
static constexpr flag_t GETOPT_FLAG_SHOW_SYSTEM
Definition flags.h:65
constexpr flag_t SYSTEM_OPTION_HELP
Definition advgetopt.h:57
static constexpr flag_t GETOPT_FLAG_DYNAMIC_CONFIGURATION
Definition flags.h:49
void less(std::basic_ostream< char > &out, std::string const &data)
Print out a string to the console or use less.
Definition utils.cpp:1076
constexpr flag_t SYSTEM_OPTION_BUILD_DATE
Definition advgetopt.h:61
std::uint32_t flag_t
Definition flags.h:42
static constexpr flag_t GETOPT_FLAG_GROUP_NONE
Definition flags.h:71
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:1012
static constexpr flag_t GETOPT_FLAG_REQUIRED
Definition flags.h:53
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:62
constexpr flag_t SYSTEM_OPTION_SHOW_OPTION_SOURCES
Definition advgetopt.h:65
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.
Definitions of the advanced getopt class version.
#define LIBADVGETOPT_COMPILER_VERSION
Definition version.h:34

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.