Derecho  0.9
Distributed systems toolkit for RDMA
GetPot.cpp
Go to the documentation of this file.
1 // SPDX license identifier: MIT; Project 'GetPot'
2 // MIT License
3 //
4 // Copyright (C) 2001-2016 Frank-Rene Schaefer.
5 //
6 // While not directly linked to license requirements, the author would like
7 // this software not to be used for military purposes.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in all
17 // copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 // SOFTWARE.
26 //=============================================================================
27 
28 #ifndef __INCLUDE_GUARD_GETPOT_CPP__
29 #define __INCLUDE_GUARD_GETPOT_CPP__
30 
31 #if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
32  // WINDOWS or SOLARIS or gcc 2.* or HP aCC
33 # define GETPOT_STRTOK(a, b, c) strtok_r(a, b, c)
34 # define GETPOT_STRTOK_3_ARGS
35 #else
36 # define GETPOT_STRTOK(a, b, c) strtok(a, b)
37 #endif
38 
39 #if defined(WIN32)
40 # define GETPOT_SNPRINTF(STR, SIZE, FORMAT_STR, ...) \
41  _snprintf(tmp, (size_t)SIZE, FORMAT_STR, __VA_ARGS__)
42 #else
43 # define GETPOT_SNPRINTF(STR, SIZE, FORMAT_STR, ...) \
44  snprintf(tmp, (int)SIZE, FORMAT_STR, __VA_ARGS__)
45 #endif
46 
47 /* In case that a single header is intended, __GETPOT_INLINE is set to 'inline'
48  * otherwise, it is set to 'empty', so that normal object code is produced. */
49 #ifndef __GETPOT_INLINE
50 # define __GETPOT_INLINE /*empty*/
51 #endif
52 
53 /* The default values for strings that represent 'true' and 'false' */
54 
55 #include "GetPot.hpp"
56 
57 #ifdef GETPOT_SETTING_NAMESPACE
58 namespace GETPOT_SETTING_NAMESPACE {
59 #endif
60 
61 #define victorate(TYPE, VARIABLE, ITERATOR) \
62  for(std::vector<TYPE >::const_iterator ITERATOR = (VARIABLE).begin(); \
63  (ITERATOR) != (VARIABLE).end(); ++(ITERATOR))
64 
65 template <class T> class TypeInfo;
66 
67 template <> class TypeInfo<bool> {
68 public: static const char* name() { return "bool"; }
69  static bool default_value() { return false; }
70  typedef bool type;
71  static bool convert(bool& X) { return (bool)X; }
72 };
73 
74 template <> class TypeInfo<const char*> {
75 public: static const char* name() { return "string"; }
76  static const char * default_value() { return ""; }
77  typedef const char* type;
78  static const char* convert(const char* X) { return (const char*)X; }
79 };
80 
81 template <> class TypeInfo<int> {
82 public: static const char* name() { return "integer"; }
83  static int default_value() { return 0; }
84  typedef int type;
85  static int convert(int& X) { return (int)X; }
86 };
87 template <> class TypeInfo<std::string> : public TypeInfo<const char*>
88 { public:
89  static const char* convert(std::string& X) { return (const char*)"inadmissible"; }
90  static std::string default_value() { return std::string(""); }
91 };
92 template <> class TypeInfo<unsigned int> : public TypeInfo<int>
93 { public: static int convert(unsigned int& X) { return (int)X; } };
94 template <> class TypeInfo<char> : public TypeInfo<int>
95 { public: static int convert(char& X) { return (int)X; } };
96 template <> class TypeInfo<unsigned char> : public TypeInfo<int>
97 { public: static int convert(unsigned char& X) { return (int)X; } };
98 template <> class TypeInfo<short> : public TypeInfo<int>
99 { public: static int convert(short& X) { return (int)X; } };
100 template <> class TypeInfo<unsigned short> : public TypeInfo<int>
101 { public: static int convert(unsigned short& X) { return (int)X; } };
102 template <> class TypeInfo<long> : public TypeInfo<int>
103 { public: static int convert(long& X) { return (int)X; } };
104 template <> class TypeInfo<unsigned long> : public TypeInfo<int>
105 { public: static int convert(unsigned long& X) { return (int)X; } };
106 
107 template <> class TypeInfo<double> {
108 public: static const char* name() { return "double"; }
109  static double default_value() { return 0.; }
110  typedef double type;
111  static double convert(double& X) { return (double)X; }
112 };
113 template <> class TypeInfo<float> : public TypeInfo<double>
114 { public: static double convert(float& X) { return (double)X; } };
115 
116 
118 // (*) constructors, destructor, assignment operator
119 //.............................................................................
120 //
121 __GETPOT_INLINE void
123 {
124  cursor = 0; nominus_cursor = -1;
125  search_failed_f = true; search_loop_f = true;
126  prefix = ""; section = "";
127 
128  // automatic request recording for later ufo detection
129  __request_recording_f = true;
130 
131  // comment start and end strings
132  _comment_start = std::string("#");
133  _comment_end = std::string("\n");
134 
135  // default: separate vector elements by whitespaces
136  _field_separator = " \t\n";
137 
138  // true and false strings
139  __split(GETPOT_SETTING_DEFAULT_TRUE_STRING_LIST, true_string_list);
140  __split(GETPOT_SETTING_DEFAULT_FALSE_STRING_LIST, false_string_list);
141 }
142 
145  built(false)
146 {
148 
149  STRING_VECTOR _apriori_argv;
150  _apriori_argv.push_back(std::string("Empty"));
151  __parse_argument_vector(_apriori_argv);
152  built = true;
153 }
154 
156 GetPot::GetPot(const int argc_, char ** argv_,
157  const StringOrCharP FieldSeparator /* =0x0 */):
158  built(false)
159  // leave 'char**' non-const to honor less capable compilers ...
160 {
161  // TODO: Ponder over the problem when the argument list is of size = 0.
162  // This is 'sabotage', but it can still occur if the user specifies
163  // it himself.
164  assert(argc_ >= 1);
166 
167  // if specified -> overwrite default string
168  if( FieldSeparator.content.length() != 0 ) _field_separator = FieldSeparator.content;
169 
170  // -- make an internal copy of the argument list:
171  STRING_VECTOR _apriori_argv;
172  // -- for the sake of clarity: we do want to include the first argument in the argument vector !
173  // it will not be a nominus argument, though. This gives us a minimun vector size of one
174  // which facilitates error checking in many functions. Also the user will be able to
175  // retrieve the name of his application by "get[0]"
176  _apriori_argv.push_back(std::string(argv_[0]));
177  int i=1;
178  for(; i<argc_; ++i) {
179  std::string tmp(argv_[i]); // recall the problem with temporaries,
180  _apriori_argv.push_back(tmp); // reference counting in arguement lists ...
181  }
182  __parse_argument_vector(_apriori_argv);
183  built = true;
184 }
185 
188  const StringOrCharP CommentStart /* = 0x0 */,
189  const StringOrCharP CommentEnd /* = 0x0 */,
190  const StringOrCharP FieldSeparator/* = 0x0 */):
191  built(false)
192 {
193  __build(FileName.content, CommentStart.content, CommentEnd.content, FieldSeparator.content);
194  built = true;
195 }
196 
198 GetPot::GetPot(const GetPot& That)
199 { GetPot::operator=(That); }
200 
203 {
204  // may be some return strings had to be created, delete now !
205  victorate(std::vector<char>*, __internal_string_container, it) {
206  delete *it;
207  }
208 }
209 
212 {
213  if (&That == this) return *this;
214 
215  built = That.built;
216  filename = That.filename;
219 
221  _comment_end = That._comment_end;
223  argv = That.argv;
224  variables = That.variables;
225  prefix = That.prefix;
226 
227  cursor = That.cursor;
230 
231  idx_nominus = That.idx_nominus;
233 
234  return *this;
235 }
236 
237 
238 __GETPOT_INLINE void
239 GetPot::absorb(const GetPot& That)
240 {
241  if (&That == this) return;
242 
243  STRING_VECTOR __tmp(That.argv);
244 
245  __tmp.erase(__tmp.begin());
246 
248 }
249 
250 __GETPOT_INLINE void
252 {
256 }
257 
258 __GETPOT_INLINE void
260 {
261  if( ARGV.size() == 0 ) return;
262 
263  // build internal databases:
264  // 1) array with no-minus arguments (usually used as filenames)
265  // 2) variable assignments:
266  // 'variable name' '=' number | string
267  STRING_VECTOR section_stack;
268  STRING_VECTOR::const_iterator it = ARGV.begin();
269 
270 
271  section = "";
272 
273  // -- do not parse the first argument, so that it is not interpreted a s a nominus or so.
274  argv.push_back(*it);
275  ++it;
276 
277  // -- loop over remaining arguments
278  unsigned i=1;
279  for(; it != ARGV.end(); ++it, ++i) {
280  std::string arg = *it;
281 
282  if( arg.length() == 0 ) continue;
283 
284  // -- [section] labels
285  if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) {
286 
287  // (*) sections are considered 'requested arguments'
288  if( __request_recording_f ) _requested_arguments.push_back(arg);
289 
290  const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2));
291  section = __process_section_label(Name, section_stack);
292  // new section --> append to list of sections
293  if( find(section_list.begin(), section_list.end(), section) == section_list.end() )
294  if( section.length() != 0 ) section_list.push_back(section);
295  argv.push_back(arg);
296  }
297  else {
298  arg = section + __DBE_expand_string(arg);
299  argv.push_back(arg);
300  }
301 
302  // -- separate array for nominus arguments
303  if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i));
304 
305  // -- variables: does arg contain a '=' operator ?
306  ptrdiff_t i = 0;
307  for(std::string::iterator it = arg.begin(); it != arg.end(); ++it, ++i) {
308  if( *it != '=' ) continue;
309 
310  // (*) record for later ufo detection
311  // arguments carriying variables are always treated as 'requested' arguments.
312  // as a whole! That is 'x=4712' is considered a requested argument.
313  //
314  // unrequested variables have to be detected with the ufo-variable
315  // detection routine.
316  if( __request_recording_f ) _requested_arguments.push_back(arg);
317 
318  const bool tmp = __request_recording_f;
319  __request_recording_f = false;
320  __set_variable(arg.substr(0, i), arg.substr(i+1));
321  __request_recording_f = tmp;
322  break;
323  }
324  }
325 }
326 
327 
329 GetPot::__read_in_file(const std::string& FileName)
330 {
331  std::ifstream i(FileName.c_str());
332  if( ! i ) {
333  throw std::runtime_error(GETPOT_STR_FILE_NOT_FOUND(FileName));
334  return STRING_VECTOR();
335  }
336  // argv[0] == the filename of the file that was read in
337  return __read_in_stream(i);
338 }
339 
341 GetPot::__read_in_stream(std::istream& istr)
342 {
343  STRING_VECTOR brute_tokens;
344  while(istr) {
345  __skip_whitespace(istr);
346  const std::string Token = __get_next_token(istr);
347  if( Token.length() == 0 || Token[0] == EOF) break;
348  brute_tokens.push_back(Token);
349  }
350 
351  // -- reduce expressions of token1'='token2 to a single
352  // string 'token1=token2'
353  // -- copy everything into 'argv'
354  // -- arguments preceded by something like '[' name ']' (section)
355  // produce a second copy of each argument with a prefix '[name]argument'
356  unsigned i1 = 0;
357  unsigned i2 = 1;
358  unsigned i3 = 2;
359 
360  STRING_VECTOR arglist;
361  while( i1 < brute_tokens.size() ) {
362  const std::string& SRef = brute_tokens[i1];
363  // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef'
364  // note: java.lang.String: substring(a,b) = from a to b-1
365  // C++ string: substr(a,b) = from a to a + b
366  if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) {
367  if( i3 >= brute_tokens.size() )
368  arglist.push_back(brute_tokens[i1] + brute_tokens[i2]);
369  else
370  arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]);
371  i1 = i3+1; i2 = i3+2; i3 = i3+3;
372  continue;
373  }
374  else {
375  arglist.push_back(SRef);
376  i1=i2; i2=i3; i3++;
377  }
378  }
379  return arglist;
380 }
381 
382 __GETPOT_INLINE void
383 GetPot::__skip_whitespace(std::istream& istr)
384  // find next non-whitespace while deleting comments
385 {
386  int tmp = istr.get();
387  do {
388  // -- search a non whitespace
389  while( isspace(tmp) ) {
390  tmp = istr.get();
391  if( ! istr ) return;
392  }
393 
394  // -- look if characters match the comment starter string
395  unsigned i=0;
396  for(; i<_comment_start.length() ; ++i) {
397  if( tmp != _comment_start[i] ) {
398  // NOTE: Due to a 'strange behavior' in Microsoft's streaming lib we do
399  // a series of unget()s instead a quick seek. See
400  // http://sourceforge.net/tracker/index.php?func=detail&aid=1545239&group_id=31994&atid=403915
401  // for a detailed discussion.
402 
403  // -- one step more backwards, since 'tmp' already at non-whitespace
404  do istr.unget(); while( i-- != 0 );
405  return;
406  }
407  tmp = istr.get();
408  if( ! istr ) { istr.unget(); return; }
409  }
410  // 'tmp' contains last character of _comment_starter
411 
412  // -- comment starter found -> search for comment ender
413  unsigned match_no=0;
414  while(1+1 == 2) {
415  tmp = istr.get();
416  if( ! istr ) { istr.unget(); return; }
417 
418  if( tmp == _comment_end[match_no] ) {
419  match_no++;
420  if( match_no == _comment_end.length() ) {
421  istr.unget();
422  break; // shuffle more whitespace, end of comment found
423  }
424  }
425  else
426  match_no = 0;
427  }
428 
429  tmp = istr.get();
430 
431  } while( istr );
432  istr.unget();
433 }
434 
435 __GETPOT_INLINE const std::string
436 GetPot::__get_next_token(std::istream& istr)
437  // get next concatinates string token. consider quotes that embrace
438  // whitespaces
439 {
440  std::string token;
441  int tmp = 0;
442  int last_letter = 0;
443  while(1+1 == 2) {
444  last_letter = tmp; tmp = istr.get();
445  if( tmp == EOF
446  || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) {
447  return token;
448  }
449  else if( tmp == '\'' && last_letter != '\\' ) {
450  // QUOTES: un-backslashed quotes => it's a string
451  token += __get_string(istr);
452  continue;
453  }
454  else if( tmp == '{' && last_letter == '$') {
455  token += '{' + __get_until_closing_bracket(istr);
456  continue;
457  }
458  else if( tmp == '$' && last_letter == '\\') {
459  token += tmp; tmp = 0; // so that last_letter will become = 0, not '$';
460  continue;
461  }
462  else if( tmp == '\\' && last_letter != '\\')
463  continue; // don't append un-backslashed backslashes
464  token += tmp;
465  }
466 }
467 
468 __GETPOT_INLINE const std::string
469 GetPot::__get_string(std::istream& istr)
470  // parse input until next matching '
471 {
472  std::string str;
473  int tmp = 0;
474  int last_letter = 0;
475  while(1 + 1 == 2) {
476  last_letter = tmp; tmp = istr.get();
477  if( tmp == EOF) return str;
478  // un-backslashed quotes => it's the end of the string
479  else if( tmp == '\'' && last_letter != '\\') return str;
480  else if( tmp == '\\' && last_letter != '\\') continue; // don't append
481 
482  str += tmp;
483  }
484 }
485 
486 __GETPOT_INLINE const std::string
488  // parse input until next matching }
489 {
490  std::string str = "";
491  int tmp = 0;
492  int last_letter = 0;
493  int brackets = 1;
494  while(1 + 1 == 2) {
495  last_letter = tmp; tmp = istr.get();
496  if( tmp == EOF) return str;
497  else if( tmp == '{' && last_letter == '$') brackets += 1;
498  else if( tmp == '}') {
499  brackets -= 1;
500  // un-backslashed brackets => it's the end of the string
501  if( brackets == 0) return str + '}';
502  else if( tmp == '\\' && last_letter != '\\')
503  continue; // do not append an unbackslashed backslash
504  }
505  str += tmp;
506  }
507 }
508 
509 __GETPOT_INLINE std::string
510 GetPot::__process_section_label(const std::string& Section,
511  STRING_VECTOR& section_stack)
512 {
513  std::string sname = Section;
514  // 1) subsection of actual section ('./' prefix)
515  if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) {
516  sname = sname.substr(2);
517  }
518  // 2) subsection of parent section ('../' prefix)
519  else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) {
520  do {
521  if( section_stack.end() != section_stack.begin() )
522  section_stack.pop_back();
523  sname = sname.substr(3);
524  } while( sname.substr(0, 3) == "../" );
525  }
526  // 3) subsection of the root-section
527  else {
528  section_stack.erase(section_stack.begin(), section_stack.end());
529  // [] => back to root section
530  }
531 
532  if( sname != "" ) {
533  // parse section name for 'slashes'
534  size_t i = 0;
535  size_t prev_slash_i = -1; // points to last slash
536  const size_t L = sname.length();
537 
538  for(i = 0; i < L; ++i) {
539  if( sname[i] != '/' ) continue;
540  if( i - prev_slash_i > 1 ) {
541  const size_t Delta = i - (prev_slash_i + 1);
542  section_stack.push_back(sname.substr(prev_slash_i + 1, Delta));
543  }
544 
545  prev_slash_i = i;
546  }
547  if( i - prev_slash_i > 1 ) {
548  const size_t Delta = i - (prev_slash_i + 1);
549  section_stack.push_back(sname.substr(prev_slash_i + 1, Delta));
550  }
551  }
552  std::string section = "";
553  if( section_stack.size() != 0 ) {
554  victorate(std::string, section_stack, it) {
555  section += *it + "/";
556  }
557  }
558  return section;
559 }
560 
561 // convert string to BOOL, if not possible return Default
562 template <> __GETPOT_INLINE bool
563 GetPot::__convert_to_type<bool>(const std::string& String, bool Default,
564  bool ThrowExceptionF /* = GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT */) const
565 {
566  // No 'lower' or 'upper' unification. If someone wants that, he
567  // han specify the true-string or fals-strings as he likes.
568 
569  victorate(std::string, true_string_list, it1) {
570  if( String == *it1 ) return true;
571  }
572 
573  victorate(std::string, false_string_list, it2) {
574  if( String == *it2 ) return false;
575  }
576 
577  if( ThrowExceptionF ) {
578  throw std::runtime_error(std::string(GETPOT_STR_FILE) + " \"" + filename + "\": " +
580  }
581  else
582  return Default;
583 }
584 
585 // convert string to DOUBLE, if not possible return Default
586 template <> __GETPOT_INLINE double
587 GetPot::__convert_to_type<double>(const std::string& String, double Default,
588  bool ThrowExceptionF /* = GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT */) const
589 {
590  double tmp;
591 
592  if( sscanf(String.c_str(),"%lf", &tmp) == 1 ) return tmp;
593 
594  if( ThrowExceptionF )
595  throw std::runtime_error(std::string(GETPOT_STR_FILE) + " \"" + filename + "\": " +
597  else
598  return Default;
599 }
600 
601 // convert string to INT, if not possible return Default
602 template <> __GETPOT_INLINE int
603 GetPot::__convert_to_type<int>(const std::string& String, int Default,
604  bool ThrowExceptionF /* = GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT */) const
605 {
606  // NOTE: intermediate results may be floating points, so that the string
607  // may look like 2.0e1 (i.e. float format) => use float conversion
608  // in any case.
609  return (int)__convert_to_type(String, (double)Default, ThrowExceptionF);
610 }
611 
612 // convert string to string, so that GetPot::read method can be generic (template).
613 template <> __GETPOT_INLINE const char*
614 GetPot::__convert_to_type<const char*>(const std::string& String, const char* Default,
615  bool ThrowExceptionF /* = GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT */) const
616 {
617  return __get_const_char(String);
618 }
619 
620 __GETPOT_INLINE const char*
621 GetPot::__get_const_char(const std::string& String) const
622 {
623  std::vector<char>* c_str_copy = new std::vector<char>(String.length() + 1, '\0');
624  std::copy(String.begin(), String.end(), c_str_copy->begin());
625 
626  ((GetPot*)this)->__internal_string_container.push_back(c_str_copy);
627  return &(*c_str_copy)[0];
628 }
629 
631 // (*) cursor oriented functions
632 //.............................................................................
633 __GETPOT_INLINE const std::string
634 GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const
635  // Checks if 'String' begins with 'Start' and returns the remaining String.
636  // Returns None if String does not begin with Start.
637 {
638  if( Start == "" ) return String;
639  // note: java.lang.String: substring(a,b) = from a to b-1
640  // C++ string: substr(a,b) = from a to a + b
641  if( String.find(Start) == 0 ) return String.substr(Start.length());
642  else return "";
643 }
644 
645 // -- search for a certain argument and set cursor to position
646 __GETPOT_INLINE bool
647 GetPot::search(const char* Option)
648 {
649  unsigned OldCursor = cursor;
650  std::string search_term;
651 
652  if( ! Option ) return false;
653 
654  search_term = prefix + Option;
655 
656  // (*) record requested arguments for later ufo detection
657  __record_argument_request(search_term);
658 
659  if( OldCursor >= argv.size() ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
660  search_failed_f = true;
661 
662  // (*) first loop from cursor position until end
663  unsigned c = cursor;
664  for(; c < argv.size(); c++) {
665  if( argv[c] == search_term )
666  { cursor = c; search_failed_f = false; return true; }
667  }
668  if( ! search_loop_f ) return false;
669 
670  // (*) second loop from 0 to old cursor position
671  for(c = 1; c < OldCursor; c++) {
672  if( argv[c] == search_term )
673  { cursor = c; search_failed_f = false; return true; }
674  }
675  // in case nothing is found the cursor stays where it was
676  return false;
677 }
678 
679 
680 __GETPOT_INLINE bool
681 GetPot::search(unsigned No, const char* P, ...)
682 {
683  // (*) recording the requested arguments happens in subroutine 'search'
684  if( No == 0 ) return false;
685 
686  // search for the first argument
687  if( search(P) == true ) return true;
688 
689  // start interpreting variable argument list
690  va_list ap;
691  va_start(ap, P);
692  unsigned i = 1;
693  for(; i < No; ++i) {
694  char* Opt = va_arg(ap, char *);
695  if( search(Opt) == true ) break;
696  }
697 
698  if( i < No ) {
699  ++i;
700  // loop was left before end of array --> hit but
701  // make sure that the rest of the search terms is marked
702  // as requested.
703  for(; i < No; ++i) {
704  char* Opt = va_arg(ap, char *);
705  // (*) record requested arguments for later ufo detection
707  }
708  va_end(ap);
709  return true;
710  }
711 
712  va_end(ap);
713  // loop was left normally --> no hit
714  return false;
715 }
716 
717 __GETPOT_INLINE void
719 { search_failed_f = false; cursor = 0; }
720 
721 __GETPOT_INLINE void
723 { disable_loop(); reset_cursor(); }
724 
725 __GETPOT_INLINE void
726 GetPot::set_true_string_list(unsigned N, const char* StringForTrue, ...)
727 {
728  true_string_list.clear();
729 
730  if( N == 0 ) return;
731 
732  va_list ap;
733  unsigned i = 1;
734 
735  va_start(ap, StringForTrue);
736  for(; i < N ; ++i) {
737  char* Opt = va_arg(ap, char *);
738  true_string_list.push_back(std::string(Opt));
739  }
740  va_end(ap);
741 }
742 
743 __GETPOT_INLINE void
744 GetPot::set_false_string_list(unsigned N, const char* StringForFalse, ...)
745 {
746  false_string_list.clear();
747 
748  if( N == 0 ) return;
749 
750  va_list ap;
751  unsigned i = 1;
752 
753  va_start(ap, StringForFalse);
754  for(; i < N ; ++i) {
755  char* Opt = va_arg(ap, char *);
756  false_string_list.push_back(std::string(Opt));
757  }
758  va_end(ap);
759 }
760 
762 // (*) direct access to command line arguments
763 //
764 __GETPOT_INLINE const std::string
765 GetPot::operator[](unsigned idx) const
766 { return idx < argv.size() ? argv[idx] : ""; }
767 
768 template <class T> __GETPOT_INLINE T
769 GetPot::get(unsigned Idx, T Default) const
770 {
771  if( Idx >= argv.size() ) return Default;
772  return __convert_to_type(argv[Idx], (typename TypeInfo<T>::type)Default);
773 }
774 
775 template <> __GETPOT_INLINE const char*
776 GetPot::get<const char*>(unsigned Idx, const char* Default) const
777 {
778  if( Idx >= argv.size() ) return Default;
779  else return __get_const_char(argv[Idx]);
780 }
781 
782 template <class T> __GETPOT_INLINE T
784 {
785  return get<T>(VarName, (const char*)0x0);
786 }
787 
788 template <class T> __GETPOT_INLINE T
789 GetPot::get(const StringOrCharP VarName, const char* Constraint)
790 {
791  return __get<T>(VarName, Constraint, /* ThrowExceptionF = */true);
792 }
793 
794 template <class T> __GETPOT_INLINE T
795 GetPot::get(const StringOrCharP VarName, const char* Constraint, T Default)
796 {
797  return __get<T>(VarName, Constraint, Default, /* ThrowExceptionF = */GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT);
798 }
799 
800 __GETPOT_INLINE unsigned
802 { return static_cast<unsigned int>(argv.size()); }
803 
804 
805 // -- next() function group
806 template <class T> __GETPOT_INLINE T
807 GetPot::next(T Default)
808 {
809  if( search_failed_f ) return Default;
810  cursor++;
811  if( cursor >= argv.size() )
812  { cursor = static_cast<unsigned int>(argv.size()); return Default; }
813 
814  // (*) record requested argument for later ufo detection
816 
817  const std::string Remain = __get_remaining_string(argv[cursor], prefix);
818 
819  return Remain != "" ? __convert_to_type(Remain, (typename TypeInfo<T>::type)Default) : Default;
820 }
821 
822 // -- follow() function group
823 // distinct option to be searched for
824 template <class T> __GETPOT_INLINE T
825 GetPot::follow(T Default, const char* Option)
826 {
827  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
828  if( search(Option) == false ) return Default;
829  return next(Default);
830 }
831 
832 
833 // -- second follow() function group
834 // multiple option to be searched for
835 template <class T> __GETPOT_INLINE T
836 GetPot::follow(T Default, unsigned No, const char* P, ...)
837 {
838  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
839  if( No == 0 ) return Default;
840  if( search(P) == true ) return next(Default);
841 
842  va_list ap;
843  va_start(ap, P);
844  unsigned i=1;
845  for(; i<No; ++i) {
846  char* Opt = va_arg(ap, char *);
847  if( search(Opt) == true ) {
848  va_end(ap);
849  return next(Default);
850  }
851  }
852  va_end(ap);
853  return Default;
854 }
855 
857 // (*) directly connected options
858 //.............................................................................
859 //
860 template <class T> __GETPOT_INLINE T
861 GetPot::direct_follow(T Default, const char* Option)
862 {
863  const char* FollowStr = __match_starting_string(Option);
864  if( FollowStr == 0x0 ) return Default;
865 
866  // (*) record requested of argument for later ufo-detection
867  __record_argument_request(std::string(Option) + FollowStr);
868 
869  if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
870  return __convert_to_type(FollowStr, (typename TypeInfo<T>::type)Default);
871 }
872 
873 __GETPOT_INLINE std::vector<std::string>
874 GetPot::string_tails(const char* StartString)
875 {
876  std::vector<std::string> result;
877  const unsigned N = static_cast<unsigned int>(strlen(StartString));
878 
879  std::vector<std::string>::iterator it = argv.begin();
880 
881  unsigned idx = 0;
882  while( it != argv.end() ) {
883  // (*) does start string match the given option?
884  // NO -> goto next option
885  if( (*it).compare(0, N, StartString) != 0 ) { ++it; ++idx; continue; }
886 
887  // append the found tail to the result vector
888  result.push_back((*it).substr(N));
889 
890  // adapt the nominus vector
891  std::vector<unsigned>::iterator nit = idx_nominus.begin();
892  for(; nit != idx_nominus.end(); ++nit) {
893  if( *nit == idx ) {
894  idx_nominus.erase(nit);
895  for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
896  break;
897  }
898  }
899 
900  // erase the found option
901  argv.erase(it);
902 
903  // 100% safe solution: set iterator back to the beginning.
904  // (normally, 'it--' would be enough, but who knows how the
905  // iterator is implemented and .erase() definitely invalidates
906  // the current iterator position.
907  if( argv.empty() ) break;
908  it = argv.begin();
909  }
910  cursor = 0;
911  nominus_cursor = -1;
912  return result;
913 }
914 
915 __GETPOT_INLINE std::vector<int>
916 GetPot::int_tails(const char* StartString, const int Default /* = -1 */)
917 {
918  std::vector<int> result;
919  const unsigned N = static_cast<unsigned int>(strlen(StartString));
920 
921  std::vector<std::string>::iterator it = argv.begin();
922 
923  unsigned idx = 0;
924  while( it != argv.end() ) {
925  // (*) does start string match the given option?
926  // NO -> goto next option
927  if( (*it).compare(0, N, StartString) != 0 ) { ++it; ++idx; continue; }
928 
929  // append the found tail to the result vector
930  result.push_back(__convert_to_type((*it).substr(N), Default));
931 
932  // adapt the nominus vector
933  std::vector<unsigned>::iterator nit = idx_nominus.begin();
934  for(; nit != idx_nominus.end(); ++nit) {
935  if( *nit == idx ) {
936  idx_nominus.erase(nit);
937  for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
938  break;
939  }
940  }
941 
942  // erase the found option
943  argv.erase(it);
944 
945  // 100% safe solution: set iterator back to the beginning.
946  // (normally, 'it--' would be enough, but who knows how the
947  // iterator is implemented and .erase() definitely invalidates
948  // the current iterator position.
949  if( argv.empty() ) break;
950  it = argv.begin();
951  }
952  cursor = 0;
953  nominus_cursor = -1;
954  return result;
955 }
956 
957 __GETPOT_INLINE std::vector<double>
958 GetPot::double_tails(const char* StartString,
959  const double Default /* = -1.0 */)
960 {
961  std::vector<double> result;
962  const unsigned N = static_cast<unsigned int>(strlen(StartString));
963 
964  std::vector<std::string>::iterator it = argv.begin();
965  unsigned idx = 0;
966  while( it != argv.end() ) {
967  // (*) does start string match the given option?
968  // NO -> goto next option
969  if( (*it).compare(0, N, StartString) != 0 ) { ++it; ++idx; continue; }
970 
971  // append the found tail to the result vector
972  result.push_back(__convert_to_type((*it).substr(N), Default));
973 
974  // adapt the nominus vector
975  std::vector<unsigned>::iterator nit = idx_nominus.begin();
976  for(; nit != idx_nominus.end(); ++nit) {
977  if( *nit == idx ) {
978  idx_nominus.erase(nit);
979  for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
980  break;
981  }
982  }
983 
984  // erase the found option
985  argv.erase(it);
986 
987  // 100% safe solution: set iterator back to the beginning.
988  // (normally, 'it--' would be enough, but who knows how the
989  // iterator is implemented and .erase() definitely invalidates
990  // the current iterator position.
991  if( argv.empty() ) break;
992  it = argv.begin();
993  }
994  cursor = 0;
995  nominus_cursor = -1;
996  return result;
997 }
998 
1000 // (*) lists of nominus following an option
1001 //
1002 __GETPOT_INLINE std::vector<std::string>
1003 GetPot::nominus_followers(const char* Option)
1004 {
1005  std::vector<std::string> result_list;
1006  if( search(Option) == false ) return result_list;
1007  while( 1 + 1 == 2 ) {
1008  ++cursor;
1009  if( cursor >= argv.size() ) {
1010  cursor = argv.size() - 1;
1011  return result_list;
1012  }
1013  if( argv[cursor].length() >= 1 ) {
1014  if( argv[cursor][0] == '-' ) {
1015  return result_list;
1016  }
1017  // -- record for later ufo-detection
1019  // -- append to the result list
1020  result_list.push_back(argv[cursor]);
1021  }
1022  }
1023 }
1024 
1025 __GETPOT_INLINE std::vector<std::string>
1026 GetPot::nominus_followers(unsigned No, ...)
1027 {
1028  std::vector<std::string> result_list;
1029  // (*) record requested of argument is entirely handled in 'search()'
1030  // and 'nominus_followers()'
1031  if( No == 0 ) return result_list;
1032 
1033  va_list ap;
1034  va_start(ap, No);
1035  for(unsigned i=0; i<No; ++i) {
1036  char* Option = va_arg(ap, char *);
1037  std::vector<std::string> tmp = nominus_followers(Option);
1038  result_list.insert(result_list.end(), tmp.begin(), tmp.end());
1039 
1040  // std::cerr << "option = '" << Option << "'" << std::endl;
1041  // std::cerr << "length = " << tmp.size() << std::endl;
1042  // std::cerr << "new result list = <";
1043  // for(std::vector<std::string>::const_iterator it = result_list.begin();
1044  // it != result_list.end(); ++it)
1045  // std::cerr << *it << ", ";
1046  // std::cerr << ">\n";
1047  }
1048  va_end(ap);
1049  return result_list;
1050 }
1051 
1052 
1053 __GETPOT_INLINE const char*
1054 GetPot::__match_starting_string(const char* StartString)
1055  // pointer to the place where the string after
1056  // the match inside the found argument starts.
1057  // 0 no argument matches the starting string.
1058 {
1059  const unsigned N = static_cast<unsigned int>(strlen(StartString));
1060  unsigned OldCursor = cursor;
1061  // const char* tmp = (const char*)0;
1062 
1063  if( OldCursor >= static_cast<unsigned int>(argv.size()) ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
1064  search_failed_f = true;
1065 
1066  // (*) first loop from cursor position until end
1067  unsigned c = cursor;
1068  for(; c < argv.size(); c++) {
1069  if( argv[c].compare(0, N, StartString) == 0 ) {
1070  cursor = c;
1071  search_failed_f = false;
1072  return __get_const_char(argv[c].substr(N));
1073  }
1074  }
1075 
1076  if( ! search_loop_f ) return (const char*)0;
1077 
1078  // (*) second loop from 0 to old cursor position
1079  for(c = 1; c < OldCursor; c++) {
1080  if( argv[c].compare(0, N, StartString) == 0 ) {
1081  cursor = c;
1082  search_failed_f = false;
1083  return __get_const_char(argv[c].substr(N));
1084  }
1085  }
1086  return 0;
1087 }
1088 
1090 // (*) search for flags
1091 //.............................................................................
1092 //
1093 __GETPOT_INLINE bool
1094 GetPot::options_contain(const char* FlagList) const
1095 {
1096  // go through all arguments that start with a '-' (but not '--')
1097  std::string str;
1098  STRING_VECTOR::const_iterator it = argv.begin();
1099  for(; it != argv.end(); ++it) {
1100  str = __get_remaining_string(*it, prefix);
1101 
1102  if( str.length() >= 2 && str[0] == '-' && str[1] != '-' )
1103  if( __check_flags(str, FlagList) ) return true;
1104  }
1105  return false;
1106 }
1107 
1108 __GETPOT_INLINE bool
1109 GetPot::argument_contains(unsigned Idx, const char* FlagList) const
1110 {
1111  if( Idx >= argv.size() ) return false;
1112 
1113  // (*) record requested of argument for later ufo-detection
1114  // an argument that is checked for flags is considered to be 'requested'
1115  ((GetPot*)this)->__record_argument_request(argv[Idx]);
1116 
1117  if( prefix == "" )
1118  // search argument for any flag in flag list
1119  return __check_flags(argv[Idx], FlagList);
1120 
1121  // if a prefix is set, then the argument index is the index
1122  // inside the 'namespace'
1123  // => only check list of arguments that start with prefix
1124  unsigned no_matches = 0;
1125  unsigned i=0;
1126  for(; i<argv.size(); ++i) {
1127  const std::string Remain = __get_remaining_string(argv[i], prefix);
1128  if( Remain != "") {
1129  no_matches += 1;
1130  if( no_matches == Idx)
1131  return __check_flags(Remain, FlagList);
1132  }
1133  }
1134  // no argument in this namespace
1135  return false;
1136 }
1137 
1138 __GETPOT_INLINE bool
1139 GetPot::__check_flags(const std::string& Str, const char* FlagList) const
1140 {
1141  const char* p=FlagList;
1142  for(; *p != '\0' ; p++)
1143  if( Str.find(*p) != std::string::npos ) return true; // found something
1144  return false;
1145 }
1146 
1148 // (*) nominus arguments
1151  // return vector of nominus arguments
1152 {
1153  STRING_VECTOR nv;
1154  std::vector<unsigned>::const_iterator it = idx_nominus.begin();
1155  for(; it != idx_nominus.end(); ++it) {
1156  nv.push_back(argv[*it]);
1157 
1158  // (*) record for later ufo-detection
1159  // when a nominus vector is requested, the entire set of nominus arguments are
1160  // tagged as 'requested'
1161  ((GetPot*)this)->__record_argument_request(argv[*it]);
1162  }
1163  return nv;
1164 }
1165 
1166 __GETPOT_INLINE std::string
1168 {
1169  if( nominus_cursor < int(idx_nominus.size()) - 1 ) {
1170  const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
1172  return Tmp;
1173  }
1174  return std::string("");
1175 }
1176 
1178 // (*) variables
1179 //.............................................................................
1180 //
1181 template <class T> __GETPOT_INLINE T
1182 GetPot::__get(const StringOrCharP VarName, const char* Constraint, bool ThrowExceptionF) const
1183 {
1184  T Default = TypeInfo<T>::default_value();
1185 
1186  const variable* sv = __find_variable(VarName.content, TypeInfo<T>::name(), ThrowExceptionF);
1187 
1188  if( sv == 0x0 )
1189  return Default;
1190 
1191  if( Constraint != 0x0 && ! __constraint_check(sv->original, Constraint, ThrowExceptionF) )
1192  return Default;
1193 
1194  return __convert_to_type<typename TypeInfo<T>::type>(sv->original, TypeInfo<T>::convert(Default), ThrowExceptionF);
1195 }
1196 
1197 template <class T> __GETPOT_INLINE T
1198 GetPot::__get(const StringOrCharP VarName, const char* Constraint, T Default, bool ThrowExceptionF) const
1199 {
1200  const variable* sv = __find_variable(VarName.content, TypeInfo<T>::name(), false);
1201 
1202  if( sv == 0x0 )
1203  return Default;
1204 
1205  if( Constraint != 0x0 && ! __constraint_check(sv->original, Constraint, ThrowExceptionF) )
1206  return Default;
1207 
1208  return __convert_to_type<typename TypeInfo<T>::type>(sv->original, TypeInfo<T>::convert(Default), ThrowExceptionF);
1209 }
1210 
1211 template <class T> __GETPOT_INLINE T
1212 GetPot::__get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint,
1213  bool ThrowExceptionF) const
1214 {
1215  T Default = TypeInfo<T>::default_value();
1216 
1217  const variable* sv = __find_variable(VarName.content, TypeInfo<T>::name(), ThrowExceptionF);
1218 
1219  if( sv == 0 )
1220  return Default;
1221 
1222  const std::string* element = sv->get_element(Idx, ThrowExceptionF);
1223 
1224  if( element == 0 )
1225  return Default;
1226 
1227  if( Constraint != 0x0 && ! __constraint_check(*element, Constraint, ThrowExceptionF) )
1228  return Default;
1229 
1230  return __convert_to_type<typename TypeInfo<T>::type>(*element, TypeInfo<T>::convert(Default), ThrowExceptionF);
1231 }
1232 
1233 template <class T> __GETPOT_INLINE T
1234 GetPot::__get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint,
1235  T Default, bool ThrowExceptionF) const
1236 {
1237  const variable* sv = __find_variable(VarName.content, TypeInfo<T>::name(), false);
1238 
1239  if( sv == 0 )
1240  return Default;
1241 
1242  const std::string* element = sv->get_element(Idx, ThrowExceptionF);
1243 
1244  if( element == 0 )
1245  return Default;
1246 
1247  else if( Constraint != 0x0 && ! __constraint_check(*element, Constraint, ThrowExceptionF) )
1248  return Default;
1249 
1250  return __convert_to_type<typename TypeInfo<T>::type>(*element, TypeInfo<T>::convert(Default), ThrowExceptionF);
1251 }
1252 
1253 template<class T> __GETPOT_INLINE T
1254 GetPot::operator()(const StringOrCharP VarName, T Default) const
1255 { return __get<T>(VarName, (const char*)0x0, Default, /* ThrowExceptionF = */GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT); }
1256 
1257 template <class T> __GETPOT_INLINE T
1258 GetPot::get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint)
1259 { return __get_element<T>(VarName, Idx, Constraint, /* ThrowExceptionF = */true); }
1260 
1261 template <class T> __GETPOT_INLINE T
1262 GetPot::get_element(const StringOrCharP VarName, unsigned Idx, const char* Constraint, T Default)
1263 { return __get_element<T>(VarName, Idx, Constraint, Default, /* ThrowExceptionF = */GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT); }
1264 
1265 template <class T> __GETPOT_INLINE T
1266 GetPot::operator()(const StringOrCharP VarName, unsigned Idx, T Default) const
1267 { return __get_element<T>(VarName, Idx, (const char*)0x0, Default, /* ThrowExceptionF = */GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT); }
1268 
1269 
1270 __GETPOT_INLINE void
1271 GetPot::__record_argument_request(const std::string& Name)
1272 {
1273  if( ! __request_recording_f ) return;
1274 
1275  // (*) record requested variable for later ufo detection
1276  _requested_arguments.push_back(Name);
1277 
1278  // (*) record considered section for ufo detection
1279  STRING_VECTOR STree = __get_section_tree(Name);
1280  victorate(std::string, STree, it) {
1281  if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) {
1282  if( section.length() != 0 ) _requested_sections.push_back(*it);
1283  }
1284  }
1285 }
1286 
1287 __GETPOT_INLINE void
1288 GetPot::__record_variable_request(const std::string& Name)
1289 {
1290  if( ! __request_recording_f ) return;
1291 
1292  // (*) record requested variable for later ufo detection
1293  _requested_variables.push_back(Name);
1294 
1295  // (*) record considered section for ufo detection
1296  STRING_VECTOR STree = __get_section_tree(Name);
1297  victorate(std::string, STree, it) {
1298  if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
1299  if( section.length() != 0 ) _requested_sections.push_back(*it);
1300  }
1301 }
1302 
1303 // To build a GetPot instance
1304 
1305 __GETPOT_INLINE void
1306 GetPot::__build(const std::string& FileName,
1307  const std::string& CommentStart, const std::string& CommentEnd,
1308  const std::string& FieldSeparator)
1309 {
1310  filename = FileName;
1312 
1313  // if specified -> overwrite default strings
1314  if( CommentStart.length() != 0 ) _comment_start = std::string(CommentStart);
1315  if( CommentEnd.length() != 0 ) _comment_end = std::string(CommentEnd);
1316  if( FieldSeparator.length() != 0 ) _field_separator = FieldSeparator;
1317 
1318  STRING_VECTOR _apriori_argv;
1319  // -- file name is element of argument vector, however, it is not parsed for
1320  // variable assignments or nominuses.
1321  _apriori_argv.push_back(std::string(FileName));
1322 
1323  STRING_VECTOR args = __read_in_file(FileName);
1324  _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end());
1325  __parse_argument_vector(_apriori_argv);
1326 }
1327 
1328 // to split a string according to delimiters and elements are stored in a vector.
1330 void GetPot::__split(std::string str, std::vector<std::string>& vect,
1331  std::string delimiters /*= " \n\t"*/)
1332 {
1333  vect.clear();
1334 
1335  std::string tmp;
1336  std::string::size_type index_beg, index_end;
1337 
1338  index_beg = str.find_first_not_of(delimiters);
1339 
1340  while (index_beg != std::string::npos) {
1341  index_end = str.find_first_of(delimiters, index_beg);
1342  tmp = str.substr(index_beg, index_end == std::string::npos ?
1343  std::string::npos : (index_end - index_beg));
1344  vect.push_back(tmp);
1345  index_beg = str.find_first_not_of(delimiters, index_end);
1346  }
1347 }
1348 
1349 // (*) following functions are to be used from 'outside', after getpot has parsed its
1350 // arguments => append an argument in the argument vector that reflects the addition
1351 __GETPOT_INLINE void
1352 GetPot::__set_variable(const std::string& VarName, const std::string& Value)
1353 {
1354  const GetPot::variable* Var;
1355  const std::string EmptyString("");
1356 
1357  if ( !built )
1358  Var = __find_variable(VarName, EmptyString, false);
1359  else
1360  Var = __find_variable(VarName, EmptyString);
1361 
1362  if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator));
1363  else ((GetPot::variable*)Var)->take(Value, _field_separator);
1364 }
1365 
1366 template <>__GETPOT_INLINE void
1367 GetPot::set_variable<const char*>(const StringOrCharP VarName, const char* Value, const bool Requested /* = true*/)
1368 {
1369  const std::string Arg = prefix + VarName.content + std::string("=") + std::string(Value);
1370  argv.push_back(Arg);
1371  __set_variable(VarName.content, Value);
1372 
1373  // if user does not specify the variable as 'not being requested' it will be
1374  // considered amongst the requested variables
1375  if( Requested ) __record_variable_request(Arg);
1376 }
1377 
1378 template <> __GETPOT_INLINE void
1379 GetPot::set_variable<double>(const StringOrCharP VarName, double Value, const bool Requested /* = true*/)
1380 { __set_variable(VarName.content, __double2string(Value)); }
1381 
1382 template <> __GETPOT_INLINE void
1383 GetPot::set_variable<int>(const StringOrCharP VarName, int Value, const bool Requested /* = true*/)
1384 { __set_variable(VarName.content, __int2string(Value)); }
1385 
1386 template <> __GETPOT_INLINE void
1387 GetPot::set_variable<bool>(const StringOrCharP VarName, bool Value, const bool Requested /* = true*/)
1388 {
1389  if( true_string_list.size() == 0 || false_string_list.size() == 0 ) {
1390  throw std::runtime_error(GETPOT_STR_TRUE_FALSE_UNDEFINED);
1391  }
1392  __set_variable(VarName.content,
1393  Value ? true_string_list[0] : false_string_list[0]);
1394 }
1395 
1396 template <class T>
1397 __GETPOT_INLINE void
1398 GetPot::set(const StringOrCharP VarName, T& Value)
1399 {
1400  Value = get<T>(VarName);
1401 }
1402 
1403 template <class T>
1404 __GETPOT_INLINE void
1405 GetPot::set(const StringOrCharP VarName, T& Value, const char* Constraint)
1406 {
1407  Value = get<T>(VarName, Constraint);
1408 }
1409 
1410 template <class T, class U>
1411 __GETPOT_INLINE void
1412 GetPot::set(const StringOrCharP VarName, T& Value, const char* Constraint, U Default)
1413 {
1414  Value = get<U>(VarName, Constraint, Default);
1415 }
1416 
1417 __GETPOT_INLINE unsigned
1419 {
1420  const std::string EmptyString("");
1421 
1422  const variable* sv = __find_variable(VarName.content, EmptyString);
1423  if( sv == 0 ) return 0;
1424  return static_cast<unsigned int>(sv->value.size());
1425 }
1426 
1429 {
1430  STRING_VECTOR result;
1431  std::vector<GetPot::variable>::const_iterator it = variables.begin();
1432  for(; it != variables.end(); ++it) {
1433  const std::string Tmp = __get_remaining_string((*it).name, prefix);
1434  if( Tmp != "" ) result.push_back(Tmp);
1435  }
1436  return result;
1437 }
1438 
1441 { return section_list; }
1442 
1444 GetPot::__find_variable(const std::string& VarName, const std::string& TypeName,
1445  bool ThrowExceptionF/*=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT*/) const
1446 {
1447  const std::string Name = prefix + VarName;
1448 
1449  // (*) record requested variable for later ufo detection
1450  ((GetPot*)this)->__record_variable_request(Name);
1451 
1452  /* Linear search (?)... maybe we can do something better ... */
1453  std::vector<variable>::const_iterator it = variables.begin();
1454  for(; it != variables.end(); ++it) {
1455  if( (*it).name == Name ) return &(*it);
1456  }
1457 
1458  if( ThrowExceptionF ) {
1459  std::string msg(GETPOT_STR_FILE " ");
1460  msg += std::string("\"") + filename + "\": ";
1461  msg += std::string(GETPOT_STR_MISSING_VARIABLE) + " \'";
1462  msg += VarName + "\' ";
1463  if( TypeName.length() != 0 ) msg += std::string(GETPOT_STR_WITH_TYPE " ") + TypeName;
1464  if( ! prefix.empty() ) msg += std::string(" " GETPOT_STR_IN_SECTION " \"") + prefix + "\"";
1465  msg += ".";
1466  throw std::runtime_error(msg);
1467  }
1468  else {
1469  return 0x0;
1470  }
1471 }
1472 
1474 // (*) ouput (basically for debugging reasons
1475 //.............................................................................
1476 //
1477 __GETPOT_INLINE int
1479 {
1480  std::cout << "argc = " << static_cast<unsigned int>(argv.size()) << std::endl;
1481  STRING_VECTOR::const_iterator it = argv.begin();
1482  for(; it != argv.end(); ++it)
1483  std::cout << *it << std::endl;
1484  std::cout << std::endl;
1485  return 1;
1486 }
1487 
1488 // (*) dollar bracket expressions (DBEs) ------------------------------------
1489 //
1490 // 1) Entry Function: __DBE_expand_string()
1491 // Takes a string such as
1492 //
1493 // "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}"
1494 //
1495 // calls __DBE_expand() for each of the expressions
1496 //
1497 // ${+ ${x} ${y}}
1498 // ${& ${section} ${subsection}}
1499 // ${Title}
1500 //
1501 // and returns the string
1502 //
1503 // "4711 Subject-1.01: Mit den Clowns kamen die Schwaene"
1504 //
1505 // assuming that
1506 // x = "4699"
1507 // y = "12"
1508 // section = "1."
1509 // subsection = "01"
1510 // title = "Mit den Clowns kamen die Schwaene"
1511 //
1512 // 2) __DBE_expand():
1513 //
1514 // checks for the command, i.e. the 'sign' that follows '${'
1515 // divides the argument list into sub-expressions using
1516 // __DBE_get_expr_list()
1517 //
1518 // ${+ ${x} ${y}} -> "${x}" "${y}"
1519 // ${& ${section} ${subsection}} -> "${section}" "${subsection}"
1520 // ${Title} -> Nothing, variable expansion
1521 //
1522 // 3) __DBE_expression_list():
1523 //
1524 // builds a vector of unbracketed whitespace separated strings, i.e.
1525 //
1526 // " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}"
1527 //
1528 // is split into a vector
1529 //
1530 // [0] ${Number}.a
1531 // [1] ${: Das Marmorbild}
1532 // [2] AB-${& Author= ${Eichendorf}}-1870
1533 //
1534 // Each sub-expression is expanded using expand().
1535 //---------------------------------------------------------------------------
1536 __GETPOT_INLINE std::string
1537 GetPot::__DBE_expand_string(const std::string str)
1538 {
1539  // Parses for closing operators '${ }' and expands them letting
1540  // white spaces and other letters as they are.
1541  std::string new_string = "";
1542  unsigned open_brackets = 0;
1543  unsigned first = 0;
1544  unsigned i = 0;
1545  for(; i<str.size(); ++i) {
1546  if( i < str.size() - 2 && str.substr(i, 2) == "${" ) {
1547  if( open_brackets == 0 ) first = i+2;
1548  open_brackets++;
1549  }
1550  else if( str[i] == '}' && open_brackets > 0) {
1551  open_brackets -= 1;
1552  if( open_brackets == 0 ) {
1553  const std::string Replacement = __DBE_expand(str.substr(first, i - first));
1554  new_string += Replacement;
1555  }
1556  }
1557  else if( open_brackets == 0 )
1558  new_string += str[i];
1559  }
1560  return new_string;
1561 }
1562 
1564 GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber)
1565  // ensures that the resulting vector has the expected number
1566  // of arguments, but they may contain an error message
1567 {
1568  std::string str = str_;
1569  // Separates expressions by non-bracketed whitespaces, expands them
1570  // and puts them into a list.
1571 
1572  unsigned i=0;
1573  // (1) eat initial whitespaces
1574  for(; i < str.size(); ++i)
1575  if( ! isspace(str[i]) ) break;
1576 
1577  STRING_VECTOR expr_list;
1578  unsigned open_brackets = 0;
1579  std::vector<unsigned> start_idx;
1580  unsigned start_new_string = i;
1581  unsigned l = static_cast<unsigned int>(str.size());
1582 
1583  // (2) search for ${ } expressions ...
1584  while( i < l ) {
1585  const char letter = str[i];
1586  // whitespace -> end of expression
1587  if( isspace(letter) && open_brackets == 0) {
1588  expr_list.push_back(str.substr(start_new_string, i - start_new_string));
1589  bool no_breakout_f = true;
1590  for(++i; i < l ; ++i) {
1591  if( ! isspace(str[i]) )
1592  { no_breakout_f = false; start_new_string = i; break; }
1593  }
1594  if( no_breakout_f ) {
1595  // end of expression list
1596  if( expr_list.size() < ExpectedNumber ) {
1597  const std::string pre_tmp("<< ${ }: missing arguments>>");
1598  STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
1599  expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
1600  }
1601  return expr_list;
1602  }
1603  }
1604 
1605  // dollar-bracket expression
1606  if( str.length() >= i+2 && str.substr(i, 2) == "${" ) {
1607  open_brackets++;
1608  start_idx.push_back(i+2);
1609  }
1610  else if( letter == '}' && open_brackets > 0) {
1611  int start = start_idx[start_idx.size()-1];
1612  start_idx.pop_back();
1613  const std::string Replacement = __DBE_expand(str.substr(start, i-start));
1614  if( start - 3 < (int)0)
1615  str = Replacement + str.substr(i+1);
1616  else
1617  str = str.substr(0, start-2) + Replacement + str.substr(i+1);
1618  l = static_cast<unsigned int>(str.size());
1619  i = start + static_cast<unsigned int>(Replacement.size()) - 3;
1620  open_brackets--;
1621  }
1622  ++i;
1623  }
1624 
1625  // end of expression list
1626  expr_list.push_back(str.substr(start_new_string, i-start_new_string));
1627 
1628  if( expr_list.size() < ExpectedNumber ) {
1629  const std::string pre_tmp("<< ${ }: missing arguments>>");
1630  STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
1631  expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
1632  }
1633 
1634  return expr_list;
1635 }
1636 
1638 GetPot::__DBE_get(std::string VarName)
1639 {
1640  static GetPot::variable ev;
1641  const std::string EmptyString("");
1642 
1643  std::string secure_Prefix = prefix;
1644 
1645  prefix = section;
1646  // (1) first search in currently active section
1647  const GetPot::variable* var = __find_variable(VarName, EmptyString, false);
1648  if( var != 0 ) { prefix = secure_Prefix; return var; }
1649 
1650  // (2) search in root name space
1651  prefix = "";
1652  var = __find_variable(VarName, EmptyString);
1653  if( var != 0 ) { prefix = secure_Prefix; return var; }
1654 
1655  prefix = secure_Prefix;
1656 
1657  // error occured => variable name == ""
1658  char* tmp = new char[VarName.length() + 25];
1659  GETPOT_SNPRINTF(tmp, (int)sizeof(char)*(VarName.length() + 25),
1660  "<<${ } variable '%s' undefined>>", VarName.c_str());
1661  ev.name = "";
1662  ev.original = std::string(tmp);
1663  delete [] tmp;
1664  return &ev;
1665 }
1666 
1667 __GETPOT_INLINE std::string
1668 GetPot::__DBE_expand(const std::string expr)
1669 {
1670  // ${: } pure text
1671  if( expr[0] == ':' )
1672  return expr.substr(1);
1673 
1674  // ${& expr expr ... } text concatination
1675  else if( expr[0] == '&' ) {
1676  const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1);
1677 
1678  STRING_VECTOR::const_iterator it = A.begin();
1679  std::string result = *it++;
1680  for(; it != A.end(); ++it) result += *it;
1681 
1682  return result;
1683  }
1684 
1685  // ${<-> expr expr expr} text replacement
1686  else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) {
1687  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3);
1688  std::string::size_type tmp = 0;
1689  const std::string::size_type L = A[1].length();
1690  while( (tmp = A[0].find(A[1])) != std::string::npos ) {
1691  A[0].replace(tmp, L, A[2]);
1692  }
1693  return A[0];
1694  }
1695  // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions
1696  else if( expr[0] == '+' ) {
1697  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1698  STRING_VECTOR::const_iterator it = A.begin();
1699  double result = __convert_to_type(*it++, 0.0);
1700  for(; it != A.end(); ++it)
1701  result += __convert_to_type(*it, 0.0);
1702 
1703  return __double2string(result);
1704  }
1705  else if( expr[0] == '-' ) {
1706  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1707  STRING_VECTOR::const_iterator it = A.begin();
1708  double result = __convert_to_type(*it++, 0.0);
1709  for(; it != A.end(); ++it)
1710  result -= __convert_to_type(*it, 0.0);
1711 
1712  return __double2string(result);
1713  }
1714  else if( expr[0] == '*' ) {
1715  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1716  STRING_VECTOR::const_iterator it = A.begin();
1717  double result = __convert_to_type(*it++, 0.0);
1718  for(; it != A.end(); ++it)
1719  result *= __convert_to_type(*it, 0.0);
1720 
1721  return __double2string(result);
1722  }
1723  else if( expr[0] == '/' ) {
1724 
1725  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1726  STRING_VECTOR::const_iterator it = A.begin();
1727  double result = __convert_to_type(*it++, 0.0);
1728  if( result == 0 ) return "0.0";
1729  for(; it != A.end(); ++it) {
1730  const double Q = __convert_to_type(*it, 0.0);
1731  if( Q == 0.0 ) return "0.0";
1732  result /= Q;
1733  }
1734  return __double2string(result);
1735  }
1736 
1737  // ${^ ... } power expressions
1738  else if( expr[0] == '^' ) {
1739  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1740  STRING_VECTOR::const_iterator it = A.begin();
1741  double result = __convert_to_type(*it++, 0.0);
1742  for(; it != A.end(); ++it)
1743  result = pow(result, __convert_to_type(*it, 0.0));
1744  return __double2string(result);
1745  }
1746 
1747  // ${== } ${<= } ${>= } comparisons (return the number of the first 'match'
1748  else if( expr.length() >= 2 &&
1749  ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" ||
1750  expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) {
1751  // differentiate between two and one sign operators
1752  unsigned op = 0;
1753  enum { EQ, GEQ, LEQ, GT, LT };
1754  if ( expr.substr(0, 2) == "==" ) op = EQ;
1755  else if ( expr.substr(0, 2) == ">=" ) op = GEQ;
1756  else if ( expr.substr(0, 2) == "<=" ) op = LEQ;
1757  else if ( expr[0] == '>' ) op = GT;
1758  else /* "<" */ op = LT;
1759 
1760  STRING_VECTOR a;
1761  if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2);
1762  else a = __DBE_get_expr_list(expr.substr(2), 2);
1763 
1764  std::string x_orig = a[0];
1765  double x = __convert_to_type(x_orig, 1e37);
1766  unsigned i = 1;
1767 
1768  STRING_VECTOR::const_iterator y_orig = a.begin();
1769  for(y_orig++; y_orig != a.end(); y_orig++) {
1770  double y = __convert_to_type(*y_orig, 1e37);
1771 
1772  // set the strings as reference if one wasn't a number
1773  if ( x == 1e37 || y == 1e37 ) {
1774  // it's a string comparison
1775  if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
1776  (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
1777  (op == LT && x_orig < *y_orig) )
1778  return __int2string(i);
1779  }
1780  else {
1781  // it's a number comparison
1782  if( (op == EQ && x == y) || (op == GEQ && x >= y) ||
1783  (op == LEQ && x <= y) || (op == GT && x > y) ||
1784  (op == LT && x < y) )
1785  return __int2string(i);
1786  }
1787  ++i;
1788  }
1789 
1790  // nothing fulfills the condition => return 0
1791  return "0";
1792  }
1793  // ${?? expr expr} select
1794  else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) {
1795  STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2);
1796  double x = __convert_to_type(a[0], 1e37);
1797  // last element is always the default argument
1798  if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1];
1799 
1800  // round x to closest integer
1801  return a[int(x+0.5)];
1802  }
1803  // ${? expr expr expr} if then else conditions
1804  else if( expr[0] == '?' ) {
1805  STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2);
1806  if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1];
1807  else if( a.size() > 2 ) return a[2];
1808  }
1809  // ${! expr} maxro expansion
1810  else if( expr[0] == '!' ) {
1811  const GetPot::variable* Var = __DBE_get(expr.substr(1));
1812  // error
1813  if( Var->name == "" ) return std::string(Var->original);
1814 
1815  const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2);
1816  return A[0];
1817  }
1818  // ${@: } - string subscription
1819  else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) {
1820  const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2);
1821  double x = __convert_to_type(A[1], 1e37);
1822 
1823  // last element is always the default argument
1824  if( x == 1e37 || x < 0 || x >= A[0].size() - 1)
1825  return "<<1st index out of range>>";
1826 
1827  if( A.size() > 2 ) {
1828  double y = __convert_to_type(A[2], 1e37);
1829  if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x )
1830  return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5));
1831  else if( y == -1 )
1832  return A[0].substr(int(x+0.5));
1833  return "<<2nd index out of range>>";
1834  }
1835  else {
1836  char* tmp = new char[2];
1837  tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0';
1838  std::string result(tmp);
1839  delete [] tmp;
1840  return result;
1841  }
1842  }
1843  // ${@ } - vector subscription
1844  else if( expr[0] == '@' ) {
1845  STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1846  const GetPot::variable* Var = __DBE_get(A[0]);
1847  // error
1848  if( Var->name == "" ) {
1849  // make a copy of the string if an error occured
1850  // (since the error variable is a static variable inside get())
1851  return std::string(Var->original);
1852  }
1853 
1854  double x = __convert_to_type(A[1], 1e37);
1855 
1856  // last element is always the default argument
1857  if (x == 1e37 || x < 0 || x >= Var->value.size() )
1858  return "<<1st index out of range>>";
1859 
1860  if ( A.size() > 2) {
1861  double y = __convert_to_type(A[2], 1e37);
1862  int begin = int(x+0.5);
1863  int end = 0;
1864  if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x)
1865  end = int(y+1.5);
1866  else if( y == -1 )
1867  end = static_cast<unsigned int>(Var->value.size());
1868  else
1869  return "<<2nd index out of range>>";
1870 
1871  std::string result = *(Var->get_element(begin));
1872  int i = begin+1;
1873  for(; i < end; ++i)
1874  result += std::string(" ") + *(Var->get_element(i));
1875  return result;
1876  }
1877  else
1878  return *(Var->get_element(int(x+0.5)));
1879  }
1880 
1881  const STRING_VECTOR A = __DBE_get_expr_list(expr, 1);
1882  const GetPot::variable* B = __DBE_get(A[0]);
1883 
1884  // make a copy of the string if an error occured
1885  // (since the error variable is a static variable inside get())
1886  if( B->name == "" ) return std::string(B->original);
1887  // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces
1888  // with: else return B->original (thanks))
1889  return B->original;
1890 }
1891 
1892 
1894 // (*) unidentified flying objects
1895 //.............................................................................
1896 //
1897 __GETPOT_INLINE bool
1898 GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const
1899 {
1900  victorate(std::string, VecStr, itk) {
1901  if( *itk == Str ) return true;
1902  }
1903  return false;
1904 }
1905 
1908  const char* KnownArgument1, ...) const
1909 {
1910  STRING_VECTOR known_arguments;
1911 
1912  // (1) create a vector of known arguments
1913  if( Number == 0 ) return STRING_VECTOR();
1914 
1915  va_list ap;
1916  va_start(ap, KnownArgument1);
1917  known_arguments.push_back(std::string(KnownArgument1));
1918  unsigned i=1;
1919  for(; i<Number; ++i)
1920  known_arguments.push_back(std::string(va_arg(ap, char *)));
1921  va_end(ap);
1922 
1923  return unidentified_arguments(known_arguments);
1924 }
1925 
1929 
1932 {
1933  STRING_VECTOR ufos;
1934  STRING_VECTOR::const_iterator it = argv.begin();
1935  ++it; // forget about argv[0] (application or filename)
1936  for(; it != argv.end(); ++it) {
1937  // -- argument belongs to prefixed section ?
1938  const std::string arg = __get_remaining_string(*it, prefix);
1939  if( arg == "" ) continue;
1940 
1941  // -- check if in list
1942  if( __search_string_vector(Knowns, arg) == false)
1943  ufos.push_back(*it);
1944  }
1945  return ufos;
1946 }
1947 
1950  const char* KnownOption1, ...) const
1951 {
1952  STRING_VECTOR known_options;
1953 
1954  // (1) create a vector of known arguments
1955  if( Number == 0 ) return STRING_VECTOR();
1956 
1957  va_list ap;
1958  va_start(ap, KnownOption1);
1959  known_options.push_back(std::string(KnownOption1));
1960  unsigned i=1;
1961  for(; i<Number; ++i)
1962  known_options.push_back(std::string(va_arg(ap, char *)));
1963  va_end(ap);
1964 
1965  return unidentified_options(known_options);
1966 }
1967 
1970 {
1971  // -- every option is an argument.
1972  // -- the set of requested arguments contains the set of requested options.
1973  // -- IF the set of requested arguments contains unrequested options,
1974  // THEN they were requested as 'follow' and 'next' arguments and not as real options.
1975  //
1976  // => it is not necessary to separate requested options from the list
1977  STRING_VECTOR option_list;
1978  victorate(std::string, _requested_arguments, it) {
1979  const std::string arg = *it;
1980  if( arg.length() == 0 ) continue;
1981  if( arg[0] == '-' ) option_list.push_back(arg);
1982  }
1983  return unidentified_options(option_list);
1984 }
1985 
1988 {
1989  STRING_VECTOR ufos;
1990  STRING_VECTOR::const_iterator it = argv.begin();
1991  ++it; // forget about argv[0] (application or filename)
1992  for(; it != argv.end(); ++it) {
1993  // -- argument belongs to prefixed section ?
1994  const std::string arg = __get_remaining_string(*it, prefix);
1995  if( arg == "" ) continue;
1996 
1997  // is argument really an option (starting with '-') ?
1998  if( arg.length() < 1 || arg[0] != '-' ) continue;
1999 
2000  if( __search_string_vector(Knowns, arg) == false)
2001  ufos.push_back(*it);
2002  }
2003 
2004  return ufos;
2005 }
2006 
2007 __GETPOT_INLINE std::string
2008 GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const
2009  // Two modes:
2010  // ArgumentNumber >= 0 check specific argument
2011  // ArgumentNumber == -1 check all options starting with one '-'
2012  // for flags
2013 {
2014  std::string ufos;
2015  STRING_VECTOR known_arguments;
2016  std::string KFL(KnownFlagList);
2017 
2018  // (2) iteration over '-' arguments (options)
2019  if( ArgumentNumber == -1 ) {
2020  STRING_VECTOR::const_iterator it = argv.begin();
2021  ++it; // forget about argv[0] (application or filename)
2022  for(; it != argv.end(); ++it) {
2023  // -- argument belongs to prefixed section ?
2024  const std::string arg = __get_remaining_string(*it, prefix);
2025  //
2026  // -- does arguments start with '-' (but not '--')
2027  if( arg.length() < 2 || arg[0] != '-' || arg[1] == '-' ) continue;
2028 
2029  // -- check out if flags inside option are contained in KnownFlagList
2030  for(ptrdiff_t i=1; i<(int)arg.length(); ++i) {
2031  if( KFL.find(arg[i]) == std::string::npos ) ufos += arg[i];
2032  }
2033  }
2034  }
2035  // (1) check specific argument
2036  else {
2037  // -- only check arguments that start with prefix
2038  int no_matches = 0;
2039  unsigned i=1;
2040  for(; i<argv.size(); ++i) {
2041  const std::string Remain = __get_remaining_string(argv[i], prefix);
2042  if( Remain != "") {
2043  no_matches++;
2044  if( no_matches == ArgumentNumber) {
2045  // -- the right argument number inside the section is found
2046  // => check it for flags
2047  for(ptrdiff_t i=1; i<(int)Remain.length(); ++i) {
2048  if( KFL.find(Remain[i]) == std::string::npos ) ufos += Remain[i];
2049  }
2050  return ufos;
2051  }
2052  }
2053  }
2054  }
2055  return ufos;
2056 }
2057 
2060  const char* KnownVariable1, ...) const
2061 {
2062  STRING_VECTOR known_variables;
2063 
2064  // create vector of known arguments
2065  if( Number == 0 ) return STRING_VECTOR();
2066 
2067  va_list ap;
2068  va_start(ap, KnownVariable1);
2069  known_variables.push_back(std::string(KnownVariable1));
2070  unsigned i=1;
2071  for(; i<Number; ++i)
2072  known_variables.push_back(std::string(va_arg(ap, char *)));
2073  va_end(ap);
2074 
2075  return unidentified_variables(known_variables);
2076 }
2077 
2080 {
2081  STRING_VECTOR ufos;
2082 
2084  // -- check if variable has specific prefix
2085  const std::string var_name = __get_remaining_string((*it).name, prefix);
2086  if( var_name == "" ) continue;
2087 
2088  // -- check if variable is known
2089  if( __search_string_vector(Knowns, var_name) == false)
2090  ufos.push_back((*it).name);
2091  }
2092  return ufos;
2093 }
2094 
2098 
2099 
2102  const char* KnownSection1, ...) const
2103 {
2104  STRING_VECTOR known_sections;
2105 
2106  // (1) create a vector of known arguments
2107  if( Number == 0 ) return STRING_VECTOR();
2108 
2109  va_list ap;
2110  va_start(ap, KnownSection1);
2111  known_sections.push_back(std::string(KnownSection1));
2112  unsigned i=1;
2113  for(; i<Number; ++i) {
2114  std::string tmp = std::string(va_arg(ap, char *));
2115  if( tmp.length() == 0 ) continue;
2116  if( tmp[tmp.length()-1] != '/' ) tmp += '/';
2117  known_sections.push_back(tmp);
2118  }
2119  va_end(ap);
2120 
2121  return unidentified_sections(known_sections);
2122 }
2123 
2127 
2130 {
2131  STRING_VECTOR ufos;
2132 
2133  victorate(std::string, section_list, it) {
2134  // -- check if section conform to prefix
2135  const std::string sec_name = __get_remaining_string(*it, prefix);
2136  if( sec_name == "" ) continue;
2137 
2138  // -- check if section is known
2139  if( __search_string_vector(Knowns, sec_name) == false )
2140  ufos.push_back(*it);
2141  }
2142 
2143  return ufos;
2144 }
2145 
2146 
2148 GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const
2149 {
2150  STRING_VECTOR known_nominuses;
2151 
2152  // create vector of known arguments
2153  if( Number == 0 ) return STRING_VECTOR();
2154 
2155  va_list ap;
2156  va_start(ap, Known);
2157  known_nominuses.push_back(std::string(Known));
2158  unsigned i=1;
2159  for(; i<Number; ++i) {
2160  std::string tmp = std::string(va_arg(ap, char *));
2161  if( tmp.length() == 0 ) continue;
2162  known_nominuses.push_back(tmp);
2163  }
2164  va_end(ap);
2165 
2166  return unidentified_nominuses(known_nominuses);
2167 }
2168 
2171  // -- every nominus is an argument.
2172  // -- the set of requested arguments contains the set of requested nominuss.
2173  // -- IF the set of requested arguments contains unrequested nominuss,
2174  // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses.
2175  //
2176  // => it is not necessary to separate requested nominus from the list
2177 
2179 }
2180 
2183 {
2184  STRING_VECTOR ufos;
2185 
2186  // (2) iterate over all arguments
2187  STRING_VECTOR::const_iterator it = argv.begin();
2188  ++it; // forget about argv[0] (application or filename)
2189  for(; it != argv.end(); ++it) {
2190  // -- check if nominus part of prefix
2191  const std::string arg = __get_remaining_string(*it, prefix);
2192  if( arg == "" ) continue;
2193 
2194  if( arg.length() < 1 ) continue;
2195  // option ? --> not a nomius
2196  if( arg[0] == '-' ) continue;
2197  // section ? --> not a real nominus
2198  if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue;
2199  // variable definition ? --> not a real nominus
2200  bool continue_f = false;
2201  unsigned i=0;
2202  for(; i<arg.length() ; ++i)
2203  if( arg[i] == '=' ) { continue_f = true; break; }
2204  if( continue_f ) continue;
2205 
2206  // real nominuses are compared with the given list
2207  if( __search_string_vector(Knowns, arg) == false )
2208  ufos.push_back(*it);
2209  }
2210  return ufos;
2211 }
2212 
2213 __GETPOT_INLINE bool
2214 GetPot::__constraint_check(const std::string& Value, const char* ConstraintStr,
2215  bool ThrowExceptionF) const
2216 {
2217  std::string ConstraintString = std::string(ConstraintStr);
2218  if( ConstraintStr == (const char *) "" ) return true;
2219  if( __constraint_check_OR(Value, &ConstraintStr) ) return true;
2220 
2221  if( ThrowExceptionF ) {
2222  std::string msg(GETPOT_STR_FILE " ");
2223  msg += std::string("\"") + filename + "\": \'";
2224  msg += std::string(Value) + "\' ";
2225  if( ! prefix.empty() )
2226  msg += std::string("\n " GETPOT_STR_IN_SECTION " \"") + prefix + "\"\n";
2227  msg += std::string(GETPOT_STR_DOES_NOT_SATISFY_CONSTRAINT) + " \'" + ConstraintString + "\'";
2228  msg += ".";
2229  throw std::runtime_error(msg);
2230  }
2231  else {
2232  return false;
2233  }
2234 }
2235 
2236 /*
2237  * GRAMMAR:
2238  *
2239  * or_expr: or_expr '|' and_expr
2240  * and_expr
2241  *
2242  * and_expr: and_expr '&' primary
2243  * primary
2244  *
2245  * primary: '>' number
2246  * '>=' number
2247  * '<' number
2248  * ...
2249  * 'string'
2250  * '(' or_expr ')' */
2251 
2252 __GETPOT_INLINE bool
2253 GetPot::__constraint_check_OR(const std::string& Value, const char** iterator) const
2254 {
2255  bool result = false;
2256 
2257  do {
2258  if (**iterator == '|') ++(*iterator);
2259  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2260  if( __constraint_check_AND(Value, iterator) ) result = true;
2261  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2262  } while ( **iterator == '|' );
2263 
2264  return result;
2265 }
2266 
2267 __GETPOT_INLINE bool
2268 GetPot::__constrain_check_EQUAL_STRING(const char* viterator, const char** iterator) const
2269 {
2270  ++(*iterator);
2271  // Compare strings from single quote to single quote
2272  // loop: 'break' means 'not equal'
2273  while( 1 + 1 == 2 ) {
2274  if( *viterator != **iterator ) break; // letter in value != letter in iterator
2275  ++(*iterator); ++viterator;
2276 
2277  if( *viterator == '\0' ) {
2278  if ( **iterator != '\'' ) break; // value ended before iterator
2279  return true;
2280  }
2281  else if( **iterator == '\'' ) break; // iterator ended before value
2282  }
2283  // iterator must proceed to the place after the single quote '
2284  while( **iterator != '\'' ) ++(*iterator);
2285  ++(*iterator);
2286  return false;
2287 }
2288 
2289 __GETPOT_INLINE bool
2290 GetPot::__constraint_check_AND(const std::string& Value, const char** iterator) const
2291 {
2292  bool result = true;
2293 
2294  do {
2295  if (**iterator == '&') ++(*iterator);
2296  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2297  if( ! __constraint_check_PRIMARY(Value, iterator) ) result = false;
2298  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2299  } while ( **iterator == '&' );
2300 
2301  return result;
2302 }
2303 
2304 __GETPOT_INLINE bool
2305 GetPot::__constraint_check_PRIMARY(const std::string& Value,
2306  const char** iterator) const
2307 {
2308  enum Operator {
2309  EQ = 0x80,
2310  GREATER = 0x01, // 'or'-ring 0x80 into an operator
2311  GREATER_EQ = EQ | GREATER, // means adding the 'equal option'.
2312  LESS = 0x02,
2313  LESS_EQ = EQ | LESS,
2314  NOT = 0x03,
2315  NOT_EQ = EQ | NOT,
2316  DEVISABLE_BY = 0x05,
2317  VOID
2318  } op = VOID;
2319 
2320  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2321 
2322  switch ( (*iterator)[0] ) {
2323 
2324  default: op = EQ; ++(*iterator); break;
2325  case '\0': throw std::runtime_error(GETPOT_STR_REACHED_END_OF_CONSTRAINT + " " +
2326  + GETPOT_STR_VALUE + ": \'" + Value + "\'.");
2327 
2328  case '>': op = GREATER; ++(*iterator); break;
2329  case '<': op = LESS; ++(*iterator); break;
2330  case '%': op = DEVISABLE_BY; ++(*iterator); break;
2331  case '!': op = NOT; ++(*iterator); break;
2332  case '\'': return __constrain_check_EQUAL_STRING(Value.c_str(), iterator);
2333  case '(': {
2334  ++(*iterator);
2335  bool result = __constraint_check_OR(Value, iterator);
2336  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2337 
2338  if( **iterator != ')' )
2339  throw std::runtime_error(std::string("Error while processing the file \"")
2340  + filename + "\": a bracket is missing in a constraint.");
2341  ++(*iterator);
2342  return result;
2343  }
2344  }
2345 
2346  if( (*iterator)[0] == '=' ) {
2347  if( op == VOID ) throw std::runtime_error(std::string("Syntax error found in a constraint")
2348  + "string while processing the file \""
2349  + filename + "\".");
2350  else {
2351  op = (Operator) (EQ | op);
2352  ++(*iterator);
2353  }
2354  }
2355  else if( op == VOID ) throw std::runtime_error(std::string("Syntax error found in a constraint")
2356  + "string while processing the file \""
2357  + filename + "\".");
2358 
2359 
2360  if( op == NOT ) {
2361  return ! __constraint_check_AND(Value, iterator);
2362  }
2363 
2364  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2365 
2366  // Conversions to double.
2367  double value_numeric = -1.0;
2368  double cmp_numeric = -1.0;
2369 
2370  int result = 0;
2371  result = sscanf(Value.c_str(),"%lf", &value_numeric);
2372  if( result == 0 || result == EOF ) return false;
2373  result = sscanf(*iterator,"%lf", &cmp_numeric);
2374  if( result == 0 || result == EOF ) return false;
2375 
2376  // Skip until whitespace or closing bracket.
2377  while( !isspace(**iterator) && (*iterator)[0] != ')' ) ++(*iterator);
2378  while( isspace(**iterator) ) ++(*iterator); // skip whitespace
2379 
2380  switch( op ) {
2381  case GREATER: return value_numeric > cmp_numeric;
2382  case GREATER_EQ: return value_numeric >= cmp_numeric;
2383  case LESS: return value_numeric < cmp_numeric;
2384  case LESS_EQ: return value_numeric <= cmp_numeric;
2385  case NOT_EQ: return value_numeric != cmp_numeric;
2386  case EQ: return value_numeric == cmp_numeric;
2387  case DEVISABLE_BY: return (value_numeric / cmp_numeric) == double(int(value_numeric / cmp_numeric));
2388  case NOT: throw std::runtime_error(std::string("Syntax error found in a constraint")
2389  + "string while processing the file \""
2390  + filename + "\".");
2391  case VOID: throw std::runtime_error(std::string("Syntax error found in a constraint")
2392  + "string while processing the file \""
2393  + filename + "\".");
2394  }
2395  throw std::runtime_error(std::string("Syntax error found in a constraint")
2396  + "string while processing the file \""
2397  + filename + "\".");
2398 }
2400 // (*) variable class
2401 //.............................................................................
2402 //
2405 {}
2406 
2409 {
2410 #ifdef WIN32
2411  operator=(That);
2412 #else
2414 #endif
2415 }
2416 
2417 
2419 GetPot::variable::variable(const std::string& Name, const std::string& Value, const std::string& FieldSeparator)
2420  : name(Name)
2421 {
2422  // make a copy of the 'Value'
2423  take(Value, FieldSeparator);
2424 }
2425 
2426 __GETPOT_INLINE const std::string*
2427 GetPot::variable::get_element(unsigned Idx, bool ThrowExceptionF /* = GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT */) const
2428 {
2429  if( Idx < value.size() ) return &(value[Idx]);
2430 
2431  if( ThrowExceptionF ) {
2432  std::string msg;
2433  char tmp[64];
2434  msg += std::string(GETPOT_STR_VARIABLE) + "\'";
2435  msg += name + "\' ";
2436  GETPOT_SNPRINTF(tmp, 64, "%i", (int)Idx);
2437  msg += std::string(GETPOT_STR_DOES_NOT_CONTAIN_ELEMENT) + ": \'" + tmp + "\'";
2438  msg += ".";
2439  throw std::runtime_error(msg);
2440  }
2441  else {
2442  return 0x0;
2443  }
2444 }
2445 
2446 __GETPOT_INLINE void
2447 GetPot::variable::take(const std::string& Value, const std::string& FieldSeparator)
2448 {
2449  using namespace std;
2450 
2451  original = Value;
2452 
2453  // separate string by white space delimiters using 'strtok'
2454  // thread safe usage of strtok (no static members)
2455 # ifdef GETPOT_STRTOK_3_ARGS
2456  char* spt = 0;
2457 # endif
2458  // make a copy of the 'Value'
2459  char* copy = new char[Value.length()+1];
2460  strcpy(copy, Value.c_str());
2461  char* follow_token = GETPOT_STRTOK(copy, FieldSeparator.c_str(), &spt);
2462  if( value.size() != 0 ) value.erase(value.begin(), value.end());
2463  while(follow_token != 0) {
2464  value.push_back(std::string(follow_token));
2465  follow_token = GETPOT_STRTOK(NULL, FieldSeparator.c_str(), &spt);
2466  }
2467 
2468  delete [] copy;
2469 }
2470 
2473 {}
2474 
2477 {
2478  if( &That != this) {
2479  name = That.name;
2480  value = That.value;
2481  original = That.original;
2482  }
2483  return *this;
2484 }
2485 
2487 // (*) useful functions
2488 //.............................................................................
2489 //
2490 
2491 __GETPOT_INLINE std::string GetPot::__double2string(const double& Value) const {
2492  // -- converts a double integer into a string
2493  char* tmp = new char[128];
2494  GETPOT_SNPRINTF(tmp, (int)sizeof(char)*128, "%e", Value);
2495  std::string result(tmp);
2496  delete [] tmp;
2497  return result;
2498 }
2499 
2500 __GETPOT_INLINE std::string GetPot::__int2string(const int& Value) const {
2501  // -- converts an integer into a string
2502  char* tmp = new char[128];
2503  GETPOT_SNPRINTF(tmp, (int)sizeof(char)*128, "%i", Value);
2504  std::string result(tmp);
2505  delete [] tmp;
2506  return result;
2507 }
2508 
2510  // -- cuts a variable name into a tree of sub-sections. this is requested for recording
2511  // requested sections when dealing with 'ufo' detection.
2512  STRING_VECTOR result;
2513  for(ptrdiff_t i=0; i<(int)FullPath.length(); ++i) {
2514  if( FullPath[i] == '/' ) {
2515  result.push_back(FullPath.substr(0, i));
2516  }
2517  }
2518 
2519  return result;
2520 }
2521 
2522 #undef victorate
2523 
2524 #ifdef GETPOT_SETTING_NAMESPACE
2525 } // namespace GetPotNamespace.
2526 #endif
2527 
2528 
2529 
2530 #endif // __INCLUDE_GUARD_GETPOT_CPP__
2531 
2532 
2533 
const std::string __get_until_closing_bracket(std::istream &istr)
Definition: GetPot.cpp:487
bool __request_recording_f
Definition: GetPot.hpp:315
void set(StringOrCharP VarName, T &Value)
std::vector< unsigned > idx_nominus
Definition: GetPot.hpp:292
static int convert(unsigned int &X)
Definition: GetPot.cpp:93
STRING_VECTOR unidentified_nominuses() const
Definition: GetPot.cpp:2170
#define GETPOT_STR_REACHED_END_OF_CONSTRAINT
Definition: GetPot.hpp:52
static const char * name()
Definition: GetPot.cpp:108
static int convert(int &X)
Definition: GetPot.cpp:85
std::string prefix
Definition: GetPot.hpp:279
void __split(std::string str, std::vector< std::string > &vect, std::string delimiters=" \")
Definition: GetPot.cpp:1330
void __record_variable_request(const std::string &Arg)
Definition: GetPot.cpp:1288
T direct_follow(T Default, const char *Option)
std::vector< std::vector< char > *> __internal_string_container
Definition: GetPot.hpp:307
STRING_VECTOR _requested_arguments
Definition: GetPot.hpp:311
void reset_cursor()
Definition: GetPot.cpp:718
std::vector< std::string > STRING_VECTOR
Definition: GetPot.hpp:91
#define GETPOT_STR_DOES_NOT_SATISFY_CONSTRAINT
Definition: GetPot.hpp:59
static double default_value()
Definition: GetPot.cpp:109
const std::string operator[](unsigned Idx) const
Definition: GetPot.cpp:765
bool __constraint_check(const std::string &Value, const char *ConstraintStr, bool ThrowExceptionF) const
Definition: GetPot.cpp:2214
variable & operator=(const variable &That)
Definition: GetPot.cpp:2476
void __record_argument_request(const std::string &Arg)
Definition: GetPot.cpp:1271
void set_false_string_list(unsigned N, const char *StringForFalse,...)
Definition: GetPot.cpp:744
#define GETPOT_STRTOK(a, b, c)
Definition: GetPot.cpp:36
bool search_failed_f
Definition: GetPot.hpp:287
#define victorate(TYPE, VARIABLE, ITERATOR)
Definition: GetPot.cpp:61
std::string unidentified_flags(const char *Known, int ArgumentNumber) const
Definition: GetPot.cpp:2008
#define GETPOT_SNPRINTF(STR, SIZE, FORMAT_STR,...)
Definition: GetPot.cpp:43
void __parse_argument_vector(const STRING_VECTOR &ARGV)
Definition: GetPot.cpp:259
T follow(T Default, const char *Option)
STL namespace.
#define GETPOT_STR_CANNOT_CONVERT_TO(X, TYPE)
Definition: GetPot.hpp:58
STRING_VECTOR section_list
Definition: GetPot.hpp:281
#define GETPOT_STR_VALUE
Definition: GetPot.hpp:55
std::string name
Definition: GetPot.hpp:269
T operator()(const StringOrCharP VarName, T Default) const
STRING_VECTOR get_section_names() const
Definition: GetPot.cpp:1440
T get(unsigned Idx, T Default) const
unsigned vector_variable_size(StringOrCharP VarName) const
Definition: GetPot.cpp:1418
const GetPot::variable * __DBE_get(const std::string str)
Definition: GetPot.cpp:1638
T next(T Default)
std::string filename
Definition: GetPot.hpp:276
std::vector< int > int_tails(const char *StartString, const int Default=1)
Definition: GetPot.cpp:916
GetPot()
Definition: GetPot.cpp:144
static const char * convert(std::string &X)
Definition: GetPot.cpp:89
bool search_loop_f
Definition: GetPot.hpp:285
static bool convert(bool &X)
Definition: GetPot.cpp:71
void init_multiple_occurrence()
Definition: GetPot.cpp:722
void __set_variable(const std::string &VarName, const std::string &Value)
Definition: GetPot.cpp:1352
~GetPot()
Definition: GetPot.cpp:202
static double convert(double &X)
Definition: GetPot.cpp:111
const char * type
Definition: GetPot.cpp:77
STRING_VECTOR unidentified_variables() const
Definition: GetPot.cpp:2096
GetPot & operator=(const GetPot &)
Definition: GetPot.cpp:211
STRING_VECTOR __read_in_file(const std::string &FileName)
Definition: GetPot.cpp:329
#define GETPOT_SETTING_DEFAULT_TRUE_STRING_LIST
Definition: GetPot.hpp:35
STRING_VECTOR false_string_list
Definition: GetPot.hpp:278
STRING_VECTOR nominus_followers(const char *Option)
Definition: GetPot.cpp:1003
static const char * default_value()
Definition: GetPot.cpp:76
const char * __get_const_char(const std::string &String) const
Definition: GetPot.cpp:621
static const char * name()
Definition: GetPot.cpp:68
static const char * convert(const char *X)
Definition: GetPot.cpp:78
const variable * __find_variable(const std::string &, const std::string &TypeName, bool ThrowExceptionF=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT) const
Definition: GetPot.cpp:1444
STRING_VECTOR _requested_sections
Definition: GetPot.hpp:313
Definition: test.cpp:24
#define __GETPOT_INLINE
Definition: GetPot.cpp:50
STRING_VECTOR unidentified_sections() const
Definition: GetPot.cpp:2125
bool options_contain(const char *FlagList) const
Definition: GetPot.cpp:1094
STRING_VECTOR __get_section_tree(const std::string &FullPath)
Definition: GetPot.cpp:2509
static std::string default_value()
Definition: GetPot.cpp:90
bool __constraint_check_OR(const std::string &Value, const char **iterator) const
Definition: GetPot.cpp:2253
STRING_VECTOR __read_in_stream(std::istream &istr)
Definition: GetPot.cpp:341
std::string original
Definition: GetPot.hpp:271
const std::string * get_element(unsigned Idx, bool ThrowExceptionF=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT) const
Definition: GetPot.cpp:2427
bool __constraint_check_AND(const std::string &Value, const char **iterator) const
Definition: GetPot.cpp:2290
#define GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT
Definition: GetPot.hpp:32
const char * __match_starting_string(const char *StartString)
Definition: GetPot.cpp:1054
bool __constraint_check_PRIMARY(const std::string &Value, const char **iterator) const
Definition: GetPot.cpp:2305
std::string __DBE_expand(const std::string str)
Definition: GetPot.cpp:1668
static const char * name()
Definition: GetPot.cpp:75
static int convert(unsigned char &X)
Definition: GetPot.cpp:97
std::string __DBE_expand_string(const std::string str)
Definition: GetPot.cpp:1537
bool argument_contains(unsigned Idx, const char *FlagList) const
Definition: GetPot.cpp:1109
static int default_value()
Definition: GetPot.cpp:83
bool __constrain_check_EQUAL_STRING(const char *viterator, const char **iterator) const
Definition: GetPot.cpp:2268
std::string __double2string(const double &Value) const
Definition: GetPot.cpp:2491
std::string __process_section_label(const std::string &Section, STRING_VECTOR &section_stack)
Definition: GetPot.cpp:510
#define GETPOT_STR_IN_SECTION
Definition: GetPot.hpp:57
unsigned size() const
Definition: GetPot.cpp:801
unsigned cursor
Definition: GetPot.hpp:284
bool built
Definition: GetPot.hpp:275
T get_element(const StringOrCharP VarName, unsigned Idx, const char *Constraint)
int nominus_cursor
Definition: GetPot.hpp:291
void absorb(const GetPot &That)
Definition: GetPot.cpp:239
#define GETPOT_STR_FILE
Definition: GetPot.hpp:50
std::string section
Definition: GetPot.hpp:280
T __get(const StringOrCharP VarName, const char *Constraint, bool ThrowExceptionF) const
std::string content
Definition: GetPot.hpp:95
void __basic_initialization()
Definition: GetPot.cpp:122
const std::string __get_next_token(std::istream &istr)
Definition: GetPot.cpp:436
std::string next_nominus()
Definition: GetPot.cpp:1167
static double convert(float &X)
Definition: GetPot.cpp:114
std::string __int2string(const int &Value) const
Definition: GetPot.cpp:2500
STRING_VECTOR unidentified_arguments() const
Definition: GetPot.cpp:1927
std::string _comment_end
Definition: GetPot.hpp:300
#define GETPOT_STR_WITH_TYPE
Definition: GetPot.hpp:56
STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber)
Definition: GetPot.cpp:1564
bool __check_flags(const std::string &Str, const char *FlagList) const
Definition: GetPot.cpp:1139
#define GETPOT_STR_FILE_NOT_FOUND(FILE)
Definition: GetPot.hpp:51
STRING_VECTOR true_string_list
Definition: GetPot.hpp:277
const std::string __get_string(std::istream &istr)
Definition: GetPot.cpp:469
STRING_VECTOR unidentified_options() const
Definition: GetPot.cpp:1969
void clear_requests()
Definition: GetPot.cpp:251
static int convert(char &X)
Definition: GetPot.cpp:95
static const char * name()
Definition: GetPot.cpp:82
void disable_loop()
Definition: GetPot.hpp:212
STRING_VECTOR get_variable_names() const
Definition: GetPot.cpp:1428
T __convert_to_type(const std::string &String, T Default, bool ThrowExceptionF=GETPOT_SETTING_THROW_EXCEPTION_ON_DEFAULT) const
void __skip_whitespace(std::istream &istr)
Definition: GetPot.cpp:383
const std::string __get_remaining_string(const std::string &String, const std::string &Start) const
Definition: GetPot.cpp:634
static bool default_value()
Definition: GetPot.cpp:69
bool search(const char *option)
Definition: GetPot.cpp:647
T __get_element(const StringOrCharP VarName, unsigned Idx, const char *Constraint, bool ThrowExceptionF) const
#define GETPOT_STR_VARIABLE
Definition: GetPot.hpp:54
std::vector< std::string > string_tails(const char *StartString)
Definition: GetPot.cpp:874
void __build(const std::string &FileName, const std::string &CommentStart, const std::string &CommentEnd, const std::string &FieldSeparator)
Definition: GetPot.cpp:1306
static int convert(unsigned long &X)
Definition: GetPot.cpp:105
static int convert(short &X)
Definition: GetPot.cpp:99
#define GETPOT_STR_TRUE_FALSE_UNDEFINED
Definition: GetPot.hpp:61
std::vector< double > double_tails(const char *StartString, const double Default=1.0)
Definition: GetPot.cpp:958
#define GETPOT_STR_DOES_NOT_CONTAIN_ELEMENT
Definition: GetPot.hpp:60
STRING_VECTOR value
Definition: GetPot.hpp:270
STRING_VECTOR nominus_vector() const
Definition: GetPot.cpp:1150
static int convert(unsigned short &X)
Definition: GetPot.cpp:101
int print() const
Definition: GetPot.cpp:1478
std::string _field_separator
Definition: GetPot.hpp:303
bool __search_string_vector(const STRING_VECTOR &Vec, const std::string &Str) const
Definition: GetPot.cpp:1898
static int convert(long &X)
Definition: GetPot.cpp:103
std::vector< variable > variables
Definition: GetPot.hpp:296
void set_true_string_list(unsigned N, const char *StringForTrue,...)
Definition: GetPot.cpp:726
STRING_VECTOR argv
Definition: GetPot.hpp:283
#define GETPOT_STR_MISSING_VARIABLE
Definition: GetPot.hpp:53
#define GETPOT_SETTING_DEFAULT_FALSE_STRING_LIST
Definition: GetPot.hpp:38
std::string _comment_start
Definition: GetPot.hpp:299
STRING_VECTOR _requested_variables
Definition: GetPot.hpp:312
void take(const std::string &Value, const std::string &FieldSeparator)
Definition: GetPot.cpp:2447