Blame gnulib/lib/gettext.h

Packit 06dd63
/* Convenience header for conditional use of GNU <libintl.h>.
Packit 06dd63
   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2019 Free Software
Packit 06dd63
   Foundation, Inc.
Packit 06dd63
Packit 06dd63
   This program is free software; you can redistribute it and/or modify
Packit 06dd63
   it under the terms of the GNU Lesser General Public License as published by
Packit 06dd63
   the Free Software Foundation; either version 2.1, or (at your option)
Packit 06dd63
   any later version.
Packit 06dd63
Packit 06dd63
   This program is distributed in the hope that it will be useful,
Packit 06dd63
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 06dd63
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 06dd63
   GNU Lesser General Public License for more details.
Packit 06dd63
Packit 06dd63
   You should have received a copy of the GNU Lesser General Public License along
Packit 06dd63
   with this program; if not, see <https://www.gnu.org/licenses/>.  */
Packit 06dd63
Packit 06dd63
#ifndef _LIBGETTEXT_H
Packit 06dd63
#define _LIBGETTEXT_H 1
Packit 06dd63
Packit 06dd63
/* NLS can be disabled through the configure --disable-nls option
Packit 06dd63
   or through "#define ENABLE NLS 0" before including this file.  */
Packit 06dd63
#if defined ENABLE_NLS && ENABLE_NLS
Packit 06dd63
Packit 06dd63
/* Get declarations of GNU message catalog functions.  */
Packit 06dd63
# include <libintl.h>
Packit 06dd63
Packit 06dd63
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
Packit 06dd63
   the gettext() and ngettext() macros.  This is an alternative to calling
Packit 06dd63
   textdomain(), and is useful for libraries.  */
Packit 06dd63
# ifdef DEFAULT_TEXT_DOMAIN
Packit 06dd63
#  undef gettext
Packit 06dd63
#  define gettext(Msgid) \
Packit 06dd63
     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
Packit 06dd63
#  undef ngettext
Packit 06dd63
#  define ngettext(Msgid1, Msgid2, N) \
Packit 06dd63
     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
Packit 06dd63
# endif
Packit 06dd63
Packit 06dd63
#else
Packit 06dd63
Packit 06dd63
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
Packit 06dd63
   chokes if dcgettext is defined as a macro.  So include it now, to make
Packit 06dd63
   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
Packit 06dd63
   as well because people using "gettext.h" will not include <libintl.h>,
Packit 06dd63
   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
Packit 06dd63
   is OK.  */
Packit 06dd63
#if defined(__sun)
Packit 06dd63
# include <locale.h>
Packit 06dd63
#endif
Packit 06dd63
Packit 06dd63
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
Packit 06dd63
   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
Packit 06dd63
   it now, to make later inclusions of <libintl.h> a NOP.  */
Packit 06dd63
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
Packit 06dd63
# include <cstdlib>
Packit 06dd63
# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
Packit 06dd63
#  include <libintl.h>
Packit 06dd63
# endif
Packit 06dd63
#endif
Packit 06dd63
Packit 06dd63
/* Disabled NLS.
Packit 06dd63
   The casts to 'const char *' serve the purpose of producing warnings
Packit 06dd63
   for invalid uses of the value returned from these functions.
Packit 06dd63
   On pre-ANSI systems without 'const', the config.h file is supposed to
Packit 06dd63
   contain "#define const".  */
Packit 06dd63
# undef gettext
Packit 06dd63
# define gettext(Msgid) ((const char *) (Msgid))
Packit 06dd63
# undef dgettext
Packit 06dd63
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
Packit 06dd63
# undef dcgettext
Packit 06dd63
# define dcgettext(Domainname, Msgid, Category) \
Packit 06dd63
    ((void) (Category), dgettext (Domainname, Msgid))
Packit 06dd63
# undef ngettext
Packit 06dd63
# define ngettext(Msgid1, Msgid2, N) \
Packit 06dd63
    ((N) == 1 \
Packit 06dd63
     ? ((void) (Msgid2), (const char *) (Msgid1)) \
Packit 06dd63
     : ((void) (Msgid1), (const char *) (Msgid2)))
Packit 06dd63
# undef dngettext
Packit 06dd63
# define dngettext(Domainname, Msgid1, Msgid2, N) \
Packit 06dd63
    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
Packit 06dd63
# undef dcngettext
Packit 06dd63
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
Packit 06dd63
    ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
Packit 06dd63
# undef textdomain
Packit 06dd63
# define textdomain(Domainname) ((const char *) (Domainname))
Packit 06dd63
# undef bindtextdomain
Packit 06dd63
# define bindtextdomain(Domainname, Dirname) \
Packit 06dd63
    ((void) (Domainname), (const char *) (Dirname))
Packit 06dd63
# undef bind_textdomain_codeset
Packit 06dd63
# define bind_textdomain_codeset(Domainname, Codeset) \
Packit 06dd63
    ((void) (Domainname), (const char *) (Codeset))
