00001
00002
00003
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef __include_guard_GETPOT_H__
00038 #define __include_guard_GETPOT_H__
00039
00040 #if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC)
00041 #define strtok_r(a, b, c) strtok(a, b)
00042 #endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC
00043
00044 extern "C" {
00045
00046
00047 #ifndef WIN32
00048
00049 #include <ctype.h>
00050 #endif
00051 #include <stdio.h>
00052 #include <stdarg.h>
00053 #include <assert.h>
00054 #include <string.h>
00055 }
00056 #include <cmath>
00057 #include <string>
00058 #include <vector>
00059 #include <algorithm>
00060
00061 #include <fstream>
00062 #include <iostream>
00063
00064
00065 typedef std::vector<std::string> STRING_VECTOR;
00066
00067 #define victorate(TYPE, VARIABLE, ITERATOR) \
00068 std::vector<TYPE>::const_iterator ITERATOR = (VARIABLE).begin(); \
00069 for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++)
00070
00071
00073
00074
00075 class GetPot {
00076
00077 inline void __basic_initialization();
00078 public:
00079
00080 inline GetPot();
00081 inline GetPot(const GetPot&);
00082 inline GetPot(const int argc_, char** argv_,
00083 const char* FieldSeparator=0x0);
00084 inline GetPot(const char* FileName,
00085 const char* CommentStart=0x0, const char* CommentEnd=0x0,
00086 const char* FieldSeparator=0x0);
00087 inline ~GetPot();
00088 inline GetPot& operator=(const GetPot&);
00089
00090
00091
00092 inline void absorb(const GetPot& That);
00093
00094 inline void clear_requests();
00095 inline void disable_request_recording() { __request_recording_f = false; }
00096 inline void enable_request_recording() { __request_recording_f = true; }
00097
00098
00099 inline const std::string operator[](unsigned Idx) const;
00100 inline int get(unsigned Idx, int Default) const;
00101 inline double get(unsigned Idx, const double& Default) const;
00102 inline const std::string get(unsigned Idx, const char* Default) const;
00103 inline unsigned size() const;
00104
00105
00106 inline bool options_contain(const char* FlagList) const;
00107 inline bool argument_contains(unsigned Idx, const char* FlagList) const;
00108
00109
00110
00111 inline int operator()(const char* VarName, int Default) const;
00112 inline double operator()(const char* VarName, const double& Default) const;
00113 inline const std::string operator()(const char* VarName, const char* Default) const;
00114
00115 inline int operator()(const char* VarName, int Default, unsigned Idx) const;
00116 inline double operator()(const char* VarName, const double& Default, unsigned Idx) const;
00117 inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const;
00118
00119
00120
00121
00122 inline void set(const char* VarName, const char* Value, const bool Requested = true);
00123 inline void set(const char* VarName, const double& Value, const bool Requested = true);
00124 inline void set(const char* VarName, const int Value, const bool Requested = true);
00125
00126 inline unsigned vector_variable_size(const char* VarName) const;
00127 inline STRING_VECTOR get_variable_names() const;
00128 inline STRING_VECTOR get_section_names() const;
00129
00130
00131
00132 inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); }
00133 inline bool search_failed() const { return search_failed_f; }
00134
00135
00136 inline void disable_loop() { search_loop_f = false; }
00137 inline void enable_loop() { search_loop_f = true; }
00138
00139
00140 inline void reset_cursor();
00141 inline void init_multiple_occurrence();
00142
00143
00144 inline bool search(const char* option);
00145 inline bool search(unsigned No, const char* P, ...);
00146
00147 inline int next(int Default);
00148 inline double next(const double& Default);
00149 inline const std::string next(const char* Default);
00150
00151 inline int follow(int Default, const char* Option);
00152 inline double follow(const double& Default, const char* Option);
00153 inline const std::string follow(const char* Default, const char* Option);
00154
00155 inline int follow(int Default, unsigned No, const char* Option, ...);
00156 inline double follow(const double& Default, unsigned No, const char* Option, ...);
00157 inline const std::string follow(const char* Default, unsigned No, const char* Option, ...);
00158
00159 inline std::vector<std::string> nominus_followers(const char* Option);
00160 inline std::vector<std::string> nominus_followers(unsigned No, ...);
00161
00162
00163 inline int direct_follow(int Default, const char* Option);
00164 inline double direct_follow(const double& Default, const char* Option);
00165 inline const std::string direct_follow(const char* Default, const char* Option);
00166
00167 inline std::vector<std::string> string_tails(const char* StartString);
00168 inline std::vector<int> int_tails(const char* StartString, const int Default = 1);
00169 inline std::vector<double> double_tails(const char* StartString, const double Default = 1.0);
00170
00171
00172 inline STRING_VECTOR nominus_vector() const;
00173 inline unsigned nominus_size() const { return static_cast<unsigned int>(idx_nominus.size()); }
00174 inline std::string next_nominus();
00175
00176
00177 inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const;
00178 inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const;
00179 inline STRING_VECTOR unidentified_arguments() const;
00180
00181 inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const;
00182 inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const;
00183 inline STRING_VECTOR unidentified_options() const;
00184
00185 inline std::string unidentified_flags(const char* Known,
00186 int ArgumentNumber ) const;
00187
00188 inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const;
00189 inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const;
00190 inline STRING_VECTOR unidentified_variables() const;
00191
00192 inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const;
00193 inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const;
00194 inline STRING_VECTOR unidentified_sections() const;
00195
00196 inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const;
00197 inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const;
00198 inline STRING_VECTOR unidentified_nominuses() const;
00199
00200
00201 inline int print() const;
00202
00203 private:
00204
00205 struct variable {
00206
00207
00208
00209
00210
00211 variable();
00212 variable(const variable&);
00213 variable(const char* Name, const char* Value, const char* FieldSeparator);
00214 ~variable();
00215 variable& operator=(const variable& That);
00216
00217 void take(const char* Value, const char* FieldSeparator);
00218
00219
00220
00221 const std::string* get_element(unsigned Idx) const;
00222
00223
00224 std::string name;
00225 STRING_VECTOR value;
00226 std::string original;
00227 };
00228
00229
00230 std::string prefix;
00231 std::string section;
00232 STRING_VECTOR section_list;
00233
00234 STRING_VECTOR argv;
00235 unsigned cursor;
00236 bool search_loop_f;
00237
00238 bool search_failed_f;
00239
00240
00241
00242 int nominus_cursor;
00243 std::vector<unsigned> idx_nominus;
00244
00245
00246
00247 std::vector<variable> variables;
00248
00249
00250 std::string _comment_start;
00251 std::string _comment_end;
00252
00253
00254 std::string _field_separator;
00255
00256
00257
00258 std::vector<char*> __internal_string_container;
00259
00260
00261
00262 STRING_VECTOR _requested_arguments;
00263 STRING_VECTOR _requested_variables;
00264 STRING_VECTOR _requested_sections;
00265
00266 bool __request_recording_f;
00267
00268
00269
00270 void __record_argument_request(const std::string& Arg);
00271 void __record_variable_request(const std::string& Arg);
00272
00273
00274
00275 inline void __set_variable(const char* VarName, const char* Value);
00276
00277
00278
00279
00280
00281 inline void __parse_argument_vector(const STRING_VECTOR& ARGV);
00282
00283
00284
00285 inline const variable* __find_variable(const char*) const;
00286
00287 inline const char* __match_starting_string(const char* StartString);
00288
00289 inline bool __check_flags(const std::string& Str, const char* FlagList) const;
00290
00291 inline int __convert_to_type(const std::string& String, int Default) const;
00292 inline double __convert_to_type(const std::string& String, double Default) const;
00293
00294 const std::string __get_remaining_string(const std::string& String,
00295 const std::string& Start) const;
00296
00297 inline bool __search_string_vector(const STRING_VECTOR& Vec,
00298 const std::string& Str) const;
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 inline void __skip_whitespace(std::istream& istr);
00309 inline const std::string __get_next_token(std::istream& istr);
00310 inline const std::string __get_string(std::istream& istr);
00311 inline const std::string __get_until_closing_bracket(std::istream& istr);
00312
00313 inline STRING_VECTOR __read_in_stream(std::istream& istr);
00314 inline STRING_VECTOR __read_in_file(const char* FileName);
00315 inline std::string __process_section_label(const std::string& Section,
00316 STRING_VECTOR& section_stack);
00317
00318
00319 std::string __DBE_expand_string(const std::string str);
00320 std::string __DBE_expand(const std::string str);
00321 const GetPot::variable* __DBE_get_variable(const std::string str);
00322 STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber);
00323
00324 std::string __double2string(const double& Value) const {
00325
00326 char* tmp = new char[128];
00327 #ifndef WIN32
00328 snprintf(tmp, (int)sizeof(char)*128, "%e", Value);
00329 #else
00330 _snprintf(tmp, sizeof(char)*128, "%e", Value);
00331 #endif
00332 std::string result(tmp);
00333 delete [] tmp;
00334 return result;
00335 }
00336
00337 std::string __int2string(const int& Value) const {
00338
00339 char* tmp = new char[128];
00340 #ifndef WIN32
00341 snprintf(tmp, (int)sizeof(char)*128, "%i", Value);
00342 #else
00343 _snprintf(tmp, sizeof(char)*128, "%i", Value);
00344 #endif
00345 std::string result(tmp);
00346 delete [] tmp;
00347 return result;
00348 }
00349
00350 STRING_VECTOR __get_section_tree(const std::string& FullPath) {
00351
00352
00353 STRING_VECTOR result;
00354 const char* Start = FullPath.c_str();
00355
00356 for(char *p = (char*)Start; *p ; p++) {
00357 if( *p == '/' ) {
00358 *p = '\0';
00359 const std::string Section = Start;
00360 *p = '/';
00361 result.push_back(Section);
00362 }
00363 }
00364
00365 return result;
00366 }
00367 };
00368
00369
00371
00372
00373
00374 inline void
00375 GetPot::__basic_initialization()
00376 {
00377 cursor = 0; nominus_cursor = -1;
00378 search_failed_f = true; search_loop_f = true;
00379 prefix = ""; section = "";
00380
00381
00382 __request_recording_f = true;
00383
00384
00385 _comment_start = std::string("#");
00386 _comment_end = std::string("\n");
00387
00388
00389 _field_separator = " \t\n";
00390 }
00391
00392 inline
00393 GetPot::GetPot()
00394 {
00395 __basic_initialization();
00396
00397 STRING_VECTOR _apriori_argv;
00398 _apriori_argv.push_back(std::string("Empty"));
00399 __parse_argument_vector(_apriori_argv);
00400 }
00401
00402 inline
00403 GetPot::GetPot(const int argc_, char ** argv_,
00404 const char* FieldSeparator )
00405
00406 {
00407
00408
00409
00410 assert(argc_ >= 1);
00411 __basic_initialization();
00412
00413
00414 if( FieldSeparator ) _field_separator = std::string(FieldSeparator);
00415
00416
00417 STRING_VECTOR _apriori_argv;
00418
00419
00420
00421
00422 _apriori_argv.push_back(std::string(argv_[0]));
00423 int i=1;
00424 for(; i<argc_; ++i) {
00425 std::string tmp(argv_[i]);
00426 _apriori_argv.push_back(tmp);
00427 }
00428 __parse_argument_vector(_apriori_argv);
00429 }
00430
00431
00432 inline
00433 GetPot::GetPot(const char* FileName,
00434 const char* CommentStart , const char* CommentEnd ,
00435 const char* FieldSeparator)
00436 {
00437 __basic_initialization();
00438
00439
00440 if( CommentStart ) _comment_start = std::string(CommentStart);
00441 if( CommentEnd ) _comment_end = std::string(CommentEnd);
00442 if( FieldSeparator ) _field_separator = FieldSeparator;
00443
00444 STRING_VECTOR _apriori_argv;
00445
00446
00447 _apriori_argv.push_back(std::string(FileName));
00448
00449 STRING_VECTOR args = __read_in_file(FileName);
00450 _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end());
00451 __parse_argument_vector(_apriori_argv);
00452 }
00453
00454 inline
00455 GetPot::GetPot(const GetPot& That)
00456 { GetPot::operator=(That); }
00457
00458 inline
00459 GetPot::~GetPot()
00460 {
00461
00462 victorate(char*, __internal_string_container, it)
00463 delete [] *it;
00464 }
00465
00466 inline GetPot&
00467 GetPot::operator=(const GetPot& That)
00468 {
00469 if (&That == this) return *this;
00470
00471 _comment_start = That._comment_start;
00472 _comment_end = That._comment_end;
00473 argv = That.argv;
00474 variables = That.variables;
00475 prefix = That.prefix;
00476
00477 cursor = That.cursor;
00478 nominus_cursor = That.nominus_cursor;
00479 search_failed_f = That.search_failed_f;
00480
00481 idx_nominus = That.idx_nominus;
00482 search_loop_f = That.search_loop_f;
00483
00484 return *this;
00485 }
00486
00487
00488 inline void
00489 GetPot::absorb(const GetPot& That)
00490 {
00491 if (&That == this) return;
00492
00493 STRING_VECTOR __tmp(That.argv);
00494
00495 __tmp.erase(__tmp.begin());
00496
00497 __parse_argument_vector(__tmp);
00498 }
00499
00500 inline void
00501 GetPot::clear_requests()
00502 {
00503 _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end());
00504 _requested_variables.erase(_requested_variables.begin(), _requested_variables.end());
00505 _requested_sections.erase(_requested_sections.begin(), _requested_sections.end());
00506 }
00507
00508 inline void
00509 GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV)
00510 {
00511 if( ARGV.size() == 0 ) return;
00512
00513
00514
00515
00516
00517 STRING_VECTOR section_stack;
00518 STRING_VECTOR::const_iterator it = ARGV.begin();
00519
00520
00521 section = "";
00522
00523
00524 argv.push_back(*it);
00525 ++it;
00526
00527
00528 unsigned i=1;
00529 for(; it != ARGV.end(); ++it, ++i) {
00530 std::string arg = *it;
00531
00532 if( arg.length() == 0 ) continue;
00533
00534
00535 if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) {
00536
00537
00538 if( __request_recording_f ) _requested_arguments.push_back(arg);
00539
00540 const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2));
00541 section = __process_section_label(Name, section_stack);
00542
00543 if( find(section_list.begin(), section_list.end(), section) == section_list.end() )
00544 if( section.length() != 0 ) section_list.push_back(section);
00545 argv.push_back(arg);
00546 }
00547 else {
00548 arg = section + __DBE_expand_string(arg);
00549 argv.push_back(arg);
00550 }
00551
00552
00553 if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i));
00554
00555
00556 const char* p = arg.c_str();
00557 for(; *p ; p++) {
00558 if( *p == '=' ) {
00559
00560
00561
00562
00563
00564
00565 if( __request_recording_f ) _requested_arguments.push_back(arg);
00566
00567
00568
00569
00570 char* o = (char*)p++;
00571 *o = '\0';
00572
00573
00574
00575 const bool tmp = __request_recording_f;
00576 __request_recording_f = false;
00577 __set_variable(arg.c_str(), p);
00578 __request_recording_f = tmp;
00579 *o = '=';
00580 break;
00581 }
00582 }
00583 }
00584 }
00585
00586
00587 inline STRING_VECTOR
00588 GetPot::__read_in_file(const char* FileName)
00589 {
00590 std::ifstream i(FileName);
00591 if( ! i ) return STRING_VECTOR();
00592
00593 return __read_in_stream(i);
00594 }
00595
00596 inline STRING_VECTOR
00597 GetPot::__read_in_stream(std::istream& istr)
00598 {
00599 STRING_VECTOR brute_tokens;
00600 while(istr) {
00601 __skip_whitespace(istr);
00602 const std::string Token = __get_next_token(istr);
00603 if( Token.length() == 0 || Token[0] == EOF) break;
00604 brute_tokens.push_back(Token);
00605 }
00606
00607
00608
00609
00610
00611
00612 unsigned i1 = 0;
00613 unsigned i2 = 1;
00614 unsigned i3 = 2;
00615
00616 STRING_VECTOR arglist;
00617 while( i1 < brute_tokens.size() ) {
00618 const std::string& SRef = brute_tokens[i1];
00619
00620
00621
00622 if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) {
00623 if( i3 >= brute_tokens.size() )
00624 arglist.push_back(brute_tokens[i1] + brute_tokens[i2]);
00625 else
00626 arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]);
00627 i1 = i3+1; i2 = i3+2; i3 = i3+3;
00628 continue;
00629 }
00630 else {
00631 arglist.push_back(SRef);
00632 i1=i2; i2=i3; i3++;
00633 }
00634 }
00635 return arglist;
00636 }
00637
00638 inline void
00639 GetPot::__skip_whitespace(std::istream& istr)
00640
00641 {
00642 int tmp = istr.get();
00643 do {
00644
00645 while( isspace(tmp) ) {
00646 tmp = istr.get();
00647 if( ! istr ) return;
00648 }
00649
00650
00651 unsigned i=0;
00652 for(; i<_comment_start.length() ; ++i) {
00653 if( tmp != _comment_start[i] ) {
00654
00655
00656
00657
00658
00659
00660 do istr.unget(); while( i-- != 0 );
00661 return;
00662 }
00663 tmp = istr.get();
00664 if( ! istr ) { istr.unget(); return; }
00665 }
00666
00667
00668
00669 unsigned match_no=0;
00670 while(1+1 == 2) {
00671 tmp = istr.get();
00672 if( ! istr ) { istr.unget(); return; }
00673
00674 if( tmp == _comment_end[match_no] ) {
00675 match_no++;
00676 if( match_no == _comment_end.length() ) {
00677 istr.unget();
00678 break;
00679 }
00680 }
00681 else
00682 match_no = 0;
00683 }
00684
00685 tmp = istr.get();
00686
00687 } while( istr );
00688 istr.unget();
00689 }
00690
00691 inline const std::string
00692 GetPot::__get_next_token(std::istream& istr)
00693
00694
00695 {
00696 std::string token;
00697 int tmp = 0;
00698 int last_letter = 0;
00699 while(1+1 == 2) {
00700 last_letter = tmp; tmp = istr.get();
00701 if( tmp == EOF
00702 || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) {
00703 return token;
00704 }
00705 else if( tmp == '\'' && last_letter != '\\' ) {
00706
00707 token += __get_string(istr);
00708 continue;
00709 }
00710 else if( tmp == '{' && last_letter == '$') {
00711 token += '{' + __get_until_closing_bracket(istr);
00712 continue;
00713 }
00714 else if( tmp == '$' && last_letter == '\\') {
00715 token += tmp; tmp = 0;
00716 continue;
00717 }
00718 else if( tmp == '\\' && last_letter != '\\')
00719 continue;
00720 token += tmp;
00721 }
00722 }
00723
00724 inline const std::string
00725 GetPot::__get_string(std::istream& istr)
00726
00727 {
00728 std::string str;
00729 int tmp = 0;
00730 int last_letter = 0;
00731 while(1 + 1 == 2) {
00732 last_letter = tmp; tmp = istr.get();
00733 if( tmp == EOF) return str;
00734
00735 else if( tmp == '\'' && last_letter != '\\') return str;
00736 else if( tmp == '\\' && last_letter != '\\') continue;
00737
00738 str += tmp;
00739 }
00740 }
00741
00742 inline const std::string
00743 GetPot::__get_until_closing_bracket(std::istream& istr)
00744
00745 {
00746 std::string str = "";
00747 int tmp = 0;
00748 int last_letter = 0;
00749 int brackets = 1;
00750 while(1 + 1 == 2) {
00751 last_letter = tmp; tmp = istr.get();
00752 if( tmp == EOF) return str;
00753 else if( tmp == '{' && last_letter == '$') brackets += 1;
00754 else if( tmp == '}') {
00755 brackets -= 1;
00756
00757 if( brackets == 0) return str + '}';
00758 else if( tmp == '\\' && last_letter != '\\')
00759 continue;
00760 }
00761 str += tmp;
00762 }
00763 }
00764
00765 inline std::string
00766 GetPot::__process_section_label(const std::string& Section,
00767 STRING_VECTOR& section_stack)
00768 {
00769 std::string sname = Section;
00770
00771 if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) {
00772 sname = sname.substr(2);
00773 }
00774
00775 else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) {
00776 do {
00777 if( section_stack.end() != section_stack.begin() )
00778 section_stack.pop_back();
00779 sname = sname.substr(3);
00780 } while( sname.substr(0, 3) == "../" );
00781 }
00782
00783 else {
00784 section_stack.erase(section_stack.begin(), section_stack.end());
00785
00786 }
00787
00788 if( sname != "" ) {
00789
00790 unsigned i=0;
00791 while( i < sname.length() ) {
00792 if( sname[i] == '/' ) {
00793 section_stack.push_back(sname.substr(0,i));
00794 if( i+1 < sname.length() )
00795 sname = sname.substr(i+1);
00796 i = 0;
00797 }
00798 else
00799 ++i;
00800 }
00801 section_stack.push_back(sname);
00802 }
00803 std::string section = "";
00804 if( section_stack.size() != 0 ) {
00805 victorate(std::string, section_stack, it)
00806 section += *it + "/";
00807 }
00808 return section;
00809 }
00810
00811
00812
00813 inline double
00814 GetPot::__convert_to_type(const std::string& String, double Default) const
00815 {
00816 double tmp;
00817 if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default;
00818 return tmp;
00819 }
00820
00821
00822 inline int
00823 GetPot::__convert_to_type(const std::string& String, int Default) const
00824 {
00825
00826
00827
00828 return (int)__convert_to_type(String, (double)Default);
00829 }
00830
00832
00833
00834 inline const std::string
00835 GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const
00836
00837
00838 {
00839 if( Start == "" ) return String;
00840
00841
00842 if( String.find(Start) == 0 ) return String.substr(Start.length());
00843 else return "";
00844 }
00845
00846
00847 inline bool
00848 GetPot::search(const char* Option)
00849 {
00850 unsigned OldCursor = cursor;
00851 const std::string SearchTerm = prefix + Option;
00852
00853
00854 __record_argument_request(SearchTerm);
00855
00856 if( OldCursor >= argv.size() ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
00857 search_failed_f = true;
00858
00859
00860 unsigned c = cursor;
00861 for(; c < argv.size(); c++) {
00862 if( argv[c] == SearchTerm )
00863 { cursor = c; search_failed_f = false; return true; }
00864 }
00865 if( ! search_loop_f ) return false;
00866
00867
00868 for(c = 1; c < OldCursor; c++) {
00869 if( argv[c] == SearchTerm )
00870 { cursor = c; search_failed_f = false; return true; }
00871 }
00872
00873 return false;
00874 }
00875
00876
00877 inline bool
00878 GetPot::search(unsigned No, const char* P, ...)
00879 {
00880
00881 if( No == 0 ) return false;
00882
00883
00884 if( search(P) == true ) return true;
00885
00886
00887 va_list ap;
00888 va_start(ap, P);
00889 unsigned i = 1;
00890 for(; i < No; ++i) {
00891 char* Opt = va_arg(ap, char *);
00892 if( search(Opt) == true ) break;
00893 }
00894
00895 if( i < No ) {
00896 ++i;
00897
00898
00899
00900 for(; i < No; ++i) {
00901 char* Opt = va_arg(ap, char *);
00902
00903 __record_argument_request(Opt);
00904 }
00905 va_end(ap);
00906 return true;
00907 }
00908
00909 va_end(ap);
00910
00911 return false;
00912 }
00913
00914 inline void
00915 GetPot::reset_cursor()
00916 { search_failed_f = false; cursor = 0; }
00917
00918 inline void
00919 GetPot::init_multiple_occurrence()
00920 { disable_loop(); reset_cursor(); }
00922
00923
00924
00925 inline const std::string
00926 GetPot::operator[](unsigned idx) const
00927 { return idx < argv.size() ? argv[idx] : ""; }
00928
00929 inline int
00930 GetPot::get(unsigned Idx, int Default) const
00931 {
00932 if( Idx >= argv.size() ) return Default;
00933 return __convert_to_type(argv[Idx], Default);
00934 }
00935
00936 inline double
00937 GetPot::get(unsigned Idx, const double& Default) const
00938 {
00939 if( Idx >= argv.size() ) return Default;
00940 return __convert_to_type(argv[Idx], Default);
00941 }
00942
00943 inline const std::string
00944 GetPot::get(unsigned Idx, const char* Default) const
00945 {
00946 if( Idx >= argv.size() ) return Default;
00947 else return argv[Idx];
00948 }
00949
00950 inline unsigned
00951 GetPot::size() const
00952 { return static_cast<unsigned int>(argv.size()); }
00953
00954
00955
00956 inline int
00957 GetPot::next(int Default)
00958 {
00959 if( search_failed_f ) return Default;
00960 cursor++;
00961 if( cursor >= argv.size() )
00962 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
00963
00964
00965 __record_argument_request(argv[cursor]);
00966
00967 const std::string Remain = __get_remaining_string(argv[cursor], prefix);
00968
00969 return Remain != "" ? __convert_to_type(Remain, Default) : Default;
00970 }
00971
00972 inline double
00973 GetPot::next(const double& Default)
00974 {
00975 if( search_failed_f ) return Default;
00976 cursor++;
00977
00978 if( cursor >= argv.size() )
00979 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
00980
00981
00982 __record_argument_request(argv[cursor]);
00983
00984 std::string Remain = __get_remaining_string(argv[cursor], prefix);
00985
00986 return Remain != "" ? __convert_to_type(Remain, Default) : Default;
00987 }
00988
00989 inline const std::string
00990 GetPot::next(const char* Default)
00991 {
00992 using namespace std;
00993
00994 if( search_failed_f ) return Default;
00995 cursor++;
00996
00997 if( cursor >= argv.size() )
00998 { cursor = static_cast<unsigned int>(argv.size()); return Default; }
00999
01000
01001 __record_argument_request(argv[cursor]);
01002
01003 const std::string Remain = __get_remaining_string(argv[cursor], prefix);
01004
01005 if( Remain == "" ) return Default;
01006
01007
01008
01009
01010
01011
01012 char* result = new char[Remain.length()+1];
01013 strncpy(result, Remain.c_str(), Remain.length()+1);
01014
01015
01016 __internal_string_container.push_back(result);
01017
01018 return result;
01019 }
01020
01021
01022
01023 inline int
01024 GetPot::follow(int Default, const char* Option)
01025 {
01026
01027 if( search(Option) == false ) return Default;
01028 return next(Default);
01029 }
01030
01031 inline double
01032 GetPot::follow(const double& Default, const char* Option)
01033 {
01034
01035 if( search(Option) == false ) return Default;
01036 return next(Default);
01037 }
01038
01039 inline const std::string
01040 GetPot::follow(const char* Default, const char* Option)
01041 {
01042
01043 if( search(Option) == false ) return Default;
01044 return next(Default);
01045 }
01046
01047
01048
01049 inline int
01050 GetPot::follow(int Default, unsigned No, const char* P, ...)
01051 {
01052
01053 if( No == 0 ) return Default;
01054 if( search(P) == true ) return next(Default);
01055
01056 va_list ap;
01057 va_start(ap, P);
01058 unsigned i=1;
01059 for(; i<No; ++i) {
01060 char* Opt = va_arg(ap, char *);
01061 if( search(Opt) == true ) {
01062 va_end(ap);
01063 return next(Default);
01064 }
01065 }
01066 va_end(ap);
01067 return Default;
01068 }
01069
01070 inline double
01071 GetPot::follow(const double& Default, unsigned No, const char* P, ...)
01072 {
01073
01074 if( No == 0 ) return Default;
01075 if( search(P) == true ) return next(Default);
01076
01077 va_list ap;
01078 va_start(ap, P);
01079 for(unsigned i=1; i<No; ++i) {
01080 char* Opt = va_arg(ap, char *);
01081 if( search(Opt) == true ) {
01082 va_end(ap);
01083 return next(Default);
01084 }
01085 }
01086 va_end(ap);
01087 return Default;
01088 }
01089
01090 inline const std::string
01091 GetPot::follow(const char* Default, unsigned No, const char* P, ...)
01092 {
01093
01094 if( No == 0 ) return Default;
01095 if( search(P) == true ) return next(Default);
01096
01097 va_list ap;
01098 va_start(ap, P);
01099 unsigned i=1;
01100 for(; i<No; ++i) {
01101 char* Opt = va_arg(ap, char *);
01102 if( search(Opt) == true ) {
01103 va_end(ap);
01104 return next(Default);
01105 }
01106 }
01107 va_end(ap);
01108 return Default;
01109 }
01110
01111
01113
01114
01115
01116 inline std::vector<std::string>
01117 GetPot::nominus_followers(const char* Option)
01118 {
01119 std::vector<std::string> result_list;
01120 if( search(Option) == false ) return result_list;
01121 while( 1 + 1 == 2 ) {
01122 ++cursor;
01123 if( cursor >= argv.size() ) {
01124 cursor = argv.size() - 1;
01125 return result_list;
01126 }
01127 if( argv[cursor].length() >= 1 ) {
01128 if( argv[cursor][0] == '-' ) {
01129 return result_list;
01130 }
01131
01132 __record_argument_request(argv[cursor]);
01133
01134 result_list.push_back(argv[cursor]);
01135 }
01136 }
01137 }
01138
01139 inline std::vector<std::string>
01140 GetPot::nominus_followers(unsigned No, ...)
01141 {
01142 std::vector<std::string> result_list;
01143
01144
01145 if( No == 0 ) return result_list;
01146
01147 va_list ap;
01148 va_start(ap, No);
01149 for(unsigned i=0; i<No; ++i) {
01150 char* Option = va_arg(ap, char *);
01151 std::vector<std::string> tmp = nominus_followers(Option);
01152 result_list.insert(result_list.end(), tmp.begin(), tmp.end());
01153
01154
01155
01156
01157
01158
01159
01160
01161 }
01162 va_end(ap);
01163 return result_list;
01164 }
01165
01166
01168
01169
01170
01171 inline int
01172 GetPot::direct_follow(int Default, const char* Option)
01173 {
01174 const char* FollowStr = __match_starting_string(Option);
01175 if( FollowStr == 0x0 ) return Default;
01176
01177
01178 __record_argument_request(std::string(Option) + FollowStr);
01179
01180 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
01181 return __convert_to_type(FollowStr, Default);
01182 }
01183
01184 inline double
01185 GetPot::direct_follow(const double& Default, const char* Option)
01186 {
01187 const char* FollowStr = __match_starting_string(Option);
01188 if( FollowStr == 0 ) return Default;
01189
01190
01191 __record_argument_request(std::string(Option) + FollowStr);
01192
01193 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
01194 return __convert_to_type(FollowStr, Default);
01195 }
01196
01197 inline const std::string
01198 GetPot::direct_follow(const char* Default, const char* Option)
01199 {
01200 if( search_failed_f ) return Default;
01201 const char* FollowStr = __match_starting_string(Option);
01202 if( FollowStr == 0 ) return Default;
01203
01204
01205 if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr);
01206
01207 if( ++cursor >= static_cast<unsigned int>(argv.size()) ) cursor = static_cast<unsigned int>(argv.size());
01208 return std::string(FollowStr);
01209 }
01210
01211 inline std::vector<std::string>
01212 GetPot::string_tails(const char* StartString)
01213 {
01214 std::vector<std::string> result;
01215 const unsigned N = static_cast<unsigned int>(strlen(StartString));
01216
01217 std::vector<std::string>::iterator it = argv.begin();
01218
01219 unsigned idx = 0;
01220 while( it != argv.end() ) {
01221
01222
01223 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
01224
01225
01226 result.push_back((*it).substr(N));
01227
01228
01229 std::vector<unsigned>::iterator nit = idx_nominus.begin();
01230 for(; nit != idx_nominus.end(); ++nit) {
01231 if( *nit == idx ) {
01232 idx_nominus.erase(nit);
01233 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
01234 break;
01235 }
01236 }
01237
01238
01239 argv.erase(it);
01240
01241
01242
01243
01244
01245 if( argv.empty() ) break;
01246 it = argv.begin();
01247 }
01248 cursor = 0;
01249 nominus_cursor = -1;
01250 return result;
01251 }
01252
01253 inline std::vector<int>
01254 GetPot::int_tails(const char* StartString, const int Default )
01255 {
01256 std::vector<int> result;
01257 const unsigned N = static_cast<unsigned int>(strlen(StartString));
01258
01259 std::vector<std::string>::iterator it = argv.begin();
01260
01261 unsigned idx = 0;
01262 while( it != argv.end() ) {
01263
01264
01265 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
01266
01267
01268 result.push_back(__convert_to_type((*it).substr(N), Default));
01269
01270
01271 std::vector<unsigned>::iterator nit = idx_nominus.begin();
01272 for(; nit != idx_nominus.end(); ++nit) {
01273 if( *nit == idx ) {
01274 idx_nominus.erase(nit);
01275 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
01276 break;
01277 }
01278 }
01279
01280
01281 argv.erase(it);
01282
01283
01284
01285
01286
01287 if( argv.empty() ) break;
01288 it = argv.begin();
01289 }
01290 cursor = 0;
01291 nominus_cursor = -1;
01292 return result;
01293 }
01294
01295 inline std::vector<double>
01296 GetPot::double_tails(const char* StartString,
01297 const double Default )
01298 {
01299 std::vector<double> result;
01300 const unsigned N = static_cast<unsigned int>(strlen(StartString));
01301
01302 std::vector<std::string>::iterator it = argv.begin();
01303 unsigned idx = 0;
01304 while( it != argv.end() ) {
01305
01306
01307 if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; }
01308
01309
01310 result.push_back(__convert_to_type((*it).substr(N), Default));
01311
01312
01313 std::vector<unsigned>::iterator nit = idx_nominus.begin();
01314 for(; nit != idx_nominus.end(); ++nit) {
01315 if( *nit == idx ) {
01316 idx_nominus.erase(nit);
01317 for(; nit != idx_nominus.end(); ++nit) *nit -= 1;
01318 break;
01319 }
01320 }
01321
01322
01323 argv.erase(it);
01324
01325
01326
01327
01328
01329 if( argv.empty() ) break;
01330 it = argv.begin();
01331 }
01332 cursor = 0;
01333 nominus_cursor = -1;
01334 return result;
01335 }
01336
01337
01338
01339
01340
01341 inline const char*
01342 GetPot::__match_starting_string(const char* StartString)
01343
01344
01345
01346 {
01347 const unsigned N = static_cast<unsigned int>(strlen(StartString));
01348 unsigned OldCursor = cursor;
01349
01350 if( OldCursor >= static_cast<unsigned int>(argv.size()) ) OldCursor = static_cast<unsigned int>(argv.size()) - 1;
01351 search_failed_f = true;
01352
01353
01354 unsigned c = cursor;
01355 for(; c < argv.size(); c++) {
01356 if( strncmp(StartString, argv[c].c_str(), N) == 0)
01357 { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
01358 }
01359
01360 if( ! search_loop_f ) return false;
01361
01362
01363 for(c = 1; c < OldCursor; c++) {
01364 if( strncmp(StartString, argv[c].c_str(), N) == 0)
01365 { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); }
01366 }
01367 return 0;
01368 }
01369
01371
01372
01373
01374 inline bool
01375 GetPot::options_contain(const char* FlagList) const
01376 {
01377
01378 std::string str;
01379 STRING_VECTOR::const_iterator it = argv.begin();
01380 for(; it != argv.end(); ++it) {
01381 str = __get_remaining_string(*it, prefix);
01382
01383 if( str.length() >= 2 && str[0] == '-' && str[1] != '-' )
01384 if( __check_flags(str, FlagList) ) return true;
01385 }
01386 return false;
01387 }
01388
01389 inline bool
01390 GetPot::argument_contains(unsigned Idx, const char* FlagList) const
01391 {
01392 if( Idx >= argv.size() ) return false;
01393
01394
01395
01396 ((GetPot*)this)->__record_argument_request(argv[Idx]);
01397
01398 if( prefix == "" )
01399
01400 return __check_flags(argv[Idx], FlagList);
01401
01402
01403
01404
01405 unsigned no_matches = 0;
01406 unsigned i=0;
01407 for(; i<argv.size(); ++i) {
01408 const std::string Remain = __get_remaining_string(argv[i], prefix);
01409 if( Remain != "") {
01410 no_matches += 1;
01411 if( no_matches == Idx)
01412 return __check_flags(Remain, FlagList);
01413 }
01414 }
01415
01416 return false;
01417 }
01418
01419 inline bool
01420 GetPot::__check_flags(const std::string& Str, const char* FlagList) const
01421 {
01422 const char* p=FlagList;
01423 for(; *p != '\0' ; p++)
01424 if( Str.find(*p) != std::string::npos ) return true;
01425 return false;
01426 }
01427
01429
01430 inline STRING_VECTOR
01431 GetPot::nominus_vector() const
01432
01433 {
01434 STRING_VECTOR nv;
01435 std::vector<unsigned>::const_iterator it = idx_nominus.begin();
01436 for(; it != idx_nominus.end(); ++it) {
01437 nv.push_back(argv[*it]);
01438
01439
01440
01441
01442 ((GetPot*)this)->__record_argument_request(argv[*it]);
01443 }
01444 return nv;
01445 }
01446
01447 inline std::string
01448 GetPot::next_nominus()
01449 {
01450 if( nominus_cursor < int(idx_nominus.size()) - 1 ) {
01451 const std::string Tmp = argv[idx_nominus[++nominus_cursor]];
01452
01453
01454 __record_argument_request(Tmp);
01455
01456
01457
01458 return Tmp;
01459 }
01460 return std::string("");
01461 }
01462
01464
01465
01466
01467 inline int
01468 GetPot::operator()(const char* VarName, int Default) const
01469 {
01470
01471 const variable* sv = __find_variable(VarName);
01472 if( sv == 0 ) return Default;
01473 return __convert_to_type(sv->original, Default);
01474 }
01475
01476 inline double
01477 GetPot::operator()(const char* VarName, const double& Default) const
01478 {
01479
01480 const variable* sv = __find_variable(VarName);
01481 if( sv == 0 ) return Default;
01482 return __convert_to_type(sv->original, Default);
01483 }
01484
01485 inline const std::string
01486 GetPot::operator()(const char* VarName, const char* Default) const
01487 {
01488
01489 const variable* sv = __find_variable(VarName);
01490 if( sv == 0 ) return Default;
01491
01492
01493 return sv->original;
01494 }
01495
01496 inline int
01497 GetPot::operator()(const char* VarName, int Default, unsigned Idx) const
01498 {
01499
01500 const variable* sv = __find_variable(VarName);
01501 if( sv == 0 ) return Default;
01502 const std::string* element = sv->get_element(Idx);
01503 if( element == 0 ) return Default;
01504 return __convert_to_type(*element, Default);
01505 }
01506
01507 inline double
01508 GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const
01509 {
01510
01511 const variable* sv = __find_variable(VarName);
01512 if( sv == 0 ) return Default;
01513 const std::string* element = sv->get_element(Idx);
01514 if( element == 0 ) return Default;
01515 return __convert_to_type(*element, Default);
01516 }
01517
01518 inline const std::string
01519 GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const
01520 {
01521
01522 const variable* sv = __find_variable(VarName);
01523 if( sv == 0 ) return Default;
01524 const std::string* element = sv->get_element(Idx);
01525 if( element == 0 ) return Default;
01526 return *element;
01527 }
01528
01529 inline void
01530 GetPot::__record_argument_request(const std::string& Name)
01531 {
01532 if( ! __request_recording_f ) return;
01533
01534
01535 _requested_arguments.push_back(Name);
01536
01537
01538 STRING_VECTOR STree = __get_section_tree(Name);
01539 victorate(std::string, STree, it)
01540 if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
01541 if( section.length() != 0 ) _requested_sections.push_back(*it);
01542 }
01543
01544 inline void
01545 GetPot::__record_variable_request(const std::string& Name)
01546 {
01547 if( ! __request_recording_f ) return;
01548
01549
01550 _requested_variables.push_back(Name);
01551
01552
01553 STRING_VECTOR STree = __get_section_tree(Name);
01554 victorate(std::string, STree, it)
01555 if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() )
01556 if( section.length() != 0 ) _requested_sections.push_back(*it);
01557 }
01558
01559
01560
01561 inline void
01562 GetPot::__set_variable(const char* VarName, const char* Value)
01563 {
01564 const GetPot::variable* Var = __find_variable(VarName);
01565 if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str()));
01566 else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str());
01567 }
01568
01569 inline void
01570 GetPot::set(const char* VarName, const char* Value, const bool Requested )
01571 {
01572 const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value);
01573 argv.push_back(Arg);
01574 __set_variable(VarName, Value);
01575
01576
01577
01578 if( Requested ) __record_variable_request(Arg);
01579 }
01580
01581 inline void
01582 GetPot::set(const char* VarName, const double& Value, const bool Requested )
01583 { __set_variable(VarName, __double2string(Value).c_str()); }
01584
01585 inline void
01586 GetPot::set(const char* VarName, const int Value, const bool Requested )
01587 { __set_variable(VarName, __int2string(Value).c_str()); }
01588
01589
01590 inline unsigned
01591 GetPot::vector_variable_size(const char* VarName) const
01592 {
01593 const variable* sv = __find_variable(VarName);
01594 if( sv == 0 ) return 0;
01595 return static_cast<unsigned int>(sv->value.size());
01596 }
01597
01598 inline STRING_VECTOR
01599 GetPot::get_variable_names() const
01600 {
01601 STRING_VECTOR result;
01602 std::vector<GetPot::variable>::const_iterator it = variables.begin();
01603 for(; it != variables.end(); ++it) {
01604 const std::string Tmp = __get_remaining_string((*it).name, prefix);
01605 if( Tmp != "" ) result.push_back(Tmp);
01606 }
01607 return result;
01608 }
01609
01610 inline STRING_VECTOR
01611 GetPot::get_section_names() const
01612 { return section_list; }
01613
01614 inline const GetPot::variable*
01615 GetPot::__find_variable(const char* VarName) const
01616 {
01617 const std::string Name = prefix + VarName;
01618
01619
01620 ((GetPot*)this)->__record_variable_request(Name);
01621
01622 std::vector<variable>::const_iterator it = variables.begin();
01623 for(; it != variables.end(); ++it) {
01624 if( (*it).name == Name ) return &(*it);
01625 }
01626 return 0;
01627 }
01628
01630
01631
01632
01633 inline int
01634 GetPot::print() const
01635 {
01636 std::cout << "argc = " << static_cast<unsigned int>(argv.size()) << std::endl;
01637 STRING_VECTOR::const_iterator it = argv.begin();
01638 for(; it != argv.end(); ++it)
01639 std::cout << *it << std::endl;
01640 std::cout << std::endl;
01641 return 1;
01642 }
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692 inline std::string
01693 GetPot::__DBE_expand_string(const std::string str)
01694 {
01695
01696
01697 std::string new_string = "";
01698 unsigned open_brackets = 0;
01699 unsigned first = 0;
01700 unsigned i = 0;
01701 for(; i<str.size(); ++i) {
01702 if( i < str.size() - 2 && str.substr(i, 2) == "${" ) {
01703 if( open_brackets == 0 ) first = i+2;
01704 open_brackets++;
01705 }
01706 else if( str[i] == '}' && open_brackets > 0) {
01707 open_brackets -= 1;
01708 if( open_brackets == 0 ) {
01709 const std::string Replacement = __DBE_expand(str.substr(first, i - first));
01710 new_string += Replacement;
01711 }
01712 }
01713 else if( open_brackets == 0 )
01714 new_string += str[i];
01715 }
01716 return new_string;
01717 }
01718
01719 inline STRING_VECTOR
01720 GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber)
01721
01722
01723 {
01724 std::string str = str_;
01725
01726
01727
01728 unsigned i=0;
01729
01730 for(; i < str.size(); ++i)
01731 if( ! isspace(str[i]) ) break;
01732
01733 STRING_VECTOR expr_list;
01734 unsigned open_brackets = 0;
01735 std::vector<unsigned> start_idx;
01736 unsigned start_new_string = i;
01737 unsigned l = static_cast<unsigned int>(str.size());
01738
01739
01740 while( i < l ) {
01741 const char letter = str[i];
01742
01743 if( isspace(letter) && open_brackets == 0) {
01744 expr_list.push_back(str.substr(start_new_string, i - start_new_string));
01745 bool no_breakout_f = true;
01746 for(++i; i < l ; ++i) {
01747 if( ! isspace(str[i]) )
01748 { no_breakout_f = false; start_new_string = i; break; }
01749 }
01750 if( no_breakout_f ) {
01751
01752 if( expr_list.size() < ExpectedNumber ) {
01753 const std::string pre_tmp("<< ${ }: missing arguments>>");
01754 STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
01755 expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
01756 }
01757 return expr_list;
01758 }
01759 }
01760
01761
01762 if( str.length() >= i+2 && str.substr(i, 2) == "${" ) {
01763 open_brackets++;
01764 start_idx.push_back(i+2);
01765 }
01766 else if( letter == '}' && open_brackets > 0) {
01767 int start = start_idx[start_idx.size()-1];
01768 start_idx.pop_back();
01769 const std::string Replacement = __DBE_expand(str.substr(start, i-start));
01770 if( start - 3 < (int)0)
01771 str = Replacement + str.substr(i+1);
01772 else
01773 str = str.substr(0, start-2) + Replacement + str.substr(i+1);
01774 l = static_cast<unsigned int>(str.size());
01775 i = start + static_cast<unsigned int>(Replacement.size()) - 3;
01776 open_brackets--;
01777 }
01778 ++i;
01779 }
01780
01781
01782 expr_list.push_back(str.substr(start_new_string, i-start_new_string));
01783
01784 if( expr_list.size() < ExpectedNumber ) {
01785 const std::string pre_tmp("<< ${ }: missing arguments>>");
01786 STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp);
01787 expr_list.insert(expr_list.end(), tmp.begin(), tmp.end());
01788 }
01789
01790 return expr_list;
01791 }
01792
01793 inline const GetPot::variable*
01794 GetPot::__DBE_get_variable(std::string VarName)
01795 {
01796 static GetPot::variable ev;
01797 std::string secure_Prefix = prefix;
01798
01799 prefix = section;
01800
01801 const GetPot::variable* var = __find_variable(VarName.c_str());
01802 if( var != 0 ) { prefix = secure_Prefix; return var; }
01803
01804
01805 prefix = "";
01806 var = __find_variable(VarName.c_str());
01807 if( var != 0 ) { prefix = secure_Prefix; return var; }
01808
01809 prefix = secure_Prefix;
01810
01811
01812 char* tmp = new char[VarName.length() + 25];
01813 #ifndef WIN32
01814 snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25),
01815 #else
01816 _snprintf(tmp, sizeof(char)*(VarName.length() + 25),
01817 #endif
01818 "<<${ } variable '%s' undefined>>", VarName.c_str());
01819 ev.name = "";
01820 ev.original = std::string(tmp);
01821 delete [] tmp;
01822 return &ev;
01823 }
01824
01825 inline std::string
01826 GetPot::__DBE_expand(const std::string expr)
01827 {
01828
01829 if( expr[0] == ':' )
01830 return expr.substr(1);
01831
01832
01833 else if( expr[0] == '&' ) {
01834 const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1);
01835
01836 STRING_VECTOR::const_iterator it = A.begin();
01837 std::string result = *it++;
01838 for(; it != A.end(); ++it) result += *it;
01839
01840 return result;
01841 }
01842
01843
01844 else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) {
01845 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3);
01846 std::string::size_type tmp = 0;
01847 const std::string::size_type L = A[1].length();
01848 while( (tmp = A[0].find(A[1])) != std::string::npos ) {
01849 A[0].replace(tmp, L, A[2]);
01850 }
01851 return A[0];
01852 }
01853
01854 else if( expr[0] == '+' ) {
01855 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
01856 STRING_VECTOR::const_iterator it = A.begin();
01857 double result = __convert_to_type(*it++, 0.0);
01858 for(; it != A.end(); ++it)
01859 result += __convert_to_type(*it, 0.0);
01860
01861 return __double2string(result);
01862 }
01863 else if( expr[0] == '-' ) {
01864 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
01865 STRING_VECTOR::const_iterator it = A.begin();
01866 double result = __convert_to_type(*it++, 0.0);
01867 for(; it != A.end(); ++it)
01868 result -= __convert_to_type(*it, 0.0);
01869
01870 return __double2string(result);
01871 }
01872 else if( expr[0] == '*' ) {
01873 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
01874 STRING_VECTOR::const_iterator it = A.begin();
01875 double result = __convert_to_type(*it++, 0.0);
01876 for(; it != A.end(); ++it)
01877 result *= __convert_to_type(*it, 0.0);
01878
01879 return __double2string(result);
01880 }
01881 else if( expr[0] == '/' ) {
01882
01883 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
01884 STRING_VECTOR::const_iterator it = A.begin();
01885 double result = __convert_to_type(*it++, 0.0);
01886 if( result == 0 ) return "0.0";
01887 for(; it != A.end(); ++it) {
01888 const double Q = __convert_to_type(*it, 0.0);
01889 if( Q == 0.0 ) return "0.0";
01890 result /= Q;
01891 }
01892 return __double2string(result);
01893 }
01894
01895
01896 else if( expr[0] == '^' ) {
01897 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
01898 STRING_VECTOR::const_iterator it = A.begin();
01899 double result = __convert_to_type(*it++, 0.0);
01900 for(; it != A.end(); ++it)
01901 result = pow(result, __convert_to_type(*it, 0.0));
01902 return __double2string(result);
01903 }
01904
01905
01906 else if( expr.length() >= 2 &&
01907 ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" ||
01908 expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) {
01909
01910 unsigned op = 0;
01911 enum { EQ, GEQ, LEQ, GT, LT };
01912 if ( expr.substr(0, 2) == "==" ) op = EQ;
01913 else if ( expr.substr(0, 2) == ">=" ) op = GEQ;
01914 else if ( expr.substr(0, 2) == "<=" ) op = LEQ;
01915 else if ( expr[0] == '>' ) op = GT;
01916 else op = LT;
01917
01918 STRING_VECTOR a;
01919 if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2);
01920 else a = __DBE_get_expr_list(expr.substr(2), 2);
01921
01922 std::string x_orig = a[0];
01923 double x = __convert_to_type(x_orig, 1e37);
01924 unsigned i = 1;
01925
01926 STRING_VECTOR::const_iterator y_orig = a.begin();
01927 for(y_orig++; y_orig != a.end(); y_orig++) {
01928 double y = __convert_to_type(*y_orig, 1e37);
01929
01930
01931 if ( x == 1e37 || y == 1e37 ) {
01932
01933 if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) ||
01934 (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) ||
01935 (op == LT && x_orig < *y_orig) )
01936 return __int2string(i);
01937 }
01938 else {
01939
01940 if( (op == EQ && x == y) || (op == GEQ && x >= y) ||
01941 (op == LEQ && x <= y) || (op == GT && x > y) ||
01942 (op == LT && x < y) )
01943 return __int2string(i);
01944 }
01945 ++i;
01946 }
01947
01948
01949 return "0";
01950 }
01951
01952 else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) {
01953 STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2);
01954 double x = __convert_to_type(a[0], 1e37);
01955
01956 if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1];
01957
01958
01959 return a[int(x+0.5)];
01960 }
01961
01962 else if( expr[0] == '?' ) {
01963 STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2);
01964 if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1];
01965 else if( a.size() > 2 ) return a[2];
01966 }
01967
01968 else if( expr[0] == '!' ) {
01969 const GetPot::variable* Var = __DBE_get_variable(expr.substr(1));
01970
01971 if( Var->name == "" ) return std::string(Var->original);
01972
01973 const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2);
01974 return A[0];
01975 }
01976
01977 else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) {
01978 const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2);
01979 double x = __convert_to_type(A[1], 1e37);
01980
01981
01982 if( x == 1e37 || x < 0 || x >= A[0].size() - 1)
01983 return "<<1st index out of range>>";
01984
01985 if( A.size() > 2 ) {
01986 double y = __convert_to_type(A[2], 1e37);
01987 if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x )
01988 return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5));
01989 else if( y == -1 )
01990 return A[0].substr(int(x+0.5));
01991 return "<<2nd index out of range>>";
01992 }
01993 else {
01994 char* tmp = new char[2];
01995 tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0';
01996 std::string result(tmp);
01997 delete [] tmp;
01998 return result;
01999 }
02000 }
02001
02002 else if( expr[0] == '@' ) {
02003 STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2);
02004 const GetPot::variable* Var = __DBE_get_variable(A[0]);
02005
02006 if( Var->name == "" ) {
02007
02008
02009 return std::string(Var->original);
02010 }
02011
02012 double x = __convert_to_type(A[1], 1e37);
02013
02014
02015 if (x == 1e37 || x < 0 || x >= Var->value.size() )
02016 return "<<1st index out of range>>";
02017
02018 if ( A.size() > 2) {
02019 double y = __convert_to_type(A[2], 1e37);
02020 int begin = int(x+0.5);
02021 int end = 0;
02022 if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x)
02023 end = int(y+1.5);
02024 else if( y == -1 )
02025 end = static_cast<unsigned int>(Var->value.size());
02026 else
02027 return "<<2nd index out of range>>";
02028
02029 std::string result = *(Var->get_element(begin));
02030 int i = begin+1;
02031 for(; i < end; ++i)
02032 result += std::string(" ") + *(Var->get_element(i));
02033 return result;
02034 }
02035 else
02036 return *(Var->get_element(int(x+0.5)));
02037 }
02038
02039 const STRING_VECTOR A = __DBE_get_expr_list(expr, 1);
02040 const GetPot::variable* B = __DBE_get_variable(A[0]);
02041
02042
02043
02044 if( B->name == "" ) return std::string(B->original);
02045
02046
02047 return B->original;
02048 }
02049
02050
02052
02053
02054
02055 inline bool
02056 GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const
02057 {
02058 victorate(std::string, VecStr, itk) {
02059 if( *itk == Str ) return true;
02060 }
02061 return false;
02062 }
02063
02064 inline STRING_VECTOR
02065 GetPot::unidentified_arguments(unsigned Number,
02066 const char* KnownArgument1, ...) const
02067 {
02068 STRING_VECTOR known_arguments;
02069
02070
02071 if( Number == 0 ) return STRING_VECTOR();
02072
02073 va_list ap;
02074 va_start(ap, KnownArgument1);
02075 known_arguments.push_back(std::string(KnownArgument1));
02076 unsigned i=1;
02077 for(; i<Number; ++i)
02078 known_arguments.push_back(std::string(va_arg(ap, char *)));
02079 va_end(ap);
02080
02081 return unidentified_arguments(known_arguments);
02082 }
02083
02084 inline STRING_VECTOR
02085 GetPot::unidentified_arguments() const
02086 { return unidentified_arguments(_requested_arguments); }
02087
02088 inline STRING_VECTOR
02089 GetPot::unidentified_arguments(const STRING_VECTOR& Knowns) const
02090 {
02091 STRING_VECTOR ufos;
02092 STRING_VECTOR::const_iterator it = argv.begin();
02093 ++it;
02094 for(; it != argv.end(); ++it) {
02095
02096 const std::string arg = __get_remaining_string(*it, prefix);
02097 if( arg == "" ) continue;
02098
02099
02100 if( __search_string_vector(Knowns, arg) == false)
02101 ufos.push_back(*it);
02102 }
02103 return ufos;
02104 }
02105
02106 inline STRING_VECTOR
02107 GetPot::unidentified_options(unsigned Number,
02108 const char* KnownOption1, ...) const
02109 {
02110 STRING_VECTOR known_options;
02111
02112
02113 if( Number == 0 ) return STRING_VECTOR();
02114
02115 va_list ap;
02116 va_start(ap, KnownOption1);
02117 known_options.push_back(std::string(KnownOption1));
02118 unsigned i=1;
02119 for(; i<Number; ++i)
02120 known_options.push_back(std::string(va_arg(ap, char *)));
02121 va_end(ap);
02122
02123 return unidentified_options(known_options);
02124 }
02125
02126 inline STRING_VECTOR
02127 GetPot::unidentified_options() const
02128 {
02129
02130
02131
02132
02133
02134
02135 STRING_VECTOR option_list;
02136 victorate(std::string, _requested_arguments, it) {
02137 const std::string arg = *it;
02138 if( arg.length() == 0 ) continue;
02139 if( arg[0] == '-' ) option_list.push_back(arg);
02140 }
02141 return unidentified_options(option_list);
02142 }
02143
02144 inline STRING_VECTOR
02145 GetPot::unidentified_options(const STRING_VECTOR& Knowns) const
02146 {
02147 STRING_VECTOR ufos;
02148 STRING_VECTOR::const_iterator it = argv.begin();
02149 ++it;
02150 for(; it != argv.end(); ++it) {
02151
02152 const std::string arg = __get_remaining_string(*it, prefix);
02153 if( arg == "" ) continue;
02154
02155
02156 if( arg.length() < 1 || arg[0] != '-' ) continue;
02157
02158 if( __search_string_vector(Knowns, arg) == false)
02159 ufos.push_back(*it);
02160 }
02161
02162 return ufos;
02163 }
02164
02165 inline std::string
02166 GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const
02167
02168
02169
02170
02171 {
02172 std::string ufos;
02173 STRING_VECTOR known_arguments;
02174 std::string KFL(KnownFlagList);
02175
02176
02177 if( ArgumentNumber == -1 ) {
02178 STRING_VECTOR::const_iterator it = argv.begin();
02179 ++it;
02180 for(; it != argv.end(); ++it) {
02181
02182 const std::string arg = __get_remaining_string(*it, prefix);
02183 if( arg == "" ) continue;
02184
02185
02186 if ( arg.length() < 2 ) continue;
02187 else if( arg[0] != '-' ) continue;
02188 else if( arg[1] == '-' ) continue;
02189
02190
02191 const char* p=arg.c_str();
02192 p++;
02193 for(; *p != '\0' ; p++)
02194 if( KFL.find(*p) == std::string::npos ) ufos += *p;
02195 }
02196 }
02197
02198 else {
02199
02200 int no_matches = 0;
02201 unsigned i=1;
02202 for(; i<argv.size(); ++i) {
02203 const std::string Remain = __get_remaining_string(argv[i], prefix);
02204 if( Remain != "") {
02205 no_matches++;
02206 if( no_matches == ArgumentNumber) {
02207
02208
02209 const char* p = Remain.c_str();
02210 p++;
02211 for(; *p != '\0' ; p++)
02212 if( KFL.find(*p) == std::string::npos ) ufos += *p;
02213 return ufos;
02214 }
02215 }
02216 }
02217 }
02218 return ufos;
02219 }
02220
02221 inline STRING_VECTOR
02222 GetPot::unidentified_variables(unsigned Number,
02223 const char* KnownVariable1, ...) const
02224 {
02225 STRING_VECTOR known_variables;
02226
02227
02228 if( Number == 0 ) return STRING_VECTOR();
02229
02230 va_list ap;
02231 va_start(ap, KnownVariable1);
02232 known_variables.push_back(std::string(KnownVariable1));
02233 unsigned i=1;
02234 for(; i<Number; ++i)
02235 known_variables.push_back(std::string(va_arg(ap, char *)));
02236 va_end(ap);
02237
02238 return unidentified_variables(known_variables);
02239 }
02240
02241 inline STRING_VECTOR
02242 GetPot::unidentified_variables(const STRING_VECTOR& Knowns) const
02243 {
02244 STRING_VECTOR ufos;
02245
02246 victorate(GetPot::variable, variables, it) {
02247
02248 const std::string var_name = __get_remaining_string((*it).name, prefix);
02249 if( var_name == "" ) continue;
02250
02251
02252 if( __search_string_vector(Knowns, var_name) == false)
02253 ufos.push_back((*it).name);
02254 }
02255 return ufos;
02256 }
02257
02258 inline STRING_VECTOR
02259 GetPot::unidentified_variables() const
02260 { return unidentified_variables(_requested_variables); }
02261
02262
02263 inline STRING_VECTOR
02264 GetPot::unidentified_sections(unsigned Number,
02265 const char* KnownSection1, ...) const
02266 {
02267 STRING_VECTOR known_sections;
02268
02269
02270 if( Number == 0 ) return STRING_VECTOR();
02271
02272 va_list ap;
02273 va_start(ap, KnownSection1);
02274 known_sections.push_back(std::string(KnownSection1));
02275 unsigned i=1;
02276 for(; i<Number; ++i) {
02277 std::string tmp = std::string(va_arg(ap, char *));
02278 if( tmp.length() == 0 ) continue;
02279 if( tmp[tmp.length()-1] != '/' ) tmp += '/';
02280 known_sections.push_back(tmp);
02281 }
02282 va_end(ap);
02283
02284 return unidentified_sections(known_sections);
02285 }
02286
02287 inline STRING_VECTOR
02288 GetPot::unidentified_sections() const
02289 { return unidentified_sections(_requested_sections); }
02290
02291 inline STRING_VECTOR
02292 GetPot::unidentified_sections(const STRING_VECTOR& Knowns) const
02293 {
02294 STRING_VECTOR ufos;
02295
02296 victorate(std::string, section_list, it) {
02297
02298 const std::string sec_name = __get_remaining_string(*it, prefix);
02299 if( sec_name == "" ) continue;
02300
02301
02302 if( __search_string_vector(Knowns, sec_name) == false )
02303 ufos.push_back(*it);
02304 }
02305
02306 return ufos;
02307 }
02308
02309
02310 inline STRING_VECTOR
02311 GetPot::unidentified_nominuses(unsigned Number, const char* Known, ...) const
02312 {
02313 STRING_VECTOR known_nominuses;
02314
02315
02316 if( Number == 0 ) return STRING_VECTOR();
02317
02318 va_list ap;
02319 va_start(ap, Known);
02320 known_nominuses.push_back(std::string(Known));
02321 unsigned i=1;
02322 for(; i<Number; ++i) {
02323 std::string tmp = std::string(va_arg(ap, char *));
02324 if( tmp.length() == 0 ) continue;
02325 known_nominuses.push_back(tmp);
02326 }
02327 va_end(ap);
02328
02329 return unidentified_nominuses(known_nominuses);
02330 }
02331
02332 inline STRING_VECTOR
02333 GetPot::unidentified_nominuses() const {
02334
02335
02336
02337
02338
02339
02340
02341 return unidentified_nominuses(_requested_arguments);
02342 }
02343
02344 inline STRING_VECTOR
02345 GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const
02346 {
02347 STRING_VECTOR ufos;
02348
02349
02350 STRING_VECTOR::const_iterator it = argv.begin();
02351 ++it;
02352 for(; it != argv.end(); ++it) {
02353
02354 const std::string arg = __get_remaining_string(*it, prefix);
02355 if( arg == "" ) continue;
02356
02357 if( arg.length() < 1 ) continue;
02358
02359 if( arg[0] == '-' ) continue;
02360
02361 if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue;
02362
02363 bool continue_f = false;
02364 unsigned i=0;
02365 for(; i<arg.length() ; ++i)
02366 if( arg[i] == '=' ) { continue_f = true; break; }
02367 if( continue_f ) continue;
02368
02369
02370 if( __search_string_vector(Knowns, arg) == false )
02371 ufos.push_back(*it);
02372 }
02373 return ufos;
02374 }
02375
02376
02378
02379
02380
02381 inline
02382 GetPot::variable::variable()
02383 {}
02384
02385 inline
02386 GetPot::variable::variable(const variable& That)
02387 {
02388 #ifdef WIN32
02389 operator=(That);
02390 #else
02391 GetPot::variable::operator=(That);
02392 #endif
02393 }
02394
02395
02396 inline
02397 GetPot::variable::variable(const char* Name, const char* Value, const char* FieldSeparator)
02398 : name(Name)
02399 {
02400
02401 take(Value, FieldSeparator);
02402 }
02403
02404 inline const std::string*
02405 GetPot::variable::get_element(unsigned Idx) const
02406 { if( Idx >= value.size() ) return 0; else return &(value[Idx]); }
02407
02408 inline void
02409 GetPot::variable::take(const char* Value, const char* FieldSeparator)
02410 {
02411 using namespace std;
02412
02413 original = std::string(Value);
02414
02415
02416
02417 char* spt = 0;
02418
02419 char* copy = new char[strlen(Value)+1];
02420 strcpy(copy, Value);
02421 char* follow_token = strtok_r(copy, FieldSeparator, &spt);
02422 if( value.size() != 0 ) value.erase(value.begin(), value.end());
02423 while(follow_token != 0) {
02424 value.push_back(std::string(follow_token));
02425 follow_token = strtok_r(NULL, FieldSeparator, &spt);
02426 }
02427
02428 delete [] copy;
02429 }
02430
02431 inline
02432 GetPot::variable::~variable()
02433 {}
02434
02435 inline GetPot::variable&
02436 GetPot::variable::operator=(const GetPot::variable& That)
02437 {
02438 if( &That != this) {
02439 name = That.name;
02440 value = That.value;
02441 original = That.original;
02442 }
02443 return *this;
02444 }
02445
02446 #undef victorate
02447
02448
02449 #endif // __include_guard_GETPOT_H__
02450
02451
02452
02453