HP OpenVMS Systems Documentation
Guide to Creating OpenVMS Modular Procedures
|ADA||Ada Run-Time Library procedures|
|APL||APL Run-Time Library procedures|
|BAS||BASIC Run-Time Library procedures|
|B32||BLISS-32 Run-Time Library procedures|
|CDU||Command Definition Utility|
|CLI||Command language interpreter|
|COB||COBOL Run-Time Library procedures|
|COR||CORAL Run-Time Library procedures|
|C74||COBOL-74 Run-Time Library procedures|
|DBL||DIBOL Run-Time Library procedures|
|ERF||Error Log Report Formatter|
|FDV||FMS Forms Driver Library procedures|
|FOR||FORTRAN Run-Time Library procedures|
|LBR||Librarian utility procedures|
|LIB||RTL General-Purpose procedures|
|MATH||Portable Math Library|
|MTH||RTL Mathematics procedures|
|OTS||RTL language-independent procedures|
|PAS||PASCAL Run-Time Library procedures|
|PLI||PL/I Run-Time Library procedures|
|RMS||Record Management Services|
|RPG||RPG II Run-Time Library procedures|
|SMG||RTL screen management procedures|
|SOR||Sort utility procedures|
|STR||RTL string manipulation procedures|
|VAX||VAX Architecture Emulation|
You can create your own facilities by defining a unique facility name and facility number. The name for your facility should be a unique name between 1 and 27 characters. Facility names supplied by Compaq all contain a dollar sign ($) after the prefix. User-supplied facility names should use an underscore (_) rather than a dollar sign ($) to avoid any name conflicts.
The facility number is used in defining condition values for the
facility. Bit 27 (STS$V_CUST_DEF) of a condition value indicates
whether the value is supplied by Compaq or by the user. This bit must
be 1 if the facility number is created by the user. For more
information, use the Help Message utility (MSGHLP) to access online
descriptions of system messages from the DCL ($) prompt. For more
information about using MSGHLP, refer to the OpenVMS System Messages: Companion Guide for Help Message Users.
18.104.22.168 Procedure Naming Conventions (Recommended)
When you create a procedure and make its name global, you allow other procedures in the same image to call that procedure. The common RTL procedures are examples of procedures with global names. In such an environment, a naming convention is required to prevent any name conflict between global procedures in the same image.
fac is a two- to four-character facility name.
symbol is a symbol from 1 to 27 characters long. (The entire procedure name may not exceed 31 characters in length.)
The facility name and symbol name are separated by a dollar sign ($) if the procedure is supplied by Compaq and by an underscore (_) if the procedure is supplied by the user. This convention should be used to avoid conflict between Compaq and user procedure names.
The procedure name usually consists of a verb and an object that together describe the action of the procedure. For example, the Run-Time Library procedure intended to get virtual memory is called LIB$GET_VM.
Some procedures, even though they have global names, are not intended to be called from outside the facility in which they are located. These procedures are only available internally, within a set of procedures, and do not by themselves provide any functionality for the facility. The names for these procedures contain a double dollar sign ($$) if they are supplied by Compaq or a triple underscore (_ <double_uscore>) if they are supplied by the user. (Three underscores are necessary to avoid conflict with user-defined condition value symbols, which use two underscores.)
Table 3-2 shows examples of procedure entry point names.
|LIB$GET_VM||Compaq supplied global procedure|
|LIB_PRINT_REPORT||User-supplied global procedure|
|OTS$$INTERNAL||Compaq supplied internal procedure|
|LIB_ <double_uscore>ADD_TAX||User-supplied internal procedure|
If a module contains a single procedure, the file name consists of the procedure name. You can remove dollar signs and underscores, but this is not required. File types are the standard default file types for the source language. For example, the file containing the RTL procedure MTH$EXP is named MTHEXP.MAR. This name makes it obvious that the file MTHEXP.MAR contains the procedure MTH$EXP and is written in VAX MACRO.
Sometimes, the module comprising the file will contain more than one
procedure. For example, the RTL procedures LIB$GET_VM and LIB$FREE_VM
are contained in the same module and thus in the same file. In this
case, a more general file name is used, composed of the facility prefix
(LIB) and the first nouns common to all procedure names in the module
(VM). Thus, the name for the file containing procedures LIB$GET_VM and
LIB$FREE_VM is LIBVM.B32. (The file type B32 indicates that the module
is written in VAX BLISS-32.)
22.214.171.124 Module Naming Conventions (Required)
Module names are identical to file names except that module names do not have extensions, and the dollar sign ($) or underscore (_), which separates the facility prefix and symbol name, is not removed.
For example, the MTH$EXP procedure is contained in module MTH$EXP and
the file MTHEXP.MAR. The LIB$GET_VM and LIB$FREE_VM procedures are
contained in the module LIB$VM and the file LIBVM.B32.
126.96.36.199 PSECT Naming Conventions (Required)
The code and data sections of a customer library procedure have two separate program sections (PSECTs), named _fac_CODE and _fac_DATA, where fac is the facility name. Compaq uses _fac$CODE and _fac$DATA as PSECT names.
Position-independent constant data is in the PSECT named _fac_CODE (_fac$CODE for Compaq) to shorten the references. For example,_LIB$CODE and _LIB$DATA are the only two PSECT names used by LIB$ procedures.
The collating sequence for leading underscores causes the linker to place all library procedures after the user program in the executable image. This prevents a library procedure from being placed between two user modules and adversely affecting any byte or word displacement addressing contained in the user programs.
Not all languages give you control over PSECT names. In VAX BASIC and VAX Pascal, it is not possible to control PSECT names except through use of COMMON. However, using COMMON is not recommended.
For additional information about declaring PSECTs, see the appropriate
language reference manual.
188.8.131.52 Lock Resource Naming Conventions (Recommended)
When using the lock manager, the resource names of root-level locks (locks without a parent) should be derived from the facility name. The naming convention used is:
Following this convention will prevent unintended resource conflicts.
184.108.40.206 Global Variable Naming Conventions (Recommended)
Global variables should be named using the following format:
The letter t indicates the contents and usage of the global variable. The possible values of t are listed in Table 3-3.
Likewise, the format for addressable global arrays is as follows:
The letter t indicates the contents and usage of the addressable global array. The possible values of t are listed in Table 3-3.
|Value of t||Content and Usage of Global Variable|
|E||Reserved for Compaq|
|I||Reserved for integer extensions|
|J||Reserved for customers for escape to other codes|
|N||Numeric string (all byte forms)|
|T||Text (character) string|
|U||Smallest unit of addressable storage|
|X||Context dependent (generic)|
|Y||Context dependent (generic)|
|Z||Unspecified or nonstandard|
The format of status codes and condition values is as follows:
For some applications, you may need to make identical argument declarations in several modules. Languages supported by the OpenVMS operating system let you centralize these declarations in one place by using common source files. Table 3-4 summarizes the common source file declarations for languages supported by the OpenVMS operating system.
|Language||Common Source File Declaration|
|Compaq Ada||To share common declarations among DEC Ada programs, you include the declarations in a package (as a separate compilation unit) and provide visibility to the package by using a WITH clause in programs you want to share the common declarations.|
|BASIC||You can use the BASIC directive %INCLUDE in your program to include the common source file, or a Common Data Dictionary (CDD) record.|
|BLISS-32||Your source program can contain a REQUIRE or LIBRARY list option that specifies a file to be included at the point of the declaration.|
|C||Include a preprocessor directive to include a file or a dictionary.|
|COBOL||The COPY statement specifies source text from a COBOL library file, a Librarian file, or a CDD record description that is to be included in the source program.|
|DIBOL||The INCLUDE directive includes a common source from a separate file, text library, or CDD record.|
|FORTRAN||The INCLUDE statement specifies a file or library module to be included at the point of the statement. You can also use a CDD record.|
|Assembly language||An auxiliary source file or macro library can be specified in the command line or by using a CDD record.|
|Pascal||The %INCLUDE directive and INHERIT attribute specify files to be included at the point of the declarations. You can also use a CDD record.|
|PL/I||The %INCLUDE preprocessor statement specifies a file to be inserted as source. You can also use a CDD record.|
|RPG II||An auxiliary source file can be specified in the command line.|
Not all OpenVMS system services are modular, according to the
definitions in this manual. Procedures that call nonmodular system
services are nonmodular themselves. If your procedure uses a nonmodular
system service, you should list the system service in the Side Effects
section of the procedure description. (For information about the
procedure description, see Section 2.6.2.) For more information about
specific system services and modularity, see the OpenVMS System Services Reference Manual.
3.1.4 Invoking Optional User-Action Routines
An optional user-action routine is a useful way to let the calling
program gain control at a critical point in your procedure's algorithm.
Success routines and error routines are the most common user-action
routines. Control is passed from your procedure to the optional error
routine if the specified error is encountered within your procedure. To
transfer control, the calling program must pass the user-action routine
as an argument to the called procedure. To make it easy for the calling
program to pass information to its action routine, your procedure
should supply an optional user-arg argument that the
calling program can pass to its action routine. Your procedure merely
copies the argument list entry of the user argument, if present, to the
argument list it passes to the action routine. This achieves the same
effect as up-level addressing.
220.127.116.11 Bound Procedure Value (VAX Only)
On VAX systems, the bound procedure value (DSC$K_DTYPE_BPV) is used by Compaq Pascal and other languages where context of the procedure must be known. The procedure might do up-level addressing of a variable defined in a syntactically outer block and allocated in another frame. (If you use a procedure entry mask, this context is specified in the user-arg argument.)
For a bound procedure value passed by reference, the argument list entry contains the address of two longwords. The first longword contains the address of the procedure, and the second contains the environment pointer to be loaded into R1 before the procedure is called. This environment pointer allows you to specify the context of your action routine enabling you to do up-level addressing. To provide a user-action routine using the bound procedure value passed by reference, the calling sequence is as follows:
CALL myproc [action-routine [,user-arg]]
In this example, action-routine is a function call of the bound procedure value type that is passed by reference, and user-arg is unspecified.
If you want to use the bound procedure value data type to pass access to a user routine specified as a procedure entry mask, you must pass the first longword by value and omit the second longword. Then, the user-action routine would have this calling sequence:
status = action-routine (...[,user-arg])
In this example, status is a longword condition value
that is passed by value, and user-arg is unspecified.
Your procedure copies the 32-bit argument list entry passed by the
calling program to the argument list provided to the action routine.
Therefore, the calling program and its action routine can communicate
using any data type, access type, passing mechanism, or OpenVMS usage.
3.2 Initializing Modular Procedures
You must perform initialization carefully to maintain modularity.
Initialization must not affect the calling program. Therefore, avoid initializing by providing an entry point that must be called before any other entry point is called. Providing an entry point that must be called first forces the calling program to provide an initialization entry point to its caller, and so forth. Also, you would have to rewrite your calling programs if you needed to substitute a procedure with an initialization call for one without an initialization call.
If your procedure uses LIB$INITIALIZE, you must preserve a modular environment that does not conflict with the environment set by any other procedure using LIB$INITIALIZE. (For more information, see OpenVMS Programming Interfaces: Calling a System Routine1.
Several ways to initialize a procedure are as follows:
The use of each method is explained in the following sections. Figure 3-2 summarizes these methods.
Figure 3-2 Methods of Initializing
1 This manual has been archived but is available on the OpenVMS Documentation CD-ROM.