Skip to content

Commit 3441490

Browse files
committed
Optionally re-allow passing variables to translation macros
Defining wxNO_REQUIRE_LITERAL_MSGIDS enables the old behaviour, where translation macros do accept variables as string arguments. The arguments nearly always need to be string literals, though, and before defining this macro, it is advisable to check whether the code should be fixed instead.
1 parent 2816e7a commit 3441490

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

docs/doxygen/mainpages/const_cpp.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,15 @@ more details.
407407
the applications using the library to disable implicit
408408
conversions from and to <tt>const char*</tt> in wxString class.
409409
Support for this option appeared in wxWidgets 3.1.4.}
410+
@itemdef{wxNO_REQUIRE_LITERAL_MSGIDS,
411+
this symbol is not defined by wxWidgets itself, but can be defined by
412+
the applications using the library to allow variables as string arguments to
413+
translation macros such as _() and wxPLURAL. The default since wxWidgets
414+
3.3.0 is to allow only string literals.
415+
Note that passing string variables as arguments to translation macros is
416+
likely to be a bug, and does not produce the expected results. If you
417+
feel you need to define this macro, you should first consider whether
418+
your code is doing the right thing.}
410419
@itemdef{WXMAKINGDLL_XXX,
411420
used internally and defined when building the
412421
library @c XXX as a DLL; when a monolithic wxWidgets build is used only a

include/wx/translation.h

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,16 @@ using wxTranslationsHashMap = std::unordered_map<wxString, wxString>;
4848
#define _(s) wxUnderscoreWrapper((s))
4949
#endif
5050

51-
#define wxPLURAL(sing, plur, n) wxwxPluralWrapper((sing), (plur), n)
51+
#define wxPLURAL(sing, plur, n) wxPluralWrapper((sing), (plur), n)
5252

5353
// wx-specific macro for translating strings in the given context: if you use
5454
// them, you need to also add
5555
// --keyword="wxGETTEXT_IN_CONTEXT:1c,2" --keyword="wxGETTEXT_IN_CONTEXT_PLURAL:1c,2,3"
5656
// options to xgettext invocation.
5757
#define wxGETTEXT_IN_CONTEXT(c, s) \
58-
wxwxGettextInContextWrapper((c), (s))
58+
wxGettextInContextWrapper((c), (s))
5959
#define wxGETTEXT_IN_CONTEXT_PLURAL(c, sing, plur, n) \
60-
wxwxGettextInContextPluralWrapper((c), (sing), (plur), (n))
60+
wxGettextInContextPluralWrapper((c), (sing), (plur), (n))
6161

6262
// another one which just marks the strings for extraction, but doesn't
6363
// perform the translation (use -kwxTRANSLATE with xgettext!)
@@ -335,6 +335,9 @@ inline const wxString& wxGetTranslation(const char *str1,
335335

336336
#endif // wxNO_IMPLICIT_WXSTRING_ENCODING
337337

338+
namespace wxTransImplStrict
339+
{
340+
338341
// Wrapper functions that only accept string literals as arguments,
339342
// not variables, not char* pointers.
340343
template<size_t N>
@@ -348,7 +351,7 @@ const wxString &wxUnderscoreWrapper(const char (&msg)[N])
348351
}
349352

350353
template<size_t M, size_t N>
351-
const wxString& wxwxPluralWrapper(const char(&msg)[M], const char(&plural)[N], int count)
354+
const wxString &wxPluralWrapper(const char (&msg)[M], const char (&plural)[N], int count)
352355
{
353356
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
354357
return wxGetTranslation(msg, plural, count);
@@ -358,7 +361,7 @@ const wxString& wxwxPluralWrapper(const char(&msg)[M], const char(&plural)[N], i
358361
}
359362

360363
template<size_t M, size_t N>
361-
const wxString& wxwxGettextInContextWrapper(const char(&ctx)[M], const char(&msg)[N])
364+
const wxString &wxGettextInContextWrapper(const char (&ctx)[M], const char (&msg)[N])
362365
{
363366
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
364367
return wxGetTranslation(msg, wxString(), ctx);
@@ -368,7 +371,7 @@ const wxString& wxwxGettextInContextWrapper(const char(&ctx)[M], const char(&msg
368371
}
369372

370373
template<size_t L, size_t M, size_t N>
371-
const wxString &wxwxGettextInContextPluralWrapper(const char (&ctx)[L],
374+
const wxString &wxGettextInContextPluralWrapper(const char (&ctx)[L],
372375
const char (&msg)[M],
373376
const char (&plural)[N], int count)
374377
{
@@ -380,6 +383,60 @@ const wxString &wxwxGettextInContextPluralWrapper(const char (&ctx)[L],
380383
#endif
381384
}
382385

386+
} // namespace wxTransImplStrict
387+
388+
namespace wxTransImplTraditional
389+
{
390+
391+
// Wrapper functions that accept both string literals and variables
392+
// as arguments.
393+
inline const wxString &wxUnderscoreWrapper(const wxString& msg)
394+
{
395+
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
396+
return wxGetTranslation(msg);
397+
#else
398+
return wxGetTranslation(wxASCII_STR(msg));
399+
#endif
400+
}
401+
402+
inline const wxString &wxPluralWrapper(const wxString& msg, const wxString& plural, int count)
403+
{
404+
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
405+
return wxGetTranslation(msg, plural, count);
406+
#else
407+
return wxGetTranslation(wxASCII_STR(msg), wxASCII_STR(plural), count);
408+
#endif
409+
}
410+
411+
inline const wxString &wxGettextInContextWrapper(const wxString& ctx, const wxString& msg)
412+
{
413+
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
414+
return wxGetTranslation(msg, wxString(), ctx);
415+
#else
416+
return wxGetTranslation(wxASCII_STR(msg), wxString(), wxASCII_STR(ctx));
417+
#endif
418+
}
419+
420+
inline const wxString &wxGettextInContextPluralWrapper(const wxString& ctx,
421+
const wxString&msg,
422+
const wxString&plural, int count)
423+
{
424+
#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING
425+
return wxGetTranslation(msg, plural, count, wxString(), ctx);
426+
#else
427+
return wxGetTranslation(wxASCII_STR(msg), wxASCII_STR(plural), count,
428+
wxString(), wxASCII_STR(ctx));
429+
#endif
430+
}
431+
432+
} // namespace wxTransImplTraditional
433+
434+
#ifdef wxNO_REQUIRE_LITERAL_MSGIDS
435+
using namespace wxTransImplTraditional;
436+
#else
437+
using namespace wxTransImplStrict;
438+
#endif
439+
383440
#else // !wxUSE_INTL
384441

385442
// the macros should still be defined - otherwise compilation would fail

0 commit comments

Comments
 (0)