Writing your own User Defined Built-in Functions

Date:Archived
Product/Release:LANSA for the AS/400
Abstract:How to create user defined own Built-in Functions
Submitted By:LANSA Technical Support

In an RDML function standard supplied built-in functions (BIF's) can be used to manipulate dates, numeric and character strings, etc. BIF's can also be written by the user.

Define the BIF in the LANSA internal database so that the function checker can control that the BIF exists and that the number of parameters expected is correct. The standard OS/400 utility DFU is used to define the BIF header information in internal file DC@F47 and the BIF parameter details in file DC@F48. These files are stored in the LANSA program library and are used not only by the function checker but also by the program that tranlates the RDML code (RPG on the AS/400 and C on the PC).

Here is an example of a BIF called UD_GET_WEEKNR that returns the week number for a given date:

File DC@F47 (BIF header details) requires the following information:

DC@F47 information
  1. Name of the BIF to be used in the RDML function. To keep this name unique and to prevent the BIF from being overwritten by any new BIF's in future releases of LANSA, prefix the BIF name with the letters 'UD_' (User defined). If BIF's are being written for resale, prefix the BIF name with the letters 'OV_' (other vendors).
  2. Unique number. For user defined BIF's use range 401 to 600. Other vendors use 601 to 999.
  3. Description. Something relevant to explain what the BIF does.
  4. C or E. This is an indicator for the translator program to either generate the coding as a CALL or as an execute subroutine .
  5. This is the name of the program or the subroutine that has been written and that should be executed when the BIF is called. Standard for program names is UD@Pnnn or OV@Pnnn and for subroutine names BIFnnnxSPC where nnn is the same value as 2. above. In this example program UD@P599 is a CL program. The listing follows the definition of these internal files.
  6. This indicator determines whether the program called should terminate between calls. If it is at all possible that a BIF is called conditionally in an RDML function then set the value of this field to Y. Otherwise the BIF will always be executed on exit from the function.e.g. if you define F47SLR=N
* RDML coding
IF COND('#USER *NE KOPEH')
RETURN...................The BIF will be called here to terminate it
ENDIF
USE BUILTIN etc...........The BIF will be called here
RETURN....................and here to terminate it.
  1. The number of arguments to be passed. The number of fields used in the WITH_ARGS parameter of the USE command should correspond to this value.
  2. The number of return values expected. The number of fields used in the TO_GET parameter of the USE command should correspond to this value.

File DC@F48 (BIF parameter details) requires the following information per parameter: (this example has a date and a week number)

DC@F48 InformationDC@F48 Information
  1. Name of the BIF to be used in the RDML function. Identical to F47BIF.
  2. ARG or RET.
  3. Sequence number within the BIF. One sequence for arguments and one for returned parameters.
  4. Sequence number within program.
  5. Identification number or letter. This is used by the RDML translator program to generate unique field names for the parameters.
  6. Description.
  7. R or O. Is the parameter REQUIRED or Optional. Define all required values first and then ll optional values.
  8. Type of value. A (alphanumeric), N (numeric) or L (working list).
  9. Minimum length allowed.
  10. Maximum length allowed.
  11. Minimum number of decimal positions.
  12. Maximum number of decimal positions.
  13. Pass or return length.
  14. Pass or return number of decimals.
  15. Default value.

For more detailed information about user defined BIF's refer to the LANSA Builtin Functions Guide

Always thoroughly test a BIF before trying to use it. To test this BIF the following RDML function was used:

FUNCTION OPTIONS(*DIRECT *DEFERWRITE *NOMESSAGES)  
DEFINE FIELD(#W_WEEK) TYPE(*DEC)LENGTH(2) DECIMALS(0) 
                  LABEL('Week  number')                  
DEFINE FIELD(#W_DATE) TYPE(*DEC) LENGTH(8) DECIMALS(0) 
                  LABEL'Date  (YYYYMMDD)')               
BEGIN_LOOP            
DISPLAY FIELDS((#W_DATE*IN) (#W_WEEK *OUT)) 
USE BUILTIN(UD_GET_WEEKNR) WITH_ARGS(#W_DATE) 
           TO_GET(#W_WEEK) 
END_LOOP

Bif Sample Source Code (PDF 12K) of the CL program called by the BIF to calculate the week number.