CL Programming (1)

CL Programming (1)

CL is the interface between OS/400 and the user of AS/400. Most of the functions the machine supports are available to you. HLL programs (Cobol, RPG, Pascal, C and Basic) would be used as the problem solving languages and for data management. Control language can only read database files (single format at that) sequentially and copy them.

You can place nearly all commands you enter interactively into a source file and compile them into a program. This is unlike other systems whose job control language requires interpretation each time it is presented for execution. Furthermore, some commands can only be used in CL Programming such as IF, ELSE, DO and flow control commands.

PGM/ENDPGM

All CL Programs begin with the PGM command (which is where you would nominate fields to hold variables passed by a calling program) and end with the ENDPGM command which closes files, frees any storage used by the program, releases any locks held at that point and returns to its caller. The equivalent in COBOL is STOP RUN and in RPG a RETRN with LR on.

DCL

All working storage used by the program must be declared to the compiler in advance using the Declare Variable command. Any number of DCLs can be used in a program. If you define a variable but do not refer to it in the program, the compiler will issue a warning and remove it from the program.

The VAR keyword states the name of the variable. It must begin with an ampersand to distinguish it from a command or object name and can be up to eleven characters long.

The type can be:

•*DEC - decimal, maximum of 15 digits, up to 9 on the right of the implied decimal point

•*CHAR - any characters up to a length of 9999

•*LGL - logical, one character in length only, '1' and '0' are the only permitted values. '1' indicates ON or TRUE; '0' means OFF or FALSE. Indicators in DDS are of this type and they also have reserved names - &INxx where xx is the indicator number

The VALUE keyword specifies the value the variable is to assume upon start of program execution. If VALUE is not specified, the variable will be initialised to zero or blanks as appropriate.

DCL VAR(&FRED) TYPE(*CHAR) LEN(2) VALUE('XX')

DCLF

The Declare File command, of which there are can only be one, declares a display file or single record format of a database file. This automatically declares all the fields in the file as CL variables - the compiler simply writes the appropriate DCL command for each field name and precedes it with an ampersand. Any indicators specified will take the form &INxx and be of type *LGL.

DCLF FILE(QGPL/MYFILE) RCDFMT(*ALL)

The RCDFMT keyword specifies which record format (screen display) to use in the program. Up to 50 may be defined (being selective helps reduce program size) or the default, *ALL, which is the first 99 in the file.

All the declarative commands are directives to the compiler and must appear before any executable commands in the program.

Expressions

CL uses the following symbolic operators in expressions:

PLUS / +
MINUS / -
MULTIPLY / *
DIVIDE / / / (preceded by a blank)
AND / & / or *AND
OR / │ / or *OR
NOT / ¬ / or *NOT
EQUAL / = / or *EQ
NOT EQUAL / -= / or *NE
GREATER THAN OR EQUAL / >= / or *GE
LESS THAN OR EQUAL / <= / or *LE
LESS THAN / < / or *LT
NOT LESS THAN / -< / or *NL
GREATER THAN / > / or *GT
NOT GREATER THAN / -> / or *NG
CONCATENATE / ║ / or *CAT
CONCAT SPACE / │ / or *BCAT
CONCAT TRUNCATE / │ / or *TCAT

There are four types of expression supported by CL:

Arithmetic

Operands in the expression must be decimal constants or variables, and complex expression can be nested to a level of 5. The division sign /(solidus) must be preceded by a blank otherwise it will be treated as a qualifier. The order in which the expression is resolved is in accordance with normal algebraic rules:

((&A + 2) / (&X - 15.7) * (0.8 * &VAT))

Character String

The only operators are the ones in the concatenate group and variables involved must be character.

*CAT is used to concatenate 2 fields together.

(&DAY *CAT &MONTH *CAT &YEAR) represents a composite field based upon &DAY, &MONTH and &YEAR.

*CAT means simply butt the characters of both fields together. There are 2 other concatenating functions:

*TCAT means strip off any trailing blanks from the first field before joining. It is useful for creating a qualified name (library/name). If &NAME and &LIB are 10 character variables then (&LIB *CAT '/' *CAT &NAME) would only create a valid qualified name if &LIB contained a 10-character library name.

*BCAT means strip off any trailing blanks from the first field, then add one blank, before joining. *BCAT is useful when creating text. You can link words into a phrase and leave one blank between each word, e.g. (&TITLE *BCAT &INIT *BCAT &SURNAME).

Relational

The operands in a relational expression can be arithmetic character or logical provided the symbolic operators are appropriate to the operators concerned. If character strings are of unequal length, the shorter fields are padded on the right with blanks. Arithmetic fields are compared algebraically.

IF (&Y *GT (&X - 15.2))...

Logical

The applicable operators are *OR and *AND. *NOT is used to negate logical variables.

IF (&X *OR &Y)...

IF &Y ....

IF (&X *OR *NOT &Y)...

Built-in Functions

%SUBSTRING, %SUBSTRING or %SST is for extracting part of a character field.

%SST

The 3 parameters are: character variable, start position, number of characters. The second and third parameters can be constants or variables.

%SST(&BUFFER 4 3) means the 4th 5th and 6th characters of field BUFFER.

%SST(&DATE 1 2) means the first 2 characters of &DATE.

%SST can be used on either side of a CHGVAR expression or within an IF.

%SWITCH %SWITCH is for testing the 8 external job switches which can be set on the SBMJOB and CHGJOB commands. 0 means test for OFF, 1 means test for ON, X means ignore. The following example tests just the first 2 switches.

IF (%SWITCH(10XXXXXX)) THEN(RETURN)

Common CL programming commands

There are a number of commands you will use in everyday CL programming.

CHGVAR

The Change Variable command is equivalent to other languages' MOVE instructions. The variables need not be of the same type because the system will perform implicit conversion. DDS indicators are set on and off with this command.

Examples:

CHGVAR VAR(&X) VALUE(&Y)

The contents of &X are changed to the value of &Y.

CHGVAR &Y (&A *CAT %SST(&B 1 2))

The first two characters of &B are concatenated to the contents of &A and the result placed in &Y.

CHGVAR &A (&B + 20)

CHGVAR &A %SST(&B &X &Y)

The substring of &B produced by getting elements from &B starting at byte &X and continuing &Y times are placed in &A.

CHGVAR &IN01 '1'

DDS indicator 01 is set on.

CVTDAT

The Convert Date command is useful for converting the date from one format to another. In particular, from DDMMYY to Julian or from MMDDYY to DDMMYY. Here's an example:

DCL &GDATE *CHAR 6 /* Variable for Gregorian date. */

CVTDAT DATE(&JDATE) TOVAR(&GDATE) FROMFMT(*JUL) TOSEP(*NONE)

The TOSEP specifies that separator characters are not wanted - if they were, the &GDATE size would have to be two characters larger to accommodate them.

Comments

Use /* to begin comments and end with */. You can use these comment delimiters virtually anywhere in a CL program.

GOTO/label

The GOTO command forces a branch to a statement that has a label in the form of XXXXX: (a character string up to ten characters long ending with a colon). The label may be on the same line as a command or on its own.

IF/ELSE

The two commands IF and ELSE are used in conjunction. The IF command evaluates a conditional expression and executes one command - and only one - if the expression is true. If there is an ELSE immediately following it is ignored. If the expression is false, the associated ELSE command (which is optional) is executed. Up to 10 levels of nesting are permitted.

IF COND(&A *EQ &B) THEN(CALL PGMA)

IF commands don't require an ELSE, but each ELSE must match up with a preceding IF. Indentation of the coding will aid visualising the logic flow:

IF (&A *GT 25) GOTO A

ELSE IF (&C *EQ &D) GOTO B

ELSE IF (&E = &F) GOTO C

ELSE GOTO ERROR

IF commands don't need to specify the THEN imperative statement providing there is a corresponding ELSE:

IF (&LIMIT *GT &BALANC)

ELSE GOTO X

: : : :

(a series of statements)

: : : :

X: CHGVAR &LIMIT 'EXCEEDED'

