Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
configuration_reader.h
Go to the documentation of this file.
1// Copyright 2012-2024:
2// GobySoft, LLC (2013-)
3// Massachusetts Institute of Technology (2007-2014)
4// Community contributors (see AUTHORS file)
5// File authors:
6// Toby Schneider <toby@gobysoft.org>
7//
8//
9// This file is part of the Goby Underwater Autonomy Project Libraries
10// ("The Goby Libraries").
11//
12// The Goby Libraries are free software: you can redistribute them and/or modify
13// them under the terms of the GNU Lesser General Public License as published by
14// the Free Software Foundation, either version 2.1 of the License, or
15// (at your option) any later version.
16//
17// The Goby Libraries are distributed in the hope that they will be useful,
18// but WITHOUT ANY WARRANTY; without even the implied warranty of
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20// GNU Lesser General Public License for more details.
21//
22// You should have received a copy of the GNU Lesser General Public License
23// along with Goby. If not, see <http://www.gnu.org/licenses/>.
24
25#ifndef GOBY_MIDDLEWARE_APPLICATION_CONFIGURATION_READER_H
26#define GOBY_MIDDLEWARE_APPLICATION_CONFIGURATION_READER_H
27
28#include <fstream> // for ostream
29#include <string> // for string
30#include <vector> // for vector
31
32#include <boost/lexical_cast/bad_lexical_cast.hpp> // for bad_lexical...
33#include <boost/program_options/options_description.hpp> // for options_des...
34#include <boost/program_options/value_semantic.hpp> // for value, bool...
35#include <boost/program_options/variables_map.hpp> // for variable_va...
36#include <google/protobuf/descriptor.h> // for FieldDescri...
37
38#include "goby/exception.h" // for Exception
39#include "goby/protobuf/option_extensions.pb.h" // for GobyFieldOpt...
40#include "goby/util/as.h" // for as
41
42namespace google
43{
44namespace protobuf
45{
46class Message;
47} // namespace protobuf
48} // namespace google
49
50namespace goby
51{
52namespace middleware
53{
57{
58 public:
59 ConfigException(const std::string& s) : Exception(s) {}
60
61 private:
62};
63
67{
68 public:
79 static int read_cfg(int argc, char* argv[], google::protobuf::Message* message,
80 std::string* application_name, std::string* binary_name,
81 boost::program_options::options_description* od_all,
82 boost::program_options::variables_map* var_map,
83 bool check_required_configuration = true);
84
90 const std::string& binary);
91
94 boost::program_options::options_description>& od_map,
95 const google::protobuf::Descriptor* desc,
96 std::map<std::string, std::string>& environmental_var_map);
97
99 {
100 std::string name;
102 int position_max_count; // -1 is infinity
103 };
104
105 static void get_positional_options(const google::protobuf::Descriptor* desc,
106 // position -> required -> name
107 std::vector<PositionalOption>& positional_options);
108
109 static void set_protobuf_program_option(const boost::program_options::variables_map& vm,
111 const std::string& full_name,
112 const boost::program_options::variable_value& value,
113 bool overwrite_if_exists);
114
115 static void
116 get_example_cfg_file(google::protobuf::Message* message, std::ostream* human_desc_ss,
117 const std::string& indent = "",
120
121 private:
122 enum
123 {
124 MAX_CHAR_PER_LINE = 66
125 };
126 enum
127 {
128 MIN_CHAR = 20
129 };
130
131 static void
132 build_description(const google::protobuf::Descriptor* desc, std::ostream& human_desc,
133 const std::string& indent = "", bool use_color = true,
136
137 static void
138 build_description_field(const google::protobuf::FieldDescriptor* desc, std::ostream& human_desc,
139 const std::string& indent, bool use_color,
141
142 static void wrap_description(std::string* description, int num_blanks);
143
144 static std::string label(const google::protobuf::FieldDescriptor* field_desc);
145
146 static std::string word_wrap(std::string s, unsigned width, const std::string& delim);
147
148 template <typename T>
149 static void set_single_option(boost::program_options::options_description& po_desc,
150 const google::protobuf::FieldDescriptor* field_desc,
151 const T& default_value, const std::string& name,
152 const std::string& description)
153 {
154 if (!field_desc->is_repeated())
155 {
156 if (field_desc->has_default_value())
157 {
158 po_desc.add_options()(
159 name.c_str(), boost::program_options::value<T>()->default_value(default_value),
160 description.c_str());
161 }
162 else
163 {
164 po_desc.add_options()(name.c_str(), boost::program_options::value<T>(),
165 description.c_str());
166 }
167 }
168 else
169 {
170 if (field_desc->has_default_value())
171 {
172 po_desc.add_options()(
173 name.c_str(),
174 boost::program_options::value<std::vector<T>>()
175 ->default_value(std::vector<T>(1, default_value),
176 goby::util::as<std::string>(default_value))
177 ->composing(),
178 description.c_str());
179 }
180 else
181 {
182 po_desc.add_options()(name.c_str(),
183 boost::program_options::value<std::vector<T>>()->composing(),
184 description.c_str());
185 }
186 }
187 }
188
189 // special case for bool presence/absence when default is false
190 // for example, for the bool field "foo", "--foo" is true and omitting "--foo" is false, rather than --foo=true/false
191 static void set_single_option(boost::program_options::options_description& po_desc,
192 const google::protobuf::FieldDescriptor* field_desc,
193 bool default_value, const std::string& name,
194 const std::string& description)
195 {
196 if (!field_desc->is_repeated() && field_desc->has_default_value() && default_value == false)
197 {
198 po_desc.add_options()(
199 name.c_str(), boost::program_options::bool_switch()->default_value(default_value),
200 description.c_str());
201 }
202 else
203 {
204 set_single_option<bool>(po_desc, field_desc, default_value, name, description);
205 }
206 }
207
208 static void write_usage(const std::string& binary,
209 const std::vector<PositionalOption>& positional_options,
210 std::ostream* out)
211 {
212 (*out) << "Usage: " << binary << " ";
213 for (const auto& po : positional_options)
214 {
215 if (!po.required)
216 (*out) << "[";
217 (*out) << "<" << po.name;
218 if (po.position_max_count > 1)
219 (*out) << "(" << po.position_max_count << ")";
220 else if (po.position_max_count == -1)
221 (*out) << "(...)";
222 (*out) << ">";
223 if (!po.required)
224 (*out) << "]";
225 (*out) << " ";
226 }
227 (*out) << "[options]\n";
228 }
229};
230} // namespace middleware
231} // namespace goby
232
233#endif
simple exception class for goby applications
Definition exception.h:35
indicates a problem with the runtime command line or .cfg file configuration (or –help was given)
Class for reading configuration from command line and/or file(s) into a Google Protocol Buffers messa...
static void get_protobuf_program_options(std::map< goby::GobyFieldOptions::ConfigurationOptions::ConfigAction, boost::program_options::options_description > &od_map, const google::protobuf::Descriptor *desc, std::map< std::string, std::string > &environmental_var_map)
static void get_example_cfg_file(google::protobuf::Message *message, std::ostream *human_desc_ss, const std::string &indent="", goby::GobyFieldOptions::ConfigurationOptions::ConfigAction action=goby::GobyFieldOptions::ConfigurationOptions::ALWAYS)
static void check_required_cfg(const google::protobuf::Message &message, const std::string &binary)
Checks that all required fields are set (either via the command line or the configuration file) in th...
static void get_positional_options(const google::protobuf::Descriptor *desc, std::vector< PositionalOption > &positional_options)
static void set_protobuf_program_option(const boost::program_options::variables_map &vm, google::protobuf::Message &message, const std::string &full_name, const boost::program_options::variable_value &value, bool overwrite_if_exists)
static int read_cfg(int argc, char *argv[], google::protobuf::Message *message, std::string *application_name, std::string *binary_name, boost::program_options::options_description *od_all, boost::program_options::variables_map *var_map, bool check_required_configuration=true)
Read the configuration into a Protobuf message using the command line parameters.
@ binary
binary array (ordered collection of bytes)
The global namespace for the Goby project.
GobyFieldOptions_ConfigurationOptions_ConfigAction
Definition dccl.h:58