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 |