gettext.h
changeset 5 390d05b2d25c
parent 1 67188bd752db
     1.1 --- a/gettext.h	Thu Jul 10 18:53:00 2008 +0100
     1.2 +++ b/gettext.h	Thu Jul 10 20:38:53 2008 +0100
     1.3 @@ -1,8 +1,8 @@
     1.4  /* Convenience header for conditional use of GNU <libintl.h>.
     1.5 -   Copyright (C) 1995-1998, 2000-2002, 2004 Free Software Foundation, Inc.
     1.6 +   Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
     1.7  
     1.8     This program is free software; you can redistribute it and/or modify it
     1.9 -   under the terms of the GNU Library General Public License as published
    1.10 +   under the terms of the GNU General Public License as published
    1.11     by the Free Software Foundation; either version 2, or (at your option)
    1.12     any later version.
    1.13  
    1.14 @@ -11,7 +11,7 @@
    1.15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    1.16     Library General Public License for more details.
    1.17  
    1.18 -   You should have received a copy of the GNU Library General Public
    1.19 +   You should have received a copy of the GNU General Public
    1.20     License along with this program; if not, write to the Free Software
    1.21     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    1.22     USA.  */
    1.23 @@ -25,6 +25,18 @@
    1.24  /* Get declarations of GNU message catalog functions.  */
    1.25  # include <libintl.h>
    1.26  
    1.27 +/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
    1.28 +   the gettext() and ngettext() macros.  This is an alternative to calling
    1.29 +   textdomain(), and is useful for libraries.  */
    1.30 +# ifdef DEFAULT_TEXT_DOMAIN
    1.31 +#  undef gettext
    1.32 +#  define gettext(Msgid) \
    1.33 +     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
    1.34 +#  undef ngettext
    1.35 +#  define ngettext(Msgid1, Msgid2, N) \
    1.36 +     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
    1.37 +# endif
    1.38 +
    1.39  #else
    1.40  
    1.41  /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
    1.42 @@ -53,17 +65,22 @@
    1.43     On pre-ANSI systems without 'const', the config.h file is supposed to
    1.44     contain "#define const".  */
    1.45  # define gettext(Msgid) ((const char *) (Msgid))
    1.46 -# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
    1.47 -# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
    1.48 +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
    1.49 +# define dcgettext(Domainname, Msgid, Category) \
    1.50 +    ((void) (Category), dgettext (Domainname, Msgid))
    1.51  # define ngettext(Msgid1, Msgid2, N) \
    1.52 -    ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
    1.53 +    ((N) == 1 \
    1.54 +     ? ((void) (Msgid2), (const char *) (Msgid1)) \
    1.55 +     : ((void) (Msgid1), (const char *) (Msgid2)))
    1.56  # define dngettext(Domainname, Msgid1, Msgid2, N) \
    1.57 -    ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
    1.58 +    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
    1.59  # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
    1.60 -    ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
    1.61 +    ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
    1.62  # define textdomain(Domainname) ((const char *) (Domainname))
    1.63 -# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
    1.64 -# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
    1.65 +# define bindtextdomain(Domainname, Dirname) \
    1.66 +    ((void) (Domainname), (const char *) (Dirname))
    1.67 +# define bind_textdomain_codeset(Domainname, Codeset) \
    1.68 +    ((void) (Domainname), (const char *) (Codeset))
    1.69  
    1.70  #endif
    1.71  
    1.72 @@ -76,4 +93,179 @@
    1.73     initializer for static 'char[]' or 'const char[]' variables.  */
    1.74  #define gettext_noop(String) String
    1.75  
    1.76 +/* The separator between msgctxt and msgid in a .mo file.  */
    1.77 +#define GETTEXT_CONTEXT_GLUE "\004"
    1.78 +
    1.79 +/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
    1.80 +   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
    1.81 +   short and rarely need to change.
    1.82 +   The letter 'p' stands for 'particular' or 'special'.  */
    1.83 +#ifdef DEFAULT_TEXT_DOMAIN
    1.84 +# define pgettext(Msgctxt, Msgid) \
    1.85 +   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
    1.86 +#else
    1.87 +# define pgettext(Msgctxt, Msgid) \
    1.88 +   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
    1.89 +#endif
    1.90 +#define dpgettext(Domainname, Msgctxt, Msgid) \
    1.91 +  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
    1.92 +#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
    1.93 +  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
    1.94 +#ifdef DEFAULT_TEXT_DOMAIN
    1.95 +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
    1.96 +   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
    1.97 +#else
    1.98 +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
    1.99 +   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
   1.100 +#endif
   1.101 +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
   1.102 +  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
   1.103 +#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
   1.104 +  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
   1.105 +
   1.106 +#ifdef __GNUC__
   1.107 +__inline
   1.108 +#else
   1.109 +#ifdef __cplusplus
   1.110 +inline
   1.111 +#endif
   1.112 +#endif
   1.113 +static const char *
   1.114 +pgettext_aux (const char *domain,
   1.115 +	      const char *msg_ctxt_id, const char *msgid,
   1.116 +	      int category)
   1.117 +{
   1.118 +  const char *translation = dcgettext (domain, msg_ctxt_id, category);
   1.119 +  if (translation == msg_ctxt_id)
   1.120 +    return msgid;
   1.121 +  else
   1.122 +    return translation;
   1.123 +}
   1.124 +
   1.125 +#ifdef __GNUC__
   1.126 +__inline
   1.127 +#else
   1.128 +#ifdef __cplusplus
   1.129 +inline
   1.130 +#endif
   1.131 +#endif
   1.132 +static const char *
   1.133 +npgettext_aux (const char *domain,
   1.134 +	       const char *msg_ctxt_id, const char *msgid,
   1.135 +	       const char *msgid_plural, unsigned long int n,
   1.136 +	       int category)
   1.137 +{
   1.138 +  const char *translation =
   1.139 +    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
   1.140 +  if (translation == msg_ctxt_id || translation == msgid_plural)
   1.141 +    return (n == 1 ? msgid : msgid_plural);
   1.142 +  else
   1.143 +    return translation;
   1.144 +}
   1.145 +
   1.146 +/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
   1.147 +   can be arbitrary expressions.  But for string literals these macros are
   1.148 +   less efficient than those above.  */
   1.149 +
   1.150 +#include <string.h>
   1.151 +
   1.152 +#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
   1.153 +  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
   1.154 +   /* || __STDC_VERSION__ >= 199901L */ )
   1.155 +
   1.156 +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   1.157 +#include <stdlib.h>
   1.158 +#endif
   1.159 +
   1.160 +#define pgettext_expr(Msgctxt, Msgid) \
   1.161 +  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
   1.162 +#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
   1.163 +  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
   1.164 +
   1.165 +#ifdef __GNUC__
   1.166 +__inline
   1.167 +#else
   1.168 +#ifdef __cplusplus
   1.169 +inline
   1.170 +#endif
   1.171 +#endif
   1.172 +static const char *
   1.173 +dcpgettext_expr (const char *domain,
   1.174 +		 const char *msgctxt, const char *msgid,
   1.175 +		 int category)
   1.176 +{
   1.177 +  size_t msgctxt_len = strlen (msgctxt) + 1;
   1.178 +  size_t msgid_len = strlen (msgid) + 1;
   1.179 +  const char *translation;
   1.180 +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   1.181 +  char msg_ctxt_id[msgctxt_len + msgid_len];
   1.182 +#else
   1.183 +  char buf[1024];
   1.184 +  char *msg_ctxt_id =
   1.185 +    (msgctxt_len + msgid_len <= sizeof (buf)
   1.186 +     ? buf
   1.187 +     : (char *) malloc (msgctxt_len + msgid_len));
   1.188 +  if (msg_ctxt_id != NULL)
   1.189 +#endif
   1.190 +    {
   1.191 +      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
   1.192 +      msg_ctxt_id[msgctxt_len - 1] = '\004';
   1.193 +      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
   1.194 +      translation = dcgettext (domain, msg_ctxt_id, category);
   1.195 +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   1.196 +      if (msg_ctxt_id != buf)
   1.197 +	free (msg_ctxt_id);
   1.198 +#endif
   1.199 +      if (translation != msg_ctxt_id)
   1.200 +	return translation;
   1.201 +    }
   1.202 +  return msgid;
   1.203 +}
   1.204 +
   1.205 +#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
   1.206 +  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
   1.207 +#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
   1.208 +  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
   1.209 +
   1.210 +#ifdef __GNUC__
   1.211 +__inline
   1.212 +#else
   1.213 +#ifdef __cplusplus
   1.214 +inline
   1.215 +#endif
   1.216 +#endif
   1.217 +static const char *
   1.218 +dcnpgettext_expr (const char *domain,
   1.219 +		  const char *msgctxt, const char *msgid,
   1.220 +		  const char *msgid_plural, unsigned long int n,
   1.221 +		  int category)
   1.222 +{
   1.223 +  size_t msgctxt_len = strlen (msgctxt) + 1;
   1.224 +  size_t msgid_len = strlen (msgid) + 1;
   1.225 +  const char *translation;
   1.226 +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   1.227 +  char msg_ctxt_id[msgctxt_len + msgid_len];
   1.228 +#else
   1.229 +  char buf[1024];
   1.230 +  char *msg_ctxt_id =
   1.231 +    (msgctxt_len + msgid_len <= sizeof (buf)
   1.232 +     ? buf
   1.233 +     : (char *) malloc (msgctxt_len + msgid_len));
   1.234 +  if (msg_ctxt_id != NULL)
   1.235 +#endif
   1.236 +    {
   1.237 +      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
   1.238 +      msg_ctxt_id[msgctxt_len - 1] = '\004';
   1.239 +      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
   1.240 +      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
   1.241 +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
   1.242 +      if (msg_ctxt_id != buf)
   1.243 +	free (msg_ctxt_id);
   1.244 +#endif
   1.245 +      if (!(translation == msg_ctxt_id || translation == msgid_plural))
   1.246 +	return translation;
   1.247 +    }
   1.248 +  return (n == 1 ? msgid : msgid_plural);
   1.249 +}
   1.250 +
   1.251  #endif /* _LIBGETTEXT_H */