From df1ef68cd8e8582724ce1192bfc202e0b9aeaf0c Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 28 Sep 2021 19:24:31 +0300 Subject: Get rid of C++ modules related code and rename *.mxx files to *.hxx --- libbutl/default-options.hxx | 162 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 libbutl/default-options.hxx (limited to 'libbutl/default-options.hxx') diff --git a/libbutl/default-options.hxx b/libbutl/default-options.hxx new file mode 100644 index 0000000..1d363b6 --- /dev/null +++ b/libbutl/default-options.hxx @@ -0,0 +1,162 @@ +// file : libbutl/default-options.hxx -*- C++ -*- +// license : MIT; see accompanying LICENSE file + +#pragma once + +#include +#include + +#include +#include +#include + +#include + +namespace butl +{ + // Default options files helper implementation. + // + struct default_options_files + { + small_vector files; + optional start; + }; + + template + struct default_options_entry + { + path file; + O options; + small_vector arguments; + bool remote; + }; + + template + using default_options = small_vector, 4>; + + // Search for and load the specified list of options files in the specified + // directories returning a vector of option class instances (O). Read + // additional options from files referenced by the specified option + // (normally --options-file). If args is false, only options are allowed and + // are parsed using scanner S in the U::fail mode. If args is true, then + // both options and arguments are allowed in any order with options parsed + // in the U::stop mode. + // + // Pass each default options file path to the specified function prior to + // load (can be used for tracing, etc). The function signature is: + // + // void (const path&, bool remote, bool overwrite) + // + // Note that the function may be called for the same file twice if it was + // later discovered that it is in fact remote. In the second call the + // overwrite flag will be true. + // + // Throw `pair` on the underlying OS error with the + // first half referring the filesystem entry the error relates to and pass + // through exceptions thrown by the options scanner/parser. + // + // Search order: + // + // - sys_dir + // - home_dir + // - extra_dir (can also be handled during the start/outer traversal) + // - start_dir and outer until home_dir or root (both excluding) + // + // Except for sys_dir and extra_dir, the options files are looked for in the + // .build2/ and .build2/local/ subdirectories of each directory. For + // sys_dir and extra_dir they are looked for in the directory itself (e.g., + // /etc/build2/). + // + // Note that the search is stopped at the directory containing a file with + // --no-default-options. + // + // Also note that all the directories should be absolute and normalized. + // + // The presence of the .git filesystem entry causes the options files in + // this directory and any of its subdirectories to be considered remote + // (note that in the current implementation this is the case even for files + // from the .build2/local/ subdirectory since the mere location is not a + // sufficient ground to definitively conclude that the file is not remote; + // to be sure we would need to query the VCS or some such). + // + // Note that the extra directory options files are never considered remote. + // + // For the convenience of implementation, the function parses the option + // files in the reverse order. Thus, to make sure that positions in the + // options list monotonically increase, it needs the maximum number of + // arguments, globally and per file, to be specified. This way the starting + // options position for each file will be less than for the previously + // parsed file by arg_max_file and equal to arg_max - arg_max_file for the + // first file. If the actual number of arguments exceeds the specified, then + // invalid_argument is thrown. + // + template + default_options + load_default_options (const optional& sys_dir, + const optional& home_dir, + const optional& extra_dir, + const default_options_files&, + F&&, + const std::string& option, + std::size_t arg_max, + std::size_t arg_max_file, + bool args = false); + + // Merge the default options/arguments and the command line + // options/arguments. + // + // Note that these are the default implementations and in some cases you may + // want to provide an options class-specific version that verifies/sanitizes + // the default options/arguments (e.g., you may not want to allow certain + // options to be specified in the default options files) or warns/prompts + // about potentially dangerous options if they came from the remote options + // files. + // + template + O + merge_default_options (const default_options&, const O& cmd_ops); + + template + AS + merge_default_arguments (const default_options&, const AS& cmd_args); + + // As above but pass each default option/argument entry to the specified + // function prior to merging. The function signature is: + // + // void (const default_options_entry&, const O& cmd_ops) + // + // This version can be used to verify the default options/arguments. For + // example, you may want to disallow certain options/arguments from being + // specified in the default options files. + // + template + O + merge_default_options (const default_options&, const O&, F&&); + + template + AS + merge_default_arguments (const default_options&, const AS&, F&&); + + // Find a common start (parent) directory for directories specified as an + // iterator range, stopping at home or root (excluding). Optionally pass a + // function resolving an iterator into a directory in a way other than just + // dereferencing it. The function signature is: + // + // const dir_path& (I) + // + template + optional + default_options_start (const optional& home, I, I, F&&); + + template + inline optional + default_options_start (const optional& home, I b, I e) + { + return default_options_start (home, + b, e, + [] (I i) -> const dir_path& {return *i;}); + } +} + +#include +#include -- cgit v1.1