LifeV
GetPot.hpp
Go to the documentation of this file.
1 /*
2 This file is part of the LifeV library
3 Copyright (C) 2001,2002,2003,2004 EPFL, INRIA and Politecnico di Milano
4 
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9 
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19 // -*- c++ -*-
20 // GetPot Version 1.1.18 (Updated from 1.0 by Cristiano Malossi on 30/03/2009)
21 //
22 // WEBSITE: http://getpot.sourceforge.net
23 //
24 // NOTE: The LPGL License for this library is only valid in case that
25 // it is not used for the production or development of applications
26 // dedicated to military industry. This is what the author calls
27 // the 'unofficial peace version of the LPGL'.
28 //
29 // This library is free software; you can redistribute it and/or modify
30 // it under the terms of the GNU Lesser General Public License as
31 // published by the Free Software Foundation; either version 2.1 of the
32 // License, or (at your option) any later version.
33 //
34 // This library is distributed in the hope that it will be useful, but
35 // WITHOUT ANY WARRANTY; without even the implied warranty of
36 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
37 // Lesser General Public License for more details.
38 //
39 // You should have received a copy of the GNU Lesser General Public
40 // License along with this library; if not, write to the Free Software
41 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
42 // USA
43 //
44 // (C) 2001-2007 Frank R. Schaefer <fschaef@users.sf.net>
45 //==========================================================================
46 
47 /*
48 \version 1.1.18-LifeV
49 This class handles the parsing of command line and options file according to the
50 rules set up in the GetPot manual.
51 
52 This is a version, modified for the LifeV library, is based on
53 the official GetPot release 1.1.18.
54 
55 LIFEV UPGRADES:
56 1) A hacking has been made in order to accept as input a list of filenames:
57 the data base will be constructed as the union of the data contained in all
58 the files in the list.
59 
60 2) Also a new constructor, which accepts strings as input, has been created.
61 
62 3) A new function which returns if a variable is present or not in the GetPot data
63 file has been added.
64 
65 4) Some functions to support boolean variables have been added.
66 
67 FOR DEVELOPERS:
68 In order to upgrade from a newer official version of GetPot, the same
69 modifications have to be carried out.
70 Search the class for: BEGIN/END Luca Formaggia
71 and BEGIN/END Cristiano Malossi
72 */
73 
74 #ifndef __include_guard_GETPOT_H__
75 #define __include_guard_GETPOT_H__
76 
77 #if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
78 #define strtok_r(a, b, c) strtok(a, b)
79 #endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC
80 
81 extern "C"
82 {
83  // leave the 'extern C' to make it 100% sure to work -
84  // expecially with older distributions of header files.
85 #ifndef WIN32
86  // this is necessary (depending on OS)
87 #include <ctype.h>
88 #endif
89 #include <stdio.h>
90 #include <stdarg.h>
91 #include <assert.h>
92 #include <string.h>
93 }
94 #include <cmath>
95 #include <string>
96 #include <vector>
97 #include <algorithm>
98 
99 #include <fstream>
100 #include <iostream> // not every compiler distribution includes <iostream>
101 // // with <fstream>
102 
104 
105 #define victorate(TYPE, VARIABLE, ITERATOR)
106  std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin();
107  for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++)
108 
109 
110 class GetPot
111 {
112  //--------
113  inline void __basic_initialization();
114 public:
115  // (*) constructors, destructor, assignment operator -----------------------
116  inline GetPot();
117  inline GetPot (const GetPot&);
118  inline GetPot (const int argc_, char** argv_,
119  const char* FieldSeparator = 0x0);
120  inline GetPot (const char* FileName,
121  const char* CommentStart = 0x0, const char* CommentEnd = 0x0,
122  const char* FieldSeparator = 0x0);
123 
124  // BEGIN Cristiano Malossi - 30/03/2009
125  template <typename STRING> //Necessary to be valid with both std::string and cstring
126  inline GetPot (const STRING& FileName,
127  const char* CommentStart = 0x0, const char* CommentEnd = 0x0,
128  const char* FieldSeparator = 0x0);
129  // END Cristiano Malossi - 30/03/2009
130 
131  inline ~GetPot();
132  inline GetPot& operator= (const GetPot&);
133 
134  // BEGIN Luca Formaggia - 29/12/2002
135  GetPot ( const STRING_VECTOR& FileNameList );
136  // END Luca Formaggia - 29/12/2002
137 
138 
139  // (*) absorbing contents of another GetPot object
140  inline void absorb (const GetPot& That);
141  // -- for ufo detection: recording requested arguments, options etc.
142  inline void clear_requests();
144  {
145  __request_recording_f = false;
146  }
148  {
149  __request_recording_f = true;
150  }
151 
152  // (*) direct access to command line arguments -----------------------------
153  inline const std::string operator[] (unsigned Idx) const;
154  inline int get (unsigned Idx, int Default) const;
155  inline double get (unsigned Idx, const double& Default) const;
156  inline const std::string get (unsigned Idx, const char* Default) const;
157  inline unsigned size() const;
158 
159  // (*) flags ---------------------------------------------------------------
160  inline bool options_contain (const char* FlagList) const;
161  inline bool argument_contains (unsigned Idx, const char* FlagList) const;
162 
163  // (*) variables -----------------------------------------------------------
164  // -- scalar values
165 
166  // BEGIN Cristiano Malossi - 05/05/2009
167  inline bool operator() (const char* VarName, bool Default) const;
168  // END Cristiano Malossi - 05/05/2009
169 
170  inline int operator() (const char* VarName, int Default) const;
171  inline double operator() (const char* VarName, const double& Default) const;
172  inline const std::string operator() (const char* VarName, const char* Default) const;
173  // -- vectors
174 
175  // BEGIN Gilles Fourestey - 05/11/2009
176  inline bool operator() (const char* VarName, bool Default, bool& found) const;
177  inline int operator() (const char* VarName, int Default, bool& found) const;
178  inline double operator() (const char* VarName, const double& Default, bool& found) const;
179  inline const std::string operator() (const char* VarName, const char* Default, bool& found) const;
180  // END Gilles Fourestey - 05/11/2009
181 
182  // BEGIN Cristiano Malossi - 05/05/2009
183  inline bool operator() (const char* VarName, bool Default, unsigned Idx) const;
184  // END Cristiano Malossi - 05/05/2009
185 
186  inline int operator() (const char* VarName, int Default, unsigned Idx) const;
187  inline double operator() (const char* VarName, const double& Default, unsigned Idx) const;
188  inline const std::string operator() (const char* VarName, const char* Default, unsigned Idx) const;
189 
190  // -- setting variables
191  // i) from outside of GetPot (considering prefix etc.)
192  // ii) from inside, use '__set_variable()' below
193  inline void set (const char* VarName, const char* Value, const bool Requested = true);
194  inline void set (const char* VarName, const double& Value, const bool Requested = true);
195  inline void set (const char* VarName, const int Value, const bool Requested = true);
196 
197  // BEGIN Cristiano Malossi - 03/04/2009
198  inline bool checkVariable (const char* VarName) const;
199  // END Cristiano Malossi - 03/04/2009
200 
201  inline unsigned vector_variable_size (const char* VarName) const;
202  inline STRING_VECTOR get_variable_names() const;
203  inline STRING_VECTOR get_section_names() const;
204 
205 
206  // (*) cursor oriented functions -------------------------------------------
207  inline void set_prefix (const char* Prefix)
208  {
209  prefix = std::string (Prefix);
210  }
211  inline bool search_failed() const
212  {
213  return search_failed_f;
214  }
215 
216  // -- enable/disable search for an option in loop
217  inline void disable_loop()
218  {
219  search_loop_f = false;
220  }
221  inline void enable_loop()
222  {
223  search_loop_f = true;
224  }
225 
226  // -- reset cursor to position '1'
227  inline void reset_cursor();
228  inline void init_multiple_occurrence();
229 
230  // -- search for a certain option and set cursor to position
231  inline bool search (const char* option);
232  inline bool search (unsigned No, const char* P, ...);
233  // -- get argument at cursor++
234  inline int next (int Default);
235  inline double next (const double& Default);
236  inline const std::string next (const char* Default);
237  // -- search for option and get argument at cursor++
238  inline int follow (int Default, const char* Option);
239  inline double follow (const double& Default, const char* Option);
240  inline const std::string follow (const char* Default, const char* Option);
241  // -- search for one of the given options and get argument that follows it
242  inline int follow (int Default, unsigned No, const char* Option, ...);
243  inline double follow (const double& Default, unsigned No, const char* Option, ...);
244  inline const std::string follow (const char* Default, unsigned No, const char* Option, ...);
245  // -- lists of nominuses following an option
246  inline std::vector<std::string> nominus_followers (const char* Option);
247  inline std::vector<std::string> nominus_followers (unsigned No, ...);
248 
249  // -- directly followed arguments
250  inline int direct_follow (int Default, const char* Option);
251  inline double direct_follow (const double& Default, const char* Option);
252  inline const std::string direct_follow (const char* Default, const char* Option);
253 
254  inline std::vector<std::string> string_tails (const char* StartString);
255  inline std::vector<int> int_tails (const char* StartString, const int Default = 1);
256  inline std::vector<double> double_tails (const char* StartString, const double Default = 1.0);
257 
258  // (*) nominus arguments ---------------------------------------------------
259  inline STRING_VECTOR nominus_vector() const;
260  inline unsigned nominus_size() const
261  {
262  return static_cast<unsigned int> (idx_nominus.size() );
263  }
264  inline std::string next_nominus();
265 
266  // (*) unidentified flying objects -----------------------------------------
267  inline STRING_VECTOR unidentified_arguments (unsigned Number, const char* Known, ...) const;
268  inline STRING_VECTOR unidentified_arguments (const STRING_VECTOR& Knowns) const;
269  inline STRING_VECTOR unidentified_arguments() const;
270 
271  inline STRING_VECTOR unidentified_options (unsigned Number, const char* Known, ...) const;
272  inline STRING_VECTOR unidentified_options (const STRING_VECTOR& Knowns) const;
273  inline STRING_VECTOR unidentified_options() const;
274 
275  inline std::string unidentified_flags (const char* Known,
276  int ArgumentNumber /* =-1 */) const;
277 
278  inline STRING_VECTOR unidentified_variables (unsigned Number, const char* Known, ...) const;
279  inline STRING_VECTOR unidentified_variables (const STRING_VECTOR& Knowns) const;
280  inline STRING_VECTOR unidentified_variables() const;
281 
282  inline STRING_VECTOR unidentified_sections (unsigned Number, const char* Known, ...) const;
283  inline STRING_VECTOR unidentified_sections (const STRING_VECTOR& Knowns) const;
284  inline STRING_VECTOR unidentified_sections() const;
285 
286  inline STRING_VECTOR unidentified_nominuses (unsigned Number, const char* Known, ...) const;
287  inline STRING_VECTOR unidentified_nominuses (const STRING_VECTOR& Knowns) const;
288  inline STRING_VECTOR unidentified_nominuses() const;
289 
290  // (*) output --------------------------------------------------------------
291  inline int print() const;
292 
293 private:
294  // (*) Type Declaration ----------------------------------------------------
295  struct variable
296  {
297  //-----------
298  // Variable to be specified on the command line or in input files.
299  // (i.e. of the form var='12 312 341')
300 
301  // -- constructors, destructors, assignment operator
302  variable();
303  variable (const variable&);
304  variable (const char* Name, const char* Value, const char* FieldSeparator);
305  ~variable();
306  variable& operator= (const variable& That);
307 
308  void take (const char* Value, const char* FieldSeparator);
309 
310  // -- get a specific element in the string vector
311  // (return 0 if not present)
312  const std::string* get_element (unsigned Idx) const;
313 
314  // -- data memebers
315  std::string name; // identifier of variable
316  STRING_VECTOR value; // value of variable stored in vector
317  std::string original; // value of variable as given on command line
318  };
319 
320  // (*) member variables --------------------------------------------------------------
321  std::string prefix; // prefix automatically added in queries
322  std::string section; // (for dollar bracket parsing)
323  STRING_VECTOR section_list; // list of all parsed sections
324  // -- argument vector
325  STRING_VECTOR argv; // vector of command line arguments stored as strings
326  unsigned cursor; // cursor for argv
327  bool search_loop_f; // shall search start at beginning after
328  // // reaching end of arg array ?
329  bool search_failed_f; // flag indicating a failed search() operation
330  // // (e.g. next() functions react with 'missed')
331 
332  // -- nominus vector
333  int nominus_cursor; // cursor for nominus_pointers
334  std::vector<unsigned> idx_nominus; // indecies of 'no minus' arguments
335 
336  // -- variables
337  // (arguments of the form "variable=value")
339 
340  // -- comment delimiters
341  std::string _comment_start;
342  std::string _comment_end;
343 
344  // -- field separator (separating elements of a vector)
345  std::string _field_separator;
346 
347  // -- some functions return a char pointer to a temporarily existing string
348  // this container makes them 'available' until the getpot object is destroyed.
350 
351  // -- keeping track about arguments that are requested, so that the UFO detection
352  // can be simplified
356 
357  bool __request_recording_f; // speed: request recording can be turned off
358 
359  // -- if an argument is requested record it and the 'tag' the section branch to which
360  // it belongs. Caution: both functions mark the sections as 'tagged'.
361  void __record_argument_request (const std::string& Arg);
362  void __record_variable_request (const std::string& Arg);
363 
364  // (*) helper functions ----------------------------------------------------
365  // set variable from inside GetPot (no prefix considered)
366  inline void __set_variable (const char* VarName, const char* Value);
367 
368  // -- produce three basic data vectors:
369  // - argument vector
370  // - nominus vector
371  // - variable dictionary
372  inline void __parse_argument_vector (const STRING_VECTOR& ARGV);
373 
374  // -- helpers for argument list processing
375  // * search for a variable in 'variables' array
376  inline const variable* __find_variable (const char*) const;
377  // * support finding directly followed arguments
378  inline const char* __match_starting_string (const char* StartString);
379  // * support search for flags in a specific argument
380  inline bool __check_flags (const std::string& Str, const char* FlagList) const;
381  // * type conversion if possible
382 
383  // BEGIN Cristiano Malossi - 05/05/2009
384  inline bool __convert_to_type (const std::string& String, bool Default) const;
385  // END Cristiano Malossi - 05/05/2009
386 
387  inline int __convert_to_type (const std::string& String, int Default) const;
388  inline double __convert_to_type (const std::string& String, double Default) const;
389  // * prefix extraction
390  const std::string __get_remaining_string (const std::string& String,
391  const std::string& Start) const;
392  // * search for a specific string
393  inline bool __search_string_vector (const STRING_VECTOR& Vec,
394  const std::string& Str) const;
395 
396  // -- helpers to parse input file
397  // create an argument vector based on data found in an input file, i.e.:
398  // 1) delete comments (in between '_comment_start' '_comment_end')
399  // 2) contract assignment expressions, such as
400  // my-variable = '007 J. B.'
401  // into
402  // my-variable='007 J. B.'
403  // 3) interprete sections like '[../my-section]' etc.
404  inline void __skip_whitespace (std::istream& istr);
405  inline const std::string __get_next_token (std::istream& istr);
406  inline const std::string __get_string (std::istream& istr);
407  inline const std::string __get_until_closing_bracket (std::istream& istr);
408 
409  inline STRING_VECTOR __read_in_stream (std::istream& istr);
410  inline STRING_VECTOR __read_in_file (const char* FileName);
411  inline std::string __process_section_label (const std::string& Section,
412  STRING_VECTOR& section_stack);
413 
414  // -- dollar bracket expressions
415  std::string __DBE_expand_string (const std::string str);
416  std::string __DBE_expand (const std::string str);
417  const GetPot::variable* __DBE_get_variable (const std::string str);
418  STRING_VECTOR __DBE_get_expr_list (const std::string str, const unsigned ExpectedNumber);
419 
420  std::string __double2string (const double& Value) const
421  {
422  // -- converts a double integer into a string
423  char* tmp = new char[128];
424 #ifndef WIN32
425  snprintf (tmp, (int) sizeof (char) * 128, "%e", Value);
426 #else
427  _snprintf (tmp, sizeof (char) * 128, "%e", Value);
428 #endif
429  std::string result (tmp);
430  delete [] tmp;
431  return result;
432  }
433 
434  std::string __int2string (const int& Value) const
435  {
436  // -- converts an integer into a string
437  char* tmp = new char[128];
438 #ifndef WIN32
439  snprintf (tmp, (int) sizeof (char) * 128, "%i", Value);
440 #else
441  _snprintf (tmp, sizeof (char) * 128, "%i", Value);
442 #endif
443  std::string result (tmp);
444  delete [] tmp;
445  return result;
446  }
447 
448  STRING_VECTOR __get_section_tree (const std::string& FullPath)
449  {
450  // -- cuts a variable name into a tree of sub-sections. this is requested for recording
451  // requested sections when dealing with 'ufo' detection.
452  STRING_VECTOR result;
453  const char* Start = FullPath.c_str();
454 
455  for (char* p = (char*) Start; *p ; p++)
456  {
457  if ( *p == '/' )
458  {
459  *p = '\0'; // set terminating zero for convinience
460  const std::string Section = Start;
461  *p = '/'; // reset slash at place
462  result.push_back (Section);
463  }
464  }
465 
466  return result;
467  }
468 };
469 
470 
471 ///////////////////////////////////////////////////////////////////////////////
472 // (*) constructors, destructor, assignment operator
473 //.............................................................................
474 //
475 inline void
477 {
478  cursor = 0;
479  nominus_cursor = -1;
480  search_failed_f = true;
481  search_loop_f = true;
482  prefix = "";
483  section = "";
484 
485  // automatic request recording for later ufo detection
486  __request_recording_f = true;
487 
488  // comment start and end strings
489  _comment_start = std::string ("#");
490  _comment_end = std::string ("\n");
491 
492  // default: separate vector elements by whitespaces
493  _field_separator = " \t\n";
494 }
495 
496 inline
498 {
500 
501  STRING_VECTOR _apriori_argv;
502  _apriori_argv.push_back (std::string ("Empty") );
503  __parse_argument_vector (_apriori_argv);
504 }
505 
506 inline
507 GetPot::GetPot (const int argc_, char** argv_,
508  const char* FieldSeparator /* =0x0 */)
509 // leave 'char**' non-const to honor less capable compilers ...
510 {
511  // TODO: Ponder over the problem when the argument list is of size = 0.
512  // This is 'sabotage', but it can still occur if the user specifies
513  // it himself.
514  assert (argc_ >= 1);
516 
517  // if specified -> overwrite default string
518  if ( FieldSeparator )
519  {
520  _field_separator = std::string (FieldSeparator);
521  }
522 
523  // -- make an internal copy of the argument list:
524  STRING_VECTOR _apriori_argv;
525  // -- for the sake of clarity: we do want to include the first argument in the argument vector !
526  // it will not be a nominus argument, though. This gives us a minimun vector size of one
527  // which facilitates error checking in many functions. Also the user will be able to
528  // retrieve the name of his application by "get[0]"
529  _apriori_argv.push_back (std::string (argv_[0]) );
530  int i = 1;
531  for (; i < argc_; ++i)
532  {
533  std::string tmp (argv_[i]); // recall the problem with temporaries,
534  _apriori_argv.push_back (tmp); // reference counting in arguement lists ...
535  }
536  __parse_argument_vector (_apriori_argv);
537 }
538 
539 
540 inline
541 GetPot::GetPot (const char* FileName,
542  const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */,
543  const char* FieldSeparator/* = 0x0 */)
544 {
546 
547  // if specified -> overwrite default strings
548  if ( CommentStart )
549  {
550  _comment_start = std::string (CommentStart);
551  }
552  if ( CommentEnd )
553  {
554  _comment_end = std::string (CommentEnd);
555  }
556  if ( FieldSeparator )
557  {
558  _field_separator = FieldSeparator;
559  }
560 
561  STRING_VECTOR _apriori_argv;
562  // -- file name is element of argument vector, however, it is not parsed for
563  // variable assignments or nominuses.
564  _apriori_argv.push_back (std::string (FileName) );
565 
566  STRING_VECTOR args = __read_in_file (FileName);
567  _apriori_argv.insert (_apriori_argv.begin() + 1, args.begin(), args.end() );
568  __parse_argument_vector (_apriori_argv);
569 }
570 
571 // BEGIN Cristiano Malossi- 30/03/2009
572 template <typename STRING>
573 inline
574 GetPot::GetPot (const STRING& FileName,
575  const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */,
576  const char* FieldSeparator/* = 0x0 */)
577 {
579 
580  // if specified -> overwrite default strings
581  if ( CommentStart )
582  {
583  _comment_start = std::string (CommentStart);
584  }
585  if ( CommentEnd )
586  {
587  _comment_end = std::string (CommentEnd);
588  }
589  if ( FieldSeparator )
590  {
591  _field_separator = FieldSeparator;
592  }
593 
594  STRING_VECTOR _apriori_argv;
595  // -- file name is element of argument vector, however, it is not parsed for
596  // variable assignments or nominuses.
597  _apriori_argv.push_back (std::string (FileName) );
598 
599  STRING_VECTOR args = __read_in_file (FileName.c_str() );
600  _apriori_argv.insert (_apriori_argv.begin() + 1, args.begin(), args.end() );
601  __parse_argument_vector (_apriori_argv);
602 }
603 // END Cristiano Malossi- 30/03/2009
604 
605 inline
606 GetPot::GetPot (const GetPot& That)
607 {
608  GetPot::operator= (That);
609 }
610 
611 inline
613 {
614  // may be some return strings had to be created, delete now !
615  victorate (char*, __internal_string_container, it)
616  delete [] *it;
617 }
618 
619 inline GetPot&
620 GetPot::operator= (const GetPot& That)
621 {
622  if (&That == this)
623  {
624  return *this;
625  }
626 
629  argv = That.argv;
630  variables = That.variables;
631  prefix = That.prefix;
632 
633  cursor = That.cursor;
636 
637  idx_nominus = That.idx_nominus;
639 
640  return *this;
641 }
642 
643 // BEGIN Luca Formaggia 29/12/2002
644 inline
645 GetPot::GetPot ( const STRING_VECTOR& FileNameList )
646  : cursor ( 0 ), search_loop_f ( true ), search_failed_f ( true ), nominus_cursor ( -1 )
647 {
648  STRING_VECTOR __argv;
649  __argv.push_back ( FileNameList[ 0 ] );
650  for ( STRING_VECTOR::const_iterator s = FileNameList.begin(); s != FileNameList.end(); ++s )
651  {
652  STRING_VECTOR args = __read_in_file ( s->c_str() );
653  __argv.insert ( __argv.end(), args.begin(), args.end() );
654  }
655  __parse_argument_vector ( __argv );
656 }
657 // END Luca Formaggia 29/12/2002
658 
659 inline void
660 GetPot::absorb (const GetPot& That)
661 {
662  if (&That == this)
663  {
664  return;
665  }
666 
667  STRING_VECTOR __tmp (That.argv);
668 
669  __tmp.erase (__tmp.begin() );
670 
672 }
673 
674 inline void
676 {
677  _requested_arguments.erase (_requested_arguments.begin(), _requested_arguments.end() );
678  _requested_variables.erase (_requested_variables.begin(), _requested_variables.end() );
679  _requested_sections.erase (_requested_sections.begin(), _requested_sections.end() );
680 }
681 
682 inline void
684 {
685  if ( ARGV.size() == 0 )
686  {
687  return;
688  }
689 
690  // build internal databases:
691  // 1) array with no-minus arguments (usually used as filenames)
692  // 2) variable assignments:
693  // 'variable name' '=' number | string
694  STRING_VECTOR section_stack;
695  STRING_VECTOR::const_iterator it = ARGV.begin();
696 
697 
698  section = "";
699 
700  // -- do not parse the first argument, so that it is not interpreted a s a nominus or so.
701  argv.push_back (*it);
702  ++it;
703 
704  // -- loop over remaining arguments
705  unsigned i = 1;
706  for (; it != ARGV.end(); ++it, ++i)
707  {
708  std::string arg = *it;
709 
710  if ( arg.length() == 0 )
711  {
712  continue;
713  }
714 
715  // -- [section] labels
716  if ( arg.length() > 1 && arg[0] == '[' && arg[arg.length() - 1] == ']' )
717  {
718 
719  // (*) sections are considered 'requested arguments'
720  if ( __request_recording_f )
721  {
722  _requested_arguments.push_back (arg);
723  }
724 
725  const std::string Name = __DBE_expand_string (arg.substr (1, arg.length() - 2) );
726  section = __process_section_label (Name, section_stack);
727  // new section --> append to list of sections
728  if ( find (section_list.begin(), section_list.end(), section) == section_list.end() )
729  if ( section.length() != 0 )
730  {
731  section_list.push_back (section);
732  }
733  argv.push_back (arg);
734  }
735  else
736  {
737  arg = section + __DBE_expand_string (arg);
738  argv.push_back (arg);
739  }
740 
741  // -- separate array for nominus arguments
742  if ( arg[0] != '-' )
743  {
744  idx_nominus.push_back (unsigned (i) );
745  }
746 
747  // -- variables: does arg contain a '=' operator ?
748  const char* p = arg.c_str();
749  for (; *p ; p++)
750  {
751  if ( *p == '=' )
752  {
753  // (*) record for later ufo detection
754  // arguments carriying variables are always treated as 'requested' arguments.
755  // as a whole! That is 'x=4712' is considered a requested argument.
756  //
757  // unrequested variables have to be detected with the ufo-variable
758  // detection routine.
759  if ( __request_recording_f )
760  {
761  _requested_arguments.push_back (arg);
762  }
763 
764  // set terminating 'zero' to treat first part as single string
765  // => arg (from start to 'p') = Name of variable
766  // p+1 (until terminating zero) = value of variable
767  char* o = (char*) p++;
768  *o = '\0'; // set temporary terminating zero
769  // __set_variable(...)
770  // calls __find_variable(...) which registers the search
771  // temporarily disable this
772  const bool tmp = __request_recording_f;
773  __request_recording_f = false;
774  __set_variable (arg.c_str(), p); // v-name = c_str() bis 'p', value = rest
775  __request_recording_f = tmp;
776  *o = '='; // reset the original '='
777  break;
778  }
779  }
780  }
781 }
782 
783 
784 inline STRING_VECTOR
785 GetPot::__read_in_file (const char* FileName)
786 {
787  std::ifstream i (FileName);
788  if ( ! i )
789  {
790  return STRING_VECTOR();
791  }
792  // argv[0] == the filename of the file that was read in
793  return __read_in_stream (i);
794 }
795 
796 inline STRING_VECTOR
797 GetPot::__read_in_stream (std::istream& istr)
798 {
799  STRING_VECTOR brute_tokens;
800  while (istr)
801  {
802  __skip_whitespace (istr);
803  const std::string Token = __get_next_token (istr);
804  if ( Token.length() == 0 || Token[0] == EOF)
805  {
806  break;
807  }
808  brute_tokens.push_back (Token);
809  }
810 
811  // -- reduce expressions of token1'='token2 to a single
812  // string 'token1=token2'
813  // -- copy everything into 'argv'
814  // -- arguments preceded by something like '[' name ']' (section)
815  // produce a second copy of each argument with a prefix '[name]argument'
816  unsigned i1 = 0;
817  unsigned i2 = 1;
818  unsigned i3 = 2;
819 
820  STRING_VECTOR arglist;
821  while ( i1 < brute_tokens.size() )
822  {
823  const std::string& SRef = brute_tokens[i1];
824  // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef'
825  // note: java.lang.String: substring(a,b) = from a to b-1
826  // C++ string: substr(a,b) = from a to a + b
827  if ( i2 < brute_tokens.size() && brute_tokens[i2] == "=" )
828  {
829  if ( i3 >= brute_tokens.size() )
830  {
831  arglist.push_back (brute_tokens[i1] + brute_tokens[i2]);
832  }
833  else
834  {
835  arglist.push_back (brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]);
836  }
837  i1 = i3 + 1;
838  i2 = i3 + 2;
839  i3 = i3 + 3;
840  continue;
841  }
842  else
843  {
844  arglist.push_back (SRef);
845  i1 = i2;
846  i2 = i3;
847  i3++;
848  }
849  }
850  return arglist;
851 }
852 
853 inline void
854 GetPot::__skip_whitespace (std::istream& istr)
855 // find next non-whitespace while deleting comments
856 {
857  int tmp = istr.get();
858  do
859  {
860  // -- search a non whitespace
861  while ( isspace (tmp) )
862  {
863  tmp = istr.get();
864  if ( ! istr )
865  {
866  return;
867  }
868  }
869 
870  // -- look if characters match the comment starter string
871  unsigned i = 0;
872  for (; i < _comment_start.length() ; ++i)
873  {
874  if ( tmp != _comment_start[i] )
875  {
876  // NOTE: Due to a 'strange behavior' in Microsoft's streaming lib we do
877  // a series of unget()s instead a quick seek. See
878  // http://sourceforge.net/tracker/index.php?func=detail&aid=1545239&group_id=31994&atid=403915
879  // for a detailed discussion.
880 
881  // -- one step more backwards, since 'tmp' already at non-whitespace
882  do
883  {
884  istr.unget();
885  }
886  while ( i-- != 0 );
887  return;
888  }
889  tmp = istr.get();
890  if ( ! istr )
891  {
892  istr.unget();
893  return;
894  }
895  }
896  // 'tmp' contains last character of _comment_starter
897 
898  // -- comment starter found -> search for comment ender
899  unsigned match_no = 0;
900  while (1 + 1 == 2)
901  {
902  tmp = istr.get();
903  if ( ! istr )
904  {
905  istr.unget();
906  return;
907  }
908 
909  if ( tmp == _comment_end[match_no] )
910  {
911  match_no++;
912  if ( match_no == _comment_end.length() )
913  {
914  istr.unget();
915  break; // shuffle more whitespace, end of comment found
916  }
917  }
918  else
919  {
920  match_no = 0;
921  }
922  }
923 
924  tmp = istr.get();
925 
926  }
927  while ( istr );
928  istr.unget();
929 }
930 
931 inline const std::string
932 GetPot::__get_next_token (std::istream& istr)
933 // get next concatinates string token. consider quotes that embrace
934 // whitespaces
935 {
936  std::string token;
937  int tmp = 0;
938  int last_letter = 0;
939  while (1 + 1 == 2)
940  {
941  last_letter = tmp;
942  tmp = istr.get();
943  if ( tmp == EOF
944  || ( (tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') )
945  {
946  return token;
947  }
948  else if ( tmp == '\'' && last_letter != '\\' )
949  {
950  // QUOTES: un-backslashed quotes => it's a string
951  token += __get_string (istr);
952  continue;
953  }
954  else if ( tmp == '{' && last_letter == '$')
955  {
956  token += '{' + __get_until_closing_bracket (istr);
957  continue;
958  }
959  else if ( tmp == '$' && last_letter == '\\')
960  {
961  token += tmp;
962  tmp = 0; // so that last_letter will become = 0, not '$';
963  continue;
964  }
965  else if ( tmp == '\\' && last_letter != '\\')
966  {
967  continue; // don't append un-backslashed backslashes
968  }
969  token += tmp;
970  }
971  return token;
972 }
973 
974 inline const std::string
975 GetPot::__get_string (std::istream& istr)
976 // parse input until next matching '
977 {
978  std::string str;
979  int tmp = 0;
980  int last_letter = 0;
981  while (1 + 1 == 2)
982  {
983  last_letter = tmp;
984  tmp = istr.get();
985  if ( tmp == EOF)
986  {
987  return str;
988  }
989  // un-backslashed quotes => it's the end of the string
990  else if ( tmp == '\'' && last_letter != '\\')
991  {
992  return str;
993  }
994  else if ( tmp == '\\' && last_letter != '\\')
995  {
996  continue; // don't append
997  }
998 
999  str += tmp;
1000  }
1001  return str;
1002 }
1003 
1004 inline const std::string
1006 // parse input until next matching }
1007 {
1008  std::string str = "";
1009  int tmp = 0;
1010  int last_letter = 0;
1011  int brackets = 1;
1012  while (1 + 1 == 2)
1013  {
1014  last_letter = tmp;
1015  tmp = istr.get();
1016  if ( tmp == EOF)
1017  {
1018  return str;
1019  }
1020  else if ( tmp == '{' && last_letter == '$')
1021  {
1022  brackets += 1;
1023  }
1024  else if ( tmp == '}')
1025  {
1026  brackets -= 1;
1027  // un-backslashed brackets => it's the end of the string
1028  if ( brackets == 0)
1029  {
1030  return str + '}';
1031  }
1032  else if ( tmp == '\\' && last_letter != '\\')
1033  {
1034  continue; // do not append an unbackslashed backslash
1035  }
1036  }
1037  str += tmp;
1038  }
1039  return str;
1040 }
1041 
1042 inline std::string
1043 GetPot::__process_section_label (const std::string& Section,
1044  STRING_VECTOR& section_stack)
1045 {
1046  std::string sname = Section;
1047  // 1) subsection of actual section ('./' prefix)
1048  if ( sname.length() >= 2 && sname.substr (0, 2) == "./" )
1049  {
1050  sname = sname.substr (2);
1051  }
1052  // 2) subsection of parent section ('../' prefix)
1053  else if ( sname.length() >= 3 && sname.substr (0, 3) == "../" )
1054  {
1055  do
1056  {
1057  if ( section_stack.end() != section_stack.begin() )
1058  {
1059  section_stack.pop_back();
1060  }
1061  sname = sname.substr (3);
1062  }
1063  while ( sname.substr (0, 3) == "../" );
1064  }
1065  // 3) subsection of the root-section
1066  else
1067  {
1068  section_stack.erase (section_stack.begin(), section_stack.end() );
1069  // [] => back to root section
1070  }
1071 
1072  if ( sname != "" )
1073  {
1074  // parse section name for 'slashes'
1075  unsigned i = 0;
1076  while ( i < sname.length() )
1077  {
1078  if ( sname[i] == '/' )
1079  {
1080  section_stack.push_back (sname.substr (0, i) );
1081  if ( i + 1 < sname.length() )
1082  {
1083  sname = sname.substr (i + 1);
1084  }
1085  i = 0;
1086  }
1087  else
1088  {
1089  ++i;
1090  }
1091  }
1092  section_stack.push_back (sname);
1093  }
1094  std::string section = "";
1095  if ( section_stack.size() != 0 )
1096  {
1097  victorate (std::string, section_stack, it)
1098  section += *it + "/";
1099  }
1100  return section;
1101 }
1102 
1103 // BEGIN Cristiano Malossi - 05/05/2009
1104 // convert string to BOOL, if not possible return Default
1105 inline bool
1106 GetPot::__convert_to_type (const std::string& String, bool Default) const
1107 {
1108  if (String.compare ( "false" ) == 0)
1109  {
1110  return false;
1111  }
1112  if (String.compare ( "true" ) == 0)
1113  {
1114  return true;
1115  }
1116  else
1117  {
1118  return Default;
1119  }
1120 }
1121 // END Cristiano Malossi - 05/05/2009
1122 
1123 // convert string to DOUBLE, if not possible return Default
1124 inline double
1125 GetPot::__convert_to_type (const std::string& String, double Default) const
1126 {
1127  double tmp;
1128  if ( sscanf (String.c_str(), "%lf", &tmp) != 1 )
1129  {
1130  return Default;
1131  }
1132  return tmp;
1133 }
1134 
1135 // convert string to INT, if not possible return Default
1136 inline int
1137 GetPot::__convert_to_type (const std::string& String, int Default) const
1138 {
1139  // NOTE: intermediate results may be floating points, so that the string
1140  // may look like 2.0e1 (i.e. float format) => use float conversion
1141  // in any case.
1142  return (int) __convert_to_type (String, (double) Default);
1143 }
1144 
1145 //////////////////////////////////////////////////////////////////////////////
1146 // (*) cursor oriented functions
1147 //.............................................................................
1148 inline const std::string
1149 GetPot::__get_remaining_string (const std::string& String, const std::string& Start) const
1150 // Checks if 'String' begins with 'Start' and returns the remaining String.
1151 // Returns None if String does not begin with Start.
1152 {
1153  if ( Start == "" )
1154  {
1155  return String;
1156  }
1157  // note: java.lang.String: substring(a,b) = from a to b-1
1158  // C++ string: substr(a,b) = from a to a + b
1159  if ( String.find (Start) == 0 )
1160  {
1161  return String.substr (Start.length() );
1162  }
1163  else
1164  {
1165  return "";
1166  }
1167 }
1168 
1169 // -- search for a certain argument and set cursor to position
1170 inline bool
1171 GetPot::search (const char* Option)
1172 {
1173  unsigned OldCursor = cursor;
1174  const std::string SearchTerm = prefix + Option;
1175 
1176  // (*) record requested arguments for later ufo detection
1177  __record_argument_request (SearchTerm);
1178 
1179  if ( OldCursor >= argv.size() )
1180  {
1181  OldCursor = static_cast<unsigned int> (argv.size() ) - 1;
1182  }
1183  search_failed_f = true;
1184 
1185  // (*) first loop from cursor position until end
1186  unsigned c = cursor;
1187  for (; c < argv.size(); c++)
1188  {
1189  if ( argv[c] == SearchTerm )
1190  {
1191  cursor = c;
1192  search_failed_f = false;
1193  return true;
1194  }
1195  }
1196  if ( ! search_loop_f )
1197  {
1198  return false;
1199  }
1200 
1201  // (*) second loop from 0 to old cursor position
1202  for (c = 1; c < OldCursor; c++)
1203  {
1204  if ( argv[c] == SearchTerm )
1205  {
1206  cursor = c;
1207  search_failed_f = false;
1208  return true;
1209  }
1210  }
1211  // in case nothing is found the cursor stays where it was
1212  return false;
1213 }
1214 
1215 
1216 inline bool
1217 GetPot::search (unsigned No, const char* P, ...)
1218 {
1219  // (*) recording the requested arguments happens in subroutine 'search'
1220  if ( No == 0 )
1221  {
1222  return false;
1223  }
1224 
1225  // search for the first argument
1226  if ( search (P) == true )
1227  {
1228  return true;
1229  }
1230 
1231  // start interpreting variable argument list
1232  va_list ap;
1233  va_start (ap, P);
1234  unsigned i = 1;
1235  for (; i < No; ++i)
1236  {
1237  char* Opt = va_arg (ap, char*);
1238  if ( search (Opt) == true )
1239  {
1240  break;
1241  }
1242  }
1243 
1244  if ( i < No )
1245  {
1246  ++i;
1247  // loop was left before end of array --> hit but
1248  // make sure that the rest of the search terms is marked
1249  // as requested.
1250  for (; i < No; ++i)
1251  {
1252  char* Opt = va_arg (ap, char*);
1253  // (*) record requested arguments for later ufo detection
1254  __record_argument_request (Opt);
1255  }
1256  va_end (ap);
1257  return true;
1258  }
1259 
1260  va_end (ap);
1261  // loop was left normally --> no hit
1262  return false;
1263 }
1264 
1265 inline void
1267 {
1268  search_failed_f = false;
1269  cursor = 0;
1270 }
1271 
1272 inline void
1274 {
1277 }
1278 ///////////////////////////////////////////////////////////////////////////////
1279 // (*) direct access to command line arguments
1280 //.............................................................................
1281 //
1282 inline const std::string
1283 GetPot::operator[] (unsigned idx) const
1284 {
1285  return idx < argv.size() ? argv[idx] : "";
1286 }
1287 
1288 inline int
1289 GetPot::get (unsigned Idx, int Default) const
1290 {
1291  if ( Idx >= argv.size() )
1292  {
1293  return Default;
1294  }
1295  return __convert_to_type (argv[Idx], Default);
1296 }
1297 
1298 inline double
1299 GetPot::get (unsigned Idx, const double& Default) const
1300 {
1301  if ( Idx >= argv.size() )
1302  {
1303  return Default;
1304  }
1305  return __convert_to_type (argv[Idx], Default);
1306 }
1307 
1308 inline const std::string
1309 GetPot::get (unsigned Idx, const char* Default) const
1310 {
1311  if ( Idx >= argv.size() )
1312  {
1313  return Default;
1314  }
1315  else
1316  {
1317  return argv[Idx];
1318  }
1319 }
1320 
1321 inline unsigned
1322 GetPot::size() const
1323 {
1324  return static_cast<unsigned int> (argv.size() );
1325 }
1326 
1327 
1328 // -- next() function group
1329 inline int
1330 GetPot::next (int Default)
1331 {
1332  if ( search_failed_f )
1333  {
1334  return Default;
1335  }
1336  cursor++;
1337  if ( cursor >= argv.size() )
1338  {
1339  cursor = static_cast<unsigned int> (argv.size() );
1340  return Default;
1341  }
1342 
1343  // (*) record requested argument for later ufo detection
1344  __record_argument_request (argv[cursor]);
1345 
1346  const std::string Remain = __get_remaining_string (argv[cursor], prefix);
1347 
1348  return Remain != "" ? __convert_to_type (Remain, Default) : Default;
1349 }
1350 
1351 inline double
1352 GetPot::next (const double& Default)
1353 {
1354  if ( search_failed_f )
1355  {
1356  return Default;
1357  }
1358  cursor++;
1359 
1360  if ( cursor >= argv.size() )
1361  {
1362  cursor = static_cast<unsigned int> (argv.size() );
1363  return Default;
1364  }
1365 
1366  // (*) record requested argument for later ufo detection
1367  __record_argument_request (argv[cursor]);
1368 
1369  std::string Remain = __get_remaining_string (argv[cursor], prefix);
1370 
1371  return Remain != "" ? __convert_to_type (Remain, Default) : Default;
1372 }
1373 
1374 inline const std::string
1375 GetPot::next (const char* Default)
1376 {
1377  using namespace std;
1378 
1379  if ( search_failed_f )
1380  {
1381  return Default;
1382  }
1383  cursor++;
1384 
1385  if ( cursor >= argv.size() )
1386  {
1387  cursor = static_cast<unsigned int> (argv.size() );
1388  return Default;
1389  }
1390 
1391  // (*) record requested argument for later ufo detection
1392  __record_argument_request (argv[cursor]);
1393 
1394  const std::string Remain = __get_remaining_string (argv[cursor], prefix);
1395 
1396  if ( Remain == "" )
1397  {
1398  return Default;
1399  }
1400 
1401 
1402  // (*) function returns a pointer to a char array (inside Remain)
1403  // this array will be deleted, though after this function call.
1404  // To ensure propper functioning, create a copy inside *this
1405  // object and only delete it, when *this is deleted.
1406  char* result = new char[Remain.length() + 1];
1407  strncpy (result, Remain.c_str(), Remain.length() + 1);
1408 
1409  // store the created string internally, delete if when object deleted
1410  __internal_string_container.push_back (result);
1411 
1412  return result;
1413 }
1414 
1415 // -- follow() function group
1416 // distinct option to be searched for
1417 inline int
1418 GetPot::follow (int Default, const char* Option)
1419 {
1420  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1421  if ( search (Option) == false )
1422  {
1423  return Default;
1424  }
1425  return next (Default);
1426 }
1427 
1428 inline double
1429 GetPot::follow (const double& Default, const char* Option)
1430 {
1431  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1432  if ( search (Option) == false )
1433  {
1434  return Default;
1435  }
1436  return next (Default);
1437 }
1438 
1439 inline const std::string
1440 GetPot::follow (const char* Default, const char* Option)
1441 {
1442  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1443  if ( search (Option) == false )
1444  {
1445  return Default;
1446  }
1447  return next (Default);
1448 }
1449 
1450 // -- second follow() function group
1451 // multiple option to be searched for
1452 inline int
1453 GetPot::follow (int Default, unsigned No, const char* P, ...)
1454 {
1455  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1456  if ( No == 0 )
1457  {
1458  return Default;
1459  }
1460  if ( search (P) == true )
1461  {
1462  return next (Default);
1463  }
1464 
1465  va_list ap;
1466  va_start (ap, P);
1467  unsigned i = 1;
1468  for (; i < No; ++i)
1469  {
1470  char* Opt = va_arg (ap, char*);
1471  if ( search (Opt) == true )
1472  {
1473  va_end (ap);
1474  return next (Default);
1475  }
1476  }
1477  va_end (ap);
1478  return Default;
1479 }
1480 
1481 inline double
1482 GetPot::follow (const double& Default, unsigned No, const char* P, ...)
1483 {
1484  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1485  if ( No == 0 )
1486  {
1487  return Default;
1488  }
1489  if ( search (P) == true )
1490  {
1491  return next (Default);
1492  }
1493 
1494  va_list ap;
1495  va_start (ap, P);
1496  for (unsigned i = 1; i < No; ++i)
1497  {
1498  char* Opt = va_arg (ap, char*);
1499  if ( search (Opt) == true )
1500  {
1501  va_end (ap);
1502  return next (Default);
1503  }
1504  }
1505  va_end (ap);
1506  return Default;
1507 }
1508 
1509 inline const std::string
1510 GetPot::follow (const char* Default, unsigned No, const char* P, ...)
1511 {
1512  // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1513  if ( No == 0 )
1514  {
1515  return Default;
1516  }
1517  if ( search (P) == true )
1518  {
1519  return next (Default);
1520  }
1521 
1522  va_list ap;
1523  va_start (ap, P);
1524  unsigned i = 1;
1525  for (; i < No; ++i)
1526  {
1527  char* Opt = va_arg (ap, char*);
1528  if ( search (Opt) == true )
1529  {
1530  va_end (ap);
1531  return next (Default);
1532  }
1533  }
1534  va_end (ap);
1535  return Default;
1536 }
1537 
1538 
1539 ///////////////////////////////////////////////////////////////////////////////
1540 // (*) lists of nominus following an option
1541 //.............................................................................
1542 //
1543 inline std::vector<std::string>
1545 {
1546  std::vector<std::string> result_list;
1547  if ( search (Option) == false )
1548  {
1549  return result_list;
1550  }
1551  while ( 1 + 1 == 2 )
1552  {
1553  ++cursor;
1554  if ( cursor >= argv.size() )
1555  {
1556  cursor = argv.size() - 1;
1557  return result_list;
1558  }
1559  if ( argv[cursor].length() >= 1 )
1560  {
1561  if ( argv[cursor][0] == '-' )
1562  {
1563  return result_list;
1564  }
1565  // -- record for later ufo-detection
1566  __record_argument_request (argv[cursor]);
1567  // -- append to the result list
1568  result_list.push_back (argv[cursor]);
1569  }
1570  }
1571  return result_list;
1572 }
1573 
1574 inline std::vector<std::string>
1575 GetPot::nominus_followers (unsigned No, ...)
1576 {
1577  std::vector<std::string> result_list;
1578  // (*) record requested of argument is entirely handled in 'search()'
1579  // and 'nominus_followers()'
1580  if ( No == 0 )
1581  {
1582  return result_list;
1583  }
1584 
1585  va_list ap;
1586  va_start (ap, No);
1587  for (unsigned i = 0; i < No; ++i)
1588  {
1589  char* Option = va_arg (ap, char*);
1590  std::vector<std::string> tmp = nominus_followers (Option);
1591  result_list.insert (result_list.end(), tmp.begin(), tmp.end() );
1592 
1593  // std::cerr << "option = '" << Option << "'" << std::endl;
1594  // std::cerr << "length = " << tmp.size() << std::endl;
1595  // std::cerr << "new result list = <";
1596  // for(std::vector<std::string>::const_iterator it = result_list.begin();
1597  // it != result_list.end(); ++it)
1598  // std::cerr << *it << ", ";
1599  // std::cerr << ">\n";
1600  }
1601  va_end (ap);
1602  return result_list;
1603 }
1604 
1605 
1606 ///////////////////////////////////////////////////////////////////////////////
1607 // (*) directly connected options
1608 //.............................................................................
1609 //
1610 inline int
1611 GetPot::direct_follow (int Default, const char* Option)
1612 {
1613  const char* FollowStr = __match_starting_string (Option);
1614  if ( FollowStr == 0x0 )
1615  {
1616  return Default;
1617  }
1618 
1619  // (*) record requested of argument for later ufo-detection
1620  __record_argument_request (std::string (Option) + FollowStr);
1621 
1622  if ( ++cursor >= static_cast<unsigned int> (argv.size() ) )
1623  {
1624  cursor = static_cast<unsigned int> (argv.size() );
1625  }
1626  return __convert_to_type (FollowStr, Default);
1627 }
1628 
1629 inline double
1630 GetPot::direct_follow (const double& Default, const char* Option)
1631 {
1632  const char* FollowStr = __match_starting_string (Option);
1633  if ( FollowStr == 0 )
1634  {
1635  return Default;
1636  }
1637 
1638  // (*) record requested of argument for later ufo-detection
1639  __record_argument_request (std::string (Option) + FollowStr);
1640 
1641  if ( ++cursor >= static_cast<unsigned int> (argv.size() ) )
1642  {
1643  cursor = static_cast<unsigned int> (argv.size() );
1644  }
1645  return __convert_to_type (FollowStr, Default);
1646 }
1647 
1648 inline const std::string
1649 GetPot::direct_follow (const char* Default, const char* Option)
1650 {
1651  if ( search_failed_f )
1652  {
1653  return Default;
1654  }
1655  const char* FollowStr = __match_starting_string (Option);
1656  if ( FollowStr == 0 )
1657  {
1658  return Default;
1659  }
1660 
1661  // (*) record requested of argument for later ufo-detection
1662  if ( FollowStr )
1663  {
1664  __record_argument_request (std::string (Option) + FollowStr);
1665  }
1666 
1667  if ( ++cursor >= static_cast<unsigned int> (argv.size() ) )
1668  {
1669  cursor = static_cast<unsigned int> (argv.size() );
1670  }
1671  return std::string (FollowStr);
1672 }
1673 
1674 inline std::vector<std::string>
1676 {
1677  std::vector<std::string> result;
1678  const unsigned N = static_cast<unsigned int> (strlen (StartString) );
1679 
1680  std::vector<std::string>::iterator it = argv.begin();
1681 
1682  unsigned idx = 0;
1683  while ( it != argv.end() )
1684  {
1685  // (*) does start string match the given option?
1686  // NO -> goto next option
1687  if ( strncmp (StartString, (*it).c_str(), N) != 0)
1688  {
1689  ++it;
1690  ++idx;
1691  continue;
1692  }
1693 
1694  // append the found tail to the result vector
1695  result.push_back ( (*it).substr (N) );
1696 
1697  // adapt the nominus vector
1698  std::vector<unsigned>::iterator nit = idx_nominus.begin();
1699  for (; nit != idx_nominus.end(); ++nit)
1700  {
1701  if ( *nit == idx )
1702  {
1703  idx_nominus.erase (nit);
1704  for (; nit != idx_nominus.end(); ++nit)
1705  {
1706  *nit -= 1;
1707  }
1708  break;
1709  }
1710  }
1711 
1712  // erase the found option
1713  argv.erase (it);
1714 
1715  // 100% safe solution: set iterator back to the beginning.
1716  // (normally, 'it--' would be enough, but who knows how the
1717  // iterator is implemented and .erase() definitely invalidates
1718  // the current iterator position.
1719  if ( argv.empty() )
1720  {
1721  break;
1722  }
1723  it = argv.begin();
1724  }
1725  cursor = 0;
1726  nominus_cursor = -1;
1727  return result;
1728 }
1729 
1730 inline std::vector<int>
1731 GetPot::int_tails (const char* StartString, const int Default /* = -1 */)
1732 {
1733  std::vector<int> result;
1734  const unsigned N = static_cast<unsigned int> (strlen (StartString) );
1735 
1736  std::vector<std::string>::iterator it = argv.begin();
1737 
1738  unsigned idx = 0;
1739  while ( it != argv.end() )
1740  {
1741  // (*) does start string match the given option?
1742  // NO -> goto next option
1743  if ( strncmp (StartString, (*it).c_str(), N) != 0)
1744  {
1745  ++it;
1746  ++idx;
1747  continue;
1748  }
1749 
1750  // append the found tail to the result vector
1751  result.push_back (__convert_to_type ( (*it).substr (N), Default) );
1752 
1753  // adapt the nominus vector
1754  std::vector<unsigned>::iterator nit = idx_nominus.begin();
1755  for (; nit != idx_nominus.end(); ++nit)
1756  {
1757  if ( *nit == idx )
1758  {
1759  idx_nominus.erase (nit);
1760  for (; nit != idx_nominus.end(); ++nit)
1761  {
1762  *nit -= 1;
1763  }
1764  break;
1765  }
1766  }
1767 
1768  // erase the found option
1769  argv.erase (it);
1770 
1771  // 100% safe solution: set iterator back to the beginning.
1772  // (normally, 'it--' would be enough, but who knows how the
1773  // iterator is implemented and .erase() definitely invalidates
1774  // the current iterator position.
1775  if ( argv.empty() )
1776  {
1777  break;
1778  }
1779  it = argv.begin();
1780  }
1781  cursor = 0;
1782  nominus_cursor = -1;
1783  return result;
1784 }
1785 
1786 inline std::vector<double>
1788  const double Default /* = -1.0 */)
1789 {
1790  std::vector<double> result;
1791  const unsigned N = static_cast<unsigned int> (strlen (StartString) );
1792 
1793  std::vector<std::string>::iterator it = argv.begin();
1794  unsigned idx = 0;
1795  while ( it != argv.end() )
1796  {
1797  // (*) does start string match the given option?
1798  // NO -> goto next option
1799  if ( strncmp (StartString, (*it).c_str(), N) != 0)
1800  {
1801  ++it;
1802  ++idx;
1803  continue;
1804  }
1805 
1806  // append the found tail to the result vector
1807  result.push_back (__convert_to_type ( (*it).substr (N), Default) );
1808 
1809  // adapt the nominus vector
1810  std::vector<unsigned>::iterator nit = idx_nominus.begin();
1811  for (; nit != idx_nominus.end(); ++nit)
1812  {
1813  if ( *nit == idx )
1814  {
1815  idx_nominus.erase (nit);
1816  for (; nit != idx_nominus.end(); ++nit)
1817  {
1818  *nit -= 1;
1819  }
1820  break;
1821  }
1822  }
1823 
1824  // erase the found option
1825  argv.erase (it);
1826 
1827  // 100% safe solution: set iterator back to the beginning.
1828  // (normally, 'it--' would be enough, but who knows how the
1829  // iterator is implemented and .erase() definitely invalidates
1830  // the current iterator position.
1831  if ( argv.empty() )
1832  {
1833  break;
1834  }
1835  it = argv.begin();
1836  }
1837  cursor = 0;
1838  nominus_cursor = -1;
1839  return result;
1840 }
1841 
1842 
1843 
1844 
1845 
1846 inline const char*
1847 GetPot::__match_starting_string (const char* StartString)
1848 // pointer to the place where the string after
1849 // the match inside the found argument starts.
1850 // 0 no argument matches the starting string.
1851 {
1852  const unsigned N = static_cast<unsigned int> (strlen (StartString) );
1853  unsigned OldCursor = cursor;
1854 
1855  if ( OldCursor >= static_cast<unsigned int> (argv.size() ) )
1856  {
1857  OldCursor = static_cast<unsigned int> (argv.size() ) - 1;
1858  }
1859  search_failed_f = true;
1860 
1861  // (*) first loop from cursor position until end
1862  unsigned c = cursor;
1863  for (; c < argv.size(); c++)
1864  {
1865  if ( strncmp (StartString, argv[c].c_str(), N) == 0)
1866  {
1867  cursor = c;
1868  search_failed_f = false;
1869  return & (argv[c].c_str() [N]);
1870  }
1871  }
1872 
1873  if ( ! search_loop_f )
1874  {
1875  return 0;
1876  }
1877 
1878  // (*) second loop from 0 to old cursor position
1879  for (c = 1; c < OldCursor; c++)
1880  {
1881  if ( strncmp (StartString, argv[c].c_str(), N) == 0)
1882  {
1883  cursor = c;
1884  search_failed_f = false;
1885  return & (argv[c].c_str() [N]);
1886  }
1887  }
1888  return 0;
1889 }
1890 
1891 ///////////////////////////////////////////////////////////////////////////////
1892 // (*) search for flags
1893 //.............................................................................
1894 //
1895 inline bool
1896 GetPot::options_contain (const char* FlagList) const
1897 {
1898  // go through all arguments that start with a '-' (but not '--')
1899  std::string str;
1900  STRING_VECTOR::const_iterator it = argv.begin();
1901  for (; it != argv.end(); ++it)
1902  {
1903  str = __get_remaining_string (*it, prefix);
1904 
1905  if ( str.length() >= 2 && str[0] == '-' && str[1] != '-' )
1906  if ( __check_flags (str, FlagList) )
1907  {
1908  return true;
1909  }
1910  }
1911  return false;
1912 }
1913 
1914 inline bool
1915 GetPot::argument_contains (unsigned Idx, const char* FlagList) const
1916 {
1917  if ( Idx >= argv.size() )
1918  {
1919  return false;
1920  }
1921 
1922  // (*) record requested of argument for later ufo-detection
1923  // an argument that is checked for flags is considered to be 'requested'
1924  ( (GetPot*) this)->__record_argument_request (argv[Idx]);
1925 
1926  if ( prefix == "" )
1927  // search argument for any flag in flag list
1928  {
1929  return __check_flags (argv[Idx], FlagList);
1930  }
1931 
1932  // if a prefix is set, then the argument index is the index
1933  // inside the 'namespace'
1934  // => only check list of arguments that start with prefix
1935  unsigned no_matches = 0;
1936  unsigned i = 0;
1937  for (; i < argv.size(); ++i)
1938  {
1939  const std::string Remain = __get_remaining_string (argv[i], prefix);
1940  if ( Remain != "")
1941  {
1942  no_matches += 1;
1943  if ( no_matches == Idx)
1944  {
1945  return __check_flags (Remain, FlagList);
1946  }
1947  }
1948  }
1949  // no argument in this namespace
1950  return false;
1951 }
1952 
1953 inline bool
1954 GetPot::__check_flags (const std::string& Str, const char* FlagList) const
1955 {
1956  const char* p = FlagList;
1957  for (; *p != '\0' ; p++)
1958  if ( Str.find (*p) != std::string::npos )
1959  {
1960  return true; // found something
1961  }
1962  return false;
1963 }
1964 
1965 ///////////////////////////////////////////////////////////////////////////////
1966 // (*) nominus arguments
1967 inline STRING_VECTOR
1969 // return vector of nominus arguments
1970 {
1971  STRING_VECTOR nv;
1972  std::vector<unsigned>::const_iterator it = idx_nominus.begin();
1973  for (; it != idx_nominus.end(); ++it)
1974  {
1975  nv.push_back (argv[*it]);
1976 
1977  // (*) record for later ufo-detection
1978  // when a nominus vector is requested, the entire set of nominus arguments are
1979  // tagged as 'requested'
1980  ( (GetPot*) this)->__record_argument_request (argv[*it]);
1981  }
1982  return nv;
1983 }
1984 
1985 inline std::string
1987 {
1988  if ( nominus_cursor < int (idx_nominus.size() ) - 1 )
1989  {
1990  const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
1991 
1992  // (*) record for later ufo-detection
1994 
1995  // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer
1996  // to something that does no longer exist.
1997  return Tmp;
1998  }
1999  return std::string ("");
2000 }
2001 
2002 ///////////////////////////////////////////////////////////////////////////////
2003 // (*) variables
2004 //.............................................................................
2005 //
2006 // BEGIN Cristiano Malossi - 05/05/2009
2007 inline bool
2008 GetPot::operator() (const char* VarName, bool Default) const
2009 {
2010  // (*) recording of requested variables happens in '__find_variable()'
2011  const variable* sv = __find_variable (VarName);
2012  if ( sv == 0 )
2013  {
2014  return Default;
2015  }
2016  return __convert_to_type (sv->original, Default);
2017 }
2018 // END Cristiano Malossi - 05/05/2009
2019 
2020 inline int
2021 GetPot::operator() (const char* VarName, int Default) const
2022 {
2023  // (*) recording of requested variables happens in '__find_variable()'
2024  const variable* sv = __find_variable (VarName);
2025  if ( sv == 0 )
2026  {
2027  return Default;
2028  }
2029  return __convert_to_type (sv->original, Default);
2030 }
2031 
2032 inline double
2033 GetPot::operator() (const char* VarName, const double& Default) const
2034 {
2035  // (*) recording of requested variables happens in '__find_variable()'
2036  const variable* sv = __find_variable (VarName);
2037  if ( sv == 0 )
2038  {
2039  return Default;
2040  }
2041  return __convert_to_type (sv->original, Default);
2042 }
2043 
2044 inline const std::string
2045 GetPot::operator() (const char* VarName, const char* Default) const
2046 {
2047  // (*) recording of requested variables happens in '__find_variable()'
2048  const variable* sv = __find_variable (VarName);
2049  if ( sv == 0 )
2050  {
2051  return Default;
2052  }
2053  // -- returning a c_str() pointer is OK here, since the variable remains existant,
2054  // while 'sv' of course is delete at the end of the function.
2055  return sv->original;
2056 }
2057 
2058 // BEGIN Gilles Fourestey - 05/11/2009
2059 inline bool
2060 GetPot::operator() (const char* VarName, bool Default, bool& found) const
2061 {
2062  // (*) recording of requested variables happens in '__find_variable()'
2063  found = false;
2064  const variable* sv = __find_variable (VarName);
2065  if ( sv == 0 )
2066  {
2067  return Default;
2068  }
2069  found = true;
2070  return __convert_to_type (sv->original, Default);
2071 }
2072 
2073 inline int
2074 GetPot::operator() (const char* VarName, int Default, bool& found) const
2075 {
2076  // (*) recording of requested variables happens in '__find_variable()'
2077  found = false;
2078  const variable* sv = __find_variable (VarName);
2079  if ( sv == 0 )
2080  {
2081  return Default;
2082  }
2083  found = true;
2084  return __convert_to_type (sv->original, Default);
2085 }
2086 
2087 inline double
2088 GetPot::operator() (const char* VarName, const double& Default, bool& found) const
2089 {
2090  // (*) recording of requested variables happens in '__find_variable()'
2091  found = false;
2092  const variable* sv = __find_variable (VarName);
2093  if ( sv == 0 )
2094  {
2095  return Default;
2096  }
2097  found = true;
2098  return __convert_to_type (sv->original, Default);
2099 }
2100 inline const std::string
2101 GetPot::operator() (const char* VarName, const char* Default, bool& found) const
2102 {
2103  // (*) recording of requested variables happens in '__find_variable()'
2104  found = false;
2105  const variable* sv = __find_variable (VarName);
2106  if ( sv == 0 )
2107  {
2108  return Default;
2109  }
2110  // -- returning a c_str() pointer is OK here, since the variable remains existant,
2111  // while 'sv' of course is delete at the end of the function.
2112  found = true;
2113  return sv->original;
2114 }
2115 // ENG Gilles Fourestey - 05/11/2009
2116 
2117 // BEGIN Cristiano Malossi - 05/05/2009
2118 inline bool
2119 GetPot::operator() (const char* VarName, bool Default, unsigned Idx) const
2120 {
2121  // (*) recording of requested variables happens in '__find_variable()'
2122  const variable* sv = __find_variable (VarName);
2123  if ( sv == 0 )
2124  {
2125  return Default;
2126  }
2127  const std::string* element = sv->get_element (Idx);
2128  if ( element == 0 )
2129  {
2130  return Default;
2131  }
2132  return __convert_to_type (*element, Default);
2133 }
2134 // END Cristiano Malossi - 05/05/2009
2135 
2136 inline int
2137 GetPot::operator() (const char* VarName, int Default, unsigned Idx) const
2138 {
2139  // (*) recording of requested variables happens in '__find_variable()'
2140  const variable* sv = __find_variable (VarName);
2141  if ( sv == 0 )
2142  {
2143  return Default;
2144  }
2145  const std::string* element = sv->get_element (Idx);
2146  if ( element == 0 )
2147  {
2148  return Default;
2149  }
2150  return __convert_to_type (*element, Default);
2151 }
2152 
2153 inline double
2154 GetPot::operator() (const char* VarName, const double& Default, unsigned Idx) const
2155 {
2156  // (*) recording of requested variables happens in '__find_variable()'
2157  const variable* sv = __find_variable (VarName);
2158  if ( sv == 0 )
2159  {
2160  return Default;
2161  }
2162  const std::string* element = sv->get_element (Idx);
2163  if ( element == 0 )
2164  {
2165  return Default;
2166  }
2167  return __convert_to_type (*element, Default);
2168 }
2169 
2170 inline const std::string
2171 GetPot::operator() (const char* VarName, const char* Default, unsigned Idx) const
2172 {
2173  // (*) recording of requested variables happens in '__find_variable()'
2174  const variable* sv = __find_variable (VarName);
2175  if ( sv == 0 )
2176  {
2177  return Default;
2178  }
2179  const std::string* element = sv->get_element (Idx);
2180  if ( element == 0 )
2181  {
2182  return Default;
2183  }
2184  return *element;
2185 }
2186 
2187 inline void
2188 GetPot::__record_argument_request (const std::string& Name)
2189 {
2190  if ( ! __request_recording_f )
2191  {
2192  return;
2193  }
2194 
2195  // (*) record requested variable for later ufo detection
2196  _requested_arguments.push_back (Name);
2197 
2198  // (*) record considered section for ufo detection
2199  STRING_VECTOR STree = __get_section_tree (Name);
2200  victorate (std::string, STree, it)
2201  if ( find (_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
2202  if ( section.length() != 0 )
2203  {
2204  _requested_sections.push_back (*it);
2205  }
2206 }
2207 
2208 inline void
2209 GetPot::__record_variable_request (const std::string& Name)
2210 {
2211  if ( ! __request_recording_f )
2212  {
2213  return;
2214  }
2215 
2216  // (*) record requested variable for later ufo detection
2217  _requested_variables.push_back (Name);
2218 
2219  // (*) record considered section for ufo detection
2220  STRING_VECTOR STree = __get_section_tree (Name);
2221  victorate (std::string, STree, it)
2222  if ( find (_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
2223  if ( section.length() != 0 )
2224  {
2225  _requested_sections.push_back (*it);
2226  }
2227 }
2228 
2229 // (*) following functions are to be used from 'outside', after getpot has parsed its
2230 // arguments => append an argument in the argument vector that reflects the addition
2231 inline void
2232 GetPot::__set_variable (const char* VarName, const char* Value)
2233 {
2234  const GetPot::variable* Var = __find_variable (VarName);
2235  if ( Var == 0 )
2236  {
2237  variables.push_back (variable (VarName, Value, _field_separator.c_str() ) );
2238  }
2239  else
2240  {
2241  ( (GetPot::variable*) Var)->take (Value, _field_separator.c_str() );
2242  }
2243 }
2244 
2245 inline void
2246 GetPot::set (const char* VarName, const char* Value, const bool Requested /* = yes */)
2247 {
2248  const std::string Arg = prefix + std::string (VarName) + std::string ("=") + std::string (Value);
2249  argv.push_back (Arg);
2250  __set_variable (VarName, Value);
2251 
2252  // if user does not specify the variable as 'not being requested' it will be
2253  // considered amongst the requested variables
2254  if ( Requested )
2255  {
2257  }
2258 }
2259 
2260 inline void
2261 GetPot::set (const char* VarName, const double& Value, const bool /*Requested = yes */)
2262 {
2263  __set_variable (VarName, __double2string (Value).c_str() );
2264 }
2265 
2266 inline void
2267 GetPot::set (const char* VarName, const int Value, const bool /*Requested = yes */)
2268 {
2269  __set_variable (VarName, __int2string (Value).c_str() );
2270 }
2271 
2272 
2273 
2274 // BEGIN Cristiano Malossi - 03/04/2009
2275 inline bool
2276 GetPot::checkVariable (const char* VarName) const
2277 {
2278  const variable* sv = __find_variable (VarName);
2279  if ( sv == 0 )
2280  {
2281  return false;
2282  }
2283  else
2284  {
2285  return true;
2286  }
2287 }
2288 // END Cristiano Malossi - 03/04/2009
2289 
2290 inline unsigned
2291 GetPot::vector_variable_size (const char* VarName) const
2292 {
2293  const variable* sv = __find_variable (VarName);
2294  if ( sv == 0 )
2295  {
2296  return 0;
2297  }
2298  return static_cast<unsigned int> (sv->value.size() );
2299 }
2300 
2301 inline STRING_VECTOR
2303 {
2304  STRING_VECTOR result;
2305  std::vector<GetPot::variable>::const_iterator it = variables.begin();
2306  for (; it != variables.end(); ++it)
2307  {
2308  const std::string Tmp = __get_remaining_string ( (*it).name, prefix);
2309  if ( Tmp != "" )
2310  {
2311  result.push_back (Tmp);
2312  }
2313  }
2314  return result;
2315 }
2316 
2317 inline STRING_VECTOR
2319 {
2320  return section_list;
2321 }
2322 
2323 inline const GetPot::variable*
2324 GetPot::__find_variable (const char* VarName) const
2325 {
2326  const std::string Name = prefix + VarName;
2327 
2328  // (*) record requested variable for later ufo detection
2329  ( (GetPot*) this)->__record_variable_request (Name);
2330 
2331  std::vector<variable>::const_iterator it = variables.begin();
2332  for (; it != variables.end(); ++it)
2333  {
2334  if ( (*it).name == Name )
2335  {
2336  return & (*it);
2337  }
2338  }
2339  return 0;
2340 }
2341 
2342 ///////////////////////////////////////////////////////////////////////////////
2343 // (*) ouput (basically for debugging reasons
2344 //.............................................................................
2345 //
2346 inline int
2347 GetPot::print() const
2348 {
2349  std::cout << "argc = " << static_cast<unsigned int> (argv.size() ) << std::endl;
2350  STRING_VECTOR::const_iterator it = argv.begin();
2351  for (; it != argv.end(); ++it)
2352  {
2353  std::cout << *it << std::endl;
2354  }
2355  std::cout << std::endl;
2356  return 1;
2357 }
2358 
2359 // (*) dollar bracket expressions (DBEs) ------------------------------------
2360 //
2361 // 1) Entry Function: __DBE_expand_string()
2362 // Takes a string such as
2363 //
2364 // "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}"
2365 //
2366 // calls __DBE_expand() for each of the expressions
2367 //
2368 // ${+ ${x} ${y}}
2369 // ${& ${section} ${subsection}}
2370 // ${Title}
2371 //
2372 // and returns the string
2373 //
2374 // "4711 Subject-1.01: Mit den Clowns kamen die Schwaene"
2375 //
2376 // assuming that
2377 // x = "4699"
2378 // y = "12"
2379 // section = "1."
2380 // subsection = "01"
2381 // title = "Mit den Clowns kamen die Schwaene"
2382 //
2383 // 2) __DBE_expand():
2384 //
2385 // checks for the command, i.e. the 'sign' that follows '${'
2386 // divides the argument list into sub-expressions using
2387 // __DBE_get_expr_list()
2388 //
2389 // ${+ ${x} ${y}} -> "${x}" "${y}"
2390 // ${& ${section} ${subsection}} -> "${section}" "${subsection}"
2391 // ${Title} -> Nothing, variable expansion
2392 //
2393 // 3) __DBE_expression_list():
2394 //
2395 // builds a vector of unbracketed whitespace separated strings, i.e.
2396 //
2397 // " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}"
2398 //
2399 // is split into a vector
2400 //
2401 // [0] ${Number}.a
2402 // [1] ${: Das Marmorbild}
2403 // [2] AB-${& Author= ${Eichendorf}}-1870
2404 //
2405 // Each sub-expression is expanded using expand().
2406 //---------------------------------------------------------------------------
2407 inline std::string
2408 GetPot::__DBE_expand_string (const std::string str)
2409 {
2410  // Parses for closing operators '${ }' and expands them letting
2411  // white spaces and other letters as they are.
2412  std::string new_string = "";
2413  unsigned open_brackets = 0;
2414  unsigned first = 0;
2415  unsigned i = 0;
2416  for (; i < str.size(); ++i)
2417  {
2418  if ( i < str.size() - 2 && str.substr (i, 2) == "${" )
2419  {
2420  if ( open_brackets == 0 )
2421  {
2422  first = i + 2;
2423  }
2424  open_brackets++;
2425  }
2426  else if ( str[i] == '}' && open_brackets > 0)
2427  {
2428  open_brackets -= 1;
2429  if ( open_brackets == 0 )
2430  {
2431  const std::string Replacement = __DBE_expand (str.substr (first, i - first) );
2432  new_string += Replacement;
2433  }
2434  }
2435  else if ( open_brackets == 0 )
2436  {
2437  new_string += str[i];
2438  }
2439  }
2440  return new_string;
2441 }
2442 
2443 inline STRING_VECTOR
2444 GetPot::__DBE_get_expr_list (const std::string str_, const unsigned ExpectedNumber)
2445 // ensures that the resulting vector has the expected number
2446 // of arguments, but they may contain an error message
2447 {
2448  std::string str = str_;
2449  // Separates expressions by non-bracketed whitespaces, expands them
2450  // and puts them into a list.
2451 
2452  unsigned i = 0;
2453  // (1) eat initial whitespaces
2454  for (; i < str.size(); ++i)
2455  if ( ! isspace (str[i]) )
2456  {
2457  break;
2458  }
2459 
2460  STRING_VECTOR expr_list;
2461  unsigned open_brackets = 0;
2462  std::vector<unsigned> start_idx;
2463  unsigned start_new_string = i;
2464  unsigned l = static_cast<unsigned int> (str.size() );
2465 
2466  // (2) search for ${ } expressions ...
2467  while ( i < l )
2468  {
2469  const char letter = str[i];
2470  // whitespace -> end of expression
2471  if ( isspace (letter) && open_brackets == 0)
2472  {
2473  expr_list.push_back (str.substr (start_new_string, i - start_new_string) );
2474  bool no_breakout_f = true;
2475  for (++i; i < l ; ++i)
2476  {
2477  if ( ! isspace (str[i]) )
2478  {
2479  no_breakout_f = false;
2480  start_new_string = i;
2481  break;
2482  }
2483  }
2484  if ( no_breakout_f )
2485  {
2486  // end of expression list
2487  if ( expr_list.size() < ExpectedNumber )
2488  {
2489  const std::string pre_tmp ("<< ${ }: missing arguments>>");
2490  STRING_VECTOR tmp (ExpectedNumber - expr_list.size(), pre_tmp);
2491  expr_list.insert (expr_list.end(), tmp.begin(), tmp.end() );
2492  }
2493  return expr_list;
2494  }
2495  }
2496 
2497  // dollar-bracket expression
2498  if ( str.length() >= i + 2 && str.substr (i, 2) == "${" )
2499  {
2500  open_brackets++;
2501  start_idx.push_back (i + 2);
2502  }
2503  else if ( letter == '}' && open_brackets > 0)
2504  {
2505  int start = start_idx[start_idx.size() - 1];
2506  start_idx.pop_back();
2507  const std::string Replacement = __DBE_expand (str.substr (start, i - start) );
2508  if ( start - 3 < (int) 0)
2509  {
2510  str = Replacement + str.substr (i + 1);
2511  }
2512  else
2513  {
2514  str = str.substr (0, start - 2) + Replacement + str.substr (i + 1);
2515  }
2516  l = static_cast<unsigned int> (str.size() );
2517  i = start + static_cast<unsigned int> (Replacement.size() ) - 3;
2518  open_brackets--;
2519  }
2520  ++i;
2521  }
2522 
2523  // end of expression list
2524  expr_list.push_back (str.substr (start_new_string, i - start_new_string) );
2525 
2526  if ( expr_list.size() < ExpectedNumber )
2527  {
2528  const std::string pre_tmp ("<< ${ }: missing arguments>>");
2529  STRING_VECTOR tmp (ExpectedNumber - expr_list.size(), pre_tmp);
2530  expr_list.insert (expr_list.end(), tmp.begin(), tmp.end() );
2531  }
2532 
2533  return expr_list;
2534 }
2535 
2536 inline const GetPot::variable*
2537 GetPot::__DBE_get_variable (std::string VarName)
2538 {
2539  static GetPot::variable ev;
2540  std::string secure_Prefix = prefix;
2541 
2542  prefix = section;
2543  // (1) first search in currently active section
2544  const GetPot::variable* var = __find_variable (VarName.c_str() );
2545  if ( var != 0 )
2546  {
2547  prefix = secure_Prefix;
2548  return var;
2549  }
2550 
2551  // (2) search in root name space
2552  prefix = "";
2553  var = __find_variable (VarName.c_str() );
2554  if ( var != 0 )
2555  {
2556  prefix = secure_Prefix;
2557  return var;
2558  }
2559 
2560  prefix = secure_Prefix;
2561 
2562  // error occured => variable name == ""
2563  char* tmp = new char[VarName.length() + 25];
2564 #ifndef WIN32
2565  snprintf (tmp, (int) sizeof (char) * (VarName.length() + 25),
2566 #else
2567  _snprintf (tmp, sizeof (char) * (VarName.length() + 25),
2568 #endif
2569  "<<${ } variable '%s' undefined>>", VarName.c_str() );
2570  ev.name = "";
2571  ev.original = std::string (tmp);
2572  delete [] tmp;
2573  return &ev;
2574 }
2575 
2576 inline std::string
2577 GetPot::__DBE_expand (const std::string expr)
2578 {
2579  // ${: } pure text
2580  if ( expr[0] == ':' )
2581  {
2582  return expr.substr (1);
2583  }
2584 
2585  // ${& expr expr ... } text concatination
2586  else if ( expr[0] == '&' )
2587  {
2588  const STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 1);
2589 
2590  STRING_VECTOR::const_iterator it = A.begin();
2591  std::string result = *it++;
2592  for (; it != A.end(); ++it)
2593  {
2594  result += *it;
2595  }
2596 
2597  return result;
2598  }
2599 
2600  // ${<-> expr expr expr} text replacement
2601  else if ( expr.length() >= 3 && expr.substr (0, 3) == "<->" )
2602  {
2603  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (3), 3);
2604  std::string::size_type tmp = 0;
2605  const std::string::size_type L = A[1].length();
2606  while ( (tmp = A[0].find (A[1]) ) != std::string::npos )
2607  {
2608  A[0].replace (tmp, L, A[2]);
2609  }
2610  return A[0];
2611  }
2612  // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions
2613  else if ( expr[0] == '+' )
2614  {
2615  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 2);
2616  STRING_VECTOR::const_iterator it = A.begin();
2617  double result = __convert_to_type (*it++, 0.0);
2618  for (; it != A.end(); ++it)
2619  {
2620  result += __convert_to_type (*it, 0.0);
2621  }
2622 
2623  return __double2string (result);
2624  }
2625  else if ( expr[0] == '-' )
2626  {
2627  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 2);
2628  STRING_VECTOR::const_iterator it = A.begin();
2629  double result = __convert_to_type (*it++, 0.0);
2630  for (; it != A.end(); ++it)
2631  {
2632  result -= __convert_to_type (*it, 0.0);
2633  }
2634 
2635  return __double2string (result);
2636  }
2637  else if ( expr[0] == '*' )
2638  {
2639  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 2);
2640  STRING_VECTOR::const_iterator it = A.begin();
2641  double result = __convert_to_type (*it++, 0.0);
2642  for (; it != A.end(); ++it)
2643  {
2644  result *= __convert_to_type (*it, 0.0);
2645  }
2646 
2647  return __double2string (result);
2648  }
2649  else if ( expr[0] == '/' )
2650  {
2651 
2652  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 2);
2653  STRING_VECTOR::const_iterator it = A.begin();
2654  double result = __convert_to_type (*it++, 0.0);
2655  if ( result == 0 )
2656  {
2657  return "0.0";
2658  }
2659  for (; it != A.end(); ++it)
2660  {
2661  const double Q = __convert_to_type (*it, 0.0);
2662  if ( Q == 0.0 )
2663  {
2664  return "0.0";
2665  }
2666  result /= Q;
2667  }
2668  return __double2string (result);
2669  }
2670 
2671  // ${^ ... } power expressions
2672  else if ( expr[0] == '^' )
2673  {
2674  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 2);
2675  STRING_VECTOR::const_iterator it = A.begin();
2676  double result = __convert_to_type (*it++, 0.0);
2677  for (; it != A.end(); ++it)
2678  {
2679  result = std::pow (result, __convert_to_type (*it, 0.0) );
2680  }
2681  return __double2string (result);
2682  }
2683 
2684  // ${== } ${<= } ${>= } comparisons (return the number of the first 'match'
2685  else if ( expr.length() >= 2 &&
2686  ( expr.substr (0, 2) == "==" || expr.substr (0, 2) == ">=" ||
2687  expr.substr (0, 2) == "<=" || expr[0] == '>' || expr[0] == '<') )
2688  {
2689  // differentiate between two and one sign operators
2690  unsigned op = 0;
2691  enum { EQ, GEQ, LEQ, GT, LT };
2692  if ( expr.substr (0, 2) == "==" )
2693  {
2694  op = EQ;
2695  }
2696  else if ( expr.substr (0, 2) == ">=" )
2697  {
2698  op = GEQ;
2699  }
2700  else if ( expr.substr (0, 2) == "<=" )
2701  {
2702  op = LEQ;
2703  }
2704  else if ( expr[0] == '>' )
2705  {
2706  op = GT;
2707  }
2708  else /* "<" */
2709  {
2710  op = LT;
2711  }
2712 
2713  STRING_VECTOR a;
2714  if ( op == GT || op == LT )
2715  {
2716  a = __DBE_get_expr_list (expr.substr (1), 2);
2717  }
2718  else
2719  {
2720  a = __DBE_get_expr_list (expr.substr (2), 2);
2721  }
2722 
2723  std::string x_orig = a[0];
2724  double x = __convert_to_type (x_orig, 1e37);
2725  unsigned i = 1;
2726 
2727  STRING_VECTOR::const_iterator y_orig = a.begin();
2728  for (y_orig++; y_orig != a.end(); y_orig++)
2729  {
2730  double y = __convert_to_type (*y_orig, 1e37);
2731 
2732  // set the strings as reference if one wasn't a number
2733  if ( x == 1e37 || y == 1e37 )
2734  {
2735  // it's a string comparison
2736  if ( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
2737  (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
2738  (op == LT && x_orig < *y_orig) )
2739  {
2740  return __int2string (i);
2741  }
2742  }
2743  else
2744  {
2745  // it's a number comparison
2746  if ( (op == EQ && x == y) || (op == GEQ && x >= y) ||
2747  (op == LEQ && x <= y) || (op == GT && x > y) ||
2748  (op == LT && x < y) )
2749  {
2750  return __int2string (i);
2751  }
2752  }
2753  ++i;
2754  }
2755 
2756  // nothing fulfills the condition => return 0
2757  return "0";
2758  }
2759  // ${?? expr expr} select
2760  else if ( expr.length() >= 2 && expr.substr (0, 2) == "??" )
2761  {
2762  STRING_VECTOR a = __DBE_get_expr_list (expr.substr (2), 2);
2763  double x = __convert_to_type (a[0], 1e37);
2764  // last element is always the default argument
2765  if ( x == 1e37 || x < 0 || x >= a.size() - 1 )
2766  {
2767  return a[a.size() - 1];
2768  }
2769 
2770  // round x to closest integer
2771  return a[int (x + 0.5)];
2772  }
2773  // ${? expr expr expr} if then else conditions
2774  else if ( expr[0] == '?' )
2775  {
2776  STRING_VECTOR a = __DBE_get_expr_list (expr.substr (1), 2);
2777  if ( __convert_to_type (a[0], 0.0) == 1.0 )
2778  {
2779  return a[1];
2780  }
2781  else if ( a.size() > 2 )
2782  {
2783  return a[2];
2784  }
2785  }
2786  // ${! expr} maxro expansion
2787  else if ( expr[0] == '!' )
2788  {
2789  const GetPot::variable* Var = __DBE_get_variable (expr.substr (1) );
2790  // error
2791  if ( Var->name == "" )
2792  {
2793  return std::string (Var->original);
2794  }
2795 
2797  return A[0];
2798  }
2799  // ${@: } - string subscription
2800  else if ( expr.length() >= 2 && expr.substr (0, 2) == "@:" )
2801  {
2802  const STRING_VECTOR A = __DBE_get_expr_list (expr.substr (2), 2);
2803  double x = __convert_to_type (A[1], 1e37);
2804 
2805  // last element is always the default argument
2806  if ( x == 1e37 || x < 0 || x >= A[0].size() - 1)
2807  {
2808  return "<<1st index out of range>>";
2809  }
2810 
2811  if ( A.size() > 2 )
2812  {
2813  double y = __convert_to_type (A[2], 1e37);
2814  if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x )
2815  {
2816  return A[0].substr (int (x + 0.5), int (y + 1.5) - int (x + 0.5) );
2817  }
2818  else if ( y == -1 )
2819  {
2820  return A[0].substr (int (x + 0.5) );
2821  }
2822  return "<<2nd index out of range>>";
2823  }
2824  else
2825  {
2826  char* tmp = new char[2];
2827  tmp[0] = A[0][int (x + 0.5)];
2828  tmp[1] = '\0';
2829  std::string result (tmp);
2830  delete [] tmp;
2831  return result;
2832  }
2833  }
2834  // ${@ } - vector subscription
2835  else if ( expr[0] == '@' )
2836  {
2837  STRING_VECTOR A = __DBE_get_expr_list (expr.substr (1), 2);
2838  const GetPot::variable* Var = __DBE_get_variable (A[0]);
2839  // error
2840  if ( Var->name == "" )
2841  {
2842  // make a copy of the string if an error occured
2843  // (since the error variable is a static variable inside get_variable())
2844  return std::string (Var->original);
2845  }
2846 
2847  double x = __convert_to_type (A[1], 1e37);
2848 
2849  // last element is always the default argument
2850  if (x == 1e37 || x < 0 || x >= Var->value.size() )
2851  {
2852  return "<<1st index out of range>>";
2853  }
2854 
2855  if ( A.size() > 2)
2856  {
2857  double y = __convert_to_type (A[2], 1e37);
2858  int begin = int (x + 0.5);
2859  int end = 0;
2860  if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x)
2861  {
2862  end = int (y + 1.5);
2863  }
2864  else if ( y == -1 )
2865  {
2866  end = static_cast<unsigned int> (Var->value.size() );
2867  }
2868  else
2869  {
2870  return "<<2nd index out of range>>";
2871  }
2872 
2873  std::string result = * (Var->get_element (begin) );
2874  int i = begin + 1;
2875  for (; i < end; ++i)
2876  {
2877  result += std::string (" ") + * (Var->get_element (i) );
2878  }
2879  return result;
2880  }
2881  else
2882  {
2883  return * (Var->get_element (int (x + 0.5) ) );
2884  }
2885  }
2886 
2887  const STRING_VECTOR A = __DBE_get_expr_list (expr, 1);
2888  const GetPot::variable* B = __DBE_get_variable (A[0]);
2889 
2890  // make a copy of the string if an error occured
2891  // (since the error variable is a static variable inside get_variable())
2892  if ( B->name == "" )
2893  {
2894  return std::string (B->original);
2895  }
2896  // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces
2897  // with: else return B->original (thanks))
2898  return B->original;
2899 }
2900 
2901 
2902 ///////////////////////////////////////////////////////////////////////////////
2903 // (*) unidentified flying objects
2904 //.............................................................................
2905 //
2906 inline bool
2907 GetPot::__search_string_vector (const STRING_VECTOR& VecStr, const std::string& Str) const
2908 {
2909  victorate (std::string, VecStr, itk)
2910  {
2911  if ( *itk == Str )
2912  {
2913  return true;
2914  }
2915  }
2916  return false;
2917 }
2918 
2919 inline STRING_VECTOR
2920 GetPot::unidentified_arguments (unsigned Number,
2921  const char* KnownArgument1, ...) const
2922 {
2923  STRING_VECTOR known_arguments;
2924 
2925  // (1) create a vector of known arguments
2926  if ( Number == 0 )
2927  {
2928  return STRING_VECTOR();
2929  }
2930 
2931  va_list ap;
2932  va_start (ap, KnownArgument1);
2933  known_arguments.push_back (std::string (KnownArgument1) );
2934  unsigned i = 1;
2935  for (; i < Number; ++i)
2936  {
2937  known_arguments.push_back (std::string (va_arg (ap, char*) ) );
2938  }
2939  va_end (ap);
2940 
2941  return unidentified_arguments (known_arguments);
2942 }
2943 
2944 inline STRING_VECTOR
2946 {
2948 }
2949 
2950 inline STRING_VECTOR
2952 {
2953  STRING_VECTOR ufos;
2954  STRING_VECTOR::const_iterator it = argv.begin();
2955  ++it; // forget about argv[0] (application or filename)
2956  for (; it != argv.end(); ++it)
2957  {
2958  // -- argument belongs to prefixed section ?
2959  const std::string arg = __get_remaining_string (*it, prefix);
2960  if ( arg == "" )
2961  {
2962  continue;
2963  }
2964 
2965  // -- check if in list
2966  if ( __search_string_vector (Knowns, arg) == false)
2967  {
2968  ufos.push_back (*it);
2969  }
2970  }
2971  return ufos;
2972 }
2973 
2974 inline STRING_VECTOR
2975 GetPot::unidentified_options (unsigned Number,
2976  const char* KnownOption1, ...) const
2977 {
2978  STRING_VECTOR known_options;
2979 
2980  // (1) create a vector of known arguments
2981  if ( Number == 0 )
2982  {
2983  return STRING_VECTOR();
2984  }
2985 
2986  va_list ap;
2987  va_start (ap, KnownOption1);
2988  known_options.push_back (std::string (KnownOption1) );
2989  unsigned i = 1;
2990  for (; i < Number; ++i)
2991  {
2992  known_options.push_back (std::string (va_arg (ap, char*) ) );
2993  }
2994  va_end (ap);
2995 
2996  return unidentified_options (known_options);
2997 }
2998 
2999 inline STRING_VECTOR
3001 {
3002  // -- every option is an argument.
3003  // -- the set of requested arguments contains the set of requested options.
3004  // -- IF the set of requested arguments contains unrequested options,
3005  // THEN they were requested as 'follow' and 'next' arguments and not as real options.
3006  //
3007  // => it is not necessary to separate requested options from the list
3008  STRING_VECTOR option_list;
3009  victorate (std::string, _requested_arguments, it)
3010  {
3011  const std::string arg = *it;
3012  if ( arg.length() == 0 )
3013  {
3014  continue;
3015  }
3016  if ( arg[0] == '-' )
3017  {
3018  option_list.push_back (arg);
3019  }
3020  }
3021  return unidentified_options (option_list);
3022 }
3023 
3024 inline STRING_VECTOR
3026 {
3027  STRING_VECTOR ufos;
3028  STRING_VECTOR::const_iterator it = argv.begin();
3029  ++it; // forget about argv[0] (application or filename)
3030  for (; it != argv.end(); ++it)
3031  {
3032  // -- argument belongs to prefixed section ?
3033  const std::string arg = __get_remaining_string (*it, prefix);
3034  if ( arg == "" )
3035  {
3036  continue;
3037  }
3038 
3039  // is argument really an option (starting with '-') ?
3040  if ( arg.length() < 1 || arg[0] != '-' )
3041  {
3042  continue;
3043  }
3044 
3045  if ( __search_string_vector (Knowns, arg) == false)
3046  {
3047  ufos.push_back (*it);
3048  }
3049  }
3050 
3051  return ufos;
3052 }
3053 
3054 inline std::string
3055 GetPot::unidentified_flags (const char* KnownFlagList, int ArgumentNumber = -1) const
3056 // Two modes:
3057 // ArgumentNumber >= 0 check specific argument
3058 // ArgumentNumber == -1 check all options starting with one '-'
3059 // for flags
3060 {
3061  std::string ufos;
3062  STRING_VECTOR known_arguments;
3063  std::string KFL (KnownFlagList);
3064 
3065  // (2) iteration over '-' arguments (options)
3066  if ( ArgumentNumber == -1 )
3067  {
3068  STRING_VECTOR::const_iterator it = argv.begin();
3069  ++it; // forget about argv[0] (application or filename)
3070  for (; it != argv.end(); ++it)
3071  {
3072  // -- argument belongs to prefixed section ?
3073  const std::string arg = __get_remaining_string (*it, prefix);
3074  if ( arg == "" )
3075  {
3076  continue;
3077  }
3078 
3079  // -- does arguments start with '-' (but not '--')
3080  if ( arg.length() < 2 )
3081  {
3082  continue;
3083  }
3084  else if ( arg[0] != '-' )
3085  {
3086  continue;
3087  }
3088  else if ( arg[1] == '-' )
3089  {
3090  continue;
3091  }
3092 
3093  // -- check out if flags inside option are contained in KnownFlagList
3094  const char* p = arg.c_str();
3095  p++; // skip starting minus
3096  for (; *p != '\0' ; p++)
3097  if ( KFL.find (*p) == std::string::npos )
3098  {
3099  ufos += *p;
3100  }
3101  }
3102  }
3103  // (1) check specific argument
3104  else
3105  {
3106  // -- only check arguments that start with prefix
3107  int no_matches = 0;
3108  unsigned i = 1;
3109  for (; i < argv.size(); ++i)
3110  {
3111  const std::string Remain = __get_remaining_string (argv[i], prefix);
3112  if ( Remain != "")
3113  {
3114  no_matches++;
3115  if ( no_matches == ArgumentNumber)
3116  {
3117  // -- the right argument number inside the section is found
3118  // => check it for flags
3119  const char* p = Remain.c_str();
3120  p++; // skip starting minus
3121  for (; *p != '\0' ; p++)
3122  if ( KFL.find (*p) == std::string::npos )
3123  {
3124  ufos += *p;
3125  }
3126  return ufos;
3127  }
3128  }
3129  }
3130  }
3131  return ufos;
3132 }
3133 
3134 inline STRING_VECTOR
3135 GetPot::unidentified_variables (unsigned Number,
3136  const char* KnownVariable1, ...) const
3137 {
3138  STRING_VECTOR known_variables;
3139 
3140  // create vector of known arguments
3141  if ( Number == 0 )
3142  {
3143  return STRING_VECTOR();
3144  }
3145 
3146  va_list ap;
3147  va_start (ap, KnownVariable1);
3148  known_variables.push_back (std::string (KnownVariable1) );
3149  unsigned i = 1;
3150  for (; i < Number; ++i)
3151  {
3152  known_variables.push_back (std::string (va_arg (ap, char*) ) );
3153  }
3154  va_end (ap);
3155 
3156  return unidentified_variables (known_variables);
3157 }
3158 
3159 inline STRING_VECTOR
3161 {
3162  STRING_VECTOR ufos;
3163 
3164  victorate (GetPot::variable, variables, it)
3165  {
3166  // -- check if variable has specific prefix
3167  const std::string var_name = __get_remaining_string ( (*it).name, prefix);
3168  if ( var_name == "" )
3169  {
3170  continue;
3171  }
3172 
3173  // -- check if variable is known
3174  if ( __search_string_vector (Knowns, var_name) == false)
3175  {
3176  ufos.push_back ( (*it).name);
3177  }
3178  }
3179  return ufos;
3180 }
3181 
3182 inline STRING_VECTOR
3184 {
3186 }
3187 
3188 
3189 inline STRING_VECTOR
3190 GetPot::unidentified_sections (unsigned Number,
3191  const char* KnownSection1, ...) const
3192 {
3193  STRING_VECTOR known_sections;
3194 
3195  // (1) create a vector of known arguments
3196  if ( Number == 0 )
3197  {
3198  return STRING_VECTOR();
3199  }
3200 
3201  va_list ap;
3202  va_start (ap, KnownSection1);
3203  known_sections.push_back (std::string (KnownSection1) );
3204  unsigned i = 1;
3205  for (; i < Number; ++i)
3206  {
3207  std::string tmp = std::string (va_arg (ap, char*) );
3208  if ( tmp.length() == 0 )
3209  {
3210  continue;
3211  }
3212  if ( tmp[tmp.length() - 1] != '/' )
3213  {
3214  tmp += '/';
3215  }
3216  known_sections.push_back (tmp);
3217  }
3218  va_end (ap);
3219 
3220  return unidentified_sections (known_sections);
3221 }
3222 
3223 inline STRING_VECTOR
3225 {
3227 }
3228 
3229 inline STRING_VECTOR
3231 {
3232  STRING_VECTOR ufos;
3233 
3234  victorate (std::string, section_list, it)
3235  {
3236  // -- check if section conform to prefix
3237  const std::string sec_name = __get_remaining_string (*it, prefix);
3238  if ( sec_name == "" )
3239  {
3240  continue;
3241  }
3242 
3243  // -- check if section is known
3244  if ( __search_string_vector (Knowns, sec_name) == false )
3245  {
3246  ufos.push_back (*it);
3247  }
3248  }
3249 
3250  return ufos;
3251 }
3252 
3253 
3254 inline STRING_VECTOR
3255 GetPot::unidentified_nominuses (unsigned Number, const char* Known, ...) const
3256 {
3257  STRING_VECTOR known_nominuses;
3258 
3259  // create vector of known arguments
3260  if ( Number == 0 )
3261  {
3262  return STRING_VECTOR();
3263  }
3264 
3265  va_list ap;
3266  va_start (ap, Known);
3267  known_nominuses.push_back (std::string (Known) );
3268  unsigned i = 1;
3269  for (; i < Number; ++i)
3270  {
3271  std::string tmp = std::string (va_arg (ap, char*) );
3272  if ( tmp.length() == 0 )
3273  {
3274  continue;
3275  }
3276  known_nominuses.push_back (tmp);
3277  }
3278  va_end (ap);
3279 
3280  return unidentified_nominuses (known_nominuses);
3281 }
3282 
3283 inline STRING_VECTOR
3285 {
3286  // -- every nominus is an argument.
3287  // -- the set of requested arguments contains the set of requested nominuss.
3288  // -- IF the set of requested arguments contains unrequested nominuss,
3289  // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses.
3290  //
3291  // => it is not necessary to separate requested nominus from the list
3292 
3294 }
3295 
3296 inline STRING_VECTOR
3298 {
3299  STRING_VECTOR ufos;
3300 
3301  // (2) iterate over all arguments
3302  STRING_VECTOR::const_iterator it = argv.begin();
3303  ++it; // forget about argv[0] (application or filename)
3304  for (; it != argv.end(); ++it)
3305  {
3306  // -- check if nominus part of prefix
3307  const std::string arg = __get_remaining_string (*it, prefix);
3308  if ( arg == "" )
3309  {
3310  continue;
3311  }
3312 
3313  if ( arg.length() < 1 )
3314  {
3315  continue;
3316  }
3317  // option ? --> not a nomius
3318  if ( arg[0] == '-' )
3319  {
3320  continue;
3321  }
3322  // section ? --> not a real nominus
3323  if ( arg[0] == '[' && arg[arg.length() - 1] == ']' )
3324  {
3325  continue;
3326  }
3327  // variable definition ? --> not a real nominus
3328  bool continue_f = false;
3329  unsigned i = 0;
3330  for (; i < arg.length() ; ++i)
3331  if ( arg[i] == '=' )
3332  {
3333  continue_f = true;
3334  break;
3335  }
3336  if ( continue_f )
3337  {
3338  continue;
3339  }
3340 
3341  // real nominuses are compared with the given list
3342  if ( __search_string_vector (Knowns, arg) == false )
3343  {
3344  ufos.push_back (*it);
3345  }
3346  }
3347  return ufos;
3348 }
3349 
3350 
3351 ///////////////////////////////////////////////////////////////////////////////
3352 // (*) variable class
3353 //.............................................................................
3354 //
3355 inline
3357 {}
3358 
3359 inline
3361 {
3362 #ifdef WIN32
3363  operator= (That);
3364 #else
3366 #endif
3367 }
3368 
3369 
3370 inline
3371 GetPot::variable::variable (const char* Name, const char* Value, const char* FieldSeparator)
3372  : name (Name)
3373 {
3374  // make a copy of the 'Value'
3375  take (Value, FieldSeparator);
3376 }
3377 
3378 inline const std::string*
3379 GetPot::variable::get_element (unsigned Idx) const
3380 {
3381  if ( Idx >= value.size() )
3382  {
3383  return 0;
3384  }
3385  else
3386  {
3387  return & (value[Idx]);
3388  }
3389 }
3390 
3391 inline void
3392 GetPot::variable::take (const char* Value, const char* FieldSeparator)
3393 {
3394  using namespace std;
3395 
3396  original = std::string (Value);
3397 
3398  // separate string by white space delimiters using 'strtok'
3399  // thread safe usage of strtok (no static members)
3400  char* spt = 0;
3401  // make a copy of the 'Value'
3402  char* copy = new char[strlen (Value) + 1];
3403  strcpy (copy, Value);
3404  char* follow_token = strtok_r (copy, FieldSeparator, &spt);
3405  if ( value.size() != 0 )
3406  {
3407  value.erase (value.begin(), value.end() );
3408  }
3409  while (follow_token != 0)
3410  {
3411  value.push_back (std::string (follow_token) );
3412  follow_token = strtok_r (NULL, FieldSeparator, &spt);
3413  }
3414 
3415  delete [] copy;
3416 }
3417 
3418 inline
3420 {}
3421 
3422 inline GetPot::variable&
3424 {
3425  if ( &That != this)
3426  {
3427  name = That.name;
3428  value = That.value;
3429  original = That.original;
3430  }
3431  return *this;
3432 }
3433 
3434 #undef victorate
3435 
3436 
3437 #endif // __include_guard_GETPOT_H__
bool search(const char *option)
Definition: GetPot.hpp:1171
STRING_VECTOR unidentified_options(unsigned Number, const char *Known,...) const
Definition: GetPot.hpp:2975
STRING_VECTOR unidentified_variables() const
Definition: GetPot.hpp:3183
std::string next_nominus()
Definition: GetPot.hpp:1986
double next(const double &Default)
Definition: GetPot.hpp:1352
bool search_loop_f
Definition: GetPot.hpp:327
double operator()(const char *VarName, const double &Default, unsigned Idx) const
Definition: GetPot.hpp:2154
double operator()(const char *VarName, const double &Default, bool &found) const
Definition: GetPot.hpp:2088
const std::string * get_element(unsigned Idx) const
Definition: GetPot.hpp:3379
int print() const
Definition: GetPot.hpp:2347
int next(int Default)
Definition: GetPot.hpp:1330
double __convert_to_type(const std::string &String, double Default) const
Definition: GetPot.hpp:1125
double operator()(const char *VarName, const double &Default) const
Definition: GetPot.hpp:2033
std::vector< variable > variables
Definition: GetPot.hpp:338
STRING_VECTOR unidentified_nominuses(const STRING_VECTOR &Knowns) const
Definition: GetPot.hpp:3297
const std::string operator[](unsigned Idx) const
Definition: GetPot.hpp:1283
std::string unidentified_flags(const char *Known, int ArgumentNumber) const
Definition: GetPot.hpp:3055
void take(const char *Value, const char *FieldSeparator)
Definition: GetPot.hpp:3392
bool search_failed_f
Definition: GetPot.hpp:329
const std::string get(unsigned Idx, const char *Default) const
Definition: GetPot.hpp:1309
void __skip_whitespace(std::istream &istr)
Definition: GetPot.hpp:854
STRING_VECTOR _requested_arguments
Definition: GetPot.hpp:353
std::vector< std::string > STRING_VECTOR
Definition: GetPot.hpp:103
#define victorate(TYPE, VARIABLE, ITERATOR)
Definition: GetPot.hpp:105
std::string _comment_end
Definition: GetPot.hpp:342
std::string section
Definition: GetPot.hpp:322
int get(unsigned Idx, int Default) const
Definition: GetPot.hpp:1289
GetPot(const int argc_, char **argv_, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:507
STRING_VECTOR get_section_names() const
Definition: GetPot.hpp:2318
std::string __double2string(const double &Value) const
Definition: GetPot.hpp:420
std::string __int2string(const int &Value) const
Definition: GetPot.hpp:434
void init_multiple_occurrence()
Definition: GetPot.hpp:1273
GetPot(const GetPot &)
Definition: GetPot.hpp:606
std::string __DBE_expand(const std::string str)
Definition: GetPot.hpp:2577
std::string __process_section_label(const std::string &Section, STRING_VECTOR &section_stack)
Definition: GetPot.hpp:1043
std::vector< unsigned > idx_nominus
Definition: GetPot.hpp:334
void enable_loop()
Definition: GetPot.hpp:221
STRING_VECTOR value
Definition: GetPot.hpp:316
STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber)
Definition: GetPot.hpp:2444
STRING_VECTOR argv
Definition: GetPot.hpp:325
std::string prefix
Definition: GetPot.hpp:321
void __record_variable_request(const std::string &Arg)
Definition: GetPot.hpp:2209
STRING_VECTOR unidentified_options() const
Definition: GetPot.hpp:3000
void enable_request_recording()
Definition: GetPot.hpp:147
double follow(const double &Default, const char *Option)
Definition: GetPot.hpp:1429
void set_prefix(const char *Prefix)
Definition: GetPot.hpp:207
double follow(const double &Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1482
std::vector< std::string > nominus_followers(unsigned No,...)
Definition: GetPot.hpp:1575
GetPot & operator=(const GetPot &)
Definition: GetPot.hpp:620
const std::string operator()(const char *VarName, const char *Default, unsigned Idx) const
Definition: GetPot.hpp:2171
std::vector< std::string > string_tails(const char *StartString)
Definition: GetPot.hpp:1675
~GetPot()
Definition: GetPot.hpp:612
const std::string __get_remaining_string(const std::string &String, const std::string &Start) const
Definition: GetPot.hpp:1149
STRING_VECTOR unidentified_variables(const STRING_VECTOR &Knowns) const
Definition: GetPot.hpp:3160
std::vector< std::string > nominus_followers(const char *Option)
Definition: GetPot.hpp:1544
const std::string __get_next_token(std::istream &istr)
Definition: GetPot.hpp:932
void disable_loop()
Definition: GetPot.hpp:217
bool search_failed() const
Definition: GetPot.hpp:211
const GetPot::variable * __DBE_get_variable(const std::string str)
Definition: GetPot.hpp:2537
STRING_VECTOR unidentified_nominuses() const
Definition: GetPot.hpp:3284
bool __convert_to_type(const std::string &String, bool Default) const
Definition: GetPot.hpp:1106
bool checkVariable(const char *VarName) const
Definition: GetPot.hpp:2276
unsigned cursor
Definition: GetPot.hpp:326
std::string _comment_start
Definition: GetPot.hpp:341
STRING_VECTOR __get_section_tree(const std::string &FullPath)
Definition: GetPot.hpp:448
STRING_VECTOR unidentified_variables(unsigned Number, const char *Known,...) const
Definition: GetPot.hpp:3135
void reset_cursor()
Definition: GetPot.hpp:1266
bool operator()(const char *VarName, bool Default, bool &found) const
Definition: GetPot.hpp:2060
const std::string __get_string(std::istream &istr)
Definition: GetPot.hpp:975
const std::string next(const char *Default)
Definition: GetPot.hpp:1375
int operator()(const char *VarName, int Default, bool &found) const
Definition: GetPot.hpp:2074
const char * __match_starting_string(const char *StartString)
Definition: GetPot.hpp:1847
const variable * __find_variable(const char *) const
Definition: GetPot.hpp:2324
STRING_VECTOR unidentified_options(const STRING_VECTOR &Knowns) const
Definition: GetPot.hpp:3025
STRING_VECTOR __read_in_file(const char *FileName)
Definition: GetPot.hpp:785
variable(const char *Name, const char *Value, const char *FieldSeparator)
Definition: GetPot.hpp:3371
int direct_follow(int Default, const char *Option)
Definition: GetPot.hpp:1611
int __convert_to_type(const std::string &String, int Default) const
Definition: GetPot.hpp:1137
void set(const char *VarName, const int Value, const bool Requested=true)
Definition: GetPot.hpp:2267
bool __check_flags(const std::string &Str, const char *FlagList) const
Definition: GetPot.hpp:1954
const std::string __get_until_closing_bracket(std::istream &istr)
Definition: GetPot.hpp:1005
STRING_VECTOR unidentified_arguments(unsigned Number, const char *Known,...) const
Definition: GetPot.hpp:2920
STRING_VECTOR unidentified_sections(unsigned Number, const char *Known,...) const
Definition: GetPot.hpp:3190
void set(const char *VarName, const double &Value, const bool Requested=true)
Definition: GetPot.hpp:2261
unsigned nominus_size() const
Definition: GetPot.hpp:260
int follow(int Default, const char *Option)
Definition: GetPot.hpp:1418
const std::string direct_follow(const char *Default, const char *Option)
Definition: GetPot.hpp:1649
bool __search_string_vector(const STRING_VECTOR &Vec, const std::string &Str) const
Definition: GetPot.hpp:2907
void __basic_initialization()
Definition: GetPot.hpp:476
GetPot(const char *FileName, const char *CommentStart=0x0, const char *CommentEnd=0x0, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:541
variable(const variable &)
Definition: GetPot.hpp:3360
double get(unsigned Idx, const double &Default) const
Definition: GetPot.hpp:1299
STRING_VECTOR nominus_vector() const
Definition: GetPot.hpp:1968
void disable_request_recording()
Definition: GetPot.hpp:143
std::vector< char * > __internal_string_container
Definition: GetPot.hpp:349
std::string __DBE_expand_string(const std::string str)
Definition: GetPot.hpp:2408
int operator()(const char *VarName, int Default, unsigned Idx) const
Definition: GetPot.hpp:2137
void set(const char *VarName, const char *Value, const bool Requested=true)
Definition: GetPot.hpp:2246
void clear_requests()
Definition: GetPot.hpp:675
unsigned size() const
Definition: GetPot.hpp:1322
std::string name
Definition: GetPot.hpp:315
int operator()(const char *VarName, int Default) const
Definition: GetPot.hpp:2021
STRING_VECTOR _requested_variables
Definition: GetPot.hpp:354
void __parse_argument_vector(const STRING_VECTOR &ARGV)
Definition: GetPot.hpp:683
int nominus_cursor
Definition: GetPot.hpp:333
bool search(unsigned No, const char *P,...)
Definition: GetPot.hpp:1217
const std::string operator()(const char *VarName, const char *Default) const
Definition: GetPot.hpp:2045
const std::string follow(const char *Default, const char *Option)
Definition: GetPot.hpp:1440
GetPot(const STRING &FileName, const char *CommentStart=0x0, const char *CommentEnd=0x0, const char *FieldSeparator=0x0)
Definition: GetPot.hpp:574
bool __request_recording_f
Definition: GetPot.hpp:357
std::vector< int > int_tails(const char *StartString, const int Default=1)
Definition: GetPot.hpp:1731
STRING_VECTOR get_variable_names() const
Definition: GetPot.hpp:2302
void __record_argument_request(const std::string &Arg)
Definition: GetPot.hpp:2188
variable & operator=(const variable &That)
Definition: GetPot.hpp:3423
bool argument_contains(unsigned Idx, const char *FlagList) const
Definition: GetPot.hpp:1915
std::string _field_separator
Definition: GetPot.hpp:345
std::vector< double > double_tails(const char *StartString, const double Default=1.0)
Definition: GetPot.hpp:1787
GetPot(const STRING_VECTOR &FileNameList)
Definition: GetPot.hpp:645
void absorb(const GetPot &That)
Definition: GetPot.hpp:660
STRING_VECTOR unidentified_nominuses(unsigned Number, const char *Known,...) const
Definition: GetPot.hpp:3255
double direct_follow(const double &Default, const char *Option)
Definition: GetPot.hpp:1630
bool operator()(const char *VarName, bool Default) const
Definition: GetPot.hpp:2008
const std::string follow(const char *Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1510
STRING_VECTOR unidentified_arguments(const STRING_VECTOR &Knowns) const
Definition: GetPot.hpp:2951
GetPot()
Definition: GetPot.hpp:497
bool operator()(const char *VarName, bool Default, unsigned Idx) const
Definition: GetPot.hpp:2119
void __set_variable(const char *VarName, const char *Value)
Definition: GetPot.hpp:2232
STRING_VECTOR __read_in_stream(std::istream &istr)
Definition: GetPot.hpp:797
STRING_VECTOR unidentified_arguments() const
Definition: GetPot.hpp:2945
STRING_VECTOR unidentified_sections() const
Definition: GetPot.hpp:3224
STRING_VECTOR _requested_sections
Definition: GetPot.hpp:355
STRING_VECTOR section_list
Definition: GetPot.hpp:323
const std::string operator()(const char *VarName, const char *Default, bool &found) const
Definition: GetPot.hpp:2101
std::string original
Definition: GetPot.hpp:317
int follow(int Default, unsigned No, const char *Option,...)
Definition: GetPot.hpp:1453
bool options_contain(const char *FlagList) const
Definition: GetPot.hpp:1896
STRING_VECTOR unidentified_sections(const STRING_VECTOR &Knowns) const
Definition: GetPot.hpp:3230
unsigned vector_variable_size(const char *VarName) const
Definition: GetPot.hpp:2291