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.
#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);
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."
NLSPATH=/usr/lib/locale/%L/%N:/usr/local/lib/locale/%L/%N:/usr/defaults/%N
$set n comment a message-a\n b message-b\n c message-c\n $quote " d " message-d " $this is a commentEach 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-nMessage #2 in set #1 is "here is a long string.\n".
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".