Packit 06dd63
Packit 06dd63
#endif
Packit 06dd63
Packit 06dd63
/* Prefer gnulib's setlocale override over libintl's setlocale override.  */
Packit 06dd63
#ifdef GNULIB_defined_setlocale
Packit 06dd63
# undef setlocale
Packit 06dd63
# define setlocale rpl_setlocale
Packit 06dd63
#endif
Packit 06dd63
Packit 06dd63
/* A pseudo function call that serves as a marker for the automated
Packit 06dd63
   extraction of messages, but does not call gettext().  The run-time
Packit 06dd63
   translation is done at a different place in the code.
Packit 06dd63
   The argument, String, should be a literal string.  Concatenated strings
Packit 06dd63
   and other string expressions won't work.
Packit 06dd63
   The macro's expansion is not parenthesized, so that it is suitable as
Packit 06dd63
   initializer for static 'char[]' or 'const char[]' variables.  */
Packit 06dd63
#define gettext_noop(String) String
Packit 06dd63
Packit 06dd63
/* The separator between msgctxt and msgid in a .mo file.  */
Packit 06dd63
#define GETTEXT_CONTEXT_GLUE "\004"
Packit 06dd63
Packit 06dd63
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
Packit 06dd63
   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
Packit 06dd63
   short and rarely need to change.
Packit 06dd63
   The letter 'p' stands for 'particular' or 'special'.  */
Packit 06dd63
#ifdef DEFAULT_TEXT_DOMAIN
Packit 06dd63
# define pgettext(Msgctxt, Msgid) \
Packit 06dd63
   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
Packit 06dd63
#else
Packit 06dd63
# define pgettext(Msgctxt, Msgid) \
Packit 06dd63
   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
Packit 06dd63
#endif
Packit 06dd63
#define dpgettext(Domainname, Msgctxt, Msgid) \
Packit 06dd63
  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
Packit 06dd63
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
Packit 06dd63
  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
Packit 06dd63
#ifdef DEFAULT_TEXT_DOMAIN
Packit 06dd63
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
Packit 06dd63
   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
Packit 06dd63
#else
Packit 06dd63
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
Packit 06dd63
   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
Packit 06dd63
#endif
Packit 06dd63
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
Packit 06dd63
  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
Packit 06dd63
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
Packit 06dd63
  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
Packit 06dd63
Packit 06dd63
#ifdef __GNUC__
Packit 06dd63
__inline
Packit 06dd63
#else
Packit 06dd63
#ifdef __cplusplus
Packit 06dd63
inline
Packit 06dd63
#endif
Packit 06dd63
#endif
Packit 06dd63
static const char *
Packit 06dd63
pgettext_aux (const char *domain,
Packit 06dd63
              const char *msg_ctxt_id, const char *msgid,
Packit 06dd63
              int category)
Packit 06dd63
{
Packit 06dd63
  const char *translation = dcgettext (domain, msg_ctxt_id, category);
Packit 06dd63
  if (translation == msg_ctxt_id)
Packit 06dd63
    return msgid;
Packit 06dd63
  else
Packit 06dd63
    return translation;
Packit 06dd63
}
Packit 06dd63
Packit 06dd63
#ifdef __GNUC__
Packit 06dd63
__inline
Packit 06dd63
#else
Packit 06dd63
#ifdef __cplusplus
Packit 06dd63
inline
Packit 06dd63
#endif
Packit 06dd63
#endif
Packit 06dd63
static const char *
Packit 06dd63
npgettext_aux (const char *domain,
Packit 06dd63
               const char *msg_ctxt_id, const char *msgid,
Packit 06dd63
               const char *msgid_plural, unsigned long int n,
Packit 06dd63
               int category)
Packit 06dd63
{
Packit 06dd63
  const char *translation =
Packit 06dd63
    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
Packit 06dd63
  if (translation == msg_ctxt_id || translation == msgid_plural)
Packit 06dd63
    return (n == 1 ? msgid : msgid_plural);
Packit 06dd63
  else
Packit 06dd63
    return translation;
Packit 06dd63
}
Packit 06dd63
Packit 06dd63
/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
Packit 06dd63
   can be arbitrary expressions.  But for string literals these macros are
Packit 06dd63
   less efficient than those above.  */
Packit 06dd63
Packit 06dd63
#include <string.h>
Packit 06dd63
Packit 06dd63
/* GNULIB_NO_VLA can be defined to disable use of VLAs even if supported.
Packit 06dd63
   This relates to the -Wvla and -Wvla-larger-than warnings, enabled in
Packit 06dd63
   the default GCC many warnings set.  This allows programs to disable use
Packit 06dd63
   of VLAs, which may be unintended, or may be awkward to support portably,
Packit 06dd63
   or may have security implications due to non-deterministic stack usage.  */
Packit 06dd63
Packit 06dd63
#if (!defined GNULIB_NO_VLA \
Packit 06dd63
     && (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
Packit 06dd63
     /*  || (__STDC_VERSION__ == 199901L && !defined __HP_cc)
Packit 06dd63
         || (__STDC_VERSION__ >= 201112L && !defined __STDC_NO_VLA__) */ ))
