The CPYCL command allows you to copy in source from another member.
CPYCL acts somewhat as an 'include' or the RPG /COPY statement.
The normal solution when you have some standard source that you want
to copy into a CL program is to use the SEU copy function (F15). The
disadvantage to this is that when the standard source changes, you
have a lot or work to find all of the places where you have done the
copy, change the source of many members, and do the re-creates.
The advantage of CPYCL is that you can significantly reduce your
effort when the standard source must be changed.
CPYCL Function
--------------
The CPYCL function is not the same as an 'include' like the RPG /COPY
statement. In some ways it is actually better.
The major difference is that the CPYCL command is not part of the
CRTCLPGM function. Therefore, you must remember to use CPYCL before
creating the program.
Once you have used CPYCL, the standard source exists in your normal
source member. The standard source acts as normal source so if you
create the program, you get the desired results.
If the standard source is changed, there is a special companion
command (CRTCPYCL) which is described later that will do the work for
you of finding the places where you have used the standard source,
refreshing the source member, and re-creating the CL programs.
If you use a function like the RPG /COPY and your standard source
changes, you must determine all of the places you have used the
function and re-create the programs one at a time. CRTCPYCL provides
a better solution than this.
Special comment statements are used to describe what must be copied.
Assume you are entering source into MBR1 and want to copy the
contents of STDSRC1. In MBR1, you would enter the special STRCPYCL
comment at the location you wanted STDSRC1 copied.
Pos
1
CALL PGMA
/*STRCPYCL STDSRC1 */
CALL PGMB
After you end SEU, use CPYCL against the same member.
CPYCL SRCMBR(MBR1) FROMSRCF(xxxx)
CPYCL reads the MBR1 source and looks for the special statement.
When it is found, the source is extracted from STDSRC1 and copied
into the MBR1 source. The STRCPYCL comment is changed slightly and
an ENDCPYCL comment is added.
In the actual implementation, CPYCL command reads your source and
splits it to 3 different temporary members:
- PGM, DCL, and DCLF commands
- Program level MONMSG commands
- All others
When the special copy statement is found, the statements are read
from the specified member and are added to one of the appropriate 3
temporary members. When all statements have been copied and there
are no errors, the 3 temporary members are merged together and
written back to your source member. The source statements are always
renumbered 1.00, 2.00 etc. See the later discussion on writing to a
different member.
Thus you can have DCL statements and program level MONMSG statements
in your standard source and they will be copied to the correct place
in the final source. See the later discussion of how 'copied in' DCL
and MONMSG commands must appear.
The results in MBR1 would look like this:
Pos
1
CALL PGMA
/*STRCPYCL - FOLLOWS - STDSRC1 */
.
. The source from STDSRC1
.
/*ENDCPYCL */
CALL PGMB
The purpose of changing the STRCPYCL comment and adding the ENDCPYCL
comment allows you to see what was copied as standard source and to
provide a boundary for refreshing the standard source. If you run
CPYCL again, it will remove all of the standard source and copy in
the current contents of STDSRC1. You should not change any of the
standard source statements for this reason.
You can have as many STRCPYCL comments in one source member as
needed. Each time you use CPYCL, it will refresh the source from the
members you name on the STRCPYCL comments.
The STRCPYCL comment may not exist in the source being copied (No
nesting is allowed).
To assist you in specifying the STRCPYCL comment correctly, there is
a very rigid syntax of the STRCPYCL comment.
- It must begin in position 1
- The exact characters /*STRCPYCL must be used
- There must be one (and only one) blank before the member name
- There must be at least one blank after the member name
- There must be at least one blank after the optional file name
- Because STRCPYCL is a comment, it must end with a */
By default, CPYCL will look for your member name in the same source
file as the member named on CPYCL. You can optionally add a file
name or a qualified file name.
The three valid choices would look like:
Pos
1
/*STRCPYCL MBR1 */
/*STRCPYCL MBR1 QCLSRC */
/*STRCPYCL MBR1 LIB1/QCLSRC */
There must be at least one blank after the member name and after the
file name. There can be no other characters in the line other than
the ending */.
Invalid syntax:
Pos
1
1. /*STRCPYCL MBR1 */
2. /*STRCPYCL MBR1 */
3. /*STRCPYCL MBR1 QCLSRC*/
4. /*STRCPYCL MBR1 QCLSRC
5. /*STRCPYCL MBR1 LIB1/ */
6. /*STRCPYCL MBR1 LIB1/QCLSRC XXX */
Invalid reasons:
1. The /*STRCPYCL does not start in pos 1.
2. There is more than one space before MBR1.
3. There is no blank after the file name.
4. There is no ending */.
5. There is no file name.
6. There are other characters after the file name.
When CPYCL has copied the source into your program it adds the text
'- FOLLOWS -' right after the STRCPYCL text and retains your member
name (also library/file if specified). You should not make any
changes to the STRCPYCL or ENDCPYCL comments. They must exist 'as
is' in order for CPYCL to be used again on the same source.
If you want to delete all of the copied in source (and the ENDCPYCL
comment), you should change the STRCPYCL comment to look like the
version before CPYCL is used. For normal use, there is no reason to
do this. If the standard source changes, you just use CPYCL again
and it will refresh the source.
If you want to prevent the use of CPYCL, just remove the STRCPYCL and
ENDCPYCL comments. The copied in source is now part of your program.
CPYCL will ensure that if a FOLLOWS comment exists, that there must
be a matching ENDCPYCL statement.
You can have GOTO or just a label in your standard source as long as
the final source makes sense to the compiler.
You can have DCL, DCLF, and program level MONMSG commands in your
standard source to be copied. For example, your standard source
might looks like:
DCL &VAR1 *CHAR LEN(5)
DCL &VAR2 *CHAR LEN(10)
MONMSG MSGID(CPF0000) EXEC(GOTO ERROR)
CHGVAR &VAR1 &VAR2
CHKOBJ OBJ(XXX) OBJTYPE(*PGM)
MONMSG MSGID(CPF9801)
The program level MONMSG must appear before any executable statements
in your standard source. The MONMSG command for CPF0000 in this
example would be considered a program level MONMSG. It would be
merged into the source after any program level MONMSG commands found
in your normal source member.
When CPYCL is copying the DCL and MONMSG commands from your standard
source, it adds a special comment to the beginning of the statement
to designate that it is from a 'copied in' member. After CPYCL is
run, your source would appear as:
DCL ... /* From your normal source */
/*CPYCL*/ DCL &VAR1 *CHAR LEN(5)
/*CPYCL*/ DCL &VAR2 *CHAR LEN(10)
MONMSG ... /* From your normal source */
/*CPYCL*/ MONMSG MSGID(CPF0000) EXEC(GOTO ERROR)
The special /*CPYCL*/ statement is necessary to allow the previously
copied in DCLs and program level MONMSG commands to be removed the
next time CPYCL is run (if ever). This allows any changes in your
standard source (e.g. a deletion of a DCL statement) to be picked up
properly.
Because of the technique used, you cannot have any data in the first
ten positions of a 'copied in' DCL, DCLF, or program level MONMSG
command. If you do, an error will be sent and your original source
will remain as is.
Using a different To file
-------------------------
By default, CPYCL will write back to the same member in the same
file. You can name a different TOSRCF and write to a totally
different source file (The same member name is always used). If the
combination of the file and library names differ, you can also
specify DROPSTRCPY(*YES) which will cause the STRCPYCL and ENDCPYCL
comments to be dropped. The /*CPYCL*/ comments are also dropped.
The intent of this approach is to allow you to generate source as if
it appears not to use the CPYCL approach.
If you drop the STRCPYCL/ENDCPYCL comments, the CRTCPYCL command
cannot be used because it is dependent on their existence in order to
re-create the programs.
You cannot use DROPSTRCPY(*YES) when writing back to the same member
in the same file.
You should only use DROPSTRCPY when you have your own create process
that will generate all the programs from your source.
CRTCPYCL Function
-----------------
The CRTCPYCL command is the companion command to CPYCL. It is
intended to be used when you have changed the standard source. At
that point you want to find all of the programs that used the
standard source and get them re-created with the new standard source.
You can use CRTCPYCL for a single program, but the real power is to
use it against all programs in a library.
Assume the following:
** CPYCL was used to copy in some standard source for several
members.
** All of the programs are part of an application set that
resides in LIBX.
** The name of the standard source members are STDSRC1, STDSRC2,
and STDSRC3.
** A change needs to be made to the STDSRC1 source member. You
make the change.
** All of the programs in LIBX that use STDSRC1 should be
re-created.
The CRTCPYCL command makes it easy. All you say is:
CRTCPYCL PGM(LIBX/*ALL) STRCPYCL(STDSRC1)
CRTCPYCL does the following:
** Builds an outfile of all the program objects in the library.
** Finds the CLP types and uses the outfile information to
determine the source member that was used to create the
program.
** Ensures that the source member exists (see later discussion of
source archive) and that you have authorization to replace the
program.
** Searches the source looking for STRCPYCL comment and the
member you named (STDSRC1).
** If it finds a member with a match, it uses CPYCL to refresh
the source. The causes the new source for STDSRC1 to be
inserted in your member. If you have other STRCPYCL
statements in your source, they will also be refreshed. CPYCL
always refreshes everything.
If the standard source name you specified does not exist
within the source, CPYCL is not used. You can specify that
*ANY standard source be refreshed in which case if any
STRCPYCL comments exist, CPYCL will be used.
** The TAA Tool RPLPGM is used to replace the program. RPLPGM
captures the attributes of the program (e.g. LOGCL and
ALWRTVSRC) and uses them on the CRTCLPGM command.
REPLACE(*YES) is specified so the old version of the program
is moved to QRPLOBJ. Any security information (USRPRF
parameter, authorizations, USEADPAUT function) remain the
same. If the program was optimized or had its observability
removed by the CHGPGM command, those functions are done to the
new program.
** If DLTSPLF(*YES) is specified (it is the default), the
compiler spooled files for successfully created programs are
deleted.
** A printed listing occurs which includes both the CLP programs
that did not use the STDSRC1 member and those that did.
Totals are generated and any errors are listed.
The source for your programs must exist in the same library as was
used to initially create the program. There is an exception if the
source archive is used. See the later discussion.
If you used CRTDUPOBJ, the original source information is retained in
the new object. It is accessed and the duplicate program would be
re-created from the original source.
STRCPYCL does not adopt any authority. If you are not authorized to
*OBJEXIST for any program, an error will occur.
CPYCL Command parameters *CMD
------------------------
CPYCL must be used before you create the CL program. It will copy
the source from the members you have described with the special
STRCPYCL comment.
SRCMBR The name of your source member that contains the
STRCPYCL comment. One or more STRCPYCL comments may
exist.
FROMSRCF The qualified name of your From source file. The
file defaults to QCLSRC and the library defaults to
*LIBL. *CURLIB may also be used as the library
name.
CPYCOMMNTS Whether comments in the standard source should be
copied. *DROPSPC (Drop special) is the default
which copies all comments except the specially
defined comments (See the later section). *NO means
no comments are copied. *YES means that all source
and comments are copied.
TOSRCF The qualified name of the To source file. The
default is *SAME meaning that the same name as the
FROMSRCF parameter is used. If the library name is
blank, the same library as the FROMSRCF parameter is
used.
The TOSRCF parameter does not appear on the command
prompt unless you use F9 or F10.
DROPSTRCPY Whether to drop the STRCPYCL/ENDCPYCL statements in
the source. The default is *NO. *YES may only be
specified when the combination of the source file
and library names differ between the From and To
files (you are writing to a different source file).
Specifying *YES prevents the use of the CRTCPYCL
command. *YES also eliminates the special comment
/*CPYCL*/ placed on copied DCL or program level
MONMSG commands. See the previous discussion for
Using a different TO file.
The DROPSTRCPY parameter does not appear on the
command prompt unless you use F9 or F10.
CRTCPYCL Command parameters *CMD
---------------------------
PGM The qualified program name to be recreated. The
program must exist. The special value *ALL may be
entered. The library defaults to *LIBL. *CURLIB
may also be used.
STRCPYCL The name of the standard source member to be
searched for. The special value *ANY may be
specified. This means that if any CL source
contains the STRCPYCL comment, CPYCL will be invoked
and the program will be re-created.
CPYCOMMNTS This is the same value as the CPYCL command and is
just passed thru. See the CPYCL definition.
DLTSPLF A *YES/*NO value for whether the spooled files for
successfully created CL programs should be deleted.
The default is *YES. This cleans up the output
queue so that only those programs which have failed
to create will have spooled files. *NO causes all
spooled files to be retained.
SRCARCLIB The source archive library. The default is *NONE.
See the later discussion of the source archive.
Restrictions
------------
** The CPYCL command must be used before you create the CL
program. Unless you are changing the standard source, you
never need to consider CPYCL again for the same source member.
** If you change the standard source, you need to run CPYCL
again. The simplest solution is to use CRTCPYCL.
** The standard source being copied may not contain a STRCPYCL
comment (no nesting).
** CRTCPYCL requires that the source exist in the same file and
member that was used to originally create the object. There
is an exception if the source archive is used. See the later
discussion.
** If you specify DROPSTRCPY(*YES) on the CPYCL command, you
cannot use the CRTCPYCL command as it is dependent on the
STRCPYCL/ENDCPYCL comments being in the source.
Copying comments
----------------
The CPYCOMMNTS parameter lets you control how comments should be
handled in the standard source being copied.
CPYCOMMNTS(*YES) copies both source and comments.
CPYCOMMNTS(*NO) does not copy comments (only source statements).
However, the definition of a 'comment' as used by CPYCL differs from
normal CL. A comment is defined to be starting with a /* as the
first 2 characters on the source statement. A comment cannot span
two lines with a plus or minus symbol. It cannot contain actual
source.
CPYCOMMNTS(*DROPSPC) is the default and allows you to have special
comments that will not be copied. The special comment must begin in
position 1 with /*CPYCMNT. All other comments are copied.
The comments must look like:
Pos
1
/* I am comment - 1 */
/* I am comment - 2. I can start anywhere */
/*CPYCMNT - I am a special comment. I must start in pos 1 */
If CPYCOMMNTS(*YES) is specified, all above comments are copied.
If CPYCOMMNTS(*NO) is specified, none of the above comments are
copied.
If CPYCOMMNTS(*DROPSPC) is specified, only the first two comments are
copied. This lets you have comments in the standard source beginning
with /*CPYCMNT explaining what the source does without copying them
when CPYCL is used.
Note that if you specify a comment after a command (on the same
line), it is considered to be part of the source statement and will
always be copied. The following are examples of this.
CALL PGMA /* This comment is always copied */
CALL PGMB /* This comment is always copied +
including the overflow on the next line */
The following is a good CL statement, but would be treated as a
comment by CPYCL.
/* Beginning comment */ CALL PGMA
Source Archive
--------------
The source archive is a TAA Tool that will allow you to store
versions of source in an archive. Members in source files that have
not been used for sometime may be automatically removed so that the
only copy exists is in the archive.
If you are using the source archive, the CRTCPYCL command may need to
check the source for a CL member that no longer exists in a source
member, but is still in the source archive.
If you specify a library for the SRCARCLIB parameter, the CRTCPYCL
command will do the following:
** If the source member does not exist, the CPYSRCARCM command is
used for source archive in the library you named. If the
member exists, it is copied out to the file and member it was
archived from.
** CPYCL is used to determine if the source needs to be
refreshed.
** If so, the source is refreshed to the member and the member
would remain. The archive is not updated (daily use of
UPDSRCARC would pick up the change).
** If the proper STRCPYCL function is not found, the member is
removed (if it had been copied out). The archive version
still exists, and you are back where you started from for this
member. The member create date would be changed in the
archive, but this would have no effect.
Prerequisites
-------------
The following TAA Tools must be on your system:
ALCTMPMBR Allocate temporary member
CHKJOBCTL Check job control
EDTVAR Edit variable
HLRMVMSG HLL Remove message
RPLPGM Replace program
SNDCOMPMSG Send completion message
SNDDIAGMSG Send diagnostic message
SNDESCMSG Send escape message
SNDSTSMSG Send status message
SRCARC Source archive
Implementation
--------------
None, the tool is ready to use.
Objects used by the tool
------------------------
Object Type Attribute Src member Src file
------ ---- --------- ---------- ----------
CPYCL *CMD TAASRCZ QATTCMD
CRTCPYCL *CMD TAASRCZ2 QATTCMD
TAASRCZC *PGM CLP TAASRCZC QATTCL
TAASRCZC2 *PGM CLP TAASRCZC2 QATTCL
TAASRCZR *PGM RPG TAASRCZR QATTRPG
TAASRCZR2 *PGM RPG TAASRCZR2 QATTRPG
TAASRCZR3 *PGM RPG TAASRCZR3 QATTRPG
Structure
---------
CPYCL Cmd
TAASRCZC CL
TAASRCZR RPG
TAASRCZR3 RPG
CRTCPYCL Cmd
TAASRCZC2 CL
TAASRCZR2 RPG
|