comparison src/gettext.h @ 1532:fffb62c7ba1e

Add pgettext for some ambiguous strings There are some strings which are ambiguous to translate. There is the pgettext function to solf that problem. For example, locations can be translated to german by Ortsangaben (geographical) or by Pfad (filesystem). I am sure there are also some ambiguous in other languages.
author mow
date Fri, 10 Apr 2009 09:47:20 +0000
parents
children
comparison
equal deleted inserted replaced
1531:b71dcbada16b 1532:fffb62c7ba1e
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) || _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 /* 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) \
108 pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
109 #endif
110 #define dpgettext(Domainname, Msgctxt, Msgid) \
111 pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
112 #define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
113 pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
114 #ifdef DEFAULT_TEXT_DOMAIN
115 # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
116 npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
117 #else
118 # define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
119 npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
120 #endif
121 #define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
122 npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
123 #define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
124 npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
125
126 #ifdef __GNUC__
127 __inline
128 #else
129 #ifdef __cplusplus
130 inline
131 #endif
132 #endif
133 static const char *
134 pgettext_aux (const char *domain,
135 const char *msg_ctxt_id, const char *msgid,
136 int category)
137 {
138 const char *translation = dcgettext (domain, msg_ctxt_id, category);
139 if (translation == msg_ctxt_id)
140 return msgid;
141 else
142 return translation;
143 }
144
145 #ifdef __GNUC__
146 __inline
147 #else
148 #ifdef __cplusplus
149 inline
150 #endif
151 #endif
152 static const char *
153 npgettext_aux (const char *domain,
154 const char *msg_ctxt_id, const char *msgid,
155 const char *msgid_plural, unsigned long int n,
156 int category)
157 {
158 const char *translation =
159 dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
160 if (translation == msg_ctxt_id || translation == msgid_plural)
161 return (n == 1 ? msgid : msgid_plural);
162 else
163 return translation;
164 }
165
166 /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
167 can be arbitrary expressions. But for string literals these macros are
168 less efficient than those above. */
169
170 #include <string.h>
171
172 #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
173 (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
174 /* || __STDC_VERSION__ >= 199901L */ )
175
176 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
177 #include <stdlib.h>
178 #endif
179
180 #define pgettext_expr(Msgctxt, Msgid) \
181 dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
182 #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
183 dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
184
185 #ifdef __GNUC__
186 __inline
187 #else
188 #ifdef __cplusplus
189 inline
190 #endif
191 #endif
192 static const char *
193 dcpgettext_expr (const char *domain,
194 const char *msgctxt, const char *msgid,
195 int category)
196 {
197 size_t msgctxt_len = strlen (msgctxt) + 1;
198 size_t msgid_len = strlen (msgid) + 1;
199 const char *translation;
200 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
201 char msg_ctxt_id[msgctxt_len + msgid_len];
202 #else
203 char buf[1024];
204 char *msg_ctxt_id =
205 (msgctxt_len + msgid_len <= sizeof (buf)
206 ? buf
207 : (char *) malloc (msgctxt_len + msgid_len));
208 if (msg_ctxt_id != NULL)
209 #endif
210 {
211 memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
212 msg_ctxt_id[msgctxt_len - 1] = '\004';
213 memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
214 translation = dcgettext (domain, msg_ctxt_id, category);
215 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
216 if (msg_ctxt_id != buf)
217 free (msg_ctxt_id);
218 #endif
219 if (translation != msg_ctxt_id)
220 return translation;
221 }
222 return msgid;
223 }
224
225 #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
226 dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
227 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
228 dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
229
230 #ifdef __GNUC__
231 __inline
232 #else
233 #ifdef __cplusplus
234 inline
235 #endif
236 #endif
237 static const char *
238 dcnpgettext_expr (const char *domain,
239 const char *msgctxt, const char *msgid,
240 const char *msgid_plural, unsigned long int n,
241 int category)
242 {
243 size_t msgctxt_len = strlen (msgctxt) + 1;
244 size_t msgid_len = strlen (msgid) + 1;
245 const char *translation;
246 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
247 char msg_ctxt_id[msgctxt_len + msgid_len];
248 #else
249 char buf[1024];
250 char *msg_ctxt_id =
251 (msgctxt_len + msgid_len <= sizeof (buf)
252 ? buf
253 : (char *) malloc (msgctxt_len + msgid_len));
254 if (msg_ctxt_id != NULL)
255 #endif
256 {
257 memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
258 msg_ctxt_id[msgctxt_len - 1] = '\004';
259 memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
260 translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
261 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
262 if (msg_ctxt_id != buf)
263 free (msg_ctxt_id);
264 #endif
265 if (!(translation == msg_ctxt_id || translation == msgid_plural))
266 return translation;
267 }
268 return (n == 1 ? msgid : msgid_plural);
269 }
270
271 #endif /* _LIBGETTEXT_H */