summaryrefslogtreecommitdiff
path: root/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot
diff options
context:
space:
mode:
authorMaurus Cuelenaere <mcuelenaere@gmail.com>2008-07-11 15:50:46 +0000
committerMaurus Cuelenaere <mcuelenaere@gmail.com>2008-07-11 15:50:46 +0000
commit14c7f45cdae826f88dc539c8c38dd95caf305731 (patch)
tree832da054b7cfb2dc6fd63339af736625f31d21aa /utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot
parent7c84ede3781c27db73403bd6302f320c76a58c8c (diff)
downloadrockbox-14c7f45cdae826f88dc539c8c38dd95caf305731.tar.gz
rockbox-14c7f45cdae826f88dc539c8c38dd95caf305731.zip
Add zook's ZenUtils to SVN
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18010 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot')
-rwxr-xr-xutils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot2433
1 files changed, 2433 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