What's New since 7.4?

This section was last updated in the first half of the year 2024.

This section describes the enhancements to ILE RPG after 7.4 with PTFs.

See https://www.ibm.com/support/pages/rpg-cafe to determine the PTFs you need on the systems where you are compiling and running your programs.

Warning: Some enhancements require a compile-time PTF and a runtime PTF.

If a program uses an enhancement that requires a runtime PTF, you must ensure that the runtime PTF is applied on any system where the program is restored.

Some enhancements are also available with PTFs for TGTRLS(*V7R3M0). If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

If you restore your program on a 7.5 system, different runtime PTFs are needed.

More options for the SND-MSG operation
You can now specify *COMP, *DIAG, *NOTIFY, and *STATUS for the message type, in addition to the previous supported types *INFO and *ESCAPE.

You can now specify *CTLBDY, *EXT, and *PGMBDY for the first parameter of the %TARGET built-in function in addition to the previous special targets *SELF and *CALLER.

In the following example, the first SND-MSG operation sends a message to the bottom of the screen indicating the progress of the program. The second SND-MSG operation sends a completion message to the caller of the program.


FOR n = 1 to total;
   . . .
   SND-MSG *STATUS
           %CHAR(n) + ' of ' + %CHAR(total) + ' complete'
           %TARGET(*EXT);
ENDFOR;
SND-MSG *COMP 'Processing complete'
        %TARGET(*CALLER : 1);
See SND-MSG (Send a Message to the Joblog) and %TARGET (program-or-procedure { : offset } ).

This enhancement is available with a compile-time PTF in the first half of the year 2024.

This enhancement is also available in 7.5 with a compile-time PTF.

Warning: A runtime PTF was provided when the SND-MSG operation code was first enabled. See New operation code SND-MSG. You must ensure that the runtime PTF is applied on any 7.4 system where the program is restored.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Define a constant standalone field or data structure
You can now specify CONST for a standalone field or data structure. When you specify the CONST, the variable cannot be modified by the program.

In the following example, data structure defaults and standalone field startTimestamp cannot be changed after they are initialized by the compiler.


DCL-DS defaults QUALIFIED CONST;
   usrprf CHAR(10) INZ(*USER);
   branch VARCHAR(50) INZ('Main');
END-DS;
DCL-S startTimestamp TIMESTAMP INZ(*SYS) CONST;
DCL-S currentBranch VARCHAR(50);

currentBranch = getBranch();
IF currentBranch <> defaults.branch;
  . . .
ENDIF;

SND-MSG 'Elapsed time is '
      + %CHAR(%DIFF(%TIMESTAMP(*SYS) : startTimestamp : *SECONDS : 2))
      + ' seconds';

See Constant variables.

This enhancement is available with a compile-time PTF in the first half of the year 2024.

This enhancement is also available in 7.5 with a compile-time PTF.

%LEFT and %RIGHT built-in functions
  • %LEFT returns the leftmost characters in a string.
  • %RIGHT returns the rightmost characters in a string.

In the following example, the input string is "abcdefghij". The %LEFT built-in function returns the 3 leftmost characters, "abc". The %RIGHT built-in function returns the 3 rightmost characters, "hij".


DCL-S myString VARCHAR(20) inz('abcdefghij');
DCL-S leftChars VARCHAR(20);
DCL-S rightChars VARCHAR(20);

myString = 'abcdefghij';

leftChars = %LEFT(myString : 3);
// leftChars = "abc"

rightChars = %RIGHT(myString : 3);
// leftChars = "hij"
See %LEFT (Get Leftmost Characters) and %RIGHT (Get Rightmost Characters).

This enhancement is available with a compile-time PTF in the last half of the year 2023.

This enhancement is also available in 7.5 with a compile-time PTF.

Enumerations to group named constants
An enumeraton is a group of named constants. The enumeration can be qualified.
In the following example:
  1. Enumeration sizes is not qualified.
  2. Enumeration jobMsgQ is qualified.
  3. The constant small from enumeration sizes is used without being qualified by the enumeration name.
  4. The constant wrap from enumeration jobMsgQ is qualified by the enumeration name.
  5. The enumeration values are assigned to an array.
  6. The enumeration name is used with the IN operator. If the value of item.size is not one of the values in the enumeration, the message will be sent.
  7. The enumeration name is used in a FOR-EACH statement to iterate through all the values in the enumeration.

DCL-ENUM sizes; //  1 
   tiny -1;
   small 0;
   medium 1;
   large 2;
END-ENUM;

DCL-ENUM jobMsgQ QUALIFIED; //  2 
   noWrap '*NOWRAP';
   wrap '*WRAP';
   prtWrap '*PRTWRAP';
END-ENUM;

DCL-S cmd VARCHAR(100);
DCL-S array INT(10) DIM(5);
DCL-DS item QUALIFIED;
   size packed(5);
END-DS;

item.size = small; //  3 

cmd = 'CHGJOB JOBMSGQFL(' + jobMsgQ.wrap + ')'; //  4 

array = sizes; //  5 

IF NOT (item.size IN sizes); //  6 
   SND-MSG *ESCAPE 'Size is not valid for item ' + item.id_no;
ENDIF;

FOR-EACH x in sizes; //  7 
   ...
ENDFOR;

See Free-Form Enumeration Definition.

This enhancement is available with a compile-time PTF in the last half of the year 2023.

This enhancement is also available in 7.5 with a compile-time PTF.

*ALLSEP option for %SPLIT to handle all separators
By default, separators following other separators, leading separators, and trailing separators are ignored by %SPLIT.

You can specify *ALLSEP to indicate that every separator is considered to separate two substrings.

In the following example, the input string has several extra separators. When *ALLSEP is specified, several empty substrings are returned by %SPLIT. The extra separators are marked by X in the comment following the assignment to the myString variable.


myString = '.cat..dog...fish..';
//          X    X    XX    XX

array = %SPLIT(myString : '.');
// %SPLIT returns
//   'cat'
//   'dog'
//   'fish'

array = %SPLIT(myString : '.' : *ALLSEP);
// %SPLIT returns
//    ''
//    'cat'
//    ''
//    'dog'
//    ''
//    ''
//    'fish'
//    ''
//    ''
See %SPLIT (Split String into Substrings).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2023.

This enhancement is also available in 7.5 with a compile-time PTF and a runtime PTF.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

Different runtime PTFs are required for 7.4 and 7.5 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New built-in function %PASSED
%PASSED returns *ON if the specified parameter was passed and *OMIT was not passed for the parameter. If %PASSED is true, the parameter can be used.

