Message Compiler

  This page was last edited on July 03, 1996

Comments?

Introduction

This document describes the cognos message compiler (cogmc). Cogmc is a utility designed to help developers create message files for use with the services messaging APIs such as the message set objects. With this utility users can compile a message file, decompile a message file and generate symbolic message identifiers from a services message file.

It should be noted that cogmc uses the NLS subsystem of services for a number of locale related operations, and as a consequence users should ensure that the appropriate environment variables are set and that a valid coglangtab file is available for the proper operation of the NLS subsystem.

This version of the cognos message compiler is available in the R95a and later versions of services.

Usage

 

Win 32

Win16

UNIX

Hpxl

VMS

Executable cogmc.exe na cogmc na na

Topics

  1. Command-line syntax.
  2. Compiling a message file.
  3. Generating a header file.
  4. Decompiling a message file.
  5. Extracting cogmc strings.
  6. Language syntax.
  7. Retrieving Information About a Message File
  8. Example Message File
  9. Migration Tips

Command-Line Syntax

cogmc [mode] [options]
 
Where mode is one of:
-compile compiles from source.
-header generates a header file from a message file.
-decompile decompiles a message file.
-extract extracts internal strings (and keywords) used by cogmc
-syntax generates of the language syntax of message source files.
-about extracts version information from a message file.
 
Where options are one or more of:
-output filename, sets output filename for all modes.
-product_version major.minor.build, sets product version for -compile mode (e.g. 1.2.45)
-product "text", sets product descriptor text for -compile mode (e.g. "Axiant 4gl").
-services_version major.minor.build, sets services version for -compile mode (e.g. 4.1.23)
-services "text", sets services descriptor text for -compile mode (e.g. "Services r95a")
-language "text", sets language descriptor text for -compile mode (e.g. "English-Canadian")
-include directory, specifies path for source files for -compile mode.
-input filename, sets input filename for -compile, -header, -about and -decompile modes.
-character_set "character set name", specifies character set used in text files for all modes.
-verbose, forces the generation of verbose output messages for all modes.
-nocase, forces case-insensitive parsing of source file for -compile mode.
-command filename, specifies a text file from which to read command line parameters for all modes.

Compiling a Message File

The compile mode of cogmc is used to create a compiled message file from one or more source files written in an appropriate syntax. Compiling a message requires that at a minimum the -input, -output and -character_set command options be specified. The character set specification is used to identify the character set used in the input source files, so that cogmc can properly translate the message information to the Unicode character set used in the message files. The specified character set corresponds to a charmap entry in the coglangtab file or one of the predefined character sets ASCII or UNICODE.

