(root)/
tar-1.35/
gnu/
gettext.h
       1  /* Convenience header for conditional use of GNU <libintl.h>.
       2     Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2023 Free Software
       3     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 */