mirror of
https://github.com/ksherlock/mpw.git
synced 2024-06-06 19:29:45 +00:00
356 lines
4.7 KiB
C++
356 lines
4.7 KiB
C++
/* Generated by re2c 0.13.5 on Sat May 18 16:26:02 2013 */
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include <cstdio>
|
|
|
|
/*
|
|
* #...comment
|
|
* var=value
|
|
* where value may contain $var and ${var} interpolations.
|
|
*
|
|
*/
|
|
|
|
namespace MPW {
|
|
std::string EvalString(std::string &s, std::unordered_map<std::string, std::string> &env)
|
|
{
|
|
|
|
std::string rv;
|
|
const char *cp = s.c_str();
|
|
const char *marker = NULL;
|
|
|
|
while (*cp)
|
|
{
|
|
const char *begin = cp;
|
|
|
|
|
|
{
|
|
char yych;
|
|
|
|
yych = (char)*cp;
|
|
switch (yych) {
|
|
case '\n': goto yy5;
|
|
case '$': goto yy2;
|
|
default: goto yy4;
|
|
}
|
|
yy2:
|
|
yych = (char)*(marker = ++cp);
|
|
switch (yych) {
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
case 'E':
|
|
case 'F':
|
|
case 'G':
|
|
case 'H':
|
|
case 'I':
|
|
case 'J':
|
|
case 'K':
|
|
case 'L':
|
|
case 'M':
|
|
case 'N':
|
|
case 'O':
|
|
case 'P':
|
|
case 'Q':
|
|
case 'R':
|
|
case 'S':
|
|
case 'T':
|
|
case 'U':
|
|
case 'V':
|
|
case 'W':
|
|
case 'X':
|
|
case 'Y':
|
|
case 'Z':
|
|
case '_':
|
|
case 'a':
|
|
case 'b':
|
|
case 'c':
|
|
case 'd':
|
|
case 'e':
|
|
case 'f':
|
|
case 'g':
|
|
case 'h':
|
|
case 'i':
|
|
case 'j':
|
|
case 'k':
|
|
case 'l':
|
|
case 'm':
|
|
case 'n':
|
|
case 'o':
|
|
case 'p':
|
|
case 'q':
|
|
case 'r':
|
|
case 's':
|
|
case 't':
|
|
case 'u':
|
|
case 'v':
|
|
case 'w':
|
|
case 'x':
|
|
case 'y':
|
|
case 'z': goto yy9;
|
|
case '{': goto yy7;
|
|
default: goto yy3;
|
|
}
|
|
yy3:
|
|
{
|
|
rv.push_back(*begin);
|
|
continue;
|
|
}
|
|
yy4:
|
|
yych = (char)*++cp;
|
|
goto yy3;
|
|
yy5:
|
|
++cp;
|
|
{
|
|
break;
|
|
}
|
|
yy7:
|
|
yych = (char)*++cp;
|
|
switch (yych) {
|
|
case '}': goto yy8;
|
|
default: goto yy13;
|
|
}
|
|
yy8:
|
|
cp = marker;
|
|
goto yy3;
|
|
yy9:
|
|
++cp;
|
|
yych = (char)*cp;
|
|
switch (yych) {
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
case 'E':
|
|
case 'F':
|
|
case 'G':
|
|
case 'H':
|
|
case 'I':
|
|
case 'J':
|
|
case 'K':
|
|
case 'L':
|
|
case 'M':
|
|
case 'N':
|
|
case 'O':
|
|
case 'P':
|
|
case 'Q':
|
|
case 'R':
|
|
case 'S':
|
|
case 'T':
|
|
case 'U':
|
|
case 'V':
|
|
case 'W':
|
|
case 'X':
|
|
case 'Y':
|
|
case 'Z':
|
|
case '_':
|
|
case 'a':
|
|
case 'b':
|
|
case 'c':
|
|
case 'd':
|
|
case 'e':
|
|
case 'f':
|
|
case 'g':
|
|
case 'h':
|
|
case 'i':
|
|
case 'j':
|
|
case 'k':
|
|
case 'l':
|
|
case 'm':
|
|
case 'n':
|
|
case 'o':
|
|
case 'p':
|
|
case 'q':
|
|
case 'r':
|
|
case 's':
|
|
case 't':
|
|
case 'u':
|
|
case 'v':
|
|
case 'w':
|
|
case 'x':
|
|
case 'y':
|
|
case 'z': goto yy9;
|
|
default: goto yy11;
|
|
}
|
|
yy11:
|
|
{
|
|
std::string tmp(begin + 1, cp);
|
|
|
|
// lookup value...
|
|
// append to rv.
|
|
auto iter = env.find(tmp);
|
|
if (iter != env.end())
|
|
{
|
|
rv.append(iter->second);
|
|
}
|
|
continue;
|
|
}
|
|
yy12:
|
|
++cp;
|
|
yych = (char)*cp;
|
|
yy13:
|
|
switch (yych) {
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
case 'E':
|
|
case 'F':
|
|
case 'G':
|
|
case 'H':
|
|
case 'I':
|
|
case 'J':
|
|
case 'K':
|
|
case 'L':
|
|
case 'M':
|
|
case 'N':
|
|
case 'O':
|
|
case 'P':
|
|
case 'Q':
|
|
case 'R':
|
|
case 'S':
|
|
case 'T':
|
|
case 'U':
|
|
case 'V':
|
|
case 'W':
|
|
case 'X':
|
|
case 'Y':
|
|
case 'Z':
|
|
case '_':
|
|
case 'a':
|
|
case 'b':
|
|
case 'c':
|
|
case 'd':
|
|
case 'e':
|
|
case 'f':
|
|
case 'g':
|
|
case 'h':
|
|
case 'i':
|
|
case 'j':
|
|
case 'k':
|
|
case 'l':
|
|
case 'm':
|
|
case 'n':
|
|
case 'o':
|
|
case 'p':
|
|
case 'q':
|
|
case 'r':
|
|
case 's':
|
|
case 't':
|
|
case 'u':
|
|
case 'v':
|
|
case 'w':
|
|
case 'x':
|
|
case 'y':
|
|
case 'z': goto yy12;
|
|
case '}': goto yy14;
|
|
default: goto yy8;
|
|
}
|
|
yy14:
|
|
++cp;
|
|
{
|
|
|
|
std::string tmp(begin + 2, cp - 1);
|
|
|
|
auto iter = env.find(tmp);
|
|
if (iter != env.end())
|
|
{
|
|
rv.append(iter->second);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
void LoadEnvironment(std::string &envfile, std::unordered_map<std::string, std::string> &env)
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
|
|
fp = fopen(envfile.c_str(), "r");
|
|
|
|
if (!fp) return;
|
|
|
|
for (;;)
|
|
{
|
|
char *begin;
|
|
char *end;
|
|
char *iter;
|
|
|
|
size_t length;
|
|
|
|
begin = fgetln(fp, &length);
|
|
if (!begin) break; // eof or error.
|
|
|
|
if (!length) continue;
|
|
if (begin[0] == '#') continue;
|
|
|
|
while (length && isspace(begin[length - 1])) --length;
|
|
if (!length) continue;
|
|
|
|
// key=value
|
|
|
|
// ehh, this could really check for [A-Za-z0-9_]+ '='
|
|
|
|
end = begin + length;
|
|
iter = std::find(begin, end, '=');
|
|
|
|
if (iter == end || iter == begin)
|
|
{
|
|
fprintf(stderr, "Invalid Environment entry: %.*s\n", length, begin);
|
|
continue;
|
|
}
|
|
|
|
std::string key(begin, iter);
|
|
std::string value(iter + 1, end);
|
|
|
|
value = EvalString(value, env);
|
|
|
|
//fprintf(stdout, "%s = %s\n", key.c_str(), value.c_str());
|
|
|
|
// todo -- does this replace an existing value?
|
|
env.emplace(key, value);
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
} |