
The vgettext() function, while declared in src/formula/string_utils.hpp, actually has its implementation out-of-line in src/formula/string_utils.cpp where GETTEXT_TEXTDOMAIN is defined to "wesnoth-lib". Because vgettext() is implemented in terms of the _() function (an inline wrapper around translation::dsgettext()), it passes the textdomain defined in the file where it was implemented as a parameter. This means that every case of vgettext() being used in other code units where GETTEXT_TEXTDOMAIN is not defined to "wesnoth-lib", is broken if the string being looked upon doesn't coincidentally exist in the wesnoth-lib textdomain. Ages ago, to work around this limitation, an overload of vgettext() that takes the textdomain name as a parameter was introduced (see commit 0ba3d05204abff72f7d95cf11a91536dab5aa20a). Since this form of vgettext() is rather unwieldy to use (and in particular, the xgettext message extraction tool mistakes the first argument for the msgid, see below), a VGETTEXT() macro was also added that uses the GETTEXT_TEXTDOMAIN symbol defined in the file where the call is made, and thus we get the correct string from the correct textdomain. Switching all cases of naked vgettext() in mainline to VGETTEXT() fixes a myriad of situations where an interpolated string that has an extant translation does not actually get translated in practice because of the mismatched textdomain reference (see issue #2709 for an example with MP game titles). I couldn't find any cases of the companion vngettext() function (which handles plurals) being used in the wild naked, but for future reference it also has a companion VNGETTEXT() macro to pass the correct textdomain to its textdomain-parameter overload. One caveat is that this commit DOES break the string freeze in one particular case -- src/units/unit.cpp has a case where the textdomain-parameter version of naked vgettext() was in use with "wesnoth" as the first parameter, and xgettext misidentified this as a translation entry for a "wesnoth" string in the file's assigned textdomain (which is the default textdomain, wesnoth). So this will result in the next pot-update both removing the spurious "wesnoth" string AND adding the correct string to the relevant catalogue template ("<span color=\"$color\">$number_or_percent</span> HP"). to that textdomain. Other than that, I believe this does not break the string freeze in any other fashion and it shouldn't result in any regressions for i18n. It might be worth considering in the future renaming vgettext() and vngettext() to names that make people less likely to misidentify them as functions they can freely call directly without regard to the textdomain assignment issue. (cherry-picked from commit c5b3947e4a837dc98868e3b2c3fa55668fec27a4)
About
The Battle for Wesnoth is an Open Source, turn-based tactical strategy game with a high fantasy theme, featuring both singleplayer and online/hotseat multiplayer combat. Fight a desperate battle to reclaim the throne of Wesnoth, or take hand in any number of other adventures.
License
Please see the wiki for information regarding The Battle for Wesnoth's licensing:
https://wiki.wesnoth.org/Wesnoth:Copyrights
Installing
See INSTALL for instructions on how to build the game from source code.
More Information
For extensive documentation about all aspects of the game, see the official Battle for Wesnoth web site.
A (translated) description of how to play the game can be found in doc/manual/manual.*.html, or online at:
https://wiki.wesnoth.org/WesnothManual
The official Battle for Wesnoth Forums (with over 400,000 posts from more than 20,000 registered members) can be found at: