27#define REGEX_PARAM "\\?\\(([a-zA-Z0-9_-]+)((\\|/([^/]+)/([^/]+)/)*)\\)(s|S|i|f|y|Y)"
115 const std::string &skill_string_template)
117 mappings_[action_name] = skill_string_template;
127 return (mappings_.find(action_name) != mappings_.end());
140 const std::map<std::string, std::string> ¶ms,
141 std::multimap<std::string, std::string> & messages)
const
145 auto mapping = mappings_.find(name);
146 if (mapping == mappings_.end())
148 std::string remainder = mapping->second;
150 std::regex re(REGEX_PARAM);
152 while (std::regex_search(remainder, m, re)) {
154 for (
const auto &p : params) {
155 std::string value = p.second;
156 if (p.first == m[1].str()) {
160 if (!m[2].str().empty()) {
161 std::string rstr = m[2].str();
162 std::list<std::string> rlst;
163 std::string::size_type rpos = 0, fpos = 0;
164 while ((fpos = rstr.find(
'|', rpos)) != std::string::npos) {
165 std::string substr = rstr.substr(rpos, fpos - rpos);
167 rlst.push_back(substr);
170 rstr = rstr.substr(rpos);
172 rlst.push_back(rstr);
174 for (
const auto &r : rlst) {
175 if (r.size() > 2 && r[0] ==
'/' && r[r.size() - 1] ==
'/') {
176 std::string::size_type slash_pos = r.find(
'/', 1);
177 if (slash_pos != std::string::npos && slash_pos < (r.size() - 1)) {
178 std::string r_match = r.substr(1, slash_pos - 1);
179 std::string r_repl = r.substr(slash_pos + 1, (r.size() - slash_pos - 2));
180 std::regex user_regex(r_match, std::regex::ECMAScript | std::regex::icase);
181 value = std::regex_replace(value, user_regex, r_repl);
184 std::make_pair(
"WARN",
" regex '" + r +
"' missing mid slash, ignoring"));
188 std::make_pair(
"WARN",
"regex '" + r +
"' missing start/end slashes, ignoring"));
193 switch (m[6].str()[0]) {
194 case 's': rv +=
"\"" + value +
"\"";
break;
196 std::string uc = value;
197 std::transform(uc.begin(), uc.end(), uc.begin(), ::toupper);
198 rv +=
"\"" + uc +
"\"";
200 case 'y': rv += value;
break;
202 std::string uc = value;
203 std::transform(uc.begin(), uc.end(), uc.begin(), ::toupper);
206 case 'i':
try { rv += std::to_string(std::stol(value));
207 }
catch (std::invalid_argument &e) {
209 std::make_pair(
"ERROR",
"Failed to convert '" + value +
"' to integer: " + e.what()));
214 case 'f':
try { rv += std::to_string(std::stod(value));
215 }
catch (std::invalid_argument &e) {
217 std::make_pair(
"ERROR",
"Failed to convert '" + value +
"' to float: " + e.what()));
226 messages.insert(std::make_pair(
"ERROR",
227 "No value for parameter '" + m[1].str() +
"' of action '"
228 + name +
"' given"));
232 remainder = m.suffix();
void add_mapping(const std::string &action_name, const std::string &skill_string_template)
Add another mapping.
std::string map_skill(const std::string &name, const std::map< std::string, std::string > ¶ms, std::multimap< std::string, std::string > &messages) const
Perform mapping.
bool has_mapping(const std::string &action_name) const
Check if mapping for an action exists.
ActionSkillMapping()
Constructor.
Fawkes library namespace.