Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Shipped U_BIF Macros

To assist you in coding User Defined Built-In Functions, the following U_BIF macros are shipped with Visual LANSA.

Please note that these macros were specifically designed to make programming user defined Built-In Functions easier, and to insulate them from future changes.

They do not have a high degree of error handling and are not designed to be "bullet proof". It is assumed that the developer using them will be capable and will understand how to use them effectively.

The U_BIF macros are defined in header file X_BIF000.H that is supplied on the LANSA Windows product CD. Do not change this file as it is totally replaced every time that Visual LANSA is upgraded and your changes will be lost.

Note that the arguments must be specified in the order they are listed in the Arguments column.

Macro Name

Arguments

Description/ Comments

U_BIF_COLUMN_ERROR

None

Fatal error message text string

U_BIF_LIST_ERROR

None

Fatal error message text string

U_BIF_LANSA_FUNCTION

None

Name of current function.

U_BIF_LANSA_FUNCTION_DESC

None

Description of current function.

U_BIF_LANSA_PROCESS

None

Name of current process.

U_BIF_LANSA_PROCESS_DESC

None

Description of current process.

U-BIF-GET_HAB

_R=HAB

Returns current HAB into _R.

U-BIF-GET_HMQ

_R=HMQ

Returns current HMQ into _R..

U_BIF_GET_HWND

_R = HWND

Returns current HWND into _R.

U_BIF_FATAL_ERROR

None

Tests for fatal error state as in "if (U_BIF_FATAL_ERROR)"

U_BIF_ISSUE_FATAL_ERROR

_T = "text" or X_PVCHAR

Issues a fatal error and returns control to the caller.

U_BIF_HANDLE_FATAL_ERROR

None

Tests for fatal error state and issues a return if one exists.

U_BIF_SET_GOOD_RETURN

None

Indicates BIF ended normally to the calling RDML function.

U_BIF_SET_BAD_RETURN

None

Indicates BIF ended abnormally to the calling RDML function.

U_BIF_RETURN

None

Returns control to the calling RDML function. Issues a C return.

U_BIF_SHUTDOWN_REQUEST

None

Tests for a Built-In Function shutdown request as in the example "if (U_BIF_SHUTDOWN_REQUEST)"

U_BIF_STANDARD_PARAMETERS

None

Defines the standard parameter list for a user defined Built-In Function.

U_BIF_STANDARD_ARGUMENTS

None

Defines the standard set of arguments to be passed to a user defined Built-In Function.

U_BIF_OPERATING_SYSTEM_WIN95

None

Use in a C #ifdef or #elif to test compilation under Windows 9x/200x.

U_BIF_OPERATING_SYSTEM_WIN

None

Use in a C #ifdef or #elif to test compilation under either Windows 9x/200x.

U_BIF_OPERATING_SYSTEM_UNIX

None

Use in a C #ifdef or #elif to test compilation under UNIX(Linux)  operating system. 

U_BIF_GET_ARGUMENT_COUNT

_N = X_SHORT

Returns a count of the total number of arguments passed into the Built-In in _N.

U_BIF_ARGUMENT_PASSED

_N = X_SHORT

Used in an "if ()" statement to test whether argument number _N was passed by the caller.

U_BIF_GET_RETURN_COUNT

_N = X_SHORT

Returns a count of the total number of return values requested by the caller in _N.

U_BIF_RETURN_REQUIRED

_N = X_SHORT

Used in an "if ()" statement to test whether return values _N was requested by the caller.

U_BIF_GET_ARG_AS_SHORT

_N = X_SHORT

_S = X_SHORT

Retrieves argument number _N as an X_SHORT value into _S. If _N is invalid, or argument _N was not passed, _S is not changed by the operation. _N is the argument number in the C style numbered from 0.

U_BIF_GET_ARG_AS_LONG

_N = X_SHORT

_L = X_LONG

Retrieves argument number _N as an X_LONG value into _S. If _N is invalid, or argument _N was not passed, _L is not changed by the operation. _N is the argument number in the C style numbered from 0.

