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>
28 using namespace mvsim;
32 std::string parseEnvVars(
const std::string& text)
36 const auto start = text.find(
"$env{");
37 if (start == std::string::npos)
return text;
39 const std::string pre = text.substr(0, start);
40 const std::string post = text.substr(start + 5);
42 const auto post_end = post.find(
'}');
43 if (post_end == std::string::npos)
46 "Column=%u: Cannot find matching `}` for `$env{` in: `%s`",
47 static_cast<unsigned int>(start), text.c_str());
50 const auto varname = post.substr(0, post_end);
52 const char* v = ::getenv(varname.c_str());
54 varvalue = std::string(v);
58 "parseEnvVars(): Undefined environment variable found: $env{%s}", varname.c_str());
61 return parseEnvVars(pre + varvalue + post.substr(post_end + 1));
66 const std::string& text,
const std::map<std::string, std::string>& variableNamesValues)
70 const auto start = text.find(
"${");
71 if (start == std::string::npos)
return text;
73 const std::string pre = text.substr(0, start);
74 const std::string post = text.substr(start + 2);
76 const auto post_end = post.find(
'}');
77 if (post_end == std::string::npos)
80 "Column=%u: Cannot find matching `}` for `${` in: `%s`",
81 static_cast<unsigned int>(start), text.c_str());
84 const auto varname = post.substr(0, post_end);
86 if (
const auto it = variableNamesValues.find(varname); it != variableNamesValues.end())
88 varvalue = it->second;
93 for (
const auto& kv : variableNamesValues)
100 "parseVars(): Undefined variable found: ${%s}. Known ones are: %s", varname.c_str(),
104 return parseVars(pre + varvalue + post.substr(post_end + 1), variableNamesValues);
108 std::string parseCmdRuns(
const std::string& text)
112 const auto start = text.find(
"$(");
113 if (start == std::string::npos)
return text;
115 const std::string pre = text.substr(0, start);
116 const std::string post = text.substr(start + 2);
118 const auto post_end = post.find(
')');
119 if (post_end == std::string::npos)
122 "Column=%u: Cannot find matching `)` for `$(` in: `%s`",
123 static_cast<unsigned int>(start), text.c_str());
126 const auto cmd = post.substr(0, post_end);
131 int ret = mrpt::system::executeCommand(cmd, &cmdOut);
134 THROW_EXCEPTION_FMT(
"Error (retval=%i) executing external command: `%s`", ret,
cmd.c_str());
138 cmdOut.erase(std::remove(cmdOut.begin(), cmdOut.end(),
'\r'), cmdOut.end());
139 cmdOut.erase(std::remove(cmdOut.begin(), cmdOut.end(),
'\n'), cmdOut.end());
141 return parseCmdRuns(pre + cmdOut + post.substr(post_end + 1));
147 auto& rng = mrpt::random::getRandomGenerator();
148 return rng.drawUniform(0.0, 1.0);
150 double my_unifrnd(
double xMin,
double xMax)
152 auto& rng = mrpt::random::getRandomGenerator();
153 return rng.drawUniform(xMin, xMax);
157 auto& rng = mrpt::random::getRandomGenerator();
158 return rng.drawGaussian1D_normalized();
160 double randomize(
double seed)
162 auto& rng = mrpt::random::getRandomGenerator();
168 std::string parseMathExpr(
169 const std::string& text,
const std::map<std::string, std::string>& variableNamesValues)
173 const auto start = text.find(
"$f{");
174 if (start == std::string::npos)
return text;
176 const std::string pre = text.substr(0, start);
177 const std::string post = text.substr(start + 3);
179 const auto post_end = post.find(
'}');
180 if (post_end == std::string::npos)
183 "Column=%u: Cannot find matching `}` for `${` in: `%s`",
184 static_cast<unsigned int>(start), text.c_str());
187 const auto sExpr = post.substr(0, post_end);
189 mrpt::expr::CRuntimeCompiledExpression expr;
191 expr.register_function(
"rand", &my_rand);
192 expr.register_function(
"unifrnd", &my_unifrnd);
193 expr.register_function(
"randn", &randn);
194 expr.register_function(
"randomize", &randomize);
196 std::map<std::string, double> numericVars;
197 for (
const auto& kv : variableNamesValues)
199 std::stringstream ss(kv.second);
202 if (!(ss >> val))
continue;
204 numericVars[kv.first] = val;
208 expr.compile(sExpr, numericVars);
209 const double val = expr.eval();
211 return parseCmdRuns(pre + mrpt::format(
"%g", val) + post.substr(post_end + 1));
218 const std::string& input,
const std::map<std::string, std::string>& variableNamesValues)
222 std::cout <<
"[mvsim::parse] Input : '" << input <<
"' "
223 <<
"with these variables: ";
224 for (
const auto& kv : variableNamesValues) std::cout << kv.first <<
", ";
228 std::string
s = input;
230 std::string prevValue =
s;
231 for (
int iter = 0; iter < 10; iter++)
236 s = parseMathExpr(
s, variableNamesValues);
239 if (
s == prevValue)
break;
245 std::cout <<
"[mvsim::parse] Output: '" <<
s <<
"'\n";
254 while (!out.empty() && (out[0] ==
'\r' || out[0] ==
'\n')) out.erase(0, 1);