To facilitate translations of messages into various languages and make them available to a program based on a user's locale, it is necessary to keep messages separate from the program by providing them in the form of message catalogs that the program can access at run time. To aid in this task, commands and subroutines are provided by the Message Facility.
Message source files containing application messages are created by the programmer and converted to message catalogs. The application uses these catalogs to retrieve and display messages, as needed. Translating message source files into other languages and then converting the files to message catalogs does not require changing and recompiling a program.
The following information is provided for understanding the Message Facility:
The Message Facility provides commands and subroutines to retrieve and display program messages located in externalized message catalogs. A programmer creates a message source file containing application messages and converts it to a message catalog with the gencat command.
To create a message-text source file, open a file using any text editor. Enter a message identification number or symbolic identifier. Then enter the message text as shown in the following example:
1 message-text $ (This message is numbered) 2 message-text $ (This message is numbered) OUTMSG message-text $ (This message has a symbolic identifier \ called OUTMSG) 4 message-text $ (This message is numbered)
Note: Symbolic identifiers are specific to the Message Facility. Portability of message source files can be affected by the use of symbolic identifiers.
You can include a comment anywhere in a message source file except within message text. Leave at least one space or tab (blank) after the $ (dollar sign). The following is an example of a comment:
$ This is a comment.
Comments do not appear in the message catalog generated from the message source file.
Comments can help developers in the process of maintaining message source files, translators in the process of translation, and writers in the process of editing and documenting messages. Use comments to identify what variables, such as % s, % c, and % d, represent. For example, create a note that states whether the variable refers to a user, file, directory, or flag. Comments also should be used to identify obsolete messages.
For clarity, you should place a comment line directly beneath the message to which it refers, rather than at the bottom of the message catalog. Global comments for an entire set can be placed directly below the $set directive.
All text following the blank after the message number is included as message text, up to the end of the line. Use the escape character \ (backslash) to continue message text on the following line. The \ (backslash) must be the last character on the line as in the following example:
5 This is the text associated with \ message number 5.
These two physical lines define the single-line message:
This is the text associated with message number 5.
Note: The use of more than one blank character after the message number or symbolic identifier is specific to the Message Facility. Portability of message source files can be affected by the use of more than one blank.
The \ (backslash) can be used to insert special characters into the message text. These special characters are:
You can use the $quote directive in a message source file to define a character for delimiting message text. This character should be an ASCII character. The format is:
$quote [character] [comment]
Use the specified character before and after the message text. In the following example, the $quote directive sets the quote character to _ (underscore), and then disables it before the last message, which contains quotation marks:
$quote _ Use an underscore to delimit message text $set MSFAC Message Facility - symbolic identifiers SYM_FORM _Symbolic identifiers can contain alphanumeric \ characters or the \_ (underscore character)\n_ SYM_LEN _Symbolic identifiers can be up to 65 \ characters long \n_ 5 _You can mix symbolic identifiers and numbers \n_ $quote MSG_H Remember to include the _msg_h_ file in your program\n
The last $quote directive in the previous example disables the underscore character.
In the following example, the $quote directive defines " (double quotation marks) as the quote character. The quote character must be the first non-blank character following the message number. Any text following the next occurrence of the quote character is ignored.
$quote " Use a double quote to delimit message text $set 10 Message Facility - Quote command messages 1 "Use the $quote directive to define a character \ \n for delimiting message text" 2 "You can include the \"quote\" character in a message \n \ by placing a \\ in front of it" 3 You can include the "quote" character in a message \n \ by having another character as the first nonblank \ \n character after the message ID number $quote 4 You can disable the quote mechanism by \n \ using the $quote directive without a character \n\ after it
This example illustrates two ways the quote character can be included in message text:
The example also shows the following:
All message sets require a set number or symbolic identifier. Use the $set directive in a source file to give a group of messages a number or identifier:
$set n [ comment ]
The message set number is specified by the value of n, a number between 1 and NL_SETMAX. Instead of a number, you can use a symbolic identifier. All messages following the $set directive are assigned to that set number until the next occurrence of a $set directive. The default set number is 1. Set numbers must be assigned in ascending order, but need not be in series. Empty sets are created for skipped numbers. However, large gaps in the number sequence decrease efficiency and performance. Moreover, performance is not enhanced by using more than one set number in a catalog.
You can also include a comment in the $set directive, as follows:
$set 10 Communication Error Messages
$set OUTMSGS Output Error Messages
Many AIX message sets have a symbolic identifier of the form MS_ PROG, where MS represents Message Set and PROG is the name of the program or utility related to the message set. For example:
$set MS_WC Message Set for the wc Utility
$set MS_XLC1 Message Set 1 for the C For AIX compiler
$set MS_XLC2 Message Set 2 for the C For AIX compiler
The $delset directive removes all of the messages belonging to a specified set from an existing catalog:
$delset n [ comment ]
The message set is specified by n. The $delset directive must be placed in the proper set-number order with respect to any $set directives in the same source file. You can also include a comment in the $delset directive.
The $len directive establishes the maximum display length of message text:
$len [ n [ comment ] ]
If n is not specified or if the $len directive is not included, the message text display is set to the NL_TEXTMAX value. The message-text display length is the maximum number of bytes allowed for a message. Any subsequent specification of a $len directive overrides a previous specification. The value of n cannot exceed the NL_TEXTMAX value.
Whenever possible, tell users exactly what has happened and what they can do to remedy the situation. The following example shows how cause and recovery information can improve a message:
Original Message: Bad arg
Revised Message: Specify year as a value between 1 and 9999.
The message Bad arg does not help users much; whereas the message Do not specify more than 2 files on the command line tells users exactly what they must do to make the command work. Similarly, the message Line too long does not give users recovery information. The message Line cannot exceed 20 characters provides the missing information.
$ This is a message source file sample. $ Define the Quote Character. $quote " $set 1 This is the set 1 of messages. 1 "The specified file does not have read permission on/n" 2 "The %1$s file and the %2$s file are same/n" 3 "Hello world!/n" $Define the quote character $quote ' $set 2 This is the set 2 of messages 1 'fieldef: Cannot open %1$s /n' 2 'Hello world/n'
$ This is a message source file sample. $ Define the Quote Character. $quote " $set MS_SET1 This is the set 1 of messages. MSG_1 "The specified file does not have read permission on/n" MSG_2 "The %1$s file and the %2$s file are same/n" MSG_3 "Hello world/n" $Define the quote character $quote $set 2 This is the set 2 of messages. $EMSG_1 'fieldef: Cannot open %1$s/n' $EMSG_2 'Hello world!/n'
catgets(cd, 1, 1, "default message")
catgets(cd, MS_SET1, MSG_1, "default message")
The Message Facility provides commands and subroutines to retrieve and display program messages located in externalized message catalogs. A programmer creates a message source file containing application messages and converts it to a message catalog. Translating message source files into other languages and then converting the files to message catalogs does not require changing or recompiling a program.
To create a message catalog, process your completed message source file with the message facility's gencat command. This command can be used three ways:
gencat x.cat x.msg
mkcatdefs x x.msg
runcat x x.msg
The preceding example is equivalent to the following example:
mkcatdefs x x.msg | gencat x.cat
If a message catalog with the name specified by the CatalogFile parameter exists, the gencat command modifies the catalog according to the statements in the message source files. If a message catalog does not exist, the gencat command creates a catalog file with the name specified by the CatalogFile parameter.
You can specify any number of message text source files. Multiple files are processed in the sequence you specify. Each successive source file modifies the catalog. If you do not specify a source file, the gencat command accepts message source data from standard input.
A message catalog can be virtually any size. The maximum numbers of sets in a catalog, messages in a catalog, and bytes in a message are defined in the /usr/include/limits.h file by the following macros:
$ file: hello.msg $set 1 prompts 1 Please, enter your name. 2 Hello, %s \n $ end of file: hello.msgTo create the hello.cat message catalog from the hello.msg source file, enter:
gencat hello.cat hello.msg
$ file: hello.msg $quote " $set PROMPTS PLEASE "Please, enter your name." HELLO "Hello, %s \n" $ end of file: hello.msgThe following is the text of the msgerrs.msg message source file that contains error messages that can be referenced by their symbolic IDs:
$ file: msgerrs.msg $quote " $set CAT_ERRORS MAXOPEN "Cannot open message catalog %s \n \ Maximum number of catalogs already open " NOT_EX "File %s not executable \n " $set MSG_ERRORS NOT_FOUND "Message %1$d, Set %2$d not found \n " $ end of file: msgerrs.msgTo process the hello.msg and msgerrs message source files, enter:
runcat hello hello.msg runcat msgerrs msgerrs.msg /usr/lib/nls/msg/$LANG/msgerrs.catThe runcat command invokes the mkcatdefs and gencat commands . The first call to the runcat command takes the hello.msg source file and uses the second parameter, hello , to produce the hello.ca t message catalog and the hello_msg.h definition file.
The hello_msg.h definition file contains symbolic names for the message catalog and symbolic IDs for the messages and sets. The symbolic name for the hello.cat message catalog is MF_HELLO . This name is produced automatically by the mkcatdefs command.
The second call to the runcat command takes the msgerrs.msg source file and uses the first parameter, msgerrs , to produce the msgerrs_msg.h definition file.
Since the third parameter, /usr/lib/nls/msg/$LANG/msgerrs.cat , is present, the runcat command uses this parameter for the catalog file name. This parameter is an absolute path name that specifies exactly where the runcat command must put the file. The symbolic name for the msgerrs.cat catalog is MF_MSGERRS .
The following commands allow you to display messages outside of an application program. These commands are specific to AIX.
dspcat | Displays the messages contained in the specified message catalog. The following example displays the messages located in the x.cat
message source file:
dspcat x.cat |
dspmsg | Displays a single message from a message catalog. The following example displays the message located in the x.cat
message source file that has the ID number of 1
and the set number of 2
:
dspmsg x.cat -s 2 1 You can use the dspmsg command in shell scripts when a message must be obtained from a message catalog. |
When programming with the Message Facility, you must include the following items in your application program:
The following subroutines provide the services necessary for displaying program messages with the message facility:
setlocale | Sets the locale. Specify the LC_ALL or LC_MESSAGES environment variable in the call to the setlocale subroutine for the preferred message catalog language. |
catopen | Opens a specified message catalog and returns a catalog descriptor, which you use to retrieve messages from the catalog. |
catgets | Retrieves a message from a catalog after a successful call to the catopen subroutine. |
printf | Converts, formats, and writes to the stdout (standard output) stream. |
catclose | Closes a specified message catalog. |
The following C program , hello , illustrates opening the hello.cat catalog with the catopen subroutine, retrieving messages from the catalog with the catgets subroutine, displaying the messages with the printf subroutine, and closing the catalog with the catclose subroutine.
/* program: hello */ #include <nl_types.h> #include <locale.h> nl_catd catd; main() { /* initialize the locale */ setlocale (LC_ALL, ""); /* open the catalog */ catd=catopen("hello.cat",NL_CAT_LOCALE); printf(catgets(catd,1,1,"Hello World!")); catclose(catd); /* close the catalog */ exit(0); }
In the previous example, the catopen subroutine refers to the hello.cat message catalog only by file name. Therefore, you must make sure that the NLSPATH environment variable is set correctly. If the message catalog is successfully opened by the catopen subroutine, the catgets subroutine returns a pointer to the specified message in the hello.cat catalog. If the message catalog is not found or the message does not exist in the catalog, the catgets subroutine returns the Hello World! default string.
The NLSPATH environment variable specifies the directories to search for message catalogs. The catopen subroutine searches these directories in the order specified when called to locate and open a message catalog. If the message catalog is not found, the message-retrieving routine returns the program-supplied default message. See the /etc/environment file for the NLSPATH default path.
All message-retrieving routines return the program-supplied default message text if the desired message cannot be retrieved for any reason. Program-supplied default messages are generally brief one-line messages that contain no message numbers in the text. Users who prefer these default messages can set the LC_MESSAGES category to the C locale or unset the NLSPATH environment variable. When none of the LC_ALL, LC_MESSAGES, or LANG environment variables are set, the LC_MESSAGES category defaults to the C locale.
Multilingual users may specify a language hierarchy for message text. To set the language hierarchy for the system default or for an individual user, see the chlang command, "Changing the Language Environment" in AIX Version 4.3 System Management Guide: Operating System and Devices or use the System Management Interface Tool (SMIT). To use SMIT to set the language hierarchy, enter the SMIT fast path
smit mlang
Select Change / Show Language Hierarchy
smit
Select Manage Language Environment
Select Change / Show Language Hierarchy
This example has three parts: the message source file, the command used to generate the message catalog file, and an example program using the message catalog.
$quote " $ every message catalog should have a beginning set number. $set MS_SET1 MSG1 "Hello world\n" MSG2 "Good Morning\n" ERRMSG1 "example: 1000.220 Read permission is denied for the file %s.\n" $set MS_SET2 MSG3 "Howdy\n"
runcat example example.msg
#include <locale.h> #include <nl_types.h> #include "example_msg.h" /*contains definitions for symbolic identifiers*/ main() { nl_catd catd; int error; (void)setlocale(LC_ALL, ""); catd = catopen(MF_EXAMPLE, NL_CAT_LOCALE); /* ** Get the message number 1 from the first set. */ printf( catgets(catd,MS_SET1,MSG1,"Hello world\n") ); /* ** Get the message number 1 from the second set. */ printf( catgets(catd, MS_SET2, MSG3,"Howdy\n") ); /* ** Display an error message. */ printf( catgets(catd, MS_SET1, ERRMSG1,"example: 100.220 Permission is denied to read the file %s.\n") , filename); catclose(catd); }
National Language Support Overview for Programming, Message Facility Overview for Programming, Creating a Message Source File, Creating a Message Catalog, List of National Language Support Subroutines.
Changing the Language Environment in AIX Version 4.3 System Management Guide: Operating System and Devices.
The chlang command, dspcat command, dspmsg command, gencat command, lslpp command, mkcatdefs command, runcat command.
The environment file.
The catclose subroutine, catgets subroutine, catopen subroutine, printf subroutine.