February 13, 2013 - Vol 3, Issue 23
Security Workshop
Powertech - Control of your Powerful Users


Is Your JD EDWARDS Database Secure? See how SKYVIEW PARTNERS can help!








Cilasoft Security Solutions - Intelligently Engineered Security Solutions



















New Control Language Built-In Functions - January 2013

By Guy Vig and Jennifer Liu - IBM - Control Language


New Control Language Built-In Functions have been added via PTF for IBM i 7.1.  The PTF (SI49061) was approved January 25, 2013 by Jennifer Liu on the CL compiler team.

Editors Note: A Big "Thank You" to Jennifer!

Support for new trim built-in functions (i.e. %TRIM, %TRIML, and %TRIMR) was added by PTF (SI48166) last October, and SI49061 supersedes SI48166.


New built-in functions have been added to both OPM CL and ILE CL that make string handling easier and faster:
  1. %CHECK        - Check Characters
  2. %CHECKR - Check Reverse
  3. %SCAN        - Scan for Characters
  4. %TRIM        - Trim Characters at Edges
  5. %TRIML        - Trim Leading Characters
  6. %TRIMR        - Trim Trailing Characters
If you want to use these new CL built-in functions on a 7.1 system, PTF SI49061 must be loaded and applied.  Support will not be PTF'ed to 6.1 or 5.4 releases, but you can compile CL code that uses these new functions on your 7.1 system and specify TGTRLS(V6R1M0) or TGTRLS(V5R4M0) and then save the CL objects off your 7.1 system and restore them on an IBM i system running the 5.4 or 6.1 release of IBM i.

All of the above built-in functions will have almost the same behavior as the RPG built-in functions by the same name.  

Descriptions of each new built-in function:
  • %CHECK built-in function
    The check built-in function (%CHECK) returns the first position of a base string  that contains a character that does not appear in the comparator string. If all of the characters in the base string also appear in the comparator string, the function returns 0. This function can only be used within a CL program or procedure.

    The %CHECK built-in function can be used anywhere that CL supports an arithmetic expression. %CHECK can be used alone or as part of a more complex arithmetic expression. For example, %CHECK could be used to compare to a numeric CL variable in the COND parameter of an IF or WHEN command. %CHECK can also be used to set the value of a CL command parameter, if the associated command object defines the parameter with EXPR(*YES) and TYPE of *DEC, *INT2, *INT4, *UINT2, or *UINT4.

    The format of the check built-in function is shown in this example:
     
    %CHECK(comparator-string base-string [starting-position])

    The comparator string must be either a CL character variable or a character literal. The base string can be a CL character variable or *LDA. When *LDA is specified, the check function is performed on the contents of the local data area for the job. The starting position is optional and defaults to 1. Checking begins at the starting position and continues to the right until a character that is not contained in the comparator string is found. The result is always the position relative to the start of the source string even if the starting position is specified. The starting position, if specified, must be either a CL integer variable or a CL decimal variable with zero decimal positions or a numeric literal with zero decimal positions. The starting position cannot be 0 or negative. If the starting position is greater than the length of the entire base variable or the local data area, an error occurs. The length of the local data area is 1024.

  • %CHECKR built-in function
    The reverse check built-in function (%CHECKR) returns the last position of a base string  that contains a character that does not appear in the comparator string. If all of the characters in the base string also appear in the  comparator string, the function returns 0. This function can only be used within a CL program or procedure.

    The %CHECKR built-in function can be used anywhere that CL supports an arithmetic expression. %CHECKR can be used alone or as part of a more complex arithmetic expression. For example, %CHECKR could be used to compare to a numeric CL variable in the COND parameter of an IF or WHEN command. %CHECKR can also be used to set the value of a CL command parameter, if the associated command object defines the parameter with EXPR(*YES) and TYPE of *DEC, *INT2, *INT4, *UINT2, or *UINT4.

    The format of the reverse check built-in function is shown in this example:
     
    %CHECKR(comparator-string base-string [starting-position])

    The comparator string must be either a CL character variable or a character literal. The base string can be a CL character variable or *LDA. When *LDA is specified, the reverse check function is performed on the contents of the local data area for the job. The starting position is optional and defaults to the end of the string. Checking begins at the starting position and continues to the left until a character that is not contained in the comparator string is found. The result is always the position relative to the start of the source string even if the starting position is specified. The starting position, if specified, must be either a CL integer variable or a CL decimal variable with zero decimal positions or a numeric literal with zero decimal positions. The starting position cannot be 0 or negative. If the starting position is greater than the length of the entire base variable or the local data area, an error occurs. The length of the local data area is 1024.

  • %SCAN built-in function
    The scan built-in function (%SCAN) returns the first position of a search argument in another string (the source string), or 0 if it was not found. This function can only be used within a CL program or procedure.

    The %SCAN built-in function can be used anywhere that CL supports an arithmetic expression. %SCAN can be used alone or as part of a more complex arithmetic expression. For example, %SCAN could be used to compare to a numeric CL variable in the COND parameter of an IF or WHEN command. %SCAN can also be used to set the value of a CL command parameter, if the associated command object defines the parameter with EXPR(*YES) and TYPE of *DEC, *INT2, *INT4, *UINT2, or *UINT4.

    The format of the scan built-in function is shown in this example:

    %SCAN(search-argument source-string [starting-position])

    The search-argument must be either a CL character variable or a character literal. The source-string can be a CL character variable or *LDA. When *LDA is specified, the scan function is performed on the contents of the local data area for the job. The starting position  is optional and defaults to 1. Searching begins at the starting position. The result is always the position relative to the start of the source string even if the starting position is specified. The starting position, if specified, must be either a CL integer variable or a CL decimal variable with zero decimal positions or a numeric literal with zero decimal positions. And the starting position can¡¯t be 0 or negative. If the starting position is greater than the length of the entire source-string variable or the local data area, an error occurs. The length of the local data area is 1024.

  • %TRIM built-in function
    The trim built-in function (%TRIM) with one parameter produces a character string with any leading and trailing blanks removed. The trim built-in function (%TRIM) with two parameters produces a character string with any leading and trailing characters that are in the characters to trim parameter removed. This function can only be used within a CL program or procedure.

    The %TRIM built-in function can be used anywhere that CL supports a character expression. %TRIM can be used alone or as part of a more complex character expression. For example, %TRIM could be used to compare to a character CL variable in the COND parameter of an IF or WHEN command. %TRIM can also be used to set the value of a CL command parameter, if the associated command object defines the parameter with EXPR(*YES) and TYPE of *CHAR, *NAME, *SNAME, *CNAME, *PNAME, *GENERIC, *DATE, *TIME, or *X.

    The format of the trim built-in function is shown in this example:  

    %TRIM(character-variable-name [characters-to-trim])

    The trim function produces a substring from the contents of the specified CL character variable. If the characters to trim parameter is specified, it must be either a CL character variable or a character literal. If after trimming, no characters are left, the trim function produces a string of blanks with corresponding length.

  • %TRIML built-in function
    The trim left built-in function (%TRIML) with one parameter produces a character string with any leading blanks removed. The trim left built-in function (%TRIML) with two parameters produces a character string with any leading characters that are in the characters to trim parameter removed. This function can only be used within a CL program or procedure.

    The %TRIML built-in function can be used anywhere that CL supports a character expression. %TRIML can be used alone or as part of a more complex character expression. For example, %TRIML could be used to compare to a character CL variable in the COND parameter of an IF or WHEN command. %TRIML can also be used to set the value of a CL command parameter, if the associated command object defines the parameter with EXPR(*YES) and TYPE of *CHAR, *NAME, *SNAME, *CNAME, *PNAME, *GENERIC, *DATE, *TIME, or *X.

    The format of the trim left built-in function is shown in this example:

    %TRIML(character-variable-name [characters-to-trim])

    The trim left function produces a substring from the contents of the specified CL character variable. If the characters to trim parameter is specified, it must be either a CL character variable or a character literal. If after trimming, no characters are left, the trim left function produces a string of blanks with corresponding length.

  • %TRIMR built-in function
    The trim right built-in function (%TRIMR) with one parameter produces a character string with any trailing blanks removed. The trim right built-in function (%TRIMR) with two parameters produces a character string with any trailing characters that are in the characters to trim parameter removed. This function can only be used within a CL program or procedure.

    The %TRIMR built-in function can be used anywhere that CL supports a character expression. %TRIMR can be used alone or as part of a more complex character expression. For example, %TRIMR could be used to compare to a character CL variable in the COND parameter of an IF or WHEN command. %TRIMR can also be used to set the value of a CL command parameter, if the associated command object defines the parameter with EXPR(*YES) and TYPE of *CHAR, *NAME, *SNAME, *CNAME, *PNAME, *GENERIC, *DATE, *TIME, or *X.

    The format of the trim right built-in function is shown in this example:

    %TRIMR(character-variable-name [characters-to-trim])

    The trim right function produces a substring from the contents of the specified CL character variable. If the characters to trim parameter is specified, it must be either a CL character variable or a character literal. If after trimming, no characters are left, the trim right function produces a string of blanks with corresponding length.
