| <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: <a rel="previous" accesskey="p" href="The-gencat-program.html#The-gencat-program">The gencat program</a>, |
| Up: <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 <stdio.h> |
| 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 <nl_types.h> |
| #include <stdio.h> |
| #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> |
| |