📄 getpot.h
字号:
_apriori_argv.push_back(std::string("Empty")); __parse_argument_vector(_apriori_argv);}inlineGetPot::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<argc_; ++i) { std::string tmp(argv_[i]); // recall the problem with temporaries, _apriori_argv.push_back(tmp); // reference counting in arguement lists ... } __parse_argument_vector(_apriori_argv);}inlineGetPot::GetPot(const char* FileName, const char* CommentStart /* = 0x0 */, const char* CommentEnd /* = 0x0 */, const char* FieldSeparator/* = 0x0 */) { __basic_initialization(); // if specified -> 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);}inlineGetPot::GetPot(const GetPot& That){ GetPot::operator=(That); }inlineGetPot::~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 voidGetPot::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 voidGetPot::__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_VECTORGetPot::__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_VECTORGetPot::__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 voidGetPot::__skip_whitespace(std::istream& istr){ bool found = false; do { int c = istr.peek(); found = isspace(c); while ((isspace(c)) && (istr)) c = istr.get(); if (found) istr.unget(); c = istr.peek(); found = _comment_start.find(char(c)) != std::string::npos; if (found) { while (((_comment_end.find(c) == std::string::npos)) && (istr)) c = istr.get(); } if (found) istr.unget(); } while (found);}inline const std::stringGetPot::__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::stringGetPot::__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::stringGetPot::__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::stringGetPot::__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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -