From: stephan b. <sg...@us...> - 2004-12-26 11:10:12
|
Update of /cvsroot/pclasses/pclasses2/src/Util In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3367/src/Util Modified Files: StringTool.cpp Log Message: Added expandVars() and expandVarsInline(), to expand a map<string,string> as a set of ${vars} in an input string. Index: StringTool.cpp =================================================================== RCS file: /cvsroot/pclasses/pclasses2/src/Util/StringTool.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- StringTool.cpp 26 Dec 2004 10:42:05 -0000 1.1 +++ StringTool.cpp 26 Dec 2004 11:10:00 -0000 1.2 @@ -215,4 +215,105 @@ map["\""] = "\\\""; } -}} // P::StringTool + std::string + expandVars( const EntityMap & src, const std::string & text ) + { + std::string foo = text; + expandVarsInline( src, foo ); + return foo; + } + + size_t + expandVarsInline( const EntityMap & src, std::string & buffer ) + { + //CERR << "expandVars(["<<buffer<<"])"<<std::endl; + if( buffer.size() < 2 ) return 0; + + EntityMap::const_iterator entit, entet = src.end(); + + std::string::size_type posA = 0, posB = 0; + static const char vardelim = '$'; + posA = buffer.find( vardelim ); + if( std::string::npos == posA ) + { + return 0; + } + static const char opener = '{'; + static const char closer = '}'; + size_t count = 0; + static const std::string allowable_chars = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_?"; + // ^^^^^^ why is '?' in the list? So that eshell can support the shell-ish $? var :/. + char atc; + posA = buffer.size() - 1; + bool slashmode = false; + std::string varname; + for( ; posA >= 0 && posA != std::string::npos; posA-- ) + { + atc = buffer[posA]; + if( atc != vardelim ) + { + continue; + } + if( posA>0 && !slashmode && buffer[posA-1] == '\\' ) slashmode = true; + if( slashmode ) + { + slashmode = false; + continue; + } + posB = buffer.find_first_not_of( allowable_chars, posA+1 ); // find first non-variablename char + if( posB != posA +1 ) posB -= 1; + if( posB == std::string::npos ) + { + posB = buffer.size() -1; + } + + if( posB == posA + 1 ) // ${VAR} or $F, hopefully + { + atc = buffer[posB]; + if( atc != opener ) + { + // $NONBRACED_VAR + posB = buffer.find_first_not_of( allowable_chars, posB ); + varname = buffer.substr( posA + 1, posB ); + //CERR << "nonbraced var? ["<<varname<<"]\n"; + // varname += atc; + // if( varname.find_first_of( allowable_chars ) != 0 ) + // { + // varname = string(); + // } + + } + else // ${VAR} + { + //cout << "Activating Bat-parser! atc="<<atc<<" posA="<<posA<<" posB="<<posB << endl; + const size_t maxpos = buffer.size()-1; + while( atc != closer && posB <= maxpos ) + { // extract variable-name part: + atc = buffer[++posB]; + if ( atc != closer ) varname += atc; + } + } + } + else + { + // extract variable-name part: + varname = buffer.substr( posA+1 /*skip '$'*/, posB-posA ); + } + //CERR << "expandVars(): varname=["<<varname<<"]"<<endl; + if( varname.empty() ) continue; + + entit = src.find( varname ); + if( entet == entit ) continue;// don't expand unknown vars to empty strings. + varname = (*entit).second; + //CERR << "expandVars(): expanded varname=["<<varname<<"]"<<endl; + ++count; + buffer.erase( posA, posB - posA +1 ); + buffer.insert( posA, varname.c_str() ); + varname.clear(); + } + return count; + } + + +} } // P::StringTool |