gerbv  2.10.1-dev~93f1b5
gettext.h
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) dgettext(DEFAULT_TEXT_DOMAIN, Msgid)
34 #undef ngettext
35 #define ngettext(Msgid1, Msgid2, N) dngettext(DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
36 #endif
37 
38 #else
39 
40 /* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
41  chokes if dcgettext is defined as a macro. So include it now, to make
42  later inclusions of <locale.h> a NOP. We don't include <libintl.h>
43  as well because people using "gettext.h" will not include <libintl.h>,
44  and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
45  is OK. */
46 #if defined(__sun)
47 #include <locale.h>
48 #endif
49 
50 /* Many header files from the libstdc++ coming with g++ 3.3 or newer include
51  <libintl.h>, which chokes if dcgettext is defined as a macro. So include
52  it now, to make later inclusions of <libintl.h> a NOP. */
53 #if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
54 #include <cstdlib>
55 #if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
56 #include <libintl.h>
57 #endif
58 #endif
59 
60 /* Disabled NLS.
61  The casts to 'const char *' serve the purpose of producing warnings
62  for invalid uses of the value returned from these functions.
63  On pre-ANSI systems without 'const', the config.h file is supposed to
64  contain "#define const". */
65 #undef gettext
66 #define gettext(Msgid) ((const char*)(Msgid))
67 #undef dgettext
68 #define dgettext(Domainname, Msgid) ((void)(Domainname), gettext(Msgid))
69 #undef dcgettext
70 #define dcgettext(Domainname, Msgid, Category) ((void)(Category), dgettext(Domainname, Msgid))
71 #undef ngettext
72 #define ngettext(Msgid1, Msgid2, N) \
73  ((N) == 1 ? ((void)(Msgid2), (const char*)(Msgid1)) : ((void)(Msgid1), (const char*)(Msgid2)))
74 #undef dngettext
75 #define dngettext(Domainname, Msgid1, Msgid2, N) ((void)(Domainname), ngettext(Msgid1, Msgid2, N))
76 #undef dcngettext
77 #define dcngettext(Domainname, Msgid1, Msgid2, N, Category) ((void)(Category), dngettext(Domainname, Msgid1, Msgid2, N))
78 #undef textdomain
79 #define textdomain(Domainname) ((const char*)(Domainname))
80 #undef bindtextdomain
81 #define bindtextdomain(Domainname, Dirname) ((void)(Domainname), (const char*)(Dirname))
82 #undef bind_textdomain_codeset
83 #define bind_textdomain_codeset(Domainname, Codeset) ((void)(Domainname), (const char*)(Codeset))
84 
85 #endif
86 
87 /* A pseudo function call that serves as a marker for the automated
88  extraction of messages, but does not call gettext(). The run-time
89  translation is done at a different place in the code.
90  The argument, String, should be a literal string. Concatenated strings
91  and other string expressions won't work.
92  The macro's expansion is not parenthesized, so that it is suitable as
93  initializer for static 'char[]' or 'const char[]' variables. */
94 #define gettext_noop(String) String
95 
96 /* The separator between msgctxt and msgid in a .mo file. */
97 #define GETTEXT_CONTEXT_GLUE "\004"
98 
99 /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
100  MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
101  short and rarely need to change.
102  The letter 'p' stands for 'particular' or 'special'. */
103 #ifdef DEFAULT_TEXT_DOMAIN
104 #define pgettext(Msgctxt, Msgid) \
105  pgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
106 #else
107 #define pgettext(Msgctxt, Msgid) pgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
108 #endif
109 #define dpgettext(Domainname, Msgctxt, Msgid) \
110  pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
111 #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
112  pgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
113 #ifdef DEFAULT_TEXT_DOMAIN
114 #define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
115  npgettext_aux(DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
116 #else
117 #define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
118  npgettext_aux(NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
119 #endif
120 #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
121  npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
122 #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
123  npgettext_aux(Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
124 
125 #ifdef __GNUC__
126 __inline
127 #else
128 #ifdef __cplusplus
129 inline
130 #endif
131 #endif
132  static const char*
133  pgettext_aux(const char* domain, const char* msg_ctxt_id, const char* msgid, int category) {
134  const char* translation = dcgettext(domain, msg_ctxt_id, category);
135  if (translation == msg_ctxt_id)
136  return msgid;
137  else
138  return translation;
139 }
140 
141 #ifdef __GNUC__
142 __inline
143 #else
144 #ifdef __cplusplus
145 inline
146 #endif
147 #endif
148  static const char*
149  npgettext_aux(
150  const char* domain, const char* msg_ctxt_id, const char* msgid, const char* msgid_plural, unsigned long int n,
151  int category
152  ) {
153  const char* translation = dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
154  if (translation == msg_ctxt_id || translation == msgid_plural)
155  return (n == 1 ? msgid : msgid_plural);
156  else
157  return translation;
158 }
159 
160 /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
161  can be arbitrary expressions. But for string literals these macros are
162  less efficient than those above. */
163 
164 #include <string.h>
165 
166 #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
167  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) /* || __STDC_VERSION__ >= 199901L */)
168 
169 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
170 #include <stdlib.h>
171 #endif
172 
173 #define pgettext_expr(Msgctxt, Msgid) dcpgettext_expr(NULL, Msgctxt, Msgid, LC_MESSAGES)
174 #define dpgettext_expr(Domainname, Msgctxt, Msgid) dcpgettext_expr(Domainname, Msgctxt, Msgid, LC_MESSAGES)
175 
176 #ifdef __GNUC__
177 __inline
178 #else
179 #ifdef __cplusplus
180 inline
181 #endif
182 #endif
183  static const char*
184  dcpgettext_expr(const char* domain, const char* msgctxt, const char* msgid, int category) {
185  size_t msgctxt_len = strlen(msgctxt) + 1;
186  size_t msgid_len = strlen(msgid) + 1;
187  const char* translation;
188 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
189  char msg_ctxt_id[msgctxt_len + msgid_len];
190 #else
191  char buf[1024];
192  char* msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof(buf) ? buf : (char*)malloc(msgctxt_len + msgid_len));
193  if (msg_ctxt_id != NULL)
194 #endif
195  {
196  memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
197  msg_ctxt_id[msgctxt_len - 1] = '\004';
198  memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
199  translation = dcgettext(domain, msg_ctxt_id, category);
200 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
201  if (msg_ctxt_id != buf)
202  free(msg_ctxt_id);
203 #endif
204  if (translation != msg_ctxt_id)
205  return translation;
206  }
207  return msgid;
208 }
209 
210 #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
211  dcnpgettext_expr(NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
212 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
213  dcnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
214 
215 #ifdef __GNUC__
216 __inline
217 #else
218 #ifdef __cplusplus
219 inline
220 #endif
221 #endif
222  static const char*
223  dcnpgettext_expr(
224  const char* domain, const char* msgctxt, const char* msgid, const char* msgid_plural, unsigned long int n,
225  int category
226  ) {
227  size_t msgctxt_len = strlen(msgctxt) + 1;
228  size_t msgid_len = strlen(msgid) + 1;
229  const char* translation;
230 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
231  char msg_ctxt_id[msgctxt_len + msgid_len];
232 #else
233  char buf[1024];
234  char* msg_ctxt_id = (msgctxt_len + msgid_len <= sizeof(buf) ? buf : (char*)malloc(msgctxt_len + msgid_len));
235  if (msg_ctxt_id != NULL)
236 #endif
237  {
238  memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
239  msg_ctxt_id[msgctxt_len - 1] = '\004';
240  memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
241  translation = dcngettext(domain, msg_ctxt_id, msgid_plural, n, category);
242 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
243  if (msg_ctxt_id != buf)
244  free(msg_ctxt_id);
245 #endif
246  if (!(translation == msg_ctxt_id || translation == msgid_plural))
247  return translation;
248  }
249  return (n == 1 ? msgid : msgid_plural);
250 }
251 
252 #endif /* _LIBGETTEXT_H */