diff --git a/src/gettext.h b/src/gettext.h --- a/src/gettext.h +++ b/src/gettext.h @@ -1,42 +1,113 @@ /* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2017 Free Software + Foundation, Inc. - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2, or (at your option) + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ + You should have received a copy of the GNU General Public License along + with this program; if not, see . */ #ifndef _LIBGETTEXT_H #define _LIBGETTEXT_H 1 +/* NLS can be disabled through the configure --disable-nls option + or through "#define ENABLE NLS 0" before including this file. */ +#if defined ENABLE_NLS && ENABLE_NLS + /* Get declarations of GNU message catalog functions. */ # include -// libintl.h redefines inline which causes MSVC to abort compilation with the message -// fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords -#undef inline /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by the gettext() and ngettext() macros. This is an alternative to calling textdomain(), and is useful for libraries. */ # ifdef DEFAULT_TEXT_DOMAIN # undef gettext # define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) + dgettext (DEFAULT_TEXT_DOMAIN, Msgid) # undef ngettext # define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) + dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) # endif +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H +# include +# endif +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# undef gettext +# define gettext(Msgid) ((const char *) (Msgid)) +# undef dgettext +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# undef dcgettext +# define dcgettext(Domainname, Msgid, Category) \ + ((void) (Category), dgettext (Domainname, Msgid)) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) (Msgid1)) \ + : ((void) (Msgid1), (const char *) (Msgid2))) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) +# undef textdomain +# define textdomain(Domainname) ((const char *) (Domainname)) +# undef bindtextdomain +# define bindtextdomain(Domainname, Dirname) \ + ((void) (Domainname), (const char *) (Dirname)) +# undef bind_textdomain_codeset +# define bind_textdomain_codeset(Domainname, Codeset) \ + ((void) (Domainname), (const char *) (Codeset)) + +#endif + +/* Prefer gnulib's setlocale override over libintl's setlocale override. */ +#ifdef GNULIB_defined_setlocale +# undef setlocale +# define setlocale rpl_setlocale +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + /* The separator between msgctxt and msgid in a .mo file. */ #define GETTEXT_CONTEXT_GLUE "\004" @@ -46,13 +117,26 @@ The letter 'p' stands for 'particular' or 'special'. */ #ifdef DEFAULT_TEXT_DOMAIN # define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid) + pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #else # define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid) + pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) #endif #define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid) + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) +#ifdef DEFAULT_TEXT_DOMAIN +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#else +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#endif +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) #ifdef __GNUC__ __inline @@ -62,39 +146,60 @@ #endif #endif static const char * -pgettext_aux(const char *domain, - const char *msg_ctxt_id, const char *msgid) +pgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + int category) { - const char *translation = dgettext(domain, msg_ctxt_id); - if (translation == msg_ctxt_id) { - return msgid; - } else { - return translation; - } + const char *translation = dcgettext (domain, msg_ctxt_id, category); + if (translation == msg_ctxt_id) + return msgid; + else + return translation; +} + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +npgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + const char *translation = + dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + if (translation == msg_ctxt_id || translation == msgid_plural) + return (n == 1 ? msgid : msgid_plural); + else + return translation; } /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID can be arbitrary expressions. But for string literals these macros are less efficient than those above. */ #include -#ifndef __STRICT_ANSI__ -#define __STRICT_ANSI__ -#define __STRICT_ANSI_FORCED__ +#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ + /* || __STDC_VERSION__ == 199901L + || (__STDC_VERSION__ >= 201112L && !defined __STDC_NO_VLA__) */ ) +# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 +#else +# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 #endif -#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ - (__STRICT_ANSI__ - 0 == 0) && (__GNUC__ >= 3 || __GNUG__ >= 2 /* || __STDC_VERSION__ >= 199901L */ ) - #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS #include #endif #define pgettext_expr(Msgctxt, Msgid) \ - dpgettext_expr (NULL, Msgctxt, Msgid) + dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dpgettext_expr (Domainname, Msgctxt, Msgid) + dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) #ifdef __GNUC__ __inline @@ -104,46 +209,44 @@ #endif #endif static const char * -dpgettext_expr(const char *domain, - const char *msgctxt, const char *msgid) +dcpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + int category) { - size_t msgctxt_len = strlen(msgctxt) + 1; - size_t msgid_len = strlen(msgid) + 1; - const char *translation; - int translation_found; + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; + char msg_ctxt_id[msgctxt_len + msgid_len]; #else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof(buf) - ? buf - : (char *) malloc(msgctxt_len + msgid_len)); - if (msg_ctxt_id != nullptr) + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) #endif { - memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dgettext(domain, msg_ctxt_id); - /* Test must occur before msg_ctxt_id freed */ - translation_found = translation != msg_ctxt_id; + int found_translation; + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcgettext (domain, msg_ctxt_id, category); + found_translation = (translation != msg_ctxt_id); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) { - free(msg_ctxt_id); - } + if (msg_ctxt_id != buf) + free (msg_ctxt_id); #endif - if (translation_found) { - return translation; - } + if (found_translation) + return translation; } - return msgid; + return msgid; } #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N) + dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N) + dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) #ifdef __GNUC__ __inline @@ -153,46 +256,39 @@ #endif #endif static const char * -dnpgettext_expr(const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n) +dcnpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) { - size_t msgctxt_len = strlen(msgctxt) + 1; - size_t msgid_len = strlen(msgid) + 1; - const char *translation; - int translation_found; + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; + char msg_ctxt_id[msgctxt_len + msgid_len]; #else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof(buf) - ? buf - : (char *) malloc(msgctxt_len + msgid_len)); - if (msg_ctxt_id != nullptr) + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) #endif { - memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dngettext(domain, msg_ctxt_id, msgid_plural, n); - /* Test must occur before msg_ctxt_id freed */ - translation_found = !(translation == msg_ctxt_id || translation == msgid_plural); + int found_translation; + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) { - free(msg_ctxt_id); - } + if (msg_ctxt_id != buf) + free (msg_ctxt_id); #endif - if (translation_found) { - return translation; - } + if (found_translation) + return translation; } - return (n == 1 ? msgid : msgid_plural); + return (n == 1 ? msgid : msgid_plural); } -#ifdef __STRICT_ANSI_FORCED__ -#undef __STRICT_ANSI__ -#undef __STRICT_ANSI_FORCED__ -#endif - #endif /* _LIBGETTEXT_H */