U_BIF_GET_ARG_AS_DOUBLE

_N = X_SHORT

_D = X_DOUBLE

Retrieves argument number _N as an X_DOUBLE value into _S. If _N is invalid, or argument _N was not passed, _D is not changed by the operation. _N is the argument number in the C style numbered from 0.

U_BIF_GET_ARG_AS_VCHAR

_N = X_SHORT

_V = X_VCHAR

Retrieves argument number _N as an X_VCHAR value into _V. If _N is invalid, or argument _N was not passed, _V is not changed by the operation. _N is the argument number in the C style numbered from 0.

U_BIF_SET_RET_FROM_SHORT

_N = X_SHORT

_S = X_SHORT

Sets return value number _N from the X_SHORT value specified by _S. If _N is invalid, or return value _N is not required, the entire request is ignored. _N is the return value number in the C style numbered from 0.

U_BIF_SET_RET_FROM_LONG

_N = X_SHORT

_L = X_LONG

Sets return value number _N from the X_LONG value specified by _L. If _N is invalid, or return value _N is not required, the entire request is ignored. _N is the return value number in the C style numbered from 0.

U_BIF_SET_RET_FROM_DOUBLE

_N = X_SHORT

_D = X_DOUBLE

Sets return value number _N from the X_DOUBLE value specified by _D. If _N is invalid, or return value _N is not required, the entire request is ignored. _N is the return value number in the C style numbered from 0.

U_BIF_SET_RET_FROM_VCHAR

_N = X_SHORT

_V = X_VCHAR

Sets return value number _N from the X_VCHAR value specified by _V. If _N is invalid, or return value _N is not required, the entire request is ignored. _N is the return value number in the C style numbered from 0.

U_BIF_DECLARE_LIST_POINTER

_L = C Name

Declares a pointer to a working list received as an argument or to be returned. This is a declarative operation so it must be positioned accordingly. Names like pListArg1, pListArg7, and pListRet5 are recommended.

A declared list pointer must be set before any attempt is made to reference this list in any way.

U_BIF_SET_ARG_LIST_POINTER

_L = C Name

_A = X_SHORT

Initializes a list pointer that has been previously declared by U_BIF_DECLARE_LIST_POINTER(_L).

_A is the argument number of the Built-In Function argument that contains the working list.

If _A is invalid, or argument _A was not passed, a fatal error will result, terminating the Built-In Function.

U_BIF_SET_RET_LIST_POINTER

_L = C Name

_A = X_SHORT

Initializes a list pointer that has been previously declared by U_BIF_DECLARE_LIST_POINTER(_L).

_A is the return value number of the Built-In Function return value that contains the working list. If _A is invalid, or return value _A is not required, a fatal error will result, terminating the Built-In Function.

U_BIF_GET_ENTRY_FROM_LIST

_L = C Name

_E = X_LIST_COUNT

_R = X_CHAR

Retrieves entry number _E from the working list pointed to by _L. If the entry was found _R is returned as YES('Y'), otherwise it is returned as NO('N'). List entries are numbered from 1 to N. This is different to most other U_BIF macros that number in the C style from 0 to (N - 1).

U_BIF_CLEAR_LIST

_L = C Name

Clears all entries from the list pointed to by _L.

U_BIF_ADD_ENTRY_TO_LIST

_L = C Name

Adds a new entry to the list pointed to by _L.

U_BIF_UPDATE_ENTRY_IN_LIST

_L = C Name

Updates the current entry in the working list pointed to by _L.

U_BIF_GET_LIST_CURRENT_ENTRYS

_L = C Name

_R = X_LIST_COUNT

Returns into _R a count of the current number of entries in the working list pointed to by _L.

U_BIF_GET_LIST_MAXIMUM_ENTRYS

_L = C Name

_R = X_LIST_COUNT

Returns into _R the maximum number of entries allowed in the working list pointed to by _L.

U_BIF_GET_LIST_ENTRY_LENGTH

_L = C Name

_R = X_LIST_COUNT

