From 14c7f45cdae826f88dc539c8c38dd95caf305731 Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Fri, 11 Jul 2008 15:50:46 +0000 Subject: Add zook's ZenUtils to SVN git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18010 a1c6a512-1295-4272-9138-f99709370657 --- .../libraries/getpot-c++-1.1.17/getpot/GetPot | 2433 +++++++++++++++++++ .../libraries/getpot-c++-1.1.17/getpot/LPGL.txt | 504 ++++ .../libraries/getpot-c++-1.1.17/getpot/README | 50 + .../libraries/getpot-c++-1.1.17/getpot/getpot.hpp | 2435 ++++++++++++++++++++ 4 files changed, 5422 insertions(+) create mode 100755 utils/zenutils/libraries/getpot-c++-1.1.17/getpot/GetPot create mode 100755 utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt create mode 100755 utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README create mode 100755 utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp (limited to 'utils/zenutils/libraries/getpot-c++-1.1.17') 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 @@ +// -*- c++ -*- +// GetPot Version $$Version$$ $$Date$$ +// +// WEBSITE: http://getpot.sourceforge.net +// +// NOTE: The LPGL License for this library is only valid in case that +// it is not used for the production or development of applications +// dedicated to military industry. This is what the author calls +// the 'unofficial peace version of the LPGL'. +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// (C) 2001-2005 Frank R. Schaefer +//========================================================================== + +#ifndef __include_guard_GETPOT_H__ +#define __include_guard_GETPOT_H__ + +#if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC) +#define strtok_r(a, b, c) strtok(a, b) +#endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC + +extern "C" { +// leave the 'extern C' to make it 100% sure to work - +// expecially with older distributions of header files. +#ifndef WIN32 +// this is necessary (depending on OS) +#include +#endif +#include +#include +#include +} +#include +#include +#include +#include + +#include +#include // not every compiler distribution includes +// // with + +typedef std::vector STRING_VECTOR; + +#define victorate(TYPE, VARIABLE, ITERATOR) \ + std::vector::const_iterator ITERATOR = (VARIABLE).begin(); \ + for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++) + + +class GetPot { + //-------- + inline void __basic_initialization(); +public: + // (*) constructors, destructor, assignment operator ----------------------- + inline GetPot(); + inline GetPot(const GetPot&); + inline GetPot(const int argc_, char** argv_, + const char* FieldSeparator=0x0); + inline GetPot(const char* FileName, + const char* CommentStart=0x0, const char* CommentEnd=0x0, + const char* FieldSeparator=0x0); + inline ~GetPot(); + inline GetPot& operator=(const GetPot&); + + + // (*) absorbing contents of another GetPot object + inline void absorb(const GetPot& That); + // -- for ufo detection: recording requested arguments, options etc. + inline void clear_requests(); + inline void disable_request_recording() { __request_recording_f = false; } + inline void enable_request_recording() { __request_recording_f = true; } + + // (*) direct access to command line arguments ----------------------------- + inline const std::string operator[](unsigned Idx) const; + inline int get(unsigned Idx, int Default) const; + inline double get(unsigned Idx, const double& Default) const; + inline const std::string get(unsigned Idx, const char* Default) const; + inline unsigned size() const; + + // (*) flags --------------------------------------------------------------- + inline bool options_contain(const char* FlagList) const; + inline bool argument_contains(unsigned Idx, const char* FlagList) const; + + // (*) variables ----------------------------------------------------------- + // -- scalar values + inline int operator()(const char* VarName, int Default) const; + inline double operator()(const char* VarName, const double& Default) const; + inline const std::string operator()(const char* VarName, const char* Default) const; + // -- vectors + inline int operator()(const char* VarName, int Default, unsigned Idx) const; + inline double operator()(const char* VarName, const double& Default, unsigned Idx) const; + inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const; + + // -- setting variables + // i) from outside of GetPot (considering prefix etc.) + // ii) from inside, use '__set_variable()' below + inline void set(const char* VarName, const char* Value, const bool Requested = true); + inline void set(const char* VarName, const double& Value, const bool Requested = true); + inline void set(const char* VarName, const int Value, const bool Requested = true); + + inline unsigned vector_variable_size(const char* VarName) const; + inline STRING_VECTOR get_variable_names() const; + inline STRING_VECTOR get_section_names() const; + + + // (*) cursor oriented functions ------------------------------------------- + inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); } + inline bool search_failed() const { return search_failed_f; } + + // -- enable/disable search for an option in loop + inline void disable_loop() { search_loop_f = false; } + inline void enable_loop() { search_loop_f = true; } + + // -- reset cursor to position '1' + inline void reset_cursor(); + inline void init_multiple_occurrence(); + + // -- search for a certain option and set cursor to position + inline bool search(const char* option); + inline bool search(unsigned No, const char* P, ...); + // -- get argument at cursor++ + inline int next(int Default); + inline double next(const double& Default); + inline const std::string next(const char* Default); + // -- search for option and get argument at cursor++ + inline int follow(int Default, const char* Option); + inline double follow(const double& Default, const char* Option); + inline const std::string follow(const char* Default, const char* Option); + // -- search for one of the given options and get argument that follows it + inline int follow(int Default, unsigned No, const char* Option, ...); + inline double follow(const double& Default, unsigned No, const char* Option, ...); + inline const std::string follow(const char* Default, unsigned No, const char* Option, ...); + // -- lists of nominuses following an option + inline std::vector nominus_followers(const char* Option); + inline std::vector nominus_followers(unsigned No, ...); + + // -- directly followed arguments + inline int direct_follow(int Default, const char* Option); + inline double direct_follow(const double& Default, const char* Option); + inline const std::string direct_follow(const char* Default, const char* Option); + + inline std::vector string_tails(const char* StartString); + inline std::vector int_tails(const char* StartString, const int Default = 1); + inline std::vector double_tails(const char* StartString, const double Default = 1.0); + + // (*) nominus arguments --------------------------------------------------- + inline STRING_VECTOR nominus_vector() const; + inline unsigned nominus_size() const { return static_cast(idx_nominus.size()); } + inline std::string next_nominus(); + + // (*) unidentified flying objects ----------------------------------------- + inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_arguments() const; + + inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_options() const; + + inline std::string unidentified_flags(const char* Known, + int ArgumentNumber /* =-1 */) const; + + inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_variables() const; + + inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_sections() const; + + inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_nominuses() const; + + // (*) output -------------------------------------------------------------- + inline int print() const; + +private: + // (*) Type Declaration ---------------------------------------------------- + struct variable { + //----------- + // Variable to be specified on the command line or in input files. + // (i.e. of the form var='12 312 341') + + // -- constructors, destructors, assignment operator + variable(); + variable(const variable&); + variable(const char* Name, const char* Value, const char* FieldSeparator); + ~variable(); + variable& operator=(const variable& That); + + void take(const char* Value, const char* FieldSeparator); + + // -- get a specific element in the string vector + // (return 0 if not present) + const std::string* get_element(unsigned Idx) const; + + // -- data memebers + std::string name; // identifier of variable + STRING_VECTOR value; // value of variable stored in vector + std::string original; // value of variable as given on command line + }; + + // (*) member variables -------------------------------------------------------------- + std::string prefix; // prefix automatically added in queries + std::string section; // (for dollar bracket parsing) + STRING_VECTOR section_list; // list of all parsed sections + // -- argument vector + STRING_VECTOR argv; // vector of command line arguments stored as strings + unsigned cursor; // cursor for argv + bool search_loop_f; // shall search start at beginning after + // // reaching end of arg array ? + bool search_failed_f; // flag indicating a failed search() operation + // // (e.g. next() functions react with 'missed') + + // -- nominus vector + int nominus_cursor; // cursor for nominus_pointers + std::vector idx_nominus; // indecies of 'no minus' arguments + + // -- variables + // (arguments of the form "variable=value") + std::vector variables; + + // -- comment delimiters + std::string _comment_start; + std::string _comment_end; + + // -- field separator (separating elements of a vector) + std::string _field_separator; + + // -- some functions return a char pointer to a temporarily existing string + // this container makes them 'available' until the getpot object is destroyed. + std::vector __internal_string_container; + + // -- keeping track about arguments that are requested, so that the UFO detection + // can be simplified + STRING_VECTOR _requested_arguments; + STRING_VECTOR _requested_variables; + STRING_VECTOR _requested_sections; + + bool __request_recording_f; // speed: request recording can be turned off + + // -- if an argument is requested record it and the 'tag' the section branch to which + // it belongs. Caution: both functions mark the sections as 'tagged'. + void __record_argument_request(const std::string& Arg); + void __record_variable_request(const std::string& Arg); + + // (*) helper functions ---------------------------------------------------- + // set variable from inside GetPot (no prefix considered) + inline void __set_variable(const char* VarName, const char* Value); + + // -- produce three basic data vectors: + // - argument vector + // - nominus vector + // - variable dictionary + inline void __parse_argument_vector(const STRING_VECTOR& ARGV); + + // -- helpers for argument list processing + // * search for a variable in 'variables' array + inline const variable* __find_variable(const char*) const; + // * support finding directly followed arguments + inline const char* __match_starting_string(const char* StartString); + // * support search for flags in a specific argument + inline bool __check_flags(const std::string& Str, const char* FlagList) const; + // * type conversion if possible + inline int __convert_to_type(const std::string& String, int Default) const; + inline double __convert_to_type(const std::string& String, double Default) const; + // * prefix extraction + const std::string __get_remaining_string(const std::string& String, + const std::string& Start) const; + // * search for a specific string + inline bool __search_string_vector(const STRING_VECTOR& Vec, + const std::string& Str) const; + + // -- helpers to parse input file + // create an argument vector based on data found in an input file, i.e.: + // 1) delete comments (in between '_comment_start' '_comment_end') + // 2) contract assignment expressions, such as + // my-variable = '007 J. B.' + // into + // my-variable='007 J. B.' + // 3) interprete sections like '[../my-section]' etc. + inline void __skip_whitespace(std::istream& istr); + inline const std::string __get_next_token(std::istream& istr); + inline const std::string __get_string(std::istream& istr); + inline const std::string __get_until_closing_bracket(std::istream& istr); + + inline STRING_VECTOR __read_in_stream(std::istream& istr); + inline STRING_VECTOR __read_in_file(const char* FileName); + inline std::string __process_section_label(const std::string& Section, + STRING_VECTOR& section_stack); + + // -- dollar bracket expressions + std::string __DBE_expand_string(const std::string str); + std::string __DBE_expand(const std::string str); + const GetPot::variable* __DBE_get_variable(const std::string str); + STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber); + + std::string __double2string(const double& Value) const { + // -- converts a double integer into a string + char* tmp = new char[128]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*128, "%e", Value); +#else + _snprintf(tmp, sizeof(char)*128, "%e", Value); +#endif + std::string result(tmp); + delete [] tmp; + return result; + } + + std::string __int2string(const int& Value) const { + // -- converts an integer into a string + char* tmp = new char[128]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*128, "%i", Value); +#else + _snprintf(tmp, sizeof(char)*128, "%i", Value); +#endif + std::string result(tmp); + delete [] tmp; + return result; + } + + STRING_VECTOR __get_section_tree(const std::string& FullPath) { + // -- cuts a variable name into a tree of sub-sections. this is requested for recording + // requested sections when dealing with 'ufo' detection. + STRING_VECTOR result; + const char* Start = FullPath.c_str(); + + for(char *p = (char*)Start; *p ; p++) { + if( *p == '/' ) { + *p = '\0'; // set terminating zero for convinience + const std::string Section = Start; + *p = '/'; // reset slash at place + result.push_back(Section); + } + } + + return result; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (*) constructors, destructor, assignment operator +//............................................................................. +// +inline void +GetPot::__basic_initialization() +{ + cursor = 0; nominus_cursor = -1; + search_failed_f = true; search_loop_f = true; + prefix = ""; section = ""; + + // automatic request recording for later ufo detection + __request_recording_f = true; + + // comment start and end strings + _comment_start = std::string("#"); + _comment_end = std::string("\n"); + + // default: separate vector elements by whitespaces + _field_separator = " \t\n"; +} + +inline +GetPot::GetPot() +{ + __basic_initialization(); + + STRING_VECTOR _apriori_argv; + _apriori_argv.push_back(std::string("Empty")); + __parse_argument_vector(_apriori_argv); +} + +inline +GetPot::GetPot(const int argc_, char ** argv_, + const char* FieldSeparator /* =0x0 */) + // leave 'char**' non-const to honor less capable compilers ... +{ + // TODO: Ponder over the problem when the argument list is of size = 0. + // This is 'sabotage', but it can still occur if the user specifies + // it himself. + assert(argc_ >= 1); + __basic_initialization(); + + // if specified -> overwrite default string + if( FieldSeparator ) _field_separator = std::string(FieldSeparator); + + // -- make an internal copy of the argument list: + STRING_VECTOR _apriori_argv; + // -- for the sake of clarity: we do want to include the first argument in the argument vector ! + // it will not be a nominus argument, though. This gives us a minimun vector size of one + // which facilitates error checking in many functions. Also the user will be able to + // retrieve the name of his application by "get[0]" + _apriori_argv.push_back(std::string(argv_[0])); + int i=1; + for(; i overwrite default strings + if( CommentStart ) _comment_start = std::string(CommentStart); + if( CommentEnd ) _comment_end = std::string(CommentEnd); + if( FieldSeparator ) _field_separator = FieldSeparator; + + STRING_VECTOR _apriori_argv; + // -- file name is element of argument vector, however, it is not parsed for + // variable assignments or nominuses. + _apriori_argv.push_back(std::string(FileName)); + + STRING_VECTOR args = __read_in_file(FileName); + _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end()); + __parse_argument_vector(_apriori_argv); +} + +inline +GetPot::GetPot(const GetPot& That) +{ GetPot::operator=(That); } + +inline +GetPot::~GetPot() +{ + // may be some return strings had to be created, delete now ! + victorate(char*, __internal_string_container, it) + delete [] *it; +} + +inline GetPot& +GetPot::operator=(const GetPot& That) +{ + if (&That == this) return *this; + + _comment_start = That._comment_start; + _comment_end = That._comment_end; + argv = That.argv; + variables = That.variables; + prefix = That.prefix; + + cursor = That.cursor; + nominus_cursor = That.nominus_cursor; + search_failed_f = That.search_failed_f; + + idx_nominus = That.idx_nominus; + search_loop_f = That.search_loop_f; + + return *this; +} + + +inline void +GetPot::absorb(const GetPot& That) +{ + if (&That == this) return; + + STRING_VECTOR __tmp(That.argv); + + __tmp.erase(__tmp.begin()); + + __parse_argument_vector(__tmp); +} + +inline void +GetPot::clear_requests() +{ + _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end()); + _requested_variables.erase(_requested_variables.begin(), _requested_variables.end()); + _requested_sections.erase(_requested_sections.begin(), _requested_sections.end()); +} + +inline void +GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV) +{ + if( ARGV.size() == 0 ) return; + + // build internal databases: + // 1) array with no-minus arguments (usually used as filenames) + // 2) variable assignments: + // 'variable name' '=' number | string + STRING_VECTOR section_stack; + STRING_VECTOR::const_iterator it = ARGV.begin(); + + + section = ""; + + // -- do not parse the first argument, so that it is not interpreted a s a nominus or so. + argv.push_back(*it); + ++it; + + // -- loop over remaining arguments + unsigned i=1; + for(; it != ARGV.end(); ++it, ++i) { + std::string arg = *it; + + if( arg.length() == 0 ) continue; + + // -- [section] labels + if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) { + + // (*) sections are considered 'requested arguments' + if( __request_recording_f ) _requested_arguments.push_back(arg); + + const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2)); + section = __process_section_label(Name, section_stack); + // new section --> append to list of sections + if( find(section_list.begin(), section_list.end(), section) == section_list.end() ) + if( section.length() != 0 ) section_list.push_back(section); + argv.push_back(arg); + } + else { + arg = section + __DBE_expand_string(arg); + argv.push_back(arg); + } + + // -- separate array for nominus arguments + if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i)); + + // -- variables: does arg contain a '=' operator ? + const char* p = arg.c_str(); + for(; *p ; p++) { + if( *p == '=' ) { + // (*) record for later ufo detection + // arguments carriying variables are always treated as 'requested' arguments. + // as a whole! That is 'x=4712' is considered a requested argument. + // + // unrequested variables have to be detected with the ufo-variable + // detection routine. + if( __request_recording_f ) _requested_arguments.push_back(arg); + + // set terminating 'zero' to treat first part as single string + // => arg (from start to 'p') = Name of variable + // p+1 (until terminating zero) = value of variable + char* o = (char*)p++; + *o = '\0'; // set temporary terminating zero + // __set_variable(...) + // calls __find_variable(...) which registers the search + // temporarily disable this + const bool tmp = __request_recording_f; + __request_recording_f = false; + __set_variable(arg.c_str(), p); // v-name = c_str() bis 'p', value = rest + __request_recording_f = tmp; + *o = '='; // reset the original '=' + break; + } + } + } +} + + +inline STRING_VECTOR +GetPot::__read_in_file(const char* FileName) +{ + std::ifstream i(FileName); + if( ! i ) return STRING_VECTOR(); + // argv[0] == the filename of the file that was read in + return __read_in_stream(i); +} + +inline STRING_VECTOR +GetPot::__read_in_stream(std::istream& istr) +{ + STRING_VECTOR brute_tokens; + while(istr) { + __skip_whitespace(istr); + const std::string Token = __get_next_token(istr); + if( Token.length() == 0 || Token[0] == EOF) break; + brute_tokens.push_back(Token); + } + + // -- reduce expressions of token1'='token2 to a single + // string 'token1=token2' + // -- copy everything into 'argv' + // -- arguments preceded by something like '[' name ']' (section) + // produce a second copy of each argument with a prefix '[name]argument' + unsigned i1 = 0; + unsigned i2 = 1; + unsigned i3 = 2; + + STRING_VECTOR arglist; + while( i1 < brute_tokens.size() ) { + const std::string& SRef = brute_tokens[i1]; + // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef' + // note: java.lang.String: substring(a,b) = from a to b-1 + // C++ string: substr(a,b) = from a to a + b + if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) { + if( i3 >= brute_tokens.size() ) + arglist.push_back(brute_tokens[i1] + brute_tokens[i2]); + else + arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]); + i1 = i3+1; i2 = i3+2; i3 = i3+3; + continue; + } + else { + arglist.push_back(SRef); + i1=i2; i2=i3; i3++; + } + } + return arglist; +} + +inline void +GetPot::__skip_whitespace(std::istream& istr) + // find next non-whitespace while deleting comments +{ + int tmp = istr.get(); + do { + // -- search a non whitespace + while( isspace(tmp) ) { + tmp = istr.get(); + if( ! istr ) return; + } + + // -- look if characters match the comment starter string + const std::istream::pos_type Pos = istr.tellg(); + unsigned i=0; + for(; i<_comment_start.length() ; ++i) { + if( tmp != _comment_start[i] ) { + istr.seekg(Pos); + // -- one step more backwards, since 'tmp' already at non-whitespace + istr.unget(); + return; + } + tmp = istr.get(); + if( ! istr ) { istr.unget(); return; } + } + // 'tmp' contains last character of _comment_starter + + // -- comment starter found -> search for comment ender + unsigned match_no=0; + while(1+1 == 2) { + tmp = istr.get(); + if( ! istr ) { istr.unget(); return; } + + if( tmp == _comment_end[match_no] ) { + match_no++; + if( match_no == _comment_end.length() ) { + istr.unget(); + break; // shuffle more whitespace, end of comment found + } + } + else + match_no = 0; + } + + tmp = istr.get(); + + } while( istr ); + istr.unget(); +} + +inline const std::string +GetPot::__get_next_token(std::istream& istr) + // get next concatinates string token. consider quotes that embrace + // whitespaces +{ + std::string token; + int tmp = 0; + int last_letter = 0; + while(1+1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF + || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) { + return token; + } + else if( tmp == '\'' && last_letter != '\\' ) { + // QUOTES: un-backslashed quotes => it's a string + token += __get_string(istr); + continue; + } + else if( tmp == '{' && last_letter == '$') { + token += '{' + __get_until_closing_bracket(istr); + continue; + } + else if( tmp == '$' && last_letter == '\\') { + token += tmp; tmp = 0; // so that last_letter will become = 0, not '$'; + continue; + } + else if( tmp == '\\' && last_letter != '\\') + continue; // don't append un-backslashed backslashes + token += tmp; + } +} + +inline const std::string +GetPot::__get_string(std::istream& istr) + // parse input until next matching ' +{ + std::string str; + int tmp = 0; + int last_letter = 0; + while(1 + 1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF) return str; + // un-backslashed quotes => it's the end of the string + else if( tmp == '\'' && last_letter != '\\') return str; + else if( tmp == '\\' && last_letter != '\\') continue; // don't append + + str += tmp; + } +} + +inline const std::string +GetPot::__get_until_closing_bracket(std::istream& istr) + // parse input until next matching } +{ + std::string str = ""; + int tmp = 0; + int last_letter = 0; + int brackets = 1; + while(1 + 1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF) return str; + else if( tmp == '{' && last_letter == '$') brackets += 1; + else if( tmp == '}') { + brackets -= 1; + // un-backslashed brackets => it's the end of the string + if( brackets == 0) return str + '}'; + else if( tmp == '\\' && last_letter != '\\') + continue; // do not append an unbackslashed backslash + } + str += tmp; + } +} + +inline std::string +GetPot::__process_section_label(const std::string& Section, + STRING_VECTOR& section_stack) +{ + std::string sname = Section; + // 1) subsection of actual section ('./' prefix) + if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) { + sname = sname.substr(2); + } + // 2) subsection of parent section ('../' prefix) + else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) { + do { + if( section_stack.end() != section_stack.begin() ) + section_stack.pop_back(); + sname = sname.substr(3); + } while( sname.substr(0, 3) == "../" ); + } + // 3) subsection of the root-section + else { + section_stack.erase(section_stack.begin(), section_stack.end()); + // [] => back to root section + } + + if( sname != "" ) { + // parse section name for 'slashes' + unsigned i=0; + while( i < sname.length() ) { + if( sname[i] == '/' ) { + section_stack.push_back(sname.substr(0,i)); + if( i+1 < sname.length()-1 ) + sname = sname.substr(i+1); + i = 0; + } + else + ++i; + } + section_stack.push_back(sname); + } + std::string section = ""; + if( section_stack.size() != 0 ) { + victorate(std::string, section_stack, it) + section += *it + "/"; + } + return section; +} + + +// convert string to DOUBLE, if not possible return Default +inline double +GetPot::__convert_to_type(const std::string& String, double Default) const +{ + double tmp; + if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default; + return tmp; +} + +// convert string to INT, if not possible return Default +inline int +GetPot::__convert_to_type(const std::string& String, int Default) const +{ + // NOTE: intermediate results may be floating points, so that the string + // may look like 2.0e1 (i.e. float format) => use float conversion + // in any case. + return (int)__convert_to_type(String, (double)Default); +} + +////////////////////////////////////////////////////////////////////////////// +// (*) cursor oriented functions +//............................................................................. +inline const std::string +GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const + // Checks if 'String' begins with 'Start' and returns the remaining String. + // Returns None if String does not begin with Start. +{ + if( Start == "" ) return String; + // note: java.lang.String: substring(a,b) = from a to b-1 + // C++ string: substr(a,b) = from a to a + b + if( String.find(Start) == 0 ) return String.substr(Start.length()); + else return ""; +} + +// -- search for a certain argument and set cursor to position +inline bool +GetPot::search(const char* Option) +{ + unsigned OldCursor = cursor; + const std::string SearchTerm = prefix + Option; + + // (*) record requested arguments for later ufo detection + __record_argument_request(SearchTerm); + + if( OldCursor >= argv.size() ) OldCursor = static_cast(argv.size()) - 1; + search_failed_f = true; + + // (*) first loop from cursor position until end + unsigned c = cursor; + for(; c < argv.size(); c++) { + if( argv[c] == SearchTerm ) + { cursor = c; search_failed_f = false; return true; } + } + if( ! search_loop_f ) return false; + + // (*) second loop from 0 to old cursor position + for(c = 1; c < OldCursor; c++) { + if( argv[c] == SearchTerm ) + { cursor = c; search_failed_f = false; return true; } + } + // in case nothing is found the cursor stays where it was + return false; +} + + +inline bool +GetPot::search(unsigned No, const char* P, ...) +{ + // (*) recording the requested arguments happens in subroutine 'search' + if( No == 0 ) return false; + + // search for the first argument + if( search(P) == true ) return true; + + // start interpreting variable argument list + va_list ap; + va_start(ap, P); + unsigned i = 1; + for(; i < No; ++i) { + char* Opt = va_arg(ap, char *); + if( search(Opt) == true ) break; + } + + if( i < No ) { + ++i; + // loop was left before end of array --> hit but + // make sure that the rest of the search terms is marked + // as requested. + for(; i < No; ++i) { + char* Opt = va_arg(ap, char *); + // (*) record requested arguments for later ufo detection + __record_argument_request(Opt); + } + va_end(ap); + return true; + } + + va_end(ap); + // loop was left normally --> no hit + return false; +} + +inline void +GetPot::reset_cursor() +{ search_failed_f = false; cursor = 0; } + +inline void +GetPot::init_multiple_occurrence() +{ disable_loop(); reset_cursor(); } +/////////////////////////////////////////////////////////////////////////////// +// (*) direct access to command line arguments +//............................................................................. +// +inline const std::string +GetPot::operator[](unsigned idx) const +{ return idx < argv.size() ? argv[idx] : ""; } + +inline int +GetPot::get(unsigned Idx, int Default) const +{ + if( Idx >= argv.size() ) return Default; + return __convert_to_type(argv[Idx], Default); +} + +inline double +GetPot::get(unsigned Idx, const double& Default) const +{ + if( Idx >= argv.size() ) return Default; + return __convert_to_type(argv[Idx], Default); +} + +inline const std::string +GetPot::get(unsigned Idx, const char* Default) const +{ + if( Idx >= argv.size() ) return Default; + else return argv[Idx]; +} + +inline unsigned +GetPot::size() const +{ return static_cast(argv.size()); } + + +// -- next() function group +inline int +GetPot::next(int Default) +{ + if( search_failed_f ) return Default; + cursor++; + if( cursor >= argv.size() ) + { cursor = static_cast(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + const std::string Remain = __get_remaining_string(argv[cursor], prefix); + + return Remain != "" ? __convert_to_type(Remain, Default) : Default; +} + +inline double +GetPot::next(const double& Default) +{ + if( search_failed_f ) return Default; + cursor++; + + if( cursor >= argv.size() ) + { cursor = static_cast(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + std::string Remain = __get_remaining_string(argv[cursor], prefix); + + return Remain != "" ? __convert_to_type(Remain, Default) : Default; +} + +inline const std::string +GetPot::next(const char* Default) +{ + if( search_failed_f ) return Default; + cursor++; + + if( cursor >= argv.size() ) + { cursor = static_cast(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + const std::string Remain = __get_remaining_string(argv[cursor], prefix); + + if( Remain == "" ) return Default; + + + // (*) function returns a pointer to a char array (inside Remain) + // this array will be deleted, though after this function call. + // To ensure propper functioning, create a copy inside *this + // object and only delete it, when *this is deleted. + char* result = new char[Remain.length()+1]; + strncpy(result, Remain.c_str(), Remain.length()+1); + + // store the created string internally, delete if when object deleted + __internal_string_container.push_back(result); + + return result; +} + +// -- follow() function group +// distinct option to be searched for +inline int +GetPot::follow(int Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +inline double +GetPot::follow(const double& Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +inline const std::string +GetPot::follow(const char* Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +// -- second follow() function group +// multiple option to be searched for +inline int +GetPot::follow(int Default, unsigned No, const char* P, ...) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( No == 0 ) return Default; + if( search(P) == true ) return next(Default); + + va_list ap; + va_start(ap, P); + unsigned i=1; + for(; i +GetPot::nominus_followers(const char* Option) +{ + std::vector result_list; + if( search(Option) == false ) return result_list; + while( 1 + 1 == 2 ) { + ++cursor; + if( cursor >= argv.size() ) { + cursor = argv.size() - 1; + return result_list; + } + if( argv[cursor].length() >= 1 ) { + if( argv[cursor][0] == '-' ) { + return result_list; + } + // -- record for later ufo-detection + __record_argument_request(argv[cursor]); + // -- append to the result list + result_list.push_back(argv[cursor]); + } + } +} + +inline std::vector +GetPot::nominus_followers(unsigned No, ...) +{ + std::vector result_list; + // (*) record requested of argument is entirely handled in 'search()' + // and 'nominus_followers()' + if( No == 0 ) return result_list; + + va_list ap; + va_start(ap, No); + for(unsigned i=0; i tmp = nominus_followers(Option); + result_list.insert(result_list.end(), tmp.begin(), tmp.end()); + + // std::cerr << "option = '" << Option << "'" << std::endl; + // std::cerr << "length = " << tmp.size() << std::endl; + // std::cerr << "new result list = <"; + // for(std::vector::const_iterator it = result_list.begin(); + // it != result_list.end(); ++it) + // std::cerr << *it << ", "; + // std::cerr << ">\n"; + } + va_end(ap); + return result_list; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) directly connected options +//............................................................................. +// +inline int +GetPot::direct_follow(int Default, const char* Option) +{ + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0x0 ) return Default; + + // (*) record requested of argument for later ufo-detection + __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast(argv.size()) ) cursor = static_cast(argv.size()); + return __convert_to_type(FollowStr, Default); +} + +inline double +GetPot::direct_follow(const double& Default, const char* Option) +{ + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0 ) return Default; + + // (*) record requested of argument for later ufo-detection + __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast(argv.size()) ) cursor = static_cast(argv.size()); + return __convert_to_type(FollowStr, Default); +} + +inline const std::string +GetPot::direct_follow(const char* Default, const char* Option) +{ + if( search_failed_f ) return Default; + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0 ) return Default; + + // (*) record requested of argument for later ufo-detection + if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast(argv.size()) ) cursor = static_cast(argv.size()); + return std::string(FollowStr); +} + +inline std::vector +GetPot::string_tails(const char* StartString) +{ + std::vector result; + const unsigned N = static_cast(strlen(StartString)); + + std::vector::iterator it = argv.begin(); + + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back((*it).substr(N)); + + // adapt the nominus vector + std::vector::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + +inline std::vector +GetPot::int_tails(const char* StartString, const int Default /* = -1 */) +{ + std::vector result; + const unsigned N = static_cast(strlen(StartString)); + + std::vector::iterator it = argv.begin(); + + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back(__convert_to_type((*it).substr(N), Default)); + + // adapt the nominus vector + std::vector::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + +inline std::vector +GetPot::double_tails(const char* StartString, + const double Default /* = -1.0 */) +{ + std::vector result; + const unsigned N = static_cast(strlen(StartString)); + + std::vector::iterator it = argv.begin(); + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back(__convert_to_type((*it).substr(N), Default)); + + // adapt the nominus vector + std::vector::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + + + + + +inline const char* +GetPot::__match_starting_string(const char* StartString) + // pointer to the place where the string after + // the match inside the found argument starts. + // 0 no argument matches the starting string. +{ + const unsigned N = static_cast(strlen(StartString)); + unsigned OldCursor = cursor; + + if( OldCursor >= static_cast(argv.size()) ) OldCursor = static_cast(argv.size()) - 1; + search_failed_f = true; + + // (*) first loop from cursor position until end + unsigned c = cursor; + for(; c < argv.size(); c++) { + if( strncmp(StartString, argv[c].c_str(), N) == 0) + { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); } + } + + if( ! search_loop_f ) return false; + + // (*) second loop from 0 to old cursor position + for(c = 1; c < OldCursor; c++) { + if( strncmp(StartString, argv[c].c_str(), N) == 0) + { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); } + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) search for flags +//............................................................................. +// +inline bool +GetPot::options_contain(const char* FlagList) const +{ + // go through all arguments that start with a '-' (but not '--') + std::string str; + STRING_VECTOR::const_iterator it = argv.begin(); + for(; it != argv.end(); ++it) { + str = __get_remaining_string(*it, prefix); + + if( str.length() >= 2 && str[0] == '-' && str[1] != '-' ) + if( __check_flags(str, FlagList) ) return true; + } + return false; +} + +inline bool +GetPot::argument_contains(unsigned Idx, const char* FlagList) const +{ + if( Idx >= argv.size() ) return false; + + // (*) record requested of argument for later ufo-detection + // an argument that is checked for flags is considered to be 'requested' + ((GetPot*)this)->__record_argument_request(argv[Idx]); + + if( prefix == "" ) + // search argument for any flag in flag list + return __check_flags(argv[Idx], FlagList); + + // if a prefix is set, then the argument index is the index + // inside the 'namespace' + // => only check list of arguments that start with prefix + unsigned no_matches = 0; + unsigned i=0; + for(; i::const_iterator it = idx_nominus.begin(); + for(; it != idx_nominus.end(); ++it) { + nv.push_back(argv[*it]); + + // (*) record for later ufo-detection + // when a nominus vector is requested, the entire set of nominus arguments are + // tagged as 'requested' + ((GetPot*)this)->__record_argument_request(argv[*it]); + } + return nv; +} + +inline std::string +GetPot::next_nominus() +{ + if( nominus_cursor < int(idx_nominus.size()) - 1 ) { + const std::string Tmp = argv[idx_nominus[++nominus_cursor]]; + + // (*) record for later ufo-detection + __record_argument_request(Tmp); + + // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer + // to something that does no longer exist. + return Tmp; + } + return std::string(""); +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) variables +//............................................................................. +// +inline int +GetPot::operator()(const char* VarName, int Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + return __convert_to_type(sv->original, Default); +} + +inline double +GetPot::operator()(const char* VarName, const double& Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + return __convert_to_type(sv->original, Default); +} + +inline const std::string +GetPot::operator()(const char* VarName, const char* Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + // -- returning a c_str() pointer is OK here, since the variable remains existant, + // while 'sv' of course is delete at the end of the function. + return sv->original; +} + +inline int +GetPot::operator()(const char* VarName, int Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return __convert_to_type(*element, Default); +} + +inline double +GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return __convert_to_type(*element, Default); +} + +inline const std::string +GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return *element; +} + +inline void +GetPot::__record_argument_request(const std::string& Name) +{ + if( ! __request_recording_f ) return; + + // (*) record requested variable for later ufo detection + _requested_arguments.push_back(Name); + + // (*) record considered section for ufo detection + STRING_VECTOR STree = __get_section_tree(Name); + victorate(std::string, STree, it) + if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) + if( section.length() != 0 ) _requested_sections.push_back(*it); +} + +inline void +GetPot::__record_variable_request(const std::string& Name) +{ + if( ! __request_recording_f ) return; + + // (*) record requested variable for later ufo detection + _requested_variables.push_back(Name); + + // (*) record considered section for ufo detection + STRING_VECTOR STree = __get_section_tree(Name); + victorate(std::string, STree, it) + if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) + if( section.length() != 0 ) _requested_sections.push_back(*it); +} + +// (*) following functions are to be used from 'outside', after getpot has parsed its +// arguments => append an argument in the argument vector that reflects the addition +inline void +GetPot::__set_variable(const char* VarName, const char* Value) +{ + const GetPot::variable* Var = __find_variable(VarName); + if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str())); + else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str()); +} + +inline void +GetPot::set(const char* VarName, const char* Value, const bool Requested /* = yes */) +{ + const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value); + argv.push_back(Arg); + __set_variable(VarName, Value); + + // if user does not specify the variable as 'not being requested' it will be + // considered amongst the requested variables + if( Requested ) __record_variable_request(Arg); +} + +inline void +GetPot::set(const char* VarName, const double& Value, const bool Requested /* = yes */) +{ __set_variable(VarName, __double2string(Value).c_str()); } + +inline void +GetPot::set(const char* VarName, const int Value, const bool Requested /* = yes */) +{ __set_variable(VarName, __int2string(Value).c_str()); } + + +inline unsigned +GetPot::vector_variable_size(const char* VarName) const +{ + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return 0; + return static_cast(sv->value.size()); +} + +inline STRING_VECTOR +GetPot::get_variable_names() const +{ + STRING_VECTOR result; + std::vector::const_iterator it = variables.begin(); + for(; it != variables.end(); ++it) { + const std::string Tmp = __get_remaining_string((*it).name, prefix); + if( Tmp != "" ) result.push_back(Tmp); + } + return result; +} + +inline STRING_VECTOR +GetPot::get_section_names() const +{ return section_list; } + +inline const GetPot::variable* +GetPot::__find_variable(const char* VarName) const +{ + const std::string Name = prefix + VarName; + + // (*) record requested variable for later ufo detection + ((GetPot*)this)->__record_variable_request(Name); + + std::vector::const_iterator it = variables.begin(); + for(; it != variables.end(); ++it) { + if( (*it).name == Name ) return &(*it); + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) ouput (basically for debugging reasons +//............................................................................. +// +inline int +GetPot::print() const +{ + std::cout << "argc = " << static_cast(argv.size()) << std::endl; + STRING_VECTOR::const_iterator it = argv.begin(); + for(; it != argv.end(); ++it) + std::cout << *it << std::endl; + std::cout << std::endl; + return 1; +} + +// (*) dollar bracket expressions (DBEs) ------------------------------------ +// +// 1) Entry Function: __DBE_expand_string() +// Takes a string such as +// +// "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}" +// +// calls __DBE_expand() for each of the expressions +// +// ${+ ${x} ${y}} +// ${& ${section} ${subsection}} +// ${Title} +// +// and returns the string +// +// "4711 Subject-1.01: Mit den Clowns kamen die Schwaene" +// +// assuming that +// x = "4699" +// y = "12" +// section = "1." +// subsection = "01" +// title = "Mit den Clowns kamen die Schwaene" +// +// 2) __DBE_expand(): +// +// checks for the command, i.e. the 'sign' that follows '${' +// divides the argument list into sub-expressions using +// __DBE_get_expr_list() +// +// ${+ ${x} ${y}} -> "${x}" "${y}" +// ${& ${section} ${subsection}} -> "${section}" "${subsection}" +// ${Title} -> Nothing, variable expansion +// +// 3) __DBE_expression_list(): +// +// builds a vector of unbracketed whitespace separated strings, i.e. +// +// " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}" +// +// is split into a vector +// +// [0] ${Number}.a +// [1] ${: Das Marmorbild} +// [2] AB-${& Author= ${Eichendorf}}-1870 +// +// Each sub-expression is expanded using expand(). +//--------------------------------------------------------------------------- +inline std::string +GetPot::__DBE_expand_string(const std::string str) +{ + // Parses for closing operators '${ }' and expands them letting + // white spaces and other letters as they are. + std::string new_string = ""; + unsigned open_brackets = 0; + unsigned first = 0; + unsigned i = 0; + for(; i 0) { + open_brackets -= 1; + if( open_brackets == 0 ) { + const std::string Replacement = __DBE_expand(str.substr(first, i - first)); + new_string += Replacement; + } + } + else if( open_brackets == 0 ) + new_string += str[i]; + } + return new_string; +} + +inline STRING_VECTOR +GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber) + // ensures that the resulting vector has the expected number + // of arguments, but they may contain an error message +{ + std::string str = str_; + // Separates expressions by non-bracketed whitespaces, expands them + // and puts them into a list. + + unsigned i=0; + // (1) eat initial whitespaces + for(; i < str.size(); ++i) + if( ! isspace(str[i]) ) break; + + STRING_VECTOR expr_list; + unsigned open_brackets = 0; + std::vector start_idx; + unsigned start_new_string = i; + unsigned l = static_cast(str.size()); + + // (2) search for ${ } expressions ... + while( i < l ) { + const char letter = str[i]; + // whitespace -> end of expression + if( isspace(letter) && open_brackets == 0) { + expr_list.push_back(str.substr(start_new_string, i - start_new_string)); + bool no_breakout_f = true; + for(++i; i < l ; ++i) { + if( ! isspace(str[i]) ) + { no_breakout_f = false; start_new_string = i; break; } + } + if( no_breakout_f ) { + // end of expression list + if( expr_list.size() < ExpectedNumber ) { + const std::string pre_tmp("<< ${ }: missing arguments>>"); + STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp); + expr_list.insert(expr_list.end(), tmp.begin(), tmp.end()); + } + return expr_list; + } + } + + // dollar-bracket expression + if( str.length() >= i+2 && str.substr(i, 2) == "${" ) { + open_brackets++; + start_idx.push_back(i+2); + } + else if( letter == '}' && open_brackets > 0) { + int start = start_idx[start_idx.size()-1]; + start_idx.pop_back(); + const std::string Replacement = __DBE_expand(str.substr(start, i-start)); + if( start - 3 < (int)0) + str = Replacement + str.substr(i+1); + else + str = str.substr(0, start-2) + Replacement + str.substr(i+1); + l = static_cast(str.size()); + i = start + static_cast(Replacement.size()) - 3; + open_brackets--; + } + ++i; + } + + // end of expression list + expr_list.push_back(str.substr(start_new_string, i-start_new_string)); + + if( expr_list.size() < ExpectedNumber ) { + const std::string pre_tmp("<< ${ }: missing arguments>>"); + STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp); + expr_list.insert(expr_list.end(), tmp.begin(), tmp.end()); + } + + return expr_list; +} + +inline const GetPot::variable* +GetPot::__DBE_get_variable(std::string VarName) +{ + static GetPot::variable ev; + std::string secure_Prefix = prefix; + + prefix = section; + // (1) first search in currently active section + const GetPot::variable* var = __find_variable(VarName.c_str()); + if( var != 0 ) { prefix = secure_Prefix; return var; } + + // (2) search in root name space + prefix = ""; + var = __find_variable(VarName.c_str()); + if( var != 0 ) { prefix = secure_Prefix; return var; } + + prefix = secure_Prefix; + + // error occured => variable name == "" + char* tmp = new char[VarName.length() + 25]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25), +#else + _snprintf(tmp, sizeof(char)*(VarName.length() + 25), +#endif + "<<${ } variable '%s' undefined>>", VarName.c_str()); + ev.name = ""; + ev.original = std::string(tmp); + delete [] tmp; + return &ev; +} + +inline std::string +GetPot::__DBE_expand(const std::string expr) +{ + // ${: } pure text + if( expr[0] == ':' ) + return expr.substr(1); + + // ${& expr expr ... } text concatination + else if( expr[0] == '&' ) { + const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1); + + STRING_VECTOR::const_iterator it = A.begin(); + std::string result = *it++; + for(; it != A.end(); ++it) result += *it; + + return result; + } + + // ${<-> expr expr expr} text replacement + else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3); + std::string::size_type tmp = 0; + const std::string::size_type L = A[1].length(); + while( (tmp = A[0].find(A[1])) != std::string::npos ) { + A[0].replace(tmp, L, A[2]); + } + return A[0]; + } + // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions + else if( expr[0] == '+' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result += __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '-' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result -= __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '*' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result *= __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '/' ) { + + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + if( result == 0 ) return "0.0"; + for(; it != A.end(); ++it) { + const double Q = __convert_to_type(*it, 0.0); + if( Q == 0.0 ) return "0.0"; + result /= Q; + } + return __double2string(result); + } + + // ${^ ... } power expressions + else if( expr[0] == '^' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result = pow(result, __convert_to_type(*it, 0.0)); + return __double2string(result); + } + + // ${== } ${<= } ${>= } comparisons (return the number of the first 'match' + else if( expr.length() >= 2 && + ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" || + expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) { + // differentiate between two and one sign operators + unsigned op = 0; + enum { EQ, GEQ, LEQ, GT, LT }; + if ( expr.substr(0, 2) == "==" ) op = EQ; + else if ( expr.substr(0, 2) == ">=" ) op = GEQ; + else if ( expr.substr(0, 2) == "<=" ) op = LEQ; + else if ( expr[0] == '>' ) op = GT; + else /* "<" */ op = LT; + + STRING_VECTOR a; + if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2); + else a = __DBE_get_expr_list(expr.substr(2), 2); + + std::string x_orig = a[0]; + double x = __convert_to_type(x_orig, 1e37); + unsigned i = 1; + + STRING_VECTOR::const_iterator y_orig = a.begin(); + for(y_orig++; y_orig != a.end(); y_orig++) { + double y = __convert_to_type(*y_orig, 1e37); + + // set the strings as reference if one wasn't a number + if ( x == 1e37 || y == 1e37 ) { + // it's a string comparison + if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) || + (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) || + (op == LT && x_orig < *y_orig) ) + return __int2string(i); + } + else { + // it's a number comparison + if( (op == EQ && x == y) || (op == GEQ && x >= y) || + (op == LEQ && x <= y) || (op == GT && x > y) || + (op == LT && x < y) ) + return __int2string(i); + } + ++i; + } + + // nothing fulfills the condition => return 0 + return "0"; + } + // ${?? expr expr} select + else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) { + STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2); + double x = __convert_to_type(a[0], 1e37); + // last element is always the default argument + if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1]; + + // round x to closest integer + return a[int(x+0.5)]; + } + // ${? expr expr expr} if then else conditions + else if( expr[0] == '?' ) { + STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2); + if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1]; + else if( a.size() > 2 ) return a[2]; + } + // ${! expr} maxro expansion + else if( expr[0] == '!' ) { + const GetPot::variable* Var = __DBE_get_variable(expr.substr(1)); + // error + if( Var->name == "" ) return std::string(Var->original); + + const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2); + return A[0]; + } + // ${@: } - string subscription + else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) { + const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2); + double x = __convert_to_type(A[1], 1e37); + + // last element is always the default argument + if( x == 1e37 || x < 0 || x >= A[0].size() - 1) + return "<<1st index out of range>>"; + + if( A.size() > 2 ) { + double y = __convert_to_type(A[2], 1e37); + if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x ) + return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5)); + else if( y == -1 ) + return A[0].substr(int(x+0.5)); + return "<<2nd index out of range>>"; + } + else { + char* tmp = new char[2]; + tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0'; + std::string result(tmp); + delete [] tmp; + return result; + } + } + // ${@ } - vector subscription + else if( expr[0] == '@' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + const GetPot::variable* Var = __DBE_get_variable(A[0]); + // error + if( Var->name == "" ) { + // make a copy of the string if an error occured + // (since the error variable is a static variable inside get_variable()) + return std::string(Var->original); + } + + double x = __convert_to_type(A[1], 1e37); + + // last element is always the default argument + if (x == 1e37 || x < 0 || x >= Var->value.size() ) + return "<<1st index out of range>>"; + + if ( A.size() > 2) { + double y = __convert_to_type(A[2], 1e37); + int begin = int(x+0.5); + int end = 0; + if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x) + end = int(y+1.5); + else if( y == -1 ) + end = static_cast(Var->value.size()); + else + return "<<2nd index out of range>>"; + + std::string result = *(Var->get_element(begin)); + int i = begin+1; + for(; i < end; ++i) + result += std::string(" ") + *(Var->get_element(i)); + return result; + } + else + return *(Var->get_element(int(x+0.5))); + } + + const STRING_VECTOR A = __DBE_get_expr_list(expr, 1); + const GetPot::variable* B = __DBE_get_variable(A[0]); + + // make a copy of the string if an error occured + // (since the error variable is a static variable inside get_variable()) + if( B->name == "" ) return std::string(B->original); + // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces + // with: else return B->original (thanks)) + return B->original; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) unidentified flying objects +//............................................................................. +// +inline bool +GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const +{ + victorate(std::string, VecStr, itk) { + if( *itk == Str ) return true; + } + return false; +} + +inline STRING_VECTOR +GetPot::unidentified_arguments(unsigned Number, + const char* KnownArgument1, ...) const +{ + STRING_VECTOR known_arguments; + + // (1) create a vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownArgument1); + known_arguments.push_back(std::string(KnownArgument1)); + unsigned i=1; + for(; i it is not necessary to separate requested options from the list + STRING_VECTOR option_list; + victorate(std::string, _requested_arguments, it) { + const std::string arg = *it; + if( arg.length() == 0 ) continue; + if( arg[0] == '-' ) option_list.push_back(arg); + } + return unidentified_options(option_list); +} + +inline STRING_VECTOR +GetPot::unidentified_options(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // is argument really an option (starting with '-') ? + if( arg.length() < 1 || arg[0] != '-' ) continue; + + if( __search_string_vector(Knowns, arg) == false) + ufos.push_back(*it); + } + + return ufos; +} + +inline std::string +GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const + // Two modes: + // ArgumentNumber >= 0 check specific argument + // ArgumentNumber == -1 check all options starting with one '-' + // for flags +{ + std::string ufos; + STRING_VECTOR known_arguments; + std::string KFL(KnownFlagList); + + // (2) iteration over '-' arguments (options) + if( ArgumentNumber == -1 ) { + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // -- does arguments start with '-' (but not '--') + if ( arg.length() < 2 ) continue; + else if( arg[0] != '-' ) continue; + else if( arg[1] == '-' ) continue; + + // -- check out if flags inside option are contained in KnownFlagList + const char* p=arg.c_str(); + p++; // skip starting minus + for(; *p != '\0' ; p++) + if( KFL.find(*p) == std::string::npos ) ufos += *p; + } + } + // (1) check specific argument + else { + // -- only check arguments that start with prefix + int no_matches = 0; + unsigned i=1; + for(; i check it for flags + const char* p = Remain.c_str(); + p++; // skip starting minus + for(; *p != '\0' ; p++) + if( KFL.find(*p) == std::string::npos ) ufos += *p; + return ufos; + } + } + } + } + return ufos; +} + +inline STRING_VECTOR +GetPot::unidentified_variables(unsigned Number, + const char* KnownVariable1, ...) const +{ + STRING_VECTOR known_variables; + + // create vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownVariable1); + known_variables.push_back(std::string(KnownVariable1)); + unsigned i=1; + for(; i it is not necessary to separate requested nominus from the list + + return unidentified_nominuses(_requested_arguments); +} + +inline STRING_VECTOR +GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + + // (2) iterate over all arguments + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- check if nominus part of prefix + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + if( arg.length() < 1 ) continue; + // option ? --> not a nomius + if( arg[0] == '-' ) continue; + // section ? --> not a real nominus + if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue; + // variable definition ? --> not a real nominus + bool continue_f = false; + unsigned i=0; + for(; i= value.size() ) return 0; else return &(value[Idx]); } + +inline void +GetPot::variable::take(const char* Value, const char* FieldSeparator) +{ + original = std::string(Value); + + // separate string by white space delimiters using 'strtok' + // thread safe usage of strtok (no static members) + char* spt = 0; + // make a copy of the 'Value' + char* copy = new char[strlen(Value)+1]; + strcpy(copy, Value); + char* follow_token = strtok_r(copy, FieldSeparator, &spt); + if( value.size() != 0 ) value.erase(value.begin(), value.end()); + while(follow_token != 0) { + value.push_back(std::string(follow_token)); + follow_token = strtok_r(NULL, FieldSeparator, &spt); + } + + delete [] copy; +} + +inline +GetPot::variable::~variable() +{} + +inline GetPot::variable& +GetPot::variable::operator=(const GetPot::variable& That) +{ + if( &That != this) { + name = That.name; + value = That.value; + original = That.original; + } + return *this; +} + +#undef victorate + + +#endif // __include_guard_GETPOT_H__ + + + diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt new file mode 100755 index 0000000000..b1e3f5a263 --- /dev/null +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/LPGL.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README new file mode 100755 index 0000000000..3d55352a6b --- /dev/null +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/README @@ -0,0 +1,50 @@ +GetPot - C++: +-------------- + +Attention: This version contains a couple of beautiful +---------- new features, that are not documented yet. + + E.g.: -- automated ufo detection + -- arbitrary comment delimiters + -- arbitrary vector field separators + -- tails, i.e. easy access to all tails + of options such as '-L' or '-I'. + + Please, refere to the example/ directory + for usage descriptions. + +This is the C++ version of the popular GetPot library for +command line and input file parsing. The documentation +can be downloaded at: + + http://getpot.sourceforge.net + +The files in the 'examples' directory should be enough, though, to be +able to use this library. It is fairly easy to use. + +Installation: +------------- + +In order to install GetPot, simply copy the file 'GetPot' +somewhere where your c++ compiler can find it. + +The 'file emacs-getpot-mode.el' contains some lines of +emacs-lisp code. If you append these lines to your .emacs +file, it will highlight your 'getpot' - input files. + +Bug reports, Feature requests: +------------------------------ + +Please, notify me in case there are any bugs or you think +that there should be more features in the library. +My email address is: + +fschaef@users.sourceforge.net + +Thanks for using this software. +Enjoy ! + + +Juli 2005, +Frank R. Schaefer + diff --git a/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp new file mode 100755 index 0000000000..fe820c91a2 --- /dev/null +++ b/utils/zenutils/libraries/getpot-c++-1.1.17/getpot/getpot.hpp @@ -0,0 +1,2435 @@ +// -*- c++ -*- +// GetPot Version $$Version$$ $$Date$$ +// +// WEBSITE: http://getpot.sourceforge.net +// +// NOTE: The LPGL License for this library is only valid in case that +// it is not used for the production or development of applications +// dedicated to military industry. This is what the author calls +// the 'unofficial peace version of the LPGL'. +// +// This library is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 2.1 of the +// License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA +// +// (C) 2001-2005 Frank R. Schaefer +//========================================================================== + +#ifndef __include_guard_GETPOT_H__ +#define __include_guard_GETPOT_H__ + +#if defined(WIN32) || defined(SOLARIS_RAW) || (__GNUC__ == 2) || defined(__HP_aCC) +#define strtok_r(a, b, c) strtok(a, b) +#endif // WINDOWS or SOLARIS or gcc 2.* or HP aCC + +extern "C" { +// leave the 'extern C' to make it 100% sure to work - +// expecially with older distributions of header files. +#ifndef WIN32 +// this is necessary (depending on OS) +#include +#endif +#include +#include +#include +} +#include +#include +#include +#include + +#include +#include // not every compiler distribution includes +// // with + +typedef std::vector STRING_VECTOR; + +#define victorate(TYPE, VARIABLE, ITERATOR) \ + std::vector::const_iterator ITERATOR = (VARIABLE).begin(); \ + for(; (ITERATOR) != (VARIABLE).end(); (ITERATOR)++) + + +class GetPot { + //-------- + inline void __basic_initialization(); +public: + // (*) constructors, destructor, assignment operator ----------------------- + inline GetPot(); + inline GetPot(const GetPot&); + inline GetPot(const int argc_, char** argv_, + const char* FieldSeparator=0x0); + inline GetPot(const char* FileName, + const char* CommentStart=0x0, const char* CommentEnd=0x0, + const char* FieldSeparator=0x0); + inline ~GetPot(); + inline GetPot& operator=(const GetPot&); + + + // (*) absorbing contents of another GetPot object + inline void absorb(const GetPot& That); + // -- for ufo detection: recording requested arguments, options etc. + inline void clear_requests(); + inline void disable_request_recording() { __request_recording_f = false; } + inline void enable_request_recording() { __request_recording_f = true; } + + // (*) direct access to command line arguments ----------------------------- + inline const std::string operator[](unsigned Idx) const; + inline int get(unsigned Idx, int Default) const; + inline double get(unsigned Idx, const double& Default) const; + inline const std::string get(unsigned Idx, const char* Default) const; + inline unsigned size() const; + + // (*) flags --------------------------------------------------------------- + inline bool options_contain(const char* FlagList) const; + inline bool argument_contains(unsigned Idx, const char* FlagList) const; + + // (*) variables ----------------------------------------------------------- + // -- scalar values + inline int operator()(const char* VarName, int Default) const; + inline double operator()(const char* VarName, const double& Default) const; + inline const std::string operator()(const char* VarName, const char* Default) const; + // -- vectors + inline int operator()(const char* VarName, int Default, unsigned Idx) const; + inline double operator()(const char* VarName, const double& Default, unsigned Idx) const; + inline const std::string operator()(const char* VarName, const char* Default, unsigned Idx) const; + + // -- setting variables + // i) from outside of GetPot (considering prefix etc.) + // ii) from inside, use '__set_variable()' below + inline void set(const char* VarName, const char* Value, const bool Requested = true); + inline void set(const char* VarName, const double& Value, const bool Requested = true); + inline void set(const char* VarName, const int Value, const bool Requested = true); + + inline unsigned vector_variable_size(const char* VarName) const; + inline STRING_VECTOR get_variable_names() const; + inline STRING_VECTOR get_section_names() const; + + + // (*) cursor oriented functions ------------------------------------------- + inline void set_prefix(const char* Prefix) { prefix = std::string(Prefix); } + inline bool search_failed() const { return search_failed_f; } + + // -- enable/disable search for an option in loop + inline void disable_loop() { search_loop_f = false; } + inline void enable_loop() { search_loop_f = true; } + + // -- reset cursor to position '1' + inline void reset_cursor(); + inline void init_multiple_occurrence(); + + // -- search for a certain option and set cursor to position + inline bool search(const char* option); + inline bool search(unsigned No, const char* P, ...); + // -- get argument at cursor++ + inline int next(int Default); + inline double next(const double& Default); + inline const std::string next(const char* Default); + // -- search for option and get argument at cursor++ + inline int follow(int Default, const char* Option); + inline double follow(const double& Default, const char* Option); + inline const std::string follow(const char* Default, const char* Option); + // -- search for one of the given options and get argument that follows it + inline int follow(int Default, unsigned No, const char* Option, ...); + inline double follow(const double& Default, unsigned No, const char* Option, ...); + inline const std::string follow(const char* Default, unsigned No, const char* Option, ...); + // -- lists of nominuses following an option + inline std::vector nominus_followers(const char* Option); + inline std::vector nominus_followers(unsigned No, ...); + + // -- directly followed arguments + inline int direct_follow(int Default, const char* Option); + inline double direct_follow(const double& Default, const char* Option); + inline const std::string direct_follow(const char* Default, const char* Option); + + inline std::vector string_tails(const char* StartString); + inline std::vector int_tails(const char* StartString, const int Default = 1); + inline std::vector double_tails(const char* StartString, const double Default = 1.0); + + // (*) nominus arguments --------------------------------------------------- + inline STRING_VECTOR nominus_vector() const; + inline unsigned nominus_size() const { return static_cast(idx_nominus.size()); } + inline std::string next_nominus(); + + // (*) unidentified flying objects ----------------------------------------- + inline STRING_VECTOR unidentified_arguments(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_arguments(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_arguments() const; + + inline STRING_VECTOR unidentified_options(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_options(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_options() const; + + inline std::string unidentified_flags(const char* Known, + int ArgumentNumber /* =-1 */) const; + + inline STRING_VECTOR unidentified_variables(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_variables(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_variables() const; + + inline STRING_VECTOR unidentified_sections(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_sections(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_sections() const; + + inline STRING_VECTOR unidentified_nominuses(unsigned Number, const char* Known, ...) const; + inline STRING_VECTOR unidentified_nominuses(const STRING_VECTOR& Knowns) const; + inline STRING_VECTOR unidentified_nominuses() const; + + // (*) output -------------------------------------------------------------- + inline int print() const; + +private: + // (*) Type Declaration ---------------------------------------------------- + struct variable { + //----------- + // Variable to be specified on the command line or in input files. + // (i.e. of the form var='12 312 341') + + // -- constructors, destructors, assignment operator + variable(); + variable(const variable&); + variable(const char* Name, const char* Value, const char* FieldSeparator); + ~variable(); + variable& operator=(const variable& That); + + void take(const char* Value, const char* FieldSeparator); + + // -- get a specific element in the string vector + // (return 0 if not present) + const std::string* get_element(unsigned Idx) const; + + // -- data memebers + std::string name; // identifier of variable + STRING_VECTOR value; // value of variable stored in vector + std::string original; // value of variable as given on command line + }; + + // (*) member variables -------------------------------------------------------------- + std::string prefix; // prefix automatically added in queries + std::string section; // (for dollar bracket parsing) + STRING_VECTOR section_list; // list of all parsed sections + // -- argument vector + STRING_VECTOR argv; // vector of command line arguments stored as strings + unsigned cursor; // cursor for argv + bool search_loop_f; // shall search start at beginning after + // // reaching end of arg array ? + bool search_failed_f; // flag indicating a failed search() operation + // // (e.g. next() functions react with 'missed') + + // -- nominus vector + int nominus_cursor; // cursor for nominus_pointers + std::vector idx_nominus; // indecies of 'no minus' arguments + + // -- variables + // (arguments of the form "variable=value") + std::vector variables; + + // -- comment delimiters + std::string _comment_start; + std::string _comment_end; + + // -- field separator (separating elements of a vector) + std::string _field_separator; + + // -- some functions return a char pointer to a temporarily existing string + // this container makes them 'available' until the getpot object is destroyed. + std::vector __internal_string_container; + + // -- keeping track about arguments that are requested, so that the UFO detection + // can be simplified + STRING_VECTOR _requested_arguments; + STRING_VECTOR _requested_variables; + STRING_VECTOR _requested_sections; + + bool __request_recording_f; // speed: request recording can be turned off + + // -- if an argument is requested record it and the 'tag' the section branch to which + // it belongs. Caution: both functions mark the sections as 'tagged'. + void __record_argument_request(const std::string& Arg); + void __record_variable_request(const std::string& Arg); + + // (*) helper functions ---------------------------------------------------- + // set variable from inside GetPot (no prefix considered) + inline void __set_variable(const char* VarName, const char* Value); + + // -- produce three basic data vectors: + // - argument vector + // - nominus vector + // - variable dictionary + inline void __parse_argument_vector(const STRING_VECTOR& ARGV); + + // -- helpers for argument list processing + // * search for a variable in 'variables' array + inline const variable* __find_variable(const char*) const; + // * support finding directly followed arguments + inline const char* __match_starting_string(const char* StartString); + // * support search for flags in a specific argument + inline bool __check_flags(const std::string& Str, const char* FlagList) const; + // * type conversion if possible + inline int __convert_to_type(const std::string& String, int Default) const; + inline double __convert_to_type(const std::string& String, double Default) const; + // * prefix extraction + const std::string __get_remaining_string(const std::string& String, + const std::string& Start) const; + // * search for a specific string + inline bool __search_string_vector(const STRING_VECTOR& Vec, + const std::string& Str) const; + + // -- helpers to parse input file + // create an argument vector based on data found in an input file, i.e.: + // 1) delete comments (in between '_comment_start' '_comment_end') + // 2) contract assignment expressions, such as + // my-variable = '007 J. B.' + // into + // my-variable='007 J. B.' + // 3) interprete sections like '[../my-section]' etc. + inline void __skip_whitespace(std::istream& istr); + inline const std::string __get_next_token(std::istream& istr); + inline const std::string __get_string(std::istream& istr); + inline const std::string __get_until_closing_bracket(std::istream& istr); + + inline STRING_VECTOR __read_in_stream(std::istream& istr); + inline STRING_VECTOR __read_in_file(const char* FileName); + inline std::string __process_section_label(const std::string& Section, + STRING_VECTOR& section_stack); + + // -- dollar bracket expressions + std::string __DBE_expand_string(const std::string str); + std::string __DBE_expand(const std::string str); + const GetPot::variable* __DBE_get_variable(const std::string str); + STRING_VECTOR __DBE_get_expr_list(const std::string str, const unsigned ExpectedNumber); + + std::string __double2string(const double& Value) const { + // -- converts a double integer into a string + char* tmp = new char[128]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*128, "%e", Value); +#else + _snprintf(tmp, sizeof(char)*128, "%e", Value); +#endif + std::string result(tmp); + delete [] tmp; + return result; + } + + std::string __int2string(const int& Value) const { + // -- converts an integer into a string + char* tmp = new char[128]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*128, "%i", Value); +#else + _snprintf(tmp, sizeof(char)*128, "%i", Value); +#endif + std::string result(tmp); + delete [] tmp; + return result; + } + + STRING_VECTOR __get_section_tree(const std::string& FullPath) { + // -- cuts a variable name into a tree of sub-sections. this is requested for recording + // requested sections when dealing with 'ufo' detection. + STRING_VECTOR result; + const char* Start = FullPath.c_str(); + + for(char *p = (char*)Start; *p ; p++) { + if( *p == '/' ) { + *p = '\0'; // set terminating zero for convinience + const std::string Section = Start; + *p = '/'; // reset slash at place + result.push_back(Section); + } + } + + return result; + } +}; + + +/////////////////////////////////////////////////////////////////////////////// +// (*) constructors, destructor, assignment operator +//............................................................................. +// +inline void +GetPot::__basic_initialization() +{ + cursor = 0; nominus_cursor = -1; + search_failed_f = true; search_loop_f = true; + prefix = ""; section = ""; + + // automatic request recording for later ufo detection + __request_recording_f = true; + + // comment start and end strings + _comment_start = std::string("#"); + _comment_end = std::string("\n"); + + // default: separate vector elements by whitespaces + _field_separator = " \t\n"; +} + +inline +GetPot::GetPot() +{ + __basic_initialization(); + + STRING_VECTOR _apriori_argv; + _apriori_argv.push_back(std::string("Empty")); + __parse_argument_vector(_apriori_argv); +} + +inline +GetPot::GetPot(const int argc_, char ** argv_, + const char* FieldSeparator /* =0x0 */) + // leave 'char**' non-const to honor less capable compilers ... +{ + // TODO: Ponder over the problem when the argument list is of size = 0. + // This is 'sabotage', but it can still occur if the user specifies + // it himself. + assert(argc_ >= 1); + __basic_initialization(); + + // if specified -> overwrite default string + if( FieldSeparator ) _field_separator = std::string(FieldSeparator); + + // -- make an internal copy of the argument list: + STRING_VECTOR _apriori_argv; + // -- for the sake of clarity: we do want to include the first argument in the argument vector ! + // it will not be a nominus argument, though. This gives us a minimun vector size of one + // which facilitates error checking in many functions. Also the user will be able to + // retrieve the name of his application by "get[0]" + _apriori_argv.push_back(std::string(argv_[0])); + int i=1; + for(; i overwrite default strings + if( CommentStart ) _comment_start = std::string(CommentStart); + if( CommentEnd ) _comment_end = std::string(CommentEnd); + if( FieldSeparator ) _field_separator = FieldSeparator; + + STRING_VECTOR _apriori_argv; + // -- file name is element of argument vector, however, it is not parsed for + // variable assignments or nominuses. + _apriori_argv.push_back(std::string(FileName)); + + STRING_VECTOR args = __read_in_file(FileName); + _apriori_argv.insert(_apriori_argv.begin()+1, args.begin(), args.end()); + __parse_argument_vector(_apriori_argv); +} + +inline +GetPot::GetPot(const GetPot& That) +{ GetPot::operator=(That); } + +inline +GetPot::~GetPot() +{ + // may be some return strings had to be created, delete now ! + victorate(char*, __internal_string_container, it) + delete [] *it; +} + +inline GetPot& +GetPot::operator=(const GetPot& That) +{ + if (&That == this) return *this; + + _comment_start = That._comment_start; + _comment_end = That._comment_end; + argv = That.argv; + variables = That.variables; + prefix = That.prefix; + + cursor = That.cursor; + nominus_cursor = That.nominus_cursor; + search_failed_f = That.search_failed_f; + + idx_nominus = That.idx_nominus; + search_loop_f = That.search_loop_f; + + return *this; +} + + +inline void +GetPot::absorb(const GetPot& That) +{ + if (&That == this) return; + + STRING_VECTOR __tmp(That.argv); + + __tmp.erase(__tmp.begin()); + + __parse_argument_vector(__tmp); +} + +inline void +GetPot::clear_requests() +{ + _requested_arguments.erase(_requested_arguments.begin(), _requested_arguments.end()); + _requested_variables.erase(_requested_variables.begin(), _requested_variables.end()); + _requested_sections.erase(_requested_sections.begin(), _requested_sections.end()); +} + +inline void +GetPot::__parse_argument_vector(const STRING_VECTOR& ARGV) +{ + if( ARGV.size() == 0 ) return; + + // build internal databases: + // 1) array with no-minus arguments (usually used as filenames) + // 2) variable assignments: + // 'variable name' '=' number | string + STRING_VECTOR section_stack; + STRING_VECTOR::const_iterator it = ARGV.begin(); + + + section = ""; + + // -- do not parse the first argument, so that it is not interpreted a s a nominus or so. + argv.push_back(*it); + ++it; + + // -- loop over remaining arguments + unsigned i=1; + for(; it != ARGV.end(); ++it, ++i) { + std::string arg = *it; + + if( arg.length() == 0 ) continue; + + // -- [section] labels + if( arg.length() > 1 && arg[0] == '[' && arg[arg.length()-1] == ']' ) { + + // (*) sections are considered 'requested arguments' + if( __request_recording_f ) _requested_arguments.push_back(arg); + + const std::string Name = __DBE_expand_string(arg.substr(1, arg.length()-2)); + section = __process_section_label(Name, section_stack); + // new section --> append to list of sections + if( find(section_list.begin(), section_list.end(), section) == section_list.end() ) + if( section.length() != 0 ) section_list.push_back(section); + argv.push_back(arg); + } + else { + arg = section + __DBE_expand_string(arg); + argv.push_back(arg); + } + + // -- separate array for nominus arguments + if( arg[0] != '-' ) idx_nominus.push_back(unsigned(i)); + + // -- variables: does arg contain a '=' operator ? + const char* p = arg.c_str(); + for(; *p ; p++) { + if( *p == '=' ) { + // (*) record for later ufo detection + // arguments carriying variables are always treated as 'requested' arguments. + // as a whole! That is 'x=4712' is considered a requested argument. + // + // unrequested variables have to be detected with the ufo-variable + // detection routine. + if( __request_recording_f ) _requested_arguments.push_back(arg); + + // set terminating 'zero' to treat first part as single string + // => arg (from start to 'p') = Name of variable + // p+1 (until terminating zero) = value of variable + char* o = (char*)p++; + *o = '\0'; // set temporary terminating zero + // __set_variable(...) + // calls __find_variable(...) which registers the search + // temporarily disable this + const bool tmp = __request_recording_f; + __request_recording_f = false; + __set_variable(arg.c_str(), p); // v-name = c_str() bis 'p', value = rest + __request_recording_f = tmp; + *o = '='; // reset the original '=' + break; + } + } + } +} + + +inline STRING_VECTOR +GetPot::__read_in_file(const char* FileName) +{ + std::ifstream i(FileName); + if( ! i ) return STRING_VECTOR(); + // argv[0] == the filename of the file that was read in + return __read_in_stream(i); +} + +inline STRING_VECTOR +GetPot::__read_in_stream(std::istream& istr) +{ + STRING_VECTOR brute_tokens; + while(istr) { + __skip_whitespace(istr); + + const std::string Token = __get_next_token(istr); + if( Token.length() == 0 || Token[0] == EOF) break; + brute_tokens.push_back(Token); + } + + // -- reduce expressions of token1'='token2 to a single + // string 'token1=token2' + // -- copy everything into 'argv' + // -- arguments preceded by something like '[' name ']' (section) + // produce a second copy of each argument with a prefix '[name]argument' + unsigned i1 = 0; + unsigned i2 = 1; + unsigned i3 = 2; + + STRING_VECTOR arglist; + while( i1 < brute_tokens.size() ) { + const std::string& SRef = brute_tokens[i1]; + // 1) concatinate 'abcdef' '=' 'efgasdef' to 'abcdef=efgasdef' + // note: java.lang.String: substring(a,b) = from a to b-1 + // C++ string: substr(a,b) = from a to a + b + if( i2 < brute_tokens.size() && brute_tokens[i2] == "=" ) { + if( i3 >= brute_tokens.size() ) + arglist.push_back(brute_tokens[i1] + brute_tokens[i2]); + else + arglist.push_back(brute_tokens[i1] + brute_tokens[i2] + brute_tokens[i3]); + i1 = i3+1; i2 = i3+2; i3 = i3+3; + continue; + } + else { + arglist.push_back(SRef); + i1=i2; i2=i3; i3++; + } + } + return arglist; +} + +inline void +GetPot::__skip_whitespace(std::istream& istr) + // find next non-whitespace while deleting comments +{ + int tmp = istr.get(); + do { + // -- search a non whitespace + while( isspace(tmp) ) { + tmp = istr.get(); + if( ! istr ) return; + } + + // -- look if characters match the comment starter string + const std::istream::pos_type Pos = istr.tellg(); + unsigned i=0; + for(; i<_comment_start.length() ; ++i) { + if( tmp != _comment_start[i] ) { +// HACK: The following line throws off msvc8: +// istr.seekg(Pos); + // -- one step more backwards, since 'tmp' already at non-whitespace + istr.unget(); + return; + } + tmp = istr.get(); + if( ! istr ) { istr.unget(); return; } + } + // 'tmp' contains last character of _comment_starter + + // -- comment starter found -> search for comment ender + unsigned match_no=0; + while(1+1 == 2) { + tmp = istr.get(); + if( ! istr ) { istr.unget(); return; } + + if( tmp == _comment_end[match_no] ) { + match_no++; + if( match_no == _comment_end.length() ) { + istr.unget(); + break; // shuffle more whitespace, end of comment found + } + } + else + match_no = 0; + } + + tmp = istr.get(); + + } while( istr ); + istr.unget(); +} + +inline const std::string +GetPot::__get_next_token(std::istream& istr) + // get next concatinates string token. consider quotes that embrace + // whitespaces +{ + std::string token; + int tmp = 0; + int last_letter = 0; + while(1+1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF + || ((tmp == ' ' || tmp == '\t' || tmp == '\n') && last_letter != '\\') ) { + return token; + } + else if( tmp == '\'' && last_letter != '\\' ) { + // QUOTES: un-backslashed quotes => it's a string + token += __get_string(istr); + continue; + } + else if( tmp == '{' && last_letter == '$') { + token += '{' + __get_until_closing_bracket(istr); + continue; + } + else if( tmp == '$' && last_letter == '\\') { + token += tmp; tmp = 0; // so that last_letter will become = 0, not '$'; + continue; + } + else if( tmp == '\\' && last_letter != '\\') + continue; // don't append un-backslashed backslashes + token += tmp; + } +} + +inline const std::string +GetPot::__get_string(std::istream& istr) + // parse input until next matching ' +{ + std::string str; + int tmp = 0; + int last_letter = 0; + while(1 + 1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF) return str; + // un-backslashed quotes => it's the end of the string + else if( tmp == '\'' && last_letter != '\\') return str; + else if( tmp == '\\' && last_letter != '\\') continue; // don't append + + str += tmp; + } +} + +inline const std::string +GetPot::__get_until_closing_bracket(std::istream& istr) + // parse input until next matching } +{ + std::string str = ""; + int tmp = 0; + int last_letter = 0; + int brackets = 1; + while(1 + 1 == 2) { + last_letter = tmp; tmp = istr.get(); + if( tmp == EOF) return str; + else if( tmp == '{' && last_letter == '$') brackets += 1; + else if( tmp == '}') { + brackets -= 1; + // un-backslashed brackets => it's the end of the string + if( brackets == 0) return str + '}'; + else if( tmp == '\\' && last_letter != '\\') + continue; // do not append an unbackslashed backslash + } + str += tmp; + } +} + +inline std::string +GetPot::__process_section_label(const std::string& Section, + STRING_VECTOR& section_stack) +{ + std::string sname = Section; + // 1) subsection of actual section ('./' prefix) + if( sname.length() >= 2 && sname.substr(0, 2) == "./" ) { + sname = sname.substr(2); + } + // 2) subsection of parent section ('../' prefix) + else if( sname.length() >= 3 && sname.substr(0, 3) == "../" ) { + do { + if( section_stack.end() != section_stack.begin() ) + section_stack.pop_back(); + sname = sname.substr(3); + } while( sname.substr(0, 3) == "../" ); + } + // 3) subsection of the root-section + else { + section_stack.erase(section_stack.begin(), section_stack.end()); + // [] => back to root section + } + + if( sname != "" ) { + // parse section name for 'slashes' + unsigned i=0; + while( i < sname.length() ) { + if( sname[i] == '/' ) { + section_stack.push_back(sname.substr(0,i)); + if( i+1 < sname.length()-1 ) + sname = sname.substr(i+1); + i = 0; + } + else + ++i; + } + section_stack.push_back(sname); + } + std::string section = ""; + if( section_stack.size() != 0 ) { + victorate(std::string, section_stack, it) + section += *it + "/"; + } + return section; +} + + +// convert string to DOUBLE, if not possible return Default +inline double +GetPot::__convert_to_type(const std::string& String, double Default) const +{ + double tmp; + if( sscanf(String.c_str(),"%lf", &tmp) != 1 ) return Default; + return tmp; +} + +// convert string to INT, if not possible return Default +inline int +GetPot::__convert_to_type(const std::string& String, int Default) const +{ + // NOTE: intermediate results may be floating points, so that the string + // may look like 2.0e1 (i.e. float format) => use float conversion + // in any case. + return (int)__convert_to_type(String, (double)Default); +} + +////////////////////////////////////////////////////////////////////////////// +// (*) cursor oriented functions +//............................................................................. +inline const std::string +GetPot::__get_remaining_string(const std::string& String, const std::string& Start) const + // Checks if 'String' begins with 'Start' and returns the remaining String. + // Returns None if String does not begin with Start. +{ + if( Start == "" ) return String; + // note: java.lang.String: substring(a,b) = from a to b-1 + // C++ string: substr(a,b) = from a to a + b + if( String.find(Start) == 0 ) return String.substr(Start.length()); + else return ""; +} + +// -- search for a certain argument and set cursor to position +inline bool +GetPot::search(const char* Option) +{ + unsigned OldCursor = cursor; + const std::string SearchTerm = prefix + Option; + + // (*) record requested arguments for later ufo detection + __record_argument_request(SearchTerm); + + if( OldCursor >= argv.size() ) OldCursor = static_cast(argv.size()) - 1; + search_failed_f = true; + + // (*) first loop from cursor position until end + unsigned c = cursor; + for(; c < argv.size(); c++) { + if( argv[c] == SearchTerm ) + { cursor = c; search_failed_f = false; return true; } + } + if( ! search_loop_f ) return false; + + // (*) second loop from 0 to old cursor position + for(c = 1; c < OldCursor; c++) { + if( argv[c] == SearchTerm ) + { cursor = c; search_failed_f = false; return true; } + } + // in case nothing is found the cursor stays where it was + return false; +} + + +inline bool +GetPot::search(unsigned No, const char* P, ...) +{ + // (*) recording the requested arguments happens in subroutine 'search' + if( No == 0 ) return false; + + // search for the first argument + if( search(P) == true ) return true; + + // start interpreting variable argument list + va_list ap; + va_start(ap, P); + unsigned i = 1; + for(; i < No; ++i) { + char* Opt = va_arg(ap, char *); + if( search(Opt) == true ) break; + } + + if( i < No ) { + ++i; + // loop was left before end of array --> hit but + // make sure that the rest of the search terms is marked + // as requested. + for(; i < No; ++i) { + char* Opt = va_arg(ap, char *); + // (*) record requested arguments for later ufo detection + __record_argument_request(Opt); + } + va_end(ap); + return true; + } + + va_end(ap); + // loop was left normally --> no hit + return false; +} + +inline void +GetPot::reset_cursor() +{ search_failed_f = false; cursor = 0; } + +inline void +GetPot::init_multiple_occurrence() +{ disable_loop(); reset_cursor(); } +/////////////////////////////////////////////////////////////////////////////// +// (*) direct access to command line arguments +//............................................................................. +// +inline const std::string +GetPot::operator[](unsigned idx) const +{ return idx < argv.size() ? argv[idx] : ""; } + +inline int +GetPot::get(unsigned Idx, int Default) const +{ + if( Idx >= argv.size() ) return Default; + return __convert_to_type(argv[Idx], Default); +} + +inline double +GetPot::get(unsigned Idx, const double& Default) const +{ + if( Idx >= argv.size() ) return Default; + return __convert_to_type(argv[Idx], Default); +} + +inline const std::string +GetPot::get(unsigned Idx, const char* Default) const +{ + if( Idx >= argv.size() ) return Default; + else return argv[Idx]; +} + +inline unsigned +GetPot::size() const +{ return static_cast(argv.size()); } + + +// -- next() function group +inline int +GetPot::next(int Default) +{ + if( search_failed_f ) return Default; + cursor++; + if( cursor >= argv.size() ) + { cursor = static_cast(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + const std::string Remain = __get_remaining_string(argv[cursor], prefix); + + return Remain != "" ? __convert_to_type(Remain, Default) : Default; +} + +inline double +GetPot::next(const double& Default) +{ + if( search_failed_f ) return Default; + cursor++; + + if( cursor >= argv.size() ) + { cursor = static_cast(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + std::string Remain = __get_remaining_string(argv[cursor], prefix); + + return Remain != "" ? __convert_to_type(Remain, Default) : Default; +} + +inline const std::string +GetPot::next(const char* Default) +{ + if( search_failed_f ) return Default; + cursor++; + + if( cursor >= argv.size() ) + { cursor = static_cast(argv.size()); return Default; } + + // (*) record requested argument for later ufo detection + __record_argument_request(argv[cursor]); + + const std::string Remain = __get_remaining_string(argv[cursor], prefix); + + if( Remain == "" ) return Default; + + + // (*) function returns a pointer to a char array (inside Remain) + // this array will be deleted, though after this function call. + // To ensure propper functioning, create a copy inside *this + // object and only delete it, when *this is deleted. + char* result = new char[Remain.length()+1]; + strncpy(result, Remain.c_str(), Remain.length()+1); + + // store the created string internally, delete if when object deleted + __internal_string_container.push_back(result); + + return result; +} + +// -- follow() function group +// distinct option to be searched for +inline int +GetPot::follow(int Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +inline double +GetPot::follow(const double& Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +inline const std::string +GetPot::follow(const char* Default, const char* Option) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( search(Option) == false ) return Default; + return next(Default); +} + +// -- second follow() function group +// multiple option to be searched for +inline int +GetPot::follow(int Default, unsigned No, const char* P, ...) +{ + // (*) record requested of argument is entirely handled in 'search()' and 'next()' + if( No == 0 ) return Default; + if( search(P) == true ) return next(Default); + + va_list ap; + va_start(ap, P); + unsigned i=1; + for(; i +GetPot::nominus_followers(const char* Option) +{ + std::vector result_list; + if( search(Option) == false ) return result_list; + while( 1 + 1 == 2 ) { + ++cursor; + if( cursor >= argv.size() ) { + cursor = argv.size() - 1; + return result_list; + } + if( argv[cursor].length() >= 1 ) { + if( argv[cursor][0] == '-' ) { + return result_list; + } + // -- record for later ufo-detection + __record_argument_request(argv[cursor]); + // -- append to the result list + result_list.push_back(argv[cursor]); + } + } +} + +inline std::vector +GetPot::nominus_followers(unsigned No, ...) +{ + std::vector result_list; + // (*) record requested of argument is entirely handled in 'search()' + // and 'nominus_followers()' + if( No == 0 ) return result_list; + + va_list ap; + va_start(ap, No); + for(unsigned i=0; i tmp = nominus_followers(Option); + result_list.insert(result_list.end(), tmp.begin(), tmp.end()); + + // std::cerr << "option = '" << Option << "'" << std::endl; + // std::cerr << "length = " << tmp.size() << std::endl; + // std::cerr << "new result list = <"; + // for(std::vector::const_iterator it = result_list.begin(); + // it != result_list.end(); ++it) + // std::cerr << *it << ", "; + // std::cerr << ">\n"; + } + va_end(ap); + return result_list; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) directly connected options +//............................................................................. +// +inline int +GetPot::direct_follow(int Default, const char* Option) +{ + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0x0 ) return Default; + + // (*) record requested of argument for later ufo-detection + __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast(argv.size()) ) cursor = static_cast(argv.size()); + return __convert_to_type(FollowStr, Default); +} + +inline double +GetPot::direct_follow(const double& Default, const char* Option) +{ + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0 ) return Default; + + // (*) record requested of argument for later ufo-detection + __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast(argv.size()) ) cursor = static_cast(argv.size()); + return __convert_to_type(FollowStr, Default); +} + +inline const std::string +GetPot::direct_follow(const char* Default, const char* Option) +{ + if( search_failed_f ) return Default; + const char* FollowStr = __match_starting_string(Option); + if( FollowStr == 0 ) return Default; + + // (*) record requested of argument for later ufo-detection + if( FollowStr ) __record_argument_request(std::string(Option) + FollowStr); + + if( ++cursor >= static_cast(argv.size()) ) cursor = static_cast(argv.size()); + return std::string(FollowStr); +} + +inline std::vector +GetPot::string_tails(const char* StartString) +{ + std::vector result; + const unsigned N = static_cast(strlen(StartString)); + + std::vector::iterator it = argv.begin(); + + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back((*it).substr(N)); + + // adapt the nominus vector + std::vector::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + +inline std::vector +GetPot::int_tails(const char* StartString, const int Default /* = -1 */) +{ + std::vector result; + const unsigned N = static_cast(strlen(StartString)); + + std::vector::iterator it = argv.begin(); + + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back(__convert_to_type((*it).substr(N), Default)); + + // adapt the nominus vector + std::vector::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + +inline std::vector +GetPot::double_tails(const char* StartString, + const double Default /* = -1.0 */) +{ + std::vector result; + const unsigned N = static_cast(strlen(StartString)); + + std::vector::iterator it = argv.begin(); + unsigned idx = 0; + while( it != argv.end() ) { + // (*) does start string match the given option? + // NO -> goto next option + if( strncmp(StartString, (*it).c_str(), N) != 0) { ++it; ++idx; continue; } + + // append the found tail to the result vector + result.push_back(__convert_to_type((*it).substr(N), Default)); + + // adapt the nominus vector + std::vector::iterator nit = idx_nominus.begin(); + for(; nit != idx_nominus.end(); ++nit) { + if( *nit == idx ) { + idx_nominus.erase(nit); + for(; nit != idx_nominus.end(); ++nit) *nit -= 1; + break; + } + } + + // erase the found option + argv.erase(it); + + // 100% safe solution: set iterator back to the beginning. + // (normally, 'it--' would be enough, but who knows how the + // iterator is implemented and .erase() definitely invalidates + // the current iterator position. + if( argv.empty() ) break; + it = argv.begin(); + } + cursor = 0; + nominus_cursor = -1; + return result; +} + + + + + +inline const char* +GetPot::__match_starting_string(const char* StartString) + // pointer to the place where the string after + // the match inside the found argument starts. + // 0 no argument matches the starting string. +{ + const unsigned N = static_cast(strlen(StartString)); + unsigned OldCursor = cursor; + + if( OldCursor >= static_cast(argv.size()) ) OldCursor = static_cast(argv.size()) - 1; + search_failed_f = true; + + // (*) first loop from cursor position until end + unsigned c = cursor; + for(; c < argv.size(); c++) { + if( strncmp(StartString, argv[c].c_str(), N) == 0) + { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); } + } + + if( ! search_loop_f ) return false; + + // (*) second loop from 0 to old cursor position + for(c = 1; c < OldCursor; c++) { + if( strncmp(StartString, argv[c].c_str(), N) == 0) + { cursor = c; search_failed_f = false; return &(argv[c].c_str()[N]); } + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) search for flags +//............................................................................. +// +inline bool +GetPot::options_contain(const char* FlagList) const +{ + // go through all arguments that start with a '-' (but not '--') + std::string str; + STRING_VECTOR::const_iterator it = argv.begin(); + for(; it != argv.end(); ++it) { + str = __get_remaining_string(*it, prefix); + + if( str.length() >= 2 && str[0] == '-' && str[1] != '-' ) + if( __check_flags(str, FlagList) ) return true; + } + return false; +} + +inline bool +GetPot::argument_contains(unsigned Idx, const char* FlagList) const +{ + if( Idx >= argv.size() ) return false; + + // (*) record requested of argument for later ufo-detection + // an argument that is checked for flags is considered to be 'requested' + ((GetPot*)this)->__record_argument_request(argv[Idx]); + + if( prefix == "" ) + // search argument for any flag in flag list + return __check_flags(argv[Idx], FlagList); + + // if a prefix is set, then the argument index is the index + // inside the 'namespace' + // => only check list of arguments that start with prefix + unsigned no_matches = 0; + unsigned i=0; + for(; i::const_iterator it = idx_nominus.begin(); + for(; it != idx_nominus.end(); ++it) { + nv.push_back(argv[*it]); + + // (*) record for later ufo-detection + // when a nominus vector is requested, the entire set of nominus arguments are + // tagged as 'requested' + ((GetPot*)this)->__record_argument_request(argv[*it]); + } + return nv; +} + +inline std::string +GetPot::next_nominus() +{ + if( nominus_cursor < int(idx_nominus.size()) - 1 ) { + const std::string Tmp = argv[idx_nominus[++nominus_cursor]]; + + // (*) record for later ufo-detection + __record_argument_request(Tmp); + + // -- cannot use the Tmp variable, since it is temporary and c_str() will return a pointer + // to something that does no longer exist. + return Tmp; + } + return std::string(""); +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) variables +//............................................................................. +// +inline int +GetPot::operator()(const char* VarName, int Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + return __convert_to_type(sv->original, Default); +} + +inline double +GetPot::operator()(const char* VarName, const double& Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + return __convert_to_type(sv->original, Default); +} + +inline const std::string +GetPot::operator()(const char* VarName, const char* Default) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + // -- returning a c_str() pointer is OK here, since the variable remains existant, + // while 'sv' of course is delete at the end of the function. + return sv->original; +} + +inline int +GetPot::operator()(const char* VarName, int Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return __convert_to_type(*element, Default); +} + +inline double +GetPot::operator()(const char* VarName, const double& Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return __convert_to_type(*element, Default); +} + +inline const std::string +GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const +{ + // (*) recording of requested variables happens in '__find_variable()' + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return Default; + const std::string* element = sv->get_element(Idx); + if( element == 0 ) return Default; + return *element; +} + +inline void +GetPot::__record_argument_request(const std::string& Name) +{ + if( ! __request_recording_f ) return; + + // (*) record requested variable for later ufo detection + _requested_arguments.push_back(Name); + + // (*) record considered section for ufo detection + STRING_VECTOR STree = __get_section_tree(Name); + victorate(std::string, STree, it) + if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) + if( section.length() != 0 ) _requested_sections.push_back(*it); +} + +inline void +GetPot::__record_variable_request(const std::string& Name) +{ + if( ! __request_recording_f ) return; + + // (*) record requested variable for later ufo detection + _requested_variables.push_back(Name); + + // (*) record considered section for ufo detection + STRING_VECTOR STree = __get_section_tree(Name); + victorate(std::string, STree, it) + if( find(_requested_sections.begin(), _requested_sections.end(), *it) == _requested_sections.end() ) + if( section.length() != 0 ) _requested_sections.push_back(*it); +} + +// (*) following functions are to be used from 'outside', after getpot has parsed its +// arguments => append an argument in the argument vector that reflects the addition +inline void +GetPot::__set_variable(const char* VarName, const char* Value) +{ + const GetPot::variable* Var = __find_variable(VarName); + if( Var == 0 ) variables.push_back(variable(VarName, Value, _field_separator.c_str())); + else ((GetPot::variable*)Var)->take(Value, _field_separator.c_str()); +} + +inline void +GetPot::set(const char* VarName, const char* Value, const bool Requested /* = yes */) +{ + const std::string Arg = prefix + std::string(VarName) + std::string("=") + std::string(Value); + argv.push_back(Arg); + __set_variable(VarName, Value); + + // if user does not specify the variable as 'not being requested' it will be + // considered amongst the requested variables + if( Requested ) __record_variable_request(Arg); +} + +inline void +GetPot::set(const char* VarName, const double& Value, const bool Requested /* = yes */) +{ __set_variable(VarName, __double2string(Value).c_str()); } + +inline void +GetPot::set(const char* VarName, const int Value, const bool Requested /* = yes */) +{ __set_variable(VarName, __int2string(Value).c_str()); } + + +inline unsigned +GetPot::vector_variable_size(const char* VarName) const +{ + const variable* sv = __find_variable(VarName); + if( sv == 0 ) return 0; + return static_cast(sv->value.size()); +} + +inline STRING_VECTOR +GetPot::get_variable_names() const +{ + STRING_VECTOR result; + std::vector::const_iterator it = variables.begin(); + for(; it != variables.end(); ++it) { + const std::string Tmp = __get_remaining_string((*it).name, prefix); + if( Tmp != "" ) result.push_back(Tmp); + } + return result; +} + +inline STRING_VECTOR +GetPot::get_section_names() const +{ return section_list; } + +inline const GetPot::variable* +GetPot::__find_variable(const char* VarName) const +{ + const std::string Name = prefix + VarName; + + // (*) record requested variable for later ufo detection + ((GetPot*)this)->__record_variable_request(Name); + + std::vector::const_iterator it = variables.begin(); + for(; it != variables.end(); ++it) { + if( (*it).name == Name ) return &(*it); + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////////// +// (*) ouput (basically for debugging reasons +//............................................................................. +// +inline int +GetPot::print() const +{ + std::cout << "argc = " << static_cast(argv.size()) << std::endl; + STRING_VECTOR::const_iterator it = argv.begin(); + for(; it != argv.end(); ++it) + std::cout << *it << std::endl; + std::cout << std::endl; + return 1; +} + +// (*) dollar bracket expressions (DBEs) ------------------------------------ +// +// 1) Entry Function: __DBE_expand_string() +// Takes a string such as +// +// "${+ ${x} ${y}} Subject-${& ${section} ${subsection}}: ${title}" +// +// calls __DBE_expand() for each of the expressions +// +// ${+ ${x} ${y}} +// ${& ${section} ${subsection}} +// ${Title} +// +// and returns the string +// +// "4711 Subject-1.01: Mit den Clowns kamen die Schwaene" +// +// assuming that +// x = "4699" +// y = "12" +// section = "1." +// subsection = "01" +// title = "Mit den Clowns kamen die Schwaene" +// +// 2) __DBE_expand(): +// +// checks for the command, i.e. the 'sign' that follows '${' +// divides the argument list into sub-expressions using +// __DBE_get_expr_list() +// +// ${+ ${x} ${y}} -> "${x}" "${y}" +// ${& ${section} ${subsection}} -> "${section}" "${subsection}" +// ${Title} -> Nothing, variable expansion +// +// 3) __DBE_expression_list(): +// +// builds a vector of unbracketed whitespace separated strings, i.e. +// +// " ${Number}.a ${: Das Marmorbild} AB-${& Author= ${Eichendorf}-1870}" +// +// is split into a vector +// +// [0] ${Number}.a +// [1] ${: Das Marmorbild} +// [2] AB-${& Author= ${Eichendorf}}-1870 +// +// Each sub-expression is expanded using expand(). +//--------------------------------------------------------------------------- +inline std::string +GetPot::__DBE_expand_string(const std::string str) +{ + // Parses for closing operators '${ }' and expands them letting + // white spaces and other letters as they are. + std::string new_string = ""; + unsigned open_brackets = 0; + unsigned first = 0; + unsigned i = 0; + for(; i 0) { + open_brackets -= 1; + if( open_brackets == 0 ) { + const std::string Replacement = __DBE_expand(str.substr(first, i - first)); + new_string += Replacement; + } + } + else if( open_brackets == 0 ) + new_string += str[i]; + } + return new_string; +} + +inline STRING_VECTOR +GetPot::__DBE_get_expr_list(const std::string str_, const unsigned ExpectedNumber) + // ensures that the resulting vector has the expected number + // of arguments, but they may contain an error message +{ + std::string str = str_; + // Separates expressions by non-bracketed whitespaces, expands them + // and puts them into a list. + + unsigned i=0; + // (1) eat initial whitespaces + for(; i < str.size(); ++i) + if( ! isspace(str[i]) ) break; + + STRING_VECTOR expr_list; + unsigned open_brackets = 0; + std::vector start_idx; + unsigned start_new_string = i; + unsigned l = static_cast(str.size()); + + // (2) search for ${ } expressions ... + while( i < l ) { + const char letter = str[i]; + // whitespace -> end of expression + if( isspace(letter) && open_brackets == 0) { + expr_list.push_back(str.substr(start_new_string, i - start_new_string)); + bool no_breakout_f = true; + for(++i; i < l ; ++i) { + if( ! isspace(str[i]) ) + { no_breakout_f = false; start_new_string = i; break; } + } + if( no_breakout_f ) { + // end of expression list + if( expr_list.size() < ExpectedNumber ) { + const std::string pre_tmp("<< ${ }: missing arguments>>"); + STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp); + expr_list.insert(expr_list.end(), tmp.begin(), tmp.end()); + } + return expr_list; + } + } + + // dollar-bracket expression + if( str.length() >= i+2 && str.substr(i, 2) == "${" ) { + open_brackets++; + start_idx.push_back(i+2); + } + else if( letter == '}' && open_brackets > 0) { + int start = start_idx[start_idx.size()-1]; + start_idx.pop_back(); + const std::string Replacement = __DBE_expand(str.substr(start, i-start)); + if( start - 3 < (int)0) + str = Replacement + str.substr(i+1); + else + str = str.substr(0, start-2) + Replacement + str.substr(i+1); + l = static_cast(str.size()); + i = start + static_cast(Replacement.size()) - 3; + open_brackets--; + } + ++i; + } + + // end of expression list + expr_list.push_back(str.substr(start_new_string, i-start_new_string)); + + if( expr_list.size() < ExpectedNumber ) { + const std::string pre_tmp("<< ${ }: missing arguments>>"); + STRING_VECTOR tmp(ExpectedNumber - expr_list.size(), pre_tmp); + expr_list.insert(expr_list.end(), tmp.begin(), tmp.end()); + } + + return expr_list; +} + +inline const GetPot::variable* +GetPot::__DBE_get_variable(std::string VarName) +{ + static GetPot::variable ev; + std::string secure_Prefix = prefix; + + prefix = section; + // (1) first search in currently active section + const GetPot::variable* var = __find_variable(VarName.c_str()); + if( var != 0 ) { prefix = secure_Prefix; return var; } + + // (2) search in root name space + prefix = ""; + var = __find_variable(VarName.c_str()); + if( var != 0 ) { prefix = secure_Prefix; return var; } + + prefix = secure_Prefix; + + // error occured => variable name == "" + char* tmp = new char[VarName.length() + 25]; +#ifndef WIN32 + snprintf(tmp, (int)sizeof(char)*(VarName.length() + 25), +#else + _snprintf(tmp, sizeof(char)*(VarName.length() + 25), +#endif + "<<${ } variable '%s' undefined>>", VarName.c_str()); + ev.name = ""; + ev.original = std::string(tmp); + delete [] tmp; + return &ev; +} + +inline std::string +GetPot::__DBE_expand(const std::string expr) +{ + // ${: } pure text + if( expr[0] == ':' ) + return expr.substr(1); + + // ${& expr expr ... } text concatination + else if( expr[0] == '&' ) { + const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 1); + + STRING_VECTOR::const_iterator it = A.begin(); + std::string result = *it++; + for(; it != A.end(); ++it) result += *it; + + return result; + } + + // ${<-> expr expr expr} text replacement + else if( expr.length() >= 3 && expr.substr(0, 3) == "<->" ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(3), 3); + std::string::size_type tmp = 0; + const std::string::size_type L = A[1].length(); + while( (tmp = A[0].find(A[1])) != std::string::npos ) { + A[0].replace(tmp, L, A[2]); + } + return A[0]; + } + // ${+ ...}, ${- ...}, ${* ...}, ${/ ...} expressions + else if( expr[0] == '+' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result += __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '-' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result -= __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '*' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result *= __convert_to_type(*it, 0.0); + + return __double2string(result); + } + else if( expr[0] == '/' ) { + + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + if( result == 0 ) return "0.0"; + for(; it != A.end(); ++it) { + const double Q = __convert_to_type(*it, 0.0); + if( Q == 0.0 ) return "0.0"; + result /= Q; + } + return __double2string(result); + } + + // ${^ ... } power expressions + else if( expr[0] == '^' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + STRING_VECTOR::const_iterator it = A.begin(); + double result = __convert_to_type(*it++, 0.0); + for(; it != A.end(); ++it) + result = pow(result, __convert_to_type(*it, 0.0)); + return __double2string(result); + } + + // ${== } ${<= } ${>= } comparisons (return the number of the first 'match' + else if( expr.length() >= 2 && + ( expr.substr(0,2) == "==" || expr.substr(0,2) == ">=" || + expr.substr(0,2) == "<=" || expr[0] == '>' || expr[0] == '<')) { + // differentiate between two and one sign operators + unsigned op = 0; + enum { EQ, GEQ, LEQ, GT, LT }; + if ( expr.substr(0, 2) == "==" ) op = EQ; + else if ( expr.substr(0, 2) == ">=" ) op = GEQ; + else if ( expr.substr(0, 2) == "<=" ) op = LEQ; + else if ( expr[0] == '>' ) op = GT; + else /* "<" */ op = LT; + + STRING_VECTOR a; + if ( op == GT || op == LT ) a = __DBE_get_expr_list(expr.substr(1), 2); + else a = __DBE_get_expr_list(expr.substr(2), 2); + + std::string x_orig = a[0]; + double x = __convert_to_type(x_orig, 1e37); + unsigned i = 1; + + STRING_VECTOR::const_iterator y_orig = a.begin(); + for(y_orig++; y_orig != a.end(); y_orig++) { + double y = __convert_to_type(*y_orig, 1e37); + + // set the strings as reference if one wasn't a number + if ( x == 1e37 || y == 1e37 ) { + // it's a string comparison + if( (op == EQ && x_orig == *y_orig) || (op == GEQ && x_orig >= *y_orig) || + (op == LEQ && x_orig <= *y_orig) || (op == GT && x_orig > *y_orig) || + (op == LT && x_orig < *y_orig) ) + return __int2string(i); + } + else { + // it's a number comparison + if( (op == EQ && x == y) || (op == GEQ && x >= y) || + (op == LEQ && x <= y) || (op == GT && x > y) || + (op == LT && x < y) ) + return __int2string(i); + } + ++i; + } + + // nothing fulfills the condition => return 0 + return "0"; + } + // ${?? expr expr} select + else if( expr.length() >= 2 && expr.substr(0, 2) == "??" ) { + STRING_VECTOR a = __DBE_get_expr_list(expr.substr(2), 2); + double x = __convert_to_type(a[0], 1e37); + // last element is always the default argument + if( x == 1e37 || x < 0 || x >= a.size() - 1 ) return a[a.size()-1]; + + // round x to closest integer + return a[int(x+0.5)]; + } + // ${? expr expr expr} if then else conditions + else if( expr[0] == '?' ) { + STRING_VECTOR a = __DBE_get_expr_list(expr.substr(1), 2); + if( __convert_to_type(a[0], 0.0) == 1.0 ) return a[1]; + else if( a.size() > 2 ) return a[2]; + } + // ${! expr} maxro expansion + else if( expr[0] == '!' ) { + const GetPot::variable* Var = __DBE_get_variable(expr.substr(1)); + // error + if( Var->name == "" ) return std::string(Var->original); + + const STRING_VECTOR A = __DBE_get_expr_list(Var->original, 2); + return A[0]; + } + // ${@: } - string subscription + else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) { + const STRING_VECTOR A = __DBE_get_expr_list(expr.substr(2), 2); + double x = __convert_to_type(A[1], 1e37); + + // last element is always the default argument + if( x == 1e37 || x < 0 || x >= A[0].size() - 1) + return "<<1st index out of range>>"; + + if( A.size() > 2 ) { + double y = __convert_to_type(A[2], 1e37); + if ( y != 1e37 && y > 0 && y <= A[0].size() - 1 && y > x ) + return A[0].substr(int(x+0.5), int(y+1.5) - int(x+0.5)); + else if( y == -1 ) + return A[0].substr(int(x+0.5)); + return "<<2nd index out of range>>"; + } + else { + char* tmp = new char[2]; + tmp[0] = A[0][int(x+0.5)]; tmp[1] = '\0'; + std::string result(tmp); + delete [] tmp; + return result; + } + } + // ${@ } - vector subscription + else if( expr[0] == '@' ) { + STRING_VECTOR A = __DBE_get_expr_list(expr.substr(1), 2); + const GetPot::variable* Var = __DBE_get_variable(A[0]); + // error + if( Var->name == "" ) { + // make a copy of the string if an error occured + // (since the error variable is a static variable inside get_variable()) + return std::string(Var->original); + } + + double x = __convert_to_type(A[1], 1e37); + + // last element is always the default argument + if (x == 1e37 || x < 0 || x >= Var->value.size() ) + return "<<1st index out of range>>"; + + if ( A.size() > 2) { + double y = __convert_to_type(A[2], 1e37); + int begin = int(x+0.5); + int end = 0; + if ( y != 1e37 && y > 0 && y <= Var->value.size() && y > x) + end = int(y+1.5); + else if( y == -1 ) + end = static_cast(Var->value.size()); + else + return "<<2nd index out of range>>"; + + std::string result = *(Var->get_element(begin)); + int i = begin+1; + for(; i < end; ++i) + result += std::string(" ") + *(Var->get_element(i)); + return result; + } + else + return *(Var->get_element(int(x+0.5))); + } + + const STRING_VECTOR A = __DBE_get_expr_list(expr, 1); + const GetPot::variable* B = __DBE_get_variable(A[0]); + + // make a copy of the string if an error occured + // (since the error variable is a static variable inside get_variable()) + if( B->name == "" ) return std::string(B->original); + // (psuggs@pobox.com mentioned to me the warning MSVC++6.0 produces + // with: else return B->original (thanks)) + return B->original; +} + + +/////////////////////////////////////////////////////////////////////////////// +// (*) unidentified flying objects +//............................................................................. +// +inline bool +GetPot::__search_string_vector(const STRING_VECTOR& VecStr, const std::string& Str) const +{ + victorate(std::string, VecStr, itk) { + if( *itk == Str ) return true; + } + return false; +} + +inline STRING_VECTOR +GetPot::unidentified_arguments(unsigned Number, + const char* KnownArgument1, ...) const +{ + STRING_VECTOR known_arguments; + + // (1) create a vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownArgument1); + known_arguments.push_back(std::string(KnownArgument1)); + unsigned i=1; + for(; i it is not necessary to separate requested options from the list + STRING_VECTOR option_list; + victorate(std::string, _requested_arguments, it) { + const std::string arg = *it; + if( arg.length() == 0 ) continue; + if( arg[0] == '-' ) option_list.push_back(arg); + } + return unidentified_options(option_list); +} + +inline STRING_VECTOR +GetPot::unidentified_options(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // is argument really an option (starting with '-') ? + if( arg.length() < 1 || arg[0] != '-' ) continue; + + if( __search_string_vector(Knowns, arg) == false) + ufos.push_back(*it); + } + + return ufos; +} + +inline std::string +GetPot::unidentified_flags(const char* KnownFlagList, int ArgumentNumber=-1) const + // Two modes: + // ArgumentNumber >= 0 check specific argument + // ArgumentNumber == -1 check all options starting with one '-' + // for flags +{ + std::string ufos; + STRING_VECTOR known_arguments; + std::string KFL(KnownFlagList); + + // (2) iteration over '-' arguments (options) + if( ArgumentNumber == -1 ) { + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- argument belongs to prefixed section ? + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + // -- does arguments start with '-' (but not '--') + if ( arg.length() < 2 ) continue; + else if( arg[0] != '-' ) continue; + else if( arg[1] == '-' ) continue; + + // -- check out if flags inside option are contained in KnownFlagList + const char* p=arg.c_str(); + p++; // skip starting minus + for(; *p != '\0' ; p++) + if( KFL.find(*p) == std::string::npos ) ufos += *p; + } + } + // (1) check specific argument + else { + // -- only check arguments that start with prefix + int no_matches = 0; + unsigned i=1; + for(; i check it for flags + const char* p = Remain.c_str(); + p++; // skip starting minus + for(; *p != '\0' ; p++) + if( KFL.find(*p) == std::string::npos ) ufos += *p; + return ufos; + } + } + } + } + return ufos; +} + +inline STRING_VECTOR +GetPot::unidentified_variables(unsigned Number, + const char* KnownVariable1, ...) const +{ + STRING_VECTOR known_variables; + + // create vector of known arguments + if( Number == 0 ) return STRING_VECTOR(); + + va_list ap; + va_start(ap, KnownVariable1); + known_variables.push_back(std::string(KnownVariable1)); + unsigned i=1; + for(; i it is not necessary to separate requested nominus from the list + + return unidentified_nominuses(_requested_arguments); +} + +inline STRING_VECTOR +GetPot::unidentified_nominuses(const STRING_VECTOR& Knowns) const +{ + STRING_VECTOR ufos; + + // (2) iterate over all arguments + STRING_VECTOR::const_iterator it = argv.begin(); + ++it; // forget about argv[0] (application or filename) + for(; it != argv.end(); ++it) { + // -- check if nominus part of prefix + const std::string arg = __get_remaining_string(*it, prefix); + if( arg == "" ) continue; + + if( arg.length() < 1 ) continue; + // option ? --> not a nomius + if( arg[0] == '-' ) continue; + // section ? --> not a real nominus + if( arg[0] == '[' && arg[arg.length()-1] == ']' ) continue; + // variable definition ? --> not a real nominus + bool continue_f = false; + unsigned i=0; + for(; i= value.size() ) return 0; else return &(value[Idx]); } + +inline void +GetPot::variable::take(const char* Value, const char* FieldSeparator) +{ + original = std::string(Value); + + // separate string by white space delimiters using 'strtok' + // thread safe usage of strtok (no static members) + char* spt = 0; + // make a copy of the 'Value' + char* copy = new char[strlen(Value)+1]; + strcpy(copy, Value); + char* follow_token = strtok_r(copy, FieldSeparator, &spt); + if( value.size() != 0 ) value.erase(value.begin(), value.end()); + while(follow_token != 0) { + value.push_back(std::string(follow_token)); + follow_token = strtok_r(NULL, FieldSeparator, &spt); + } + + delete [] copy; +} + +inline +GetPot::variable::~variable() +{} + +inline GetPot::variable& +GetPot::variable::operator=(const GetPot::variable& That) +{ + if( &That != this) { + name = That.name; + value = That.value; + original = That.original; + } + return *this; +} + +#undef victorate + + +#endif // __include_guard_GETPOT_H__ + + + -- cgit v1.2.3