RPG - 3.4

Extension ID


What’s new?

See RPG 3.4 - Release Notes .


This extension provides support for applications written using RPG languages and/or CL languages.

Supported languages

  • RPG III (also known as GAP 3)
  • RPG IV (fixed-form and free format)
  • CL

Function Point, Quality and Sizing support

This extension provides the following support:

  • Function Points (transactions): a green tick indicates that OMG Function Point counting and Transaction Risk Index are supported
  • Quality and Sizing: a green tick indicates that CAST can measure size and that a minimum set of Quality Rules exist
Function Points (transactions) Quality and Sizing
✔️ ✔️


CAST Imaging Core release Supported
8.3.x ✔️

Download and installation instructions

The extension will be automatically downloaded and installed in CAST Console when at least one RPG type file is delivered for analysis. You can manage the extension using the Application - Extensions interface.

Prepare and deliver the source code

When the extension is downloaded and installed, you can now package your source code and run an analysis. The process of preparing and delivering your source code is described below:

Source code preparation

Before the RPG source code can be delivered and then analyzed, it needs to be collected from the proper iSeries libraries and transferred to the designated location. During this operation, each artifact (program, CL, DSPF) must be put into a single file only. This will result in a single artifact per file. Furthermore, the type of source code must be expressed using the extension to the file. The appropriate file extensions are listed in the following table.

Source code is kept in a member of a file. The file is kept in a library. Each file can have many members. Each member is the source code for a program. The source code files can have any name but conventionally the names start with Q and end with SRC, for source.

Source code type iSeries library Required extension Used in MetaModel
RPG-III programs QRPGSRC *.rpg, *.rpg38 RPG300
ILE RPG Programs QRPGLESRC *.rpgle RPG400
ILE RPG Programs with SQL QSQLRPGLESRC *.sqlrpgle RPG400
Copy source members QCPYLESRC *.cpyle RPG400
CL programs QCLSRC *.cl, *.clp, *.cl38, *.clp38 CL400
ILE CL Programs QCLLESRC *.clle CL400
Display Files QDDSSRC *.dspf, *.dspf38 DDS400
Printer Files QDDSSRC *.prtf, *.prtf38 DDS400
Logical Files QDBSRC *.lf, *.lf38 SQL Analyzer/DDS400
Physical Files QDBSRC *.pf, *.pf38 SQL Analyzer/DDS400

The RPG Analyzer is able to autodetect RPG III versus RPG IV, so there is no difference in using *.rpg or *.rpgle. What is very important is to distinguish between Display, Printer, Logical and Physical files using the specific file extensions listed in above table.

What about IBM Db2 for i source code?

In previous releases of the RPG Analyzer extension, when IBM Db2 for i source code was delivered, a dedicated extraction process was launched within the RPG Analyzer to transform this source code into a format that could be analyzed. Starting in release ≥ 3.1.x, the RPG Analyzer is no longer responsible for analyzing source code from IBM DB2 for i. Instead, this task is undertaken by the com.castsoftware.sqlanalyzer (release ≥ 3.5.4 is required).

There is no change to source code delivery process when using AIP Console - the IBM DB2 for i source code should be delivered together with the RPG source code and AIP Console will be able to detect this type of source code and create the necessary Analysis Units. For those using legacy CAST Management Studio/Delivery Manager Tool, the source code delivery process has changed and is explained below.

IBM Db2 for i is also known as DB400.

Deliver the source code

Using CAST Imaging Console

RPG is supported in CAST Console ≥ 1.22.

Note about using RPG ≥ 3.1.0 with AIP Console 1.22, 1.23, 1.24 and 1.25

RPG ≥ 3.1.0 does not function correctly with CAST Imaging Console 1.22, 1.23, 1.24 and 1.25, however, a workaround exists. Before delivering your source code, locate the following file on the Node that will be performing the analysis:


Edit the file and remove or comment out the following section:

<package packageType="dmtdb400techno.DB400Package"

Save the file and restart the Node.