Packit 06dd63
# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
Packit 06dd63
#else
Packit 06dd63
# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
Packit 06dd63
#endif
Packit 06dd63
Packit 06dd63
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
Packit 06dd63
#include <stdlib.h>
Packit 06dd63
#endif
Packit 06dd63
Packit 06dd63
#define pgettext_expr(Msgctxt, Msgid) \
Packit 06dd63
  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
Packit 06dd63
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
Packit 06dd63
  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
Packit 06dd63
Packit 06dd63
#ifdef __GNUC__
Packit 06dd63
__inline
Packit 06dd63
#else
Packit 06dd63
#ifdef __cplusplus
Packit 06dd63
inline
Packit 06dd63
#endif
Packit 06dd63
#endif
Packit 06dd63
static const char *
Packit 06dd63
dcpgettext_expr (const char *domain,
Packit 06dd63
                 const char *msgctxt, const char *msgid,
Packit 06dd63
                 int category)
Packit 06dd63
{
Packit 06dd63
  size_t msgctxt_len = strlen (msgctxt) + 1;
Packit 06dd63
  size_t msgid_len = strlen (msgid) + 1;
Packit 06dd63
  const char *translation;
Packit 06dd63
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
Packit 06dd63
  char msg_ctxt_id[msgctxt_len + msgid_len];
Packit 06dd63
#else
Packit 06dd63
  char buf[1024];
Packit 06dd63
  char *msg_ctxt_id =
Packit 06dd63
    (msgctxt_len + msgid_len <= sizeof (buf)
Packit 06dd63
     ? buf
Packit 06dd63
     : (char *) malloc (msgctxt_len + msgid_len));
Packit 06dd63
  if (msg_ctxt_id != NULL)
Packit 06dd63
#endif
Packit 06dd63
    {
Packit 06dd63
      int found_translation;
Packit 06dd63
      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
Packit 06dd63
      msg_ctxt_id[msgctxt_len - 1] = '\004';
Packit 06dd63
      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
Packit 06dd63
      translation = dcgettext (domain, msg_ctxt_id, category);
Packit 06dd63
      found_translation = (translation != msg_ctxt_id);
Packit 06dd63
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
Packit 06dd63
      if (msg_ctxt_id != buf)
Packit 06dd63
        free (msg_ctxt_id);
Packit 06dd63
#endif
Packit 06dd63
      if (found_translation)
Packit 06dd63
        return translation;
Packit 06dd63
    }
Packit 06dd63
  return msgid;
Packit 06dd63
}
Packit 06dd63
Packit 06dd63
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
Packit 06dd63
  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
Packit 06dd63
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
Packit 06dd63
  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
Packit 06dd63
Packit 06dd63
#ifdef __GNUC__
Packit 06dd63
__inline
Packit 06dd63
#else
Packit 06dd63
#ifdef __cplusplus
Packit 06dd63
inline
Packit 06dd63
#endif
Packit 06dd63
#endif
Packit 06dd63
static const char *
Packit 06dd63
dcnpgettext_expr (const char *domain,
Packit 06dd63
                  const char *msgctxt, const char *msgid,
Packit 06dd63
                  const char *msgid_plural, unsigned long int n,
Packit 06dd63
                  int category)
Packit 06dd63
{
Packit 06dd63
  size_t msgctxt_len = strlen (msgctxt) + 1;
Packit 06dd63
  size_t msgid_len = strlen (msgid) + 1;
Packit 06dd63
  const char *translation;
Packit 06dd63
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
Packit 06dd63
  char msg_ctxt_id[msgctxt_len + msgid_len];
Packit 06dd63
#else
Packit 06dd63
  char buf[1024];
Packit 06dd63
  char *msg_ctxt_id =
Packit 06dd63
    (msgctxt_len + msgid_len <= sizeof (buf)
Packit 06dd63
     ? buf
Packit 06dd63
     : (char *) malloc (msgctxt_len + msgid_len));
Packit 06dd63
  if (msg_ctxt_id != NULL)
Packit 06dd63
#endif
Packit 06dd63
    {
Packit 06dd63
      int found_translation;
Packit 06dd63
      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
Packit 06dd63
      msg_ctxt_id[msgctxt_len - 1] = '\004';
Packit 06dd63
      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
Packit 06dd63
      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
Packit 06dd63
      found_translation = !(translation == msg_ctxt_id || translation == msgid_plural);
Packit 06dd63
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
Packit 06dd63
      if (msg_ctxt_id != buf)
Packit 06dd63
        free (msg_ctxt_id);
Packit 06dd63
#endif
Packit 06dd63
      if (found_translation)
Packit 06dd63
        return translation;
Packit 06dd63
    }
Packit 06dd63
  return (n == 1 ? msgid : msgid_plural);
Packit 06dd63
}
Packit 06dd63
Packit 06dd63
#endif /* _LIBGETTEXT_H */