1<section xmlns="http://docbook.org/ns/docbook" version="5.0" 
2	 xml:id="std.localization.facet.messages" xreflabel="Messages">
3<?dbhtml filename="messages.html"?>
4
5<info><title>messages</title>
6  <keywordset>
7    <keyword>ISO C++</keyword>
8    <keyword>messages</keyword>
9  </keywordset>
10</info>
11
12
13
14<para>
15The <classname>std::messages</classname> facet implements message retrieval functionality
16equivalent to Java's <classname>java.text.MessageFormat</classname> using either GNU <function>gettext</function>
17or IEEE 1003.1-200 functions.
18</para>
19
20<section xml:id="facet.messages.req"><info><title>Requirements</title></info>
21
22
23<para>
24The <classname>std::messages</classname> facet is probably the most vaguely defined facet in
25the standard library. It's assumed that this facility was built into
26the standard library in order to convert string literals from one
27locale to the other. For instance, converting the "C" locale's
28<code>const char* c = "please"</code> to a German-localized <code>"bitte"</code>
29during program execution.
30</para>
31
32<blockquote>
33<para>
3422.2.7.1 - Template class messages [lib.locale.messages]
35</para>
36</blockquote>
37
38<para>
39This class has three public member functions, which directly
40correspond to three protected virtual member functions.
41</para>
42
43<para>
44The public member functions are:
45</para>
46
47<para>
48<code>catalog open(const string&amp;, const locale&amp;) const</code>
49</para>
50
51<para>
52<code>string_type get(catalog, int, int, const string_type&amp;) const</code>
53</para>
54
55<para>
56<code>void close(catalog) const</code>
57</para>
58
59<para>
60While the virtual functions are:
61</para>
62
63<para>
64<code>catalog do_open(const string&amp; name, const locale&amp; loc) const</code>
65</para>
66<blockquote>
67<para>
68<emphasis>
69-1- Returns: A value that may be passed to <code>get()</code> to retrieve a
70message, from the message catalog identified by the string <code>name</code>
71according to an implementation-defined mapping. The result can be used
72until it is passed to <code>close()</code>.  Returns a value less than 0 if no such
73catalog can be opened.
74</emphasis>
75</para>
76</blockquote>
77
78<para>
79<code>string_type do_get(catalog cat, int set , int msgid, const string_type&amp; dfault) const</code>
80</para>
81<blockquote>
82<para>
83<emphasis>
84-3- Requires: A catalog <code>cat</code> obtained from <code>open()</code> and not yet closed.
85-4- Returns: A message identified by arguments <code>set</code>, <code>msgid</code>, and <code>dfault</code>,
86according to an implementation-defined mapping. If no such message can
87be found, returns <code>dfault</code>.
88</emphasis>
89</para>
90</blockquote>
91
92<para>
93<code>void do_close(catalog cat) const</code>
94</para>
95<blockquote>
96<para>
97<emphasis>
98-5- Requires: A catalog cat obtained from <code>open()</code> and not yet closed.
99-6- Effects: Releases unspecified resources associated with <code>cat</code>.
100-7- Notes: The limit on such resources, if any, is implementation-defined.
101</emphasis>
102</para>
103</blockquote>
104
105
106</section>
107
108<section xml:id="facet.messages.design"><info><title>Design</title></info>
109
110
111<para>
112A couple of notes on the standard.
113</para>
114
115<para>
116First, why is <code>messages_base::catalog</code> specified as a typedef
117to int? This makes sense for implementations that use
118<code>catopen</code> and define <code>nl_catd</code> as int, but not for
119others. Fortunately, it's not heavily used and so only a minor irritant. 
120This has been reported as a possible defect in the standard (LWG 2028).
121</para>
122
123<para>
124Second, by making the member functions <code>const</code>, it is
125impossible to save state in them. Thus, storing away information used
126in the 'open' member function for use in 'get' is impossible. This is
127unfortunate.
128</para>
129
130<para>
131The 'open' member function in particular seems to be oddly
132designed. The signature seems quite peculiar. Why specify a <code>const
133string&amp; </code> argument, for instance, instead of just <code>const
134char*</code>? Or, why specify a <code>const locale&amp;</code> argument that is
135to be used in the 'get' member function? How, exactly, is this locale
136argument useful? What was the intent? It might make sense if a locale
137argument was associated with a given default message string in the
138'open' member function, for instance. Quite murky and unclear, on
139reflection.
140</para>
141
142<para>
143Lastly, it seems odd that messages, which explicitly require code
144conversion, don't use the codecvt facet. Because the messages facet
145has only one template parameter, it is assumed that ctype, and not
146codecvt, is to be used to convert between character sets.
147</para>
148
149<para>
150It is implicitly assumed that the locale for the default message
151string in 'get' is in the "C" locale. Thus, all source code is assumed
152to be written in English, so translations are always from "en_US" to
153other, explicitly named locales.
154</para>
155
156</section>
157
158<section xml:id="facet.messages.impl"><info><title>Implementation</title></info>
159
160
161  <section xml:id="messages.impl.models"><info><title>Models</title></info>
162  
163  <para>
164    This is a relatively simple class, on the face of it. The standard
165    specifies very little in concrete terms, so generic
166    implementations that are conforming yet do very little are the
167    norm. Adding functionality that would be useful to programmers and
168    comparable to Java's java.text.MessageFormat takes a bit of work,
169    and is highly dependent on the capabilities of the underlying
170    operating system.
171  </para>
172
173  <para>
174    Three different mechanisms have been provided, selectable via
175    configure flags:
176  </para>
177
178<itemizedlist>
179   <listitem>
180     <para>
181       generic
182     </para>
183     <para>
184       This model does very little, and is what is used by default.
185     </para>
186   </listitem>
187
188   <listitem>
189     <para>
190       gnu
191     </para>
192     <para>
193       The gnu model is complete and fully tested. It's based on the
194       GNU gettext package, which is part of glibc. It uses the
195       functions <code>textdomain, bindtextdomain, gettext</code> to
196       implement full functionality. Creating message catalogs is a
197       relatively straight-forward process and is lightly documented
198       below, and fully documented in gettext's distributed
199       documentation.
200     </para>
201   </listitem>
202
203   <listitem>
204     <para>
205       ieee_1003.1-200x
206     </para>
207     <para>
208       This is a complete, though untested, implementation based on
209       the IEEE standard. The functions <code>catopen, catgets,
210       catclose</code> are used to retrieve locale-specific messages
211       given the appropriate message catalogs that have been
212       constructed for their use. Note, the script <code>
213       po2msg.sed</code> that is part of the gettext distribution can
214       convert gettext catalogs into catalogs that
215       <code>catopen</code> can use.
216   </para>
217   </listitem>
218</itemizedlist>
219
220<para>
221A new, standards-conformant non-virtual member function signature was
222added for 'open' so that a directory could be specified with a given
223message catalog. This simplifies calling conventions for the gnu
224model.
225</para>
226
227  </section>
228
229  <section xml:id="messages.impl.gnu"><info><title>The GNU Model</title></info>
230  
231
232  <para>
233    The messages facet, because it is retrieving and converting
234    between characters sets, depends on the ctype and perhaps the
235    codecvt facet in a given locale. In addition, underlying "C"
236    library locale support is necessary for more than just the
237    <code>LC_MESSAGES</code> mask: <code>LC_CTYPE</code> is also
238    necessary. To avoid any unpleasantness, all bits of the "C" mask
239    (i.e. <code>LC_ALL</code>) are set before retrieving messages.
240  </para>
241
242  <para>
243    Making the message catalogs can be initially tricky, but become
244    quite simple with practice. For complete info, see the gettext
245    documentation. Here's an idea of what is required:
246  </para>
247
248<itemizedlist>
249   <listitem>
250     <para>
251       Make a source file with the required string literals that need
252       to be translated. See <code>intl/string_literals.cc</code> for
253       an example.
254     </para>
255   </listitem>
256
257   <listitem>
258     <para>
259       Make initial catalog (see "4 Making the PO Template File" from
260       the gettext docs).</para>
261   <para>
262   <code> xgettext --c++ --debug string_literals.cc -o libstdc++.pot </code>
263   </para>
264   </listitem>
265
266   <listitem>
267     <para>Make language and country-specific locale catalogs.</para>
268   <para>
269   <code>cp libstdc++.pot fr_FR.po</code>
270   </para>
271   <para>
272   <code>cp libstdc++.pot de_DE.po</code>
273   </para>
274   </listitem>
275
276   <listitem>
277     <para>
278       Edit localized catalogs in emacs so that strings are
279       translated.
280     </para>
281   <para>
282   <code>emacs fr_FR.po</code>
283   </para>
284   </listitem>
285
286   <listitem>
287     <para>Make the binary mo files.</para>
288   <para>
289   <code>msgfmt fr_FR.po -o fr_FR.mo</code>
290   </para>
291   <para>
292   <code>msgfmt de_DE.po -o de_DE.mo</code>
293   </para>
294   </listitem>
295
296   <listitem>
297     <para>Copy the binary files into the correct directory structure.</para>
298   <para>
299   <code>cp fr_FR.mo (dir)/fr_FR/LC_MESSAGES/libstdc++.mo</code>
300   </para>
301   <para>
302   <code>cp de_DE.mo (dir)/de_DE/LC_MESSAGES/libstdc++.mo</code>
303   </para>
304   </listitem>
305
306   <listitem>
307     <para>Use the new message catalogs.</para>
308   <para>
309   <code>locale loc_de("de_DE");</code>
310   </para>
311   <para>
312   <code>
313   use_facet&lt;messages&lt;char&gt; &gt;(loc_de).open("libstdc++", locale(), dir);
314   </code>
315   </para>
316   </listitem>
317</itemizedlist>
318
319  </section>
320</section>
321
322<section xml:id="facet.messages.use"><info><title>Use</title></info>
323
324 <para>
325   A simple example using the GNU model of message conversion.
326 </para>
327
328<programlisting>
329#include &lt;iostream&gt;
330#include &lt;locale&gt;
331using namespace std;
332
333void test01()
334{
335  typedef messages&lt;char&gt;::catalog catalog;
336  const char* dir =
337  "/mnt/egcs/build/i686-pc-linux-gnu/libstdc++/po/share/locale";
338  const locale loc_de("de_DE");
339  const messages&lt;char&gt;&amp; mssg_de = use_facet&lt;messages&lt;char&gt; &gt;(loc_de);
340
341  catalog cat_de = mssg_de.open("libstdc++", loc_de, dir);
342  string s01 = mssg_de.get(cat_de, 0, 0, "please");
343  string s02 = mssg_de.get(cat_de, 0, 0, "thank you");
344  cout &lt;&lt; "please in german:" &lt;&lt; s01 &lt;&lt; '\n';
345  cout &lt;&lt; "thank you in german:" &lt;&lt; s02 &lt;&lt; '\n';
346  mssg_de.close(cat_de);
347}
348</programlisting>
349
350</section>
351
352<section xml:id="facet.messages.future"><info><title>Future</title></info>
353
354
355<itemizedlist>
356<listitem>
357  <para>
358    Things that are sketchy, or remain unimplemented:
359  </para>
360   <itemizedlist>
361      <listitem>
362	<para>
363	  _M_convert_from_char, _M_convert_to_char are in flux,
364	  depending on how the library ends up doing character set
365	  conversions. It might not be possible to do a real character
366	  set based conversion, due to the fact that the template
367	  parameter for messages is not enough to instantiate the
368	  codecvt facet (1 supplied, need at least 2 but would prefer
369	  3).
370	</para>
371      </listitem>
372
373      <listitem>
374	<para>
375	  There are issues with gettext needing the global locale set
376	  to extract a message. This dependence on the global locale
377	  makes the current "gnu" model non MT-safe. Future versions
378	  of glibc, i.e. glibc 2.3.x will fix this, and the C++ library
379	  bits are already in place.
380	</para>
381      </listitem>
382   </itemizedlist>
383</listitem>
384
385<listitem>
386  <para>
387    Development versions of the GNU "C" library, glibc 2.3 will allow
388    a more efficient, MT implementation of std::messages, and will
389    allow the removal of the _M_name_messages data member. If this is
390    done, it will change the library ABI. The C++ parts to support
391    glibc 2.3 have already been coded, but are not in use: once this
392    version of the "C" library is released, the marked parts of the
393    messages implementation can be switched over to the new "C"
394    library functionality.
395  </para>
396</listitem>
397<listitem>
398  <para>
399    At some point in the near future, std::numpunct will probably use
400    std::messages facilities to implement truename/falsename
401    correctly. This is currently not done, but entries in
402    libstdc++.pot have already been made for "true" and "false" string
403    literals, so all that remains is the std::numpunct coding and the
404    configure/make hassles to make the installed library search its
405    own catalog. Currently the libstdc++.mo catalog is only searched
406    for the testsuite cases involving messages members.
407  </para>
408</listitem>
409
410<listitem>
411  <para> The following member functions:</para>
412
413   <para>
414   <code>
415	catalog
416	open(const basic_string&lt;char&gt;&amp; __s, const locale&amp; __loc) const
417   </code>
418   </para>
419
420   <para>
421   <code>
422   catalog
423   open(const basic_string&lt;char&gt;&amp;, const locale&amp;, const char*) const;
424   </code>
425   </para>
426
427   <para>
428   Don't actually return a "value less than 0 if no such catalog
429   can be opened" as required by the standard in the "gnu"
430   model. As of this writing, it is unknown how to query to see
431   if a specified message catalog exists using the gettext
432   package.
433   </para>
434</listitem>
435</itemizedlist>
436
437</section>
438
439<bibliography xml:id="facet.messages.biblio"><info><title>Bibliography</title></info>
440
441
442  <biblioentry>
443    <citetitle>
444      The GNU C Library
445    </citetitle>
446    <author><personname><surname>McGrath</surname><firstname>Roland</firstname></personname></author>
447    <author><personname><surname>Drepper</surname><firstname>Ulrich</firstname></personname></author>
448    <copyright>
449      <year>2007</year>
450      <holder>FSF</holder>
451    </copyright>
452    <pagenums>Chapters 6 Character Set Handling, and 7 Locales and Internationalization
453    </pagenums>
454  </biblioentry>
455
456  <biblioentry>
457    <citetitle>
458      Correspondence
459    </citetitle>
460    <author><personname><surname>Drepper</surname><firstname>Ulrich</firstname></personname></author>
461    <copyright>
462      <year>2002</year>
463      <holder/>
464    </copyright>
465  </biblioentry>
466
467  <biblioentry>
468    <citetitle>
469      ISO/IEC 14882:1998 Programming languages - C++
470    </citetitle>
471    <copyright>
472      <year>1998</year>
473      <holder>ISO</holder>
474    </copyright>
475  </biblioentry>
476
477  <biblioentry>
478    <citetitle>
479      ISO/IEC 9899:1999 Programming languages - C
480    </citetitle>
481
482    <copyright>
483      <year>1999</year>
484      <holder>ISO</holder>
485    </copyright>
486  </biblioentry>
487
488  <biblioentry>
489      <title>
490	<link xmlns:xlink="http://www.w3.org/1999/xlink"
491	      xlink:href="https://pubs.opengroup.org/onlinepubs/9699919799/">
492      System Interface Definitions, Issue 7 (IEEE Std. 1003.1-2008)
493	</link>
494      </title>
495        <copyright>
496      <year>2008</year>
497      <holder>
498	The Open Group/The Institute of Electrical and Electronics
499	Engineers, Inc.
500      </holder>
501    </copyright>
502  </biblioentry>
503
504  <biblioentry>
505    <citetitle>
506      The C++ Programming Language, Special Edition
507    </citetitle>
508    <author><personname><surname>Stroustrup</surname><firstname>Bjarne</firstname></personname></author>
509    <copyright>
510      <year>2000</year>
511      <holder>Addison Wesley, Inc.</holder>
512    </copyright>
513    <pagenums>Appendix D</pagenums>
514    <publisher>
515      <publishername>
516	Addison Wesley
517      </publishername>
518    </publisher>
519  </biblioentry>
520
521  <biblioentry>
522    <citetitle>
523      Standard C++ IOStreams and Locales
524    </citetitle>
525    <subtitle>
526      Advanced Programmer's Guide and Reference
527    </subtitle>
528    <author><personname><surname>Langer</surname><firstname>Angelika</firstname></personname></author>
529    <author><personname><surname>Kreft</surname><firstname>Klaus</firstname></personname></author>
530    <copyright>
531      <year>2000</year>
532      <holder>Addison Wesley Longman, Inc.</holder>
533    </copyright>
534    <publisher>
535      <publishername>
536	Addison Wesley Longman
537      </publishername>
538    </publisher>
539  </biblioentry>
540
541  <biblioentry>
542      <title>
543	<link xmlns:xlink="http://www.w3.org/1999/xlink"
544	      xlink:href="https://www.oracle.com/technetwork/java/api/index.html">
545	API Specifications, Java Platform
546	</link>
547      </title>
548
549    <pagenums>java.util.Properties, java.text.MessageFormat,
550java.util.Locale, java.util.ResourceBundle
551    </pagenums>
552  </biblioentry>
553
554
555  <biblioentry>
556      <title>
557	<link xmlns:xlink="http://www.w3.org/1999/xlink"
558	      xlink:href="https://www.gnu.org/software/gettext/">
559      GNU gettext tools, version 0.10.38, Native Language Support
560      Library and Tools.
561	</link>
562      </title>
563
564  </biblioentry>
565
566</bibliography>
567
568</section>
569