CAST Imaging Console expects either a ZIP/archive file or source code located in a folder configured in Console. You should include in the ZIP/source code folder all RPG and IBM DB2 for i (if present) source code. CAST highly recommends placing the files in a folder dedicated to RPG. If you are using a ZIP/archive file, zip the folders in the “temp” folder - but do not zip the “temp” folder itself, nor create any intermediary folders:


When the source code has been delivered, CAST Imaging Console will create an Analysis Unit for:

  • IBM Db2 for i (if present)
  • RPG

Analysis configuration

Add a dependency between the RPG Analysis Unit as Source and SQL Universal Analysis Unit as the target:

Starting from CAST Imaging Console 1.26, this dependency will be automatically added and no manual intervention is required. You should still check that the dependency is present, however.

Configuring Technical Size measures for RPG in the CAST Health Dashboard

Technical Size measures can be displayed for RPG analysis results in the CAST Health Dashboard by manually editing the following file:

1.x WAR file: %CATALINA_HOME%\webapps\<dashboard>\portal\resources\app.json
2.x WAR file: %CATALINA_HOME%\webapps\<dashboard>\WEB-INF\classes\config\hd\app.json
2.x ZIP file: com.castsoftware.aip.dashboard.2.0.0\config\hd\app.json

Add the following entries into the existing section “TechnicalSizeMeasures”:

"TechnicalSizeMeasures": {
        "id": 1008000,
        "label": "Number of RPG400 Program(RPG400)"
        "id": 1008001,
        "label": "Number of RPG400 Subroutine(RPG400)"
        "id": 1008002,
        "label": "Number of RPG400 Procedure(RPG400)"
        "id": 1008003,
        "label": "Number of RPG IV Copy Member(RPG400)"
        "id": 1009000,
        "label": "Number of RPG300 Program(RPG300)"
        "id": 1009001,
        "label": "Number of RPG300 Subroutine(RPG300)"
        "id": 1009003,
        "label": "Number of RPG300 Copy Member(RPG300)"

Following any changes you make, save the app.json file and then restart your application server so that the changes are taken into account.

What results can you expect?

Transaction Sample

C                   IF        %FOUND
C                   DELETE    RACCLV
C                   ENDIF


CL language

Note: Calculation of “Number of code Line” property have been changed ( version of com.castsoftware.rpg ≥ 3.4.0-beta1) for CL objects.

DataQ CL example

/* QSNDDTAQ and QRCVDTAQ example for DataQ                           */
             DCL VAR(&DQLIB) TYPE(*CHAR) LEN(10) VALUE('QGPL')
             DCL VAR(&DQSNDLEN) TYPE(*DEC) LEN(5 0) VALUE(14)
             DCL VAR(&DQLEN) TYPE(*DEC) LEN(5 0)
             DCL VAR(&DQSNDDATA) TYPE(*CHAR) LEN(100)
             DCL VAR(&DQDATA) TYPE(*CHAR) LEN(100)
             DCL VAR(&DQWAIT) TYPE(*DEC) LEN(5 0) VALUE(0)

IBM MQ CL example

CALL PGM(QMQMSAMP/AMQ3GET4) PARM('Queue_Name','Queue_Manager_Name')

CALL PGM(QMQMSAMP/AMQ3PUT4) PARM('Queue_Name','Queue_Manager_Name')

SQL CL examples

exec sql update vrtfilep set vrupdf = ' ' where vrupdf <> ' ';


SQL Script CL example


Note: The callLink between “CL Call to Sql File” and “SQL Script” is created by the com.castsoftware.wbslinker (≥ 1.7.30).

DCLF command examples

Two modelisations have been made for DCLF instructions based on the type of file. DCLF commands can declare database file or display device file. To distiguish between both types of file, we must look at the presence of other commands:

Command available to file type description
RCVF both read the file within the CL program
SNDF display device file write the file within the CL program
SNDRCVF display device file write and then read the file within the CL program

Also, when multiple declarations of DCLF are present in the same file, then a matching OPNID or RCDFMT must be present between a specific DCLF command and for example a RCVF command.

Disk File (alias for database file)

For the following sample file ‘TAACFGAC.clp’:


The associated results:

When the DDS Physical File is present the CL Missing Disk File is replaced by the DDS Physical File or DDS Logical File object and an additionnal link is made from the CL program to the DDS Physical File or DDS Logical File. Also, If Table or View are found by the com.castsoftware.sqlanalyzer then these objects are prioritized as follows:

Display File
  DCLF FILE(TAADTQCD)                                                        
  DCL VAR(&DTAQ) TYPE(*CHAR) LEN(10) VALUE(DTQ1)                             
  DCL VAR(&LIB) TYPE(*CHAR) LEN(10) VALUE(*LIBL)                             
  CHGVAR VAR(&RCDINPUT) VALUE('')                                                                                   
  CHGVAR VAR(&WAIT) VALUE(99999)                                                                                     
  CALL PGM(QRCVDTAQ) PARM(&DTAQ &LIB &ENTLEN &ENTRY &WAIT)                                                           
  IF COND('*DSPF' *EQ %SST(&ENTRY 1 5)) THEN(DO)                                                                     

The Read Access Link is added based on the RCVF command when the Write Access Link is add based on the SNDF command. In case of SDNRCVF then both Read Access Link and Write Access Link are added.


  1. If evaluation of the file type failed, the default type is ‘Disk File’.

RPG Language

SQL RPG fix format example

     PDelFactArc       b                   Export
        W_Requete = 'Select * From Viewsq';
     C/Exec Sql
     C+ Prepare S1 From :W_Requete
    ‚PDelFactArc       e     

SQL RPG free format example

         SqlStmt = 'Select * From Viewsq';

         Exec Sql
         Prepare p1 From :SqlStmt ;

RPG IV Missing Physical/Logical File

In absence of Table/View with name matching:

In presence of Table/View with name matching:

The RPG IV Missing Physical/Logical File “APAGLQUA” object is created at analyzer level because com.castsoftware.rpg cannot know at that point that a Table or View exists resulting from a com.castsoftware.sqlanalyser analysis. At application level, a matching protocol is used to link “RPG IV File Disk” to the “Table” and delete the RPG IV Missing Physical/Logical File only if a match has been found.

RPG III/IV Work Station

"     Fgrpabol1  if   e           k disk                                         "
"     Fwdgrpabo  cf   e             workstn sfile(SFL:ligne_sfl)                 "
"     F                                     sfile(SFL01:Å“Å“rang1)               "
"      *====================================================================*    "

Similarly to CL language for CL Display File, the RPG III and RPG IV Work Station expected results are:

DataQ RPG example

I              'INKOOP    '          C         DTAQ

I                                        1   3 CTRL
I                                        4   9 BLVNR
C           *ENTRY    PLIST
C                     PARM           PLVNR   6
C                     PARM           DTAQL  10
C                     MOVEL'BEL'     CTRL
C                     MOVELPLVNR     BLVNR
C                     CALL 'QSNDDTAQ'
C                     PARM DTAQ      PDTAQ  10
C                     PARM DTAQL     PDTAQL 10
C                     PARM 9         LEN     50
C                     PARM           INKOOP
C                     MOVE *ON       *INLR
C                     RETRN

d DQLib           s             10    inz('*LIBL')
d DQName          s             10    inz('CONVMAIL')
d DQLen           s              5  0 inz(512)
c     snddtq        begsr
c                   call      'QSNDDTAQ'
c                   parm                    DQName
c                   parm                    DQLib
c                   parm                    DQLen
c                   parm                    DQData
c                   endsr

dcl-pr QSNDDTAQ extpgm ;
  *n char(10) const ;  //Data queue name
  *n char(10) const ;  //Library
  *n packed(5) ;       //Length of data
  *n char(100) ;       //Data
end-pr ;
for QData.Counter = 1 to 10 ;
    QData.Field1 = %char(QData.Counter) ;
    QData.Field2 = %char(QData.Counter * 10) ;
    QData.Field3 = %char(QData.Counter * 100) ;
    QSNDDTAQ('TESTDTAQ':'MYLIB':LengthOfData:QData) ;
endfor ;

dcl-pr QSNDDTAQ extpgm ;
  *n char(10) const ;  //Data queue name
  *n char(10) const ;  //Library
  *n packed(5) ;       //Length of data
  *n char(100) ;       //Data
end-pr ;

BegSr srDTAQ;

IBM MQ RPG example

001 C                   EVAL      ODON = TestQueue                                            UTT07R

     P  GetEqMsg       B                   export                                             UTT07R
      Procedure interface                                                                  UTT07R
      -------------------                                                                  UTT07R
     D GetEqMsg        PI         12000A                                                      UTT07R
     D  Queue                        48A   value                                              UTT07R
     D  Remove                        1A   value options(*nopass)                             UTT07R
     D  WaitMillis                   10I 0 value options(*nopass)                             UTT07R
      Local variables                                                                      UTT07R
      ---------------                                                                      UTT07R
     *  The last-used queue, held in static storage for persisitence over calls              UTT07R
     D LastQueue       S                   like(Queue) static                                 UTT07R
     *  Local error code                                                                     UTT07R
     D GetError        S              4A                                                      UTT07R
     * 0Reply from user if there is an error                                                 UTT07R
     D Reply           S              1A                                                      UTT07R
     *  Alpha versions of reason code                                                        UTT07R
     D ReasonA         DS             9                                                       UTT07R
     D ReasonA4                1      4A                                                      UTT07R
     *  The data returned from MQSeries                                                      UTT07R
     D MQMessage       S          12000A                                                      UTT07R
     *  Has there been a handle error                                                        UTT07R
     D HandleErr       S              1A                                                      UTT07R
      Parameter lists                                                                      UTT07R
      ---------------                                                                      UTT07R
     * MQ get message from queue (receive message)                                           UTT07R
     C     PLMQGET       PLIST                                                                UTT07R
     C                   PARM                    CID                                          UTT07R
     C                   PARM                    HCONN                                        UTT07R
     C                   PARM                    HOBJ                                         UTT07R
     C                   PARM                    MQMD                                         UTT07R
     C                   PARM                    MQGMO                                        UTT07R
     C                   PARM                    BUFLEN                                       UTT07R
     C                   PARM                    MQMessage                                    UTT07R
     C                   PARM                    MESLEN            9 0                        UTT07R
     C                   PARM                    CCODE                                        UTT07R
     C                   PARM                    REASON                                       UTT07R
      Procedure processing                                                                 UTT07R
      --------------------                                                                 UTT07R
     *  Connect to the queue manager to ensure connection                                    UTT07R
     C                   Eval      ReasonA4 = ConnectMQM( QueueManager )                      UTT07R
     *  If the connection failed dump and exit                                               UTT07R
B001 C                   if        ReasonA4 <> *blanks                                        UTT07R
 001 C                   dump                                                                 UTT07R
 001 C                   return    GET_ERROR                                                  UTT07R
E001 C                   ENDif                                                  ReasonA4 <> *bUTT07R
     *  Open MQSeries queue                                                                  UTT07R
     C                   eval      ReasonA4 = OpenQueue( Queue )                              UTT07R
     *  If the called procedures reported an error, dump and exit                            UTT07R
B001 C                   if        ReasonA4 <> *blanks                                        UTT07R
 001 C                   dump                                                                 UTT07R
 001 C                   return    GET_ERROR                                                  UTT07R
E001 C                   ENDif                                                  ReasonA4 <> *bUTT07R
     *  Use the queue name to get the MQSeries object handle                                 UTT07R
     C                   eval      HOBJ = GetHandle( Queue )                                  UTT07R
     *  Set up the options for an MQGET call                                                 UTT07R
     *  Set to 'Get Message'                                                                 UTT07R
     C                   Z-ADD     MQGET         CID   

The value of the parameter ODON is evaluated. This parameter holds the name of the queue. Here are three examples of how the name of the queue can be declared.

    D TestQueue       S             10    INZ('TESTQUEUE    ')                              UTT07R                                                                                              
001 C                   EVAL      ODON = TestQueue                                            UTT07R

001 C                   EVAL      TestQueue = 'TESTQUEUE'                                            UTT07R
001 C                   EVAL      ODON = TestQueue                                            UTT07R

001 C                   EVAL      TestQueue = $TESTQUEUE                                            UTT07R
001 C                   EVAL      ODON = TestQueue                                            UTT07R

If there is no file in the application where $TESTQUEUE is declared, we create an unknown queue object.

REST RPG examples

Support of http_get, http_put, http_post, http_delete APIs : example for http_get API

    url = 'http://example.com:8500/cust';
    rc = http_get(url: options);
    if (rc<>1 and rc<>500);
    if rc=500;
        xml-into errMsg %xml(stmf: 'path=error doc=file');
        dsply errMsg;
        xml-into custInfo %xml(stmf: 'path=result/cust doc=file');
        dsply custInfo.name;
        dsply custInfo.street;
        dsply ( custInfo.city + ' '
                + custInfo.state + ' '
                + custInfo.postal );
    *inlr = *on;

Support of http_string API

dcl-proc translate;
   url = 'https://gateway.platform.net/language-translator/api' 
       + '/v3/translate?version=2018-05-01';

      response = http_string('POST': url: request: 'application/json');
      http_error(*omit: httpstatus);
      httpcode = %char(httpstatus);
      httpcode = http_error();


Support of http_url_get and http_url_post APIs : example for http_url_get API

   url = 'http://rss.test.com/rss/test.rss';                                                    
   filename = 'http_file.xml';                                                                  
   rc = http_url_get( url : filename );                                                                 
   if (rc <> 1);                                                                                        
      PrintLine = http_error();                                                                         

REST services with Embedded SQL

dcl-proc translate;
  url = 'http://example.com:8500/cust';
   exec SQL
     select SYSTOOLS.HTTPPOSTCLOB(:url, :hdr, :request)
       into :response
       from SYSIBM.SYSDUMMY1;

dcl-proc translate;
  url = 'http://example.com:8500/cust';
   exec SQL
     values QSYS2.HTTP_GET(:url, :hdr, :request)
       into :response
       from SYSIBM.SYSDUMMY1;

IBM-supplied AXISC routines

Support of AXISC routine : axiscTransportSetProperty API with AXISC_PROPERTY_HTTP_METHOD parameter

dcl-proc translate;
   dcl-s url      varchar(2000);
   dcl-s request  varchar(2000);
   dcl-s response varchar(5000);
   dcl-s rcvBuf   char(5000);
   dcl-s rc       int(10);
   dcl-s propName char(200);
   dcl-s propVal  char(200);
   dcl-s transportHandle pointer;
   userid = 'apikey';
   password = '8OD0RY71zMwXjkNiBLzTN8i848R9wXMOmADjuvoKY2zw';
   url = 'https://gateway.platform.net/language-translator/api' 
       + '/v3/translate?version=2018-05-01';
   transportHandle = axiscTransportCreate(url: AXISC_PROTOCOL_HTTP11);
   if (transportHandle = *null);
     failWithError(transportHandle: 'axiscTransportCreate');
   propName = 'POST' + x'00';
   axiscTransportSetProperty( transportHandle
                            : AXISC_PROPERTY_HTTP_METHOD
                            : %addr(propName));



Icon Object Name
CL Program
CL Project
CL Subroutine
CL Call to Generic Program
CL Call to Sql File
CL Data Queue Publisher
CL Data Queue Receiver
CL Data Unknown Queue Publisher
CL Data Unknown Queue Receiver
CL IBM MQ Queue Publisher
CL IBM MQ Queue Receiver
CL IBM MQ Unknown Queue Publisher
CL IBM MQ Unknown Queue Receiver
CL Disk File
CL File Display
CL Missing File Disk
CL Missing Display File


Icon Object Name
DDS Project
DDS Section
DDS Printer File
DDS Display File
DDS Join Structure
DDS Logical File
DDS Physical File
DDS Record Structure LF
DDS Record Structure PF

RPG 300

Icon Object Name
RPG III Project
RPG III Program
RPG III MainSubroutine
RPG III Subroutine
RPG III File Printer
RPG III File Disk
RPG III File Workstn
RPG III File Special
RPG III File Seq
RPG III Copy Member
RPG III SQL Statement/Structure
RPG III Procedure
RPG III Call to Generic Program
RPG III Missing Copy Member
RPG III Missing Physical/Logical File
RPG III Missing Display File
RPG III Missing Printer File
RPG III Data Queue Publisher
RPG III Data Queue Receiver
RPG III Data Unknown Queue Publisher
RPG III Data Unknown Queue Receiver
RPG III IBM MQ Queue Publisher
RPG III IBM MQ Queue Receiver
RPG III IBM MQ Unknown Queue Publisher
RPG III IBM MQ Unknown Queue Receiver

RPG 400

Icon Object Name
RPG IV Project
RPG IV Program
RPG IV MainSubroutine
RPG IV Subroutine
RPG IV File Printer
RPG IV File Disk
RPG IV File Workstn
RPG IV File Special
RPG IV File Seq
RPG IV Procedure
RPG IV Procedure Prototype
RPG IV Copy Member
RPG IV Call to Generic Program
RPG IV Module
RPG IV Missing Copy Member
RPG IV Missing Physical/Logical File
RPG IV Missing Display File
RPG IV Missing Printer File
RPG IV Missing Procedure
RPG IV Data Queue Publisher
RPG IV Data Queue Receiver
RPG IV Data Unknown Queue Publisher
RPG IV Data Unknown Queue Receiver
RPG IV IBM MQ Queue Publisher
RPG IV IBM MQ Queue Receiver
RPG IV IBM MQ Unknown Queue Publisher
RPG IV IBM MQ Unknown Queue Receiver
RPG IV Get Resource Service
RPG IV Post Resource Service
RPG IV Put Resource Service
RPG IV Delete Resource Service

Analysis messages


Identifier RPG-001
Message Cannot resolve copy …
Severity Warning
Explanation Analyser could not find the source file included by a /copy statement. This can lead to various missing results.
User Action Ensure that all required source code is packaged and delivered.


Identifier RPG-002
Message Cannot resolve DDS file …
Severity Warning
Explanation Analyser could not find a DDS file (pf, lf, dspf, prtf, …)
User Action Ensure that all required source code is packaged and delivered.


Identifier RPG-003
Message Cannot resolve program …
Severity Warning
Explanation Analyser could not find a program.
User Action Ensure that all required source code is packaged and delivered. The program can also be in a different technology (COBOL, etc…) in that case it will be linked in a latter analysis step.

Note: RPG-003 had been expanded to also include the same warning from CL analyser in version of com.castsoftware.rpg ≥ 3.4.0-beta1.


Identifier RPG-004
Message Cannot resolve procedure …
Severity Warning
Explanation Analyser could not find a procedure.
User Action Ensure that all required source code is packaged and delivered.

Structural Rules

The following structural rules are provided:

Release Link
3.4.0-alpha3 https://technologies.castsoftware.com/rules?sec=srs_rpg&ref=||3.4.0-alpha3
3.4.0-alpha2 https://technologies.castsoftware.com/rules?sec=srs_rpg&ref=||3.4.0-alpha2
3.4.0-alpha1 https://technologies.castsoftware.com/rules?sec=srs_rpg&ref=||3.4.0-alpha1

Known limitations

  • SOAP services are not supported
  • In RPG
    • Dynamic calls are not supported
    • Dynamic SQL is partially supported since 3.3.0-alpha2 (’prepare’ and ‘execute immediate’ with variables are resolved when encountered in RPG IV free format; the support for RPG IV fixed format and CL is available since 3.3.0-alpha3)