blob: 67d822de9b746163685e351431d8352cb30e0956 [file] [log] [blame]
<html lang="en">
<head>
<title>Common Usage - The GNU C Library</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="The GNU C Library">
<meta name="generator" content="makeinfo 4.13">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Message-catalogs-a-la-X_002fOpen.html#Message-catalogs-a-la-X_002fOpen" title="Message catalogs a la X/Open">
<link rel="prev" href="The-gencat-program.html#The-gencat-program" title="The gencat program">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<!--
This file documents the GNU C library.
This is Edition 0.12, last updated 2007-10-27,
of `The GNU C Library Reference Manual', for version
2.8 (Sourcery G++ Lite 2011.03-41).
Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002,
2003, 2007, 2008, 2010 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with the
Invariant Sections being ``Free Software Needs Free Documentation''
and ``GNU Lesser General Public License'', the Front-Cover texts being
``A GNU Manual'', and with the Back-Cover Texts as in (a) below. A
copy of the license is included in the section entitled "GNU Free
Documentation License".
(a) The FSF's Back-Cover Text is: ``You have the freedom to
copy and modify this GNU manual. Buying copies from the FSF
supports it in developing GNU and promoting software freedom.''-->
<meta http-equiv="Content-Style-Type" content="text/css">
<style type="text/css"><!--
pre.display { font-family:inherit }
pre.format { font-family:inherit }
pre.smalldisplay { font-family:inherit; font-size:smaller }
pre.smallformat { font-family:inherit; font-size:smaller }
pre.smallexample { font-size:smaller }
pre.smalllisp { font-size:smaller }
span.sc { font-variant:small-caps }
span.roman { font-family:serif; font-weight:normal; }
span.sansserif { font-family:sans-serif; font-weight:normal; }
--></style>
<link rel="stylesheet" type="text/css" href="../cs.css">
</head>
<body>
<div class="node">
<a name="Common-Usage"></a>
<p>
Previous:&nbsp;<a rel="previous" accesskey="p" href="The-gencat-program.html#The-gencat-program">The gencat program</a>,
Up:&nbsp;<a rel="up" accesskey="u" href="Message-catalogs-a-la-X_002fOpen.html#Message-catalogs-a-la-X_002fOpen">Message catalogs a la X/Open</a>
<hr>
</div>
<h4 class="subsection">8.1.4 How to use the <code>catgets</code> interface</h4>
<p>The <code>catgets</code> functions can be used in two different ways. By
following slavishly the X/Open specs and not relying on the extension
and by using the GNU extensions. We will take a look at the former
method first to understand the benefits of extensions.
<h5 class="subsubsection">8.1.4.1 Not using symbolic names</h5>
<p>Since the X/Open format of the message catalog files does not allow
symbol names we have to work with numbers all the time. When we start
writing a program we have to replace all appearances of translatable
strings with something like
<pre class="smallexample"> catgets (catdesc, set, msg, "string")
</pre>
<p class="noindent"><var>catgets</var> is retrieved from a call to <code>catopen</code> which is
normally done once at the program start. The <code>"string"</code> is the
string we want to translate. The problems start with the set and
message numbers.
<p>In a bigger program several programmers usually work at the same time on
the program and so coordinating the number allocation is crucial.
Though no two different strings must be indexed by the same tuple of
numbers it is highly desirable to reuse the numbers for equal strings
with equal translations (please note that there might be strings which
are equal in one language but have different translations due to
difference contexts).
<p>The allocation process can be relaxed a bit by different set numbers for
different parts of the program. So the number of developers who have to
coordinate the allocation can be reduced. But still lists must be keep
track of the allocation and errors can easily happen. These errors
cannot be discovered by the compiler or the <code>catgets</code> functions.
Only the user of the program might see wrong messages printed. In the
worst cases the messages are so irritating that they cannot be
recognized as wrong. Think about the translations for <code>"true"</code> and
<code>"false"</code> being exchanged. This could result in a disaster.
<h5 class="subsubsection">8.1.4.2 Using symbolic names</h5>
<p>The problems mentioned in the last section derive from the fact that:
<ol type=1 start=1>
<li>the numbers are allocated once and due to the possibly frequent use of
them it is difficult to change a number later.
<li>the numbers do not allow to guess anything about the string and
therefore collisions can easily happen.
</ol>
<p>By constantly using symbolic names and by providing a method which maps
the string content to a symbolic name (however this will happen) one can
prevent both problems above. The cost of this is that the programmer
has to write a complete message catalog file while s/he is writing the
program itself.
<p>This is necessary since the symbolic names must be mapped to numbers
before the program sources can be compiled. In the last section it was
described how to generate a header containing the mapping of the names.
E.g., for the example message file given in the last section we could
call the <code>gencat</code> program as follow (assume <samp><span class="file">ex.msg</span></samp> contains
the sources).
<pre class="smallexample"> gencat -H ex.h -o ex.cat ex.msg
</pre>
<p class="noindent">This generates a header file with the following content:
<pre class="smallexample"> #define SetTwoSet 0x2 /* ex.msg:8 */
#define SetOneSet 0x1 /* ex.msg:4 */
#define SetOnetwo 0x2 /* ex.msg:6 */
</pre>
<p>As can be seen the various symbols given in the source file are mangled
to generate unique identifiers and these identifiers get numbers
assigned. Reading the source file and knowing about the rules will
allow to predict the content of the header file (it is deterministic)
but this is not necessary. The <code>gencat</code> program can take care for
everything. All the programmer has to do is to put the generated header
file in the dependency list of the source files of her/his project and
to add a rules to regenerate the header of any of the input files
change.
<p>One word about the symbol mangling. Every symbol consists of two parts:
the name of the message set plus the name of the message or the special
string <code>Set</code>. So <code>SetOnetwo</code> means this macro can be used to
access the translation with identifier <code>two</code> in the message set
<code>SetOne</code>.
<p>The other names denote the names of the message sets. The special
string <code>Set</code> is used in the place of the message identifier.
<p>If in the code the second string of the set <code>SetOne</code> is used the C
code should look like this:
<pre class="smallexample"> catgets (catdesc, SetOneSet, SetOnetwo,
" Message with ID \"two\", which gets the value 2 assigned")
</pre>
<p>Writing the function this way will allow to change the message number
and even the set number without requiring any change in the C source
code. (The text of the string is normally not the same; this is only
for this example.)
<h5 class="subsubsection">8.1.4.3 How does to this allow to develop</h5>
<p>To illustrate the usual way to work with the symbolic version numbers
here is a little example. Assume we want to write the very complex and
famous greeting program. We start by writing the code as usual:
<pre class="smallexample"> #include &lt;stdio.h&gt;
int
main (void)
{
printf ("Hello, world!\n");
return 0;
}
</pre>
<p>Now we want to internationalize the message and therefore replace the
message with whatever the user wants.
<pre class="smallexample"> #include &lt;nl_types.h&gt;
#include &lt;stdio.h&gt;
#include "msgnrs.h"
int
main (void)
{
nl_catd catdesc = catopen ("hello.cat", NL_CAT_LOCALE);
printf (catgets (catdesc, SetMainSet, SetMainHello,
"Hello, world!\n"));
catclose (catdesc);
return 0;
}
</pre>
<p>We see how the catalog object is opened and the returned descriptor used
in the other function calls. It is not really necessary to check for
failure of any of the functions since even in these situations the
functions will behave reasonable. They simply will be return a
translation.
<p>What remains unspecified here are the constants <code>SetMainSet</code> and
<code>SetMainHello</code>. These are the symbolic names describing the
message. To get the actual definitions which match the information in
the catalog file we have to create the message catalog source file and
process it using the <code>gencat</code> program.
<pre class="smallexample"> $ Messages for the famous greeting program.
$quote "
$set Main
Hello "Hallo, Welt!\n"
</pre>
<p>Now we can start building the program (assume the message catalog source
file is named <samp><span class="file">hello.msg</span></samp> and the program source file <samp><span class="file">hello.c</span></samp>):
<pre class="smallexample"> <p><table class="cartouche" summary="cartouche" border="1"><tr><td>
% gencat -H msgnrs.h -o hello.cat hello.msg
% cat msgnrs.h
#define MainSet 0x1 /* hello.msg:4 */
#define MainHello 0x1 /* hello.msg:5 */
% gcc -o hello hello.c -I.
% cp hello.cat /usr/share/locale/de/LC_MESSAGES
% echo $LC_ALL
de
% ./hello
Hallo, Welt!
%
</td></tr></table>
</pre>
<p>The call of the <code>gencat</code> program creates the missing header file
<samp><span class="file">msgnrs.h</span></samp> as well as the message catalog binary. The former is
used in the compilation of <samp><span class="file">hello.c</span></samp> while the later is placed in a
directory in which the <code>catopen</code> function will try to locate it.
Please check the <code>LC_ALL</code> environment variable and the default path
for <code>catopen</code> presented in the description above.
</body></html>