DCL-PROC myProc;
   DCL-PI *n;
      p1 CHAR(10) OPTIONS(*OMIT);
      p2 DATE(*ISO) CONST OPTIONS(*OMIT : *NOPASS);
      p3 INT(10) VALUE OPTIONS(*NOPASS);
   END-PI;

   IF %PASSED(p1);
      DSPLY p1;
   ELSE;
      DSPLY 'P1 is not available';
   ENDIF;

   IF %PASSED(p2);
      DSPLY p2;
   ELSE;
      DSPLY 'P2 is not available';
   ENDIF;

   IF %PASSED(p3);
      DSPLY p3;
   ELSE;
      DSPLY 'P3 is not available';
   ENDIF;
END-PROC;
See %PASSED (Return Parameter-Passed Condition).

This enhancement is available with a compile-time PTF in the first half of the year 2023.

This enhancement is also available in 7.5 with a compile-time PTF.

Note:

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New built-in function %OMITTED
%OMITTED returns *ON if *OMIT was passed for the specified parameter.

DCL-PROC myProc;
   DCL-PI *n;
      p1 CHAR(10) OPTIONS(*OMIT);
      p2 DATE(*ISO) CONST OPTIONS(*OMIT : *NOPASS);
   END-PI;

   IF %PASSED(p1);
      DSPLY p1;
   ELSEIF %OMITTED(p1);
      DSPLY '*OMIT was passed for P1';
   ENDIF;

   IF %PASSED(p2);
      DSPLY p2;
   ELSEIF %OMITTED(p2);
      DSPLY '*OMIT was passed for P2';
   ELSE;
      DSPLY 'P2 was not passed at all';
   ENDIF;
END-PROC;
See %OMITTED (Return Parameter-Omitted Condition).

This enhancement is available with a compile-time PTF in the first half of the year 2023.

This enhancement is also available in 7.5 with a compile-time PTF.

Note:

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Specify an operand for SELECT
You can specify an operand for the SELECT statement to be used for all the comparisons in the select group. The WHEN operation code is not used when the SELECT operation has an operand. Instead, two new operation codes are used for the comparisons.
  • Use new operation code WHEN-IN to start a block where the select operand is IN the WHEN-IN operand.
  • Use new operation code WHEN-IS to start a block where the select operand is equal to the WHEN-IS operand.

SELECT a.b(i).c(j);
WHEN-IS 0;
   // Handle a.b(i).c(j) = 0
WHEN-IN %RANGE(5 : 20);
   // Handle a.b(i).c(j) between 5 and 100
WHEN-IN %LIST(2 : 3 : N : M + 1):
   // Handle a.b(i).c(j) = 5, 10, N, or (M + 1)
WHEN-IS N + 1;
   // Handle a.b(i).c(j) = N + 1
OTHER;
   // Handle any other values for a.b(i).c(j)
ENDSL;
See SELECT (Begin a Select Group), WHEN-IN (When the SELECT Operand is IN the WHEN-IN Operand), and WHEN-IS (When the SELECT Operand is Equal to the WHEN-IS Operand).

This enhancement is available with a compile-time PTF in the first half of the year 2023.

This enhancement is also available in 7.5 with a compile-time PTF.

Note:

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Support for PCML version 8
If you want to take advantage of version 8 of PCML, you can specify *V8 in the PGMINFO keyword, or you can set environment variable QIBM_RPG_PCML_VERSION to the value '8.0' at compile time.

With PCML version 8, the generated PCML adds a "boolean" attribute to indicator items.


CTL-OPT PGMINFO(*PCML : V8);
See PGMINFO(*PCML | *NO | *DCLCASE { : *MODULE { : *Vx }}).

This enhancement is available with a compile-time PTF in the first half of the year 2023.

This enhancement is also available in 7.3 and 7.5 with a compile-time PTF.

Note:

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New command parameter to improve CRTSQLRPGI with *LVL1 or *LVL2 for the RPGPPOPT parameter
If you use the CRTSQLRPG with RPGPPOPT(*LVL1) or RPGPPOPT(*LVL2), you can control the record length of the output file QTEMP/QSQLPRE created by the RPG preprocessor. The default record length is 112, which supports a line length up to 100. If your fully-free source is in a stream file, the default line length of 100 might not be long enough to handle all the lines in the source.

You can control the line length of the file created by the RPG preprocessor in two ways.

  • To request that the QTEMP/QSQLPRE file be created with a specific line length, you can use environment variable QIBM_RPG_PPSRCFILE_LENGTH.

    For example, if you know that a line length of 500 is sufficient for all the source in the compilation, specify a value of 500 for the environment variable.

    
    ADDENVVAR QIBM_RPG_PPSRCFILE_LENGTH VALUE(500)
    
  • If the environment variable is not present, the new parameter PPMINOUTLN for CRTBNDRPG and CRTRPGMOD sets the minimum line length for the output file.

    If the length of a line in the source file specified by the SRCFILE parameter or the maximum length of a line in the source file specified by the SRCSTMF parameter is longer than the length specified by the PPMINOUTLN parameter, the output file is created with the longer length.

    For example, to request that the QTEMP/QSQLPRE file be created with a line length at least 500, specify COMPILEOPT('PPMINOUTLN(500)'). That will cause the RPG preprocessor to create the output file with a line length that is at least 500, but might be longer if the longest line in the input file is longer than 500.

    
    CRTSQLRPGI MYLIB/MYPGM SRCSTMF('mypgm.sqlrpgle') RPGPPOPT(*LVL1) COMPILEOPT('PPMINOUTLN(500)')
    

This enhancement is available with compile-time PTFs in the first half of the year 2023.

This enhancement is also available in 7.3 and 7.5 with compile-time PTFs.

Options to process strings by natural characters instead of bytes or double bytes

By default, RPG processes strings in the CHARCOUNT STDCHARSIZE, by bytes for alphanumeric data and by double bytes for UCS-2 and graphic data. If the data type is UTF-8, UTF-16, or mixed SBCS/DBCS, the number of bytes for each character can be different. When strings are processed by bytes or double bytes, the result might not be correct.

