31 bool allow_missing{
false};
33 std::unique_ptr<cet::filepath_maker> policy;
37 using supported_types_t =
39 using strings_t = std::vector<std::string>;
41 std::variant<Options, Help>
42 process_arguments(
int argc,
44 supported_types_t
const& supported_types)
46 namespace bpo = boost::program_options;
50 bpo::options_description
desc(
51 "Usage: fhicl-get [options] [key] <file>\n\n" 52 "Required parameters:\n" 53 " [key] A fully-qualified parameter key of the form 'a.b.c.d'.\n" 54 " When used with the --names-in program option, one may " 56 " this option to print all top-level names in the file.\n" 57 " <file> A valid FHiCL document that contains the parameter with\n" 58 " the name as specified for <key>\n\n" 62 (
"help,h",
"Produce this help message")
63 (
"atom-as", bpo::value<std::string>(&opts.atom_as),
64 "Return value for the supplied key as an atom with the provided C++ type.")
65 (
"sequence-of", bpo::value<std::string>(&opts.sequence_of),
66 "Return value for the supplied key as a sequence of the provided C++ type.")
67 (
"names-in",
"Print the top-level names of the supplied key, which " 68 "must correspond to a FHiCL table.")
70 "Return to the command line if the supplied key does not exist when using " 71 "the --names-in option.")
73 bpo::value<std::string>()->default_value(
"permissive"),
"see --supported-policies")
75 bpo::value<std::string>(&opts.lookup_path)->default_value(fhicl_env_var),
76 "path or environment variable to be used by lookup-policy")
77 (
"supported-types",
"list the C++ types supported for by the --atom-as and --sequence-of options.")
78 (
"supported-policies",
"list the supported file lookup policies");
81 bpo::options_description positional_desc;
82 auto split_args = [&
opts](
auto const&
args) {
84 assert(n_args < 3ull);
86 opts.input_filename =
args[0];
90 opts.parameter_key =
args[0];
91 opts.input_filename =
args[1];
96 positional_desc.add_options()
97 (
"key-conf", bpo::value<strings_t>()->composing()->notifier(split_args));
100 bpo::positional_options_description
p;
101 p.add(
"key-conf", 2);
103 bpo::options_description
all;
104 all.add(
desc).add(positional_desc);
108 if (vm.count(
"help")) {
109 std::ostringstream oss;
110 oss <<
'\n' <<
desc <<
'\n';
111 return Help{oss.str()};
114 if (vm.count(
"supported-types")) {
116 For the following command line: 118 fhicl-get --atom-as=T <key> <file> 120 the <file> is queried for the <key>, and an attempt is made to 121 interpret the corresponding value as an object of type T. 123 If instead the command line were specified as: 125 fhicl-get --sequence-of=T <key> <file> 127 then the value corresponding to <key> would be interpreted as an 128 std::vector<T> object. 130 For either the --atom-as or --sequence-of program options, an 131 exception will be thrown if the <key> parameter does not exist in the 132 <file>, or if the parameter does not correspond to a value that can be 133 interpreted according to the user-specified command-line. 136 result += supported_types.help_message(); 142 if (vm.count(
"supported-policies")) {
146 if (
empty(opts.input_filename)) {
147 std::ostringstream err_stream;
148 err_stream <<
"\nMissing input configuration file.\n\n" << desc <<
'\n';
152 opts.names_in = vm.count(
"names-in") == 1;
153 auto const options_count = vm.count(
"atom-as") + vm.count(
"sequence-of") +
154 static_cast<unsigned>(opts.names_in);
156 if (options_count == 0) {
158 <<
"One of the 'atom-as', 'sequence-of', and 'names-in' program " 159 "options must be specified.\n";
161 if (options_count > 1) {
163 <<
"The 'atom-as', 'sequence-of', and 'names-in' program options " 164 "are mutually exclusive and may only appear once in the command " 168 if (not opts.names_in and
empty(opts.parameter_key)) {
170 <<
"A key must be specified unless the '--names-in' option is used.\n";
173 opts.allow_missing = vm.count(
"allow-missing");
174 if (opts.allow_missing) {
175 if (not opts.names_in) {
177 <<
"The 'allow-missing' program option may be used only with the " 178 "'names-in' option.\n";
180 if (
empty(opts.parameter_key)) {
182 <<
"The 'allow-missing' program option may be used only when a " 183 "fully-qualified key is also specified.\n";
187 supported_policies.select(vm[
"lookup-policy"].as<std::string>(),
188 vm[
"lookup-path"].as<std::string>());
197 std::cout <<
name <<
'\n';
204 bool const allow_missing)
217 <<
"A parameter with the fully-qualified key '" << key
218 <<
"' does not exist.";
223 <<
"' does not have a table value.";
232 supported_types_t
const printer_for_types{};
233 auto const maybe_opts = process_arguments(argc, argv, printer_for_types);
235 if (std::holds_alternative<Help>(maybe_opts)) {
236 std::cout << std::get<Help>(maybe_opts).
msg;
240 auto const& opts = std::get<Options>(maybe_opts);
245 auto const& key = opts.parameter_key;
248 print_table_names(pset, key, opts.allow_missing);
252 if (not pset.has_key(key)) {
254 << key <<
"' does not exist.";
257 if (not
empty(opts.atom_as)) {
258 printer_for_types.value_for_atom(pset, opts.atom_as, key);
262 if (not
empty(opts.sequence_of)) {
263 printer_for_types.value_for_sequence(pset, opts.sequence_of, key);
270 std::cerr << e.what();
boost::program_options::variables_map parsed_program_options(int argc, char **argv, boost::program_options::options_description const &desc, boost::program_options::positional_options_description const &pos={})
void msg(const char *fmt,...)
static ParameterSet make(intermediate_table const &tbl)
std::vector< std::string > strings_t
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
bool is_key_to_table(std::string const &key) const
T get(std::string const &key) const
int fhicl_get_impl(int argc, char **argv)
bool has_key(std::string const &key) const
static QInternalList< QTextCodec > * all
std::vector< std::string > get_names() const
static std::vector< std::string > const names
cet::coded_exception< error, detail::translate > exception
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
std::string help_message() const