Examples:

1. Check for any characters that are not digits (0-9):

PGM PARM(&SN)
DCL VAR(&SN) TYPE(*CHAR) LEN(10)
IF COND(%CHECK('0123456789' &SN) *NE 0) +
   THEN(SNDPGMMSG ('INVALID CHARACTER FOUND!'))

2. Figure out the length of a string which is padded at the end with some characters:

DCL VAR(&LEN) TYPE(*INT)
DCL VAR(&STRING) TYPE(*CHAR) LEN(20) VALUE('JOHN SMITH*****')
DCL VAR(&PADCHARS) TYPE(*CHAR) LEN(2) VALUE(' *')
CHGVAR VAR(&LEN) VALUE(%CHECKR(&PADCHARS &STRING))
/* &LEN will have the value 10 */

3. Search characters from the local data area (*LDA):

DCL VAR(&POS) TYPE(*UINT) LEN(2)
CHGVAR VAR(&POS) VALUE(%SCAN('Escape' *LDA))

4. Trimming blanks:

DCL VAR(&FIRSTNAME) TYPE(*CHAR) VALUE('   JOHN  ')
DCL VAR(&LASTNAME) TYPE(*CHAR) VALUE('   SMITH  ')
DCL VAR(&NAME) TYPE(*CHAR) LEN(10)
/* &NAME will have the value 'JOHN SMITH' */
CHGVAR VAR(&NAME) VALUE(%TRIM(&FIRSTNAME) *BCAT %TRIM(&LASTNAME))

5. Trimming leading characters specified in a literal string:

DCL VAR(&PRICE) TYPE(*CHAR) VALUE('     $5.27')
DCL VAR(&TRIMMED) TYPE(*CHAR) LEN(5)
DCL VAR(&DEC) TYPE(*DEC) LEN(3 2)
/* &TRIMMED will have the value '5.27 ' */
CHGVAR VAR(&TRIMMED) VALUE(%TRIML(&PRICE '$ '))
/* &DEC will have the value 5.27 */
CHGVAR VAR(&DEC) VALUE(&TRIMMED)

6. Trimming trailing characters specified in a CL variable:

DCL VAR(&NAME) TYPE(*CHAR) LEN(10) VALUE('12345***  ')
DCL VAR(&TCHAR) TYPE(*CHAR) LEN(2) VALUE('* ')
IF COND(%TRIMR(&NAME &TCHAR) *EQ '12345') +
   THEN(SNDPGMMSG ('EQUAL!'))



About the Authors



Guy Vig, "MR CL" - IBM i CL Architect

 




Jennifer Liu - IBM - "Queen" of IBM i Control Language



 
Training from The 400 School