Several features are available to request that RPG handle strings by the natural size of each character. See Processing string data by the natural size of each character.

  • Control specification keyword CHARCOUNTTYPES sets the data types affected by the CHARCOUNT(*NATURAL) Control keyword or the /CHARCOUNT NATURAL directive.
  • Directive /CHARCOUNT sets the CHARCOUNT mode for file definitions and calculations following the directive.
  • Control specification keyword CHARCOUNT sets the initial CHARCOUNT mode.
  • Keyword CHARCOUNT for file definitions sets the CHARCOUNT mode for moving data from RPG expressions to the output buffer and key buffer for the file.
  • New built-in function %CHARCOUNT returns the number of natural characters.
  • You can specify either *NATURAL or *STDCHARSIZE for built-in functions that handle strings.
    Note: However, note that %LEN and %STR always operate in the standard-character-size mode.
In the following example
  1. The CHARCOUNTTYPES specifies that only UTF-8 data is handled by CHARCOUNT NATURAL mode.
  2. The UTF-8 value "ábç" is assigned to variable string. The UTF-8 characters 'á' and 'ç' have two bytes. There are three characters and five bytes.
  3. The %LEN built-in function always operates in CHARCOUNT STDCHARSIZE mode, so it returns 5.
  4. The %CHARCOUNT built-in function always operates in CHARCOUNT NATURAL mode, so it returns 3.
  5. The %SUBST built-in function has a starting position of 1 and a length of 3. This statement is in CHARCOUNT STDCHARSIZE mode because the CHARCOUNT mode has not been set by either the CHARCOUNT Control keyword or the /CHARCOUNT directive. The substring assigned to variable string2 has three bytes, "áb".
  6. The %SUBST built-in function has *NATURAL specified as the last parameter. This statement is in CHARCOUNT STDCHARSIZE mode but the %SUBST built-in function operates in CHARCOUNT NATURAL mode. The substring assigned to variable string2 has three characters, "ábç".
  7. Directive /CHARCOUNT sets the mode to CHARCOUNT NATURAL.
  8. The %LEN built-in function always operates in CHARCOUNT STDCHARSIZE mode, so it returns 5.
  9. The %CHARCOUNT built-in function always operates in CHARCOUNT NATURAL mode, so it returns 3.
  10. The %SUBST built-in function has a starting position of 1 and a length of 3. This statement is in CHARCOUNT NATURAL mode due to the /CHARCOUNT NATURAL directive. The substring assigned to variable string2 has three characters, "ábç".
  11. The %SUBST built-in function has *STDCHARSIZE specified as the last parameter. This statement is in CHARCOUNT NATURAL mode but the %SUBST built-in function operates in CHARCOUNT STDCHARSIZE mode. The substring assigned to variable string2 has three bytes, "áb".

CTL-OPT CHARCOUNTTYPES(*UTF8); //  1 

DCL-S string VARCHAR(10) CCSID(*UTF8);
DCL-S string2 VARCHAR(10) CCSID(*UTF8);
DCL-S n INT(10);

string = 'ábç';  //  2 

n = %LEN(string); //  3 
// n = 5

n = %CHARCOUNT(string); //  4 
// n = 3

string2 = %SUBST(string : 1 : 3); //  5 
// string2 = 'áb'

string2 = %SUBST(string : 1 : 3 : *NATURAL); //  6 
// string2 = 'ábç'

/CHARCOUNT NATURAL //  7 

n = %LEN(string); //  8 
// n = 5

n = %CHARCOUNT(string); //  9 
// n = 3

string2 = %SUBST(string : 1 : 3); //  10 
// string2 = 'ábç'

string2 = %SUBST(string : 1 : 3 : *STDCHARSIZE); //  11 
// string2 = 'áb'

See Processing string data by the natural size of each character.

This enhancement is available with a compile-time PTF and a runtime PTF in the second half of the year 2022.

This enhancement is also available in 7.5 with a compile-time PTF and a runtime PTF.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

Different runtime PTFs are required for 7.4 and 7.5 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New built-in function %CONCAT
%CONCAT concatenates several strings with a common separator between the strings.
In the following example, name, addr, and city are concatenated into a result string, separated by the first operand, which is a comma followed by a space.

DCL-S list VARCHAR(50);
DCL-S name VARCHAR(10) INZ('Sally');
DCL-S addr VARCHAR(20) INZ('123 Elm St.');
DCL-S city VARCHAR(20) INZ('Springfield');

list = %CONCAT(', ' : name : addr : city);
// list = "Sally, 123 Elm St., Springfield"
If no separator is required, you can specify *NONE. If a single blank is required as the separator, you can specify *BLANK or *BLANKS.

list = %CONCAT(*BLANKS : name : addr : city);
// list = "Sally 123 Elm St. Springfield"
See %CONCAT (Concatenate with Separator).

This enhancement is available with a compile-time PTF in the second half of the year 2022.

Note:

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New built-in function %CONCATARR
%CONCATARR concatenates the elements of an array with a common separator between the elements.
In the following example, the array elements are concatenated into a result string, separated by the first operand, which is a comma followed by a space.

DCL-S list VARCHAR(50);
DCL-S arr VARCHAR(20) DIM(3);

arr(1) = 'Cat';
arr(2) = 'Dog';
arr(3) = 'Pony';
list = %CONCATARR(', ' : arr);
// list = "Cat, Dog, Pony"

The array operand can be any array expression, including %SUBARR, %LIST, and %SPLIT.

If no separator is required, you can specify *NONE. If a single blank is required as the separator, you can specify *BLANK or *BLANKS.

list = %CONCATARR(*NONE :  arr);
// list = "CatDogPony"
See %CONCATARR (Concatenate Array Elements with Separator).

This enhancement is available with a compile-time PTF in the second half of the year 2022.

Note:

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

OPTIONS(*CONVERT) to convert parameters to strings
With OPTIONS(*CONVERT), the passed parameter can have a different type from the prototyped parameter.
  • When OPTIONS(*CONVERT) is specified for a prototyped parameter of type alphanumeric or UCS-2, the passed parameter can be numeric, date, time, timestamp, alphanumeric, graphic, or UCS-2.
  • When OPTIONS(*CONVERT) is specified for a prototyped parameter of type pointer, the passed parameter can be numeric, date, time, timestamp, alphanumeric, graphic, UCS-2, or pointer.

If the prototyped parameter is alphanumeric or UCS-2, and the passed parameter is numeric, date, time or timestamp, the value is first converted to character using the %CHAR rules, and then it is converted to the required type of the prototyped parameter.

If the prototyped parameter has type pointer, and the passed parameter is not a pointer, the parameter is converted to a null-terminated string in the job CCSID. If the passed parameter is a pointer, no conversion is needed.

In the following example, the parameters received by the procedure are
  1. "2022-12-25     "
  2. "25.7", converted to a varying-length UCS-2 value
  3. A null-terminated string in the job CCSID with the value "/home/mydir/myfile.txt"

