Control Language (CL) is the most important programming language on the i5 server, because every i5 must have it. CL is an integral part of the operating system, and it is the way you control the system. CL was born with the S/38s operating system, CPF. Since CPF Release 1.0, CL has undergone a series of improvements that continue to the present day.
CL is comprised of commands, and commands are comprised of a command name and a list of parameters. Therefore, CL has a particular look that is not shared by other programming languages. For example, the addition of numeric variables A, B, and C (storing the result in R) would be expressed in a language like C as follows:
r = a + b + c;
CL expresses the same statement in a form that looks entirely different at first sight:
CHGVAR VAR(&R) VALUE(&A + &B + &C)
The name of the command is Change Variable (CHGVAR) and it has two parameters, which have keywords (names) VAR and VALUE. The value of the VAR parameter is &R, which is a variable. The value of the VALUE parameter is the expression &A + &B + &C.
CL commands can be written into a source file member (source type CLLE or CLP) and the member compiled into a program using the Create Bound Control Language Program (CRTBNDCL) or Create Control Language Program (CRTCLPGM) command.
You can use CL whenever you need your program to start a system activity through a command. For example, you could create a CL program that would present a menu to the user. When the user selects the option marked "start printer," the CL program would run the Start Printer Writer (STRPRTWTR) or the Release Writer (RLSWTR) commands.
Most of the commands available in i5/OS can be executed from within an RPG program by using the application programming interface, Command Execute, QCMDEXC. However, commands that return data will not return data through the API.
You can write CL programs that execute almost every one of the commands available in i5/OS. Along with some rudimentary program flow control commands, a CL program can automate the operation of your system by eliminating the need for you to execute commands manually.
CL should not be used for regular data processing activitiessuch as report generation and file processing because it's not suited for those sorts of tasks. CL is somewhat slower than other languages, such as RPG or COBOL, and it provides only the most rudimentary support to process database files. CL can only read from database files.
All CL programs have the same general outline:
The Program (PGM) command at the very top of the program. The PGM command marks the beginning of the program. If any parameters are to be received by this program, they are listed in the PARM parameter.
A series of Declare (DCL) commands to define all the variables used in the program. All variables must be declared before the program does anything else. Consequently, all DCL commands must be grouped together right after the PGM command. If the CL program uses any files, they must be declared here as well, using the Declare File (DCLF) command. Up to five files may be declared within each CL program.
An optional, global error trap using the Monitor Message (MONMSG) command. This is described in more detail later.
The body of the program, which executes whatever commands are necessary to perform the task you have in mind. You can insert program flow control commands to alter the order in which the commands are executed. Program flow control commands are described later.
The End Program (ENDPGM) command to mark the end of the program.
CL supports three types of variables: character, decimal, and logical.
Character variables are declared using TYPE(*CHAR). They can have any length between 1 and 32,767 characters. They can be given any value at all, including hexadecimal values such as X‘01’.
Decimal variables are declared using TYPE(*DEC). They can have any length between 1 and 15 digits and have between 0 and 9 decimal positions. They can contain any numeric value that falls within those limits, whether it is positive, zero, or negative.
Logical variables are declared using TYPE(*LGL). They are always 1-byte long, and can only have two values: true (‘1’) or false (‘0’).
Integer variables contain signed binary values and are declared using TYPE(*INT). The length must be 2 or 4, which indicates the number of bytes allocated to the variable, not the number of numeric digits of allowable values.
Unsigned integer variables contain unsigned binary values and are declared using TYPE(*INT). The length must be 2 or 4, which indicates the number of bytes allocated to the variable, not the number of numeric digits of allowable values.
All variable names must begin with an ampersand (&). The ampersand is what makes the rest of the name a variable.
The rest of the name must conform to the following rules:
The first character must be a letter (A to Z) or the characters @, #, or $.
Following characters in the name can be letters, the characters @, #, $, or _ (underscore), or digits (0 to 9).
At least one character must follow the & character.
No more than 10 characters can follow the & character.
CL variables can obtain a value in three different ways:
If the variable is a parameter passed to your CL program, the variable receives a value from the caller.
By being declared with an initial value. The DCL command can have an optional parameter, VALUE, in which you can specify any initial value you want to give the variable. If you do not specify VALUE, character variables default to blank, decimal variables default to zero, and logical variables default to false.
From the Change Variable (CHGVAR) command, which is CL's assignment command. If you want to assign variable &X the value ‘ABC,’ you code it in a CHGVAR command:
CHGVAR VAR(&X) VALUE(ABC)
The VALUE parameter can contain a single constant, a variable, or an expression that consists of many variables and/or constants, as in:
CHGVAR VAR(&NUMBER) VALUE(3 * (&COUNTER + 2))
In addition to the usual four arithmetic operations (which you can perform on decimal variables only), you can use the following operations on character strings:
Concatenation. Three types of concatenation are possible: *CAT (splicing together the two strings as they are, keeping trailing and leading blanks), *BCAT (removes the trailing blanks at the end of the first string and then inserts a single blank space between the two), and *TCAT (removes trailing blanks at the end of the first string and then joins them).
For example, if variable &FIRST is 10 characters long and contains ‘John,’ and &LAST is 10 characters long and contains ‘Smith,’ &FIRST *CAT &LAST yields ‘John Smith’ (six blanks in between) because *CAT keeps the trailing blanks in &FIRST. &FIRST *BCAT &LAST would yield ‘John Smith’ (one blank), and &FIRST *TCAT &LAST yields ‘JohnSmith.’
Substring. The substring function lets you extract part of a string and place the result into another string variable. The substring function is referenced as %SST or %SUBSTRING. If you want to extract the first three characters of &FIRST, code %SST(&FIRST 1 3). The ‘1’ indicates the beginning position for the extraction and the ‘3’ indicates how many characters to extract.
CHGVAR VAR(&NAME) VALUE(&FIRST *BCAT %SST(&LAST 1 4))
This CHGVAR command concatenates (with a single space between) variable &FIRST and the first four characters of &LAST. If &FIRST contains ‘John’ and &LAST contains ‘Smith,’ &NAME is given the value ‘John Smith.’