HP OpenVMS Systems Documentation
HP BASIC for OpenVMS
When you call a HP BASIC subprogram from another language, there are some additional considerations that you should be aware of. For example, although HP BASIC conforms to the OpenVMS Calling Standard, you should specify explicit passing mechanisms when calling a routine written in another language. The default passing mechanisms of BASIC may not match what the procedure expects. In the following section, FORTRAN refers to VAX FORTRAN and HP Fortran.
FORTRAN passes and receives numeric data by reference; only the default parameter-passing mechanisms are required for passing numeric data back and forth between FORTRAN and HP BASIC programs.
Both HP BASIC and FORTRAN pass strings by descriptor. However, FORTRAN subprograms cannot change the length of strings passed to them. Therefore, if you pass a string to a FORTRAN subprogram, you must make sure that the string is long enough to receive the result. You do this in one of two ways:
Because the length of the returned string does not change, it is either padded with spaces or truncated.
To pass an array to a FORTRAN subprogram, you must specify BY REF.
Note that FORTRAN arrays are one-based, while HP BASIC arrays are zero-based by default. For example, in FORTRAN the array Two_D(5,3) represents a 5 by 3 matrix, while in HP BASIC the array Two_d(5,3) represents a 6 by 4 matrix. You can adjust your array bounds in HP BASIC by using the keyword TO when defining the array bounds. For more information about array bounds, see Chapter 6.
When passing two-dimensional arrays as parameters, keep in mind that FORTRAN addresses array elements in column major order, while BASIC refers to array elements in row major order. That is, FORTRAN arrays are of the form Fortran_array(column,row), while HP BASIC array elements are addressed as Basic_array(row,column). The FORTRAN array Grid(x,y) is therefore referred to as GRID(y,x) in HP BASIC. You should reverse references to array elements when passing arrays between HP BASIC and FORTRAN program modules. You can do this in one of two ways:
|Example 19-1 BASIC Main Program|
PROGRAM call_fortran ! The BASIC main program prints the array before ! calling the subroutine EXTERNAL SUB forsub (WORD DIM(,) BY REF) DIM WORD array_x(1 TO 10, 1 TO 5) FOR column = 1 TO 5 FOR row = 1 TO 10 array_x(row,column)=(10*row + column) PRINT array_x(row,column); NEXT row PRINT NEXT column PRINT CALL forsub(array_x(,) BY REF) END PROGRAM
|Example 19-2 FORTRAN Subprogram|
C The FORTRAN subprogram receives C and then prints the same array SUBROUTINE forsub(f_array) INTEGER*2 f_array(5,10) DO 20 row = 1,5 TYPE *, (f_array(row,column), column = 1,10) 20 CONTINUE RETURN END
You can pass only the data types that HP BASIC and FORTRAN have in
common. You cannot pass a complex number from a FORTRAN program to a
HP BASIC program, because HP BASIC does not support complex
numbers. However, you can pass a complex number as two floating-point
numbers and treat them independently in the HP BASIC program.
19.4 Calling System Routines
The steps for calling system routines are the same as those for calling
any external routine. However, when calling system routines, you need
to provide additional information, which is discussed in the following
19.4.1 OpenVMS Run-Time Library Routines
The OpenVMS Run-Time Library routines are grouped according to the types of tasks they perform. The routines in each group have a prefix that identifies them as members of a particular OpenVMS Run-Time Library facility. Table 19-2 lists all the language-independent Run-Time Library facility prefixes and the types of tasks each facility performs.
|Facility Prefix||Types of Tasks Performed|
|DTK$||DECtalk routines that are used to control the DECtalk device|
|LIB$||General purpose routines that obtain records from devices, manipulate strings, convert data types for I/O, allocate resources, obtain system information, signal exceptions, establish condition handlers, enable detection of hardware exceptions, and process cross-reference data|
|MTH$||Mathematics routines that perform arithmetic, algebraic, and trigonometric calculations|
|OTS$||Language-independent support routines that perform tasks such as data type conversions as part of a compiler's generated code|
|PPL$||Parallel processing routines that help you implement concurrent programs on single-CPU and multiprocessor systems|
|SMG$||Screen management routines that are used in designing, composing, and keeping track of complex images on a video screen|
|STR$||String manipulation routines that perform such tasks as searching for substrings, concatenating strings, and prefixing and appending strings|
System services are system routines that perform a variety of tasks such as controlling processes, communicating among processes, and coordinating I/O.
Unlike the OpenVMS Run-Time Library routines, which are divided into groups by facility, all system services share the same facility prefix (SYS$). However, these services are logically divided into groups that perform similar tasks. Table 19-3 describes these groups.
|Group||Types of Tasks Performed|
|AST||Allows processes to control the handling of ASTs|
|Change Mode||Changes the access mode of particular routines|
|Condition Handling||Designates condition handlers for special purposes|
|Event Flag||Clears, sets, reads, and waits for event flags, and associates with event flag clusters|
|Information||Returns information about the system, queues, jobs, processes, locks, and devices|
|Input/Output||Performs I/O directly, without going through RMS|
|Lock Management||Enables processes to coordinate access to shareable system resources|
|Logical Names||Provides methods of accessing and maintaining pairs of character string logical names and equivalence names|
|Memory Management||Increases or decreases available virtual memory, controls paging and swapping, and creates and accesses shareable files of code or data|
|Process Control||Creates, deletes, and controls execution of processes|
|Security||Enhances the security of OpenVMS systems|
|Time and Timing||Schedules events, and obtains and formats binary time values|
OpenVMS usages are data structures that are layered on the standard OpenVMS data types. For example, the OpenVMS usage mask_longword signifies an unsigned longword integer that is used as a bit mask, and the OpenVMS usage floating_point represents any OpenVMS floating-point data type. Table 19-4 lists all the OpenVMS usages and the HP BASIC statements you need to implement them.
|OpenVMS Usage||BASIC Implementation|
|access_bit_names||Not applicable (NA)|
|ast_procedure||EXTERNAL LONG FUNCTION ast_proc 1|
WORD iosb_field(1 to 4)
GROUP item (15)
END RECORD item_list_pair
|null_arg||A null argument is indicated by a comma used as a placekeeper in the argument list.|
|procedure||EXTERNAL LONG FUNCTION proc|
|varying_arg||Dependent upon application.|
|vector_byte_unsigned||BYTE array(n) 2|
|vector_longword_unsigned||LONG array(n) 2|
|vector_quadword_unsigned||QUAD array(n) 2|
|vector_word_unsigned||WORD array(n) 2|
If a system routine argument is optional, it will be indicated in the format section of the routine description in one of the following ways:
If the comma appears outside the brackets, you must either pass a zero
by value or use a comma in the argument list as a placeholder to
indicate the place of the omitted argument. If this is the last
argument in the list, you must still include the comma as a
placeholder. If the comma appears inside the brackets, you can omit the
argument altogether as long as it is the last argument in the list.
19.4.4 Including Symbolic Definitions
To enhance program development, BASIC allows you to use symbolic definitions. Symbolic definitions are names or symbols associated with values. These symbols are used in many ways; the value associated with a symbol can be a status code, a mask, or an offset into a data structure. Many system routines depend on values that are defined in separate symbol definition files. For example, the status code for successful completion has a value of one; however, this code for successful completion is defined in the system library (STARLET) as the symbol SS$_NORMAL.
A program might compare the status code returned by a system service to either the symbolic constant SS$_NORMAL or the integer value one. The program would execute the same way in either case. In the first case, the value for SS$_NORMAL is supplied at link time by the OpenVMS Linker. In the second case, the value 1 is included in the program as a literal constant.
The advantages of using symbolic definitions are as follows:
For Run-Time Library routines, the only time that you need to include symbolic definitions is when you are calling an SMG$ routine, or when you are calling a routine that is a jacket to a system service. (A jacket routine in the Run-Time Library is a routine that provides a simpler, more easily used interface to a system service.) If you call a routine in the SMG$ facility, you must include the definition file SMGDEF. All system services, however, require that you include SSDEF to check status. Many other system services require other symbol definitions as well.
To determine whether or not you need to include other symbolic definitions for the system service you want to reference, see the documentation for that service. If the documentation states that values are defined in the specified macro, you must include those symbolic definitions in your program. BASIC provides a text library that contains symbolic definitions that can be accessed using the %INCLUDE directive. In the following example, the definition file, SMGDEF is included from the text library SYS$LIBRARY:BASIC$STARLET.TLB:
%INCLUDE "SMGDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET.TLB"
Many system routines return a condition value that indicates success or failure. If a condition value is returned, you should check this value after you call a system routine and control returns to your program.
Condition values indicating success always appear first in the list of condition values for a particular routine, and success codes always have odd values. A success code that is common to many system routines is the condition value SS$_NORMAL, which indicates that the routine completed normally and successfully. You can test for this condition value as follows:
ret_status = SMG$CREATE_PASTEBOARD(pb_id) IF (ret_status <> SS$_NORMAL) THEN CALL LIB$STOP(ret_status BY VALUE) END IF
Because all success codes have odd values, you can check a return status for any success code. For example, you can cause execution to continue only if a success code is returned by including the following statements in your program:
ret_status = SMG$CREATE_PASTEBOARD(pb_id) IF (ret_status AND 1%) = 0% THEN CALL LIB$STOP(ret_status BY VALUE) END IF