DCL-PR myProc;
   p1 CHAR(15) CONST OPTIONS(*CONVERT);     //  1 
   p2 VARUCS2(20) CONST OPTIONS(*CONVERT);  //  2 
   p3 POINTER VALUE OPTIONS(*CONVERT);      //  3 
END-PR;
DCL-S filename VARUCS2(30) INZ('/home/mydir/myfile.txt');

myProc (D'2022-12-25'     //  1 
      : 25.7              //  2 
      : filename);        //  3 
Note: See OPTIONS(*CONVERT).

This enhancement is available with a compile-time PTF in the second half of the year 2022.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New operation code SND-MSG
With SND-MSG, you can send an informational message or an escape message to a program or procedure on the call stack.
  • In the following example, "Hello from RPG" is sent to the joblog as an informational message.

    The two SND-MSG operations are equivalent. The first SND-MSG defaults to having *INFO as the message type. The second SND-MSG explicitly specifies *INFO.

    When *INFO is specified as the message-type, or the message-type operand is not specified, the message is sent by default to the current procedure.

    
    DCL-S name VARCHAR(20) inz('RPG');
    
    SND-MSG 'Hello from ' + name;
    
    SND-MSG *INFO 'Hello from ' + name;
    
  • In the following example, message ACT1234 from message file *LIBL/MYMSGF is sent as an escape message to the caller of the current procedure. When *ESCAPE is specified, the message is sent by default to the caller of the current procedure.

    Assume that the message has two replacement values.

    1. TYPE(*CHAR) LEN(25)
    2. TYPE(*DEC) LEN(10)
    
    DCL-DS ACT1234_text qualified;
       account_name char(25);
       account_number packed(10);
    END-DS;
    
    CHAIN (acct_num) FILE;
    IF NOT %FOUND();
       ACT1234_text.account_name = name;
       ACT1234_text.account_number = acct_num;
       SND-MSG *ESCAPE %MSG('ACT1234' : 'MYMSGF' : ACT1234_text);
    ENDIF;
    
  • The SND-MSG operation in the following example is similar to the previous example, but the message is explicitly sent to the call-stack entry 'MYCLPGM'. The RPG programmer expects that a program called MYCLPGM has been called before the current procedure, and that MYCLPGM has not returned yet. If the RPG programmer is debugging the program, and uses the DSPJOB command with parameter OPTION(*PGMSTK), the program stack must show that MYCLPGM is an active caller of the current procedure.
    
       SND-MSG *ESCAPE %MSG('ACT1234' : 'MYMSGF' : ACT1234_text)
                       %TARGET('MYCLPGM');
    
  • The SND-MSG operation in the following example is similar to the previous example, but the message is explicitly sent to the caller of MYCLPGM, by specifying the value 1 for the offset operand of %TARGET.
    
       SND-MSG *ESCAPE %MSG('ACT1234' : 'MYMSGF' : ACT1234_text)
                       %TARGET('MYCLPGM' : 1);
    
  • If an error occurs while sending the message, the SND-MSG operation fails with new status code 126. If you send an escape message to the current procedure, the RPG procedure fails with status code 9999.
See SND-MSG (Send a Message to the Joblog).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2022.

This enhancement is also available in 7.3 with a compile-time PTF and a runtime PTF.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New operation code ON-EXCP
You can monitor for specific message IDs in a MONITOR group by listing the message IDs in an ON-EXCP operation code. ON-EXCP is similar to ON-ERROR, but with ON-EXCP, you list the message IDs to be monitored.

The ON-EXCP operations must precede any ON-ERROR operations in the MONITOR group.

Specify the (C) extender to limit ON-EXCP to escape messages sent to the procedure containing the ON-EXCP statement.

In the following example, the MONITOR group has two ON-EXCP blocks and one ON-ERROR block.


MONITOR;
ON-EXCP 'ABC1234' : 'ABC2345';
   // handle exception messages
ON-EXCP 'DEF1234';
   // handle another exception message
ON-ERROR 222;
   // handle pointer-not-set
ENDMON;
See ON-EXCP (On Exception).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2022.

This enhancement is also available in 7.3 with a compile-time PTF and a runtime PTF.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New built-in functions %MAXARR and %MINARR
You can find the index of the maximum value or minimum value in an array by using %MAXARR or %MINARR.
In the following example
  1. After the assignment from %LIST, the maximum value in the array is 'Yellow' (array1(2)). The minimum value is 'Blue' (array1(3)).
  2. %MAXARR(array1) returns 2.
  3. %MINARR(array1) returns 3. When %MINARR(array1) is used as an index for array1, the value assigned to minVal is 'Blue'.

DCL-S array1 VARCHAR(10) DIM(3);
DCL-S i INT(10);
DCL-S minVal LIKE(array1);

array1 = %LIST('Red' : 'Yellow' : 'Blue'); //  1 

i = %MAXARR(array1); //  2 
// i = 2

minVal = array1(%MINARR(array1)); //  3 
// minVal = 'Blue'

See %MAXARR and %MINARR (Maximum or Minimum Element in an Array).

This enhancement is available with a compile-time PTF in the last half of the year 2021.

This enhancement is also available in 7.3 with a compile-time PTF.

Sort an array data structure by more than one subfield
Use %FIELDS to list the subfields for sorting an array data structure.

In the following example, data structure array info is sorted by subfields dueDate and orderId. To determine the required order of two elements of info, subfield dueDate is compared first. If the value of dueDate is equal in the two elements, then subfield orderId is used to determine the order of the two elements of info.

info(2).dueDate is greater than info(3).dueDate so it is not necessary to compare the second subfield orderId to determine the relative order of elements 2 and 3.

info(1).dueDate is equal to info(3).dueDate so info(1).orderId is compared to info(3).orderId to determine the relative order of elements 1 and 3.


DCL-DS info QUALIFIED DIM(3);
   orderId packed(5);
   dueDate DATE(*ISO);
   quantity int(10);
END-DS;

info(1).orderId = 23456;
info(1).dueDate = D'2021-09-08';
info(1).quantity = 5;

info(2).orderId = 12345;
info(2).dueDate = D'2021-10-08';
info(2).quantity = 3;

info(3).orderId = 12345;
info(3).dueDate = D'2021-09-08';
info(3).quantity = 25;

SORTA info %FIELDS(dueDate : orderId);

