12 #include <mrpt/core/exceptions.h> 13 #include <mrpt/core/get_env.h> 14 #include <mrpt/expr/CRuntimeCompiledExpression.h> 15 #include <mrpt/random/RandomGenerators.h> 16 #include <mrpt/system/filesystem.h> 17 #include <mrpt/system/os.h> 18 #include <mrpt/system/string_utils.h> 19 #include <mrpt/version.h> 27 mrpt::get_env<bool>(
"MVSIM_VERBOSE_PARSE",
false);
29 using namespace mvsim;
35 const auto start = text.find(
"$env{");
36 if (start == std::string::npos)
return text;
38 const std::string pre = text.substr(0, start);
39 const std::string post = text.substr(start + 5);
41 const auto post_end = post.find(
'}');
42 if (post_end == std::string::npos)
45 "Column=%u: Cannot find matching `}` for `$env{` in: `%s`",
46 static_cast<unsigned int>(start), text.c_str());
49 const auto varname = post.substr(0, post_end);
51 const char* v = ::getenv(varname.c_str());
53 varvalue = std::string(v);
57 "parseEnvVars(): Undefined environment variable found: $env{%s}",
61 return parseEnvVars(pre + varvalue + post.substr(post_end + 1));
66 const std::string& text,
67 const std::map<std::string, std::string>& variableNamesValues)
71 const auto start = text.find(
"${");
72 if (start == std::string::npos)
return text;
74 const std::string pre = text.substr(0, start);
75 const std::string post = text.substr(start + 2);
77 const auto post_end = post.find(
'}');
78 if (post_end == std::string::npos)
81 "Column=%u: Cannot find matching `}` for `${` in: `%s`",
82 static_cast<unsigned int>(start), text.c_str());
85 const auto varname = post.substr(0, post_end);
87 if (
const auto it = variableNamesValues.find(varname);
88 it != variableNamesValues.end())
90 varvalue = it->second;
95 "parseEnvVars(): Undefined variable found: ${%s}", varname.c_str());
98 return parseEnvVars(pre + varvalue + post.substr(post_end + 1));
106 const auto start = text.find(
"$(");
107 if (start == std::string::npos)
return text;
109 const std::string pre = text.substr(0, start);
110 const std::string post = text.substr(start + 2);
112 const auto post_end = post.find(
')');
113 if (post_end == std::string::npos)
116 "Column=%u: Cannot find matching `)` for `$(` in: `%s`",
117 static_cast<unsigned int>(start), text.c_str());
120 const auto cmd = post.substr(0, post_end);
125 int ret = mrpt::system::executeCommand(cmd, &cmdOut);
129 "Error (retval=%i) executing external command: `%s`", ret,
133 cmdOut = mrpt::system::trim(cmdOut);
134 cmdOut.erase(std::remove(cmdOut.begin(), cmdOut.end(),
'\r'), cmdOut.end());
135 cmdOut.erase(std::remove(cmdOut.begin(), cmdOut.end(),
'\n'), cmdOut.end());
137 return parseCmdRuns(pre + cmdOut + post.substr(post_end + 1));
141 #if MRPT_VERSION >= 0x258 142 static double my_rand()
144 auto& rng = mrpt::random::getRandomGenerator();
145 return rng.drawUniform(0.0, 1.0);
147 static double my_unifrnd(
double xMin,
double xMax)
149 auto& rng = mrpt::random::getRandomGenerator();
150 return rng.drawUniform(xMin, xMax);
152 static double randn()
154 auto& rng = mrpt::random::getRandomGenerator();
155 return rng.drawGaussian1D_normalized();
161 const std::string& text,
162 const std::map<std::string, std::string>& variableNamesValues)
166 const auto start = text.find(
"$f{");
167 if (start == std::string::npos)
return text;
169 const std::string pre = text.substr(0, start);
170 const std::string post = text.substr(start + 3);
172 const auto post_end = post.find(
'}');
173 if (post_end == std::string::npos)
176 "Column=%u: Cannot find matching `}` for `${` in: `%s`",
177 static_cast<unsigned int>(start), text.c_str());
180 const auto sExpr = post.substr(0, post_end);
182 mrpt::expr::CRuntimeCompiledExpression expr;
184 #if MRPT_VERSION >= 0x258 185 expr.register_function(
"rand", &my_rand);
186 expr.register_function(
"unifrnd", &my_unifrnd);
187 expr.register_function(
"randn", &randn);
190 std::map<std::string, double> numericVars;
191 for (
const auto& kv : variableNamesValues)
193 std::stringstream ss(kv.second);
196 if (!(ss >> val))
continue;
198 numericVars[kv.first] = val;
202 expr.compile(sExpr, numericVars);
203 const double val = expr.eval();
206 pre + mrpt::format(
"%g", val) + post.substr(post_end + 1));
212 const std::string& input,
213 const std::map<std::string, std::string>& variableNamesValues)
217 std::cout <<
"[mvsim::parse] Input : '" << input <<
"' " 218 <<
" with these variables: ";
219 for (
const auto& kv : variableNamesValues)
220 std::cout << kv.first <<
", ";
224 std::string
s = input;
226 std::string prevValue = s;
227 for (
int iter = 0; iter < 10; iter++)
235 if (s == prevValue)
break;
241 std::cout <<
"[mvsim::parse] Output: '" << s <<
"'\n";
static std::string parseMathExpr(const std::string &text, const std::map< std::string, std::string > &variableNamesValues)
static std::string parseCmdRuns(const std::string &text)
static std::string parseVars(const std::string &text, const std::map< std::string, std::string > &variableNamesValues)
std::string parse(const std::string &input, const std::map< std::string, std::string > &variableNamesValues={})
static std::string parseEnvVars(const std::string &text)
thread_local const bool MVSIM_VERBOSE_PARSE