Specifies a user-defined function.
Character label that is used to identify and call the function from within the PSL program. The name cannot be the same as a PSL built-in function or a PSL variable.
Up to 20 optional PSL variables that are passed to the function as parameters when it is called for execution. The argument list can be a NULL entry if no variables are passed to the function, a single argument, or several arguments separated by commas. Optional ellipses indicating that the function will accept an additional variable number of arguments. This variable portion of the argument list is processed using the va_start() and va_arg() PSL built-in functions. For more information, see va_arg() and va_start().
One or more PSL statements that define the action the function performs.
function statement provides user-defined functions within PSL programs similar to those available in the C programming language. The function keyword is required in a user function definition.
Two additional keywords,
return, are optional:
localdeclares variables that will be used only within the function.
returnidentifies function output that is returned to the caller
Functions must be defined before their first use, and the correct argument list must be passed in a
function call. A
function call always returns a character that represents a character string or numeric value. (All data types are represented within PSL as character strings.)
Arguments are passed by value to parameters (that is, local copies are created from the arguments' data passed in), and thus changing a parameter will not affect the value of the argument. Function parameters are local to a function and can be named the same as global variables (or the same as parameters of other functions).
If a function definition appears in the middle of executable statements and control flow reaches that definition from above, the definition is skipped as a comment is skipped. The only way to enter the body of a function is to explicitly call it. The function definitions serve merely to define a function and are not invoked until called. Hence, it is possible to place executable code above, below, and between function definitions.
There are three ways to exit a user-defined function:
- return with a return value
- return without a return value (return value = NULL string)
- fall through to the bottom right brace (return omitted, no return value)
PSL does not interpret falling through the bottom of a function as an error condition, although it is not recommend relying on fall-through for a function where the return value is used.
PSL produces a compilation warning similar to that produced by C compilers when it encounters return statements within a function of which some have return values and while others do not. Having multiple exit points in a function that exit in different ways may indicate confusion over whether the function was defined to perform an action or return a value.
BMC Software recommends that you design functions that return a value to explicitly return a NULL string when the functions have no other value to return. This is preferred to exiting a function with a
return statement and no return value.
Functions with Variable Length Argument Lists
The use of the ellipsis (...) in a
function() statement indicates that the function will accept zero or more additional arguments. A
function() statement that contains ellipses is said to be a variable length argument list function.
Following is an example of a variable argument list function that also has two fixed arguments, argno1 and argno2:
Because argno1 and argno2 are fixed arguments, they must be included in every call to
my_func(). The ellipsis, however, indicates that any number of additional arguments may also be included in a call to
my_func(). For example, the following are legal calls to
my_func() because each includes two or more arguments:
The following, however, is not a valid call to
my_func() because it does not include the minimum two fixed arguments:
You can process a variable argument list within your
function() statement using the PSL
va_start()function initializes the variable argument list to return the first argument. You can use the
va_start()function multiple times within a
function()statement to initialize the variable argument list, allowing the
function()statement to traverse the variable argument list more than one time.
va_arg()function returns the current argument in the variable argument list and increments. Successive
va_arg()function calls return successive arguments from the variable argument list until all arguments have been returned. Unless you call the
va_start()function to reinitialize the variable argument list, the
va_arg()function returns a NULL after all variable arguments have been returned.
Defining Local Variables
User-defined function local variables are declared using the
local keyword inside the body of the function. The
local keyword declares one or more variables specified in a comma-separated list that is terminated by a semicolon. These names become local variables to the function. Following is an example of local variable definitions:
Local variables cannot have the same name as a function parameter or another local variable in the same function. Local variable names in one function do not affect those in another function. Local variables can have the same name as a global variable and, consequently, can hide a global name. BMC Software does not recommend that you use local variables this way, and PSL will generate a compiler warning each time it detects this situation.
Local variable declarations are treated as expressions and can appear anywhere within the function that an expression is valid. However, there is no concept of inner scopes in inner blocks, and a local variable has scope extending from its point of declaration to the end of the enclosing function (not the enclosing block). BMC Software recommends that you declare all local variables at the start of the function body.
Local variables are initialized to the empty string every time the function is entered. They do not retain their values from a previous call.
Each user-defined function (except for the
main() function) permits a maximum of 20 local variables.
Entry Point Function
In earlier releases of PSL, the program entry point was always the first PSL statement. Although the current PSL still supports this concept, the addition of user-defined functions defined at the beginning of a program causes a need for other possible entry points. One of these is the PSL entry point function.
The PSL entry point function is equivalent to the C language function
main(). If a PSL program contains a user-defined function named
main, execution begins at the first statement in
main(). The PSL program terminates normally when
You can specify that a user-defined function with a label other than
main() be treated as the main program entry point by specifying the
-eoption to the PSL standalone compiler. For a description of the PSL compiler command and options, see PSL External Commands The function you specify as the entry point is permitted to have the same properties as
main() or the entry point function must be defined in the top-level PSL program and not in any imported libraries. Functions imported from libraries are ignored when determining whether an entry point function is available.
Start of Execution Without an Entry Point Function
If there is no
main() function and no entry point function specified using the PSL compiler option
-e, execution begins at the first executable statement that is not inside a function definition. This behavior maintains backward compatibility with previous versions of PSL.
A program without an entry function will normally have function definitions at the top (they must be defined before their first use) and the main executable statements afterward. A typical example would be the following:
As indicated, program execution begins immediately after the function definition.
Backward Compatibility with earlier PSL versions
Almost all programs written in earlier versions of PSL should function identically under the new PSL version. Notably, there is no need to change older PSL scripts to have a
main() function or entry point function since the current PSL version supports and defaults to the older style of execution at the first statement.
Run-time errors may occur if you attempt to migrate a program written using the current version of PSL back to an earlier version. Older versions of PSL will not recognize the following function keywords:
Limitations of User-Defined functions
User-defined functions are subject to the following limitations.
Function Calls Are Non-Recursive
User-defined functions can make unlimited calls to other functions provided that there is no direct or indirect recursion in the sequence of calls.
PSL user-defined functions do not support recursion because each function has only one block of memory for its parameters and local variables. A recursive call would overwrite the parameters for the previous (and still active) call.
PSL prevents direct recursion by generating a compilation error. The PSL compiler may compile and execute a program with indirect recursion, but the potential for overwriting the parameters and variables for an active function will produce unexpected results.
Argument Pass by Reference Not Supported
PSL functions do not support argument passing by reference; only argument pass-by-value is supported. PSL also has no concept of pointers, like those used in the C programming language, to mimic pass-by-reference.
Parameter and Local Variable Limits
User-defined PSL functions, including
main(), have the following parameter and local variable limits:
- maximum of 20 parameters (note that this differs from the 100 parameter limit for built-in functions)
- maximum of 20 local variables
Function Nesting Not Permitted
PSL does not permit function nesting--each function definition must be global in scope and cannot be defined inside any other function.