// info(1).orderId = 12345
// info(1).dueDate = D'2021-09-08'
// info(1).quantity = 25
//
// info(2).orderId = 23456
// info(2).dueDate = D'2021-09-08'
// info(2).quantity = 5
//
// info(3).orderId = 12345
// info(3).dueDate = D'2021-10-08'
// info(3).quantity = 3

See %FIELDS (Subfields for sorting).

This enhancement is available with a compile-time PTF in the last half of the year 2021.

This enhancement is also available in 7.3 with a compile-time PTF.

See the value of named constants in the debugger
Specify Control keyword DEBUG(*CONSTANTS) to enable viewing the value of named constants in the debugger.

CTL-OPT DEBUG(*CONSTANTS);

See DEBUG{(*DUMP | *INPUT | *RETVAL | *XMLSAX | *NO | *YES)}.

This enhancement is available with a compile-time PTF in the last half of the year 2021. A PTF is also needed for the debugger at compile-time and runtime. This enhancement is also available in 7.3 with a compile-time PTF and a debugger PTF.
Warning: You must ensure that the debugger PTF is applied on any system where the program is restored. See https://www.ibm.com/support/pages/rpg-cafe for PTF details.
New built-in functions %LOWER and %UPPER
You can convert the case of a character or UCS-2 string to lower case by using the %LOWER built-in function or to upper case by using the built-in function %UPPER.

You can limit the conversion to only part of the string by specifying the start and length for the conversion.

In the following example, the characters following the first character are converted to lower case.

DCL-S string VARCHAR(20);

string = %LOWER('GÖTEBORG' : 2);
// string = "Göteborg"

See %LOWER and %UPPER (Convert to Lower or Upper Case).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2021.

This enhancement is also available in 7.3 with compile-time and runtime PTFs.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

New built-in function %SPLIT
You can split a string into a temporary array of substrings by using %SPLIT.

By default, the string is split at blanks. You can specify a second parameter with the characters you want to split at.

In the following examples, the result of %SPLIT is assigned to an array.

  1. In the first assignment, the string is split at blanks.
  2. In the second assignment, the string is split at either asterisks or blanks.

DCL-S array VARCHAR(20) DIM(10);

array = %SPLIT(' **One** **Two** **Three** '); //  1 
// array(1) = '**One**'
// array(2) = '**Two**'
// array(3) = '**Three**'

array = %SPLIT(' **One** **Two** **Three** ' : ' *');  //  2 
// array(1) = 'One'
// array(2) = 'Two'
// array(3) = 'Three'

See %SPLIT (Split String into Substrings).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2021.

This enhancement is also available in 7.3 with compile-time and runtime PTFs.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

A new option *STRICTKEYS is added to the EXPROPTS Control keyword.
When EXPROPTS(*STRICTKEYS) is specified, the rules are more strict for specifying the search argument for keyed file operations by using a list of keys or %KDS.

See *STRICTKEYS.

This enhancement is available with a compile-time PTF in the first half of the year 2021.

This enhancement is also available in 7.3 with a compile-time PTF.

New built-in function %RANGE
You can check whether a value is in the range of two other values by using the %RANGE built-in function.
In the following example, the IF statement is true if num is greater than or equal to 1 and less than or equal to 10.

DCL-S num PACKED(15:5);

IF num IN %RANGE(1 : 10);
   ...
ENDIF;

See %RANGE (lower-limit : upper-limit).

This enhancement is available with a compile-time PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with a compile-time PTF.

New built-in function %LIST
You can define a temporary array by using built-in function %LIST. %LIST is allowed in calculations anywhere an array is allowed except SORTA, %LOOKUPxx, or %SUBARR.
In the following example, the first four elements of the libraries array are assigned from the values in the %LIST built-in function. The first element of libraries is assigned the value 'QGPL', the second element is assigned the value of variable currentUserProfile and so on.

DCL-S libraries CHAR(10) DIM(10);

libraries = %LIST ('QGPL'
                 : currentUserProfile
                 : 'QTEMP'
                 : getDevLib ());

See %LIST (item { : item { : item ... } } ).

This enhancement is available with a compile-time PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with a compile-time PTF.

New operation code FOR-EACH
The FOR-EACH operation code begins a group of operations that iterates through the elements of an array, %LIST, or %SUBARR.

The first operand of FOR-EACH is a variable that receives the value of the current element in the array or %LIST.

The loop ends with the ENDFOR operation code.

In the following example, each element of the filenames array is processed in the FOR-EACH group. Within the group of operation codes between the FOR-EACH operation and the ENDFOR operation, the file variable has the value of the current element of the filenames array.

DCL-S filenames CHAR(10) DIM(10);
DCL-S file CHAR(10);
DCL-S numFilenames INT(10);
...
FOR-EACH file in %SUBARR(filenames : 1 : numFilenames);
   process (file);
ENDFOR;

See FOR-EACH (For Each).

This enhancement is available with a compile-time PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with a compile-time PTF.

New IN operator
The IN operator is used to determine whether an item is in an array or %LIST, or in a range.

IF item IN %RANGE(lower_limit : upper_limit);
   ...
ENDIF;
IF item IN myArray;
   ...
ENDIF;

IF item IN %LIST(item1 : item2 : ...);
ENDIF;

See IN operator.

This enhancement is available with a compile-time PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with a compile-time PTF.

Allow blanks for built-in functions that convert character to numeric
A new option *ALWBLANKNUM is added to the EXPROPTS Control keyword.

When EXPROPTS(*ALWBLANKNUM) is specified, the numeric conversion built-in functions %DEC, %DECH, %FLOAT, %INT, %INTH, %UNS, and %UNSH, a blank character value is allowed. These built-in functions return zero if the character operand is blank or it has a length of zero. For DATA-INTO and XML-INTO, if the value for a numeric field is blank or empty, a value of zero is placed in the value.

In the following example, the %DEC operation does not fail due to a blank value because EXPROPTS(*ALWBLANKNUM) is specified.

CTL-OPT EXPROPTS(*ALWBLANKNUM);

DCL-S num PACKED(15:5);
DCL-S string CHAR(10) INZ(*BLANKS);

num = %DEC(string : 63 : 15);

See EXPROPTS(*MAXDIGITS | *RESDECPOS | *ALWBLANKNUM | *USEDECEDIT) and Rules for converting character values to numeric values using built-in functions.

This enhancement is available with a compile-time PTF and a runtime PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with a compile-time PTF and a runtime PTF.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Allow thousands separators for built-in functions that convert character to numeric
A new option *USEDECEDIT is added to the EXPROPTS Control keyword.

