Built-in functions are similar to operation codes in that they perform operations on data you specify. Built-in functions can be used in expressions. Additionally, constant-valued built-in functions can be used in named constants. These named constants can be used in any specification.
All built-in functions have the percent symbol (%) as their first character. The syntax of built-in functions is:
function-name{(argument{:argument...})}
Arguments for the function may be variables, constants, expressions, a prototyped procedure, or other built-in functions. An expression argument can include a built-in function. The following example illustrates this.
CL0N01Factor1+++++++Opcode(E)+Extended-factor2++++++++++++++++++++++++++
*
* This example shows a complex expression with multiple
* nested built-in functions.
*
* %TRIM takes as its argument a string. In this example, the
* argument is the concatenation of string A and the string
* returned by the %SUBST built-in function. %SUBST will return
* a substring of string B starting at position 11 and continuing
* for the length returned by %SIZE minus 20. %SIZE will return
* the length of string B.
*
* If A is the string ' Toronto,' and B is the string
* ' Ontario, Canada ' then the argument for %TRIM will
* be ' Toronto, Canada ' and RES will have the value
* 'Toronto, Canada'.
*
C EVAL RES = %TRIM(A + %SUBST(B:11:%SIZE(B) - 20))
See the individual built-in function descriptions for details on what arguments are allowed.
Unlike operation codes, built-in functions return a value rather than placing a value in a result field. The following example illustrates this difference.
CL0N01Factor1+++++++Opcode(E)+Factor2+++++++Result++++++++Len++D+HiLoEq....
*
* In the following example, CITY contains the string
* 'Toronto, Ontario'. The SCAN operation is used to locate the
* separating blank, position 9 in this illustration. SUBST
* places the string 'Ontario' in field TCNTRE.
*
* Next, TCNTRE is compared to the literal 'Ontario' and
* 1 is added to CITYCNT.
*
C ' ' SCAN CITY C
C ADD 1 C
C SUBST CITY:C TCNTRE
C 'Ontario' IFEQ TCNTRE
C ADD 1 CITYCNT
C ENDIF
*
* In this example, CITY contains the same value, but the
* variable TCNTRE is not necessary since the %SUBST built-in
* function returns the appropriate value. In addition, the
* intermediary step of adding 1 to C is simplified since
* %SUBST accepts expressions as arguments.
*
C ' ' SCAN CITY C
C IF %SUBST(CITY:C+1) = 'Ontario'
C EVAL CITYCNT = CITYCNT+1
C ENDIF
Note that the arguments used in this example (the variable CITY and the expression C+1) are analogous to the factor values for the SUBST operation. The return value of the function itself is analogous to the result. In general, the arguments of the built-in function are similar to the factor 1 and factor 2 fields of an operation code.
Another useful feature of built-in functions is that they can simplify maintenance of your code when used on the definition specification. The following example demonstrates this feature.
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords++++++++++++++++++++++++++
*
* In this example, CUSTNAME is a field in the
* externally described data structure CUSTOMER.
* If the length of CUSTNAME is changed, the attributes of
* both TEMPNAME and NAMEARRAY would be changed merely by
* recompiling. The use of the %SIZE built-in function means
* no changes to your code would be necessary.
*
D CUSTOMER E DS
D DS
D TEMPNAME LIKE(CUSTNAME)
D NAMEARRAY 1 OVERLAY(TEMPNAME)
D DIM(%SIZE(TEMPNAME))
Built-in functions can be used in expressions on the extended factor 2 calculation specification and with keywords on the definition specification. When used with definition specification keywords, the value of the built-in function must be known at compile time and the argument cannot be an expression.
The following table lists the built-in functions, their arguments, and the value they return.
Name | Arguments | Value Returned |
---|---|---|
%ABS | numeric expression | absolute value of expression |
%ADDR | variable name {: *DATA} | address of variable, or address of the data portion of a variable-length variable |
%ALLOC | number of bytes to allocate | pointer to allocated storage |
%BITAND | character, numeric | bit wise ANDing of the bits of all the arguments |
%BITNOT | character, numeric | bit-wise reverse of the bits of the argument |
%BITOR | character, numeric | bit-wise ORing of the bits of all the arguments |
%BITXOR | character, numeric | bit-wise exclusive ORing of the bits of the two arguments |
%CHAR | graphic, UCS-2, numeric, date, time, or timestamp expression {: date, time, or timestamp format} | value in character format |
%CHECK | comparator string:string to be checked{:start position} | first position of a character that is not in the comparator string, or zero if not found |
%CHECKR | comparator string:string to be checked{:start position} | last position of a character that is not in the comparator string, or zero if not found |
%DATE | {value {: date format}} | the date that corresponds to the specified value, or the current system date if none is specified |
%DAYS | number of days | number of days as a duration |
%DEC |
numeric expression {:digits:decpos} character expression: digits:decpos date, time or timestamp expression {:format} |
value in packed numeric format |
%DECH |
numeric or character expression: digits:decpos |
half-adjusted value in packed numeric format |
%DECPOS | numeric expression | number of decimal digits |
%DIFF | date or time expression: date or time expression: unit | difference between the two dates, times, or timestamps in the specified unit |
%DIV | dividend: divisor | the quotient from the division of the two arguments |
%EDITC | non-float numeric expression:edit code {:*CURSYM | *ASTFILL | currency symbol} | string representing edited value |
%EDITFLT | numeric expression | character external display representation of float |
%EDITW | non-float numeric expression:edit word | string representing edited value |
%ELEM | array, table, or multiple occurrence data structure name | number of elements or occurrences |
%EOF | {file name} | '1' if the most recent cycle input, read operation, or write to a subfile (for a particular file, if specified) ended in an end-of-file or beginning-of-file condition; and, when a file is specified, if a more recent OPEN, CHAIN, SETGT or SETLL to the file was not successful |
'0' otherwise | ||
%EQUAL | {file name} | '1' if the most recent SETLL (for a particular file, if specified) or LOOKUP operation found an exact match |
'0' otherwise | ||
%ERROR | '1' if the most recent operation code with extender 'E' specified resulted in an error | |
'0' otherwise | ||
%FIELDS | list of fields to be updated | not applicable |
%FLOAT | numeric or character expression | value in float format |
%FOUND | {file name} | '1' if the most recent relevant operation (for a particular file, if specified) found a record (CHAIN, DELETE, SETGT, SETLL), an element (LOOKUP), or a match (CHECK, CHECKR, SCAN) |
'0' otherwise | ||
%GRAPH | character, graphic, or UCS-2 expression | value in graphic format |
%HANDLER | handling procedure : communication area | not applicable |
%HOURS | number of hours | number of hours as a duration |
%INT | numeric or character expression | value in integer format |
%INTH | numeric or character expression | half-adjusted value in integer format |
%KDS |
data structure containing keys {: number of keys} |
not applicable |
%LEN | any expression | length in digits or characters |
%LOOKUPxx | argument: array{:start index {:number of elements}} | array index of the matching element |
%MINUTES | number of minutes | number of minutes as a duration |
%MONTHS | number of months | number of months as a duration |
%MSECONDS | number of microseconds | number of microseconds as a duration |
%NULLIND | null-capable field name | value in indicator format representing the null indicator setting for the null-capable field |
%OCCUR | multiple-occurrence data structure name | current occurrence of the multiple-occurrence data structure |
%OPEN | file name | '1' if the specified file is open |
'0' if the specified file is closed | ||
%PADDR | procedure or prototype name | address of procedure or prototype |
%PARMS | none | number of parameters passed to procedure |
%PARMNUM | procedure-interface parameter name | number of a procedure-interface parameter |
%REALLOC | pointer: numeric expression | pointer to allocated storage |
%REM | dividend: divisor | the remainder from the division of the two arguments |
%REPLACE | replacement string: source string {:start position {:source length to replace}} | string produced by inserting replacement string into source string, starting at start position and replacing the specified number of characters |
%SCAN | search argument:string to be searched{:start position} | first position of search argument in string or zero if not found |
%SCANRPL | scan string: replacement string: source string {:scan start position {:scan length}} | string produced by replacing scan string by replacement string in source string, with the scan starting at start position for the specified length |
%SECONDS | number of seconds | number of seconds as a duration |
%SHTDN | '1' if the system operator has requested shutdown | |
'0' otherwise | ||
%SIZE | variable, array, or literal {:* ALL} | size of variable or literal |
%SQRT | numeric value | square root of the numeric value |
%STATUS | {file name} | 0 if no program or file error occurred since the most recent operation code with extender 'E' specified |
most recent value set for any program or file status, if an error occurred | ||
if a file is specified, the value returned is the most recent status for that file | ||
%STR | pointer{:maximum length} | characters addressed by pointer argument up to but not including the first x'00' |
%SUBARR | array name:start index{:number of elements} | array subset |
%SUBDT | date or time expression: unit | an unsigned numeric value that contains the specified portion of the date or time value |
%SUBST | string:start{:length} | substring |
%THIS | the class instance for the native method | |
%TIME | {value {: time format}} | the time that corresponds to the specified value, or the current system time if none is specified |
%TIMESTAMP | {(value {: timestamp format})} | the timestamp that corresponds to the specified value, or the current system timestamp if none is specified |
%TLOOKUPxx | argument: search table {: alternate table} | '*ON' if there is a match |
'*OFF' otherwise | ||
%TRIM | string {: characters to trim} | string with left and right blanks or specified characters trimmed |
%TRIML | string {: characters to trim} | string with left blanks or specified characters trimmed |
%TRIMR | string {: characters to trim} | string with right blanks or specified characters trimmed |
%UCS2 | character, graphic, or UCS-2 expression | value in UCS-2 format |
%UNS | numeric or character expression | value in unsigned format |
%UNSH | numeric or character expression | half-adjusted value in unsigned format |
%XFOOT | array expression | sum of the elements |
%XLATE | from-characters: to-characters: string {: start position} | the string with from-characters replaced by to-characters |
%XML | xml document { : options } | not applicable |
%YEARS | number of years | number of years as a duration |