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