72 std::string res = str;
75 int rfind_dollars_sign_from = res.size();
76 while(rfind_dollars_sign_from >= 0) {
79 const std::string::size_type var_begin_loc = res.rfind(
'$', rfind_dollars_sign_from);
82 if(var_begin_loc == std::string::npos) {
88 rfind_dollars_sign_from =
static_cast<int>(var_begin_loc) - 1;
91 const std::string::iterator var_begin = res.begin() + var_begin_loc;
94 const std::string::iterator var_name_begin = var_begin + 1;
95 std::string::iterator var_end = var_name_begin;
97 if(var_name_begin == res.end()) {
100 }
else if(*var_name_begin ==
'(') {
102 int paren_nesting_level = 0;
103 bool in_string =
false,
108 if(!in_string && !in_comment) {
109 ++paren_nesting_level;
113 if(!in_string && !in_comment) {
114 --paren_nesting_level;
119 in_comment = !in_comment;
124 in_string = !in_string;
129 }
while(++var_end != res.end() && paren_nesting_level > 0);
131 WRN_NG <<
"Formula substitution ignored (and removed) because WFL engine is not present in the server.";
132 res.replace(var_begin, var_end,
"");
135 if(paren_nesting_level > 0) {
136 ERR_NG <<
"Formula in WML string cannot be evaluated due to "
137 <<
"a missing closing parenthesis:\n\t--> \""
138 << std::string(var_begin, var_end) <<
"\"";
139 res.replace(var_begin, var_end,
"");
147 for(
int bracket_nesting_level = 0; var_end != res.end(); ++var_end) {
148 const char c = *var_end;
150 ++bracket_nesting_level;
153 if(--bracket_nesting_level < 0) {
158 else if (!(((
c) & ~0x7f) == 0) || (!isalnum(
c) &&
c !=
'.' &&
c !=
'_')) {
165 var_end = std::adjacent_find(var_name_begin, var_end,
two_dots);
167 const std::string::iterator default_start = var_end < res.end() && *var_end ==
'?' ? var_end + 1 : res.end();
174 if(*(var_end-1) ==
'.'
181 && *(var_end-2) !=
']') {
185 const std::string var_name(var_name_begin, var_end);
186 if(default_start == res.end()) {
187 if(var_end != res.end() && *var_end ==
'|') {
197 if (var_name.empty()) {
200 res.replace(var_begin, var_end,
"$");
204 res.replace(var_begin, var_end,
205 set.get_variable_const(var_name));
209 var_end = default_start;
210 while(var_end != res.end() && *var_end !=
'|') {
213 const std::string::iterator default_end = var_end;
215 if(var_end == res.end()) {
216 res.replace(var_begin, default_start - 1, val);
218 else if(!val.
empty()) {
219 res.replace(var_begin, var_end + 1, val);
222 res.replace(var_begin, var_end + 1, std::string(default_start, default_end));
321 auto s1_first = str_1.begin();
322 auto s2_first = str_2.begin();
324 while(s1_first != str_1.end() && s2_first != str_2.end() && *s1_first == *s2_first) {
330 auto s1_size =
static_cast<std::size_t
>(str_1.end() - s1_first);
331 auto s2_size =
static_cast<std::size_t
>(str_2.end() - s2_first);
333 while(s1_size != 0 && s2_size != 0 && s1_first[s1_size - 1] == s2_first[s2_size - 1]) {
347 s1_size = std::min(s1_size, std::size_t{15});
348 s2_size = std::min(s2_size, std::size_t{15});
350 if(s1_size < s2_size) {
351 std::swap(s1_first, s2_first);
352 std::swap(s1_size, s2_size);
361 std::array<std::size_t, 16> row{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
363 for(std::size_t
i = 0;
i != s1_size; ++
i) {
367 for(std::size_t j = 0; j != s2_size; ++j) {
368 const auto up = row[j + 1];
369 const bool transposed =
i > 0 && j > 0 && s1_first[
i] == s2_first[j - 1] && s1_first[
i - 1] == s2_first[j];
371 if(s1_first[
i] != s2_first[j] && !transposed) {
372 row[j + 1] = std::min({up, row[j], upper_left}) + 1;
374 row[j + 1] = upper_left;