CL Programming
CL Programming
CL Programming
Version 4
SC41-5721-02
AS/400e IBM
CL Programming
Version 4
SC41-5721-02
Note
Before using this information and the product it supports, be sure to read the information in “Appendix D. Notices” on
page 405.
Chapter 1. Introduction . . . . . . . . . . . . . . . . . . . . . 1
Control Language . . . . . . . . . . . . . . . . . . . . . . . 1
Procedure . . . . . . . . . . . . . . . . . . . . . . . . . 1
Module . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Program . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Service Program . . . . . . . . . . . . . . . . . . . . . . . 2
Command Syntax . . . . . . . . . . . . . . . . . . . . . . 2
CL Procedures . . . . . . . . . . . . . . . . . . . . . . . . 2
Command Definition . . . . . . . . . . . . . . . . . . . . . . 4
Menus. . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Objects and Libraries . . . . . . . . . . . . . . . . . . . . . . 4
Objects . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Libraries . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Messages . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Message Descriptions . . . . . . . . . . . . . . . . . . . . . 8
Message Queues . . . . . . . . . . . . . . . . . . . . . . 8
Testing Functions . . . . . . . . . . . . . . . . . . . . . . . 9
Chapter 2. CL Programming . . . . . . . . . . . . . . . . . . . 11
Creating a CL Program . . . . . . . . . . . . . . . . . . . . . 12
Interactive Entry . . . . . . . . . . . . . . . . . . . . . . . 13
Batch Entry . . . . . . . . . . . . . . . . . . . . . . . . . 13
Parts of a CL Procedure . . . . . . . . . . . . . . . . . . . . 14
Example of a Simple CL Program . . . . . . . . . . . . . . . . 15
Commands Used in CL Procedures . . . . . . . . . . . . . . . . . 17
Commands Entered on the RQSDTA and CMD Parameters . . . . . . . 17
CL Commands . . . . . . . . . . . . . . . . . . . . . . . 17
Using CL Procedures . . . . . . . . . . . . . . . . . . . . . . 19
Working with Variables. . . . . . . . . . . . . . . . . . . . . . 22
Declaring a Variable . . . . . . . . . . . . . . . . . . . . . 24
Using Variables to Specify a List or Qualified Name . . . . . . . . . . 24
Lowercase Characters in Variables . . . . . . . . . . . . . . . . 25
Variables Replacing Reserved or Numeric Parameter Values . . . . . . 26
Changing the Value of a Variable . . . . . . . . . . . . . . . . . 27
Trailing Blanks on Command Parameters . . . . . . . . . . . . . . 28
Writing Comments in CL Procedures . . . . . . . . . . . . . . . 29
Controlling Processing within a CL Procedure . . . . . . . . . . . . . 30
Using the GOTO Command and Labels . . . . . . . . . . . . . . 31
Using the IF Command . . . . . . . . . . . . . . . . . . . . 31
Using the DO Command and DO Groups . . . . . . . . . . . . . . 33
Using the ELSE Command . . . . . . . . . . . . . . . . . . . 34
Contents v
Chapter 6. Advanced Programming Topics . . . . . . . . . . . . . 161
Using the QCAPCMD Program . . . . . . . . . . . . . . . . . . 161
Using the QCMDEXC Program . . . . . . . . . . . . . . . . . . 161
Using the QCMDEXC Program with DBCS Data . . . . . . . . . . . 163
Using the QCMDCHK Program . . . . . . . . . . . . . . . . . . 164
Using Message Subfiles in a CL Program or Procedure . . . . . . . . . 166
Allowing User Changes to CL Commands at Run Time . . . . . . . . . . 166
Using the Prompter within a CL Procedure or Program . . . . . . . . . 166
Selective Prompting for CL Commands . . . . . . . . . . . . . . 168
QCMDEXC with Prompting in CL Procedures and Programs . . . . . . . 171
Using the Programmer Menu . . . . . . . . . . . . . . . . . . . 171
Uses of the Start Programmer Menu (STRPGMMNU) Command . . . . . 171
Application Programming for DBCS Data . . . . . . . . . . . . . . . 173
Designing DBCS Application Programs. . . . . . . . . . . . . . . 173
Converting Alphanumeric Programs to Process DBCS Data . . . . . . . 173
Using DBCS Data in a CL Program . . . . . . . . . . . . . . . . . 174
Sample CL Programs . . . . . . . . . . . . . . . . . . . . . . 174
Initial Program for Setup (Programmer) . . . . . . . . . . . . . . 175
Moving an Object from a Test Library to a Production Library (Programmer) . 175
Saving Specific Objects in an Application (System Operator). . . . . . . 176
Recovery from Abnormal End (System Operator) . . . . . . . . . . . 176
Submitting a Job (System Operator). . . . . . . . . . . . . . . . 176
Timing Out While Waiting for Input from a Device Display . . . . . . . . 176
Retrieving Program Attributes . . . . . . . . . . . . . . . . . . 178
Loading and Running an Application from Tapes or Diskettes . . . . . . . 178
Responsibilities of the Application Writer . . . . . . . . . . . . . . 178
Contents vii
Displaying Messages from IBM Commands More Than Once . . . . . . 344
Creating Abbreviated Commands . . . . . . . . . . . . . . . . . 344
Deleting Files and Source Members . . . . . . . . . . . . . . . . 345
Deleting Program Objects . . . . . . . . . . . . . . . . . . . 346
Bibliography . . . . . . . . . . . . . . . . . . . . . . . . . 409
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
Contents ix
x OS/400 CL Programming V4R4
Figures
1. AS/400 Operations Navigator Display . . . . . . . . . . . . . . xiii
2. Example of Accessing a Remote Data Queue . . . . . . . . . . . 82
3. Example of an Application Using the LODRUN Command . . . . . . . 179
4. Example of runtime call stack . . . . . . . . . . . . . . . . . 216
5. Example of TOPGMQ(*PRV *) . . . . . . . . . . . . . . . . . 217
6. Example of using a simple name . . . . . . . . . . . . . . . . 219
7. Example of using a complex name . . . . . . . . . . . . . . . 220
8. Example 1 of using *PGMBDY . . . . . . . . . . . . . . . . . 222
9. Example 2 of using *PGMBDY . . . . . . . . . . . . . . . . . 223
10. Example 3 of using *PGMBDY . . . . . . . . . . . . . . . . . 224
11. Example of runtime call stack . . . . . . . . . . . . . . . . . 226
12. Example of using *CTLBDY . . . . . . . . . . . . . . . . . . 227
13. Simple List Example. . . . . . . . . . . . . . . . . . . . . 303
14. REXX Simple List Example . . . . . . . . . . . . . . . . . . 304
15. Command Relationships for CL and HLL . . . . . . . . . . . . . 338
16. Command Relationships for REXX . . . . . . . . . . . . . . . 340
17. Adding an ILE Program Object to a Debug Session . . . . . . . . . 353
18. Adding an ILE Program Object to a Debug Session . . . . . . . . . 354
19. Removing an ILE Program Object from a Debug Session . . . . . . . 355
20. Removing an ILE Program Object from a Debug Session . . . . . . . 355
21. Display a Module View . . . . . . . . . . . . . . . . . . . . 357
22. Changing a View of a Module Object . . . . . . . . . . . . . . 358
23. Setting a Conditional Breakpoint . . . . . . . . . . . . . . . . 360
24. Displaying a Variable using F11 (Display variable) . . . . . . . . . . 366
This new interface has been designed to make you more productive and is the only
user interface to new, advanced features of OS/400. Therefore, IBM recommends
that you use AS/400 Operations Navigator, which has online help to guide you.
To select the subcomponents that you want to install, select the Custom installation
option. (After Operations Navigator has been installed, you can add subcomponents
by using Client Access Selective Setup.)
1. Display the list of currently installed subcomponents in the Component
Selection window of Custom installation or Selective Setup.
2. Select AS/400 Operations Navigator.
3. Select any additional subcomponents that you want to install and continue with
Custom installation or Selective Setup.
After you install Client Access, double-click the AS400 Operations Navigator icon
on your desktop to access Operations Navigator and create an AS/400 connection.
Control Language
Control language (CL) is the primary interface to the operating system and can be
used at the same time by users at different work stations. A single control language
statement is called a command. Commands can be entered in the following ways:
v Individually from a work station.
v As part of batch jobs.
v As source statements to create a CL program or procedure.
Commands can be entered individually from any command line or the Command
Entry display.
To simplify the use of CL, all the commands use a consistent syntax. In addition,
the operating system provides prompting support for all commands, default values
for most command parameters, and validity checking to ensure that a command is
entered correctly before the function is performed. Thus, CL provides a single,
flexible interface to many different system functions that can be used by different
system users.
Procedure
| A procedure is a set of self-contained high-level language statements that performs
| a particular task and then returns to the caller.
In CL, a procedure usually begins with a PGM statement and ends with an
ENDPGM statement.
Module
Module is the object that results from compiling source. A module must be bound
into a program to run.
Service Program
| Service program is an OS/400 object that combines one or more modules. While a
| program has only one entry point, a service program can have multiple entry points.
| You cannot call service programs directly. You can call procedures in a service
| program from other procedures in programs and service programs.
Command Syntax
| A command name and parameters make up each command. A command name
| usually consists of a verb, or action, followed by a noun or phrase that identifies the
| receiver of the action. Abbreviated words, usually to three letters, make up the
| command name. This reduces the amount of typing that is required to enter the
| command. For example, one of the CL commands is the Send Message command.
| You would use the command that is named SNDMSG to send a message from a
| user to a message queue.
CL Procedures
CL programs and procedures are made up of CL commands. The commands are
compiled into an OPM program or a module that can be bound into programs made
up of modules written in CL or other languages. Advantages of using CL programs
and procedures include:
| v Using CL programs and procedures is faster than entering and running the
| commands individually.
v CL programs and procedures provide consistent processing of the same set of
commands and logic.
v Some functions require CL commands that cannot be entered individually and
must be part of a CL program or procedure.
v CL programs and procedures can be tested and debugged like other high-level
language (HLL) programs and procedures.
v Parameters can be passed to CL programs and procedures to adapt the
operations performed by the program or procedure to the particular requirements
of that use.
| v You can bind CL modules with other ILE* high-level language modules into a
| program.
CL programs and procedures can be used for many kinds of applications. For
example, CL procedures can be used to:
Most of the CL commands provided by the system can be used in CL programs and
procedures. Some commands are specifically designed for use in CL programs and
procedures and are not available when commands are entered individually. These
commands include:
v Logic control commands that can be used to control which operations are
performed by the program or procedure according to conditions that exist when
the program or procedure is run. For example, if a certain condition exists, then
do certain processing, else do some other operation. These logic operations
provide both conditional and unconditional branching within the CL program or
procedure.
v Data operations that provide a way for the program or procedure to communicate
with a work station user. Data operations let the program or procedure send
formatted data to and receive data from the work station, and allow limited
access to the database.
v Commands that allow the program or procedure to send messages to the display
station user.
v Commands that receive messages sent by other programs and procedures.
These messages can provide normal communication between programs and
procedures, or indicate that errors or other exceptional conditions exist.
v The use of variables and parameters for passing information between commands
in the program or procedure and between programs and procedures.
v Calling other procedures (only programs can be called from the command line or
in the batch job stream).
CL programs and procedures provide the flexibility needed to let the application
user select what operations to perform and run the necessary procedures.
Chapter 1. Introduction 3
Command Definition
Command definition allows system users to create additional commands to meet
specific application needs. These commands are similar to the system commands.
Each command on the system has a command definition object and a command
processing program (CPP). The command definition object defines the command,
including:
v The command name
v The CPP
v The parameters and values that are valid for the command
v Validity checking information the system can use to validate the command when
it is entered
v Prompt text to be displayed if a prompt is requested for the command.
v Online help information
The CPP is the program called when the command is entered. Because the system
performs validity checking when the command is entered, the CPP does not always
have to check the parameters passed to it.
Menus
The system provides a large number of menus that allow users to perform many
functions just by selecting menu options. The advantages of using menus to
perform system tasks include:
v Users do not need to understand CL commands and command syntax.
v The amount of typing and the chance of errors are greatly reduced.
The System Operation for New Users book provides detailed descriptions of system
menus and information about how to use these menus.
Information about creating menus that can be used like the system-supplied menus
is described in the Application Display Programming book.
Objects
The functions performed by most of the CL commands are applied to objects. Some
commands can be used on any type of object and others apply only to a specific
type of object.
The system supports various unique types of objects. Some types identify objects
common to many data processing systems, such as:
v Files
v Programs
v Commands
v Libraries
v Queues
v Modules
v Service programs
Each object has a name. The object name and the object type are used to identify
an object. The object name is assigned by the user creating the object. The object
type is determined by the command used to create the object. For example, if a
program was created and given the name OEUPDT (for order entry update), the
program could always be referred to by that name. The system uses the object
name (OEUPDT) and object type (program) to locate the object and perform
operations on it. Several objects can have the same name, but they must either be
different object types or be stored in different libraries.
Libraries
| A library is an object that is used to group related objects, and to find objects by
| name when they are used. Thus, a library is a directory to a group of objects. You
| can use libraries to group the objects into any meaningful collection. For example,
Chapter 1. Introduction 5
| you can group objects according to security requirements, backup requirements, or
| processing requirements. The amount of available storage limits the number of
| objects that a library can contain, and the number of libraries on the system.
| Most types of objects are placed in a library when they are created. The AUT
| parameter on CRTLIB defines the public authority of the library. The CRTAUT
| parameter specifies the default authority for objects that are created into the library.
| If the command creating the object specifies *LIBCRTAUT for the AUT parameter,
| the object’s public authority is the create authority that was specified for the library.
| You can move most object types from one library to another, but a single object
| cannot be in more than one library at the same time. When you move an object to
| a different library, the object is not moved in storage. You now locate the object
| through the new library. You can also rename and copy most object types from one
| library into another.
A library name can be used to provide another level of identification to the name of
an object. As described earlier, an object is identified by its name and its type. The
name of the library further qualifies the object name. The combination of an object
name and the library name is called the qualified name of the object. The qualified
name tells the system the name of the object and the library it is in.
The following diagram shows two libraries and the qualified names of the objects in
them:
Qualified
Library: OELIB Object Names Library: PAYLIB
┌──────────────────────┐ ┌───────────────────────┐
│ ┌────────┐ │ │ ┌─────────┐ │
│ │ ORDFIL │ │ ┌───┼──────────Ê│ EMPMAST │ │
│ │ │Í──────────┼────OELIB/ORDFIL │ │ │ │ │
│ └────────┘ ┌───────┐ │ ┌──OELIB/OEUPDT │ │ └─────────┘ │
│ │ │ │ │┌─OELIB/CUSTMAST │ │ ┌───────┐ │
│ │OEUPDT │Í┼─┘│ │ ┌─┼Ê│ PAYPGM│ │
│ │ │ │ │ │ │ │ │ │ │
│ └───────┘ │ │ PAYLIB/EMPMAST─┘ │ │ │ │ │
│ ┌──────────┐ │ │ PAYLIB/PAYPGM────┘ │ └───────┘ │
│ │ CUSTMAST │ │ │ PAYLIB/PAYHIST──┐ │ ┌─────────┐ │
│ │ │Í────────┼──┘ └──┼──────────Ê│ PAYHIST │ │
│ │ │ │ │ │ │ │
│ └──────────┘ │ │ └─────────┘ │
│ │ │ │
└──────────────────────┘ └───────────────────────┘
Two objects with the same name and type can exist in different libraries. Two
different objects with the same name cannot exist in the same library unless their
object types differ. This design allows a program that refers to objects by name to
work with different objects (objects with the same name but stored in different
libraries) in successive runs of the program without changing the program itself.
Also, a work station user who is creating a new object does not need to be
An object is identified within a library by the object name and type. Many CL
commands apply only to a single object type, so the object type does not have to
be explicitly identified. For those commands that apply to many object types, the
object type must be explicitly identified.
| See “Using Libraries” on page 108 for detail on how to use libraries to find objects.
Messages
A message is a communication sent from one user, program, or procedure to
another. Most data processing systems provide communications between the
system and the operator to handle errors and other conditions that occur during
processing. OS/400 also provides message handling functions that support two-way
communications between programs and system users, between programs, between
procedures within a program, and between system users. Two types of messages
are supported:
v Immediate messages, which are created by the program or system user when
they are sent and are not permanently stored in the system.
v Predefined messages, which are created before they are used. These messages
are placed in a message file when they are created, and retrieved from that file
when they are used.
Chapter 1. Introduction 7
Because messages can be used to provide communications between programs,
between procedures in a program, and between programs and users, using the
OS/400 message handling functions should be considered when developing
applications. The following concepts of message handling are important to
application development:
v Messages can be defined in messages files, which are outside the programs that
use them, and variable information can be provided in the message text when a
message is sent. Because messages are defined outside the programs, the
programs do not have to be changed when the messages are changed. This
approach also allows the same program to be used with message files containing
translations of the messages into different languages.
v Messages are sent to and received from message queues, which are separate
objects on the system. A message sent to a queue can remain on the queue until
it is explicitly received by a program or work station user.
v A program can send messages to a user who requested the program regardless
of what work station that user has signed on to. Messages do not have to be
sent to a specific device; one program can be used from different work stations
without change.
See the National Language Support book for information on Coded Character Set
Identifier (CCSID) for menus, messages, and message descriptions.
Message Descriptions
A message description defines a message to OS/400. The message description
contains the text of the message and information about replacement variables, and
can include variable data that is provided by the message sender when the
message is sent.
Message descriptions are stored in message files. Each description must have an
identifier that is unique within the file. When a message is sent, the message file
and the message identifier tell the system which message description is to be used.
Message Queues
When a message is sent to a procedure, a program, or a system user, it is placed
on a message queue associated with that procedure, program, or user. The
procedure, program, or user sees the message by receiving it from the queue.
The testing functions narrow the search for errors that are difficult to find in the
procedure’s source statements. Often, an error is apparent only because the output
produced is not what is expected. To find those errors, you need to be able to stop
the program at a given point (called a breakpoint) and examine variable information
in the program to see if it is correct. You might want to make changes to those
variables before letting the program continue running.
You do not need to know machine language instructions, nor is there a need to
include special instructions in the program to use the testing functions. The OS/400
testing functions lets you:
v Stop a running program at any named point in the program’s source statements.
v Display information about procedure variables at any point where the program
can be stopped. You can also change the variable information before continuing
procedure processing.
See either “Chapter 10. Debugging ILE Programs” on page 349, for more
information on debugging Integrated Language Environment* (ILE*) programs or
“Appendix A. Debugging OPM Programs” on page 373 for more information on
debugging OPM programs.
See the appropriate ILE guide for debugging information with other ILE languages.
Chapter 1. Introduction 9
10 OS/400 CL Programming V4R4
Chapter 2. CL Programming
The focus of Chapter 2 is now ILE rather than OPM. For this reason, ‘procedure’ is
used rather than ‘program’ for this chapter. However, when the discussion is about
CL commands in general, the word ‘program’ may still be used.
When you enter CL commands individually (from the Command Entry display, for
instance, or as individual commands in an input stream), each command is
separately processed. When you enter CL commands as source statements for a
CL procedure, the source remains for later modification if you choose, and the
commands are compiled into a module. This module remains as a permanent
system object that can be bound into other programs and run. Thus, CL is actually
a high-level programming language for system functions. CL procedures ensure
consistent processing of groups of commands. You can perform functions with a CL
procedure that you cannot perform by entering commands individually, and the CL
program or procedure provides better performance at run time than the processing
of several separate commands.
Pgm: B,I
(2)
ÊÊ PGM ÊÍ
.
(1)
PARM( · &CL-variable-name )
Notes:
1. A maximum of 40 repetitions
2. All parameters preceding this point can be specified positionally.
The Pgm: B,I in the syntax diagram for the PGM command shows that this
command can be used in either batch or interactive jobs, but can be used only
within a CL program or procedure.
Creating a CL Program
All programs are created in steps:
1. Source creation. CL procedures consist of CL commands. In most cases,
source statements are entered into a database file in the logical sequence
determined by your application design.
Note: If you want to create a program consisting of only one CL module, you can
use the Create Bound CL Program (CRTBNDCL) command, which combines
steps 2 and 3.
Interactive Entry
The AS/400 system provides many menus and displays to assist the programmer,
including the Programmer Menu, the Command Entry display, command prompt
displays, and the Programming Development Manager (PDM) Menu. If your AS/400
system uses the security functions described in Security - Reference, your ability to
use these displays is controlled by the authority given to you in your user profile.
User profiles are generally created and maintained by a system security officer.
The most frequently used source entry method is the source entry utility (SEU),
which is part of the AS/400 Application Development ToolSet/400 licensed program.
Batch Entry
You can create CL source, a CL module, and a program in one batch input stream
from diskette. The following example shows the basic parts of the input stream from
a diskette unit. The input is submitted to a job queue using the Submit Diskette Job
(SBMDKTJOB) command. The input stream should follow this format:
// BCHJOB
CRTBNDCL PGM(QGPL/EDUPGM) SRCFILE(PERLIST)
// DATA FILE(PERLIST) FILETYPE(*SRC)
.
. (CL Procedure Source)
.
//
/*
// ENDINP
This stream creates a program from on-line source. If you want to keep the source
on-line, a Copy File (CPYF) command could be used to copy the source into a
database file. The program could then be created using the database file.
You can also create a CL module directly from CL source on external media, such
as diskette, using an IBM-supplied device file. The IBM-supplied diskette source file
is QDKTSRC (use QTAPSRC for tape). Assume, for instance, that the CL source
statements are in a source file on diskette named PGMA.
The first step is to identify the location of the source on diskette by using the
following override command with LABEL attribute override:
OVRDKTF FILE(QDKTSRC) LABEL(PGMA)
Now you can consider the QDKTSRC file as the source file on the Create CL
Module (CRTCLMOD) command. To create the CL module based on the source
input from the diskette, enter the following command:
CRTCLMOD MODULE(QGPL/PGMA) SRCFILE(QDKTSRC)
Chapter 2. CL Programming 13
When the CRTCLMOD command is processed, it treats the QDKTSRC source file
like any database source file. Using the override, the source is located on diskette.
PGMA is created in QGPL, and the source for that module remains on diskette. See
Data Management for more information on device files.
Parts of a CL Procedure
While each source statement entered as part of a CL procedure is actually a CL
command, the source can be divided into the following basic parts used in many
typical CL procedures.
PGM command
PGM PARM(&A)
Optional PGM command beginning the procedure and identifying any
parameters received.
Declare commands
(DCL, DCLF)
Mandatory declaration of procedure variables when variables are used. The
declare commands must precede all other commands except the PGM
command.
CL processing commands
CHGVAR, SNDPGMMSG, OVRDBF, DLTF, ...
CL commands used as source statements to manipulate constants or
variables (this is a partial list).
Logic control commands
IF, THEN, ELSE, DO, ENDDO, GOTO
Commands used to control processing within the CL procedure.
Built-in functions
%SUBSTRING (%SST), %SWITCH, and %BINARY (%BIN)
Built-in functions and operators used in arithmetic, relational or logical
expressions.
Program control commands
CALL, RETURN
CL commands used to pass control to other programs.
Procedure control commands
CALLPRC, RETURN
CL commands used to pass control to other procedures.
ENDPGM command
ENDPGM
Optional End Program command.
The sequence, combination, and extent of these components are determined by the
logic and design of your application.
A CL procedure may refer to other objects that must exist when the procedure is
created, when the command is processed, or both. This distinction is discussed in
“Accessing Objects in CL Programs” on page 143, and in the sections discussing
various objects. In some circumstances, for your procedure to run successfully, you
may need:
In this example, the Programmer Menu is used to create the program. You could
also use the programming development manager (PDM), which is part of the
Application Development ToolSet/400 licensed program.
Chapter 2. CL Programming 15
┌─────────────────────────┐ ┌────────────────────────┐
│ Enter CL Source │ Display │ Physical File Member │
├─────────────────────────┤ ┌────────────┐ ├────────────────────────┤
│ Interactively enter CL │ │ Option 8 │ │ 0001.00 PGM /*STARTUP*/│
│ source in a physical ├───┤ Programmer ├──Ê│ 0002.00 CALL PGM(A) │
│ file member, using the │ │ Menu │ │ 0003.00 CALL PGM(B) │
│ source entry ulitity │ └────────────┘ │ 0004.00 CALL PGM(C) │
│ (SEU). │ │ 0005.00 ENDPGM │
└─────────────────────────┘ └────────────┬───────────┘
│
┌─────────────────────────┐ │
│ │ ø
│ Create Program │ Display STARTUP
├─────────────────────────┤ ┌────────────┐ ┌───────────┐
│ Create a program │ │ Option 3 │ │ Object │
│ object from the source ├───┤ Programmer ├─────────Ê│ after │Í──┐
│ using the CRTBNDCL │ │ Menu │ │ Creation │ │
│ command. │ └────────────┘ └───────────┘ │
│ │ │
└─────────────────────────┘ │
│
┌─────────────────────────┐ │
│ Run Program │ Display │
├─────────────────────────┤ ┌────────────┐ │
│ Call the program │ │ Option 4 │ │
│ using a CALL ├───┤ Programmer ├──────────────────────────┘
│ command. │ │ Menu │
└─────────────────────────┘ └────────────┘
To enter CL source:
v Select option 8 (Edit source) on the Programmer Menu and specify STARTUP in
the Parm field. (This option creates a source member named STARTUP that will
also be the name of the program.)
v Specify CLLE in the Type field and press the Enter key.
v On the SEU display, use the I (insert) line command to enter the CL commands
(CALL is a CL command).
Columns........: 1 71 Edit QGPL/QCLSRC
Find......: _____________________________________________ STARTUP
FMT A* .....A*. 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
************** Beginning of data ***********************************
.......
.......
.......
.......
.......
.......
Note: The referenced programs (A, B, and C) do not have to exist when the
program STARTUP is created.
CL Commands
The following is a list of commands frequently used in CL procedures. You can use
this list to select the appropriate command for the function you want, and to
determine which command you might need to refer to in the CL Reference
(Abridged) book. Familiarity with the function of these commands will help you to
understand subsequent topics in this chapter. Superscript 1 indicates the
commands that can be used only in CL procedures.
Chapter 2. CL Programming 17
System Function Command Command Function
1
Files ENDRCV (End Receive) Cancels a request for input previously issued by a
RCVF, SNDF, or SNDRCVF command to a display file
DCLF (Declare File) 1 Declares a display or database file
RCVF (Receive File) 1 Reads a record from a display or database file
RTVMBRD (Retrieve Member Retrieves a description of a specific member of a
Description) 1 database file
SNDF (Send File) 1 Writes a record to a display file
1
SNDRCVF (Send/Receive File) Writes a record to a display file and reads that record
after the user has replied
1
WAIT (Wait) Waits for data to be received from an SNDF, RCVF, or
SNDRCVF command issued to a display file
1
Messages MONMSG (Monitor Message) Monitors for escape, status, and notify messages sent to
a program’s message queue
1
RCVMSG (Receive Message) Copies a message from a message queue into CL
variables in a CL procedure
1
RMVMSG (Remove Message) Removes a specified message from a specified message
queue
1
RTVMSG (Retrieve Message) Copies a predefined message from a message file into
CL procedure variables
SNDPGMMSG (Send Program Sends a program message to a message queue
Message) 1
SNDRPY (Send Reply) 1 Sends a reply message to the sender of an inquiry
message
SNDUSRMSG (Send User Message) Sends an informational or inquiry message to a display
station or system operator
Miscellaneous CHKOBJ (Check Object) Checks for the existence of an object and, optionally, the
Commands necessary authority to use the object
PRTCMDUSG (Print Command Produces a cross-reference list for a specified group of
Usage) commands used in a specified group of CL procedures
RTVCFGSRC (Retrieve Configuration Generates CL command source for creating existing
Source) configuration objects and places the source in a source
file member
RTVCFGSTS (Retrieve Configuration Gives applications the capability to retrieve configuration
Status) 1 status from three configuration objects: line, controller,
and device.
1
RTVJOBA (Retrieve Job Attributes) Retrieves the value of one or more job attributes and
places the values in a CL variable
RTVSYSVAL (Retrieve System Value) Retrieves a system value and places it into a CL variable
1
RTVUSRPRF (Retrieve User Profile) Retrieves user profile attributes and places them into CL
1
variables
Program Creation CRTCLMOD (Create CL Module) Creates a CL module
Commands
DLTMOD (Delete Module) Deletes a module
DLTPGM (Delete Program) Deletes a program
CRTBNDCL (Create Bound Control Creates a bound CL program.
Language Program)
| CRTCLPGM (Create CL Program) Creates an OPM CL program.
| CRTPGM (Create Program) Creates a program from one or more modules.
| CRTSRVPGM (Create Service Creates a service program from one or more modules.
| Program)
v Send and receive data to and from a display file with a CL procedure.
Chapter 2. CL Programming 19
┌──────────────────┐
│ Data Description │
│ Specifications │
│ (DDS) │
└────────┬─────────┘
│
ø PGM
┌──────────────────┐ DCL FILE(DISPLAY)
│ Display │ DCL &OPTION *CHAR 2
│ │ v
│ │ v
│ │ v
│ │ RCVF ...
│ Option __ ───────┼─────Ê IF (&OPTION *EQ 1) THEN(CALL PGMA)
└──────────────────┘ v
v
v
ENDPGM
v Create a CL procedure to monitor error messages for a job, and take corrective
action if necessary.
PGM
Chapter 2. CL Programming 21
┌──────────────────────────────────────────────────────────────────┐
│ Start │
│ │ │
│ └────Ê PGMA (CL) ┌─────Ê PGMB (RPG) ┌────Ê PGMC (RPG) │
│ ┌──────────────┐ │ ┌────────────┐ │ ┌────────────┐ │
│ │ . │ │ │ . │ │ │ . │ │
│ │ . │ │ │ . │ │ │ . │ │
│ │ . │ │ . │ │ │ . │ │
│ │ CALLPRC PGMB─┼──┘ │ CALLB PGMC─┼──┘ │ . │ │
│ │ . Í──────┼─────┐ │ . Í──────┼───────┼─END │ │
│ │ . │ │ │ . │ └────────────┘ │
│ │ . │ │ │ . │ │
│ │ CALLPRC PGME─┼──┐ │ │ . │ ┌────Ê PGMD (CL) │
│ ┌────┼─Ê . │ │ │ │ . │ │ ┌────────────┐ │
│ │ │ . │ │ │ │ . │ │ │ . │ │
│ │ │ . │ │ │ │ . │ │ │ . │ │
│ │ │ ENDPGM │ │ │ │ CALLB PGMD─┼──┘ │ . │ │
│ │ └──────────────┘ │ │ │ . Í──────┼───────┼─RETURN │ │
│ │ │ │ │ . │ └────────────┘ │
│ │ ┌──────────────────┘ │ │ . │ │
│ │ │ └──┼─RETURN │ │
│ │ └──Ê PGME (COBOL) └────────────┘ │
│ │ ┌─────────────┐ │
│ │ │ . │ ┌────Ê PGMF (CL) │
│ │ │ . │ │ ┌─────────────┐ │
│ │ │ . │ │ │ . │ │
│ │ │ CALL PGMF ──┼──┘ │ . │ │
│ │ │ . Í───────┼───────┼─RETURN │ │
│ │ │ . │ └─────────────┘ │
│ │ │ . │ │
│ └──────┼─EXIT PROGRAM│ │
│ └─────────────┘ │
└──────────────────────────────────────────────────────────────────┘
The procedures can be created as indicated in the following example. You can
enter source for procedures in separate source members.
CRTCLMOD PGMA
CRTRPGMOD PGMB
CRTRPGMOD PGMC
CRTCLMOD PGMD
CRTCBLMOD PGME
CRTCLMOD PGMF
CRTPGM PGM(PGMA) +
MODULE(PGMA PGMB PGMC PGMD PGME PGMF) +
ENTMOD(*FIRST)
| Variables are not stored in libraries; they are not objects; and their values are
| destroyed when the procedure that contains them is no longer active. The use of
| variables as values gives CL programming a special flexibility, because this allows
| high-level manipulation of objects whose content may change by specific
| applications. You might, for instance, write a CL procedure to direct the processing
| of other programs or the operation of several work stations without specifying which
| programs or work stations are to be controlled. The system identifies these as
| variables in the CL procedure. You can define (specify) the value of the variables
| when running the CL procedure.
All variables must be declared (defined) to the CL procedure before they can be
used by the procedure:
v Declare variable. Defining it is accomplished using the Declare CL Variable (DCL)
command and consists of defining the attributes of the variable. The attributes
are type, length, and initial value.
DCL VAR(&AREA) TYPE(*CHAR) LEN(4) VALUE(BOOK)
v Declare file. If your CL procedure uses a file, you must specify the name of the
file in the FILE parameter on the Declare File (DCLF) command. The file
contains a description (format) of the records in the file and the fields in the
records. During compilation, the DCLF command implicitly declares CL variables
for the fields and indicators defined in the file.
| For example, if the DDS for the file has one record in it with two fields (F1 and
| F2), then two variables, &F1 and &F2, are automatically declared in the program.
| DCLF FILE(MCGANN/GUIDE)
| If the file is a physical file which was created without DDS, one variable is
declared for the entire record. The variable has the same name as the file, and
its length is the same as the record length of the file.
The declare commands must precede all other commands in the procedure (except
the PGM command), but they can be intermixed in any order.
In addition to the uses discussed in this section, variables can be used to:
v Pass information between procedures and jobs. See “Chapter 3. Controlling Flow
and Communicating between Programs and Procedures” on page 65.
v Pass information between procedures and device displays. See “Working with
Multiple Device Display Files” on page 156.
v Conditionally process commands. See “Controlling Processing within a CL
Procedure” on page 30.
v Create objects. A variable can be used in place of an object name or library
name, or both. The following example shows the Create Physical File (CRTPF)
command used with a specified library in the first line, and with a variable
replacing the library name in the second line:
CRTPF FILE(DSTPRODLB/&FILE)
CRTPF FILE(&LIB/&FILE)
Chapter 2. CL Programming 23
be changed during the processing of a CL procedure through the use of the
prompting function. See “Allowing User Changes to CL Commands at Run Time” on
page 166 for more information.
It is also possible to assemble the keywords and parameters for a command and
process it using the QCAPCMD API or QCMDEXC API. See “Using the QCAPCMD
Program” on page 161 and “Using the QCMDEXC Program” on page 161 for more
information.
Declaring a Variable
In its simplest form, the Declare CL Variable (DCL) command has the following
parameters:
RV2W271-1
When you use a DCL command, you must use the following rules:
v The CL variable name must begin with an ampersand (&) followed by as many
as 10 characters. The first character following the & must be alphabetic and the
remaining characters alphanumeric. For example, &PART
v The CL variable value must be one of the following:
– A character string as long as 5000 characters.
– A packed decimal value totaling up to 15 digits with as many as 9 decimal
positions.
– A logical value ’0’ or ’1’, where ’0’ can mean off, false, or no, and ’1’ can
mean on, true, or yes. A logical variable must be either ’0’ or ’1’.
v If you do not specify an initial value, the following is assumed:
– 0 for decimal variables
– Blanks for character variables
– ’0’ for logical variables.
For decimal and character types, if you specify an initial value and do not specify
the LEN parameter, the default length is the same as the length of the initial
value. For type *CHAR, if you do not specify the LEN parameter, the string can
be as long as 5000.
v Declare the parameters as variables in the program DCL statements.
When variables are used to specify elements in a list, each element must be
declared separately:
Incorrect:
DCL VAR(&LIBS) TYPE(*CHAR) LEN(20) +
VALUE('QTEMP QGPL DISTLIB')
CHGLIBL LIBL(&LIBS)
When presented as a single character string, the system does not view the list as a
list of separate elements, and an error will occur.
You can also use variables to specify a qualified name, if each qualifier is declared
as a separate variable:
DCL VAR(&PGM) TYPE(*CHAR) LEN(10)
DCL VAR(&LIB) TYPE(*CHAR) LEN(10)
CHGVAR VAR(&PGM) VALUE(MYPGM)
CHGVAR VAR(&LIB) VALUE(MYLIB)
.
.
.
DLTPGM PGM(&LIB/&PGM)
ENDPGM
In this example, the program and library name are declared separately. The
program and library name cannot be specified in one variable, as in the following
example:
Incorrect:
DCL VAR(&PGM) TYPE(*CHAR) LEN(11)
CHGVAR VAR(&PGM) VALUE('MYLIB/MYPGM')
DLTPGM PGM(&PGM)
Here again the value is viewed by the system as a single character string, not as
two objects (a library and an object). If a qualified name must be handled as a
single variable with a character string value, you can use the built-in function
%SUBSTRING and the *TCAT concatenation function to assign object and library
names to separate variables. See “Using the %SUBSTRING Built-In Function” on
page 43 and Chapter 9 for examples using the %SUBSTRING function.
Note that if this VALUE parameter had not been enclosed in apostrophes, it would
have been correct, because without the apostrophes it would be translated to
Chapter 2. CL Programming 25
uppercase automatically. This error frequently occurs when the parameter is passed
as input to a procedure or program from a display as a character string, and the
| display entry is made in lowercase.
| Note: The above paragraph does not take into account the fact that translation to
| uppercase is language dependent. REMEMBER: Relying on the system to
| translate values to uppercase may produce unexpected results.
Each parameter on a command can accept only certain types of values. The
parameter may allow an integer, a character string, a reserved value, a variable of a
specified type, or some mixture of these, as values. Some types of values are
required for parameters. If the parameter allows numeric values (if the value is
defined in the command as *INT2, *INT4, or *DEC) and also allows reserved values
(a character string preceded by an asterisk), you can use a variable as the value for
the parameter. The variable must be declared as TYPE(*CHAR) if you intend to use
a reserved value.
For example, the Change Output Queue (CHGOUTQ) command has a job
separator (JOBSEP) parameter that can have a value of either a number (0 through
9) or the predefined default, *SAME. Because both the number and the predefined
value are acceptable, you can also write a CL procedure that substitutes a
character variable for the JOBSEP value:
PGM
DCL &NRESP *CHAR LEN(6)
DCL &SEP *CHAR LEN(4)
DCL &FILNAM *CHAR LEN(10)
DCL &FILLIB *CHAR LEN(10)
DCLF.....
.
.
.
LOOP: SNDRCVF.....
IF (&SEP *EQ IGNR) GOTO END
ELSE IF (&SEP *EQ NONE) CHGVAR &NRESP '0'
ELSE IF (&SEP *EQ NORM) CHGVAR &NRESP '1'
ELSE IF (&SEP *EQ SAME) CHGVAR &NRESP '*SAME'
CHGOUTQ OUTQ(&FILLIB/&FILNAM) JOBSEP(&NRESP)
GOTO LOOP
END: RETURN
ENDPGM
In the preceding example, the display station user enters information on a display
describing the number of job separators desired for a specified output queue. The
variable &NRESP is a character variable manipulating numeric and predefined
values (note the use of apostrophes). The JOBSEP parameter on the CHGOUTQ
command will recognize these values as if they had been entered as numeric or
predefined values. The DDS for the display file used in this program should use the
VALUES keyword to restrict the user responses to IGNR, NONE, NORM, or SAME.
If the parameter allows a numeric type of value (*INT2, *INT4, or *DEC) and you do
not intend to enter any reserved values (such as *SAME), then you can use a
decimal variable in that parameter.
Another alternative for this function is to use the prompter within CL procedures.
or
CHGVAR &INVCMPLT 0
&INVCMPLT is set to 0.
v To the value of another variable:
CHGVAR VAR(&A) VALUE(&B)
or
CHGVAR &A &B
or
CHGVAR &A (&A + 1)
&A is set to the first five characters of the value of the variable &B
v To the value produced by the built-in function %SWITCH (see “Using the
%SWITCH Built-In Function” on page 45 for more information):
CHGVAR VAR(&A) VALUE(%SWITCH(0XX111X0))
&A is set to 1 if job switches 1 and 8 are 0 and job switches 4, 5 and 6 are 1;
otherwise, &A is set to 0.
v To the value produced by the built-in function %BIN (see “Using the %BINARY
Built-In Function” on page 41 for more information):
CHGVAR VAR(&A) VALUE(%BIN((%B 1 4))
The first four characters of variable &B are converted to the decimal equivalent
and stored in decimal variable &A
The CHGVAR command can be used to retrieve and to change the local data area
also. For example, the following commands blank out 10 bytes of the local data
area and retrieve part of the local data area:
Chapter 2. CL Programming 27
CHGVAR %SST(*LDA 1 10) ' '
For a logical variable, the value to which the variable is to be changed must be a
logical value. For decimal variables, a decimal or character value can be used. For
character variables, either character or decimal values are accepted.
When specifying a decimal value for a character variable, remember the following:
v The value of the character variable is right-justified and, if necessary, padded
with leading zeros.
v The character variable must be long enough to contain a decimal point and a
minus (-) sign, when necessary.
v When used, a minus (-) sign is placed in the leftmost position of the value.
For example, &A is a character variable to be changed to the value of the decimal
variable &B The length of &A is 6. The length and decimal positions of &B are 5
and 2, respectively. The current value of &B is 123. The resulting value of &A is
123.00.
When specifying a character value for a decimal variable, remember the following:
v The decimal point is determined by the placement of a decimal point in the
character value. If the character value does not contain a decimal point, the
decimal point is placed in the rightmost position of the value.
v The character value can contain a minus (-) sign or plus (+) sign immediately to
the left of the value; no intervening blanks are allowed. If the character value has
no sign, the value is assumed to be positive.
v If the character value contains more characters to the right of the decimal point
than can be contained in the decimal variable, the characters are truncated.
However, if the excess characters are to the left of the decimal point, they are
not truncated and an error occurs.
For example, &C is a decimal variable to be changed to the value of the
character variable &D The length of &C is 5 with 2 decimal positions. The length
of &D is 10 and its current value is +123.1bbbb (where b=blank). The resulting
value of &C is 123.10.
When this condition could occur, the desired result can be attained for these
parameters by constructing a command string that delimits the parameter value with
apostrophes and passing the string to QCMDEXC or QCAPCMD for processing.
Note: If you use VARY(*YES) and RTNVAL(*YES) and are passing a CL variable,
the length of the variable is passed rather than the length of the data in the
CL variable.
The starting comment delimiter, /*, requires three characters unless the /*
characters appear in the first two positions of the command string. In the latter
situation, /* can be used without a following blank before a command.
You can enter the three-character starting comment delimiters in any of the
following ways (b represents a blank):
Chapter 2. CL Programming 29
/*b
b/*
/**
Therefore, the starting comment delimiter can be entered four ways. The starting
comment delimiter, /*, can:
v Begin in the first position of the command string
v Be preceded by a blank
v Be followed by a blank
v Be followed by an asterisk (/**).
For example, in the following procedure, comments are written to describe possible
user responses to a set of menu options:
The label in this example is START. A label can have as many as 10 characters and
must be immediately followed by a colon, but blanks can occur between the label
and the command name.
The command includes an expression, which is tested (true or false), and a THEN
parameter that specifies the action to be taken if the expression is true. The IF
command is formatted as follows:
IF COND(logical-expression) THEN(CL-command)
The logical expression on the COND parameter may be a single logical variable or
constant, or it must describe a relationship between two or more operands; the
expression is then evaluated as true or false. See “Using the *AND, *OR, and *NOT
Operators” on page 37 for more detailed information on the construction of logical
expressions.
Chapter 2. CL Programming 31
If the condition described by the logical expression is evaluated as true, the
procedure processes the CL command on the THEN parameter. This may be a
single command, or a group of commands (see “Using the DO Command and DO
Groups” on page 33). If the condition is not true, the procedure runs the next
sequential command.
Both COND and THEN are keywords on the command, and they can be omitted for
positional entry. The following are syntactically correct uses of this command:
IF COND(&RESP=1) THEN(CALL CUS210)
IF (&A *EQ &B) THEN(GOTO LABEL)
IF (&A=&B) GOTO LABEL
Blanks are required between the command name (IF) and the keyword (COND) or
value (&A..). No blanks are permitted between the keyword, if specified, and the left
parenthesis enclosing the value.
In this case, the procedure processes the first IF command before branching to
FINAL, skipping the intermediate code. It does not return to the second IF
command. At FINAL, because the test for &C=5:; fails, PROGA is not called. The
procedure then processes the next command, ENDPGM, which signals the end of
the procedure, and returns control to the calling procedure.
Processing logic would be different if, using the same code, the initial values of the
variables were different. For instance, if at the beginning of this code the value of
&A is 3 and the value of &C is 4, the first IF statement is evaluated as false.
Instead of processing the GOTO FINAL command, the procedure ignores the first IF
statement and moves on to the next one. The second IF statement is evaluated as
true, and the value of &C is changed to 5. Subsequent statements, not shown here,
are also processed consecutively. When processing reaches the last IF statement,
the condition &C=5; is evaluated as true, and PROGA is called.
If, in this example, &A is not equal to &B,; the next statement is run. If &C is equal
to &D, PGMA is called. When PGMA returns, the third IF statement is considered,
and so on. Note the difference in logic and processing between these simple
sequential IF statements and the use of IF with ELSE or the use of embedded IF
commands described later in the chapter (see “Using the ELSE Command” on
page 34 and “Using Embedded IF Commands” on page 36).
Do Group
RV2W272-0
If the logical expression (&A=&B) is true, then the Do group is processed. If the
expression is not true, then processing starts after the ENDDO command; the Do
group is skipped.
Chapter 2. CL Programming 33
In the following procedure, if &A is not equal to &B, the system calls PROCB.
PROCA is not called, nor are any other commands in the Do group processed.
Do Group
RV3W198-0
There are three levels of nesting in the following example. Note how each Do group
is completed by an ENDDO command.
RV3W199-0
In this example, if &A in the first nest does not equal 5, PGMC is called. If &A does
equal 5, the statements in the second Do group are processed. If &AREA in the
second Do group does not equal YES, procedure ACCTSPAY is called, because
processing moves to the next command after the Do group.
| The CL compiler does not indicate the beginning or ending of Do groups. If the CL
| compiler notes any unbalanced conditions, it is not easy to detect the actual errors.
In this case, PROCA is called only if &A=&B;, but PROCB is always called.
The real usefulness of the ELSE command is best demonstrated when combined
with Do groups. In the following example, the Do group may not be run, depending
on the evaluation of the IF expression, but the remaining commands are always
processed.
RSLF157-0
With the ELSE command you can specify that a command or set of commands be
processed only if the expression is not true, thus completing the logical alternatives:
Each ELSE command must have an associated IF command preceding it. If nested
levels of IF commands are present, each ELSE command is matched with the
innermost IF command that has not already been matched with another ELSE
command.
IF ... THEN ...
IF ...THEN(DO)
IF ...THEN(DO)
.
.
.
ENDDO
ELSE DO
IF ...THEN(DO)
.
.
.
Chapter 2. CL Programming 35
ENDDO
ELSE DO
.
.
.
ENDDO
ENDDO
ELSE IF ... THEN ...
IF ... THEN ...
IF ... THEN ...
In reviewing your procedure for matched ELSE commands, always start with the
innermost set.
The ELSE command can be used to test a series of mutually exclusive options. In
the following example, after the first successful IF test, the embedded command is
processed and the procedure processes the RCLRSC command:
IF COND(&OPTION=1) THEN(CALLPRC PRC(ADDREC))
ELSE CMD(IF COND(&OPTION=2) THEN(CALLPRC PRC(DSPFILE)))
ELSE CMD(IF COND(&OPTION=3) THEN(CALLPRC PRC(PRINTFILE)))
ELSE CMD(IF COND(&OPTION=4) THEN(CALLPRC PRC(DUMP)))
RCLRSC
RETURN
This can be useful when several conditions must be satisfied before a certain
command or group of commands is run. In the preceding example, if the first
expression is true, the system then reads the first THEN parameter; within that, if
the &C=&D; expression is evaluated as true, the system processes the command in
the second THEN parameter, GOTO END. Both expressions must be true to
process the GOTO END command. If one or the other is false, the GOTO START
command is run. Note the use of parentheses to organize expressions and
commands.
As the levels of embedding increase and logic grows more complex, you may wish
to enter the code in free-form design to clarify relationships:
PGM
DCL &A *DEC 1
DCL &B *CHAR 2
DCL &RESP *DEC 1
IF (&RESP=1) +
IF (&A=5) +
IF (&B=NO) THEN(DO)
.
.
.
ENDDO
CHGVAR &A VALUE(8)
CALL PGM(DAILY)
ENDPGM
Here, if all conditions are true, the SNDPGMMSG command is processed, followed
by the CHGVAR command. If the first and second conditions (&RESP=1; and &A=5)
are true, but the third (&B=NO) is false, PROCA is called; when PROCA returns, the
CHGVAR command is processed. If the second conditions fails, PROCB is called
(&B=NO is not tested), followed by the CHGVAR command. Finally, if &RESP does
not equal 1, the CHGVAR command is immediately processed. The ELSE
command has been used to provide a different branch for each test.
Note: The following three examples are correct syntactical equivalents to the
embedded IF command in the preceding example:
IF (&RESP=1) THEN(IF (&A=5) THEN(IF (&B=NO) THEN(DO)))
IF (&RESP=1) THEN +
(IF (&A=5) THEN +
(IF (&B=NO) THEN(DO)))
IF (&RESP=1) +
(IF (&A=5) +
(IF (&B=NO) THEN(DO)))
Chapter 2. CL Programming 37
either side of the operator) have to be true to produce a true result. The *OR
operator indicates that one or the other of its operands must be true to produce a
| true result.
| Note: Using the ampersand symbol or the vertical bar can cause problems
| because the symbols are not at the same code point for all code pages. To
| avoid this, use *AND and *OR instead of the symbols.
In each of these cases, the logical expression consists of three parts: two operands
and one operator (*AND or *OR, or their symbols). It is the type of operator (*AND
or *OR) that characterizes the expression as logical, not the type of operand.
Operands in logical expressions can be logical variables or other expressions, such
as relational expressions. (Relational expressions are characterized by >, <, or =
symbols or corresponding reserved values.) For instance, in the example:
((&C *LT 1) *AND (&TIME *GT 1430))
the entire logical expression is enclosed in parentheses, and both operands are
relational expressions, also enclosed separately in parentheses. As you can see
from the second example of logical expressions, the operands need not be
enclosed in separate parentheses, but it is recommended for clarity. Parentheses
are not needed because *AND and *OR have different priorities. *AND is always
considered before *OR. For operators of the same priority, parentheses can be
used to control the order in which operations are performed.
If you wish to specify more than one condition, you can use a logical expression
with relational expressions as operands:
IF ((&A=&B) *AND (&C=&D)) THEN(DO)
.
.
.
ENDDO
Here the logical operators are again used between relational expressions.
Because a logical expression can also have other logical expressions as operands,
quite complex logic is possible:
IF (((&A=&B) *OR (&A=&C)) *AND ((&C=1) *OR (&D='0'))) THEN(DO)
The result of the evaluation of any relational or logical expression is a ’1’ or ’0’ (true
or false). The dependent command is processed only if the complete expression is
evaluated as true (’1’). The following command is interpreted in these terms:
IF ((&A = &B) *AND (&C = &D)) THEN(DO)
The expression is finally evaluated as not true (’0’), and, therefore, the DO is not
processed. For an explanation of how this evaluation was reached, see the
matrices later in this section.
This same process is used to evaluate a logical expression using logical variables,
as in this example:
PGM
DCL &A *LGL
DCL &B *LGL
IF (&A *OR &B) THEN(CALL PGM(PGMA))
.
.
.
ENDPGM
Here the conditional expression is evaluated to see if the value of &A or of &B is
equal to ’1’ (true). If either is true, the whole expression is true, and PGMA is called.
The final evaluation arrived at for all these examples of logical expressions is based
on standard matrices comparing two values (referred to here as &A and &B) under
an *OR or *AND operator.
Use the following matrix when using *OR with logical variables or constants:
If &A is:
’0’ ’0’ ’1’ ’1’
and &B is:
’0’ ’1’ ’0’ ’1’
Chapter 2. CL Programming 39
the OR expression is:
’0’ ’1’ ’1’ ’1’
Here the values are not all false; therefore, the expression is true, and PGMA is
called.
Use the following matrix when evaluating a logical expression with *AND with
logical variables or constants:
If &A is:
’0’ ’0’ ’1’ ’1’
and &B is:
’0’ ’1’ ’0’ ’1’
For multiple AND operators with logical variables or constants, the expression is
false (’0’) when any value is false, and true when they are all true.
PGM
DCL &A *LGL VALUE('0')
DCL &B *LGL VALUE('1')
DCL &C *LGL VALUE('1')
IF (&A *AND &B *AND &C) THEN(CALL PGMA)
.
.
.
ENDPGM
Here the values are not all true; therefore, the expression is false, and PGMA is not
called.
These logical operators can only be used within an expression when the operands
represent a logical value, as in the preceding examples. It is incorrect to attempt to
use OR or AND for variables that are not logical. For instance:
PGM
DCL &A *CHAR 3
DCL &B *CHAR 3
DCL &C *CHAR 3
The logical operator *NOT (or ¬) is used to negate logical variables or constants.
Any *NOT operators must be evaluated before the *AND or *OR operators are
evaluated. Any values that follow *NOT operators must be evaluated before the
logical relationship between the operands is evaluated.
PGM
DCL &A *LGL '1'
DCL &B *LGL '0'
IF (&A *AND *NOT &B) THEN(CALL PGMA)
In this example, the values are all true; therefore, the expression is true, and PGMA
is called.
PGM
DCL &A *LGL
DCL &B *CHAR 3 VALUE('ABC')
DCL &C *CHAR 3 VALUE('XYZ')
CHGVAR &A VALUE(&B *EQ &C)
IF (&A) THEN(CALLPRC PROCA)
For more information about logical and relational expressions, see the CL
Reference (Abridged) book.
or
%BIN(character-variable-name starting-position length)
| The starting position and length are optional. However, if the starting position and
| length are not specified, a starting position of 1 and length of the character variable
| that is specified are used. In that case, you must declare the length of the character
| variable as either 2 or 4.
If the starting position is specified, you must also specify a constant length of 2 or
4. The starting position must be a positive number equal to or greater than 1. If the
sum of the starting position and the length is greater than the length of the
character variable, an error occurs. (A CL decimal variable may also be used for the
starting position.)
You can use the binary built-in function with both the IF and CHGVAR commands. It
can be used by itself or as part of an arithmetic or logical expression. You can also
use the binary built-in function on any command parameter that is defined as
numeric (TYPE of *DEC, *INT2, or *INT4) with EXPR(*YES).
Chapter 2. CL Programming 41
When the binary built-in function is used with the condition (COND) parameter on
the IF command or with the VALUE parameter on the Change Variable (CHGVAR)
command, the contents of the character variable is interpreted as a
binary-to-decimal conversion.
When the binary built-in function is used with the VAR parameter on the CHGVAR
command, the decimal value in the VALUE parameter is converted to a 2-byte or
4-byte signed binary integer and the result stored in the character variable at the
starting position specified. Decimal fractions are truncated.
| The system uses the binary built-in function on the RTNVAL parameter of the
| CALLPRC command to indicate that the calling procedure expects the called
| procedure to return a signed binary integer.
A 2-byte character variable can hold signed binary integer values from -32 768
through 32 767. A 4-byte character variable can hold signed binary integer values
from -2 147 483 648 through 2 147 483 647.
The contents of variable &B2 is treated as a 2-byte signed binary integer and
converted to its decimal equivalent of 28. It is then assigned to the decimal
variable &N
v
DCL VAR(&N) TYPE(*DEC) LEN(5 0) VALUE(107)
DCL VAR(&B4) TYPE(*CHAR) LEN(4)
CHGVAR %BIN(&B4) &N
The value of the decimal variable &N is converted to a 4-byte signed binary
number and is placed in character variable &B4 Variable &B4 will have the value
of X'0000006B'.
v
DCL VAR(&P) TYPE(*CHAR) LEN(100)
DCL VAR(&L) TYPE(*DEC) LEN(5 0)
CHGVAR &L VALUE(%BIN(&P 1 2) * 5)
The first two characters of variable &P is treated as a signed binary integer,
converted to its decimal equivalent, and multiplied by 5. The product is assigned
to the decimal variable &L
v
DCL VAR(&X) TYPE(*CHAR) LEN(50)
CHGVAR %BINARY(&X 15 2) VALUE(122.56)
The number 122.56 is truncated to the whole number 122 and is then converted
to a 2-byte signed binary integer and is placed at positions 15 and 16 of the
character variable &X Positions 15 and 16 of variable &X will contain the
hexadecimal equivalent of X'007A'.
v
DCL VAR(&B4) TYPE(*CHAR) LEN(4)
CHGVAR %BIN(&B4) VALUE(-57)
The contents of variable &B2 is treated as a 2-byte signed binary integer and
converted to its decimal equivalent of -229. The number is converted to character
form and stored in the variable character &C5 The character variable &C5 will
then contain the value ‘-0229&csq.
v
DCL VAR(&C5) TYPE(*CHAR) LEN(5) VALUE(' 1253')
DCL VAR(&B2) TYPE(*CHAR) LEN(2)
CHGVAR %BINARY(&B2) VALUE(&C5)
The first 2 bytes of the character variable &S are treated as a signed binary
integer when compared to the number 10. If the binary number has a value
larger than 10, then the SNDPGMMSG (Send Program Message) command is
run.
v
DCL VAR(&RTNV) TYPE(*CHAR) LEN(4)
CALLPRC PRC(PROCA) RTNVAL(%BIN(&RTNV 1 4))
or
%SST(character-variable-name starting-position length)
You can code *LDA in place of the character variable name to indicate that the
substring function is performed on the contents of the local data area.
Chapter 2. CL Programming 43
The substring function produces a substring from the contents of the specified CL
character variable or the local data area. The substring begins at the specified
starting position (which can be a variable name) and continues for the length
specified (which can also be a variable name). Neither the starting position nor the
length can be 0 or negative. If the sum of the starting position and the length of the
substring are greater than the length of the entire variable or the local data area, an
error occurs. The length of the local data area is 1024.
If the length of the substring is shorter than the operand, the substring is padded
with blanks for the comparison. For example:
DCL VAR(&NAME) TYPE(*CHAR) LEN(5) VALUE(YESNO)
.
.
.
IF (%SST(&NAME 1 3 ) *EQ YESNO) THEN(CALL PROG)
This condition is false because YESbb (where bb is two blanks) does not equal
YESNO.
v The value of the variable &A is placed into positions 1 through 10 of the local
data area.
CHGVAR %SST(*LDA 1 10) &A
v If the concatenation of positions 1 through 3 of the local data area plus the
constant ’XYZ’ is equal to variable &A, then PROCA is called. For example, if
The following procedure uses the substring built-in function to find the first sentence
in a 50-character field &INPUT and to place any remaining text in a field
&REMAINDER It assumes that a sentence must have at least 2 characters, and no
embedded periods.
PGM (&INPUT &REMAINDER) /* SEARCH */
DCL &INPUT *CHAR LEN(50)
DCL &REMAINDER *CHAR LEN(50)
DCL &X *DEC LEN(2 0) VALUE(03)
DCL &L *DEC LEN(2 0) /* REMAINING LENGTH */
SCAN: IF (%SST(&INPUT &X 1) *EQ '.') THEN(DO)
CHGVAR VAR(&L) VALUE(50-&X)
CHGVAR VAR(&X) VALUE(&X+1)
CHGVAR VAR(&REMAINDER) VALUE(%SST(&INPUT &X &L))
RETURN
ENDDO
IF (&X *EQ 49) THEN(RETURN)
CHGVAR &X (&X+1)
GOTO SCAN
ENDPGM
The procedure starts by checking the third position for a period. Note that the
substring function checks &INPUT from position 3 to a length of 1, which is position
3 only (length cannot be zero). If position 3 is a period, the remaining length of
&INPUT is calculated. The value of &X is advanced to the beginning of the
remainder, and the remaining portion of &INPUT is moved to &REMAINDER
If position 3 is not a period, the procedure checks to see if it is at position 49. If so,
it assumes that position 50 is a period and returns. If it is not at position 49, the
procedure advances &X to position 4 and repeats the process.
If, in the comparison of your %SWITCH values against the job values, every switch
is the same, a logical value of ’1’ (true) is returned. If any switch tested does not
have the value indicated, the result is a ’0’ (false).
Chapter 2. CL Programming 45
The syntax of the %SWITCH built-in function is:
%SWITCH(8-character-mask)
The 8-character mask is used to indicate which job switches are to be tested, and
what value each switch is to be tested for. Each position in the mask corresponds
with one of the eight job switches in a job. Position 1 corresponds with job switch 1,
position 2 with switch 2, and so on. Each position in the mask can be specified as
one of three values: 0, 1, or X.
0 The corresponding job switch is to be tested for a 0 (off).
1 The corresponding job switch is to be tested for a 1 (on).
X The corresponding job switch is not to be tested. The value in the switch
does not affect the result of %SWITCH.
If %SWITCH(0X111XX0) is specified, job switches 1 and 8 are tested for 0s; switches
3, 4, and 5 are tested for 1s; and switches 2, 6, and 7 are not tested. If each job
switch contains the value (1 or 0 only) shown in the mask, the result of %SWITCH
is true ’1’.
Switches can be tested in a CL procedure to control the flow of the procedure. This
function is used in CL procedures with the IF and CHGVAR commands. Switches
can be changed in a CL procedure by the Change Job (CHGJOB) command. For
CL procedures, these changes take effect immediately.
PGM /* CONTROL */
IF (%SWITCH(11XXXXXX)) CALLPRC PROCA
IF (%SWITCH(10XXXXXX)) CALLPRC PROCB
IF (%SWITCH(01XXXXXX)) CALLPRC PROCC
IF (%SWITCH(00XXXXXX)) CALLPRC PROCD
ENDPGM
PGM /* PROCA */
CALLPRC TRANS
IF (%SWITCH(1XXXXXXX)) CALLPRC CUS520
ELSE CALLPRC CUS521
ENDPGM
Using the Monitor Message (MONMSG) command, you can direct a procedure to
take predetermined action if specific errors occur during the processing of the
immediately preceding command. The MONMSG command is used to monitor for
escape, notify, or status messages sent to the call stack of the procedure in which
the MONMSG command is used. The MONMSG command has the following
parameters:
MONMSG MSGID(message-identifier) CMPDTA(comparison-data) +
EXEC(CL-command)
Each message that is sent for a specific error has a unique identifier. You can enter
as many as 50 message identifiers on the MSGID parameter. (See On—line help
for messages and identifiers). The CMPDTA parameter allows even greater
specification of error messages because you can check for a specific character
string in the MSGDTA portion of the message. On the EXEC parameter, you can
specify a CL command (such as a Call Program (CALL), Do (DO), or a Go To
(GOTO)), which directs the procedure to perform error recovery.
In the following example, the MONMSG command follows the Receive File (RCVF)
command and, therefore, is only monitoring for messages sent by the RCVF
command:
READLOOP: RCVF /* Read a file record */
MONMSG MSGID(CPF0864) EXEC(GOTO CMDLBL(EOF))
/* Process the file record */
GOTO CMDLBL(READLOOP) /* Get another record */
EOF: /* End of file processing */
The escape message, CPF0864, is sent to the procedure’s invocation queue when
there are no more records in the file to read. Because the example specifies
MSGID(CPF0864), the MONMSG monitors for this condition. When it receives the
message, the GOTO CMDLBL(EOF) command is run.
You can also use the MONMSG command to monitor for messages sent by any
command in a CL procedure. The following example includes two MONMSG
Chapter 2. CL Programming 47
commands. The first MONMSG command monitors for the messages CPF0001 and
CPF1999; these messages might be sent by any command run later in the
procedure. When either message is received from any of the commands running in
the procedure, control branches to the command identified by the label EXIT2.
The second MONMSG command monitors for the messages CPF2105 and
MCH1211. Because no command is coded for the EXEC parameter, these
messages are ignored.
PGM
DCL
MONMSG MSGID(CPF0001 CPF1999) EXEC(GOTO EXIT2)
MONMSG MSGID(CPF2105 MCH1211)
.
.
.
ENDPGM
Message CPF0001 states that an error was found in the command that is identified
in the message itself. Message CPF1999, which can be sent by many of the
debugging commands, such as Change Program Variable (CHGPGMVAR), states
that errors occurred on the command, but it does not identify the command in the
message.
All error conditions monitored for by the MONMSG command with the EXEC
parameter specified (CPF0001 or CPF1999) are handled in the same way at EXIT2,
and it is not possible to return to the next sequential statement after the error. You
can avoid this by monitoring for specific conditions after each command and
branching to specific error correction procedures.
All error conditions monitored for by the MONMSG command without the EXEC
parameter specified (CPF2105 or MCH1211) are ignored, and procedure processing
continues with the next command.
If the error occurs when evaluating the expression on an IF command, the condition
is considered false. In the following example, MCH1211 (divide by zero) could occur
on the IF command. The condition would be considered false, and PROCA would
be called.
IF(&A / &B *EQ 5) THEN(DLTF ABC)
ELSE CALLPRC PROCA
If you code the MONMSG command at the beginning of your CL procedure, the
messages you specify are monitored throughout the program, regardless of which
command produces these messages. If the EXEC parameter is used, only the
GOTO command can be specified.
Because many escape messages can be sent to a procedure, you must decide
which ones you want to monitor for and handle. Most of these messages are sent
to a procedure only if there is an error in the procedure. Others are sent because of
conditions outside the procedure. Generally, a CL procedure should monitor for
those messages that pertain to its basic function and that it can handle
appropriately. For all other messages, OS/400 assumes an error has occurred and
takes appropriate default action.
You can bring system values into your procedure and manipulate them as variables
using the Retrieve System Value (RTVSYSVAL) command:
RTVSYSVAL SYSVAL(system-value-name) RTNVAR(CL-variable-name)
The RTNVAR parameter specifies the name of the variable in your CL procedure
that is to receive the value of the system value.
The type of the variable must match the type of the system value. For character
and logical system values, the length of the CL variable must equal the length of
the value. For decimal values, the length of the variable must be greater than or
equal to the length of the system value. System value attributes are defined in the
Work Management book.
ENDDO
ENDPGM
See the Work Management book for a list of system values and how you can
change and display them.
Chapter 2. CL Programming 49
System Value QDATE
In many applications, you may want to use the current date in your procedure by
retrieving the system value QDATE and placing it in a variable. You may also want
to change the format of that date for use in your procedure. To convert the format of
a date in a CL procedure, use the Convert Date (CVTDAT) command.
The format for the system date is the system value QDATFMT, which is initially
MDY (monthdayyear). For example, 062488 is the MDY format for June 24 1988.
You can change this format to the YMD, DMY, or the JUL (Julian) format. For
Julian, the QDAY value is a 3-character value from 001 to 366. It is used to
determine the number of days between two dates. You can also delete the date
separators or change the character used as a date separator with the CVTDAT
| command.
The CVTDAT command can be useful when creating objects or adding a member
that uses a date as part of its name. For example, assume that a member must be
added to a file using the current system date. Also, assume that the current date is
in the MDY format and is to be converted to the Julian format.
PGM
DCL &DATE6 *CHAR LEN(6)
DCL &DATE5 *CHAR LEN(5)
RTVSYSVAL QDATE RTNVAR(&DATE6)
CVTDAT DATE(&DATE6) TOVAR(&DATE5) TOFMT(*JUL) TOSEP(*NONE)
ADDPFM LIB1/FILEX MBR('MBR' *CAT &DATE5)
.
.
.
ENDPGM
If the current date is 5 January 1988, the added member would be named
MBR88005.
Error messages are sent for converted characters that do not fit in the variable. If
the converted date is shorter than the variable, it is padded on the right with
blanks.
| v In every date format except Julian, the month and day are 2-byte fields no matter
| what value they contain. The year may be either 2-byte or 4-byte fields. All
| converted values are right-justified and, when necessary, padded with leading
| zeros.
| v In the Julian format, day is a 3-byte field, and year is a 2-byte or 4-byte field. All
| converted values are right-justified and, when necessary, padded with leading
| zeros.
The following is an alternative program that uses the ILE bindable API, Get Current
Local Time (CEELOCT), to convert a date to Julian format. To create this program,
you must use the CRTBNDCL command alone or the CRTCLMOD command and
the CRTPGM command together.
PGM
DCL &LILDATE *CHAR LEN(4)
DCL &PICTSTR *CHAR LEN(5) VALUE(YYDDD)
DCL &JULDATE *CHAR LEN(5)
DCL &SECONDS *CHAR 8 /* Seconds from CEELOCT */
DCL &GREG *CHAR 23 /* Gregorian date from CEELOCT */
/* */
CALLPRC PRC(CEELOCT) /* Get current date and time */ +
PARMS (&LILDATE) /* Date in Lilian format */ +
&SECONDS /* Seconds field will not be used */
&GREG /* Gregorian field will not be used */
*OMIT /* Omit feedback parameter so exceptions +
are signalled */
CALLPRC PRC(CEEDATE) +
PARMS (&LILDATE) /* Today's date */ +
&PICTSTR /* How to format */ +
&JULDATE /* Julian date */ +
*OMIT
Chapter 2. CL Programming 51
ADDPGM LIB1/FILEX MBR('MBR' *CAT &JULDATE')
ENDPGM
See the System API Reference book, SC41-4801, for more information on ILE
API’s.
RTVNETA Example
In the following example, the default network output queue and the library that
contains it are retrieved, changed to QGPL/QPRINT, and later changed back to the
previous value.
PGM
DCL VAR(&OUTQNAME) TYPE(*CHAR) LEN(10)
DCL VAR(&OUTQLIB) TYPE(*CHAR) LEN(10)
RTVNETA OUTQ(&OUTQNAME) OUTQLIB(&OUTQLIB)
CHGNETA OUTQ(QGPL/QPRINT)
.
.
.
CHGNETA OUTQ(&OUTQLIB/&OUTQNAME)
ENDPGM
The variable &CLKNAM, in which the user name is to be passed, is first declared
using a DCL command. The RTVJOBA command follows the declare commands.
When the program ORD410S2 is called, two variables, &NXTPGM and &CLKNAM,
are passed to it. &NXTPGM is passed as blanks but could be changed by
ORD410S2.
RTVJOBA Example
Assume in the following CL procedure, an interactive job submits a program
including the CL procedure to batch. A Retrieve Job Attributes (RTVJOBA)
command retrieves the name of the message queue to which the job’s completion
message is sent, and uses that message queue to communicate with the user who
submitted the job.
PGM
DCL &MSGQ *CHAR 10
DCL &MSGQLIB *CHAR 10
DCL &MSGKEY *CHAR 4
DCL &REPLY *CHAR 1
DCL &ACCTNO *CHAR 6
.
.
.
RTVJOBA SBMMSGQ(&MSGQ) SBMMSGQLIB(&MSGQLIB)
IF (&MSGQ *EQ '*NONE') THEN(DO)
CHGVAR &MSGQ 'QSYSOPR'
CHGVAR &MSGQLIB 'QSYS'
ENDDO
.
.
.
IF (. . . ) THEN(DO)
SNDMSG:SNDPGMMSG MSG('Account number ' *CAT &ACCTNO *CAT 'is +
not valid. Do you want to cancel the update +
(Y or N)?') TOMSGQ(&MSGQLIB/&MSGQ) MSGTYPE(*INQ) +
KEYVAR(&MSGKEY)
RCVMSG MSGQ(*PGMQ) MSGTYPE(*RPY) MSGKEY(&MSGKEY) +
MSG(&REPLY) WAIT(*MAX)
IF (&REPLY *EQ 'Y') THEN(RETURN)
ELSE IF (&REPLY *NE 'N') THEN(GOTO SNDMSG)
Chapter 2. CL Programming 53
ENDDO
.
.
.
Two variables, &MSGQ and &MSGQLIB, are declared to receive the name and
library of the message queue to be used. The RTVJOBA command is used to
retrieve the message queue name and library name. Because it is possible that a
message queue is not specified for the job, the message queue name is compared
to the value *NONE. If the comparison is equal, no message queue is specified,
and the variables are changed so that message queue QSYSOPR in library QSYS
is used. Later in the procedure, when an error condition is detected, an inquiry
message is sent to the specified message queue and the reply is received and
processed. Some of the other possible uses of the RTVJOBA command are:
v Retrieve one or more of the job attributes (such as output queue, library list) so
that they can be changed temporarily and later restored to their original values.
v Retrieve one or more of the job attributes for use in the SBMJOB command, so
that the submitted job will have the same attributes as the submitting job.
You can also use the Retrieve Object Description (QUSROBJD) application
programming interface (API) to return the description of a specific object to a
procedure. A variable is used to return the descriptions. For more information, see
the System API Reference book.
You can also monitor for escape messages after running the RTVUSRPRF
command. See the CL Reference (Abridged) book for a list of the messages that
could be sent.
RTVUSRPRF Example
In the following CL procedure, a RTVUSRPRF command retrieves the name of the
user who called the procedure and the name of a message queue to which to send
messages for that user:
DCL &USR *CHAR 10
DCL &USRMSGQ *CHAR 10
DCL &USRMSGQLIB *CHAR 10
.
.
.
RTVUSRPRF USRPRF(*CURRENT) RTNUSRPRF(&USR) +
MGSQ(&USRMSGQ) MSGQLIB(&USRMSGQLIB)
RTVMBRD Example
In the following CL procedure, a RTVMBRD command retrieves the description of a
specific member. Assume a database file called MFILE exists in the current library
(MYLIB) and contains 3 members (AMEMBER, BMEMBER, and CMEMBER).
DCL &LIB TYPE(*CHAR) LEN(10)
DCL &MBR TYPE(*CHAR) LEN(10)
DCL &SYS TYPE(*CHAR) LEN(4)
DCL &MTYPE TYPE(*CHAR) LEN(5)
DCL &CRTDATE TYPE(*CHAR) LEN(13)
DCL &CHGDATE TYPE(*CHAR) LEN(13)
DCL &TEXT TYPE(*CHAR) LEN(50)
DCL &NBRRCD TYPE(*DEC) LEN(10 0)
DCL &SIZE TYPE(*DEC) LEN(10 0)
DCL &USEDATE TYPE(*CHAR) LEN(13)
DCL &USECNT TYPE(*DEC) LEN(5 0)
DCL &RESET TYPE(*CHAR) LEN(13)
.
.
.
RTVMBRD FILE(*CURLIB/MYFILE) MBR(AMEMBER *NEXT) +
RTNLIB(&LIB) RTNSYSTEM(&SYS) RTNMBR(&MBR) +
FILEATR(&MTYPE) CRTDATE(&CRTDATE) TEXT(&TEXT) +
NBRCURRCD(&NBRRCD) DTASPCSIZ(&SIZE) USEDATE(&USEDATE) +
USECOUNT(&USECNT) RESETDATE(&RESET)
Chapter 2. CL Programming 55
v The date that BMEMBER was last used is placed into the CL variable called
&USEDATE
v The number of days that BMEMBER has been used is placed into the CL
variable called &USECNT The start date of this count is the value placed into the
CL variable called &RESET
To create a CL program in one step, you can use the CRTBNDCL command and
create a bound program with one module.
You can also create a module with the CRTCLMOD command. The module must
then be bound into a program or service program using the Create Program
(CRTPGM) or Create Service Program (CRTSRVPGM) command.
The following CRTCLMOD command creates the module ORD040C and places it in
library DSTPRODLB:
CRTCLMOD MODULE(DSTPRODLB/ORD040C) SRCFILE(QCLSRC)
TEXT('Order dept general menu program')
The source commands for ORD040C are in the source file QCLSRC, and the
source member name is ORD040C. By default, a compiler list is created.
On the CRTBNDCL command, you can specify list options and whether the
program should operate under the program owner’s user profile.
A program can run using either the owner’s user profile or the user’s user profile.
Because these values are part of the CRTCLMOD and CRTBNDCL commands, you
must recompile the module or program to change them.
Not all commands are logged to the job log. Following is a list of commands that
are not logged:
CHGVAR DO GOTO
DCL ELSE IF
DCLF ENDDO MONMSG
PGM ENDPGM CALLPRC
If the logging option is on, logging messages are sent to the CL procedure’s
message queue. If the CL procedure is running interactively, and the message level
on the job’s LOG parameter is set to 4, you can press F10 (Display detail
messages) to view the logging of all commands. You can print the log if the
message level is 4 and you specify *PRINT when you sign off.
The log includes the time, program and procedure names, message texts, and
command names. Command names are qualified as they are on the original source
statement. Command parameters are also logged; if the parameter information is a
CL variable, the contents of the variable are printed (except for the RTNVAL
parameter).
The list created by specifying the OUTPUT parameter is called a compiler list. The
following shows a sample compiler list. The callout numbers refer to descriptions
following the list.
1
2
3
5763SS1 V3R1M0 940909 Control Language MYLIB/DUMPERR 05/06/94 11:12:55 Page 1
Program . . . . . . . . . . . . . . . . . . . : DUMPERR
Library . . . . . . . . . . . . . . . . . . : MYLIB
Source file . . . . . . . . . . . . . . . . . : QCLSRC
Library . . . . . . . . . . . . . . . . . . : MYLIB
Source member name . . . . . . . . . . . . . : DUMPERR 05/06/94 10:42:26 4
Source printing options . . . . . . . . . . . : *XREF *NOSECLVL *NOEVENTF
User profile . . . . . . . . . . . . . . . . : *USER
Program logging . . . . . . . . . . . . . . . : *JOB
Default activation group . . . . . . . . . . : *YES
Chapter 2. CL Programming 57
Replace program . . . . . . . . . . . . . . . : *YES
Target release . . . . . . . . . . . . . . . : V3R1M0
Authority . . . . . . . . . . . . . . . . . . : *LIBCRTAUT
Sort sequence . . . . . . . . . . . . . . . . : *HEX
Language identifier . . . . . . . . . . . . . : *JOBRUN
Text . . . . . . . . . . . . . . . . . . . . : Test program
Optimization . . . . . . . . . . . . . . . . : *NONE
Debugging view . . . . . . . . . . . . . . . : *STMT
Compiler . . . . . . . . . . . . . . . . . . : IBM AS/400 Control Language Compiler 5
6 Control Language Source
SEQNBR *...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7 ...+... 8 ...+... 9 ...+. DATE 8
100- PGM 05/06/94
200- DCL &ABC *CHAR 10 VALUE('THIS') 05/06/94
300- DCL &XYZ *CHAR 10 VALUE('THAT') 7 05/06/94
400- DCL &MNO *CHAR 10 VALUE('OTHER') 05/06/94
500- CRTLIB LB(LARRY) 05/06/94
* CPD0043 30 Keyword LB not valid for this command. 9
600- DLTLIB LIB(MOE 05/06/94
* CPD0013 30 A matching parenthesis not found.
700- MONMSG CPF0000 EXEC(GOTO ERR) 05/06/94
800- ERROR: 05/06/94
900- CHGVAR &ABC 'ONE' 05/06/94
1000- CHGVAR &XYZ 'TWO' 05/06/94
1100- CHGVAR &MNO 'THREE' 05/06/94
1200- DMPCLPGM 05/06/94
1300- ENDPGM 05/06/94
* * * * * E N D O F S O U R C E * * * * *
5763SS1 V3R1M0 940909 Control Language MYLIB/DUMPERR 05/06/94 11:12:55 Page 2
Cross Reference
Declared Variables
Name Defined Type Length References
&ABC 200 *CHAR 10 900
&MNO 400 *CHAR 10 1100
10
&XYZ 300 *CHAR 10 1000
Defined Labels
Label Defined References 11
ERR ****** 700
* CPD0715 30 Label 'ERR ' does not exist.
ERROR 800
* * * * * E N D O F C R O S S R E F E R E N C E * * * * *
5763SS1 V3R1M0 940909 Control Language MYLIB/DUMPERR 05/06/94 11:12:55 Page 3
Message Summary
Severity
Total 0-9 10-19 20-29 30-39 40-49 50-59 60-69 70-79 80-89 90-99 12
3 0 0 0 3 0 0 0 0 0 0
Program DUMPERR not created in library MYLIB. Maximum error severity 30. 13
* * * * * E N D O F M E S S A G E S U M M A R Y * * * * *
* * * * * E N D O F C O M P I L A T I O N * * * * *
Title:
1 The program number, release, modification level and date of OS/400.
2 The date and time of the compiler run.
3 The page number in the list.
Prolog:
| 4 The parameter values specified, (or defaults if not specified), on the
| CRTBNDCL command. If the source is not in a database file, the member
| name, date, and time are omitted.
5 The name of the compiler.
Source:
6 The sequence numbers of lines (records) in the source. A dash following a
sequence number indicates that a source statement begins at that
sequence number. The absence of a dash indicates that a statement is the
continuation of the previous statement.
Comments between source statements are handled like any other source
statement and have sequence numbers.
See the DB2 UDB for AS/400 Database Programming book for information
about how sequence numbers are assigned.
7 The source statements.
8 The last date the source statement was changed or added. If the source is
not in a database file, or the dates have been reset using RGZPFM, the
date is omitted.
9 If an error is found during compilation and can be traced to a specific
source statement, the error message is printed immediately following the
Cross-References:
10 The symbolic variable table is a cross-reference list of the variables validly
declared in the program. The table lists the variable, the sequence number
of the statement where the variable is declared, the variable’s attributes,
and the sequence numbers of statements that refer to the variable.
11 The label table is a cross-reference list of the labels validly defined in the
program. The table lists the label, the sequence number of the statement
where the label is defined, and the sequence numbers of statements that
refer to the label.
Messages:
This section is not included in the sample list because no general error messages
were issued for the sample module. If there were general error messages for this
module, this section would contain, for each message, the message identifier, the
severity, and the message.
Message Summary:
12 A summary of the number of messages issued during compilation. The total
number is given along with totals by severity.
13 A completion message is printed following the message summary.
The title, prologue, source, and message summary sections are always printed for
the *SOURCE option. The cross-reference section is printed if the *XREF option is
specified. The message section is printed only if general errors are found.
The types of errors that are detected at compile time include syntax errors,
references to variables and labels not defined, and missing statements. The
following types of errors stop the procedure from being created (severity codes are
ignored).
v Value errors
v Syntax errors
v Errors related to dependencies between parameters within a command
v Errors detected during validity checking.
Chapter 2. CL Programming 59
Even after an error that stops the procedure from being created is encountered, the
compiler continues to check the source for errors. This lets you see and correct as
many errors as possible before you try to create the module or program again.
| Note: The security officer, or another user with update authority to the
| QCPFMSG file, must enter the CHGMSGD command.
| Changing the message default causes a dump to be printed under any of the
following conditions:
v The system operator message queue is in default mode and the message is sent
from a batch job.
v The display station user presses the Enter key without typing a response,
causing the message default to be used.
v INQMSGRPY(*DFT) is specified for the job.
1
5763SS1 V3R1M0 940909 CL Program Dump 5/24/94 11:05:032 Page 1
Messages
Message 6 Message From To
Time ID Sev Type Text Program Inst Program Inst
110503 CPC2102 00 COMP Library LARRY created. QLICRLIB *N DUMP *N
110503 CPF2110 40 ESC Library MOE not found. QLICLLIB *N DUMP *N
Variables 7
Variable Type Length Value Value in Hexadecimal
*...+....1....+....2....+ * . . . + . . . . 1 . . . . + . . . . 2 . . . . +
&ABC *CHAR 10 'ONE ' D6D5C540404040404040
&XYZ *CHAR 10 'TWO ' E3E6D640404040404040
* * * * * E N D O F D U M P * * * * *
For more information on this command, see the CL Reference (Abridged) book.
For more information on this command, see the CL Reference (Abridged) book.
The following list summarizes the return codes used by languages supported on the
&sys system:
v RPG IV programs
Chapter 2. CL Programming 61
The return codes sent by the RPG IV compiler are:
0 When the program is created
2 When the program is not created
The return code cannot be tested directly by the user in the RPG IV program.
v ILE COBOL/400 programs
The return codes sent by running COBOL/400 programs are:
0 By each CALL statement before a program is called
2 When a program receives a function check (CPF9999) or the generic I/O
exception handler gets control and there is no applicable USE procedure
COBOL/400 programs cannot retrieve these return codes. A return code value of
2 sends message CBE9001 and runs a Reclaim Resources (RCLRSC) command
with the *ABNORMAL option.
v BASIC programs
Compiled or interpreted BASIC programs can set the return code to any value
between -32768 and 32767 by coding an expression on the END or STOP
statements. If no expression is coded, the return codes are set to:
0 For normal completion
1 For programs ending because of an error
BASIC return code values can be retrieved using the CODE intrinsic function.
v PL/I programs
The return codes sent by PL/I programs are:
0 For normal completion, set at the beginning of the run unit
2 When set by a STOP statement or a call to PLIDUMP with the S option
3 When an ERROR condition is raised
4 When PL/I detects an error that did not allow the ERROR condition to be
raised
Pascal does not explicitly set the return code at run time. The user can use the
ONERROR exception handling routine to monitor for particular exceptions, then
set the return code using the RETCODE procedure.
Pascal return codes can be retrieved using the RETVALUE parameter of the
Pascal SYSTEM procedure. The return code is set to 0 before the SYSTEM call
and will contain the updated return code when returned.
v CL program
The current value of the return code for compiled CL programs can be retrieved
using the RTNCDE parameter on the RTVJOBA command.
v C/400* programs
The current value of the integer return code returned by the last C/400 return
statement in a C/400 program.
| When the CL compiler compiles for a supported previous release, it first checks for
| commands and files in the previous-release libraries. When failing to find the
| command or file in the previous-release libraries, the system performs a search of
| the library list (*LIBL) or the qualified library.
| QSYSVxRxMx Libraries: The QSYSVxRxMx libraries install at the same time as the
| CL compiler support for a previous release installs. The QSYSVxRxMx libraries
| include the command definition objects and output files (*OUTFILE) that are found
| in library QSYS for that particular previous release.
Chapter 2. CL Programming 63
QUSRVxRxMx Libraries: You can create your own QUSRVxRxMx libraries to hold
copies of your commands and files as they existed in the supported previous
release. This is especially important if the commands or files have changed on the
current release.
When the compiler looks for previous-release commands and files, it checks the
| QUSRVxRxMx library (if it exists) before checking the QSYSVxRxMx library.
| Do not add previous-release libraries to the library list (*LIBL). They contain
| commands and files that support earlier releases and cannot run on the current
| system. Only the CL compiler refers to and uses the commands and files in the
| previous-release libraries. The system commands that are supplied for a previous
| release are in the primary language for the system. There are no secondary
| national language versions available.
CALL Command
The CALL command calls a program named on the command, and passes control
to it. The CALL command has the following format:
CALL PGM(library-name/program-name) PARM(parameter-values)
The program name or library name may be a variable. If the called program is in a
library that is not on the library list, you must specify the qualified name of the
program on the PGM parameter. The PARM parameter is discussed under “Passing
Parameters between Programs and Procedures” on page 68. When the called
program finishes running, control returns to the next command in the calling
program.
The sequence of CALL commands in a set of programs calling each other is the
call stack. For example, in this series:
When PROGC finishes processing, control returns to PROGB at the command after
the call to PROGC. Control is thus returned up the call stack. This occurs whether
or not PROGC ends with a RETURN or an ENDPGM command.
CALLPRC Command
The CALLPRC command calls a procedure named on the command, and passes
control to it. The CALLPRC command has the following format:
CALLPRC Procedure(procedure-name) PARM(parameter-values) RTNVAL(return-value-variable)
The procedure name may not be a variable. The PARM parameter is discussed
under “Passing Parameters between Programs and Procedures” on page 68. When
the called procedure finishes running, control returns to the next command in the
calling procedure.
PGMA SRVPGMA
┌─────────────────────────────────────────────┐ ┌───────────────────┐
│ │ │ │
│ PROCA ┌──Ê PROCB │ ┌──┼──Ê PROCC │
│ ┌────────────────┐ │ ┌────────────────┐ │ │ │ ┌─────────────┐ │
│ │ . │ │ │ . │ │ │ │ │ . │ │
│ │ . │ │ │ . │ │ │ │ │ . │ │
│ │ . │ │ │ . │ │ │ │ │ . │ │
│ │ CALLPRC PROCB ─┼──┘ │ CALLPRC PROCC ─┼──┼──┘ │ │ . │ │
│ │ . Í───────────┼──┐ │ . Í───────────┼──┼──┐ │ │ . │ │
│ │ . │ │ │ . │ │ │ │ │ . │ │
│ │ . │ │ │ . │ │ │ │ │ . │ │
│ │ ENDPGM │ └──┼─ENDPGM │ │ └──┼──┼─ENDPGM │ │
│ └────────────────┘ └────────────────┘ │ │ └─────────────┘ │
│ │ │ │
└─────────────────────────────────────────────┘ └───────────────────┘
When PROGC finishes processing, control returns to PROGB at the command after
the call to PROGC. Control is thus returned up the call stack. This occurs whether
or not PROGC ends with a RETURN or an ENDPGM command.
RETURN Command
The RETURN command in a CL procedure or OPM program removes that
procedure or OPM program from the call stack.
Note: If you have a RETURN command in an initial program, the command entry
display is shown. You may wish to avoid this for security reasons.
then it calls PROGB and passes the value of &AREA to it. PROGB must start with
the PGM command, which also must specify the parameter it is to receive:
PGM PARM(&AREA) /* PROGB */
For the CALL command or the CALLPRC command, you must specify the
parameters passed on the PARM parameter, and you must specify them on the
PARM parameter of the PGM command in the receiving program or procedure.
Because parameters are passed by position, not name, the position of the value
passed in the CALL command or the CALLPRC command must be the same as its
position on the receiving PGM command. For example, if PROGA contains the
following command:
CALL PROGB PARM(&A &B &C ABC)
it passes three variables and a character string, and if PROGB starts with:
PGM PARM(&C &B &A &D) /*PROGB*/
then the value of &A in PROGA is used for &C in PROGB, and so on; &D in
PROGB is ABC. The order of the DCL statements in PROGB is unimportant. Only
the order in which the parameters are specified on the PGM statement determines
what variables are passed.
When you use the CALLPRC command and pass character string constants, you
must specify the exact number of bytes, and pass exactly that number. The called
procedure can use the information in the operational descriptor to determine the
exact number of bytes passed. You can use the API CEEDOD to access the
operational descriptor. See the System API Referencefor information on the API
CEEDOD.
When you use the CALL command, character string constants of 32 bytes or less
are always passed with a length of 32 bytes. If the string is longer than 32, you
must specify the exact number of bytes, and pass exactly that number.
The character string DATA is passed to &P1; the decimal value 136 is passed to
&P2
Referring to locally defined variables incurs less overhead than referring to passed
variables. Therefore, if the called procedure or program frequently refers to passed
variables, performance can be improved by copying the passed values into a local
variable and referring to the locally defined value rather than the passed value.
| When calling an OPM CL program, the number of parameters that are passed to it
| must exactly match the number that is expected by the program. The number that
| is expected is determined at the time the program is created. (The operating system
| prevents you from calling a program with more or fewer parameters than the
| program expects). When calling an ILE program or procedure, the operating system
| does not check the number of parameters that are passed on the call. In addition,
| the space where the operating system stores the parameters does not reinitialize
| between procedure calls. Calling a procedure that expects ″n″ parameters with
| ″n-1″ parameters makes the system use whatever is in the parameter space to
This also gives you more flexibility when you write ILE CL procedures, because you
can write procedures that have variable length parameter lists. For example, based
on the value of one parameter, a parameter that is specified later in the list may not
be required. If the controlling parameter indicated an unspecified optional
parameter, the called procedure should not attempt to refer to the optional
parameter.
| You can also specify the special value *OMIT for any parameter that you want to
| omit from the parameter list. If you specify *OMIT for a parameter, the calling
| procedure passes a null pointer. The procedure that is called has to be prepared to
| handle a null pointer if it refers to a parameter that is omitted. In control language
| (CL), you can check for a null pointer by monitoring for MCH3601 on the first
| reference to the omittable parameter. The procedure must take appopriate action if
| it receives a MCH3601.
The following example has two CL procedures. The first procedure expects one
parameter; if that parameter remains unspecified, results will be unpredictable. The
first procedure calls another procedure, PROC1. PROC1 expects one or two
parameters. If the value of the first parameter is ’1’, it expects the second
parameter as specified. If the value of the second parameter is ’0’, it assumes that
the second parameter remained unspecified and used a default value instead.
PROC1 also uses the CEEDOD API to determine the actual length that is passed
for the second parameter.
The result is that when a variable is passed, the called program can change the
value of the variable, and the change is reflected in the calling program. The new
value does not have to be returned to the calling program for later use; it is already
there. Thus no special coding is needed for a variable that is to be returned to the
calling program. When a constant is passed, and its value is changed by the called
program, the changed value is not known to the calling program. Therefore, if the
calling program calls the same program again, it reinitializes the values of
constants, but not of variables.
| An exception to the previous description is when the CALL command calls an ILE
| C/400 program. When using the CALL command to call a C/400 program and pass
| character or logical constants, the system adds a null character (x’00’) after the last
| non-blank character. If the constant is a character string that is enclosed in
| apostrophes or a hexadecimal constant, the null character is added after the last
| character that was specified. This preserves the trailing blanks (x ’40’ characters).
| Numeric values are not null-terminated. See the IBM SAA C/400 User’s Guide,
| SC09-1347 for more information.
If a CL program might be called using a CALL command that has not been
compiled (an interactive CALL command or through the SBMJOB command), the
decimal parameters (*DEC) should be declared with LEN(15 5), and the character
parameters (*CHAR) should be declared LEN(32) or less in the receiving program.
In the following example, program A passes six parameters: one logical constant,
three variables, one character constant, and one numeric constant.
PGM /* PROGRAM A */
DCL VAR(&B) TYPE(*CHAR)
DCL VAR(&C) TYPE(*DEC) LEN(15 5) VALUE(13.529)
DCL VAR(&D) TYPE(*CHAR) VALUE('1234.56')
CHGVAR VAR(&B) VALUE(ABCDEF)
CALL PGM(B) PARM('1' &B &C &D XYZ 2) /* Note blanks between parms */
.
.
.
ENDPGM
PGM PARM(&A
&B &C &W &V &U) /* PROGRAM B */
DCL VAR(&A)
TYPE(*LGL)
DCL VAR(&B)
TYPE(*CHAR) LEN(4)
DCL VAR(&C)
TYPE(*DEC)
/* Default length (15 5) matches DCL LEN in program A */
DCL VAR(&W) TYPE(*CHAR)
DCL VAR(&V) TYPE(*CHAR)
DCL VAR(&U) TYPE(*DEC)
.
.
. ENDPGM
The logical constant ’1’ does not have to be declared in the calling program. It is
declared as type logical and named &A in program B.
Because no length is specified on the DCL command for &B, the default length,
which is 32 characters, is passed. Only 6 characters of &B are specified (ABCDEF).
Because &B is declared with only 4 characters in program B, only those 4
characters are received. If they are changed in program B, those 4 positions for &B
will also be changed in program A for the remainder of this call.
The length (LEN) parameter must be specified for &C in program A. If it were not
specified, the length would default to the specified value’s length, which would be
incompatible with the default length expected in program B. &C has a value of
13.52900.
The variable &V is a character string XYZ, padded with blanks on the right. The
variable &U is numeric data, 2.00000.
For more information on the default lengths in the DCL commands, refer to online
help for the DCL command, or see the DCL command in the CL Reference
(Abridged) book.
When the CALL command is used with the CMD parameter on the SBMJOB
command, unexpected results may occur. Syntactically, the CALL command
appears the same when used with the CMD parameter as it does when used as the
compiler directive for the CALL command. When used with the CMD parameter, the
CALL command is converted to a command string that is run at a later time when
the batch subsystem initiates it. When the CALL command is used by itself, the CL
compiler generates code to perform the call.
If a decimal variable had been declared with LEN(5 2) in the calling program or
procedure and the value had been passed as a variable instead of as a constant,
no error would occur.
If a decimal value is passed with the correct length but with the wrong precision
(number of decimal positions), the receiving procedure or program interprets the
value incorrectly. In the following example, the numeric constant value (with length
(15 5)) passed to the procedure is handled as 25124.00.
CALL PGMA PARM(25.124) /* CALLING PGM */
These errors occur when the variable is first referred to, not when it is passed or
declared. In the next example, the called program does not refer to the variable, but
instead simply places a value (of the detected wrong length) in the variable returned
to the calling program. The error is not detected until the variable is returned to the
calling program and first referred to. This kind of error can be especially difficult to
detect.
PGM /* PGMA */
DCL &A *DEC (7 2)
CALL PGMB PARM(&A) /* (7 2) PASSED TO PGMB */
IF (&A *NE 0) THEN(...) /* *MCH1202 OCCURS HERE */
While this kind of error does not cause an escape message, variables handled this
way may function differently than expected.
If the value passed to a procedure or program is shorter than its declared length in
the receiving procedure or program, there may be more serious consequences. In
this case, the value of the variable in the called procedure or program consists of its
values as originally passed, and whatever follows that value in storage, up to the
length declared in the called procedure or program. The content of this adopted
storage cannot be predicted. If the passed value is a variable, it could be followed
by other variables or by internal control structures for the procedure or program. If
the passed value is a constant, it could be followed in storage by other constants
passed on the CALL or CALLPRC command or by internal control structures.
If the receiving procedure or program changes the value, it operates on the original
value and on the adopted storage. The immediate effect of this could be to change
other variables or constants, or to change internal structures in such a way that the
procedure or program fails. Changes to the adopted storage take effect
immediately.
In the following example, two 3-character constants are passed to the called
program. Character constants are passed with a minimum of 32 characters for the
CALL command. (Normally, the value is passed as 3 characters left-adjusted with
trailing blanks.) If the receiving program declares the receiving variable to be longer
In the following example, two 3-character constants are passed to the called
procedure. Only the number of characters specified are passed for the CALLPRC
command. If the receiving program declares the receiving variable to be longer than
the length of the passed constant, the extra positions use adopted storage of
unknown value.
In the following example, assume the two constants are adjacent in storage.
CALLPRC PRCA ('ABC' 'DEF') /* PASSING PROG */
The following is an example showing how data queues work. Several jobs place
entries on a data queue. The entries are handled by a server job. This might be
used to have jobs send processed orders to a single job that would do the printing.
Any number of jobs can send to the same queue.
┌────────────┐
Sending Job 1 ────Ê│ │
│ │
Sending Job 2 ────Ê│ DTAQ ├────Ê Server Job
│ │
Sending Job 3 ────Ê│ │
└────────────┘
Another example using data queues follows. A primary job gets the work requests
and sends the entries to a data queue (by calling the QSNDDTAQ program). The
server jobs receive the entries from the data queue (by calling the QRCVDTAQ
program) and process the data. The server jobs can report status back to the
primary job using another data queue.
Data queues allow the primary job to route the work to the server jobs. This frees
the primary job to receive the next work request. Any number of server jobs can
receive from the same data queue.
When no entries are on a data queue, server jobs have the following options:
v Wait until an entry is placed on the queue
v Wait for a specific period of time; if the entry still has not arrived, then continue
processing
v Do not wait, return immediately.
Data queues can also be used when a program needs to wait for input from display
files, ICF files, and data queues at the same time. When you specify the DTAQ
parameter for the following commands:
v Create Display File (CRTDSPF) command
v Change Display File (CHGDSPF) command
v Override Display File (OVRDSPF) command
v Create ICF File (CRTICFF) command
v Change ICF File (CHGICFF) command
v Override ICF File (OVRICFF) command
you can indicate a data queue that will have entries placed on it when any of the
following happens:
v An enabled command key or Enter key is pressed from an invited display device
v Data becomes available from an invited ICF session
Jobs running on the system can also place entries on the same data queue as the
one specified in the DTAQ parameter by using the QSNDDTAQ program.
An application program that currently uses a standard data queue can also access
a remote DDM data queue without changing or compiling the application again. To
ensure the correct data queue is accessed, you may need to do one of the
following:
v Delete the standard data queue and create a DDM data queue that has the
same name as the original standard data queue.
v Rename the standard data queue.
You can create a DDM data queue with the following command:
CRTDTAQ DTAQ(LOCALLIB/DDMDTAQ) TYPE(*DDM)
RMTDTAQ(REMOTELIB/REMOTEDTAQ) RMTLOCNAME(SYSTEMB)
TEXT('DDM data queue to access data queue on SYSTEMB')
You can also use an expansion of the previous example (″Master Job/Server Job″)
to create a DDM data queue to use with remote data queues. The master job
resides on SystemA; the data queues and server jobs are moved to SystemB. After
creating two DDM data queues (INPUT and STATUS), the master job continues to
communicate asynchronously with the server jobs that reside on SystemB. The
following example shows how to create a DDM data queue with remote data
queues:
CRTDTAQ DTAQ(LOCALLIB/INPUT) TYPE(*DDM)
RMTDTAQ(REMOTELIB/INPUT) RMTLOCNAME(SystemB)
TEXT('DDM data queue to access INPUT on SYSTEMB')
The master job calls QSNDDTAQ, then passes the data queue name of
LOCALLIB/INPUT and sends the data to the remote data queue
(REMOTELIB/INPUT) on SystemB. To receive data from the remote data queue,
(REMOTELIB/STATUS), the master job passes the data queue name of
LOCALLIB/STATUS for the call to QRCVDTAQ.
See the CL Reference (Abridged) book or the Data Management book for more
information on DDM data queues.
The ALCOBJ command does not, by itself, restrict another job from sending or
receiving data from a data queue or clearing a data queue. However, if all
applications are coded to include the ALCOBJ command before any use of a data
queue, the allocation of a data queue already allocated to another job will fail,
preventing the data queue from use by more than one job at a time.
When an allocation fails because the data queue is already allocated to another job,
the system issues an error message, CPF1002. The Monitor Message (MONMSG)
Job A
┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ ICF │Í──Ê│ Application │ │ Display │
│ File │ │ Program │ │ File │
└──────┬───────┘ └─────────────┘ └───────┬──────┘
│ õ │
│ ┌──────┴──────┐ │
└───────────Ê│ Data │Í───────────┘
│ Queue │
└─────────────┘
In this example, a program is waiting for input from a display file and an ICF file.
Instead of alternately waiting for one and then the other, a data queue is used to
allow the program to wait on one object (the data queue). The program calls
QRCVDTAQ and waits for an entry to be placed on the data queue that was
specified on the display file and the ICF file. Both files specify the same data
queue. Two types of entries are put on the queue by display data management and
ICF data management support when the data is available from either file. ICF file
entries start with *ICFF and display file entries start with *DSPF.
The display file or ICF file entry that is put on the data queue is 80 characters in
length and contains the field attributes described in the following list. Therefore, the
data queue that is specified using the CRTDSPF, CHGDSPF, OVRDSPF, CRTICFF,
CHGICFF, and OVRICFF commands must have a length of at least 80 characters.
Position (and Data Type)
Description
1 through 10 (character)
The type of file that placed the entry on the data queue. This field will have
one of two values:
*ICFF for ICF file
*DSPF for display file
If the job receiving the data from the data queue has only one display file or
one ICF file open, then this is the only field needed to determine what type
of entry has been received from the data queue.
11 through 12 (binary)
The unique identifier for the file. The value of the identifier is the same as
the value in the open feedback area for the file. This field should be used
by the program receiving the entry from the data queue only if there is more
than one file with the same name placing entries on the data queue.
13 through 22 (character)
The name of the display file or ICF file. This is the name of the file actually
opened, after all overrides have been processed, and is the same as the
file name found in the open feedback area for the file. This field should be
used by the program receiving the entry from the data queue only if there is
more than one display file or ICF file that is placing entries on the data
queue.
The following example shows coding logic that the program previously described
might use:
.
.
.
.
OPEN DSPFILE ... /* Open the Display file. DTAQ parameter specified on*/
/* CRTDSPF, CHGDSPF, or OVRDSPF for the file. */
OPEN ICFFILE ... /* Open the ICF file. DTAQ parameter specified on */
/* CRTICFF, CHGICFF, or OVRICFF for the file. */
.
.
DO
WRITE DSPFILE /* Write with Invite for the Display file */
WRITE ICFFILE /* Write with Invite for the ICF file */
Job A Job B
┌───────────────────────┐ ┌───────────────────────┐
│ Batch Job │ ┌───────────────┐ │ Interactive Job Using │
│ Placing User Entries │ │ │ │ Display File and │
│ on the ├──Ê│ Data Queue ├──Ê│ Receiving Entries │
│ Data Queue │ │ │ │ from the Data Queue │
└───────────────────────┘ └───────────────┘ └───────────────────────┘
õ õ
│ │
│ ø
│ ┌──────────────┐
│ │ │
└────────────────┤ Display File │
│ │
└──────────────┘
| The program calls QRCVDTAQ and waits for the placement of an entry on the data
| queue that was specified on the display file. Job A is also placing entries on the
| same data queue. There are two types of entries that are put on this queue, the
| display file entry, and the user-defined entry. Display data management places the
| display file entry on the data queue when data is available from the display file. Job
| A places the user-defined entry on the data queue.
The structure of the display file entry is described in the previous example.
The structure of the entry placed on the queue by Job A is defined by the
application programmer.
The following example shows coding logic that the application program in Job B
might use:
.
.
.
.
OPEN DSPFILE ... /* Open the Display file. DTAQ parameter specified on*/
/* CRTDSPF, CHGDSPF, or OVRDSPF for the file. */
.
.
DO
To create a data area other than a local or group data area, use the Create Data
Area (CRTDTAARA) command. By doing this, you create a separate object in a
specific library, and you can initialize it to a value. To use the value in a CL
procedure or program, use a Retrieve Data Area (RTVDTAARA) command to bring
the current value into a variable in your procedure or program. If you change this
value in your CL procedure or program and want to return the new value to the data
area, use the Change Data Area (CHGDTAARA) command.
To display the current value, use the Display Data Area (DSPDTAARA) command.
You can delete a data area using the Delete Data Area (DLTDTAARA) command.
The system creates a local data area, which is initially filled with blanks, with a
length of 1024 and type *CHAR. When you submit a job using the SBMJOB
command, the value of the submitting job’s local data area is copied into the
submitted job’s local data area. You can refer to your job’s local data area by
specifying *LDA for the DTAARA keyword on the CHGDTAARA, RTVDTAARA, and
DSPDTAARA commands or *LDA for the substring built-in function (%SST).
The local data area contents exist across routing step boundaries. Therefore, using
a Transfer Job (TFRJOB), Transfer Batch Job (TFRBCHJOB), Reroute Job
(RRTJOB), or Return (RETURN) command does not affect the contents of the local
data area.
Most high-level languages can also use the local data area. The SBMxxxJOB and
STRxxxRDR commands cause jobs to start with a local data area initialized to
blanks. Only the SBMJOB command allows the contents of the submitting job’s
local data area to be passed to the new job.
A group data area, which is initially filled with blanks, has a length of 512 and type
*CHAR. You can use a group data area from within a group job by specifying *GDA
The contents of a group data area are unchanged by the Transfer to Group Job
(TFRGRPJOB) command.
In addition to using the group data area as you use other data areas, you can use
the group data area to communicate information between group jobs in the same
group. For example, after issuing the Change Group Job Attributes (CHGGRPA)
command, the following command can be used to set the value of the group data
area:
CHGDTAARA DTAARA(*GDA) VALUE('January1988')
This command can be run from a program or can be issued by the work station
user.
Any other CL procedure or program in the group can retrieve the value of the group
data area with the following CL command:
RTVDTAARA DTAARA(*GDA) RTNVAR(&GRPARA)
This command places the value of the group data area (January1988) into CL
variable &GRPARA.
To use a value from a data area on a remote AS/400 in a CL program, use the
Retrieve Data Area (RTVDTAARA) command. Specify the name of a DDM data
area to bring the current value into a variable in your program. If you change this
value in your CL program and want to return the new value to the remote data area,
use the Change Data Area (CHGDTAARA) command and specify the same DDM
data area.
If you specify the name of a DDM data area when using the Display Data Area
(DSPDTAARA) command, the value of the DDM data area is displayed, rather than
the value of the remote data area. You can delete a DDM data area using the
Delete Data Area (DLTDTAARA) command.
See the CL Reference (Abridged) book and the Data Management book for more
information on DDM data areas.
When you create a data area, you can also specify an initial value for the data
area. If you do not specify one, the following is assumed:
v 0 for decimal.
v Blanks for character.
v ’0’ for logical.
To create a data area, use the Create Data Area (CRTDTAARA) command. In the
following example, a data area is created to pass a customer number from one
program to another:
CRTDTAARA DTAARA(CUST) TYPE(*DEC) +
LEN(5 0) TEXT('Next customer number')
For information on handling data areas in other (non-CL) languages, refer to the
appropriate HLL reference manual.
The display uses the 24-digit format with leading zeros suppressed.
To retrieve the order status into &ORDSTAT, you would enter the following:
RTVDTAARA DTAARA(ORDINFO (1 1)) RTNVAR(&ORDSTAT)
To retrieve the stock condition into &STOCK, you would enter the following:
RTVDTAARA DTAARA(ORDINFO (2 1)) RTNVAR(&STOCKC)
To retrieve the clerk’s initials into &CLERK, you would enter the following:
RTVDTAARA DTAARA(ORDINFO (3 3)) RTNVAR(&CLERK)
Example 2
The following example of the RTVDTAARA command places the specified contents
of a 5-character data area into a 3-character variable. This example:
v Creates a 5-character data area named DA1 (in library MYLIB) with the initial
value of 'ABCDE'
v Declares a 3-character variable named &CLVAR1
v Copies the contents of the last three positions of DA1 into &CLVAR1
Example 3
The following example of the RTVDTAARA command places the contents of a
5-digit decimal data area into a 5-digit decimal digit variable. This example:
v Creates a 5-digit data area named DA2 (in library MYLIB) with two decimal
positions and the initial value of 12.39
v Declares a 5-digit variable named &CLVAR2 with one decimal position
v Copies the contents of DA2 into &CLVAR2
This example:
v Creates a 10-character data area named DA1 (in library MYLIB) with initial value
ABCD5678IJ
v Declares a 5-character variable named &CLVAR1
v Changes the contents of data area DA1 (starting at position 5 for length 4) to the
value EFG padding after the G with 1 blank)
v Retrieves the contents of data area DA1 (starting at position 5 for length 5) into
the CL variable &CLVAR1
Note: Objects can reside in both libraries and directories. (Previously, an object
could reside only in a library.) This chapter contains information only about
objects residing in libraries. See the Integrated File System Introduction
book, SC41-4711, for specific information about directories.
Each object type has a set of common attributes that describes the object. These
common attributes are listed in Table 2 on page 118. The online help information for
the Display Object Description (DSPOBJD) display describes these attributes.
Libraries
On the AS/400 system, objects are grouped in special objects called libraries.
Objects are found using libraries. To access an object in a library, you must be
authorized to the library and to the object. See “Security Considerations for Objects”
on page 111 and “Specifying Authority for Libraries” on page 109 for more
information.
If you specify a library name in the same parameter as the object name, the object
name is called a qualified name. If you are entering a command in which you must
specify a qualified name, for example, the object name could be:
DISTLIB/ORD040C
job), or use a library list. Library lists are described in the following section.
Library Lists
For commands in which a qualified name can be specified, you can omit specifying
the library name. If you do so, either of the following happens:
v For a create command, the object is created and placed in the user’s current
library, *CURLIB, or in a system library, depending on the object type. For
example, programs are created and placed in *CURLIB; authorization lists are
created and placed in the system library, QSYS.
v For commands other than a create command, the system normally uses a library
list to find the object.
Library lists used by the AS/400 system consist of the following four parts.
System part
The system part of the library list contains objects needed by the system.
Product libraries
Two product libraries may be included in the library list. The system uses
product libraries to support languages and utilities that are dependent on
libraries other than QSYS to process their commands.
User commands and menus can also specify a product library on the
PRDLIB parameter on the Create Command (CRTCMD) and Create Menu
(CRTMNU) commands to ensure that dependent objects can be found.
The product libraries are managed by the system, which automatically
places product libraries (such as QRPG) into the reserved product library
position in the library list when needed. A product library may be a duplicate
of the current library or of a library in the user part of the library list.
| For example, assume that there is a product library in the library list when a
| command or menu that has a product library starts. The system will replace
| the product library in the library list with the new product library until the
| new command ends or the user leaves the new menu.
Current library
The current library can be, but does not have to be, a duplicate of any
library in the library list. The value *CURLIB (current library) may be used
on most commands as a library name to represent whatever library has
been specified as the current library for the job. If no current library exists in
the library list and *CURLIB is specified as the library, QGPL is used. You
can change the current library for a job by using the Change Current
Library (CHGCURLIB) or Change Library List (CHGLIBL) command.
User part
The user part of the library list contains those libraries referred to by the
system’s users and applications. The user part, and the product and current
libraries, may be different for each job on the system. There is a limit of 25
libraries.
For a list of the libraries shipped with the system or optionally installable on the
system, see the Programming Reference Summary book.
The following diagram shows an example of the structure of the library list:
Chapter 4. Objects and Libraries 99
Search order ┌───────────┐
│ QSYS │ System Part
│ │ QSYS2 │
│ │ QUSRSYS │
│ │ QHLPSYS │
│ ├───────────┤
│ │ QPDA │ Product Library 1
│ ├───────────┤
│ │ QRPG │ Product Library 2
│ ├───────────┤
│ │ OELIB │ Current Library
│ ├───────────┤
│ │ OELIB │ User Part
│ │ QGPL │
ø │ QTEMP │
└───────────┘
Note: The system places library QPDA in product library 1 when the source entry
utility (SEU) is used. When SEU is being used to syntax check source code,
a second product library can be added to product library 2. For example, if
you are syntax checking RPG source, then QPDA is product library 1 and
QRPG is product library 2. In most other system functions, product library 2
is not used.
Using a library list simplifies finding objects on the system. Each job has a library
list associated with it. When a library list is used to find an object, each library in the
list is searched in the order of its occurrence in the list until an object of the
specified name and type is found. If two or more objects of the same type and
name exist in the list, you get the object from the library that appears first in the
library list. The following diagram shows the searches made for an object both
when the library list (*LIBL) is used and when a library name is specified:
| Note: Alternatively, use *NLVLIBL instead of *LIBL to qualify any command. Enter
| the command from a CL program, on a command line, or anywhere you
| normally enter a command. The system uses *NLVLIBL to determine which
| libraries to search for the *CMD object. You search only the NLS libraries in
| the library list by specifying *NLVLIBL.
|
┌────────┐
│ ______ │
│ ______ │
│ ORDHDRP│
│ . │
│ . │
│ . │
└────────┘
The following diagram shows what happens when two objects of the same name
but different types are in the library list. The system will search for CUSTINQ *FILE
in the library list by specifying:
DSPOBJD OBJ(*LIBL/CUSTINQ) OBJTYPE(*FILE)
Generally, a library list is more flexible and easier to use than qualified names.
More important than the advantage of not entering the library name, is the
advantage of performing functions in an application on different data simply by
using a different library list without having to change the application. For example, a
CL program PGMA updates a data area CHKNBR. If the library name is not
specified, the program can update the data area named CHKNBR in different
libraries depending on the use of the library list. For example, assume that JOBA
and JOBB both call PGMA as shown in the following illustration:
If, however, you call a program using a qualified name and the program attempts to
open files whose names are not qualified, the files are not opened if they are not in
the library list, as shown in the following example:
The call to PGMA is successful because the program name is qualified on the CALL
command. However, when the program attempts to open file ORDENTP, the open
operation fails because the file is not in one of the libraries in the library list, and its
name is not qualified. If library DISTLIB2 was added to the library list or a qualified
file name was used, the program could open the file. Some high-level languages do
not allow a qualified file name to be specified. By using an Override (OVRxxx)
command, a qualified name can be specified.
When the system is shipped, the system value QSYSLIBL contains the names of
the libraries to become the system part of the library list. The shipped values are
QSYSLIBL can contain 15 library names, and QUSRLIBL can contain 25 library
names. To change the system portion of a job’s library list, use the Change System
Library List (CHGSYSLIBL) command. To change the value of either QSYSLIBL or
QUSRLIBL, use the Change System Value (CHGSYSVAL) command. A change to
these system values takes effect on new jobs that are started after the system
values are changed.
The current library may be added or changed using the Change Current Library
(CHGCURLIB) or CHGLIBL command. The current library can also be changed in
the user’s user profile, at sign-on, or on the Submit Job (SBMJOB) command. The
product libraries cannot be added using a CL command; these libraries are added
by the system when a command or menu using them is run. The product libraries
cannot be changed with a CL command; however, they can be changed with the
Change Library List (QLICHGLL) API.
When you use these commands, the change to the library list affects only the job in
which the command is run, and the change is effective only as long as the job is
running, or until you change the job’s library list again. When the library list is
changed through the use of these commands, the libraries must exist when the
command is run. A library cannot be deleted if it exists on an active user’s library
list.
When a job is started, the user portion of the library list is determined by the values
contained in the job description or by values specified on the SBMJOB command. A
value of *SYSVAL can be specified, which causes the libraries specified by the
system value QUSRLIBL to become the user portion of the library list. If you have
specified library names in both the job description and the Batch Job (BCHJOB) or
SBMJOB command, the library names specified in the BCHJOB or SBMJOB
command override both the libraries specified in the job description and the system
value QUSRLIBL.
The following shows the order in which the user part of the library list specified in
QUSRLIBL is overridden by commands for individual jobs:
v A library list can be specified in the job description that, when the job is run,
overrides the library list specified in QUSRLIBL. (See the Work Management
book for information on job descriptions.)
v When a job is submitted either through a BCHJOB command or a SBMJOB
command, a library list can be specified on the command. This list overrides the
library list specified in the job description or in the system value QUSRLIBL.
v When a job is submitted using the SBMJOB command, *CURRENT (the default)
can be specified for the library list. *CURRENT indicates that the library list of the
job issuing the SBMJOB command is used.
v Within a job, an ADDLIBLE, RMVLIBLE, or CHGLIBL command can be used.
These commands override any previous library list specifications.
Instead of entering the CHGLIBL command each time you want to change the
library list, you can place the command in a CL program:
PGM /* SETLIBL - Set library list */
CHGLIBL LIBL(APPDEVLIB QGPL QTEMP)
ENDPGM
If you normally work with this library list, you could set up an initial program to
establish the library list instead of calling the program each time:
PGM /* Initial program for QPGMR */
CHGLIBL LIBL(APPDEVLIB QGPL QTEMP)
TFRCTL PGM(QPGMMENU)
ENDPGM
This program must be created and the user profile to which it will apply changed to
specify the new initial program. Control then transfers from this program to the
QPGMMENU program, which displays the Programmer Menu.
If you occasionally need to add a library to the library list specified in your initial
program, you can use the ADDLIBLE command to add that library to the library list.
For example, the following command adds the library JONES to the end of the
library list:
ADDLIBLE LIB(JONES) POSITION(*LAST)
If part of your job requires a different library list, you can write a CL program that
saves the current library list and later restores it, such as the following program.
PGM
DCL &LIBL *CHAR 275
DCL &CMD *CHAR 285
(1) RTVJOBA USRLIBL(&LIBL)
(2) CHGLIBL (QGPL QTEMP)
.
.
.
(3) CHGVAR &CMD ('CHGLIBL (' *CAT &LIBL *TCAT ')')
(4) CALL QCMDEXC (&CMD 285)
.
.
.
ENDPGM
(1) Command to save the library list. The library list is stored into variable
&LIBL. Each library name occupies 10 bytes (padded on the right with
blanks if necessary), and one blank is between each library name.
(2) This command changes the library list as required by the following function.
(3) The Change Variable (CHGVAR) command builds a CHGLIBL command in
variable &CMD.
(4) QCMDEXC is called to process the command string in variable &CMD. The
CHGVAR command is required before the call to QCMDEXC because
concatenation cannot be done on the CALL command.
You can also display the library list for an active job using the Display Job
(DSPJOB) command and selecting option 13 from the Display Job menu.
To use a generic search, specify a generic name in place of the object name on the
command. A generic name consists of a set of characters common to all the object
names that identifies a group of objects and ends with an * (asterisk). All objects
whose names begin with the specified characters and to which you are authorized
have the requested function performed on them. For example, if you entered the
Display Object Description (DSPOBJD) command using the generic name ORD*,
object descriptions for the objects beginning with ORD are shown.
A generic search can be limited by the following library qualifiers on the generic
name (the library name parameter value is given in parentheses, if applicable):
v A specified library. The operation you requested is performed on the generically
named objects in the specified library only.
v The library list for the job (*LIBL). The libraries are searched in the order they are
listed in the library list. The operation you requested is performed on the
generically named objects in the libraries specified in the library list for the job.
v The current library for the job (*CURLIB). The current library for the job is
searched. If no current library exists, QGPL is used.
QDSNX QUSER38
QGPL QUSRADSM
QGPL38 USRBRM
QMQMDATA USRIJS
QMQMPROC QUSRINFSKR
QPFRDATA QUSRNOTES
QRCL QUSRRDARS
QS36F USRSYS
QUSRVxRxMx (VxRxMx is version, release, and modification level of the library)
The libraries are searched in alphanumeric order. The following S/36 environment
libraries that begin with # are not searched with *ALLUSR specified: #CGULIB,
#COBLIB, #DFULIB, #DSULIB, #RPGLIB, #SDALIB, and #SEULIB. The
operation you requested is performed on the generically named objects in all the
user libraries for which you are authorized.
v All libraries on the system for which you are authorized (*ALL). The libraries are
searched in alphanumeric order. The operation you requested is performed on
the generically named objects in all the libraries on the system for which you are
authorized.
Using Libraries
A library is an object used to group related objects and to find objects by name.
Thus, a library is a directory to a group of objects.
Multiple libraries make it easier to use objects. For example, you can have two files
with the same name but in different libraries so that one can be used for testing and
the other for normal processing. As long as you do not specify the library name in
your program, the file name in the program does not have to be changed for testing
or normal processing. You control which library is used by using the library list.
(Objects of the same type can have the same names only if they are in different
libraries.)
The two types of libraries are production and test. A production library is for normal
processing. In debug mode, you can protect database files in production libraries
from being updated. While in debug mode, any files in test libraries can be updated
without any unique specifications. (See Appendix A. for more information on using
test libraries.)
Creating a Library
To create a library, use the Create Library (CRTLIB) command. For example, the
following CRTLIB command creates a library to be used to contain order entry files
and programs. The library is named DISTLIB and is a production library. The default
authority given to the public prevents a user from accessing the library. Any object
created into the library is given the default public authority of *CHANGE based on
the CRTAUT value.
CRTLIB LIB(DISTLIB) TYPE(*PROD) CRTAUT(*CHANGE) CRTOBJAUD(*USRPRF) +
AUT(*EXCLUDE) TEXT('Distribution library')
You should not create a library with a name that begins with the letter Q. During a
generic search, the system assumes that most libraries with names that begin with
the letter Q (such as QRPG or QPDA) are system libraries. See “Using Generic
Object Names” on page 107 for more information.
Object existence authority and use authority gives the user authority to delete a
library.
Object existence authority and object operational authority gives the user
authority to transfer ownership of the library.
Data Authority
Add authority and read authority for a library allows a user to create a new object
in the library or to move an object into the library.
Update authority and execute authority for a library allow a user to change the
name of an object in the library, provided the user is also authorized to the object.
Delete authority allows the user to remove entries from an object. Delete authority
for a library does not allow a user to delete objects in the library. Authority for the
object in the library is used to determine if the object can be deleted.
Execute authority allows the user to search the library for an object.
Combined Authority
*USE authority for a library (consisting of object operational authority, read
authority, and execute authority) includes authority to:
v Use a library to find an object
v Display library contents
v Place a library in the library list
v Save a library (if sufficient authority to the object)
v Delete objects from the library (if the user is authorized to the object in the
library)
*CHANGE authority for a library (consisting of object operational authority and all
data authorities to the library) includes authority to:
v Use a library to find an object
v Display library contents
v Place a library in the library list
v Save a library (if sufficient authority to the object)
v Delete objects from the library (if the user is authorized to the object in the
library)
v Add objects to the library.
To display the authority associated with your library, you may use the Display
Object Authority (DSPOBJAUT) command.
Object authority is controlled by the system’s security functions, which include the
following:
v An object owner and users with *ALLOBJ special authority have all authority for
an object, and can grant and revoke authority to and from other users.
v Users have public authority when private authority has not been granted to them
for the object.
The Security - Reference book explains in detail the types of authority that can be
granted for an object and what authority a user needs to perform a function on that
object. Authority that can be granted for libraries is discussed under “Specifying
Authority for Libraries” on page 109.
Special considerations apply when writing a program that must be secure (for
example, a program that adopts the security officer’s user profile). See the Security
- Reference book for information about writing these programs.
By specifying:
CRTLIB LIB(TESTLIB) CRTAUT(*USE) AUT(*LIBCRTAUT)
The library TESTLIB is created. All objects created into library TESTLIB will, by
default, have public authority of *USE. The public authority for library TESTLIB is
determined by the CRTAUT value of library QSYS.
By specifying:
CRTDTAARA DTAARA(TESTLIB/DTA1) TYPE(*CHAR) +
AUT(*LIBCRTAUT)
Data area DTA2 is created into library TESTLIB. The public authority of DTA2 is
*EXCLUDE. *EXCLUDE was specified on the AUT parameter of the Create Data
Area (CRTDTAARA) command.
An authorization list can also be used to secure an object when it is created into a
library.
By specifying:
CRTAUTL AUTL(PAYROLL)
CRTLIB LIB(PAYLIB) CRTAUT(PAYROLL) +
AUT(*EXCLUDE)
An authorization list called PAYROLL is created. Library PAYLIB is created with the
public authority of *EXCLUDE. By default, an object created into library PAYLIB is
secured by authorization list PAYROLL.
By specifying:
CRTPF FILE(PAYLIB/PAYFILE) +
AUT(*LIBCRTAUT)
CRTPF FILE(PAYLIB/PAYACC) +
AUT(*CHANGE)
File PAYACC is created into library PAYLIB. The public authority for file PAYACC is
*CHANGE since it was specified on the AUT parameter of the CRTPF command.
Note: The *LIBCRTAUT value of the AUT parameter that exists on most CRT
commands indicates that the public authority for the object is set to the
CRTAUT value of the library that the object is being created into.
The CRTAUT value on the library specifies the default authority for public use of the
objects created into the library. These possible values are:
*SYSVAL
The public authority for the object being created is the value specified in
system value QCRTAUT
*ALL All public authorities
*CHANGE
Change authority
*USE Use authority
*EXCLUDE
Exclude authority
authorization list name
The authorization list secures the object
By specifying:
CRTLIB LIB(PAYROLL) AUT(*EXCLUDE) CRTAUT(*EXCLUDE) CRTOBJAUD(*ALL)
all objects created into the payroll library are audited for both read and change
access. See the Security - Reference book for details on auditing.
To place an object in a library, you must have read and add authorities for the
library.
More than one object of the same type cannot have the same name and be in the
same library. For example, two files with the name ORDHDRP cannot both be in
the library DISTLIB. If you try to place into a library an object of the same name
and type as an object already in the library, the system rejects the request and
| sends you a message indicating the reason.
| Note: Use the QSYS library for system objects only. Do not restore other licensed
| programs to the QSYS library because changes are lost when installing a
| new release of OS/400.
or:
CLRLIB LIB(DISTLIB)
To delete a library, you must have object existence authority for both the library and
the objects within the library, and use authority for the library. If you try to delete a
library but do not have object existence authority for all the objects in the library, the
library and all objects for which you do not have authority are not deleted. All
objects for which you have authority are deleted. If you try to delete a library but do
You cannot delete a library in an active job’s library list. You must wait until the end
of the job before the deletion of the library is allowed. Because of this, you must
delete the library before the next routing step begins. When you delete a library,
you must be sure no one else needs the library or the objects within the library.
If a library is part of the initial library list defined by the system values QSYSLIBL
and QUSRLIBL, the following steps should be followed to delete the library:
1. Use the Change System Value (CHGSYSVAL) command to remove the library
from the system value it is contained in. (The changed system value does not
affect the library list of any jobs running.)
2. Use the Change Library List (CHGLIBL) command to change the job’s library
list.
The Change System Library List (CHGSYSLIBL), Add Library List Entry
(ADDLIBLE), Edit Library List (EDTLIBL), and Remove Library List Entry
(RMVLIBLE) commands are also used to change the library list.
3. Use the DLTLIB command to delete the library and the objects in the library.
Note: You cannot delete the library QSYS and should not delete any objects in it.
You may cause the system to end because the system needs objects that
are in QSYS to operate properly. You should not delete the library QGPL
because it also contains some objects that are necessary for the system to
be able to perform effectively. You should not use the library QRECOVERY
because it is intended for system use only. The library QRECOVERY
contains objects that the system needs to operate properly.
For concerns about deleting objects other than libraries, see “Deleting Objects” on
page 136.
To clear a library, you must have object existence authority for the objects within the
library and use authority for the library. If you try to clear a library but do not have
object existence authority for all the objects in the library, the objects you do not
have authority for are not deleted from the library. If an object is allocated to
someone else, it is not deleted.
On the DSPLIB command, you can also specify a specific library name or names,
in which case you bypass the library selection display. In this list, the objects are
For example, the following DSPLIB command displays a list of the objects
contained in DISTLIB:
DSPLIB LIB(DISTLIB) OUTPUT(*)
The asterisk (*) for the OUTPUT parameter means that the libraries are to be
shown at the display station if in interactive processing and printed if in batch
processing. To print a list when in interactive processing, specify *PRINT instead of
taking the default *.
See the CL Reference (Abridged) book for more information and sample displays
for the DSPLIB command.
The language information for the primary language of the system is stored in the
same libraries as the programs for IBM licensed programs. For example, if the
primary national language of the system is English, then libraries such as QSYS,
National language versions other than the system primary language are installed in
secondary national language libraries. Each secondary language library contains a
single national language version of the displays, messages, commands prompts,
and help for all IBM licensed programs. The name of a secondary language library
is in the form QSYSnnnn, where nnnn is a language feature code. For example, the
feature code for French is 2928, so the secondary national language library name
for French is QSYS2928.
Note: The authority shipped with the CHGSYSLIBL command does not allow all
users to run the command.
To enable a user to run the CHGSYSLIBL command without granting the user rights
to the command, you can write a CL program containing the CHGSYSLIBL
command. The program is owned by the security officer, and adopts the security
officer’s authority when created. Any user with authority to run the program can use
it to change the system part of the library list in the user’s job. The following is an
example of a program to set the library list for a French user.
PGM
CHGSYSLIBL LIB(QSYS2928) /* Use French information */
ENDPGM
Describing Objects
Whenever you use a create command to create an object, you can describe the
object in a 50-character field on the TEXT parameter of the create command. Some
commands allow a default of *SRCMBRTXT which indicates the text for the object
being created is to be taken from the text of the source member from which the
object is being created. This is valid only for objects created from source in
database source files.
You can display basic, full, or service attributes for object descriptions. These object
descriptions are found in the following table:
Notes:
1. The service information is used by programming support personnel to determine the level of the
system on which an object was created and whether or not the object has been changed since it was
shipped. Some of this information may be helpful to you because it indicates the source member used
to create an object and the last date of change to that source from which the object was created.
2. Library objects contain only the names of the objects included in the library. If DSPOBJD for object
type *LIB is used, the object size information refers to the size of the library object only, not the total
size of the objects included in the library.
You can use either the Retrieve Library Description API (QLIRLIBD) or the command DSPLIB
OUTPUT(*PRINT) to find the total size of the library.
Using the DSPOBJD or WRKOBJ command, you can list the objects in a library for which you are
authorized by:
v Name
v Generic name
The objects are listed by library; within a library, they are listed by type. Within object type, the objects are
listed in alphanumeric order.
You may want to use the DSPOBJD command in a batch job if you want to display many objects with the
*FULL or *SERVICE option. The output can go to a spooled printer file and be printed instead of being
shown at the display station, or the output can go to a database file. If you direct the output to a database
file, all the attributes of the object are written to the file. Use the Display File Field Description (DSPFFD)
command for file QADSPOBJ, in library QSYS, to view the record format for this file.
The following command displays the descriptions of the order entry files (that is, the files in DISTLIB)
whose names begin with ORD. ORD* is the generic name.
DSPOBJD OBJ(DISTLIB/ORD*) OBJTYPE(*FILE) +
DETAIL(*BASIC) OUTPUT(*)
Bottom
F3=Exit F12=Cancel F17=Top F18=Bottom
If you specify *FULL instead of *BASIC or if you enter a 5 in front of ORDDTLP on the basic display, the
resulting full display is:
Table 3 contains additional information about operations that cause the last-used
date to be updated for various object types.
Table 3. Updating Usage Information
Type of Object Commands and Operations
All object types Create Duplicate Object (CRTDUPOBJ) command and
other commands, such as the Copy Library (CPYLIB)
command, that use CRTDUPOBJ to copy objects.
When cleared
When initialized
When reorganized
Commands:
v Apply Journaled Changes (APYJRNCHG) command
v Remove Journaled Changes (RMVJRNCHG)
command
Font resource When referred to during a print operation
Form definition When referred to during a print operation
Graphics symbol set When referred to by a GDDM* or PGR graphics
application program
When retrieved
Note: The AS/400 system cannot determine the difference between old and
new device files. If you restore a device file on to the system and a
device file of that same name already exists, delete the existing file if
you want the days used count to be reset to zero. If the file is not
deleted, the system will interpret this as a restore operation of an old
object and retain the days used count.
– The days used count for a database file is the sum of the days used counts
for all file members. If there is an overflow on the sum, the maximum value (of
the days used counts field) is shown.
v Date days used count was reset
– When the days used count is reset using the Change Object Description
(CHGOBJD) command or the Change Object Description (QLICOBJD) API,
the date is recorded. The user then knows how long the days used count has
been active.
– If the days used count is reset for a file, all of the members have their days
used count reset.
| Common situations that can delete the days used count and the last used date are
| as follows:
| v Restoring damaged objects on the system.
| v Restoring programs when the system is not in a restricted state.
| The Display Object Description (DSPOBJD) command can be used to display a full
description of an object. You can use the same command to write the description to
an output file. To retrieve the descriptions, use the Retrieve Object Description
(RTVOBJD) command.
Object usage information is not updated for the following object types:
v Alert table (*ALRTBL)
v Authorization list (*AUTL)
v Configuration list (*CFGL)
v Class-of-service description (*COSD)
v Data Dictionary (*DTADCT)
v Document (*DOC)
v Double-byte character set dictionary (*IGCDCT)
v Double-byte character set sort (*IGCSRT)
v Double-byte character set table (*IGCTBL)
v Edit description (*EDTD)
v Exit Registration (*EXITRG)
v Filter (*FTR)
v Forms control table (*FCT)
v Folder (*FLR)
v Internet Packet Exchange Description (*IPXD)
v Journal (*JRN)
v Journal receiver (*JRNRCV)
v Library (*LIB)
v Mode description (*MODD)
v Network Server Description (*NWSD)
v NetBIOS Description (*NTBD)
v Product definition (*PRDDFN)
v Reference code translation table (*RCT)
v Session description (*SSND)
v S/36 machine description (*S36)
| v User-defined SQL type (SQLUDT)
v User queue (*USRQ)
You can move an object out of the temporary library, QTEMP, but you cannot move
an object into QTEMP. Also, you cannot move an output queue unless it is empty.
Moving journals and journal receivers is limited to moving these object types back
into the library in which they were originally created. If the journal objects have
been placed into QRCL by a Reclaim Storage (RCLSTG) command, they must be
moved back into their original library to be made operational.
In the following example, a file from QGPL (where it was placed when it was
created) is moved to the order entry library DISTLIB so that it is grouped with other
order entry files.
To move the object, you must specify the to-library (TOLIB) as well as the object
type (OBJTYPE):
MOVOBJ OBJ(QGPL/ORDFILL) OBJTYPE(*FILE) TOLIB(DISTLIB)
When you move objects, you should be careful not to move objects that other
objects depend on. For example, CL procedures may depend on the command
definitions of the commands used in the procedure to be in the same library at run
time as they were at module creation time. At compile time and at run time, the
command definitions are found either in the specified library or in a library in the
library list if *LIBL is specified. If a library name is specified, the command
definitions must be in the same library at run time as they were at compile time. If
*LIBL is specified, the command definitions can be moved between compile time
and program run time as long as they are moved to a library in the library list.
Similarly, any application program you write can depend on certain objects being in
specific libraries.
Note: You should be careful when moving objects from the system library QSYS.
These objects are necessary for the system to perform effectively and the
system must be able to find the objects. This is also true for some of the
objects in the general-purpose library QGPL, particularly for job and output
queues.
You can duplicate an object if you have object management and use authority for
the object, use and add authority for the library in which the duplicate object is to be
placed, use authority for the library in which the original object exists, and add
authority for the process user profile.
Only the definitions of job queues, message queues, output queues and data
queues are duplicated. Job queues and output queues cannot be duplicated into
the temporary library (QTEMP). For a physical file or a save file, you can specify
whether the data in the file is also to be duplicated.
In some cases, you may want to duplicate only some of the data in a file by
following the CRTDUPOBJ command with a CPYF command that specifies the
selection values.
The following command creates a duplicate copy of the order header physical file,
and duplicates the data in the file:
CRTDUPOBJ OBJ(ORDHDRP) FROMLIB(DSTPRODLIB) OBJTYPE(*FILE) +
TOLIB(DISTLIB2) NEWOBJ(*SAME) DATA(*YES)
When you create a duplicate object, you should consider the consequences of
creating a duplicate of an object that refers to another object. Many objects refer to
other objects by name, and many of these references are qualified by a specific
library name. Therefore, the duplicate object could contain a reference to an object
that exists in a library different from the one in which the duplicate object resides.
For all object types other than files, references to other objects are duplicated in the
duplicate object. For files, the duplicate objects share the formats of the original file.
Any physical files which exist in the from-library, and on which a logical file is
based, must also exist in the to-library. The record format name and record level ID
of the physical files in the to- and from-libraries are compared; if the physical files
do not match, the logical file is not duplicated.
If a logical file uses a format selection that exists in the from-library, it is assumed
that the format selection also exists in the to-library.
Renaming Objects
You can use the Rename Object (RNMOBJ) command to rename objects. However,
you can rename an object only if you have object management authority for the
object and update and execute authority for the library containing the object.
Also, you cannot rename an output queue unless it is empty. You should not
rename IBM-supplied commands because the licensed programs also use
IBM-supplied commands.
To rename an object, you must specify the current name of the object, the name to
which the object is to be renamed, and the object type.
| You cannot specify a qualified name for the new object name because the object
| remains in the same library. If the object you want to rename is in use when you
| issue the RNMOBJ command, the command runs, but does not rename the object.
| As a result, the system sends you a message.
When you rename objects, you should be careful not to rename objects that other
objects depend on. For example, CL programs depend on the command definitions
of the commands used in the program to be named the same at run time as they
were at compile time. Therefore, if the command definition is renamed in between
these two times, the program cannot be run because the commands will not be
found. Similarly, any application program you write depends on certain objects
being named the same at both times.
| You cannot rename a library that contains a journal, journal receiver, data dictionary,
| cluster resource group, or SQL package.
An object referring to another object may be dependent on the object and library
names (even though *LIBL can be specified for the library name). Therefore, if you
rename an object, you should change any references to it in other objects. See
“Moving Objects from One Library to Another” on page 128 for a list of objects that
refer to other objects.
If you rename a physical or logical file, the members in the file are not renamed.
However, you can use the Rename Member (RNMM) command to rename a
physical or logical file member.
Compression of Objects
Object types, *PGM, *SRVPGM, *MODULE, *PNLGRP, *MENU, and *FILE (display
and print files only) can be compressed or decompressed using the CPROBJ or
DCPOBJ commands. Objects can be compressed only when both of the following
are true:
v If the system can obtain an exclusive lock on the object.
v When the compressed size saves disk space.
Compression runs much faster if you use multiple jobs in nonrestricted state as
shown in the following table:
Table 4. Compressing Objects using Multiple Jobs
Object Type IBM-supplied User-supplied
*FILE Job 3: QSYS Job 7: USRLIB1
*MENU Job 2: QSYS Job 8: USRLIB1
The number of QDCPOBJ jobs is based on number of processors + 1. The jobs are
system jobs running at priority 60 which can’t be changed, ended or held by the
user. A QDCPOBJx job may be in one of the following statuses, which are from the
Work Active Job (WRKACTJOB) command:
v RUN (running): The job is actively decompressing objects.
The following storage requirements apply if the operating system was installed over
an existing operating system:
v The system must have greater than 250 megabytes of unused storage for the
QDCPOBJx jobs to start.
v On a system with available storage of greater than 750MB, the jobs are
submitted to decompress all system objects just installed.
v On a system with available storage of less than 250MB, jobs are not submitted,
and the objects are decompressed as they are used.
v On a system with available storage between 250MB and 750MB, only
frequently-used objects are automatically decompressed.
Frequently-used objects are objects that have been used at least five times and
the last use was within the last 14 days. The remaining low-use objects remain
compressed.
The system must have greater than 1000MB of unused storage if the operating
system is installed on a system that has been initialized using options 2, Install
Licensed Internal Code and Initialize the system, from the Install Licensed Internal
Code (LIC) display.
If QDCPOBJx jobs are active at the last system termination, the jobs are started
again at the time of the next IPL.
Deleting Objects
To delete an object, you can use a delete (DLTxxx) command for that type of object
or you can use the delete option on the Work with Objects display (shown from the
Work with Libraries (WRKLIB) display). To delete an object, you must have object
existence authority to the object and execute authority to the library. Only the owner
of an authorization list, or a user with *ALLOBJ special authority, can delete the
authorization list.
When you delete an object, you must be sure no one else needs the object or is
using the object. Generally, if someone is using an object, it cannot be deleted.
However, programs can be deleted unless you use the Allocate Object (ALCOBJ)
command to allocate the program before it is called.
| Some create commands, such as commands that are used to create programs and
| device files, have a REPLACE option. This option allows users to continue using
You should be careful of deleting objects that exist in the system libraries. These
objects are necessary for the system to perform properly.
On most delete commands, you can specify a generic name in place of an object
name. Before using a generic delete, you may want to specify the generic name by
using the DSPOBJD command to verify that the generic delete will delete only the
objects you want to delete. See “Using Generic Object Names” on page 107 for
more information on specifying objects generically.
For information about deleting libraries, see “Deleting and Clearing Libraries” on
page 113.
Allocating Resources
Objects are allocated on the system to guarantee integrity and to promote the
highest possible degree of concurrency. An object is protected even though several
operations may be performed on it at the same time. For example, an object is
allocated so that two users can read the object at the same time or one user can
only read the object while another can read and update the same object.
OS/400 allocates objects by the function being performed on the object. For
example:
v If a user is displaying or dumping an object, another user can read the object.
v If a user is changing, deleting, renaming, or moving an object, no one else can
use the object.
v If a user is saving an object, someone else can read the object, but not update
or delete it; if a user is restoring the object, no one else can read or update the
object.
v If a user is opening a database file for input, another user can read the file. If a
user is opening a database file for output, another user can update the file.
v If a user is opening a device file, another user can only read the file.
Generally, objects are allocated on demand; that is, when a job step needs an
object, it allocates the object, uses the object, and deallocates the object so another
job can use it. The first job that requests the object is allocated the object. In your
program, you can handle the exceptions that occur if an object cannot be allocated
by your request. (See Chapter 7 and Chapter 8 for more information on monitoring
for messages or your high-level language reference manual for information on
handling exceptions.)
Sometimes you want to allocate an object for a job before the job needs the object,
to ensure its availability so a function that has only partially completed would not
have to wait for an object. This is called preallocating an object. You can preallocate
objects using the Allocate Object (ALCOBJ) command.
Objects are allocated on the basis of their intended use (read or update) and
whether they can be shared (used by more than one job). The file and member are
always allocated *SHRRD and the file data is allocated with the level of lock
Note: The allocation of a library does not restrict the operations that can be
performed on the objects within the library. That is, if one job places an
exclusive-allow-read or shared-for-update lock state on a library, other jobs
can no longer place objects in or remove objects from the library; however,
the other jobs can still update objects within the library.
The following table shows the valid lock state combinations for an object:
Table 5. Valid Lock State Combinations
If One Job Obtains This Lock State: Another Job Can Obtain This Lock State:
*EXCL None
*EXCLRD *SHRRD
*SHRUPD *SHRUPD or *SHRRD
*SHRNUP *SHRNUP or *SHRRD
*SHRRD *EXCLRD, *SHRUPD, *SHRNUP, or
*SHRRD
You can specify all five lock states (*EXCL, *EXCLRD, SHRUPD, SHRNUP, and
SHRRD) for most object types. this does not apply to all object types. Object types
that cannot have all five lock states specified are listed in the following table with
valid lock states for the object type:
Table 6. Valid Lock States for Specific Object Types
Object Type *EXCL *EXCLRD *SHRUPD *SHRNUP *SHRRD
Device x
description
To allocate an object, you must have object existence authority, object management
authority, or operational authority for the object. Allocated objects are automatically
deallocated at the end of a routing step. To deallocate an object at any other time,
use the Deallocate Object (DLCOBJ) command.
You can allocate a program before it is called to protect it from being deleted. To
prevent a program from running in different jobs at the same time, an exclusive lock
must be placed on the program in each job before the program is called in any job.
The following objects cannot be allocated with the ALCOBJ command:
v AS/400 Advanced 36 Machine
v AS/400 Advanced 36 Machine Configuration
You cannot use the ALCOBJ or DLCOBJ commands to allocate an APPC device
description.
The following example is a batch job that needs two files members for updating.
Members from either file can be read by another program while being updated, but
no other programs can update these members while this job is running. The first
member of each file is preallocated with an exclusive-allow-read lock state.
//JOB JOBD(ORDER)
ALCOBJ OBJ((FILEA *FILE *EXCLRD) (FILEB *FILE *EXCLRD))
CALL PROGX
//ENDJOB
Objects that are allocated to you should be deallocated as soon as you are finished
using them because other users may need those objects. However, allocated
objects are automatically deallocated at the end of the routing step.
If the first members of FILEA and FILEB had not been preallocated, the
exclusive-allow-read restriction would not have been in effect. When you are using
files, you may want to preallocate them so that you are assured they are not
changing while you are using them.
Note: If a single object has been allocated more than once (by more than one
allocate command), a single DLCOBJ command will not completely
deallocate that object. One deallocate command is required for each allocate
command.
It is not an error if the DLCOBJ command is issued against an object where you do
not have a lock or do not have the specific lock state requested to be allocated.
You can change the lock state of an object, as the following example shows:
PGM
ALCOBJ OBJ((FILEX *FILE *EXCL)) WAIT(0)
CALL PGMA
You can use record locks to allocate data records within a file. You can also use the
WAITFILE parameter on a Create File command to specify how long your program
is to wait for that file before a time-out occurs.
The WAITRCD parameter on a Create File command specifies how long to wait for
a record lock. The DFTWAIT parameter on the Create Class (CRTCLS) command
specifies how long to wait for other objects. For a discussion of the WAITRCD
parameter, see the Backup and Recovery book.
The WRKOBJLCK command displays all the lock state requests in the system for a
specified object. It displays both the held locks and the locks being waited for. For a
database file, the WRKOBJLCK command displays the locks at the file level (the
object level) but not at the record level. For example, if a database file is open for
update, the lock on the file is displayed, but the lock on any records within the file is
not. Locks on database file members can also be displayed using the WRKOBJLCK
command.
If you use the WRKJOB command, you can select the locks option on the Display
Job menu. This option displays all the lock state requests outstanding for the
specified active job, the locks being held by the job, and the locks for which the job
is waiting. However, if a job is waiting for a database record lock, this does not
appear on the object locks display.
The following command displays all the lock state requests in the system for the
logical file ORDFILL:
WRKOBJLCK OBJ(QGPL/ORDFILL) OBJTYPE(*FILE)
Most objects referred to in CL procedures and programs are not accessed until the
command referring to them is run. To qualify the name (library/name)of an object, it
must be in the specified library when the command that refers to it runs. However,
the object does not have to be in that library at the creation of the program. This
means that most objects can be qualified in CL source statements that are simply
based only on their run–time location. “Exceptions: Accessing Command Definitions,
Files, and Procedures.” on page 144 discusses the exceptions.
You can avoid this run–time consideration for all objects if you do not qualify object
names on CL source statements, but refer to the library list (*LIBL/name) instead. If
you refer to the library list at compile time, the object can be in any library on the
library list at command run time. This is possible providing you do not have
duplicate-name objects in different libraries. If you use the library list, you can move
the object to a different library between procedure creation and command
processing.
| Objects do not need to exist until the command that refers to them runs. Because
| of this, the CL program successfully compiles even though program PAYROLL does
| not exist at compile time:
| PGM /*TEST*/
| DCL...
| MONMSG...
| .
| .
| .
| CALL PGM(QGPL/PAYROLL)
| .
| .
| .
| ENDPGM
|
| In fact, PAYROLL does not have to exist when activating the program TEST, but
| only when running the CALL command. This creates the called program within the
| calling program immediately prior to the CALL command:
| PGM /*TEST*/
| DCL...
| .
| .
| .
| MONMSG
| .
| .
| .
| CRTCLPGM PGM(QGPL/PAYROLL)
| CALL PGM(QGPL/PAYROLL)
| .
| The name of the command must be the same when the program runs as when the
| system created it. An error occurs if the command name changes after creating a
| program that refers to that command. This is because the program cannot find the
| command when it runs. However, if a default changes for a parameter on a
| command, the new default is used when that command runs. For more detail on
| attributes that you may change on a command without having to re-create the
| command, see:
| v ″Effect of Changing the Command Definition of a Command in a Program″
| v The online help information for Change Command (CHGCMD) command.
| Accessing Files
| The compiler accesses files when compiling a program module that has a Declare
| File (DCLF) command. The file must exist when compiling a CL module or OPM
| program that uses it. The file does not have to exist when creating a program or
| service program that uses the module.
| Note: You can create other types of files from DDS, and each type has its own
| command: Create Physical File (CRTPF) and Create Logical File (CRTLF)
| are two that create files that you can use in CL programs and procedures.
| The fields that are described in the DDS can be input or output fields (or both). The
| system declares the fields in the CL program or procedure as variables when it
| compiles a program or module. The program manipulates data from display through
| these variables.
| If you do not use DDS to create a physical file, the system declares a CL variable
| to contain the entire record. This variable has the same name as the file, and its
| length is the same as the record length of the file.
CL programs and procedures cannot manipulate data in any types of files other
than display files and database files, except with specific CL commands.
| Deletion of the DDS after creating the file is possible but not recommended. You
| can delete the file after the system compiles the CL program or module that refers
| to the file. This is true provided the file exists when the command referring to it,
| such as a Receive File (RCVF), is processed in the program.
The rules on qualified names that are described here for command definitions also
apply to files. For more details on files, see “Working with Files in CL Procedures”
on page 146.
Accessing Procedures
| A procedure that is specified by Call Bound Procedure (CALLPRC), does not have
| to exist at the time a module that refers to it is created. The system requires the
| existence of the procedure in order to create a program or service program that
| uses the procedure. The called procedure may be:
| v In a module that is specified on the MODULE parameter on the Create Program
| (CRTPGM) or CRTSRVPGM command.
| v In a service program that is specified on the BNDSRVPGM parameter. The
| service program must be available at run time.
| v In a service program or module that is listed in a binding directory that is
| specified on the BNDDIR parameter of the CRTPGM command or CRTSRVPGM
| command. The binding directory and modules do not have to be available at run
| time.
To check for the existence of an object, use the Check Object (CHKOBJ) command.
You can use this command at any place in a procedure or program. The CHKOBJ
command has the following format:
CHKOBJ OBJ(library-name/object-name) OBJTYPE(object-type)
| When this command runs, the system sends messages to the program or
| procedure to report the result of the object check. You can monitor for these
| messages and handle them as you wish. For example:
| CHKOBJ OBJ(OELIB/PGMA) OBJTYPE(*PGM)
| MONMSG MSGID(CPF9801) EXEC(GOTO NOTFOUND)
| CALL OELIB/PGMA
| .
| .
| .
| NOTFOUND: CALL FIX001 /*PGMA Not Found Routine*/
| ENDPGM
| In this example, the MONMSG command checks only for the object-not-found
escape message. For a list of all the messages which the CHKOBJ command may
send see the online help information for the CHKOBJ command. “Using the Monitor
Message (MONMSG) Command” on page 47, Chapter 7, and Chapter 8 contain
additional information about monitoring for messages.
| The CHKOBJ command does not allocate an object. For many application uses the
| check for existence is not an adequate function, the application should allocate the
| object. The Allocate Object (ALCOBJ) command provides both an existence check
| and allocation.
Use the Check Tape (CHKTAP) or Check Diskette (CHKDKT) command to ensure
that a specific tape or diskette is placed on the drive and ready. These commands
also provide an escape message that you can monitor for in your CL program.
Note: Database files are made available for use within the CL procedure or
program through the DCLF and RCVF commands. See the discussion on
opening and closing database files in the DB2 UDB for AS/400 Database
Programming book; it contains information about the OPNDBF and CLOF
commands, which make database files available for later use in other
High-Level Language (HLL) programs and procedures.
Only one display or database file can be referred to in a CL procedure. The support
for database files and display files is similar as the same commands are used.
However, there are a few differences, which are described here.
v The following statements apply only to database files used with CL procedures
and programs:
– Only database files with a single record format may be used by a CL
procedure or program.
– The file may be either a physical or logical file, and a logical file may be
defined over multiple physical file members.
– Only input operations, with the RCVF command, are allowed. The SNDF,
SNDRCVF, ENDRCV, WAIT and DEV parameters on the RCVF command are
not allowed for database files.
– DDS is not required to create a physical file which is referred to in a CL
procedure or program. If DDS is not used to create a physical file, the file has
a record format with the same name as the file, and there is one field in the
record format with the same name as the file, and with the same length as the
record length of the file (RCDLEN parameter of the CRTPF command).
– The file need not have a member when it is created for the module or
program. It must, however, have a member when the file is processed by the
program.
– The file is opened for input only when the first RCVF command is processed.
The file must exist and have a member at that time.
– The file remains open until the procedure or OPM program returns or when
the end of file is reached. When end of file is reached, message CPF0864 is
sent to the CL procedure or program, and additional operations are not
allowed for the file. The procedure or program should monitor for this
message and take appropriate action when end of file is reached.
v The following statements apply only to display files used with CL procedures and
programs:
– Display files may have up to 99 record formats.
– All data manipulation commands (SNDF, SNDRCVF, RCVF, ENDRCV and
WAIT) are allowed for display files.
– The display file must be defined with the DDS.
– The display file is opened for both input and output when the first SNDF,
SNDRCVF, or RCVF command is processed. The file remains open until the
procedure or OPM program returns.
Note: The open does not occur for both types of files until the first send or receive
occurs. Because of this, the file to be used can be created during the
procedure or program and an override can be performed before the first
send or receive.
The format for the display is identified as a record format in DDS. Each record
format may contain fields (input, output, and input/output), conditions/indicators, and
See the DDS Reference book for more information about DDS.
You can use the methods discussed in the Application Display Programming book
or the Screen Design Aid (SDA) to enter DDS source for records and fields in the
display file. See the
These commands let a running program communicate with a device display using
the display functions provided by DDS, and to read records from a database file.
DDS provides functions for writing menus and performing basic application-oriented
data requests that are characteristic of many CL applications.
The fields on the display or in the record are identified in the DDS for the file. In
order for the CL procedure or program to use the fields, the file must be referred to
in the CL procedure or program by the DCLF command. This reference causes the
fields and indicators in the file to be declared automatically in your procedure or
program as variables. You can use these variables in any way in CL commands;
however, their primary purpose is to send information to and receive information
from a display. The DCLF command is not used at run time.
The format of the display and the options for the fields are specified in the device
file and controlled through the use of indicators. Up to 99 indicator values can be
used with DDS and CL support. Indicator variables are declared in your CL
procedure or program in the form of logical variables with names &IN01 through
&IN99 for each indicator that appears in the device file record formats referred to on
the DCLF command. Indicators let you display fields and control data management
display functions, and provide response information to your procedure or program
from the device display. Indicators are not used with database files.
If you have qualified the name of the file at compile time, the file must be in that
library at run time. If you have used the library list at compile time, the file must be
in a library on the library list at run time.
| When a database file opens, the first member in the file will open, unless you
| previously used an OVRDBF command to specify a different member (MBR
| parameter). If a procedure or OPM program ends because of an error, the files
| close. A file remains open until the procedure or OPM program in which that file
| was opened ends. Because of this, you have an easy way to share open data
| You can share files in this way between any two procedures or programs. Use
| online help for a detailed description of the function available when open data paths
| are shared. Additionally, you can see the description of the SHARE parameter on
| the CRTDSPF, CRTPF, and CRTLF commands in the CL Reference (Abridged)
| book. A display file opened in a CL procedure or OPM program always opens for
| both input and output. A database file opened in a CL procedure or OPM program
| opens for input only.
Declaring a File
The Declare File (DCLF) command is used to declare a display or database file to
your CL procedure or program. The DCLF command cannot be used to declare files
such as tape, diskette, printer, and mixed files. Only one DCLF command is allowed
in a CL procedure or OPM program. The DCLF command has the following
parameters:
DCLF FILE(library-name/file-name)
RCDFMT(record-format-names)
Note that the file must exist before the module or program is compiled.
| If you are using a display file in your procedure or program, you may have to
| specify input and output fields in your DDS. These fields are handled as variables in
| the procedure or program. When processing a DCLF command, the CL compiler
| declares CL variables for each field and option indicator in each record format in the
| file. For a field, the CL variable name is the field name preceded by an ampersand
| (&). For an option indicator, the CL variable name is the indicator that is preceded
| by &IN.
For example, if a field named INPUT and indicator 10 are defined in DDS, the
DCLF command automatically declares them as &INPUT and &IN10. This
declaration is performed when the CL module or program is compiled. Up to 50
record format names can be specified on one command, but none can be variables.
Only one record format may be specified for a database file.
If the following DDS were used to create display file CNTRLDSP in library
MCGANN:
Three variables, &IN01, &TEXT, and &RESPONSE, would be available from the
display file. In a CL procedure referring to this display file, you would enter only the
DCLF source statement:
DCLF MCGANN/CNTRLDSP
The compiler will expand this statement to individually declare all display file
variables. The expanded declaration in the compiler list looks like this:
v
v
v
500- DCLF MCGANN/CNTRLDSP
QUALIFIED FILE NAME 'MCGANN ' 'CNTRLDSP '
| The system formats the content of the variables associated with the output or
| output/input fields in the record format when you run a SNDF command.
| Additionally the system sends it to the display device. This is similar to when you
| run a RCVF command. The values of the fields associated with input or output/input
| fields in the record format on the display are placed in the corresponding CL
| variables.
| The SNDRCVF command sends the contents of the CL variables to the display.
| The command then performs the equivalent of a RCVF command to obtain the
| updated fields from the display. Note that CL does not support zoned decimal
| numbers. Consequently, fields in the display file that are defined as zoned decimal,
| cause *DEC fields to be defined in the CL procedure or program. *DEC fields are
| internally supported as packed decimal, and the CL commands convert the packed
| and zoned data types as required. Fields that overlap in the display file because of
| coincident display positions result in separately defined CL variables that do not
| overlap. You cannot use record formats that contain floating point data in a CL
| procedure or program.
The following example shows the steps required to create a typical operator menu
and to send and receive data using the SNDRCVF command. The menu looks like
this:
Operator Menu
1. Accounts Payable
2. Accounts Receivable
90. Signoff
Option:
First, enter the following DDS source. The record format is MENU, and OPTION is
an input-capable field. The OPTION field uses DSPATR(MDT). This causes the
system to check this field for valid values even if the operator does not enter
anything.
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A R MENU
A 1 2'Operator Menu'
A 3 4'1. Accounts Payable'
A 5 4'2. Accounts Receivable'
A 5 4'90. Signoff'
A 7 2'Option'
A OPTION 2Y 01 + 2VALUES(1 2 90) DSPATR(MDT)
A
A
Enter the CRTDSPF command to create the display file. In CL programming, the
display file name (INTMENU) can be the same as the record format name (MENU),
though this is not true for some other languages, like RPG for OS/400.
The display file could also be created using the Screen Design Aid (SDA) utility.
When this source is compiled, the DCLF command automatically declares the input
field OPTION in the procedure as a CL variable.
The SNDRCVF command defaults to WAIT(*YES); that is, the program waits until
input is received by the program.
This example shows a CL procedure, ORD040C, that controls the displaying of the
order department general menu and determines which HLL procedure to call based
on the option selected from the menu. The procedure shows the menu at the
display station.
Option:
The DDS for the display file ORD040C looks like this:
|...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
A* MENU ORDO4OCD ORDER DEPT GENERAL MENU
A
A R MENU TEXT('General Menu')
A 1 2'Order Dept General Menu'
A 3 3'1 Inquire into customer file'
A 4 3'2 Inquire into item file'
A 5 3'3 Customer name search'
A 6 3'4 Inquire into orders for a custom+
A er'
A 7 3'5 Inquire into existing order'
A 8 3'6 Order Entry'
A 9 2'98 End of menu'
A 11 2'Option'
A RESP 2Y001 11 10VALUES(1 2 3 4 5 6 98)
A DSPATR(MDT)
A
A
The DCLF command indicates which file contains the field attributes the system
needs to format the order department general menu when the SNDRCVF command
is processed. The system automatically declares a variable for each field in the
record format in the specified file if that record format is used in an SNDF, RCVF, or
SNDRCVF command. The variable name for each field automatically declared is an
ampersand (&) followed by the field name. For example, the variable name of the
response field RESP in ORD040C is &RESP.
Note: This menu is run using the CALL command. See the Application Display
Programming book for a discussion of those menus run using the GO
command.
When you override to a different file, only those record format names referred to on
the SNDF, RCVF, or SNDRCVF command need to be in the overriding file. In the
following illustration, display file FILEY does not need record format TWO or
THREE.
You should make sure that the record format referred to names of the original file
and the overriding files have the same field definitions and indicator names in the
same order. You may get unexpected results if you specify LVLCHK(*NO).
Another consideration has to do with the DEV parameter on the SNDF, RCVF, and
SNDRCVF commands when an OVRDSPF command is applied. If *FILE is
specified on the DEV parameter of the RCVF, SNDF, or SNDRCVF command, the
system automatically directs the operation to the correct device for the overridden
file. If a specific device is specified on the DEV keyword of the RCVF, SNDF, or
SNDRCVF command, one of the following may occur:
v If a single device display file is being used, an error will occur if the display file is
overridden to a device other than the one specified on the RCVF, SNDF, or
SNDRCVF command.
v If a multiple device display file is being used, an error will occur if the device
specified on the RCVF, SNDF, or SNDRCVF command is not among those
specified on the OVRDSPF command.
A multiple device display configuration occurs when a single job called by one
requester communicates with multiple display stations through one display file.
While only one display file can be handled by a CL procedure, the display file, or
different record formats within it, can be sent to several device displays. Commands
used primarily with multiple device display files are:
v End Receive (ENDRCV). This command cancels requests for input that have not
been satisfied.
v Wait (WAIT). Accepts input from any device display from which user data was
requested by one or more previous RCVF or SNDRCVF commands when
WAIT(*NO) was specified on the command, or by one or more previous SNDF
commands to a record format containing the INVITE DDS keyword.
If you use a multiple device display file, the device names must be specified on the
DEV parameter on the CRTDSPF command when the display file is created, on the
CHGDSPF command when the display file is changed, or on an override command,
and the number of devices must be less than or equal to the number specified on
the MAXDEV parameter on the CRTDSPF command.
Multiple device display configurations affect the SNDRCVF and the RCVF
commands and you may need to use the WAIT or ENDRCV commands. When an
RCVF or SNDRCVF command is used with multiple display devices, the default
value WAIT(*YES) prevents further processing until an input-capable field is
returned to the program from the device named on the DEV parameter. Because
the response may be delayed, it is sometimes useful to specify WAIT(*NO), thus
letting your procedure or program continue running other commands before the
receive operation is satisfied.
Using a SNDF command with a record format which has the DDS INVITE keyword
is equivalent to using a SNDRCVF command with WAIT(*NO) specified. The DDS
INVITE keyword is ignored for SNDRCVF and RCVF commands.
The WAIT will also be satisfied by the job being canceled with the controlled option
on the ENDJOB, ENDSYS, PWRDWNSYS, and ENDSBS commands. In this case,
message CPF0888 is issued and no data is returned. If a WAIT command is issued
without a preceding receive request (such as RCVF . . . WAIT(*NO)), a processing
error occurs.
DSPFILE WS2
┌───────────────────────────────────────┐ ┌───────────┐ ┌──────────┐
│ SNDF DEV(WS2) RCDFMT(1) ──────────────┼──┐ │ ┌───────┐ │ │ ________ │
│ RCVF DEV(WS2) RCDFMT(1) WAIT(*YES) Í──┼─┐└─┼─┤ FMT 1 ├─┼──Ê│ ________ │
│ . │ │ │ └───────┘ │ │ ________ │
│ . │ └──┼───────────┼───┤ │
│ SNDRCVF DEV(WS1) RCDFMT(2) WAIT (*NO)─┼─┐ │ │ └──────────┘
│ CALL PROGA │ │ │ │ WS1
│ . │ │ │ ┌───────┐ │ ┌──────────┐
│ . │ └──┼─┤ FMT 2 ├─┼──Ê│ ________ │
│ . │ │ └───────┘ │ │ ________ │
│ WAIT │ │ │ │ ________ │
│ . │ │ │ │ │
│ . │ │ │ └──────────┘
│ . │ │ │
└───────────────────────────────────────┘ └───────────┘
In the above example, the first two commands show a typical sequence in which
the default is taken; processing waits for the receive operation from WS2 to
complete. Because WS2 is specified on the DEV parameter, the RCVF command
does not run until WS2 responds, even if prior outstanding requests (not shown)
from other stations are satisfied.
The SNDRCVF command, however, has WAIT(*NO) specified and so does not wait
for a response from WS1. Instead, processing continues and PROGA is called.
Processing then stops at the WAIT command until an outstanding request is
satisfied by a work station, or until the function reaches time-out.
If the DEV parameter is specified, the CL variable name is the name of the device
that responded. (The default is *NONE.) If there are several receive requests (such
as RCVF. . . WAIT(*NO)), this variable takes the name of the first device to respond
after the WAIT command is encountered and processing continues. The data
received is placed in the variable associated with the field in the device display.
A RCVF command with WAIT(*YES) specified can be used to wait for data from a
specific device. The same record format name must be specified for both the
operation that started the receive request and the RCVF command.
In some cases, several receive requests are outstanding, but processing cannot
proceed further without a reply from a specific device display. In the following
example, three commands specify WAIT(*NO), but processing cannot continue at
label LOOP until WS3 replies:
PGM
.
.
.
SNDF DEV(WS1) RCDFMT(ONE)
SNDF DEV(WS2) RCDFMT(TWO)
SNDRCVF DEV(WS3) RCDFMT(THREE) WAIT(*NO)
RCVF DEV(WS2) RCDFMT(TWO) WAIT(*NO)
RCVF DEV(WS1) RCDFMT(ONE) WAIT(*NO)
CALL...
CL procedures and programs also support the ENDRCV command, which lets you
cancel a request for input that has not yet been satisfied. A SNDF or SNDRCVF
command will also cancel a request for input that has not yet been satisfied.
However, if the data was available at the time the SNDF or SNDRCVF command
was processed, message CPF0887 is sent. In this case the data must be received
with the WAIT command or RCVF command, or the request must be explicitly
canceled with a ENDRCV command before the SNDF or SNDRCVF command can
be processed.
When you run a RCVF command, the next record on the file’s access path is read,
and the values of the fields defined in the database record format are placed in the
corresponding CL variables. Note that CL does not support zoned decimal or binary
numbers. Consequently, fields in the database file defined as zoned decimal or
binary cause *DEC fields to be defined in the CL procedure or program. *DEC fields
are internally supported as packed decimal, and the RCVF command performs the
conversion from zoned decimal and binary to packed decimal as required.
Database files which contain floating point data cannot be used in a CL procedure
or program.
When the end of file is reached, message CPF0864 is sent to the procedure or
OPM program. The CL variables declared for the record format are not changed by
the processing of the RCVF command when this message is sent. You should
monitor for this message and perform the appropriate action for end of file. If you
attempt to run additional RCVF commands after end of file has been reached,
message CPF0864 is sent again.
When you override to a different file, the overriding file must have only one record
format. A logical file which has multiple record formats defined in DDS may be used
if it is defined over only one physical file member. A logical file which has only one
record format defined in the DDS may be defined over more than one physical file
member. The name of the format does not have to be the same as the format name
referred to when the program was created. You should ensure that the format of the
data in the overriding file is the same as in the original file. You may get unexpected
results if you specify LVLCHK(*NO). See the DB2 UDB for AS/400 Database
Programming book for more information about LVLCHK considerations.
The following CL procedure accepts two parameters, a user name and a library
name. The procedure determines the names of all programs, files, and data areas
in the library and grants normal authority to the specified users.
PGM PARM(&USER &LIB)
DCL &USER *CHAR 10
DCL &LIB *CHAR 10
(1) DCLF QSYS/QADSPOBJ
(2) DSPOBJD OBJ(&LIB/*ALL) OBJTYPE(*FILE *PGM *DTAARA) +
OUTPUT(*OUTFILE) OUTFILE(QTEMP/DSPOBJD)
(3) OVRDBF QADSPOBJ TOFILE(QTEMP/DSPOBJD)
(4) READ: RCVF
(5) MONMSG CPF0864 EXEC(RETURN) /* EXIT WHEN END OF FILE REACHED */
(6) GRTOBJAUT OBJ(&ODLBNM/&ODOBNM) OBJTYPE(&ODOBTP) +
USER(&USER) AUT(*CHANGE)
GOTO READ /*GO BACK FOR NEXT RECORD*/
ENDPGM
(1) The declared file, QADSPOBJ in QSYS, is the IBM-supplied file that is used
by the DSPOBJD command. This file is the primary file which is referred to
by the command when creating the output file. It is referred to by the CL
compiler to determine the format of the records and to declare variables for
the fields in the record format.
(2) The DSPOBJD command creates a file named DSPOBJD in library
QTEMP. This file has the same format as file QADSPOBJ.
This chapter includes General Use Programming Interface (GUPI), which IBM
makes available for use in customer-written programs.
After the command runs, control returns to your HLL or CL procedure or program.
| Enter the command you wish to run as a character string on the first parameter.
| You must enclose the command in apostrophes if it contains blanks. The maximum
| length of the character string is 6000 characters; never count the delimiters (the
| apostrophes ) as part of the string. The length that is specified as the second value
| on the PARM parameter is the length of the character string that is passed as the
| command. Length must be a packed decimal value of length 15 with 5 decimal
| positions.
Thus, to replace a library list, the call to the QCMDEXC program would look like
this:
CALL PGM(QCMDEXC) PARM('CHGLIBL LIBL(QGPL NEWLIB QTEMP)' 31)
It is possible to code this statement into the HLL or CL program to replace the
library list when the program runs. The QCMDEXC program does not provide
run-time flexibility when used this way.
| For instance:
|
| The command length, passed to the QCMDEXC program on the second parameter,
is the maximum length of the passed command string. Should the command string
be passed as a quoted string, the command length is exactly the length of the
quoted string. Should the command string be passed in a variable, the command
length is the length of the CL variable. It is not necessary to reduce the command
length to the actual length of the command string in the variable, although it is
permissible to do so.
Not all commands can be run using the QCMDEXC program. The command
passed on a call to the QCMDEXC program must be valid within the current
environment (interactive or batch) in which the call is being made. The command
cannot be one of the following:
v An input stream control command (BCHJOB, ENDBCHJOB, and DATA)
v A command that can be used only in a CL program
You can precede the CL command with a question mark (?) to request prompting or
use selective prompting when you call QCMDEXC in an interactive job.
See the appropriate HLL reference for information on how HLL programs handle
errors on calls.
The third parameter of the QCMDEXC program, IGC, instructs the system to accept
double-byte data. For example, the following CL program asks a user to provide
double-byte text for a message. Then the system sends the following message:
PGM
CALL QCMDEXC ('?SNDMSG' 7 IGC)
ENDPGM
The following display is shown after running the QCMDEXC program. You can use
double-byte conversion on this display:
SEND MESSAGE (SNDMSG)
BOTTOM
F3=EXIT F4=PROMPT F5=REFRESH F10=ADDITIONAL PARAMETERS F12=CANCEL
F13=HOW TO USE THIS DISPLAY F24=MORE KEYS
The second parameter is the maximum length of the command string being passed.
If the command string is passed as a quoted string, the command length is exactly
the length of the quoted string. If the command string is passed in a variable, the
command length is the length of the CL variable. The second parameter must be a
packed decimal value of length 15 with 5 decimal positions.
If a syntax error is detected on the command, message CPF0006 is sent. You can
monitor for this message to determine if an error occurred on the command.
Message CPF0006 is preceded by one or more diagnostic messages that identify
the error. In the following example, control is passed to the label ERROR within the
program, because the value 123 is not valid for the PGM parameter of the
CRTCLPGM command.
CALL QCMDCHK ('CRTCLPGM PGM(QGPL/123)' 22)
MONMSG CPF0006 EXEC(GOTO ERROR)
You can request prompting for the command by either placing a question mark
before the command name or by placing selective prompt characters before one or
more keyword names in the command string.
If no errors are detected during checking and prompting for the command, the
updated command string is placed in the variable specified for the first parameter.
The prompt request characters are removed from the command string. This is
shown in the following example:
DCL &CMD *CHAR 2000
.
.
CHGVAR &CMD '?CRTCLPGM'
CALL QCMDCHK (&CMD 2000)
After the call to the QCMDCHK program is run, variable &CMD contains the
command string with all values entered through the prompter. This might be
something like:
CRTCLPGM PGM(PGMA) SRCFILE(TESTLIB/SOURCE) USRPRF(*OWNER)
Note that the question mark preceding the command name is removed.
When prompting is requested through the QCMDCHK program, the command string
should be passed in a CL variable. Otherwise, the updated command string is not
returned to your procedure or program. You must also be sure that the variable for
the command string is long enough to contain the updated command string which is
returned from the prompter. If it is not long enough, message CPF0005 is sent, and
the variable containing the command string is not changed. Without selective
prompting, the prompter only returns entries that were typed by the user.
The length of the variable is determined by the value of the second parameter, and
not the actual length of the variable. In the following example, escape message
CPF0005 is sent because the specified length is too short to contain the updated
command, even though the variable was declared with an adequate length.
DCL &CMD *CHAR 2000
.
.
CHGVAR &CMD '?CRTCLPGM'
CALL QCMDCHK (&CMD 9)
When you use message subfiles in CL procedures and programs, you must name a
procedure or program. You cannot specify an * for the SFLPGMQ keyword in DDS.
When you specify a procedure or OPM program name, all messages sent to that
procedure’s or program’s message queue are taken from the invocation message
queue and placed in the message subfile. All messages associated with the current
request are taken from the CALL message queue and placed in the message
subfile.
Message subfiles let a controlling procedure or program display one or more error
messages.
You can also prompt the work station user for input to a CL procedure or program
in the following ways:
v If you enter a ? before the CL command in the CL procedure or program source,
the system displays a prompt for the CL command. Parameter values you have
already specified in your procedure or program are filled in and cannot be
changed by the work station user. See “Using the Prompter within a CL
Procedure or Program” later in this section.
v If you call the QCMDEXC program and request selective prompting, the system
displays a prompt for a CL command, but you need not specify in the CL
program source which CL command is to be used at processing time. For more
information on the QCMDEXC program, see “Using the QCMDEXC Program” on
page 161.
In this case, the prompt for the Display Library (DSPLIB) command appears on the
display during processing of the program. Processing of the DSPLIB command
waits until you have entered values for required parameters and pressed the Enter
key.
Any values specified in the source procedure cannot be changed directly by the
operator (or user). For example:
PGM
.
.
.
?SNDMSG TOMSGQ(WS01 WS02)
.
.
.
ENDPGM
When the procedure is called and the prompt for the Send Message (SNDMSG)
command appears, the operator (or user) can enter values on the MSG,
MSGTYPE, and RPYMSGQ parameters, but cannot alter the values on the
TOMSGQ parameter. For example, the operator (or user) cannot add WS03 or
delete WS02. See “QCMDEXC with Prompting in CL Procedures and Programs” on
page 171 for an exception to this restriction. The following restrictions apply to the
use of the prompter within a CL procedure at processing time:
v When the prompter is called from a CL procedure or program, you cannot enter a
variable name or an expression for a parameter value on the prompt.
v Prompting cannot be requested on a command embedded on an IF, ELSE, or
MONMSG command:
Correct Incorrect
If you press F3 or F12 to cancel the prompted command while running that
command, an escape message (CPF6801) is sent to the CL procedure or program.
You can monitor for this message using the MONMSG command in the CL
procedure or program.
When you prompt for a command, your procedure or program does not receive the
command string you entered. To achieve this, prompt using QCMDCHK, then run
the command using QCMDEXC. You can also use QCAPCMD to prompt and run
the command.
You can press F5 while you are using selective prompting to again display those
values initially shown on the display.
the three parameters, FILE, TOFILE, and MBR is shown on the prompt display. The
value specified for the FILE parameter cannot be changed by you, but the values
for the TOFILE and MBR parameters can be changed. Assume that the CL variable
&FILENAME has a value of FILE1, and you change it to FILE2. When the
command is run, the value of FILE2 is used, but the value of &FILENAME is not
changed in the procedure. The following tables list the various selective prompting
characters and the resulting action.
Value Passed to
CPP if Nothing Marked with >
You Enter Value Displayed Protected Specified Symbol
??KEYWORD() Default No Default No
??KEYWORD(VALUE) Value No Value Yes
?*KEYWORD() Default Yes Default No
?*KEYWORD(VALUE) Value Yes Value Yes
?<KEYWORD() Default No Default No
?<KEYWORD(VALUE) Value No Default No
?/KEYWORD() Default Yes Default No
?/KEYWORD(VALUE) Value Yes Default No
?-KEYWORD() None N/A Default N/A
?-KEYWORD(VALUE) None N/A Value N/A
?&KEYWORD() Default No Default No
?&KEYWORD(VALUE) Value No Default No
?%KEYWORD() Default Yes Default No
?%KEYWORD(VALUE) Value Yes Default No
Selective prompting can be used with the QCMDEXC or QCMDCHK program. The
format of the call is:
CALL PGM(QCMDEXC or QCMDCHK) PARM(command command-length)
you can specify a value for any parameter except FILE. However, if the command is
called during processing of a program using the QCMDEXC program, such as:
CALL QCMDEXC PARM('?OVRDBF FILE(FILEX)' 19)
you can specify a value for any parameter, including FILE. In this example, FILEX is
the default.
The command may be used with one or more of the parameters that control the
initial values of the menu. You could design this as part of an initial program for
sign-on or for situations in which a user calls a specific user-written function. The
following example shows such a program, with a separate function for each
application area requiring different initial values.
PGM
CHGLIBL LIBL(PGMR1 QGPL QTEMP)
LOOP:
STRPGMMNU SRCLIB(PGMR1) OBJLIB(PGMR1) JOBD(PGMR1)
MONMSG MSGID(CPF2320) EXEC(GOTO END) /* F3 or F12 to leave menu */
GOTO LOOP
END: ENDPGM
v Controlling programmer menu options
The other parameters assist you in controlling the menu and its functions. For
example, you can specify ALWUSRCHG(*NO) to prevent a user from changing
the values that appear on the menu. This parameter should not be considered to
be a security feature because a user who is using the menu can call the
STRPGMMNU command and change the values in a separate call. (The user
can also start functions by using F10 to call the command entry display.) If the
menu is displayed by the STRPGMMNU command, you can prevent the user (by
authorization) from calling the QPGMMENU program directly, but you cannot
prevent the user from requesting another call of the STRPGMMNU command.
v Adapting the menu create option
The EXITPGM and DLTOPT parameters allow you to provide your own support
for the menu create option (option 3). A user program may be called when option
3 is requested. For a full discussion of the parameters and the parameter list
passed to the user program, see CL Reference (Abridged). The following
describes some typical uses of the EXITPGM parameter.
When run, this program shows you how the different keyboard shifts for DDS
display files are used. See DDS Reference for information about double-byte
keyboard shifts.
RV3W197-0
Sample CL Programs
The following sample programs demonstrate the flexibility, simplicity, and versatility
of CL programs. The following programs are described by their function and
probable user.
| Note: Code generated by the ILE CL compiler in V4R3 and later releases is
| threadsafe. However, many commands are not threadsafe. Therefore, do not
| consider a CL procedure as threadsafe unless all the commands the CL
| procedure uses are threadsafe. You can use the Display Command
| (DSPCMD) command to determine if a command is threadsafe. For
| additional information on threads, please access the IBM Information Center
| and open the topics under the PROGRAMMING heading. The uniform
| resource locator (URL) for the Information Center is:
The test library is placed first on the library list, an output queue is selected for a
convenient printer, and the programmer menu is displayed.
The object name, object type, and operation code are passed from another program
or procedure. Checks are performed to see that the operation code and object type
are correct, and that the object exists in the test library. The object is moved unless
it already exists in the production library. The move is then confirmed. More
commands can be added to grant additional authority to the object or to handle
additional exceptions and additional object types.
This program ensures consistent command entry for regularly repeated procedures.
PGM
DCL &SWITCH *CHAR LEN(1)
RTVSYSVAL SYSVAL(QABNORMSW) RTNVAR(&SWITCH)
IF (&SWITCH *EQ '1') THEN(DO) /*CALL RECOVERY PROGRAMS*/
SNDPGMMSG MSG('Recovery programs in process. +
Do not start subsystems until notified') +
MSGTYPE(*INFO) TOMSGQ(QSYSOPR)
CALL PGMA
CALL PGMB
SNDPGMMSG MSG('Recovery programs complete. +
Startup subsystems') +
MSGTYPE(*INFO) TOMSGQ(QSYSOPR)
RETURN
ENDDO
ENDPGM
Instead of typing in all the parameters for submitting a job, the system operator
simply calls DAILYAC.
This program illustrates how to write a CL program using a display file that will wait
for a specified amount of time for the user to enter an option. If he does not, the
user is signed off.
The display file will use the *REQUESTER device. When a WAIT command is
issued, it waits for the number of seconds (60) specified on the WAITRCD keyword.
The following is the DDS for the display file:
SEQNBR *... ... 1 ... ... 2 ... ... 3 ... ... 4 ... ... 5 ... ... 6 ... ... 7 ... ... 8
* * * * * * E N D O F S O U R C E * * * * *
The program performs a SNDRCVF WAIT(*NO) to display the menu and request an
option from the user. Then it issues a WAIT command to accept an option from the
user. If the user enters a 1 through 4, the appropriate program is called. If the user
enters a 9, the SIGNOFF command is issued. If the user enters an option that is
not valid, the menu is displayed with an ’OPTION SELECTED NOT VALID’
message. The user can then enter another valid option. If the user does not
respond within 60 seconds, the CPF0889 message is issued to the program and
the MONMSG command issues the SIGNOFF command.
END: ENDPGM
Your system comes with an extensive set of predefined messages that allow
communication between programs within the system and between the system and
its users. Each licensed program you order has a message file that is stored in the
same library as the licensed program it applies to. For example, system messages
are stored in the file QCPFMSG in the library QSYS.
All messages that are sent or received in the system are transmitted through a
message queue. Messages that are issued in response to a direct request, such as
a command, are automatically displayed on the display from which the request was
made. For all other messages, the user, program or procedure must receive the
message from the queue or display it. There are several IBM-supplied message
queues in the system; these message queues are described later in this chapter
(see “Types of Message Queues” on page 199).
The system also writes some of the messages that are issued to logs. A job log
contains information related to requests entered for a job, the history log contains
job, subsystem, and device status information. See “Message Logging” on page 265
for more information on logging.
You can create your own message files and message descriptions. By creating
predefined messages, you can use the same message in several procedures or
programs but define it only once. You can also change and translate predefined
messages into languages other than English (based on the user viewing the
messages) without affecting the procedures and programs that use them. If the
messages were defined in the procedure or program, the module or program would
have to be recompiled when you change the messages.
In addition to creating your own messages and message files, the system message
handling function allows you to:
v Create and change message queues (Create Message Queue [CRTMSGQ],
Change Message Queue [CHGMSGQ], and Work with Message Queues
[WRKMSGQ] commands)
On the CRTMSGF command, you can specify the maximum size in K bytes on the
SIZE parameter. The following formula can be used to determine the maximum:
S + (I x N)
where:
S Is the initial amount of storage
I Is the amount of storage to add each time
N Is the number of times to add storage
For example, you specify S as 5, I as 1, and N as 2. When the file reaches the
initial storage amount of 5K, the system automatically adds another 1K to the initial
storage. The amount added (1K) can be added to the storage two times to make
the total maximum of 7K. If you specify *NOMAX as N, the maximum size of the
message file is 16M.
When you specify a maximum size for a message file and the message file
becomes full, you cannot change the size of the message file. You then need to
create another message file and re-create the messages in the new file. The Merge
Message File (MRGMSGF) command can be used to copy message descriptions
from one message file to another. Since you will want to avoid this step, it is
important to calculate the size needed for your message file when you create it, or
specify *NOMAX.
The smallest possible entry in a message file is 59 bytes and the largest possible
entry is 5764 bytes. The following table describes the largest possible entry:
In the following example, the CRTMSGF command creates the message file
USRMSG:
CRTMSGF MSGF(QGPL/USRMSG) +
TEXT('Message file for user-created messages')
If you are creating a message file to be used with the DSPLY operation code in
RPG for OS/400, the message file must be named QUSERMSG.
Each of the items that can be contained in the message description is described in
more detail on the following pages.
The following commands are also available for use with message descriptions:
Change Message Description (CHGMSGD)
Changes a message description.
Display Message Description (DSPMSGD)
Displays a message description. (A range of message identifiers can be
specified in this command.)
Remove Message Description (RMVMSGD)
Removes a message description from a message file.
Retrieve Message (RTVMSG)
Retrieves a message from a message file.
Merge Message File (MRGMSGF)
Merges messages from one message file into another message file.
Work with Message Descriptions (WRKMSGD)
Displays a list of messages in a file and allows you to add, change, or
delete message descriptions.
where ppp is the product or application code, mm is the numeric group code, and nn
is the numeric subtype code. The number specified as mmnn can be used to further
divide a set of product or application messages. Numeric group and subtype codes
consist of decimal numbers 0 through 9 and the characters A through F.
For example:
CPF1234
When you create your own messages, using the letter U as the first character in the
product code is a good way to distinguish your messages from system messages.
For example:
USR3567
You should use care in using a numeric subtype code of 00 in the message
identifier. If you use a numeric subtype code of 00 for a message that can be sent
as an escape, notify, or status message and that can, therefore, be monitored, a
subtype code of 00 in the Monitor Message (MONMSG) command causes all
messages in the numeric group to be monitored. See “Monitoring for Messages in a
CL Program or Procedure” on page 235 for more information.
Each of the three format control characters must be followed by a blank to separate
them from the message text.
&Nb (where b is a blank)
Forces the text to a new line (column 2). If the text is longer than one line,
the next lines are indented to column 4 until the end of the text or until
another format control character is found.
&Pb (where b is a blank)
Forces the text to a new line, indented to column 6. If the text is longer than
one line, the next lines start in column 4 until the end of the text or until
another format control character is found.
&Bb (where b is a blank)
Forces the text to a new line, starting in column 4. If the text is longer than
one line, the next lines are indented to column 6 until the end of the text or
until another format control character is found.
00: Information. For information purposes only; no error was detected and no reply
is needed. The message could indicate that a function is in progress or that a
function has completed successfully.
20: Error. An error has been detected, but it is one for which automatic recovery
procedures probably were applied; processing has continued. A default may have
been taken to replace erroneous input. The results of the operation may not be
valid. The function may have been only partially completed; for example, some
items in a list processed correctly while others failed.
30: Severe error. The error detected is too severe for automatic recovery, and no
defaults are possible. If the error was in source data, the entire input record was
skipped. If the error occurred during procedure or program processing, it leads to
an abnormal end of the procedure or program (severity 40). The results of the
operation are not valid.
40: Abnormal end of procedure or function. The operation has ended, possibly
because the procedure or program was unable to handle data that was not valid, or
possibly because the user has canceled it.
50: Abnormal end of job. The job was ended or was not started. A routing step may
have ended abnormally or failed to start, a job-level function may not have been
performed as required, or the job may have been canceled.
60: System status. Issued only to the system operator. It gives either the status of
or a warning about a device, a subsystem, or the system.
70: Device integrity. Issued only to the system operator. It indicates that a device is
malfunctioning or in some way is no longer operational. The user may be able to
recover from the failure, or the assistance of a service representative may be
required.
80: System alert. A message with a severity code of 80 is issued for immediate
messages. It also warns of a condition that, although not severe enough to stop the
system now, could become more severe unless preventive measures are taken.
90: System integrity. Issued only to the system operator. It describes a condition
that renders either a subsystem or the system inoperative.
99: Action. Some manual action is required, such as entering a reply, changing
printer forms, or replacing diskettes.
For a detailed discussion of the SEV parameter, see the CL Reference (Abridged)
book.
contains the substitution variable &1. When the message is displayed or retrieved,
the variable &1 is replaced with the name of the file that could not be found. This
name is supplied by the sender of the message. For example:
File ORDHDRP not found
Substitution variables can make your message more specific and more meaningful.
The substitution variable must begin with & (ampersand) and be followed by n,
where n is any number from 1 through 99. For example, for the message:
File &1 not found
When you assign numbers to substitution variables, you must begin with the
number 1 and use the numbers consecutively. For example, &1, &2, &3, and so on.
However, you do not have to use all the substitution variables defined for a
message description in the message that is sent.
is valid even though &1 and &2 are not used in the messages. However, to do this,
you must define &1, &2, and &3 on the FMT parameter of the ADDMSGD
command. For the preceding message, the FMT parameter could be:
FMT((*CHAR 10) (*CHAR 2) (*CHAR 10))
where the first value describes &1, the second &2, and the third &3. The description
for &1 and &2 must be present if &3 is used. In addition, when this message is
sent, the MSGDTA parameter on the Send Program Message (SNDPGMMSG)
command should include all the data described on the FMT parameter. To send the
preceding message, the MSGDTA parameter should be at least 22 characters long.
For the preceding message, you could also specify the FMT parameter as:
FMT((*CHAR 0) (*CHAR 0) (*CHAR 10))
Because &1 and &2 are not used in the message, they can be described with a
length of 0. Then no message data needs to be sent. (The MSGDTA parameter on
the SNDPGMMSG command needs to be only 10 characters long in this case.)
An example of using &3 in the message and including &1 and &2 in the FMT
parameter is when &1 and &2 are specified on the DMPLST parameter. (The
DMPLST parameter specifies that the data is to be dumped when this message is
sent as an escape message to a program that is not monitoring for it.)
The substitution variables do not have to be specified in the message in the same
order in which they are defined in the FMT parameter. For example, three values
can be defined in the FMT parameter as:
FMT((*CHAR 10) (*CHAR 10) (*CHAR 7))
The following data types are valid only in IBM-supplied message descriptions and
should not be used for other messages:
v Time interval (*ITV). An 8-byte time interval that contains the time to the nearest
whole second for various wait time out conditions.
v Date and time stamp (*DTS). An 8-byte system date and time stamp for which
the date is to be formatted as specified in the QDATFMT and QDATSEP system
values and the time is to be formatted as hh:mm:ss.
Note: If you do not specify any validity checking (VALUES, RANGE, REL,
SPCVAL, DFT), the maximum length of a reply is 132 characters for types
*CHAR and *ALPHA.
v Values that can be used for the reply
– A list of values (VALUES)
– A list of special values (SPCVAL)
– A range of values (RANGE)
– A simple relationship that the reply value must meet (REL)
Note: The special values are values that can be accepted but that do not satisfy
any other validity checking values.
When a display station user enters a reply to a message, the keyboard is in lower
shift which causes lowercase characters to be entered. If your program needs the
reply to be in uppercase characters, you can do one of the following:
v Use the SNDUSRMSG command which supports a translation table option which
defaults to converting lowercase to uppercase.
v Require the display station user to enter uppercase characters by specifying only
uppercase characters for the VALUES parameter.
v Specify the VALUES parameter as uppercase and use the SPCVAL parameter to
convert the corresponding lowercase characters to uppercase.
v Use TYPE(*NAME) if the characters to be entered are all letters (A-Z). The
characters are converted to uppercase before being checked.
The SNDPGMMSG command sends the message and specifies the KEYVAR
parameter. This returns a message reference key, which uniquely identifies this
message so that the reply can be properly matched with the RCVMSG command.
The KEYVAR value must be defined as a character field length of 4.
The RCVMSG command specifies the message reference key value from the
SNDPGMMSG command for the MSGKEY parameter to receive the specific
message. The reply is passed back into the MSG parameter. The WAIT parameter
specifies how long to wait for a reply before timing out.
When the reply is received, the procedure logic checks for an upper or lower case
value of the Y or N. Normally the value is entered by the operator as a lower case
value. If the operator enters a non-blank value other than Y or N, the procedure
sends a different message and then repeats the inquiry message.
If the operator had entered a blank, no reply is sent to the procedure. If a blank is
returned to the procedure, the time out occurred (the operator did not reply). The
procedure sends a message to the system operator stating that a reply was not
received and the default was assumed (the ’Y’’ value is shown as ’Y’ in the
message queue). Because the assumed value of ’Y’ is not displayed as the reply,
you cannot determine when looking at a message queue whether the message
should be answered or has already timed out. The procedure does not remove a
message from the message queue once it has been sent. The second message
should minimize this concern and provides an audit trail for what has occurred.
If the time out has already occurred and the operator replies to the message, the
reply is ignored. The operator receives no indication that the reply has been
ignored.
Default replies are also used when the job attribute of INQMSGRPY is set to *DFT
and may be used if set to *SYSRPYL option. You can use the system reply list to
change the default reply.
| Default replies are also used on the Display Program Messages screen (which
| shows messages that are sent to *EXT). The sending of the default reply occurs
| during either of the two following conditions:
| v The Display Program Messages screen appears showing an unanswered inquiry
| message and the user presses Enter (to continue) without keying-in any reply.
| v The user pressed the F3 key to exit the Display Program Messages screen.
| .
If you do not specify default actions in message descriptions, you will get a dump of
the job (as if DSPJOB JOB(*) OUTPUT(*PRINT) was specified).
The default action specified in a message is taken only after the message
percolation action is completed without the escape message being handled. See
“Default Handling” on page 240 for more information on handling defaults.
The program receives all the diagnostic messages in FIFO order. Then it sends the
last diagnostic message as an escape message to allow the previous program to
monitor for it.
You can use the DSPMSGD or WRKMSGD command to print or display message
descriptions.
The SECLVL parameter provides very simple text. To make this appear on the
Additional Message Information display, you specify SECLVL('message text'). The
text you specify on this parameter appears on the Additional Message Information
display when you press the Help key after placing the cursor on this message.
When a message file name is overridden but the message identifier is not
contained in the overridden file, the message file name and library specified are
also used to search for the message file.
The system search depends on whether you specify the message file library as
either *CURLIB or *LIBL. The following describes the search path for *CURLIB and
*LIBL:
v Specify as *CURLIB or explicitly specify the message file library
The system searches for the message file named in the specified library or the
job’s current library (*CURLIB).
v Specify the message file library as *LIBL
The system searches for the message file named in the job’s library list (*LIBL).
The search stops after finding the first message file with the specified name.
If the message file is found, but does not contain a description for the message
identifier, the message attributes and text of message CPF2457 in QCPFMSG are
used in place of the missing message description.
If the message file was not found, the system attempts to retrieve the message
from the message file that was used at the time the message was sent.
Note: A message file may be found but cannot be accessed due to damage or an
authorization problem.
To override a message file, use the Override Message File (OVRMSGF) command.
The file overridden is specified in the MSGF parameter; the file overriding it is
specified in the TOMSGF parameter.
For example, to override QCPFMSG with a user message file named USRMSGF,
the following command would be used:
OVRMSGF MSGF(QCPFMSG) TOMSGF(USRMSGF)
Another way you can select the message file from which messages are to be
retrieved is by changing the order of the files in the library list for the job. However,
if you use this approach, the search for the message stops on the first message file
found that has the specified name. If the message is not in that file, the search
stops.
For example, assume that a message file named USRMSG is in library USRLIB1,
and another message file named USRMSG is in library USRLIB2. To use the
message file in USRLIB1, USRLIB1 should precede USRLIB2 in the library list:
The system searches the first message file found with the correct name. If that file
does not contain the message, the search stops. However, if you use the
OVRMSGF command, the system searches the overriding file, and if the message
is not there, it searches the overridden file.
to say:
Object XXX in YYY deleted
Specifics on how to describe the FMT parameter are provided by displaying the
detailed description of CPC2191.
You then use the OVRMSGF command to override the message file when you run
the job:
OVRMSGF MSGF(QCPFMSG) TOMSGF(USRMSG/OVRCPF)
Libraries
QSYS
Library List ┌────────┐
┌───────────┐ ┌────────Ê│ QCPFMSG│
│ QSYS ├─┘ │ │
├───────────┤ │ . │
│ QGPL │ │ . │
├───────────┤ │ . │
│ QTEMP │ └────────┘
├───────────┤ QGPL
│ USERLIB │ ┌────────┐
├───────────┤ │ │
│ USRMSG ├─────────┐ │ │
└───────────┘ │ │ . │
│ │ . │
│ │ . │
│ └────────┘
│ QTEMP
│ ┌────────┐
│ │ │
│ │ │
│ │ . │
│ │ . │
│ │ . │
│ └────────┘
│ USERLI
│ ┌────────┐
│ │ │
│ │ │
│ │ . │
│ │ . │
│ │ . │
The system searches │ └────────┘
the overriding │ USRMSG
message file (USRMSG) │ ┌────────┐
for the message. If └Ê│ OVRCPF │
the message is not in │ │
the overriding file, │ . │
the system then │ . │
searches the overidden │ . │
file (QCPFMSG). └────────┘
If you want to change this message for use in all your jobs, you can use the
Change Message Description (CHGMSGD) command to change the message.
Then you do not have to override the system message file.
You can also override overriding files. For example, you can specify the following
OVRMSGF commands during a job.
OVRMSGF MSGF(MSGFILE1) TOMSGF(MSGFILE2)
OVRMSGF MSGF(MSGFILE2) TOMSGF(MSGFILE3)
First, file MSGFILE1 was overridden with MSGFILE2. Second, MSGFILE2 was
overridden with MSGFILE3. When a message is sent, the files are searched in this
order:
1. MSGFILE3
2. MSGFILE2
3. MSGFILE1
You can prevent message files from being overridden. To do so, you must specify
the SECURE parameter on the OVRMSGF command.
The following diagrams show the message queues supplied by IBM. A message
queue is supplied for each display station (where DSP01 and DSP02 are display
station names) and each user profile (where BOB and RAY are user profile names):
┌─────────┐ ┌─────────┐ ┌─────────┐
│ DSP01 │ │ DSP02 │ . . . │ DSPxx │
│ │ │ │ │ │
└─────────┘ └─────────┘ └─────────┘
Job message queues are supplied for each job running on the system. Each job is
given an external message queue (*EXT) and each call of an OPM program or ILE
procedure within the job has its own call message queue.
JOB1 JOB2 JOBx
┌─────────┐ ┌─────────┐ ┌─────────┐
│ *EXT │ │ *EXT │ │ *EXT │ External message queue
├─────────┤ ├─────────┤ ├─────────┤
│ PROG1 │ │ PROC_A │ │ PROGX │ Call message queues
├─────────┤ ├─────────┤ . . . ├─────────┤
│ PROC_1 │ │ PROGB │ │ PROC_Y │ │
├─────────┤ ├─────────┤ ├─────────┤ │
│ PROC_2 │ │ PROGC │ │ PROGZ │ ø
└─────────┘ └─────────┘ └─────────┘
Message queues are also supplied for the system history log (QHST) and the
system operator (QSYSOPR):
In addition to these message queues, you can create your own user message
queues for sending messages to system users and between application programs.
| Note: When a work station device description is created, the system establishes a
message queue for the device to receive all action messages for the device.
For work station printers, tape drives, and APPC devices, the MSGQ
parameter can be used to specify a message queue when creating a device
description. If no message queue is specified for these devices, the default,
QSYSOPR, is used as the message queue. All other devices are assigned to
the QSYSOPR message queue when they are created.
If your user message queue is in break or notify delivery mode while you are signed
on a display station and then you sign on another display station, the user message
queue will not change the delivery mode for the new sign on. User message
queues (along with work station message queues and the QSYSOPR message
queue) cannot have their delivery mode changed by a job when the message
queue is in break or notify delivery mode for a different job.
When you sign off the display station, or the job ends unexpectedly, the user
message queue delivery mode is changed to hold mode, if the delivery mode of the
user message queue is break or notify for this job. The user message queue
delivery mode is also changed from break or notify mode to hold mode when you
transfer to an alternative job. You can do this using the Transfer Secondary Job
(TFRSECJOB) command or by pressing the System Request key and specifying
option 1 on the System Request menu.
After transferring to an alternative job, you sign on using your user profile. Your user
message queue is put into the delivery mode specified in your user profile. This
allows the user message queue to transfer to the alternative job. You are then able
to transfer back and forth between these two jobs and have your user message
queue follow you.
However, if after transferring to an alternative job, you sign on using a user profile
other than your own, the user message queue for the job from which you
transferred is left in hold delivery mode. The user message queue for the user
profile you signed on with is put in the delivery mode specified in that user profile.
Because of this, your user message queue could be put into break or notify delivery
mode by another user. If another user still has your user message queue in that
delivery mode when you transfer back to the first job, your user message queue
delivery mode cannot be changed back to the original delivery mode.
The QSYSOPR message queue is the message queue for the system operator,
unless it has been changed. The above situation can occur for a system operator
as well.
Break-Handling Program
A break-handling program is called whenever a message of equal or higher severity
than the severity code filter arrives on a message queue that is in break delivery
mode. To request a break-handling program, you must specify the name of the
program and break delivery on the same CHGMSGQ command. The message
handling program must receive the message with the Receive Message (RCVMSG)
command so the message is marked as handled and the program is not called
again. For more information on receiving messages and break handling programs,
see Chapter 8. Working with Messages.
Note: This program cannot open a display file if the interrupted program is waiting
for input data from the device display.
You can use the system reply list to specify that the system issue the reply to
specified predefined inquiry messages so that the display station user does not
need to reply. See “Using the System Reply List” on page 262 for more information.
The following procedure in a CL initial program can be used to place the QSYSOPR
message queue in break mode. Initial programs can use similar procedures to
monitor message queues other than the one specified in a user’s own user profile.
PGM /* Procedure to place a msg queue in break mode */
CHGMSGQ QSYSOPR DLVRY(*BREAK) SEV(50)
MONMSG MSGID(CPF0000) EXEC(SNDPGMMSG MSG('Unable to put QSYSOPR +
message queue in *BREAK mode') TOPGMQ(*EXT))
ENDPGM
The procedure attempts to set the QSYSOPR message queue to break delivery
with a severity level of 50. If this is unsuccessful, a message is sent to the external
job message queue (*EXT). When the program which contains this procedure ends,
the initial menu is displayed. A severity level of 50 is used to decrease the number
of break messages that interrupts the work station user. A common reason for
failure is when another user has QSYSOPR in break mode already.
The external message queue (*EXT) is used to communicate with the external
requester (such as a display station user) of the job. Messages (except status
messages) sent to the external message queue of a job are also placed on the job
log (see “Job Log” on page 265 for more information).
If a status message is sent to the external message queue of an interactive job, the
message is displayed on the message line of the display station. You can use
status messages like this to inform the display station user of the progress of a
Note: When your application completes the long-running operation, you must send
another message to clear the message line at the display. You can use
message CPI9801, which is a blank message, for this purpose. For example:
PGM
.
.
.
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Status 1') +
TOPGMQ(*EXT) MSGTYPE(*STATUS)
.
.
.
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Status 2') +
TOPGMQ(*EXT) MSGTYPE(*STATUS)
.
.
.
SNDPGMMSG MSGID(CPI9801) MSGF(QCPFMSG) TOPGMQ(*EXT) +
MSGTYPE(*STATUS)
.
.
.
ENDPGM
The call message queue for an OPM program or ILE procedure is created when
that program or procedure is called. The call message queue is exclusively
associated only with the call stack entry in which the program or procedure is
running. A call message queue is identified indirectly by identifying the call stack
entry. A call stack entry is identified by the name of the program or procedure that is
running in that call stack entry.
In the case of an OPM program, the associated call stack entry is identified by the
(up to) 10 character program name. In the case of an ILE procedure, the associated
call stack entry is identified by a three part name which consists of the (up to) 256
character procedure name, the (up to) 10 character module name, and the (up to)
10 character program name. The module name is the name of the module into
which the procedure was compiled. The ILE program name is the name of the ILE
program into which the module was bound.
When identifying the call stack entry for an ILE procedure, it is sufficient to specify
only the procedure name. If the procedure name by itself does not uniquely identify
the call stack entry, the module name or the ILE program name can also be
specified. If, at the time a message is sent, a program or procedure is on the call
stack more than once, the name specified will identify the most recently called
occurrence of that program or procedure.
There are other methods to identify a call stack entry. These methods are discussed
in detail in “Call Stack Entry Identification on SNDPGMMSG” on page 214.
| For example, assume that procedure A calls procedure B which calls procedure C.
| Procedure C sends a message to procedure B and ends. The message is available
| to procedure B. However, when procedure B ends, its call message queue is no
| longer available. As a result, you cannot access procedure B by using procedure A,
| even though the message appears in the job log. Procedure A cannot access
| messages that are sent to Procedure B unless Procedure A has the message
| reference key to that message.
┌─────────────────┐
│ Procedure A │
├─────────────────┤
│ CALLPRC B ├──┐
└─────────────────┘ │
┌─────────────────┐ │
│ Procedure B │Í─┘
├─────────────────┤
│ CALLPRC C ├──┐
├─────────────────┤ │ ┌────────────────────────────────────┐
│ RETURN │ │ │ External message queue │
└─────────────────┘ │ ├────────────────────────────────────┤
┌─────────────────┐ │ │ Procedure A call message queue │
│ Procedure C │Í─┘ ├────────────────────────────────────┤
├─────────────────┤ ┌─Ê│ Procedure B call message queue │
│ SNDPGMMSG │ │ ├────────────────────────────────────┤
│ RETURN │──────────┘ │ Procedure C call message queue │
└─────────────────┘ └────────────────────────────────────┘
In the preceding figure, procedure B has two call stack entry queues, one for each
call of the procedure. There are no message queues for procedure C because no
messages were sent to procedure C. When procedure C sends a message to
procedure B, the message goes to the call stack entry queue for the last call of
procedure B.
Note: When you are using the command entry display, you can display all the
messages sent to the job message queue by pressing F10 (Include detailed
messages). Once the messages are displayed, you can roll through them
using one of the roll keys.
You can also display the messages for a job by using the Display Job Log
(DSPJOBLOG) command.
Interactive system users can send only immediate messages and replies.
The following SNDMSG command is sent by a display station user to the system
operator:
SNDMSG MSG('Mount tape on device TAP1') TOUSR(*SYSOPR)
The following SNDBRKMSG command is sent by the system operator to all the
display station message queues:
SNDBRKMSG MSG('System going down in 15 minutes')
TOMSGQ(*ALLWS)
The disadvantage of sending this message is that it is sent to all users, not just
those users who are active at the time the message is sent.
Using the SNDPGMMSG command, you can send the following types of messages:
v Informational
v Inquiry
v Completion
v Diagnostic
v Request
v Escape
v Status
v Notify
You can send messages from a CL procedure or program to the following types of
queues:
v External message queue of the requester of the job (see “Job Message Queues”
on page 203)
v Call message queue of a program or procedure called by the job (see “Job
Message Queues” on page 203)
v System operator message queue
v Work station message queue
v User message queue
To send a message from a procedure or program, you can specify the following on
the SNDPGMMSG command:
v Message identifier or an immediate message. The message identifier is the name
of the message description for a predefined message.
v Message file. The name of the message file containing the message description
when a predefined message is sent.
v Message data fields. If a predefined message is sent, these fields contain the
values for the substitution variables in the message. The format of each field
must be described in the message description. If an immediate message is sent,
there are no message data fields.
v Message queue or user to receive the message.
v Message type. The following indicates which types of messages can be sent to
which types of queues (V = valid).
The substitution variable for the message is the customer number. Because the
customer number varies, you cannot specify the exact customer number in the
message. Instead, declare a CL variable in the CL procedure or program for the
customer number (&CUSNO). Then specify this variable as the message data field.
When the message is sent, the current value of the variable is passed in the
message:
Customer number 35500 not found
In addition, you do not always know which display station is using the procedure or
program, so you cannot specify the exact display station message queue that the
message is to be sent to (TOPGMQ parameter); therefore, you specify the external
message queue *EXT.
Messages
Inquiry and Informational Messages
Using the SNDUSRMSG command, you can send an inquiry message or an
informational message to a display station user, the system operator, or a
user-defined message queue. If you use the SNDUSRMSG command to send an
inquiry message to the user, the procedure or program waits for a response from
the user. The message can be either an immediate message or a predefined
message. For an interactive job, the message is sent to the display station operator
by default. For a batch job, the message is sent to the system operator by default.
To send a message from a procedure or program using the SNDUSRMSG
command, you can specify the following on the SNDUSRMSG command:
Normally, an escape message is sent to the message queue of the calling program
or procedure to tell the caller what the problem was or that diagnostic messages
were also sent. For a completion message, an escape message is usually not sent
because the requested function was performed.
If the SAVOBJ command fails, the CL procedure function checks and the system
operator has to display the detailed messages to locate the specific escape
message explaining the reason for the failure as described later in this chapter. If
the SAVOBJ command completes successfully, the completion message is sent to
the call message queue associated with the program that displays the system
operator menu.
If the caller is another procedure within the same program, the program itself does
not end. The procedure to which the escape message was sent is allowed to
continue. If the escape message was sent to the caller of the program itself, then all
active procedures within the program are ended immediately. As a result, the
program cannot continue to run. If the caller does not monitor for an escape
message, default system action is taken.
| You can send notify messages from a CL procedure or program to the message
| queue of the calling program or procedure or to the external message queue. A
| notify message tells the caller about a condition under which processing can
| continue. The calling program or procedure can monitor for the arrival of the notify
| message and handle the condition it describes. If the caller is an Integrated
| Language Environment procedure, it can perform the following functions:
| v It can handle the condition.
| v It can send a reply back to the caller.
| v It can allow the sending procedure to continue processing.
| If the caller is an OPM program and is not monitoring for the message, the sender
| receives a default reply. If the caller is an ILE procedure, then the message
| percolates to the control boundary. When finding no monitor, the system returns a
| default reply to the sender. The sender then resumes processing. See “Monitoring
| for Messages in a CL Program or Procedure” on page 235.
Immediate messages are not allowed as escape and notify messages. The system
has defined the message CPF9898, which can be used for immediate escape and
notify messages in application programs. For example:
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) MSGDTA('Error condition') +
MSGTYPE(*ESCAPE)
The WAIT parameter must be specified on the RCVMSG command so that the
procedure waits for the reply. If the WAIT parameter is not specified, the procedure
continues with the instruction following the RCVMSG command, without receiving
the reply. The MSGKEY parameter is used in the RCVMSG command to allow the
procedure to receive the reply to a specific message. The variable &MSGKEY in the
SNDPGMMSG command is returned to the procedure for use in the RCVMSG
command.
Example 6: The following procedure allows the system operator to send a message
to several display stations. When the system operator calls the program, this
procedure, contained within the called program, displays a prompt which the system
operator can enter the type of message to be sent and the text for the message.
The procedure concatenates the date, time, and text of the message.
PGM
DCLF WSMSGD
DCL &MSG TYPE(*CHAR) LEN(150)
DCL &HOUR TYPE(*CHAR) LEN(2)
DCL &MINUTE TYPE(*CHAR) LEN(2)
DCL &MONTH TYPE(*CHAR) LEN(2)
DCL &DAY TYPE(*CHAR) LEN(2)
DCL &WORKHR TYPE(*DEC) LEN(2 0)
SNDRCVF RCDFMT(PROMPT)
IF &IN91 RETURN /* Request was ended */
RTVSYSVAL QMONTH RTNVAR(&MONTH)
RTVSYSVAL QDAY RTNVAR(&DAY)
RTVSYSVAL QHOUR RTNVAR(&HOUR)
IF (&HOUR *GT '12') DO
CHGVAR &WORKHR &HOUR
CHGVAR &WORKHR (&WORKHR - 12)
CHGVAR &HOUR &WORKHR /* Change from military time */
ENDDO
RTVSYSVAL QMINUTE RTNVAR(&MINUTE)
CHGVAR &MSG ('From Sys Opr ' *CAT &MONTH *CAT '/' +
*CAT &DAY +
*BCAT &HOUR *CAT ':' *CAT &MINUTE +
*BCAT &TEXT)
IF (&TYPE *EQ 'B') GOTO BREAK
NORMAL: SNDPGMMSG MSG(&MSG) TOMSGQ(WS1 WS2 WS3)
GOTO ENDMSG
BREAK: SNDBRKMSG MSG(&MSG) TOMSGQ(WS1 WS2 WS3)
ENDMSG: SNDPGMMSG MSG('Message sent to display stations') +
MSGTYPE(*COMP)
ENDPGM
The DDS for the display file, WSMSGD, used in this program follows:
The TOPGMQ parameter of the SNDPGMMSG command is used to identify the call
stack entry to which a message is sent. Identification of a call stack entry consists
of the following two parts:
v Specification of a base entry
The specification TOPGMQ(*PRV *) identifies the base entry as being the one in
which the procedure using the SNDPGMMSG command is running. The offset is
specified as being one entry previous to that base. This specification identifies
the caller of the procedure which is using the command.
v Offset specification of a base entry
The offset specification (element 1 of TOPGMQ) identifies if you send the
message to the base (*SAME) or if you send the message to the caller of the
base (*PRV).
To understand how to identify the base entry, element 2 of TOPGMQ, you also
need to understand the call stack when an ILE program is running. Two programs
are used to illustrate this. Program CLPGM1 is an OPM CL program and Program
CLPGM2 is an ILE program. Since program CLPGM2 is ILE, it can consist of
several procedures, such as: CLPROC1, CLPROC2, CLPROC3, and CLPROC4. At
| runtime the following calls take place:
| v CLPGM1 is called first.
| v CLPGM1 calls CLPGM2.
| v CLPGM2 calls CLPROC1.
| v CLPROC1 calls CLPROC2.
| v CLPROC2 calls CLPROC3 or CLPROC4.
Note: The first procedure to run when an ILE program is called is the Program
Entry Procedure (PEP) for the program. In CL, this procedure (_CL_PEP) is
generated by the system and calls the first procedure you provide. In this
example, the entry for the PEP is between the entry for the OPM program
CLPGM1 and the entry for the procedure CLPROC1.
Following are different ways of specifying the base call stack entry.
Note: You should be aware of the following information when a procedure sends a
message to the caller by specifying TOPGMQ(*PRV *).
v When CLPROC4 and CLPROC2 send a message back to the callers, the
message does not leave the containing program. The message is sent
between procedures that are within the same program. If the objective is
to send a message to the caller of the program (CLPGM1 in this
example), specifying TOPGMQ(*PRV *) is not the right choice to use.
v When CLPROC1 sends its message back to the caller, the Program Entry
Procedure is skipped. The message is sent to CLPGM1 even though the
caller is the PEP. When TOPGMQ(*PRV *) is specified, the PEP entry is
not visible and not included in the send operation. If TOPGMQ is specified
in some other way, the PEP is visible to the sender.
Figure 5 on page 217 illustrates the results when CLPROC1, CLPROC2, and
CLPROC4 each send a message back to the caller of each procedure.
┌───────────────┐
│ │
│ OPM PROGRAM │
│ CLPGM1 │
│ │
└───────┬───────┘
│
│ CALL PGM(CLPGM2)
│
ø
┌───────────────┐
│ │
│ PROCEDURE │
│ _CL_PEP │
│(in pgm CLPGM2)│
└───────┬───────┘
│
│ CALLPRC CLPROC1
│
ø
┌───────────────┐
│ │
│ PROCEDURE │
│ CLPROC1 │
│(in pgm CLPGM2)│
└───────┬───────┘
│
│ CALLPRC CLPROC2
│
ø
┌───────────────┐
│ │
│ PROCEDURE │
│ CLPROC2 │
│(in pgm CLPGM2)│
└───────┬───────┘
│ CALLPRC CLPROC4
│
ø
┌───────────────┐
│ │
│ PROCEDURE │
│ CLPROC4 │
│(in pgm CLPGM2)│
└───────────────┘
You can identify the base entry by providing the name of the OPM program or ILE
procedure running in that entry. The name provided is either a simple name (one
part) or a complex name (two or three parts). Following are descriptions of the
simple and complex names:
v Simple name
A simple name is used to identify an OPM program or an ILE procedure. If the
simple name you provide is 10 characters or less in length, it is determined by
When you want to uniquely identify the procedure to which you want to send the
message, a complex name can be used in one of the following combinations:
– procedure name, module name, program name
– procedure name and module name
– procedure name and program name
You must specify the module name as *NONE.
If you use a complex name, the base being identified cannot be running an OPM
program.
See Figure 7 on page 220 for an example of sending a message using a complex
name. In this example, CLPROC4 is sending a message to CLPROC1 using a two
part name consisting of (procedure name, program name).
Rather than using the full OPM program name or the full ILE procedure name, you
may use partial names. See the CL Reference (Abridged), SC41-5722-03 book, for
details on how to partially specify the name for a specific command.
The special value *PGMBDY is used by itself or with a program name to identify the
PEP of a CL program. The entry for the PEP of the identified CL program then is
the base entry. This option is useful when you want to send a message from within
a CL procedure outside the boundary of the program which contains the procedure.
See Figure 9 on page 223 for an example of sending a message using the special
value *PGMBDY and a program name. The following programs and procedures are
used in Figure 9 on page 223:
v CLPGM1 and CLPGM2. These are defined as in the previous examples.
v CLPGM3. This is another ILE program
v CLPROCA in CLPGM3. A message is sent from CLPROCA to the caller of
CLPGM2.
A message is sent from CLPROCA to the caller of CLPGM2 by using the special
value *PGMBDY with program name CLPGM2.
The special value *PGMBDY can also be used with an OPM program. If you specify
an OPM program name with *PGMBDY, you have the same results as when only
the OPM program name is used. For example, TOPGMQ(*SAME *PGMBDY
*NONE opmname) sends the message to the same place as TOPGMQ(*SAME
opmname).
The exception to this is when a message is sent to an OPM program that called
itself recursively. TOPGMQ(*SAME pgmname) sends the message to the latest
recursion level. However, TOPGMQ(*SAME *PGMBDY *NONE pgmname) sends
│ CALL PGM(PGM1)
│
│
ø
┌───────────────┐
│ │
┌─────────Ê │ OPM PROGRAM │
│ │ PGM1 │
│ │ (level 1) │
│ └───────┬───────┘
│ │ CALL PGM(PGM1)
│ ø
│ ┌───────────────┐
│ │ │
│ │ OPM PROGRAM │
│ │ PGM1 │
│ │ (level 2) │
│ └───────┬───────┘
│ │ CALL PGM(PGM1)
│ ø
│ ┌───────────────┐
│ │ │
│ │ OPM PROGRAM │Í──────────┐
│ │ PGM1 │ │
│ │ (level 3) │ │
│ └───────┬───────┘ │
│ │ CALL PGM(PGM2) │
│ ø │
│ ┌───────────────┐ │
│ │ │ │
└───────────┤ OPM PROGRAM ├───────────┘
SNDPGMMSG │ PGM2 │ SNDPGMMSG
TOPGMQ(*SAME *PGMBDY *NONE PGM1) │ │ TOMSGQ(*SAME PGM1)
... └───────────────┘
Although you may not know the name of a procedure, you may want to send a
message back to the most recently called procedure of an ILE program. The special
value *PGMNAME is used with a ILE program name to use the base entry name as
the name for the most recently called procedure of the identified program. The
programs in this example are:
v CLPGM1 is an ILE program with procedures PROCA and PROCB.
v CLPGM2 and CLPGM3 are both OPM programs.
v CLPGM3 is to send a message to CLPGM1 and does not know which procedure
is the most recently called.
The send is accomplished using the special value *PGMNAME and the program
name CLPGM1.
The special value *PGMNAME is useful if you convert some CL programs, but not
all CL programs, to ILE programs. For example, CLPGM1 is an OPM CL program;
CLPGM3 sent messages to CLPGM1 and specifies TOPGMQ(*SAME CLPGM1). If
CLPGM1 is converted to ILE, only the SNDPGMMSG command in CLPGM3 (OPM)
works. CLPGM1 does not work because there was no entry in the call stack for
CLPGM1. If you change the command to TOPGMQ(*SAME *PGMNAME *NONE
CLPGM1), CLPGM3 sends messages successfully to CLPGM1 regardless of the
names you may have used for procedure names.
The special value *PGMNAME can also be used in with an OPM program name. In
this case the effect is the same as if you just used the name. For example,
TOPGMQ(*SAME *PGMNAME *NONE opmpgm) sends the message to the same
place as TOPGMQ(*SAME opmpgm). The use of *PGMNAME should be
considered when you cannot determine whether the message is being sent to an
OPM program name or and ILE program name.
You can identify the base entry as the one at the nearest control boundary by using
the special value *CTLBDY. A control boundary exists between two call stack
entries if the two entries are running in two different activation groups. The one
identified by using this special value is running in the same activation group as the
entry that is sending the message.
See Figure 12 on page 227. for an example of sending a message using the special
value *CTLBDY. The three programs in this example (CLPGM1, CLPGM2, and
CLPGM3) are all ILE programs. CLPGM1 runs in activation group AG1 while both
CLPGM2 and CLPGM3 run in activation group AG2. In this example, PROC3A
sends a message back to the entry that immediately precedes the boundary for
AG2.
Previous discussions apply to both ILE programs and ILE service programs. The
most important difference between an ILE program and an ILE service program is
related to message handling. The service program does not have a PEP.
The PEP is not necessary for any of the options used to identify a base entry. An
exception to this is when the name _CL_PEP is used explicitly. For example,
TOPGMQ(*PRV *PGMBDY) always sends a message to the caller of the ILE
program or service program. If it is an ILE program, the PEP is identified as the
The message received is placed in the variable &MSG. *ANY is the default value
on the MSGTYPE parameter.
When working with the call stack entry message queue of an ILE procedure written
in a language other than CL, it is possible to receive an exception message
(Escape or Notify) when the exception is not yet handled. The RCVMSG command
can be used to both receive a message and indicate to the system that the
exception has been handled.
This can be controlled by using the RMV keyword. If *NO is specified for this
keyword, the exception is handled and the message is left on the message queue
as an old message. If *KEEPEXCP is specified, the exception is not handled and
the message is left on the message queue as a new message. If *YES is specified,
the exception message is handled and the message is removed from the message
queue.
Request Messages
Receiving request messages is a method for your CL procedure or program to
process CL commands. For example, your procedure or program can obtain input
Your procedure or program must define the syntax of the data in the request
message, interpret the request, and diagnose any errors. While the request is being
analyzed or the request function is being run, any number of errors can be
detected. As a result of these errors, messages are sent to the call message queue
for the procedure or program. The procedure or program handles these messages
and then receives the next request message. Thus, a request processing cycle is
defined; a request message is received, the request is analyzed and run by your
procedure or program with resulting messages displayed, and the next request
received. If there are no more request messages to be received in a batch job, an
escape message is sent to your procedure or program to indicate this.
More than one OPM program or ILE procedure of a job can receive request
messages for processing. The requests received by more recent program calls are
considered to be nested within those received by higher level program calls. The
request processing cycles at each nesting level are independent of each other.
Within an ILE program, one or more procedures within that program can be
receiving request messages. If more than one procedure is processing requests
than the nesting occurs within the same ILE program and the nesting levels remain
independent.
The following diagram shows how request messages are processed by QCMD:
CPP
Job Log
SNDPGMMSG TOPGMQ(*PRV)
MSGTYPE(*DIAG)
SNDPGMMSG TOPGMQ(*PRV)
MSGTYPE(*ESCAPE)
RSLF166-1
| The request message is received from PGMQ *EXT. When any request message is
| received, it is moved (actually, it is removed and resent) to the call message queue
| of the procedure or program that specified the RCVMSG command. Therefore, the
| correct call message queue must be used when the message is removed.
| If the request message is removed using the message reference key (MRK), you
| should obtain the MRK from the KEYVAR keyword of the RCVMSG command and
| not the SNDPGMMSG command. (The MRK changes when receiving a request
| message.) You must specify RMV(*NO) on the RCVMSG command because the
| procedure or program is not a request processor if the request message is removed
| from the call message queue.
The procedure or program remains a request processor until the procedure ends
(either normally or abnormally) or until a RMVMSG command is run to remove all
the request messages from the request-processor’s call message queue. For
example, the following command removes all request messages from the message
queue and, therefore, ends request processing:
RMVMSG CLEAR(*ALL)
Call the QCAPCMD API and specify the message retrieve key to have the AS/400
command analyzer to process a request message for an AS/400 command. You
can get the message retrieve key when you receive the request message. Process
Commands (QCAPCMD) will update the request message in the job log and add
any new value supplied. QCAPCMD also hides any parameter values, such as
passwords, that are to hidden in the job log. The system will not update the request
message in the job log when one of two conditions exists.
| v Using the Execute Command (QCMDEXC or QCAEXEC) APIs.
v Failing to supply a message retrieve key to QCAPCMD.
Request Program or
Opt Level Procedure Library Statement Instruction
QCMD QSYS 01DC
1 QCMD QSYS 016B
QTECADTR QSYS 0001
2 QTEVIREF QSYS 02BA
Bottom
The first two commands in the procedure make it a request processor. The
procedure remains a request processor until the RMVMSG command is run. A
Monitor Message command is placed after the call to program PGMONE because
an end request may be sent from PGMONE to the request-processor. If monitoring
is not used, a function check would occur for an end request. No message monitor
is specified after the call to PGMTWO because the RMVMSG command ends
request processing.
Note: In the sample programs, the RCVMSG command uses the minimal number
of parameters needed to become a request processor. You need to say you
want to receive a request message but do not want to remove it. You also
need to identify the specific call queue from which the message request
originated. Other parameters can be added as necessary.
For example, the following command adds the message description for the
message USR1001 to the message file USRMSG:
ADDMSGD MSGID(USR1001) MSGF(QGPL/USRMSG) +
MSG('File &1 not found in library &2') +
SECLVL('Change file name or library name') +
SEV(40) FMT((*CHAR 10) (*CHAR 10))
The following commands result in the substitution of the file name INVENT in the
10-character variable &FILE and the library name QGPL in the 10-character
variable &LIB in the retrieved message USR1001.
DCL &FILE TYPE(*CHAR) LEN(10) VALUE(INVENT)
DCL &LIB TYPE(*CHAR) LEN(10) VALUE(QGPL)
DCL &A TYPE(*CHAR) LEN(20)
DCL &MSG TYPE(*CHAR) LEN(50)
CHGVAR VAR(&A) VALUE(&FILE||&LIB)
RTVMSG MSGID(USR1001) MSGF(QGPL/USRMSG) +
MSGDTA(&A) MSG(&MSG)
The data for &1 and &2; is contained in the procedure variable &A, in which the
values of the procedure variables &FILE and &LIB have been concatenated. The
following message is placed in the CL variable &MSG:
File INVENT not found in library QGPL
If the MSGDTA parameter is not used in the RTVMSG command, the following
message is placed in the CL variable &MSG:
File not found in library
After the message is placed in the variable &MSG, you could do the following:
v Send the message using the SNDPGMMSG command
v Use the variable as the text for a message line in DDS (M in position 38)
v Use a message subfile
v Print or display the message
| Note: You cannot retrieve the message text with the variable names that are
| included in the text. The system intends on RTVMSGD to return a sendable
| message.
Note: The message reference key can also be used to receive a message and to
reply to a message.
If you remove an inquiry message that you have not answered, a default reply is
sent to the sender of the message and the inquiry message and the default reply
are removed. If you remove an inquiry message that you have already answered,
both the message and your reply are removed.
To remove all messages for all inactive programs and procedures from a user’s job
message queue, specify *ALLINACT for the PGMQ parameter and *ALL for the
CLEAR parameter on the RMVMSG command. If you want to print your job log
before you remove all the inactive messages, use the Display Job Log
(DSPJOBLOG) command and specify *PRINT for the OUTPUT parameter.
When working with a call message queue of an ILE procedure, it is possible that an
exception message for unhandled exceptions is on the queue at the time the
RMVMSG command is run. The RMVEXCP keyword of this command can be used
to control actions for messages of this type. If *YES is specified for this keyword,
the RMVMSG command causes the exception to be handled and the message to
be removed. If *NO is specified, the message is not removed. As a result, the
exception is not handled.
The following RMVMSG command removes a message from the user message
queue JONES. The message reference key is in the CL variable &MRKEY.
DCL &MRKEY TYPE(*CHAR) LEN(4)
RCVMSG MSGQ(JONES) RMV(*NO) KEYVAR(&MRKEY)
RMVMSG MSGQ(JONES) MSGKEY(&MRKEY)
The following RMVMSG command removes all messages from a message queue.
RMVMSG CLEAR(*ALL)
Status or Notify Messages Status and notify messages are sent to tell your
procedure or program of an abnormal condition that is not serious enough for the
sender to end. By monitoring for status or notify messages, your procedure or
program can detect this condition and not allow the function to continue.
You can monitor for messages using two levels of MONMSG commands:
v Procedure level: You can monitor for an escape, notify, or status message sent
by any command in your procedure by specifying the MONMSG command
immediately following the last declare command in your CL procedure or
program. This is called a procedure-level MONMSG command. You can use as
many as 100 procedure-level MONMSG commands in a procedure or OPM
program. (A CL procedure or OPM program can contain a total of 1000
MONMSG commands.) This lets you handle the same escape message in the
same way for all commands. The EXEC parameter is optional, and only the
GOTO command can be specified on this EXEC parameter.
Note: Do not use MONMSG CPF0000 when doing system function, such as install or
saving or restoring your entire system, since you may lose important
information.
v CPF9999
Monitors for function check messages for all generic message identifiers. If an
error message is not monitored, it becomes a CPF9999 (function check).
Note: Generally, when monitoring, your monitor also gets control when notify and
status messages are sent.
The compare data can be as long as 28 characters, and the comparison starts with
the first character of the first field of the message data. If the compare data
matches the message data, the action specified on the EXEC parameter is run.
| The value of the variable &A is changed to the value of &A divided by &B. If &B
| equals 0, the divide operation cannot be done and the zero divide escape message
In the following example, the procedure monitors for the escape message CPF9801
(object not found message) on the Check Object (CHKOBJ) command:
PGM
CHKOBJ LIB1/PGMA *PGM
MONMSG MSGID(CPF9801) EXEC(GOTO NOTFOUND)
CALL LIB1/PGMA
RETURN
NOTFOUND: CALL FIX001 /* PGMA Not Found Routine */
ENDPGM
You can also monitor for the same escape message to be sent by a specific
command in your procedure or program and by another command. This requires
| Note: The above paragraph is not true for ILE procedures because of the way
| messages percolate. The system requires MONMSG to handle any escape
| message that is sent to a procedure. Otherwise, the message percolates up
| the call stack until it finds a procedure that has a MONMSG to handle it or
| hits a control boundary.
| Default Handling
Many escape messages can be sent to a procedure that calls commands,
programs, and procedures. You will not want to monitor and handle all of the
messages. However, you may want to monitor and handle the escape messages
which pertain to the function of your procedure. The system provides default
monitoring and handling of any messages you do not monitor.
Default handling assumes that an error has been detected in a procedure. If you
are debugging the procedure, the message is sent to your display station. You can
then enter commands to analyze and correct the error. If you are not debugging the
procedure, the system performs a message percolation function.
| If the procedure has a MONMSG command for the escape, the message
| percolation action stops, and the system takes the action that is specified by the
| MONMSG command. Message percolation continues until either finding a
| MONMSG command, or until finding the nearest control boundary. This means that
| the escape message does not percolate across control boundaries.
| The function check processing begins by finding the control boundary before finding
| a procedure with a MONMSG command which applies to the message. The system
| considers action on the original escape exception complete. The system then sends
| the function check message (CPF9999) to the procedure that was the target of the
| original escape. If that procedure has a MONMSG for the function check message,
| then it takes the action that is specified by that command. Otherwise, the system
| sends an inquiry message to the workstation operator if the job is an interactive job.
| The workstation operation can reply with one of the following replies:
| R Retry the failing command in the procedure.
| I Ignore the message. Continue processing at the next command in the
| procedure.
| The system does not percolate the function check across the control boundary. If
| any reply causes the function check to move across an activation group boundary,
| this stops further action on the function check. The system cancels all procedures
| up to the activation group boundary, and sends the escape message CEE9901 to
| the prior call stack entry.
You can monitor for function-check escape messages so that you can either:
v Clean up and end the procedure
v Continue with some other aspect of your procedure
Note: If the message description for the unmonitored escape specifies a default
action, the default handling program is called before the function check
message is sent. When the default handling program returns, function check
processing begins.
Notify Messages
Besides monitoring for escape messages, you can monitor for notify messages that
are sent to your CL procedure’s or program’s call message queue by the
commands in your procedure or program or by the programs and procedures it
calls. Notify messages are sent to tell your procedure or program of a condition that
is not typically an error. By monitoring for notify messages, you can specify an
action different from what you would specify if the condition had not been detected.
Very few IBM-supplied commands send notify messages.
Monitoring for and handling notify messages is similar to monitoring for and
handling escape messages. The difference is in what happens if you do not monitor
for and handle notify messages. Notify messages are also percolated from
procedure to procedure within the boundary of the activation group. If the activation
group boundary is reached without a MONMSG command being found for it, the
default reply is automatically returned to the sender of the notify message and the
sender is allowed to continue processing. Unlike escape messages, unmonitored
notify messages are not considered an indication of an error in your procedure or
program.
Status Messages
You can monitor for status messages that are sent by the commands in your CL
procedure or by the programs or procedures it calls. Status messages tell your
procedure the status of the work performed by the sender. By monitoring for status
messages, you can prevent the sending program or procedure from proceeding with
any more processing.
Status messages sent to the external message queue are shown on the interactive
display, informing the user of a function in progress. For example, the Copy File
(CPYF) command sends a message informing the user that a copy operation is in
progress.
When the function is completed, your procedure or program should remove the
status message from the interactive display. The message cannot be removed using
a command, but sending another status message to *EXT with a blank message
gives the appearance of removing the message. The system-supplied message ID
CPI9801 can be used for this purpose. When control returns to the OS/400
program, the *STATUS message may be cleared from line 24, without sending the
CPI9801 message. The following example shows a typical application of message
IDs CPF9898 and CPI9801:
SNDPGMMSG MSGID(CPF9898) MSGF(QCPFMSG) +
MSGDTA('Function xxx being performed') +
TOPGMQ(*EXT) MSGTYPE(*STATUS)
v
v /* Your processing function */
v
SNDPGMMSG MSGID(CPI9801) MSGF(QCPFMSG) +
TOPGMQ(*EXT) MSGTYPE(*STATUS)
There are two preferred ways to prevent the status messages from being shown:
v Change User Profile (CHGUSRPRF) command
You can change your user profile so that whenever you sign on using that profile,
status messages are not shown. To do this, use the CHGUSRPRF command and
specify *NOSTSMSG on the User Option (USROPT) parameter.
v Change Job (CHGJOB) command
You can change the job you are currently running so that status messages are
not shown. To do this, use the CHGJOB command and specify *NONE on the
Status Message (STSMSG) parameter. You can also use the CHGJOB command
to see status messages by specifying *NORMAL on the STSMSG parameter.
A third alternative, however less preferred, is to use the Override Message File
(OVRMSGF) command and change the status message identifiers to a blank
message.
The following program (PGMA), which consists of only this one procedure, is an
example of a break-handling program.
PGM PARM(&MSGQ &MSGLIB &MRK)
DCL VAR(&MSGQ) TYPE(*CHAR) LEN(10)
DCL VAR(&MSGLIB) TYPE(*CHAR) LEN(10)
DCL VAR(&MRK) TYPE(*CHAR) LEN(4)
DCL VAR(&MSG) TYPE(*CHAR) LEN(75)
RCVMSG MSGQ(&MSGLIB/&MSGQ) MSGKEY(&MRK) +
MSG(&MSG)
.
.
.
ENDPGM
Attention:
Note: This program cannot open a display file if the interrupted program is waiting
for input data from the display.
You can use the system reply list to indicate the system will issue a reply to
predefined inquiry messages. The display station user, therefore, does not need to
reply. For more information, see “Using the System Reply List” on page 262.
The following example clarifies the user procedure and display file needed to
suspend and restore the display:
Once the QSYSMSG message queue is created, all of the specific messages
(shown below in “Messages Sent to QSYSMSG Message Queue”) are directed to it.
You can write a program to receive messages for which you can perform special
action and send other messages to the QSYSOPR message queue or another
message queue. This program should be written as a break-handling program.
| Have the user try the request again with a valid user ID and password. If
| the user has no authorization to the device, use the Grant Object Authority
| (GRTOBJAUT) command to authorize the user to this device.
| CPF5257
| Failure for device or member &4 file &2 in library &3.
| An error occurred during a read or write operation. If this is a display file,
| the display may not be usable.
| See the previously listed messages, correct the errors, and try the request
| again. If the problem continues, report the problem (ANZPRB command).
| CPF5260
| Switched connection failed for device &4 in file &2 in &3.
| Close the file and then try the request again.
| CPF5274
| Error on device for remote location &5 file &2 in &3.
| The program attempted an input operation or an output operation to
| program device &4, remote location &5 that had a prior error.
| Vary off device associated with remote location &5 and then on again
| (VRYCFG or WRKCFGSTS command). Then try the request again.
| CPF5341
| SNA session not established for remote location &5, device
| description &4.
| The Systems Network Architecture (SNA) session could not be established.
| The Synchronous Data Link Control (SDLC) frame size is not compatible
| with the request/response unit (RU) size. This is either a configuration error,
| or the SDLC frame size has been negotiated to a smaller value by the
| AS/400 system. This occured while the remote controller is using the
| Exchange Identification (XID) command.
| The MAXLENRU parameter of the device description contains the
| specification of the RU size for retail and finance devices.
| The MAXFRAME parameter of the line description contains the SDLC
| frame size specification. The MAXFRAME parameter of the controller
| description also contains the specification for retail and finance devices.
| Do one or more of the following and try the request again:
| v Verify that the frame size and the RU size values are compatible.
| v Increase the SDLC frame size, or decrease the RU size, if necessary.
| Failure to reduce the storage usage may lead to a situation that requires
| initialization of auxiliary storage and loss of user data. Use the
| WRKSYSSTS command to monitor the amount of storage that is used. Use
| the PRTDSKINF command to print information about storage usage. The
| WRKSYSVAL command can be used to display and change the auxiliary
| storage lower limit value (QSTGLOWLMT) and action (QSTGLOWACN).
| CPI099D
| System starting in storage restricted state.
| The system is being started to the restricted state because the amount of
| storage available is below the auxiliary storage lower limit. Failure to reduce
| storage usage may lead to a situation that requires initialization of auxiliary
| storage and the loss of user data. The console is the only active device.
| You can reduce the use of storage through the following actions:
| v Delete any unused objects.
| v Save objects by specifying STG(*FREE).
| v Save the old unused log versions of QHST and then delete them.
| v Print or delete spooled files on the system.
| Failure to reduce the storage usage may lead to a situation that requires
| initialization of auxiliary storage and loss of user data. Use the
| WRKSYSSTS command to monitor the amount of storage that is used. Use
| the PRTDSKINF command to print information about storage usage. The
| WRKSYSVAL command can be used to display and change the auxiliary
| storage lower limit value (QSTGLOWLMT) and action (QSTGLOWACN).
| CPI099E
| Storage lower limit exit program error occurred.
| An error occurred while calling a user exit program for exit point
| QIBM_QWC_QSTGLOWACN. The reason code is &1. The reason codes
| and their meanings follow:
| 1. An error occurred while running the user exit program.
| 2. The system did not find a user exit program.
| 3. The system did not find a registered user exit program.
| 4. A user exit program did not complete in 30 minutes.
| 5. The job running the user exit program ended.
| 6. The system did not submit the user exit program job because the
| system is ending.
| 7. The system did not submit the user exit program job because errors
| occurred.
| 8. The system submitted the user exit program job, but issued warnings
| as well.
| 9. The system could not retrieve registration information for the exit point.
| 10. The system did not submit the user exit program job because the
| maximum number of failed exit program jobs was exceeded.
| The system will automatically resume mirroring after corrections are made
| to the error.
| CPI116B
| Mirrored protection still suspended on the load source disk unit.
| Mirrored protection remains suspended on disk unit 1. Data has not been
| lost. Disk unit 1 is attached to the Multi-Function I/O Processor (MFIOP).
| Repair the disk unit as soon as possible. Do not power down the system,
| IPL the system, or perform any operation which would IPL the system until
| after repairing disk unit 1.
| The following information identifies the unit that is suspended:
| v Disk serial number: &5
| v Disk type: &3
| v Disk model: &4
| v Device resource name: &26
| See the previously listed messages in this message queue to determine the
| failure that caused suspension of mirrored protection. Perform the
| recommended recovery procedures.
| CPI116C
| Compressed disk unit &1 is full.
| Compressed disk unit &1 is temporarily full. The storage subsystem
| controller has detected the condition and is repositioning the data on the
| compressed disk unit. The system does this to maximize the amount of
| storable data on the disk unit. This operation could take a number of
| minutes to complete. When the storage subsystem controller has completed
| the repositioning of the data, the system will resume normal operations.
| The following information identifies the unit that is full:
| v Disk serial number: &5
| v Disk type: &3
| v Disk model: &4
| v Device resource name: &26
A separate job would be started to call this sample program. The job would remain
active, waiting for a message to arrive. The job could be ended using the ENDJOB
command.
PGM
MONMSG MSGID(CPF0000) +
EXEC(SNDPGMMSG MSG(&MSG) TOMSGQ(QSYSOPR))
ENDDO
/**********************************************************/
/* Notify QSYSOPR of abnormal end */
/**********************************************************/
ENDPGM
The system reply list contains message identifiers, optional compare data, a reply
value for each message, and a dump attribute. The system reply list applies only to
predefined inquiry messages that are sent by a job that uses the system reply list.
You specify that a job is to use the system reply list for inquiry messages on the
INQMSGRPY(*SYSRPYL) parameter on the following commands:
v Batch Job (BCHJOB)
v Submit Job (SBMJOB)
v Change Job (CHGJOB)
v Create Job Description (CRTJOBD)
v Change Job Description (CHGJOBD)
When a predefined inquiry message is sent by a job that uses the system reply list,
the system searches the reply list in ascending sequence number order for an entry
that matches the message identifier and, optionally, the compare data of the reply
message. If an entry is found, the reply specified is issued and the user is not
required to enter a reply. If an entry is not found, the message is sent to the display
station user for interactive jobs or system operator for batch jobs.
Sequence Message
Number Identifier Compare Value Reply Dump
10 CPA0700 *NONE D *YES
20 RPG0000 *NONE D *YES
30 CBE0000 *NONE D *YES
40 PLI0000 *NONE D *YES
These entries indicate that a reply of D is to be sent and a job dump is to be taken
if the message CPA0700-CPA0799, RPG0000-RPG9999, CBE0000-CBE9999, or
PLI0000-PLI9999 (which indicate a program failure) is sent by a job using the
system reply list. For the system to use these entries, you must specify that the
jobs are to use the system reply list.
To add other inquiry messages to the system reply list, use the Add Reply List Entry
(ADDRPYLE) command. On this command you can specify the sequence number,
the message identifier, optional compare data, compare data CCSID, reply action,
and the dump attribute. The ADDRPYLE command function can be easily accessed
by using the Work with System Reply List Entries (WRKRPYLE) command.
The following reply actions can be specified for the inquiry messages that are
placed on the system reply list (the parameter value is given in parentheses):
v Send the default reply for the inquiry messages (*DFT). In this case, the default
reply for the message is sent. The message is not displayed, and no default
handling program is called.
v Require the work station user or system operator to respond to the message
(*RQD). If the message queue to which the message is sent (work station
message queue for interactive jobs and QSYSOPR for batch jobs) is in break
mode, the message is displayed, and the work station user must respond to the
message. This option operates as if the system reply list were not being used.
v Send the reply specified in the system reply list entry (message reply, 32
characters maximum). In this case, the specified reply is sent as the response to
the message. The message is not displayed, and no default handling program is
called.
The following commands add entries to the system reply list for messages
RPG1241, RPG1200, CPA4002, CPA5316, and any other inquiry messages:
v ADDRPYLE SEQNBR(15) MSGID(RPG1241) RPY(C)
v ADDRPYLE SEQNBR(18) MSGID(RPG1200) RPY(*DFT) DUMP(*YES)
v ADDRPYLE SEQNBR(22) MSGID(CPA4002) RPY(*RQD) + CMPDTA('QSYSPRT')
v ADDRPYLE SEQNBR(25) MSGID(CPA4002) RPY(G)
v ADDRPYLE SEQNBR(27) MSGID(CPA5316) RPY(I) DUMP(*NO) + CMPDTA('QSYSPRT'
21)
v ADDRPYLE SEQNBR(9999) MSGID(*ANY) RPY(*DFT)
Compare Compare
Sequence Message Value (b is a Start
Number Identifier blank) Position Reply Dump
10 CPA0700 1 D *YES
15 RPG1241 1 C *NO
18 RPG1200 1 *DFT *YES
20 RPG0000 1 D *YES
22 CPA4002 'QSYSPRT' 1 *RQD *NO
25 CPA4002 1 G *NO
27 CPA5316 'QSYSPRT' 21 I *NO
30 CBE0000 1 D *YES
40 PLI0000 1 D *YES
9999 *ANY 1 *DFT *NO
For a job that uses this system reply list, the following occurs when the messages
that were added to the reply list are sent by the job:
v For sequence number 15, whenever an RPG1241 message is sent by a job that
uses the system reply list, a reply of C is sent and the job is not dumped.
v For sequence number 18, a generic message identifier is used so whenever an
RPG1200 inquiry message is sent by the job, the default reply is sent. The
default reply can be the default reply specified in the message description or the
system default reply. Before the default reply is sent, the job is dumped. The
previous entry that was added overrides this entry for message RPG1241.
v For sequence number 22, if the inquiry message CPA4002 is sent with the
compare data of QSYSPRT, the message is sent to the display station user, and
the user must issue the reply.
When a compare value is specified without a start position, the compare value is
compared to the message data beginning in position 1 of the substitution data in
the message.
Sequence number 22 tests for a printer device name of QSYSPRT. For an
example of testing one substitution variable with a different start position, see
sequence number 27.
v For sequence number 25, if the inquiry message CPA4002 (verify alignment on
printer &1;) is sent with the compare not equal to QSYSPRT, a reply of G is sent.
The job is not dumped. Sequence number 22 requires an operator response to
the forms alignment message if the printer device is QSYSPRT. Sequence
number 25 defines that if the forms alignment inquiry message occurs for any
other device, to assume a default response of G=Go.
v For sequence number 27, if the inquiry message CPA5316 is sent with the
compare data of TESTEDFILETSTLIBRARYQSYSPRT, a reply of I is sent.
When a compare value and a start position are specified, the compare value is
compared with the message data beginning with the start position. In this case,
position 21 is the beginning of the third substitution variable. For message
CPA5316, the first four substitution variables are as follows:
When the compare value contains *CCHAR data, the message data from the
sending function is converted to the CCSID of the message data stored in the
system reply list before the compare is made. Only data that is of type *CCHAR is
converted. See the Add Message Description (ADDMSGD) command in the CL
Reference (Abridged) book for more information about *CCHAR data.
CAUTION:
The following restrictions apply when using *CCHAR data as compare data:
v You cannot mix *CCHAR data with other data when adding this type of
reply list entry.
v You cannot include the length of the *CCHAR data in the compare data.
If you mix *CCHAR data or include the length of the *CCHAR data,
unpredictable results may occur.
An entry remains on the system reply list until you use the Remove Reply List Entry
(RMVRPYLE) command to remove it. You can use the Change Reply List Entry
(CHGRPYLE) command to change the attributes of a reply list entry, and you can
use the Work with System Reply List Entry (WRKRPYLE) command to display the
reply entries currently in the reply list.
The job log receives a completion message indicating a successful change when
the system reply list is updated using (ADDRPYLE), (CHGRPYLE), or
(RMVRPYLE). The history log QHST also receives a completion message to record
the change.
Message Logging
The two types of logs for messages are:
v Job log
v History log
A job log contains information related to requests entered for a job. The QHST log
contains system data, such as a history of job start and end activity on your system.
Job Log
Each job has an associated job log that can contain the following for the job:
v The commands in the job.
v The commands in a CL program if the CL program was created with the
LOG(*YES) option or with the LOG(*JOB) option and a Change Job (CHGJOB)
command was run with the LOGCLPGM(*YES) option (for more information on
logging CL program commands, see “Logging CL Procedure Commands” on
page 56).
After the job ends, the job log can be written to either the output file QPJOBLOG or
a database file. From the output file QPJOBLOG, the job log can be printed; from a
database file, job log information can be queried using a database feature. You can
also specify to not write job logs for jobs that have run successfully—a discussion
about preventing job logs is presented later in this chapter.
Writing a job log to a database requires the use of the QMHCTLJL API—see the
System API Reference book for more information about APIs. When the job log is
directed to the database, one or two files can be generated. The primary file
contains the essential information of a message such as message ID, message
severity, message type, and message data. The secondary file contains the print
images of the message text. Production of the secondary file is optional and is
controlled by parameters on the QMHCTLJL API. Both files are externally described
and can be processed using database and query features of the system. See
“Appendix C. Job Log Output Files” on page 395 for information on the formats of
the primary and secondary files.
You can control what information is written in the job log. To do this, you specify the
LOG parameter on the Create Job Description (CRTJOBD) command. You can
change these levels using the Change Job (CHGJOB) command or the Change Job
Description (CHGJOBD) command. The LOG parameter is made up of 3 values:
message level, message severity, and message text level. For more information on
these commands, see the CL Reference (Abridged) book.
The second value, message severity, specifies the minimum severity level that
causes error messages to be entered in the job log. Values 0 through 99 are
allowed. Only those messages with a severity greater than or equal to this value
are entered in the job log.
The third value in the LOG parameter, message text level, specifies the level of
message text that is written in the job log. The values are:
*MSG Only message text is written to the job log (message help is not included).
*SECLVL
The message and the message help are written to the job log.
*NOLIST
No job log is produced if the job ends normally. If the job end code is 20 or
greater, a job log is produced with the message and message help
included.
Filtering does not occur after every CL command is called within a program.
Therefore, if a CL program is run interactively or submitted to batch, the filtering
runs once after the program ends because the program is not a request processor.
Note: Since *NOLIST specifies that no job log is spooled for jobs that end normally,
it is a waste of system resource in batch jobs to remove the messages from
this log by specifying log level 0.
The following example shows how the logging level affects the information that is
stored in the job message queue and, therefore, written to the job log, if one is
requested. The example also shows that when the command is run interactively,
filtering occurs after each command.
Note: Both high-level and detailed message logging levels are included in the
examples. High-level messages are identified as Message; detailed
messages are identified as Detailed Message.
1. The CHGJOB command specifies a logging level of 2 and a message severity
of 50, and that only messages are to be written to the job log (*MSG).
Command Entry SYSTEM1
Request level: 1
Previous commands and messages:
> CHGJOB LOG(2 50 *MSG)
2. PGMA sends three informational messages with severity codes of 20, 50, and
60 to its own call message queue and to the call message queue of the
program called before the specified call (*PRV). The messages that PGMA
sends to its own call message queue are called detailed messages. Detailed
messages are those messages that are sent to the call message queue of the
lower-level program call.
Bottom
Type command, press Enter.
===> _________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
_____________________________________________________________________________
F3=Exit F4=Prompt F9=Retrieve F10=Include detailed messages
F11=Display full F12=Cancel F13=Information Assistant F24=More keys
Bottom
Type command, press Enter.
===> _________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
_____________________________________________________________________________
F3=Exit F4=Prompt F9=Retrieve F10=Exclude detailed messages
F11=Display full F12=Cancel F13=Information Assistant F24=More Keys
4. When another command is entered (in this example, CHGJOB), the CALL PGMB
command and all messages (including detailed messages) are removed. They
are removed because the severity code for the high-level message associated
with this request was not equal to or greater than the severity code specified in
Bottom
Type command, press Enter.
===> _________________________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
_____________________________________________________________________________
F3=Exit F4=Prompt F9=Retrieve F10=Include detailed messages
F11=Display full F12=Cancel F13=Information Assistant F24=More Keys
5. When another command is entered after the CALL PGMD command was entered,
the CALL PGMD command remains on the display, but its associated message is
deleted. The message is deleted because its severity code is not equal to or
greater than the severity code specified on the LOG parameter of the CHGJOB
command.
The command SIGNOFF *LIST is entered to print the job log.
Bottom
Type command, press Enter.
===> SIGNOFF *LIST____________________________________________________________
______________________________________________________________________________
______________________________________________________________________________
_____________________________________________________________________________
F3=Exit F4=Prompt F9=Retrieve F10=Include detailed messages
F11=Display full F12=Cancel F13=Information assistant F24=More Keys
The job log, which follows, contains all the requests and all the messages that have
remained on the Command Entry display. In addition, the job log contains the
message help associated with each message, as specified by the CHGJOB
command. Notice that the job log contains the message help of any message
issued during the job, not just for the messages issued since the second CHGJOB
command was entered.
5763SS1 V2R3M0 930925 Job Log SYSAS727 12/12/92 07:58:53 Page 1
Job name . . . . . . . . . . : QPADEV0007 User . . . . . . : JOHNDOE Number . . . . : 004201
Job description . . . . . . : QDFTJOBD Library . . . . . : QGPL
MSGID TYPE SEV DATE TIME FROM PGM LIBRARY INST TO PGM LIBRARY INST
CPF1124 Information 00 12/12/93 07:57:16 QWTPIIPP QSYS 04FC *EXT 0000
Message . . . . : Job 004201/JOHNDOE/QPADEV0007 started on 12/12/92 at
07:57:16 in subsystem QINTER in QSYS. Job entered system on 12/12/92 at
07:57:16.
*NONE Request 12/12/93 07:57:50 QMHGSD QSYS 0322 QCMD QSYS 00B6
Message . . . . : -call pgma
CPF1001 Information 20 12/12/93 07:57:50 PGMA JOHNDOE 000C PGMA JOHNDOE 000C
Message . . . . : Detailed message sev 20 - PGMA
CPF1001 second level text - PGMA
CPF1002 Information 50 12/12/93 07:57:50 PGMA JOHNDOE 0010 PGMA JOHNDOE 0010
Message . . . . : Detailed message sev 50 - PGMA
CPF1002 second level text - PGMA
CPF1003 Information 60 12/12/93 07:57:50 PGMA JOHNDOE 0014 PGMA JOHNDOE 0014
Message . . . . : Detailed message sev 60 - PGMA
CPF1003 second level text - PGMA
CPF1004 Information 20 12/12/93 07:57:50 PGMA JOHNDOE 0018 QCMD QSYS 00DE
Message . . . . : Message sev 20 - PGMA
CPF1004 second level text - PGMA
CPF1005 Information 50 12/12/93 07:57:50 PGMA JOHNDOE 001C QCMD QSYS 00DE
Message . . . . : Message sev 50 - PGMA
CPF1005 second level text - PGMA
CPF1006 Information 60 12/12/93 07:57:50 PGMA JOHNDOE 0020 QCMD QSYS 00DE
Message . . . . : Message sev 60 - PGMA
CPF1006 second level text - PGMA
*NONE Request 12/12/93 07:58:31 QMHGSD QSYS 0322 QCMD QSYS 00B6
Message . . . . : -chgjob log(3 40 *seclvl)
*NONE Request 12/12/93 07:58:34 QMHGSD QSYS 0322 QCMD QSYS 00B6
Message . . . . : -call pgmc
CPF100F Information 30 12/12/93 07:58:34 PGMC JOHNDOE 000C QCMD QSYS 00DE
Message . . . . : Message sev 30 - PGMC
CPF100F second level text - PGMC
CPF1010 Information 40 12/12/93 07:58:34 PGMC JOHNDOE 0010 QCMD QSYS 00DE
Message . . . . : Message sev 40 - PGMC
CPF1010 second level text - PGMC
*NONE Request 12/12/93 07:58:38 QMHGSD QSYS 0322 QCMD QSYS 00B6
Message . . . . : -call pgmd
*NONE Request 12/12/93 07:58:45 QMHGSD QSYS 0322 QCMD QSYS 00B6
Message . . . . : -call pgme
*NONE Request 12/12/93 07:58:52 QMHGSD QSYS 0322 QCMD QSYS 00B6
Message . . . . : -signoff *list
CPF1164 Completion 00 12/12/93 07:58:52 QWTMCEOJ QSYS 01EE *EXT 0000
Message . . . . : Job 004201/JOHNDOE/QPADEV0007 ended on 12/12/92 at
07:58:52; 3 seconds used; end code 0 .
Cause . . . . . : Job 004201/JOHNDOE/QPADEV0007 completed on 12/12/92 at
07:58:52 after it used 3 seconds processing unit time. The job had ending
code 0. The job ended after 1 routing steps with a secondary ending code of
0. The job ending codes and their meanings are as follows: 0 - The job
completed normally. 10 - The job completed normally during controlled ending
or controlled subsystem ending. 20 - The job exceeded end severity (ENDSEV
job attribute). 30 - The job ended abnormally. 40 - The job ended before
becoming active. 50 - The job ended while the job was active. 60 - The
subsystem ended abnormally while the job was active. 70 - The system ended
abnormally while the job was active. 80 - The job ended (ENDJOBABN command).
90 - The job was forced to end after the time limit ended (ENDJOBABN
command). Recovery . . . : For more information, see the Work Management,
SC41-8078.
The logging levels affect a batch job log in the same way as shown in the
preceding example. If the job uses APPC, the heading contains a line showing the
unit of work identifier for APPC. See the APPC Programming book for more
information on APPC.
to display the job logs for job number 001293 associated with user FRED at
display station WS3.
v If the job is still active (batch or interactive jobs) or is on a job queue and has not
yet started, use the Display Job Log (DSPJOBLOG) command. For example, to
display the job log of the interactive job for user JSMITH at display station WS1,
enter:
DSPJOBLOG JOB(nnnnnn/JSMITH/WS1)
To display the job log of your own interactive job, do one of the following:
v Enter the following command:
DSPJOBLOG
v Enter the WRKJOB command and select option 10 (Display job log) from the
Work with Job display.
v Press F10=Include detailed messages from the Command Entry display (this key
displays the messages that are shown in the job log).
v If the input-inhibited light on your display station is on and remains on, do the
following:
1. Press the System Request key, then press the Enter key.
2. On the System Request menu, select option 3 (Display current job).
3. On the Display Job menu, select option 10 (Display Job log, if active or on
job queue).
4. On the Job Log display, DSPJOB appears as the processing request. Press
F10 (Display detailed messages).
5. On the Display All Messages display, press the Roll Down key to see
messages that were received before you pressed the System Request key.
v Sign off the work station, specifying LOG(*LIST) on the SIGNOFF command.
When you use the Display Job Log (DSPJOBLOG) command, you see the Job Log
display. This display shows program names with special symbols, as follows:
>> The running command or the next command to be run. For example, if a
program was called, the call to the program is shown.
> The command has completed processing.
. . The command has not yet been processed.
? Reply message. This symbol marks both those messages needing a reply
and those that have been answered.
You may use the DSPJOBLOG command to direct the job to a database file instead
of having it printed or displayed. There are two options available. In the first option,
you may specify a file and member name on the command. In this option, the
primary job log information is written to the database file specified on the command.
In the second option you may use the command in conjunction with the information
provided on the QMHCTLJL API which was run previously. In this option, the job log
is written to the file(s) specified on the API call. With this option, both primary and
secondary files can be produced and message filtering can be performed as the
messages are written to the file. With both these options, when the DSPJOBLOG
command completes, the output will not be displayed nor will there be a spooled file
available for printing.
For an interactive job, the value specified for the LOG parameter on the SIGNOFF
command takes precedence over the LOG parameter value specified for the job.
or
CHGPRTF FILE(QSYS/QPJOBLOG)
OUTQ(USROUTQ)
v To change the QPJOBLOG printer file to use output queue QEZJOBLOG, use
the Operational Assistant cleanup function. When you want to use automatic
cleanup of the job logs, the printer files must be directed to this output queue.
For more information on the Operational Assistant cleanup function, see the
System Operation book.
v To specify the output queue to which a job’s job log is written, make sure that file
QPJOBLOG has OUTQ(*JOB) specified. You can use the OUTQ parameter on
any of the following commands: BCHJOB, CRTJOBD, CHGJOBD, or CHGJOB.
The following is an example:
CHGJOB OUTQ(*JOB)
If a display station user uses an IBM-supplied menu or the command entry display,
all error messages are displayed. If the display station user uses a user-written
initial program, any unmonitored message causes the initial program to end and a
job log to be produced. However, if the initial program monitors for messages, it
receives control when a message is received. In this case, it may be important to
ensure that the job log is produced so you can determine the specific error that
occurred. For example, assume that the initial program displays a menu that
includes a sign-off option, which defaults to *NOLIST. The initial program monitors
for all exceptions and includes a Change Variable (CHGVAR) command that
changes the sign-off option to *LIST if an exception occurs:
PGM
DCLF MENU
DCL &SIGNOFFOPT TYPE(*CHAR) LEN(7) VALUE(*NOLIST)
.
.
.
MONMSG MSG(CPF0000) EXEC(GOTO ERROR)
PROMPT: SNDRCVF RCDFMT(PROMPT)
CHGVAR &IN41 '0'
.
.
If you want to print the job log in all cases, use the Change Job Description
(CHGJOBD) command to change the job description, or specify a different LOG
value on the BCHJOB or SBMJOB command. See “Job Log” on page 265 for a
description of logging levels.
CL commands are also logged if you specify LOGCLPGM(*YES) when you use the
CHGJOB command and the SBMJOB command.
When a log-version is full, a new version of the log is automatically created. Each
version is a physical file that is named in the following way:
Qxxxyydddn
where:
xxx Is a 3-character description of the log type (HST)
yyddd Is the Julian date of the first message in the log version
| n Is a sequence number within the Julian date (A through Z and 0 through
| 9)?
Note: The number of records in each version of the history log is specified in the
system value QHSTLOGSIZ.
The text of the log version file contains the date and time of the first message and
last message in the log version. The date and time of the first message are in
positions 1-13 of the text; the date and time of the last message are in positions
14-26. The date and time are in the format cyymmddhhmmss, where:
c Is the century guard digit
yymmdd Is the date the message was sent
hhmmss Is the time the message was sent
You can create a maximum of 36 log versions with the same Julian date. If more
than 36 log versions are created on the same day, the next available Julian day is
used for subsequent log versions. If some of the older log versions are then
deleted, it is possible to use the names again. Log versions are out of order when
sequenced by name if log versions are deleted and names used again.
You can also write a program to process history log records. Because several
versions of each log may be available, you must select the log-version to be
processed. To determine the available log-versions, use the Display Object
Description (DSPOBJD) command. For example, the following DSPOBJD command
displays what versions of the history log are available:
DSPOBJD OBJ(QSYS/QHST*) OBJTYPE(*FILE)
| You can delete logs on your system by using the delete option from the display that
| is presented on the Work with Objects (WRKOBJ) command.
You can display or print the information in a log using the Display Log (DSPLOG)
command. You can select the information you want displayed or printed by
specifying any combination of the following:
v Period of time
v Name of job that sent the log entry
v Message identifiers of entries
The following DSPLOG command displays all the available entries for the job
OEDAILY in the current day:
DSPLOG JOB(OEDAILY)
Bottom
Press Enter to continue.
If you reset the system date or time to an earlier setting, or if you advanced the
system date and time by more than 48 hours, a new log version is started. This
ensures that all messages in a single log version are in chronological order.
Log versions created on a release prior to V3R6M0 may contain entries that are not
in chronological order if the system date and time was reset to an earlier setting.
Therefore, when you try to display the log-version, some entries may be missed.
For example, if the log-version contains entries dated 1988 followed by entries
dated 1987, and you want to display those 1987 entries, you specify the 1987 dates
on the PERIOD parameter on the DSPLOG command but the expected entries are
not displayed. You should always use the system date (QDATE) and the system
time (QTIME), or you should specify the PERIOD parameter as follows:
PERIOD((start-time start-date) (*AVAIL *END))
The system writes the messages sent to a log message queue to the current
version physical file when the message queue is full or when the DSPLOG
command was used. If you want to ensure the current version is up-to-date, specify
a fictitious message identifier, such as ###0000, on the DSPLOG command. No
messages are displayed, but the log-version physical file is made current.
If you print the information in a log using the Display Log command and output
parameter *PRINT, (DSPLOG OUTPUT(*PRINT), only one line from each message
is printed, using the first 105 characters of each message.
If you print the information in a log using the Display Log command and output
parameter *PRTWRAP, (DSPLOG OUTPUT(*PRTWRAP), messages longer than
105 characters are wrapped to include additional lines to a limit of 2000 characters.
If you display the information in a log using the Display Log (DSPLOG) command,
only 105 characters of message text are shown. Any characters after 105
characters are truncated at the right.
The third field (data) of the first record has the following format:
The third field (data) of the remaining records has the following format:
A message is never split when a new version of a log is started. The first and last
records of a message are always in the same QHST version.
For a description of the message data for a message, see “Defining Substitution
Variables” on page 187.
The time and date the job entered the system are when the system becomes aware
of a job to be initiated (a job structure is set aside for the job). For an interactive
job, the job entry time is the time the password is recognized by the system. For a
batch job, it is the time the BCHJOB or SBMJOB command is processed. For a
monitor job, reader or writer, it is the time the corresponding start command is
processed, and for autostart jobs it is during the start of the subsystem.
Following the times and dates are the total response time and the number of
transactions. The total response time is in seconds and contains the accumulated
value of all the intervals the job was processing between pressing the Enter key at
the work station and when the next display is shown. This information is similar to
that shown on the WRKACTJOB display. This field is only meaningful for interactive
jobs.
It is also possible in the case of a system failure or abnormal job end that the last
transaction will not be included in the total. The job end code in this case would be
a 40 or greater. The transaction count is also only meaningful for interactive jobs
other than the console job and is the number of response time intervals counted by
the system during the job.
The final field in the performance statistics is the job type. Values for this field are:
A Automatically started job
B Batch job
I Interactive job
M Subsystem monitor
R Spooling reader
S System job
W Spooling writer
For messages in which the message data begins in a variable position, you can
access the message data by doing the following:
v Determine the length of the variables in the message. For example, assume that
a message uses the following five variables:
Job name *CHAR 10
User name *CHAR 10
Job number *CHAR 6
Time *CHAR 8
Date *CHAR 8
These variables are fixed in the first 42 positions of the message data.
v To find the location of the message data, consider that:
– The message always begins in position 11 of the second record.
– The length of the message is stored in a 2-position field beginning at position
111 of the first record. This length is stored in a binary value so if the
message length is 60, the field contains hex 003C.
Then, by using the length of the message and the start position of the message,
you can determine the location of the message data.
| The Operational Assistant* provides a cleanup function which includes the deletion
| of old QHST files. Another alternative is:
| v As the security officer, specify:
| WRKOBJ OBJ(QSYS/QHST*) OBJTYPE(*FILE)
┌─────────────────────────────────────┐
│ Command Definition │
│ Statments │
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │ │ │ │ │ │ │
│ └───┬───┘ └───┬───┘ └───┬───┘ │
│ └──────────┼──────────┘ │
│ │ │
└──────────────────┼──────────────────┘
│
Display │
┌──────┴──────┐
│ Create │
│ Command │
│ Command │
└──────┬──────┘
│
┌──────┴───────┐
│ Command │
│ Definition │
│ Object │
└──────┬───────┘
│
┌───────────────────┼───────────────────┐
│ │ │
┌──────┴───────┐ ┌──────┴───────┐ ┌──────┴───────┐
│ Command │ │ Validity │ │ Prompt │
│ Processing │ │ Checker │ │ Override │
│ Program │ │ Program │ │ Program │
└──────────────┘ └──────────────┘ └──────────────┘
Writing your own validity checking and prompt override programs are optional steps.
Step Description
Command Definition Statements
The command definition statements contain the information that is necessary to
prompt the work station user for input, to validate that input, and to define the
values to be passed to the program that is called when the command is run.
Validity Checking
The system performs validity checking on commands. You may also write your own
validity checking program although it is not required.
If you need more validity checking than the system performs, you can write a
program called a validity checking program (see “Writing a Validity Checking
Program” on page 340) or you can include the checking in the command processing
program. You specify the names of both the command processing and validity
checking programs on the CRTCMD command.
| If a command has a validity checking program, the system passes the command
| parameter values to the validity checking program. This happens before the system
| calls the command processing program. A validity checking program runs during
| syntax checking during the following conditions:
| v When running the command.
| v When using the source entry utility (SEU) to enter commands into a CL source
| member and the programmer uses constants instead of variables for the
| parameters that are specified on the command.
| v When compiling a CL program or procedure that uses constants instead of
| variables for all the parameters that are specified on the command.
| When the program finds an error, the user receives a message to allow immediate
| correction of errors. The command processing program can assume that the data
| that is passed to it is correct. Refer to “Writing a Validity Checking Program” on
| page 340 for further information on writing validity checking programs.
The CPP must accept the parameters as defined by the command definition
statements.
In the previous example, S is the name of the new command (specified by the CMD
parameter). STARTUP is the name of the command processing program (specified
by the PGM parameter) and also the name of the source member that contains the
command definition statement (specified by the SRCMBR parameter). Now the
system operator can either enter S to call the command or CALL STARTUP to call the
command processing program.
At least one PARM statement must precede any ELEM or QUAL statements in the
source file. The source file in which you enter the command definition statements is
used by the CRTCMD command when you create a command. For information on
entering statements into a source file, see the Screen Design Aid User’s Guide and
Reference SC09-1340 or the DB2 UDB for AS/400 Database Programming book.
If you want to specify prompt text for the command, use the PROMPT parameter on
the CMD statement to specify the heading for the prompt. You then specify the
prompts for the parameters, elements of a list, and qualifiers on the PROMPT
parameters for the PARM, ELEM, and QUAL statements.
On the PROMPT parameter for the CMD statement, you can specify the actual
prompt heading text as a character string 30 characters maximum, or you can
specify the message identifier of a message description. In the following example, a
character string is specified for the command ORDENTRY.
CMD PROMPT('Order Entry')
Line 1 of the prompt looks like this after the user types in the command name and
presses F4.
Order Entry (ORDENTRY)
If you do not provide prompt text for the command you are defining, you only need
to use the word CMD for the CMD statement. However, you may want to use the
PROMPT keyword for documentation purposes.
Defining Parameters
You can define as many as 75 parameters for each command. To define a
parameter, you must use the PARM statement.
In addition, you must consider the following information when defining parameters.
(The associated PARM statement parameter is given in parentheses.)
v Whether a value is returned by the command processing program (RTNVAL). If
RTNVAL (*YES) is specified, a return variable must be coded on the command
when it is called, if you want to have the value returned. If no variable is
specified for a RTNVAL(*YES) parameter, a null pointer is passed to the
command processing program.
v Whether the parameter is not to appear on the prompt to the user but is to be
passed to the command processing program as a constant (CONSTANT).
v Whether the parameter is restricted (RSTD) to specific values (specified on the
VALUES, SPCVAL, or SNGVAL parameter) or can include any value that
matches the parameter type, length, value range, and a specified relationship.
v What the specific valid parameter values are (VALUES, SPCVAL, and SNGVAL).
v What tests should be performed on the parameter value to determine its validity
(REL and RANGE).
v Whether the parameter is optional or required (MIN).
Parameter Types
The basic parameter types are (parameter TYPE value given in parentheses):
v Decimal (*DEC). The parameter value is a decimal number, which is passed to
the command processing program as a packed decimal value of the length
specified on the LEN parameter. Values specified with more fractional digits than
defined for the parameter are truncated.
v Logical (*LGL). The parameter value is a logical value, ’1’ or ’0’, which is passed
to the command processing program as a character string of length 1 (F1 or F0).
v Character (*CHAR). The parameter value is a character string, which can be
enclosed in apostrophes and which is passed to the command processing
The maximum length that is shown here is the maximum allowed length for these
parameter types when the command runs. However, the maximum length that is
allowed for character constants in the command definition statements is 32
characters. This restriction applies to the CONSTANT, DFT, VALUES, REL, RANGE,
SPCVAL, and SNGVAL parameters. There are specific lengths for input fields
available when prompting for a CL command. The input field lengths are 1 through
12 characters and 17, 25, 32, 50, 80, 132, 256, and 512 characters. If a particular
parameter has a length that is not allowed,the input field displays with the next
larger field length. The prompter displays a 512–character input field for parameters
that can be longer than 512 characters.
Default Values
If you are defining an optional parameter, you can define a value on the DFT
parameter to be used if the user does not enter the parameter value on the
command. This value is called a default value. The default value must meet all the
value requirements for that parameter (such as type, length, and special values). If
you do not specify a default value for an optional parameter, the following default
values are used.
The OETYPE parameter is required (MIN parameter is 1) and its value is restricted
(RSTD parameter is *YES) to the values DAILY, WEEKLY, or MONTHLY. The
PROMPT parameter contains the prompt text for the parameter. Since no LEN
keyword is specified and TYPE(*CHAR) is defined, a length of 32 is the default.
LEN RTNVAL CONSTANT RSTD DFT VALUES REL RANGE SPCVAL SNGVAL
*DEC X 2 X X X X X X 3 1
*LGL X 2 X X X X 3 1
*CHAR X 2 X X X X X X 3 1
*NAME X X X X X X X 3 1
*SNAME X X X X X X X 3 1
*CNAME X X X X X X X 3 1
*PNAME X 2 X X X X X X 3 1
*GENERIC X X X X X X X 3 1
*DATE X X X X X X 3 1
*TIME X X X X X X 3 1
*HEX X X X X X X X 3 1
*ZEROELEM
*INT2 X X X X X X 3 1
*INT4 X X X X X X 3 1
*CMDSTR X X X
*NULL X
STMT LABEL X X X
Notes:
MIN MAX ALWUNPRT ALWVAR PGM DTAARA FILE FULL EXPR VARY
*DEC X X X X
*LGL X X X X X 1
*CHAR X X X X X X X X X 1
*NAME X X X X X X X X 1
*SNAME X X X X X X X X 1
*CNAME X X X X X X X X 1
*PNAME X X X X X X X X X 1
*GENERIC X X X X X X X X 1
*DATE X X X X
*TIME X X X X
*HEX X X X X X
*ZEROELEM X X
*INT2 X X X X
*INT4 X X X X
*CMDSTR 2 3 4 1
*NULL 2 3
STMT LABEL X X X
Notes:
1. Parameter is ignored when CPP is a REXX procedure.
2. The value for MIN cannot exceed 1 for TYPE(*NULL).
3. The value for MAX cannot exceed 1 for TYPE(*NULL) or TYPE(*CMDSTR).
4. The ALWVAR value is ignored for this type of parameter. CL variables are not
allowed when the parameter type is *CMDSTR.
Notes:
1. Parameter is ignored when CPP is a REXX procedure.
2. PASSVAL passes a keyword with no blanks or other characters between
parentheses when CPP is a REXX procedure.
3. Case (*MIXED) is allowed only with type *CHAR and *PNAME.
The next figure shows the valid parameter combinations and restrictions for the
PARM, ELEM, and QUAL statements. For example, the intersection of the row for
LEN and the column for DFT are blank; therefore, there are no restrictions and
combination of LEN(XX) and DFT(XX) is valid. However, the intersection of the row
for DFT and the column for CONSTANT contains a 4 which refers to a note at the
bottom of the table describing the restriction.
LEN RTNVAL CONSTANT RSTD DFT VALUES REL RANGE SPCVAL SNGVAL
LEN
RTNVAL 1 1 1 1 1 1 1 1
Notes:
1. The RTNVAL parameter cannot be used with any of the following parameters:
CONSTANT, RSTD, DFT, VALUES, REL, RANGE, SPCVAL, SNGVAL, PGM,
DTAARA, FILE, FULL, or EXPR. The RTNVAL parameter cannot be used on
any command using a REXX procedure as a CPP.
2. A MAX value greater than 1 is not allowed.
3. If PASSATR(*YES) and RTNVAL(*YES) are specified, VARY(*YES) must also
be specified. If RTNVAL(*YES) and VARY(*YES) are specified, you must use
either *INT2 or *INT4. Combinations of *INT2 and *INT4 are not valid.
4. The CONSTANT and DFT parameters are mutually exclusive.
5. The EXPR(*YES) and CONSTANT parameters are mutually exclusive.
6. The PROMPT parameter is not allowed.
7. If the RSTD parameter is specified, one of the following parameters must also
be specified: VALUES, SPCVAL, or SNGVAL.
MIN MAX ALWUNPRT ALWVAR PGM DTAARA FILE FULL EXPR VARY
LEN
RTNVAL 2 8 1 1 1 1 1 3
CONSTANT 2 4
RSTD
DFT 5
VALUES
REL
RANGE
SPCVAL
SNGVAL 7
MIN 6
MAX 6
ALWUNPRT
ALWVAR
PGM 9 9
DTAARA 9 9
FILE 9 9
FULL
EXPR
VARY
PASSATR 3
PASSVAL 10
CASE
LISTDSPL
CHOICE
CHOICEPGM
Notes:
1. The RTNVAL parameter cannot be used with any of the following parameters:
CONSTANT, RSTD, DFT, VALUES, REL, RANGE, SPCVAL, SNGVAL, PGM,
DTAARA, FILE, FULL, or EXPR. The RTNVAL parameter cannot be used on
any command using a REXX procedure as a CPP.
2. A MAX value greater than 1 is not allowed.
3. If PASSATR(*YES) and RTNVAL(*YES) are specified, VARY(*YES) must also
be specified. If RTNVAL(*YES) and VARY(*YES) are specified, you must use
either *INT2 or *INT4. Combinations of *INT2 and *INT4 are not valid.
4. The EXPR(*YES) and CONSTANT parameters are mutually exclusive.
5. The MIN value must be 0.
6. The value specified for the MIN parameter must not exceed the value specified
for the MAX parameter.
7. Either the MAX value must be greater than 1 or the parameter type must be a
statement label, or both.
8. If RTNVAL(*YES) is specified, ALWVAR(*NO) cannot be specified.
9. PGM(*YES), DTAARA(*YES), and a value other than *NO for the FILE
parameters are mutually exclusive.
10. PASSVAL(*NULL) is not allowed with RTNVAL(*YES) or a value greater than 0
for MIN.
11. PMTCTL is not allowed with a value greater than 0 for MIN.
Notes:
1. If PASSATR(*YES) and RTNVAL(*YES) are specified, VARY(*YES) must also
be specified. If RTNVAL(*YES) and VARY(*YES) are specified, you must use
either *INT2 or *INT4. Combinations of *INT2 and *INT4 are not valid.
2. The PROMPT parameter is not allowed.
3. The parameter may not refer to a parameter defined with the parameter
PASSVAL(*NULL). A range between parameters is not valid on a PARM
statement defined with PASSVAL(*NULL).
4. PASSVAL(*NULL) is not allowed with RTNVAL(*YES) or a value greater than 0
for MIN.
5. The CHOICE and CONSTANT parameters are mutually exclusive.
6. CHOICE(*PGM) requires a name for CHOICEPGM.
7. CONSTANT is mutually exclusive with the PMTCTL and PMTCTLPGM
parameters.
8. PMTCTL is not allowed with a value greater than 0 for MIN.
9. CONSTANT is mutually exclusive with DSPINPUT(*NO) and
DSPINPUT(*PROMPT).
10. The CASE parameter is valid only on PARM and ELEM statements. CASE is
not valid on the QUAL statement.
11. The LISTDSPL parameter is valid only on the PARM statement.
The following sample command source illustrates the different types of lists:
CMD PROMPT('Example of lists command')
The following display shows the prompt for the preceding sample command:
Bottom
F3=Exit F4=List F5=Refresh F12=Cancel F13=Prompter help
F24=More keys
The following example defines a parameter USER for which the display station user
can specify up to five user names (a simple list).
PARM KWD(USER) TYPE(*NAME) LEN(10) MIN(0) MAX(5) +
SPCVAL(*ALL) DFT(*ALL)
When the elements in a simple list are passed to the command processing
program, the format varies depending on whether you are using CL or HLL, or
REXX. The following section describes how the elements used in the previous
example are passed using CL and HLL. For an explanation of the differences when
using REXX, see “Using REXX for Simple Lists” on page 304.
┌───────────┬───────────┬───────────┬───────────┬─────────────┐
│ Number │ │ │ │ │
│ of Values │ Value │ Value │ Value │ Value . . . │
│ Passed │ │ │ │ │
└───────────┴───────────┴───────────┴───────────┴─────────────┘
The number of values passed is specified by a binary value that is two characters
long. This number indicates how many values were actually entered (are being
passed), not how many can be specified. The values are passed by the type of
parameter just as a value of a single parameter is passed (as described under
Defining Parameters). For example, if two user names (BJONES and TBROWN)
are specified for the USER parameter, the following is passed.
┌──────┬────────┬──────────────────────┐
│ 0002 │ BJONES │ TBROWN │
└──────┴────────┴──────────────────────┘
The user names are passed as 10-character values that are left-adjusted and
padded with blanks.
When a simple list is passed, only the number of elements specified on the
command are passed. The storage immediately following the last element passed is
not part of the list and must not be referred to as part of the list. Therefore, when
the command processing program (CPP) processes a simple list, it uses the
number of elements passed to determine how many elements can be processed.
For a simple list, a single value such as *ALL or *NONE can be entered on the
command instead of the list. Single values are passed as an individual value.
Similarly, if no values are specified for a parameter, the default value, if any is
defined, is passed as the only value in the list. For example, if the default value
*ALL is used for the USER parameter, the following is passed.
┌──────┬──────────┐
│ 0001 │ *ALL │
└──────┴──────────┘
*ALL is passed as a 10-character value that is left-adjusted and padded with blanks.
┌──────┐
│ 0000 │
└──────┘
For example, if two user names (BJONES and TBROWN) are specified for the
USER parameter, the following is passed:
. . . USER(BJONES TBROWN) . . .
When a simple list is passed, only the number of elements specified on the
command are passed. Therefore, when the CPP processes a simple list, it uses the
number of elements passed to determine how many elements can be processed.
The REXX example in Figure 14 produces the same result as the CL procedure in
Figure 13 on page 303:
.
.
.
PARSE ARG . 'USER(' user ')' .
.
.
CT = WORDS(user)
IF CT > 0 THEN user1 = WORD(user,1) else user1 = '
IF CT > 1 THEN user2 = WORD(user,2) else user2 = '
IF CT > 2 THEN user3 = WORD(user,3) else user3 = '
IF CT > 3 THEN user4 = WORD(user,4) else user4 = '
IF CT > 4 THEN user5 = WORD(user,5) else user5 = '
IF CT > 5 THEN
DO
/* If CT is greater than 5, the values passed
is greater than the program expects, and error
logic should be performed */
.
.
.
END
ELSE
DO
/* The correct number of values are passed
and the program can continue processing */
END
EXIT
This same procedure can be used to process other lists in a REXX program.
If no default value is defined for an optional simple list parameter, the following is
passed:
. . . USER() . . .
For more information about REXX procedures, see the REXX/400 Programmer’s
Guide , SC24-5665 and the REXX/400 Reference , SC24-5664.
The TYPE parameter on the associated PARM statement must have a label that
refers to the first ELEM statement for the list.
PARM KWD(LOG) TYPE(LOGLST) ...
The first ELEM statement is the only ELEM statement that can have a label.
Specify the ELEM statements in the order in which the elements occur in the list.
Note that when the MAX parameter has a value greater than 1 on the PARM
statement, and the TYPE parameter refers to ELEM statements, the parameter
being defined is a list within a list.
Parameters that you can specify on the ELEM statement include TYPE, LEN,
CONSTANT, RSTD, DFT, VALUES, REL, RANGE, SPCVAL, SNGVAL, MIN, MAX,
ALWUNPRT, ALWVAR, PGM, DTAARA, FILE, FULL, EXPR, VARY, PASSATR,
CHOICE, CHOICEPGM, and PROMPT.
In the following example, a parameter CMPVAL is defined for which the display
station user can specify a comparison value and a starting position for the
comparison (a mixed list).
PARM KWD(CMPVAL) TYPE(CMP) SNGVAL(*ANY) DFT(*ANY) +
MIN(0)
CMP: ELEM TYPE(*CHAR) LEN(80) MIN(1)
ELEM TYPE(*DEC) LEN(2 0) RANGE(1 80) DFT(1)
When the elements in a mixed list are passed to the command processing program,
the format varies depending on whether you are using CL or HLL, or REXX. The
following section describes how the elements used in the previous example are
┌───────────────┬─────────────┬─────────────┬─────────────┬────────────┐
│ Number of │ Value of │ Value of │ │ Value of │
│ Values in the │ Element 1 │ Element 2 │ . . . │ Element n │
│ Mixed List │ │ │ │ │
└───────────────┴─────────────┴─────────────┴─────────────┴────────────┘
The number of values in the mixed list is passed as a binary value of length 2. This
value always indicates how many values have been defined for the mixed list, not
how many were actually entered on the command. This value may be 1 if the
SNGVAL parameter is entered or is passed as the default value. If the user does
not enter a value for an element, a default value is passed. The elements are
passed by their types just as single parameter values are passed (as described
under “Defining Parameters” on page 288). For example, if, in the previous example
the user enters a comparison value of QCMDI for the CMPVAL parameter, but does
not enter a value for the starting position, whose default value is 1, the following is
passed.
┌──────┬───────────────────────────┬───┐
│ 0002 │ QCMDI │ 1 │
└──────┴───────────────────────────┴───┘
When the display station user enters a single value or when a single value is the
default for a mixed list, the value is passed as the first element in the list. For
example, if the display station user enters *ANY as a single value for the parameter,
the following is passed.
┌──────┬───────────────────────────────┐
│ 0001 │ *ANY │
└──────┴───────────────────────────────┘
Mixed lists can be processed in CL programs. Unlike simple lists, the binary value
does not need to be tested to determine how many values are in the list because
this value is always the same for a given mixed list unless the SNGVAL parameter
was passed to the command processing program. In this case, the value is 1. If the
In one case, only a binary value of 0000 is passed as the number of values for a
mixed list. If no default value is defined on the PARM statement for an optional
parameter and the first value of the list is required (MIN(1)), then the parameter
itself is not required; but if any element is specified the first element is required. In
this case, if the command is entered without specifying a value for the parameter,
the following is passed.
┌──────┐
│ 0000 │
└──────┘
If the user does not enter a value for an element, a default value is passed. For
example, if in the previous example, the user enters a comparison value of QCMDI
for the CMPVAL parameter, but does not enter a value for the starting position,
whose default value is 1, the following is passed:
. . . CMPVAL(QCMDI 1) . . .
Note that trailing blanks are not passed with REXX values.
When a display station user enters a single value or when a single value is the
default for a mixed list, the value is passed as the first element in the list. For
example, if the display station user enters *ANY as a single value for the parameter,
the following is passed:
. . . CMPVAL(*ANY) . . .
Again note that trailing blanks are not passed with REXX values.
If no default value is defined on the PARM statement for an optional parameter and
the first value of the list is required (MIN(1)), then the parameter itself is not
required. But if any element is specified, the first element is required. In this case, if
the command is entered without specifying a value for the parameter, the following
is passed:
The outside set of parentheses enclose the list that can be specified for the
parameter (the outer list) while each set of inner parentheses encloses a list within
a list (an inner list).
In the following example, a mixed list is defined within a simple list. A mixed list is
specified, and the MAX value on the PARM statement is greater than 1; therefore,
the mixed list can be specified up to the number of times specified on the MAX
parameter.
PARM KWD(PARM1) TYPE(LIST1) MAX(5)
LIST1: ELEM TYPE(*CHAR) LEN(10)
ELEM TYPE(*DEC) LEN(3 0)
In this example, the two elements can be specified up to five times. When a value
is entered for this parameter, it could appear as follows:
PARM1((VAL1 1.0) (VAR2 2.0) (VAR3 3.0))
In the following example, a simple list is specified as a value in a mixed list. In this
example, the MAX value on the ELEM statement is greater than 1; therefore, the
element can be repeated up to the number of times specified on the MAX
parameter.
PARM KWD(PARM2) TYPE(LIST2)
LIST2: ELEM TYPE(*CHAR) LEN(10) MAX(5)
ELEM TYPE(*DEC) LEN(3 0)
In this example, the first element can be specified up to five times, but the second
element can be specified only once. When a value is entered for this parameter, it
could appear as follows.
PARM2((NAME1 NAME2 NAME3) 123.0)
When lists within lists are passed to the command processing program, the format
varies depending on whether you are using CL or HLL, or REXX. The following
section describes how elements are passed using CL and HLL. For an explanation
of the differences when using REXX, see “Using REXX for Lists within Lists” on
page 311.
The number of lists is passed as a binary value of length 2. Following the number
of lists, the displacement to the lists is passed (not the values that were entered in
the lists). Each displacement is passed as a binary value of length 2 or length 4
depending on the value of the LISTDSPL parameter.
The following example shows a definition for a parameter KWD2 (which is a mixed
list within a simple list) how the parameter can be specified by the display station
user, and what is passed. The parameter definition is:
PARM KWD(KWD2) TYPE(LIST) MAX(20) MIN(0) +
DFT(*NONE) SNGVAL(*NONE) LISTDSPL(*INT2)
LIST: ELEM TYPE(*CHAR) LEN(10) MIN(1) /*From value*/
ELEM TYPE(*CHAR) LEN(5) MIN(0) /*To value*/
┌──────┬──────┬──────┬─────────────┬─────────┐
│ 0001 │ 0004 │ 0002 │ A │ B │
└─┬────┴─┬───┬┴─┬────┴─┬───────────┴─┬───────┘
│ │ │ │ │ │
│ │ │ │ │ Passed as 5 Characters
│ │ │ │ │
│ │ │ │ Passed as 10 Characters
│ │ │ │
│ │ │ Number of Values Specified in Inner List
│ │ │
│ │ Start of Inner List
│ │
│ Displacement to Inner List (LISTDSPL (*INT2)
│
Number of Lists
Lists within a list are passed to the command processing program in the order n
(the last one entered by the display station user) to 1 (the first one entered by the
display station user). The displacements, however, are passed from 1 to n.
The following is a more complex example of lists within lists. The parameter
definition is:
PARM KWD(PARM1) TYPE(LIST3) MAX(25)
LIST3: ELEM TYPE(LIST4)
ELEM TYPE(*CHAR) LEN(3)
ELEM TYPE(*NAME) LEN(2) MAX(5)
LIST4: ELEM TYPE(*DEC) LEN(7 2)
ELEM TYPE(*TIME)
The following example shows a definition for a parameter KWD2, which is a mixed
list within a simple list, how the parameter can be specified by the display station
user, and what is passed. The parameter definition is:
PARM KWD(KWD2) TYPE(LIST) MAX(20) MIN(0) +
DFT(*NONE) SNGVAL(*NONE)
LIST: ELEM TYPE(*CHAR) LEN(10) MIN(1) /*From value*/
ELEM TYPE(*CHAR) LEN(5) MIN(0) /*To value*/
The following is a more complex example of lists within lists. The parameter
definition is:
PARM KWD(PARM1) TYPE(LIST3) MAX(25)
LIST3: ELEM TYPE(LIST4)
ELEM TYPE(*CHAR) LEN(3)
ELEM TYPE(*NAME) LEN(2) MAX(5)
LIST4: ELEM TYPE(*DEC) LEN(7 2)
ELEM TYPE(*TIME)
The following command definition statements define the most common qualified
name. A qualified object consists of the library name which contains an object
followed by the name of the object itself. The QUAL statements must appear in the
order in which they are to occur in the qualified name.
Many of the parameters that can be specified for the QUAL statement are the same
as those described for the PARM statement (see “Defining Parameters” on
page 288). However, only the following values can be specified for the TYPE
parameter:
v *NAME
v *GENERIC
v *CHAR
When a qualified name is passed to the command processing program, the format
varies depending on whether you are using CL or HLL, or REXX. The following
section describes how qualified names are passed using CL and HLL. For an
explanation of the differences when using REXX, see “Using REXX for a Qualified
Name” on page 315.
┌──────────────┬──────────────┐
│ Value │ Value │
│ of │ of │
│ Qualifier 1 │ Qualifier 2 │
└──────────────┴──────────────┘
For example, if the display station user enters NAME(USER/A) for the previously
defined QUAL statements, the name is passed to the command processing program
as follows:
┌──────────────┬───────────────┐
│ A │ USER │
└─┬──────────┬─┴─┬──────────┬──┘
└─10 Bytes─┘ └ 10 Bytes─┘
If the display station user enters a single value for a qualified name, the length of
the value passed is the total of the length of the parts of the qualified name. For
example, if you define a qualified name with two values each of length 10, and if
the display station user enters a single value, the single value passed is
left-adjusted and padded to the right with blanks so that a total of 20 characters is
passed. If the display station user enters *NONE as the single value, the following
20-character value is passed:
┌─────────────────┐
│ *NONE │
└─────────────────┘
You can then specify the qualified name in the proper CL syntax. For example,
OBJ(&LIB/&OBJ).
You can also separate the qualified name into two values using the following
method:
PGM PARM(&QLFDNAM)
DCL &QLFDNAM TYPE(*CHAR) LEN(20)
CHKOBJ (%SST(&QLFDNAM 11 10)/%SST(&QLFDNAM 1 10)) *PGM
.
.
.
ENDPGM
┌─────────────┬─────────────┬─────────────┬─────────────┬─────────────┬────────┐
│ Number of │ Value 1 │ Value 1 │ Value 2 │ Value 2 │ │
│ Qualified │ Qualifier 1 │ Qualifier 2 │ Qualifier 1 │ Qualifier 2 │ . . . │
│ Names │ │ │ │ │ │
└─────────────┴─────────────┴─────────────┴─────────────┴─────────────┴────────┘
For example, assume that MAX(3) were added as follows to the PARM statement
for the NAME parameter.
PARM KWD(NAME) TYPE(NAME1) SNGVAL(*NONE) MAX(3)
NAME1: QUAL TYPE(*NAME)
QUAL TYPE(*NAME)
then the name parameter would be passed to the command processing program as
follows.
┌───────────────┬─────────────┬─────────────┬─────────────┬────────────┐
│ 0002 │ A │ QGPL │ B │ USER │
└───────────────┴┬──────────┬─┴┬──────────┬─┴┬──────────┬─┴┬──────────┬┘
└─10 Bytes─┘ └─10 Bytes─┘ └─10 Bytes─┘ └─10 Bytes─┘
If the display station user enters the single value NAME(*NONE), the name
parameter is passed as follows.
For example, if a display station user enters the following for the QUAL statements
defined previously in this section:
NAME(USER/A)
the qualified name is passed to the command processing program in the following
format:
NAME(USER/A)
If the display station user enters *NONE as the single value, the following
20-character value is passed:
NAME(*NONE)
The following example shows how a display station user would enter a simple list of
qualified names:
NAME(QGPL/A USER/B)
Using REXX, the name parameter would be passed to the command processing
program as the following:
NAME(QGPL/A USER/B)
| In the following example, if the display station user specifies the TYPE(LIST)
parameter, the display station user must also specify the ELEMLIST parameter.
DEP CTL(&TYPE *EQ LIST) PARM(ELEMLIST)
In the following example, the parameter &WRITER must never be equal to the
parameter &NEWWTR. If this condition is not true, message USR0001 is issued to
the display station user.
DEP CTL(*ALWAYS) PARM((&WRITER *NE &NEWWTR)) MSGID(USR0001)
In the following example, if the display station user specifies the FILE parameter,
the display station user must also specify both the VOL and LABEL parameters.
DEP CTL(FILE) PARM(VOL LABEL) NBRTRUE(*EQ 2)
The text for possible choices is defined by the CHOICE parameter. The default for
this parameter is *VALUES, which indicates that the text is to be created
automatically from the values specified for the TYPE, RANGE, VALUES, SPCVAL,
and SNGVAL keywords. The text is limited to 30 characters; if there are more
values than can fit in this size, an ellipsis (...) is added to the end of the text to
indicate that it is incomplete.
You can specify that no possible choices should be displayed (*NONE), or you can
specify either a text string to be displayed or the ID of a text message which is
retrieved from the message file specified in the PMTFILE parameter of the
CRTCMD command.
You can also specify that an exit program to run during prompting to provide the
possible choices text. This could be done if, for example, you want to show the user
a list of objects that currently exist on the system. The same exit program can be
used to provide the list of permissible values shown on the Specify Value for
Parameter display. To specify an exit program, specify *PGM for the CHOICE
parameter, and the qualified name of the exit program in the CHOICEPGM
parameter on the PARM, ELEM, or QUAL statement.
If any exception occurs when the program is called, the possible choices text is left
blank, and the list of permissible values is taken from the command.
You can specify that a parameter be displayed depending on the value specified for
other parameters. This specification is useful when a parameter has meaning only
when another parameter (called a controlling parameter) has a certain value.
You can also specify that a parameter be selected for prompting only if additional
parameters are requested by pressing a function key during prompting. This
specification can be used for parameters that are seldom specified by the user,
either because the default is normally used or because they control seldom-used
functions.
If you want to show all parameters for a command that has prompt control
specified, you can request that all parameters be displayed by pressing F9 during
prompting.
Conditional Prompting
When prompting the user for a command, a parameter which is conditioned by
other parameters is displayed if:
v It is selected by the value specified for the controlling parameter.
v The value specified for the controlling parameter is in error.
v A value was specified for the conditioned parameter.
v A function key was pressed during prompting to request that all parameters be
displayed.
On the PMTCTL statement, specify the name of the controlling parameter, one or
more conditions to be tested, and the number of conditions that must be true to
select the conditioned parameters for prompting. If the controlling parameter has
special value mapping, the value entered on the PMTCTL statement must be the
to-value. If the controlling parameter is a list or qualified name, only the first list item
or qualifier is compared.
In this previous example, the user is prompted for the OUTLINK parameter after the
condition for OUTMBR parameter has been tested. In some cases, the user should
be prompted for the OUTLINK parameter before the OUTMBR parameter is tested.
To specify a different prompt order, either reorder the parameters in the command
definition source or use the PROMPT keyword on the PARM statement for the
OUTLINK parameter.
A label can refer to a group of PMTCTL statements. This allows you to condition a
parameter with more than one controlling parameter. To specify a group of PMTCTL
statements, enter the label on the first statement in the group. No other statements
can be placed between the PMTCTL statements in the group.
Use the LGLREL parameter to specify the logical relationship between the
statements in the group. The LGLREL parameter is not allowed on the first
PMTCTL statement in a group. For subsequent PMTCTL statements, the LGLREL
parameter specifies the logical relationship (*AND or *OR) to the PMTCTL
statement or statements preceding it. Statements in a group can be logically related
in any combination of *AND and *OR relationships (*AND relationships are checked
first, then *OR relationships).
The following example shows how the logical relationship is used to group multiple
PMTCTL statements. In this example, parameter P3 is selected when any one of
the following conditions exists:
v *ALL is specified for P1.
To specify an exit program, specify the qualified name of the program in the
PMTCTLPGM parameter on the PARM statement for the controlling parameter. The
exit program is run during prompting when checking a parameter. The conditions on
the PMTCTL statement are compared with the value returned by the exit program
rather than the value specified for the controlling parameter.
If the exit program cannot be found or does not run successfully, a single asterisk is
placed in the return value. The exit program should be written to return a value of a
single asterisk when it detects an error. Consider this when coding the PMTCTL
statements; for example, displaying all parameters conditioned by that parameter
when an error occurs.
In the following example, OBJ is a qualified name which may be the name of a
command, program, or file. The exit program determines the object type and returns
the type in the variable &RTNVAL:
CMD
PARM OBJ TYPE(Q1) PMTCTLPGM(CNVTYPE)
Q1: QUAL TYPE(*NAME) LEN(10)
QUAL TYPE(*NAME) LEN(10) SPCVAL(*LIBL) DFT(*LIBL)
PARM CMDPARM TYPE(*CHAR) LEN(10) PMTCTL(CMD)
PARM PGMPARM TYPE(*CHAR) LEN(10) PMTCTL(PGM)
PARM FILEPARM TYPE(*CHAR) LEN(10) PMTCTL(FILE)
Additional Parameters
You can specify that a parameter which is not frequently used will not be prompted
for unless the user requests additional parameters by pressing a function key during
prompting. This is done by specifying PMTCTL(*PMTRQS) on the PARM statement
for the parameter. When prompting for a command, parameters with
PMTCTL(*PMTRQS) coded will not be prompted unless a value was specified for
them or the user presses F10 to request the additional parameters.
If a prompt override program is defined for a command, you can see the results of
calling the prompt override program in the following two ways:
v Type the name of the command without parameters on any command line and
press F4=Prompt. The next screen shows the key parameters for the command.
Key parameters are parameters, such as the name of an object, that uniquely
identify the object.
For an example of CL source for a prompt override program, see “CL Sample for
Using the Prompt Override Program” on page 325.
| Information Returned from the Prompt Override Program: Based on the values
passed, the prompt override program retrieves the current values for the
parameters that are not key parameters. These values are placed into a command
string, where the length of the string is determined and returned.
Use the following guidelines to ensure your command string is correctly defined:
v Use the keyword format for the command string just as you would on the
command line.
v Do not include the command name and the key parameters in the command
string.
v Precede each keyword with a selective prompt character to define how to display
the parameter and what value to pass to the CPP. For information about using
selective prompt characters, see “Selective Prompting for CL Commands” on
page 168.
When using selective prompts, do the following:
– If a parameter is defined as MIN(1) in the command definition source (that is,
the parameter is required), you must use the ?? selective prompt character for
that keyword in the command string from the prompt override program.
– Do not use the ?- selective prompt character in the prompt override program
command string.
v Include only the parameters in the command string whose current values you
want displayed when the command is prompted. Parameters not included in the
command string have their defaults displayed.
v Use character form for any numbers that appear in the command string. Do not
use binary or packed form. Do not include any hexadecimal numbers in the
command string.
v Do not put blank spaces between the library and the qualifier or the qualifier and
the object. For example:
??KWD1(library /object)
Not valid
??KWD1(library/ object)
Not valid
??KWD1(library/object)
Valid
??KWD1( library/object )
Valid
v If you use special values or single values, make sure they are translated into the
from-value defined in the command definition source.
For example, a keyword has a special value defined as SPCVAL(*SPECIAL *) in
the command definition source. *SPECIAL is the from-value and * is the to-value.
When the current value is retrieved for this keyword, * is the value retrieved, but
*SPECIAL must appear in the command string returned from the prompt override
program. The correct from-value must be placed into the command string since
more than one special value or single value can have the same to-value. For
example, if KWD1 SPCVAL((*SPC *) (*SPECIAL *)) is specified, the prompt
override program must determine whether * is the to-value for *SPC or
*SPECIAL.
v Define the length of fields used to retrieve text as follows:
(2*(field length defined in command definition source)) + 2
This length allows for the maximum number of quotation marks allowed in the
text field. For example, if the TEXT parameter on the CHGxxx command is
defined in the command definition source as LEN(50), then the parameter is
If the parameter for a text field is not correctly defined in the prompt override
program and the text string retrieved by the prompt override program contains a
quote, the command does not prompt correctly.
| v Make sure that you double any embedded apostrophes, for example:
| ?<TEXT('Carol''s library')
| Some commands can only be run in certain modes (such as DEBUG) or job status
(such as *BATCH) but can still be prompted for from other modes or job statuses.
When the command is prompted, the prompt override program is called regardless
of the user’s environment. If the prompt override program is called in a mode or
environment that is not valid for the command, the defaults are displayed for the
command and a value of 0 is returned for the length. Using the debug commands
Change Debug (CHGDBG) and Add Program (ADDPGM) when not in debug mode
are examples of this condition.
For example, if you need a message saying that a library does not exist, add a
message description similar to the following:
ADDMSGD MSG('Library &2 does not exist') +
MSGID(USR0012) +
MSGF(QGPL/ACTMSG) +
SEV(40) +
FMT((*CHAR 4) (*CHAR 10))
Note: The substitution variable &1 is not in the message but is defined in the FMT
parameter as 4 characters. &1 is reserved for use by the system and must
always be 4 characters. If the substitution variable &1 is the only substitution
variable defined in the message, you must ensure that the fourth byte of the
message data does not contain a blank when you send the message. The
fourth byte is used by the system to manage messages during command
processing and prompting.
This message can be sent to the calling program of the prompt override program by
specifying the following in the prompt override program:
SNDPGMMSG MSGID(USR0012) MSGF(QGPL/ACTMSG) +
MSGDTA('0000' || &libname) MSGTYPE(*DIAG)
After the prompt override program sends all the necessary diagnostic messages, it
should then send message CPF0011. To send message CPF0011, use the Send
Program Message (SNDPGMMSG) command as follows:
SNDPGMMSG MSGID(CPF0011) MSGF(QCPFMSG) +
MSGTYPE(*ESCAPE)
If key parameters are defined in the command definition source but the prompt
override program is not specified when the command is created or changed,
warning message CPD029B results. The key parameters are ignored, and when the
command is prompted, it is displayed using the defaults specified in the command
definition source.
This prompt override program uses the ″?|″ selective prompt characters.
/********************************************************************/
/* */
/* Return command string structure declaration */
/* */
/********************************************************************/
/********************************************************************/
/* */
/* Variables related to command string declarations */
/* */
/********************************************************************/
DCL VAR("e) TYPE(*CHAR) LEN(1) VALUE('''')
DCL VAR(&closparen) TYPE(*CHAR) LEN(1) VALUE(')')
/********************************************************************/
/* */
/* Start of operable code */
/* */
/********************************************************************/
/********************************************************************/
/* */
/* Monitor for exceptions */
/* */
/********************************************************************/
MONMSG MSGID(CPF0000) +
EXEC(GOTO CMDLBL(error))
/********************************************************************/
/* */
/* Build the command string */
/* */
/********************************************************************/
CHGVAR VAR(&rtnstring) VALUE(&binlen)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT &ownerkwd)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT &name)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT &closparen)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT &textkwd)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT "e)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT &descript)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT "e)
CHGVAR VAR(&rtnstring) VALUE(&rtnstring *TCAT &closparen)
GOTO CMDLBL(pgmend)
ERROR:
VALUE(0)
CHGVAR VAR(%BIN(&rtnstring 1 2)) VALUE(&stringlen)
VALUE(&binlen)
/********************************************************************/
/* */
/* Send error message(s) */
/* */
/* NOTE: If you wish to send a diagnostic message as well as CPF0011*/
/* you will have to enter a valid error message ID in the */
/* MSGID parameter and a valid message file in the MSGF */
/* parameter for the first SNGPGMMSG command listed below. */
/* If you do not wish to send a diagnostic message, do not */
/* include the first SNDPGMMSG your program. However, in */
/* error conditions, you must ALWAYS send CPF0011 so the */
/* second SNDPGMMSG command must be included in your program. */
/* */
/********************************************************************/
SNDPGMMSG MSGID(XXXXXXX) MSGF(MSGLIB/MSGFILE) MSGTYPE(*DIAG)
SNDPGMMSG MSGID(CPF0011) MSGF(QCPFMSG) MSGTYPE(*ESCAPE)
PGMEND:
ENDPGM
For commands with REXX CPPs, you can also specify the following:
v The initial command environment to handle commands when the procedure is
started
v Exit programs to control running of your procedure
Prologue
4 The parameter values specified (or defaults if not specified) on the
CRTCMD command. If the source is not in a database file, the member
name, date, and time are omitted.
5 The name of the create command definition compiler.
Source:
6 The sequence number of lines (records) in the source file. A dash following
a sequence number indicates that a source statement begins at that
sequence number. The absence of a dash indicates that a statement is the
continuation of the previous statement. For example, a PARM source
statement starts at sequence number 200 and continues at sequence
numbers 300 and 400. (Note the continuation character of + on the PARM
statement at sequence number 200 and 300.)
Comment source statements are handled like any other source statement
and have sequence numbers.
See the DB2 UDB for AS/400 Database Programming book for information
about how sequence numbers are assigned.
7 The source statements.
8 The last date the source statement was changed or added. If the statement
has not been changed or added, no date is shown. If the source is not in a
database file, the date is omitted.
If an error is found during processing of the command definition statements
and can be traced to a specific source statement, the error message is
printed immediately following the source statement. An asterisk (*) indicates
that the line contains an error message. The line contains the message
identifier, severity, and the text of the message.
For more information about the command definition errors, see “Errors
Encountered when Processing Command Definition Statements” on
page 331.
Cross-references:
9 The keyword table is a cross-reference list of the keywords validly defined
in the command definition. The table lists the keyword, the position of the
keyword in the command, the sequence number of the statement where the
keyword is defined, and the sequence numbers of statements that refer to
the keyword.
If valid labels are defined in the command definition, a cross-reference list
of the labels (label table) is provided. The table lists the label, the sequence
number of the statement where the label is defined, and the sequence
numbers of statements that refer to the label.
Messages:
Message summary:
11 A summary of the number of messages issued during processing of the
command definition statements. The total number is given along with totals
by severity.
12 A completion message is printed following the message summary.
Even after an error that stops the command from being created is encountered, the
command definition compiler continues to check the source for other errors. Syntax
errors and fixed value errors prevent final checking that identifies errors in user
names and values or references to keywords or labels. Checking for syntax errors
and fixed value errors does continue. This lets you see and correct as many errors
as possible before you try to create the command again. To correct errors made in
the source statements, see the DB2 UDB for AS/400 Database Programming book
or the Screen Design Aid User’s Guide and Reference book, SC09-1340.
In the command definition source list, an error condition that relates directly to a
specific source statement is listed after that command. See “Command Definition
Source Listing” on page 329 for an example of these inline messages. Messages
that do not relate to a specific source statement but are more general in nature are
listed in a messages section of the list, not inline with source statements.
You can make the following changes to the command definition statements for a
command without re-creating the modules and programs that use the command.
Some of these changes are made to the command definition statements source,
The following changes can be made to the command definition statements, but may
cause the procedure or program that uses the command to function differently:
v Change the meaning of a value.
v Change the default value.
v Change a SNGVAL parameter to a SPCVAL parameter.
v Change a value to a SNGVAL parameter.
v Change a list to a list within a list.
v Change case value from *MIXED to *MONO.
The following changes to the command definition statements require that the
procedures or program using the command be re-created.
v Addition of a new required parameter.
v Removal of a required parameter.
v Changing the name of a required parameter.
v Changing a required parameter to a constant.
v Changing the command processing program to or from *REXX
In addition, if you specify *LIBL as the qualifier on the name of the command
processing program or the validity checking when the command is created or
changed, you can move the command processing program or the validity checking
to another library in the library list without changing the command definition
statements.
The following steps can be used to build the NEWDFT command string for the
CHGCMDDFT command. The USRQSYS/CRTCLPGM command is used in this
example.
1. Create a duplicate copy of the command to be changed in a user library with
the following command:
CRTDUPOBJ OBJ(CRTCLPGM) FROMLIB(QSYS) OBJTYPE(*CMD) +
TOLIB(USRQSYS) NEWOBJ(*SAME)
2. Enter the command name to be changed in a source file referred to by the
Source Entry Utility (SEU).
3. Press F4 to call the command prompter.
| 4. Enter any new default values for the keywords you want changed. In this
| example, AUT(*EXCLUDE) and TEXT('Isn''t this nice text') is entered.
5. Required keywords cannot have a default value; however, in order to get the
command string in the source file, a valid value must be specified for each
required keyword. Specify PGM1 for the PGM parameter.
| 6. Press the Enter key to put the command string into the source file. The
| command string returned would look like this:
| USRQSYS/CRTCLPGM PGM(PGM1) AUT(*EXCLUDE) +
| TEXT('Isn''t this nice text')
| 7. Remove the required keywords from the command string:
| USRQSYS/CRTCLPGM AUT(*EXCLUDE) +
| TEXT('Isn''t this nice text')
| Remember that you may change only parameters, elements, or qualifiers that
| have existing default values. Specifying a value for a parameter, element, or
| qualifier that does not have an existing default value makes no default
| changes.
| 8. Insert the CHGCMDDFT at the beginning as shown in the example below:
Example 1
To provide a default value of *NOMAX for the MAXMBRS keyword of command
CRTPF, do the following:
CRTPF FILE(FILE1) RCDLEN(96) MAXMBRS(1)
.
.
CHGCMDDFT CMD(CRTPF) NEWDFT('MAXMBRS(*NOMAX)')
Example 2
To provide a default value of 10 for the MAXMBRS keyword of the command
CRTPF, do the following:
CRTPF FILE(FILE1) RCDLEN(96) MAXMBRS(*NOMAX)
.
.
CHGCMDDFT CMD(CRTPF) NEWDFT('MAXMBRS(10)')
Example 3
The following allows you to provide a default value of LIB001 for the first qualifier of
the SRCFILE keyword and FILE001 for the second qualifier of the SRCFILE
keyword for the command CRTCLPGM. The AUT keyword now have a default
value of *EXCLUDE.
CRTCLPGM PGM(PROGRAM1) SRCFILE(*LIBL/QCMDSRC)
.
.
CHGCMDDFT CMD(CRTCLPGM) +
NEWDFT('SRCFILE(LIB001/FILE001) AUT(*EXCLUDE)')
| Example 5
The following provides a default value of QGPL for the first qualifier (library name)
of the first list item of the DTAMBRS keyword for the command CRTLF. The new
default value for the second list item of the DTAMBRS keyword (member name) is
MBR1.
CRTLF FILE(FILE1) DTAMBRS(*ALL)
.
.
CHGCMDDFT CMD(CRTLF) +
NEWDFT('DTAMBRS((QGPL/*N (MBR1)))')
Since *ALL is a SNGVAL (single value) for the entire DTAMBRS list, the defaults of
*CURRENT for the library name and *NONE for the member name do not show up
on the original command prompt display. The defaults *CURRENT and *NONE can
be changed to a new default value but do not show up on the original prompt
display because of the *ALL single value for the entire DTAMBRS list.
Example 6
Create a command that will display the spool files for a job:
CRTDUPOBJ OBJ(WRKJOB) FROMLIB(QSYS) +
TOLIB(MYLIB) NEWOBJ(WRKJOBSPLF)
WRKJOBSPLF OPTION(*SPLF)
.
.
CHGCMDDFT CMD(MYLIB/WRKJOBSPLF) +
NEWDFT('OPTION(*SPLF)')
┌───────────────────────────────────────────┐
│ PGM (&ORDER) │
│ │
│ DCL &ORDER + │
│ TYPE (*DEC) + │
│ LEN (6 0) │
│ RANGE (100000 600000) + │
│ PROMPT ('Order number :') │
│ . │
│ . │
│ . │
│ │
└───────────────────────────────────────────┘
If the command processing program is a program written in CL, the variables that
receive the parameter values must be declared to correspond to the type and
length specified for each PARM statement. The following shows this
correspondence. (Note the declare for the parameter ORDER in Figure 15.)
| The remainder of this section describes how to send messages from a validity
| checking program that is written in CL.
Note that the substitution variable &1 is not in the message but is defined in the
FMT parameter as 4 characters. &1 is reserved for use by the system and must
always be 4 characters. If the substitution variable &1 is the only substitution
variable defined in the message, you must ensure that the fourth byte of the
message data does not contain a blank when you send the message.
This message can be sent to the system by specifying the following in the validity
checking:
SNDPGMMSG MSGID(USR0012) MSGF(QGPL/ACTMSG) +
MSGDTA('0000' || &ACCOUNT) MSGTYPE(*DIAG)
After the validity checking has sent all the necessary diagnostic messages, it should
then send message CPF0002. The Send Program Message (SNDPGMMSG)
command to send message CPF0002 looks like this:
SNDPGMMSG MSGID(CPF0002) MSGF(QCPFMSG) +
MSGTYPE(*ESCAPE)
When the system receives message CPF0002, it sends message CPF0001 to the
calling program to indicate that errors have been found.
Message CPD0006 has been defined for use by the user-defined validity checking
programs. An immediate message can be sent in the message data. Note in the
following example that the message must be preceded by four character zeros.
If the program were called directly from the display, the second parameter would be
in the wrong format for the program. A numeric constant on the CALL command is
always 15 digits with 5 decimal positions, and the LBLWRT program expects a
3-digit number with no decimal positions. A command can be created that provides
the data in the format required by the program.
The command definition statements for a command to call the LBLWRT program
are:
CMD PROMPT('Label Writing Program')
PARM KWD(CUSNBR) TYPE(*CHAR) LEN(5) MIN(1) +
PROMPT('Customer Number')
PARM KWD(COUNT) TYPE(*DEC) LEN(3) DFT(20) RANGE(10 150) +
PROMPT('Number of Labels')
PARM KWD(FRMTYP) TYPE(*CHAR) LEN(3) DFT('TWO') RSTD(*YES) +
SPCVAL(('ONE') ('TWO') ('1' 'ONE') ('2' 'TWO')) +
PROMPT('Form Type')
For the second parameter, COUNT, a default value of 20 is specified and the
RANGE parameter allows only values from 10 to 150 to be entered for the number
of labels.
For the third parameter, FRMTYP, the SPCVAL parameter allows the display station
user to enter 'ONE', 'TWO', '1', or '2' for this parameter. The program expects
the value 'ONE' or 'TWO'; however, if the display station user enters '1' or '2', the
command makes the necessary substitution for the FRMTYP parameter.
The command processing program for this command is the application program
LBLWRT. If the application program were an RPG for OS/400 program, the
following specifications would be made in the program to receive the parameters:
*ENTRY PLIST
PARM CUST 5
PARM COUNT 30
PARM FORM 3
| The RSTD parameter on the second PARM statement specifies that the entry can
only be one of the list of values.
The QUAL statements are used to define the qualified name that the user can enter
for the OUTQ parameter. If the user does not enter a name, *LIBL/PGMR is used.
The SPCVAL parameter is used because any library name must follow the rules for
a valid name (for example, begin with A through Z), and the value *LIBL breaks
these rules. The SPCVAL parameter specifies that if *LIBL is entered, OS/400 is to
ignore the name validation rules.
For example, you create a command named CQ2 to clear the output queue
QPRINT2.
The CPP, which receives the completion message and displays it, is as follows:
PGM /* Clear QPRINT2 output queue CPP */
DCL &MSGID TYPE(*CHAR) LEN(7)
DCL &MSGDTA TYPE(*CHAR) LEN(100)
CLROUTQ QPRINT2
RCVMSG MSGID(&MSGID) MSGDTA(&MSGDTA) MSGTYPE(*COMP)
SNDPGMMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGDTA(&MSGDTA) MSGTYPE(*COMP)
ENDPGM
The MSGDTA length for message CPF3417 is 28 bytes. However, by defining the
variable &MSGDTA as 100 bytes, the same approach can be used on most
messages because any unused positions are ignored.
PARM KWD(PRTDEV) +
TYPE(*NAME) +
LEN(10) +
SPCVAL(*SAME *USRPRF *SYSVAL *WRKSTN) +
PROMPT('Printer Device')
v Step two: Processing program
PGM PARM(&PRTDEV)
DCL VAR(&PRTDEV) TYPE(*CHAR) LEN(10)
CHGJOB PRTDEV(&PRTDEV)
ENDPGM
v Step three: CRTCMD command
CRTCMD CMD(CJ) PGM(CJ) SRCMBR(CJ)
Example 2
You could create an abbreviated command called DW1 to start the printer writer
W1.
The command definition statements for the command named DFS are:
CMD PROMPT('Delete File and Source')
PARM KWD(FILE) TYPE(*NAME) LEN(10) PROMPT('File Name')
The command processing program is written assuming that the name of the file and
the source file member are the same. The program also assumes that both the file
and the source file are on the library list. If the program cannot delete the file, an
information message is sent and the command attempts to remove the source
member. If the source member does not exist, an escape message is sent.
The command definition statements for the command named DPS are:
CMD PROMPT ('Delete Program and Source')
PARM KWD(PGM) TYPE(*NAME) LEN(10) PROMPT('Program Name')
| The command processing program is written assuming that the name of the
| program and the source file member are the same. Additionally, you have to use
| the IBM-supplied source files of QCLSRC, QRPGSRC, and QCBLSRC. The
| program also assumes that both the program and the source file are on the library
| list. If you cannot open the program, the system sends an information message,
| and the command attempts to remove the source member. If the source member
| does not exist, the system sends an escape message. The command processing
| program is:
| PGM PARM(&PGM)
| DCL &PGM TYPE(*CHAR) LEN(10)
| DCL &MSGID TYPE(*CHAR) LEN(7)
| DCL &MSGDTA TYPE(*CHAR) LEN(80)
| DCL &SRCFILE TYPE(*CHAR) LEN(10)
| MONMSG MSGID(CPF0000) EXEC(GOTO ERROR) /* CATCH ALL */
| DLTPGM &PGM
| MONMSG MSGID(CPF2105) EXEC(DO) /* NOT FOUND*/
| RCVMSG MSGTYPE(*EXCP) MSGID(&MSGID) MSGDTA(&MSGDTA)
| SNDPGMMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGTYPE(*INFO) +
| MSGDTA(&MSGDTA)
| GOTO TRYCL /* TRY TO DELETE SOURCE MEMBER */
| ENDDO
| RCVMSG MSGTYPE(*COMP) MSGID(&MSGID) MSGDTA(&MSGDTA)
| /* DELETE PROGRAM COMPLETED */
| SNDPGMMSG MSGID(&MSGID) MSGF(QCPFMSG) MSGTYPE(*COMP) +
| MSGDTA(&MSGDTA) /* TRY IN QCLSRC */
| TRYCL: CHKOBJ QCLSRC OBJTYPE(*FILE) MBR(&PGM)
| MONMSG MSGID(CPF9815) EXEC(GOTO TRYRPG) /* NO CL MEMBER */
| RMVM QCLSRC MBR(&PGM)
| CHGVAR &SRCFILE 'QCLSRC'
| GOTO END
| TRYRPG: /* TRY IN QRPGSRC FILE */
| CHKOBJ QRPGSRC OBJTYPE(*FILE) MBR(&PGM)
| MONMSG MSGID(CPF9815) EXEC(GOTO TRYCBL) /* NO RPG MEMBER */
While debugging and testing your programs, ensure that your library list is changed
to direct the programs to a test library containing test data so that any existing real
data is not affected.
You can prevent database files in production libraries from being modified
unintentionally by using one of the following commands:
v Use the Start Debug (STRDBG) command and retain the default *NO for the
UPDPROD parameter.
v Use the Change Debug (CHGDBG) command.
Debug Commands
Many debug commands are available for use with the ILE source debugger. The
debug commands and their parameters are entered on the debug command line
displayed on the bottom of the Display Module Source and Evaluate Expression
displays. These commands can be entered in upper case, lower case, or mixed
case.
Note: The debug commands entered on the source debugger command line are
not CL commands.
Table 9 summarizes these debug commands. The online help for the ILE source
debugger describes the debug commands and explains their allowed abbreviations.
Table 9. ILE source debugger commands
Debug
Command Description
ATTR Permits you to display the attributes of a variable. The attributes are the
size and type of the variable as recorded in the debug symbol table.
BREAK Permits you to enter either an unconditional or conditional breakpoint at
a position in the program being tested. Use BREAK position WHEN
expression to enter a conditional breakpoint.
CLEAR Permits you to remove conditional and unconditional breakpoints.
DISPLAY Allows you to display the names and definitions assigned by using the
EQUATE command. It also allows you to display a different source
module than the one currently shown on the Display Module Source
display. The module object must exist in the current program object.
EQUATE Allows you to assign an expression, variable, or debug command to a
name for shorthand use.
EVAL Allows you to display or change the value of a variable or to display the
value of expressions.
QUAL Allows you to define the scope of variables that appear in subsequent
EVAL commands.
STEP Allows you to run one or more statements of the program being
debugged.
FIND Searches the module currently displayed for a specified line-number or
string or text.
UP Moves the displayed window of source towards the beginning of the
view by the amount entered.
DOWN Moves the displayed window of source towards the end of the view by
the amount entered.
LEFT Moves the displayed window of source to the left by the number of
characters entered.
RIGHT Moves the displayed window of source to the right the number of
characters entered.
For each ILE CL module object that you want to debug, you can create one of three
views:
v Root source view
v Listing view
v Statement view
To use the root source view with the ILE source debugger, the ILE CL compiler
creates the root source view while the module object (*MODULE) is being created.
Note: The module object is created by using references to locations of the source
statements in the root source member instead of copying the source
statements into the view. Therefore, you should not modify, rename, or move
root source members between the creation of the module and the debugging
of the module created from these members.
To debug an ILE CL module object by using a root source view, use the *SOURCE
or *ALL option on the DBGVIEW parameter for either the CRTCLMOD or
CRTBNDCL commands.
The Create CL Module (CRTCLMOD) command with *SOURCE for the DBGVIEW
parameter creates a root source view for module object MYPGM.
To debug an ILE CL module object by using a listing view, use the *LIST or *ALL
option on the DBGVIEW parameter for either the CRTCLMOD or CRTBNDCL
commands when you create the module.
Note: No data is shown in the Display Module Source display when a statement
view is used to debug an ILE CL module object.
To debug an ILE CL module object by using a statement view, use the *STMT,
*SOURCE, *LIST, or *ALL option on the DBGVIEW parameter for either the
CRTCLMOD or CRTBNDCL commands when you create the module.
To start the ILE source debugger, use the Start Debug (STRDBG) command. Once
the debugger is started, it remains active until you enter the End Debug (ENDDBG)
command.
| Initially, you can add as many as twenty (20) program objects and twenty (20)
| service programs to a debug session. Do this by using the Program (PGM) and
| Service Program (SRVPGM) parameters on the STRDBG command. The program
| objects can be any combination of ILE or original program model (OPM) programs.
| To start a debug session with three program objects, type:
| STRDBG
| PGM(*LIBL/MYPGM1 *LIBL/MYPGM2 *LIBL/MYPGM3) SRVPGM(*LIBL/SRVPGM1 *LIBL/SRVPGM2)
| DBGMODSRC(*YES)
| Note: You must have *CHANGE authority to a program object to add it to a debug
| session.
| The option to use the ILE source debugger to debug OPM programs exists for
| users. OPM programs contain source debug data when created. Do this only by
| specifying the OPTION(*SRCDBG) parameter of the Create CL Program
| (CRTCLPGM) command. The source debug data is actually part of the program
| object.
| To add OPM programs that are created containing source debug data to the ILE
| source debugger, use the Program (PGM) and OPM Source Level Debug
| (OPMSRC) parameters on the STRDBG command. To start a debug session with
| an OPM program created with source debug data, type:
| STRDBG PGM(*LIBL/MYOPMPGM) OPMSRC(*YES) DSPMODSRC(*YES)
|
Adding Program Objects to a Debug Session
You can add more program objects to a debug session after starting the session.
To add ILE program objects and service programs to a debug session, use option 1
(Add program) and type the name of the program object on the first line of the Work
with Module List display. See Table 9 on page 350 for a list of ILE source debugger
commands. The Work with Module List display can be accessed from the Display
Module Source display by pressing F14 (Work with Module List). To add a service
program, change the default program type from *PGM to *SRVPGM. There is no
limit to the number of ILE program objects and service programs that can be
included in a debug session at any given time.
Bottom
Command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
</fig>
Figure 17. Adding an ILE Program Object to a Debug Session. When the Enter is pressed,
program WEEKDAY2 is added to the debug session
Bottom
Command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
Program WEEKDAY2 added to source debugger.
Figure 18. Adding an ILE Program Object to a Debug Session. The information message at
the bottom of the display shows that program WEEKDAY2 was added to the debug session.
When you have finished adding program objects to the debug session, press F3
(Exit) from the Work with Module List display to return to the Display Module
Source display. You can also use option 5 (Display Module Source) to select and
display a module.
| To add OPM programs to a debug session, use the Add Program (ADDPGM)
| command. A debug session can include up to twenty (20) OPM programs at any
| given time. You can add OPM programs that contain source debug data to the
| debug session by using option 1 (Add program) on the Work with Module List
| display. (This is true provided the debug session allows OPM source level
| debugging.) You can allow OPM source level debugging by starting the debug
| session and by using the OPMSRC parameter on the STRDBG command. If the
| OPMSRC parameter was not specified on the STRDBG command, activate OPM
| source level debugging. Do this by using the OPM Source Level Debug (OPMSRC)
| parameter on the Change Debug (CHGDBG) command. Alternately, you can
| change the value of the OPM source debug support option by using the SET debug
| command.
To remove ILE program objects and service programs from a debug session, use
option 4 (Remove program), next to the program object you want to remove, on the
Work with Module List display. See Figure 19 on page 355. The Work with Module
List display can be accessed from the Display Module Source display by pressing
F14 (Work with Module List). To remove a service program, change the default
program type from *PGM to *SRVPGM.
Bottom
Command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
Figure 19. Removing an ILE Program Object from a Debug Session. When the Enter key is
pressed, program WEEKDAY2 is removed from the debug session.
Bottom
Command
===>
F3=Exit F4=Prompt F5=Refresh F9=Retrieve F12=Cancel
Program WEEKDAY2 removed from source debugger.
When you have finished removing program objects from the debug session, press
F3 (Exit) from the Work with Module List display to return to the Display Module
Source display.
Note: You must have *CHANGE authority to a program to remove it from a debug
session.
There are two methods to change what is shown on the Display Module Source
display:
v Change a view
v Change a module
When you change a view, the ILE source debugger maps to equivalent positions in
the view you are changing to. When you change the module, the executable
statement on the displayed view is stored in memory and is viewed when the
module is displayed again. Line numbers that have breakpoints set are highlighted.
When a breakpoint, step, or message causes the program to stop and the display
to be shown, the source line where the event occurred is highlighted.
To select a module object, type 5 (Display module source) next to the module
object you want to show.
After you select the module object that you want to view, press Enter. The selected
module object is shown in the Display Module Source display.
The module object module-name will now be shown. The module object must exist
in a program or service program object that has been added to the debug session.
You can change the view of the module object that is shown on the Display Module
Source display through the Select View display. The Select View display can be
accessed from the Display Module Source display by pressing F15 (Select View).
The Select View display is shown in Figure 22 on page 358. The current view is
listed at the top of the window, and the other views that are available are shown
below. Each module object in a program object can have a different set of views
available, depending on the debug options used to create it.
To select a view, type 1 (Select) next to the view you want to show.
After you select the view of the module object that you want to show, press Enter
and the selected view of the module object is shown in the Display Module Source
display.
When the program object stops, the Display Module Source display is shown. The
appropriate module object is shown with the source positioned at the line where the
breakpoint occurred. This line is highlighted. At this point, you can evaluate
variables, set more breakpoints, and run any of the debug commands.
You should know the following characteristics about breakpoints before using them:
v When a breakpoint is bypassed, for example with the GOTO statement, that
breakpoint isn’t processed.
v When a breakpoint is set on a statement, the breakpoint occurs before that
statement is processed.
v When a statement with a conditional breakpoint is reached, the conditional
expression associated with the breakpoint is evaluated before the statement is
processed.
v Breakpoint functions are specified through debug commands.
These functions include:
– Adding breakpoints to program objects
– Removing breakpoints from program objects
– Displaying breakpoint information
Repeat the previous steps for each unconditional breakpoint you want to set.
Note: If the line on which you want to set a breakpoint is not a runnable statement,
the breakpoint is set at the next runnable statement.
After the breakpoints are set, press F3 (Exit) to leave the Display Module Source
display. You can also use F21 (Command Line) from the Display Module Source
display to call the program from a command line.
Call the program object. When a breakpoint is reached, the program stops and the
Display Module Source display is shown again. At this point, you can evaluate
variables, set more breakpoints, and run any of the debug commands.
on the debug command line. Line-number is the line number in the currently
displayed view of the module object on which you want to set a breakpoint.
on the debug command line. Line-number is the line number in the currently
displayed view of the module object from which you want to remove a breakpoint.
If using the statement view, there is no line numbers displayed. To set unconditional
breakpoints in the statement view, type:
BREAK procedure-name/statement-number
One way you can set or remove conditional breakpoints is through the Work with
Module Breakpoints display. The Work with Module Breakpoints display can be
accessed from the Display Module Source display by pressing F13 (Work with
Module Breakpoints). The Work with Module Breakpoints display is shown in
Figure 23. To set a conditional breakpoint, type the following:
v 1 (Add) in the Opt field,
v the debugger line number where you want to set the breakpoint in the Line field,
v a conditional expression in the Condition field,
and press Enter. For example, to set a conditional breakpoint at debugger line 35,
as shown in Figure 23, type the following:
v 1 (Add) in the Opt field,
v 35 in the Line field,
v type &I=21 in the Condition field,
and press Enter.
| To remove a conditional breakpoint, type 4 (Clear) in the Opt field next to the
| breakpoint you want to remove, and press Enter. You can also remove
| unconditional breakpoints in this manner.
Repeat the previous steps for each conditional breakpoint you want to set or
remove.
Note: If the line on which you want to set a breakpoint is not a runnable statement,
the breakpoint is set at the next runnable statement.
After you specify all breakpoints that you want to set or remove, press F3 (Exit) to
return to the Display Module Source display.
Call the program object. When a statement with a conditional breakpoint is reached,
the conditional expression associated with the breakpoint is evaluated before the
statement is run. If the result is false, the program object continues to run. If the
result is true, the program object stops, and the Display Module Source display is
shown. At this point, you can evaluate variables, set more breakpoints, and run any
of the debug commands.
on the debug command line. Line-number is the line number in the currently
displayed view of the module object on which you want to set a breakpoint.
expression is the conditional expression that is evaluated when the breakpoint is
encountered. The relational operators supported for conditional breakpoints are <,
>, =, <=, >=, and <> (not equal).
on the debug command line. Line-number is number in the currently displayed view
of the module object from which you want to remove a breakpoint.
In the statement view, no line numbers are displayed. To set conditional breakpoints
in the statement view, type:
BREAK procedure-name/statement-name WHEN expression
If the resolved sort sequence table is *HEX, no sort sequence table is used.
Therefore, the source debugger uses the hexadecimal values of the characters to
determine the sort sequence. Otherwise, the specified sort sequence table is used
to assign weights to each byte before the comparison is made. Bytes between, and
including, shift-out/shift-in characters are not assigned weights.
Note: The name of the sort sequence table is saved during compilation. At debug
time, the source debugger uses the name saved from the compilation to
access the sort sequence table. If the sort sequence table specified at
compilation time resolves to something other than *HEX or *JOBRUN, it is
important the sort sequence table does not get altered before debugging is
started. If the table cannot be accessed because it is damaged or deleted,
the source debugger uses the *HEX sort sequence table.
Table 10. Non-numeric Conditional Breakpoint Expressions
Type Possibilities
Char-8
v Character variable compared to character variable
v Character variable compared to character literal 1
v Character literal 1
compared to character variable
v Character literal 1
compared to character literal 1
v Character literal 1
compared to hex literal 2
v Hex literal 2
compared to character variable 1
v Hex literal 2
compared to character literal 1
v Hex literal 2
compared to hex literal 2
v Graphic literal 3
compared to DBCS character variable
v Graphic literal 3
compared to Graphic literal 3
v Graphic literal 3
compared to hex literal 2
v Hex literal 2
compared to DBCS character variable
v Hex literal 2
compared to Graphic literal 3
:
1
Character literal is of the form ‘abc’.
2
Hexadecimal literal is of the form X‘hex digits’.
3
Graphic literal is of the form G‘<so>DBCS data<si>’. Shift-out is represented as
<so> and shift-in is represented as <si>.
The %SUBSTR built-in function allows you to substring a character string variable.
The first argument must be a string identifier, the second argument is the starting
position, and the third argument is the number of single byte or double byte
characters. Arguments are delimited by one or more spaces.
on the debug command line. The breakpoints are removed from all of the modules
bound to the program or service program.
Note: You cannot specify the number of statements to step through when you use
F10 (Step) or F22 (Step into). Pressing F10 (Step) or F22 (Step into)
performs a single step.
on the debug command line, the next five statements of your program object are
run, then the program object is stopped again and the Display Module Source
display is shown.
If you choose to step over the called program object, then the CALL statement and
the called program object are run as a single step. The called program object is run
to completion before the calling program object is stopped at the next step. Step
over is the default step mode.
If you choose to step into the called program object, then each statement in the
called program object is run as a single step. If the next step at which the running
program object is to stop falls within the called program object, the called program
object is halted at this point. The called program object is then shown in the Display
Module Source display if the called program object is compiled with debug data and
you have the correct authority to debug it.
Using F10(Step)
You can use F10 (Step) on the Display Module Source display to step over a called
program object in a debug session. If the next statement to be run is a CALL
statement to another program object, then pressing F10 (Step) will cause the called
program object to run to completion before the calling program object is stopped
again.
Note: The called program object must have debug data associated with it in order
for it to be shown in the Display Module Source display.
on the debug command line, the next five statements of the program object are run.
If the third statement is a CALL statement to another program object, then two
statements of the calling program object are run and the first three statements of
the called program object are run.
The scope of the variables used in the EVAL command is defined by using the
QUAL command. However, you do not need to specifically define the scope of the
variables contained in a CL module because they are all of global scope.
Figure 24. Displaying a Variable using F11 (Display variable). Using the EVAL Debug
Command
You can also use the EVAL debug command to determine the value of a variable.
To display the value of a variable using the EVAL debug command, type:
EVAL variable-name
on the debug command line. Variable-name is the name of the variable that you
want to display. The value of the variable is shown on the message line if the EVAL
debug command is entered from the Display Module Source display and the value
can be shown on a single line. If the value cannot be shown on a single line, it is
shown on the Evaluate Expression display.
For example, to display the value of the variable &DAYOFWK; on line 7 of the
module object shown in Figure 24, type:
EVAL &DAYOFWK
Result: %SUBSTR(&CHAR1 7 4) = ‘E ’
The %SUBSTR built-in function allows you to substring a character string variable.
The first argument must be a string identifier, the second argument is the starting
position, and the third argument is the number of single byte or double byte
characters. Arguments are delimited by one or more spaces.
Variable-name is the name of the variable that you want to display in hexadecimal
format. 'x' specifies that the variable is to be displayed in hexadecimal format and
number-of-bytes indicates the number of bytes displayed. If no length is specified
after the 'x', the size of the variable is used as the length. A minimum of 16 bytes is
Result:
00000 C1C2C340 40404040 4040C4C5 C6404040 ABC DEF
00010 40404040 00000000 00000000 00000000 ............
The scope of the variables used in the EVAL command is defined by using the
QUAL command. However, you do not need to specifically define the scope of the
variables contained in a CL module because they are all of global scope.
You can use the EVAL debug command to assign numeric, character, and
hexadecimal data to variables provided they match the definition of the variable.
on the debug command line. Variable-name is the name of the variable that you
want to change and value is an identifier or literal value that you want to assign to
variable-name. For example,
EVAL &COUNTER = 3.0
on the message line of the Display Module Source display. The result is preceded
by the variable-name and value you are changing.
When you assign values to a character variable, the following rules apply:
v If the length of the source expression is less than the length of the target
expression, the data is left justified in the target expression and the remaining
positions are filled with blanks.
v If the length of the source expression is greater than the length of the target
expression, the data is left justified in the target expression and truncated to the
length of the target expression.
The %SUBSTR built-in function allows you to substring a character string variable.
The first argument must be a string identifier, the second argument is the starting
position, and the third argument is the number of single byte or double byte
characters. Arguments are delimited by one or more spaces.
on the debug command line. shorthand-name is the name that you want to equate
with a variable, expression, or debug command, and definition is the variable,
expression, or debug command that you are equating with the name.
For example, to define a shorthand name called DC that displays the contents of a
variable called &COUNTER;, type:
EQUATE DC EVAL &COUNTER
on the debug command line. Now, each time DC is typed on the debug command
line, the command EVAL &COUNTER; is performed.
To see the names that have been defined with the EQUATE debug command for a
debug session, type:
DISPLAY EQUATE
on the debug command line. A list of the active names is shown on the Evaluate
Expression display.
The CCSID of the module can be found using the Display Module (DSPMOD) CL
command. If you need to work with CL Root Source View and the source file
CCSID is different from the module CCSID, you can take one of the following
actions:
v Ensure the CCSID of CL source is the same as the CCSID of the compile-time
job.
v Change the CCSID of the compile-time job to 65 535 and compile.
v Use the CL Listing View if the previous two options are not possible.
See the ILE Concepts book, Chapter 9, “Debugging Considerations” for more
information on NLS Restrictions for Debugging.
The following are the CL commands which can cause the breakpoint or step to be
temporarily removed:
Note: When the CL commands are operating on the program, you will receive error
message CPF7102 when you issue the BREAK or STEP command.
No special commands specifically for testing are contained in the program being
tested. The same program being tested can be run normally without changes. All
test commands are specified within the job the program is in, not as a permanent
part of the program being tested. With the testing commands, you interact with the
programs symbolically in the same terms as the high-level language (HLL) program
was written in. You refer to variables by their names and statements by their
numbers. (These are the numbers used in the program’s source list.) In addition,
the test functions are only applicable to the job they are set up in. The same
program can be used at the same time in another job without being affected by the
testing functions set up.
Debug Mode
To begin testing, your program must be put in debug mode. Debug mode is a
special environment in which the testing functions can be used in addition to the
normal system functions. Testing functions cannot be used outside debug mode. To
start debug mode, you must use the Start Debug (STRDBG) command. In addition
to placing your program in debug mode, the STRDBG command lets you specify
certain testing information such as the programs that are being debugged. Your
program remains in debug mode until an End Debug (ENDDBG) or Remove
Program (RMVPGM) command is encountered or your current routing step ends.
The following STRDBG command places the job in debug mode and adds program
CUS310 as the program to be debugged.
STRDBG PGM(CUS310)
| The option exists to use the ILE source debugger to debug OPM programs. To
| create OPM programs that contain source debug data, specify the
| OPTION(*SRCDBG) parameter on the Create CL Program (CRTCLPGM)
| command. The source debug data is actually part of the program object.
| To add OPM programs that get created containing source debug data to the ILE
| source debugger, use the Program (PGM) and OPM Source Level Debug
| (OPMSRC) parameters on the STRDBG command. To start a debug session with
| an OPM program created with source debug data, type:
| STRDBG PGM(*LIBL/MYOPMPGM) OPMSRC(*YES) DSPMODSRC(*YES)
| For more information on ILE source debugging , see “Chapter 10. Debugging ILE
| Programs” on page 349.
If you specified twenty (20) programs for debug mode (using either the STRDBG or
ADDPGM command or both commands) and you want to add more programs to the
debug job, you must remove some of the previously specified programs. Use the
Remove Program (RMVPGM) command. When debug mode ends, all programs are
automatically removed from debug mode.
When you start debug mode, you can specify that a program be a default program.
By specifying a default program, you can use any debug command that has the
PGM parameter without having to specify a program name each time a command is
used. This is helpful if you are only debugging one program. For example, in the
Add Breakpoint (ADDBKP) command, you would not specify a program name on
the PGM parameter because the default program is assumed to be the program the
breakpoint is being added to. The default program name must be specified in the
list of programs to be debugged (PGM parameter). If more than one program is
listed to be debugged, you can specify the default program on the DFTPGM
parameter. If you do not, the first program in the list on the PGM parameter on the
STRDBG command is assumed to be the default program.
The default program can be changed any time during testing by using either the
Change Debug (CHGDBG) or the ADDPGM command.
You can use this function with the library list. In the library list for your debug job,
you can place a test library before a production library. You should have copies of
the production files that might be updated by the program being debugged in the
test library. Then, when the program runs, it uses the files in the test library.
Therefore, production files cannot be unintentionally updated.
A call of a program is the allocation of automatic storage for the program and the
transfer of machine processing to the program. A series of calls is placed in a call
stack. When a program finishes processing or transfers control, it is removed from
the call stack. For more information about the call stack, see Chapter 3.
A program may be called a number of times while the first call is still in the call
stack. Each call of a program is a recursion level of the program.
When a call is ended (the program returns or transfers control), automatic storage
is returned to the system.
Notes:
1. CL programs can be recursive; that is, a CL program can call itself either
directly or indirectly through a program it has called.
2. Some high-level languages do not allow recursive program calls. Other
languages allow not only programs to be recursive, but also procedures within a
program to be recursive. (In this guide, the term recursion level refers to the
number of times the program has been called in the call stack. A procedure’s
recursion level is referred to explicitly as the procedure recursion level.)
3. All CL commands and displays make use of only the program qualified name
recursion level.
Program Activations
An activation of a program is the allocation of static storage for the program. An
activation is always ended when one of the following happens:
v The current routing step ends.
v The request that activated the program is canceled.
v The Reclaim Resources (RCLRSC) command is run such that the last (or only)
call of a program is ended.
An RPG/400 program is deactivated when the last record indicator (LR) is set on
before the program ends. If there is a return operation and LR is off, the program is
not deactivated.
You can try to isolate the source of the error by using the testing functions.
However, the original request in error is still stopped at the point where the error
occurred. To remove the request in error from the call stack, you must use the End
Request (ENDRQS) command or press F3 when the unmonitored message
breakpoint display is shown. You can let the usual function check processing
continue by pressing the Enter key when the unmonitored message breakpoint
display is shown. If you press F10 to call the command entry display, you must
press F3 to return to the unmonitored message breakpoint display.
Program calls are destroyed when a ENDRQS command is entered. (In the
previous diagram, the program call of PGMA is destroyed.)
Breakpoints
A breakpoint is a place in a program at which the system stops program processing
and gives control to you at a display station (interactive mode) or to a program
specified on the BKPPGM parameter in the Add Breakpoint (ADDBKP) command
(batch mode).
You can also specify the name of the program to which the breakpoint is to be
added. If you do not specify the name of the program that you want the breakpoint
added to, the breakpoint is added to the default program specified on the STRDBG,
CHGDBG, or ADDPGM command.
When you add a breakpoint to a program, you can also specify program variables
whose values or partial values you want to display when the breakpoint is reached.
These variables can be shown in character or hexadecimal format.
The result of different statements being mapped to the same instruction is that a
breakpoint being added may redefine a previous breakpoint that was added for a
different statement. When this occurs, a new breakpoint replaces the previously
added breakpoint, that is, the previous breakpoint is removed and the new
breakpoint is added. After this information is displayed, you can do any of the
following:
v End the most recent request by pressing F3.
v Continue program processing by pressing Enter.
v Go to the command entry display at the next request level by pressing F10. From
this display, you can:
– Enter any CL command that can be used in an interactive debug environment.
You may display or change the values of variables in your program, add or
remove programs from debug mode, or perform other debug commands.
– Continue processing the program by entering the Resume Breakpoint
(RSMBKP) command.
– Return to the breakpoint display by pressing F3.
– Return to the command entry display at the previous request level by entering
the End Request (ENDRQS) command.
For a batch job, a breakpoint program can be called when a breakpoint is reached.
You must create this breakpoint program to handle the breakpoint information. The
breakpoint information is passed to the breakpoint program. The breakpoint
program is another program such as a CL program that can contain the same
commands (requests for function) that you would have entered interactively for an
interactive job. For example, the program can display and change variables or add
and remove breakpoints. Any function valid in a batch job can be requested. When
the breakpoint program completes processing, the program being debugged
continues.
A message is recorded in the job log for every breakpoint for the debug job.
Variable . . . . . . . . . . . . . . . : &ARBAL
Type . . . . . . . . . . . . . . . . : PACKED
Length . . . . . . . . . . . . . . . : 5 2
'610.00'
The variable &ARBAL is shown. (Note that the value of &ARBAL will vary
depending on the parameter values passed to the program.) You can press F10 to
display the command entry display so that you could change the value of the
variable &ARBAL to alter your program’s processing. You use the Change Program
Variable (CHGPGMVAR) command to change the value of a variable.
Conditional Breakpoints
You may add a conditional breakpoint to a program that is being debugged. Use the
Add Breakpoint (ADDBKP) command to specify the statement and condition. If the
condition is met, the system stops the program processing at the specified
statement.
You may specify a skip value on the ADDBKP command. A skip value is a number
that indicates how many times a statement should be processed before the system
stops the program. For example, to stop a program at statement 1200 after the
statement has been processed 100 times, enter the following command:
ADDBKP STMT(1200) SKIP(100)
If you specify multiple statements when the SKIP parameter is specified, each
statement has a separate count. The following command causes your program to
stop on statement 150 or 200, but only after the statement has processed 400
times:
ADDBKP STMT(150 200) SKIP(400)
If statement 150 has processed 400 times but statement 200 has processed only
300 times, then the program does not stop on statement 200.
If a statement has not processed as many times as was specified on the SKIP
parameter, the Display Breakpoint (DSPBKP) command can be used to show how
many times the statement was processed. To reset the SKIP count for a statement
to zero, enter the breakpoint again for that statement.
You can specify a more general breakpoint condition on the ADDBKP command.
This expression uses a program variable, an operator, and another variable or
The SKIP and BKPCOND parameters can be used together to specify a complex
breakpoint condition. For example, to stop a program on statement 1000 after the
statement has been processed 50 times and only when the character string &STR
is TRUE, enter the following command:
ADDBKP STMT(1000) PGMVAR('&STR') SKIP(50)
BKPCOND(*PGMVAR1 *EQ 'TRUE ')
Traces
A trace is the process of recording the sequence in which the statements in a
program are processed. A trace differs from a breakpoint in that you are not given
control during the trace. The system records the traced statements that were
processed. However, the trace information is not automatically displayed when the
program completes processing. You must request the display of trace information
using the Display Trace Data (DSPTRCDTA) command. The display shows the
sequence in which the statements were processed and, if requested, the values of
the variables specified on the Add Trace (ADDTRC) command.
You can change the maximum and the default action any time during the debug job
using the Change Debug (CHGDBG) command. However, the change does not
affect traces that have already been recorded.
You can only specify a total of five statement ranges for a single program at any
one time, which is a total taken from all the Add Trace (ADDTRC) commands for
the program. In addition, only 10 variables can be specified for each statement
range.
When you specify CL variables, you must enclose the & and the variable name in
single apostrophes. For example:
ADDTRC PGMVAR('&IN01')
When you specify a statement range, the source statement number for the stop
statement is ordinarily larger than the number for the start statement. Tracing,
however, is performed with machine interface (MI) instructions, and some compilers
(notably RPG/400) generate programs in which the order of MI instructions is not
the same as the order of the source statements. Therefore, in some cases, the MI
number of the stop statement may not be larger than the MI number of the start
statement, and you will receive message CPF1982.
When you receive this message, you should do one of the following:
v Trace all statements in the program.
v Restrict a statement range to one specification.
v Use MI instruction numbers gotten from an intermediate representation of a
program (IRP) list of the program. (See “Debugging at the Machine Interface
Level” on page 390.)
The following Add Trace (ADDTRC) command adds a trace to the program
CUS310. CUS310 is the default program, so it does not have to be specified. The
The following displays result from this trace and are displayed using the Display
Trace Data (DSPTRCDTA) command. Note that column headers are not supplied
for all displays.
Display Trace Data
Statement/
Program Instruction Recursion level Sequence number
CUS310 900 1 1
Start position . . . . . . . . . . . . : 1
Length . . . . . . . . . . . . . . . . : *DCL
Format . . . . . . . . . . . . . . . . : *CHAR
Variable . . . . . . . . . . . . . . . : &TOTBAL
Type . . . . . . . . . . . . . . . . : PACKED
Length . . . . . . . . . . . . . . . : 5 2
' .00'
Statement/
Program Instruction Recursion level Sequence number
CUS310 1000 1 2
CUS310 1100 1 3 +
F3=Exit F12=Cancel
Start position . . . . . . . . . . . . : 1
Length . . . . . . . . . . . . . . . . : *DCL
Format . . . . . . . . . . . . . . . . : *CHAR
*Variable . . . . . . . . . . . . . . . : &TOTBAL
Type . . . . . . . . . . . . . . . . : PACKED
Length . . . . . . . . . . . . . . . : 5 2
' 1.00'
Statement/
Program Instruction Recursion level Sequence number
CUS310 1600 1 4
CUS310 1700 1 5
CUS310 2100 1 6
CUS310 2200 1 7
CUS310 2600 1 8 +
F3=Exit F12=Cancel
CUS310 2700 1 9
Start position . . . . . . . . . . . . : 1
Length . . . . . . . . . . . . . . . . : *DCL
Format . . . . . . . . . . . . . . . . : *CHAR
*Variable . . . . . . . . . . . . . . . : &TOTBAL
Type . . . . . . . . . . . . . . . . : PACKED
Length . . . . . . . . . . . . . . . : 5 2
' 2.00'
F3=Exit F12=Cancel
Instruction Stepping
You can step through the instructions of a program by using the STRDBG or
CHGDBG commands and setting the MAXTRC parameter to 1 and the TRCFULL
parameter to *STOPTRC. When you specify a trace range (ADDTRC command)
and the program processes an instruction within that range, a breakpoint display
with an error message appears. If you press Enter, another breakpoint display with
the same error message appears for the next instruction processed in the trace
range. When tracing is completed, the trace data contains a list of the instructions
traced. You can display this data by entering the Display Trace Data (DSPTRCDTA)
command.
You can use the STMT parameter on the RMVTRC command to specify:
v All HLL statements and/or machine instructions in the specified program are not
to be traced regardless of how the trace was defined by the ADDTRC command.
v The start and stop trace location of the HLL statements and/or system
instructions to be removed.
The RMVPGM and ENDDBG commands also remove traces, but they also remove
the program from debug mode.
Display Functions
In debug mode, you can display testing information that lets you review how you
have set up your debug job. You can display what programs are in debug mode
and what breakpoints and traces have been defined for those programs. In addition,
you can display the status of the programs in debug mode.
The following DSPPGMVAR command displays the variable ARBAL used in the
program CUS310. CUS310 is the default program, so it does not have to be
specified. The entire value is to be displayed in character format.
DSPPGMVAR PGMVAR('&ARBAL')
Program . . . . . . . . . . . . . . . . : CUS310
Recursion level . . . . . . . . . . . . : 1
Start position . . . . . . . . . . . . : 1
Format . . . . . . . . . . . . . . . . : *CHAR
Length . . . . . . . . . . . . . . . . : *DCL
Variable . . . . . . . . . . . . . . . : &ARBAL
Type . . . . . . . . . . . . . . . . : PACKED
Length . . . . . . . . . . . . . . . : 5 2
'610.00'
F3=Exit F12=Cancel
When changing the value of variables, you should be aware of whether the variable
is an automatic variable or a static variable. The difference between the two is in
the storage for the variables. For automatic variables, the storage is associated with
the call of the program. Every time a program is called, a new copy of the variable
is placed in automatic storage. A change to an automatic variable remains in effect
only for the program call the change was made in.
Note: In some languages, the definition of a call is made at the procedure level
and not just at the program level. For these languages, storage for automatic
variables is associated with the call of the procedure. Every time a procedure
is called, a new copy of the variable is gotten. A change to an automatic
variable remains in effect only while that procedure is called. Only the
automatic variables in the most recent procedure call can be changed. The
RCRLVL (recursion level) parameter on the commands applies only on a
program basis and not on a procedure basis.
For static variables, the storage is associated with the activation. Only one copy of
a static variable exists in storage no matter how many times a program is called. A
change to a static variable remains in effect for the duration of the activation.
When changing a variable that is an array, you must specify one element of the
array. Consequently, you must specify the subscript values for the array element
you want to change.
Note: You can use the Display Debug (DSPDBG) command to show the call
stack. However, unless the program is stopped for some reason, the
stack is correct only for an instant, and the program continues to run.
4. If you know a statement to be run, enter the Add Breakpoint (ADDBKP)
command to stop the job at the statement.
If you do not know what statements are being run, do the following:
a. Enter the Add Trace (ADDTRC) command.
b. After a short time, enter the Remove Trace (RMVTRC) command to stop
tracing the program.
c. Enter the Display Trace Data (DSPTRCDTA) command to show what
statements have processed. Use the trace data to determine which data
statements to process next (for example, statements inside a program loop).
d. Enter the Add Breakpoint (ADDBKP) command to stop the job at the
statement.
5. Enter the desired debug commands when the program is stopped at a
breakpoint.
When the job being debugged is stopped at a breakpoint, the display station is
locked.
The ODV and MI instruction numbers can be obtained from the IRP listing produced
by most high-level language compilers. Use the *LIST value of the GENOPT
parameter to produce the IRP listing at program creation time.
Note: When you debug at the machine interface level, only the characteristics that
are defined at the machine interface level are available; the HLL
characteristics that are normally passed to the test environment are not
available. These HLL characteristics may include: the variable type, number
of fractional digits, length, and array information. For example, a numeric
variable in your HLL program may be displayed without the correct decimal
alignment or possibly as a character string.
Security Considerations
To debug a program, you must have *CHANGE authority to that program. The
*CHANGE authority available by adopting another user’s profile is not considered
when determining whether a user has authority to debug a program. This prevents
users from accessing program data in debug mode by adopting another user’s
profile.
Note: When the CL commands are running on your program, you may not be able
to add breakpoints or add traces to the program. If you enter the Add
Breakpoint (ADDBKP) command or the Add Trace (ADDTRC) command
when any of the commands are running on your program, you will receive
error message CPF7102.
In the following example, the first TRFCTL is valid. The second TFRCTL command
is not valid because &B was not passed to this program. The third TFRCTL
command is not valid because a constant cannot be specified as an argument.
Passing Parameters
The TFRCTL command can be used to pass parameters to the program being
called in the same way the CALL command passes parameters, but with these
restrictions:
v The parameters passed must be CL variables.
v The CL variables passed by the transferring program must have been received
as parameters by that program.
v This command is valid only within OPM CL programs.
In the following example, PROGA calls PROGB and passes two variables, &A and
&B, to it. PROGB uses these two variables and another internally declared variable,
&C. When control is transferred to PROGC, only &A and &B can be passed to
PROGC. When PROGC finishes processing, control is returned to PROGA, where
these variables originated.
PROGA ┌────Ê PROGB
┌─────────────────────┐ │ ┌─────────────────────────┐
│ PGM │ │ │ PGM (&A &B) │
│ DCL &A │ │ │ DCL &A *DEC │
│ DCL &B │ │ │ DCL &B *DEC │
│ . │ │ │ DCL &C *DEC │
│ . │ │ │ CHGVAR &C (&A + &B) │
│ . │ │ │ CHGVAR &A (&A - 2) │
│ CALL PROGB (&A &B) ┼──┘ │ IF (&A = 3) GOTO LABEL │
│ . Í─────────────────┼──┐ │ TFRCTL PROGC (&A &B)─┐ │
│ . │ │ │ LABEL: RETURN │ │
│ . │ │ │ ENDPGM │ │
│ ENDPGM │ │ └──────────────────────┼──┘
└─────────────────────┘ │ ┌────────────────────────┘
│ └─Ê PROGC
│ ┌─────────────────────────┐
│ │ PGM (&A &B) │
│ │ DCL &A *DEC │
│ │ DCL &B *DEC │
│ │ CHGVAR &B (&B - &A) │
└────┼─RETURN │
│ ENDPGM │
└─────────────────────────┘
The secondary job log file contains the first and second level text for a message.
The text is in print format. Any message data is merged with the message
description and the result is formatted into one or more print lines. For each
message selected for processing there can be more than one record in the
secondary job log file; one record for each first and second level print line.
Records in the primary file can be related to records in the secondary file through
use of the Message Reference Key. Each record placed in the primary file contains
a field that is the Message Reference Key (MRK) of the related message. Similarly,
each secondary file record contains the MRK of the related message. The MRK for
a message is unique within the context of a job. Once the MRK of a primary file
record is known, the related secondary records can be readily identified since only
these secondary records will contain the same MRK value.
Field Length in
Order Field Name Data Type Bytes Field Description
1 QMHJDT DATE 10 Date job log created
2 QMHJTM TIME 8 Time job log created
3 QMHMRK CHAR 4 Message reference key
4 QMHTYP CHAR 10 Message type
5 QMHSEV BIN 4 Message severity
6 QMHMID CHAR 7 Message ID
7 QMHDAT DATE 10 Message sent date
8 QMHTIM TIME 8 Message sent time
9 QMHMF CHAR 20 Message file name
10 QMHRPY CHAR 4 Reply reference key
11 QMHRQS CHAR 1 Request Message Status
12 QMHSTY CHAR 1 Sending program type
13 QMHRTY CHAR 1 Receiving program type
14 QMHSSN BIN 4 Number of statements for sending
program
15 QMHRSN BIN 4 Number of statements for
receiving program
16 QMHCID BIN 4 CCSID of the message data or
immediate message
17 QMHPRL CHAR 1 Message percolated indicator
18 QMHSPR VAR CHAR 256 MAX Sending procedure name
The date the production of the job log began. The field is a date field in the
database record. The format of the date is *ISO. A value in this date field is in
the format yyyy-mm-dd. Each record produced for the same job log will have
the same value in this field.
QMHJTM
Time job log create; TIME(8)
The time the production of the job log began. This field is defined as a time field
in the database record. The format of the time is defined to be *ISO. A value in
this time field is in the format hh.mm.ss. Each record produced for the same job
log will have the same value in this field.
QMHMRK
Message reference key; CHAR(4)
The message reference key the related message had in the job message
queue. The records are placed in the primary database file in strictly ascending
sequence by message reference key. Within the set of records produced for a
single job log, this field is unique for each record and thus can be used as a
unique key for the record. If the records for two or more job logs are placed into
the same member, the key may no longer be unique.
QMHTYP
Message type; CHAR(10)
The message type of the related message. One of the following special values
will appear in this field:
*CMD Commands that are logged from the execution of a CL program.
The severity the message has. This is a value from 0 through 99.
QMHMID
Message ID; CHAR(7)
The message ID for the message. This field will contain the special value
*IMMED if the message is an immediate message which has no message ID.
QMHDAT
Message sent date; DATE(10)
The date the message was sent. This field is defined as a date field in the
database record. The format of the date is *ISO. A value in this field is in the
format yyyy-mm-dd.
QMHTIM
Message sent time; TIME(8)
The time the message was sent. The field is defined as a time field in the
database record. The format of the time is defined to be *ISO. A value in this
field is in the format hh.mm.ss.
QMHMF
Message File; CHAR(20)
The name of the message file that is to be used to obtain the message
description for the message. The first 10 characters of the field contain the
message file name. The second 10 characters contain the library name. If the
field QMHMID contains *IMMED to indicate an immediate message, this field
will contain all blanks.
QMHRPY
Reply reference key; CHAR(4)
v If the message type of the message is inquiry, notify, or sender’s copy, this is
the message reference key of the related reply message.
v If there is no reply message available this field will contain a null value
(’00000000’X).
An indicator with the following values that shows whether the sending program
was an OPM program or an ILE program.
v If this indicator is set to zero (’F0’X), the sending program is an OPM or
System Licensed Internal Code (SLIC) program with a name less than or
equal to 12 characters. The program name is placed in fields QMHSPG and
QMHLSP.
v If the indicator is set to one (’F1’X), the sending program is an ILE program
with a procedure name less than or equal to 256 characters. The procedure
name is placed in fields QMHSPR and QMHCSP.
v If the indicator is set to two (’F2’X), the sending program is an ILE program
with a procedure name greater than 256 characters and up to 4096
characters. The complete sending sending procedure name is in field
QMHCSP; field QMHSPR is blank.
v If the indicator is set to three (’F3’X), the sending program is a SLIC program
with a name greater than 12 characters and up to 256 characters. The
complete sending program name is in field QMHLSP; field QMHSPG is
blank.
QMHRTY
Receiving program type; CHAR(1)
An indicator with the following values that shows the type of the receiving
program:
v If this indicator is set to zero (’F0’X), the receiving program was an OPM
program. The program name is placed in field QMHRPG.
v If the indicator is set to one (’F1’X), the receiving program was an ILE
program with a procedure name less than or equal to 256 characters. The
procedure name is placed in fields QMHRPR and QMHCRP.
v If the indicator is set to two (’F2’X), the receiving program is an ILE program
with a procedure name greater than 256 and up to 4096 characters. The
entire receiving procedure name is placed field QMHCRP; the field QMHRPR
is blank.
QMHSSN
Number of statements for sending program; BIN(4)
The value provided in this field defines how many statement numbers are in the
field QMHSTM.
QMHRSN
Number of statements for receiving program; BIN(4)
The CCSID of the message data or immediate message that is contained in the
field QMHMDT.
QMHPRL
Message percolate indicator; CHAR(1)
An indicator that shows whether the message was percolated to the receiving
program or not.
v If the message was not percolated this field contains a zero (’F0’X).
v If the message was sent this field contains a one (’F1’X).
Message percolation can only occur within an ILE program. Therefore, this field
contains a one only if the receiving program type field QMHRTY contains a one
(’F1’X) or a two (’F2’X).
QMHSPR
Sending procedure name; VAR CHAR(*)
v If the sending program type field QMHSTY contains a zero (’F0’X) or three
(’F3’X), this field contains the value *N.
v If the sending program type field QMHSTY contains a one (’F1’X), this field
contains the sending ILE procedure name. The name can be a maximum of
256 characters in length.
v If the sending program type field QMHSTY contains a two (’F2’X), this filed
contains blanks, while the entire name will be contained in the field
QMHCSP.
This field can contain a nested procedure name for a sending program type of
one (’F1’X) or two (’F2’X); each procedure name is separated by a colon. The
outer-most procedure name is identified first and is followed by the procedures
contained in it. The inner-most procedures are identified last in the string.
QMHSMD
Sending module name; CHAR(10)
v If the sending program type field QMHSTY contains a zero (’F0’X) or a three
(’F3’X), this field contains the value *N.
The name of the library that the sending program was contained in.
QMHSTM
Statement number(s) for sending program; CHAR(30)
The statement number(s) at which the sending program sent the message.
Each statement number is 10 characters in length.
v If the sending program type field QMHSTY contains a zero (’F0’X) or a three
(’F3’X), there is, at most, one statement number in the first 10 characters.
That statement number represents an MI instruction number. The number is
a hexadecimal number.
v If the sending program type field contains a one (’F1’X) or a two (’F2’X), this
field can contain statement numbers of 0, 1, 2, or 3. The field QMHSSN
specifies how many there are. In this case, a statement number is a higher
level language statement number and not an MI instruction number. Each
number is a decimal number.
QMHRPR
Receiving procedure name; VAR CHAR(*)
v If the receiving program type field contains a zero (’F0’X), this field contains
the value *N.
v If the Receiving program type field QMHRTY contains a one (’F1’X), this field
contains the receiving ILE procedure name. The name can be a maximum of
256 characters in length.
v If the Receiving program type field QMHRTY contains a two (’F2’X), this field
contains blanks, while the entire name will be contained in the field
QMHCRP.
This field can contain a nested procedure name for a sending program type of 1
or 2; each procedure name is separated by a colon. The outer-most procedure
name is identified first and is followed by the procedures contained in it. The
inner-most procedures are identified last in the string.
QMHRMD
Receiving module name; CHAR(10)
v If the receiving program type field contains a zero (’0F’X), this field contains
the value *N.
v If the receiving program type field QMHRTY contains a one (’F1’X) or a two
(’F2’X), this field contains the receiving ILE module name.
QMHRPG
Receiving program name; CHAR(10)
The name of the library that the receiving program was in.
QMHRTM
Statement number(s) for receiving program; CHAR(30)
The statement number(s) at which the receiving program was stopped when the
message was sent. Each statement number is 10 characters in length.
v If the receiving program type field QMHRTY contains a zero (’F0’X), there is,
at most, one statement number in the first 10 characters. That statement
number represents an MI instruction number. The number is a hexadecimal
number.
For any other value of the receiving program type, there can be 0, 1, 2, or 3
statement numbers in this field. The field QMHRSN specifies how many there
are. In this case, a statement number is a higher level language statement
number and not an MI instruction number. Each number is a decimal number.
QMHSYS
System name; CHAR(8)
The name of the system that the job log was produced on.
QMHJOB
Qualified job Name; CHAR(26)
The fully qualified name of the job for which the message is being logged for.
The first 10 positions contain the job name, the next 10 positions the user
name, and the last six positions the job number.
QMHMDT
Message data; VAR CHAR(*)
If the field QMHMID contains the special value *IMMED, this field contains an
immediate message. Otherwise, this field contains the message data that was
used when the message was sent. This field can contain a maximum of 3000
characters. If the immediate message or message data is longer, it is truncated
to 3000 characters.
If the message data contains pointers, the pointers is invalidated before the
message data is written to the database file.
QMHCSP
Complete sending procedure name; CHAR(VAR)
v If the sending program type is zero (’F0’X) or three (’F3’X), this field contains
blanks.
v If the sending program type is one (’F1’X) or two (’F2’X), this field contains
the entire ILE procedure name. The name can be a maximum of 4096
characters in length.
This field can contain a nested procedure name where each procedure name
is separated by a colon. The outer-most procedure name is identified first
and is followed by the procedures contained in it. The inner-most procedures
are identified last in the string.
This field contains the entire sending program name from which the message
was sent for all sending program types. The name can be a maximum of 6144
characters in length.
| QMHTID
| Thread; CHAR(8)
| This field identifies the thread within the job that sent the message.
The IBM supplied model for the secondary job log file is QAMHJLSC in library
QSYS. The secondary record format name is QMHSFT. A detailed description of the
secondary record format follows:
Field Order Field Name Data Type Length in Bytes Field Description
| 1 QMHJDS DATE 10 Date job log created
2 QMHJTS TIME 8 Time job log created
3 QMHMKS CHAR 4 Message reference
key
7 QMHSYN CHAR 8 System name
8 QMHJBN CHAR 26 Qualified job name
4 QMHLNN BIN 4 Message line number
5 QMHSID BIN 4 CCSID of text line
6 QMHTTY CHAR 1 Message text indicator
9 QMHLIN CHAR 78 Message text line
The length of the field indicates the number of total bytes for the field.
The date the production of the job log began. The field is a date field in the database record. The
format of the date is *ISO. A value in this field is in the format yyyy-mm-dd. Each record produced for
the same job log will have the same value in this field.
QMHJTS
Time job log created; TIME(8);
The time the production of the job log began. This field is defined as a time field in the database
record. The format of the time is defined to be *ISO. A value in this field is in the format hh.mm.ss.
Each record produced for the same job log will have the same value in this field.
The message reference key the related message had in the job message queue. The records are
placed in the secondary database file in ascending sequence by message reference key. There can be
more than one secondary record for a specific message reference key. This field also exists in the
related primary record. Therefore, once the message reference key is obtained from a primary record,
it can be used to read the related records from the secondary file.
QMHSYN
System name; CHAR(8)
The name of the system that the job log was produced on.
QMHJBN
Qualified job Name; CHAR(26)
The fully qualified name of the job for which the message is being logged for. The first 10 positions
contain the job name, the next 10 positions the user name, and the last six positions the job number.
QMHLNN
Message line number; BIN(4)
The line number of the line within the text type. For both the first and second level text, the line
number starts at one for the first line of the text and is incremented by one for each additional line
within that level.
QMHSID
CCSID of message text line; BIN(4)
The CCSID of the message text line that is contained in field QMHLIN.
QMHTTY
Message text type; CHAR(1)
An indicator which specifies whether field QMHLIN contains a line of the first or second level text. This
field will contain one of the following values:
1 Field QMHLIN contains first level text.
2 Field QMHLIN contains second level text.
QMHLIN
Message text line: CHAR(78)
This field contains one line of the first or second level text.
IBM may have patents or pending patent applications covering subject matter
described in this document. The furnishing of this document does not give you any
license to these patents. You can send license inquiries, in writing, to:
IBM Director of Licensing
IBM Corporation
North Castle Drive
Armonk, NY 10504-1785
U.S.A.
For license inquiries regarding double-byte (DBCS) information, contact the IBM
Intellectual Property Department in your country or send inquiries, in writing, to:
IBM World Trade Asia Corporation
Licensing
2-31 Roppongi 3-chome, Minato-ku
Tokyo 106, Japan
The following paragraph does not apply to the United Kingdom or any other
country where such provisions are inconsistent with local law:
INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS
PUBLICATION “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A
PARTICULAR PURPOSE. Some states do not allow disclaimer of express or
implied warranties in certain transactions, therefore, this statement may not apply to
you.
Licensees of this program who wish to have information about it for the purpose of
enabling: (i) the exchange of information between independently created programs
and other programs (including this one) and (ii) the mutual use of the information
which has been exchanged, should contact:
IBM Corporation
Software Interoperability Coordinator
3605 Highway 52 N
Rochester, MN 55901-7829
U.S.A.
The licensed program described in this information and all licensed material
available for it are provided by IBM under terms of the IBM Customer Agreement,
IBM International Program License Agreement, or any equivalent agreement
between us.
Information concerning non-IBM products was obtained from the suppliers of those
products, their published announcements or other publicly available sources. IBM
has not tested those products and cannot confirm the accuracy of performance,
compatibility or any other claims related to non-IBM products. Questions on the
capabilities of non-IBM products should be addressed to the suppliers of those
products.
This information contains examples of data and reports used in daily business
operations. To illustrate them as completely as possible, the examples include the
names of individuals, companies, brands, and products. All of these names are
fictitious and any similarity to the names and addresses used by an actual business
enterprise is entirely coincidental.
COPYRIGHT LICENSE:
Each copy or any portion of these sample programs or any derivative work, must
include a copyright notice as follows:
© (your company name) (year). Portions of this code are derived from IBM Corp.
Sample Programs. © Copyright IBM Corp. _enter the year or years_. All rights
reserved.
If you are viewing this information softcopy, the photographs and color illustrations
may not appear.
Trademarks
The following terms are trademarks of International Business Machines Corporation
in the United States, or other countries, or both:
400
Application System/400
AS/400
AS/400e
C/400
COBOL/400
CT
GDDM
IBM
Integrated Language Environment
Operating System/400
OS/400
RPG/400
System/36
System/38
Other company, product, and service names may be trademarks or service marks
of others.
Index 413
command, CL 305, 17, 31, 33, 34, 36, 68, 156, command, CL 17, 17, 31, 33, 34, 36, 68, 156,
305mdit (continued) 305mdit (continued)
ADDLIBLE (Add Library List Entry) 305 CREATE PROGRAM 305
ADDMSGD (Add Message Description) Create Program (CRTPGM) 17
defining substitution variables 187 CREATE SERVICE PROGRAM 17
example 194 Create Service Program (CRTSRVPGM) 17
ADDPGM (Add Program) 374 creating
ADDTRC (Add Trace) 382 definition 284
attribute 328 process 328
CALL (Call Program) 65, 71 steps 283
Call Procedure (CALLPRC) 66 CRTCLMOD (Create Control Language Module) 17,
Call Program (CALL) 65, 71 56
calling CRTCMD (Create Command) 284, 328
description 78 CRTDTAARA (Create Data Area) 17, 92
CALLPRC (Call Procedure) 66, 78 CRTDUPOBJ (Create Duplicate Object) 131
Change Command (CHGCMD) 332 CRTLIB (Create Library) 109
Change Current Library (CHGCURLIB) 105 CRTMSGF (Create Message File) 183, 184
Change Data Area (CHGDTAARA) 17, 93 CRTMSGQ (Create Message Queue) 200
Change Debug (CHGDBG) 374 CVTDAT (Convert Date) 17, 50
Change Job (CHGJOB) 265 DCL (Declare CL Variable) 14, 17
Change Library List (CHGLIBL) 24, 105 DCLF (Declare File)
Change Message Description (CHGMSGD) 185, description 14
198 using 150
Change Message Queue (CHGMSGQ) 200, 203 variables 22
Change Program Variable (CHGPGMVAR) 387 Deallocate Object (DLCOBJ) 139
Change System Library List (CHGSYSLIBL) 105 Declare CL Variable (DCL) 14, 17
Change Variable (CHGVAR) 14, 27 Declare File (DCLF)
changing 332 description 14
changing program control command 17 using 150
Check Object (CHKOBJ) 17, 145 variables 22
CHGCMD (Change Command) 332 defined, authority needed 286
CHGCURLIB (Change Current Library) 105 defining
CHGDBG (Change Debug) 374 dependent relationship 315
CHGDTAARA (Change Data Area) 17, 93 description 283
CHGJOB (Change Job) 265 error encountered 331
CHGLIBL (Change Library List) 24, 105 example 341
CHGMSGD (Change Message Description) 185, instructions 287
198 list within list 308
CHGMSGQ (Change Message Queue) 200, 203 mixed list 305
CHGPGMVAR (Change Program Variable) 387 qualified name 312
CHGSYSLIBL (Change System Library List) 105 source list 329
CHGVAR (Change Variable) 14, 27 validity checking 340
CHKOBJ (Check Object) 17, 145 Delete Command (DLTMCD) 329
Clear Library (CLRLIB) 113 Delete Data Area (DLTDTAARA) 17
Clear Trace Data (CLRTRCDTA) 382, 383 Delete File (DLTF) 14
CLRLIB (Clear Library) 113 Delete Library (DLTLIB) 113
CLRTRCDTA (Clear Trace Data) 382, 383 Delete Program (DLTPGM) 17
CMD (Command) statement 287 Display Breakpoints (DSPBKP) 385
command processing program (CPP) 285 Display Command (DSPCMD) 331
Convert Date (CVTDAT) 17, 50 Display Data Area (DSPDTAARA) 17, 93
CREATE BOUND CONTROL LANGUAGE (Create Display Debug (DSPDBG) 385
Bound CL) 17 Display Job (DSPJOB) 140
Create Bound Control Language (CRTBNDCL) 17 Display Job Log (DSPJOBLOG) 272
Create Command (CRTCMD) 284, 328 Display Library (DSPLIB) 114
Create Control Language Module (CRTCLMOD) 17, Display Library Description (DSPLIBD) 115
56 Display Log (DSPLOG) 276
Create Data Area (CRTDTAARA) 17, 92 Display Message Descriptions (DSPMSGD) 185,
Create Duplicate Object (CRTDUPOBJ) 131 194
Create Library (CRTLIB) 109 Display Messages (DSPMSG) 200
Create Message File (CRTMSGF) 183, 184 Display Object Description (DSPOBJD)
Create Message Queue (CRTMSGQ) 200 common attributes 97
Index 415
command, CL 305, 17, 31, 33, 34, 36, 68, 156, command definition 315, 292, 300, 305, 312, 313,
305mdit (continued) 315, 329mdit (continued)
Send Reply (SNDRPY) 305, 234 statement
Send User Message (SNDUSRMSG) 17, 209 DEP 315
setting CL procedure limits command 17 description 283
SNDBRKMSG (Send Break Message) 207 ELEM 305
SNDF (Send File) 148, 157 error during processing 331
SNDMSG (Send Message) 207 QUAL 312
SNDPGMMSG (Send Program Message) 14, 208 usage 4
call stack entry 214 use of qualified name 312
SNDRCVF (Send/Receive File) 148, 152 valid parameter by parameter type 300
SNDRPY (Send Reply) 17, 234 Command Entry display 267
SNDUSRMSG (Send User Message) 17, 209 command processing procedure
specifying prompt override program writing REXX 339
when changing 325 command processing program (CPP)
when creating 325 definition 4
Start Debug (STRDBG) 374, 382 description 285
Start Programmer Menu (STRPGMMNU) 171 example 342
STRDBG (Start Debug) 374, 382 writing 337
STRPGMMNU (Start Programmer Menu) 171 command usage
TFRCTL (Transfer Control) 393, 394 printing 17
Transfer Control (TFRCTL) 393, 394 comment delimiter (/*) 30
used frequently in CL procedure 17 communicate
used in CL procedure 17 between procedure 89
using the prompter 168 using data area 89
Work with Object Locks (WRKOBJLCK) 140 compiler, CL
WRKOBJLCK (Work with Object Locks) 140 installing support for 64
command (CMD) parameter 17 compiler error 59
compiler list
Command (CMD) statement
CL procedure 57
defining 287 sample program 57
example 342 compiling
command default source programs 63
changing 334 completion message 183, 210
command definition 288, 292, 300, 305, 312, 313, compressing
315, 329, 331, 332, 341, 342, 343, 345 object 134
object table 134
data type parameter restriction 293
conditional breakpoint
defining
adding 380
simple list 300
example 362
displaying 331
removing 360
effect of changing 332
setting 360
example 313
conditional processing of command 30
creating a command to call an application
conditional prompting 317
program 341
configuration source
creating a command to display an output
queue 343 retrieving 17, 52
creating a command to substitute default configuration status
value 342 retrieving 17, 52
creating abbreviated commands 345 constant value
defining a parameter 292 defining for parameter 288
introduction 4 control
mixed list with 305 transferring
object 284 description 393
parameter combination, valid 300 use 394
processing control language (CL) 283
qualified name in a CL program 313 command
prompt text for parameter 288 definition 1
required parameter for 288 entering 1
return value for parameter 288 syntax 2
simple list with 300 menu
source list 329 using CL program to control 153
Index 417
database file 14 (continued) default handling 240
receiving data area 14 unmonitored, default handling 376
referring to output file 159 unmonitored message while testing 376
using as data queue 82 default program
date used in testing 374
conversion 17 default value
converting format 50 changing command 334
DBCS (double-byte character set) defining for parameter 292
defining message 194 message 191
designing application program 173 reply 191
sending message 191 default value table 292
using QCMDEXC with 163 defining
writing CL program with DBCS data 174 CL command table 283
DCL (Declare CL Variable) command 14, 17 command
DCLF (Declare File) command authority 286
CL procedure 14, 17 definition 283
declaring parameter 316
variable 150 statements 287
description 22 element in list
Deallocate Object (DLCOBJ) command 139 simple list 301
deallocating list for parameter 300
object 139 list within list 308
debug optional parameter 288
changing 374 parameter 288
command 350 prompt text for a parameter 288
displaying 385 qualified name 312
session required parameter 288
adding program object 353 restricted value for parameter 288
prepare program object 351 return value for parameter 288
removing program object 354 simple list 301
starting 382 substitution variable 187
debug command valid parameter 288
BREAK 361 definition object, command 284
CLEAR 361 definition statement, command 283
debugger delete authority 110
ILE source 349 Delete Command (DLTCMD) command 329
debugging 373 Delete Data Area (DLTDTAARA) command 17
batch job not started from job queue 388 Delete File (DLTF) command 14
batch job submitted to a job queue 387 Delete Library (DLTLIB) command 113
considerations for one job from another job 390 Delete Program (DLTPGM) command 17
from another job 387 deleting
ILE program 349 command 329
ILE source debugger commands 352 data area 17
interactive job 389 file 14
machine interface level 390 file member 346
running job 389 HLL programs 346
starting 374 library 113
starting ILE source debugger 352 object 136
testing applications 373 program 17
decimal length error 76 program object 346
Declare CL Variable (DCL) command 14, 17 QHST file 281
Declare File (DCLF) command source member 346
CL procedure 14, 17 DEP (Dependent) statement
declaring command definition 287
variable 24, 150 example 316
description 22 use 315
declaring detailed message
CL variable 14 description 267
decompressing detecting unused object on system 122
object 134 diagnostic message 183, 210
default delivery of message 201 display 379
Index 419
Element (ELEM) statement example (continued)
command definition 287 changing (continued)
example 305, 308 message 139
use 305 variable value 27
ELSE (Else) command 17, 34 CL procedure
embedded IF (If) command 36 control processing 21
end, abnormal 176 simple 15
End Do (ENDDO) command 17, 33 typical 13, 19
End Program (ENDPGM) command CL program
CL procedure 14, 17 processing qualified name 313
example 166 command processing program 342
End Receive (ENDRCV) command compiler list 57
multiple device display files 156, 157, 158 conditional breakpoint 362
End Request (ENDRQS) command 376 controlling menu 153
ENDDO (End Do) command 17, 33 converting system value 50
ending creating
program 14, 17 CL procedure 16
receive 156, 157, 158 command 286, 341, 343
request 376 command to call application program 341
ENDPGM (End Program) command command to display output queue 343
CL procedure 14, 17 command to substitute default value 342
example 166 creating abbreviated commands 345
ENDRCV (End Receive) command CRTMSGF (Create Message File) command 184
multiple device display files 156, 157, 158 data queue 84
ENDRQS (End Request) command 376 DBCS data in CL programs 174
entry DDS
batch 13 display file 150
interactive 13 declaring display file 150
error defining
calling program 74 parameter 293, 341
character length 77 prompt text for command name 341
command definition statement 331 deleting QHST file 281
compiler 59 describing
data type 74 message 194
decimal length 76 display character variable 367
precision 76 display decimal variable 367
procedure 74 display file 150
display logical variable 367
escape message
displaying variables in hexadecimal format 367
CPF2469 196
DO command 33
definition 183
ENDDO command 33
monitoring 235
GOTO command 31
sending 211
IF (If) command 31
example
initial program 106
*BCAT value 212
logging message in job log 267
adding
logical expression 37
breakpoint to program 378
message 194
trace to program 381
message handling program 202
ADDMSGD (Add Message Description)
monitoring
command 194
message for specific command 237
attribute of variable 370
message within procedures 239
BIN function 41
moving object 130
binary function 41
nested Do group 34
break-handling program 243
object
CALL command 65
qualified name 6
CALLPRC command 66
overriding message file 197
change variable
passing
character 369
control to procedure 66
decimal 369
control to program 65
logical 368
parameter 74
changing
lock state 139
Index 421
format of date initializing
converting 50 library list 105
frequently-used objects input field length 292
description 136
inquiry message 181, 209
function
CL commands 17 installing
testing CL compiler support 64
description 9 instruction, stepping 384
Integrated Language Environment (ILE) model
message queue
G call stack entry 204
general purpose library (QGPL) 114 notify message 211
generic name procedure
description 107 receiving 271
Get Current Local Time (CEELOCT) 51 sending 271
GOTO (Go To) command 17, 31
Integrated Language Environment (ILE) procedure
call stack entry message queue 204
H receiving 271
sending 271
handling
default 240 interactive
help information 285 entry 13
help panel group job
online help information 285 debugging another 389
high-level language (HLL) program 164 job log
mixed list 306 consideration 274
QCMDEXC program 161
history log (QHST)
description 275 J
format 278 job
format table 278 batch
version 275 testing functions 373
HLL (high-level language) program changing 265
mixed list 306 displaying 140
QCMDEXC program 161 interactive
hold delivery of message 201 testing functions 373
submitting 176
job attribute
I retrieving 17, 53
IF (If) command 17
If (IF) command job log
CL procedure 17 consideration for interactive 274
IF (If) command description 265
description 17 directing 395
embedded 36 displaying 272
example 31 model for primary 395
using %SWITCH with 46 output file 395
ILE (Integrated Language Environment) model preventing production of 273
CL program suggestions when using 273
debugging 349 job message queue 200, 203
message queue job queue
call stack entry 204
debugging batch job not started from 388
notify message 211
debugging batch job submitted to 387
procedure
receiving 271
sending 271
source debugger 349
K
starting source debugger 352 key parameter
immediate message 181 defining 288
impromptu message 7 identifying 321
informational message 181, 209 using 320
Index 423
message 184, 275 (continued) message 17, 275 (continued)
assigning message identifier 184 removing
assigning severity code 186 CL procedure 17
break delivery 200 from message queue 234
break-handling program 202 reply 183
changing delivery mode 203 request 183, 229
completion 183 retrieving
default handling while testing 376 CL procedure 17
default value 191 from CL procedure 233
defining in CL procedure 233
description 186 sample program to receive from QSYSMSG 260
help 186 sending 181, 207
substitution variable 187 sending from CL program 208
definition 7 sending to system user 207
delivery 200 sent to QSYSMSG message queue
describing predefined 184 CPD4070 245
description CPF0907 245
definition 8 CPF1269 246
diagnostic 183 CPF1393 246
displaying CPF1397 246
break delivery 200 CPF210C 246
command options 181 CPF2182 246
double-byte CPF510E 247
defining 194 CPF5167 247
escape CPF5244 247
definition 183 CPF5248 247
description 235 CPF5250 247
purpose 210 CPF5251 247
example CPF5257 248
changing 211 CPF5260 248
sending 211 CPF5274 248
file CPF5341 248
IBM-supplied 181 CPF5342 249
filtering CPF5344 249
description 267 CPF5346 249
handling 181 CPF5355 249
IBM-supplied message file 181 CPF8AC4 245
immediate 7, 181 CPF9E7C 245
informational 181, 209 CPI0948 249
inquiry 181, 209 CPI0949 250
job message queue 203 CPI0950 250
logging in history log 265 CPI0953 250
logging on job log 265 CPI0954 250
monitoring CPI0955 250
description 235 CPI0964 250
example 17 CPI0965 250
numeric subtype code 186 CPI0966 250
use 47 CPI0970 250
notify 183, 241 CPI0988 250
online help information 186 CPI0989 251
overriding message file 195 CPI0998 251
parameters 47 CPI0999 251
predefined CPI099C 251
description 7 CPI099D 252
IBM-supplied file 181 CPI099E 252
message queue 181 CPI1117 251
QHST (history log) file 279 CPI1136 254
queue 8 CPI1138 254
receiving CPI1139 254
CL procedure 17, 228 CPI1153 254
CL program 228 CPI1154 254
Index 425
module object (continued)
description 1 CL procedure
module attribute working with 143
displaying 61 command definition 284
module object common attribute 97
changing view 356, 357 common function table 98
Monitor Message (MONMSG) command compressing
in CL procedure 235 restriction 134
use 47 table 134
monitoring use 134
message creating 131
in CL procedure 235 information 122
program level 237 providing description 116
specific command level 237 using variable 22
use 47 damage detection and notification 97
MONMSG (Monitor Message) command deallocating 139
in CL procedure 235 decompressing
use 47 after operating system installation 135
Move Object (MOVOBJ) command 128 restrictions 134
moving temporarily 135
object from one library to another 128 default auditing attribute 113
MOVOBJ (Move Object) command 128 default public authority 111
MRGMSGF (Merge Message File) command 183, 185 definition 4
deleting 136
describing 116
N description 97
National Language Sort Sequence (NLSS) 361 detecting unused 122
national language support 115 displaying in library 114
National Language Support 371 duplicate 131
national language version function performed on 97, 98
definition 115 generic name 107
nested Do group grouping 6
example 34 library 98
nesting lock enforcement 97
description 375 lock state 137
network attribute module
retrieving 52 changing 356
notify delivery of message 200 changing view 357
notify message moving
defining 183 restriction 129
monitoring 236, 241 moving between libraries 128
sending 211 moving from test library to production 175
number of naming 5
number of statement ranges for 382 placing in library 113
programs that can be debugged program
simultaneously 374 adding to debug session 353
statement ranges for trace 382 prepare for debug session 351
values in list 288 removing from debug session 354
numeric parameter value qualified name
replacing 26 description 6
variable replacing 17 example 6
referring to
in CL procedure 143
O object 143
renaming 132
object
renaming object
accessing
restriction 132
with library list 99
restriction
with qualified name 98
duplicating 131
allocating 137
saving specific 176
authority verification 97
searching for multiple 108
checking 17, 145
Index 427
Parameter (PARM) statement printing
example 293 command usage 17
use 288 procedure
parameter combination table 293 calling
parameter value description 66
list of CL 2
defining 300 control language (CL) introduction 2
mixed 305 description 1
simple 301 parts of CL
replacing 26 description 14
PARM (Parameter) command definition statement working with object 143
description 287 receiving message 228
example 342 procedure command
use 288 logging 56
PARM (Parameter) statement procedure control command 14
example 293 processing
use 288 using CL command 21
passing 289 within CL procedure 30
attribute information for a parameter 288 production library 109, 175
parameter value to CPP 289 program 337, 340
character value 289 activation 375
decimal value 289 adding 374
generic name 289 adding breakpoint to 377
list 300 adding trace to 381
logical value 289 break-handling 243
name 289 breakpoint 377
path name value 289 call 375
qualified name 312 calling
variable 289 CL procedure 17
type description 65
date (*DATE) 289 use 71
time (*TIME) 289 controlling program logic command 17
percolate 211 creating CL 56
performance default, in testing 374
benefit deleting 17
using TFRCTL command 393 description 2
consideration 82 dump 60
data queue advantage 82 ending 14, 17
message queue 82 number that can be debugged simultaneously 374
performing placing in debug mode 374
calculation program logic command 17
arithmetic 37 prompt override program 285
character 37 QCMDCHK 164
relational 37 QCMDEXC 167
PGM (Program) command 14, 17 removing 374
placing object in library 113 removing breakpoint from 381
PMTCTL (Prompt Control) command definition removing trace from 385
statement 287 service 2
precision error 76 variable
predefined message 7, 181 displaying 385
prepare writing command processing procedure 337
program object for debug session 351 writing command processing program 337
preventing writing prompt control 317
display of status message 242 writing prompt override 322
job log 273 writing validity checking 337, 340
production of job log 273 Program (PGM) command 14, 17
update to files while testing 374 program attribute
previous release displaying 61
compiling source programs for 63 program control command 14
install compiler support 64 program dump
Print Command Usage (PRTCMDUSG) command 17 obtaining 60
Index 429
QSYSMSG (continued) qualified name (continued)
CPI1168 245 defining 98
CPI1169 255 example of defining for command 344
CPI116A 253 passing to CPP 313, 315
CPI116B 253 processing in CL program 313
CPI116C 253 specifying 24
CPI1171 255 specifying with prompting 98
CPI2283 256 syntax for 98
CPI2284 256 using CL or HLL 313
CPI8898 256 using REXX 315
CPI8A13 256 Qualifier (QUAL) statement
CPI8A14 256 definition 287
CPI9014 256 qualifier (QUAL) statement
CPI9490 256 example 312
CPI94A0 256 Qualifier (QUAL) statement
CPI94CE 257 example 344
CPI94CF 257 use 312
CPI94FC 257 queue
CPI96C0 257 changing message queue delivery type 203
CPI96C1 257 external message (*EXT) 203
CPI96C2 257 job message queue 203
CPI96C3 257 message 8, 199
CPI96C4 257 QSYSMSG 245
CPI96C5 257 receiving message from 228
CPI96C6 257 removing message from 234
CPI96C7 258
CPP0DD9 257
CPP0DDA 258
CPP0DDB 258
R
CPP0DDC 258 RCLRSC (Reclaim Resources) command 375
CPP0DDD 258 RCVF (Receive File) command 148, 157
CPP0DDE 258 RCVMSG (Receive Message) command 228, 229
CPP0DDF 258 read authority 110
CPP29B0 258 receive
CPP29B8 258 ending 156, 157, 158
CPP29B9 259 Receive File (RCVF) command 148, 157
CPP29BA 259 Receive Message (RCVMSG) command 228, 229
CPP951B 259 receiving
CPP9522 259 database file 17, 148
CPP955E 259 display data 148
CPP9575 259 file
CPP9576 259 example 152, 157
CPP9589 259 message
CPP9616 259 function 17
CPP9617 259 in CL procedure 228
CPP9618 259 in CL program 228
CPP961F 260 information placement 229
CPP9620 260 user reply 17
CPP9621 260 Reclaim Resources (RCLRSC) command 375
CPP9622 260 reclaiming
CPP9623 260 resources 375
CPP962B 260 recovery
definition 245 after abnormal system end 176
sample program 245 reference key
QSYSOPR message queue 200 message 228
QUAL (Qualifier) statement relational expression 37
definition 287 relationship
example 312, 344 PARM statement and DCL command 338
use 312 part of command definition 338
qualified name remote data areas
accessing object 98 remote data areas 91
Index 431
RTVCFGSRC (Retrieve Configuration Source) Send File (SNDF) command (continued)
command 17, 52 function 157
RTVCFGSTS (Retrieve Configuration Status) Send Message (SNDMSG) command 207
command 17, 52 Send Message (SNDMSG) display 164
RTVDTAARA (Retrieve Data Area) command 17, 93 Send Program Message (SNDPGMMSG) command
RTVJOBA (Retrieve Job Attributes) command 17, 52 CL procedure 14, 17
RTVLIBD (Retrieve Library Description) command 115 use 208
RTVMBRD (Retrieve Member Description) Send/Receive File (SNDRCVF) command
command 17, 55 CL procedure 17
RTVMSG (Retrieve Message) command 17, 233 function 148
RTVNETA (Retrieve Network Attributes) command 52 use 152
RTVOBJD (Retrieve Object Description) command 54, Send Reply (SNDRPY) command 17, 234
120 Send User Message (SNDUSRMSG) command 17,
RTVSYSVAL (Retrieve System Value) command 17, 209
49
sending
RTVUSRPRF (Retrieve User Profile) command 17, 54
break message 207
run time
data to display 148
allowing user changes to CL commands 166
display file 17, 148
file
data 152
S example 157
sample program to receive message from message 207, 211
QSYSMSG 260 message to system user 207
searching program message 14, 208
for object 107 reply 17, 234
securing user message 17, 209
object 110 service program 2
security session
for object 111
debug
see=’breakpoint’.debug mode 374, 385, 390
adding program object 353
see=’breakpoint’.trace 382, 383
removing program object 354
description 381
setting
removing from a program 385
breakpoint 358
removing information from system 384
severity code 186
see=’breakpoint program’.breakpointdisplaying 385
using breakpoint within trace 384 shared-for-read (*SHRRD) lock state 137
see=’breakpoint program’.breakpoint 378, 379, 381 shared-for-update (*SHRUPD) lock state 137
adding to program 377 shared-no-update (*SHRNUP) lock state 137
using within trace 384 simple list
see=’member’.database file parameter value
preventing, update in production library 374 defining 301
see=’message queue’.message 376 description 301
see=’object’.data area 89, 90, 91, 92 passing to CPP 301
see=’testing’.debug mode 385, 390 using CL or HLL for 302
adding program 374 using REXX for 304
placing program 374 skip value
see=’trace’.breakpoint 377, 378, 379, 384 definition 380
displaying location 385 SNDBRKMSG (Send Break Message) command 207
removing from program 381 SNDF (Send File) command
see=’trace’.debug mode 374 canceling request for input 157
security consideration 390 CL procedure 17
see=’user profile’.security function 148
debugging consideration 390 SNDMSG (Send Message) command 207
selective prompting SNDPGMMSG (Send Program Message) command
character description table 170 CL procedure 14, 17
character table 169 use 208
description 168 SNDRCVF (Send/Receive File) command
Send Break Message (SNDBRKMSG) command 207 CL procedure 17
Send File (SNDF) command function 148
canceling request for input 157 use 152
CL procedure 17 SNDRPY (Send Reply) command 17, 234
Index 433
user message (continued) writing (continued)
inquiry 17 REXX command processing procedure 29
user profile attribute WRKOBJLCK (Work with Object Locks) command 140
retrieving 17, 54
using
listing view 352
QCMDCHK program 164
root source view 351
statement view 352
V
validity checking
program 284
reply 189
writing 340
value
parameter 316
variable
changing
CL procedure 14, 17
example 27, 213
value in program 387
value of 27, 368
creating object 22
declaring
description 24
for field 150
for file 150
definition 22
displaying 366
displaying value in program 385
equating a name 370
indicator declared as variable 149
lowercase character in 25
replacing parameter value 26
retrieving system value 49
specifying list 24
specifying qualified name 24
substitution 187
value used as 49
working with 22
view
program source 356
W
WAIT (Wait) command 17
Wait (WAIT) command 17
WAIT (Wait) command 156
Wait (WAIT) command 156
WAIT (Wait) command 156
work station message queue 200
Work with Object Locks (WRKOBJLCK) command 140
working with
messages 207
object locks 140
working with message 17
writing
comment in CL procedure 29
request-processing procedure 231
AS/400e
CL Programming
Version 4
Overall, how satisfied are you with the information in this book?
How satisfied are you that the information in this book is:
When you send comments to IBM, you grant IBM a nonexclusive right to use or distribute your comments in any way
it believes appropriate without incurring any obligation to you.
Name Address
Company or Organization
Phone No.
___________________________________________________________________________________________________
Readers’ Comments — We’d Like to Hear from You Cut or Fold
SC41-5721-02 IBMR Along Line
_ _ _ _ _ _ _Fold
_ _ _ and
_ _ _Tape
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _Please
_ _ _ _ do
_ _ not
_ _ _staple
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _Fold
_ _ _and
_ _ Tape
______
NO POSTAGE
NECESSARY
IF MAILED IN THE
UNITED STATES
IBM CORPORATION
ATTN DEPT 542 IDCLERK
3605 HWY 52 N
ROCHESTER MN 55901-7829
________________________________________________________________________________________
Fold and Tape Please do not staple Fold and Tape
Cut or Fold
SC41-5721-02 Along Line
IBMR
SC41-5721-02
Spine information: