Branch data Line data Source code
1 : : /* Convenience header for conditional use of GNU <libintl.h>.
2 : : Copyright (C) 1995-1998, 2000-2002, 2004-2006 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 2, 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 && !defined __UCLIBC__) || _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 : : # define gettext(Msgid) ((const char *) (Msgid))
68 : : # define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
69 : : # define dcgettext(Domainname, Msgid, Category) \
70 : : ((void) (Category), dgettext (Domainname, Msgid))
71 : : # define ngettext(Msgid1, Msgid2, N) \
72 : : ((N) == 1 \
73 : : ? (const char *)(Msgid1) \
74 : : : (const char *)(Msgid2))
75 : : # define dngettext(Domainname, Msgid1, Msgid2, N) \
76 : : ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
77 : : # define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
78 : : ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
79 : : # define textdomain(Domainname) ((const char *) (Domainname))
80 : : # define bindtextdomain(Domainname, Dirname) \
81 : : ((void) (Domainname), (const char *) (Dirname))
82 : : # define bind_textdomain_codeset(Domainname, Codeset) \
83 : : ((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 : : #if ENABLE_NLS
100 : :
101 : : /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
102 : : MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
103 : : short and rarely need to change.
104 : : The letter 'p' stands for 'particular' or 'special'. */
105 : : #ifdef DEFAULT_TEXT_DOMAIN
106 : : # define pgettext(Msgctxt, Msgid) \
107 : : pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
108 : : #else
109 : : # define pgettext(Msgctxt, Msgid) \
110 : : pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
111 : : #endif
112 : : #define dpgettext(Domainname, Msgctxt, Msgid) \
113 : : pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
114 : : #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
115 : : pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
116 : : #ifdef DEFAULT_TEXT_DOMAIN
117 : : # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
118 : : npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
119 : : #else
120 : : # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
121 : : npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
122 : : #endif
123 : : #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
124 : : npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
125 : : #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
126 : : npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
127 : :
128 : : #ifdef __GNUC__
129 : : __inline
130 : : #else
131 : : #ifdef __cplusplus
132 : : inline
133 : : #endif
134 : : #endif
135 : : static const char *
136 : 4 : pgettext_aux (const char *domain,
137 : : const char *msg_ctxt_id, const char *msgid,
138 : : int category)
139 : : {
140 : 4 : const char *translation = dcgettext (domain, msg_ctxt_id, category);
141 [ + - ]: 4 : if (translation == msg_ctxt_id)
142 : 4 : return msgid;
143 : : else
144 : 0 : return translation;
145 : : }
146 : :
147 : : #ifdef __GNUC__
148 : : __inline
149 : : #else
150 : : #ifdef __cplusplus
151 : : inline
152 : : #endif
153 : : #endif
154 : : static const char *
155 : : npgettext_aux (const char *domain,
156 : : const char *msg_ctxt_id, const char *msgid,
157 : : const char *msgid_plural, unsigned long int n,
158 : : int category)
159 : : {
160 : : const char *translation =
161 : : dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
162 : : if (translation == msg_ctxt_id || translation == msgid_plural)
163 : : return (n == 1 ? msgid : msgid_plural);
164 : : else
165 : : return translation;
166 : : }
167 : :
168 : : /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
169 : : can be arbitrary expressions. But for string literals these macros are
170 : : less efficient than those above. */
171 : :
172 : : #include <string.h>
173 : :
174 : : /* We do not want VLAs, which have a terrible failure mode on stack
175 : : * exhaustion. */
176 : : #if 0
177 : : #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
178 : : (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
179 : : /* || __STDC_VERSION__ >= 199901L */ )
180 : : #endif
181 : :
182 : : #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
183 : : #include <stdlib.h>
184 : : #endif
185 : :
186 : : #define pgettext_expr(Msgctxt, Msgid) \
187 : : dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
188 : : #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
189 : : dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
190 : :
191 : : #ifdef __GNUC__
192 : : __inline
193 : : #else
194 : : #ifdef __cplusplus
195 : : inline
196 : : #endif
197 : : #endif
198 : : static const char *
199 : : dcpgettext_expr (const char *domain,
200 : : const char *msgctxt, const char *msgid,
201 : : int category)
202 : : {
203 : : size_t msgctxt_len = strlen (msgctxt) + 1;
204 : : size_t msgid_len = strlen (msgid) + 1;
205 : : const char *translation;
206 : : #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
207 : : char msg_ctxt_id[msgctxt_len + msgid_len];
208 : : #else
209 : : char buf[1024];
210 : : char *msg_ctxt_id =
211 : : (msgctxt_len + msgid_len <= sizeof (buf)
212 : : ? buf
213 : : : (char *) malloc (msgctxt_len + msgid_len));
214 : : if (msg_ctxt_id != NULL)
215 : : #endif
216 : : {
217 : : memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
218 : : msg_ctxt_id[msgctxt_len - 1] = '\004';
219 : : memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
220 : : translation = dcgettext (domain, msg_ctxt_id, category);
221 : : #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
222 : : if (msg_ctxt_id != buf)
223 : : free (msg_ctxt_id);
224 : : #endif
225 : : if (translation != msg_ctxt_id)
226 : : return translation;
227 : : }
228 : : return msgid;
229 : : }
230 : :
231 : : #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
232 : : dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
233 : : #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
234 : : dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
235 : :
236 : : #ifdef __GNUC__
237 : : __inline
238 : : #else
239 : : #ifdef __cplusplus
240 : : inline
241 : : #endif
242 : : #endif
243 : : static const char *
244 : : dcnpgettext_expr (const char *domain,
245 : : const char *msgctxt, const char *msgid,
246 : : const char *msgid_plural, unsigned long int n,
247 : : int category)
248 : : {
249 : : size_t msgctxt_len = strlen (msgctxt) + 1;
250 : : size_t msgid_len = strlen (msgid) + 1;
251 : : const char *translation;
252 : : #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
253 : : char msg_ctxt_id[msgctxt_len + msgid_len];
254 : : #else
255 : : char buf[1024];
256 : : char *msg_ctxt_id =
257 : : (msgctxt_len + msgid_len <= sizeof (buf)
258 : : ? buf
259 : : : (char *) malloc (msgctxt_len + msgid_len));
260 : : if (msg_ctxt_id != NULL)
261 : : #endif
262 : : {
263 : : memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
264 : : msg_ctxt_id[msgctxt_len - 1] = '\004';
265 : : memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
266 : : translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
267 : : #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
268 : : if (msg_ctxt_id != buf)
269 : : free (msg_ctxt_id);
270 : : #endif
271 : : if (!(translation == msg_ctxt_id || translation == msgid_plural))
272 : : return translation;
273 : : }
274 : : return (n == 1 ? msgid : msgid_plural);
275 : : }
276 : :
277 : : #else /* ENABLE_NLS */
278 : :
279 : : #define pgettext(Msgctxt, Msgid) ((void) (Msgctxt), gettext (Msgid))
280 : : #define dpgettext(Domainname, Msgctxt, Msgid) \
281 : : ((void) (Domainname), pgettext (Msgctxt, Msgid))
282 : : #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
283 : : ((void) (Category), dpgettext (Domainname, Msgctxt, Msgid))
284 : :
285 : : #define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
286 : : ((void) (Msgctxt), ngettext (Msgid, MsgidPlural, N))
287 : : #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
288 : : ((void) (Domainname), npgettext (Msgctxt, Msgid, MsgidPlural, N)
289 : : #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
290 : : ((void) (Category), dnpgettext (Domainname, Msgctxt, Msgid, MsgidPlural, N)
291 : :
292 : : #define pgettext_expr(Msgctxt, Msgid) pgettext (Msgctxt, Msgid)
293 : : #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
294 : : dpgettext (Domainname, Msgctxt, Msgid)
295 : : #define dcpgettext_expr(Domainname, Msgctxt, Msgid, Category) \
296 : : dcpgettext (Domainname, Msgctxt, Msgid, Category)
297 : :
298 : : #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
299 : : npgettext (Msgctxt, Msgid, MsgidPlural, N)
300 : : #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
301 : : dnpgettext (Domainname, Msgctxt, Msgid, MsgidPlural, N)
302 : : #define dcnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
303 : : dcnpgettext (Domainname, Msgctxt, Msgid, MsgidPlural, N, Category)
304 : :
305 : : #endif /* ENABLE_NLS */
306 : :
307 : : #endif /* _LIBGETTEXT_H */
|