37#include <cppthread/log.h>
48#include <snapdev/poison.h>
88 ,
char * argv[])
const
101 int const mode(R_OK | (writable ? W_OK : 0));
104 if(access(r.c_str(), mode) == 0)
106 existing_files.push_back(r);
110 return existing_files;
130 if(std::find(names.begin(), names.end(), add) == names.end())
132 names.push_back(add);
160 ,
char * argv[])
const
179 std::size_t
const max(
size(
"config-dir"));
180 directories.reserve(max);
181 for(std::size_t idx(0); idx < max; ++idx)
183 directories.push_back(
get_string(
"config-dir", idx));
192 if(directories.empty())
196 std::vector<char *> sub_argv;
197 sub_argv.resize(args.size() + 2);
199 for(std::size_t idx(0); idx < args.size(); ++idx)
201 sub_argv[idx + 1] =
const_cast<char *
>(args[idx].c_str());
203 sub_argv[args.size() + 1] =
nullptr;
213 *configuration_directories !=
nullptr;
214 ++configuration_directories)
216 directories.push_back(*configuration_directories);
220 if(directories.empty())
226 std::string directory_name(
"/usr/share/advgetopt/options/");
227 directory_name += name;
228 directories.push_back(directory_name);
230 directory_name =
"/usr/share/";
231 directory_name += name;
232 directory_name +=
"/options";
233 directories.push_back(directory_name);
235 directory_name =
"/etc/";
236 directory_name += name;
237 directories.push_back(directory_name);
243 for(
auto directory : directories)
245 if(!directory.empty())
247 std::string
const full_filename(directory + (
"/" + filename));
249 if(user_filename == full_filename)
260 if(!with_project_name.empty())
262 for(
auto const & n : with_project_name)
294 ,
bool writable)
const
304 *configuration_files !=
nullptr;
305 ++configuration_files)
307 char const * filename(*configuration_files);
308 if(*filename ==
'\0')
314 if(user_filename == filename)
325 if(!with_project_name.empty())
327 for(
auto const & n : with_project_name)
376 char const * found(
nullptr);
378 *configuration_files !=
nullptr;
379 ++configuration_files)
381 char const * filename(*configuration_files);
382 if(*filename ==
'\0')
389 if(filename[0] ==
'~'
390 && (filename[1] ==
'/' || filename[1] ==
'\0'))
422 std::string directory;
426 *configuration_directories !=
nullptr;
427 ++configuration_directories)
429 char const * dir(*configuration_directories);
436 && (dir[1] ==
'/' || dir[1] ==
'\0'))
447 if(directory.empty())
452 directory =
"/etc/" + name;
455 if(directory.back() !=
'/')
471 std::string filename(
"/etc/");
487 return std::string();
504 throw getopt_logic_error(
"we just checked both of those names and at least one was valid.");
536 for(
int idx(1); idx < argc; ++idx)
538 if(strcmp(argv[idx],
"--config-dir") == 0)
540 for(++idx; idx < argc; ++idx)
542 if(argv[idx][0] ==
'-')
547 result.push_back(argv[idx]);
550 else if(strncmp(argv[idx],
"--config-dir=", 13) == 0)
552 result.push_back(argv[idx] + 13);
608 for(
auto f : filenames)
647 conf_setup = std::make_shared<conf_file_setup>(filename);
651 conf_setup = std::make_shared<conf_file_setup>(
655 if(!conf_setup->is_valid())
668 conf->section_to_variables(
674 if(!sections.empty())
678 if(configuration_sections ==
nullptr)
680 configuration_sections = std::make_shared<option_info>(name);
681 configuration_sections->add_flag(
688 cppthread::log << cppthread::log_level_t::error
691 <<
"\" must have GETOPT_FLAG_MULTIPLE set."
695 for(
auto s : sections)
697 if(!configuration_sections->has_value(s))
699 configuration_sections->add_value(
707 for(
auto const & param : conf->get_parameters())
715 || param.first.length() == 1)
717 cppthread::log << cppthread::log_level_t::error
718 <<
"unknown option \""
720 <<
"\" found in configuration file \""
723 << param.second.get_line()
732 opt = std::make_shared<option_info>(param.first);
740 opt->set_default(param.second);
752 cppthread::log << cppthread::log_level_t::error
755 <<
"\" is not supported in configuration files (found in \""
763 std::string value(param.second.get_value());
764 switch(param.second.get_assignment_operator())
773 if(opt->is_defined())
787 value = opt->get_value() + value;
792 if(opt->is_defined())
796 cppthread::log << cppthread::log_level_t::error
799 <<
"\" found in configuration file \""
802 << param.second.get_line()
803 <<
" uses the := operator but the value is already defined."
Definitions of the advanced getopt class.
std::shared_ptr< conf_file_setup > pointer_t
std::shared_ptr< conf_file > pointer_t
static pointer_t get_conf_file(conf_file_setup const &setup)
Create and read a conf_file.
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::string get_group_or_project_name() const
Retrieve the group or project name.
std::size_t size(std::string const &name) const
Retrieve the number of arguments.
options_environment f_options_environment
void add_option_from_string(option_info::pointer_t opt, std::string const &value, std::string const &filename, string_list_t const &option_keys, option_source_t source=option_source_t::SOURCE_DIRECT)
Add an option with a value defined in a string.
void get_managed_configuration_filenames(string_list_t &names, bool writable, int argc, char *argv[]) const
Generate the list of managed configuration filenames.
void process_configuration_file(std::string const &filename)
Parse one specific configuration file and process the results.
void parse_configuration_files(int argc=0, char *argv[]=nullptr)
This function checks for arguments in configuration files.
void get_direct_configuration_filenames(string_list_t &names, bool writable) const
Define the list of direct configuration filenames.
option_info::map_by_name_t f_options_by_name
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.
static string_list_t find_config_dir(int argc, char *argv[])
Search for the "--config-dir" option in a set of arguments.
std::string f_program_fullname
static void add_configuration_filename(string_list_t &names, std::string const &add)
Add one configuration filename to our list.
std::string f_environment_variable
bool has_flag(flag_t flag) const
Check whether an environment flag is set or not.
static string_list_t split_environment(std::string const &environment)
Transform a string in an array of arguments.
std::string get_output_filename() const
Determine the best suited file for updates.
variables::pointer_t f_variables
std::shared_ptr< option_info > pointer_t
static void set_configuration_filename(std::string const &filename)
Save the filename of the current configuration file.
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.
string_list_t insert_group_name(std::string const &filename, char const *group_name, char const *project_name, bool add_default_on_empty)
Insert the group (or project) name in the filename.
constexpr flag_t GETOPT_ENVIRONMENT_FLAG_DYNAMIC_PARAMETERS
static constexpr flag_t GETOPT_FLAG_CONFIGURATION_FILE
std::string option_with_underscores(std::string const &s)
Converts an option back to using underscores.
static constexpr flag_t GETOPT_FLAG_DYNAMIC
static constexpr flag_t GETOPT_FLAG_MULTIPLE
constexpr flag_t GETOPT_ENVIRONMENT_FLAG_SYSTEM_PARAMETERS
std::vector< std::string > string_list_t
std::string handle_user_directory(std::string const &filename)
Replace a starting ~/... with the contents of the $HOME variable.
std::string default_group_name(std::string const &filename, char const *group_name, char const *project_name, int priority)
Generate the default filename (the ".../50-...")
constexpr char const CONFIGURATION_SECTIONS[]
char const *const * f_configuration_directories
conf_file_setup const * f_config_setup
char const * f_section_variables_name
char const * f_configuration_filename
char const * f_project_name
char const *const * f_configuration_files
char const * f_group_name