Derecho  0.9
Distributed systems toolkit for RDMA
GetPot.hpp
Go to the documentation of this file.
1 // SPDX license identifier: MIT; Project 'GetPot'
2 // MIT License
3 //
4 // Copyright (C) 2001-2016 Frank-Rene Schaefer.
5 //
6 // While not directly linked to license requirements, the author would like
7 // this software not to be used for military purposes.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in all
17 // copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 // SOFTWARE.
26 //=============================================================================
27 
28 #ifndef __INCLUDE_GUARD_GETPOT_HPP__
29 #define __INCLUDE_GUARD_GETPOT_HPP__
30 
31 #ifndef GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT
32 # define GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT false
33 #endif
34 #ifndef GETPOT_SETTING_DEFAULT_TRUE_STRING_LIST
35 # define GETPOT_SETTING_DEFAULT_TRUE_STRING_LIST "true True TRUE yes Yes YES"
36 #endif
37 #ifndef GETPOT_SETTING_DEFAULT_FALSE_STRING_LIST
38 # define GETPOT_SETTING_DEFAULT_FALSE_STRING_LIST "false False FALSE no No NO"
39 #endif
40 
41 #ifndef GETPOT_SETTING_NAMESPACE
42  // The '#define' line below can be uncommented, if it is desired to run
43  // GetPot in a particular namespace. Or, the definition of the macro
44  // might also happen before including this file.
45 
46  // #define GETPOT_SETTING_NAMESPACE GetPotSpace
47 #endif
48 
49 /* Strings used by GetPot; Adaptation for Non-English may happen here. */
50 #define GETPOT_STR_FILE "File"
51 #define GETPOT_STR_FILE_NOT_FOUND(FILE) std::string("File \"") + FILE + "\" not found."
52 #define GETPOT_STR_REACHED_END_OF_CONSTRAINT std::string("Unexpected end of constraint string reached")
53 #define GETPOT_STR_MISSING_VARIABLE "missing variable"
54 #define GETPOT_STR_VARIABLE "variable"
55 #define GETPOT_STR_VALUE "for the value (read in configuration file)"
56 #define GETPOT_STR_WITH_TYPE "of type"
57 #define GETPOT_STR_IN_SECTION "in section"
58 #define GETPOT_STR_CANNOT_CONVERT_TO(X, TYPE) std::string("Cannot convert '") + X + "' to type " + (TYPE) + "."
59 #define GETPOT_STR_DOES_NOT_SATISFY_CONSTRAINT "does not fulfill the constraint"
60 #define GETPOT_STR_DOES_NOT_CONTAIN_ELEMENT "does not contain element"
61 #define GETPOT_STR_TRUE_FALSE_UNDEFINED "GetPot: no strings defined for meaning of 'true' and 'false'."
62 
63 extern "C" {
64 // Leave the 'extern C' to make it 100% sure to work -
65 // expecially with older distributions of header files.
66 #ifndef WIN32
67  // this is necessary (depending on OS)
68 # include <ctype.h>
69 #endif
70 #include <stdio.h>
71 #include <stdarg.h>
72 #include <assert.h>
73 #include <string.h>
74 }
75 #include <cmath>
76 #include <string>
77 #include <vector>
78 #include <algorithm>
79 
80 #include <sstream>
81 #include <fstream>
82 #include <iostream> // Not every compiler distribution includes <iostream>
83 // // with <fstream>
84 #include <stdexcept>
85 #include <cstddef>
86 
87 #ifdef GETPOT_SETTING_NAMESPACE
88 namespace GETPOT_SETTING_NAMESPACE {
89 #endif
90 
91 typedef std::vector<std::string> STRING_VECTOR;
92 
94 public:
95  std::string content;
96 
97  /* This class has the only purpose to cut the number of functions
98  * by factor 2 which are needed to take a std::string and a char pointer. */
99  StringOrCharP(const char* Value)
100  { if( Value == 0 ) content = std::string(""); else content = std::string(Value); }
101  StringOrCharP(const std::string& Value)
102  { content = std::string(Value); }
103 };
104 
105 
106 class GetPot {
107  //--------
108  void __basic_initialization();
109 public:
110  // (*) constructors, destructor, assignment operator -----------------------
111  GetPot();
112  GetPot(const GetPot&);
113  GetPot(const int argc_, char** argv_, const StringOrCharP FieldSeparator=(const char*)0x0);
114  GetPot(const StringOrCharP FileName,
115  const StringOrCharP CommentStart=(const char*)0x0,
116  const StringOrCharP CommentEnd=(const char*)0x0,
117  const StringOrCharP FieldSeparator=(const char*)0x0);
118  ~GetPot();
119 #ifndef SWIG
120  GetPot& operator=(const GetPot&);
121 #endif
122 
123  // (*) Setup ---------------------------------------------------------------
124  // -- define the possible strings for 'true' and 'false'
125  // i.e. for what are the strings for 'boolean'.
126  void set_true_string_list(unsigned N, const char* StringForTrue, ...);
127  void set_false_string_list(unsigned N, const char* StringForFalse, ...);
128 
129  // -- absorbing contents of another GetPot object
130  void absorb(const GetPot& That);
131 
132  // -- for ufo detection: recording requested arguments, options etc.
133  void clear_requests();
134  void disable_request_recording() { __request_recording_f = false; }
135  void enable_request_recording() { __request_recording_f = true; }
136 
137 
138  // (*) direct access to command line arguments -----------------------------
139 #ifndef SWIG
140  const std::string operator[](unsigned Idx) const;
141 #endif
142  unsigned size() const;
143 
144  // (*) flags ---------------------------------------------------------------
145  bool options_contain(const char* FlagList) const;
146  bool argument_contains(unsigned Idx, const char* FlagList) const;
147 
148  // -- get argument at cursor++
149  template <class T> T next(T Default);
150 
151  // -- search for option and get argument at cursor++
152  // -- search for one of the given options and get argument that follows it
153  template <class T> T follow(T Default, const char* Option);
154  template <class T> T follow(T Default, unsigned No, const char* Option, ...);
155 
156  // -- directly followed arguments
157  template <class T> T direct_follow(T Default, const char* Option);
158 
159  std::vector<std::string> string_tails(const char* StartString);
160  std::vector<int> int_tails(const char* StartString, const int Default = 1);
161  std::vector<double> double_tails(const char* StartString, const double Default = 1.0);
162 
163 
164  // -- lists of nominuses following an option
165  STRING_VECTOR nominus_followers(const char* Option);
166  STRING_VECTOR nominus_followers(unsigned No, ...);
167 
168  // (*) nominus arguments ---------------------------------------------------
169  STRING_VECTOR nominus_vector() const;
170  unsigned nominus_size() const { return static_cast<unsigned int>(idx_nominus.size()); }
171  std::string next_nominus();
172 
173  // (*) Get command line argument number Idx
174  template <class T> T get(unsigned Idx, T Default) const;
175 
176  // (*) variables -----------------------------------------------------------
177  // -- operator() for quick access to variables
178  // -- get() for constraint based access using 'GetPot' constraints
179  STRING_VECTOR get_section_names() const;
180  void set_prefix(StringOrCharP Prefix) { prefix = Prefix.content; }
181  STRING_VECTOR get_variable_names() const;
182  // -- scalar values
183  template <class T> T operator()(const StringOrCharP VarName, T Default) const;
184  template <class T> T get(const StringOrCharP VarName);
185  template <class T> T get(const StringOrCharP VarName, const char* Constraint);
186  template <class T> T get(const StringOrCharP VarName, const char* Constraint,
187  T Default);
188  // -- vectors (access element via 'Idx')
189  unsigned vector_variable_size(StringOrCharP VarName) const;
190  template <class T> T operator()(const StringOrCharP VarName, unsigned Idx, T Default) const;
191  template <class T> T get_element(const StringOrCharP VarName, unsigned Idx,
192  const char* Constraint);
193  template <class T> T get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint,
194  T Default);
195 
196  // -- setting variables
197  // i) from outside of GetPot (considering prefix etc.)
198  // ii) from inside, use '__set_variable()' below
199  template <class T> void set_variable(StringOrCharP VarName, T Value, const bool Requested = true);
200  template <class T> void set(StringOrCharP VarName, T& Value);
201  template <class T> void set(StringOrCharP VarName, T& Value, const char* Constraint);
202  template <class T, class U> void set(StringOrCharP VarName, T& Value, const char* Constraint, U Default);
203 
204  // (*) cursor oriented functions -------------------------------------------
205  bool search_failed() const { return search_failed_f; }
206 
207  // -- search for a certain option and set cursor to position
208  bool search(const char* option);
209  bool search(unsigned No, const char* P, ...);
210 
211  // -- enable/disable search for an option in loop
212  void disable_loop() { search_loop_f = false; }
213  void enable_loop() { search_loop_f = true; }
214 
215  // -- reset cursor to position '1'
216  void reset_cursor();
217  void init_multiple_occurrence();
218 
219  // (*) unidentified flying objects -----------------------------------------
220  STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const;
221  STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const;
222  STRING_VECTOR unidentified_arguments() const;
223 
224  STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const;
225  STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const;
226  STRING_VECTOR unidentified_options() const;
227 
228  std::string unidentified_flags(const char* Known,
229  int ArgumentNumber /* =-1 */) const;
230 
231  STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const;
232  STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const;
233  STRING_VECTOR unidentified_variables() const;
234 
235  STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const;
236  STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const;
237  STRING_VECTOR unidentified_sections() const;
238 
239  STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const;
240  STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const;
241  STRING_VECTOR unidentified_nominuses() const;
242 
243  // (*) output --------------------------------------------------------------
244 # ifndef SWIG
245  int print() const;
246 # endif
247 
248 private:
249  // (*) Type Declaration ----------------------------------------------------
250  struct variable {
251  //-----------
252  // Variable to be specified on the command line or in input files.
253  // (i.e. of the form var='12 312 341')
254 
255  // -- constructors, destructors, assignment operator
256  variable();
257  variable(const variable&);
258  variable(const std::string& Name, const std::string& Value, const std::string& FieldSeparator);
259  ~variable();
260  variable& operator=(const variable& That);
261 
262  void take(const std::string& Value, const std::string& FieldSeparator);
263 
264  // -- get a specific element in the string vector
265  // (return 0 if not present)
266  const std::string* get_element(unsigned Idx, bool ThrowExceptionF=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT) const;
267 
268  // -- data memebers
269  std::string name; // identifier of variable
270  STRING_VECTOR value; // value of variable stored in vector
271  std::string original; // value of variable as given on command line
272  };
273 
274  // (*) member variables --------------------------------------------------------------
275  bool built; // false while in constructor, true afterwards
276  std::string filename; // the configuration file
277  STRING_VECTOR true_string_list; // strings that mean 'true'
278  STRING_VECTOR false_string_list; // strings that mean 'false'
279  std::string prefix; // prefix automatically added in queries
280  std::string section; // (for dollar bracket parsing)
281  STRING_VECTOR section_list; // list of all parsed sections
282  // -- argument vector
283  STRING_VECTOR argv; // vector of command line arguments stored as strings
284  unsigned cursor; // cursor for argv
285  bool search_loop_f; // shall search start at beginning after
286  // // reaching end of arg array ?
287  bool search_failed_f; // flag indicating a failed search() operation
288  // // (e.g. next() functions react with 'missed')
289 
290  // -- nominus vector
291  int nominus_cursor; // cursor for nominus_pointers
292  std::vector<unsigned> idx_nominus; // indecies of 'no minus' arguments
293 
294  // -- variables
295  // (arguments of the form "variable=value")
296  std::vector<variable> variables;
297 
298  // -- comment delimiters
299  std::string _comment_start;
300  std::string _comment_end;
301 
302  // -- field separator (separating elements of a vector)
303  std::string _field_separator;
304 
305  // -- some functions return a char pointer to a temporarily existing string
306  // this container makes them 'available' until the getpot object is destroyed.
307  std::vector<std::vector<char>* > __internal_string_container;
308 
309  // -- keeping track about arguments that are requested, so that the UFO detection
310  // can be simplified
311  STRING_VECTOR _requested_arguments;
312  STRING_VECTOR _requested_variables;
313  STRING_VECTOR _requested_sections;
314 
315  bool __request_recording_f; // speed: request recording can be turned off
316 
317  // -- if an argument is requested record it and the 'tag' the section branch to which
318  // it belongs. Caution: both functions mark the sections as 'tagged'.
319  void __record_argument_request(const std::string& Arg);
320  void __record_variable_request(const std::string& Arg);
321 
322  // (*) helper functions ----------------------------------------------------
323  // build a GetPot instance
324  void __build(const std::string& FileName,
325  const std::string& CommentStart, const std::string& CommentEnd,
326  const std::string& FieldSeparator);
327  // split a string according to delimiters and elements are stored in a vector.
328  void __split(std::string str, std::vector<std::string>& vect, std::string delimiters = " \n\t");
329  // set variable from inside GetPot (no prefix considered)
330  void __set_variable(const std::string& VarName, const std::string& Value);
331 
332  // -- produce three basic data vectors:
333  // - argument vector
334  // - nominus vector
335  // - variable dictionary
336  void __parse_argument_vector(const STRING_VECTOR& ARGV);
337 
338  // -- helpers for argument list processing
339  // * search for a variable in 'variables' array
340  const variable* __find_variable(const std::string&, const std::string& TypeName,
341  bool ThrowExceptionF=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT) const;
342  template <class T> T __get(const StringOrCharP VarName, const char* Constraint,
343  bool ThrowExceptionF) const;
344  template <class T> T __get(const StringOrCharP VarName, const char* Constraint, T Default,
345  bool ThrowExceptionF) const;
346  template <class T> T __get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint,
347  bool ThrowExceptionF) const;
348  template <class T> T __get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint,
349  T Default, bool ThrowExceptionF) const;
350 
351  // * support finding directly followed arguments
352  const char* __match_starting_string(const char* StartString);
353  // * support search for flags in a specific argument
354  bool __check_flags(const std::string& Str, const char* FlagList) const;
355  // * type conversion if possible
356  template <class T> T __convert_to_type(const std::string& String, T Default,
357  bool ThrowExceptionF=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT) const;
358 
359  // * provide a const char* to maintained copies of strings.
360  const char* __get_const_char(const std::string& String) const;
361 
362  // * check for GetPot constraints
363  bool __constraint_check(const std::string& Value,
364  const char* ConstraintStr,
365  bool ThrowExceptionF) const;
366  bool __constraint_check_OR(const std::string& Value, const char** iterator) const;
367  bool __constraint_check_AND(const std::string& Value, const char** iterator) const;
368  bool __constraint_check_PRIMARY(const std::string& Value, const char** iterator) const;
369  bool __constrain_check_EQUAL_STRING(const char* viterator, const char** iterator) const;
370  // * prefix extraction
371  const std::string __get_remaining_string(const std::string& String,
372  const std::string& Start) const;
373  // * search for a specific string
374  bool __search_string_vector(const STRING_VECTOR& Vec,
375  const std::string& Str) const;
376 
377  // -- helpers to parse input file
378  // create an argument vector based on data found in an input file, i.e.:
379  // 1) delete comments (in between '_comment_start' '_comment_end')
380  // 2) contract assignment expressions, such as
381  // my-variable = '007 J. B.'
382  // into
383  // my-variable='007 J. B.'
384  // 3) interprete sections like '[../my-section]' etc.
385  void __skip_whitespace(std::istream& istr);
386  const std::string __get_next_token(std::istream& istr);
387  const std::string __get_string(std::istream& istr);
388  const std::string __get_until_closing_bracket(std::istream& istr);
389 
390  STRING_VECTOR __read_in_stream(std::istream& istr);
391  STRING_VECTOR __read_in_file(const std::string& FileName);
392  std::string __process_section_label(const std::string& Section,
393  STRING_VECTOR& section_stack);
394 
395  // -- dollar bracket expressions
396  std::string __DBE_expand_string(const std::string str);
397  std::string __DBE_expand(const std::string str);
398  const GetPot::variable* __DBE_get(const std::string str);
399  STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber);
400 
401  std::string __double2string(const double& Value) const;
402  std::string __int2string(const int& Value) const;
403  STRING_VECTOR __get_section_tree(const std::string& FullPath);
404 };
405 
406 #ifdef GETPOT_SETTING_NAMESPACE
407 } // namespace GetPotNamespace.
408 #endif
409 
410 
411 #endif // __INCLUDE_GUARD_GETPOT_HPP__
412 
413 
414 
bool __request_recording_f
Definition: GetPot.hpp:315
std::vector< unsigned > idx_nominus
Definition: GetPot.hpp:292
std::string prefix
Definition: GetPot.hpp:279
std::vector< std::vector< char > *> __internal_string_container
Definition: GetPot.hpp:307
STRING_VECTOR _requested_arguments
Definition: GetPot.hpp:311
std::vector< std::string > STRING_VECTOR
Definition: GetPot.hpp:91
StringOrCharP(const char *Value)
Definition: GetPot.hpp:99
bool search_failed_f
Definition: GetPot.hpp:287
void enable_loop()
Definition: GetPot.hpp:213
STRING_VECTOR section_list
Definition: GetPot.hpp:281
void set_prefix(StringOrCharP Prefix)
Definition: GetPot.hpp:180
std::string name
Definition: GetPot.hpp:269
void disable_request_recording()
Definition: GetPot.hpp:134
std::string filename
Definition: GetPot.hpp:276
bool search_loop_f
Definition: GetPot.hpp:285
STRING_VECTOR false_string_list
Definition: GetPot.hpp:278
unsigned nominus_size() const
Definition: GetPot.hpp:170
void enable_request_recording()
Definition: GetPot.hpp:135
STRING_VECTOR _requested_sections
Definition: GetPot.hpp:313
StringOrCharP(const std::string &Value)
Definition: GetPot.hpp:101
std::string original
Definition: GetPot.hpp:271
#define GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT
Definition: GetPot.hpp:32
unsigned cursor
Definition: GetPot.hpp:284
bool built
Definition: GetPot.hpp:275
int nominus_cursor
Definition: GetPot.hpp:291
std::string section
Definition: GetPot.hpp:280
std::string content
Definition: GetPot.hpp:95
std::string _comment_end
Definition: GetPot.hpp:300
STRING_VECTOR true_string_list
Definition: GetPot.hpp:277
void disable_loop()
Definition: GetPot.hpp:212
bool search_failed() const
Definition: GetPot.hpp:205
STRING_VECTOR value
Definition: GetPot.hpp:270
std::string _field_separator
Definition: GetPot.hpp:303
std::vector< variable > variables
Definition: GetPot.hpp:296
STRING_VECTOR argv
Definition: GetPot.hpp:283
std::string _comment_start
Definition: GetPot.hpp:299
STRING_VECTOR _requested_variables
Definition: GetPot.hpp:312