Wednesday, July 22, 2015

Data Structures in CL

data structures in CL using defined variables

Data structures have always been a useful part of RPG, especially when returning information from a procedure. In CL I can create "Defined Variables", which are the equivalent of a RPG data structure. This becomes useful when I have a CL procedure that is called by RPG procedure, or vice versa. I will explain that in detail in a future post.

I am sure we have all encountered a situation where a data structure is passed to a CL program, and I have seen many programs were the subfields are broken out into individual variables using the Substring command, %SST. While this is easy if the data structure contains only character subfields, it can get messy if there are numeric subfields as I have to determine the start and end positions while considering the packing of the number.

By using Defined Variables, I can define the subfields at the top of the CL source using the Declare Variable command, DCL. Once the "data structure" and subfields are defined I can reference the data straight away just by using the variable name.

In this example I have a RPG program that has a data structure defined thus, I will give example in fixed format at the bottom of this post:

01  dcl-ds TestDs len(20) ;
02    Subf1 char(2) pos(1) ;
03    Subf2 packed(5:2) pos(3) ;
04    Subf3 char(10) ;
05  end-ds ;

The equivalent in CL code, using Defined Variables, would be:

01  DCL VAR(&DATA_STRCT) TYPE(*CHAR) LEN(20)

02  DCL VAR(&SUBFLD1) TYPE(*CHAR) STG(*DEFINED) +
          LEN(2) DEFVAR(&DATA_STRCT 1)

03  DCL VAR(&SUBFLD2) TYPE(*DEC) STG(*DEFINED) +
          LEN(5 2)  DEFVAR(&DATA_STRCT 3)

04  DCL VAR(&SUBFLD3) TYPE(*CHAR) STG(*DEFINED) +
          LEN(10) DEFVAR(&DATA_STRCT 6)

Line 1 is the variable that would be passed to this CL program, it is the equivalent of the data structure in the RPG.

The other three lines are the subfield equivalents. Notice that these lines have two additional parameters in the DCL command that I would not used for standalone fields:

  • STG(*DEFINED) - Storage: the value for this variable is specified in the variable defined in the DEFVAR parameter.
  • DEFVAR(&DATA_STRCT ?) - Defined on variable: specifies the variable that contains this subfield, and its starting position.

Below is the code for the free format RPG program that calls the CL:

01  dcl-pr TESTCL extpgm
02    *n char(20) ;
03  end-pr ;

04  dcl-ds TestDs len(20) ;
05    Subf1 char(2) pos(1) ;
06    Subf2 packed(5:2) pos(3) ;
07    Subf3 char(10) ;
08  end-ds ;

09  Subf1 = 'AB' ;
10  Subf2 = 123.45 ;
11  Subf3 = 'Test data' ;

12  TESTCL(TestDs) ;

13  *inlr = *on ;

If you want to see this with fixed format definitions see the example code here.

Lines 1 – 3 is the prototype definition for the CL program. If you are unfamiliar with this see Use a Procedure to call a program.

The data structure is defined in lines 4 - 8. If you are not familiar with defining data structures in free format see Data Areas in the all free RPG.

I am moving values to the subfields on lines 9 – 11.

On line 12 I am calling the CL program.

The CL code is very simple:

01  PGM PARM(&DATA_STRCT)

02  DCL VAR(&DATA_STRCT) TYPE(*CHAR) LEN(20)

03  DCL VAR(&SUBFLD1) TYPE(*CHAR) STG(*DEFINED) +
          LEN(2) DEFVAR(&DATA_STRCT 1)

04  DCL VAR(&SUBFLD2) TYPE(*DEC) STG(*DEFINED) +
          LEN(5 2)  DEFVAR(&DATA_STRCT 3)

05  DCL VAR(&SUBFLD3) TYPE(*CHAR) STG(*DEFINED) +
          LEN(10) DEFVAR(&DATA_STRCT 6)

06  ENDPGM

On line 1 the incoming parameter is given, and defined on line 2. Its subfields are defined on lines 3 – 4.

If I use debug and look at the values of the variables in the CL program I see that these subfields contain the same values as the RPG's data structure subfields:

&DATA_STRCT = 'AB  ¬Test data      '
&SUBFLD1 = 'AB'
&SUBFLD2 = 123.45
&SUBFLD3 = 'Test data '

 

You can learn more about CL's Declare Variable command, DCL on the IBM website here.

 

This article was written for IBM i 7.2, and should work for earlier releases too.

 


Fixed format definitions RPG

01  D TestDs          DS            20
02  D   Subf1                        2
03  D   Subf2                        5P 2
04  D   Subf3                       10
     /free
05     Subf1 = 'AB' ;
06     Subf2 = 123.45 ;
07     Subf3 = 'Test data' ;
     /end-free
08  C                   call      'TESTCL'
09  C                   parm                    TestDs
     /free
10     *inlr = *on ;

Return

6 comments:

  1. Simon, Do you have plans to write an article on subroutines in CL?

    ReplyDelete
  2. what compiler version is this possible in. Still on 5.3 at work...

    ReplyDelete
    Replies
    1. I can find reference to this for releases V5R4 - 7.2 in IBM's documentation web sites.

      Delete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.