Returns into _R the aggregate byte length of an entry in the working list pointed to by _L.

U_BIF_GET_LIST_COLUMN_TOTAL

_L = C Name

_R = X_SHORT

Returns into _R the total number of columns defined in the working list pointed to by _L.

U_BIF_GET_LIST_COLUMN_ATTRIBS

_L = C Name

_C = X_SHORT

_T = X_CHAR

_E = X_ULONG

_D = X_SHORT

_B = X_SHORT

Queries the definition of column number _C (in 0 -> (N-1) style) of the working list pointed to by _L and returns :

_T : The column type

_E : The column length/total digits

_D : The number of decimal positions

_B : The byte length

_T is returned according to these types defined in X_FUNSTR.H ....

X_TYPE_ALPHA= Alphanumeric,

X_TYPE_CHAR = Char or String,

X_TYPE_PACKED = Packed Decimal,

X_TYPE_SIGNED = Signed Decimal,

X_TYPE_FLOAT = Float,

X_TYPE_INTEGER  = Integer,

X_TYPE_LONG= X_LONG format,

X_TYPE_DOUBLE = X_DOUBLE format,

X_TYPE_DATETIME = DateTime,

X_TYPE_DATE = Date ,

X_TYPE_TIME = Time,

X_TYPE_BOOLEAN= Boolean,

X_TYPE_BINARY = Binary or VarBinary,

X_TYPE_CLOB = CLOB,

X_TYPE_BLOB = BLOB.

If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

For X_TYPE_CLOB or X_TYPE_BLOB _E is the maximum length that the file name can be, not the content of the file.


U_BIF_LIST_COLUMN_NAME_LEN

None

Defines the length of column name (i.e. currently 10 bytes).

U_BIF_GET_LIST_COLUMN_NAME

_L = C Name

_C = X_SHORT

_R = X_VCHAR

Queries the definition of column number _C (in 0 -> (N-1) style) of the working list pointed to by _L and returns the name of the column (i.e. the RDML field name).

_R must be of type X_VCHAR and must be at least (U_BIF_COLUMN_NAME_LEN + 1) bytes long.

If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

U_BIF_GET_LIST_COLUMN_AS_SHORT

_L = C Name

_C = X_SHORT

_R = X_SHORT

Returns the value of column number _C (in 0 -> (N-1) style) from the current entry of the working list pointed to by _L. The value is returned in _R which must be of type X_SHORT. If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

U_BIF_GET_LIST_COLUMN_AS_LONG

_L = C Name

_C = X_SHORT

_R = X_LONG

Returns the value of column number _C (in 0 -> (N-1) style) from the current entry of the working list pointed to by _L. The value is returned in _R which must be of type X_LONG. If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

U_BIF_GET_LIST_COLUMN_AS_LONGLONG

_L = C Name

_C = X_SHORT

_R = X_LONGLONG

Returns the value of column number _C (in 0 -> (N-1) style) from the current entry of the working list pointed to by _L. The value is returned in _R which must be of type X_LONGLONG. If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

U_BIF_GET_LIST_COLUMN_AS_DOUBLE


Returns the value of column number _C (in 0 -> (N-1) style) from the current entry of the working list pointed to by _L. The value is returned in _R which must be of type X_DOUBLE. If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

U_BIF_GET_LIST_COLUMN_AS_VCHAR

_L = C Name

_C = X_SHORT

_R = X_VCHAR

Returns the value of column number _C (in 0 -> (N-1) style) from the current entry of the working list pointed to by _L.

The value is returned in _R which must be of type X_VCHAR. If _C is an invalid column number a fatal error will result, terminating the Built-In Function.

U_BIF_SET_LIST_COLUMN_FROM_SHORT

_L = C Name

_C = X_SHORT

_R = X_SHORT

Sets the value of column number _C (in 0 -> (N-1) style) into the current entry of the working list pointed to by _L. The value is set from _R which must be of type X_SHORT. If _C is an invalid column number a fatal error will result, terminating the Built-In Function. The current entry in a list must be subsequently inserted or updated for it to actually be applied to the stored list.

