libMesh
getpot.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 // GetPot Version libMeshHPCT_fork-1.2 Apr/14/2010
3 // Based on "getpot-1.1.1.tgz" version from SourceForge
4 //
5 // New code (C) 2009-2013 Roy Stogner, Karl Schulz
6 //
7 // GetPot Version 1.0 Sept/13/2002
8 //
9 // WEBSITE: http://getpot.sourceforge.net
10 //
11 // This library is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Lesser General Public License as
13 // published by the Free Software Foundation; either version 2.1 of the
14 // License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful, but
17 // WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 // USA
25 //
26 // (C) 2001-2002 Frank R. Schaefer
27 //==========================================================================
28 #ifndef LIBMESH_GETPOT_H
29 #define LIBMESH_GETPOT_H
30 
31 #if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
32 #define strtok_r(a, b, c) strtok(a, b)
33 #endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC
34 
35 #include <algorithm>
36 #include <cstddef>
37 #include <fstream>
38 #include <iostream> // not every compiler distribution includes <iostream> with <fstream>
39 #include <memory>
40 #include <set>
41 #include <sstream>
42 #include <stdexcept>
43 #include <string>
44 #include <typeinfo>
45 #include <vector>
46 
47 #include <cmath>
48 #include <cstdlib>
49 #include <ctime>
50 #include <cctype>
51 
52 extern "C" {
53 #include <stdarg.h> // --> va_list and friends
54 #include <string.h> // --> strcmp, strncmp, strlen, strncpy
55 }
56 
57 // Undefine USE_LIBMESH to avoid libMesh-specific code
58 
59 #define USE_LIBMESH 1
60 
61 #ifdef USE_LIBMESH
62 
63 #include "libmesh/libmesh_common.h"
64 
65 // We need a mutex to keep const operations thread-safe in the
66 // presence of mutable containers. Right now GetPot supports a
67 // Threads::scoped_mutex wrapper around TBB, and we're assuming that
68 // users aren't doing any threaded GetPot usage when TBB threads are
69 // disabled.
70 #if !defined(GETPOT_DISABLE_MUTEX)
71 #include "libmesh/threads.h"
72 #define SCOPED_MUTEX libMesh::Threads::spin_mutex::scoped_lock lock(_getpot_mtx)
73 #define GETPOT_MUTEX_DECLARE mutable libMesh::Threads::spin_mutex _getpot_mtx
74 #else
75 #define SCOPED_MUTEX
76 #define GETPOT_MUTEX_DECLARE
77 #endif
78 
79 #define getpot_cerr libMesh::err
80 #define getpot_error() libmesh_error()
81 #define getpot_file_error(filename) libmesh_file_error(filename)
82 #define getpot_cast_int libMesh::cast_int
83 
84 // If libmesh detected the inverse hyperbolic trig functions, set
85 // special #defines for getpot.h
86 #ifdef LIBMESH_HAVE_CXX11_INVERSE_HYPERBOLIC_SINE
87 #define HAVE_INVERSE_HYPERBOLIC_SINE
88 #endif
89 
90 #ifdef LIBMESH_HAVE_CXX11_INVERSE_HYPERBOLIC_COSINE
91 #define HAVE_INVERSE_HYPERBOLIC_COSINE
92 #endif
93 
94 #ifdef LIBMESH_HAVE_CXX11_INVERSE_HYPERBOLIC_TANGENT
95 #define HAVE_INVERSE_HYPERBOLIC_TANGENT
96 #endif
97 
98 #else // !USE_LIBMESH
99 
100 // Currently threaded GetPot use is only supported via libMesh Threads
101 #define GETPOT_DISABLE_MUTEX
102 #define SCOPED_MUTEX
103 #define GETPOT_MUTEX_DECLARE
104 
105 #define getpot_cerr std::cerr
106 #define getpot_error() throw std::runtime_error(std::string("GetPot Error"))
107 #define getpot_file_error(filename) getpot_error()
108 #define getpot_cast_int static_cast
109 
110 // Clang provides the __has_builtin macro, we define it for compilers
111 // that don't...
112 #ifndef __has_builtin
113 #define __has_builtin(x) 0
114 #endif
115 
116 // Fine-grained ifdefs for all three inverse hyperbolic trig
117 // functions. This works for the two clang compilers I tried it
118 // on... a hand-built one and one from Apple.
119 #if __cplusplus > 199711L && (!defined(__clang__) || __has_builtin(asinh))
120 #define HAVE_INVERSE_HYPERBOLIC_SINE
121 #endif
122 
123 #if __cplusplus > 199711L && (!defined(__clang__) || __has_builtin(acosh))
124 #define HAVE_INVERSE_HYPERBOLIC_COSINE
125 #endif
126 
127 #if __cplusplus > 199711L && (!defined(__clang__) || __has_builtin(atanh))
128 #define HAVE_INVERSE_HYPERBOLIC_TANGENT
129 #endif
130 
131 #endif // #ifdef USE_LIBMESH
132 
133 
134 typedef std::vector<std::string> STRING_VECTOR;
135 
136 #define victorate(TYPE, VARIABLE, ITERATOR) \
137  std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin(); \
138  for (; (ITERATOR) != (VARIABLE).end(); ++(ITERATOR))
139 
140 // We allow GETPOT_NAMESPACE to be defined before this file is
141 // included; if libraries using two different versions of GetPot might
142 // be linked together, the result may be unsafe unless they're put in
143 // different namespaces.
144 #ifdef GETPOT_NAMESPACE
145 namespace GETPOT_NAMESPACE {
146 #endif
147 
155 class GetPot
156 {
157  inline void _basic_initialization();
158 
159 public:
163  inline GetPot();
164  inline GetPot(const GetPot&);
165  inline GetPot(const int argc_, const char* const* argv_,
166  const char* FieldSeparator=0x0);
167  inline GetPot(const char* FileName,
168  const char* CommentStart=0x0, const char* CommentEnd=0x0,
169  const char* FieldSeparator=0x0);
170  inline GetPot(const std::string& FileName,
171  const std::string& CommentStart = std::string("#"),
172  const std::string& CommentEnd = std::string("\n"),
173  const std::string& FieldSeparator = std::string(" \t\n"));
174 
179  inline GetPot(std::istream& FileStream,
180  const std::string& CommentStart = std::string("#"),
181  const std::string& CommentEnd = std::string("\n"),
182  const std::string& FieldSeparator = std::string(" \t\n"));
183  inline ~GetPot();
184  inline GetPot& operator=(const GetPot&);
185 
189  inline void parse_command_line(const int argc_, const char * const* argv_,
190  const char* FieldSeparator =0x0);
191  inline void parse_input_file(const std::string& FileName,
192  const std::string& CommentStart=std::string("#"),
193  const std::string& CommentEnd=std::string("\n"),
194  const std::string& FieldSeparator=std::string(" \t\n"));
195 
196  inline void parse_input_stream(std::istream& FileStream,
197  const std::string& FileName=std::string("ParsedFromStream"),
198  const std::string& CommentStart=std::string("#"),
199  const std::string& CommentEnd=std::string("\n"),
200  const std::string& FieldSeparator=std::string(" \t\n"));
201 
205  inline void absorb(const GetPot& Other);
206 
210  inline void clear_requests();
213 
217  inline const char* operator[](unsigned Idx) const;
218 
219  template <typename T>
220  inline T get(unsigned Idx, const T& Default) const;
221 
222  inline const char* get(unsigned Idx, const char* Default) const;
223  inline unsigned size() const;
224 
228  inline bool options_contain(const char* FlagList) const;
229  inline bool argument_contains(unsigned Idx, const char* FlagList) const;
230 
238  inline bool have_variable(const char* VarName) const;
239  inline bool have_variable(const std::string& VarName) const;
240 
250  bool have_section(const char* section_name) const;
251 
261  bool have_section(const std::string& section_name) const;
262 
266  template<typename T>
267  inline T operator()(const char* VarName, const T& Default) const;
268 
269  template<typename T>
270  inline T operator()(const std::string& VarName, const T& Default) const;
271 
272  inline const char* operator()(const char* VarName, const char* Default) const;
273  inline const char* operator()(const std::string& VarName, const char* Default) const;
274 
278  template<typename T>
279  inline T operator()(const char* VarName, const T& Default, unsigned Idx) const;
280 
281  template<typename T>
282  inline T operator()(const std::string& VarName, const T& Default, unsigned Idx) const;
283 
284  inline const char* operator()(const char* VarName, const char* Default, unsigned Idx) const;
285  inline const char* operator()(const std::string& VarName, const char* Default, unsigned Idx) const;
286 
291  template<typename T>
292  inline T get_value_no_default(const char* VarName, const T& Default) const;
293 
294  template<typename T>
295  inline T get_value_no_default(const std::string& VarName, const T& Default) const;
296 
297  inline const char* get_value_no_default(const char* VarName, const char* Default) const;
298  inline const char* get_value_no_default(const std::string& VarName, const char* Default) const;
299 
303  template<typename T>
304  inline T get_value_no_default(const char* VarName, const T& Default, unsigned Idx) const;
305 
306  template<typename T>
307  inline T get_value_no_default(const std::string& VarName, const T& Default, unsigned Idx) const;
308 
309  inline const char* get_value_no_default(const char* VarName, const char* Default, unsigned Idx) const;
310  inline const char* get_value_no_default(const std::string& VarName, const char* Default, unsigned Idx) const;
311 
317  template<typename T>
318  inline void set(const char* VarName, const T& Value, const bool Requested = true);
319 
320  template<typename T>
321  inline void set(const std::string& VarName, const T& Value, const bool Requested = true);
322 
323  inline void set(const char* VarName, const char* Value, const bool Requested = true);
324  inline void set(const std::string& VarName, const char* Value, const bool Requested = true);
325 
326  inline unsigned vector_variable_size(const char* VarName) const;
327  inline unsigned vector_variable_size(const std::string& VarName) const;
328 
329  /*
330  * Return a list of all variables set by the current input
331  */
332  inline STRING_VECTOR get_variable_names() const;
333 
334  /*
335  * Return a list of all sections present in the current input
336  */
337  inline STRING_VECTOR get_section_names() const;
338 
339  /*
340  * Return a list of all subsections of the given section name in the
341  * current input.
342  *
343  * Subsections will be returned in the order they appear in the
344  * input.
345  *
346  * Subsections which exist multiple times in the input file will
347  * only be returned once, in the position of their first appearance.
348  */
349  inline STRING_VECTOR get_subsection_names(const std::string & section_name) const;
350 
351  inline std::set<std::string> get_overridden_variables() const;
352 
356  inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); }
357  inline bool search_failed() const { return search_failed_f; }
358 
362  inline void disable_loop() { search_loop_f = false; }
363  inline void enable_loop() { search_loop_f = true; }
364 
368  inline void reset_cursor();
369  inline void init_multiple_occurrence();
370 
374  inline bool search(const char* option);
375  inline bool search(const std::string& option);
376  inline bool search(unsigned No, const char* P, ...);
377 
381  template<typename T>
382  inline T next(const T& Default);
383 
384  inline const char* next(const char* Default);
385 
389  template<typename T>
390  inline T follow(const T& Default, const char* Option);
391 
392  inline const char* follow(const char* Default, const char* Option);
393 
397  template<typename T>
398  inline T follow(const T& Default, unsigned No, const char* Option, ...);
399 
400  inline const char* follow(const char* Default, unsigned No, const char* Option, ...);
401 
405  template<typename T>
406  inline T direct_follow(const T& Default, const char* Option);
407 
408  inline const char* direct_follow(const char* Default, const char* Option);
409 
413  inline void reset_nominus_cursor();
414  inline STRING_VECTOR nominus_vector() const;
415  inline unsigned nominus_size() const { return getpot_cast_int<unsigned>(idx_nominus.size()); }
416  inline const char* next_nominus();
417  inline std::string next_nominus_string();
418 
422  inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const;
423  inline STRING_VECTOR unidentified_arguments(const std::set<std::string>& Knowns) const;
424  inline STRING_VECTOR unidentified_arguments(const std::vector<std::string>& Knowns) const;
425  inline STRING_VECTOR unidentified_arguments() const;
426 
427  inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const;
428  inline STRING_VECTOR unidentified_options(const std::set<std::string>& Knowns) const;
429  inline STRING_VECTOR unidentified_options(const std::vector<std::string>& Knowns) const;
430  inline STRING_VECTOR unidentified_options() const;
431 
432  inline std::string unidentified_flags(const char* Known, int ArgumentNumber /* =-1 */) const;
433 
434  inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const;
435  inline STRING_VECTOR unidentified_variables(const std::set<std::string>& Knowns) const;
436  inline STRING_VECTOR unidentified_variables(const std::vector<std::string>& Knowns) const;
437  inline STRING_VECTOR unidentified_variables() const;
438 
439  inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const;
440  inline STRING_VECTOR unidentified_sections(const std::set<std::string>& Knowns) const;
441  inline STRING_VECTOR unidentified_sections(const std::vector<std::string>& Knowns) const;
442  inline STRING_VECTOR unidentified_sections() const;
443 
444  inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const;
445  inline STRING_VECTOR unidentified_nominuses(const std::set<std::string>& Knowns) const;
446  inline STRING_VECTOR unidentified_nominuses(const std::vector<std::string>& Knowns) const;
447  inline STRING_VECTOR unidentified_nominuses() const;
448 
452  std::set<std::string> get_requested_arguments() const;
453  std::set<std::string> get_requested_variables() const;
454  std::set<std::string> get_requested_sections() const;
455 
463  inline int print(std::ostream &out_stream = std::cout) const;
464 
470  inline int print(const char *custom_prefix,
471  std::ostream &out_stream = std::cout,
472  unsigned int skip_count=1) const;
473 
474 private:
475 
480  struct variable
481  {
485  variable();
486  variable(const variable&);
487  variable(const char* Name, const char* Value, const char* FieldSeparator);
488  ~variable();
489  variable& operator=(const variable& Other);
490 
491  void take(const char* Value, const char* FieldSeparator);
492 
497  const std::string* get_element(unsigned Idx) const;
498 
502  std::string name; // identifier of variable
503  STRING_VECTOR value; // value of variable stored in vector
504  std::string original; // value of variable as given on command line
505  };
506 
510  std::string prefix; // prefix automatically added in queries
511  std::string section; // (for dollar bracket parsing)
512  STRING_VECTOR section_list; // list of all parsed sections
513 
517  STRING_VECTOR argv; // vector of command line arguments stored as strings
518  unsigned cursor; // cursor for argv
519  bool search_loop_f; // shall search start at beginning after reaching end of arg array ?
520  bool search_failed_f; // flag indicating a failed search() operation (e.g. next() functions react with 'missed')
521  std::set<std::string> overridden_vars; // vector of variables that were supplied more than once during parsing
522 
526  int nominus_cursor; // cursor for nominus_pointers
527  std::vector<unsigned> idx_nominus; // indices of 'no minus' arguments
528 
532  std::vector<variable> variables;
533 
537  std::string _comment_start;
538  std::string _comment_end;
539 
543  std::string _field_separator;
544 
552 
557  struct ltstr
558  {
565  using is_transparent = void;
566 
567  bool operator()(const std::unique_ptr<const char[]> & s1,
568  const std::unique_ptr<const char[]> & s2) const
569  { return strcmp(s1.get(), s2.get()) < 0; }
570 
571  bool operator()(const std::unique_ptr<const char[]> & s1,
572  const char * const & s2) const
573  { return strcmp(s1.get(), s2) < 0; }
574 
575  bool operator()(const char * const & s1,
576  const std::unique_ptr<const char[]> & s2) const
577  { return strcmp(s1, s2.get()) < 0; }
578  };
579 
588  mutable std::set<std::unique_ptr<const char[]>, ltstr> _internal_string_container;
589 
594  const char* _internal_managed_copy(const std::string& Arg) const;
595 
600  mutable std::set<std::string> _requested_arguments;
601  mutable std::set<std::string> _requested_variables;
602  mutable std::set<std::string> _requested_sections;
603 
604  bool request_recording_f; // speed: request recording can be turned off
605 
612  void _record_argument_request(const std::string& Arg) const;
613  void _record_variable_request(const std::string& Arg) const;
614 
622  inline void _set_variable(const std::string& VarName,
623  const std::string& Value,
624  const bool Requested);
625 
632  inline void _parse_argument_vector(const STRING_VECTOR& ARGV);
633 
641  inline const variable* _find_variable(const char*) const;
642 
646  inline const variable* _request_variable(const char*) const;
647 
651  inline const char* _match_starting_string(const char* StartString);
652 
656  inline bool _check_flags(const std::string& Str, const char* FlagList) const;
657 
661  template<typename T>
662  inline T _convert_to_type(const std::string& String, const T& Default) const;
663 
664  inline std::string _convert_to_type(const std::string& String, const char* Default) const;
665 
666  template<typename T>
667  inline T _convert_to_type_no_default(const char* VarName, const std::string& String, const T& Default) const;
668 
669  inline std::string _convert_to_type_no_default(const char* VarName, const std::string& String, const char* Default) const;
670 
674  const std::string _get_remaining_string(const std::string& String,
675  const std::string& Start) const;
679  inline bool _search_string_vector(const STRING_VECTOR& Vec,
680  const std::string& Str) const;
681 
692  inline void _skip_whitespace(std::istream& istr);
693  inline const std::string _get_next_token(std::istream& istr);
694  inline const std::string _get_string(std::istream& istr);
695  inline const std::string _get_until_closing_bracket(std::istream& istr);
696  inline const std::string _get_until_closing_square_bracket(std::istream& istr);
697 
698  inline STRING_VECTOR _read_in_stream(std::istream& istr);
699  inline std::string _process_section_label(const std::string& Section,
700  STRING_VECTOR& section_stack);
701 
705  std::string _DBE_expand_string(const std::string& str);
706  std::string _DBE_expand(const std::string& str);
707  const GetPot::variable* _DBE_get_variable(const std::string& str);
708  STRING_VECTOR _DBE_get_expr_list(const std::string& str, const unsigned ExpectedNumber);
709 
710  template <typename T>
711  static std::string _convert_from_type(const T& Value)
712  {
713  std::ostringstream out_string;
714  out_string << Value;
715  return out_string.str();
716  }
717 
722  static STRING_VECTOR _get_section_tree(const std::string& FullPath)
723  {
724  STRING_VECTOR result;
725  for (std::size_t pos = 0; pos != FullPath.size(); ++pos)
726  {
727  if (FullPath[pos] == '/')
728  result.push_back(FullPath.substr(0,pos));
729  }
730 
731  return result;
732  }
733 };
734 
735 
737 // (*) constructors, destructor, assignment operator
738 //.............................................................................
739 //
740 inline void
742 {
743  cursor = 0;
744  nominus_cursor = -1;
745  search_failed_f = true;
746  search_loop_f = true;
747  prefix = "";
748  section = "";
749 
750  // automatic request recording for later ufo detection
751  request_recording_f = true;
752 
753  // comment start and end strings
754  _comment_start = std::string("#");
755  _comment_end = std::string("\n");
756 
757  // default: separate vector elements by whitespaces
758  _field_separator = " \t\n";
759 }
760 
761 
762 
763 inline
765  prefix(),
766  section(),
767  section_list(),
768  argv(),
769  cursor(),
770  search_loop_f(),
771  search_failed_f(),
772  nominus_cursor(),
773  idx_nominus(),
774  variables(),
775  _comment_start(),
776  _comment_end(),
777  _field_separator(),
778 #if !defined(GETPOT_DISABLE_MUTEX)
779  _getpot_mtx(),
780 #endif
781  _internal_string_container(),
782  _requested_arguments(),
783  _requested_variables(),
784  _requested_sections(),
785  request_recording_f()
786 {
788 }
789 
790 
791 
792 inline
793 GetPot::GetPot(const int argc_, const char * const * argv_,
794  const char* FieldSeparator /* =0x0 */) :
795  // leave 'char**' non-const to honor less capable compilers ...
796  prefix(),
797  section(),
798  section_list(),
799  argv(),
800  cursor(),
801  search_loop_f(),
802  search_failed_f(),
803  nominus_cursor(),
804  idx_nominus(),
805  variables(),
806  _comment_start(),
807  _comment_end(),
808  _field_separator(),
809 #if !defined(GETPOT_DISABLE_MUTEX)
810  _getpot_mtx(),
811 #endif
812  _internal_string_container(),
813  _requested_arguments(),
814  _requested_variables(),
815  _requested_sections(),
816  request_recording_f()
817 {
818  this->parse_command_line(argc_, argv_, FieldSeparator);
819 }
820 
821 
822 
823 // leave 'char**' non-const to honor less capable compilers ...
824 inline void
825 GetPot::parse_command_line(const int argc_, const char * const * argv_,
826  const char* FieldSeparator /* =0x0 */)
827 {
829 
830  // if specified -> overwrite default string
831  if (FieldSeparator)
832  _field_separator = std::string(FieldSeparator);
833 
834  // -- make an internal copy of the argument list:
835  STRING_VECTOR _apriori_argv;
836  // -- for the sake of clarity: we do want to include the first
837  // argument of the first parsing source in the argument vector!
838  // it will not be a nominus argument, though. This gives us a
839  // minimum vector size of one which facilitates error checking
840  // in many functions. Also the user will be able to retrieve
841  // the name of his application or input file by "get[0]"
842  _apriori_argv.push_back(std::string(argv_[0]));
843  for (int i=1; i<argc_; i++)
844  {
845  std::string tmp(argv_[i]); // recall the problem with temporaries,
846  _apriori_argv.push_back(tmp); // reference counting in argument lists ...
847  }
848  _parse_argument_vector(_apriori_argv);
849 }
850 
851 
852 
853 inline
854 GetPot::GetPot(const char* FileName,
855  const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */,
856  const char* FieldSeparator/* = 0x0 */) :
857  prefix(),
858  section(),
859  section_list(),
860  argv(),
861  cursor(),
862  search_loop_f(),
863  search_failed_f(),
864  nominus_cursor(),
865  idx_nominus(),
866  variables(),
867  _comment_start(),
868  _comment_end(),
869  _field_separator(),
870 #if !defined(GETPOT_DISABLE_MUTEX)
871  _getpot_mtx(),
872 #endif
873  _internal_string_container(),
874  _requested_arguments(),
875  _requested_variables(),
876  _requested_sections(),
877  request_recording_f()
878 {
879  const std::string& StrCommentStart = CommentStart ? CommentStart : std::string("#");
880  const std::string& StrCommentEnd = CommentEnd ? CommentEnd : std::string("\n");
881  const std::string& StrFieldSeparator = FieldSeparator ? FieldSeparator : std::string(" \t\n");
882  this->parse_input_file(FileName, StrCommentStart, StrCommentEnd, StrFieldSeparator);
883 }
884 
885 
886 
887 inline
888 GetPot::GetPot(const std::string& FileName,
889  const std::string& CommentStart,
890  const std::string& CommentEnd,
891  const std::string& FieldSeparator) :
892  prefix(),
893  section(),
894  section_list(),
895  argv(),
896  cursor(),
897  search_loop_f(),
898  search_failed_f(),
899  nominus_cursor(),
900  idx_nominus(),
901  variables(),
902  _comment_start(),
903  _comment_end(),
904  _field_separator(),
905 #if !defined(GETPOT_DISABLE_MUTEX)
906  _getpot_mtx(),
907 #endif
908  _internal_string_container(),
909  _requested_arguments(),
910  _requested_variables(),
911  _requested_sections(),
912  request_recording_f()
913 {
914  this->parse_input_file(FileName, CommentStart, CommentEnd, FieldSeparator);
915 }
916 
917 inline void
918 GetPot::parse_input_file(const std::string& FileName,
919  const std::string& CommentStart,
920  const std::string& CommentEnd,
921  const std::string& FieldSeparator)
922 {
923  std::ifstream input(FileName.c_str());
924 
925  if (!input)
926  getpot_file_error(FileName);
927 
928  this->parse_input_stream(input,FileName,CommentStart,CommentEnd,FieldSeparator);
929 }
930 
931 
932 inline
933 GetPot::GetPot(std::istream& FileStream,
934  const std::string& CommentStart,
935  const std::string& CommentEnd,
936  const std::string& FieldSeparator) :
937  prefix(),
938  section(),
939  section_list(),
940  argv(),
941  cursor(),
942  search_loop_f(),
943  search_failed_f(),
944  nominus_cursor(),
945  idx_nominus(),
946  variables(),
947  _comment_start(),
948  _comment_end(),
949  _field_separator(),
950 #if !defined(GETPOT_DISABLE_MUTEX)
951  _getpot_mtx(),
952 #endif
953  _internal_string_container(),
954  _requested_arguments(),
955  _requested_variables(),
956  _requested_sections(),
957  request_recording_f()
958 {
959  this->parse_input_stream(FileStream,
960  std::string("ParsedFromStream"),// We don't have a filename here
961  CommentStart, CommentEnd, FieldSeparator);
962 }
963 
964 
965 inline void
966 GetPot::parse_input_stream(std::istream& FileStream,
967  const std::string& FileName,
968  const std::string& CommentStart,
969  const std::string& CommentEnd,
970  const std::string& FieldSeparator)
971 {
973 
974  // overwrite default strings
975  _comment_start = std::string(CommentStart);
976  _comment_end = std::string(CommentEnd);
977  _field_separator = FieldSeparator;
978 
979  STRING_VECTOR _apriori_argv;
980  // -- the first element of the argument vector stores the name of
981  // the first parsing source; however, this element is not
982  // parsed for variable assignments or nominuses.
983  //
984  // Regardless, we don't add more than one name to the argument
985  // vector. In this case, we're parsing from a stream, so we'll
986  // hardcode the "filename" to "ParsedFromStream"
987  _apriori_argv.push_back(FileName);
988 
989  STRING_VECTOR args = _read_in_stream(FileStream);
990  _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end());
991  _parse_argument_vector(_apriori_argv);
992 }
993 
994 
995 
996 inline
997 GetPot::GetPot(const GetPot& Other) :
998  prefix(Other.prefix),
999  section(Other.section),
1000  section_list(Other.section_list),
1001  argv(Other.argv),
1002  cursor(Other.cursor),
1003  search_loop_f(Other.search_loop_f),
1004  search_failed_f(Other.search_failed_f),
1005  overridden_vars(),
1006  nominus_cursor(Other.nominus_cursor),
1007  idx_nominus(Other.idx_nominus),
1008  variables(Other.variables),
1009  _comment_start(Other._comment_start),
1010  _comment_end(Other._comment_end),
1011  _field_separator(Other._field_separator),
1012  // #if !defined(GETPOT_DISABLE_MUTEX)
1013  // _getpot_mtx(Other._getpot_mtx),
1014  // #endif
1015  _internal_string_container(),
1016  _requested_arguments(Other._requested_arguments),
1017  _requested_variables(Other._requested_variables),
1018  _requested_sections(Other._requested_sections),
1019  request_recording_f(Other.request_recording_f)
1020 {
1021  for (const auto & otherstr : Other._internal_string_container)
1022  {
1023  auto newlen = strlen(otherstr.get()) + 1;
1024  auto newcopy = std::make_unique<char[]>(newlen);
1025  strncpy(newcopy.get(), otherstr.get(), newlen);
1026  this->_internal_string_container.insert(std::move(newcopy));
1027  }
1028 }
1029 
1030 
1031 
1032 inline
1033 GetPot::~GetPot() = default;
1034 
1035 
1036 
1037 inline GetPot&
1039 {
1040  if (&Other == this)
1041  return *this;
1042 
1043  prefix = Other.prefix;
1044  section = Other.section;
1045  section_list = Other.section_list;
1046  argv = Other.argv;
1047  cursor = Other.cursor;
1048  search_loop_f = Other.search_loop_f;
1052  idx_nominus = Other.idx_nominus;
1053  variables = Other.variables;
1055  _comment_end = Other._comment_end;
1057  // #if !defined(GETPOT_DISABLE_MUTEX)
1058  // _getpot_mtx = Other._getpot_mtx;
1059  // #endif
1064 
1065  // Clear existing strings
1067 
1068  for (const auto & otherstr : Other._internal_string_container)
1069  {
1070  auto newlen = strlen(otherstr.get()) + 1;
1071  auto newcopy = std::make_unique<char[]>(newlen);
1072  strncpy(newcopy.get(), otherstr.get(), newlen);
1073  this->_internal_string_container.insert(std::move(newcopy));
1074  }
1075 
1076  return *this;
1077 }
1078 
1079 
1080 
1081 inline void
1082 GetPot::absorb(const GetPot& Other)
1083 {
1084  if (&Other == this)
1085  return;
1086 
1087  // variables that are not influenced by absorption:
1088  // _comment_start
1089  // _comment_end
1090  // cursor
1091  // nominus_cursor
1092  // search_failed
1093  // idx_nominus
1094  // search_loop_f
1095  argv = Other.argv;
1096  variables = Other.variables;
1097 
1098  if (request_recording_f)
1099  {
1100  // Get a lock before touching anything mutable
1101  SCOPED_MUTEX;
1102 
1103  _requested_arguments.insert(Other._requested_arguments.begin(), Other._requested_arguments.end());
1104  _requested_variables.insert(Other._requested_variables.begin(), Other._requested_variables.end());
1105  _requested_sections.insert(Other._requested_sections.begin(), Other._requested_sections.end());
1106  }
1107 }
1108 
1109 
1110 
1111 inline void
1113 {
1114  // Get a lock before touching anything mutable
1115  SCOPED_MUTEX;
1116 
1117  _requested_arguments.clear();
1118  _requested_variables.clear();
1119  _requested_sections.clear();
1120 }
1121 
1122 
1123 
1124 inline void
1126 {
1127  if (ARGV.empty())
1128  return;
1129 
1130  // build internal databases:
1131  // 1) array with no-minus arguments (usually used as filenames)
1132  // 2) variable assignments:
1133  // 'variable name' '=' number | string
1134  STRING_VECTOR section_stack;
1135  STRING_VECTOR::const_iterator it = ARGV.begin();
1136 
1137 
1138  section = "";
1139 
1140  // -- do not parse the first argument, so that this parsing source
1141  // name is not interpreted a s a nominus or so. If we already
1142  // have parsed arguments, don't bother adding another parsing
1143  // source name
1144  if (argv.empty())
1145  argv.push_back(*it);
1146  ++it;
1147 
1148  // -- loop over remaining arguments
1149  for (; it != ARGV.end(); ++it)
1150  {
1151  std::string arg = *it;
1152 
1153  if (arg.length() == 0)
1154  continue;
1155 
1156  // -- [section] labels and [include file] directives
1157  if (arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']')
1158  {
1159 
1160  // Is this an include file directive?
1161  std::size_t include_pos = arg.find("include ", 1);
1162  if (include_pos != std::string::npos)
1163  {
1164 
1165  const std::string includefile =
1166  _DBE_expand_string(arg.substr(9, arg.length()-9-include_pos));
1167 
1168  this->parse_input_file
1169  (includefile, _comment_start, _comment_end, _field_separator);
1170  }
1171 
1172  else
1173  {
1174  // (*) sections are considered 'requested arguments'
1175  if (request_recording_f)
1176  {
1177  // Get a lock before touching anything mutable
1178  SCOPED_MUTEX;
1179 
1180  _requested_arguments.insert(arg);
1181  }
1182 
1183  const std::string Name = _DBE_expand_string(arg.substr(1, arg.length()-2));
1184  section = _process_section_label(Name, section_stack);
1185  // new section --> append to list of sections
1186  if (find(section_list.begin(), section_list.end(), section) == section_list.end())
1187  if (section.length() != 0) section_list.push_back(section);
1188  argv.push_back(arg);
1189  }
1190  }
1191  else
1192  {
1193  arg = section + _DBE_expand_string(arg);
1194  argv.push_back(arg);
1195  }
1196 
1197  // -- separate array for nominus arguments
1198  if (arg[0] != '-')
1199  idx_nominus.push_back(getpot_cast_int<unsigned>(argv.size()-1));
1200 
1201  // -- variables: does arg contain a '=' operator ?
1202  const std::size_t equals_pos = arg.find_first_of('=');
1203  if (equals_pos != std::string::npos)
1204  {
1205  // (*) record for later ufo detection
1206  // arguments carrying variables are always treated as 'requested' arguments.
1207  // unrequested variables have to be detected with the ufo-variable
1208  // detection routine.
1209  if (request_recording_f)
1210  {
1211  // Get a lock before touching anything mutable
1212  SCOPED_MUTEX;
1213 
1214  _requested_arguments.insert(arg);
1215  }
1216 
1217  // => arg (from start to '=') = Name of variable
1218  // (from '=' to end) = value of variable
1219  _set_variable(arg.substr(0,equals_pos),
1220  arg.substr(equals_pos+1), false);
1221  }
1222  }
1223 }
1224 
1225 
1226 
1227 inline STRING_VECTOR
1228 GetPot::_read_in_stream(std::istream& istr)
1229 {
1230  STRING_VECTOR brute_tokens;
1231  while (istr)
1232  {
1233  _skip_whitespace(istr);
1234  const std::string Token = _get_next_token(istr);
1235  // Allow 'keyword =' to parse with an empty string as value.
1236  // Only break at EOF.
1237  // if (Token.length() == 0 || Token[0] == EOF) break;
1238  if (Token[0] == EOF)
1239  break;
1240  brute_tokens.push_back(Token);
1241  }
1242 
1243  // -- reduce expressions of token1'='token2 to a single
1244  // string 'token1=token2'
1245  // -- copy everything into 'argv'
1246  // -- arguments preceded by something like '[' name ']' (section)
1247  // produce a second copy of each argument with a prefix '[name]argument'
1248  unsigned i1 = 0;
1249  unsigned i2 = 1;
1250  unsigned i3 = 2;
1251 
1252  STRING_VECTOR arglist;
1253  while (i1 < brute_tokens.size())
1254  {
1255  // 1) concatenate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef'
1256  // note: java.lang.String: substring(a,b) = from a to b-1
1257  // C++ string: substr(a,b) = from a to a + b
1258  std::string result;
1259  if (i2 < brute_tokens.size() && brute_tokens[i2] == "=")
1260  {
1261  if (i3 >= brute_tokens.size())
1262  result = brute_tokens[i1] + brute_tokens[i2];
1263  else
1264  result = brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3];
1265  i1 = i3+1; i2 = i3+2; i3 = i3+3;
1266  }
1267  else if (i2 < brute_tokens.size() &&
1268  brute_tokens[i2].length() > 0 &&
1269  brute_tokens[i2][0] == '=')
1270  {
1271  // This case should not be hit if '=' at the beginning of a word
1272  // is always separated into its own word
1273  result = brute_tokens[i1] + brute_tokens[i2];
1274  i1 = i3; i2 = i3+1; i3 = i3+2;
1275  }
1276  else if (i2 < brute_tokens.size() && brute_tokens[i1][brute_tokens[i1].size()-1] == '=')
1277  {
1278  result = brute_tokens[i1] + brute_tokens[i2];
1279  i1 = i3; i2 = i3+1; i3 = i3+2;
1280  }
1281  else
1282  {
1283  result = brute_tokens[i1];
1284  i1=i2; i2=i3; i3++;
1285  }
1286 
1287  // Now strip out any comment
1288  size_t comment_start_loc = result.find(_comment_start, 0);
1289  if (comment_start_loc != std::string::npos)
1290  result = result.substr(0, comment_start_loc);
1291 
1292  arglist.push_back(result);
1293  }
1294  return arglist;
1295 }
1296 
1297 
1298 
1299 inline void
1300 GetPot::_skip_whitespace(std::istream& istr)
1301 {
1302  // find next non-whitespace while deleting comments
1303  int tmp = istr.get();
1304  do {
1305  // -- search a non whitespace
1306  while (std::isspace(tmp))
1307  {
1308  tmp = istr.get();
1309  if (!istr)
1310  return;
1311  }
1312 
1313  // -- look if characters match the comment starter string
1314  for (unsigned i=0; i<_comment_start.length() ; i++)
1315  {
1316  if (tmp != _comment_start[i])
1317  {
1318  // -- one step more backwards, since 'tmp' already at non-whitespace
1319  istr.unget();
1320  return;
1321  }
1322 
1323  // RHS: Why is this here? It breaks on empty comments
1324  // tmp = istr.get();
1325  // if (!istr) { istr.unget(); return; }
1326  }
1327  // 'tmp' contains last character of _comment_starter
1328 
1329  // -- comment starter found -> search for comment ender
1330  unsigned match_no=0;
1331  while (true)
1332  {
1333  tmp = istr.get();
1334  if (!istr)
1335  {
1336  istr.unget();
1337  return;
1338  }
1339 
1340  if (tmp == _comment_end[match_no])
1341  {
1342  match_no++;
1343  if (match_no == _comment_end.length())
1344  {
1345  istr.unget();
1346  break; // shuffle more whitespace, end of comment found
1347  }
1348  }
1349  else
1350  match_no = 0;
1351  }
1352 
1353  tmp = istr.get();
1354 
1355  } while (istr);
1356  istr.unget();
1357 }
1358 
1359 
1360 
1361 inline const std::string
1362 GetPot::_get_next_token(std::istream& istr)
1363 {
1364  // get next concatenates string token. consider quotes that embrace
1365  // whitespaces
1366  std::string token;
1367  int tmp = 0;
1368  while (true)
1369  {
1370  int last_letter = tmp;
1371  tmp = istr.get();
1372 
1373  if (tmp == '=')
1374  {
1375  // Always break at '='.
1376  // This separates '=' at the beginning of a word into its own word.
1377  token += getpot_cast_int<char>(tmp);
1378  return token;
1379  }
1380 
1381  else if (tmp == EOF || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\'))
1382  return token;
1383 
1384  else if (tmp == '\'' && last_letter != '\\')
1385  {
1386  // QUOTES: un-backslashed quotes => it's a string
1387  token += _get_string(istr);
1388  continue;
1389  }
1390 
1391  else if (tmp == '{' && last_letter == '$')
1392  {
1393  token += '{' + _get_until_closing_bracket(istr);
1394  continue;
1395  }
1396 
1397  else if (tmp == '[')
1398  {
1400  continue;
1401  }
1402 
1403  else if (tmp == '$' && last_letter == '\\')
1404  {
1405  token += getpot_cast_int<char>(tmp); tmp = 0; // so that last_letter will become = 0, not '$';
1406  continue;
1407  }
1408 
1409  else if (tmp == '\\' && last_letter != '\\')
1410  continue; // don't append un-backslashed backslashes
1411 
1412  token += getpot_cast_int<char>(tmp);
1413  }
1414 }
1415 
1416 
1417 
1418 inline const std::string
1419 GetPot::_get_string(std::istream& istr)
1420 {
1421  // parse input until next matching '
1422  std::string str;
1423  int tmp = 0;
1424  while (true)
1425  {
1426  int last_letter = tmp;
1427  tmp = istr.get();
1428  if (tmp == EOF)
1429  return str;
1430 
1431  // un-backslashed quotes => it's the end of the string
1432  else if (tmp == '\'' && last_letter != '\\')
1433  return str;
1434 
1435  else if (tmp == '\\' && last_letter != '\\')
1436  continue; // don't append
1437 
1438  str += getpot_cast_int<char>(tmp);
1439  }
1440 }
1441 
1442 
1443 
1444 inline const std::string
1446 {
1447  // parse input until next matching }
1448  std::string str = "";
1449  int tmp = 0;
1450  int brackets = 1;
1451  while (true)
1452  {
1453  int last_letter = tmp;
1454  tmp = istr.get();
1455  if (tmp == EOF)
1456  return str;
1457 
1458  else if (tmp == '{' && last_letter == '$')
1459  brackets += 1;
1460 
1461  else if (tmp == '}')
1462  {
1463  brackets -= 1;
1464  // un-backslashed brackets => it's the end of the string
1465  if (brackets == 0)
1466  return str + '}';
1467 
1468  else if (tmp == '\\' && last_letter != '\\')
1469  continue; // do not append an unbackslashed backslash
1470  }
1471  str += getpot_cast_int<char>(tmp);
1472  }
1473 }
1474 
1475 
1476 
1477 inline const std::string
1479 {
1480  // parse input until next matching ]
1481  std::string str = "";
1482  int brackets = 1;
1483  while (true)
1484  {
1485  int tmp = istr.get();
1486  if (tmp == EOF)
1487  return str;
1488 
1489  else if (tmp == '[')
1490  brackets += 1;
1491 
1492  else if (tmp == ']')
1493  {
1494  brackets -= 1;
1495  if (brackets == 0)
1496  return str + ']';
1497  }
1498 
1499  str += getpot_cast_int<char>(tmp);
1500  }
1501 }
1502 
1503 
1504 
1505 inline std::string
1506 GetPot::_process_section_label(const std::string& Section,
1507  STRING_VECTOR& section_stack)
1508 {
1509  std::string sname = Section;
1510  // 1) subsection of actual section ('./' prefix)
1511  if (sname.length() >= 2 && sname.substr(0, 2) == "./")
1512  sname = sname.substr(2);
1513 
1514  // 2) subsection of parent section ('../' prefix)
1515  else if (sname.length() >= 3 && sname.substr(0, 3) == "../")
1516  {
1517  do
1518  {
1519  if (section_stack.end() != section_stack.begin())
1520  section_stack.pop_back();
1521  sname = sname.substr(3);
1522  } while (sname.substr(0, 3) == "../");
1523  }
1524 
1525  // 3) subsection of the root-section
1526  else
1527  // [] => back to root section
1528  section_stack.erase(section_stack.begin(), section_stack.end());
1529 
1530  if (sname != "")
1531  {
1532  // parse section name for 'slashes'
1533  unsigned i=0;
1534  while (i < sname.length())
1535  {
1536  if (sname[i] == '/')
1537  {
1538  section_stack.push_back(sname.substr(0,i));
1539  if (i+1 < sname.length())
1540  sname = sname.substr(i+1);
1541  i = 0;
1542  }
1543  else
1544  i++;
1545  }
1546  section_stack.push_back(sname);
1547  }
1548 
1549  std::string section_label = "";
1550  if (!section_stack.empty())
1551  {
1552  victorate(std::string, section_stack, it)
1553  section_label += *it + "/";
1554  }
1555  return section_label;
1556 }
1557 
1558 
1559 
1560 // Use C++ istream/ostream to handle most type conversions.
1561 template <typename T>
1562 inline T
1563 GetPot::_convert_to_type(const std::string& String, const T& Default) const
1564 {
1565  std::istringstream in_string(String);
1566  T retval;
1567  in_string >> retval;
1568  if (in_string.fail())
1569  retval = Default;
1570  return retval;
1571 }
1572 
1573 
1574 
1575 // copy string - operator>> would have stopped upon seeing whitespace!
1576 template <>
1577 inline std::string
1578 GetPot::_convert_to_type(const std::string& String, const std::string&) const
1579 {
1580  return String;
1581 }
1582 
1583 
1584 
1585 // copy string
1586 inline std::string
1587 GetPot::_convert_to_type(const std::string& String, const char*) const
1588 {
1589  return String;
1590 }
1591 
1592 
1593 
1594 // be more liberal than std C++ in what we interpret as a boolean
1595 template<>
1596 inline bool
1597 GetPot::_convert_to_type<bool>(const std::string& String, const bool & Default) const
1598 {
1599  std::string newstring(String);
1600  //std::transform(newstring.begin(), newstring.end(), newstring.begin(), std::toupper);
1601  for (unsigned int i=0; i<newstring.length(); ++i)
1602  newstring[i] = getpot_cast_int<char>(toupper(newstring[i]));
1603 
1604  // "true"/"True"/"TRUE" should work
1605  if (newstring.find("TRUE")!=std::string::npos)
1606  return true;
1607 
1608  if (newstring.find("FALSE")!=std::string::npos)
1609  return false;
1610 
1611  // And if we don't find that, let's search for an integer and use C unsigned
1612  // int->bool conversion before giving up; i.e. a user could specify "0" for
1613  // false or "1" for true
1614  std::istringstream in_string(String);
1615  unsigned int retval;
1616  in_string >> retval;
1617  if (in_string.fail())
1618  return Default;
1619 
1620  return retval;
1621 }
1622 
1623 
1624 
1625 // Use C++ istream/ostream to handle most type conversions.
1626 template <typename T>
1627 inline T
1628 GetPot::_convert_to_type_no_default(const char* VarName, const std::string& String, const T&) const
1629 {
1630  std::istringstream in_string(String);
1631  T retval;
1632  in_string >> retval;
1633  if (in_string.fail())
1634  {
1635  getpot_cerr <<"ERROR: Input value for variable "<<VarName<<" is of the wrong type."<<std::endl;
1636  getpot_cerr <<" value = "<<String<<" expected type = "<<typeid(T).name()<<std::endl;
1637  getpot_error();
1638  }
1639  return retval;
1640 }
1641 
1642 
1643 
1644 // copy string - operator>> would have stopped upon seeing whitespace!
1645 template <>
1646 inline std::string
1647 GetPot::_convert_to_type_no_default(const char*, const std::string& String, const std::string&) const
1648 {
1649  return String;
1650 }
1651 
1652 
1653 
1654 // copy string
1655 inline std::string
1656 GetPot::_convert_to_type_no_default(const char*, const std::string& String, const char*) const
1657 {
1658  return String;
1659 }
1660 
1661 
1662 
1663 // be more liberal than std C++ in what we interpret as a boolean
1664 template<>
1665 inline bool
1666 GetPot::_convert_to_type_no_default<bool>(const char* VarName, const std::string& String, const bool &) const
1667 {
1668  std::string newstring(String);
1669  //std::transform(newstring.begin(), newstring.end(), newstring.begin(), std::toupper);
1670  for (unsigned int i=0; i<newstring.length(); ++i)
1671  {
1672  newstring[i]=getpot_cast_int<char>(toupper(newstring[i]));
1673  }
1674 
1675  // "true"/"True"/"TRUE" should work
1676  if (newstring.find("TRUE")!=std::string::npos)
1677  return true;
1678 
1679  if (newstring.find("FALSE")!=std::string::npos)
1680  return false;
1681 
1682  // And if we don't find that, let's search for an integer and use C unsigned
1683  // int->bool conversion before giving up; i.e. a user could specify "0" for
1684  // false or "1" for true
1685  std::istringstream in_string(String);
1686  unsigned int retval;
1687  in_string >> retval;
1688  if (in_string.fail())
1689  {
1690  getpot_cerr <<"ERROR: Input value for variable "<<VarName<<" is of the wrong type."<<std::endl;
1691  getpot_cerr <<" value = "<<String<<" expected type = "<<typeid(bool).name()<<std::endl;
1692  getpot_error();
1693  }
1694 
1695  return retval;
1696 }
1697 
1698 
1699 
1700 inline const char*
1701 GetPot::_internal_managed_copy(const std::string& Arg) const
1702 {
1703  const char* arg = Arg.c_str();
1704 
1705  // Get a lock before touching anything mutable
1706  SCOPED_MUTEX;
1707 
1708  // See if there's already an identical string saved
1709  // If so, return it
1710  if (auto it = _internal_string_container.find(arg);
1711  it != _internal_string_container.end())
1712  return it->get();
1713 
1714  // Otherwise, create a new one
1715  const std::size_t bufsize = strlen(arg)+1;
1716  auto newcopy = std::make_unique<char[]>(bufsize);
1717  strncpy(newcopy.get(), arg, bufsize);
1718  auto pr = _internal_string_container.insert(std::move(newcopy));
1719  return pr.first->get();
1720 }
1721 
1722 
1723 
1725 // (*) cursor oriented functions
1726 //.............................................................................
1727 
1728 // Checks if 'String' begins with 'Start' and returns the remaining String.
1729 // Returns None if String does not begin with Start.
1730 inline const std::string
1731 GetPot::_get_remaining_string(const std::string& String, const std::string& Start) const
1732 {
1733  if (Start == "")
1734  return String;
1735 
1736  // note: java.lang.String: substring(a,b) = from a to b-1
1737  // C++ string: substr(a,b) = from a to a + b
1738  if (String.find(Start) == 0)
1739  return String.substr(Start.length());
1740 
1741  else
1742  return "";
1743 }
1744 
1745 
1746 
1747 // -- search for a certain argument and set cursor to position
1748 inline bool
1749 GetPot::search(const std::string &Option)
1750 {
1751  return search(Option.c_str());
1752 }
1753 
1754 
1755 
1756 // -- search for a certain argument and set cursor to position
1757 inline bool
1758 GetPot::search(const char* Option)
1759 {
1760  unsigned OldCursor = cursor;
1761  const std::string SearchTerm = prefix + Option;
1762 
1763  // (*) record requested arguments for later ufo detection
1764  _record_argument_request(SearchTerm);
1765 
1766  if (OldCursor >= argv.size())
1767  OldCursor = getpot_cast_int<unsigned>(argv.size() - 1);
1768  search_failed_f = true;
1769 
1770  // (*) first loop from cursor position until end
1771  for (unsigned c = cursor; c < argv.size(); c++)
1772  {
1773  if (argv[c] == SearchTerm)
1774  {
1775  cursor = c;
1776  search_failed_f = false;
1777  return true;
1778  }
1779  }
1780  if (!search_loop_f)
1781  return false;
1782 
1783  // (*) second loop from 0 to old cursor position
1784  for (unsigned c = 1; c <= OldCursor; c++)
1785  {
1786  if (argv[c] == SearchTerm)
1787  {
1788  cursor = c;
1789  search_failed_f = false;
1790  return true;
1791  }
1792  }
1793 
1794  // in case nothing is found the cursor stays where it was
1795  return false;
1796 }
1797 
1798 
1799 
1800 inline bool
1801 GetPot::search(unsigned No, const char* P, ...)
1802 {
1803  // (*) recording the requested arguments happens in subroutine 'search'
1804  if (No == 0)
1805  return false;
1806 
1807  // search for the first argument
1808  if (search(P) == true)
1809  return true;
1810 
1811  // start interpreting variable argument list
1812  va_list ap;
1813  va_start(ap, P);
1814  unsigned i = 1;
1815  for (; i < No; i++)
1816  {
1817  char* Opt = va_arg(ap, char *);
1818  // (*) search records itself for later ufo detection
1819  if (search(Opt) == true)
1820  break;
1821  }
1822 
1823  if (i < No)
1824  {
1825  i++;
1826  // loop was left before end of array --> hit but
1827  // make sure that the rest of the search terms is marked
1828  // as requested.
1829  for (; i < No; i++)
1830  {
1831  char* Opt = va_arg(ap, char *);
1832  // (*) record requested arguments for later ufo detection
1834  }
1835  va_end(ap);
1836  return true;
1837  }
1838 
1839  va_end(ap);
1840  // loop was left normally --> no hit
1841  return false;
1842 }
1843 
1844 
1845 
1846 inline void
1848 {
1849  search_failed_f = false;
1850  cursor = 0;
1851 }
1852 
1853 
1854 
1855 inline void
1857 {
1858  disable_loop();
1859  reset_cursor();
1860 }
1861 
1862 
1863 
1865 // (*) direct access to command line arguments
1866 //.............................................................................
1867 //
1868 inline const char*
1869 GetPot::operator[](unsigned idx) const
1870 {
1871  return idx<argv.size() ? argv[idx].c_str() : 0;
1872 }
1873 
1874 
1875 
1876 template <typename T>
1877 inline T
1878 GetPot::get(unsigned int Idx, const T& Default) const
1879 {
1880  if (Idx >= argv.size())
1881  return Default;
1882  return _convert_to_type(argv[Idx], Default);
1883 }
1884 
1885 
1886 
1887 inline const char*
1888 GetPot::get(unsigned int Idx, const char* Default) const
1889 {
1890  if (Idx >= argv.size())
1891  return Default;
1892  return argv[Idx].c_str();
1893 }
1894 
1895 
1896 
1897 inline unsigned
1899 {
1900  return getpot_cast_int<unsigned>(argv.size());
1901 }
1902 
1903 
1904 
1905 // -- next() function group
1906 template <typename T>
1907 inline T
1908 GetPot::next(const T& Default)
1909 {
1910  if (search_failed_f)
1911  return Default;
1912  cursor++;
1913  if (cursor >= argv.size())
1914  {
1915  cursor = getpot_cast_int<unsigned>(argv.size());
1916  return Default;
1917  }
1918 
1919  // (*) record requested argument for later ufo detection
1921 
1922  const std::string Remain = _get_remaining_string(argv[cursor], prefix);
1923 
1924  return Remain != "" ? _convert_to_type(Remain, Default) : Default;
1925 }
1926 
1927 
1928 
1929 inline const char*
1930 GetPot::next(const char* Default)
1931 {
1932  return _internal_managed_copy(next(std::string(Default)));
1933 }
1934 
1935 
1936 
1937 // -- follow() function group
1938 // distinct option to be searched for
1939 template <typename T>
1940 inline T
1941 GetPot::follow(const T& Default, const char* Option)
1942 {
1943  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1944  if (search(Option) == false)
1945  return Default;
1946 
1947  return next(Default);
1948 }
1949 
1950 
1951 
1952 inline const char*
1953 GetPot::follow(const char* Default, const char* Option)
1954 {
1955  return _internal_managed_copy(follow(std::string(Default), Option));
1956 }
1957 
1958 
1959 
1960 // -- second follow() function group
1961 // multiple option to be searched for
1962 template <typename T>
1963 inline T
1964 GetPot::follow(const T& Default, unsigned int No, const char* P, ...)
1965 {
1966  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1967  if (No == 0)
1968  return Default;
1969 
1970  if (search(P) == true)
1971  return next(Default);
1972 
1973  va_list ap;
1974  va_start(ap, P);
1975  for (unsigned i=1; i<No; i++)
1976  {
1977  char* Opt = va_arg(ap, char *);
1978  if (search(Opt) == true)
1979  {
1980  va_end(ap);
1981  return next(Default);
1982  }
1983  }
1984  va_end(ap);
1985  return Default;
1986 }
1987 
1988 
1989 
1990 inline const char*
1991 GetPot::follow(const char* Default, unsigned No, const char* P, ...)
1992 {
1993  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1994  if (No == 0)
1995  return Default;
1996 
1997  if (search(P) == true)
1998  return next(Default);
1999 
2000  va_list ap;
2001  va_start(ap, P);
2002  for (unsigned i=1; i<No; i++)
2003  {
2004  char* Opt = va_arg(ap, char *);
2005  if (search(Opt) == true)
2006  {
2007  va_end(ap);
2008  return next(Default);
2009  }
2010  }
2011  va_end(ap);
2012  return Default;
2013 }
2014 
2015 
2016 
2018 // (*) directly connected options
2019 //.............................................................................
2020 //
2021 template <typename T>
2022 inline T
2023 GetPot::direct_follow(const T& Default, const char* Option)
2024 {
2025  const char* FollowStr = _match_starting_string(Option);
2026 
2027  // (*) record requested of argument for later ufo-detection
2028  _record_argument_request(std::string(Option) + FollowStr);
2029 
2030  if (FollowStr == 0)
2031  return Default;
2032 
2033  if (++cursor >= argv.size())
2034  cursor = getpot_cast_int<unsigned>(argv.size());
2035  return _convert_to_type(FollowStr, Default);
2036 }
2037 
2038 
2039 
2040 inline const char*
2041 GetPot::direct_follow(const char* Default, const char* Option)
2042 {
2043  return _internal_managed_copy(direct_follow(std::string(Default), Option));
2044 }
2045 
2046 
2047 
2048 // pointer to the place where the string after
2049 // the match inside the found argument starts.
2050 // 0 no argument matches the starting string.
2051 inline const char*
2052 GetPot::_match_starting_string(const char* StartString)
2053 {
2054  const unsigned N =
2055  getpot_cast_int<unsigned>(strlen(StartString));
2056  unsigned OldCursor = cursor;
2057 
2058  if (OldCursor >= argv.size())
2059  OldCursor = getpot_cast_int<unsigned>(argv.size() - 1);
2060  search_failed_f = true;
2061 
2062  // (*) first loop from cursor position until end
2063  for (unsigned c = cursor; c < argv.size(); c++)
2064  {
2065  if (strncmp(StartString, argv[c].c_str(), N) == 0)
2066  {
2067  cursor = c;
2068  search_failed_f = false;
2069  return &(argv[c].c_str()[N]);
2070  }
2071  }
2072 
2073  if (!search_loop_f)
2074  return NULL;
2075 
2076  // (*) second loop from 0 to old cursor position
2077  for (unsigned c = 1; c < OldCursor; c++)
2078  {
2079  if (strncmp(StartString, argv[c].c_str(), N) == 0)
2080  {
2081  cursor = c;
2082  search_failed_f = false;
2083  return &(argv[c].c_str()[N]);
2084  }
2085  }
2086  return 0;
2087 }
2088 
2089 
2090 
2092 // (*) search for flags
2093 //.............................................................................
2094 //
2095 inline bool
2096 GetPot::options_contain(const char* FlagList) const
2097 {
2098  // go through all arguments that start with a '-' (but not '--')
2099  std::string str;
2100  STRING_VECTOR::const_iterator it = argv.begin();
2101  for (; it != argv.end(); ++it)
2102  {
2103  str = _get_remaining_string(*it, prefix);
2104 
2105  if (str.length() >= 2 && str[0] == '-' && str[1] != '-')
2106  if (_check_flags(str, FlagList))
2107  return true;
2108  }
2109  return false;
2110 }
2111 
2112 
2113 
2114 inline bool
2115 GetPot::argument_contains(unsigned Idx, const char* FlagList) const
2116 {
2117  if (Idx >= argv.size())
2118  return false;
2119 
2120  // (*) record requested of argument for later ufo-detection
2121  // an argument that is checked for flags is considered to be 'requested'
2123 
2124  if (prefix == "")
2125  // search argument for any flag in flag list
2126  return _check_flags(argv[Idx], FlagList);
2127 
2128  // if a prefix is set, then the argument index is the index
2129  // inside the 'namespace'
2130  // => only check list of arguments that start with prefix
2131  unsigned no_matches = 0;
2132  for (unsigned i=0; i<argv.size(); i++)
2133  {
2134  const std::string Remain = _get_remaining_string(argv[i], prefix);
2135  if (Remain != "")
2136  {
2137  no_matches += 1;
2138  if (no_matches == Idx)
2139  return _check_flags(Remain, FlagList);
2140  }
2141  }
2142 
2143  // no argument in this namespace
2144  return false;
2145 }
2146 
2147 
2148 
2149 inline bool
2150 GetPot::_check_flags(const std::string& Str, const char* FlagList) const
2151 {
2152  for (const char* p=FlagList; *p != '\0' ; p++)
2153  if (Str.find(*p) != std::string::npos)
2154  return true; // found something
2155  return false;
2156 }
2157 
2158 
2159 
2161 // (*) nominus arguments
2162 
2163 // return vector of nominus arguments
2164 inline STRING_VECTOR
2166 {
2167  STRING_VECTOR nv;
2168  std::vector<unsigned>::const_iterator it = idx_nominus.begin();
2169  for (; it != idx_nominus.end(); ++it)
2170  {
2171  nv.push_back(argv[*it]);
2172 
2173  // (*) record for later ufo-detection
2174  // when a nominus vector is requested, the entire set of nominus arguments are
2175  // tagged as 'requested'
2177  }
2178  return nv;
2179 }
2180 
2181 
2182 
2183 inline const char*
2185 {
2186  if (nominus_cursor < int(idx_nominus.size()) - 1)
2187  {
2188  const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
2189 
2190  // (*) record for later ufo-detection
2192 
2193  return _internal_managed_copy(Tmp);
2194  }
2195 
2196  return 0;
2197 }
2198 
2199 
2200 inline std::string
2202 {
2203  if (nominus_cursor < int(idx_nominus.size()) - 1)
2204  {
2205  const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
2206 
2207  // (*) record for later ufo-detection
2209 
2210  return Tmp;
2211  }
2212 
2213  return "";
2214 }
2215 
2216 
2217 
2218 inline void
2220 {
2221  nominus_cursor = -1;
2222 }
2223 
2224 
2225 
2227 // (*) variables
2228 //.............................................................................
2229 //
2230 inline bool
2231 GetPot::have_variable(const char* VarName) const
2232 {
2233  const variable* sv = _request_variable(VarName);
2234 
2235  if (sv == 0)
2236  return false;
2237 
2238  return true;
2239 }
2240 
2241 
2242 
2243 inline bool
2244 GetPot::have_variable(const std::string& VarName) const
2245 {
2246  return have_variable(VarName.c_str());
2247 }
2248 
2249 inline bool
2250 GetPot::have_section(const char* section_name) const
2251 {
2252  std::string s = std::string(section_name);
2253  return this->have_section(s);
2254 }
2255 
2256 inline bool
2257 GetPot::have_section(const std::string& section_name) const
2258 {
2259  const char slash('/');
2260 
2261  std::string::const_reverse_iterator it = section_name.rbegin();
2262 
2263  bool found_section = false;
2264 
2265  // Check if section_name ends with a "/". If not, append it for the search since
2266  // the section names are stored with a "/" at the end.
2267  if( (*it) != slash )
2268  // We need to use a linear search because we can't sort section_list
2269  // without violating some assumptions. See libMesh #481 for more discussion.
2270  found_section = ( std::find(section_list.begin(), section_list.end(), section_name+slash) != section_list.end() );
2271  else
2272  found_section = ( std::find(section_list.begin(), section_list.end(), section_name) != section_list.end() );
2273 
2274  return found_section;
2275 }
2276 
2277 template <typename T>
2278 inline T
2279 GetPot::operator()(const char* VarName, const T& Default) const
2280 {
2281  // (*) recording of requested variables happens in '_request_variable()'
2282  const variable* sv = _request_variable(VarName);
2283 
2284  if (sv == 0)
2285  return Default;
2286 
2287  return _convert_to_type(sv->original, Default);
2288 }
2289 
2290 
2291 
2292 template <typename T>
2293 inline T
2294 GetPot::operator()(const std::string& VarName, const T& Default) const
2295 {
2296  return operator()(VarName.c_str(), Default);
2297 }
2298 
2299 
2300 
2301 inline const char*
2302 GetPot::operator()(const char* VarName, const char* Default) const
2303 {
2304  return _internal_managed_copy(operator()(VarName, std::string(Default)));
2305 }
2306 
2307 
2308 
2309 inline const char*
2310 GetPot::operator()(const std::string& VarName, const char* Default) const
2311 {
2312  return operator()(VarName.c_str(), Default);
2313 }
2314 
2315 
2316 
2317 template <typename T>
2318 inline T
2319 GetPot::operator()(const char* VarName, const T& Default, unsigned int Idx) const
2320 {
2321  // (*) recording of requested variables happens in '_request_variable()'
2322  const variable* sv = _request_variable(VarName);
2323  if (sv == 0)
2324  return Default;
2325 
2326  const std::string* element = sv->get_element(Idx);
2327  if (element == 0)
2328  return Default;
2329  return _convert_to_type(*element, Default);
2330 }
2331 
2332 
2333 
2334 template <typename T>
2335 inline T
2336 GetPot::operator()(const std::string& VarName, const T& Default, unsigned int Idx) const
2337 {
2338  return operator()(VarName.c_str(), Default, Idx);
2339 }
2340 
2341 
2342 
2343 inline const char*
2344 GetPot::operator()(const char* VarName, const char* Default, unsigned int Idx) const
2345 {
2346  return _internal_managed_copy(operator()(VarName, std::string(Default), Idx));
2347 }
2348 
2349 
2350 
2351 inline const char*
2352 GetPot::operator()(const std::string& VarName, const char* Default, unsigned int Idx) const
2353 {
2354  return operator()(VarName.c_str(), Default, Idx);
2355 }
2356 
2357 
2358 
2359 template <typename T>
2360 inline T
2361 GetPot::get_value_no_default(const char* VarName, const T& Default) const
2362 {
2363  // (*) recording of requested variables happens in '_request_variable()'
2364  const variable* sv = _request_variable(VarName);
2365  if (sv == 0)
2366  {
2367  getpot_cerr << "ERROR: cannot find variable "<<VarName<<std::endl;
2368  getpot_error();
2369  }
2370  return _convert_to_type_no_default(VarName, sv->original, Default);
2371 }
2372 
2373 
2374 
2375 template <typename T>
2376 inline T
2377 GetPot::get_value_no_default(const std::string& VarName, const T& Default) const
2378 {
2379  return get_value_no_default(VarName.c_str(),Default);
2380 }
2381 
2382 
2383 
2384 inline const char*
2385 GetPot::get_value_no_default(const char* VarName, const char* Default) const
2386 {
2387  return _internal_managed_copy(get_value_no_default(VarName, std::string(Default)));
2388 }
2389 
2390 
2391 
2392 inline const char*
2393 GetPot::get_value_no_default(const std::string& VarName, const char* Default) const
2394 {
2395  return get_value_no_default(VarName.c_str(),Default);
2396 }
2397 
2398 
2399 
2400 template <typename T>
2401 inline T
2402 GetPot::get_value_no_default(const char* VarName, const T& Default, unsigned int Idx) const
2403 {
2404  // (*) recording of requested variables happens in '_request_variable()'
2405  const variable* sv = _request_variable(VarName);
2406  if (sv == 0)
2407  {
2408  getpot_cerr << "ERROR: cannot find variable "<<VarName<<std::endl;
2409  getpot_error();
2410  }
2411 
2412  const std::string* element = sv->get_element(Idx);
2413  if (element == 0)
2414  {
2415  getpot_cerr << "ERROR: cannot find index "<<Idx<<" of variable "<<VarName<<std::endl;
2416  getpot_error();
2417  }
2418  return _convert_to_type_no_default(VarName, *element, Default);
2419 }
2420 
2421 
2422 
2423 template <typename T>
2424 inline T
2425 GetPot::get_value_no_default(const std::string& VarName, const T& Default, unsigned int Idx) const
2426 {
2427  return get_value_no_default(VarName.c_str(), Default, Idx);
2428 }
2429 
2430 
2431 
2432 inline const char*
2433 GetPot::get_value_no_default(const char* VarName, const char* Default, unsigned int Idx) const
2434 {
2435  return _internal_managed_copy(get_value_no_default(VarName, std::string(Default), Idx));
2436 }
2437 
2438 
2439 
2440 inline const char*
2441 GetPot::get_value_no_default(const std::string& VarName, const char* Default, unsigned int Idx) const
2442 {
2443  return get_value_no_default(VarName.c_str(), Default, Idx);
2444 }
2445 
2446 
2447 
2448 inline void
2449 GetPot::_record_argument_request(const std::string& Name) const
2450 {
2451  if (!request_recording_f)
2452  return;
2453 
2454  // Get a lock before touching anything mutable
2455  SCOPED_MUTEX;
2456 
2457  // (*) record requested variable for later ufo detection
2458  _requested_arguments.insert(Name);
2459 
2460  // (*) record considered section for ufo detection
2461  STRING_VECTOR STree = _get_section_tree(Name);
2462  victorate(std::string, STree, it)
2463  if (_requested_sections.find(*it) == _requested_sections.end())
2464  if (section.length() != 0)
2465  _requested_sections.insert(*it);
2466 }
2467 
2468 
2469 
2470 inline void
2471 GetPot::_record_variable_request(const std::string& Name) const
2472 {
2473  if (!request_recording_f)
2474  return;
2475 
2476  // Get a lock before touching anything mutable
2477  SCOPED_MUTEX;
2478 
2479  // (*) record requested variable for later ufo detection
2480  _requested_variables.insert(Name);
2481 
2482  // (*) record considered section for ufo detection
2483  STRING_VECTOR STree = _get_section_tree(Name);
2484  victorate(std::string, STree, it)
2485  if (_requested_sections.find(*it) == _requested_sections.end())
2486  if (section.length() != 0)
2487  _requested_sections.insert(*it);
2488 }
2489 
2490 
2491 
2492 // (*) following functions are to be used from 'outside', after getpot has parsed its
2493 // arguments => append an argument in the argument vector that reflects the addition
2494 inline void
2495 GetPot::_set_variable(const std::string& VarName,
2496  const std::string& Value, const bool Requested /* = true */)
2497 {
2498  const GetPot::variable* Var = Requested ?
2499  _request_variable(VarName.c_str()) :
2500  _find_variable(VarName.c_str());
2501  if (Var == 0)
2502  variables.push_back(variable(VarName.c_str(), Value.c_str(), _field_separator.c_str()));
2503  else
2504  {
2505  overridden_vars.insert(VarName.c_str());
2506  (const_cast<GetPot::variable*>(Var))->take(Value.c_str(), _field_separator.c_str());
2507  }
2508 }
2509 
2510 
2511 
2512 template <typename T>
2513 inline void
2514 GetPot::set(const char* VarName, const T& Value, const bool Requested /* = true */)
2515 {
2516  std::ostringstream string_value;
2517  string_value << Value;
2518  _set_variable(VarName, string_value.str().c_str(), Requested);
2519 }
2520 
2521 
2522 
2523 template <typename T>
2524 inline void
2525 GetPot::set(const std::string& VarName, const T& Value, const bool Requested /* = true */)
2526 {
2527  set(VarName.c_str(), Value, Requested);
2528 }
2529 
2530 
2531 
2532 inline void
2533 GetPot::set(const char* VarName, const char* Value, const bool Requested /* = true */)
2534 {
2535  _set_variable(VarName, Value, Requested);
2536 }
2537 
2538 
2539 
2540 inline void
2541 GetPot::set(const std::string& VarName, const char* Value, const bool Requested /* = true */)
2542 {
2543  set(VarName.c_str(), Value, Requested);
2544 }
2545 
2546 
2547 
2548 inline unsigned
2549 GetPot::vector_variable_size(const char* VarName) const
2550 {
2551  const variable* sv = _request_variable(VarName);
2552  if (sv == 0)
2553  return 0;
2554  return (unsigned)(sv->value.size());
2555 }
2556 
2557 
2558 
2559 inline unsigned
2560 GetPot::vector_variable_size(const std::string& VarName) const
2561 {
2562  return vector_variable_size(VarName.c_str());
2563 }
2564 
2565 
2566 
2567 inline STRING_VECTOR
2569 {
2570  STRING_VECTOR result;
2571  std::vector<GetPot::variable>::const_iterator it = variables.begin();
2572  for (; it != variables.end(); ++it)
2573  {
2574  const std::string Tmp = _get_remaining_string((*it).name, prefix);
2575  if (Tmp != "")
2576  result.push_back(Tmp);
2577  }
2578  return result;
2579 }
2580 
2581 
2582 
2583 inline STRING_VECTOR
2585 {
2586  return section_list;
2587 }
2588 
2589 
2590 
2591 inline STRING_VECTOR
2592 GetPot::get_subsection_names(const std::string & sec_prefix) const
2593 {
2594  // GetPot functions should understand user-provided section names
2595  // either with or without a trailing slash.
2596  const std::string full_prefix =
2597  *sec_prefix.rbegin() == '/' ? sec_prefix : sec_prefix + '/';
2598 
2599  const std::size_t full_prefix_len = full_prefix.size();
2600 
2601  // Subsections-of-subsections are in the section_list, so we'll be
2602  // adding subsections multiple times. Using std::set as an
2603  // intermediate data structure helps us check for duplicates with
2604  // O(N log N) rather than O(N^2) cost.
2605  std::set<std::string> subsections;
2606 
2607  STRING_VECTOR returnval;
2608 
2609  for (STRING_VECTOR::const_iterator it = section_list.begin();
2610  it != section_list.end(); ++it)
2611  {
2612  const std::string & section_name = *it;
2613 
2614  // If this section name begins with the prefix
2615  if (section_name.compare(0, full_prefix_len, full_prefix) == 0)
2616  {
2617  const std::size_t next_slash_len =
2618  section_name.find('/', full_prefix_len);
2619 
2620  const std::string subsection_name =
2621  section_name.substr(full_prefix_len,
2622  next_slash_len - full_prefix_len);
2623 
2624  // If there is a subsection, and if this is the first time
2625  // we've seen it, add the prefix-less, postfix-less
2626  // subsection name.
2627  if (!subsection_name.empty() &&
2628  !subsections.count(subsection_name))
2629  {
2630  returnval.push_back(subsection_name);
2631  subsections.insert(subsection_name);
2632  }
2633  }
2634  }
2635 
2636  return returnval;
2637 }
2638 
2639 
2640 
2641 inline std::set<std::string>
2643 {
2644  return overridden_vars;
2645 }
2646 
2647 
2648 
2649 inline const GetPot::variable*
2650 GetPot::_find_variable(const char* VarName) const
2651 {
2652  const std::string Name = prefix + VarName;
2653 
2654  std::vector<variable>::const_iterator it = variables.begin();
2655  for (; it != variables.end(); ++it)
2656  {
2657  if ((*it).name == Name)
2658  return &(*it);
2659  }
2660  return 0;
2661 }
2662 
2663 
2664 
2665 inline const GetPot::variable*
2666 GetPot::_request_variable(const char* VarName) const
2667 {
2668  // (*) record requested variable for later ufo detection
2669  this->_record_variable_request(VarName);
2670 
2671  return this->_find_variable(VarName);
2672 }
2673 
2674 
2675 
2677 // (*) output (basically for debugging reasons
2678 //.............................................................................
2679 //
2680 inline int
2681 GetPot::print(std::ostream &out_stream) const
2682 {
2683  out_stream << "argc = " << argv.size() << std::endl;
2684  STRING_VECTOR::const_iterator it = argv.begin();
2685  for (; it != argv.end(); ++it)
2686  out_stream << *it << std::endl;
2687  out_stream << std::endl;
2688  return 1;
2689 }
2690 
2691 
2692 
2693 // PECOS/HPCT Addition - add option to prepend output with a delimiter
2694 // while also disabling argc print and skipping first print (the name
2695 // of the input file)
2696 //
2697 // PECOS Development Team: (ks. 4/16/09)
2698 inline int
2699 GetPot::print(const char* custom_prefix, std::ostream &out_stream, unsigned int skip_count) const
2700 {
2701  STRING_VECTOR::const_iterator it = argv.begin();
2702  it += skip_count;
2703  for (; it != argv.end(); ++it)
2704  {
2705  out_stream << custom_prefix;
2706  out_stream << *it << std::endl;
2707  }
2708  out_stream << std::endl;
2709  return 1;
2710 }
2711 
2712 
2713 
2714 // (*) dollar bracket expressions (DBEs) ------------------------------------
2715 //
2716 // 1) Entry Function: _DBE_expand_string()
2717 // Takes a string such as
2718 //
2719 // "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}"
2720 //
2721 // calls _DBE_expand() for each of the expressions
2722 //
2723 // ${+ ${x} ${y}}
2724 // ${& ${section} ${subsection}}
2725 // ${Title}
2726 //
2727 // and returns the string
2728 //
2729 // "4711 Subject-1.01: Mit den Clowns kamen die Schwaene"
2730 //
2731 // assuming that
2732 // x = "4699"
2733 // y = "12"
2734 // section = "1."
2735 // subsection = "01"
2736 // title = "Mit den Clowns kamen die Schwaene"
2737 //
2738 // 2) _DBE_expand():
2739 //
2740 // checks for the command, i.e. the 'sign' that follows '${'
2741 // divides the argument list into sub-expressions using
2742 // _DBE_get_expr_list()
2743 //
2744 // ${+ ${x} ${y}} -> "${x}" "${y}"
2745 // ${& ${section} ${subsection}} -> "${section}" "${subsection}"
2746 // ${Title} -> Nothing, variable expansion
2747 //
2748 // 3) _DBE_expression_list():
2749 //
2750 // builds a vector of unbracketed whitespace separated strings, i.e.
2751 //
2752 // " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}"
2753 //
2754 // is split into a vector
2755 //
2756 // [0] ${Number}.a
2757 // [1] ${: Das Marmorbild}
2758 // [2] AB-${& Author= ${Eichendorf}}-1870
2759 //
2760 // Each sub-expression is expanded using expand().
2761 //---------------------------------------------------------------------------
2762 inline std::string
2763 GetPot::_DBE_expand_string(const std::string& str)
2764 {
2765  // Parses for closing operators '${ }' and expands them letting
2766  // white spaces and other letters as they are.
2767  std::string new_string = "";
2768  unsigned open_brackets = 0;
2769  unsigned first = 0;
2770  for (unsigned i = 0; i<str.size(); i++)
2771  {
2772  if (i + 2 < str.size() && str.substr(i, 2) == "${")
2773  {
2774  if (open_brackets == 0)
2775  first = i+2;
2776  open_brackets++;
2777  }
2778  else if (str[i] == '}' && open_brackets > 0)
2779  {
2780  open_brackets -= 1;
2781  if (open_brackets == 0)
2782  {
2783  const std::string Replacement = _DBE_expand(str.substr(first, i - first));
2784  new_string += Replacement;
2785  }
2786  }
2787  else if (open_brackets == 0)
2788  new_string += str[i];
2789  }
2790  return new_string;
2791 }
2792 
2793 
2794 
2795 inline STRING_VECTOR
2796 GetPot::_DBE_get_expr_list(const std::string& str_, const unsigned ExpectedNumber)
2797 {
2798  // ensures that the resulting vector has the expected number
2799  // of arguments, but they may contain an error message
2800  std::string str = str_;
2801  // Separates expressions by non-bracketed whitespaces, expands them
2802  // and puts them into a list.
2803 
2804  unsigned i=0;
2805  // (1) eat initial whitespaces
2806  for (; i < str.size(); i++)
2807  if (!std::isspace(str[i]))
2808  break;
2809 
2810  STRING_VECTOR expr_list;
2811  unsigned open_brackets = 0;
2812  std::vector<unsigned> start_idx;
2813  unsigned start_new_string = i;
2814  unsigned l = (unsigned)(str.size());
2815 
2816  // (2) search for ${ } expressions ...
2817  while (i < l)
2818  {
2819  const char letter = str[i];
2820  // whitespace -> end of expression
2821  if (std::isspace(letter) && open_brackets == 0)
2822  {
2823  expr_list.push_back(str.substr(start_new_string, i - start_new_string));
2824  bool no_breakout_f = true;
2825  for (i++; i < l ; i++)
2826  {
2827  if (!std::isspace(str[i]))
2828  {
2829  no_breakout_f = false;
2830  start_new_string = i;
2831  break;
2832  }
2833  }
2834 
2835  if (no_breakout_f)
2836  {
2837  // end of expression list
2838  if (expr_list.size() < ExpectedNumber)
2839  {
2840  const std::string pre_tmp("<< ${ }: missing arguments>>");
2841  STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
2842  expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
2843  }
2844  return expr_list;
2845  }
2846  }
2847 
2848  // dollar-bracket expression
2849  if (str.length() >= i+2 && str.substr(i, 2) == "${")
2850  {
2851  open_brackets++;
2852  start_idx.push_back(i+2);
2853  }
2854 
2855  else if (letter == '}' && open_brackets > 0)
2856  {
2857  int start = start_idx[start_idx.size()-1];
2858  start_idx.pop_back();
2859  const std::string Replacement = _DBE_expand(str.substr(start, i-start));
2860  if (start - 3 < (int)0)
2861  str = Replacement + str.substr(i+1);
2862  else
2863  str = str.substr(0, start-2) + Replacement + str.substr(i+1);
2864  l = (int)(str.size());
2865  i = start + (int)(Replacement.size()) - 3;
2866  open_brackets--;
2867  }
2868  i++;
2869  }
2870 
2871  // end of expression list
2872  expr_list.push_back(str.substr(start_new_string, i-start_new_string));
2873 
2874  if (expr_list.size() < ExpectedNumber)
2875  {
2876  const std::string pre_tmp("<< ${ }: missing arguments>>");
2877  STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
2878  expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
2879  }
2880 
2881  return expr_list;
2882 }
2883 
2884 
2885 
2886 inline const GetPot::variable*
2887 GetPot::_DBE_get_variable(const std::string& VarName)
2888 {
2889  static GetPot::variable ev;
2890  std::string secure_Prefix = prefix;
2891 
2892  prefix = section;
2893  // (1) first search in currently active section
2894  const GetPot::variable* var = _request_variable(VarName.c_str());
2895  if (var != 0)
2896  {
2897  prefix = secure_Prefix;
2898  return var;
2899  }
2900 
2901  // (2) search in root name space
2902  prefix = "";
2903  var = _request_variable(VarName.c_str());
2904  if (var != 0)
2905  {
2906  prefix = secure_Prefix;
2907  return var;
2908  }
2909 
2910  prefix = secure_Prefix;
2911 
2912  // error occurred => variable name == ""
2913  ev.original = "<<${ } variable '";
2914  ev.original += VarName + "' undefined>>";
2915  return &ev;
2916 }
2917 
2918 
2919 
2920 inline std::string
2921 GetPot::_DBE_expand(const std::string& expr)
2922 {
2923  // ${: } pure text
2924  if (expr[0] == ':')
2925  return expr.substr(1);
2926 
2927  // ${& expr expr ... } text concatenation
2928  else if (expr[0] == '&')
2929  {
2930  const STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 1);
2931 
2932  STRING_VECTOR::const_iterator it = A.begin();
2933  std::string result = *it++;
2934  for (; it != A.end(); ++it) result += *it;
2935 
2936  return result;
2937  }
2938 
2939  // ${<-> expr expr expr} text replacement
2940  else if (expr.length() >= 3 && expr.substr(0, 3) == "<->")
2941  {
2942  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(3), 3);
2943  size_t tmp = 0;
2944  const size_t L = A[1].length();
2945 
2946  while ((tmp = A[0].find(A[1])) != std::string::npos)
2947  A[0].replace(tmp, L, A[2]);
2948 
2949  return A[0];
2950  }
2951 
2952  // ${=func [expr...] } function evaluation
2953  else if (expr.length() >= 2 &&
2954  expr.substr(0, 1) == "=" &&
2955  expr.substr(0, 2) != "==")
2956  {
2957  size_t funcnamestart = expr.find_first_not_of(" \t", 1);
2958  if (funcnamestart != std::string::npos)
2959  {
2960  size_t funcnameend = expr.find_first_of(" \t",funcnamestart);
2961  std::string funcname = expr.substr(funcnamestart,
2962  funcnameend-funcnamestart);
2963  if (funcname == "log")
2964  {
2965  STRING_VECTOR A =
2966  _DBE_get_expr_list(expr.substr(funcnameend), 1);
2967  double arg = _convert_to_type(A[0], 0.0);
2968  return _convert_from_type(std::log(arg));
2969  }
2970  else if (funcname == "log10")
2971  {
2972  STRING_VECTOR A =
2973  _DBE_get_expr_list(expr.substr(funcnameend), 1);
2974  double arg = _convert_to_type(A[0], 0.0);
2975  return _convert_from_type(std::log10(arg));
2976  }
2977  else if (funcname == "exp")
2978  {
2979  STRING_VECTOR A =
2980  _DBE_get_expr_list(expr.substr(funcnameend), 1);
2981  double arg = _convert_to_type(A[0], 0.0);
2982  return _convert_from_type(std::exp(arg));
2983  }
2984  else if (funcname == "sin")
2985  {
2986  STRING_VECTOR A =
2987  _DBE_get_expr_list(expr.substr(funcnameend), 1);
2988  double arg = _convert_to_type(A[0], 0.0);
2989  return _convert_from_type(std::sin(arg));
2990  }
2991  else if (funcname == "cos")
2992  {
2993  STRING_VECTOR A =
2994  _DBE_get_expr_list(expr.substr(funcnameend), 1);
2995  double arg = _convert_to_type(A[0], 0.0);
2996  return _convert_from_type(std::cos(arg));
2997  }
2998  else if (funcname == "tan")
2999  {
3000  STRING_VECTOR A =
3001  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3002  double arg = _convert_to_type(A[0], 0.0);
3003  return _convert_from_type(std::tan(arg));
3004  }
3005  else if (funcname == "asin")
3006  {
3007  STRING_VECTOR A =
3008  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3009  double arg = _convert_to_type(A[0], 0.0);
3010  return _convert_from_type(std::asin(arg));
3011  }
3012  else if (funcname == "acos")
3013  {
3014  STRING_VECTOR A =
3015  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3016  double arg = _convert_to_type(A[0], 0.0);
3017  return _convert_from_type(std::acos(arg));
3018  }
3019  else if (funcname == "atan")
3020  {
3021  STRING_VECTOR A =
3022  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3023  double arg = _convert_to_type(A[0], 0.0);
3024  return _convert_from_type(std::atan(arg));
3025  }
3026  else if (funcname == "atan2")
3027  {
3028  STRING_VECTOR A =
3029  _DBE_get_expr_list(expr.substr(funcnameend), 2);
3030  double arg1 = _convert_to_type(A[0], 0.0);
3031  double arg2 = _convert_to_type(A[1], 0.0);
3032  return _convert_from_type(std::atan2(arg1, arg2));
3033  }
3034  else if (funcname == "sinh")
3035  {
3036  STRING_VECTOR A =
3037  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3038  double arg = _convert_to_type(A[0], 0.0);
3039  return _convert_from_type(std::sinh(arg));
3040  }
3041  else if (funcname == "cosh")
3042  {
3043  STRING_VECTOR A =
3044  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3045  double arg = _convert_to_type(A[0], 0.0);
3046  return _convert_from_type(std::cosh(arg));
3047  }
3048  else if (funcname == "tanh")
3049  {
3050  STRING_VECTOR A =
3051  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3052  double arg = _convert_to_type(A[0], 0.0);
3053  return _convert_from_type(std::tanh(arg));
3054  }
3055 #ifdef HAVE_INVERSE_HYPERBOLIC_SINE
3056  else if (funcname == "asinh")
3057  {
3058  STRING_VECTOR A =
3059  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3060  double arg = _convert_to_type(A[0], 0.0);
3061  return _convert_from_type(std::asinh(arg));
3062  }
3063 #endif
3064 #ifdef HAVE_INVERSE_HYPERBOLIC_COSINE
3065  else if (funcname == "acosh")
3066  {
3067  STRING_VECTOR A =
3068  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3069  double arg = _convert_to_type(A[0], 0.0);
3070  return _convert_from_type(std::acosh(arg));
3071  }
3072 #endif
3073 #ifdef HAVE_INVERSE_HYPERBOLIC_TANGENT
3074  else if (funcname == "atanh")
3075  {
3076  STRING_VECTOR A =
3077  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3078  double arg = _convert_to_type(A[0], 0.0);
3079  return _convert_from_type(std::atanh(arg));
3080  }
3081 #endif
3082  else if (funcname == "sqrt")
3083  {
3084  STRING_VECTOR A =
3085  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3086  double arg = _convert_to_type(A[0], 0.0);
3087  return _convert_from_type(std::sqrt(arg));
3088  }
3089  else if (funcname == "abs")
3090  {
3091  STRING_VECTOR A =
3092  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3093  double arg = _convert_to_type(A[0], 0.0);
3094  return _convert_from_type(std::abs(arg));
3095  }
3096  else if (funcname == "max")
3097  {
3098  STRING_VECTOR A =
3099  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3100  STRING_VECTOR::const_iterator it = A.begin();
3101  double result = _convert_to_type(*it++, 0.0);
3102  for (; it != A.end(); ++it)
3103  result = std::max(result, _convert_to_type(*it, 0.0));
3104  return _convert_from_type(result);
3105  }
3106  else if (funcname == "min")
3107  {
3108  STRING_VECTOR A =
3109  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3110  STRING_VECTOR::const_iterator it = A.begin();
3111  double result = _convert_to_type(*it++, 0.0);
3112  for (; it != A.end(); ++it)
3113  result = std::min(result, _convert_to_type(*it, 0.0));
3114  return _convert_from_type(result);
3115  }
3116  else if (funcname == "ceil")
3117  {
3118  STRING_VECTOR A =
3119  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3120  double arg = _convert_to_type(A[0], 0.0);
3121  return _convert_from_type(std::ceil(arg));
3122  }
3123  else if (funcname == "floor")
3124  {
3125  STRING_VECTOR A =
3126  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3127  double arg = _convert_to_type(A[0], 0.0);
3128  return _convert_from_type(std::floor(arg));
3129  }
3130  else if (funcname == "fmod")
3131  {
3132  STRING_VECTOR A =
3133  _DBE_get_expr_list(expr.substr(funcnameend), 2);
3134  double arg1 = _convert_to_type(A[0], 0.0);
3135  double arg2 = _convert_to_type(A[1], 0.0);
3136  return _convert_from_type(std::fmod(arg1, arg2));
3137  }
3138  else if (funcname == "srand")
3139  {
3140  STRING_VECTOR A =
3141  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3142  unsigned int arg = _convert_to_type(A[0], 0u);
3143  std::srand(arg);
3144  return A[0];
3145  }
3146  // ${=rand range} with default range==RAND_MAX
3147  else if (funcname == "rand")
3148  {
3149  if (funcnameend >= expr.length() ||
3150  expr.find_first_not_of(" \t", funcnameend) == std::string::npos)
3151  return _convert_from_type(std::rand());
3152 
3153  STRING_VECTOR A =
3154  _DBE_get_expr_list(expr.substr(funcnameend), 1);
3155  unsigned int range = _convert_to_type(A[0],0u);
3156  if (!range)
3157  return _convert_from_type(0);
3158  const unsigned int x = (RAND_MAX + 1u) / range;
3159  const unsigned int y = x * range;
3160  unsigned int returnval;
3161  do
3162  {
3163  returnval = rand();
3164  } while (returnval >= y);
3165  return _convert_from_type(returnval / x);
3166  }
3167  else if (funcname == "time")
3168  return _convert_from_type(std::time(NULL));
3169  else
3170  {
3171  getpot_cerr << "ERROR: unrecognized function "
3172  << funcname << std::endl;
3173  getpot_error();
3174  }
3175  }
3176  }
3177 
3178  // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions
3179  else if (expr[0] == '+')
3180  {
3181  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 2);
3182  STRING_VECTOR::const_iterator it = A.begin();
3183  double result = _convert_to_type(*it++, 0.0);
3184  for (; it != A.end(); ++it)
3185  result += _convert_to_type(*it, 0.0);
3186 
3187  return _convert_from_type(result);
3188  }
3189  else if (expr[0] == '-')
3190  {
3191  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 2);
3192  STRING_VECTOR::const_iterator it = A.begin();
3193  double result = _convert_to_type(*it++, 0.0);
3194  for (; it != A.end(); ++it)
3195  result -= _convert_to_type(*it, 0.0);
3196 
3197  return _convert_from_type(result);
3198  }
3199  else if (expr[0] == '*')
3200  {
3201  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 2);
3202  STRING_VECTOR::const_iterator it = A.begin();
3203  double result = _convert_to_type(*it++, 0.0);
3204  for (; it != A.end(); ++it)
3205  result *= _convert_to_type(*it, 0.0);
3206 
3207  return _convert_from_type(result);
3208  }
3209  else if (expr[0] == '/')
3210  {
3211  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 2);
3212  STRING_VECTOR::const_iterator it = A.begin();
3213  double result = _convert_to_type(*it++, 0.0);
3214  if (result == 0)
3215  return "0.0";
3216 
3217  for (; it != A.end(); ++it)
3218  {
3219  const double Q = _convert_to_type(*it, 0.0);
3220  result /= Q;
3221  }
3222  return _convert_from_type(result);
3223  }
3224 
3225  // ${^ ... } power expressions
3226  else if (expr[0] == '^')
3227  {
3228  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 2);
3229  STRING_VECTOR::const_iterator it = A.begin();
3230  double result = _convert_to_type(*it++, 0.0);
3231  for (; it != A.end(); ++it)
3232  result = pow(result, _convert_to_type(*it, 0.0));
3233  return _convert_from_type(result);
3234  }
3235 
3236  // ${== } ${<= } ${>= } comparisons (return the number of the first 'match'
3237  else if (expr.length() >= 2 &&
3238  (expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" ||
3239  expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<'))
3240  {
3241  // differentiate between two and one sign operators
3242  unsigned op = 0;
3243  enum { EQ, GEQ, LEQ, GT, LT };
3244 
3245  if (expr.substr(0, 2) == "==")
3246  op = EQ;
3247 
3248  else if (expr.substr(0, 2) == ">=")
3249  op = GEQ;
3250 
3251  else if (expr.substr(0, 2) == "<=")
3252  op = LEQ;
3253 
3254  else if (expr[0] == '>')
3255  op = GT;
3256 
3257  else
3258  op = LT;
3259 
3260  STRING_VECTOR a;
3261  if (op == GT || op == LT)
3262  a = _DBE_get_expr_list(expr.substr(1), 2);
3263 
3264  else
3265  a = _DBE_get_expr_list(expr.substr(2), 2);
3266 
3267  std::string x_orig = a[0];
3268  double x = _convert_to_type(x_orig, 1e37);
3269  unsigned i = 1;
3270 
3271  STRING_VECTOR::const_iterator y_orig = a.begin();
3272  for (y_orig++; y_orig != a.end(); ++y_orig)
3273  {
3274  double y = _convert_to_type(*y_orig, 1e37);
3275 
3276  // set the strings as reference if one wasn't a number
3277  if (x == 1e37 || y == 1e37)
3278  {
3279  // it's a string comparison
3280  if ((op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
3281  (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
3282  (op == LT && x_orig < *y_orig))
3283  return _convert_from_type(i);
3284  }
3285  else
3286  {
3287  // it's a number comparison
3288  if ((op == EQ && x == y) || (op == GEQ && x >= y) ||
3289  (op == LEQ && x <= y) || (op == GT && x > y) ||
3290  (op == LT && x < y))
3291  return _convert_from_type(i);
3292  }
3293  i++;
3294  }
3295 
3296  // nothing fulfills the condition => return 0
3297  return "0";
3298  }
3299 
3300  // ${?? expr expr} select
3301  else if (expr.length() >= 2 && expr.substr(0, 2) == "??")
3302  {
3303  STRING_VECTOR a = _DBE_get_expr_list(expr.substr(2), 2);
3304  double x = _convert_to_type(a[0], 1e37);
3305 
3306  // last element is always the default argument
3307  if (x == 1e37 || x < 0 || x >= double(a.size() - 1))
3308  return a[a.size()-1];
3309 
3310  // round x to closest integer
3311  return a[int(x+0.5)];
3312  }
3313 
3314  // ${? expr expr expr} if then else conditions
3315  else if (expr[0] == '?')
3316  {
3317  STRING_VECTOR a = _DBE_get_expr_list(expr.substr(1), 2);
3318 
3319  if (_convert_to_type(a[0], 0.0) == 1.0)
3320  return a[1];
3321 
3322  else if (a.size() > 2)
3323  return a[2];
3324  }
3325  // ${! expr} maxro expansion
3326  else if (expr[0] == '!')
3327  {
3328  const GetPot::variable* Var = _DBE_get_variable(expr.substr(1));
3329  // error
3330  if (Var->name == "")
3331  return std::string(Var->original);
3332 
3333  const STRING_VECTOR A = _DBE_get_expr_list(Var->original, 2);
3334  return A[0];
3335  }
3336  // ${@: } - string subscription
3337  else if (expr.length() >= 2 && expr.substr(0,2) == "@:")
3338  {
3339  const STRING_VECTOR A = _DBE_get_expr_list(expr.substr(2), 2);
3340  double x = _convert_to_type(A[1], 1e37);
3341 
3342  // last element is always the default argument
3343  if (x == 1e37 || x < 0 || x >= double(A[0].size() - 1))
3344  return "<<1st index out of range>>";
3345 
3346  if (A.size() > 2)
3347  {
3348  double y = _convert_to_type(A[2], 1e37);
3349  if (y != 1e37 && y > 0 && y <= double(A[0].size() - 1) && y > x)
3350  return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5));
3351 
3352  else if (y == -1)
3353  return A[0].substr(int(x+0.5));
3354 
3355  return "<<2nd index out of range>>";
3356  }
3357  else
3358  {
3359  char* tmp = new char[2];
3360  tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0';
3361  std::string result(tmp);
3362  delete [] tmp;
3363  return result;
3364  }
3365  }
3366  // ${@ } - vector subscription
3367  else if (expr[0] == '@')
3368  {
3369  STRING_VECTOR A = _DBE_get_expr_list(expr.substr(1), 2);
3370  const GetPot::variable* Var = _DBE_get_variable(A[0]);
3371  // error
3372  if (Var->name == "")
3373  {
3374  // make a copy of the string if an error occurred
3375  // (since the error variable is a static variable inside get_variable())
3376  return std::string(Var->original);
3377  }
3378 
3379  double x = _convert_to_type(A[1], 1e37);
3380 
3381  // last element is always the default argument
3382  if (x == 1e37 || x < 0 || x >= double(Var->value.size()))
3383  return "<<1st index out of range>>";
3384 
3385  if (A.size() > 2)
3386  {
3387  double y = _convert_to_type(A[2], 1e37);
3388  int begin = int(x+0.5);
3389  int end = 0;
3390  if (y != 1e37 && y > 0 && y <= double(Var->value.size()) && y > x)
3391  end = int(y+1.5);
3392  else if (y == -1)
3393  end = int(Var->value.size());
3394  else
3395  return "<<2nd index out of range>>";
3396 
3397  std::string result = *(Var->get_element(begin));
3398  for (int i = begin+1; i < end; i++)
3399  result += std::string(" ") + *(Var->get_element(i));
3400  return result;
3401  }
3402  else
3403  return *(Var->get_element(int(x+0.5)));
3404  }
3405 
3406  const STRING_VECTOR A = _DBE_get_expr_list(expr, 1);
3407  const GetPot::variable* B = _DBE_get_variable(A[0]);
3408 
3409  // make a copy of the string if an error occurred
3410  // (since the error variable is a static variable inside get_variable())
3411  if (B->name == "")
3412  return std::string(B->original);
3413 
3414  // ([email protected] mentioned to me the warning MSVC++6.0 produces
3415  // with: else return B->original (thanks))
3416  return B->original;
3417 }
3418 
3419 
3420 
3422 // (*) unidentified flying objects
3423 //.............................................................................
3424 //
3425 inline bool
3426 GetPot::_search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const
3427 {
3428  victorate(std::string, VecStr, itk)
3429  {
3430  if (*itk == Str)
3431  return true;
3432  }
3433  return false;
3434 }
3435 
3436 
3437 
3438 inline STRING_VECTOR
3440  const char* KnownArgument1, ...) const
3441 {
3442  std::set<std::string> known_arguments;
3443 
3444  // (1) create a vector of known arguments
3445  if (Number == 0)
3446  return STRING_VECTOR();
3447 
3448  va_list ap;
3449  va_start(ap, KnownArgument1);
3450  known_arguments.insert(std::string(KnownArgument1));
3451  for (unsigned i=1; i<Number; i++)
3452  known_arguments.insert(std::string(va_arg(ap, char *)));
3453  va_end(ap);
3454 
3455  return unidentified_arguments(known_arguments);
3456 }
3457 
3458 
3459 
3460 inline STRING_VECTOR
3462 {
3464 }
3465 
3466 
3467 
3468 inline STRING_VECTOR
3469 GetPot::unidentified_arguments(const std::vector<std::string>& Knowns) const
3470 {
3471  // We use set for efficiency, but want to support vector inputs for
3472  // backwards compatibility.
3473  return unidentified_arguments(std::set<std::string> (Knowns.begin(), Knowns.end()));
3474 }
3475 
3476 
3477 
3478 inline STRING_VECTOR
3479 GetPot::unidentified_arguments(const std::set<std::string>& Knowns) const
3480 {
3481  STRING_VECTOR ufos;
3482  STRING_VECTOR::const_iterator it = argv.begin();
3483  ++it; // forget about argv[0] (application or filename)
3484  for (; it != argv.end(); ++it)
3485  {
3486  // -- argument belongs to prefixed section ?
3487  const std::string arg = _get_remaining_string(*it, prefix);
3488  if (arg == "")
3489  continue;
3490 
3491  // -- check if in list
3492  if (Knowns.find(arg) == Knowns.end())
3493  ufos.push_back(*it);
3494  }
3495  return ufos;
3496 }
3497 
3498 
3499 
3500 inline STRING_VECTOR
3502  const char* KnownOption1, ...) const
3503 {
3504  std::set<std::string> known_options;
3505 
3506  // (1) create a vector of known arguments
3507  if (Number == 0)
3508  return STRING_VECTOR();
3509 
3510  va_list ap;
3511  va_start(ap, KnownOption1);
3512  known_options.insert(std::string(KnownOption1));
3513  for (unsigned i=1; i<Number; i++)
3514  known_options.insert(std::string(va_arg(ap, char *)));
3515  va_end(ap);
3516 
3517  return unidentified_options(known_options);
3518 }
3519 
3520 
3521 
3522 inline STRING_VECTOR
3524 {
3525  // -- every option is an argument.
3526  // -- the set of requested arguments contains the set of requested options.
3527  // -- IF the set of requested arguments contains unrequested options,
3528  // THEN they were requested as 'follow' and 'next' arguments and not as real options.
3529  //
3530  // => it is not necessary to separate requested options from the list
3532 }
3533 
3534 
3535 
3536 inline STRING_VECTOR
3537 GetPot::unidentified_options(const std::vector<std::string>& Knowns) const
3538 {
3539  // We use set for efficiency, but want to support vector inputs for
3540  // backwards compatibility.
3541  return unidentified_options(std::set<std::string> (Knowns.begin(), Knowns.end()));
3542 }
3543 
3544 
3545 
3546 inline STRING_VECTOR
3547 GetPot::unidentified_options(const std::set<std::string>& Knowns) const
3548 {
3549  STRING_VECTOR ufos;
3550  STRING_VECTOR::const_iterator it = argv.begin();
3551  ++it; // forget about argv[0] (application or filename)
3552  for (; it != argv.end(); ++it)
3553  {
3554  // -- argument belongs to prefixed section ?
3555  const std::string arg = _get_remaining_string(*it, prefix);
3556  if (arg == "")
3557  continue;
3558 
3559  // is argument really an option (starting with '-') ?
3560  if (arg.length() < 1 || arg[0] != '-')
3561  continue;
3562 
3563  if (Knowns.find(arg) == Knowns.end())
3564  ufos.push_back(*it);
3565  }
3566 
3567  return ufos;
3568 }
3569 
3570 
3571 
3572 // Two modes:
3573 // ArgumentNumber >= 0 check specific argument
3574 // ArgumentNumber == -1 check all options starting with one '-'
3575 // for flags
3576 inline std::string
3577 GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const
3578 {
3579  std::string ufos;
3580  // STRING_VECTOR known_arguments;
3581  std::string KFL(KnownFlagList);
3582 
3583  // (2) iteration over '-' arguments (options)
3584  if (ArgumentNumber == -1)
3585  {
3586  STRING_VECTOR::const_iterator it = argv.begin();
3587  ++it; // forget about argv[0] (application or filename)
3588  for (; it != argv.end(); ++it)
3589  {
3590  // -- argument belongs to prefixed section ?
3591  const std::string arg = _get_remaining_string(*it, prefix);
3592  if (arg == "") continue;
3593 
3594  // -- does arguments start with '-' (but not '--')
3595  if (arg.length() < 2)
3596  continue;
3597 
3598  else if (arg[0] != '-')
3599  continue;
3600 
3601  else if (arg[1] == '-')
3602  continue;
3603 
3604  // -- check out if flags inside option are contained in KnownFlagList
3605  const char* p=arg.c_str();
3606  p++; // skip starting minus
3607  for (; *p != '\0' ; p++)
3608  if (KFL.find(*p) == std::string::npos) ufos += *p;
3609  }
3610  }
3611  // (1) check specific argument
3612  else
3613  {
3614  // -- only check arguments that start with prefix
3615  int no_matches = 0;
3616  for (unsigned i=1; i<argv.size(); i++)
3617  {
3618  const std::string Remain = _get_remaining_string(argv[i], prefix);
3619  if (Remain != "")
3620  {
3621  no_matches++;
3622  if (no_matches == ArgumentNumber)
3623  {
3624  // -- the right argument number inside the section is found
3625  // => check it for flags
3626  const char* p = Remain.c_str();
3627  p++; // skip starting minus
3628  for (; *p != '\0' ; p++)
3629  if (KFL.find(*p) == std::string::npos) ufos += *p;
3630  return ufos;
3631  }
3632  }
3633  }
3634  }
3635  return ufos;
3636 }
3637 
3638 
3639 
3640 inline STRING_VECTOR
3642  const char* KnownVariable1, ...) const
3643 {
3644  std::set<std::string> known_variables;
3645 
3646  // create vector of known arguments
3647  if (Number == 0)
3648  return STRING_VECTOR();
3649 
3650  va_list ap;
3651  va_start(ap, KnownVariable1);
3652  known_variables.insert(std::string(KnownVariable1));
3653  for (unsigned i=1; i<Number; i++)
3654  known_variables.insert(std::string(va_arg(ap, char *)));
3655  va_end(ap);
3656 
3657  return unidentified_variables(known_variables);
3658 }
3659 
3660 
3661 
3662 inline STRING_VECTOR
3663 GetPot::unidentified_variables(const std::vector<std::string>& Knowns) const
3664 {
3665  // We use set for efficiency, but want to support vector inputs for
3666  // backwards compatibility.
3667  return unidentified_variables(std::set<std::string> (Knowns.begin(), Knowns.end()));
3668 }
3669 
3670 
3671 
3672 inline STRING_VECTOR
3673 GetPot::unidentified_variables(const std::set<std::string>& Knowns) const
3674 {
3675  STRING_VECTOR ufos;
3676 
3677  victorate(GetPot::variable, variables, it)
3678  {
3679  // -- check if variable has specific prefix
3680  const std::string var_name = _get_remaining_string((*it).name, prefix);
3681  if (var_name == "")
3682  continue;
3683 
3684  // -- check if variable is known
3685  if (Knowns.find(var_name) == Knowns.end())
3686  ufos.push_back((*it).name);
3687  }
3688  return ufos;
3689 }
3690 
3691 
3692 
3693 inline STRING_VECTOR
3695 {
3697 }
3698 
3699 
3700 
3701 inline STRING_VECTOR
3703  const char* KnownSection1, ...) const
3704 {
3705  std::set<std::string> known_sections;
3706 
3707  // (1) create a vector of known arguments
3708  if (Number == 0)
3709  return STRING_VECTOR();
3710 
3711  va_list ap;
3712  va_start(ap, KnownSection1);
3713  known_sections.insert(std::string(KnownSection1));
3714  for (unsigned i=1; i<Number; i++)
3715  {
3716  std::string tmp = std::string(va_arg(ap, char *));
3717 
3718  if (tmp.length() == 0)
3719  continue;
3720 
3721  if (tmp[tmp.length()-1] != '/')
3722  tmp += '/';
3723 
3724  known_sections.insert(tmp);
3725  }
3726  va_end(ap);
3727 
3728  return unidentified_sections(known_sections);
3729 }
3730 
3731 
3732 
3733 inline STRING_VECTOR
3735 {
3737 }
3738 
3739 
3740 
3741 inline STRING_VECTOR
3742 GetPot::unidentified_sections(const std::vector<std::string>& Knowns) const
3743 {
3744  // We use set for efficiency, but want to support vector inputs for
3745  // backwards compatibility.
3746  return unidentified_sections(std::set<std::string> (Knowns.begin(), Knowns.end()));
3747 }
3748 
3749 
3750 
3751 inline STRING_VECTOR
3752 GetPot::unidentified_sections(const std::set<std::string>& Knowns) const
3753 {
3754  STRING_VECTOR ufos;
3755 
3756  victorate(std::string, section_list, it)
3757  {
3758  // -- check if section conform to prefix
3759  const std::string sec_name = _get_remaining_string(*it, prefix);
3760  if (sec_name == "")
3761  continue;
3762 
3763  // -- check if section is known
3764  if (Knowns.find(sec_name) == Knowns.end())
3765  ufos.push_back(*it);
3766  }
3767 
3768  return ufos;
3769 }
3770 
3771 
3772 
3773 inline STRING_VECTOR
3774 GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const
3775 {
3776  std::set<std::string> known_nominuses;
3777 
3778  // create vector of known arguments
3779  if (Number == 0)
3780  return STRING_VECTOR();
3781 
3782  va_list ap;
3783  va_start(ap, Known);
3784  known_nominuses.insert(std::string(Known));
3785  for (unsigned i=1; i<Number; i++)
3786  {
3787  std::string tmp = std::string(va_arg(ap, char *));
3788  if (tmp.length() == 0)
3789  continue;
3790  known_nominuses.insert(tmp);
3791  }
3792  va_end(ap);
3793 
3794  return unidentified_nominuses(known_nominuses);
3795 }
3796 
3797 
3798 
3799 inline STRING_VECTOR
3801 {
3802  // -- every nominus is an argument.
3803  // -- the set of requested arguments contains the set of requested nominuss.
3804  // -- IF the set of requested arguments contains unrequested nominuss,
3805  // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses.
3806  //
3807  // => it is not necessary to separate requested nominus from the list
3808 
3810 }
3811 
3812 
3813 
3814 inline STRING_VECTOR
3815 GetPot::unidentified_nominuses(const std::vector<std::string>& Knowns) const
3816 {
3817  // We use set for efficiency, but want to support vector inputs for
3818  // backwards compatibility.
3819  return unidentified_nominuses(std::set<std::string> (Knowns.begin(), Knowns.end()));
3820 }
3821 
3822 
3823 
3824 inline STRING_VECTOR
3825 GetPot::unidentified_nominuses(const std::set<std::string>& Knowns) const
3826 {
3827  STRING_VECTOR ufos;
3828 
3829  // (2) iterate over all arguments
3830  STRING_VECTOR::const_iterator it = argv.begin();
3831  ++it; // forget about argv[0] (application or filename)
3832  for (; it != argv.end(); ++it)
3833  {
3834  // -- check if nominus part of prefix
3835  const std::string arg = _get_remaining_string(*it, prefix);
3836  if (arg == "")
3837  continue;
3838 
3839  if (arg.length() < 1)
3840  continue;
3841 
3842  // option ? --> not a nomius
3843  if (arg[0] == '-')
3844  continue;
3845 
3846  // section ? --> not a real nominus
3847  if (arg[0] == '[' && arg[arg.length()-1] == ']')
3848  continue;
3849 
3850  // variable definition ? --> not a real nominus
3851  bool continue_f = false;
3852  for (unsigned i=0; i<arg.length() ; i++)
3853  if (arg[i] == '=')
3854  {
3855  continue_f = true;
3856  break;
3857  }
3858 
3859  if (continue_f)
3860  continue;
3861 
3862  // real nominuses are compared with the given list
3863  if (Knowns.find(arg) == Knowns.end())
3864  ufos.push_back(*it);
3865  }
3866  return ufos;
3867 }
3868 
3869 
3871 // (*) Accessors for requested types
3872 //.............................................................................
3873 
3874 inline
3875 std::set<std::string>
3877 {
3878  return _requested_arguments;
3879 }
3880 
3881 
3882 
3883 inline
3884 std::set<std::string>
3886 {
3887  return _requested_variables;
3888 }
3889 
3890 
3891 
3892 inline
3893 std::set<std::string>
3895 {
3896  return _requested_sections;
3897 }
3898 
3899 
3900 
3902 // (*) variable class
3903 //.............................................................................
3904 //
3905 inline
3907  : name(),
3908  value(),
3909  original()
3910 {}
3911 
3912 
3913 
3914 inline
3916 {
3917 #ifdef WIN32
3918  operator=(Other);
3919 #else
3921 #endif
3922 }
3923 
3924 
3925 
3926 inline
3927 GetPot::variable::variable(const char* Name, const char* Value, const char* FieldSeparator)
3928  : name(Name)
3929 {
3930  // make a copy of the 'Value'
3931  take(Value, FieldSeparator);
3932 }
3933 
3934 
3935 
3936 inline const std::string*
3938 {
3939  if (Idx >= value.size())
3940  return 0;
3941  else
3942  return &(value[Idx]);
3943 }
3944 
3945 
3946 
3947 inline void
3948 GetPot::variable::take(const char* Value, const char* FieldSeparator)
3949 {
3950  original = std::string(Value); // string member var
3951  value.clear(); // vector<string> member var
3952 
3953  /*
3954  // separate string by white space delimiters using 'strtok'
3955  // thread safe usage of strtok (no static members)
3956  char* spt = 0;
3957  // make a copy of the 'Value'
3958  char* copy = new char[strlen(Value)+1];
3959  strcpy(copy, Value);
3960  char* follow_token = strtok_r(copy, FieldSeparator, &spt);
3961  while (follow_token != 0)
3962  {
3963  value.push_back(std::string(follow_token));
3964  follow_token = strtok_r(NULL, FieldSeparator, &spt);
3965  }
3966 
3967  delete [] copy;
3968  */
3969 
3970  // Don't use strtok, instead tokenize the input char "Value" using std::string operations so
3971  // that the results end up in the local "value" member
3972 
3973  // Construct std::string objects from the input char*s. I think the only
3974  // FieldSeparator recognized by GetPot is whitespace?
3975  std::string Value_str = std::string(Value);
3976  std::string delimiters = std::string(FieldSeparator);
3977 
3978  // Skip delimiters at beginning.
3979  std::string::size_type lastPos = Value_str.find_first_not_of(delimiters, 0);
3980 
3981  // Find first "non-delimiter".
3982  std::string::size_type pos = Value_str.find_first_of(delimiters, lastPos);
3983 
3984  // Loop over the input string until all the tokens have been pushed back
3985  // into the local "value" member.
3986  while (std::string::npos != pos || std::string::npos != lastPos)
3987  {
3988  // Found a token, add it to the vector.
3989  value.push_back(Value_str.substr(lastPos, pos - lastPos));
3990 
3991  // Skip delimiters. Note the "not_of"
3992  lastPos = Value_str.find_first_not_of(delimiters, pos);
3993 
3994  // Find next "non-delimiter"
3995  pos = Value_str.find_first_of(delimiters, lastPos);
3996  }
3997 
3998  // We're done, all the tokens should now be in the vector<string>
3999 }
4000 
4001 inline
4003 {}
4004 
4005 
4006 
4007 inline GetPot::variable&
4009 {
4010  if (&Other != this)
4011  {
4012  name = Other.name;
4013  value = Other.value;
4014  original = Other.original;
4015  }
4016  return *this;
4017 }
4018 
4019 #ifdef GETPOT_NAMESPACE
4020 }
4021 #endif
4022 
4023 #undef victorate
4024 
4025 #endif // LIBMESH_GETPOT_H
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
bool search_failed() const
Definition: getpot.h:357
GETPOT_MUTEX_DECLARE
we have some mutable non-thread-safe members, but we want to be able to call const member functions f...
Definition: getpot.h:551
bool argument_contains(unsigned Idx, const char *FlagList) const
Definition: getpot.h:2115
STRING_VECTOR unidentified_variables() const
Definition: getpot.h:3694
static STRING_VECTOR _get_section_tree(const std::string &FullPath)
cuts a variable name into a tree of sub-sections.
Definition: getpot.h:722
int nominus_cursor
nominus vector
Definition: getpot.h:526
T get_value_no_default(const char *VarName, const T &Default) const
access variables, but error out if not present scalar values
Definition: getpot.h:2361
const std::string _get_string(std::istream &istr)
Definition: getpot.h:1419
void is_transparent
As of C++14, std::set::find() can be a templated overload.
Definition: getpot.h:565
bool _search_string_vector(const STRING_VECTOR &Vec, const std::string &Str) const
search for a specific string
Definition: getpot.h:3426
std::string _DBE_expand(const std::string &str)
Definition: getpot.h:2921
std::set< std::string > get_requested_variables() const
Definition: getpot.h:3885
void disable_loop()
enable/disable search for an option in loop
Definition: getpot.h:362
void reset_cursor()
reset cursor to position &#39;1&#39;
Definition: getpot.h:1847
bool have_section(const char *section_name) const
Check for a section name.
Definition: getpot.h:2250
STRING_VECTOR _read_in_stream(std::istream &istr)
Definition: getpot.h:1228
std::string section
Definition: getpot.h:511
Variable to be specified on the command line or in input files.
Definition: getpot.h:480
STRING_VECTOR get_variable_names() const
Definition: getpot.h:2568
variable()
constructors, destructors, assignment operator
Definition: getpot.h:3906
std::string name
data members
Definition: getpot.h:502
T _convert_to_type_no_default(const char *VarName, const std::string &String, const T &Default) const
Definition: getpot.h:1628
Transparent comparator object used for making std::sets that contain unique_ptrs. ...
Definition: getpot.h:557
void parse_input_file(const std::string &FileName, const std::string &CommentStart=std::string("#"), const std::string &CommentEnd=std::string("\), const std::string &FieldSeparator=std::string(" \\"))
Definition: getpot.h:918
STRING_VECTOR unidentified_nominuses() const
Definition: getpot.h:3800
const std::string _get_until_closing_bracket(std::istream &istr)
Definition: getpot.h:1445
bool search(const char *option)
search for a certain option and set cursor to position
Definition: getpot.h:1758
const variable * _find_variable(const char *) const
helpers for argument list processing
Definition: getpot.h:2650
STRING_VECTOR unidentified_sections() const
Definition: getpot.h:3734
static std::string _convert_from_type(const T &Value)
Definition: getpot.h:711
const std::string _get_until_closing_square_bracket(std::istream &istr)
Definition: getpot.h:1478
STRING_VECTOR unidentified_arguments() const
Definition: getpot.h:3461
unsigned nominus_size() const
Definition: getpot.h:415
variable & operator=(const variable &Other)
Definition: getpot.h:4008
int print(std::ostream &out_stream=std::cout) const
output
Definition: getpot.h:2681
const std::string * get_element(unsigned Idx) const
get a specific element in the string vector (return 0 if not present)
Definition: getpot.h:3937
void _parse_argument_vector(const STRING_VECTOR &ARGV)
produce three basic data vectors:
Definition: getpot.h:1125
void set(const char *VarName, const T &Value, const bool Requested=true)
setting variables i) from outside of GetPot (considering prefix etc.) ii) from inside, use &#39;_set_variable()&#39; below
Definition: getpot.h:2514
T follow(const T &Default, const char *Option)
search for option and get argument at cursor++
Definition: getpot.h:1941
const std::string _get_remaining_string(const std::string &String, const std::string &Start) const
prefix extraction
Definition: getpot.h:1731
void disable_request_recording()
Definition: getpot.h:211
const std::string _get_next_token(std::istream &istr)
Definition: getpot.h:1362
std::vector< unsigned > idx_nominus
Definition: getpot.h:527
bool _check_flags(const std::string &Str, const char *FlagList) const
support search for flags in a specific argument
Definition: getpot.h:2150
STRING_VECTOR get_subsection_names(const std::string &section_name) const
Definition: getpot.h:2592
STRING_VECTOR _DBE_get_expr_list(const std::string &str, const unsigned ExpectedNumber)
Definition: getpot.h:2796
std::string prefix
member variables
Definition: getpot.h:510
std::vector< variable > variables
variables (arguments of the form "variable=value")
Definition: getpot.h:532
T operator()(const char *VarName, const T &Default) const
scalar values
Definition: getpot.h:2279
bool operator()(const std::unique_ptr< const char[]> &s1, const std::unique_ptr< const char[]> &s2) const
Definition: getpot.h:567
GetPot & operator=(const GetPot &)
Definition: getpot.h:1038
Definition: assembly.h:38
const char * _match_starting_string(const char *StartString)
support finding directly followed arguments
Definition: getpot.h:2052
T direct_follow(const T &Default, const char *Option)
directly followed arguments
Definition: getpot.h:2023
T pow(const T &x)
Definition: utility.h:328
unsigned vector_variable_size(const char *VarName) const
Definition: getpot.h:2549
GetPot - A class for parsing command line arguments and configuration files.
Definition: getpot.h:155
GetPot()
constructors, destructor, assignment operator
Definition: getpot.h:764
void absorb(const GetPot &Other)
absorbing contents of another GetPot object
Definition: getpot.h:1082
void _basic_initialization()
Definition: getpot.h:741
std::set< std::unique_ptr< const char[]>, ltstr > _internal_string_container
some functions return a char pointer to a string created on the fly.
Definition: getpot.h:588
std::set< std::string > get_overridden_variables() const
Definition: getpot.h:2642
T _convert_to_type(const std::string &String, const T &Default) const
type conversion if possible
Definition: getpot.h:1563
const char * _internal_managed_copy(const std::string &Arg) const
some functions return a char pointer to a temporarily existing string this function adds them to our ...
Definition: getpot.h:1701
void parse_input_stream(std::istream &FileStream, const std::string &FileName=std::string("ParsedFromStream"), const std::string &CommentStart=std::string("#"), const std::string &CommentEnd=std::string("\), const std::string &FieldSeparator=std::string(" \\"))
Definition: getpot.h:966
std::set< std::string > _requested_sections
Definition: getpot.h:602
void _skip_whitespace(std::istream &istr)
helpers to parse input file create an argument vector based on data found in an input file...
Definition: getpot.h:1300
STRING_VECTOR argv
argument vector
Definition: getpot.h:517
void enable_request_recording()
Definition: getpot.h:212
STRING_VECTOR nominus_vector() const
Definition: getpot.h:2165
std::set< std::string > get_requested_sections() const
Definition: getpot.h:3894
bool have_variable(const char *VarName) const
variables
Definition: getpot.h:2231
const char * next_nominus()
Definition: getpot.h:2184
const GetPot::variable * _DBE_get_variable(const std::string &str)
Definition: getpot.h:2887
unsigned size() const
Definition: getpot.h:1898
void set_prefix(const char *Prefix)
cursor oriented functions
Definition: getpot.h:356
STRING_VECTOR unidentified_options() const
Definition: getpot.h:3523
void reset_nominus_cursor()
nominus arguments
Definition: getpot.h:2219
const variable * _request_variable(const char *) const
search (and record request) for a variable in &#39;variables&#39; array
Definition: getpot.h:2666
void clear_requests()
for ufo detection: recording requested arguments, options etc.
Definition: getpot.h:1112
std::string next_nominus_string()
Definition: getpot.h:2201
void init_multiple_occurrence()
Definition: getpot.h:1856
static const bool value
Definition: xdr_io.C:54
void _set_variable(const std::string &VarName, const std::string &Value, const bool Requested)
helper functions
Definition: getpot.h:2495
std::set< std::string > _requested_variables
Definition: getpot.h:601
std::string _process_section_label(const std::string &Section, STRING_VECTOR &section_stack)
Definition: getpot.h:1506
bool operator()(const char *const &s1, const std::unique_ptr< const char[]> &s2) const
Definition: getpot.h:575
std::string _field_separator
field separator (separating elements of a vector)
Definition: getpot.h:543
void take(const char *Value, const char *FieldSeparator)
Definition: getpot.h:3948
T get(unsigned Idx, const T &Default) const
void parse_command_line(const int argc_, const char *const *argv_, const char *FieldSeparator=0x0)
Re-initialization methods.
Definition: getpot.h:825
bool options_contain(const char *FlagList) const
flags
Definition: getpot.h:2096
std::string _comment_end
Definition: getpot.h:538
STRING_VECTOR section_list
Definition: getpot.h:512
std::vector< std::string > STRING_VECTOR
Definition: getpot.h:134
const char * operator[](unsigned Idx) const
direct access to command line arguments
Definition: getpot.h:1869
std::set< std::string > get_requested_arguments() const
Accessors for requested variables.
Definition: getpot.h:3876
T next(const T &Default)
get argument at cursor++
Definition: getpot.h:1908
std::string _comment_start
comment delimiters
Definition: getpot.h:537
STRING_VECTOR get_section_names() const
Definition: getpot.h:2584
std::string unidentified_flags(const char *Known, int ArgumentNumber) const
Definition: getpot.h:3577
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
std::set< std::string > overridden_vars
Definition: getpot.h:521
std::set< std::string > _requested_arguments
keeping track about arguments that are requested, so that the UFO detection can be simplified ...
Definition: getpot.h:600
void _record_argument_request(const std::string &Arg) const
if an argument is requested record it and the &#39;tag&#39; the section branch to which it belongs...
Definition: getpot.h:2449
void _record_variable_request(const std::string &Arg) const
Definition: getpot.h:2471
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
A useful inline function which replaces the macros used previously.
bool operator()(const std::unique_ptr< const char[]> &s1, const char *const &s2) const
Definition: getpot.h:571
std::string _DBE_expand_string(const std::string &str)
dollar bracket expressions
Definition: getpot.h:2763