Created
March 25, 2014 05:06
-
-
Save beyondwdq/9755557 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Compile: g++ -std=c++11 -Wall replace_var.cc -o replace_var | |
// Tested with g++-4.7.2 | |
#include <string> | |
#include <map> | |
#include <cctype> | |
#include <iostream> | |
typedef std::map<std::string, std::string> TVarMap; | |
using namespace std; | |
constexpr char kVarBegin[] = "$("; | |
constexpr char kVarEnd = ')'; | |
constexpr size_t kVarBeginLen = sizeof(kVarBegin) - 1; | |
/****************************************** | |
* A helper function to extract the variable | |
* name. Invoked by replaceVars() | |
* ****************************************/ | |
std::string extractVar(const std::string &buf, size_t bpos, size_t epos) | |
{ | |
bpos += kVarBeginLen; | |
--epos; | |
while (std::isspace(buf[bpos])) ++bpos; | |
while (std::isspace(buf[epos])) --epos; | |
if (bpos > epos) return std::string(); | |
return buf.substr(bpos, epos - bpos + 1); | |
} | |
/************************************************* | |
* Replace the variables with their values defined | |
* in varmap. A variable is identified by $(var). | |
* Example: | |
* let varmap = {"x"="1", "y"="2", z="3"} | |
* buf = "$(x) + $(y) = $(z)" | |
* The content in buf at the end of this functions is: | |
* buf = "1 + 2 = 3" | |
* Nested variable is allowed. See the example in main(). | |
* | |
* Return number of replacements happened on success, | |
* -1 on failure. | |
* ************************************************/ | |
int replaceVars(std::string &buf, const TVarMap &varmap) | |
{ | |
int pos = 0; | |
int cnt = 0; | |
for(auto epos = buf.find(kVarEnd, 0); | |
epos != std::string::npos && pos < (int)buf.size(); | |
epos = buf.find(kVarEnd, pos)) { | |
pos = epos + 1; | |
if (epos > kVarBeginLen) { | |
auto bpos = buf.rfind(kVarBegin, epos - 1); | |
if (bpos == std::string::npos) continue; | |
auto var = extractVar(buf, bpos, epos); | |
auto it = varmap.find(var); | |
if (it == varmap.end()) { | |
cerr << "variable '" << var << "' not defined" << endl; | |
return -1; | |
} | |
int len = epos - bpos + 1; | |
buf.replace(bpos, len, it->second); | |
pos += (int)it->second.size() - len; | |
++cnt; | |
} | |
} | |
return cnt; | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
string buf("$( x ) + $( y) = $($(z))"); | |
TVarMap varmap{{"x", "1"}, {"y", "2"}, {"xy", "3"}, {"z", "xy"}}; | |
int cnt = replaceVars(buf, varmap); | |
cout << cnt << endl; | |
cout << buf << endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment