Next | Prev | Up | Top | Contents | Index

XPG/4 Message Catalogs

The XPG/4 message catalog interface requires that a catalog be opened before it is read, and requires that catalog references specify a catalog descriptor.

Since catalog references include a default to be used in case of failure, applications will work normally without a catalog when in the default locale. This means catalog generation is exclusively the task of localizers. But in order to inform the localizer as to what strings to translate and how they should comprise a catalog, the application developer should provide a catalog for the developer's locale.


Opening and Closing XPG/4 Catalogs

catopen() locates and opens a message catalog file:

#include <nl_types.h>
nl_catd catopen(char *name, int unused);
The argument name is used to locate the catalog. Usually, this is a simple, relative pathname that is combined with environment variables to indicate the path to the catalog (see "XPG/4 Catalog Location" for details). However, the catalog assumes names that begin with "/ " are absolute pathnames. Use of a hard-coded pathname like this is strongly discouraged; it doesn't allow the user to specify the catalog's locale through environment variables.

When an application is finished using a message catalog, it should close the catalog and free the descriptor using catclose():

int catclose(nl_catd);

Using an XPG/4 Catalog

Catalogs contain sets of numbered messages. The application developer must know the contents of the catalog in order to specify the set and number of a message to be obtained.

catgets() is used to retrieve strings from a message catalog (see the catopen(3) and catgets(3) reference pages). Example 6-3 shows a program that reads the first message from the first message set in the appropriate catalog, and displays the result.

Example 6-3 : Reading an XPG/4 Catalog

#include <stdio.h>
#include <locale.h>
#include <nl_types.h>
#define SET1      1
#define WRLD_MSG  1
int main(){
    nl_catd msgd;
    char *message;
    setlocale(LC_ALL, ""); 
msgd = catopen("hw",0);
    message = catgets(msgd, SET1, WRLD_MSG,"Hello, world\n");
    printf(message);
    catclose(msgd);
}
The previous example uses printf() instead of puts() in order to make a point: the format string of printf() came from a catalog. Note the crucial difference between these two statements:

printf(catgets(msgd, set, num, defaultStr));
printf("%s", catgets(msgd, set, num, defaultStr));
In the first statement, the catalog provides the printf() formatting string, possibly containing conversion specifications and escape sequences. In the second statement, the string from the catalog is treated as data and not interpreted for conversion specifications. For further discussion of issues relating to this important distinction, see "Variably Ordered Referencing of printf() Arguments."


XPG/4 Catalog Location

XPG/4 message catalogs are located using the environment variable NLSPATH. The default NLSPATH is /nlslib/%L/%N, where %L is filled in by the LANG environment variable and %N is filled in by the name argument to catopen(). NLSPATH can specify multiple pathnames in ordered precedence, much like the PATH variable. The following is a sample NLSPATH assignment:

NLSPATH=/usr/lib/locale/%L/%N:/usr/local/lib/locale/%L/%N:/usr/defaults/%N

Creating XPG/4 Message Catalogs

Message catalogs are of this general form (these forms are detailed in the gencat(1) reference page):

$set n comment
a message-a\n
b message-b\n
c message-c\n
$quote "
d " message-d "
$this is a comment
Each message is identified by a message number and a set. Sets are often used to separate messages into more easily usable groups, such as error messages, help messages, directives, and so on. Alternatively, you could use a different set for each source file, containing all of that source file's messages.

$set n specifies the beginning of set n, where n is a set identifier in the range from 1 to NL_SETMAX. All messages following the $set statement belong to set n until either a $delset or another $set is reached. You can skip set numbers (for example, you can have a set 3 without having a set 2), but the set numbers that you use must be listed in ascending numerical order (and every set must have a number). Any string following the set identifier on the same line is considered a comment.

$delset n deletes the set n from a message catalog.

$quote c specifies a quote character, c, which can be used to surround message text so that trailing spaces or null (empty) messages are visible in a message source line. By default, there is no quote character and messages are separated by newlines. To continue a message onto a second line, add a backslash to the end of the first line:

$set 1
1 Hello, world.
2 here is a long \
string.\n
3 Hello again.
n message-text-n
Message #2 in set #1 is "here is a long string.\n".


Compiling XPG/4 Message Catalogs

After creating the message catalog sources, you need to compile them into binary form using gencat, which has the following syntax:

gencat catfile msgfile [msgfile ...]
where catfile is the target message catalog and msgfile is the message source file (see the gencat(1) reference page). If an old catfile exists, gencat attempts to merge new entries with the old. gencat "resolves" set and message number conflicts with new information replacing the old.

The catfile then needs to be placed in a location where catopen() can find it; see the "XPG/4 Catalog Location".


Next | Prev | Up | Top | Contents | Index