gettext.h - enscript - GNU Enscript
 (HTM) git clone git://thinkerwim.org/enscript.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       gettext.h (9807B)
       ---
            1 /* Convenience header for conditional use of GNU <libintl.h>.
            2    Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009 Free Software Foundation, Inc.
            3 
            4    This program is free software; you can redistribute it and/or modify it
            5    under the terms of the GNU General Public License as published
            6    by the Free Software Foundation; either version 3, or (at your option)
            7    any later version.
            8 
            9    This program is distributed in the hope that it will be useful,
           10    but WITHOUT ANY WARRANTY; without even the implied warranty of
           11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           12    Library General Public License for more details.
           13 
           14    You should have received a copy of the GNU General Public
           15    License along with this program; if not, write to the Free Software
           16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
           17    USA.  */
           18 
           19 #ifndef _LIBGETTEXT_H
           20 #define _LIBGETTEXT_H 1
           21 
           22 /* NLS can be disabled through the configure --disable-nls option.  */
           23 #if 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) || _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 /* A pseudo function call that serves as a marker for the automated
           97    extraction of messages, but does not call gettext().  The run-time
           98    translation is done at a different place in the code.
           99    The argument, String, should be a literal string.  Concatenated strings
          100    and other string expressions won't work.
          101    The macro's expansion is not parenthesized, so that it is suitable as
          102    initializer for static 'char[]' or 'const char[]' variables.  */
          103 #define gettext_noop(String) String
          104 
          105 /* The separator between msgctxt and msgid in a .mo file.  */
          106 #define GETTEXT_CONTEXT_GLUE "\004"
          107 
          108 /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
          109    MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
          110    short and rarely need to change.
          111    The letter 'p' stands for 'particular' or 'special'.  */
          112 #ifdef DEFAULT_TEXT_DOMAIN
          113 # define pgettext(Msgctxt, Msgid) \
          114    pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
          115 #else
          116 # define pgettext(Msgctxt, Msgid) \
          117    pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
          118 #endif
          119 #define dpgettext(Domainname, Msgctxt, Msgid) \
          120   pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
          121 #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
          122   pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
          123 #ifdef DEFAULT_TEXT_DOMAIN
          124 # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
          125    npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
          126 #else
          127 # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
          128    npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
          129 #endif
          130 #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
          131   npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
          132 #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
          133   npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
          134 
          135 #ifdef __GNUC__
          136 __inline
          137 #else
          138 #ifdef __cplusplus
          139 inline
          140 #endif
          141 #endif
          142 static const char *
          143 pgettext_aux (const char *domain,
          144               const char *msg_ctxt_id, const char *msgid,
          145               int category)
          146 {
          147   const char *translation = dcgettext (domain, msg_ctxt_id, category);
          148   if (translation == msg_ctxt_id)
          149     return msgid;
          150   else
          151     return translation;
          152 }
          153 
          154 #ifdef __GNUC__
          155 __inline
          156 #else
          157 #ifdef __cplusplus
          158 inline
          159 #endif
          160 #endif
          161 static const char *
          162 npgettext_aux (const char *domain,
          163                const char *msg_ctxt_id, const char *msgid,
          164                const char *msgid_plural, unsigned long int n,
          165                int category)
          166 {
          167   const char *translation =
          168     dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
          169   if (translation == msg_ctxt_id || translation == msgid_plural)
          170     return (n == 1 ? msgid : msgid_plural);
          171   else
          172     return translation;
          173 }
          174 
          175 /* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
          176    can be arbitrary expressions.  But for string literals these macros are
          177    less efficient than those above.  */
          178 
          179 #include <string.h>
          180 
          181 #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
          182   (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
          183    /* || __STDC_VERSION__ >= 199901L */ )
          184 
          185 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
          186 #include <stdlib.h>
          187 #endif
          188 
          189 #define pgettext_expr(Msgctxt, Msgid) \
          190   dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
          191 #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
          192   dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
          193 
          194 #ifdef __GNUC__
          195 __inline
          196 #else
          197 #ifdef __cplusplus
          198 inline
          199 #endif
          200 #endif
          201 static const char *
          202 dcpgettext_expr (const char *domain,
          203                  const char *msgctxt, const char *msgid,
          204                  int category)
          205 {
          206   size_t msgctxt_len = strlen (msgctxt) + 1;
          207   size_t msgid_len = strlen (msgid) + 1;
          208   const char *translation;
          209 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
          210   char msg_ctxt_id[msgctxt_len + msgid_len];
          211 #else
          212   char buf[1024];
          213   char *msg_ctxt_id =
          214     (msgctxt_len + msgid_len <= sizeof (buf)
          215      ? buf
          216      : (char *) malloc (msgctxt_len + msgid_len));
          217   if (msg_ctxt_id != NULL)
          218 #endif
          219     {
          220       memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
          221       msg_ctxt_id[msgctxt_len - 1] = '\004';
          222       memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
          223       translation = dcgettext (domain, msg_ctxt_id, category);
          224 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
          225       if (msg_ctxt_id != buf)
          226         free (msg_ctxt_id);
          227 #endif
          228       if (translation != msg_ctxt_id)
          229         return translation;
          230     }
          231   return msgid;
          232 }
          233 
          234 #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
          235   dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
          236 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
          237   dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
          238 
          239 #ifdef __GNUC__
          240 __inline
          241 #else
          242 #ifdef __cplusplus
          243 inline
          244 #endif
          245 #endif
          246 static const char *
          247 dcnpgettext_expr (const char *domain,
          248                   const char *msgctxt, const char *msgid,
          249                   const char *msgid_plural, unsigned long int n,
          250                   int category)
          251 {
          252   size_t msgctxt_len = strlen (msgctxt) + 1;
          253   size_t msgid_len = strlen (msgid) + 1;
          254   const char *translation;
          255 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
          256   char msg_ctxt_id[msgctxt_len + msgid_len];
          257 #else
          258   char buf[1024];
          259   char *msg_ctxt_id =
          260     (msgctxt_len + msgid_len <= sizeof (buf)
          261      ? buf
          262      : (char *) malloc (msgctxt_len + msgid_len));
          263   if (msg_ctxt_id != NULL)
          264 #endif
          265     {
          266       memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
          267       msg_ctxt_id[msgctxt_len - 1] = '\004';
          268       memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
          269       translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
          270 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
          271       if (msg_ctxt_id != buf)
          272         free (msg_ctxt_id);
          273 #endif
          274       if (!(translation == msg_ctxt_id || translation == msgid_plural))
          275         return translation;
          276     }
          277   return (n == 1 ? msgid : msgid_plural);
          278 }
          279 
          280 #endif /* _LIBGETTEXT_H */