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

18 comments:

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

    ReplyDelete
    Replies
    1. Could you please share us subroutines in CL articles

      Delete
    2. If you had used the search function you would have found I have already written about CL subroutines.

      Delete
  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
    2. Anonymous,
      Missed it by .1 :-) Support for *BASED variables arrived in V5R4.
      - DrFranken

      Delete
  3. Great as usual - J

    ReplyDelete
  4. Nice article very helpful !!
    But can we handle multi occurance or array Data structure also in CL ?

    ReplyDelete
  5. It's very useful.
    I'll apply this technic to my cl program.
    Thanks for providing good information.

    ReplyDelete
  6. Hi Simon,
    Very helpful article!!
    Do we have any method to declare the CL variable with LIKE key word. Can we declare External DS structure in CL. Thanks,
    Srinidhi

    ReplyDelete
    Replies
    1. Declaring CL variables with the LIKE keyword is not possible in the current releases of IBM i.

      Declaring external DS in CL is also not possible.

      Both would be nice additions to the CL language. I think you should submit these as a RFE at IBM's website here.

      Delete
  7. Really nice. Thank you Simon.
    Regards
    Carlos

    ReplyDelete
  8. Very usefull and cool. I use a lot of APIs in my programs this will simplify my work in a big way. Thanks.

    ReplyDelete
  9. Too good information, I never tried this option earlier.

    ReplyDelete

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.