16 #define GETTEXT_DOMAIN "wesnoth-lib" 26 #define ERR_NG LOG_STREAM(err, log_engine) 27 #define WRN_NG LOG_STREAM(warn, log_engine) 29 static bool two_dots(
char a,
char b) {
return a ==
'.' && b ==
'.'; }
46 const auto itor = map_.find(key);
47 if (itor != map_.end())
54 for(
const auto&
p : map_) {
55 temp_->insert(
p.first,
p.second);
60 const std::map<std::string,T>&
map_;
61 mutable std::shared_ptr<config>
temp_;
67 std::string res = str;
70 int rfind_dollars_sign_from = res.size();
71 while(rfind_dollars_sign_from >= 0) {
74 const std::string::size_type var_begin_loc = res.rfind(
'$', rfind_dollars_sign_from);
77 if(var_begin_loc == std::string::npos) {
83 rfind_dollars_sign_from =
static_cast<int>(var_begin_loc) - 1;
92 if(var_name_begin == res.end()) {
95 }
else if(*var_name_begin ==
'(') {
97 int paren_nesting_level = 0;
98 bool in_string =
false,
103 if(!in_string && !in_comment) {
104 ++paren_nesting_level;
108 if(!in_string && !in_comment) {
109 --paren_nesting_level;
114 in_comment = !in_comment;
119 in_string = !in_string;
124 }
while(++var_end != res.end() && paren_nesting_level > 0);
126 WRN_NG <<
"Formula substitution ignored (and removed) because WFL engine is not present in the server.\n";
127 res.replace(var_begin, var_end,
"");
130 if(paren_nesting_level > 0) {
131 ERR_NG <<
"Formula in WML string cannot be evaluated due to " 132 <<
"a missing closing parenthesis:\n\t--> \"" 133 << std::string(var_begin, var_end) <<
"\"\n";
134 res.replace(var_begin, var_end,
"");
142 for(
int bracket_nesting_level = 0; var_end != res.end(); ++var_end) {
143 const char c = *var_end;
145 ++bracket_nesting_level;
148 if(--bracket_nesting_level < 0) {
153 else if (!(((c) & ~0x7f) == 0) || (!isalnum(c) && c !=
'.' && c !=
'_')) {
160 var_end = std::adjacent_find(var_name_begin, var_end,
two_dots);
162 const std::string::iterator default_start = var_end < res.end() && *var_end ==
'?' ? var_end + 1 : res.end();
169 if(*(var_end-1) ==
'.' 176 && *(var_end-2) !=
']') {
180 const std::string var_name(var_name_begin, var_end);
181 if(default_start == res.end()) {
182 if(var_end != res.end() && *var_end ==
'|') {
192 if (var_name.empty()) {
195 res.replace(var_begin, var_end,
"$");
199 res.replace(var_begin, var_end,
200 set.get_variable_const(var_name));
204 var_end = default_start;
205 while(var_end != res.end() && *var_end !=
'|') {
210 if(var_end == res.end()) {
211 res.replace(var_begin, default_start - 1, val);
213 else if(!val.
empty()) {
214 res.replace(var_begin, var_end + 1, val);
217 res.replace(var_begin, var_end + 1, std::string(default_start, default_end));
246 if(!tstr.
str().empty()) {
248 if(tstr.
str() != interp) {
256 switch(elems.size()) {
257 case 0:
return empty;
258 case 1:
return elems[0];
260 case 2:
return VGETTEXT(
"conjunct pair^$first and $second", {{
"first", elems[0]}, {
"second", elems[1]}});
263 std::string prefix =
VGETTEXT(
"conjunct start^$first, $second", {{
"first", elems[0]}, {
"second", elems[1]}});
265 for(std::size_t
i = 2;
i < elems.size() - 1;
i++) {
267 prefix =
VGETTEXT(
"conjunct mid^$prefix, $next", {{
"prefix", prefix}, {
"next", elems[
i]}});
270 return VGETTEXT(
"conjunct end^$prefix, and $last", {{
"prefix", prefix}, {
"last", elems.back()}});
274 switch(elems.size()) {
275 case 0:
return empty;
276 case 1:
return elems[0];
278 case 2:
return VGETTEXT(
"disjunct pair^$first or $second", {{
"first", elems[0]}, {
"second", elems[1]}});
281 std::string prefix =
VGETTEXT(
"disjunct start^$first, $second", {{
"first", elems[0]}, {
"second", elems[1]}});
283 for(std::size_t
i = 2;
i < elems.size() - 1;
i++) {
285 prefix =
VGETTEXT(
"disjunct mid^$prefix, $next", {{
"prefix", prefix}, {
"next", elems[
i]}});
288 return VGETTEXT(
"disjunct end^$prefix, or $last", {{
"prefix", prefix}, {
"last", elems.back()}});
294 return _(
"timespan^expired");
297 typedef std::tuple<std::time_t, const char*, const char*> time_factor;
300 time_factor{ 31104000,
N_(
"timespan^$num year"),
N_(
"timespan^$num years") },
301 time_factor{ 2592000,
N_(
"timespan^$num month"),
N_(
"timespan^$num months") },
302 time_factor{ 604800,
N_(
"timespan^$num week"),
N_(
"timespan^$num weeks") },
303 time_factor{ 86400,
N_(
"timespan^$num day"),
N_(
"timespan^$num days") },
304 time_factor{ 3600,
N_(
"timespan^$num hour"),
N_(
"timespan^$num hours") },
305 time_factor{ 60,
N_(
"timespan^$num minute"),
N_(
"timespan^$num minutes") },
306 time_factor{ 1,
N_(
"timespan^$num second"),
N_(
"timespan^$num seconds") },
309 std::vector<t_string> display_text;
313 const int amount = time / std::get<0>(factor);
316 time -= std::get<0>(factor) * amount;
317 i18n[
"num"] = std::to_string(amount);
318 const auto fmt = amount == 1 ? std::get<1>(factor) : std::get<2>(factor);
319 display_text.emplace_back(
VGETTEXT(fmt, i18n));
338 const char* singular,
std::string format_timespan(std::time_t time)
Formats a timespan into human-readable text.
bool empty() const
Tests for an attribute that either was never set or was set to "".
std::string format_conjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a conjunctive list.
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
std::map< std::string, t_string > string_map
Variant for storing WML attributes.
std::string dsngettext(const char *domainname, const char *singular, const char *plural, int n)
std::shared_ptr< config > temp_
std::string format_disjunct_list(const t_string &empty, const std::vector< t_string > &elems)
Format a disjunctive list.
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
static std::string _(const char *str)
Definitions for the interface to Wesnoth Markup Language (WML).
const std::map< std::string, T > & map_
std::string dsgettext(const char *domainname, const char *msgid)
variable_info< const variable_info_implementation::vi_policy_const > variable_access_const
Read-only access.
virtual config::attribute_value get_variable_const(const std::string &key) const
virtual variable_access_const get_variable_access_read(const std::string &varname) const
string_map_variable_set(const std::map< std::string, T > &map)
std::string(* evaluate_formula)(const std::string &formula)
Information on a WML variable.
Standard logging facilities (interface).
A config object defines a single node in a WML file, with access to child nodes.
const std::string & str() const
t_string interpolate_variables_into_tstring(const t_string &tstr, const variable_set &variables)
Function that does the same as the above, for t_stringS.
std::string::const_iterator iterator