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