U_BIF_SET_LIST_COLUMN_FROM_LONG

_L = C Name

_C = X_SHORT

_R = X_LONG

Sets the value of column number _C (in 0 -> (N-1) style) into the current entry of the working list pointed to by _L. The value is set from _R which must be of type X_LONG. If _C is an invalid column number a fatal error will result, terminating the Built-In Function. The current entry in a list must be subsequently inserted or updated for it to actually be applied to the stored list.

U_BIF_SET_LIST_COLUMN_FROM_LONG

_L = C Name

_C = X_SHORT

_R = X_LONGLONG

Sets the value of column number _C (in 0 -> (N-1) style) into the current entry of the working list pointed to by _L. The value is set from _R which must be of type X_LONGLONG. If _C is an invalid column number a fatal error will result, terminating the Built-In Function. The current entry in a list must be subsequently inserted or updated for it to actually be applied to the stored list.

U_BIF_SET_LIST_COLUMN_FROM_DOUBLE

_L = C Name

_C = X_SHORT

_R = X_DOUBLE

Sets the value of column number _C (in 0 -> (N-1) style) into the current entry of the working list pointed to by _L. The value is set from _R which must be of type X_DOUBLE. If _C is an invalid column number a fatal error will result, terminating the Built-In Function. The current entry in a list must be subsequently inserted or updated for it to actually be applied to the stored list.

U_BIF_SET_LIST_COLUMN_FROM_VCHAR

_L = C Name

_C = X_SHORT

_R = X_VCHAR

Sets the value of column number _C (in 0 -> (N-1) style) into the current entry of the working list pointed to by _L. The value is set from _R which must be of type X_VCHAR. If _C is an invalid column number a fatal error will result, terminating the Built-In Function. The current entry in a list must be subsequently inserted or updated for it to actually be applied to the stored list.

Steps to Create 3GL Built-In Functions on Windows/Linux/IBM i

1.      Design the Built-In Function by giving the Built-In Function program a name according to the Naming Conventions for 3GL BIFs on Windows/Linux.

2.      Complete a Built-In Function definition form. You can print the example supplied in Built-In Function Sample Form or one that you have designed yourself. Refer to an example of a 3GL BIF definition, such as Example - A Simple Averaging Function, to understand the composition of the BIF definition.

         Note: This step is not compulsory but it is recommended, especially if you are creating your first Built-In Function. It is meant as an aid to translating your Built-In Function design into the necessary data.

3.      Enter the relevant information into the Built-In Function definition files.

         Note: The next two steps must be performed. If the Built-In Function is not described in these files then it will not be recognized by LANSA. If this data is incorrect, then the Built-In Function will not work as expected.

4.      Create Definitions in LX_F47 and LX_F48

         There are two available methods for creating Definitions in LX_F47 and LX_F48.

      Method 1: Define the BIF on IBM i and port to Windows

a.      Define your Built-In Function into the IBM i based table DC@F47 as described in the Create your own 3GL Built-In Functions on IBM i for RDML Functions.

b.      Define your Built-In Function's arguments and return values into the IBM i based table DC@F48 as described in the Examples in Create your own 3GL Built-In Functions on IBM i for RDML Functions.

c.      Optionally, design, code and test an IBM i based version of your Built-In Function. The LANSA Built-In Function facility is designed to be a generic interface between LANSA applications and multiple platforms.

       Note: If you need to supply Built-In Functions that will eventually be required on multiple platforms, you may consider producing fatal error "stubs" for your Built-In Function(s) on all supported platforms. This means that if your Built-In Function is accidentally invoked on a non-supported platform (e.g. the IBM i) then a neat "fatal error" explaining the situation will result, rather than a more complex problem involving compile and/or run time linkage problems.

d.      Export the definition of your Built-In Function from the IBM i Repository using the standard LANSA REQUEST(PCMAINT) facility.