The compiled message file is a binary file with all data stored in big-endian format for portability, so that for example, a message file compiled on Windows NT can be manipulated by the message compiler (or messaging API's) compiled on UNIX systems.

Message Construction

The message compiler will construct messages to have one of the two following forms depending upon the prefix specifier used to define the severity class in which the message is found. If the prefix specifier is used:

message text = "<COMPONENT NAME>-<SEVERITY TEXT>-<MESSAGE NAME>, Message text"

Where:

<COMPONENT NAME> is the name of the component defined with the name statement.
<SEVERITY TEXT> is the severity text string associated with a specific severity level via a severity statement.
<MESSAGE NAME> is the name of the message as defined in a message statement.
 
If the noprefix specifier is used, then the message prefix (with trailing comma and space) will be stripped from the message when it is retrieved from the message file at run time.

A typical use for messages generated by the message compiler is to act as format strings for language-independent messaging systems. To support this usage, the message compiler provides a simple mechanism for specifying substitutions within a message. The mechanism consists of a single substitution character which must be followed by a single digit (0-9). The specific character used to indicate a substitution sequence is user-definable via the use of the parameter statement of the message source language to make the substitution sequence language and character set independent. Regardless of the character specified in the source file, cogmc will insert a Unicode 0x0001 character in its place in the compiled message file. Thus, API's using cogmc generated message files should look for this character to determine the location in the string where substitutions should be made.

Message and Component Identifiers

Each message and component specified in the message source receive a unique numeric identifier to allow the retrieval of the text of a message without regard to the internal format of the message file. The use of unique message identifiers makes it possible to substitute alternate message files (and thus message text) without having to recompile an application. All identifiers are generated using a hashing function on the Unicode equivalent of the text of the symbolic name of a component or message using the cogStringHash() function of the string objects API. The use of identifiers based on names helps make the message system insensitive to the addition/deletion of messages, since the value of any identifier is independent of every other identifier. The message identifiers used by cogmc are 32-bit integer values constructed in the following manner:

Special Messages

A compiled message file contains extra information in addition to the messages specified in the source files. This information falls into three general categories: version, language and file integrity information. This information can be accessed in the form of strings by extracting one or more reserved messages from the messaging API. Each of these messages is an unadorned string containing only the text of the indicated information. Thus extracting the message MSG_INTERNAL_CRC will return a string of the form "0x1E4A". If the requested information is undefined the message defaults to an empty string, not a NULL pointer. The complete list of internal messages is given in the following table.

Message ID

Meaning

MSG_INTERNAL_FILE_LENGTH The file length information read from the message file header.
MSG_INTERNAL_CRC The cyclic-redundancy-code information read from the message file header (hex).
MSG_INTERNAL_LANGUAGE Language string specified with the -language option of cogmc.
MSG_INTERNAL_SERVICES_MAJOR Services major version id specified with the -services_version option of cogmc.
MSG_INTERNAL_SERVICES_MINOR Services minor version id specified with the -services_version option of cogmc
MSG_INTERNAL_SERVICES_BUILD Services build id specified with the -services_version option of cogmc.
MSG_INTERNAL_SERVICES_TEXT Services descriptor string specified with the -services option of cogmc.
MSG_INTERNAL_PRODUCT_MAJOR Product major version id specified with the -services_version option of cogmc.
MSG_INTERNAL_PRODUCT_MINOR Product minor version id specified with the -services_version option of cogmc.
MSG_INTERNAL_PRODUCT_BUILD Product build id specified with the -services_version option of cogmc.
MSG_INTERNAL_PRODUCT_TEXT Product descriptor string specified with the -services option of cogmc.
MSG_INTERNAL_MESSAGE_COUNT Number of messages in the message file.
MSG_INTERNAL_FILE_NAME Name of the message file (fully qualified path name).

Examples

The ASCII message source text in example.str can be compiled to the message file example.msg with the following command line:

cogmc -compile -input example.str -output example.msg -character_set ASCII services_version 5.1.30 -services "Connectivity Services Version R95a" -language English
 
alternatively, we could place the command line parameters into the file example.mc and use the following command:
 
cogmc -command example.mc
 
where example.mc contains the following text:
-compile
-input example.str
-output example.msg
-character_set ASCII
services_version 5.1.30
 
-services "Connectivity Services version R95a"
-language English

Generating a Header File

The header mode of cogmc is used to generate C/C++ compatible symbolic identifiers for each of the messages defined in a message file. In order to generate a header file the -input, -output and -character_set command options must also be specified on the cogmc command line.

The symbolic names are derived from the component and message name information of the message source compiled by cogmc. The general form of a symbolic name is the following:

message symbolic name = <COMPONENT PREFIX>-'MSG'-<MESSAGE NAME>

Where:

<COMPONENT PREFIX> is a string defined with the prefix statement for the component in which the message is found.
<MESSAGE NAME> is the name of the message as defined in a message statement.

In addition, symbols for each component are also defined as follows:

component symbolic name = <COMPONENT NAME>

Where:

<COMPONENT NAME> is the name of the component defined with the component statement.

Example

An C/C++ header file can be extracted from the example message file with the following command:

cogmc -header -input example.msg -output example.h -character_set ASCII

Where message.h will contain the following text:

#ifndef MC_HEADER_31911
define MC_HEADER_31911
#ifdef __cplusplus
extern "C" {
#endif
#define MSGCOMPILER 0x24
#define MC_MSG_FLAG_COMPILE 0x2437D576
#define MC_MSG_SYNTAX_ERROR 0x243031D4
...
#ifdef __cplusplus
}
#endif
#endif

Decompiling a Message File

The decompile mode of cogmc is provided to allow developers to generate user-editable source from an existing compiled message file. To use this mode, the user must specify at a minimum, the -input, -output and character_set options. The generated source code can be recompiled to recreate the initial or modified message file if so desired. This facility is useful if messages need to be modified, added to or removed from an existing message file when the original message source is not available.

Example

Two existing message files exampleA.msg and exampleB.msg can be merged with the following sequence of commands:

cogmc -decompile -input exampleA.msg -output exampleA.str -character_set ASCII

cogmc -decompile -input exampleB.msg -output exampleB.str -character_set ASCII

Now add the following line to exampleA.str:

include exampleB.str

Now create the merged message file by recompiling exampleA.str.

cogmc -compile -input exampleA.str -output mergeAB.msg -character_set ASCII


Extracting cogmc Strings

The extract mode is provided to aid in the translation of the message compiler language and message to other locales, character sets and languages. The default strings used in the message compiler are 7-bit ASCII encoded English, all of which can be dumped into a compilable source file via the -extract mode of cogmc. Translators can then use this source file as a basis for generating an alternate language/locale version of cogmc by translating the content of the extracted source file to the target language.

Users can then force the message compiler to bypass its default string information and use a message file by one of the following:

  1. set the COGMCMSGS entry of the "Cognos Locations" section of cognos.ini to indicate the name/path of the new message file (Windows only).
  2. set the COGMCMSGS environment variable to indicate the name/path of the new message file.
  3. rename the message file to COGMCMSGS and place it in the directory from which cogmc will be run.

Example

A Unicode text file containing the message source equivalent to the default messages of cogmc can be created with the following command:

cogmc -extract -output cogmc.str -character_set UNICODE


Retrieving Information About a Message File

The -about mode of the message compiler is used to extract version, file integrity and statistical information about the specified message file. The information retreived is simply the results of extracting the special informational messages from the specified message file. The main uses of this command is to gather information about a message file for installation purposes and to provide a way of verifying that the specified is or is not a valid message file. For example:

cogmc -about -input possiblyvalid.msg


Language Syntax

The following is the EBNF specification of the syntax of the message source text accepted by cogmc.

<str-file> ::= [<statement>...]
<statement> ::= {<component> | <name> | <prefix> | <category> | <include> | <parameter> | <comment> | <message> | <severity>}
<component> ::= COMPONENT <identifier>
<name> ::= NAME <identifier>
<prefix> ::= PREFIX <identifier>
<category> ::= CATEGORY <identifier>
<include> ::= INCLUDE <identifier>
<parameter> ::= PARAMETER <identifier>
<comment> ::= /* [character | whitespace]... */
<severity> ::= SEVERITY <identifier> <number> <severity text> { PREFIX | NOPREFIX}
<message> ::= <identifier> <string>
<string> ::= " {character | digit | whitespace} ... "
<number> ::= {digit} ...
<identifier>::= {character | digit} ...

Notes:

  1. Up to 254 distinct components can be defined per message file (COMPONENT statement).
  2. Up to 524288 distinct messages can be defined per component (MESSAGE statement).
  3. Up to 16 distinct severity levels can be defined per message file (SEVERITY/CATEGORY statements).

Component Statement

The component statement is used to signify that subsequent message definitions are to be associated with the indicated component. This association will continue until another component statement is reached. The component statement consists of the component keyword followed by a single token indicating the name of the component. For example:

component MSG_COMPILER

Name Statement

The name statement is used to associate a short form name with the current component. This name will be used in the message prefix generated by cogmc when compiling a message file. Only one name statement is allowed per component. The name statement consists of the name keyword followed by a single token indicating the short form name of the current component. For example:

name MC

Prefix Statement

The prefix statement is used to indicate the component prefix used to create symbolic identifiers for messages by cogmc when generating header files. Only one prefix statement is allowed per component. The prefix statement consists of the prefix keyword followed by a single token indicating the prefix code for the current component. For example:

prefix MC

Category Statement

The category statement is used to indicate the severity category to associate with subsequent message definitions. This association will continue until another category or severity statement is reached. Any number of category statements are allowed per component/file. The category statement consists of the category keyword followed by a single token indicating the name of a severity level. Severity levels can referenced before their definition via the severity command. For example:

category error

Include Statement

The include statement is used to specify a source file to be inserted into the input stream at the point where the include statement occurs. This facility allows developers to group messages into separate files as necessary. Any number of include statements may occur in a file and they can be nested as deeply as the memory constraints of the host system will allow.

The surest way to force cogmc to run out of memory is to have an include file recursively include itself! So don't do that.

The include statement consists of the include keyword followed by a single token indicating the name of the file to include. Cogmc will search for the include file in the working directory and then in the directories specified with -include options on the cogmc command line. The message compiler assembles the file specification by appending the indicated filename with each include specification in order to generate a complete file/path specification. For portability, it is best not to include directory information in the filename specified in the include statement, rather use the base file name in the source file and select the directory using the -include command line options.

For example, while both of the following examples of the include statement are valid under MS-DOS, the later is also portable to UNIX:

include ..\msgs\english.str
and compile with
cogmc -compile ...

and

include english.str
and compile with
cogmc -compile -include ../msgs/ ...

Parameter Statement

The parameter statement is used to specify which character is to be to indicate where substitutions are to be applied in subsequent messages. This specification will be valid until another parameter statement is reached. Any number of parameter statements are allowed per component/file. The parameter statement consists of the parameter keyword followed by a single character indicating the substitution character. For example:

parameter %

Severity Statement

<severity> ::= SEVERITY <identifier> <number> <severity text> { PREFIX | NOPREFIX}

The severity statement is used to define a severity category for use with subsequent category statements. It also has the side effect of setting the current message category to the newly defined severity. The severity statement consists of the severity keyword followed by the symbolic name to be assigned to the severity (i.e. error, fatal, warning), a numeric severity level (in the range 0 to 15), a severity code to used when generating message prefixes (i.e. E, F or W) and an prefix/noprefix specification which determines if a generated message prefix is to be prepended to the text of messages in the indicated severity category. Only sixteen severity categories can be defined per message file. Severity codes cannot have multiple definitions. For example:

severity error 14 E prefix

Message Definition

A message definition is assumed to be in progress when a token is encountered at the beginning of a statement that is not one of: component, name, prefix, category, include, parameter, comment, message, severity or /*. The syntax of a message definition is quite simple: an identifier followed by a quoted string. The identifier is interpreted as the message name while the quoted string is taken to be the text of the message being defined. Each message within a component must have a unique name (actually, a unique hash identifier, see -compile). For example:

file_error_message "Invalid file: ^1. Load operation aborted"

Comments

Comments are similar in use and syntax to standard C style comments, beginning with /* and ending with */. There is however, an added restriction not found in the C language; comments are not allowed within the body of any statement - only before or after a statement. The following examples are valid uses of comments:

/* this is a good place for a comment */
parameter % /* so is this !*/
/* this is
good too */ include yetanother.file

The following are examples of invalid comments.

parameter /* uh-oh! */ %
include /* this won't work */ afile.str
 

Example Message File

The following is an example of a valid message source file.

SEVERITY FLAG 3 F NOPREFIX
SEVERITY ERROR 3 E PREFIX
 
COMPONENT MSGCOMPILER
NAME MC
PREFIX MC
 
PARAMETER ^
CATEGORY FLAG
FLAG_COMPILE "-compile"
 
CATEGORY ERROR
SYNTAX_ERROR "^1: syntax error in file <^2> at or near line ^3:"
/*
* include some more message info
*/
include othermsgs.str

Migration Tips

The source language used by Cogmc is sufficiently different from that used in previous message systems that some minor changes will be necessary to enable existing message source files to be used with the newer compiler. The changes fall into three categories; obsolete statements, new required statements and language enhancements.

Obsolete Statements

The previous messaging system allowed two ways of specifying comments in a source files, C style comments and OS400 style curly-braces; { and }. Since cogmc does not support the OS400 style comments, the affected comments must either be removed or the { and } keywords must be replaced with /* and */ respectively.

As the message compiler now generates unique identifiers using a hashing algorithm, the base keyword is no longer used. Simply remove all base statements from the message source files.

New Required Statements

The only new statement that is required to ensure proper compilation is the severity statement. This statement was added to the language to remove the implicit English/ASCII locale of the category statements used in previous message systems. The only remedy is to add the appropriate severity statements to your message source.

Language Enhancements

The major enhancement to the message language introduced with cogmc is the include statement. Previous message systems relied on external preprocessors (such as cpp) to merge include files for later processing by a message compiler. Any include statements in message source files will have to be modified in accordance with the new syntax.