When EXPROPTS(*USEDECEDIT) is specified, the numeric conversion built-in functions %DEC, %DECH, %FLOAT, %INT, %INTH, %UNS, and %UNSH interpret the period and comma characters according to the setting defined by the Control keyword DECEDIT. This keyword also affects the way the data for a numeric field is processed by DATA-INTO and XML-INTO.

By default, and with DECEDIT('.') or DECEDIT('0.'), or with DECEDIT(*JOBRUN) when the job DECFMT value is not J, the period is the decimal-point character and the comma is the digit-separator (thousands separator) character.

With DECEDIT(',') or DECEDIT('0,'), or with DECEDIT(*JOBRUN) when the job DECFMT value is J, the comma is the decimal-point character and the period is the digit-separator.

In the following example
  • Keyword EXPROPTS(*USEDECEDIT) is specified.
  • Keyword DECEDIT keyword is not specified, so the decimal-point character defaults to the period and the digit-separator character defaults to the comma.
  • The string '1,234,567.89' is allowed for %DEC. The commas are ignored because the comma is the digit-separator character.
  • The %DEC built-in function returns 1234567.89.

CTL-OPT EXPROPTS(*USEDECEDIT);

DCL-S num PACKED(15:5);

num = %DEC('1,234,567.89' : 15 : 5);

See EXPROPTS(*MAXDIGITS | *RESDECPOS | *ALWBLANKNUM | *USEDECEDIT) and Rules for converting character values to numeric values using built-in functions.

This enhancement is available with a compile-time PTF and a runtime PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with compile-time and runtime PTFs.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Optionally require prototypes for the main procedure and exported procedures
Parameter REQPREXP is added to the CRTBNDRPG and CRTRPGMOD commands to control how the compiler responds when no prototype is specified for an exported procedure. Additionally, the keyword REQPREXP can be specified as a Control Specification keyword.

The default for the parameter is *NO.

With the *WARN level, the compiler issues a warning diagnostic message.

With the *REQUIRE level, the compiler issues a severe diagnostic message, which causes the compile to fail.

You can specify keyword REQPROTO(*NO) for an exported procedure or for the procedure interface of the cycle-main procedure to indicate that a prototype is never required for the procedure.

See REQPREXP(*NO | *WARN | *REQUIRE), REQPROTO(*NO) for exported procedures, and REQPROTO(*NO) for the procedure interface of the cycle-main procedure.

This enhancement is available with several compile-time PTFs in the last half of the year 2020.

This enhancement is also available in 7.3 with compile-time PTFs.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

See or change the return value from a procedure while debugging
If Control keyword DEBUG(*RETVAL) is specified, you can evaluate special variable _QRNU_RETVAL to see or change the value that the procedure will return.
Set a breakpoint on the last statement of the procedure to view or change the value of this variable.
  • In free-form code, set the breakpoint on the END-PROC statement.
  • In fixed-form code, set the breakpoint on the Procedure-End specification.
For example, a programmer is debugging the following procedure.
  1. The procedure returns the value 'abcde'.
  2. The programmer sets a breakpoint on the END-PROC statement.
  3. In the debug session, the programmer displays the return value.

CTL-OPT DEBUG(*RETVAL);
...
DCL-PROC myProc;
   DCL-PI *n CHAR(10) END-PI;

   RETURN 'abcde';  1 
END-PROC;           2 
  1. In the debug session at the END-PROC statement, the programmer displays the return value.
  2. The programmer changes the return value to '12345'.
  3. The value '12345' is returned from the procedure.

> EVAL _qrnu_retval                     1 
  _QRNU_RETVAL = 'abcde     '
> EVAL _qrnu_retval = '12345'           2 
  _QRNU_RETVAL = '12345' = '12345     '

See DEBUG{(*DUMP | *INPUT | *RETVAL | *XMLSAX | *NO | *YES)}.

This enhancement is available with a compile-time PTF in the last half of the year 2020.

This enhancement is also available in 7.3 with a compile-time PTF.

%TIMESTAMP to return microsecond precision
%TIMESTAMP() now returns a timestamp with microsecond precision.

If you specify %TIMESTAMP(*UNIQUE), the returned timestamp has a nonzero value for all 12 fractional digits. The first 6 fractional seconds provide microsecond precision. The final 6 digits are used to create a unique timestamp.

See %TIMESTAMP (Convert to Timestamp).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2020.

This enhancement is also available in 7.3 with compile-time and runtime PTFs.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

A variable or expression is allowed for the second parameter of %KDS
The second parameter of %KDS is the number of keys to use for the keyed operation. You can now specify a variable or expression for the second parameter.

DCL-F myfile KEYED;
DCL-DS keys LIKEREC(myRec : *KEY);
DCL-S numKeys INT(10);

numKeys = 3;
CHAIN %KDS(keys : numKeys) myRec;
READE %KDS(keys : numKeys - 1) myRec;
See %KDS (Search Arguments in Data Structure).

This enhancement is available with a compile-time PTF and a runtime PTF in the first half of the year 2020.

This enhancement is also available in 7.3 with compile-time and runtime PTFs.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Qualified name for the LIKEDS keyword
You can now specify a qualified name for the LIKEDS keyword. In the following example
  1. Data structure subfield employees is defined directly in data structure employee_info.
  2. The LIKEDS keyword for the parameter for procedure check_employee is defined by using the LIKEDS keyword to define the parameter the same as the qualified subfield employee_info.employeeds.

DCL-DS employee_info QUALIFIED;
   num_employees INT(10);
   DCL-DS employees DIM(20);  //  1 
      name VARCHAR(25);
      salary PACKED(7:2);
   END-DS;
END-DS;
DCL-PR check_employee IND;
   employee LIKEDS(employee_info.employees);  //  2 
END-PI;
See Specifying LIKEDS with a qualified data structure name.

This enhancement is available with a compile-time PTF in the last half of the year 2019.

This enhancement is also available in 7.3 with a compile-time PTF.

*ON and *OFF can be logical expressions
You can now use *ON and *OFF directly in conditional statements. For example, if you want an infinitely DOW loop, you can code "DOW *ON".

   DOW *ON;
    ...
   ENDDO;

This enhancement is available with a compile-time PTF in the last half of the year 2019.

This enhancement is also available in 7.3 with a compile-time PTF.

New operation code DATA-GEN
DATA-GEN generates a structured document, such as JSON or CSV, from an RPG variable. It requires a generator to generate the document. The DATA-GEN operation calls the generator, passing it the names and values of the RPG variables, and the generator passes the text for the structured document back to the DATA-GEN operation, which places the information into the output file or the output RPG variable.

