KI18n

gettext.h
1 /* Convenience header for conditional use of GNU <libintl.h>.
2  SPDX-FileCopyrightText: 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 // clang-format off
7 #ifndef _LIBGETTEXT_H
8 #define _LIBGETTEXT_H 1
9 
10 /* Get declarations of GNU message catalog functions. */
11 # include <libintl.h>
12 // libintl.h redefines inline which causes MSVC to abort compilation with the message
13 // fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords
14 #undef inline
15 
16 /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
17  the gettext() and ngettext() macros. This is an alternative to calling
18  textdomain(), and is useful for libraries. */
19 # ifdef DEFAULT_TEXT_DOMAIN
20 # undef gettext
21 # define gettext(Msgid) \
22  dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
23 # undef ngettext
24 # define ngettext(Msgid1, Msgid2, N) \
25  dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
26 # endif
27 
28 /* The separator between msgctxt and msgid in a .mo file. */
29 #define GETTEXT_CONTEXT_GLUE "\004"
30 
31 /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
32  MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
33  short and rarely need to change.
34  The letter 'p' stands for 'particular' or 'special'. */
35 #ifdef DEFAULT_TEXT_DOMAIN
36 # define pgettext(Msgctxt, Msgid) \
37  pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid)
38 #else
39 # define pgettext(Msgctxt, Msgid) \
40  pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid)
41 #endif
42 #define dpgettext(Domainname, Msgctxt, Msgid) \
43  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid)
44 
45 #ifdef __GNUC__
46 __inline
47 #else
48 #ifdef __cplusplus
49 inline
50 #endif
51 #endif
52 static const char *
53 pgettext_aux(const char *domain,
54  const char *msg_ctxt_id, const char *msgid)
55 {
56  const char *translation = dgettext(domain, msg_ctxt_id);
57  if (translation == msg_ctxt_id) {
58  return msgid;
59  } else {
60  return translation;
61  }
62 }
63 
64 /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
65  can be arbitrary expressions. But for string literals these macros are
66  less efficient than those above. */
67 
68 #include <string.h>
69 
70 #ifndef __STRICT_ANSI__
71 #define __STRICT_ANSI__
72 #define __STRICT_ANSI_FORCED__
73 #endif
74 
75 #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
76  (__STRICT_ANSI__ - 0 == 0) && (__GNUC__ >= 3 || __GNUG__ >= 2 /* || __STDC_VERSION__ >= 199901L */ )
77 
78 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
79 #include <stdlib.h>
80 #endif
81 
82 #define pgettext_expr(Msgctxt, Msgid) \
83  dpgettext_expr (NULL, Msgctxt, Msgid)
84 #define dpgettext_expr(Domainname, Msgctxt, Msgid) \
85  dpgettext_expr (Domainname, Msgctxt, Msgid)
86 
87 #ifdef __GNUC__
88 __inline
89 #else
90 #ifdef __cplusplus
91 inline
92 #endif
93 #endif
94 static const char *
95 dpgettext_expr(const char *domain,
96  const char *msgctxt, const char *msgid)
97 {
98  size_t msgctxt_len = strlen(msgctxt) + 1;
99  size_t msgid_len = strlen(msgid) + 1;
100  const char *translation;
101  int translation_found;
102 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
103  char msg_ctxt_id[msgctxt_len + msgid_len];
104 #else
105  char buf[1024];
106  char *msg_ctxt_id =
107  (msgctxt_len + msgid_len <= sizeof(buf)
108  ? buf
109  : (char *) malloc(msgctxt_len + msgid_len));
110  if (msg_ctxt_id != nullptr)
111 #endif
112  {
113  memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
114  msg_ctxt_id[msgctxt_len - 1] = '\004';
115  memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
116  translation = dgettext(domain, msg_ctxt_id);
117  /* Test must occur before msg_ctxt_id freed */
118  translation_found = translation != msg_ctxt_id;
119 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
120  if (msg_ctxt_id != buf) {
121  free(msg_ctxt_id);
122  }
123 #endif
124  if (translation_found) {
125  return translation;
126  }
127  }
128  return msgid;
129 }
130 
131 #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
132  dnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N)
133 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
134  dnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N)
135 
136 #ifdef __GNUC__
137 __inline
138 #else
139 #ifdef __cplusplus
140 inline
141 #endif
142 #endif
143 static const char *
144 dnpgettext_expr(const char *domain,
145  const char *msgctxt, const char *msgid,
146  const char *msgid_plural, unsigned long int n)
147 {
148  size_t msgctxt_len = strlen(msgctxt) + 1;
149  size_t msgid_len = strlen(msgid) + 1;
150  const char *translation;
151  int translation_found;
152 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
153  char msg_ctxt_id[msgctxt_len + msgid_len];
154 #else
155  char buf[1024];
156  char *msg_ctxt_id =
157  (msgctxt_len + msgid_len <= sizeof(buf)
158  ? buf
159  : (char *) malloc(msgctxt_len + msgid_len));
160  if (msg_ctxt_id != nullptr)
161 #endif
162  {
163  memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1);
164  msg_ctxt_id[msgctxt_len - 1] = '\004';
165  memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len);
166  translation = dngettext(domain, msg_ctxt_id, msgid_plural, n);
167  /* Test must occur before msg_ctxt_id freed */
168  translation_found = !(translation == msg_ctxt_id || translation == msgid_plural);
169 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
170  if (msg_ctxt_id != buf) {
171  free(msg_ctxt_id);
172  }
173 #endif
174  if (translation_found) {
175  return translation;
176  }
177  }
178  return (n == 1 ? msgid : msgid_plural);
179 }
180 
181 #ifdef __STRICT_ANSI_FORCED__
182 #undef __STRICT_ANSI__
183 #undef __STRICT_ANSI_FORCED__
184 #endif
185 
186 #endif /* _LIBGETTEXT_H */
187 // clang-format on
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Tue Aug 16 2022 04:07:13 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.