File: [VAX.DOC]RTLSTDS.RNO .br Date: 9-Nov-78 .skip10 The information in this doucment subject to change without notice and should not be construed as a commitment by Digital Equipment Corporation. Digital Equipment Corporation assumes no responsibility for any errors that may appear in this document. .b The software described in this document is furnished to the purchaser under a license for use on a single computer system and can be copied (with inclusion of DIGITAL's copyright notice) only for use in such system, except as otherwise may be provided in writing by DIGITAL. .b Digital Equipment Corporation assumes no responsibility for the use or reliability of its software on equipment that is not supplied by DIGITAL. .b .c Copyright (C) 1978, by Digital Equipment Corporation .pg .title SUMMARY OF MODULAR PROGRAMMING STANDARDS .rm70 This document summarizes the modular programming standards that must be followed by VAX-11 modular procedures written in any language. .b These standards are designed to be the minimum set necessary to ensure modularity and compatibility between languages. Any modular procedure can thus be added to either an object library or included in a shareable image without conflict with existing procedures or any that may be added in the future. Furthermore, any modular procedure allows its caller to control the produced results so that any modular procedure can call any other modular procedure. .b If you are unsure whether your procedure follows a particular standard, refer to the VAX-11 Guide for Creating Modular Library Procedures. The section numbers after each standard refer to appropriate text in that manual. .HL1 REQUIRED MODULAR PROCEDURE STANDARDS The following standards must be followed by modular procedures that are available to the calling program except for internal procedures and entry points not intended for use by the calling program. .b Standards that have asterisks (*) preceding them are optional standards, but the procedure documentation must indicate the deviation from modular standards: .LS .le;Calls to procedures must follow the VAX-11 Procedure Calling Standard. (See Appendix C of the VAX-11 Common Run-Time Procedure Library Reference Manual.) .le;Modules must be relocatable. (See Section 4.4). .le;Procedure entry point names have the following forms: fac$name for DIGITAL-supplied procedures, and fac__name for user-supplied procedures, where fac can be LIB, MTH, FOR, BLI, B32, MTH, OTS, or any other language abbreviation (and file type) or meaningful facility name. Global entry point names that are not intended for use by the calling program have two dollar signs ($$) or two underlines (____), respectively. (See Section 2.2). .le;The form for module names is the same as that for procedure entry point names. Modules containing one procedure have the same name as that procedure. (See Section 4.2.1). .le;The PSECT declarations for code and data respectively are: .b in MACRO: .b.nf.nj ##.PSECT __fac$CODE PIC,USR,CON,REL,LCL,SHR,EXE,RD,NOWRT .b ##.PSECT __fac$DATA PIC,USR,CON,REL,LCL,NOSHR,NOEXE,RD,WRT .b.f.j in BLISS: .b ## __fac$CODE READ, NOWRITE, EXECUTE, SHARE, PIC, ADDRESSING__MODE (WORD__RELATIVE) .b ##__fac$DATA READ, WRITE, NOEXECUTE, NOSHARE, PIC, ADDRESSING__MODE, (LONG__RELATIVE) .b (In the examples above, user PSECTS replace $ with __) (See Section 4.2.2) .LE;Position-independent references to data PSECTs use longword displacement addressing. This is done so that the data PSECT can be allocated anywhere with respect to the code PSECT by the linker. .le;A procedure does not print error or informational messages. Instead, it either returns a condition value in R0 as a function value or calls LIB$SIGNAL or LIB$STOP to output all messages. (See Sections 5.2 and 5.3). .le;If a procedure requires initialization once per image activation, it is done without the caller's knowledge. This may be done by: (1) the linker at link time, (2) by checking a statically allocated first-time flag on each call, or (3) by making a PSECT contribution to LIB$INITIALIZE (see Section 4.3). NOTE: see PSECT restrictions for shared libraries in Standard no. 30. .le;If a procedure uses a process-wide resource, it calls the appropriate resource allocating library procedure or system service in order to avoid conflicting with allocations of other procedures. (See Section 4.4) .le;If a procedure retains values from one call to the next and is not a resource allocating procedure, it uses one of the following techniques to permit multiple callers: .b .ls.le;The procedure's caller pushes down the storage automatically on the first of a series of calls. (See Section 3.3.1) .le;The procedure's caller passes a handle that is assigned a unique process-wide value on the first call. (see Section 3.3.2) .le;The procedure's caller allocates all storage and passes a pointer to it on each call. (see Section 3.3.3) .le;During a single procedure activation, a procedure does not read from a static storage location without first having written it. (see Section 3.3.4) .els .le;*#A procedure executes in any VAX-11 access mode and at any address. (You should not assume that the address is always positive). .le;The storage for input and output parameters may overlap at the option of the calling program. Therefore, a procedure is programmed to behave the same regardless of whether there is overlap. .le;*#A procedure's caller indicates omitted trailing optional parameters by either passing zero argument list entries or by passing a shortened argument list. When a new version of a procedure replaces an existing library procedure, all added parameters are made optional to maintain upward compatibility. (See Section 2.3.4) .le;A procedure avoids using implicit global data areas that are available to its caller. (See Section 2.5). .le;A procedure provides an interface with its callers that allows the callers to follow all required modular standards. .le;A procedure making calls outside of its module or set of functionally related procedures confines itself to calls to those system services and other procedures that follow all required modular standards. (See Section 4.6). .le;A procedure makes no assumptions about its environment other than these modular standards. .i-8 .HL1 Additional Facility-specific Standards These standards apply to procedures placed in a specific library facility. The facility codes below are used to represent the corresponding library facilities: .b.literal LIB General Utility and Resource Allocation Procedures MTH Mathematics Procedures OTS Language Independent Support Procedures FOR FORTRAN-specific Support Procedures BLI Transporable BLISS-specific Support Procedures B32 VAX-11 Unique Native Mode BLISS-specific Support Procedures .end literal.b .i-8 LIB-specific Standards .le; LIB procedures pass arrays and strings by-descriptor, and input scalars by-reference. (LIB procedures can pass parameters by-value if a procedure provides a service for BLISS and MACRO programmers that is generally supplied as part of higher-level languages. For output strings, the semantics are indicated by the descriptor code passed by the procedure's caller, (either fixed-length, unspecified, or dynamic). If the class code is fixed or unspecified, the output string must be written using the library procedure LIB$SCOPY__DXDX or LIB$SCOPY__R__DX. (See Sections 2.3.2 and 4.5). .le; LIB procedures must return error conditions to the caller using the standard completion codes rather than signaling. (See Chapter 5) .b.i-8 MTH - specific Standards .le; MTH procedures pass input scalars by reference. .le; MTH procedures signal errors if the function value (R0) is used to return a mathematical value. However, math procedures (such as matrix) that are not part of many higher-level languages return an error status in R0 rather than signaling. (see Chapter 5). .b.i-8 Higher Level Language-specific Support Standards (FOR, B32, BLI) .le;Higher-level language support procedures pass input scalars by-value, output scalars by-reference, input and output arrays by-reference, and input and output strings by-descriptor. (see Section 4.5). .le;Higher-level language support procedures return a completion code to the caller on an error when a check of the code is not an excessive speed or space penalty. Otherwise, it retains the error transfer address in the first of a series of calls. (see Chapter 5). .b.i-9 Language Independent Support Standards (OTS) .le; Language-independent support procedures follow the standards for language-specific support procedures described above. .le;Language-independent support procedures should use the procedure OTS$SCOPY__DXDX to write a formal string argument using the semantics defined by the procedure's caller if the class code is not fixed-length or unspecified. (see Section 4.5.2). .i-8 .HL1 *#AST-reentrance Standards The following standards are required for all AST-reentrant procedures. To be AST-reentrant, a procedure allows any procedure including itself to be called between any two instructions. This other procedure may be an AST- level procedure, a condition handler, or another library procedure. (See Chapter 6.) A procedure that uses no static storage and calls only AST-reentrant procedures is automatically AST-reentrant. .le;*#A procedure that uses static storage must use one of the following methods to be AST-reentrant: .ls .le; Perform access and modification of the data base in a single uninterruptible instruction. (See Section 6.3.1) .le; Detect concurrency of data base accyss with 'test and set' instructions at each access of the data base. (See Section 6.3.2) .le; Keep a reentrance level count that is incremented upon entry to the procedure and decremented upon return. (See Section 6.3.3) .le; Disable AST-interrupts on entry to the procedure and restore on return. (See Section 6.3.4) .els .le;*#A procedure performs I/O from the AST level by using VAX-11 RMS $GET and $PUT services. Returns from $GET or $PUT calls must check for record stream active error (RMS$__RSA). If the error is encountered, the procedure issues the $WAIT system service and then retries the $PUT service (see Section 6.4). .le;It is recommended that a procedure not disable AST- interrupts whenever other means are available to avoid race conditions. When disabling AST-interrupts is unavoidable, establish a condition handler that restores the state of the AST-interrupt in case an exception condition or stack unwind occurs. The state of the AST-interrupt enable must be restored before returning to the calling program. (See Section 6.3) .i-8 .HL1*# Shareable Image Library Standards The following standards are required for procedures that are to be included in a shareable image library. Following these standards permits a user to include the procedure in a shareable image library at any time. .le;*#A procedure's code is position-independent. .le;A procedure cannot use LIB$INITIALIZE to initialize data since a shared image cannot make a contribution to a PSECT at link time. (See Section 4.3.4) .i-8 .HL1*#Upwards Compatible Shareable Image Libraries In order to be upwards compatible, shareable image library procedures follow these rules: .le;A procedure's entry points are vectored. (see Section 8.4 ) .le;A procedure's data is position-independent. Initializating to zero is recommended, since a copy-on-reference page can be used. .i-8 .HL 1 Modular Programming Recommendations The following list of recommendations should be followed by modular library procedures if possible. These recommendations are made in the hope that modular library procedures will be similar in form and format. .le;The order of required parameters should be the same as that of the VAX-11 hardware instructions, namely, read, modify, and write. Optional parameters follow in the same order. However, according to the VAX-11 Procedure Calling Standard, if a function cannot be represented in 64 bits, the first parameter specifies where to store the function value, and all other parameters are shifted one position to the right. (See Section 2.3.4) .le;A procedure should avoid the use of static storage unless it is a process-wide resource allocating procedure, or must retain results for implicit inputs on subsequent activations. .le;If a procedure produces bulk output, it provides the caller with an optional parameter that consists of an action routine to do the outputting. (See Section 2.6) The action routine is called with each line as a string descriptor containing a leading space and no carriage-return/line-feed. The action routine returns a condition value that is either: success (the caller continues), or failure (the caller stops further calls to the procedure.) .le;A procedure that allocates process-wide resources provides an entry point that will show the state of the resource (for debugging and performance statistics.) If such an entry point produces bulk output, it must conform to the preceding standard. (See Sections 2.6 and 4.4). .le;Timing procedures and resource allocation procedures should make statistics available for performance evaluation and debugging. (see Section 2.7). Such procedures should provide two entry points which accept an input parameter code (1,...,n) indicating the desired statistic and which return a completion status in R0: .b fac$SHOW__name_** Provides formatted strings containing desired information. (with a leading space and no imbedded ASCII CR, LF, VT, or FF by default output to SYS$OUTPUT or passed to a user-supplied action routine) .b fac$STAT__name_** Returns binary result designating desired statistics (see Section 4.6) A 0 input code indicates all desired statistics. .b ** #(User versions substitute $ with __) .le;Prompt strings should be an English word followed by a colon (:), one space and no CRLF. (VMS utilities use _> with no trailing spaces.) .le; Procedures should follow structured programming guidelines. This includes placing a minimum number of procedures -- typically one -- in a module, and arranging procedures in levels of abstraction. (see Section 4.1). .le;Procedures should be placed in a module that is documented with a module description. Every procedure should be documented with a procedure description. (See Section 2.8) .le;File names should be identical to the first nine characters of the module name, with $ and __ characters omitted. (See Section 4.2.1) When declarations are to be coordinated between more than one module, procedures should use the following techniques depending upon the language which they are written: .b.lm10.ts20 .nf.nj MACRO Parameter file or macro BLISS REQUIRE file FORTRAN INCLUDE file .f.j.lm9 .le;JSB calling sequences should be avoided as they are not available to most languages. When a procedure uses a JSB entry point, it should also provide an equivalent CALL entry point. (See Section 7. .) .le;Instructions and statements are uppercase, comments are lowercase. A space follows every comma, semicolon, and exclamation point. On the other hand, a space precedes a left parenthesis but not a left angle bracket or square bracket. Block comments are placed at the left margin with a blank line, in addition to the flag line symbols preceding and following the comment. (See Section 4.2). .le;Use symbols rather than numbers in the body of the procedure. (see Section 4.2.4)