Creating Portable Programs | National Language Support (NLS) Demonstration |
This chapter describes the internationalization support provided by Server Express.
Server Express offers several levels of internationalization support:
NLS provides a means of adapting your program to the character code set, collating sequence, and editing symbols associated with a particular country, without your program knowing these in advance. This facility is also useful in English-speaking countries for handling codepages, collating upper-case and lower-case letters correctly and selecting the appropriate currency symbol.
Examples of language and character sets that NLS accommodates are:
ISO646 National Variants: | French, German, Swedish, Danish, Italian, Spanish, Portuguese |
ISO8859/1: | West European languages |
IBM Personal Computer 8-bit Character Set: | West European languages |
When you run a program compiled with the NLS directive, it behaves according to the language, country and character set specified in the language environment variable.
DBCS support enables you to create native language applications that use double-byte character strings, for countries such as Japan, China and Korea.
Server Express includes some support for handling double-byte characters. A fully DBCS-enabled and localized version of Server Express is available in Japan.
You can create DBCS applications using existing tools and syntax, such as ACCEPT/DISPLAY with PIC X. However, Server Express also supports additional COBOL syntax used in DBCS environments. This syntax is described in your Language Reference - Additional Topics. To enable this support, use the DBCS, NCHAR or JAPANESE Compiler directive.
The library routine CBL_GET_OS_INFO enables your application to detect the character encoding for Far Eastern countries. See the chapter Library Routines.
DBCS transparency support is available in Object COBOL on many platforms. See the on-disk document on DBCS support for full details.
DBCS transparency support enables users of your applications to enter, store, manipulate, display and print single-byte and double-byte character strings in their native language. In addition, you can use tools such as Animator, Editor and Screens to create and maintain application programs that support your native language.
Editing operations such as backspace, delete and insert, as well as cursor movement, are by byte and not by character. For example, a delete operation needs two keystrokes to delete both bytes of a DBCS character. After the deletion of the first byte (half a DBCS character) the remaining characters may appear corrupted, but if you press the delete key a second time the other byte of the character is deleted with no corruption at all.
However, with some tools and on some terminal environments, editing operations and cursor movement are by DBCS character and not by single bytes.
DBCS transparency support is restricted in the following tools, which are described in your Utilities Handbook.
The routines CBL_GET_SCR_LINE_DRAW and CBL_GET_SCR_GRAPHICS support the line draw and graphics characters used in all the environments supported by Object COBOL. See the chapter Generic Line Drawing in your Programmer's Guide to Creating User Interfaces.
Some demonstration programs supplied with this system contain IBM PC encoded line draw characters. Under some environments, you need to amend these characters in the COBOL source before using these programs.
Object COBOL supports the following items, which you can use in DBCS applications in addition to the standard PIC X support:
Note: When performing a Format 4 or Format 5 ACCEPT statement into an identifier of class DBCS, you must enter double-byte data only. See the chapter Double-Byte Character Set Support in your Language Reference - Additional Topics.
Object COBOL provides the CHARSET Compiler directive and the _CODESET program for converting between ASCII and EBCDIC. It also provides some preconfigured _CODESET programs supporting ASCII and EBCDIC codepages for several Far Eastern languages and German.
To use NLS or DBCS transparency support:
Server Express relies on UNIX to provide the appropriate national language tables for the language, country and character set that you specified. These are known as locales.
Before you run a program that uses NLS or that uses DBCS support on UNIX, you must define your locale in the language environment variable. The locale is the combination of language, territory and codepage.
The locale might already be defined for you. If it is not, you define it as follows:
LANG=language[_territory[.codepage]] export LANG
where the parameters are:
Refer to your operating system documentation for valid territory
and codepage
values.
The following example on SCO UNIX or AIX specifies the the language as French, the territory as France, and uses the the ISO 8859-1 codeset:
LANG=fr_FR export LANG
To use the NLS facility in your program, you must specify the NLS Compiler directive when you compile your program. By default, the NLS directive is not set. Throughout the rest of this chapter, a program compiled using the NLS directive is referred to as NLS-enabled.
You must not use the following syntax in an NLS-enabled program:
PROGRAM COLLATING SEQUENCE IS alphabet-name
alphabet-name IS
STANDARD-1
NATIONAL
literal-1 THRU literal-2
CURRENCY SIGN IS literal
DECIMAL-POINT IS COMMA
COLLATING SEQUENCE IS alphabet-name.
You can NLS-enable any program in your application. Thus some programs within an application might use NLS facilities, while others might not. See the section Mixing Programs with and without NLS later in this chapter for details.
You run NLS-enabled programs in the same way as you run programs without it.
The run-time system initializes the NLS facility only once during an application's run; that is, when it encounters the first NLS-enabled program. It uses the LANG environment variable to determine the language environment to set up for this program. The run-time system uses the same language environment for any subsequent programs that areNLS-enabled. See the section Mixing NLS-enabled and Non-NLS-enabled Programs later in this chapter for details.
If an error occurs during initialization, for example the language specified in the LANG environment variable is not supported, the run-time system issues an error message and terminates its run. Full details on NLS error messages are in your Error Messages.
You must not use indexed files with variable length records when the NLS directive is set.
You cannot use indexed files created with one collating sequence in a file language environment that uses a different collating sequence. If you do and you specified file status bytes in your program, the COBOL system returns the file status 9/45. If you did not specify file status bytes in your program, the run-time system issues an error message.
When you run an NLS-enabled program, the language specified in the LANG environment variable defines the behavior of:
Other language-dependent features, such as the symbols used to denote the decimal points and the currency character , also appear in the format of the specified language. However, in languages that define the currency sign as trailing, this has no effect and the usual COBOL rules are observed.
Certain NLS definitions have characters other than the ASCII characters 0-9 defined as numerics. You cannot use the ACCEPT syntax to enter such characters into numeric picture strings, nor can they be used in numeric operations. In all NLS operations in the COBOL environment, a numeric item must be formed only from the ASCII digits 0-9, with or without the ASCII operational signs "+" or "-". There is no means of automatically converting the NLS representation to the ASCII equivalent.
It is possible to enter European modifying characters into numeric ACCEPT fields. These are accepted as zero.
The values assigned to figurative constants, for example LOW-VALUES, are not changed by using NLS features.
Unpredictable results occur in the following circumstances when you use the NLS facility:
You can also use the Adis Flip Case Control key when using NLS characters. However, if you attempt to convert a European character to upper case using this key, the character will be replaced by spaces if it has no upper case equivalent.
See your Server Express User's Guide for full details on running programs.
For NLS-enabled programs, the run-time system invokes the CBL_NLS_COMPARE routine to compare strings. This routine is also called for alphanumeric comparisons if the program uses the intrinsic functions Max, Min, Ord-max or Ord-min on alphanumeric operands.
During a MOVE operation of one alphanumeric item to another which is longer, padding with spaces occurs. Similar padding is also implied before the comparison of two such items. In both cases, an ASCII space is assumed.
For NLS-enabled programs, the run-time system invokes locale-specific tests when it needs to carry out class condition tests. These tests determine if a string of information is in ALPHABETIC, ALPHABETIC-UPPER, ALPHABETIC-LOWER or NUMERIC format. The numeric test always tests that all characters are in the range of ASCII 0-9.
The run-time system uses the CBL_NLS_COMPARE routine for key comparisons associated with NLS files.
If the logical filename of an indexed sequential file is preceded by the five characters "%NLS%", the file is treated as being keyed according to the collating sequence specified in the LANG environment variable. This applies whether "%NLS%" precedes the logical filename before the filename is resolved using environment variables or after it is resolved. This also applies only if the program that OPENs the file was compiled with the NLS directive set.
If the logical filename is preceded by "%NLS%" after it is resolved using environment variables, but the program that OPENs the file was compiled without the NLS directive set, the OPEN fails and returns a run-time system error.
If your file contains variable length records, the NLS collating sequence is not used.
For details on assigning logical filenames to be resolved using environment variables, see the Filenames chapter in your File Handling.
If an NLS-enabled program performs a SORT or MERGE operation, it automatically uses NLS key comparisons.
The logical filename of the work file must be preceded by the characters "%NLS%" in the ASSIGN statement, and the program that opens it must be NLS-enabled. This is as described in the previous section for indexed sequential files.
The run-time system invokes the CBL_NLS_COMPARE routine for all key comparisons used in SORT or MERGE operations.
If an NLS-enabled program performs a case conversion, either by using the intrinsic functions Upper-case and Lower-case, or by calling the library routines CBL_TOUPPER and CBL_TOLOWER, the run-time system invokes a routine to change the case of national characters correctly.
For NLS-enabled programs, a collating sequence appropriate to the locale is used. If the program performs a collating sequence operation by using the intrinsic functions Char and Ord, then this special collating sequence is used.
If an NLS-enabled program performs an editing or de-editing move, then the decimal point and thousands separator appropriate to the national language locale are used. Also, the currency symbol used is the first character of the currency symbol of the locale territory.
If an NLS-enabled program attempts to convert a number or a monetary value in a display item to a numeric value by using the intrinsic functions Numval or Numval-c, then the run-time system uses the decimal point and thousands separator appropriate to the locale. Also, if no second argument is supplied for Numval-c, then the currency symbol used is the currency symbol of the locale territory.
If you require information concerning the language environment you are using, you can access the NLS library routines supported by your COBOL system. Details on all of these routines can be found later in this chapter.
You also can access the UNIX operating system routines, such as nl_langinfo(), though these routines are not portable to other environments. Full details on these routines can be found in your operating system documentation.
If an application comprises more than one program, you only need to set the NLS Compiler directive for those programs that you want to be NLS-enabled. Both NLS-enabled programs and non-NLS-enabled can call programs NLS-enabled and non-NLS-enabled programs.
An NLS-enabled program has no particular language or locale associated with it. It uses the application locale, which is initialized along with the NLS facility when the first NLS-enabled program in the application is called.
Once the application locale is set, it is used for all subsequently called NLS-enabled programs. You cannot change the language environment after this, even if you change the setting of the LANG environment variable. You must therefore ensure that all NLS-enabled programs use the same language.
The library routines for NLS can be called from any NLS-enabled program. Programs in the application that are not NLS-enabled can also call these routines, but only after the National Language Support module has been loaded and initialized by calling an NLS-enabled program.
You can pass parameters from an NLS-enabled program to a non-NLS-enabled program. However, parameters that depend on the language environment in which they are created retain their format regardless of the language environment in which they are used. If you attempt to use a parameter created in an NLS-enabled program in a non-NLS-enabled program, the result might not be as you expect. We recommend that you do not attempt to pass such parameters to programs other than those that have the same language environment.
You can output messages in the user's language. You provide the messages in message catalogs and access them using the NLS library routines, such as CBL_NLS_READ_MSG. The user chooses the language in which they want messages by setting the $LC_MESSAGES or $LANG environment variables at run-time.
The UNIX system expects messages to be stored in message catalogs. To create a message catalog, you create a source message file containing your messages, and then compile it using the gencat command.
A message file consists of lines of text, and is named filename.src. Each line can have the following format:
$ comment |
A line beginning with a dollar followed by a space (or tab) is treated as a comment |
$set n |
Specifies a set of messages, and assigns a set number n. Subsequent lines containing messages belong to this set, until the next line starting with $set. Set numbers must be in ascending order, but need not be contiguous. If you do not specify a $set, a default set is used. This default set is implementation defined and is not guaranteed to be 1 (or any other number). |
$quote c |
Specifies an optional quotation character, c, which you can use to surround the message text so that trailing spaces or null messages are visible. By default, or if the $quote directive is empty, any quotes are ignored. |
m message-text |
The message-text is stored in the message catalog with the set number specified in the last $set statement, and with message number m. Message numbers must be in ascending order within a single set, but need not be contiguous. |
Blank | Blank lines are ignored. |
For example, the message file errmsg.src could contain the following:
$quote " $ $set 1 1 "Too small a starting balance to open this type of account" 2 "This debit exceeds overdraft limit" 3 "This debit overdraws account" $ ***********************************************************
To create a UNIX message catalog from this file you use the UNIX gencat command. For example:
gencat -m errmsg.lng errmsg.src
where errmsg.src is the source message file, and errmsg.lng is the file that will contain the compiled message catalog.
Note: The -m flag of gencat is not required on some UNIX platforms, but you should always try the above command first. For detailed information on the gencat command, see the gencat manpage.
You need to set the $NLSPATH environment variable to point to your compiled message catalogues. For example:
export NLSPATH=`pwd`/%N:$NLSPATH
%N
is replaced by the message filename at run time.
If you have several versions of the message file (for example, English and French), you should put them in subdirectories using the locale name for the subdirectory names. For example, to create English and French versions of a message file:
mkdir msgs mkdir msgs/en_GB msgs/en_US msgs/C msg/fr_FR gencat -m errmsg.lng errmsg.src ln errmsg.lng msgs/en_GB ln errmsg.lng msgs/en_US ln errmsg.lng msgs/en_C rm -f errmsg.lng gencat -m errmsg.lng errmsg.src.fr mv errmsg.lng msgs/en_FR
You then need to set $NLSPATH:
export NLSPATH=`pwd`/msgs/%L/%N:$NLSPATH
%L
is replaced by the locale name (that is, the value of
$LANG) and %N
is replaced by the message filename at run
time.
The following library routines are available to help you write programs supporting NLS:
CBL_NLS_CLOSE_MSG_FILE | Close NLS message file |
CBL_NLS_COMPARE | Compare two strings |
CBL_NLS_INFO | Get/set national information |
CBL_NLS_OPEN_MSG_FILE | Open NLS message file |
CBL_NLS_READ_MSG | Read message from message file |
These routines can be called only from a program compiled with the NLS directive.
Normally you use data that is in ASCII format, although with Server Express you can also use data that is in EBCDIC format. Storing data in EBCDIC format enhances the testing of programs targeted to run on the mainframe and eases data exchange between the mainframe and your system.
If you want to use EBCDIC data on your system, make sure your programs are in ASCII format, and then compile them with the CHARSET(EBCDIC) directive. You can then use the resulting compiled programs with unconverted data files.
By default, Server Express supports ASCII/EBCDIC conversions of a standard US codepage based on PC codepage 437. Additional preconfigured modules are available for converting various Far Eastern languages and German. To convert EBCDIC correctly in these environments, you need to replace the default module with the preconfigured module for the relevant character set.
You can convert your data between the ASCII and EBCDIC character sets by using the CHARSET directive. Compile your program with the CHARSET directive as follows:
CHARSET "character-set"
Where character-set
is ASCII or EBCDIC.
The CHARSET directive also sets the related directives NATIVE and SIGN. If you have CHARSET(EBCDIC) set, you also have the behavior of SIGN(EBCDIC) and NATIVE(EBCDIC).
Both the called and the calling programs must be compiled with the same setting for the CHARSET directive.
Compiling with the EBCDIC option results in a Data Division that looks exactly the same as it would when compiling with a mainframe compiler running in an EBCDIC environment. This means that DISPLAY type values are in EBCDIC, and COMP values are binary fields, as normal. Similarly, any alphanumeric literal in the Procedure Division (for example, MOVE "HELLO" TO FRED or MOVE ALL "X" TO FRED) is in EBCDIC. The procedural code expects all DISPLAY type data, including numeric data, to be in EBCDIC.
When reading a file, if portions of the record represent characters while other portions are binary, it is necessary to have a suitable record definition in the COBOL program, just as it is on the mainframe. The intention is that data accessible to the user (such as file records and Working-Storage) should always appear exactly as on the mainframe.
The only concessions to an ASCII environment when using the EBCDIC support are as follows:
call data-name
or:
assign to data-name (a Micro Focus extension)
ASCII and EBCDIC are limited in the following ways:
The collating sequences for ASCII and EBCDIC are different. If you convert from EBCDIC to ASCII, comparisons might no longer give the same results. ASCII numerics and upper and lower case orderings are different from EBCDIC. For example, the ASCII numbers (hexadecimal 30 to 39) come before uppercase letters (hexadecimal 41 to 5A), followed by lower-case letters (hexadecimal 61 to 7A).
EBCDIC lower-case letters sort first (hexadecimal 81 to 89, 91 to 99, A2 to A9), followed by uppercase letters (hexadecimal C1 to C9, D1 to D9, E2 to E9), followed by numbers (hexadecimal F0 to F9). EBCDIC has special characters throughout the range.
For example, in the following code, the results are different, depending on whether you are executing in an ASCII or EBCDIC environment.
data division working-storage section. 01 item-1 pic x value"a". 01 item-2 pic x value"a". ... procedure division ... if item-1 < item-2 display "ASCII" else display "EBCDIC" end-if
When a program collating sequence is in effect, alphanumeric comparisons (including group comparisons) that contain numeric data are likely to produce meaningless results.
Without an EBCDIC collating sequence, field-a is less than field-b. With an EBCDIC collating sequence, however, the x"4F" is mapped onto the EBCDIC "O", which is x"D6". The underscore character, x"5F", is mapped onto the EBCDIC character x"6D". With the NATIVE(EBCDIC) Compiler directive, field-a is greater than field-b.
Some of the areas affected by using different collating sequences are IF statements, SORT statements, writing data to indexed files, and any areas where you assume data to contain the EBCDIC hexadecimal values (for example, assuming space = X"40").
For normal applications, you use the CHARSET directive to convert ASCII and EBCDIC. However, under some circumstances, you might want to call the _CODESET program yourself to convert them.
To invoke the _CODESET program, use the following command line:
call "_CODESET" using function-code, text-length, text-string
function-code |
pic 9(2) comp-x. |
text-length |
pic 9(9) comp-x. |
text-string |
pic x(n). |
function-code |
A function code that specifies the type of conversion:
|
||||||||||||
text-length |
Length of text-string. | ||||||||||||
text-string |
Text-string to convert. |
text-string |
Converted text. |
The _CODESET program cannot work from a program that is compiled with the reserved word directives for one of the mainframe COBOL compilers (for example, OSVS for OS/VS COBOL and VSC2 for VS COBOL II) because it uses COMP-X data types, which are not supported on the mainframe.
Use the _CODESET program for converting single-byte data only, using a
function-code
of 0 or 1
The Codecomp utility enables you to reconfigure the _CODESET program for single-byte characters.
_CODESET operates by calling a program that contains the mapping configuration. This program has the name CSnnnn.ext, where nnnn is a numeric identifier, and ext indicates the type of executable. You can create your own CSnnnn.ext files and specify that mapping information should be obtained from them. You specify which files to use using the MFCODESET environment variable. The steps required are:
The Codecomp utility:
You can use the Codecomp utility to create mapping files of the currently used EBCDIC to ASCII translation scheme. The mapping files created are based on the current setting of the MFCODESET environment variable. To create the mapping files, enter:
codecomp -p filename-1 [filename-2]
where the parameters are:
-p |
Specifies that the current mapping tables are to be output to file. |
name-1, name-2 |
The names of the mapping files to receive the current configuration. Filename extensions specify which file contains which mapping table.Give one of these files the extension .a2e for ASCII to EBCDIC mapping, the other .e2a for EBCDIC to ASCII mapping. |
If you do not specify at least one file, an error is returned. All command-line errors result in a help message specifying the correct format for the command-line.
You can use the Codecomp utility to specify new translation schemes. To do this, enter:
codecomp name-1 [name-2]
where the parameters are:
name-1, name-2 |
The mapping files containing the mapping configuration. Filename extensions specify which file contains which mapping table. Give the file that contains the ASCII to EBCDIC mapping the extension .a2e. Give the file that contains the EBCDIC to ASCII mapping the .e2a extension. If you specify only one file, the inverse of the table in this file is implicitly taken as the second table. In this case, the second column of the table in the single input file must contain all values from 0 to 255. |
If you do not specify at least one file, an error is returned. All command-line errors result in a help message specifying the correct format for the command-line.
The result of using this command is a copyfile called codeset.cpy that contains the required EBCDIC to ASCII translations. This .cpy file is used by the CSnnnn.ext file. You create a CSnnnn.ext file for a specific locale. For example, to create a translation table for country X, you could create a file called CS2001.cbl, and compile it.
A template translation file is supplied by MERANT; this is called CSnnnn.cbl, and can be found in the directory $COBDIR/src/codeset. To create your own translation tables, you:
cp $COBDIR/src/codeset/CSnnnn.cbl CS2001.cbl
cob -u CS2001.cbl
This creates the file CS2001.gnt.
You can then specify which translation tables to use through the MFCODESET environment variable. This has the format:
MFCODESET=nnnn
where nnnn is a value from 2000 to 9999. Values below 2000 are reserved for MERANT use.
MFCODESET directs _CODESET to call the program that contains the correct mapping tables. For example, if you have created the file CS2001.gnt and copied it to $COBDIR/dynload, then:
MFCODESET=2001
would direct _CODESET to use the translation tables in the executable CS2001.gnt
The format for a mapping file is as follows:
$ identifying-string ; date/time 00 corresponding-value 01 .... 02 .... . .... . ....
When creating or editing a mapping file, follow these rules:
identifying-string
is mandatory and is denoted
by the dollar sign ($) as the first non-space on the line and should be
the first non-comment line in the file. Failure to conform to this
causes an error, and Codecomp terminates with no change to _CODESET. The following mappings are valid:
1:1 | legal |
many:1 | legal only if 2 input files specified |
1:many | illegal |
many:many | illegal |
To configure the _CODESET program to use different translation tables:
codecomp -p map.a2e map.e2a
where the current mappings from ASCII to EBCDIC are in map.a2e and EBCDIC to ASCII in map.e2a.
codecomp map.a2e map.e2a
cp $COBDIR/src/codeset/CSnnnn.cbl CS2001.cbl
cob -u CS2001.gnt
MFCODESET=2001
You can manually reconfigure the _CODESET program for single-byte characters, by amending and recompiling the source file and building the new module into the COBOL system.
The source and copyfile are provided in the src subdirectory within your COBOL system directory. You change the 256-byte conversion tables in the source. When amending these conversion tables, you must use the binary value of the source character + 1 to index into the table. The character at this index point is the target character.
When you have modified the _CODESET source, you need to recompile it, create an executable version in some form, and package the executable version appropriately. Do this in the same way as if you had used the Codecomp utility to modify _CODESET.
Copyright © 2000 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names
used herein are protected by international law.
Creating Portable Programs | National Language Support (NLS) Demonstration |