I am sure we are all familiar with using a copy compiler directive to copy source code from a "copy book" source member into another. As we can now edit and compile individual source files in the IFS, how can I insert code from those members into the source code of my source file members?

Below I am going to give examples in my three favorite IBM i programming languages:

I have three files in an IFS folder, MyFolder , that contain snippets of RPG, CL, and SQL that I want to copy into programs in a source file, DEVSRC , in my library, MYLIB . I also have code snippets in other source members I want to include too. How to do it?

RPG

This will work for IBM i 7.3 and greater.

In an earlier post I gave examples of using RPG compiler directives including the ones used to copy source from one source member to another. The /COPY directive has been around for as long as I have programmed in the RPG language. It has been joined by the /INCLUDE directive, that does the same. What does this look like?

Let me start with the source member snippet, RPGCPYMBR :

01 **free 02 FromMbr = *on ;

Line 1: I need to have the **FREE as the RPG code within starts in the first position of the source member. If I do not have this in the source member the program that this is copied/included into will not compile.

Line 2: Just moving the value of *ON into an indicator variable.

The source member in the IFS folder is called RpgCopy.rpgle . I have created it with the " rpgle " file extension, but anything will do here including " txt ".

01 **free 02 FromIFS = *on ;

This is the same as the "copybook" source member, just with a different indicator.

The source code for the program looks like:

01 **free 02 dcl-s FromIFS ind ; 03 dcl-s FromMbr ind ; 04 /copy mylib/devsrc,rpgcpymbr 05 /copy '/myfolder/rpgcopy.rpgle' 06 /include mylib/devsrc,rpgcpymbr 07 /include '/myfolder/rpgcopy.rpgle'

Line 2 and 3: I have defined the indicator variables that are in the snippets in the main source member of the program.

I wanted to give examples of using the both the /COPY and /INCLUDE as this is possible with both.

Lines 4 and 6: Personally I prefer to give the library and source file when copying/including from a source member. But you do not have to, the post about RPG compiler directives gives other examples of allowed formats.

Line 5 and 7: The path to the file that contains the snippet I want to copy/include is enclosed with apostrophes ( ' ). I do find it interesting that the path I give is not case sensitive even though the folder is MyFolder and the file is RpgCopy.rpgle , I would have thought the given path would be case specific but it does not.

When I compile the program and I look in the compile listing I can see that my member and IFS files were copied/included into the program:

000800 /include mylib/devsrc,rpgcpymbr *---------------------------------------------- * RPG member name . : RPGCPYMBR * External name . . : MYLIB/DEVSRC(RPGCPYMBR) * Last change . . . : DD/DD/DD TT:TT:TT *---------------------------------------------- Seq

CL

This will work for IBM i 7.3 and greater.

I did mention the Include source command, INCLUDE , in passing in an earlier post showing how it could be used to include a subroutine into any CL program. The program and snippets to be copied are the CL version of what I did with RPG.

The source member CLCPYMBR just contains one line of code:

01 CHGVAR VAR(&FROM_MBR) VALUE('1')

The IFS file, ClCopy.clle in the IFS folder MyFolder , also contains just one line:

01 CHGVAR VAR(&FROM_IFS) VALUE('1')

The source code for the CL program is straight forward:

01 PGM 02 DCL VAR(&FROM_IFS) TYPE(*LGL) 03 DCL VAR(&FROM_MBR) TYPE(*LGL) 04 INCLUDE SRCMBR(CLCPYMBR) SRCFILE(MYLIB/DEVSRC) 05 INCLUDE SRCSTMF('/myfolder/clcopy.clle') 06 ENDPGM

Line 4: If I am including from a source member then I must give the source member, source file, and library.

Line 5: If I am including from an IFS file I use the "Source stream file" parameter. The path name I enter here is not case sensitive.

After I have compiled the CL program the compile listing shows that the contents from the source member and IFS file have been included:

/* START INCLUDE SRCMBR(CLCPYMBR) SRCFILE(MYLIB/DEVSRC) */ CHGVAR VAR(&FROM_MBR) VALUE('1') /* END INCLUDE SRCMBR(CLCPYMBR) SRCFILE(MYLIB/DEVSRC) */ /* START INCLUDE SRCSTMF('/myfolder/clcopy.clle') */ CHGVAR VAR(&FROM_IFS) VALUE('1') /* END INCLUDE SRCSTMF('/myfolder/clcopy.clle') */

SQL

This will work for IBM i 7.2 and greater.

Before I start making my copy member and IFS file I am going to need a very simple DDL Table to insert rows into:

CREATE TABLE QTEMP.TESTFILE (VALUE INT)

This statement creates a table, TESTFILE , in QTEMP that just contains one column, VALUE , that is an integer type column.

My source file member, SQLCPYMBR is going to insert one row in this Table:

01 INSERT INTO QTEMP.TESTFILE VALUES(1) ;

The file I created in my IFS folder, SqlCopy.sql , just contains another Insert statement:

01 INSERT INTO QTEMP.TESTFILE VALUES(2) ;

This is the source member, SQLTEST , containing SQL statements into which I want to include the contents of these two:

01 BEGIN 02 DELETE FROM QTEMP.TESTFILE ; 03 INCLUDE SQL MYLIB/DEVSRC(SQLCPYMBR) ; 04 INCLUDE SQL '/MYFOLDER/SQLCOPY.SQL' ; 05 END ;

Line 1: I need to "begin" this section of code. Notice that the BEGIN is not followed by a semi colon ( ; ).

Line 2: This Delete statement deletes the contents of the table.

Line 3: The Include statement includes the contents of the source member into here.

Line 4: This Include statement includes the contents from the file in the IFS. Yet again this is not case sensitive.

Line 5: End of the section of code.

I can execute this code just by using the Run SQL Statements command, RUNSQLSTM :

RUNSQLSTM SRCFILE(MYLIB/DEVSRC) SRCMBR(SQLTEST)

I having not compiled this code, just executed the statements. The Include statements perform the statements contained within too. When I use a Select statement to view the contents of TESTFILE I can see the records inserted by the Insert statements that were in the included member and IFS file:

SELECT * FROM QTEMP.TESTFILE VALUE ----- 1 2

These examples are deliberately extremely simple, but they do show how to use the copy and include in these languages. I am sure you can think of more useful examples you can use these in your own work.

You can learn more about this from the IBM website:

This article was written for IBM i 7.4, and will work for the earlier releases mentioned.