e.      Import the definition of your Built-In Function into each Visual LANSA system that will need to use it. To do this, use the standard Visual LANSA import facilities from CD or shared folder. This facility will update SQL tables LX_F47 and LX_F48 with details of the Built-In Functions exported from the IBM i in step 4. 

      Method 2: Define the BIF via SQL directly in Windows

         This is an alternative method, which can be used where the IBM i is non-existent or if you are familiar with inserting and updating your database on the Windows/Linux platform using SQL statements. This method requires you to directly enter your definitions into the LX_F47 and LX_F48 files.

Inserting/updating records in the LX_F47 and LX_F48 internal LANSA tables via SQL, if not completed correctly, can potentially cause database corruption. If you require assistance with inserting/updating records in the LX_F47 and LX_F48 internal LANSA files via SQL, you should consult your Database Administrator.

         Example of an insert to file LX_F47

      INSERT INTO "LX_DTA"."LX_F47" VALUES('UD_AVERAGE',413,'Get the Average','C','U_BIF413','N',2,1)

         Example of an insert to file LX_F48

      INSERT INTO "LX_DTA"."LX_F48" VALUES('UD_AVERAGE','ARG',1,1,'A','First Value','R','N',7,7,0,0,10,0,'')

5.      If you are writing a BIF specifically for Windows or you require 64 bit support on Windows then you may find the LANSA User Defined BIF Wizard an easier method than the remainder of these steps 6 - 9. Instead go to Define Built In Functions with a Visual Studio Wizard It is particularly useful for existing Visual Studio users and when requiring more than one user defined BIF.

6.      Create copies of the following files that are installed in your x_win95\x_lansa\source directory. Change the "NNN" portion of the name to the unique identifier assigned to your Built-In Function.

         For example, if you were making Built-In Function 445, and working from the C: drive then you might use these commands:

              CD \X_WIN95\X_LANSA\SOURCE

              COPY U_BIFNNN.*  U_BIF445.*

         These are the files that are installed in your x_win95\x_lansa\source directory:

...

U_BIFNNN.C

...

A sample/skeleton of a user Built-In C program.

...

U_BIFNNN.MAK

...

A sample/skeleton of a make file required to compile and link your C program with Microsoft Visual C/C++ into a DLL under the Windows Operating System.

...

U_BIFNNN.DEF

...

A sample/skeleton of a module definition file required to link your C program with Microsoft Visual C/C++ into a DLL under the Windows Operating System.

...

u_bifnnn.unx

...

A sample/skeleton of a make file required to compile and link your C program into a shared library under a supported Linux operating system.

...

U_BIFNNN.ISB

...

A sample/skeleton of a module definition file required to link your C program into a service program on IBM i.

7.      Edit each of the copied files using a standard source editor such as E or EPM:

...

File

...

Description Of Changes

...

.C

...

Scan/Replace all "nnn" with "xxx" where xxx is the unique id. Include code appropriate for your requirement.

...

.MAK

...

Only required if compiling with Microsoft Visual C/C++. 

Replace "nnn" with "xxx" in the BIFNAME line, where xxx is the unique id.

...

.DEF

...

Only required if compiling with Microsoft Visual C/C++.

Replace "nnn" with "xxx" where xxx is the unique id.

Replace xxxxxxxx in DESCRIPTION with a short description of the Built-In Function

...

.unx

...

(Only if planning to execute this BIF on Linux.)

Scan/Replace all "nnn" with "xxx" where xxx is the unique id.

...

.ISB

...

Only required if planning to execute this BIF on IBM i.)

Replace "nnn" with "xxx" where xxx is the unique id.

Replace xxxxxxxx in the comment area (/* */) with a short description of the Built-In Function

8.      Back up your .C, .MAK, .WMK, .DEF, .unx and .ISB files as soon as possible. This is source code and it needs to be backed up frequently. Accidental loss of source code is a very common problem on unsecured PC systems.

9.      Compile your Built-In Function using one of the following examples depending on the platform you are using:

         Compile your Built-In Function on Windows

         Compile your Built-In Function on Linux

...