Blame gl/gettext.h

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