The Scan CLP IF tool is designed as an aid to assist in finding
potential year 2000 date problems.
Most potential year 2000 date problems will occur when two 6 position
date variables are compared for other than 'equal' or 'non-equal'
conditions. If you compare for an equal condition, the application
should work the same in the year 2000. However, a statement
comparing two date variables in YYMMDD format such as the following
will probably cause problems:
IF (&DATE1 *GT &DATE2) DO
The SCNCLPIF tool is designed to find these potential problems. It
scans for variables with a specified length that are used in an IF
command with *GT, *LT etc. *EQ/*NE type comparisons are excluded. A
specific member, generic members, or all members in a file of source
type CLP, CLLE, or CLMOD may be scanned. A spooled file of the
statements that match the criteria is produced.
A typical command would be:
SCNCLPIF MBR(xxx) SRCFILE(QCLSRC) VARLEN(6)
The command finds the IF commands in the source and determines if the
variables being compared are length 6. Any *EQ or *NE type of
comparisons are excluded. If it is a *CHAR or *DEC field that
matches the length specified, it is printed. *DEC type fields are
only considered if they have 0 decimals.
Library list implications
SCNCLPIF is directed at a source file. If an Externally described
file exists in the source, an attempt is made to obtain the variable
definitions by using the library list.
To gain the best benefit of the tool, you should ensure that the
library list includes the externally described files.
You can have a compound IF statement such as:
IF ((&FLDA *EQ &FLDB) *AND +
(&FLDC *GT &FLDD)) DO
IF (&FLDA *EQ &FLDB *AND +
&FLDC *GT &FLDD) DO
&FLDA and &FLDB are not considered because of the *EQ, but &FLDC and
&FLDD will still be checked for the length specified.
Complex forms of the IF command are supported such as:
IF ((&FLDA *EQ &FLDB *OR &FLDA *EQ FLDC) *AND +
(&FLDC *GT %SST(&FLDX 1 6)) DO
The operators such as ¬> or | are also supported.
You need to determine from the listing and looking at your source
whether the fields are date fields.
While SCNCLPIF is not a perfect solution for determining where your
year 2000 problems exist, it can be very effective in pinpointing the
code where you are most likely to have problems.
What is not found by SCNCLPIF
The length of literals is not considered by SCNCLPIF. However, as
long as a variable in the comparison matches the length specified,
SCNCLPIF will print the statement. For example, SCNCLPIF will find
DCL &DATE *CHAR LEN(6)
IF (&DATE *GT '010101') DO
The %SST (substring function) is not completely handled. The only
variable tested is the variable to be used in the substring operation
(not the start or length). It would be possible to have a 7
character date that is compared using a substring of 6 characters
that would not be found by SCNCLPIF.
For example, assume you make the following DCLs.
DCL &CYMD *CHAR LEN(7) /* CYYMMDD */
DCL &DATE *CHAR LEN(6)
The following IF would not be found:
IF (%SST(&CYMD 2 6) *GT '010101') DO
But, the following IF would be found because &DATE is declared as
IF (%SST(&CYMD 2 6) *GT &DATE) DO
Different forms of concatenation are not handled. For example, you
could generate a 6 character value within the IF command by
concatenating month, day, and year variables before making a
comparison such as:
DCL &MTH *CHAR LEN(2)
DCL &DAY *CHAR LEN(2)
DCL &YR *CHAR LEN(2)
IF (&MTH *CAT &DAY *CAT &YR *GT '010101') DO
This would not be found by SCNCLPIF. However, if you first
concatenated &MTH, &DAY, and &YR into a 6 character work variable and
compared the work variable or compared against a 6 character variable
instead of a literal, SCNCLPIF would find the statement.
The IF command allows the user to specify a very complex expression
involving arithmetic, built in functions, *ANDs, *ORs, sets of
parenthesis, etc. Most users do not take advantage of the complete
syntactical capability. It is not expected that SCNCLPIF will handle
every valid IF statement, but typical coding solutions are handled.
Other commands and functions
Only the IF command is tested for. Few CL commands other than IF
provide for direct comparisons of variables.
The following are exceptions:
** OPNQRYF command allows an expression in the QRYSLT parameter
which can compare dates. To check for this situation, you
could use the SCNSRC TAA Tool to determine all the source
statements where you have specified OPNQRYF.
OPNQRYF also supports the KEYFLD parameter where it is possible to
build an access path over a date field.
The SCNOPNQRYF tool will assist you in identifying all of the source
that uses OPNQRYF.
** An access path may be built over a date field in YYMMDD
format. This can cause problems although CL would normally
not be used to read such a file. The SCNACCPTH tool may be
used to assist in determining if any such key fields exist.
** CPYF supports INCCHAR which allows a relational operator of
*GT, *LT, etc. A scan for INCCHAR should be effective in
finding any use of this function.
** The FMTDTA command provides a sort capability that allows
selection based on *GT, *LT, etc. You can scan for the use of
FMTDTA or if you have all FMTDTA specifications in a specific
source file you could scan for the characters GT, LT, GE, and
** The SORTDB TAA Tool provides a front end to the FMTDTA
command. It supports the SEL1, SEL2, and SEL3 parameters
which allow *GT, *LT, etc. You could scan for the use of
** Other Query products may make date comparisons which cannot be
Command parameters *CMD
MBR The source member to be scanned. A single member, a
generic name, or the special value *ALL may be used.
If a generic name or *ALL is specified, the source
types checked are CLP, CLLE, and CLMOD. The other
types are bypassed.
SRCFILE The qualified file name of the file. The file name
defaults to QCLSRC. The library value defaults to
*LIBL. *CURLIB may also be used.
VARLEN The variable length to be tested. The default is 6.
Both *CHAR and *DEC type variables are tested for.
*DEC type variables are only tested if they have 0
decimals. The value must be between 1 and 256.
RQDEXTDSC Determines whether any externally described files
*NO is the default which means if an Externally
Described file exists, the field specifications are
used. If an Externally Described file does not
exist on the library list, no error occurs, but the
information about some of the fields may be missing.
If *YES is specified and an Externally Described
file is specified in the source, it must exist on
the library list or an error will occur.
DLTSPLF A *YES/*NO value that defaults to *NO. *NO retains
any spooled files created.
*YES may be specified to delete any spooled files
that have no CLP type members.
See the previous section on what is not found by SCNCLPIF.
The correct syntax of CL source must be used (the source must compile
into a program without serious errors).
One of the base tools used is RTVCLPVAR. It has restrictions
regarding its ability to determine the attributes of a variable.
The following TAA Tools must be on your system:
CHKGENERC Check generic
EDTVAR Edit variable
HLRMVMSG HLL Remove message
RTVMBRLST2 Retrieve member list 2
RTVCLPVAR Retrieve CLP variables
RTVSYSVAL3 Retrieve system value 3
SNDCOMPMSG Send completion message
SNDESCMSG Send escape message
SNDSTSMSG Send status message
None, the tool is ready to use.
Objects used by the tool
Object Type Attribute Src member Src file
------ ---- --------- ---------- ----------
SCNCLPIF *CMD TAACLQN QATTCMD
TAACLQNC *PGM CLP TAACLQNC QATTCL
TAACLQNC2 *PGM CLP TAACLQNC2 QATTCL
TAACLQNR *PGM RPG TAACLQNR QATTRPG