📄 getpot.h
字号:
inline const char*GetPot::operator()(const char* VarName, const char* Default, unsigned Idx) const{ 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->c_str();}inline unsignedGetPot::vector_variable_size(const char* VarName) const{ const variable* sv = __find_variable(VarName); if( sv == 0 ) return 0; return sv->value.size();}inline std::vector<std::string>GetPot::get_variable_names() const{ std::vector<std::string> result; for(std::vector<GetPot::variable>::const_iterator it = variables.begin(); it != variables.end(); it++) { const std::string Tmp = __get_remaining_string((*it).name, prefix); if( Tmp != "" ) result.push_back(Tmp); } return result;}inline std::vector<std::string>GetPot::get_section_names() const{ return section_list; }inline const GetPot::variable*GetPot::__find_variable(const char* Name) const{ std::string name = prefix + Name; for(std::vector<variable>::const_iterator it = variables.begin(); 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 = " << argv.size() << std::endl; for(std::vector<std::string>::const_iterator it = argv.begin(); 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; for(unsigned i = 0; i<str.size(); i++) { if( i < str.size() - 2 && str.substr(i, 2) == "${" ) { if( open_brackets == 0 ) first = i+2; open_brackets++; } else if( str[i] == '}' && open_brackets > 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 std::vector<std::string>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; std::vector<std::string> expr_list; unsigned open_brackets = 0; std::vector<unsigned> start_idx; unsigned start_new_string = i; unsigned l = 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>>"); std::vector<std::string> 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) { unsigned 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) str = Replacement + str.substr(i+1); else str = str.substr(0, start-2) + Replacement + str.substr(i+1); l = str.size(); i = start + 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>>"); std::vector<std::string> 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(const 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]; std::sprintf(tmp, "<<${ } 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 std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 1); std::vector<std::string>::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) == "<->" ) { std::vector<std::string> 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] == '+' ) { std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 2); std::vector<std::string>::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] == '-' ) { std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 2); std::vector<std::string>::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] == '*' ) { std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 2); std::vector<std::string>::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] == '/' ) { std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 2); std::vector<std::string>::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] == '^' ) { std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 2); std::vector<std::string>::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; std::vector<std::string> 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; std::vector<std::string>::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) == "??" ) { std::vector<std::string> 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] == '?' ) { std::vector<std::string> 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 std::vector<std::string> A = __DBE_get_expr_list(Var->original, 2); return A[0]; } // ${@: } - string subscription else if( expr.length() >= 2 && expr.substr(0,2) == "@:" ) { const std::vector<std::string> 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] == '@' ) { std::vector<std::string> A = __DBE_get_expr_list(expr.substr(1), 2); const GetPot::variable* Var = __DBE_get_variable(A[0]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -