Mercurial > repos > rliterman > csp2
comparison CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/share/doc/gettext/gettext_11.html @ 68:5028fdace37b
planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author | jpayne |
---|---|
date | Tue, 18 Mar 2025 16:23:26 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
67:0e9998148a16 | 68:5028fdace37b |
---|---|
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html401/loose.dtd"> | |
2 <html> | |
3 <!-- Created on February, 21 2024 by texi2html 1.78a --> | |
4 <!-- | |
5 Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) | |
6 Karl Berry <karl@freefriends.org> | |
7 Olaf Bachmann <obachman@mathematik.uni-kl.de> | |
8 and many others. | |
9 Maintained by: Many creative people. | |
10 Send bugs and suggestions to <texi2html-bug@nongnu.org> | |
11 | |
12 --> | |
13 <head> | |
14 <title>GNU gettext utilities: 11. The Programmer's View</title> | |
15 | |
16 <meta name="description" content="GNU gettext utilities: 11. The Programmer's View"> | |
17 <meta name="keywords" content="GNU gettext utilities: 11. The Programmer's View"> | |
18 <meta name="resource-type" content="document"> | |
19 <meta name="distribution" content="global"> | |
20 <meta name="Generator" content="texi2html 1.78a"> | |
21 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
22 <style type="text/css"> | |
23 <!-- | |
24 a.summary-letter {text-decoration: none} | |
25 pre.display {font-family: serif} | |
26 pre.format {font-family: serif} | |
27 pre.menu-comment {font-family: serif} | |
28 pre.menu-preformatted {font-family: serif} | |
29 pre.smalldisplay {font-family: serif; font-size: smaller} | |
30 pre.smallexample {font-size: smaller} | |
31 pre.smallformat {font-family: serif; font-size: smaller} | |
32 pre.smalllisp {font-size: smaller} | |
33 span.roman {font-family:serif; font-weight:normal;} | |
34 span.sansserif {font-family:sans-serif; font-weight:normal;} | |
35 ul.toc {list-style: none} | |
36 --> | |
37 </style> | |
38 | |
39 | |
40 </head> | |
41 | |
42 <body lang="en" bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#800080" alink="#FF0000"> | |
43 | |
44 <table cellpadding="1" cellspacing="1" border="0"> | |
45 <tr><td valign="middle" align="left">[<a href="gettext_10.html#SEC173" title="Beginning of this chapter or previous chapter"> << </a>]</td> | |
46 <td valign="middle" align="left">[<a href="gettext_12.html#SEC217" title="Next chapter"> >> </a>]</td> | |
47 <td valign="middle" align="left"> </td> | |
48 <td valign="middle" align="left"> </td> | |
49 <td valign="middle" align="left"> </td> | |
50 <td valign="middle" align="left"> </td> | |
51 <td valign="middle" align="left"> </td> | |
52 <td valign="middle" align="left">[<a href="gettext_toc.html#SEC_Top" title="Cover (top) of document">Top</a>]</td> | |
53 <td valign="middle" align="left">[<a href="gettext_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td> | |
54 <td valign="middle" align="left">[<a href="gettext_21.html#SEC389" title="Index">Index</a>]</td> | |
55 <td valign="middle" align="left">[<a href="gettext_abt.html#SEC_About" title="About (help)"> ? </a>]</td> | |
56 </tr></table> | |
57 | |
58 <hr size="2"> | |
59 <a name="Programmers"></a> | |
60 <a name="SEC197"></a> | |
61 <h1 class="chapter"> <a href="gettext_toc.html#TOC190">11. The Programmer's View</a> </h1> | |
62 | |
63 | |
64 <p>One aim of the current message catalog implementation provided by | |
65 GNU <code>gettext</code> was to use the system's message catalog handling, if the | |
66 installer wishes to do so. So we perhaps should first take a look at | |
67 the solutions we know about. The people in the POSIX committee did not | |
68 manage to agree on one of the semi-official standards which we'll | |
69 describe below. In fact they couldn't agree on anything, so they decided | |
70 only to include an example of an interface. The major Unix vendors | |
71 are split in the usage of the two most important specifications: X/Open's | |
72 catgets vs. Uniforum's gettext interface. We'll describe them both and | |
73 later explain our solution of this dilemma. | |
74 </p> | |
75 | |
76 | |
77 <a name="catgets"></a> | |
78 <a name="SEC198"></a> | |
79 <h2 class="section"> <a href="gettext_toc.html#TOC191">11.1 About <code>catgets</code></a> </h2> | |
80 | |
81 <p>The <code>catgets</code> implementation is defined in the X/Open Portability | |
82 Guide, Volume 3, XSI Supplementary Definitions, Chapter 5. But the | |
83 process of creating this standard seemed to be too slow for some of | |
84 the Unix vendors so they created their implementations on preliminary | |
85 versions of the standard. Of course this leads again to problems while | |
86 writing platform independent programs: even the usage of <code>catgets</code> | |
87 does not guarantee a unique interface. | |
88 </p> | |
89 <p>Another, personal comment on this that only a bunch of committee members | |
90 could have made this interface. They never really tried to program | |
91 using this interface. It is a fast, memory-saving implementation, an | |
92 user can happily live with it. But programmers hate it (at least I and | |
93 some others do…) | |
94 </p> | |
95 <p>But we must not forget one point: after all the trouble with transferring | |
96 the rights on Unix they at last came to X/Open, the very same who | |
97 published this specification. This leads me to making the prediction | |
98 that this interface will be in future Unix standards (e.g. Spec1170) and | |
99 therefore part of all Unix implementation (implementations, which are | |
100 <em>allowed</em> to wear this name). | |
101 </p> | |
102 | |
103 | |
104 <a name="Interface-to-catgets"></a> | |
105 <a name="SEC199"></a> | |
106 <h3 class="subsection"> <a href="gettext_toc.html#TOC192">11.1.1 The Interface</a> </h3> | |
107 | |
108 <p>The interface to the <code>catgets</code> implementation consists of three | |
109 functions which correspond to those used in file access: <code>catopen</code> | |
110 to open the catalog for using, <code>catgets</code> for accessing the message | |
111 tables, and <code>catclose</code> for closing after work is done. Prototypes | |
112 for the functions and the needed definitions are in the | |
113 <code><nl_types.h></code> header file. | |
114 </p> | |
115 <a name="IDX1059"></a> | |
116 <p><code>catopen</code> is used like in this: | |
117 </p> | |
118 <table><tr><td> </td><td><pre class="example">nl_catd catd = catopen ("catalog_name", 0); | |
119 </pre></td></tr></table> | |
120 | |
121 <p>The function takes as the argument the name of the catalog. This usual | |
122 refers to the name of the program or the package. The second parameter | |
123 is not further specified in the standard. I don't even know whether it | |
124 is implemented consistently among various systems. So the common advice | |
125 is to use <code>0</code> as the value. The return value is a handle to the | |
126 message catalog, equivalent to handles to file returned by <code>open</code>. | |
127 </p> | |
128 <a name="IDX1060"></a> | |
129 <p>This handle is of course used in the <code>catgets</code> function which can | |
130 be used like this: | |
131 </p> | |
132 <table><tr><td> </td><td><pre class="example">char *translation = catgets (catd, set_no, msg_id, "original string"); | |
133 </pre></td></tr></table> | |
134 | |
135 <p>The first parameter is this catalog descriptor. The second parameter | |
136 specifies the set of messages in this catalog, in which the message | |
137 described by <code>msg_id</code> is obtained. <code>catgets</code> therefore uses a | |
138 three-stage addressing: | |
139 </p> | |
140 <table><tr><td> </td><td><pre class="display">catalog name ⇒ set number ⇒ message ID ⇒ translation | |
141 </pre></td></tr></table> | |
142 | |
143 | |
144 <p>The fourth argument is not used to address the translation. It is given | |
145 as a default value in case when one of the addressing stages fail. One | |
146 important thing to remember is that although the return type of catgets | |
147 is <code>char *</code> the resulting string <em>must not</em> be changed. It | |
148 should better be <code>const char *</code>, but the standard is published in | |
149 1988, one year before ANSI C. | |
150 </p> | |
151 <a name="IDX1061"></a> | |
152 <p>The last of these functions is used and behaves as expected: | |
153 </p> | |
154 <table><tr><td> </td><td><pre class="example">catclose (catd); | |
155 </pre></td></tr></table> | |
156 | |
157 <p>After this no <code>catgets</code> call using the descriptor is legal anymore. | |
158 </p> | |
159 | |
160 <a name="Problems-with-catgets"></a> | |
161 <a name="SEC200"></a> | |
162 <h3 class="subsection"> <a href="gettext_toc.html#TOC193">11.1.2 Problems with the <code>catgets</code> Interface?!</a> </h3> | |
163 | |
164 <p>Now that this description seemed to be really easy — where are the | |
165 problems we speak of? In fact the interface could be used in a | |
166 reasonable way, but constructing the message catalogs is a pain. The | |
167 reason for this lies in the third argument of <code>catgets</code>: the unique | |
168 message ID. This has to be a numeric value for all messages in a single | |
169 set. Perhaps you could imagine the problems keeping such a list while | |
170 changing the source code. Add a new message here, remove one there. Of | |
171 course there have been developed a lot of tools helping to organize this | |
172 chaos but one as the other fails in one aspect or the other. We don't | |
173 want to say that the other approach has no problems but they are far | |
174 more easy to manage. | |
175 </p> | |
176 | |
177 <a name="gettext"></a> | |
178 <a name="SEC201"></a> | |
179 <h2 class="section"> <a href="gettext_toc.html#TOC194">11.2 About <code>gettext</code></a> </h2> | |
180 | |
181 <p>The definition of the <code>gettext</code> interface comes from a Uniforum | |
182 proposal. It was submitted there by Sun, who had implemented the | |
183 <code>gettext</code> function in SunOS 4, around 1990. Nowadays, the | |
184 <code>gettext</code> interface is specified by the OpenI18N standard. | |
185 </p> | |
186 <p>The main point about this solution is that it does not follow the | |
187 method of normal file handling (open-use-close) and that it does not | |
188 burden the programmer with so many tasks, especially the unique key handling. | |
189 Of course here also a unique key is needed, but this key is the message | |
190 itself (how long or short it is). See <a href="#SEC209">Comparing the Two Interfaces</a> for a more | |
191 detailed comparison of the two methods. | |
192 </p> | |
193 <p>The following section contains a rather detailed description of the | |
194 interface. We make it that detailed because this is the interface | |
195 we chose for the GNU <code>gettext</code> Library. Programmers interested | |
196 in using this library will be interested in this description. | |
197 </p> | |
198 | |
199 | |
200 <a name="Interface-to-gettext"></a> | |
201 <a name="SEC202"></a> | |
202 <h3 class="subsection"> <a href="gettext_toc.html#TOC195">11.2.1 The Interface</a> </h3> | |
203 | |
204 <p>The minimal functionality an interface must have is a) to select a | |
205 domain the strings are coming from (a single domain for all programs is | |
206 not reasonable because its construction and maintenance is difficult, | |
207 perhaps impossible) and b) to access a string in a selected domain. | |
208 </p> | |
209 <p>This is principally the description of the <code>gettext</code> interface. It | |
210 has a global domain which unqualified usages reference. Of course this | |
211 domain is selectable by the user. | |
212 </p> | |
213 <table><tr><td> </td><td><pre class="example">char *textdomain (const char *domain_name); | |
214 </pre></td></tr></table> | |
215 | |
216 <p>This provides the possibility to change or query the current status of | |
217 the current global domain of the <code>LC_MESSAGE</code> category. The | |
218 argument is a null-terminated string, whose characters must be legal in | |
219 the use in filenames. If the <var>domain_name</var> argument is <code>NULL</code>, | |
220 the function returns the current value. If no value has been set | |
221 before, the name of the default domain is returned: <em>messages</em>. | |
222 Please note that although the return value of <code>textdomain</code> is of | |
223 type <code>char *</code> no changing is allowed. It is also important to know | |
224 that no checks of the availability are made. If the name is not | |
225 available you will see this by the fact that no translations are provided. | |
226 </p> | |
227 <p>To use a domain set by <code>textdomain</code> the function | |
228 </p> | |
229 <table><tr><td> </td><td><pre class="example">char *gettext (const char *msgid); | |
230 </pre></td></tr></table> | |
231 | |
232 <p>is to be used. This is the simplest reasonable form one can imagine. | |
233 The translation of the string <var>msgid</var> is returned if it is available | |
234 in the current domain. If it is not available, the argument itself is | |
235 returned. If the argument is <code>NULL</code> the result is undefined. | |
236 </p> | |
237 <p>One thing which should come into mind is that no explicit dependency to | |
238 the used domain is given. The current value of the domain is used. | |
239 If this changes between two | |
240 executions of the same <code>gettext</code> call in the program, both calls | |
241 reference a different message catalog. | |
242 </p> | |
243 <p>For the easiest case, which is normally used in internationalized | |
244 packages, once at the beginning of execution a call to <code>textdomain</code> | |
245 is issued, setting the domain to a unique name, normally the package | |
246 name. In the following code all strings which have to be translated are | |
247 filtered through the gettext function. That's all, the package speaks | |
248 your language. | |
249 </p> | |
250 | |
251 <a name="Ambiguities"></a> | |
252 <a name="SEC203"></a> | |
253 <h3 class="subsection"> <a href="gettext_toc.html#TOC196">11.2.2 Solving Ambiguities</a> </h3> | |
254 | |
255 <p>While this single name domain works well for most applications there | |
256 might be the need to get translations from more than one domain. Of | |
257 course one could switch between different domains with calls to | |
258 <code>textdomain</code>, but this is really not convenient nor is it fast. A | |
259 possible situation could be one case subject to discussion during this | |
260 writing: all | |
261 error messages of functions in the set of common used functions should | |
262 go into a separate domain <code>error</code>. By this mean we would only need | |
263 to translate them once. | |
264 Another case are messages from a library, as these <em>have</em> to be | |
265 independent of the current domain set by the application. | |
266 </p> | |
267 <p>For this reasons there are two more functions to retrieve strings: | |
268 </p> | |
269 <table><tr><td> </td><td><pre class="example">char *dgettext (const char *domain_name, const char *msgid); | |
270 char *dcgettext (const char *domain_name, const char *msgid, | |
271 int category); | |
272 </pre></td></tr></table> | |
273 | |
274 <p>Both take an additional argument at the first place, which corresponds | |
275 to the argument of <code>textdomain</code>. The third argument of | |
276 <code>dcgettext</code> allows to use another locale category but <code>LC_MESSAGES</code>. | |
277 But I really don't know where this can be useful. If the | |
278 <var>domain_name</var> is <code>NULL</code> or <var>category</var> has an value beside | |
279 the known ones, the result is undefined. It should also be noted that | |
280 this function is not part of the second known implementation of this | |
281 function family, the one found in Solaris. | |
282 </p> | |
283 <p>A second ambiguity can arise by the fact, that perhaps more than one | |
284 domain has the same name. This can be solved by specifying where the | |
285 needed message catalog files can be found. | |
286 </p> | |
287 <table><tr><td> </td><td><pre class="example">char *bindtextdomain (const char *domain_name, | |
288 const char *dir_name); | |
289 </pre></td></tr></table> | |
290 | |
291 <p>Calling this function binds the given domain to a file in the specified | |
292 directory (how this file is determined follows below). Especially a | |
293 file in the systems default place is not favored against the specified | |
294 file anymore (as it would be by solely using <code>textdomain</code>). A | |
295 <code>NULL</code> pointer for the <var>dir_name</var> parameter returns the binding | |
296 associated with <var>domain_name</var>. If <var>domain_name</var> itself is | |
297 <code>NULL</code> nothing happens and a <code>NULL</code> pointer is returned. Here | |
298 again as for all the other functions is true that none of the return | |
299 value must be changed! | |
300 </p> | |
301 <p>It is important to remember that relative path names for the | |
302 <var>dir_name</var> parameter can be trouble. Since the path is always | |
303 computed relative to the current directory different results will be | |
304 achieved when the program executes a <code>chdir</code> command. Relative | |
305 paths should always be avoided to avoid dependencies and | |
306 unreliabilities. | |
307 </p> | |
308 <table><tr><td> </td><td><pre class="example">wchar_t *wbindtextdomain (const char *domain_name, | |
309 const wchar_t *dir_name); | |
310 </pre></td></tr></table> | |
311 | |
312 <p>This function is provided only on native Windows platforms. It is like | |
313 <code>bindtextdomain</code>, except that the <var>dir_name</var> parameter is a | |
314 wide string (in UTF-16 encoding, as usual on Windows). | |
315 </p> | |
316 | |
317 <a name="Locating-Catalogs"></a> | |
318 <a name="SEC204"></a> | |
319 <h3 class="subsection"> <a href="gettext_toc.html#TOC197">11.2.3 Locating Message Catalog Files</a> </h3> | |
320 | |
321 <p>Because many different languages for many different packages have to be | |
322 stored we need some way to add these information to file message catalog | |
323 files. The way usually used in Unix environments is have this encoding | |
324 in the file name. This is also done here. The directory name given in | |
325 <code>bindtextdomain</code>s second argument (or the default directory), | |
326 followed by the name of the locale, the locale category, and the domain name | |
327 are concatenated: | |
328 </p> | |
329 <table><tr><td> </td><td><pre class="example"><var>dir_name</var>/<var>locale</var>/LC_<var>category</var>/<var>domain_name</var>.mo | |
330 </pre></td></tr></table> | |
331 | |
332 <p>The default value for <var>dir_name</var> is system specific. For the GNU | |
333 library, and for packages adhering to its conventions, it's: | |
334 </p><table><tr><td> </td><td><pre class="example">/usr/local/share/locale | |
335 </pre></td></tr></table> | |
336 | |
337 <p><var>locale</var> is the name of the locale category which is designated by | |
338 <code>LC_<var>category</var></code>. For <code>gettext</code> and <code>dgettext</code> this | |
339 <code>LC_<var>category</var></code> is always <code>LC_MESSAGES</code>.<a name="DOCF3" href="gettext_fot.html#FOOT3">(3)</a> | |
340 The name of the locale category is determined through | |
341 <code>setlocale (LC_<var>category</var>, NULL)</code>. | |
342 <a name="DOCF4" href="gettext_fot.html#FOOT4">(4)</a> | |
343 When using the function <code>dcgettext</code>, you can specify the locale category | |
344 through the third argument. | |
345 </p> | |
346 | |
347 <a name="Charset-conversion"></a> | |
348 <a name="SEC205"></a> | |
349 <h3 class="subsection"> <a href="gettext_toc.html#TOC198">11.2.4 How to specify the output character set <code>gettext</code> uses</a> </h3> | |
350 | |
351 <p><code>gettext</code> not only looks up a translation in a message catalog. It | |
352 also converts the translation on the fly to the desired output character | |
353 set. This is useful if the user is working in a different character set | |
354 than the translator who created the message catalog, because it avoids | |
355 distributing variants of message catalogs which differ only in the | |
356 character set. | |
357 </p> | |
358 <p>The output character set is, by default, the value of <code>nl_langinfo | |
359 (CODESET)</code>, which depends on the <code>LC_CTYPE</code> part of the current | |
360 locale. But programs which store strings in a locale independent way | |
361 (e.g. UTF-8) can request that <code>gettext</code> and related functions | |
362 return the translations in that encoding, by use of the | |
363 <code>bind_textdomain_codeset</code> function. | |
364 </p> | |
365 <p>Note that the <var>msgid</var> argument to <code>gettext</code> is not subject to | |
366 character set conversion. Also, when <code>gettext</code> does not find a | |
367 translation for <var>msgid</var>, it returns <var>msgid</var> unchanged – | |
368 independently of the current output character set. It is therefore | |
369 recommended that all <var>msgid</var>s be US-ASCII strings. | |
370 </p> | |
371 <dl> | |
372 <dt><u>Function:</u> char * <b>bind_textdomain_codeset</b><i> (const char *<var>domainname</var>, const char *<var>codeset</var>)</i> | |
373 <a name="IDX1062"></a> | |
374 </dt> | |
375 <dd><p>The <code>bind_textdomain_codeset</code> function can be used to specify the | |
376 output character set for message catalogs for domain <var>domainname</var>. | |
377 The <var>codeset</var> argument must be a valid codeset name which can be used | |
378 for the <code>iconv_open</code> function, or a null pointer. | |
379 </p> | |
380 <p>If the <var>codeset</var> parameter is the null pointer, | |
381 <code>bind_textdomain_codeset</code> returns the currently selected codeset | |
382 for the domain with the name <var>domainname</var>. It returns <code>NULL</code> if | |
383 no codeset has yet been selected. | |
384 </p> | |
385 <p>The <code>bind_textdomain_codeset</code> function can be used several times. | |
386 If used multiple times with the same <var>domainname</var> argument, the | |
387 later call overrides the settings made by the earlier one. | |
388 </p> | |
389 <p>The <code>bind_textdomain_codeset</code> function returns a pointer to a | |
390 string containing the name of the selected codeset. The string is | |
391 allocated internally in the function and must not be changed by the | |
392 user. If the system went out of core during the execution of | |
393 <code>bind_textdomain_codeset</code>, the return value is <code>NULL</code> and the | |
394 global variable <var>errno</var> is set accordingly. | |
395 </p></dd></dl> | |
396 | |
397 | |
398 <a name="Contexts"></a> | |
399 <a name="SEC206"></a> | |
400 <h3 class="subsection"> <a href="gettext_toc.html#TOC199">11.2.5 Using contexts for solving ambiguities</a> </h3> | |
401 | |
402 <p>One place where the <code>gettext</code> functions, if used normally, have big | |
403 problems is within programs with graphical user interfaces (GUIs). The | |
404 problem is that many of the strings which have to be translated are very | |
405 short. They have to appear in pull-down menus which restricts the | |
406 length. But strings which are not containing entire sentences or at | |
407 least large fragments of a sentence may appear in more than one | |
408 situation in the program but might have different translations. This is | |
409 especially true for the one-word strings which are frequently used in | |
410 GUI programs. | |
411 </p> | |
412 <p>As a consequence many people say that the <code>gettext</code> approach is | |
413 wrong and instead <code>catgets</code> should be used which indeed does not | |
414 have this problem. But there is a very simple and powerful method to | |
415 handle this kind of problems with the <code>gettext</code> functions. | |
416 </p> | |
417 <p>Contexts can be added to strings to be translated. A context dependent | |
418 translation lookup is when a translation for a given string is searched, | |
419 that is limited to a given context. The translation for the same string | |
420 in a different context can be different. The different translations of | |
421 the same string in different contexts can be stored in the in the same | |
422 MO file, and can be edited by the translator in the same PO file. | |
423 </p> | |
424 <p>The ‘<tt>gettext.h</tt>’ include file contains the lookup macros for strings | |
425 with contexts. They are implemented as thin macros and inline functions | |
426 over the functions from <code><libintl.h></code>. | |
427 </p> | |
428 <a name="IDX1063"></a> | |
429 <table><tr><td> </td><td><pre class="example">const char *pgettext (const char *msgctxt, const char *msgid); | |
430 </pre></td></tr></table> | |
431 | |
432 <p>In a call of this macro, <var>msgctxt</var> and <var>msgid</var> must be string | |
433 literals. The macro returns the translation of <var>msgid</var>, restricted | |
434 to the context given by <var>msgctxt</var>. | |
435 </p> | |
436 <p>The <var>msgctxt</var> string is visible in the PO file to the translator. | |
437 You should try to make it somehow canonical and never changing. Because | |
438 every time you change an <var>msgctxt</var>, the translator will have to review | |
439 the translation of <var>msgid</var>. | |
440 </p> | |
441 <p>Finding a canonical <var>msgctxt</var> string that doesn't change over time can | |
442 be hard. But you shouldn't use the file name or class name containing the | |
443 <code>pgettext</code> call – because it is a common development task to rename | |
444 a file or a class, and it shouldn't cause translator work. Also you shouldn't | |
445 use a comment in the form of a complete English sentence as <var>msgctxt</var> – | |
446 because orthography or grammar changes are often applied to such sentences, | |
447 and again, it shouldn't force the translator to do a review. | |
448 </p> | |
449 <p>The ‘<samp>p</samp>’ in ‘<samp>pgettext</samp>’ stands for “particular”: <code>pgettext</code> | |
450 fetches a particular translation of the <var>msgid</var>. | |
451 </p> | |
452 <a name="IDX1064"></a> | |
453 <a name="IDX1065"></a> | |
454 <table><tr><td> </td><td><pre class="example">const char *dpgettext (const char *domain_name, | |
455 const char *msgctxt, const char *msgid); | |
456 const char *dcpgettext (const char *domain_name, | |
457 const char *msgctxt, const char *msgid, | |
458 int category); | |
459 </pre></td></tr></table> | |
460 | |
461 <p>These are generalizations of <code>pgettext</code>. They behave similarly to | |
462 <code>dgettext</code> and <code>dcgettext</code>, respectively. The <var>domain_name</var> | |
463 argument defines the translation domain. The <var>category</var> argument | |
464 allows to use another locale category than <code>LC_MESSAGES</code>. | |
465 </p> | |
466 <p>As as example consider the following fictional situation. A GUI program | |
467 has a menu bar with the following entries: | |
468 </p> | |
469 <table><tr><td> </td><td><pre class="smallexample">+------------+------------+--------------------------------------+ | |
470 | File | Printer | | | |
471 +------------+------------+--------------------------------------+ | |
472 | Open | | Select | | |
473 | New | | Open | | |
474 +----------+ | Connect | | |
475 +----------+ | |
476 </pre></td></tr></table> | |
477 | |
478 <p>To have the strings <code>File</code>, <code>Printer</code>, <code>Open</code>, | |
479 <code>New</code>, <code>Select</code>, and <code>Connect</code> translated there has to be | |
480 at some point in the code a call to a function of the <code>gettext</code> | |
481 family. But in two places the string passed into the function would be | |
482 <code>Open</code>. The translations might not be the same and therefore we | |
483 are in the dilemma described above. | |
484 </p> | |
485 <p>What distinguishes the two places is the menu path from the menu root to | |
486 the particular menu entries: | |
487 </p> | |
488 <table><tr><td> </td><td><pre class="smallexample">Menu|File | |
489 Menu|Printer | |
490 Menu|File|Open | |
491 Menu|File|New | |
492 Menu|Printer|Select | |
493 Menu|Printer|Open | |
494 Menu|Printer|Connect | |
495 </pre></td></tr></table> | |
496 | |
497 <p>The context is thus the menu path without its last part. So, the calls | |
498 look like this: | |
499 </p> | |
500 <table><tr><td> </td><td><pre class="smallexample">pgettext ("Menu|", "File") | |
501 pgettext ("Menu|", "Printer") | |
502 pgettext ("Menu|File|", "Open") | |
503 pgettext ("Menu|File|", "New") | |
504 pgettext ("Menu|Printer|", "Select") | |
505 pgettext ("Menu|Printer|", "Open") | |
506 pgettext ("Menu|Printer|", "Connect") | |
507 </pre></td></tr></table> | |
508 | |
509 <p>Whether or not to use the ‘<samp>|</samp>’ character at the end of the context is a | |
510 matter of style. | |
511 </p> | |
512 <p>For more complex cases, where the <var>msgctxt</var> or <var>msgid</var> are not | |
513 string literals, more general macros are available: | |
514 </p> | |
515 <a name="IDX1066"></a> | |
516 <a name="IDX1067"></a> | |
517 <a name="IDX1068"></a> | |
518 <table><tr><td> </td><td><pre class="example">const char *pgettext_expr (const char *msgctxt, const char *msgid); | |
519 const char *dpgettext_expr (const char *domain_name, | |
520 const char *msgctxt, const char *msgid); | |
521 const char *dcpgettext_expr (const char *domain_name, | |
522 const char *msgctxt, const char *msgid, | |
523 int category); | |
524 </pre></td></tr></table> | |
525 | |
526 <p>Here <var>msgctxt</var> and <var>msgid</var> can be arbitrary string-valued expressions. | |
527 These macros are more general. But in the case that both argument expressions | |
528 are string literals, the macros without the ‘<samp>_expr</samp>’ suffix are more | |
529 efficient. | |
530 </p> | |
531 | |
532 <a name="Plural-forms"></a> | |
533 <a name="SEC207"></a> | |
534 <h3 class="subsection"> <a href="gettext_toc.html#TOC200">11.2.6 Additional functions for plural forms</a> </h3> | |
535 | |
536 <p>The functions of the <code>gettext</code> family described so far (and all the | |
537 <code>catgets</code> functions as well) have one problem in the real world | |
538 which have been neglected completely in all existing approaches. What | |
539 is meant here is the handling of plural forms. | |
540 </p> | |
541 <p>Looking through Unix source code before the time anybody thought about | |
542 internationalization (and, sadly, even afterwards) one can often find | |
543 code similar to the following: | |
544 </p> | |
545 <table><tr><td> </td><td><pre class="smallexample"> printf ("%d file%s deleted", n, n == 1 ? "" : "s"); | |
546 </pre></td></tr></table> | |
547 | |
548 <p>After the first complaints from people internationalizing the code people | |
549 either completely avoided formulations like this or used strings like | |
550 <code>"file(s)"</code>. Both look unnatural and should be avoided. First | |
551 tries to solve the problem correctly looked like this: | |
552 </p> | |
553 <table><tr><td> </td><td><pre class="smallexample"> if (n == 1) | |
554 printf ("%d file deleted", n); | |
555 else | |
556 printf ("%d files deleted", n); | |
557 </pre></td></tr></table> | |
558 | |
559 <p>But this does not solve the problem. It helps languages where the | |
560 plural form of a noun is not simply constructed by adding an | |
561 ‘s’ | |
562 but that is all. Once again people fell into the trap of believing the | |
563 rules their language is using are universal. But the handling of plural | |
564 forms differs widely between the language families. For example, | |
565 Rafal Maszkowski <code><rzm@mat.uni.torun.pl></code> reports: | |
566 </p> | |
567 <blockquote><p>In Polish we use e.g. plik (file) this way: | |
568 </p><table><tr><td> </td><td><pre class="example">1 plik | |
569 2,3,4 pliki | |
570 5-21 pliko'w | |
571 22-24 pliki | |
572 25-31 pliko'w | |
573 </pre></td></tr></table> | |
574 <p>and so on (o' means 8859-2 oacute which should be rather okreska, | |
575 similar to aogonek). | |
576 </p></blockquote> | |
577 | |
578 <p>There are two things which can differ between languages (and even inside | |
579 language families); | |
580 </p> | |
581 <ul> | |
582 <li> | |
583 The form how plural forms are built differs. This is a problem with | |
584 languages which have many irregularities. German, for instance, is a | |
585 drastic case. Though English and German are part of the same language | |
586 family (Germanic), the almost regular forming of plural noun forms | |
587 (appending an | |
588 ‘s’) | |
589 is hardly found in German. | |
590 | |
591 </li><li> | |
592 The number of plural forms differ. This is somewhat surprising for | |
593 those who only have experiences with Romanic and Germanic languages | |
594 since here the number is the same (there are two). | |
595 | |
596 <p>But other language families have only one form or many forms. More | |
597 information on this in an extra section. | |
598 </p></li></ul> | |
599 | |
600 <p>The consequence of this is that application writers should not try to | |
601 solve the problem in their code. This would be localization since it is | |
602 only usable for certain, hardcoded language environments. Instead the | |
603 extended <code>gettext</code> interface should be used. | |
604 </p> | |
605 <p>These extra functions are taking instead of the one key string two | |
606 strings and a numerical argument. The idea behind this is that using | |
607 the numerical argument and the first string as a key, the implementation | |
608 can select using rules specified by the translator the right plural | |
609 form. The two string arguments then will be used to provide a return | |
610 value in case no message catalog is found (similar to the normal | |
611 <code>gettext</code> behavior). In this case the rules for Germanic language | |
612 is used and it is assumed that the first string argument is the singular | |
613 form, the second the plural form. | |
614 </p> | |
615 <p>This has the consequence that programs without language catalogs can | |
616 display the correct strings only if the program itself is written using | |
617 a Germanic language. This is a limitation but since the GNU C library | |
618 (as well as the GNU <code>gettext</code> package) are written as part of the | |
619 GNU package and the coding standards for the GNU project require program | |
620 being written in English, this solution nevertheless fulfills its | |
621 purpose. | |
622 </p> | |
623 <dl> | |
624 <dt><u>Function:</u> char * <b>ngettext</b><i> (const char *<var>msgid1</var>, const char *<var>msgid2</var>, unsigned long int <var>n</var>)</i> | |
625 <a name="IDX1069"></a> | |
626 </dt> | |
627 <dd><p>The <code>ngettext</code> function is similar to the <code>gettext</code> function | |
628 as it finds the message catalogs in the same way. But it takes two | |
629 extra arguments. The <var>msgid1</var> parameter must contain the singular | |
630 form of the string to be converted. It is also used as the key for the | |
631 search in the catalog. The <var>msgid2</var> parameter is the plural form. | |
632 The parameter <var>n</var> is used to determine the plural form. If no | |
633 message catalog is found <var>msgid1</var> is returned if <code>n == 1</code>, | |
634 otherwise <code>msgid2</code>. | |
635 </p> | |
636 <p>An example for the use of this function is: | |
637 </p> | |
638 <table><tr><td> </td><td><pre class="smallexample">printf (ngettext ("%d file removed", "%d files removed", n), n); | |
639 </pre></td></tr></table> | |
640 | |
641 <p>Please note that the numeric value <var>n</var> has to be passed to the | |
642 <code>printf</code> function as well. It is not sufficient to pass it only to | |
643 <code>ngettext</code>. | |
644 </p> | |
645 <p>In the English singular case, the number – always 1 – can be replaced with | |
646 "one": | |
647 </p> | |
648 <table><tr><td> </td><td><pre class="smallexample">printf (ngettext ("One file removed", "%d files removed", n), n); | |
649 </pre></td></tr></table> | |
650 | |
651 <p>This works because the ‘<samp>printf</samp>’ function discards excess arguments that | |
652 are not consumed by the format string. | |
653 </p> | |
654 <p>If this function is meant to yield a format string that takes two or more | |
655 arguments, you can not use it like this: | |
656 </p> | |
657 <table><tr><td> </td><td><pre class="smallexample">printf (ngettext ("%d file removed from directory %s", | |
658 "%d files removed from directory %s", | |
659 n), | |
660 n, dir); | |
661 </pre></td></tr></table> | |
662 | |
663 <p>because in many languages the translators want to replace the ‘<samp>%d</samp>’ | |
664 with an explicit word in the singular case, just like “one” in English, | |
665 and C format strings cannot consume the second argument but skip the first | |
666 argument. Instead, you have to reorder the arguments so that ‘<samp>n</samp>’ | |
667 comes last: | |
668 </p> | |
669 <table><tr><td> </td><td><pre class="smallexample">printf (ngettext ("%2$d file removed from directory %1$s", | |
670 "%2$d files removed from directory %1$s", | |
671 n), | |
672 dir, n); | |
673 </pre></td></tr></table> | |
674 | |
675 <p>See <a href="gettext_15.html#SEC267">C Format Strings</a> for details about this argument reordering syntax. | |
676 </p> | |
677 <p>When you know that the value of <code>n</code> is within a given range, you can | |
678 specify it as a comment directed to the <code>xgettext</code> tool. This | |
679 information may help translators to use more adequate translations. Like | |
680 this: | |
681 </p> | |
682 <table><tr><td> </td><td><pre class="smallexample">if (days > 7 && days < 14) | |
683 /* xgettext: range: 1..6 */ | |
684 printf (ngettext ("one week and one day", "one week and %d days", | |
685 days - 7), | |
686 days - 7); | |
687 </pre></td></tr></table> | |
688 | |
689 <p>It is also possible to use this function when the strings don't contain a | |
690 cardinal number: | |
691 </p> | |
692 <table><tr><td> </td><td><pre class="smallexample">puts (ngettext ("Delete the selected file?", | |
693 "Delete the selected files?", | |
694 n)); | |
695 </pre></td></tr></table> | |
696 | |
697 <p>In this case the number <var>n</var> is only used to choose the plural form. | |
698 </p></dd></dl> | |
699 | |
700 <dl> | |
701 <dt><u>Function:</u> char * <b>dngettext</b><i> (const char *<var>domain</var>, const char *<var>msgid1</var>, const char *<var>msgid2</var>, unsigned long int <var>n</var>)</i> | |
702 <a name="IDX1070"></a> | |
703 </dt> | |
704 <dd><p>The <code>dngettext</code> is similar to the <code>dgettext</code> function in the | |
705 way the message catalog is selected. The difference is that it takes | |
706 two extra parameter to provide the correct plural form. These two | |
707 parameters are handled in the same way <code>ngettext</code> handles them. | |
708 </p></dd></dl> | |
709 | |
710 <dl> | |
711 <dt><u>Function:</u> char * <b>dcngettext</b><i> (const char *<var>domain</var>, const char *<var>msgid1</var>, const char *<var>msgid2</var>, unsigned long int <var>n</var>, int <var>category</var>)</i> | |
712 <a name="IDX1071"></a> | |
713 </dt> | |
714 <dd><p>The <code>dcngettext</code> is similar to the <code>dcgettext</code> function in the | |
715 way the message catalog is selected. The difference is that it takes | |
716 two extra parameter to provide the correct plural form. These two | |
717 parameters are handled in the same way <code>ngettext</code> handles them. | |
718 </p></dd></dl> | |
719 | |
720 <p>Now, how do these functions solve the problem of the plural forms? | |
721 Without the input of linguists (which was not available) it was not | |
722 possible to determine whether there are only a few different forms in | |
723 which plural forms are formed or whether the number can increase with | |
724 every new supported language. | |
725 </p> | |
726 <p>Therefore the solution implemented is to allow the translator to specify | |
727 the rules of how to select the plural form. Since the formula varies | |
728 with every language this is the only viable solution except for | |
729 hardcoding the information in the code (which still would require the | |
730 possibility of extensions to not prevent the use of new languages). | |
731 </p> | |
732 <a name="IDX1072"></a> | |
733 <a name="IDX1073"></a> | |
734 <a name="IDX1074"></a> | |
735 <p>The information about the plural form selection has to be stored in the | |
736 header entry of the PO file (the one with the empty <code>msgid</code> string). | |
737 The plural form information looks like this: | |
738 </p> | |
739 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1; | |
740 </pre></td></tr></table> | |
741 | |
742 <p>The <code>nplurals</code> value must be a decimal number which specifies how | |
743 many different plural forms exist for this language. The string | |
744 following <code>plural</code> is an expression which is using the C language | |
745 syntax. Exceptions are that no negative numbers are allowed, numbers | |
746 must be decimal, and the only variable allowed is <code>n</code>. Spaces are | |
747 allowed in the expression, but backslash-newlines are not; in the | |
748 examples below the backslash-newlines are present for formatting purposes | |
749 only. This expression will be evaluated whenever one of the functions | |
750 <code>ngettext</code>, <code>dngettext</code>, or <code>dcngettext</code> is called. The | |
751 numeric value passed to these functions is then substituted for all uses | |
752 of the variable <code>n</code> in the expression. The resulting value then | |
753 must be greater or equal to zero and smaller than the value given as the | |
754 value of <code>nplurals</code>. | |
755 </p> | |
756 <a name="IDX1075"></a> | |
757 <p>The following rules are known at this point. The language with families | |
758 are listed. But this does not necessarily mean the information can be | |
759 generalized for the whole family (as can be easily seen in the table | |
760 below).<a name="DOCF5" href="gettext_fot.html#FOOT5">(5)</a> | |
761 </p> | |
762 <dl compact="compact"> | |
763 <dt> Only one form:</dt> | |
764 <dd><p>Some languages only require one single form. There is no distinction | |
765 between the singular and plural form. An appropriate header entry | |
766 would look like this: | |
767 </p> | |
768 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=1; plural=0; | |
769 </pre></td></tr></table> | |
770 | |
771 <p>Languages with this property include: | |
772 </p> | |
773 <dl compact="compact"> | |
774 <dt> Asian family</dt> | |
775 <dd><p>Japanese, Vietnamese, Korean </p></dd> | |
776 <dt> Tai-Kadai family</dt> | |
777 <dd><p>Thai </p></dd> | |
778 </dl> | |
779 | |
780 </dd> | |
781 <dt> Two forms, singular used for one only</dt> | |
782 <dd><p>This is the form used in most existing programs since it is what English | |
783 is using. A header entry would look like this: | |
784 </p> | |
785 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=2; plural=n != 1; | |
786 </pre></td></tr></table> | |
787 | |
788 <p>(Note: this uses the feature of C expressions that boolean expressions | |
789 have to value zero or one.) | |
790 </p> | |
791 <p>Languages with this property include: | |
792 </p> | |
793 <dl compact="compact"> | |
794 <dt> Germanic family</dt> | |
795 <dd><p>English, German, Dutch, Swedish, Danish, Norwegian, Faroese </p></dd> | |
796 <dt> Romanic family</dt> | |
797 <dd><p>Spanish, Portuguese, Italian </p></dd> | |
798 <dt> Latin/Greek family</dt> | |
799 <dd><p>Greek </p></dd> | |
800 <dt> Slavic family</dt> | |
801 <dd><p>Bulgarian </p></dd> | |
802 <dt> Finno-Ugric family</dt> | |
803 <dd><p>Finnish, Estonian </p></dd> | |
804 <dt> Semitic family</dt> | |
805 <dd><p>Hebrew </p></dd> | |
806 <dt> Austronesian family</dt> | |
807 <dd><p>Bahasa Indonesian </p></dd> | |
808 <dt> Artificial</dt> | |
809 <dd><p>Esperanto </p></dd> | |
810 </dl> | |
811 | |
812 <p>Other languages using the same header entry are: | |
813 </p> | |
814 <dl compact="compact"> | |
815 <dt> Finno-Ugric family</dt> | |
816 <dd><p>Hungarian </p></dd> | |
817 <dt> Turkic/Altaic family</dt> | |
818 <dd><p>Turkish </p></dd> | |
819 </dl> | |
820 | |
821 <p>Hungarian does not appear to have a plural if you look at sentences involving | |
822 cardinal numbers. For example, “1 apple” is “1 alma”, and “123 apples” is | |
823 “123 alma”. But when the number is not explicit, the distinction between | |
824 singular and plural exists: “the apple” is “az alma”, and “the apples” is | |
825 “az almák”. Since <code>ngettext</code> has to support both types of sentences, | |
826 it is classified here, under “two forms”. | |
827 </p> | |
828 <p>The same holds for Turkish: “1 apple” is “1 elma”, and “123 apples” is | |
829 “123 elma”. But when the number is omitted, the distinction between singular | |
830 and plural exists: “the apple” is “elma”, and “the apples” is | |
831 “elmalar”. | |
832 </p> | |
833 </dd> | |
834 <dt> Two forms, singular used for zero and one</dt> | |
835 <dd><p>Exceptional case in the language family. The header entry would be: | |
836 </p> | |
837 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=2; plural=n>1; | |
838 </pre></td></tr></table> | |
839 | |
840 <p>Languages with this property include: | |
841 </p> | |
842 <dl compact="compact"> | |
843 <dt> Romanic family</dt> | |
844 <dd><p>Brazilian Portuguese, French </p></dd> | |
845 </dl> | |
846 | |
847 </dd> | |
848 <dt> Three forms, special case for zero</dt> | |
849 <dd><p>The header entry would be: | |
850 </p> | |
851 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2; | |
852 </pre></td></tr></table> | |
853 | |
854 <p>Languages with this property include: | |
855 </p> | |
856 <dl compact="compact"> | |
857 <dt> Baltic family</dt> | |
858 <dd><p>Latvian </p></dd> | |
859 </dl> | |
860 | |
861 </dd> | |
862 <dt> Three forms, special cases for one and two</dt> | |
863 <dd><p>The header entry would be: | |
864 </p> | |
865 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2; | |
866 </pre></td></tr></table> | |
867 | |
868 <p>Languages with this property include: | |
869 </p> | |
870 <dl compact="compact"> | |
871 <dt> Celtic</dt> | |
872 <dd><p>Gaeilge (Irish) </p></dd> | |
873 </dl> | |
874 | |
875 </dd> | |
876 <dt> Three forms, special case for numbers ending in 00 or [2-9][0-9]</dt> | |
877 <dd><p>The header entry would be: | |
878 </p> | |
879 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; \ | |
880 plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2; | |
881 </pre></td></tr></table> | |
882 | |
883 <p>Languages with this property include: | |
884 </p> | |
885 <dl compact="compact"> | |
886 <dt> Romanic family</dt> | |
887 <dd><p>Romanian </p></dd> | |
888 </dl> | |
889 | |
890 </dd> | |
891 <dt> Three forms, special case for numbers ending in 1[2-9]</dt> | |
892 <dd><p>The header entry would look like this: | |
893 </p> | |
894 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; \ | |
895 plural=n%10==1 && n%100!=11 ? 0 : \ | |
896 n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2; | |
897 </pre></td></tr></table> | |
898 | |
899 <p>Languages with this property include: | |
900 </p> | |
901 <dl compact="compact"> | |
902 <dt> Baltic family</dt> | |
903 <dd><p>Lithuanian </p></dd> | |
904 </dl> | |
905 | |
906 </dd> | |
907 <dt> Three forms, special cases for numbers ending in 1 and 2, 3, 4, except those ending in 1[1-4]</dt> | |
908 <dd><p>The header entry would look like this: | |
909 </p> | |
910 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; \ | |
911 plural=n%10==1 && n%100!=11 ? 0 : \ | |
912 n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; | |
913 </pre></td></tr></table> | |
914 | |
915 <p>Languages with this property include: | |
916 </p> | |
917 <dl compact="compact"> | |
918 <dt> Slavic family</dt> | |
919 <dd><p>Russian, Ukrainian, Belarusian, Serbian, Croatian </p></dd> | |
920 </dl> | |
921 | |
922 </dd> | |
923 <dt> Three forms, special cases for 1 and 2, 3, 4</dt> | |
924 <dd><p>The header entry would look like this: | |
925 </p> | |
926 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; \ | |
927 plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; | |
928 </pre></td></tr></table> | |
929 | |
930 <p>Languages with this property include: | |
931 </p> | |
932 <dl compact="compact"> | |
933 <dt> Slavic family</dt> | |
934 <dd><p>Czech, Slovak </p></dd> | |
935 </dl> | |
936 | |
937 </dd> | |
938 <dt> Three forms, special case for one and some numbers ending in 2, 3, or 4</dt> | |
939 <dd><p>The header entry would look like this: | |
940 </p> | |
941 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=3; \ | |
942 plural=n==1 ? 0 : \ | |
943 n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2; | |
944 </pre></td></tr></table> | |
945 | |
946 <p>Languages with this property include: | |
947 </p> | |
948 <dl compact="compact"> | |
949 <dt> Slavic family</dt> | |
950 <dd><p>Polish </p></dd> | |
951 </dl> | |
952 | |
953 </dd> | |
954 <dt> Four forms, special case for one and all numbers ending in 02, 03, or 04</dt> | |
955 <dd><p>The header entry would look like this: | |
956 </p> | |
957 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=4; \ | |
958 plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3; | |
959 </pre></td></tr></table> | |
960 | |
961 <p>Languages with this property include: | |
962 </p> | |
963 <dl compact="compact"> | |
964 <dt> Slavic family</dt> | |
965 <dd><p>Slovenian </p></dd> | |
966 </dl> | |
967 | |
968 </dd> | |
969 <dt> Six forms, special cases for one, two, all numbers ending in 02, 03, … 10, all numbers ending in 11 … 99, and others</dt> | |
970 <dd><p>The header entry would look like this: | |
971 </p> | |
972 <table><tr><td> </td><td><pre class="smallexample">Plural-Forms: nplurals=6; \ | |
973 plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 \ | |
974 : n%100>=11 ? 4 : 5; | |
975 </pre></td></tr></table> | |
976 | |
977 <p>Languages with this property include: | |
978 </p> | |
979 <dl compact="compact"> | |
980 <dt> Afroasiatic family</dt> | |
981 <dd><p>Arabic </p></dd> | |
982 </dl> | |
983 </dd> | |
984 </dl> | |
985 | |
986 <p>You might now ask, <code>ngettext</code> handles only numbers <var>n</var> of type | |
987 ‘<samp>unsigned long</samp>’. What about larger integer types? What about negative | |
988 numbers? What about floating-point numbers? | |
989 </p> | |
990 <p>About larger integer types, such as ‘<samp>uintmax_t</samp>’ or | |
991 ‘<samp>unsigned long long</samp>’: they can be handled by reducing the value to a | |
992 range that fits in an ‘<samp>unsigned long</samp>’. Simply casting the value to | |
993 ‘<samp>unsigned long</samp>’ would not do the right thing, since it would treat | |
994 <code>ULONG_MAX + 1</code> like zero, <code>ULONG_MAX + 2</code> like singular, and | |
995 the like. Here you can exploit the fact that all mentioned plural form | |
996 formulas eventually become periodic, with a period that is a divisor of 100 | |
997 (or 1000 or 1000000). So, when you reduce a large value to another one in | |
998 the range [1000000, 1999999] that ends in the same 6 decimal digits, you | |
999 can assume that it will lead to the same plural form selection. This code | |
1000 does this: | |
1001 </p> | |
1002 <table><tr><td> </td><td><pre class="smallexample">#include <inttypes.h> | |
1003 uintmax_t nbytes = ...; | |
1004 printf (ngettext ("The file has %"PRIuMAX" byte.", | |
1005 "The file has %"PRIuMAX" bytes.", | |
1006 (nbytes > ULONG_MAX | |
1007 ? (nbytes % 1000000) + 1000000 | |
1008 : nbytes)), | |
1009 nbytes); | |
1010 </pre></td></tr></table> | |
1011 | |
1012 <p>Negative and floating-point values usually represent physical entities for | |
1013 which singular and plural don't clearly apply. In such cases, there is no | |
1014 need to use <code>ngettext</code>; a simple <code>gettext</code> call with a form suitable | |
1015 for all values will do. For example: | |
1016 </p> | |
1017 <table><tr><td> </td><td><pre class="smallexample">printf (gettext ("Time elapsed: %.3f seconds"), | |
1018 num_milliseconds * 0.001); | |
1019 </pre></td></tr></table> | |
1020 | |
1021 <p>Even if <var>num_milliseconds</var> happens to be a multiple of 1000, the output | |
1022 </p><table><tr><td> </td><td><pre class="smallexample">Time elapsed: 1.000 seconds | |
1023 </pre></td></tr></table> | |
1024 <p>is acceptable in English, and similarly for other languages. | |
1025 </p> | |
1026 <p>The translators' perspective regarding plural forms is explained in | |
1027 <a href="gettext_12.html#SEC228">Translating plural forms</a>. | |
1028 </p> | |
1029 | |
1030 <a name="Optimized-gettext"></a> | |
1031 <a name="SEC208"></a> | |
1032 <h3 class="subsection"> <a href="gettext_toc.html#TOC201">11.2.7 Optimization of the *gettext functions</a> </h3> | |
1033 | |
1034 <p>At this point of the discussion we should talk about an advantage of the | |
1035 GNU <code>gettext</code> implementation. Some readers might have pointed out | |
1036 that an internationalized program might have a poor performance if some | |
1037 string has to be translated in an inner loop. While this is unavoidable | |
1038 when the string varies from one run of the loop to the other it is | |
1039 simply a waste of time when the string is always the same. Take the | |
1040 following example: | |
1041 </p> | |
1042 <table><tr><td> </td><td><pre class="example">{ | |
1043 while (…) | |
1044 { | |
1045 puts (gettext ("Hello world")); | |
1046 } | |
1047 } | |
1048 </pre></td></tr></table> | |
1049 | |
1050 <p>When the locale selection does not change between two runs the resulting | |
1051 string is always the same. One way to use this is: | |
1052 </p> | |
1053 <table><tr><td> </td><td><pre class="example">{ | |
1054 str = gettext ("Hello world"); | |
1055 while (…) | |
1056 { | |
1057 puts (str); | |
1058 } | |
1059 } | |
1060 </pre></td></tr></table> | |
1061 | |
1062 <p>But this solution is not usable in all situation (e.g. when the locale | |
1063 selection changes) nor does it lead to legible code. | |
1064 </p> | |
1065 <p>For this reason, GNU <code>gettext</code> caches previous translation results. | |
1066 When the same translation is requested twice, with no new message | |
1067 catalogs being loaded in between, <code>gettext</code> will, the second time, | |
1068 find the result through a single cache lookup. | |
1069 </p> | |
1070 | |
1071 <a name="Comparison"></a> | |
1072 <a name="SEC209"></a> | |
1073 <h2 class="section"> <a href="gettext_toc.html#TOC202">11.3 Comparing the Two Interfaces</a> </h2> | |
1074 | |
1075 | |
1076 <p>The following discussion is perhaps a little bit colored. As said | |
1077 above we implemented GNU <code>gettext</code> following the Uniforum | |
1078 proposal and this surely has its reasons. But it should show how we | |
1079 came to this decision. | |
1080 </p> | |
1081 <p>First we take a look at the developing process. When we write an | |
1082 application using NLS provided by <code>gettext</code> we proceed as always. | |
1083 Only when we come to a string which might be seen by the users and thus | |
1084 has to be translated we use <code>gettext("…")</code> instead of | |
1085 <code>"…"</code>. At the beginning of each source file (or in a central | |
1086 header file) we define | |
1087 </p> | |
1088 <table><tr><td> </td><td><pre class="example">#define gettext(String) (String) | |
1089 </pre></td></tr></table> | |
1090 | |
1091 <p>Even this definition can be avoided when the system supports the | |
1092 <code>gettext</code> function in its C library. When we compile this code the | |
1093 result is the same as if no NLS code is used. When you take a look at | |
1094 the GNU <code>gettext</code> code you will see that we use <code>_("…")</code> | |
1095 instead of <code>gettext("…")</code>. This reduces the number of | |
1096 additional characters per translatable string to <em>3</em> (in words: | |
1097 three). | |
1098 </p> | |
1099 <p>When now a production version of the program is needed we simply replace | |
1100 the definition | |
1101 </p> | |
1102 <table><tr><td> </td><td><pre class="example">#define _(String) (String) | |
1103 </pre></td></tr></table> | |
1104 | |
1105 <p>by | |
1106 </p> | |
1107 <a name="IDX1076"></a> | |
1108 <table><tr><td> </td><td><pre class="example">#include <libintl.h> | |
1109 #define _(String) gettext (String) | |
1110 </pre></td></tr></table> | |
1111 | |
1112 <p>Additionally we run the program ‘<tt>xgettext</tt>’ on all source code file | |
1113 which contain translatable strings and that's it: we have a running | |
1114 program which does not depend on translations to be available, but which | |
1115 can use any that becomes available. | |
1116 </p> | |
1117 <a name="IDX1077"></a> | |
1118 <p>The same procedure can be done for the <code>gettext_noop</code> invocations | |
1119 (see section <a href="gettext_4.html#SEC31">Special Cases of Translatable Strings</a>). One usually defines <code>gettext_noop</code> as a | |
1120 no-op macro. So you should consider the following code for your project: | |
1121 </p> | |
1122 <table><tr><td> </td><td><pre class="example">#define gettext_noop(String) String | |
1123 #define N_(String) gettext_noop (String) | |
1124 </pre></td></tr></table> | |
1125 | |
1126 <p><code>N_</code> is a short form similar to <code>_</code>. The ‘<tt>Makefile</tt>’ in | |
1127 the ‘<tt>po/</tt>’ directory of GNU <code>gettext</code> knows by default both of the | |
1128 mentioned short forms so you are invited to follow this proposal for | |
1129 your own ease. | |
1130 </p> | |
1131 <p>Now to <code>catgets</code>. The main problem is the work for the | |
1132 programmer. Every time he comes to a translatable string he has to | |
1133 define a number (or a symbolic constant) which has also be defined in | |
1134 the message catalog file. He also has to take care for duplicate | |
1135 entries, duplicate message IDs etc. If he wants to have the same | |
1136 quality in the message catalog as the GNU <code>gettext</code> program | |
1137 provides he also has to put the descriptive comments for the strings and | |
1138 the location in all source code files in the message catalog. This is | |
1139 nearly a Mission: Impossible. | |
1140 </p> | |
1141 <p>But there are also some points people might call advantages speaking for | |
1142 <code>catgets</code>. If you have a single word in a string and this string | |
1143 is used in different contexts it is likely that in one or the other | |
1144 language the word has different translations. Example: | |
1145 </p> | |
1146 <table><tr><td> </td><td><pre class="example">printf ("%s: %d", gettext ("number"), number_of_errors) | |
1147 | |
1148 printf ("you should see %d %s", number_count, | |
1149 number_count == 1 ? gettext ("number") : gettext ("numbers")) | |
1150 </pre></td></tr></table> | |
1151 | |
1152 <p>Here we have to translate two times the string <code>"number"</code>. Even | |
1153 if you do not speak a language beside English it might be possible to | |
1154 recognize that the two words have a different meaning. In German the | |
1155 first appearance has to be translated to <code>"Anzahl"</code> and the second | |
1156 to <code>"Zahl"</code>. | |
1157 </p> | |
1158 <p>Now you can say that this example is really esoteric. And you are | |
1159 right! This is exactly how we felt about this problem and decide that | |
1160 it does not weight that much. The solution for the above problem could | |
1161 be very easy: | |
1162 </p> | |
1163 <table><tr><td> </td><td><pre class="example">printf ("%s %d", gettext ("number:"), number_of_errors) | |
1164 | |
1165 printf (number_count == 1 ? gettext ("you should see %d number") | |
1166 : gettext ("you should see %d numbers"), | |
1167 number_count) | |
1168 </pre></td></tr></table> | |
1169 | |
1170 <p>We believe that we can solve all conflicts with this method. If it is | |
1171 difficult one can also consider changing one of the conflicting string a | |
1172 little bit. But it is not impossible to overcome. | |
1173 </p> | |
1174 <p><code>catgets</code> allows same original entry to have different translations, | |
1175 but <code>gettext</code> has another, scalable approach for solving ambiguities | |
1176 of this kind: See section <a href="#SEC203">Solving Ambiguities</a>. | |
1177 </p> | |
1178 | |
1179 <a name="Using-libintl_002ea"></a> | |
1180 <a name="SEC210"></a> | |
1181 <h2 class="section"> <a href="gettext_toc.html#TOC203">11.4 Using libintl.a in own programs</a> </h2> | |
1182 | |
1183 <p>Starting with version 0.9.4 the library <code>libintl.h</code> should be | |
1184 self-contained. I.e., you can use it in your own programs without | |
1185 providing additional functions. The ‘<tt>Makefile</tt>’ will put the header | |
1186 and the library in directories selected using the <code>$(prefix)</code>. | |
1187 </p> | |
1188 | |
1189 <a name="gettext-grok"></a> | |
1190 <a name="SEC211"></a> | |
1191 <h2 class="section"> <a href="gettext_toc.html#TOC204">11.5 Being a <code>gettext</code> grok</a> </h2> | |
1192 | |
1193 <p><strong> NOTE: </strong> This documentation section is outdated and needs to be | |
1194 revised. | |
1195 </p> | |
1196 <p>To fully exploit the functionality of the GNU <code>gettext</code> library it | |
1197 is surely helpful to read the source code. But for those who don't want | |
1198 to spend that much time in reading the (sometimes complicated) code here | |
1199 is a list comments: | |
1200 </p> | |
1201 <ul> | |
1202 <li> Changing the language at runtime | |
1203 <a name="IDX1078"></a> | |
1204 | |
1205 <p>For interactive programs it might be useful to offer a selection of the | |
1206 used language at runtime. To understand how to do this one need to know | |
1207 how the used language is determined while executing the <code>gettext</code> | |
1208 function. The method which is presented here only works correctly | |
1209 with the GNU implementation of the <code>gettext</code> functions. | |
1210 </p> | |
1211 <p>In the function <code>dcgettext</code> at every call the current setting of | |
1212 the highest priority environment variable is determined and used. | |
1213 Highest priority means here the following list with decreasing | |
1214 priority: | |
1215 </p> | |
1216 <ol> | |
1217 <li><a name="IDX1079"></a> | |
1218 </li><li> <code>LANGUAGE</code> | |
1219 <a name="IDX1080"></a> | |
1220 </li><li> <code>LC_ALL</code> | |
1221 <a name="IDX1081"></a> | |
1222 <a name="IDX1082"></a> | |
1223 <a name="IDX1083"></a> | |
1224 <a name="IDX1084"></a> | |
1225 <a name="IDX1085"></a> | |
1226 <a name="IDX1086"></a> | |
1227 </li><li> <code>LC_xxx</code>, according to selected locale category | |
1228 <a name="IDX1087"></a> | |
1229 </li><li> <code>LANG</code> | |
1230 </li></ol> | |
1231 | |
1232 <p>Afterwards the path is constructed using the found value and the | |
1233 translation file is loaded if available. | |
1234 </p> | |
1235 <p>What happens now when the value for, say, <code>LANGUAGE</code> changes? According | |
1236 to the process explained above the new value of this variable is found | |
1237 as soon as the <code>dcgettext</code> function is called. But this also means | |
1238 the (perhaps) different message catalog file is loaded. In other | |
1239 words: the used language is changed. | |
1240 </p> | |
1241 <p>But there is one little hook. The code for gcc-2.7.0 and up provides | |
1242 some optimization. This optimization normally prevents the calling of | |
1243 the <code>dcgettext</code> function as long as no new catalog is loaded. But | |
1244 if <code>dcgettext</code> is not called the program also cannot find the | |
1245 <code>LANGUAGE</code> variable be changed (see section <a href="#SEC208">Optimization of the *gettext functions</a>). A | |
1246 solution for this is very easy. Include the following code in the | |
1247 language switching function. | |
1248 </p> | |
1249 <table><tr><td> </td><td><pre class="example"> /* Change language. */ | |
1250 setenv ("LANGUAGE", "fr", 1); | |
1251 | |
1252 /* Make change known. */ | |
1253 { | |
1254 extern int _nl_msg_cat_cntr; | |
1255 ++_nl_msg_cat_cntr; | |
1256 } | |
1257 </pre></td></tr></table> | |
1258 | |
1259 <a name="IDX1088"></a> | |
1260 <p>The variable <code>_nl_msg_cat_cntr</code> is defined in ‘<tt>loadmsgcat.c</tt>’. | |
1261 You don't need to know what this is for. But it can be used to detect | |
1262 whether a <code>gettext</code> implementation is GNU gettext and not non-GNU | |
1263 system's native gettext implementation. | |
1264 </p> | |
1265 </li></ul> | |
1266 | |
1267 | |
1268 <a name="Temp-Programmers"></a> | |
1269 <a name="SEC212"></a> | |
1270 <h2 class="section"> <a href="gettext_toc.html#TOC205">11.6 Temporary Notes for the Programmers Chapter</a> </h2> | |
1271 | |
1272 <p><strong> NOTE: </strong> This documentation section is outdated and needs to be | |
1273 revised. | |
1274 </p> | |
1275 | |
1276 | |
1277 <a name="Temp-Implementations"></a> | |
1278 <a name="SEC213"></a> | |
1279 <h3 class="subsection"> <a href="gettext_toc.html#TOC206">11.6.1 Temporary - Two Possible Implementations</a> </h3> | |
1280 | |
1281 <p>There are two competing methods for language independent messages: | |
1282 the X/Open <code>catgets</code> method, and the Uniforum <code>gettext</code> | |
1283 method. The <code>catgets</code> method indexes messages by integers; the | |
1284 <code>gettext</code> method indexes them by their English translations. | |
1285 The <code>catgets</code> method has been around longer and is supported | |
1286 by more vendors. The <code>gettext</code> method is supported by Sun, | |
1287 and it has been heard that the COSE multi-vendor initiative is | |
1288 supporting it. Neither method is a POSIX standard; the POSIX.1 | |
1289 committee had a lot of disagreement in this area. | |
1290 </p> | |
1291 <p>Neither one is in the POSIX standard. There was much disagreement | |
1292 in the POSIX.1 committee about using the <code>gettext</code> routines | |
1293 vs. <code>catgets</code> (XPG). In the end the committee couldn't | |
1294 agree on anything, so no messaging system was included as part | |
1295 of the standard. I believe the informative annex of the standard | |
1296 includes the XPG3 messaging interfaces, “…as an example of | |
1297 a messaging system that has been implemented…” | |
1298 </p> | |
1299 <p>They were very careful not to say anywhere that you should use one | |
1300 set of interfaces over the other. For more on this topic please | |
1301 see the Programming for Internationalization FAQ. | |
1302 </p> | |
1303 | |
1304 <a name="Temp-catgets"></a> | |
1305 <a name="SEC214"></a> | |
1306 <h3 class="subsection"> <a href="gettext_toc.html#TOC207">11.6.2 Temporary - About <code>catgets</code></a> </h3> | |
1307 | |
1308 <p>There have been a few discussions of late on the use of | |
1309 <code>catgets</code> as a base. I think it important to present both | |
1310 sides of the argument and hence am opting to play devil's advocate | |
1311 for a little bit. | |
1312 </p> | |
1313 <p>I'll not deny the fact that <code>catgets</code> could have been designed | |
1314 a lot better. It currently has quite a number of limitations and | |
1315 these have already been pointed out. | |
1316 </p> | |
1317 <p>However there is a great deal to be said for consistency and | |
1318 standardization. A common recurring problem when writing Unix | |
1319 software is the myriad portability problems across Unix platforms. | |
1320 It seems as if every Unix vendor had a look at the operating system | |
1321 and found parts they could improve upon. Undoubtedly, these | |
1322 modifications are probably innovative and solve real problems. | |
1323 However, software developers have a hard time keeping up with all | |
1324 these changes across so many platforms. | |
1325 </p> | |
1326 <p>And this has prompted the Unix vendors to begin to standardize their | |
1327 systems. Hence the impetus for Spec1170. Every major Unix vendor | |
1328 has committed to supporting this standard and every Unix software | |
1329 developer waits with glee the day they can write software to this | |
1330 standard and simply recompile (without having to use autoconf) | |
1331 across different platforms. | |
1332 </p> | |
1333 <p>As I understand it, Spec1170 is roughly based upon version 4 of the | |
1334 X/Open Portability Guidelines (XPG4). Because <code>catgets</code> and | |
1335 friends are defined in XPG4, I'm led to believe that <code>catgets</code> | |
1336 is a part of Spec1170 and hence will become a standardized component | |
1337 of all Unix systems. | |
1338 </p> | |
1339 | |
1340 <a name="Temp-WSI"></a> | |
1341 <a name="SEC215"></a> | |
1342 <h3 class="subsection"> <a href="gettext_toc.html#TOC208">11.6.3 Temporary - Why a single implementation</a> </h3> | |
1343 | |
1344 <p>Now it seems kind of wasteful to me to have two different systems | |
1345 installed for accessing message catalogs. If we do want to remedy | |
1346 <code>catgets</code> deficiencies why don't we try to expand <code>catgets</code> | |
1347 (in a compatible manner) rather than implement an entirely new system. | |
1348 Otherwise, we'll end up with two message catalog access systems installed | |
1349 with an operating system - one set of routines for packages using GNU | |
1350 <code>gettext</code> for their internationalization, and another set of routines | |
1351 (catgets) for all other software. Bloated? | |
1352 </p> | |
1353 <p>Supposing another catalog access system is implemented. Which do | |
1354 we recommend? At least for Linux, we need to attract as many | |
1355 software developers as possible. Hence we need to make it as easy | |
1356 for them to port their software as possible. Which means supporting | |
1357 <code>catgets</code>. We will be implementing the <code>libintl</code> code | |
1358 within our <code>libc</code>, but does this mean we also have to incorporate | |
1359 another message catalog access scheme within our <code>libc</code> as well? | |
1360 And what about people who are going to be using the <code>libintl</code> | |
1361 + non-<code>catgets</code> routines. When they port their software to | |
1362 other platforms, they're now going to have to include the front-end | |
1363 (<code>libintl</code>) code plus the back-end code (the non-<code>catgets</code> | |
1364 access routines) with their software instead of just including the | |
1365 <code>libintl</code> code with their software. | |
1366 </p> | |
1367 <p>Message catalog support is however only the tip of the iceberg. | |
1368 What about the data for the other locale categories? They also have | |
1369 a number of deficiencies. Are we going to abandon them as well and | |
1370 develop another duplicate set of routines (should <code>libintl</code> | |
1371 expand beyond message catalog support)? | |
1372 </p> | |
1373 <p>Like many parts of Unix that can be improved upon, we're stuck with balancing | |
1374 compatibility with the past with useful improvements and innovations for | |
1375 the future. | |
1376 </p> | |
1377 | |
1378 <a name="Temp-Notes"></a> | |
1379 <a name="SEC216"></a> | |
1380 <h3 class="subsection"> <a href="gettext_toc.html#TOC209">11.6.4 Temporary - Notes</a> </h3> | |
1381 | |
1382 <p>X/Open agreed very late on the standard form so that many | |
1383 implementations differ from the final form. Both of my system (old | |
1384 Linux catgets and Ultrix-4) have a strange variation. | |
1385 </p> | |
1386 <p>OK. After incorporating the last changes I have to spend some time on | |
1387 making the GNU/Linux <code>libc</code> <code>gettext</code> functions. So in future | |
1388 Solaris is not the only system having <code>gettext</code>. | |
1389 </p> | |
1390 | |
1391 <table cellpadding="1" cellspacing="1" border="0"> | |
1392 <tr><td valign="middle" align="left">[<a href="#SEC197" title="Beginning of this chapter or previous chapter"> << </a>]</td> | |
1393 <td valign="middle" align="left">[<a href="gettext_12.html#SEC217" title="Next chapter"> >> </a>]</td> | |
1394 <td valign="middle" align="left"> </td> | |
1395 <td valign="middle" align="left"> </td> | |
1396 <td valign="middle" align="left"> </td> | |
1397 <td valign="middle" align="left"> </td> | |
1398 <td valign="middle" align="left"> </td> | |
1399 <td valign="middle" align="left">[<a href="gettext_toc.html#SEC_Top" title="Cover (top) of document">Top</a>]</td> | |
1400 <td valign="middle" align="left">[<a href="gettext_toc.html#SEC_Contents" title="Table of contents">Contents</a>]</td> | |
1401 <td valign="middle" align="left">[<a href="gettext_21.html#SEC389" title="Index">Index</a>]</td> | |
1402 <td valign="middle" align="left">[<a href="gettext_abt.html#SEC_About" title="About (help)"> ? </a>]</td> | |
1403 </tr></table> | |
1404 <p> | |
1405 <font size="-1"> | |
1406 This document was generated by <em>Bruno Haible</em> on <em>February, 21 2024</em> using <a href="https://www.nongnu.org/texi2html/"><em>texi2html 1.78a</em></a>. | |
1407 </font> | |
1408 <br> | |
1409 | |
1410 </p> | |
1411 </body> | |
1412 </html> |