The Execute Source command is designed for those cases where objects
must be created from source and one or more of the following exists:
** PDM cannot be used without prompting for the CRT command.
Most of the CRTxxxPGM commands only require the program name.
Other parameters (e.g. source file) can be defaulted or
filled in by PDM. Although other optional parameters exist
(e.g. LOG on CRTCLPGM), they are normally not used.
However, a command like CRTCMD requires the PGM parameter and
PDM cannot provide a default for the value. In addition,
there are many optional parameters on CRTCMD and they are more
likely to be specified.
ILE supports several new object types and CRT commands. Many
of the ILE commands will be like CRTCMD. Not only are there
parameters that PDM cannot fill in, but there are also
optional parameters that you will probably want to specify
frequently.
You'll receive a command prompt if you try to use an ILE
command that PDM cannot supply a value for or you can prompt
yourself.
Anytime you need to re-create an object, this can become very
tedious and error prone.
** Additional commands besides the CRT command are needed to
tailor the object such as CHGPGM.
As object creation becomes more complex, you will often have
the need to precede or follow a create command with other
commands related to the object.
This can also become very tedious and error prone if the
object must be re-created.
** The same object needs to be created in a different library or
from test source etc.
If you have some form of complex object creation, what do you
do when you need a test version in a separate library or when
you want to create using test source? Often, the same basic
create steps need to be run, but with slight variations.
The EXCSRC command allows you to place the CRT commands and any
associated commands (e.g. CHGPGM) in a source file member and
execute the commands on a consistent basis. EXCSRC is not limited to
just CRT functions. You can use it for other situations as well, but
it does have its limitations as will be discussed later.
Simple usage
------------
EXCSRC executes commands from a source member based on a label.
Assume you enter the following source into a source member named
STDCRT in the QCLSRC file.
PGM1: CRTxxxPGM PGM(PGM1) ...
CHGPGM PGM(PGM1) ...
PGM2: CRTxxxPGM PGM(PGM2)
PGM3: CRTPGM PGM(PGM3) MODULE(...) ...
CPROBJ OBJ(PGM3) ...
DLTSPLF FILE(PGM3) SPLNBR(*LAST)
MOD1: CRTMOD MOD(MOD1) ...
To execute the commands associated with the label PGM1, you would
specify the EXCSRC command as follows:
EXCSRC LABEL(PGM1) SRCFILE(QCLSRC) SRCMBR(STDCRT)
You can have as many labels as needed in the source member. Each set
of commands for a label would represent a different object. You can
use EXCSRC to execute the commands for a specific label, a generic
label name, or execute the commands for all labels.
For example, you might specify:
EXCSRC LABEL(PGM*) SRCFILE(QCLSRC) SRCMBR(STDCRT)
to create all objects beginning with a label of PGM.
Note that you do not compile a program from the source that you enter
for the CRT commands. You just enter the CL commands into the member
and EXCSRC executes directly against the source.
The source file member that you use to store the source should be
specified as type CLP. This allows you to have the full range of
syntax checking and command prompting. Commands which can only be
executed within a CL program (e.g. MONMSG, RTVxxx, DCL, IF, CHGVAR,
etc.) cannot be used (no error will occur until you attempt to
execute the command).
Commands that you will typically want to enter are CRT, CHG, CPROBJ,
etc. In the example for PGM3, DLTSPLF is used. If the CRT command
is successful, you can delete the spooled file automatically with
this approach.
See the later section for how to make a PDM option for the EXCSRC
command.
OVR commands
------------
Because of the way EXCSRC operates, an OVR command must specify
OVRSCOPE(*JOB) in order for a subsequent command to use the override.
The following would be the correct approach to allow program PGM1 to
specify the simple file name of ABC.
STEP1: OVRDBF FILE(ABC) TOFILE(yyy/ABC) OVRSCOPE(*JOB)
CALL PGM(PGM1) ...
DLTOVR FILE(ABC) OVRSCOPE(*JOB)
Error handling
--------------
********************************************
* *
* Any escape messages received during *
* execution of the source by EXCSRC *
* will cause an error and all the *
* remaining commands for that label *
* will be bypassed. *
* *
********************************************
Because of this rule, you must be careful in the types of commands
that you specify with EXCSRC. In most standard create situations,
this is probably a good rule to follow. For example, if the compiler
does not create the object because of source errors, you probably
don't want to complete the remaining steps to tailor the object.
EXCSRC produces a spooled describing the commands that were executed,
the messages received, and any error conditions. The spooled file
acts as an audit trail of what occurred. You should find the spooled
file more useful than a job log in most cases.
EXCSRC supports a DLTSPLF parameter that defaults to retain the
spooled file. You can specify DLTSPLF(*YES) to delete the spooled
file if EXCSRC completes normally. The spooled file is always
retained if EXCSRC senses any error conditions.
There are two functions that will allow you to avoid typical escape
messages:
** STRCND/ENDCND (Start/End condition). These commands are part
of the EXCSRC tool and allow you to have a block of code that
is or is not executed based on whether an object (or member)
exists.
** TAA Tool DLTOBJ2. This allows a method of ensuring that an
object does not exist without the use of the MONMSG command.
See the later section.
Because the MONMSG function is not available, you must be careful in
what commands are used in the source member. In general, you should
avoid the use of EXCSRC if you need a good degree of error handling
capability. Write a CL program if you need more flexibility.
Conditional execution
---------------------
There are two special commands that are provided with EXCSRC to allow
a minimal amount of conditional execution. The STRCND (Start
Condition) command lets you identify an object and check for
existence. You can conditionally execute the following set of
commands based on whether the object is 'found' or 'not found'.
The STRCND command does not allow variables. You must use actual
names and an object type.
For example, you could specify:
PGM1: /* PGM1 create steps */
STRCND IF(*NOTFOUND) OBJ(ABC) OBJTYPE(*FILE)
CRTPF FILE(ABC) ...
ENDCND
CRTxxxPGM PGM(PGM1) ...
The STRCND IF parameter supports only *FOUND and *NOTFOUND. If the
condition is met, any commands that follow until the next ENDCND will
be executed. If the condition is not met, the group of commands
(bounded by STRCND/ENDCND) will be bypassed.
STRCND also supports a MBR parameter to allow you to check for the
existence or absence of a member. STRCND just executes the system
CHKOBJ command. Only the escape messages CPF9801 (No object found)
and CPF9815 (No member found) are valid conditions. Any other escape
messages from CHKOBJ will cause an error.
The STRCND/ENDCND commands must be properly paired in a manner
similar to DO/ENDDO. The STRCND/ENDCND commands can be prompted for,
but cannot be executed by the system. Only the EXCSRC command will
execute STRCND/ENDCND. An escape message will occur if you attempt
to execute STRCND/ENDCND outside of the EXCSRC environment.
For STRCND, the parameters OBJ, OBJTYPE, and MBR are just passed to
the system CHKOBJ command. Any object type valid on CHKOBJ can be
used.
You can specify a comment on STRCND, but it must follow the last
parameter (it cannot precede the command nor occur before the IF
parameter. For ENDCND, you can specify a comment, but it must be
after the command name.
Valid use of comments:
STRCND IF(*FOUND) OBJ(PGM1) OBJTYPE(*PGM) /* If found */
.
.
ENDCND /* If found */
Invalid because comments precede the special commands:
/* Check it */ STRCND IF(*FOUND) OBJ(PGM1) OBJTYPE(*PGM)
.
.
/* End the check */ ENDCND
Replacement values
------------------
EXCSRC also allows you to specify replacement values on the command.
For example, assume that you want to use the same create steps, but
want to be able to vary the library where the object is created in.
You could specify the source as:
PGM1: CRTxxxPGM PGM(&PRMOBJLIB/PGM1) ...
CHGPGM PGM(&PRMOBJLIB/PGM1) ...
For EXCSRC, you would specify:
EXCSRC LABEL(PGM1) ... PRMOBJLIB(TEST)
When EXCSRC executes the source, it would use the value TEST when it
executes a command where the &PRMOBJLIB value is found.
PRMOBJLIB is just one of the variables that can be used. Other
standard names are PRMSRCLIB and PRMSRCFIL. These are intended to be
used as replacement values when you want to vary the source library
and/or source file. Additional general parameters PRMVARNB1 -
PRMVARNB5 are also supported which can be used for any purpose.
The default for all of the replacement values is *NONE. If you had
used the default on EXCSRC and &PRMOBJLIB was found in a command to
be executed, an error would occur. You do not use DCL for the
replacement values. Each is assumed to be 10 characters long.
A variable name may not be used on STRCND.
Note that it is only an error if EXCSRC attempts to execute a
statement where a replacement value is *NONE. If you specify:
EXCSRC LABEL(PGM2) SRCFILE(xxx) SRCMBR(yyy)
and do not name any replacement values for PGM2, EXCSRC will ignore
any of the commands for the other labels which may require
replacement values.
Recursive use
-------------
When you create modules and multiple module programs, there may be a
good reason to want to specify the EXCSRC command within the source
being executed by EXCSRC. For example, you may have several steps
relative to creating a module that you do not want to replicate
multiple times in the same source.
If you specify EXCSRC within the same source, a failure will occur
because the RPG program TAASRDFR is already active and cannot be
called recursively.
A simple solution is to use the EXCSRC2 command which is provided as
part of the EXCSRC tool. EXCSRC2 is identical to EXCSRC, but uses
different objects. Therefore, you can make one level of recursive
use.
For example, assume your source is in the member EXCSRC in the file
SOURCE and looks like:
MOD1: /* Simple module */
CRTMODxxx MOD(MOD1) ...
CHGMOD MOD(MOD1) ...
PGM5: /* Multiple module program */
STRCND IF(*NOTFOUND) OBJ(MOD1) OBJTYPE(*MOD)
/* Instead of using CRTMODxxx which might have */
/* to be replicated in multiple places in */
/* this source, use EXCSRC2 */
EXCSRC2 LABEL(MOD1) SRCFILE(SOURCE)
ENDCND /* If found */
.
. /* Create other modules in a similar manner */
.
CRTPGM MODULE(MOD1 ...) ...
To create PGM5 you would specify:
EXCSRC2 LABEL(PGM5) SRCFILE(SOURCE)
If the MOD1 module does not exist, the EXCSRC2 command would be
executed which would read the same source member (using a different
ODP) and create the MOD1 object. Because EXCSRC2 uses different
objects than EXCSRC, no recursion error would occur.
It would be an error if the MOD1 label had specified the use of
either EXCSRC or EXCSRC2. There is only one level of recursion
supported with EXCSRC2.
Note that it does not matter where label MOD1 is specified within the
source member. It could be before or after the PGM5 label. The
EXCSRC2 command just reads the source until it finds the correct
label.
TAA Tool DLTOBJ2
----------------
The TAA Tool DLTOBJ2 supports an optional parameter to prevent the
CPF2105 escape message 'Object not found' from occurring.
Assume you wanted to ensure that the program ABC does not exist
before you create it. If you specify:
DLTPGM PGM(ABC)
and the program does not exist, you would receive the escape message
CPF2105. The CPF2105 message is sent for most of the DLT commands
when the object does not exist. If you received this escape message,
any remaining commands for the label would be bypassed.
You could have used STR/ENDCND such as:
STRCND IF(*FOUND) OBJ(ABC) OBJTYPE(*PGM)
DLTPGM PGM(ABC)
ENDCND
but you may prefer the DLTOBJ2 command.
The TAA Tool DLTOBJ2 is a generic delete command and supports a
parameter to allow you to avoid the escape message. You would
specify:
DLTOBJ2 OBJ(ABC) OBJTYPE(*PGM) IGNDLTERR(*YES)
DLTOBJ2 determines the type of object you want to delete and issues
the correct DLT command. If the object exists, it is deleted and the
completion message sent by DLTPGM is resent as a completion message.
If the object does not exist, the escape message sent by DLTPGM
(CPF2105) is resent as TAA9891 and specified as a diagnostic message.
Thus DLTOBJ2 provides a good audit trail of what happened and avoids
any escape messages.
Could you write a CL program to do the EXCSRC functions?
--------------------------------------------------------
Certainly, and you could use the full range of CL program statements
such as IF, CHGVAR, MONMSG, etc. The advantage of EXCSRC is that it
is already coded and provides for the typical kinds of things you
will want to use along with appropriate audit trail output.
EXCSRC Command parameters *CMD
-------------------------
LABEL The label identifying the commands to be executed.
A specific name, a generic name, or *ALL may be
specified. Normally, you will use the name of the
object you want to create as the label name.
If you have two identical label names, both sets of
source will be executed if you specify the name on
EXCSRC.
SRCFILE The qualified source file to be used. The source
file name defaults to QCLSRC. The library name
defaults to *LIBL. *CURLIB may also be specified.
SRCMBR The name of the source member containing the source
to be read by EXCSRC. The default is EXCSRC.
PRMOBJLIB A replacement value that will be used in place of
any &PRMOBJLIB values found in the source. You do
not do a DCL for &PRMOBJLIB. It is automatically
defined as *CHAR LEN(10). PRMOBJLIB is intended to
be used when you want the object library to be a
variable.
The default is *NONE. You cannot use the default
and attempt to execute a command that contains
&PRMOBJLIB.
PRMSRCLIB Like PRMOBJLIB, but intended to be used when you
want the source library to be a variable.
PRMSRCFIL Like PRMOBJLIB, but intended to be used when you
want the source file to be a variable.
PRMVARNB1-5 Five different parameters that are like PRMOBJLIB.
You may use them wherever you have a value that
should be replaced.
DLTSPLF A *YES/*NO value that determines if the spooled file
will be kept if EXCSRC completes successfully. The
default is *NO to always retain the spooled file as
an audit trail. If an error occurs, the spooled
file is always retained. The spooled file will have
a name of ALLLABELS or ONELABEL.
EXCSRC2 Command parameters *CMD
--------------------------
The EXCSRC2 command uses the identical parameters as the EXCSRC
command. Different internal objects are used to allow a single level
of recursive use.
STRCND Command parameters *CMD
-------------------------
See the previous comments about the restrictions for the STRCND
command.
IF The type of condition to be tested. You must enter
either *FOUND or *NOTFOUND. Based on the condition
being satisfied, the commands which follow STRCND
will be executed. The conditional execution ends
with an ENDCND command.
The OBJ, OBJTYPE, and MBR parameters are just passed
to the system CHKOBJ command.
OBJ The qualified object to be tested. The library
defaults to *LIBL. A specific library or *CURLIB
may be used.
Variable names may not be used.
OBJTYPE The object type to be tested. Any value found on
CHKOBJ may be used.
A variable name may not be used.
MBR The member within a data base file object to be
checked for. *NONE is the default. A specific name
or *FIRST may be specified for a data base file.
A variable name may not be used.
ENDCND Command *CMD
--------------
See the previous comments about the restrictions for the ENDCND
command.
There are no parameters for the command.
EXCSRC Use with PDM
-------------------
PDM provides for user defined options in addition to the standard
options (e.g. 2=Edit). You can enter a user defined option for the
EXCSRC command.
When a user option is specified, PDM will not prompt for
missing parameters.
Do the following if you are not familiar with how to create a PDM
option:
** You must first consider where you want to place the options.
The default is the QAUOOPT file in QGPL. You can see which
options file is being used by specifying F18 'Change defaults'
from the PDM 'Work' display.
** If you do not want to use the default, then you must create
your own file. A typical solution would be to use CRTDUPOBJ
to duplicate the existing QAUOOPT file in QGPL to a library of
your choice (use the same name of QAUOOPT). Then use the
'Change Defaults' display and modify the library for the
QAUOOPT file.
After you have selected which file to use, the PDM 'Work'
display should appear. You can use the F16 key for 'User
Options'. This will display the 'Work with User-Defined
Options' display and you will see the existing options. To
create a new option, specify F6.
A display will appear named 'Create User-Defined Options'.
You can enter a 2 character ID for the option. You may choose
any characters.
PDM has a syntax for how a User-Defined option should be
entered that allows variable names. The variable names (like
&N for member name) are entered with the option you create and
are then substituted by PDM when you execute the option.
Assume you will want to use a user defined option to do a SBMJOB of
the EXCSRC command for the member that you identify. Assume the
following:
** The letters XS (EXCSRC) will be used.
** The job name should be the member name.
** The JOBD on SBMJOB should be the default.
** The EXCSRC label name should be the member name.
** The source file that contains the EXCSRC source is the same as
the one you are currently using with PDM.
** The source member containing the commands is EXCSRC which is
the default for EXCSRC.
For the XS user defined option, you would enter:
SBMJOB JOB(&N) CMD(EXCSRC LABEL(&N) SRCFILE(&L/&F))
When you enter XS next to a member name and press Enter, a job would
be submitted with the EXCSRC command which would execute the commands
you had specified for the label.
Note that with this solution there is no prompt if the object already
exists. To achieve a prompt, you would have to create a user command
(e.g. SBMEXCSRC) and determine in the CPP if the object already
existed. You could then do the SBMJOB for the EXCSRC command.
Note that if you use the PDM approach, you could still have
replacement variables and specify them as constants. For example,
you might say:
SBMJOB JOB(&N) CMD(EXCSRC LABEL(&N) SRCFILE(&L/&F)
PRMOBJLIB(TEST)
In the source read by EXCSRC you would use the &PRMOBJLIB value
whenever you specified an object library. Then you could execute a
separate EXCSRC command when you wanted the object created in a
production library.
Restrictions
------------
See the previous restrictions discussed about how to enter the source
and the use of the STRCND/ENDCND commands.
Prerequisites
-------------
The following TAA Tools must be on your system:
CHKGENERC Check generic
CHKJOBCTL Check job control
FILEFDBCK File feedback
HLRMVMSG HLL Remove message
RPGSTSDS RPG Status data structure
SNDCOMPMSG Send completion message
SNDESCMSG Send escape message
SNDSTSMSG Send status message
Implementation
--------------
None, the tool is ready to use.
Objects used by the tool
------------------------
Object Type Attribute Src member Src file
------ ---- --------- ---------- ----------
EXCSRC *CMD TAASRDF QATTCMD
STRCND *CMD TAASRDF2 QATTCMD
ENDCND *CMD TAASRDF3 QATTCMD
EXCSRC2 *CMD TAASRDF4 QATTCMD
TAASRDFC *PGM CLP TAASRDFC QATTCL
TAASRDFC2 *PGM CLP TAASRDFC2 QATTCL
TAASRDFC3 *PGM CLP TAASRDFC3 QATTCL
TAASRDFC4 *PGM CLP TAASRDFC4 QATTCL
TAASRDFC9 *PGM CLP TAASRDFC9 QATTCL
TAASRDFR *PGM RPG TAASRDFR QATTRPG
TAASRDFR4 *PGM RPG TAASRDFR4 QATTRPG
Structure
---------
EXCSRC Cmd
TAASRDFC CL pgm
TAASRDFR RPG pgm
TAASRDFC9 CL pgm
STRCND Cmd
TAASRDFC2 CL pgm
ENDCND Cmd
TAASRDFC3 CL pgm
EXCSRC2 Cmd
TAASRDFC4 CL pgm
TAASRDFR4 RPG pgm
TAASRDFC9 CL pgm
The TAASRDFC2/TAASRDFC3 CPPs are simple CL programs that will send an
escape message if the commands are executed outside of the EXCSRC
environment.
The EXCSRC2 command is identical with EXCSRC, but allows a single
level of recursive use.
|