summaryrefslogtreecommitdiff
path: root/utils/zenutils/libraries/getpot-c++-1.1.17
diff options
context:
space:
mode:
Diffstat (limited to 'utils/zenutils/libraries/getpot-c++-1.1.17')
-rwxr-xr-xutils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot2433
-rwxr-xr-xutils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt504
-rwxr-xr-xutils/zenutils/libraries/getpot-c++-1.1.17/getpot/README50
-rwxr-xr-xutils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp2435
4 files changed, 5422 insertions, 0 deletions
diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot
new file mode 100755
index 0000000000..0663880990
--- /dev/null
+++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot
@@ -0,0 +1,2433 @@
1// -*- c++ -*-
2// GetPot Version $$Version$$ $$Date$$
3//
4// WEBSITE: http://getpot.sourceforge.net
5//
6// NOTE: The LPGL License for this library is only valid in case that
7// it is not used for the production or development of applications
8// dedicated to military industry. This is what the author calls
9// the 'unofficial peace version of the LPGL'.
10//
11// This library is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Lesser General Public License as
13// published by the Free Software Foundation; either version 2.1 of the
14// License, or (at your option) any later version.
15//
16// This library is distributed in the hope that it will be useful, but
17// WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19// Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public
22// License along with this library; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24// USA
25//
26// (C) 2001-2005 Frank R. Schaefer <fschaef@users.sf.net>
27//==========================================================================
28
29#ifndef __include_guard_GETPOT_H__
30#define __include_guard_GETPOT_H__
31
32#if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
33#define strtok_r(a, b, c) strtok(a, b)
34#endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC
35
36extern "C" {
37// leave the 'extern C' to make it 100% sure to work -
38// expecially with older distributions of header files.
39#ifndef WIN32
40// this is necessary (depending on OS)
41#include <ctype.h>
42#endif
43#include <stdio.h>
44#include <stdarg.h>
45#include <assert.h>
46}
47#include <cmath>
48#include <string>
49#include <vector>
50#include <algorithm>
51
52#include <fstream>
53#include <iostream> // not every compiler distribution includes <iostream>
54// // with <fstream>
55
56typedef std::vector<std::string> STRING_VECTOR;
57
58#define victorate(TYPE, VARIABLE, ITERATOR) \
59 std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin(); \
60 for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++)
61
62
63class GetPot {
64 //--------
65 inline void __basic_initialization();
66public:
67 // (*) constructors, destructor, assignment operator -----------------------
68 inline GetPot();
69 inline GetPot(const GetPot&);
70 inline GetPot(const int argc_, char** argv_,
71 const char* FieldSeparator=0x0);
72 inline GetPot(const char* FileName,
73 const char* CommentStart=0x0, const char* CommentEnd=0x0,
74 const char* FieldSeparator=0x0);
75 inline ~GetPot();
76 inline GetPot& operator=(const GetPot&);
77
78
79 // (*) absorbing contents of another GetPot object
80 inline void absorb(const GetPot& That);
81 // -- for ufo detection: recording requested arguments, options etc.
82 inline void clear_requests();
83 inline void disable_request_recording() { __request_recording_f = false; }
84 inline void enable_request_recording() { __request_recording_f = true; }
85
86 // (*) direct access to command line arguments -----------------------------
87 inline const std::string operator[](unsigned Idx) const;
88 inline int get(unsigned Idx, int Default) const;
89 inline double get(unsigned Idx, const double& Default) const;
90 inline const std::string get(unsigned Idx, const char* Default) const;
91 inline unsigned size() const;
92
93 // (*) flags ---------------------------------------------------------------
94 inline bool options_contain(const char* FlagList) const;
95 inline bool argument_contains(unsigned Idx, const char* FlagList) const;
96
97 // (*) variables -----------------------------------------------------------
98 // -- scalar values
99 inline int operator()(const char* VarName, int Default) const;
100 inline double operator()(const char* VarName, const double& Default) const;
101 inline const std::string operator()(const char* VarName, const char* Default) const;
102 // -- vectors
103 inline int operator()(const char* VarName, int Default, unsigned Idx) const;
104 inline double operator()(const char* VarName, const double& Default, unsigned Idx) const;
105 inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const;
106
107 // -- setting variables
108 // i) from outside of GetPot (considering prefix etc.)
109 // ii) from inside, use '__set_variable()' below
110 inline void set(const char* VarName, const char* Value, const bool Requested = true);
111 inline void set(const char* VarName, const double& Value, const bool Requested = true);
112 inline void set(const char* VarName, const int Value, const bool Requested = true);
113
114 inline unsigned vector_variable_size(const char* VarName) const;
115 inline STRING_VECTOR get_variable_names() const;
116 inline STRING_VECTOR get_section_names() const;
117
118
119 // (*) cursor oriented functions -------------------------------------------
120 inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); }
121 inline bool search_failed() const { return search_failed_f; }
122
123 // -- enable/disable search for an option in loop
124 inline void disable_loop() { search_loop_f = false; }
125 inline void enable_loop() { search_loop_f = true; }
126
127 // -- reset cursor to position '1'
128 inline void reset_cursor();
129 inline void init_multiple_occurrence();
130
131 // -- search for a certain option and set cursor to position
132 inline bool search(const char* option);
133 inline bool search(unsigned No, const char* P, ...);
134 // -- get argument at cursor++
135 inline int next(int Default);
136 inline double next(const double& Default);
137 inline const std::string next(const char* Default);
138 // -- search for option and get argument at cursor++
139 inline int follow(int Default, const char* Option);
140 inline double follow(const double& Default, const char* Option);
141 inline const std::string follow(const char* Default, const char* Option);
142 // -- search for one of the given options and get argument that follows it
143 inline int follow(int Default, unsigned No, const char* Option, ...);
144 inline double follow(const double& Default, unsigned No, const char* Option, ...);
145 inline const std::string follow(const char* Default, unsigned No, const char* Option, ...);
146 // -- lists of nominuses following an option
147 inline std::vector<std::string> nominus_followers(const char* Option);
148 inline std::vector<std::string> nominus_followers(unsigned No, ...);
149
150 // -- directly followed arguments
151 inline int direct_follow(int Default, const char* Option);
152 inline double direct_follow(const double& Default, const char* Option);
153 inline const std::string direct_follow(const char* Default, const char* Option);
154
155 inline std::vector<std::string> string_tails(const char* StartString);
156 inline std::vector<int> int_tails(const char* StartString, const int Default = 1);
157 inline std::vector<double> double_tails(const char* StartString, const double Default = 1.0);
158
159 // (*) nominus arguments ---------------------------------------------------
160 inline STRING_VECTOR nominus_vector() const;
161 inline unsigned nominus_size() const { return static_cast<unsigned int>(idx_nominus.size()); }
162 inline std::string next_nominus();
163
164 // (*) unidentified flying objects -----------------------------------------
165 inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const;
166 inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const;
167 inline STRING_VECTOR unidentified_arguments() const;
168
169 inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const;
170 inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const;
171 inline STRING_VECTOR unidentified_options() const;
172
173 inline std::string unidentified_flags(const char* Known,
174 int ArgumentNumber /* =-1 */) const;
175
176 inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const;
177 inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const;
178 inline STRING_VECTOR unidentified_variables() const;
179
180 inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const;
181 inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const;
182 inline STRING_VECTOR unidentified_sections() const;
183
184 inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const;
185 inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const;
186 inline STRING_VECTOR unidentified_nominuses() const;
187
188 // (*) output --------------------------------------------------------------
189 inline int print() const;
190
191private:
192 // (*) Type Declaration ----------------------------------------------------
193 struct variable {
194 //-----------
195 // Variable to be specified on the command line or in input files.
196 // (i.e. of the form var='12 312 341')
197
198 // -- constructors, destructors, assignment operator
199 variable();
200 variable(const variable&);
201 variable(const char* Name, const char* Value, const char* FieldSeparator);
202 ~variable();
203 variable& operator=(const variable& That);
204
205 void take(const char* Value, const char* FieldSeparator);
206
207 // -- get a specific element in the string vector
208 // (return 0 if not present)
209 const std::string* get_element(unsigned Idx) const;
210
211 // -- data memebers
212 std::string name; // identifier of variable
213 STRING_VECTOR value; // value of variable stored in vector
214 std::string original; // value of variable as given on command line
215 };
216
217 // (*) member variables --------------------------------------------------------------
218 std::string prefix; // prefix automatically added in queries
219 std::string section; // (for dollar bracket parsing)
220 STRING_VECTOR section_list; // list of all parsed sections
221 // -- argument vector
222 STRING_VECTOR argv; // vector of command line arguments stored as strings
223 unsigned cursor; // cursor for argv
224 bool search_loop_f; // shall search start at beginning after
225 // // reaching end of arg array ?
226 bool search_failed_f; // flag indicating a failed search() operation
227 // // (e.g. next() functions react with 'missed')
228
229 // -- nominus vector
230 int nominus_cursor; // cursor for nominus_pointers
231 std::vector<unsigned> idx_nominus; // indecies of 'no minus' arguments
232
233 // -- variables
234 // (arguments of the form "variable=value")
235 std::vector<variable> variables;
236
237 // -- comment delimiters
238 std::string _comment_start;
239 std::string _comment_end;
240
241 // -- field separator (separating elements of a vector)
242 std::string _field_separator;
243
244 // -- some functions return a char pointer to a temporarily existing string
245 // this container makes them 'available' until the getpot object is destroyed.
246 std::vector<char*> __internal_string_container;
247
248 // -- keeping track about arguments that are requested, so that the UFO detection
249 // can be simplified
250 STRING_VECTOR _requested_arguments;
251 STRING_VECTOR _requested_variables;
252 STRING_VECTOR _requested_sections;
253
254 bool __request_recording_f; // speed: request recording can be turned off
255
256 // -- if an argument is requested record it and the 'tag' the section branch to which
257 // it belongs. Caution: both functions mark the sections as 'tagged'.
258 void __record_argument_request(const std::string& Arg);
259 void __record_variable_request(const std::string& Arg);
260
261 // (*) helper functions ----------------------------------------------------
262 // set variable from inside GetPot (no prefix considered)
263 inline void __set_variable(const char* VarName, const char* Value);
264
265 // -- produce three basic data vectors:
266 // - argument vector
267 // - nominus vector
268 // - variable dictionary
269 inline void __parse_argument_vector(const STRING_VECTOR& ARGV);
270
271 // -- helpers for argument list processing
272 // * search for a variable in 'variables' array
273 inline const variable* __find_variable(const char*) const;
274 // * support finding directly followed arguments
275 inline const char* __match_starting_string(const char* StartString);
276 // * support search for flags in a specific argument
277 inline bool __check_flags(const std::string& Str, const char* FlagList) const;
278 // * type conversion if possible
279 inline int __convert_to_type(const std::string& String, int Default) const;
280 inline double __convert_to_type(const std::string& String, double Default) const;
281 // * prefix extraction
282 const std::string __get_remaining_string(const std::string& String,
283 const std::string& Start) const;
284 // * search for a specific string
285 inline bool __search_string_vector(const STRING_VECTOR& Vec,
286 const std::string& Str) const;
287
288 // -- helpers to parse input file
289 // create an argument vector based on data found in an input file, i.e.:
290 // 1) delete comments (in between '_comment_start' '_comment_end')
291 // 2) contract assignment expressions, such as
292 // my-variable = '007 J. B.'
293 // into
294 // my-variable='007 J. B.'
295 // 3) interprete sections like '[../my-section]' etc.
296 inline void __skip_whitespace(std::istream& istr);
297 inline const std::string __get_next_token(std::istream& istr);
298 inline const std::string __get_string(std::istream& istr);
299 inline const std::string __get_until_closing_bracket(std::istream& istr);
300
301 inline STRING_VECTOR __read_in_stream(std::istream& istr);
302 inline STRING_VECTOR __read_in_file(const char* FileName);
303 inline std::string __process_section_label(const std::string& Section,
304 STRING_VECTOR& section_stack);
305
306 // -- dollar bracket expressions
307 std::string __DBE_expand_string(const std::string str);
308 std::string __DBE_expand(const std::string str);
309 const GetPot::variable* __DBE_get_variable(const std::string str);
310 STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber);
311
312 std::string __double2string(const double& Value) const {
313 // -- converts a double integer into a string
314 char* tmp = new char[128];
315#ifndef WIN32
316 snprintf(tmp, (int)sizeof(char)*128, "%e", Value);
317#else
318 _snprintf(tmp, sizeof(char)*128, "%e", Value);
319#endif
320 std::string result(tmp);
321 delete [] tmp;
322 return result;
323 }
324
325 std::string __int2string(const int& Value) const {
326 // -- converts an integer into a string
327 char* tmp = new char[128];
328#ifndef WIN32
329 snprintf(tmp, (int)sizeof(char)*128, "%i", Value);
330#else
331 _snprintf(tmp, sizeof(char)*128, "%i", Value);
332#endif
333 std::string result(tmp);
334 delete [] tmp;
335 return result;
336 }
337
338 STRING_VECTOR __get_section_tree(const std::string& FullPath) {
339 // -- cuts a variable name into a tree of sub-sections. this is requested for recording
340 // requested sections when dealing with 'ufo' detection.
341 STRING_VECTOR result;
342 const char* Start = FullPath.c_str();
343
344 for(char *p = (char*)Start; *p ; p++) {
345 if( *p == '/' ) {
346 *p = '\0'; // set terminating zero for convinience
347 const std::string Section = Start;
348 *p = '/'; // reset slash at place
349 result.push_back(Section);
350 }
351 }
352
353 return result;
354 }
355};
356
357
358///////////////////////////////////////////////////////////////////////////////
359// (*) constructors, destructor, assignment operator
360//.............................................................................
361//
362inline void
363GetPot::__basic_initialization()
364{
365 cursor = 0; nominus_cursor = -1;
366 search_failed_f = true; search_loop_f = true;
367 prefix = ""; section = "";
368
369 // automatic request recording for later ufo detection
370 __request_recording_f = true;
371
372 // comment start and end strings
373 _comment_start = std::string("#");
374 _comment_end = std::string("\n");
375
376 // default: separate vector elements by whitespaces
377 _field_separator = " \t\n";
378}
379
380inline
381GetPot::GetPot()
382{
383 __basic_initialization();
384
385 STRING_VECTOR _apriori_argv;
386 _apriori_argv.push_back(std::string("Empty"));
387 __parse_argument_vector(_apriori_argv);
388}
389
390inline
391GetPot::GetPot(const int argc_, char ** argv_,
392 const char* FieldSeparator /* =0x0 */)
393 // leave 'char**' non-const to honor less capable compilers ...
394{
395 // TODO: Ponder over the problem when the argument list is of size = 0.
396 // This is 'sabotage', but it can still occur if the user specifies
397 // it himself.
398 assert(argc_ >= 1);
399 __basic_initialization();
400
401 // if specified -> overwrite default string
402 if( FieldSeparator ) _field_separator = std::string(FieldSeparator);
403
404 // -- make an internal copy of the argument list:
405 STRING_VECTOR _apriori_argv;
406 // -- for the sake of clarity: we do want to include the first argument in the argument vector !
407 // it will not be a nominus argument, though. This gives us a minimun vector size of one
408 // which facilitates error checking in many functions. Also the user will be able to
409 // retrieve the name of his application by "get[0]"
410 _apriori_argv.push_back(std::string(argv_[0]));
411 int i=1;
412 for(; i<argc_; ++i) {
413 std::string tmp(argv_[i]); // recall the problem with temporaries,
414 _apriori_argv.push_back(tmp); // reference counting in arguement lists ...
415 }
416 __parse_argument_vector(_apriori_argv);
417}
418
419
420inline
421GetPot::GetPot(const char* FileName,
422 const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */,
423 const char* FieldSeparator/* = 0x0 */)
424{
425 __basic_initialization();
426
427 // if specified -> overwrite default strings
428 if( CommentStart ) _comment_start = std::string(CommentStart);
429 if( CommentEnd ) _comment_end = std::string(CommentEnd);
430 if( FieldSeparator ) _field_separator = FieldSeparator;
431
432 STRING_VECTOR _apriori_argv;
433 // -- file name is element of argument vector, however, it is not parsed for
434 // variable assignments or nominuses.
435 _apriori_argv.push_back(std::string(FileName));
436
437 STRING_VECTOR args = __read_in_file(FileName);
438 _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end());
439 __parse_argument_vector(_apriori_argv);
440}
441
442inline
443GetPot::GetPot(const GetPot& That)
444{ GetPot::operator=(That); }
445
446inline
447GetPot::~GetPot()
448{
449 // may be some return strings had to be created, delete now !
450 victorate(char*, __internal_string_container, it)
451 delete [] *it;
452}
453
454inline GetPot&
455GetPot::operator=(const GetPot& That)
456{
457 if (&That == this) return *this;
458
459 _comment_start = That._comment_start;
460 _comment_end = That._comment_end;
461 argv = That.argv;
462 variables = That.variables;
463 prefix = That.prefix;
464
465 cursor = That.cursor;
466 nominus_cursor = That.nominus_cursor;
467 search_failed_f = That.search_failed_f;
468
469 idx_nominus = That.idx_nominus;
470 search_loop_f = That.search_loop_f;
471
472 return *this;
473}
474
475
476inline void
477GetPot::absorb(const GetPot& That)
478{
479 if (&That == this) return;
480
481 STRING_VECTOR __tmp(That.argv);
482
483 __tmp.erase(__tmp.begin());
484
485 __parse_argument_vector(__tmp);
486}
487
488inline void
489GetPot::clear_requests()
490{
491 _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end());
492 _requested_variables.erase(_requested_variables.begin(), _requested_variables.end());
493 _requested_sections.erase(_requested_sections.begin(), _requested_sections.end());
494}
495
496inline void
497GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV)
498{
499 if( ARGV.size() == 0 ) return;
500
501 // build internal databases:
502 // 1) array with no-minus arguments (usually used as filenames)
503 // 2) variable assignments:
504 // 'variable name' '=' number | string
505 STRING_VECTOR section_stack;
506 STRING_VECTOR::const_iterator it = ARGV.begin();
507
508
509 section = "";
510
511 // -- do not parse the first argument, so that it is not interpreted a s a nominus or so.
512 argv.push_back(*it);
513 ++it;
514
515 // -- loop over remaining arguments
516 unsigned i=1;
517 for(; it != ARGV.end(); ++it, ++i) {
518 std::string arg = *it;
519
520 if( arg.length() == 0 ) continue;
521
522 // -- [section] labels
523 if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) {
524
525 // (*) sections are considered 'requested arguments'
526 if( __request_recording_f ) _requested_arguments.push_back(arg);
527
528 const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2));
529 section = __process_section_label(Name, section_stack);
530 // new section --> append to list of sections
531 if( find(section_list.begin(), section_list.end(), section) == section_list.end() )
532 if( section.length() != 0 ) section_list.push_back(section);
533 argv.push_back(arg);
534 }
535 else {
536 arg = section + __DBE_expand_string(arg);
537 argv.push_back(arg);
538 }
539
540 // -- separate array for nominus arguments
541 if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i));
542
543 // -- variables: does arg contain a '=' operator ?
544 const char* p = arg.c_str();
545 for(; *p ; p++) {
546 if( *p == '=' ) {
547 // (*) record for later ufo detection
548 // arguments carriying variables are always treated as 'requested' arguments.
549 // as a whole! That is 'x=4712' is considered a requested argument.
550 //
551 // unrequested variables have to be detected with the ufo-variable
552 // detection routine.
553 if( __request_recording_f ) _requested_arguments.push_back(arg);
554
555 // set terminating 'zero' to treat first part as single string
556 // => arg (from start to 'p') = Name of variable
557 // p+1 (until terminating zero) = value of variable
558 char* o = (char*)p++;
559 *o = '\0'; // set temporary terminating zero
560 // __set_variable(...)
561 // calls __find_variable(...) which registers the search
562 // temporarily disable this
563 const bool tmp = __request_recording_f;
564 __request_recording_f = false;
565 __set_variable(arg.c_str(), p); // v-name = c_str() bis 'p', value = rest
566 __request_recording_f = tmp;
567 *o = '='; // reset the original '='
568 break;
569 }
570 }
571 }
572}
573
574
575inline STRING_VECTOR
576GetPot::__read_in_file(const char* FileName)
577{
578 std::ifstream i(FileName);
579 if( ! i ) return STRING_VECTOR();
580 // argv[0] == the filename of the file that was read in
581 return __read_in_stream(i);
582}
583
584inline STRING_VECTOR
585GetPot::__read_in_stream(std::istream& istr)
586{
587 STRING_VECTOR brute_tokens;
588 while(istr) {
589 __skip_whitespace(istr);
590 const std::string Token = __get_next_token(istr);
591 if( Token.length() == 0 || Token[0] == EOF) break;
592 brute_tokens.push_back(Token);
593 }
594
595 // -- reduce expressions of token1'='token2 to a single
596 // string 'token1=token2'
597 // -- copy everything into 'argv'
598 // -- arguments preceded by something like '[' name ']' (section)
599 // produce a second copy of each argument with a prefix '[name]argument'
600 unsigned i1 = 0;
601 unsigned i2 = 1;
602 unsigned i3 = 2;
603
604 STRING_VECTOR arglist;
605 while( i1 < brute_tokens.size() ) {
606 const std::string& SRef = brute_tokens[i1];
607 // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef'
608 // note: java.lang.String: substring(a,b) = from a to b-1
609 // C++ string: substr(a,b) = from a to a + b
610 if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) {
611 if( i3 >= brute_tokens.size() )
612 arglist.push_back(brute_tokens[i1] + brute_tokens[i2]);
613 else
614 arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]);
615 i1 = i3+1; i2 = i3+2; i3 = i3+3;
616 continue;
617 }
618 else {
619 arglist.push_back(SRef);
620 i1=i2; i2=i3; i3++;
621 }
622 }
623 return arglist;
624}
625
626inline void
627GetPot::__skip_whitespace(std::istream& istr)
628 // find next non-whitespace while deleting comments
629{
630 int tmp = istr.get();
631 do {
632 // -- search a non whitespace
633 while( isspace(tmp) ) {
634 tmp = istr.get();
635 if( ! istr ) return;
636 }
637
638 // -- look if characters match the comment starter string
639 const std::istream::pos_type Pos = istr.tellg();
640 unsigned i=0;
641 for(; i<_comment_start.length() ; ++i) {
642 if( tmp != _comment_start[i] ) {
643 istr.seekg(Pos);
644 // -- one step more backwards, since 'tmp' already at non-whitespace
645 istr.unget();
646 return;
647 }
648 tmp = istr.get();
649 if( ! istr ) { istr.unget(); return; }
650 }
651 // 'tmp' contains last character of _comment_starter
652
653 // -- comment starter found -> search for comment ender
654 unsigned match_no=0;
655 while(1+1 == 2) {
656 tmp = istr.get();
657 if( ! istr ) { istr.unget(); return; }
658
659 if( tmp == _comment_end[match_no] ) {
660 match_no++;
661 if( match_no == _comment_end.length() ) {
662 istr.unget();
663 break; // shuffle more whitespace, end of comment found
664 }
665 }
666 else
667 match_no = 0;
668 }
669
670 tmp = istr.get();
671
672 } while( istr );
673 istr.unget();
674}
675
676inline const std::string
677GetPot::__get_next_token(std::istream& istr)
678 // get next concatinates string token. consider quotes that embrace
679 // whitespaces
680{
681 std::string token;
682 int tmp = 0;
683 int last_letter = 0;
684 while(1+1 == 2) {
685 last_letter = tmp; tmp = istr.get();
686 if( tmp == EOF
687 || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) {
688 return token;
689 }
690 else if( tmp == '\'' && last_letter != '\\' ) {
691 // QUOTES: un-backslashed quotes => it's a string
692 token += __get_string(istr);
693 continue;
694 }
695 else if( tmp == '{' && last_letter == '$') {
696 token += '{' + __get_until_closing_bracket(istr);
697 continue;
698 }
699 else if( tmp == '$' && last_letter == '\\') {
700 token += tmp; tmp = 0; // so that last_letter will become = 0, not '$';
701 continue;
702 }
703 else if( tmp == '\\' && last_letter != '\\')
704 continue; // don't append un-backslashed backslashes
705 token += tmp;
706 }
707}
708
709inline const std::string
710GetPot::__get_string(std::istream& istr)
711 // parse input until next matching '
712{
713 std::string str;
714 int tmp = 0;
715 int last_letter = 0;
716 while(1 + 1 == 2) {
717 last_letter = tmp; tmp = istr.get();
718 if( tmp == EOF) return str;
719 // un-backslashed quotes => it's the end of the string
720 else if( tmp == '\'' && last_letter != '\\') return str;
721 else if( tmp == '\\' && last_letter != '\\') continue; // don't append
722
723 str += tmp;
724 }
725}
726
727inline const std::string
728GetPot::__get_until_closing_bracket(std::istream& istr)
729 // parse input until next matching }
730{
731 std::string str = "";
732 int tmp = 0;
733 int last_letter = 0;
734 int brackets = 1;
735 while(1 + 1 == 2) {
736 last_letter = tmp; tmp = istr.get();
737 if( tmp == EOF) return str;
738 else if( tmp == '{' && last_letter == '$') brackets += 1;
739 else if( tmp == '}') {
740 brackets -= 1;
741 // un-backslashed brackets => it's the end of the string
742 if( brackets == 0) return str + '}';
743 else if( tmp == '\\' && last_letter != '\\')
744 continue; // do not append an unbackslashed backslash
745 }
746 str += tmp;
747 }
748}
749
750inline std::string
751GetPot::__process_section_label(const std::string& Section,
752 STRING_VECTOR& section_stack)
753{
754 std::string sname = Section;
755 // 1) subsection of actual section ('./' prefix)
756 if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) {
757 sname = sname.substr(2);
758 }
759 // 2) subsection of parent section ('../' prefix)
760 else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) {
761 do {
762 if( section_stack.end() != section_stack.begin() )
763 section_stack.pop_back();
764 sname = sname.substr(3);
765 } while( sname.substr(0, 3) == "../" );
766 }
767 // 3) subsection of the root-section
768 else {
769 section_stack.erase(section_stack.begin(), section_stack.end());
770 // [] => back to root section
771 }
772
773 if( sname != "" ) {
774 // parse section name for 'slashes'
775 unsigned i=0;
776 while( i < sname.length() ) {
777 if( sname[i] == '/' ) {
778 section_stack.push_back(sname.substr(0,i));
779 if( i+1 < sname.length()-1 )
780 sname = sname.substr(i+1);
781 i = 0;
782 }
783 else
784 ++i;
785 }
786 section_stack.push_back(sname);
787 }
788 std::string section = "";
789 if( section_stack.size() != 0 ) {
790 victorate(std::string, section_stack, it)
791 section += *it + "/";
792 }
793 return section;
794}
795
796
797// convert string to DOUBLE, if not possible return Default
798inline double
799GetPot::__convert_to_type(const std::string& String, double Default) const
800{
801 double tmp;
802 if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default;
803 return tmp;
804}
805
806// convert string to INT, if not possible return Default
807inline int
808GetPot::__convert_to_type(const std::string& String, int Default) const
809{
810 // NOTE: intermediate results may be floating points, so that the string
811 // may look like 2.0e1 (i.e. float format) => use float conversion
812 // in any case.
813 return (int)__convert_to_type(String, (double)Default);
814}
815
816//////////////////////////////////////////////////////////////////////////////
817// (*) cursor oriented functions
818//.............................................................................
819inline const std::string
820GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const
821 // Checks if 'String' begins with 'Start' and returns the remaining String.
822 // Returns None if String does not begin with Start.
823{
824 if( Start == "" ) return String;
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( String.find(Start) == 0 ) return String.substr(Start.length());
828 else return "";
829}
830
831// -- search for a certain argument and set cursor to position
832inline bool
833GetPot::search(const char* Option)
834{
835 unsigned OldCursor = cursor;
836 const std::string SearchTerm = prefix + Option;
837
838 // (*) record requested arguments for later ufo detection
839 __record_argument_request(SearchTerm);
840
841 if( OldCursor >= argv.size() ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
842 search_failed_f = true;
843
844 // (*) first loop from cursor position until end
845 unsigned c = cursor;
846 for(; c < argv.size(); c++) {
847 if( argv[c] == SearchTerm )
848 { cursor = c; search_failed_f = false; return true; }
849 }
850 if( ! search_loop_f ) return false;
851
852 // (*) second loop from 0 to old cursor position
853 for(c = 1; c < OldCursor; c++) {
854 if( argv[c] == SearchTerm )
855 { cursor = c; search_failed_f = false; return true; }
856 }
857 // in case nothing is found the cursor stays where it was
858 return false;
859}
860
861
862inline bool
863GetPot::search(unsigned No, const char* P, ...)
864{
865 // (*) recording the requested arguments happens in subroutine 'search'
866 if( No == 0 ) return false;
867
868 // search for the first argument
869 if( search(P) == true ) return true;
870
871 // start interpreting variable argument list
872 va_list ap;
873 va_start(ap, P);
874 unsigned i = 1;
875 for(; i < No; ++i) {
876 char* Opt = va_arg(ap, char *);
877 if( search(Opt) == true ) break;
878 }
879
880 if( i < No ) {
881 ++i;
882 // loop was left before end of array --> hit but
883 // make sure that the rest of the search terms is marked
884 // as requested.
885 for(; i < No; ++i) {
886 char* Opt = va_arg(ap, char *);
887 // (*) record requested arguments for later ufo detection
888 __record_argument_request(Opt);
889 }
890 va_end(ap);
891 return true;
892 }
893
894 va_end(ap);
895 // loop was left normally --> no hit
896 return false;
897}
898
899inline void
900GetPot::reset_cursor()
901{ search_failed_f = false; cursor = 0; }
902
903inline void
904GetPot::init_multiple_occurrence()
905{ disable_loop(); reset_cursor(); }
906///////////////////////////////////////////////////////////////////////////////
907// (*) direct access to command line arguments
908//.............................................................................
909//
910inline const std::string
911GetPot::operator[](unsigned idx) const
912{ return idx < argv.size() ? argv[idx] : ""; }
913
914inline int
915GetPot::get(unsigned Idx, int Default) const
916{
917 if( Idx >= argv.size() ) return Default;
918 return __convert_to_type(argv[Idx], Default);
919}
920
921inline double
922GetPot::get(unsigned Idx, const double& Default) const
923{
924 if( Idx >= argv.size() ) return Default;
925 return __convert_to_type(argv[Idx], Default);
926}
927
928inline const std::string
929GetPot::get(unsigned Idx, const char* Default) const
930{
931 if( Idx >= argv.size() ) return Default;
932 else return argv[Idx];
933}
934
935inline unsigned
936GetPot::size() const
937{ return static_cast<unsigned int>(argv.size()); }
938
939
940// -- next() function group
941inline int
942GetPot::next(int Default)
943{
944 if( search_failed_f ) return Default;
945 cursor++;
946 if( cursor >= argv.size() )
947 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
948
949 // (*) record requested argument for later ufo detection
950 __record_argument_request(argv[cursor]);
951
952 const std::string Remain = __get_remaining_string(argv[cursor], prefix);
953
954 return Remain != "" ? __convert_to_type(Remain, Default) : Default;
955}
956
957inline double
958GetPot::next(const double& Default)
959{
960 if( search_failed_f ) return Default;
961 cursor++;
962
963 if( cursor >= argv.size() )
964 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
965
966 // (*) record requested argument for later ufo detection
967 __record_argument_request(argv[cursor]);
968
969 std::string Remain = __get_remaining_string(argv[cursor], prefix);
970
971 return Remain != "" ? __convert_to_type(Remain, Default) : Default;
972}
973
974inline const std::string
975GetPot::next(const char* Default)
976{
977 if( search_failed_f ) return Default;
978 cursor++;
979
980 if( cursor >= argv.size() )
981 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
982
983 // (*) record requested argument for later ufo detection
984 __record_argument_request(argv[cursor]);
985
986 const std::string Remain = __get_remaining_string(argv[cursor], prefix);
987
988 if( Remain == "" ) return Default;
989
990
991 // (*) function returns a pointer to a char array (inside Remain)
992 // this array will be deleted, though after this function call.
993 // To ensure propper functioning, create a copy inside *this
994 // object and only delete it, when *this is deleted.
995 char* result = new char[Remain.length()+1];
996 strncpy(result, Remain.c_str(), Remain.length()+1);
997
998 // store the created string internally, delete if when object deleted
999 __internal_string_container.push_back(result);
1000
1001 return result;
1002}
1003
1004// -- follow() function group
1005// distinct option to be searched for
1006inline int
1007GetPot::follow(int Default, const char* Option)
1008{
1009 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1010 if( search(Option) == false ) return Default;
1011 return next(Default);
1012}
1013
1014inline double
1015GetPot::follow(const double& Default, const char* Option)
1016{
1017 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1018 if( search(Option) == false ) return Default;
1019 return next(Default);
1020}
1021
1022inline const std::string
1023GetPot::follow(const char* Default, const char* Option)
1024{
1025 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1026 if( search(Option) == false ) return Default;
1027 return next(Default);
1028}
1029
1030// -- second follow() function group
1031// multiple option to be searched for
1032inline int
1033GetPot::follow(int Default, unsigned No, const char* P, ...)
1034{
1035 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1036 if( No == 0 ) return Default;
1037 if( search(P) == true ) return next(Default);
1038
1039 va_list ap;
1040 va_start(ap, P);
1041 unsigned i=1;
1042 for(; i<No; ++i) {
1043 char* Opt = va_arg(ap, char *);
1044 if( search(Opt) == true ) {
1045 va_end(ap);
1046 return next(Default);
1047 }
1048 }
1049 va_end(ap);
1050 return Default;
1051}
1052
1053inline double
1054GetPot::follow(const double& Default, unsigned No, const char* P, ...)
1055{
1056 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1057 if( No == 0 ) return Default;
1058 if( search(P) == true ) return next(Default);
1059
1060 va_list ap;
1061 va_start(ap, P);
1062 for(unsigned i=1; i<No; ++i) {
1063 char* Opt = va_arg(ap, char *);
1064 if( search(Opt) == true ) {
1065 va_end(ap);
1066 return next(Default);
1067 }
1068 }
1069 va_end(ap);
1070 return Default;
1071}
1072
1073inline const std::string
1074GetPot::follow(const char* Default, unsigned No, const char* P, ...)
1075{
1076 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1077 if( No == 0 ) return Default;
1078 if( search(P) == true ) return next(Default);
1079
1080 va_list ap;
1081 va_start(ap, P);
1082 unsigned i=1;
1083 for(; i<No; ++i) {
1084 char* Opt = va_arg(ap, char *);
1085 if( search(Opt) == true ) {
1086 va_end(ap);
1087 return next(Default);
1088 }
1089 }
1090 va_end(ap);
1091 return Default;
1092}
1093
1094
1095///////////////////////////////////////////////////////////////////////////////
1096// (*) lists of nominus following an option
1097//.............................................................................
1098//
1099inline std::vector<std::string>
1100GetPot::nominus_followers(const char* Option)
1101{
1102 std::vector<std::string> result_list;
1103 if( search(Option) == false ) return result_list;
1104 while( 1 + 1 == 2 ) {
1105 ++cursor;
1106 if( cursor >= argv.size() ) {
1107 cursor = argv.size() - 1;
1108 return result_list;
1109 }
1110 if( argv[cursor].length() >= 1 ) {
1111 if( argv[cursor][0] == '-' ) {
1112 return result_list;
1113 }
1114 // -- record for later ufo-detection
1115 __record_argument_request(argv[cursor]);
1116 // -- append to the result list
1117 result_list.push_back(argv[cursor]);
1118 }
1119 }
1120}
1121
1122inline std::vector<std::string>
1123GetPot::nominus_followers(unsigned No, ...)
1124{
1125 std::vector<std::string> result_list;
1126 // (*) record requested of argument is entirely handled in 'search()'
1127 // and 'nominus_followers()'
1128 if( No == 0 ) return result_list;
1129
1130 va_list ap;
1131 va_start(ap, No);
1132 for(unsigned i=0; i<No; ++i) {
1133 char* Option = va_arg(ap, char *);
1134 std::vector<std::string> tmp = nominus_followers(Option);
1135 result_list.insert(result_list.end(), tmp.begin(), tmp.end());
1136
1137 // std::cerr << "option = '" << Option << "'" << std::endl;
1138 // std::cerr << "length = " << tmp.size() << std::endl;
1139 // std::cerr << "new result list = <";
1140 // for(std::vector<std::string>::const_iterator it = result_list.begin();
1141 // it != result_list.end(); ++it)
1142 // std::cerr << *it << ", ";
1143 // std::cerr << ">\n";
1144 }
1145 va_end(ap);
1146 return result_list;
1147}
1148
1149
1150///////////////////////////////////////////////////////////////////////////////
1151// (*) directly connected options
1152//.............................................................................
1153//
1154inline int
1155GetPot::direct_follow(int Default, const char* Option)
1156{
1157 const char* FollowStr = __match_starting_string(Option);
1158 if( FollowStr == 0x0 ) return Default;
1159
1160 // (*) record requested of argument for later ufo-detection
1161 __record_argument_request(std::string(Option) + FollowStr);
1162
1163 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
1164 return __convert_to_type(FollowStr, Default);
1165}
1166
1167inline double
1168GetPot::direct_follow(const double& Default, const char* Option)
1169{
1170 const char* FollowStr = __match_starting_string(Option);
1171 if( FollowStr == 0 ) return Default;
1172
1173 // (*) record requested of argument for later ufo-detection
1174 __record_argument_request(std::string(Option) + FollowStr);
1175
1176 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
1177 return __convert_to_type(FollowStr, Default);
1178}
1179
1180inline const std::string
1181GetPot::direct_follow(const char* Default, const char* Option)
1182{
1183 if( search_failed_f ) return Default;
1184 const char* FollowStr = __match_starting_string(Option);
1185 if( FollowStr == 0 ) return Default;
1186
1187 // (*) record requested of argument for later ufo-detection
1188 if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr);
1189
1190 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
1191 return std::string(FollowStr);
1192}
1193
1194inline std::vector<std::string>
1195GetPot::string_tails(const char* StartString)
1196{
1197 std::vector<std::string> result;
1198 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1199
1200 std::vector<std::string>::iterator it = argv.begin();
1201
1202 unsigned idx = 0;
1203 while( it != argv.end() ) {
1204 // (*) does start string match the given option?
1205 // NO -> goto next option
1206 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
1207
1208 // append the found tail to the result vector
1209 result.push_back((*it).substr(N));
1210
1211 // adapt the nominus vector
1212 std::vector<unsigned>::iterator nit = idx_nominus.begin();
1213 for(; nit != idx_nominus.end(); ++nit) {
1214 if( *nit == idx ) {
1215 idx_nominus.erase(nit);
1216 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
1217 break;
1218 }
1219 }
1220
1221 // erase the found option
1222 argv.erase(it);
1223
1224 // 100% safe solution: set iterator back to the beginning.
1225 // (normally, 'it--' would be enough, but who knows how the
1226 // iterator is implemented and .erase() definitely invalidates
1227 // the current iterator position.
1228 if( argv.empty() ) break;
1229 it = argv.begin();
1230 }
1231 cursor = 0;
1232 nominus_cursor = -1;
1233 return result;
1234}
1235
1236inline std::vector<int>
1237GetPot::int_tails(const char* StartString, const int Default /* = -1 */)
1238{
1239 std::vector<int> result;
1240 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1241
1242 std::vector<std::string>::iterator it = argv.begin();
1243
1244 unsigned idx = 0;
1245 while( it != argv.end() ) {
1246 // (*) does start string match the given option?
1247 // NO -> goto next option
1248 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
1249
1250 // append the found tail to the result vector
1251 result.push_back(__convert_to_type((*it).substr(N), Default));
1252
1253 // adapt the nominus vector
1254 std::vector<unsigned>::iterator nit = idx_nominus.begin();
1255 for(; nit != idx_nominus.end(); ++nit) {
1256 if( *nit == idx ) {
1257 idx_nominus.erase(nit);
1258 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
1259 break;
1260 }
1261 }
1262
1263 // erase the found option
1264 argv.erase(it);
1265
1266 // 100% safe solution: set iterator back to the beginning.
1267 // (normally, 'it--' would be enough, but who knows how the
1268 // iterator is implemented and .erase() definitely invalidates
1269 // the current iterator position.
1270 if( argv.empty() ) break;
1271 it = argv.begin();
1272 }
1273 cursor = 0;
1274 nominus_cursor = -1;
1275 return result;
1276}
1277
1278inline std::vector<double>
1279GetPot::double_tails(const char* StartString,
1280 const double Default /* = -1.0 */)
1281{
1282 std::vector<double> result;
1283 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1284
1285 std::vector<std::string>::iterator it = argv.begin();
1286 unsigned idx = 0;
1287 while( it != argv.end() ) {
1288 // (*) does start string match the given option?
1289 // NO -> goto next option
1290 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
1291
1292 // append the found tail to the result vector
1293 result.push_back(__convert_to_type((*it).substr(N), Default));
1294
1295 // adapt the nominus vector
1296 std::vector<unsigned>::iterator nit = idx_nominus.begin();
1297 for(; nit != idx_nominus.end(); ++nit) {
1298 if( *nit == idx ) {
1299 idx_nominus.erase(nit);
1300 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
1301 break;
1302 }
1303 }
1304
1305 // erase the found option
1306 argv.erase(it);
1307
1308 // 100% safe solution: set iterator back to the beginning.
1309 // (normally, 'it--' would be enough, but who knows how the
1310 // iterator is implemented and .erase() definitely invalidates
1311 // the current iterator position.
1312 if( argv.empty() ) break;
1313 it = argv.begin();
1314 }
1315 cursor = 0;
1316 nominus_cursor = -1;
1317 return result;
1318}
1319
1320
1321
1322
1323
1324inline const char*
1325GetPot::__match_starting_string(const char* StartString)
1326 // pointer to the place where the string after
1327 // the match inside the found argument starts.
1328 // 0 no argument matches the starting string.
1329{
1330 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1331 unsigned OldCursor = cursor;
1332
1333 if( OldCursor >= static_cast<unsigned int>(argv.size()) ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
1334 search_failed_f = true;
1335
1336 // (*) first loop from cursor position until end
1337 unsigned c = cursor;
1338 for(; c < argv.size(); c++) {
1339 if( strncmp(StartString, argv[c].c_str(), N) == 0)
1340 { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
1341 }
1342
1343 if( ! search_loop_f ) return false;
1344
1345 // (*) second loop from 0 to old cursor position
1346 for(c = 1; c < OldCursor; c++) {
1347 if( strncmp(StartString, argv[c].c_str(), N) == 0)
1348 { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
1349 }
1350 return 0;
1351}
1352
1353///////////////////////////////////////////////////////////////////////////////
1354// (*) search for flags
1355//.............................................................................
1356//
1357inline bool
1358GetPot::options_contain(const char* FlagList) const
1359{
1360 // go through all arguments that start with a '-' (but not '--')
1361 std::string str;
1362 STRING_VECTOR::const_iterator it = argv.begin();
1363 for(; it != argv.end(); ++it) {
1364 str = __get_remaining_string(*it, prefix);
1365
1366 if( str.length() >= 2 && str[0] == '-' && str[1] != '-' )
1367 if( __check_flags(str, FlagList) ) return true;
1368 }
1369 return false;
1370}
1371
1372inline bool
1373GetPot::argument_contains(unsigned Idx, const char* FlagList) const
1374{
1375 if( Idx >= argv.size() ) return false;
1376
1377 // (*) record requested of argument for later ufo-detection
1378 // an argument that is checked for flags is considered to be 'requested'
1379 ((GetPot*)this)->__record_argument_request(argv[Idx]);
1380
1381 if( prefix == "" )
1382 // search argument for any flag in flag list
1383 return __check_flags(argv[Idx], FlagList);
1384
1385 // if a prefix is set, then the argument index is the index
1386 // inside the 'namespace'
1387 // => only check list of arguments that start with prefix
1388 unsigned no_matches = 0;
1389 unsigned i=0;
1390 for(; i<argv.size(); ++i) {
1391 const std::string Remain = __get_remaining_string(argv[i], prefix);
1392 if( Remain != "") {
1393 no_matches += 1;
1394 if( no_matches == Idx)
1395 return __check_flags(Remain, FlagList);
1396 }
1397 }
1398 // no argument in this namespace
1399 return false;
1400}
1401
1402inline bool
1403GetPot::__check_flags(const std::string& Str, const char* FlagList) const
1404{
1405 const char* p=FlagList;
1406 for(; *p != '\0' ; p++)
1407 if( Str.find(*p) != std::string::npos ) return true; // found something
1408 return false;
1409}
1410
1411///////////////////////////////////////////////////////////////////////////////
1412// (*) nominus arguments
1413inline STRING_VECTOR
1414GetPot::nominus_vector() const
1415 // return vector of nominus arguments
1416{
1417 STRING_VECTOR nv;
1418 std::vector<unsigned>::const_iterator it = idx_nominus.begin();
1419 for(; it != idx_nominus.end(); ++it) {
1420 nv.push_back(argv[*it]);
1421
1422 // (*) record for later ufo-detection
1423 // when a nominus vector is requested, the entire set of nominus arguments are
1424 // tagged as 'requested'
1425 ((GetPot*)this)->__record_argument_request(argv[*it]);
1426 }
1427 return nv;
1428}
1429
1430inline std::string
1431GetPot::next_nominus()
1432{
1433 if( nominus_cursor < int(idx_nominus.size()) - 1 ) {
1434 const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
1435
1436 // (*) record for later ufo-detection
1437 __record_argument_request(Tmp);
1438
1439 // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer
1440 // to something that does no longer exist.
1441 return Tmp;
1442 }
1443 return std::string("");
1444}
1445
1446///////////////////////////////////////////////////////////////////////////////
1447// (*) variables
1448//.............................................................................
1449//
1450inline int
1451GetPot::operator()(const char* VarName, int Default) const
1452{
1453 // (*) recording of requested variables happens in '__find_variable()'
1454 const variable* sv = __find_variable(VarName);
1455 if( sv == 0 ) return Default;
1456 return __convert_to_type(sv->original, Default);
1457}
1458
1459inline double
1460GetPot::operator()(const char* VarName, const double& Default) const
1461{
1462 // (*) recording of requested variables happens in '__find_variable()'
1463 const variable* sv = __find_variable(VarName);
1464 if( sv == 0 ) return Default;
1465 return __convert_to_type(sv->original, Default);
1466}
1467
1468inline const std::string
1469GetPot::operator()(const char* VarName, const char* Default) const
1470{
1471 // (*) recording of requested variables happens in '__find_variable()'
1472 const variable* sv = __find_variable(VarName);
1473 if( sv == 0 ) return Default;
1474 // -- returning a c_str() pointer is OK here, since the variable remains existant,
1475 // while 'sv' of course is delete at the end of the function.
1476 return sv->original;
1477}
1478
1479inline int
1480GetPot::operator()(const char* VarName, int Default, unsigned Idx) const
1481{
1482 // (*) recording of requested variables happens in '__find_variable()'
1483 const variable* sv = __find_variable(VarName);
1484 if( sv == 0 ) return Default;
1485 const std::string* element = sv->get_element(Idx);
1486 if( element == 0 ) return Default;
1487 return __convert_to_type(*element, Default);
1488}
1489
1490inline double
1491GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const
1492{
1493 // (*) recording of requested variables happens in '__find_variable()'
1494 const variable* sv = __find_variable(VarName);
1495 if( sv == 0 ) return Default;
1496 const std::string* element = sv->get_element(Idx);
1497 if( element == 0 ) return Default;
1498 return __convert_to_type(*element, Default);
1499}
1500
1501inline const std::string
1502GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const
1503{
1504 // (*) recording of requested variables happens in '__find_variable()'
1505 const variable* sv = __find_variable(VarName);
1506 if( sv == 0 ) return Default;
1507 const std::string* element = sv->get_element(Idx);
1508 if( element == 0 ) return Default;
1509 return *element;
1510}
1511
1512inline void
1513GetPot::__record_argument_request(const std::string& Name)
1514{
1515 if( ! __request_recording_f ) return;
1516
1517 // (*) record requested variable for later ufo detection
1518 _requested_arguments.push_back(Name);
1519
1520 // (*) record considered section for ufo detection
1521 STRING_VECTOR STree = __get_section_tree(Name);
1522 victorate(std::string, STree, it)
1523 if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
1524 if( section.length() != 0 ) _requested_sections.push_back(*it);
1525}
1526
1527inline void
1528GetPot::__record_variable_request(const std::string& Name)
1529{
1530 if( ! __request_recording_f ) return;
1531
1532 // (*) record requested variable for later ufo detection
1533 _requested_variables.push_back(Name);
1534
1535 // (*) record considered section for ufo detection
1536 STRING_VECTOR STree = __get_section_tree(Name);
1537 victorate(std::string, STree, it)
1538 if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
1539 if( section.length() != 0 ) _requested_sections.push_back(*it);
1540}
1541
1542// (*) following functions are to be used from 'outside', after getpot has parsed its
1543// arguments => append an argument in the argument vector that reflects the addition
1544inline void
1545GetPot::__set_variable(const char* VarName, const char* Value)
1546{
1547 const GetPot::variable* Var = __find_variable(VarName);
1548 if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str()));
1549 else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str());
1550}
1551
1552inline void
1553GetPot::set(const char* VarName, const char* Value, const bool Requested /* = yes */)
1554{
1555 const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value);
1556 argv.push_back(Arg);
1557 __set_variable(VarName, Value);
1558
1559 // if user does not specify the variable as 'not being requested' it will be
1560 // considered amongst the requested variables
1561 if( Requested ) __record_variable_request(Arg);
1562}
1563
1564inline void
1565GetPot::set(const char* VarName, const double& Value, const bool Requested /* = yes */)
1566{ __set_variable(VarName, __double2string(Value).c_str()); }
1567
1568inline void
1569GetPot::set(const char* VarName, const int Value, const bool Requested /* = yes */)
1570{ __set_variable(VarName, __int2string(Value).c_str()); }
1571
1572
1573inline unsigned
1574GetPot::vector_variable_size(const char* VarName) const
1575{
1576 const variable* sv = __find_variable(VarName);
1577 if( sv == 0 ) return 0;
1578 return static_cast<unsigned int>(sv->value.size());
1579}
1580
1581inline STRING_VECTOR
1582GetPot::get_variable_names() const
1583{
1584 STRING_VECTOR result;
1585 std::vector<GetPot::variable>::const_iterator it = variables.begin();
1586 for(; it != variables.end(); ++it) {
1587 const std::string Tmp = __get_remaining_string((*it).name, prefix);
1588 if( Tmp != "" ) result.push_back(Tmp);
1589 }
1590 return result;
1591}
1592
1593inline STRING_VECTOR
1594GetPot::get_section_names() const
1595{ return section_list; }
1596
1597inline const GetPot::variable*
1598GetPot::__find_variable(const char* VarName) const
1599{
1600 const std::string Name = prefix + VarName;
1601
1602 // (*) record requested variable for later ufo detection
1603 ((GetPot*)this)->__record_variable_request(Name);
1604
1605 std::vector<variable>::const_iterator it = variables.begin();
1606 for(; it != variables.end(); ++it) {
1607 if( (*it).name == Name ) return &(*it);
1608 }
1609 return 0;
1610}
1611
1612///////////////////////////////////////////////////////////////////////////////
1613// (*) ouput (basically for debugging reasons
1614//.............................................................................
1615//
1616inline int
1617GetPot::print() const
1618{
1619 std::cout << "argc = " << static_cast<unsigned int>(argv.size()) << std::endl;
1620 STRING_VECTOR::const_iterator it = argv.begin();
1621 for(; it != argv.end(); ++it)
1622 std::cout << *it << std::endl;
1623 std::cout << std::endl;
1624 return 1;
1625}
1626
1627// (*) dollar bracket expressions (DBEs) ------------------------------------
1628//
1629// 1) Entry Function: __DBE_expand_string()
1630// Takes a string such as
1631//
1632// "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}"
1633//
1634// calls __DBE_expand() for each of the expressions
1635//
1636// ${+ ${x} ${y}}
1637// ${& ${section} ${subsection}}
1638// ${Title}
1639//
1640// and returns the string
1641//
1642// "4711 Subject-1.01: Mit den Clowns kamen die Schwaene"
1643//
1644// assuming that
1645// x = "4699"
1646// y = "12"
1647// section = "1."
1648// subsection = "01"
1649// title = "Mit den Clowns kamen die Schwaene"
1650//
1651// 2) __DBE_expand():
1652//
1653// checks for the command, i.e. the 'sign' that follows '${'
1654// divides the argument list into sub-expressions using
1655// __DBE_get_expr_list()
1656//
1657// ${+ ${x} ${y}} -> "${x}" "${y}"
1658// ${& ${section} ${subsection}} -> "${section}" "${subsection}"
1659// ${Title} -> Nothing, variable expansion
1660//
1661// 3) __DBE_expression_list():
1662//
1663// builds a vector of unbracketed whitespace separated strings, i.e.
1664//
1665// " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}"
1666//
1667// is split into a vector
1668//
1669// [0] ${Number}.a
1670// [1] ${: Das Marmorbild}
1671// [2] AB-${& Author= ${Eichendorf}}-1870
1672//
1673// Each sub-expression is expanded using expand().
1674//---------------------------------------------------------------------------
1675inline std::string
1676GetPot::__DBE_expand_string(const std::string str)
1677{
1678 // Parses for closing operators '${ }' and expands them letting
1679 // white spaces and other letters as they are.
1680 std::string new_string = "";
1681 unsigned open_brackets = 0;
1682 unsigned first = 0;
1683 unsigned i = 0;
1684 for(; i<str.size(); ++i) {
1685 if( i < str.size() - 2 && str.substr(i, 2) == "${" ) {
1686 if( open_brackets == 0 ) first = i+2;
1687 open_brackets++;
1688 }
1689 else if( str[i] == '}' && open_brackets > 0) {
1690 open_brackets -= 1;
1691 if( open_brackets == 0 ) {
1692 const std::string Replacement = __DBE_expand(str.substr(first, i - first));
1693 new_string += Replacement;
1694 }
1695 }
1696 else if( open_brackets == 0 )
1697 new_string += str[i];
1698 }
1699 return new_string;
1700}
1701
1702inline STRING_VECTOR
1703GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber)
1704 // ensures that the resulting vector has the expected number
1705 // of arguments, but they may contain an error message
1706{
1707 std::string str = str_;
1708 // Separates expressions by non-bracketed whitespaces, expands them
1709 // and puts them into a list.
1710
1711 unsigned i=0;
1712 // (1) eat initial whitespaces
1713 for(; i < str.size(); ++i)
1714 if( ! isspace(str[i]) ) break;
1715
1716 STRING_VECTOR expr_list;
1717 unsigned open_brackets = 0;
1718 std::vector<unsigned> start_idx;
1719 unsigned start_new_string = i;
1720 unsigned l = static_cast<unsigned int>(str.size());
1721
1722 // (2) search for ${ } expressions ...
1723 while( i < l ) {
1724 const char letter = str[i];
1725 // whitespace -> end of expression
1726 if( isspace(letter) && open_brackets == 0) {
1727 expr_list.push_back(str.substr(start_new_string, i - start_new_string));
1728 bool no_breakout_f = true;
1729 for(++i; i < l ; ++i) {
1730 if( ! isspace(str[i]) )
1731 { no_breakout_f = false; start_new_string = i; break; }
1732 }
1733 if( no_breakout_f ) {
1734 // end of expression list
1735 if( expr_list.size() < ExpectedNumber ) {
1736 const std::string pre_tmp("<< ${ }: missing arguments>>");
1737 STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
1738 expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
1739 }
1740 return expr_list;
1741 }
1742 }
1743
1744 // dollar-bracket expression
1745 if( str.length() >= i+2 && str.substr(i, 2) == "${" ) {
1746 open_brackets++;
1747 start_idx.push_back(i+2);
1748 }
1749 else if( letter == '}' && open_brackets > 0) {
1750 int start = start_idx[start_idx.size()-1];
1751 start_idx.pop_back();
1752 const std::string Replacement = __DBE_expand(str.substr(start, i-start));
1753 if( start - 3 < (int)0)
1754 str = Replacement + str.substr(i+1);
1755 else
1756 str = str.substr(0, start-2) + Replacement + str.substr(i+1);
1757 l = static_cast<unsigned int>(str.size());
1758 i = start + static_cast<unsigned int>(Replacement.size()) - 3;
1759 open_brackets--;
1760 }
1761 ++i;
1762 }
1763
1764 // end of expression list
1765 expr_list.push_back(str.substr(start_new_string, i-start_new_string));
1766
1767 if( expr_list.size() < ExpectedNumber ) {
1768 const std::string pre_tmp("<< ${ }: missing arguments>>");
1769 STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
1770 expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
1771 }
1772
1773 return expr_list;
1774}
1775
1776inline const GetPot::variable*
1777GetPot::__DBE_get_variable(std::string VarName)
1778{
1779 static GetPot::variable ev;
1780 std::string secure_Prefix = prefix;
1781
1782 prefix = section;
1783 // (1) first search in currently active section
1784 const GetPot::variable* var = __find_variable(VarName.c_str());
1785 if( var != 0 ) { prefix = secure_Prefix; return var; }
1786
1787 // (2) search in root name space
1788 prefix = "";
1789 var = __find_variable(VarName.c_str());
1790 if( var != 0 ) { prefix = secure_Prefix; return var; }
1791
1792 prefix = secure_Prefix;
1793
1794 // error occured => variable name == ""
1795 char* tmp = new char[VarName.length() + 25];
1796#ifndef WIN32
1797 snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25),
1798#else
1799 _snprintf(tmp, sizeof(char)*(VarName.length() + 25),
1800#endif
1801 "<<${ } variable '%s' undefined>>", VarName.c_str());
1802 ev.name = "";
1803 ev.original = std::string(tmp);
1804 delete [] tmp;
1805 return &ev;
1806}
1807
1808inline std::string
1809GetPot::__DBE_expand(const std::string expr)
1810{
1811 // ${: } pure text
1812 if( expr[0] == ':' )
1813 return expr.substr(1);
1814
1815 // ${& expr expr ... } text concatination
1816 else if( expr[0] == '&' ) {
1817 const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1);
1818
1819 STRING_VECTOR::const_iterator it = A.begin();
1820 std::string result = *it++;
1821 for(; it != A.end(); ++it) result += *it;
1822
1823 return result;
1824 }
1825
1826 // ${<-> expr expr expr} text replacement
1827 else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) {
1828 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3);
1829 std::string::size_type tmp = 0;
1830 const std::string::size_type L = A[1].length();
1831 while( (tmp = A[0].find(A[1])) != std::string::npos ) {
1832 A[0].replace(tmp, L, A[2]);
1833 }
1834 return A[0];
1835 }
1836 // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions
1837 else if( expr[0] == '+' ) {
1838 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1839 STRING_VECTOR::const_iterator it = A.begin();
1840 double result = __convert_to_type(*it++, 0.0);
1841 for(; it != A.end(); ++it)
1842 result += __convert_to_type(*it, 0.0);
1843
1844 return __double2string(result);
1845 }
1846 else if( expr[0] == '-' ) {
1847 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1848 STRING_VECTOR::const_iterator it = A.begin();
1849 double result = __convert_to_type(*it++, 0.0);
1850 for(; it != A.end(); ++it)
1851 result -= __convert_to_type(*it, 0.0);
1852
1853 return __double2string(result);
1854 }
1855 else if( expr[0] == '*' ) {
1856 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1857 STRING_VECTOR::const_iterator it = A.begin();
1858 double result = __convert_to_type(*it++, 0.0);
1859 for(; it != A.end(); ++it)
1860 result *= __convert_to_type(*it, 0.0);
1861
1862 return __double2string(result);
1863 }
1864 else if( expr[0] == '/' ) {
1865
1866 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1867 STRING_VECTOR::const_iterator it = A.begin();
1868 double result = __convert_to_type(*it++, 0.0);
1869 if( result == 0 ) return "0.0";
1870 for(; it != A.end(); ++it) {
1871 const double Q = __convert_to_type(*it, 0.0);
1872 if( Q == 0.0 ) return "0.0";
1873 result /= Q;
1874 }
1875 return __double2string(result);
1876 }
1877
1878 // ${^ ... } power expressions
1879 else if( expr[0] == '^' ) {
1880 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1881 STRING_VECTOR::const_iterator it = A.begin();
1882 double result = __convert_to_type(*it++, 0.0);
1883 for(; it != A.end(); ++it)
1884 result = pow(result, __convert_to_type(*it, 0.0));
1885 return __double2string(result);
1886 }
1887
1888 // ${== } ${<= } ${>= } comparisons (return the number of the first 'match'
1889 else if( expr.length() >= 2 &&
1890 ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" ||
1891 expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) {
1892 // differentiate between two and one sign operators
1893 unsigned op = 0;
1894 enum { EQ, GEQ, LEQ, GT, LT };
1895 if ( expr.substr(0, 2) == "==" ) op = EQ;
1896 else if ( expr.substr(0, 2) == ">=" ) op = GEQ;
1897 else if ( expr.substr(0, 2) == "<=" ) op = LEQ;
1898 else if ( expr[0] == '>' ) op = GT;
1899 else /* "<" */ op = LT;
1900
1901 STRING_VECTOR a;
1902 if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2);
1903 else a = __DBE_get_expr_list(expr.substr(2), 2);
1904
1905 std::string x_orig = a[0];
1906 double x = __convert_to_type(x_orig, 1e37);
1907 unsigned i = 1;
1908
1909 STRING_VECTOR::const_iterator y_orig = a.begin();
1910 for(y_orig++; y_orig != a.end(); y_orig++) {
1911 double y = __convert_to_type(*y_orig, 1e37);
1912
1913 // set the strings as reference if one wasn't a number
1914 if ( x == 1e37 || y == 1e37 ) {
1915 // it's a string comparison
1916 if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
1917 (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
1918 (op == LT && x_orig < *y_orig) )
1919 return __int2string(i);
1920 }
1921 else {
1922 // it's a number comparison
1923 if( (op == EQ && x == y) || (op == GEQ && x >= y) ||
1924 (op == LEQ && x <= y) || (op == GT && x > y) ||
1925 (op == LT && x < y) )
1926 return __int2string(i);
1927 }
1928 ++i;
1929 }
1930
1931 // nothing fulfills the condition => return 0
1932 return "0";
1933 }
1934 // ${?? expr expr} select
1935 else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) {
1936 STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2);
1937 double x = __convert_to_type(a[0], 1e37);
1938 // last element is always the default argument
1939 if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1];
1940
1941 // round x to closest integer
1942 return a[int(x+0.5)];
1943 }
1944 // ${? expr expr expr} if then else conditions
1945 else if( expr[0] == '?' ) {
1946 STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2);
1947 if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1];
1948 else if( a.size() > 2 ) return a[2];
1949 }
1950 // ${! expr} maxro expansion
1951 else if( expr[0] == '!' ) {
1952 const GetPot::variable* Var = __DBE_get_variable(expr.substr(1));
1953 // error
1954 if( Var->name == "" ) return std::string(Var->original);
1955
1956 const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2);
1957 return A[0];
1958 }
1959 // ${@: } - string subscription
1960 else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) {
1961 const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2);
1962 double x = __convert_to_type(A[1], 1e37);
1963
1964 // last element is always the default argument
1965 if( x == 1e37 || x < 0 || x >= A[0].size() - 1)
1966 return "<<1st index out of range>>";
1967
1968 if( A.size() > 2 ) {
1969 double y = __convert_to_type(A[2], 1e37);
1970 if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x )
1971 return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5));
1972 else if( y == -1 )
1973 return A[0].substr(int(x+0.5));
1974 return "<<2nd index out of range>>";
1975 }
1976 else {
1977 char* tmp = new char[2];
1978 tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0';
1979 std::string result(tmp);
1980 delete [] tmp;
1981 return result;
1982 }
1983 }
1984 // ${@ } - vector subscription
1985 else if( expr[0] == '@' ) {
1986 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1987 const GetPot::variable* Var = __DBE_get_variable(A[0]);
1988 // error
1989 if( Var->name == "" ) {
1990 // make a copy of the string if an error occured
1991 // (since the error variable is a static variable inside get_variable())
1992 return std::string(Var->original);
1993 }
1994
1995 double x = __convert_to_type(A[1], 1e37);
1996
1997 // last element is always the default argument
1998 if (x == 1e37 || x < 0 || x >= Var->value.size() )
1999 return "<<1st index out of range>>";
2000
2001 if ( A.size() > 2) {
2002 double y = __convert_to_type(A[2], 1e37);
2003 int begin = int(x+0.5);
2004 int end = 0;
2005 if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x)
2006 end = int(y+1.5);
2007 else if( y == -1 )
2008 end = static_cast<unsigned int>(Var->value.size());
2009 else
2010 return "<<2nd index out of range>>";
2011
2012 std::string result = *(Var->get_element(begin));
2013 int i = begin+1;
2014 for(; i < end; ++i)
2015 result += std::string(" ") + *(Var->get_element(i));
2016 return result;
2017 }
2018 else
2019 return *(Var->get_element(int(x+0.5)));
2020 }
2021
2022 const STRING_VECTOR A = __DBE_get_expr_list(expr, 1);
2023 const GetPot::variable* B = __DBE_get_variable(A[0]);
2024
2025 // make a copy of the string if an error occured
2026 // (since the error variable is a static variable inside get_variable())
2027 if( B->name == "" ) return std::string(B->original);
2028 // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces
2029 // with: else return B->original (thanks))
2030 return B->original;
2031}
2032
2033
2034///////////////////////////////////////////////////////////////////////////////
2035// (*) unidentified flying objects
2036//.............................................................................
2037//
2038inline bool
2039GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const
2040{
2041 victorate(std::string, VecStr, itk) {
2042 if( *itk == Str ) return true;
2043 }
2044 return false;
2045}
2046
2047inline STRING_VECTOR
2048GetPot::unidentified_arguments(unsigned Number,
2049 const char* KnownArgument1, ...) const
2050{
2051 STRING_VECTOR known_arguments;
2052
2053 // (1) create a vector of known arguments
2054 if( Number == 0 ) return STRING_VECTOR();
2055
2056 va_list ap;
2057 va_start(ap, KnownArgument1);
2058 known_arguments.push_back(std::string(KnownArgument1));
2059 unsigned i=1;
2060 for(; i<Number; ++i)
2061 known_arguments.push_back(std::string(va_arg(ap, char *)));
2062 va_end(ap);
2063
2064 return unidentified_arguments(known_arguments);
2065}
2066
2067inline STRING_VECTOR
2068GetPot::unidentified_arguments() const
2069{ return unidentified_arguments(_requested_arguments); }
2070
2071inline STRING_VECTOR
2072GetPot::unidentified_arguments(const STRING_VECTOR& Knowns) const
2073{
2074 STRING_VECTOR ufos;
2075 STRING_VECTOR::const_iterator it = argv.begin();
2076 ++it; // forget about argv[0] (application or filename)
2077 for(; it != argv.end(); ++it) {
2078 // -- argument belongs to prefixed section ?
2079 const std::string arg = __get_remaining_string(*it, prefix);
2080 if( arg == "" ) continue;
2081
2082 // -- check if in list
2083 if( __search_string_vector(Knowns, arg) == false)
2084 ufos.push_back(*it);
2085 }
2086 return ufos;
2087}
2088
2089inline STRING_VECTOR
2090GetPot::unidentified_options(unsigned Number,
2091 const char* KnownOption1, ...) const
2092{
2093 STRING_VECTOR known_options;
2094
2095 // (1) create a vector of known arguments
2096 if( Number == 0 ) return STRING_VECTOR();
2097
2098 va_list ap;
2099 va_start(ap, KnownOption1);
2100 known_options.push_back(std::string(KnownOption1));
2101 unsigned i=1;
2102 for(; i<Number; ++i)
2103 known_options.push_back(std::string(va_arg(ap, char *)));
2104 va_end(ap);
2105
2106 return unidentified_options(known_options);
2107}
2108
2109inline STRING_VECTOR
2110GetPot::unidentified_options() const
2111{
2112 // -- every option is an argument.
2113 // -- the set of requested arguments contains the set of requested options.
2114 // -- IF the set of requested arguments contains unrequested options,
2115 // THEN they were requested as 'follow' and 'next' arguments and not as real options.
2116 //
2117 // => it is not necessary to separate requested options from the list
2118 STRING_VECTOR option_list;
2119 victorate(std::string, _requested_arguments, it) {
2120 const std::string arg = *it;
2121 if( arg.length() == 0 ) continue;
2122 if( arg[0] == '-' ) option_list.push_back(arg);
2123 }
2124 return unidentified_options(option_list);
2125}
2126
2127inline STRING_VECTOR
2128GetPot::unidentified_options(const STRING_VECTOR& Knowns) const
2129{
2130 STRING_VECTOR ufos;
2131 STRING_VECTOR::const_iterator it = argv.begin();
2132 ++it; // forget about argv[0] (application or filename)
2133 for(; it != argv.end(); ++it) {
2134 // -- argument belongs to prefixed section ?
2135 const std::string arg = __get_remaining_string(*it, prefix);
2136 if( arg == "" ) continue;
2137
2138 // is argument really an option (starting with '-') ?
2139 if( arg.length() < 1 || arg[0] != '-' ) continue;
2140
2141 if( __search_string_vector(Knowns, arg) == false)
2142 ufos.push_back(*it);
2143 }
2144
2145 return ufos;
2146}
2147
2148inline std::string
2149GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const
2150 // Two modes:
2151 // ArgumentNumber >= 0 check specific argument
2152 // ArgumentNumber == -1 check all options starting with one '-'
2153 // for flags
2154{
2155 std::string ufos;
2156 STRING_VECTOR known_arguments;
2157 std::string KFL(KnownFlagList);
2158
2159 // (2) iteration over '-' arguments (options)
2160 if( ArgumentNumber == -1 ) {
2161 STRING_VECTOR::const_iterator it = argv.begin();
2162 ++it; // forget about argv[0] (application or filename)
2163 for(; it != argv.end(); ++it) {
2164 // -- argument belongs to prefixed section ?
2165 const std::string arg = __get_remaining_string(*it, prefix);
2166 if( arg == "" ) continue;
2167
2168 // -- does arguments start with '-' (but not '--')
2169 if ( arg.length() < 2 ) continue;
2170 else if( arg[0] != '-' ) continue;
2171 else if( arg[1] == '-' ) continue;
2172
2173 // -- check out if flags inside option are contained in KnownFlagList
2174 const char* p=arg.c_str();
2175 p++; // skip starting minus
2176 for(; *p != '\0' ; p++)
2177 if( KFL.find(*p) == std::string::npos ) ufos += *p;
2178 }
2179 }
2180 // (1) check specific argument
2181 else {
2182 // -- only check arguments that start with prefix
2183 int no_matches = 0;
2184 unsigned i=1;
2185 for(; i<argv.size(); ++i) {
2186 const std::string Remain = __get_remaining_string(argv[i], prefix);
2187 if( Remain != "") {
2188 no_matches++;
2189 if( no_matches == ArgumentNumber) {
2190 // -- the right argument number inside the section is found
2191 // => check it for flags
2192 const char* p = Remain.c_str();
2193 p++; // skip starting minus
2194 for(; *p != '\0' ; p++)
2195 if( KFL.find(*p) == std::string::npos ) ufos += *p;
2196 return ufos;
2197 }
2198 }
2199 }
2200 }
2201 return ufos;
2202}
2203
2204inline STRING_VECTOR
2205GetPot::unidentified_variables(unsigned Number,
2206 const char* KnownVariable1, ...) const
2207{
2208 STRING_VECTOR known_variables;
2209
2210 // create vector of known arguments
2211 if( Number == 0 ) return STRING_VECTOR();
2212
2213 va_list ap;
2214 va_start(ap, KnownVariable1);
2215 known_variables.push_back(std::string(KnownVariable1));
2216 unsigned i=1;
2217 for(; i<Number; ++i)
2218 known_variables.push_back(std::string(va_arg(ap, char *)));
2219 va_end(ap);
2220
2221 return unidentified_variables(known_variables);
2222}
2223
2224inline STRING_VECTOR
2225GetPot::unidentified_variables(const STRING_VECTOR& Knowns) const
2226{
2227 STRING_VECTOR ufos;
2228
2229 victorate(GetPot::variable, variables, it) {
2230 // -- check if variable has specific prefix
2231 const std::string var_name = __get_remaining_string((*it).name, prefix);
2232 if( var_name == "" ) continue;
2233
2234 // -- check if variable is known
2235 if( __search_string_vector(Knowns, var_name) == false)
2236 ufos.push_back((*it).name);
2237 }
2238 return ufos;
2239}
2240
2241inline STRING_VECTOR
2242GetPot::unidentified_variables() const
2243{ return unidentified_variables(_requested_variables); }
2244
2245
2246inline STRING_VECTOR
2247GetPot::unidentified_sections(unsigned Number,
2248 const char* KnownSection1, ...) const
2249{
2250 STRING_VECTOR known_sections;
2251
2252 // (1) create a vector of known arguments
2253 if( Number == 0 ) return STRING_VECTOR();
2254
2255 va_list ap;
2256 va_start(ap, KnownSection1);
2257 known_sections.push_back(std::string(KnownSection1));
2258 unsigned i=1;
2259 for(; i<Number; ++i) {
2260 std::string tmp = std::string(va_arg(ap, char *));
2261 if( tmp.length() == 0 ) continue;
2262 if( tmp[tmp.length()-1] != '/' ) tmp += '/';
2263 known_sections.push_back(tmp);
2264 }
2265 va_end(ap);
2266
2267 return unidentified_sections(known_sections);
2268}
2269
2270inline STRING_VECTOR
2271GetPot::unidentified_sections() const
2272{ return unidentified_sections(_requested_sections); }
2273
2274inline STRING_VECTOR
2275GetPot::unidentified_sections(const STRING_VECTOR& Knowns) const
2276{
2277 STRING_VECTOR ufos;
2278
2279 victorate(std::string, section_list, it) {
2280 // -- check if section conform to prefix
2281 const std::string sec_name = __get_remaining_string(*it, prefix);
2282 if( sec_name == "" ) continue;
2283
2284 // -- check if section is known
2285 if( __search_string_vector(Knowns, sec_name) == false )
2286 ufos.push_back(*it);
2287 }
2288
2289 return ufos;
2290}
2291
2292
2293inline STRING_VECTOR
2294GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const
2295{
2296 STRING_VECTOR known_nominuses;
2297
2298 // create vector of known arguments
2299 if( Number == 0 ) return STRING_VECTOR();
2300
2301 va_list ap;
2302 va_start(ap, Known);
2303 known_nominuses.push_back(std::string(Known));
2304 unsigned i=1;
2305 for(; i<Number; ++i) {
2306 std::string tmp = std::string(va_arg(ap, char *));
2307 if( tmp.length() == 0 ) continue;
2308 known_nominuses.push_back(tmp);
2309 }
2310 va_end(ap);
2311
2312 return unidentified_nominuses(known_nominuses);
2313}
2314
2315inline STRING_VECTOR
2316GetPot::unidentified_nominuses() const {
2317 // -- every nominus is an argument.
2318 // -- the set of requested arguments contains the set of requested nominuss.
2319 // -- IF the set of requested arguments contains unrequested nominuss,
2320 // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses.
2321 //
2322 // => it is not necessary to separate requested nominus from the list
2323
2324 return unidentified_nominuses(_requested_arguments);
2325}
2326
2327inline STRING_VECTOR
2328GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const
2329{
2330 STRING_VECTOR ufos;
2331
2332 // (2) iterate over all arguments
2333 STRING_VECTOR::const_iterator it = argv.begin();
2334 ++it; // forget about argv[0] (application or filename)
2335 for(; it != argv.end(); ++it) {
2336 // -- check if nominus part of prefix
2337 const std::string arg = __get_remaining_string(*it, prefix);
2338 if( arg == "" ) continue;
2339
2340 if( arg.length() < 1 ) continue;
2341 // option ? --> not a nomius
2342 if( arg[0] == '-' ) continue;
2343 // section ? --> not a real nominus
2344 if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue;
2345 // variable definition ? --> not a real nominus
2346 bool continue_f = false;
2347 unsigned i=0;
2348 for(; i<arg.length() ; ++i)
2349 if( arg[i] == '=' ) { continue_f = true; break; }
2350 if( continue_f ) continue;
2351
2352 // real nominuses are compared with the given list
2353 if( __search_string_vector(Knowns, arg) == false )
2354 ufos.push_back(*it);
2355 }
2356 return ufos;
2357}
2358
2359
2360///////////////////////////////////////////////////////////////////////////////
2361// (*) variable class
2362//.............................................................................
2363//
2364inline
2365GetPot::variable::variable()
2366{}
2367
2368inline
2369GetPot::variable::variable(const variable& That)
2370{
2371#ifdef WIN32
2372 operator=(That);
2373#else
2374 GetPot::variable::operator=(That);
2375#endif
2376}
2377
2378
2379inline
2380GetPot::variable::variable(const char* Name, const char* Value, const char* FieldSeparator)
2381 : name(Name)
2382{
2383 // make a copy of the 'Value'
2384 take(Value, FieldSeparator);
2385}
2386
2387inline const std::string*
2388GetPot::variable::get_element(unsigned Idx) const
2389{ if( Idx >= value.size() ) return 0; else return &(value[Idx]); }
2390
2391inline void
2392GetPot::variable::take(const char* Value, const char* FieldSeparator)
2393{
2394 original = std::string(Value);
2395
2396 // separate string by white space delimiters using 'strtok'
2397 // thread safe usage of strtok (no static members)
2398 char* spt = 0;
2399 // make a copy of the 'Value'
2400 char* copy = new char[strlen(Value)+1];
2401 strcpy(copy, Value);
2402 char* follow_token = strtok_r(copy, FieldSeparator, &spt);
2403 if( value.size() != 0 ) value.erase(value.begin(), value.end());
2404 while(follow_token != 0) {
2405 value.push_back(std::string(follow_token));
2406 follow_token = strtok_r(NULL, FieldSeparator, &spt);
2407 }
2408
2409 delete [] copy;
2410}
2411
2412inline
2413GetPot::variable::~variable()
2414{}
2415
2416inline GetPot::variable&
2417GetPot::variable::operator=(const GetPot::variable& That)
2418{
2419 if( &That != this) {
2420 name = That.name;
2421 value = That.value;
2422 original = That.original;
2423 }
2424 return *this;
2425}
2426
2427#undef victorate
2428
2429
2430#endif // __include_guard_GETPOT_H__
2431
2432
2433
diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt
new file mode 100755
index 0000000000..b1e3f5a263
--- /dev/null
+++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt
@@ -0,0 +1,504 @@
1 GNU LESSER GENERAL PUBLIC LICENSE
2 Version 2.1, February 1999
3
4 Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9[This is the first released version of the Lesser GPL. It also counts
10 as the successor of the GNU Library Public License, version 2, hence
11 the version number 2.1.]
12
13 Preamble
14
15 The licenses for most software are designed to take away your
16freedom to share and change it. By contrast, the GNU General Public
17Licenses are intended to guarantee your freedom to share and change
18free software--to make sure the software is free for all its users.
19
20 This license, the Lesser General Public License, applies to some
21specially designated software packages--typically libraries--of the
22Free Software Foundation and other authors who decide to use it. You
23can use it too, but we suggest you first think carefully about whether
24this license or the ordinary General Public License is the better
25strategy to use in any particular case, based on the explanations below.
26
27 When we speak of free software, we are referring to freedom of use,
28not price. Our General Public Licenses are designed to make sure that
29you have the freedom to distribute copies of free software (and charge
30for this service if you wish); that you receive source code or can get
31it if you want it; that you can change the software and use pieces of
32it in new free programs; and that you are informed that you can do
33these things.
34
35 To protect your rights, we need to make restrictions that forbid
36distributors to deny you these rights or to ask you to surrender these
37rights. These restrictions translate to certain responsibilities for
38you if you distribute copies of the library or if you modify it.
39
40 For example, if you distribute copies of the library, whether gratis
41or for a fee, you must give the recipients all the rights that we gave
42you. You must make sure that they, too, receive or can get the source
43code. If you link other code with the library, you must provide
44complete object files to the recipients, so that they can relink them
45with the library after making changes to the library and recompiling
46it. And you must show them these terms so they know their rights.
47
48 We protect your rights with a two-step method: (1) we copyright the
49library, and (2) we offer you this license, which gives you legal
50permission to copy, distribute and/or modify the library.
51
52 To protect each distributor, we want to make it very clear that
53there is no warranty for the free library. Also, if the library is
54modified by someone else and passed on, the recipients should know
55that what they have is not the original version, so that the original
56author's reputation will not be affected by problems that might be
57introduced by others.
58
59 Finally, software patents pose a constant threat to the existence of
60any free program. We wish to make sure that a company cannot
61effectively restrict the users of a free program by obtaining a
62restrictive license from a patent holder. Therefore, we insist that
63any patent license obtained for a version of the library must be
64consistent with the full freedom of use specified in this license.
65
66 Most GNU software, including some libraries, is covered by the
67ordinary GNU General Public License. This license, the GNU Lesser
68General Public License, applies to certain designated libraries, and
69is quite different from the ordinary General Public License. We use
70this license for certain libraries in order to permit linking those
71libraries into non-free programs.
72
73 When a program is linked with a library, whether statically or using
74a shared library, the combination of the two is legally speaking a
75combined work, a derivative of the original library. The ordinary
76General Public License therefore permits such linking only if the
77entire combination fits its criteria of freedom. The Lesser General
78Public License permits more lax criteria for linking other code with
79the library.
80
81 We call this license the "Lesser" General Public License because it
82does Less to protect the user's freedom than the ordinary General
83Public License. It also provides other free software developers Less
84of an advantage over competing non-free programs. These disadvantages
85are the reason we use the ordinary General Public License for many
86libraries. However, the Lesser license provides advantages in certain
87special circumstances.
88
89 For example, on rare occasions, there may be a special need to
90encourage the widest possible use of a certain library, so that it becomes
91a de-facto standard. To achieve this, non-free programs must be
92allowed to use the library. A more frequent case is that a free
93library does the same job as widely used non-free libraries. In this
94case, there is little to gain by limiting the free library to free
95software only, so we use the Lesser General Public License.
96
97 In other cases, permission to use a particular library in non-free
98programs enables a greater number of people to use a large body of
99free software. For example, permission to use the GNU C Library in
100non-free programs enables many more people to use the whole GNU
101operating system, as well as its variant, the GNU/Linux operating
102system.
103
104 Although the Lesser General Public License is Less protective of the
105users' freedom, it does ensure that the user of a program that is
106linked with the Library has the freedom and the wherewithal to run
107that program using a modified version of the Library.
108
109 The precise terms and conditions for copying, distribution and
110modification follow. Pay close attention to the difference between a
111"work based on the library" and a "work that uses the library". The
112former contains code derived from the library, whereas the latter must
113be combined with the library in order to run.
114
115 GNU LESSER GENERAL PUBLIC LICENSE
116 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117
118 0. This License Agreement applies to any software library or other
119program which contains a notice placed by the copyright holder or
120other authorized party saying it may be distributed under the terms of
121this Lesser General Public License (also called "this License").
122Each licensee is addressed as "you".
123
124 A "library" means a collection of software functions and/or data
125prepared so as to be conveniently linked with application programs
126(which use some of those functions and data) to form executables.
127
128 The "Library", below, refers to any such software library or work
129which has been distributed under these terms. A "work based on the
130Library" means either the Library or any derivative work under
131copyright law: that is to say, a work containing the Library or a
132portion of it, either verbatim or with modifications and/or translated
133straightforwardly into another language. (Hereinafter, translation is
134included without limitation in the term "modification".)
135
136 "Source code" for a work means the preferred form of the work for
137making modifications to it. For a library, complete source code means
138all the source code for all modules it contains, plus any associated
139interface definition files, plus the scripts used to control compilation
140and installation of the library.
141
142 Activities other than copying, distribution and modification are not
143covered by this License; they are outside its scope. The act of
144running a program using the Library is not restricted, and output from
145such a program is covered only if its contents constitute a work based
146on the Library (independent of the use of the Library in a tool for
147writing it). Whether that is true depends on what the Library does
148and what the program that uses the Library does.
149
150 1. You may copy and distribute verbatim copies of the Library's
151complete source code as you receive it, in any medium, provided that
152you conspicuously and appropriately publish on each copy an
153appropriate copyright notice and disclaimer of warranty; keep intact
154all the notices that refer to this License and to the absence of any
155warranty; and distribute a copy of this License along with the
156Library.
157
158 You may charge a fee for the physical act of transferring a copy,
159and you may at your option offer warranty protection in exchange for a
160fee.
161
162 2. You may modify your copy or copies of the Library or any portion
163of it, thus forming a work based on the Library, and copy and
164distribute such modifications or work under the terms of Section 1
165above, provided that you also meet all of these conditions:
166
167 a) The modified work must itself be a software library.
168
169 b) You must cause the files modified to carry prominent notices
170 stating that you changed the files and the date of any change.
171
172 c) You must cause the whole of the work to be licensed at no
173 charge to all third parties under the terms of this License.
174
175 d) If a facility in the modified Library refers to a function or a
176 table of data to be supplied by an application program that uses
177 the facility, other than as an argument passed when the facility
178 is invoked, then you must make a good faith effort to ensure that,
179 in the event an application does not supply such function or
180 table, the facility still operates, and performs whatever part of
181 its purpose remains meaningful.
182
183 (For example, a function in a library to compute square roots has
184 a purpose that is entirely well-defined independent of the
185 application. Therefore, Subsection 2d requires that any
186 application-supplied function or table used by this function must
187 be optional: if the application does not supply it, the square
188 root function must still compute square roots.)
189
190These requirements apply to the modified work as a whole. If
191identifiable sections of that work are not derived from the Library,
192and can be reasonably considered independent and separate works in
193themselves, then this License, and its terms, do not apply to those
194sections when you distribute them as separate works. But when you
195distribute the same sections as part of a whole which is a work based
196on the Library, the distribution of the whole must be on the terms of
197this License, whose permissions for other licensees extend to the
198entire whole, and thus to each and every part regardless of who wrote
199it.
200
201Thus, it is not the intent of this section to claim rights or contest
202your rights to work written entirely by you; rather, the intent is to
203exercise the right to control the distribution of derivative or
204collective works based on the Library.
205
206In addition, mere aggregation of another work not based on the Library
207with the Library (or with a work based on the Library) on a volume of
208a storage or distribution medium does not bring the other work under
209the scope of this License.
210
211 3. You may opt to apply the terms of the ordinary GNU General Public
212License instead of this License to a given copy of the Library. To do
213this, you must alter all the notices that refer to this License, so
214that they refer to the ordinary GNU General Public License, version 2,
215instead of to this License. (If a newer version than version 2 of the
216ordinary GNU General Public License has appeared, then you can specify
217that version instead if you wish.) Do not make any other change in
218these notices.
219
220 Once this change is made in a given copy, it is irreversible for
221that copy, so the ordinary GNU General Public License applies to all
222subsequent copies and derivative works made from that copy.
223
224 This option is useful when you wish to copy part of the code of
225the Library into a program that is not a library.
226
227 4. You may copy and distribute the Library (or a portion or
228derivative of it, under Section 2) in object code or executable form
229under the terms of Sections 1 and 2 above provided that you accompany
230it with the complete corresponding machine-readable source code, which
231must be distributed under the terms of Sections 1 and 2 above on a
232medium customarily used for software interchange.
233
234 If distribution of object code is made by offering access to copy
235from a designated place, then offering equivalent access to copy the
236source code from the same place satisfies the requirement to
237distribute the source code, even though third parties are not
238compelled to copy the source along with the object code.
239
240 5. A program that contains no derivative of any portion of the
241Library, but is designed to work with the Library by being compiled or
242linked with it, is called a "work that uses the Library". Such a
243work, in isolation, is not a derivative work of the Library, and
244therefore falls outside the scope of this License.
245
246 However, linking a "work that uses the Library" with the Library
247creates an executable that is a derivative of the Library (because it
248contains portions of the Library), rather than a "work that uses the
249library". The executable is therefore covered by this License.
250Section 6 states terms for distribution of such executables.
251
252 When a "work that uses the Library" uses material from a header file
253that is part of the Library, the object code for the work may be a
254derivative work of the Library even though the source code is not.
255Whether this is true is especially significant if the work can be
256linked without the Library, or if the work is itself a library. The
257threshold for this to be true is not precisely defined by law.
258
259 If such an object file uses only numerical parameters, data
260structure layouts and accessors, and small macros and small inline
261functions (ten lines or less in length), then the use of the object
262file is unrestricted, regardless of whether it is legally a derivative
263work. (Executables containing this object code plus portions of the
264Library will still fall under Section 6.)
265
266 Otherwise, if the work is a derivative of the Library, you may
267distribute the object code for the work under the terms of Section 6.
268Any executables containing that work also fall under Section 6,
269whether or not they are linked directly with the Library itself.
270
271 6. As an exception to the Sections above, you may also combine or
272link a "work that uses the Library" with the Library to produce a
273work containing portions of the Library, and distribute that work
274under terms of your choice, provided that the terms permit
275modification of the work for the customer's own use and reverse
276engineering for debugging such modifications.
277
278 You must give prominent notice with each copy of the work that the
279Library is used in it and that the Library and its use are covered by
280this License. You must supply a copy of this License. If the work
281during execution displays copyright notices, you must include the
282copyright notice for the Library among them, as well as a reference
283directing the user to the copy of this License. Also, you must do one
284of these things:
285
286 a) Accompany the work with the complete corresponding
287 machine-readable source code for the Library including whatever
288 changes were used in the work (which must be distributed under
289 Sections 1 and 2 above); and, if the work is an executable linked
290 with the Library, with the complete machine-readable "work that
291 uses the Library", as object code and/or source code, so that the
292 user can modify the Library and then relink to produce a modified
293 executable containing the modified Library. (It is understood
294 that the user who changes the contents of definitions files in the
295 Library will not necessarily be able to recompile the application
296 to use the modified definitions.)
297
298 b) Use a suitable shared library mechanism for linking with the
299 Library. A suitable mechanism is one that (1) uses at run time a
300 copy of the library already present on the user's computer system,
301 rather than copying library functions into the executable, and (2)
302 will operate properly with a modified version of the library, if
303 the user installs one, as long as the modified version is
304 interface-compatible with the version that the work was made with.
305
306 c) Accompany the work with a written offer, valid for at
307 least three years, to give the same user the materials
308 specified in Subsection 6a, above, for a charge no more
309 than the cost of performing this distribution.
310
311 d) If distribution of the work is made by offering access to copy
312 from a designated place, offer equivalent access to copy the above
313 specified materials from the same place.
314
315 e) Verify that the user has already received a copy of these
316 materials or that you have already sent this user a copy.
317
318 For an executable, the required form of the "work that uses the
319Library" must include any data and utility programs needed for
320reproducing the executable from it. However, as a special exception,
321the materials to be distributed need not include anything that is
322normally distributed (in either source or binary form) with the major
323components (compiler, kernel, and so on) of the operating system on
324which the executable runs, unless that component itself accompanies
325the executable.
326
327 It may happen that this requirement contradicts the license
328restrictions of other proprietary libraries that do not normally
329accompany the operating system. Such a contradiction means you cannot
330use both them and the Library together in an executable that you
331distribute.
332
333 7. You may place library facilities that are a work based on the
334Library side-by-side in a single library together with other library
335facilities not covered by this License, and distribute such a combined
336library, provided that the separate distribution of the work based on
337the Library and of the other library facilities is otherwise
338permitted, and provided that you do these two things:
339
340 a) Accompany the combined library with a copy of the same work
341 based on the Library, uncombined with any other library
342 facilities. This must be distributed under the terms of the
343 Sections above.
344
345 b) Give prominent notice with the combined library of the fact
346 that part of it is a work based on the Library, and explaining
347 where to find the accompanying uncombined form of the same work.
348
349 8. You may not copy, modify, sublicense, link with, or distribute
350the Library except as expressly provided under this License. Any
351attempt otherwise to copy, modify, sublicense, link with, or
352distribute the Library is void, and will automatically terminate your
353rights under this License. However, parties who have received copies,
354or rights, from you under this License will not have their licenses
355terminated so long as such parties remain in full compliance.
356
357 9. You are not required to accept this License, since you have not
358signed it. However, nothing else grants you permission to modify or
359distribute the Library or its derivative works. These actions are
360prohibited by law if you do not accept this License. Therefore, by
361modifying or distributing the Library (or any work based on the
362Library), you indicate your acceptance of this License to do so, and
363all its terms and conditions for copying, distributing or modifying
364the Library or works based on it.
365
366 10. Each time you redistribute the Library (or any work based on the
367Library), the recipient automatically receives a license from the
368original licensor to copy, distribute, link with or modify the Library
369subject to these terms and conditions. You may not impose any further
370restrictions on the recipients' exercise of the rights granted herein.
371You are not responsible for enforcing compliance by third parties with
372this License.
373
374 11. If, as a consequence of a court judgment or allegation of patent
375infringement or for any other reason (not limited to patent issues),
376conditions are imposed on you (whether by court order, agreement or
377otherwise) that contradict the conditions of this License, they do not
378excuse you from the conditions of this License. If you cannot
379distribute so as to satisfy simultaneously your obligations under this
380License and any other pertinent obligations, then as a consequence you
381may not distribute the Library at all. For example, if a patent
382license would not permit royalty-free redistribution of the Library by
383all those who receive copies directly or indirectly through you, then
384the only way you could satisfy both it and this License would be to
385refrain entirely from distribution of the Library.
386
387If any portion of this section is held invalid or unenforceable under any
388particular circumstance, the balance of the section is intended to apply,
389and the section as a whole is intended to apply in other circumstances.
390
391It is not the purpose of this section to induce you to infringe any
392patents or other property right claims or to contest validity of any
393such claims; this section has the sole purpose of protecting the
394integrity of the free software distribution system which is
395implemented by public license practices. Many people have made
396generous contributions to the wide range of software distributed
397through that system in reliance on consistent application of that
398system; it is up to the author/donor to decide if he or she is willing
399to distribute software through any other system and a licensee cannot
400impose that choice.
401
402This section is intended to make thoroughly clear what is believed to
403be a consequence of the rest of this License.
404
405 12. If the distribution and/or use of the Library is restricted in
406certain countries either by patents or by copyrighted interfaces, the
407original copyright holder who places the Library under this License may add
408an explicit geographical distribution limitation excluding those countries,
409so that distribution is permitted only in or among countries not thus
410excluded. In such case, this License incorporates the limitation as if
411written in the body of this License.
412
413 13. The Free Software Foundation may publish revised and/or new
414versions of the Lesser General Public License from time to time.
415Such new versions will be similar in spirit to the present version,
416but may differ in detail to address new problems or concerns.
417
418Each version is given a distinguishing version number. If the Library
419specifies a version number of this License which applies to it and
420"any later version", you have the option of following the terms and
421conditions either of that version or of any later version published by
422the Free Software Foundation. If the Library does not specify a
423license version number, you may choose any version ever published by
424the Free Software Foundation.
425
426 14. If you wish to incorporate parts of the Library into other free
427programs whose distribution conditions are incompatible with these,
428write to the author to ask for permission. For software which is
429copyrighted by the Free Software Foundation, write to the Free
430Software Foundation; we sometimes make exceptions for this. Our
431decision will be guided by the two goals of preserving the free status
432of all derivatives of our free software and of promoting the sharing
433and reuse of software generally.
434
435 NO WARRANTY
436
437 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446
447 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456DAMAGES.
457
458 END OF TERMS AND CONDITIONS
459
460 How to Apply These Terms to Your New Libraries
461
462 If you develop a new library, and you want it to be of the greatest
463possible use to the public, we recommend making it free software that
464everyone can redistribute and change. You can do so by permitting
465redistribution under these terms (or, alternatively, under the terms of the
466ordinary General Public License).
467
468 To apply these terms, attach the following notices to the library. It is
469safest to attach them to the start of each source file to most effectively
470convey the exclusion of warranty; and each file should have at least the
471"copyright" line and a pointer to where the full notice is found.
472
473 <one line to give the library's name and a brief idea of what it does.>
474 Copyright (C) <year> <name of author>
475
476 This library is free software; you can redistribute it and/or
477 modify it under the terms of the GNU Lesser General Public
478 License as published by the Free Software Foundation; either
479 version 2.1 of the License, or (at your option) any later version.
480
481 This library is distributed in the hope that it will be useful,
482 but WITHOUT ANY WARRANTY; without even the implied warranty of
483 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 Lesser General Public License for more details.
485
486 You should have received a copy of the GNU Lesser General Public
487 License along with this library; if not, write to the Free Software
488 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
489
490Also add information on how to contact you by electronic and paper mail.
491
492You should also get your employer (if you work as a programmer) or your
493school, if any, to sign a "copyright disclaimer" for the library, if
494necessary. Here is a sample; alter the names:
495
496 Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498
499 <signature of Ty Coon>, 1 April 1990
500 Ty Coon, President of Vice
501
502That's all there is to it!
503
504
diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README
new file mode 100755
index 0000000000..3d55352a6b
--- /dev/null
+++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README
@@ -0,0 +1,50 @@
1GetPot - C++:
2--------------
3
4Attention: This version contains a couple of beautiful
5---------- new features, that are not documented yet.
6
7 E.g.: -- automated ufo detection
8 -- arbitrary comment delimiters
9 -- arbitrary vector field separators
10 -- tails, i.e. easy access to all tails
11 of options such as '-L' or '-I'.
12
13 Please, refere to the example/ directory
14 for usage descriptions.
15
16This is the C++ version of the popular GetPot library for
17command line and input file parsing. The documentation
18can be downloaded at:
19
20 http://getpot.sourceforge.net
21
22The files in the 'examples' directory should be enough, though, to be
23able to use this library. It is fairly easy to use.
24
25Installation:
26-------------
27
28In order to install GetPot, simply copy the file 'GetPot'
29somewhere where your c++ compiler can find it.
30
31The 'file emacs-getpot-mode.el' contains some lines of
32emacs-lisp code. If you append these lines to your .emacs
33file, it will highlight your 'getpot' - input files.
34
35Bug reports, Feature requests:
36------------------------------
37
38Please, notify me in case there are any bugs or you think
39that there should be more features in the library.
40My email address is:
41
42fschaef@users.sourceforge.net
43
44Thanks for using this software.
45Enjoy !
46
47
48Juli 2005,
49Frank R. Schaefer
50
diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp
new file mode 100755
index 0000000000..fe820c91a2
--- /dev/null
+++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp
@@ -0,0 +1,2435 @@
1// -*- c++ -*-
2// GetPot Version $$Version$$ $$Date$$
3//
4// WEBSITE: http://getpot.sourceforge.net
5//
6// NOTE: The LPGL License for this library is only valid in case that
7// it is not used for the production or development of applications
8// dedicated to military industry. This is what the author calls
9// the 'unofficial peace version of the LPGL'.
10//
11// This library is free software; you can redistribute it and/or modify
12// it under the terms of the GNU Lesser General Public License as
13// published by the Free Software Foundation; either version 2.1 of the
14// License, or (at your option) any later version.
15//
16// This library is distributed in the hope that it will be useful, but
17// WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19// Lesser General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public
22// License along with this library; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24// USA
25//
26// (C) 2001-2005 Frank R. Schaefer <fschaef@users.sf.net>
27//==========================================================================
28
29#ifndef __include_guard_GETPOT_H__
30#define __include_guard_GETPOT_H__
31
32#if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
33#define strtok_r(a, b, c) strtok(a, b)
34#endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC
35
36extern "C" {
37// leave the 'extern C' to make it 100% sure to work -
38// expecially with older distributions of header files.
39#ifndef WIN32
40// this is necessary (depending on OS)
41#include <ctype.h>
42#endif
43#include <stdio.h>
44#include <stdarg.h>
45#include <assert.h>
46}
47#include <cmath>
48#include <string>
49#include <vector>
50#include <algorithm>
51
52#include <fstream>
53#include <iostream> // not every compiler distribution includes <iostream>
54// // with <fstream>
55
56typedef std::vector<std::string> STRING_VECTOR;
57
58#define victorate(TYPE, VARIABLE, ITERATOR) \
59 std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin(); \
60 for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++)
61
62
63class GetPot {
64 //--------
65 inline void __basic_initialization();
66public:
67 // (*) constructors, destructor, assignment operator -----------------------
68 inline GetPot();
69 inline GetPot(const GetPot&);
70 inline GetPot(const int argc_, char** argv_,
71 const char* FieldSeparator=0x0);
72 inline GetPot(const char* FileName,
73 const char* CommentStart=0x0, const char* CommentEnd=0x0,
74 const char* FieldSeparator=0x0);
75 inline ~GetPot();
76 inline GetPot& operator=(const GetPot&);
77
78
79 // (*) absorbing contents of another GetPot object
80 inline void absorb(const GetPot& That);
81 // -- for ufo detection: recording requested arguments, options etc.
82 inline void clear_requests();
83 inline void disable_request_recording() { __request_recording_f = false; }
84 inline void enable_request_recording() { __request_recording_f = true; }
85
86 // (*) direct access to command line arguments -----------------------------
87 inline const std::string operator[](unsigned Idx) const;
88 inline int get(unsigned Idx, int Default) const;
89 inline double get(unsigned Idx, const double& Default) const;
90 inline const std::string get(unsigned Idx, const char* Default) const;
91 inline unsigned size() const;
92
93 // (*) flags ---------------------------------------------------------------
94 inline bool options_contain(const char* FlagList) const;
95 inline bool argument_contains(unsigned Idx, const char* FlagList) const;
96
97 // (*) variables -----------------------------------------------------------
98 // -- scalar values
99 inline int operator()(const char* VarName, int Default) const;
100 inline double operator()(const char* VarName, const double& Default) const;
101 inline const std::string operator()(const char* VarName, const char* Default) const;
102 // -- vectors
103 inline int operator()(const char* VarName, int Default, unsigned Idx) const;
104 inline double operator()(const char* VarName, const double& Default, unsigned Idx) const;
105 inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const;
106
107 // -- setting variables
108 // i) from outside of GetPot (considering prefix etc.)
109 // ii) from inside, use '__set_variable()' below
110 inline void set(const char* VarName, const char* Value, const bool Requested = true);
111 inline void set(const char* VarName, const double& Value, const bool Requested = true);
112 inline void set(const char* VarName, const int Value, const bool Requested = true);
113
114 inline unsigned vector_variable_size(const char* VarName) const;
115 inline STRING_VECTOR get_variable_names() const;
116 inline STRING_VECTOR get_section_names() const;
117
118
119 // (*) cursor oriented functions -------------------------------------------
120 inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); }
121 inline bool search_failed() const { return search_failed_f; }
122
123 // -- enable/disable search for an option in loop
124 inline void disable_loop() { search_loop_f = false; }
125 inline void enable_loop() { search_loop_f = true; }
126
127 // -- reset cursor to position '1'
128 inline void reset_cursor();
129 inline void init_multiple_occurrence();
130
131 // -- search for a certain option and set cursor to position
132 inline bool search(const char* option);
133 inline bool search(unsigned No, const char* P, ...);
134 // -- get argument at cursor++
135 inline int next(int Default);
136 inline double next(const double& Default);
137 inline const std::string next(const char* Default);
138 // -- search for option and get argument at cursor++
139 inline int follow(int Default, const char* Option);
140 inline double follow(const double& Default, const char* Option);
141 inline const std::string follow(const char* Default, const char* Option);
142 // -- search for one of the given options and get argument that follows it
143 inline int follow(int Default, unsigned No, const char* Option, ...);
144 inline double follow(const double& Default, unsigned No, const char* Option, ...);
145 inline const std::string follow(const char* Default, unsigned No, const char* Option, ...);
146 // -- lists of nominuses following an option
147 inline std::vector<std::string> nominus_followers(const char* Option);
148 inline std::vector<std::string> nominus_followers(unsigned No, ...);
149
150 // -- directly followed arguments
151 inline int direct_follow(int Default, const char* Option);
152 inline double direct_follow(const double& Default, const char* Option);
153 inline const std::string direct_follow(const char* Default, const char* Option);
154
155 inline std::vector<std::string> string_tails(const char* StartString);
156 inline std::vector<int> int_tails(const char* StartString, const int Default = 1);
157 inline std::vector<double> double_tails(const char* StartString, const double Default = 1.0);
158
159 // (*) nominus arguments ---------------------------------------------------
160 inline STRING_VECTOR nominus_vector() const;
161 inline unsigned nominus_size() const { return static_cast<unsigned int>(idx_nominus.size()); }
162 inline std::string next_nominus();
163
164 // (*) unidentified flying objects -----------------------------------------
165 inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const;
166 inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const;
167 inline STRING_VECTOR unidentified_arguments() const;
168
169 inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const;
170 inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const;
171 inline STRING_VECTOR unidentified_options() const;
172
173 inline std::string unidentified_flags(const char* Known,
174 int ArgumentNumber /* =-1 */) const;
175
176 inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const;
177 inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const;
178 inline STRING_VECTOR unidentified_variables() const;
179
180 inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const;
181 inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const;
182 inline STRING_VECTOR unidentified_sections() const;
183
184 inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const;
185 inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const;
186 inline STRING_VECTOR unidentified_nominuses() const;
187
188 // (*) output --------------------------------------------------------------
189 inline int print() const;
190
191private:
192 // (*) Type Declaration ----------------------------------------------------
193 struct variable {
194 //-----------
195 // Variable to be specified on the command line or in input files.
196 // (i.e. of the form var='12 312 341')
197
198 // -- constructors, destructors, assignment operator
199 variable();
200 variable(const variable&);
201 variable(const char* Name, const char* Value, const char* FieldSeparator);
202 ~variable();
203 variable& operator=(const variable& That);
204
205 void take(const char* Value, const char* FieldSeparator);
206
207 // -- get a specific element in the string vector
208 // (return 0 if not present)
209 const std::string* get_element(unsigned Idx) const;
210
211 // -- data memebers
212 std::string name; // identifier of variable
213 STRING_VECTOR value; // value of variable stored in vector
214 std::string original; // value of variable as given on command line
215 };
216
217 // (*) member variables --------------------------------------------------------------
218 std::string prefix; // prefix automatically added in queries
219 std::string section; // (for dollar bracket parsing)
220 STRING_VECTOR section_list; // list of all parsed sections
221 // -- argument vector
222 STRING_VECTOR argv; // vector of command line arguments stored as strings
223 unsigned cursor; // cursor for argv
224 bool search_loop_f; // shall search start at beginning after
225 // // reaching end of arg array ?
226 bool search_failed_f; // flag indicating a failed search() operation
227 // // (e.g. next() functions react with 'missed')
228
229 // -- nominus vector
230 int nominus_cursor; // cursor for nominus_pointers
231 std::vector<unsigned> idx_nominus; // indecies of 'no minus' arguments
232
233 // -- variables
234 // (arguments of the form "variable=value")
235 std::vector<variable> variables;
236
237 // -- comment delimiters
238 std::string _comment_start;
239 std::string _comment_end;
240
241 // -- field separator (separating elements of a vector)
242 std::string _field_separator;
243
244 // -- some functions return a char pointer to a temporarily existing string
245 // this container makes them 'available' until the getpot object is destroyed.
246 std::vector<char*> __internal_string_container;
247
248 // -- keeping track about arguments that are requested, so that the UFO detection
249 // can be simplified
250 STRING_VECTOR _requested_arguments;
251 STRING_VECTOR _requested_variables;
252 STRING_VECTOR _requested_sections;
253
254 bool __request_recording_f; // speed: request recording can be turned off
255
256 // -- if an argument is requested record it and the 'tag' the section branch to which
257 // it belongs. Caution: both functions mark the sections as 'tagged'.
258 void __record_argument_request(const std::string& Arg);
259 void __record_variable_request(const std::string& Arg);
260
261 // (*) helper functions ----------------------------------------------------
262 // set variable from inside GetPot (no prefix considered)
263 inline void __set_variable(const char* VarName, const char* Value);
264
265 // -- produce three basic data vectors:
266 // - argument vector
267 // - nominus vector
268 // - variable dictionary
269 inline void __parse_argument_vector(const STRING_VECTOR& ARGV);
270
271 // -- helpers for argument list processing
272 // * search for a variable in 'variables' array
273 inline const variable* __find_variable(const char*) const;
274 // * support finding directly followed arguments
275 inline const char* __match_starting_string(const char* StartString);
276 // * support search for flags in a specific argument
277 inline bool __check_flags(const std::string& Str, const char* FlagList) const;
278 // * type conversion if possible
279 inline int __convert_to_type(const std::string& String, int Default) const;
280 inline double __convert_to_type(const std::string& String, double Default) const;
281 // * prefix extraction
282 const std::string __get_remaining_string(const std::string& String,
283 const std::string& Start) const;
284 // * search for a specific string
285 inline bool __search_string_vector(const STRING_VECTOR& Vec,
286 const std::string& Str) const;
287
288 // -- helpers to parse input file
289 // create an argument vector based on data found in an input file, i.e.:
290 // 1) delete comments (in between '_comment_start' '_comment_end')
291 // 2) contract assignment expressions, such as
292 // my-variable = '007 J. B.'
293 // into
294 // my-variable='007 J. B.'
295 // 3) interprete sections like '[../my-section]' etc.
296 inline void __skip_whitespace(std::istream& istr);
297 inline const std::string __get_next_token(std::istream& istr);
298 inline const std::string __get_string(std::istream& istr);
299 inline const std::string __get_until_closing_bracket(std::istream& istr);
300
301 inline STRING_VECTOR __read_in_stream(std::istream& istr);
302 inline STRING_VECTOR __read_in_file(const char* FileName);
303 inline std::string __process_section_label(const std::string& Section,
304 STRING_VECTOR& section_stack);
305
306 // -- dollar bracket expressions
307 std::string __DBE_expand_string(const std::string str);
308 std::string __DBE_expand(const std::string str);
309 const GetPot::variable* __DBE_get_variable(const std::string str);
310 STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber);
311
312 std::string __double2string(const double& Value) const {
313 // -- converts a double integer into a string
314 char* tmp = new char[128];
315#ifndef WIN32
316 snprintf(tmp, (int)sizeof(char)*128, "%e", Value);
317#else
318 _snprintf(tmp, sizeof(char)*128, "%e", Value);
319#endif
320 std::string result(tmp);
321 delete [] tmp;
322 return result;
323 }
324
325 std::string __int2string(const int& Value) const {
326 // -- converts an integer into a string
327 char* tmp = new char[128];
328#ifndef WIN32
329 snprintf(tmp, (int)sizeof(char)*128, "%i", Value);
330#else
331 _snprintf(tmp, sizeof(char)*128, "%i", Value);
332#endif
333 std::string result(tmp);
334 delete [] tmp;
335 return result;
336 }
337
338 STRING_VECTOR __get_section_tree(const std::string& FullPath) {
339 // -- cuts a variable name into a tree of sub-sections. this is requested for recording
340 // requested sections when dealing with 'ufo' detection.
341 STRING_VECTOR result;
342 const char* Start = FullPath.c_str();
343
344 for(char *p = (char*)Start; *p ; p++) {
345 if( *p == '/' ) {
346 *p = '\0'; // set terminating zero for convinience
347 const std::string Section = Start;
348 *p = '/'; // reset slash at place
349 result.push_back(Section);
350 }
351 }
352
353 return result;
354 }
355};
356
357
358///////////////////////////////////////////////////////////////////////////////
359// (*) constructors, destructor, assignment operator
360//.............................................................................
361//
362inline void
363GetPot::__basic_initialization()
364{
365 cursor = 0; nominus_cursor = -1;
366 search_failed_f = true; search_loop_f = true;
367 prefix = ""; section = "";
368
369 // automatic request recording for later ufo detection
370 __request_recording_f = true;
371
372 // comment start and end strings
373 _comment_start = std::string("#");
374 _comment_end = std::string("\n");
375
376 // default: separate vector elements by whitespaces
377 _field_separator = " \t\n";
378}
379
380inline
381GetPot::GetPot()
382{
383 __basic_initialization();
384
385 STRING_VECTOR _apriori_argv;
386 _apriori_argv.push_back(std::string("Empty"));
387 __parse_argument_vector(_apriori_argv);
388}
389
390inline
391GetPot::GetPot(const int argc_, char ** argv_,
392 const char* FieldSeparator /* =0x0 */)
393 // leave 'char**' non-const to honor less capable compilers ...
394{
395 // TODO: Ponder over the problem when the argument list is of size = 0.
396 // This is 'sabotage', but it can still occur if the user specifies
397 // it himself.
398 assert(argc_ >= 1);
399 __basic_initialization();
400
401 // if specified -> overwrite default string
402 if( FieldSeparator ) _field_separator = std::string(FieldSeparator);
403
404 // -- make an internal copy of the argument list:
405 STRING_VECTOR _apriori_argv;
406 // -- for the sake of clarity: we do want to include the first argument in the argument vector !
407 // it will not be a nominus argument, though. This gives us a minimun vector size of one
408 // which facilitates error checking in many functions. Also the user will be able to
409 // retrieve the name of his application by "get[0]"
410 _apriori_argv.push_back(std::string(argv_[0]));
411 int i=1;
412 for(; i<argc_; ++i) {
413 std::string tmp(argv_[i]); // recall the problem with temporaries,
414 _apriori_argv.push_back(tmp); // reference counting in arguement lists ...
415 }
416 __parse_argument_vector(_apriori_argv);
417}
418
419
420inline
421GetPot::GetPot(const char* FileName,
422 const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */,
423 const char* FieldSeparator/* = 0x0 */)
424{
425 __basic_initialization();
426
427 // if specified -> overwrite default strings
428 if( CommentStart ) _comment_start = std::string(CommentStart);
429 if( CommentEnd ) _comment_end = std::string(CommentEnd);
430 if( FieldSeparator ) _field_separator = FieldSeparator;
431
432 STRING_VECTOR _apriori_argv;
433 // -- file name is element of argument vector, however, it is not parsed for
434 // variable assignments or nominuses.
435 _apriori_argv.push_back(std::string(FileName));
436
437 STRING_VECTOR args = __read_in_file(FileName);
438 _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end());
439 __parse_argument_vector(_apriori_argv);
440}
441
442inline
443GetPot::GetPot(const GetPot& That)
444{ GetPot::operator=(That); }
445
446inline
447GetPot::~GetPot()
448{
449 // may be some return strings had to be created, delete now !
450 victorate(char*, __internal_string_container, it)
451 delete [] *it;
452}
453
454inline GetPot&
455GetPot::operator=(const GetPot& That)
456{
457 if (&That == this) return *this;
458
459 _comment_start = That._comment_start;
460 _comment_end = That._comment_end;
461 argv = That.argv;
462 variables = That.variables;
463 prefix = That.prefix;
464
465 cursor = That.cursor;
466 nominus_cursor = That.nominus_cursor;
467 search_failed_f = That.search_failed_f;
468
469 idx_nominus = That.idx_nominus;
470 search_loop_f = That.search_loop_f;
471
472 return *this;
473}
474
475
476inline void
477GetPot::absorb(const GetPot& That)
478{
479 if (&That == this) return;
480
481 STRING_VECTOR __tmp(That.argv);
482
483 __tmp.erase(__tmp.begin());
484
485 __parse_argument_vector(__tmp);
486}
487
488inline void
489GetPot::clear_requests()
490{
491 _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end());
492 _requested_variables.erase(_requested_variables.begin(), _requested_variables.end());
493 _requested_sections.erase(_requested_sections.begin(), _requested_sections.end());
494}
495
496inline void
497GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV)
498{
499 if( ARGV.size() == 0 ) return;
500
501 // build internal databases:
502 // 1) array with no-minus arguments (usually used as filenames)
503 // 2) variable assignments:
504 // 'variable name' '=' number | string
505 STRING_VECTOR section_stack;
506 STRING_VECTOR::const_iterator it = ARGV.begin();
507
508
509 section = "";
510
511 // -- do not parse the first argument, so that it is not interpreted a s a nominus or so.
512 argv.push_back(*it);
513 ++it;
514
515 // -- loop over remaining arguments
516 unsigned i=1;
517 for(; it != ARGV.end(); ++it, ++i) {
518 std::string arg = *it;
519
520 if( arg.length() == 0 ) continue;
521
522 // -- [section] labels
523 if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) {
524
525 // (*) sections are considered 'requested arguments'
526 if( __request_recording_f ) _requested_arguments.push_back(arg);
527
528 const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2));
529 section = __process_section_label(Name, section_stack);
530 // new section --> append to list of sections
531 if( find(section_list.begin(), section_list.end(), section) == section_list.end() )
532 if( section.length() != 0 ) section_list.push_back(section);
533 argv.push_back(arg);
534 }
535 else {
536 arg = section + __DBE_expand_string(arg);
537 argv.push_back(arg);
538 }
539
540 // -- separate array for nominus arguments
541 if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i));
542
543 // -- variables: does arg contain a '=' operator ?
544 const char* p = arg.c_str();
545 for(; *p ; p++) {
546 if( *p == '=' ) {
547 // (*) record for later ufo detection
548 // arguments carriying variables are always treated as 'requested' arguments.
549 // as a whole! That is 'x=4712' is considered a requested argument.
550 //
551 // unrequested variables have to be detected with the ufo-variable
552 // detection routine.
553 if( __request_recording_f ) _requested_arguments.push_back(arg);
554
555 // set terminating 'zero' to treat first part as single string
556 // => arg (from start to 'p') = Name of variable
557 // p+1 (until terminating zero) = value of variable
558 char* o = (char*)p++;
559 *o = '\0'; // set temporary terminating zero
560 // __set_variable(...)
561 // calls __find_variable(...) which registers the search
562 // temporarily disable this
563 const bool tmp = __request_recording_f;
564 __request_recording_f = false;
565 __set_variable(arg.c_str(), p); // v-name = c_str() bis 'p', value = rest
566 __request_recording_f = tmp;
567 *o = '='; // reset the original '='
568 break;
569 }
570 }
571 }
572}
573
574
575inline STRING_VECTOR
576GetPot::__read_in_file(const char* FileName)
577{
578 std::ifstream i(FileName);
579 if( ! i ) return STRING_VECTOR();
580 // argv[0] == the filename of the file that was read in
581 return __read_in_stream(i);
582}
583
584inline STRING_VECTOR
585GetPot::__read_in_stream(std::istream& istr)
586{
587 STRING_VECTOR brute_tokens;
588 while(istr) {
589 __skip_whitespace(istr);
590
591 const std::string Token = __get_next_token(istr);
592 if( Token.length() == 0 || Token[0] == EOF) break;
593 brute_tokens.push_back(Token);
594 }
595
596 // -- reduce expressions of token1'='token2 to a single
597 // string 'token1=token2'
598 // -- copy everything into 'argv'
599 // -- arguments preceded by something like '[' name ']' (section)
600 // produce a second copy of each argument with a prefix '[name]argument'
601 unsigned i1 = 0;
602 unsigned i2 = 1;
603 unsigned i3 = 2;
604
605 STRING_VECTOR arglist;
606 while( i1 < brute_tokens.size() ) {
607 const std::string& SRef = brute_tokens[i1];
608 // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef'
609 // note: java.lang.String: substring(a,b) = from a to b-1
610 // C++ string: substr(a,b) = from a to a + b
611 if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) {
612 if( i3 >= brute_tokens.size() )
613 arglist.push_back(brute_tokens[i1] + brute_tokens[i2]);
614 else
615 arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]);
616 i1 = i3+1; i2 = i3+2; i3 = i3+3;
617 continue;
618 }
619 else {
620 arglist.push_back(SRef);
621 i1=i2; i2=i3; i3++;
622 }
623 }
624 return arglist;
625}
626
627inline void
628GetPot::__skip_whitespace(std::istream& istr)
629 // find next non-whitespace while deleting comments
630{
631 int tmp = istr.get();
632 do {
633 // -- search a non whitespace
634 while( isspace(tmp) ) {
635 tmp = istr.get();
636 if( ! istr ) return;
637 }
638
639 // -- look if characters match the comment starter string
640 const std::istream::pos_type Pos = istr.tellg();
641 unsigned i=0;
642 for(; i<_comment_start.length() ; ++i) {
643 if( tmp != _comment_start[i] ) {
644// HACK: The following line throws off msvc8:
645// istr.seekg(Pos);
646 // -- one step more backwards, since 'tmp' already at non-whitespace
647 istr.unget();
648 return;
649 }
650 tmp = istr.get();
651 if( ! istr ) { istr.unget(); return; }
652 }
653 // 'tmp' contains last character of _comment_starter
654
655 // -- comment starter found -> search for comment ender
656 unsigned match_no=0;
657 while(1+1 == 2) {
658 tmp = istr.get();
659 if( ! istr ) { istr.unget(); return; }
660
661 if( tmp == _comment_end[match_no] ) {
662 match_no++;
663 if( match_no == _comment_end.length() ) {
664 istr.unget();
665 break; // shuffle more whitespace, end of comment found
666 }
667 }
668 else
669 match_no = 0;
670 }
671
672 tmp = istr.get();
673
674 } while( istr );
675 istr.unget();
676}
677
678inline const std::string
679GetPot::__get_next_token(std::istream& istr)
680 // get next concatinates string token. consider quotes that embrace
681 // whitespaces
682{
683 std::string token;
684 int tmp = 0;
685 int last_letter = 0;
686 while(1+1 == 2) {
687 last_letter = tmp; tmp = istr.get();
688 if( tmp == EOF
689 || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) {
690 return token;
691 }
692 else if( tmp == '\'' && last_letter != '\\' ) {
693 // QUOTES: un-backslashed quotes => it's a string
694 token += __get_string(istr);
695 continue;
696 }
697 else if( tmp == '{' && last_letter == '$') {
698 token += '{' + __get_until_closing_bracket(istr);
699 continue;
700 }
701 else if( tmp == '$' && last_letter == '\\') {
702 token += tmp; tmp = 0; // so that last_letter will become = 0, not '$';
703 continue;
704 }
705 else if( tmp == '\\' && last_letter != '\\')
706 continue; // don't append un-backslashed backslashes
707 token += tmp;
708 }
709}
710
711inline const std::string
712GetPot::__get_string(std::istream& istr)
713 // parse input until next matching '
714{
715 std::string str;
716 int tmp = 0;
717 int last_letter = 0;
718 while(1 + 1 == 2) {
719 last_letter = tmp; tmp = istr.get();
720 if( tmp == EOF) return str;
721 // un-backslashed quotes => it's the end of the string
722 else if( tmp == '\'' && last_letter != '\\') return str;
723 else if( tmp == '\\' && last_letter != '\\') continue; // don't append
724
725 str += tmp;
726 }
727}
728
729inline const std::string
730GetPot::__get_until_closing_bracket(std::istream& istr)
731 // parse input until next matching }
732{
733 std::string str = "";
734 int tmp = 0;
735 int last_letter = 0;
736 int brackets = 1;
737 while(1 + 1 == 2) {
738 last_letter = tmp; tmp = istr.get();
739 if( tmp == EOF) return str;
740 else if( tmp == '{' && last_letter == '$') brackets += 1;
741 else if( tmp == '}') {
742 brackets -= 1;
743 // un-backslashed brackets => it's the end of the string
744 if( brackets == 0) return str + '}';
745 else if( tmp == '\\' && last_letter != '\\')
746 continue; // do not append an unbackslashed backslash
747 }
748 str += tmp;
749 }
750}
751
752inline std::string
753GetPot::__process_section_label(const std::string& Section,
754 STRING_VECTOR& section_stack)
755{
756 std::string sname = Section;
757 // 1) subsection of actual section ('./' prefix)
758 if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) {
759 sname = sname.substr(2);
760 }
761 // 2) subsection of parent section ('../' prefix)
762 else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) {
763 do {
764 if( section_stack.end() != section_stack.begin() )
765 section_stack.pop_back();
766 sname = sname.substr(3);
767 } while( sname.substr(0, 3) == "../" );
768 }
769 // 3) subsection of the root-section
770 else {
771 section_stack.erase(section_stack.begin(), section_stack.end());
772 // [] => back to root section
773 }
774
775 if( sname != "" ) {
776 // parse section name for 'slashes'
777 unsigned i=0;
778 while( i < sname.length() ) {
779 if( sname[i] == '/' ) {
780 section_stack.push_back(sname.substr(0,i));
781 if( i+1 < sname.length()-1 )
782 sname = sname.substr(i+1);
783 i = 0;
784 }
785 else
786 ++i;
787 }
788 section_stack.push_back(sname);
789 }
790 std::string section = "";
791 if( section_stack.size() != 0 ) {
792 victorate(std::string, section_stack, it)
793 section += *it + "/";
794 }
795 return section;
796}
797
798
799// convert string to DOUBLE, if not possible return Default
800inline double
801GetPot::__convert_to_type(const std::string& String, double Default) const
802{
803 double tmp;
804 if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default;
805 return tmp;
806}
807
808// convert string to INT, if not possible return Default
809inline int
810GetPot::__convert_to_type(const std::string& String, int Default) const
811{
812 // NOTE: intermediate results may be floating points, so that the string
813 // may look like 2.0e1 (i.e. float format) => use float conversion
814 // in any case.
815 return (int)__convert_to_type(String, (double)Default);
816}
817
818//////////////////////////////////////////////////////////////////////////////
819// (*) cursor oriented functions
820//.............................................................................
821inline const std::string
822GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const
823 // Checks if 'String' begins with 'Start' and returns the remaining String.
824 // Returns None if String does not begin with Start.
825{
826 if( Start == "" ) return String;
827 // note: java.lang.String: substring(a,b) = from a to b-1
828 // C++ string: substr(a,b) = from a to a + b
829 if( String.find(Start) == 0 ) return String.substr(Start.length());
830 else return "";
831}
832
833// -- search for a certain argument and set cursor to position
834inline bool
835GetPot::search(const char* Option)
836{
837 unsigned OldCursor = cursor;
838 const std::string SearchTerm = prefix + Option;
839
840 // (*) record requested arguments for later ufo detection
841 __record_argument_request(SearchTerm);
842
843 if( OldCursor >= argv.size() ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
844 search_failed_f = true;
845
846 // (*) first loop from cursor position until end
847 unsigned c = cursor;
848 for(; c < argv.size(); c++) {
849 if( argv[c] == SearchTerm )
850 { cursor = c; search_failed_f = false; return true; }
851 }
852 if( ! search_loop_f ) return false;
853
854 // (*) second loop from 0 to old cursor position
855 for(c = 1; c < OldCursor; c++) {
856 if( argv[c] == SearchTerm )
857 { cursor = c; search_failed_f = false; return true; }
858 }
859 // in case nothing is found the cursor stays where it was
860 return false;
861}
862
863
864inline bool
865GetPot::search(unsigned No, const char* P, ...)
866{
867 // (*) recording the requested arguments happens in subroutine 'search'
868 if( No == 0 ) return false;
869
870 // search for the first argument
871 if( search(P) == true ) return true;
872
873 // start interpreting variable argument list
874 va_list ap;
875 va_start(ap, P);
876 unsigned i = 1;
877 for(; i < No; ++i) {
878 char* Opt = va_arg(ap, char *);
879 if( search(Opt) == true ) break;
880 }
881
882 if( i < No ) {
883 ++i;
884 // loop was left before end of array --> hit but
885 // make sure that the rest of the search terms is marked
886 // as requested.
887 for(; i < No; ++i) {
888 char* Opt = va_arg(ap, char *);
889 // (*) record requested arguments for later ufo detection
890 __record_argument_request(Opt);
891 }
892 va_end(ap);
893 return true;
894 }
895
896 va_end(ap);
897 // loop was left normally --> no hit
898 return false;
899}
900
901inline void
902GetPot::reset_cursor()
903{ search_failed_f = false; cursor = 0; }
904
905inline void
906GetPot::init_multiple_occurrence()
907{ disable_loop(); reset_cursor(); }
908///////////////////////////////////////////////////////////////////////////////
909// (*) direct access to command line arguments
910//.............................................................................
911//
912inline const std::string
913GetPot::operator[](unsigned idx) const
914{ return idx < argv.size() ? argv[idx] : ""; }
915
916inline int
917GetPot::get(unsigned Idx, int Default) const
918{
919 if( Idx >= argv.size() ) return Default;
920 return __convert_to_type(argv[Idx], Default);
921}
922
923inline double
924GetPot::get(unsigned Idx, const double& Default) const
925{
926 if( Idx >= argv.size() ) return Default;
927 return __convert_to_type(argv[Idx], Default);
928}
929
930inline const std::string
931GetPot::get(unsigned Idx, const char* Default) const
932{
933 if( Idx >= argv.size() ) return Default;
934 else return argv[Idx];
935}
936
937inline unsigned
938GetPot::size() const
939{ return static_cast<unsigned int>(argv.size()); }
940
941
942// -- next() function group
943inline int
944GetPot::next(int Default)
945{
946 if( search_failed_f ) return Default;
947 cursor++;
948 if( cursor >= argv.size() )
949 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
950
951 // (*) record requested argument for later ufo detection
952 __record_argument_request(argv[cursor]);
953
954 const std::string Remain = __get_remaining_string(argv[cursor], prefix);
955
956 return Remain != "" ? __convert_to_type(Remain, Default) : Default;
957}
958
959inline double
960GetPot::next(const double& Default)
961{
962 if( search_failed_f ) return Default;
963 cursor++;
964
965 if( cursor >= argv.size() )
966 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
967
968 // (*) record requested argument for later ufo detection
969 __record_argument_request(argv[cursor]);
970
971 std::string Remain = __get_remaining_string(argv[cursor], prefix);
972
973 return Remain != "" ? __convert_to_type(Remain, Default) : Default;
974}
975
976inline const std::string
977GetPot::next(const char* Default)
978{
979 if( search_failed_f ) return Default;
980 cursor++;
981
982 if( cursor >= argv.size() )
983 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
984
985 // (*) record requested argument for later ufo detection
986 __record_argument_request(argv[cursor]);
987
988 const std::string Remain = __get_remaining_string(argv[cursor], prefix);
989
990 if( Remain == "" ) return Default;
991
992
993 // (*) function returns a pointer to a char array (inside Remain)
994 // this array will be deleted, though after this function call.
995 // To ensure propper functioning, create a copy inside *this
996 // object and only delete it, when *this is deleted.
997 char* result = new char[Remain.length()+1];
998 strncpy(result, Remain.c_str(), Remain.length()+1);
999
1000 // store the created string internally, delete if when object deleted
1001 __internal_string_container.push_back(result);
1002
1003 return result;
1004}
1005
1006// -- follow() function group
1007// distinct option to be searched for
1008inline int
1009GetPot::follow(int Default, const char* Option)
1010{
1011 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1012 if( search(Option) == false ) return Default;
1013 return next(Default);
1014}
1015
1016inline double
1017GetPot::follow(const double& Default, const char* Option)
1018{
1019 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1020 if( search(Option) == false ) return Default;
1021 return next(Default);
1022}
1023
1024inline const std::string
1025GetPot::follow(const char* Default, const char* Option)
1026{
1027 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1028 if( search(Option) == false ) return Default;
1029 return next(Default);
1030}
1031
1032// -- second follow() function group
1033// multiple option to be searched for
1034inline int
1035GetPot::follow(int Default, unsigned No, const char* P, ...)
1036{
1037 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1038 if( No == 0 ) return Default;
1039 if( search(P) == true ) return next(Default);
1040
1041 va_list ap;
1042 va_start(ap, P);
1043 unsigned i=1;
1044 for(; i<No; ++i) {
1045 char* Opt = va_arg(ap, char *);
1046 if( search(Opt) == true ) {
1047 va_end(ap);
1048 return next(Default);
1049 }
1050 }
1051 va_end(ap);
1052 return Default;
1053}
1054
1055inline double
1056GetPot::follow(const double& Default, unsigned No, const char* P, ...)
1057{
1058 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1059 if( No == 0 ) return Default;
1060 if( search(P) == true ) return next(Default);
1061
1062 va_list ap;
1063 va_start(ap, P);
1064 for(unsigned i=1; i<No; ++i) {
1065 char* Opt = va_arg(ap, char *);
1066 if( search(Opt) == true ) {
1067 va_end(ap);
1068 return next(Default);
1069 }
1070 }
1071 va_end(ap);
1072 return Default;
1073}
1074
1075inline const std::string
1076GetPot::follow(const char* Default, unsigned No, const char* P, ...)
1077{
1078 // (*) record requested of argument is entirely handled in 'search()' and 'next()'
1079 if( No == 0 ) return Default;
1080 if( search(P) == true ) return next(Default);
1081
1082 va_list ap;
1083 va_start(ap, P);
1084 unsigned i=1;
1085 for(; i<No; ++i) {
1086 char* Opt = va_arg(ap, char *);
1087 if( search(Opt) == true ) {
1088 va_end(ap);
1089 return next(Default);
1090 }
1091 }
1092 va_end(ap);
1093 return Default;
1094}
1095
1096
1097///////////////////////////////////////////////////////////////////////////////
1098// (*) lists of nominus following an option
1099//.............................................................................
1100//
1101inline std::vector<std::string>
1102GetPot::nominus_followers(const char* Option)
1103{
1104 std::vector<std::string> result_list;
1105 if( search(Option) == false ) return result_list;
1106 while( 1 + 1 == 2 ) {
1107 ++cursor;
1108 if( cursor >= argv.size() ) {
1109 cursor = argv.size() - 1;
1110 return result_list;
1111 }
1112 if( argv[cursor].length() >= 1 ) {
1113 if( argv[cursor][0] == '-' ) {
1114 return result_list;
1115 }
1116 // -- record for later ufo-detection
1117 __record_argument_request(argv[cursor]);
1118 // -- append to the result list
1119 result_list.push_back(argv[cursor]);
1120 }
1121 }
1122}
1123
1124inline std::vector<std::string>
1125GetPot::nominus_followers(unsigned No, ...)
1126{
1127 std::vector<std::string> result_list;
1128 // (*) record requested of argument is entirely handled in 'search()'
1129 // and 'nominus_followers()'
1130 if( No == 0 ) return result_list;
1131
1132 va_list ap;
1133 va_start(ap, No);
1134 for(unsigned i=0; i<No; ++i) {
1135 char* Option = va_arg(ap, char *);
1136 std::vector<std::string> tmp = nominus_followers(Option);
1137 result_list.insert(result_list.end(), tmp.begin(), tmp.end());
1138
1139 // std::cerr << "option = '" << Option << "'" << std::endl;
1140 // std::cerr << "length = " << tmp.size() << std::endl;
1141 // std::cerr << "new result list = <";
1142 // for(std::vector<std::string>::const_iterator it = result_list.begin();
1143 // it != result_list.end(); ++it)
1144 // std::cerr << *it << ", ";
1145 // std::cerr << ">\n";
1146 }
1147 va_end(ap);
1148 return result_list;
1149}
1150
1151
1152///////////////////////////////////////////////////////////////////////////////
1153// (*) directly connected options
1154//.............................................................................
1155//
1156inline int
1157GetPot::direct_follow(int Default, const char* Option)
1158{
1159 const char* FollowStr = __match_starting_string(Option);
1160 if( FollowStr == 0x0 ) return Default;
1161
1162 // (*) record requested of argument for later ufo-detection
1163 __record_argument_request(std::string(Option) + FollowStr);
1164
1165 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
1166 return __convert_to_type(FollowStr, Default);
1167}
1168
1169inline double
1170GetPot::direct_follow(const double& Default, const char* Option)
1171{
1172 const char* FollowStr = __match_starting_string(Option);
1173 if( FollowStr == 0 ) return Default;
1174
1175 // (*) record requested of argument for later ufo-detection
1176 __record_argument_request(std::string(Option) + FollowStr);
1177
1178 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
1179 return __convert_to_type(FollowStr, Default);
1180}
1181
1182inline const std::string
1183GetPot::direct_follow(const char* Default, const char* Option)
1184{
1185 if( search_failed_f ) return Default;
1186 const char* FollowStr = __match_starting_string(Option);
1187 if( FollowStr == 0 ) return Default;
1188
1189 // (*) record requested of argument for later ufo-detection
1190 if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr);
1191
1192 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
1193 return std::string(FollowStr);
1194}
1195
1196inline std::vector<std::string>
1197GetPot::string_tails(const char* StartString)
1198{
1199 std::vector<std::string> result;
1200 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1201
1202 std::vector<std::string>::iterator it = argv.begin();
1203
1204 unsigned idx = 0;
1205 while( it != argv.end() ) {
1206 // (*) does start string match the given option?
1207 // NO -> goto next option
1208 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
1209
1210 // append the found tail to the result vector
1211 result.push_back((*it).substr(N));
1212
1213 // adapt the nominus vector
1214 std::vector<unsigned>::iterator nit = idx_nominus.begin();
1215 for(; nit != idx_nominus.end(); ++nit) {
1216 if( *nit == idx ) {
1217 idx_nominus.erase(nit);
1218 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
1219 break;
1220 }
1221 }
1222
1223 // erase the found option
1224 argv.erase(it);
1225
1226 // 100% safe solution: set iterator back to the beginning.
1227 // (normally, 'it--' would be enough, but who knows how the
1228 // iterator is implemented and .erase() definitely invalidates
1229 // the current iterator position.
1230 if( argv.empty() ) break;
1231 it = argv.begin();
1232 }
1233 cursor = 0;
1234 nominus_cursor = -1;
1235 return result;
1236}
1237
1238inline std::vector<int>
1239GetPot::int_tails(const char* StartString, const int Default /* = -1 */)
1240{
1241 std::vector<int> result;
1242 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1243
1244 std::vector<std::string>::iterator it = argv.begin();
1245
1246 unsigned idx = 0;
1247 while( it != argv.end() ) {
1248 // (*) does start string match the given option?
1249 // NO -> goto next option
1250 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
1251
1252 // append the found tail to the result vector
1253 result.push_back(__convert_to_type((*it).substr(N), Default));
1254
1255 // adapt the nominus vector
1256 std::vector<unsigned>::iterator nit = idx_nominus.begin();
1257 for(; nit != idx_nominus.end(); ++nit) {
1258 if( *nit == idx ) {
1259 idx_nominus.erase(nit);
1260 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
1261 break;
1262 }
1263 }
1264
1265 // erase the found option
1266 argv.erase(it);
1267
1268 // 100% safe solution: set iterator back to the beginning.
1269 // (normally, 'it--' would be enough, but who knows how the
1270 // iterator is implemented and .erase() definitely invalidates
1271 // the current iterator position.
1272 if( argv.empty() ) break;
1273 it = argv.begin();
1274 }
1275 cursor = 0;
1276 nominus_cursor = -1;
1277 return result;
1278}
1279
1280inline std::vector<double>
1281GetPot::double_tails(const char* StartString,
1282 const double Default /* = -1.0 */)
1283{
1284 std::vector<double> result;
1285 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1286
1287 std::vector<std::string>::iterator it = argv.begin();
1288 unsigned idx = 0;
1289 while( it != argv.end() ) {
1290 // (*) does start string match the given option?
1291 // NO -> goto next option
1292 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
1293
1294 // append the found tail to the result vector
1295 result.push_back(__convert_to_type((*it).substr(N), Default));
1296
1297 // adapt the nominus vector
1298 std::vector<unsigned>::iterator nit = idx_nominus.begin();
1299 for(; nit != idx_nominus.end(); ++nit) {
1300 if( *nit == idx ) {
1301 idx_nominus.erase(nit);
1302 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
1303 break;
1304 }
1305 }
1306
1307 // erase the found option
1308 argv.erase(it);
1309
1310 // 100% safe solution: set iterator back to the beginning.
1311 // (normally, 'it--' would be enough, but who knows how the
1312 // iterator is implemented and .erase() definitely invalidates
1313 // the current iterator position.
1314 if( argv.empty() ) break;
1315 it = argv.begin();
1316 }
1317 cursor = 0;
1318 nominus_cursor = -1;
1319 return result;
1320}
1321
1322
1323
1324
1325
1326inline const char*
1327GetPot::__match_starting_string(const char* StartString)
1328 // pointer to the place where the string after
1329 // the match inside the found argument starts.
1330 // 0 no argument matches the starting string.
1331{
1332 const unsigned N = static_cast<unsigned int>(strlen(StartString));
1333 unsigned OldCursor = cursor;
1334
1335 if( OldCursor >= static_cast<unsigned int>(argv.size()) ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
1336 search_failed_f = true;
1337
1338 // (*) first loop from cursor position until end
1339 unsigned c = cursor;
1340 for(; c < argv.size(); c++) {
1341 if( strncmp(StartString, argv[c].c_str(), N) == 0)
1342 { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
1343 }
1344
1345 if( ! search_loop_f ) return false;
1346
1347 // (*) second loop from 0 to old cursor position
1348 for(c = 1; c < OldCursor; c++) {
1349 if( strncmp(StartString, argv[c].c_str(), N) == 0)
1350 { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
1351 }
1352 return 0;
1353}
1354
1355///////////////////////////////////////////////////////////////////////////////
1356// (*) search for flags
1357//.............................................................................
1358//
1359inline bool
1360GetPot::options_contain(const char* FlagList) const
1361{
1362 // go through all arguments that start with a '-' (but not '--')
1363 std::string str;
1364 STRING_VECTOR::const_iterator it = argv.begin();
1365 for(; it != argv.end(); ++it) {
1366 str = __get_remaining_string(*it, prefix);
1367
1368 if( str.length() >= 2 && str[0] == '-' && str[1] != '-' )
1369 if( __check_flags(str, FlagList) ) return true;
1370 }
1371 return false;
1372}
1373
1374inline bool
1375GetPot::argument_contains(unsigned Idx, const char* FlagList) const
1376{
1377 if( Idx >= argv.size() ) return false;
1378
1379 // (*) record requested of argument for later ufo-detection
1380 // an argument that is checked for flags is considered to be 'requested'
1381 ((GetPot*)this)->__record_argument_request(argv[Idx]);
1382
1383 if( prefix == "" )
1384 // search argument for any flag in flag list
1385 return __check_flags(argv[Idx], FlagList);
1386
1387 // if a prefix is set, then the argument index is the index
1388 // inside the 'namespace'
1389 // => only check list of arguments that start with prefix
1390 unsigned no_matches = 0;
1391 unsigned i=0;
1392 for(; i<argv.size(); ++i) {
1393 const std::string Remain = __get_remaining_string(argv[i], prefix);
1394 if( Remain != "") {
1395 no_matches += 1;
1396 if( no_matches == Idx)
1397 return __check_flags(Remain, FlagList);
1398 }
1399 }
1400 // no argument in this namespace
1401 return false;
1402}
1403
1404inline bool
1405GetPot::__check_flags(const std::string& Str, const char* FlagList) const
1406{
1407 const char* p=FlagList;
1408 for(; *p != '\0' ; p++)
1409 if( Str.find(*p) != std::string::npos ) return true; // found something
1410 return false;
1411}
1412
1413///////////////////////////////////////////////////////////////////////////////
1414// (*) nominus arguments
1415inline STRING_VECTOR
1416GetPot::nominus_vector() const
1417 // return vector of nominus arguments
1418{
1419 STRING_VECTOR nv;
1420 std::vector<unsigned>::const_iterator it = idx_nominus.begin();
1421 for(; it != idx_nominus.end(); ++it) {
1422 nv.push_back(argv[*it]);
1423
1424 // (*) record for later ufo-detection
1425 // when a nominus vector is requested, the entire set of nominus arguments are
1426 // tagged as 'requested'
1427 ((GetPot*)this)->__record_argument_request(argv[*it]);
1428 }
1429 return nv;
1430}
1431
1432inline std::string
1433GetPot::next_nominus()
1434{
1435 if( nominus_cursor < int(idx_nominus.size()) - 1 ) {
1436 const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
1437
1438 // (*) record for later ufo-detection
1439 __record_argument_request(Tmp);
1440
1441 // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer
1442 // to something that does no longer exist.
1443 return Tmp;
1444 }
1445 return std::string("");
1446}
1447
1448///////////////////////////////////////////////////////////////////////////////
1449// (*) variables
1450//.............................................................................
1451//
1452inline int
1453GetPot::operator()(const char* VarName, int Default) const
1454{
1455 // (*) recording of requested variables happens in '__find_variable()'
1456 const variable* sv = __find_variable(VarName);
1457 if( sv == 0 ) return Default;
1458 return __convert_to_type(sv->original, Default);
1459}
1460
1461inline double
1462GetPot::operator()(const char* VarName, const double& Default) const
1463{
1464 // (*) recording of requested variables happens in '__find_variable()'
1465 const variable* sv = __find_variable(VarName);
1466 if( sv == 0 ) return Default;
1467 return __convert_to_type(sv->original, Default);
1468}
1469
1470inline const std::string
1471GetPot::operator()(const char* VarName, const char* Default) const
1472{
1473 // (*) recording of requested variables happens in '__find_variable()'
1474 const variable* sv = __find_variable(VarName);
1475 if( sv == 0 ) return Default;
1476 // -- returning a c_str() pointer is OK here, since the variable remains existant,
1477 // while 'sv' of course is delete at the end of the function.
1478 return sv->original;
1479}
1480
1481inline int
1482GetPot::operator()(const char* VarName, int Default, unsigned Idx) const
1483{
1484 // (*) recording of requested variables happens in '__find_variable()'
1485 const variable* sv = __find_variable(VarName);
1486 if( sv == 0 ) return Default;
1487 const std::string* element = sv->get_element(Idx);
1488 if( element == 0 ) return Default;
1489 return __convert_to_type(*element, Default);
1490}
1491
1492inline double
1493GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const
1494{
1495 // (*) recording of requested variables happens in '__find_variable()'
1496 const variable* sv = __find_variable(VarName);
1497 if( sv == 0 ) return Default;
1498 const std::string* element = sv->get_element(Idx);
1499 if( element == 0 ) return Default;
1500 return __convert_to_type(*element, Default);
1501}
1502
1503inline const std::string
1504GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const
1505{
1506 // (*) recording of requested variables happens in '__find_variable()'
1507 const variable* sv = __find_variable(VarName);
1508 if( sv == 0 ) return Default;
1509 const std::string* element = sv->get_element(Idx);
1510 if( element == 0 ) return Default;
1511 return *element;
1512}
1513
1514inline void
1515GetPot::__record_argument_request(const std::string& Name)
1516{
1517 if( ! __request_recording_f ) return;
1518
1519 // (*) record requested variable for later ufo detection
1520 _requested_arguments.push_back(Name);
1521
1522 // (*) record considered section for ufo detection
1523 STRING_VECTOR STree = __get_section_tree(Name);
1524 victorate(std::string, STree, it)
1525 if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
1526 if( section.length() != 0 ) _requested_sections.push_back(*it);
1527}
1528
1529inline void
1530GetPot::__record_variable_request(const std::string& Name)
1531{
1532 if( ! __request_recording_f ) return;
1533
1534 // (*) record requested variable for later ufo detection
1535 _requested_variables.push_back(Name);
1536
1537 // (*) record considered section for ufo detection
1538 STRING_VECTOR STree = __get_section_tree(Name);
1539 victorate(std::string, STree, it)
1540 if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
1541 if( section.length() != 0 ) _requested_sections.push_back(*it);
1542}
1543
1544// (*) following functions are to be used from 'outside', after getpot has parsed its
1545// arguments => append an argument in the argument vector that reflects the addition
1546inline void
1547GetPot::__set_variable(const char* VarName, const char* Value)
1548{
1549 const GetPot::variable* Var = __find_variable(VarName);
1550 if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str()));
1551 else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str());
1552}
1553
1554inline void
1555GetPot::set(const char* VarName, const char* Value, const bool Requested /* = yes */)
1556{
1557 const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value);
1558 argv.push_back(Arg);
1559 __set_variable(VarName, Value);
1560
1561 // if user does not specify the variable as 'not being requested' it will be
1562 // considered amongst the requested variables
1563 if( Requested ) __record_variable_request(Arg);
1564}
1565
1566inline void
1567GetPot::set(const char* VarName, const double& Value, const bool Requested /* = yes */)
1568{ __set_variable(VarName, __double2string(Value).c_str()); }
1569
1570inline void
1571GetPot::set(const char* VarName, const int Value, const bool Requested /* = yes */)
1572{ __set_variable(VarName, __int2string(Value).c_str()); }
1573
1574
1575inline unsigned
1576GetPot::vector_variable_size(const char* VarName) const
1577{
1578 const variable* sv = __find_variable(VarName);
1579 if( sv == 0 ) return 0;
1580 return static_cast<unsigned int>(sv->value.size());
1581}
1582
1583inline STRING_VECTOR
1584GetPot::get_variable_names() const
1585{
1586 STRING_VECTOR result;
1587 std::vector<GetPot::variable>::const_iterator it = variables.begin();
1588 for(; it != variables.end(); ++it) {
1589 const std::string Tmp = __get_remaining_string((*it).name, prefix);
1590 if( Tmp != "" ) result.push_back(Tmp);
1591 }
1592 return result;
1593}
1594
1595inline STRING_VECTOR
1596GetPot::get_section_names() const
1597{ return section_list; }
1598
1599inline const GetPot::variable*
1600GetPot::__find_variable(const char* VarName) const
1601{
1602 const std::string Name = prefix + VarName;
1603
1604 // (*) record requested variable for later ufo detection
1605 ((GetPot*)this)->__record_variable_request(Name);
1606
1607 std::vector<variable>::const_iterator it = variables.begin();
1608 for(; it != variables.end(); ++it) {
1609 if( (*it).name == Name ) return &(*it);
1610 }
1611 return 0;
1612}
1613
1614///////////////////////////////////////////////////////////////////////////////
1615// (*) ouput (basically for debugging reasons
1616//.............................................................................
1617//
1618inline int
1619GetPot::print() const
1620{
1621 std::cout << "argc = " << static_cast<unsigned int>(argv.size()) << std::endl;
1622 STRING_VECTOR::const_iterator it = argv.begin();
1623 for(; it != argv.end(); ++it)
1624 std::cout << *it << std::endl;
1625 std::cout << std::endl;
1626 return 1;
1627}
1628
1629// (*) dollar bracket expressions (DBEs) ------------------------------------
1630//
1631// 1) Entry Function: __DBE_expand_string()
1632// Takes a string such as
1633//
1634// "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}"
1635//
1636// calls __DBE_expand() for each of the expressions
1637//
1638// ${+ ${x} ${y}}
1639// ${& ${section} ${subsection}}
1640// ${Title}
1641//
1642// and returns the string
1643//
1644// "4711 Subject-1.01: Mit den Clowns kamen die Schwaene"
1645//
1646// assuming that
1647// x = "4699"
1648// y = "12"
1649// section = "1."
1650// subsection = "01"
1651// title = "Mit den Clowns kamen die Schwaene"
1652//
1653// 2) __DBE_expand():
1654//
1655// checks for the command, i.e. the 'sign' that follows '${'
1656// divides the argument list into sub-expressions using
1657// __DBE_get_expr_list()
1658//
1659// ${+ ${x} ${y}} -> "${x}" "${y}"
1660// ${& ${section} ${subsection}} -> "${section}" "${subsection}"
1661// ${Title} -> Nothing, variable expansion
1662//
1663// 3) __DBE_expression_list():
1664//
1665// builds a vector of unbracketed whitespace separated strings, i.e.
1666//
1667// " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}"
1668//
1669// is split into a vector
1670//
1671// [0] ${Number}.a
1672// [1] ${: Das Marmorbild}
1673// [2] AB-${& Author= ${Eichendorf}}-1870
1674//
1675// Each sub-expression is expanded using expand().
1676//---------------------------------------------------------------------------
1677inline std::string
1678GetPot::__DBE_expand_string(const std::string str)
1679{
1680 // Parses for closing operators '${ }' and expands them letting
1681 // white spaces and other letters as they are.
1682 std::string new_string = "";
1683 unsigned open_brackets = 0;
1684 unsigned first = 0;
1685 unsigned i = 0;
1686 for(; i<str.size(); ++i) {
1687 if( i < str.size() - 2 && str.substr(i, 2) == "${" ) {
1688 if( open_brackets == 0 ) first = i+2;
1689 open_brackets++;
1690 }
1691 else if( str[i] == '}' && open_brackets > 0) {
1692 open_brackets -= 1;
1693 if( open_brackets == 0 ) {
1694 const std::string Replacement = __DBE_expand(str.substr(first, i - first));
1695 new_string += Replacement;
1696 }
1697 }
1698 else if( open_brackets == 0 )
1699 new_string += str[i];
1700 }
1701 return new_string;
1702}
1703
1704inline STRING_VECTOR
1705GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber)
1706 // ensures that the resulting vector has the expected number
1707 // of arguments, but they may contain an error message
1708{
1709 std::string str = str_;
1710 // Separates expressions by non-bracketed whitespaces, expands them
1711 // and puts them into a list.
1712
1713 unsigned i=0;
1714 // (1) eat initial whitespaces
1715 for(; i < str.size(); ++i)
1716 if( ! isspace(str[i]) ) break;
1717
1718 STRING_VECTOR expr_list;
1719 unsigned open_brackets = 0;
1720 std::vector<unsigned> start_idx;
1721 unsigned start_new_string = i;
1722 unsigned l = static_cast<unsigned int>(str.size());
1723
1724 // (2) search for ${ } expressions ...
1725 while( i < l ) {
1726 const char letter = str[i];
1727 // whitespace -> end of expression
1728 if( isspace(letter) && open_brackets == 0) {
1729 expr_list.push_back(str.substr(start_new_string, i - start_new_string));
1730 bool no_breakout_f = true;
1731 for(++i; i < l ; ++i) {
1732 if( ! isspace(str[i]) )
1733 { no_breakout_f = false; start_new_string = i; break; }
1734 }
1735 if( no_breakout_f ) {
1736 // end of expression list
1737 if( expr_list.size() < ExpectedNumber ) {
1738 const std::string pre_tmp("<< ${ }: missing arguments>>");
1739 STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
1740 expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
1741 }
1742 return expr_list;
1743 }
1744 }
1745
1746 // dollar-bracket expression
1747 if( str.length() >= i+2 && str.substr(i, 2) == "${" ) {
1748 open_brackets++;
1749 start_idx.push_back(i+2);
1750 }
1751 else if( letter == '}' && open_brackets > 0) {
1752 int start = start_idx[start_idx.size()-1];
1753 start_idx.pop_back();
1754 const std::string Replacement = __DBE_expand(str.substr(start, i-start));
1755 if( start - 3 < (int)0)
1756 str = Replacement + str.substr(i+1);
1757 else
1758 str = str.substr(0, start-2) + Replacement + str.substr(i+1);
1759 l = static_cast<unsigned int>(str.size());
1760 i = start + static_cast<unsigned int>(Replacement.size()) - 3;
1761 open_brackets--;
1762 }
1763 ++i;
1764 }
1765
1766 // end of expression list
1767 expr_list.push_back(str.substr(start_new_string, i-start_new_string));
1768
1769 if( expr_list.size() < ExpectedNumber ) {
1770 const std::string pre_tmp("<< ${ }: missing arguments>>");
1771 STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
1772 expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
1773 }
1774
1775 return expr_list;
1776}
1777
1778inline const GetPot::variable*
1779GetPot::__DBE_get_variable(std::string VarName)
1780{
1781 static GetPot::variable ev;
1782 std::string secure_Prefix = prefix;
1783
1784 prefix = section;
1785 // (1) first search in currently active section
1786 const GetPot::variable* var = __find_variable(VarName.c_str());
1787 if( var != 0 ) { prefix = secure_Prefix; return var; }
1788
1789 // (2) search in root name space
1790 prefix = "";
1791 var = __find_variable(VarName.c_str());
1792 if( var != 0 ) { prefix = secure_Prefix; return var; }
1793
1794 prefix = secure_Prefix;
1795
1796 // error occured => variable name == ""
1797 char* tmp = new char[VarName.length() + 25];
1798#ifndef WIN32
1799 snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25),
1800#else
1801 _snprintf(tmp, sizeof(char)*(VarName.length() + 25),
1802#endif
1803 "<<${ } variable '%s' undefined>>", VarName.c_str());
1804 ev.name = "";
1805 ev.original = std::string(tmp);
1806 delete [] tmp;
1807 return &ev;
1808}
1809
1810inline std::string
1811GetPot::__DBE_expand(const std::string expr)
1812{
1813 // ${: } pure text
1814 if( expr[0] == ':' )
1815 return expr.substr(1);
1816
1817 // ${& expr expr ... } text concatination
1818 else if( expr[0] == '&' ) {
1819 const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1);
1820
1821 STRING_VECTOR::const_iterator it = A.begin();
1822 std::string result = *it++;
1823 for(; it != A.end(); ++it) result += *it;
1824
1825 return result;
1826 }
1827
1828 // ${<-> expr expr expr} text replacement
1829 else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) {
1830 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3);
1831 std::string::size_type tmp = 0;
1832 const std::string::size_type L = A[1].length();
1833 while( (tmp = A[0].find(A[1])) != std::string::npos ) {
1834 A[0].replace(tmp, L, A[2]);
1835 }
1836 return A[0];
1837 }
1838 // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions
1839 else if( expr[0] == '+' ) {
1840 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1841 STRING_VECTOR::const_iterator it = A.begin();
1842 double result = __convert_to_type(*it++, 0.0);
1843 for(; it != A.end(); ++it)
1844 result += __convert_to_type(*it, 0.0);
1845
1846 return __double2string(result);
1847 }
1848 else if( expr[0] == '-' ) {
1849 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1850 STRING_VECTOR::const_iterator it = A.begin();
1851 double result = __convert_to_type(*it++, 0.0);
1852 for(; it != A.end(); ++it)
1853 result -= __convert_to_type(*it, 0.0);
1854
1855 return __double2string(result);
1856 }
1857 else if( expr[0] == '*' ) {
1858 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1859 STRING_VECTOR::const_iterator it = A.begin();
1860 double result = __convert_to_type(*it++, 0.0);
1861 for(; it != A.end(); ++it)
1862 result *= __convert_to_type(*it, 0.0);
1863
1864 return __double2string(result);
1865 }
1866 else if( expr[0] == '/' ) {
1867
1868 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1869 STRING_VECTOR::const_iterator it = A.begin();
1870 double result = __convert_to_type(*it++, 0.0);
1871 if( result == 0 ) return "0.0";
1872 for(; it != A.end(); ++it) {
1873 const double Q = __convert_to_type(*it, 0.0);
1874 if( Q == 0.0 ) return "0.0";
1875 result /= Q;
1876 }
1877 return __double2string(result);
1878 }
1879
1880 // ${^ ... } power expressions
1881 else if( expr[0] == '^' ) {
1882 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1883 STRING_VECTOR::const_iterator it = A.begin();
1884 double result = __convert_to_type(*it++, 0.0);
1885 for(; it != A.end(); ++it)
1886 result = pow(result, __convert_to_type(*it, 0.0));
1887 return __double2string(result);
1888 }
1889
1890 // ${== } ${<= } ${>= } comparisons (return the number of the first 'match'
1891 else if( expr.length() >= 2 &&
1892 ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" ||
1893 expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) {
1894 // differentiate between two and one sign operators
1895 unsigned op = 0;
1896 enum { EQ, GEQ, LEQ, GT, LT };
1897 if ( expr.substr(0, 2) == "==" ) op = EQ;
1898 else if ( expr.substr(0, 2) == ">=" ) op = GEQ;
1899 else if ( expr.substr(0, 2) == "<=" ) op = LEQ;
1900 else if ( expr[0] == '>' ) op = GT;
1901 else /* "<" */ op = LT;
1902
1903 STRING_VECTOR a;
1904 if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2);
1905 else a = __DBE_get_expr_list(expr.substr(2), 2);
1906
1907 std::string x_orig = a[0];
1908 double x = __convert_to_type(x_orig, 1e37);
1909 unsigned i = 1;
1910
1911 STRING_VECTOR::const_iterator y_orig = a.begin();
1912 for(y_orig++; y_orig != a.end(); y_orig++) {
1913 double y = __convert_to_type(*y_orig, 1e37);
1914
1915 // set the strings as reference if one wasn't a number
1916 if ( x == 1e37 || y == 1e37 ) {
1917 // it's a string comparison
1918 if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
1919 (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
1920 (op == LT && x_orig < *y_orig) )
1921 return __int2string(i);
1922 }
1923 else {
1924 // it's a number comparison
1925 if( (op == EQ && x == y) || (op == GEQ && x >= y) ||
1926 (op == LEQ && x <= y) || (op == GT && x > y) ||
1927 (op == LT && x < y) )
1928 return __int2string(i);
1929 }
1930 ++i;
1931 }
1932
1933 // nothing fulfills the condition => return 0
1934 return "0";
1935 }
1936 // ${?? expr expr} select
1937 else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) {
1938 STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2);
1939 double x = __convert_to_type(a[0], 1e37);
1940 // last element is always the default argument
1941 if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1];
1942
1943 // round x to closest integer
1944 return a[int(x+0.5)];
1945 }
1946 // ${? expr expr expr} if then else conditions
1947 else if( expr[0] == '?' ) {
1948 STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2);
1949 if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1];
1950 else if( a.size() > 2 ) return a[2];
1951 }
1952 // ${! expr} maxro expansion
1953 else if( expr[0] == '!' ) {
1954 const GetPot::variable* Var = __DBE_get_variable(expr.substr(1));
1955 // error
1956 if( Var->name == "" ) return std::string(Var->original);
1957
1958 const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2);
1959 return A[0];
1960 }
1961 // ${@: } - string subscription
1962 else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) {
1963 const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2);
1964 double x = __convert_to_type(A[1], 1e37);
1965
1966 // last element is always the default argument
1967 if( x == 1e37 || x < 0 || x >= A[0].size() - 1)
1968 return "<<1st index out of range>>";
1969
1970 if( A.size() > 2 ) {
1971 double y = __convert_to_type(A[2], 1e37);
1972 if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x )
1973 return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5));
1974 else if( y == -1 )
1975 return A[0].substr(int(x+0.5));
1976 return "<<2nd index out of range>>";
1977 }
1978 else {
1979 char* tmp = new char[2];
1980 tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0';
1981 std::string result(tmp);
1982 delete [] tmp;
1983 return result;
1984 }
1985 }
1986 // ${@ } - vector subscription
1987 else if( expr[0] == '@' ) {
1988 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
1989 const GetPot::variable* Var = __DBE_get_variable(A[0]);
1990 // error
1991 if( Var->name == "" ) {
1992 // make a copy of the string if an error occured
1993 // (since the error variable is a static variable inside get_variable())
1994 return std::string(Var->original);
1995 }
1996
1997 double x = __convert_to_type(A[1], 1e37);
1998
1999 // last element is always the default argument
2000 if (x == 1e37 || x < 0 || x >= Var->value.size() )
2001 return "<<1st index out of range>>";
2002
2003 if ( A.size() > 2) {
2004 double y = __convert_to_type(A[2], 1e37);
2005 int begin = int(x+0.5);
2006 int end = 0;
2007 if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x)
2008 end = int(y+1.5);
2009 else if( y == -1 )
2010 end = static_cast<unsigned int>(Var->value.size());
2011 else
2012 return "<<2nd index out of range>>";
2013
2014 std::string result = *(Var->get_element(begin));
2015 int i = begin+1;
2016 for(; i < end; ++i)
2017 result += std::string(" ") + *(Var->get_element(i));
2018 return result;
2019 }
2020 else
2021 return *(Var->get_element(int(x+0.5)));
2022 }
2023
2024 const STRING_VECTOR A = __DBE_get_expr_list(expr, 1);
2025 const GetPot::variable* B = __DBE_get_variable(A[0]);
2026
2027 // make a copy of the string if an error occured
2028 // (since the error variable is a static variable inside get_variable())
2029 if( B->name == "" ) return std::string(B->original);
2030 // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces
2031 // with: else return B->original (thanks))
2032 return B->original;
2033}
2034
2035
2036///////////////////////////////////////////////////////////////////////////////
2037// (*) unidentified flying objects
2038//.............................................................................
2039//
2040inline bool
2041GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const
2042{
2043 victorate(std::string, VecStr, itk) {
2044 if( *itk == Str ) return true;
2045 }
2046 return false;
2047}
2048
2049inline STRING_VECTOR
2050GetPot::unidentified_arguments(unsigned Number,
2051 const char* KnownArgument1, ...) const
2052{
2053 STRING_VECTOR known_arguments;
2054
2055 // (1) create a vector of known arguments
2056 if( Number == 0 ) return STRING_VECTOR();
2057
2058 va_list ap;
2059 va_start(ap, KnownArgument1);
2060 known_arguments.push_back(std::string(KnownArgument1));
2061 unsigned i=1;
2062 for(; i<Number; ++i)
2063 known_arguments.push_back(std::string(va_arg(ap, char *)));
2064 va_end(ap);
2065
2066 return unidentified_arguments(known_arguments);
2067}
2068
2069inline STRING_VECTOR
2070GetPot::unidentified_arguments() const
2071{ return unidentified_arguments(_requested_arguments); }
2072
2073inline STRING_VECTOR
2074GetPot::unidentified_arguments(const STRING_VECTOR& Knowns) const
2075{
2076 STRING_VECTOR ufos;
2077 STRING_VECTOR::const_iterator it = argv.begin();
2078 ++it; // forget about argv[0] (application or filename)
2079 for(; it != argv.end(); ++it) {
2080 // -- argument belongs to prefixed section ?
2081 const std::string arg = __get_remaining_string(*it, prefix);
2082 if( arg == "" ) continue;
2083
2084 // -- check if in list
2085 if( __search_string_vector(Knowns, arg) == false)
2086 ufos.push_back(*it);
2087 }
2088 return ufos;
2089}
2090
2091inline STRING_VECTOR
2092GetPot::unidentified_options(unsigned Number,
2093 const char* KnownOption1, ...) const
2094{
2095 STRING_VECTOR known_options;
2096
2097 // (1) create a vector of known arguments
2098 if( Number == 0 ) return STRING_VECTOR();
2099
2100 va_list ap;
2101 va_start(ap, KnownOption1);
2102 known_options.push_back(std::string(KnownOption1));
2103 unsigned i=1;
2104 for(; i<Number; ++i)
2105 known_options.push_back(std::string(va_arg(ap, char *)));
2106 va_end(ap);
2107
2108 return unidentified_options(known_options);
2109}
2110
2111inline STRING_VECTOR
2112GetPot::unidentified_options() const
2113{
2114 // -- every option is an argument.
2115 // -- the set of requested arguments contains the set of requested options.
2116 // -- IF the set of requested arguments contains unrequested options,
2117 // THEN they were requested as 'follow' and 'next' arguments and not as real options.
2118 //
2119 // => it is not necessary to separate requested options from the list
2120 STRING_VECTOR option_list;
2121 victorate(std::string, _requested_arguments, it) {
2122 const std::string arg = *it;
2123 if( arg.length() == 0 ) continue;
2124 if( arg[0] == '-' ) option_list.push_back(arg);
2125 }
2126 return unidentified_options(option_list);
2127}
2128
2129inline STRING_VECTOR
2130GetPot::unidentified_options(const STRING_VECTOR& Knowns) const
2131{
2132 STRING_VECTOR ufos;
2133 STRING_VECTOR::const_iterator it = argv.begin();
2134 ++it; // forget about argv[0] (application or filename)
2135 for(; it != argv.end(); ++it) {
2136 // -- argument belongs to prefixed section ?
2137 const std::string arg = __get_remaining_string(*it, prefix);
2138 if( arg == "" ) continue;
2139
2140 // is argument really an option (starting with '-') ?
2141 if( arg.length() < 1 || arg[0] != '-' ) continue;
2142
2143 if( __search_string_vector(Knowns, arg) == false)
2144 ufos.push_back(*it);
2145 }
2146
2147 return ufos;
2148}
2149
2150inline std::string
2151GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const
2152 // Two modes:
2153 // ArgumentNumber >= 0 check specific argument
2154 // ArgumentNumber == -1 check all options starting with one '-'
2155 // for flags
2156{
2157 std::string ufos;
2158 STRING_VECTOR known_arguments;
2159 std::string KFL(KnownFlagList);
2160
2161 // (2) iteration over '-' arguments (options)
2162 if( ArgumentNumber == -1 ) {
2163 STRING_VECTOR::const_iterator it = argv.begin();
2164 ++it; // forget about argv[0] (application or filename)
2165 for(; it != argv.end(); ++it) {
2166 // -- argument belongs to prefixed section ?
2167 const std::string arg = __get_remaining_string(*it, prefix);
2168 if( arg == "" ) continue;
2169
2170 // -- does arguments start with '-' (but not '--')
2171 if ( arg.length() < 2 ) continue;
2172 else if( arg[0] != '-' ) continue;
2173 else if( arg[1] == '-' ) continue;
2174
2175 // -- check out if flags inside option are contained in KnownFlagList
2176 const char* p=arg.c_str();
2177 p++; // skip starting minus
2178 for(; *p != '\0' ; p++)
2179 if( KFL.find(*p) == std::string::npos ) ufos += *p;
2180 }
2181 }
2182 // (1) check specific argument
2183 else {
2184 // -- only check arguments that start with prefix
2185 int no_matches = 0;
2186 unsigned i=1;
2187 for(; i<argv.size(); ++i) {
2188 const std::string Remain = __get_remaining_string(argv[i], prefix);
2189 if( Remain != "") {
2190 no_matches++;
2191 if( no_matches == ArgumentNumber) {
2192 // -- the right argument number inside the section is found
2193 // => check it for flags
2194 const char* p = Remain.c_str();
2195 p++; // skip starting minus
2196 for(; *p != '\0' ; p++)
2197 if( KFL.find(*p) == std::string::npos ) ufos += *p;
2198 return ufos;
2199 }
2200 }
2201 }
2202 }
2203 return ufos;
2204}
2205
2206inline STRING_VECTOR
2207GetPot::unidentified_variables(unsigned Number,
2208 const char* KnownVariable1, ...) const
2209{
2210 STRING_VECTOR known_variables;
2211
2212 // create vector of known arguments
2213 if( Number == 0 ) return STRING_VECTOR();
2214
2215 va_list ap;
2216 va_start(ap, KnownVariable1);
2217 known_variables.push_back(std::string(KnownVariable1));
2218 unsigned i=1;
2219 for(; i<Number; ++i)
2220 known_variables.push_back(std::string(va_arg(ap, char *)));
2221 va_end(ap);
2222
2223 return unidentified_variables(known_variables);
2224}
2225
2226inline STRING_VECTOR
2227GetPot::unidentified_variables(const STRING_VECTOR& Knowns) const
2228{
2229 STRING_VECTOR ufos;
2230
2231 victorate(GetPot::variable, variables, it) {
2232 // -- check if variable has specific prefix
2233 const std::string var_name = __get_remaining_string((*it).name, prefix);
2234 if( var_name == "" ) continue;
2235
2236 // -- check if variable is known
2237 if( __search_string_vector(Knowns, var_name) == false)
2238 ufos.push_back((*it).name);
2239 }
2240 return ufos;
2241}
2242
2243inline STRING_VECTOR
2244GetPot::unidentified_variables() const
2245{ return unidentified_variables(_requested_variables); }
2246
2247
2248inline STRING_VECTOR
2249GetPot::unidentified_sections(unsigned Number,
2250 const char* KnownSection1, ...) const
2251{
2252 STRING_VECTOR known_sections;
2253
2254 // (1) create a vector of known arguments
2255 if( Number == 0 ) return STRING_VECTOR();
2256
2257 va_list ap;
2258 va_start(ap, KnownSection1);
2259 known_sections.push_back(std::string(KnownSection1));
2260 unsigned i=1;
2261 for(; i<Number; ++i) {
2262 std::string tmp = std::string(va_arg(ap, char *));
2263 if( tmp.length() == 0 ) continue;
2264 if( tmp[tmp.length()-1] != '/' ) tmp += '/';
2265 known_sections.push_back(tmp);
2266 }
2267 va_end(ap);
2268
2269 return unidentified_sections(known_sections);
2270}
2271
2272inline STRING_VECTOR
2273GetPot::unidentified_sections() const
2274{ return unidentified_sections(_requested_sections); }
2275
2276inline STRING_VECTOR
2277GetPot::unidentified_sections(const STRING_VECTOR& Knowns) const
2278{
2279 STRING_VECTOR ufos;
2280
2281 victorate(std::string, section_list, it) {
2282 // -- check if section conform to prefix
2283 const std::string sec_name = __get_remaining_string(*it, prefix);
2284 if( sec_name == "" ) continue;
2285
2286 // -- check if section is known
2287 if( __search_string_vector(Knowns, sec_name) == false )
2288 ufos.push_back(*it);
2289 }
2290
2291 return ufos;
2292}
2293
2294
2295inline STRING_VECTOR
2296GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const
2297{
2298 STRING_VECTOR known_nominuses;
2299
2300 // create vector of known arguments
2301 if( Number == 0 ) return STRING_VECTOR();
2302
2303 va_list ap;
2304 va_start(ap, Known);
2305 known_nominuses.push_back(std::string(Known));
2306 unsigned i=1;
2307 for(; i<Number; ++i) {
2308 std::string tmp = std::string(va_arg(ap, char *));
2309 if( tmp.length() == 0 ) continue;
2310 known_nominuses.push_back(tmp);
2311 }
2312 va_end(ap);
2313
2314 return unidentified_nominuses(known_nominuses);
2315}
2316
2317inline STRING_VECTOR
2318GetPot::unidentified_nominuses() const {
2319 // -- every nominus is an argument.
2320 // -- the set of requested arguments contains the set of requested nominuss.
2321 // -- IF the set of requested arguments contains unrequested nominuss,
2322 // THEN they were requested as 'follow' and 'next' arguments and not as real nominuses.
2323 //
2324 // => it is not necessary to separate requested nominus from the list
2325
2326 return unidentified_nominuses(_requested_arguments);
2327}
2328
2329inline STRING_VECTOR
2330GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const
2331{
2332 STRING_VECTOR ufos;
2333
2334 // (2) iterate over all arguments
2335 STRING_VECTOR::const_iterator it = argv.begin();
2336 ++it; // forget about argv[0] (application or filename)
2337 for(; it != argv.end(); ++it) {
2338 // -- check if nominus part of prefix
2339 const std::string arg = __get_remaining_string(*it, prefix);
2340 if( arg == "" ) continue;
2341
2342 if( arg.length() < 1 ) continue;
2343 // option ? --> not a nomius
2344 if( arg[0] == '-' ) continue;
2345 // section ? --> not a real nominus
2346 if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue;
2347 // variable definition ? --> not a real nominus
2348 bool continue_f = false;
2349 unsigned i=0;
2350 for(; i<arg.length() ; ++i)
2351 if( arg[i] == '=' ) { continue_f = true; break; }
2352 if( continue_f ) continue;
2353
2354 // real nominuses are compared with the given list
2355 if( __search_string_vector(Knowns, arg) == false )
2356 ufos.push_back(*it);
2357 }
2358 return ufos;
2359}
2360
2361
2362///////////////////////////////////////////////////////////////////////////////
2363// (*) variable class
2364//.............................................................................
2365//
2366inline
2367GetPot::variable::variable()
2368{}
2369
2370inline
2371GetPot::variable::variable(const variable& That)
2372{
2373#ifdef WIN32
2374 operator=(That);
2375#else
2376 GetPot::variable::operator=(That);
2377#endif
2378}
2379
2380
2381inline
2382GetPot::variable::variable(const char* Name, const char* Value, const char* FieldSeparator)
2383 : name(Name)
2384{
2385 // make a copy of the 'Value'
2386 take(Value, FieldSeparator);
2387}
2388
2389inline const std::string*
2390GetPot::variable::get_element(unsigned Idx) const
2391{ if( Idx >= value.size() ) return 0; else return &(value[Idx]); }
2392
2393inline void
2394GetPot::variable::take(const char* Value, const char* FieldSeparator)
2395{
2396 original = std::string(Value);
2397
2398 // separate string by white space delimiters using 'strtok'
2399 // thread safe usage of strtok (no static members)
2400 char* spt = 0;
2401 // make a copy of the 'Value'
2402 char* copy = new char[strlen(Value)+1];
2403 strcpy(copy, Value);
2404 char* follow_token = strtok_r(copy, FieldSeparator, &spt);
2405 if( value.size() != 0 ) value.erase(value.begin(), value.end());
2406 while(follow_token != 0) {
2407 value.push_back(std::string(follow_token));
2408 follow_token = strtok_r(NULL, FieldSeparator, &spt);
2409 }
2410
2411 delete [] copy;
2412}
2413
2414inline
2415GetPot::variable::~variable()
2416{}
2417
2418inline GetPot::variable&
2419GetPot::variable::operator=(const GetPot::variable& That)
2420{
2421 if( &That != this) {
2422 name = That.name;
2423 value = That.value;
2424 original = That.original;
2425 }
2426 return *this;
2427}
2428
2429#undef victorate
2430
2431
2432#endif // __include_guard_GETPOT_H__
2433
2434
2435