This says 'if the credit limit is greater than balance, continue. Otherwise (ELSE) branch to the statement labelled X'.

DO/ENDDO

The DO and ENDDO commands delimit a group of commands. Up to 10 nested levels of DO are supported (but not encouraged):

IF (&A = &B) +

DO

CHGVAR &X 'abcd'

CHGVAR &B (&B - 1)

ENDDO

Note the continuation character '+' !

CALL

The CALL command invokes another program (it doesn't matter which language it is written in) and passes control to it. The calling program can pass data in the form of variables and constants. To receive this data the called program must specify variables on the PARM parameter of its PGM command. The declaration of the variables in both programs must be identical; the lengths, type and decimal positions must match in the called and the calling program. As the system passes the addresses of the variables in the calling program to the called program, changes to the passed variables by the called program are reflected in the calling program. Each program may refer to the same variable with differing names.

RETURN

The called program can return to its caller by executing the ENDPGM command (the final command in the program) or, more flexibly, by executing the RETURN command at any point in the program. The two commands behave identically.

TFRCTL

The TFRCTL (Transfer Control) command behaves in a similar way to CALL except that:

•The transferring program is shut down and does not receive control back from the program it transferred control to

•The program to which control has been transferred returns to the caller of the program containing the TFRCTL command

•The parameters passed on to a program to which control is transferred must have been passed those parameters from its caller - they may not have originated only in transferring program

A CL program can call itself either directly or indirectly. The occasions when recursive programming (as it's called) is required are rare and unusual.

SNDF

This command is used to send a single record format from a display file to a display station. The file must be declared in the DCLF command.

RCVF

This command reads from the file declared in the DCLF command. For a data base file, the record is read into the variables associated with the field names in the program (they begin with an ampersand). For a display file, a read is issued for a previous SNDF (Send file) command.

SNDRCVF

This command is a combined write then read operation to a display station. It sends a named record format out to the display and waits until the operator presses the enter or enabled function key. The necessary data is incorporated from the program variables before display. Observe that the first parameter is the name of the device to which the record format should be transmitted (OS/400 programs support multiple display stations). As the default is the device from which the program is called it is usually omitted. The second parameter names the record format from the display file you want displayed on the screen.

SNDRCVF DEV(*) RCDFMT(MENU1)

or more usually coded as:

SNDRCVF RCDFMT(MENU1)

Job Control

CL provides numerous commands for job control. Retrieve Job Attributes (RTVJOBA), Delay Job (DLYJOB) and Change Job (CHGJOB) are commonly used operations.

RTVJOBA

The Retrieve Job Attributes command can be used by a CL program to find out more than 30 items of information about the job in which it runs.

These include the job name - which is the name of the display station the program is executing from in an interactive program, the name of the user who called this program, the library list in effect for the job, and the cancellation status of the job. For example to retrieve the name of the display station and the library list in effect for the job:

DCL &TERMID *CHAR 10

DCL &LIBL *CHAR 275

RTVJOBA JOB(&TERMID) USRLIBL(&LIBL)

DLYJOB

Delay Job can be used to specify either a delay period (DLY) up to about 11 days, specified as up to 999,999 seconds, or a resume time (RSMTIME) which is considered to be at today's date unless the time specified is earlier than the current time in which case it is assumed to be tomorrow's date. For example,

DLYJOB DLY(10)

would force that job to be suspended for 10 seconds

DLYJOB RSMTIME('00:00')

would force the job to sleep until midnight. This might well be used when writing an overnight backup or spooling program.

CHGJOB

Change Job may be used to modify some of the attributes of a job including execution priority, CPU timeslice, print queue and many others.

When specifying which job is meant (JOB) it is possible to put either the name of the job (qualified and therefore unique, or otherwise) or simply *, meaning the current job itself. For instance,

CHGJOB JOB(*) OUTQ(POSHPRINT) RUNPTY(30)

: : : :

CHGJOB JOB(*) OUTQ(CHEAPPRINT) RUNPTY(50)

would elevate that job's priority and allow spooled output to be sent to a high quality printer. At the end of this activity, the job would receive its old parameters again.