root/lib/gettext.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. pgettext_aux
  2. npgettext_aux
  3. dcpgettext_expr
  4. dcnpgettext_expr

     1 /* Convenience header for conditional use of GNU <libintl.h>.
     2    Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2023 Free
     3    Software Foundation, Inc.
     4 
     5    This file is free software: you can redistribute it and/or modify
     6    it under the terms of the GNU Lesser General Public License as
     7    published by the Free Software Foundation; either version 2.1 of the
     8    License, or (at your option) any later version.
     9 
    10    This file is distributed in the hope that it will be useful,
    11    but WITHOUT ANY WARRANTY; without even the implied warranty of
    12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13    GNU Lesser General Public License for more details.
    14 
    15    You should have received a copy of the GNU Lesser General Public License
    16    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
    17 
    18 #ifndef _LIBGETTEXT_H
    19 #define _LIBGETTEXT_H 1
    20 
    21 /* NLS can be disabled through the configure --disable-nls option
    22    or through "#define ENABLE NLS 0" before including this file.  */
    23 #if defined ENABLE_NLS && ENABLE_NLS
    24 
    25 /* Get declarations of GNU message catalog functions.  */
    26 # include <libintl.h>
    27 
    28 /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
    29    the gettext() and ngettext() macros.  This is an alternative to calling
    30    textdomain(), and is useful for libraries.  */
    31 # ifdef DEFAULT_TEXT_DOMAIN
    32 #  undef gettext
    33 #  define gettext(Msgid) \
    34      dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
    35 #  undef ngettext
    36 #  define ngettext(Msgid1, Msgid2, N) \
    37      dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
    38 # endif
    39 
    40 #else
    41 
    42 /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
    43    chokes if dcgettext is defined as a macro.  So include it now, to make
    44    later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
    45    as well because people using "gettext.h" will not include <libintl.h>,
    46    and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
    47    is OK.  */
    48 #if defined(__sun)
    49 # include <locale.h>
    50 #endif
    51 
    52 /* Many header files from the libstdc++ coming with g++ 3.3 or newer include
    53    <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
    54    it now, to make later inclusions of <libintl.h> a NOP.  */
    55 #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
    56 # include <cstdlib>
    57 # if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
    58 #  include <libintl.h>
    59 # endif
    60 #endif
    61 
    62 /* Disabled NLS.
    63    The casts to 'const char *' serve the purpose of producing warnings
    64    for invalid uses of the value returned from these functions.
    65    On pre-ANSI systems without 'const', the config.h file is supposed to
    66    contain "#define const".  */
    67 # undef gettext
    68 # define gettext(Msgid) ((const char *) (Msgid))
    69 # undef dgettext
    70 # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
    71 # undef dcgettext
    72 # define dcgettext(Domainname, Msgid, Category) \
    73     ((void) (Category), dgettext (Domainname, Msgid))
    74 # undef ngettext
    75 # define ngettext(Msgid1, Msgid2, N) \
    76     ((N) == 1 \
    77      ? ((void) (Msgid2), (const char *) (Msgid1)) \
    78      : ((void) (Msgid1), (const char *) (Msgid2)))
    79 # undef dngettext
    80 # define dngettext(Domainname, Msgid1, Msgid2, N) \
    81     ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
    82 # undef dcngettext
    83 # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
    84     ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
    85 # undef textdomain
    86 # define textdomain(Domainname) ((const char *) (Domainname))
    87 # undef bindtextdomain
    88 # define bindtextdomain(Domainname, Dirname) \
    89     ((void) (Domainname), (const char *) (Dirname))
    90 # undef bind_textdomain_codeset
    91 # define bind_textdomain_codeset(Domainname, Codeset) \
    92     ((void) (Domainname), (const char *) (Codeset))
    93 
    94 #endif
    95 
    96 /* Prefer gnulib's setlocale override over libintl's setlocale override.  */
    97 #ifdef GNULIB_defined_setlocale
    98 # undef setlocale
    99 # define setlocale rpl_setlocale
   100 #endif
   101 
   102 /* A pseudo function call that serves as a marker for the automated
   103    extraction of messages, but does not call gettext().  The run-time
   104    translation is done at a different place in the code.
   105    The argument, String, should be a literal string.  Concatenated strings
   106    and other string expressions won't work.
   107    The macro's expansion is not parenthesized, so that it is suitable as
   108    initializer for static 'char[]' or 'const char[]' variables.  */
   109 #define gettext_noop(String) String
   110 
   111 /* The separator between msgctxt and msgid in a .mo file.  */
   112 #define GETTEXT_CONTEXT_GLUE "\004"
   113 
   114 /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
   115    MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
   116    short and rarely need to change.
   117    The letter 'p' stands for 'particular' or 'special'.  */
   118 #ifdef DEFAULT_TEXT_DOMAIN
   119 # define pgettext(Msgctxt, Msgid) \
   120    pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
   121 #else
   122 # define pgettext(Msgctxt, Msgid) \
   123    pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
   124 #endif
   125 #define dpgettext(Domainname, Msgctxt, Msgid) \
   126   pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
   127 #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
   128   pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
   129 #ifdef DEFAULT_TEXT_DOMAIN
   130 # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
   131    npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
   132 #else
   133 # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
   134    npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
   135 #endif
   136 #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
   137   npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
   138 #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
   139   npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
   140 
   141 #if defined __GNUC__ || defined __clang__
   142 __inline
   143 #else
   144 #ifdef __cplusplus
   145 inline
   146 #endif
   147 #endif
   148 static const char *
   149 pgettext_aux (const char *domain,
   150               const char *msg_ctxt_id, const char *msgid,
   151               int category)
   152 {
   153   const char *translation = dcgettext (domain, msg_ctxt_id, category);
   154   if (translation == msg_ctxt_id)
   155     return msgid;
   156   else
   157     return translation;
   158 }
   159 
   160 #if defined __GNUC__ || defined __clang__
   161 __inline
   162 #else
   163 #ifdef __cplusplus
   164 inline
   165 #endif
   166 #endif
   167 static const char *
   168 npgettext_aux (const char *domain,
   169                const char *msg_ctxt_id, const char *msgid,
   170                const char *msgid_plural, unsigned long int n,
   171                int category)
   172 {
   173   const char *translation =
   174     dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
   175   if (translation == msg_ctxt_id || translation == msgid_plural)
   176     return (n == 1 ? msgid : msgid_plural);
   177   else
   178     return translation;
   179 }
   180 
   181 /* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
   182    can be arbitrary expressions.  But for string literals these macros are
   183    less efficient than those above.  */
   184 
   185 #include <string.h>
   186 
   187 /* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported.
   188    This relates to the -Wvla and -Wvla-larger-than warnings, enabled in
   189    the default GCC many warnings set.  This allows programs to disable use
   190    of VLAs, which may be unintended, or may be awkward to support portably,
   191    or may have security implications due to non-deterministic stack usage.  */
   192 
   193 #if (!defined GNULIB_NO_VLA \
   194      && defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__ \
   195      && !defined __STDC_NO_VLA__)
   196 # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
   197 #else
   198 # define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
   199 #endif
   200 
   201 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   202 #include <stdlib.h>
   203 #endif
   204 
   205 #define pgettext_expr(Msgctxt, Msgid) \
   206   dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
   207 #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
   208   dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
   209 
   210 #if defined __GNUC__ || defined __clang__
   211 __inline
   212 #else
   213 #ifdef __cplusplus
   214 inline
   215 #endif
   216 #endif
   217 static const char *
   218 dcpgettext_expr (const char *domain,
   219                  const char *msgctxt, const char *msgid,
   220                  int category)
   221 {
   222   size_t msgctxt_len = strlen (msgctxt) + 1;
   223   size_t msgid_len = strlen (msgid) + 1;
   224   const char *translation;
   225 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   226   char msg_ctxt_id[msgctxt_len + msgid_len];
   227 #else
   228   char buf[1024];
   229   char *msg_ctxt_id =
   230     (msgctxt_len + msgid_len <= sizeof (buf)
   231      ? buf
   232      : (char *) malloc (msgctxt_len + msgid_len));
   233   if (msg_ctxt_id != NULL)
   234 #endif
   235     {
   236       int found_translation;
   237       memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
   238       msg_ctxt_id[msgctxt_len - 1] = '\004';
   239       memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
   240       translation = dcgettext (domain, msg_ctxt_id, category);
   241       found_translation = (translation != msg_ctxt_id);
   242 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   243       if (msg_ctxt_id != buf)
   244         free (msg_ctxt_id);
   245 #endif
   246       if (found_translation)
   247         return translation;
   248     }
   249   return msgid;
   250 }
   251 
   252 #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
   253   dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
   254 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
   255   dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
   256 
   257 #if defined __GNUC__ || defined __clang__
   258 __inline
   259 #else
   260 #ifdef __cplusplus
   261 inline
   262 #endif
   263 #endif
   264 static const char *
   265 dcnpgettext_expr (const char *domain,
   266                   const char *msgctxt, const char *msgid,
   267                   const char *msgid_plural, unsigned long int n,
   268                   int category)
   269 {
   270   size_t msgctxt_len = strlen (msgctxt) + 1;
   271   size_t msgid_len = strlen (msgid) + 1;
   272   const char *translation;
   273 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   274   char msg_ctxt_id[msgctxt_len + msgid_len];
   275 #else
   276   char buf[1024];
   277   char *msg_ctxt_id =
   278     (msgctxt_len + msgid_len <= sizeof (buf)
   279      ? buf
   280      : (char *) malloc (msgctxt_len + msgid_len));
   281   if (msg_ctxt_id != NULL)
   282 #endif
   283     {
   284       int found_translation;
   285       memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
   286       msg_ctxt_id[msgctxt_len - 1] = '\004';
   287       memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
   288       translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
   289       found_translation = !(translation == msg_ctxt_id || translation == msgid_plural);
   290 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   291       if (msg_ctxt_id != buf)
   292         free (msg_ctxt_id);
   293 #endif
   294       if (found_translation)
   295         return translation;
   296     }
   297   return (n == 1 ? msgid : msgid_plural);
   298 }
   299 
   300 #endif /* _LIBGETTEXT_H */

/* [<][>][^][v][top][bottom][index][help] */