File indexing completed on 2024-04-28 11:40:00
0001 /* Convenience header for conditional use of GNU <libintl.h>. 0002 SPDX-FileCopyrightText: 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc. 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 // clang-format off 0007 #ifndef _LIBGETTEXT_H 0008 #define _LIBGETTEXT_H 1 0009 0010 /* Get declarations of GNU message catalog functions. */ 0011 # include <libintl.h> 0012 // libintl.h redefines inline which causes MSVC to abort compilation with the message 0013 // fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords 0014 #undef inline 0015 0016 /* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by 0017 the gettext() and ngettext() macros. This is an alternative to calling 0018 textdomain(), and is useful for libraries. */ 0019 # ifdef DEFAULT_TEXT_DOMAIN 0020 # undef gettext 0021 # define gettext(Msgid) \ 0022 dgettext (DEFAULT_TEXT_DOMAIN, Msgid) 0023 # undef ngettext 0024 # define ngettext(Msgid1, Msgid2, N) \ 0025 dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) 0026 # endif 0027 0028 /* The separator between msgctxt and msgid in a .mo file. */ 0029 #define GETTEXT_CONTEXT_GLUE "\004" 0030 0031 /* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a 0032 MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be 0033 short and rarely need to change. 0034 The letter 'p' stands for 'particular' or 'special'. */ 0035 #ifdef DEFAULT_TEXT_DOMAIN 0036 # define pgettext(Msgctxt, Msgid) \ 0037 pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid) 0038 #else 0039 # define pgettext(Msgctxt, Msgid) \ 0040 pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid) 0041 #endif 0042 #define dpgettext(Domainname, Msgctxt, Msgid) \ 0043 pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid) 0044 0045 #ifdef __GNUC__ 0046 __inline 0047 #else 0048 #ifdef __cplusplus 0049 inline 0050 #endif 0051 #endif 0052 static const char * 0053 pgettext_aux(const char *domain, 0054 const char *msg_ctxt_id, const char *msgid) 0055 { 0056 const char *translation = dgettext(domain, msg_ctxt_id); 0057 if (translation == msg_ctxt_id) { 0058 return msgid; 0059 } else { 0060 return translation; 0061 } 0062 } 0063 0064 /* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID 0065 can be arbitrary expressions. But for string literals these macros are 0066 less efficient than those above. */ 0067 0068 #include <string.h> 0069 0070 #ifndef __STRICT_ANSI__ 0071 #define __STRICT_ANSI__ 0072 #define __STRICT_ANSI_FORCED__ 0073 #endif 0074 0075 #define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ 0076 (__STRICT_ANSI__ - 0 == 0) && (__GNUC__ >= 3 || __GNUG__ >= 2 /* || __STDC_VERSION__ >= 199901L */ ) 0077 0078 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0079 #include <stdlib.h> 0080 #endif 0081 0082 #define pgettext_expr(Msgctxt, Msgid) \ 0083 dpgettext_expr (NULL, Msgctxt, Msgid) 0084 #define dpgettext_expr(Domainname, Msgctxt, Msgid) \ 0085 dpgettext_expr (Domainname, Msgctxt, Msgid) 0086 0087 #ifdef __GNUC__ 0088 __inline 0089 #else 0090 #ifdef __cplusplus 0091 inline 0092 #endif 0093 #endif 0094 static const char * 0095 dpgettext_expr(const char *domain, 0096 const char *msgctxt, const char *msgid) 0097 { 0098 size_t msgctxt_len = strlen(msgctxt) + 1; 0099 size_t msgid_len = strlen(msgid) + 1; 0100 const char *translation; 0101 int translation_found; 0102 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0103 char msg_ctxt_id[msgctxt_len + msgid_len]; 0104 #else 0105 char buf[1024]; 0106 char *msg_ctxt_id = 0107 (msgctxt_len + msgid_len <= sizeof(buf) 0108 ? buf 0109 : (char *) malloc(msgctxt_len + msgid_len)); 0110 if (msg_ctxt_id != nullptr) 0111 #endif 0112 { 0113 memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1); 0114 msg_ctxt_id[msgctxt_len - 1] = '\004'; 0115 memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len); 0116 translation = dgettext(domain, msg_ctxt_id); 0117 /* Test must occur before msg_ctxt_id freed */ 0118 translation_found = translation != msg_ctxt_id; 0119 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0120 if (msg_ctxt_id != buf) { 0121 free(msg_ctxt_id); 0122 } 0123 #endif 0124 if (translation_found) { 0125 return translation; 0126 } 0127 } 0128 return msgid; 0129 } 0130 0131 #define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ 0132 dnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N) 0133 #define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ 0134 dnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N) 0135 0136 #ifdef __GNUC__ 0137 __inline 0138 #else 0139 #ifdef __cplusplus 0140 inline 0141 #endif 0142 #endif 0143 static const char * 0144 dnpgettext_expr(const char *domain, 0145 const char *msgctxt, const char *msgid, 0146 const char *msgid_plural, unsigned long int n) 0147 { 0148 size_t msgctxt_len = strlen(msgctxt) + 1; 0149 size_t msgid_len = strlen(msgid) + 1; 0150 const char *translation; 0151 int translation_found; 0152 #if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0153 char msg_ctxt_id[msgctxt_len + msgid_len]; 0154 #else 0155 char buf[1024]; 0156 char *msg_ctxt_id = 0157 (msgctxt_len + msgid_len <= sizeof(buf) 0158 ? buf 0159 : (char *) malloc(msgctxt_len + msgid_len)); 0160 if (msg_ctxt_id != nullptr) 0161 #endif 0162 { 0163 memcpy(msg_ctxt_id, msgctxt, msgctxt_len - 1); 0164 msg_ctxt_id[msgctxt_len - 1] = '\004'; 0165 memcpy(msg_ctxt_id + msgctxt_len, msgid, msgid_len); 0166 translation = dngettext(domain, msg_ctxt_id, msgid_plural, n); 0167 /* Test must occur before msg_ctxt_id freed */ 0168 translation_found = !(translation == msg_ctxt_id || translation == msgid_plural); 0169 #if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0170 if (msg_ctxt_id != buf) { 0171 free(msg_ctxt_id); 0172 } 0173 #endif 0174 if (translation_found) { 0175 return translation; 0176 } 0177 } 0178 return (n == 1 ? msgid : msgid_plural); 0179 } 0180 0181 #ifdef __STRICT_ANSI_FORCED__ 0182 #undef __STRICT_ANSI__ 0183 #undef __STRICT_ANSI_FORCED__ 0184 #endif 0185 0186 #endif /* _LIBGETTEXT_H */ 0187 // clang-format on