DCL-DS product QUALIFIED;
   name VARCHAR(25);
   id CHAR(10);
   price PACKED(9 : 2);
END-DS product;

DATA-GEN product %DATA('ProductInfo.JSON' : 'doc=file')
                  %GEN('MYLIB/MYJSONGEN');
See DATA-GEN (Generate a Document from a Variable), %DATA (document {:options}), %GEN (generator {: options}).

This enhancement is available with a compile-time PTF and a runtime PTF in the last half of the year 2019.

This enhancement is also available in 7.3 with compile-time and runtime PTFs.

Warning: You must ensure that the runtime PTF is applied on any system where the program is restored.

If you compile your program with TGTRLS(*V7R3M0), different runtime PTFs are required for 7.3 and 7.4 systems.

See https://www.ibm.com/support/pages/rpg-cafe for PTF details.

Overloaded prototypes
The OVERLOAD keyword defines a list of other prototypes that can be called by using the name of the prototype with the OVERLOAD keyword. When the prototype with the OVERLOAD keyword is used in a call operation, the compiler uses the parameters that are specified for the call to determine which of the candidate prototypes that are listed in the OVERLOAD keyword to call.
In the following example, FORMAT is defined with the OVERLOAD keyword.
  1. For the first call to FORMAT, the parameter has type Date, so FORMAT_DATE is called.
  2. For the second call to FORMAT, the parameter has type Time, so FORMAT_TIME is called.
  3. For the second call to FORMAT, the parameters have type Character, so FORMAT_MESSAGE is called.

DCL-PR format_date VARCHAR(100);
   dateParm DATE(*ISO) CONST;
END-PR;
DCL-PR format_time VARCHAR(100);
   timeParm TIME(*ISO) CONST;
END-PR;
DCL-PR format_message VARCHAR(100);
   msgid CHAR(7) CONST;
   replacement_text VARCHAR(100) CONST OPTIONS(*NOPASS);
END-PR;
DCL-PR format VARCHAR(100) OVERLOAD(format_time : format_date : format_message);
DCL-S result varchar(50);

result = format(%date());              //  1 
result = format(%time());              //  2 
result = format('MSG0100' : filename); //  3 
See OVERLOAD(prototype1 { : prototype2 ...}).

This enhancement is available with a compile-time PTF in the last half of the year 2019.

This enhancement is also available in 7.3 with a compile-time PTF.

OPTIONS(*EXACT) for prototyped parameters
When OPTIONS(*EXACT) is specified for a prototyped parameter, additional rules apply to ensure that the called procedure receives the same value as the passed parameter. For example, without OPTIONS(*EXACT), the compiler allows the passed parameter to be longer than the prototyped parameter, and it allows a data structure to be passed that is related by LIKEDS to a different data structure from the passed parameter. With OPTIONS(*EXACT), the passed parameter cannot be longer than the prototyped parameter, and if the prototyped parameter is defined with LIKEDS keyword, the passed parameter must be related by LIKEDS to the same data structure.

In the following example, field fld10 can be passed to parameter parm5 of prototype p1, but the called procedure receives the value "abcde" instead of the full value 'abcdefghij' of fld10.

Field fld10 cannot be passed to parameter parm5Exact of prototype p2 because the length, 10, of fld10 is greater than the length, 5, of the prototyped parameter parm5Exact.


dcl-pr p1;
   parm5 char(5);
end-pr;
dcl-pr p2;
   parm5Exact char(5) OPTIONS(*EXACT);
end-pr;
dcl-s fld10 char(10) inz('abcdefghij');

p1 (fld10);
p2 (fld10);  // Error
See OPTIONS(*EXACT).

This enhancement is available with a compile-time PTF in the last half of the year 2019.

This enhancement is also available in 7.3 with a compile-time PTF.

Table 1. Changed Language Elements Since 7.4: Built-in functions
Element Description
%CHECK The last parameter can be *NATURAL or *STDCHARSIZE. See %CHECK (Check Characters)
%CHECKR The last parameter can be *NATURAL or *STDCHARSIZE. See %CHECKR (Check Reverse)
%KDS A variable can now be specified as the second parameter of %KDS See %KDS (Search Arguments in Data Structure).
%LOWER The last parameter can be *NATURAL or *STDCHARSIZE. See %LOWER (Convert to Lower Case)
%REPLACE The last parameter can be *NATURAL or *STDCHARSIZE. See %REPLACE (Replace Character String)
%SCAN The last parameter can be *NATURAL or *STDCHARSIZE. See %SCAN (Scan for Characters)
%SCANR The last parameter can be *NATURAL or *STDCHARSIZE. See %SCANR (Scan Reverse for Characters)
%SCANRPL The last parameter can be *NATURAL or *STDCHARSIZE. See %SCANRPL (Scan and Replace Characters)
%SPLIT
  • The last parameter can be *NATURAL or *STDCHARSIZE.
  • The third parameter can be *ALLSEP.
See %SPLIT (Split String into Substrings)
%SUBST The last parameter can be *NATURAL or *STDCHARSIZE. See %SUBST (Get Substring)
%TARGET The first parameter can be *CTLBDY, *EXT, or *PGMBDY. See %TARGET (program-or-procedure { : offset } )
%TIMESTAMP %TIMESTAMP() returns a value with microsecond precision. %TIMESTAMP(*UNIQUE) returns a unique timestamp. See %TIMESTAMP (Convert to Timestamp).
%TRIM, %TRIML, %TRIMR The last parameter can be *NATURAL or *STDCHARSIZE. See %TRIM (Trim Characters at Edges)
%UPPER The last parameter can be *NATURAL or *STDCHARSIZE. See %UPPER (Convert to Upper Case)
%XLATE The last parameter can be *NATURAL or *STDCHARSIZE. See %XLATE (Translate)
Table 2. Changed Language Elements Since 7.4: Control specification keywords
Element Description
DEBUG keyword
  • Specify parameter *RETVAL if you want to debug the return value from a procedure.
  • Specify parameter *CONSTANTS if you want to view the value of named constants in the debugger.
