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 : : ? ((void) (Msgid2), (const char *) (Msgid1)) \
74 : : : ((void) (Msgid1), (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 : : #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
175 : : (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
176 : : /* || __STDC_VERSION__ >= 199901L */ )
177 : :
178 : : #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
179 : : #include <stdlib.h>
180 : : #endif
181 : :
182 : : #define pgettext_expr(Msgctxt, Msgid) \
183 : : dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
184 : : #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
185 : : dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
186 : :
187 : : #ifdef __GNUC__
188 : : __inline
189 : : #else
190 : : #ifdef __cplusplus
191 : : inline
192 : : #endif
193 : : #endif
194 : : static const char *
195 : : dcpgettext_expr (const char *domain,
196 : : const char *msgctxt, const char *msgid,
197 : : int category)
198 : : {
199 : : size_t msgctxt_len = strlen (msgctxt) + 1;
200 : : size_t msgid_len = strlen (msgid) + 1;
201 : : const char *translation;
202 : : #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
203 : : char msg_ctxt_id[msgctxt_len + msgid_len];
204 : : #else
205 : : char buf[1024];
206 : : char *msg_ctxt_id =
207 : : (msgctxt_len + msgid_len <= sizeof (buf)
208 : : ? buf
209 : : : (char *) malloc (msgctxt_len + msgid_len));
210 : : if (msg_ctxt_id != NULL)
211 : : #endif
212 : : {
213 : : memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
214 : : msg_ctxt_id[msgctxt_len - 1] = '\004';
215 : : memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
216 : : translation = dcgettext (domain, msg_ctxt_id, category);
217 : : #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
218 : : if (msg_ctxt_id != buf)
219 : : free (msg_ctxt_id);
220 : : #endif
221 : : if (translation != msg_ctxt_id)
222 : : return translation;
223 : : }
224 : : return msgid;
225 : : }
226 : :
227 : : #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
228 : : dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
229 : : #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
230 : : dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
231 : :
232 : : #ifdef __GNUC__
233 : : __inline
234 : : #else
235 : : #ifdef __cplusplus
236 : : inline
237 : : #endif
238 : : #endif
239 : : static const char *
240 : : dcnpgettext_expr (const char *domain,
241 : : const char *msgctxt, const char *msgid,
242 : : const char *msgid_plural, unsigned long int n,
243 : : int category)
244 : : {
245 : : size_t msgctxt_len = strlen (msgctxt) + 1;
246 : : size_t msgid_len = strlen (msgid) + 1;
247 : : const char *translation;
248 : : #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
249 : : char msg_ctxt_id[msgctxt_len + msgid_len];
250 : : #else
251 : : char buf[1024];
252 : : char *msg_ctxt_id =
253 : : (msgctxt_len + msgid_len <= sizeof (buf)
254 : : ? buf
255 : : : (char *) malloc (msgctxt_len + msgid_len));
256 : : if (msg_ctxt_id != NULL)
257 : : #endif
258 : : {
259 : : memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
260 : : msg_ctxt_id[msgctxt_len - 1] = '\004';
261 : : memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
262 : : translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
263 : : #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
264 : : if (msg_ctxt_id != buf)
265 : : free (msg_ctxt_id);
266 : : #endif
267 : : if (!(translation == msg_ctxt_id || translation == msgid_plural))
268 : : return translation;
269 : : }
270 : : return (n == 1 ? msgid : msgid_plural);
271 : : }
272 : :
273 : : #else /* ENABLE_NLS */
274 : :
275 : : #define pgettext(Msgctxt, Msgid) ((void) (Msgctxt), gettext (Msgid))
276 : : #define dpgettext(Domainname, Msgctxt, Msgid) \
277 : : ((void) (Domainname), pgettext (Msgctxt, Msgid))
278 : : #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
279 : : ((void) (Category), dpgettext (Domainname, Msgctxt, Msgid))
280 : :
281 : : #define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
282 : : ((void) (Msgctxt), ngettext (Msgid, MsgidPlural, N))
283 : : #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
284 : : ((void) (Domainname), npgettext (Msgctxt, Msgid, MsgidPlural, N)
285 : : #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
286 : : ((void) (Category), dnpgettext (Domainname, Msgctxt, Msgid, MsgidPlural, N)
287 : :
288 : : #define pgettext_expr(Msgctxt, Msgid) pgettext (Msgctxt, Msgid)
289 : : #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
290 : : dpgettext (Domainname, Msgctxt, Msgid)
291 : : #define dcpgettext_expr(Domainname, Msgctxt, Msgid, Category) \
292 : : dcpgettext (Domainname, Msgctxt, Msgid, Category)
293 : :
294 : : #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
295 : : npgettext (Msgctxt, Msgid, MsgidPlural, N)
296 : : #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
297 : : dnpgettext (Domainname, Msgctxt, Msgid, MsgidPlural, N)
298 : : #define dcnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
299 : : dcnpgettext (Domainname, Msgctxt, Msgid, MsgidPlural, N, Category)
300 : :
301 : : #endif /* ENABLE_NLS */
302 : :
303 : : #endif /* _LIBGETTEXT_H */
|