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