See DEBUG{(*DUMP | *INPUT | *RETVAL | *XMLSAX | *NO | *YES)}.
EXPROPTS keyword Parameters *ALWBLANKNUM, *USEDECEDIT, and *STRICTKEYS can now be specified for the EXPROPTS keyword. See EXPROPTS(*MAXDIGITS | *RESDECPOS | *ALWBLANKNUM | *USEDECEDIT).
PGMINFO keyword Parameter *V8 can now be specified for the PGMINFO keyword. See PGMINFO(*PCML | *NO | *DCLCASE { : *MODULE { : *Vx }}).
Table 3. Changed Language Elements Since 7.4: Definitions
Element Description
CONST Allowed for standalone fields and data structures See Constant variables.
LIKEDS Allows a qualified name See Specifying LIKEDS with a qualified data structure name.
OPTIONS(*EXACT) The OPTIONS keyword for a prototyped parameter can have value *EXACT, indicating that additional rules must be applied by the compiler when checking the validity of the passed parameter. See OPTIONS(*EXACT).
OPTIONS(*CONVERT) The OPTIONS keyword for a prototyped parameter can have value *CONVERT, indicating that the data type of the passed parameter can be different from the data type of the prototyped parameter. See OPTIONS(*CONVERT).
Table 4. Changed Language Elements Since 7.4: Operation codes
Element Description
SELECT operation code The SELECT operation code can have an operand. See SELECT (Begin a Select Group).
SND-MSG operation code The SND-MSG operation code allows the following new message types: *COMP, *DIAG, *NOTIFY, and *STATUS. See SND-MSG (Send a Message to the Joblog).
SORTA operation code %FIELDS can be specified with SORTA to list the subfields for sorting. See %FIELDS (Subfields for sorting).
Table 5. New Language Elements Since 7.4: Directives
Element Description
/CHARCOUNT Specify /CHARCOUNT NATURAL to set the natural-character-size mode for processing strings. Specify /CHARCOUNT STDCHARSIZE to set the standard-character-size mode for processing strings. See /CHARCOUNT NATURAL | STDCHARSIZE.
/OVERLOAD Specify /OVERLOAD DETAIL to obtain detailed information about calls to overloaded prototypes in the statements following the directive. Specify /OVERLOAD NODETAIL to stop obtaining the detailed information. See /OVERLOAD DETAIL | NODETAIL.
Table 6. New Language Elements Since 7.4: File specification keywords
Element Description
CHARCOUNT keyword This keyword controls the movement of data from RPG fields to the output buffer and key buffer used for the file operations for specified by the CHARCOUNTTYPES Control keyword. See CHARCOUNT(*NATURAL | *STDCHARSIZE).
Table 7. New Language Elements Since 7.4: Definition specification keywords
Element Description
OVERLOAD Defines candidate prototypes that can be called by the name of the overloaded prototype (the prototype with the OVERLOAD keyword) See OVERLOAD(prototype1 { : prototype2 ...}).
REQPROTO REQPROTO(*NO) can be specified on the procedure interface for the cycle-main procedure to indicate that a prototype is never required. See REQPROTO(*NO).
Table 8. New Language Elements Since 7.4: Control specification keywords
Element Description
CHARCOUNTTYPES Sets the data types affected by the CHARCOUNT mode. See CHARCOUNTTYPES(*UTF8 *UTF16 *JOBRUN *MIXEDEBCDIC *MIXEDASCII).
CHARCOUNT Sets the initial CHARCOUNT mode. See CHARCOUNT(*NATURAL | *STDCHARSIZE).
REQPREXP Controls whether prototypes are required for the main procedure and exported subprocedures. See REQPREXP(*NO | *WARN | *REQUIRE).
Table 9. New Language Elements Since 7.4: Expression Operators
Element Description
IN Used in a binary conditional statement that tests whether the first operand is in the second operand. See IN operator.
Table 10. New Language Elements Since 7.4: Built-in functions
Element Description
%CHARCOUNT Returns the number of natural characters in the string See %CHARCOUNT (Return the Number of Characters).
%CONCAT Concatenates strings with a separator See %CONCAT (Concatenate with Separator).
%CONCATARR Concatenates arrays with a separator See %CONCATARR (Concatenate Array Elements with Separator).
%GEN Specifies the generator for the DATA-GEN operation code See %GEN (generator {: options}).
%LEFT Returns the leftmost characters in a string See %LEFT (Get Leftmost Characters).
%LIST Returns a temporary array See %LIST (item { : item { : item ... } } ).
%LOWER Returns the input string converted to lower case. See %LOWER (Convert to Lower Case).
%MAXARR Returns the index of the maximum value in the array See %MAXARR and %MINARR (Maximum or Minimum Element in an Array).
%MINARR Returns the index of the minimum value in the array See %MAXARR and %MINARR (Maximum or Minimum Element in an Array).
%MSG Specifies the message ID for SND-MSG See %MSG (message-id : message-file { : replacement-text } ).
%PASSED Checks whether a parameter was passed and not omitted See %PASSED (Return Parameter-Passed Condition).
%OMITTED Checks whether *OMIT was passed for a parameter See %OMITTED (Return Parameter-Omitted Condition).
%RANGE Specifies the range to check with the IN operator See %RANGE (lower-limit : upper-limit).
%RIGHT Returns the rightmost characters in a string See %RIGHT (Get Rightmost Characters).
%SPLIT Returns an array of substrings See %SPLIT (Split String into Substrings).
%TARGET Specifies the target program or procedure for SND-MSG See %TARGET (program-or-procedure { : offset } ).
%UPPER Returns the input string converted to upper case. See %UPPER (Convert to Upper Case).
Table 11. New Language Elements Since 7.4: Free-form statements
Element Description
DCL-ENUM Begins a free-form enumeration definition See Free-Form Enumeration Definition.
END-ENUM Ends a free-form enumeration definition See Free-Form Enumeration Definition.
Table 12. New Language Elements Since 7.4: Operation codes
Element Description
DATA-GEN Generate a structured document from an RPG variable. See DATA-GEN (Generate a Document from a Variable).
FOR-EACH Iterate through the items in an array, %LIST, or sub-array See FOR-EACH (For Each).
ON-EXCP Monitor for a specific escape message ID See ON-EXCP (On Exception).
SND-MSG Send a message to the joblog See SND-MSG (Send a Message to the Joblog).
WHEN-IN In a SELECT group, it is true if the operand for the SELECT statement is in the operand for the WHEN-IN statement See WHEN-IN (When the SELECT Operand is IN the WHEN-IN Operand).
WHEN-IS In a SELECT group, it is true if the operand for the SELECT statement is equal to the operand for the WHEN-IS statement See WHEN-IS (When the SELECT Operand is Equal to the WHEN-IS Operand).
Table 13. New Language Elements Since 7.4: Procedure specification keywords
Element Description
REQPROTO REQPROTO(*NO) indicates that a prototype is never required for the exported procedure. See REQPROTO(*NO).